public/packs-test/application.js
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "/packs-test/";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 209);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
/**
* Use invariant() to assert state which your program assumes to be true.
*
* Provide sprintf-style format (only %s is supported) and arguments
* to provide information about what broke and what you were
* expecting.
*
* The invariant message will be stripped in production, but the invariant
* will remain to ensure logic does not differ in production.
*/
var validateFormat = function validateFormat(format) {};
if (true) {
validateFormat = function validateFormat(format) {
if (format === undefined) {
throw new Error('invariant requires an error message argument');
}
};
}
function invariant(condition, format, a, b, c, d, e, f) {
validateFormat(format);
if (!condition) {
var error;
if (format === undefined) {
error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.');
} else {
var args = [a, b, c, d, e, f];
var argIndex = 0;
error = new Error(format.replace(/%s/g, function () {
return args[argIndex++];
}));
error.name = 'Invariant Violation';
}
error.framesToPop = 1; // we don't care about invariant's own frame
throw error;
}
}
module.exports = invariant;
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2014-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var emptyFunction = __webpack_require__(8);
/**
* Similar to invariant but only logs a warning if the condition is not met.
* This can be used to log issues in development environments in critical
* paths. Removing the logging code for production environments will keep the
* same logic and follow the same code paths.
*/
var warning = emptyFunction;
if (true) {
var printWarning = function printWarning(format) {
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
var argIndex = 0;
var message = 'Warning: ' + format.replace(/%s/g, function () {
return args[argIndex++];
});
if (typeof console !== 'undefined') {
console.error(message);
}
try {
// --- Welcome to debugging React ---
// This error was thrown as a convenience so that you can use this stack
// to find the callsite that caused this warning to fire.
throw new Error(message);
} catch (x) {}
};
warning = function warning(condition, format) {
if (format === undefined) {
throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument');
}
if (format.indexOf('Failed Composite propType: ') === 0) {
return; // Ignore CompositeComponent proptype check.
}
if (!condition) {
for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
args[_key2 - 2] = arguments[_key2];
}
printWarning.apply(undefined, [format].concat(args));
}
};
}
module.exports = warning;
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
/**
* WARNING: DO NOT manually require this module.
* This is a replacement for `invariant(...)` used by the error code system
* and will _only_ be required by the corresponding babel pass.
* It always throws.
*/
function reactProdInvariant(code) {
var argCount = arguments.length - 1;
var message = 'Minified React error #' + code + '; visit ' + 'http://facebook.github.io/react/docs/error-decoder.html?invariant=' + code;
for (var argIdx = 0; argIdx < argCount; argIdx++) {
message += '&args[]=' + encodeURIComponent(arguments[argIdx + 1]);
}
message += ' for the full message or use the non-minified dev environment' + ' for full errors and additional helpful warnings.';
var error = new Error(message);
error.name = 'Invariant Violation';
error.framesToPop = 1; // we don't care about reactProdInvariant's own frame
throw error;
}
module.exports = reactProdInvariant;
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*
object-assign
(c) Sindre Sorhus
@license MIT
*/
/* eslint-disable no-unused-vars */
var getOwnPropertySymbols = Object.getOwnPropertySymbols;
var hasOwnProperty = Object.prototype.hasOwnProperty;
var propIsEnumerable = Object.prototype.propertyIsEnumerable;
function toObject(val) {
if (val === null || val === undefined) {
throw new TypeError('Object.assign cannot be called with null or undefined');
}
return Object(val);
}
function shouldUseNative() {
try {
if (!Object.assign) {
return false;
}
// Detect buggy property enumeration order in older V8 versions.
// https://bugs.chromium.org/p/v8/issues/detail?id=4118
var test1 = new String('abc'); // eslint-disable-line no-new-wrappers
test1[5] = 'de';
if (Object.getOwnPropertyNames(test1)[0] === '5') {
return false;
}
// https://bugs.chromium.org/p/v8/issues/detail?id=3056
var test2 = {};
for (var i = 0; i < 10; i++) {
test2['_' + String.fromCharCode(i)] = i;
}
var order2 = Object.getOwnPropertyNames(test2).map(function (n) {
return test2[n];
});
if (order2.join('') !== '0123456789') {
return false;
}
// https://bugs.chromium.org/p/v8/issues/detail?id=3056
var test3 = {};
'abcdefghijklmnopqrst'.split('').forEach(function (letter) {
test3[letter] = letter;
});
if (Object.keys(Object.assign({}, test3)).join('') !==
'abcdefghijklmnopqrst') {
return false;
}
return true;
} catch (err) {
// We don't expect any of the above to throw, but better to be safe.
return false;
}
}
module.exports = shouldUseNative() ? Object.assign : function (target, source) {
var from;
var to = toObject(target);
var symbols;
for (var s = 1; s < arguments.length; s++) {
from = Object(arguments[s]);
for (var key in from) {
if (hasOwnProperty.call(from, key)) {
to[key] = from[key];
}
}
if (getOwnPropertySymbols) {
symbols = getOwnPropertySymbols(from);
for (var i = 0; i < symbols.length; i++) {
if (propIsEnumerable.call(from, symbols[i])) {
to[symbols[i]] = from[symbols[i]];
}
}
}
}
return to;
};
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _prodInvariant = __webpack_require__(2);
var DOMProperty = __webpack_require__(13);
var ReactDOMComponentFlags = __webpack_require__(59);
var invariant = __webpack_require__(0);
var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME;
var Flags = ReactDOMComponentFlags;
var internalInstanceKey = '__reactInternalInstance$' + Math.random().toString(36).slice(2);
/**
* Check if a given node should be cached.
*/
function shouldPrecacheNode(node, nodeID) {
return node.nodeType === 1 && node.getAttribute(ATTR_NAME) === String(nodeID) || node.nodeType === 8 && node.nodeValue === ' react-text: ' + nodeID + ' ' || node.nodeType === 8 && node.nodeValue === ' react-empty: ' + nodeID + ' ';
}
/**
* Drill down (through composites and empty components) until we get a host or
* host text component.
*
* This is pretty polymorphic but unavoidable with the current structure we have
* for `_renderedChildren`.
*/
function getRenderedHostOrTextFromComponent(component) {
var rendered;
while (rendered = component._renderedComponent) {
component = rendered;
}
return component;
}
/**
* Populate `_hostNode` on the rendered host/text component with the given
* DOM node. The passed `inst` can be a composite.
*/
function precacheNode(inst, node) {
var hostInst = getRenderedHostOrTextFromComponent(inst);
hostInst._hostNode = node;
node[internalInstanceKey] = hostInst;
}
function uncacheNode(inst) {
var node = inst._hostNode;
if (node) {
delete node[internalInstanceKey];
inst._hostNode = null;
}
}
/**
* Populate `_hostNode` on each child of `inst`, assuming that the children
* match up with the DOM (element) children of `node`.
*
* We cache entire levels at once to avoid an n^2 problem where we access the
* children of a node sequentially and have to walk from the start to our target
* node every time.
*
* Since we update `_renderedChildren` and the actual DOM at (slightly)
* different times, we could race here and see a newer `_renderedChildren` than
* the DOM nodes we see. To avoid this, ReactMultiChild calls
* `prepareToManageChildren` before we change `_renderedChildren`, at which
* time the container's child nodes are always cached (until it unmounts).
*/
function precacheChildNodes(inst, node) {
if (inst._flags & Flags.hasCachedChildNodes) {
return;
}
var children = inst._renderedChildren;
var childNode = node.firstChild;
outer: for (var name in children) {
if (!children.hasOwnProperty(name)) {
continue;
}
var childInst = children[name];
var childID = getRenderedHostOrTextFromComponent(childInst)._domID;
if (childID === 0) {
// We're currently unmounting this child in ReactMultiChild; skip it.
continue;
}
// We assume the child nodes are in the same order as the child instances.
for (; childNode !== null; childNode = childNode.nextSibling) {
if (shouldPrecacheNode(childNode, childID)) {
precacheNode(childInst, childNode);
continue outer;
}
}
// We reached the end of the DOM children without finding an ID match.
true ? true ? invariant(false, 'Unable to find element with ID %s.', childID) : _prodInvariant('32', childID) : void 0;
}
inst._flags |= Flags.hasCachedChildNodes;
}
/**
* Given a DOM node, return the closest ReactDOMComponent or
* ReactDOMTextComponent instance ancestor.
*/
function getClosestInstanceFromNode(node) {
if (node[internalInstanceKey]) {
return node[internalInstanceKey];
}
// Walk up the tree until we find an ancestor whose instance we have cached.
var parents = [];
while (!node[internalInstanceKey]) {
parents.push(node);
if (node.parentNode) {
node = node.parentNode;
} else {
// Top of the tree. This node must not be part of a React tree (or is
// unmounted, potentially).
return null;
}
}
var closest;
var inst;
for (; node && (inst = node[internalInstanceKey]); node = parents.pop()) {
closest = inst;
if (parents.length) {
precacheChildNodes(inst, node);
}
}
return closest;
}
/**
* Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent
* instance, or null if the node was not rendered by this React.
*/
function getInstanceFromNode(node) {
var inst = getClosestInstanceFromNode(node);
if (inst != null && inst._hostNode === node) {
return inst;
} else {
return null;
}
}
/**
* Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding
* DOM node.
*/
function getNodeFromInstance(inst) {
// Without this first invariant, passing a non-DOM-component triggers the next
// invariant for a missing parent, which is super confusing.
!(inst._hostNode !== undefined) ? true ? invariant(false, 'getNodeFromInstance: Invalid argument.') : _prodInvariant('33') : void 0;
if (inst._hostNode) {
return inst._hostNode;
}
// Walk up the tree until we find an ancestor whose DOM node we have cached.
var parents = [];
while (!inst._hostNode) {
parents.push(inst);
!inst._hostParent ? true ? invariant(false, 'React DOM tree root should always have a node reference.') : _prodInvariant('34') : void 0;
inst = inst._hostParent;
}
// Now parents contains each ancestor that does *not* have a cached native
// node, and `inst` is the deepest ancestor that does.
for (; parents.length; inst = parents.pop()) {
precacheChildNodes(inst, inst._hostNode);
}
return inst._hostNode;
}
var ReactDOMComponentTree = {
getClosestInstanceFromNode: getClosestInstanceFromNode,
getInstanceFromNode: getInstanceFromNode,
getNodeFromInstance: getNodeFromInstance,
precacheChildNodes: precacheChildNodes,
precacheNode: precacheNode,
uncacheNode: uncacheNode
};
module.exports = ReactDOMComponentTree;
/***/ }),
/* 5 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
/**
* Simple, lightweight module assisting with the detection and context of
* Worker. Helps avoid circular dependencies and allows code to reason about
* whether or not they are in a Worker, even if they never include the main
* `ReactWorker` dependency.
*/
var ExecutionEnvironment = {
canUseDOM: canUseDOM,
canUseWorkers: typeof Worker !== 'undefined',
canUseEventListeners: canUseDOM && !!(window.addEventListener || window.attachEvent),
canUseViewport: canUseDOM && !!window.screen,
isInWorker: !canUseDOM // For now, this is true - might change in the future.
};
module.exports = ExecutionEnvironment;
/***/ }),
/* 6 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2016-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var _prodInvariant = __webpack_require__(17);
var ReactCurrentOwner = __webpack_require__(9);
var invariant = __webpack_require__(0);
var warning = __webpack_require__(1);
function isNative(fn) {
// Based on isNative() from Lodash
var funcToString = Function.prototype.toString;
var hasOwnProperty = Object.prototype.hasOwnProperty;
var reIsNative = RegExp('^' + funcToString
// Take an example native function source for comparison
.call(hasOwnProperty
// Strip regex characters so we can use it for regex
).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&'
// Remove hasOwnProperty from the template to make it generic
).replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$');
try {
var source = funcToString.call(fn);
return reIsNative.test(source);
} catch (err) {
return false;
}
}
var canUseCollections =
// Array.from
typeof Array.from === 'function' &&
// Map
typeof Map === 'function' && isNative(Map) &&
// Map.prototype.keys
Map.prototype != null && typeof Map.prototype.keys === 'function' && isNative(Map.prototype.keys) &&
// Set
typeof Set === 'function' && isNative(Set) &&
// Set.prototype.keys
Set.prototype != null && typeof Set.prototype.keys === 'function' && isNative(Set.prototype.keys);
var setItem;
var getItem;
var removeItem;
var getItemIDs;
var addRoot;
var removeRoot;
var getRootIDs;
if (canUseCollections) {
var itemMap = new Map();
var rootIDSet = new Set();
setItem = function (id, item) {
itemMap.set(id, item);
};
getItem = function (id) {
return itemMap.get(id);
};
removeItem = function (id) {
itemMap['delete'](id);
};
getItemIDs = function () {
return Array.from(itemMap.keys());
};
addRoot = function (id) {
rootIDSet.add(id);
};
removeRoot = function (id) {
rootIDSet['delete'](id);
};
getRootIDs = function () {
return Array.from(rootIDSet.keys());
};
} else {
var itemByKey = {};
var rootByKey = {};
// Use non-numeric keys to prevent V8 performance issues:
// https://github.com/facebook/react/pull/7232
var getKeyFromID = function (id) {
return '.' + id;
};
var getIDFromKey = function (key) {
return parseInt(key.substr(1), 10);
};
setItem = function (id, item) {
var key = getKeyFromID(id);
itemByKey[key] = item;
};
getItem = function (id) {
var key = getKeyFromID(id);
return itemByKey[key];
};
removeItem = function (id) {
var key = getKeyFromID(id);
delete itemByKey[key];
};
getItemIDs = function () {
return Object.keys(itemByKey).map(getIDFromKey);
};
addRoot = function (id) {
var key = getKeyFromID(id);
rootByKey[key] = true;
};
removeRoot = function (id) {
var key = getKeyFromID(id);
delete rootByKey[key];
};
getRootIDs = function () {
return Object.keys(rootByKey).map(getIDFromKey);
};
}
var unmountedIDs = [];
function purgeDeep(id) {
var item = getItem(id);
if (item) {
var childIDs = item.childIDs;
removeItem(id);
childIDs.forEach(purgeDeep);
}
}
function describeComponentFrame(name, source, ownerName) {
return '\n in ' + (name || 'Unknown') + (source ? ' (at ' + source.fileName.replace(/^.*[\\\/]/, '') + ':' + source.lineNumber + ')' : ownerName ? ' (created by ' + ownerName + ')' : '');
}
function getDisplayName(element) {
if (element == null) {
return '#empty';
} else if (typeof element === 'string' || typeof element === 'number') {
return '#text';
} else if (typeof element.type === 'string') {
return element.type;
} else {
return element.type.displayName || element.type.name || 'Unknown';
}
}
function describeID(id) {
var name = ReactComponentTreeHook.getDisplayName(id);
var element = ReactComponentTreeHook.getElement(id);
var ownerID = ReactComponentTreeHook.getOwnerID(id);
var ownerName;
if (ownerID) {
ownerName = ReactComponentTreeHook.getDisplayName(ownerID);
}
true ? warning(element, 'ReactComponentTreeHook: Missing React element for debugID %s when ' + 'building stack', id) : void 0;
return describeComponentFrame(name, element && element._source, ownerName);
}
var ReactComponentTreeHook = {
onSetChildren: function (id, nextChildIDs) {
var item = getItem(id);
!item ? true ? invariant(false, 'Item must have been set') : _prodInvariant('144') : void 0;
item.childIDs = nextChildIDs;
for (var i = 0; i < nextChildIDs.length; i++) {
var nextChildID = nextChildIDs[i];
var nextChild = getItem(nextChildID);
!nextChild ? true ? invariant(false, 'Expected hook events to fire for the child before its parent includes it in onSetChildren().') : _prodInvariant('140') : void 0;
!(nextChild.childIDs != null || typeof nextChild.element !== 'object' || nextChild.element == null) ? true ? invariant(false, 'Expected onSetChildren() to fire for a container child before its parent includes it in onSetChildren().') : _prodInvariant('141') : void 0;
!nextChild.isMounted ? true ? invariant(false, 'Expected onMountComponent() to fire for the child before its parent includes it in onSetChildren().') : _prodInvariant('71') : void 0;
if (nextChild.parentID == null) {
nextChild.parentID = id;
// TODO: This shouldn't be necessary but mounting a new root during in
// componentWillMount currently causes not-yet-mounted components to
// be purged from our tree data so their parent id is missing.
}
!(nextChild.parentID === id) ? true ? invariant(false, 'Expected onBeforeMountComponent() parent and onSetChildren() to be consistent (%s has parents %s and %s).', nextChildID, nextChild.parentID, id) : _prodInvariant('142', nextChildID, nextChild.parentID, id) : void 0;
}
},
onBeforeMountComponent: function (id, element, parentID) {
var item = {
element: element,
parentID: parentID,
text: null,
childIDs: [],
isMounted: false,
updateCount: 0
};
setItem(id, item);
},
onBeforeUpdateComponent: function (id, element) {
var item = getItem(id);
if (!item || !item.isMounted) {
// We may end up here as a result of setState() in componentWillUnmount().
// In this case, ignore the element.
return;
}
item.element = element;
},
onMountComponent: function (id) {
var item = getItem(id);
!item ? true ? invariant(false, 'Item must have been set') : _prodInvariant('144') : void 0;
item.isMounted = true;
var isRoot = item.parentID === 0;
if (isRoot) {
addRoot(id);
}
},
onUpdateComponent: function (id) {
var item = getItem(id);
if (!item || !item.isMounted) {
// We may end up here as a result of setState() in componentWillUnmount().
// In this case, ignore the element.
return;
}
item.updateCount++;
},
onUnmountComponent: function (id) {
var item = getItem(id);
if (item) {
// We need to check if it exists.
// `item` might not exist if it is inside an error boundary, and a sibling
// error boundary child threw while mounting. Then this instance never
// got a chance to mount, but it still gets an unmounting event during
// the error boundary cleanup.
item.isMounted = false;
var isRoot = item.parentID === 0;
if (isRoot) {
removeRoot(id);
}
}
unmountedIDs.push(id);
},
purgeUnmountedComponents: function () {
if (ReactComponentTreeHook._preventPurging) {
// Should only be used for testing.
return;
}
for (var i = 0; i < unmountedIDs.length; i++) {
var id = unmountedIDs[i];
purgeDeep(id);
}
unmountedIDs.length = 0;
},
isMounted: function (id) {
var item = getItem(id);
return item ? item.isMounted : false;
},
getCurrentStackAddendum: function (topElement) {
var info = '';
if (topElement) {
var name = getDisplayName(topElement);
var owner = topElement._owner;
info += describeComponentFrame(name, topElement._source, owner && owner.getName());
}
var currentOwner = ReactCurrentOwner.current;
var id = currentOwner && currentOwner._debugID;
info += ReactComponentTreeHook.getStackAddendumByID(id);
return info;
},
getStackAddendumByID: function (id) {
var info = '';
while (id) {
info += describeID(id);
id = ReactComponentTreeHook.getParentID(id);
}
return info;
},
getChildIDs: function (id) {
var item = getItem(id);
return item ? item.childIDs : [];
},
getDisplayName: function (id) {
var element = ReactComponentTreeHook.getElement(id);
if (!element) {
return null;
}
return getDisplayName(element);
},
getElement: function (id) {
var item = getItem(id);
return item ? item.element : null;
},
getOwnerID: function (id) {
var element = ReactComponentTreeHook.getElement(id);
if (!element || !element._owner) {
return null;
}
return element._owner._debugID;
},
getParentID: function (id) {
var item = getItem(id);
return item ? item.parentID : null;
},
getSource: function (id) {
var item = getItem(id);
var element = item ? item.element : null;
var source = element != null ? element._source : null;
return source;
},
getText: function (id) {
var element = ReactComponentTreeHook.getElement(id);
if (typeof element === 'string') {
return element;
} else if (typeof element === 'number') {
return '' + element;
} else {
return null;
}
},
getUpdateCount: function (id) {
var item = getItem(id);
return item ? item.updateCount : 0;
},
getRootIDs: getRootIDs,
getRegisteredIDs: getItemIDs,
pushNonStandardWarningStack: function (isCreatingElement, currentSource) {
if (typeof console.reactStack !== 'function') {
return;
}
var stack = [];
var currentOwner = ReactCurrentOwner.current;
var id = currentOwner && currentOwner._debugID;
try {
if (isCreatingElement) {
stack.push({
name: id ? ReactComponentTreeHook.getDisplayName(id) : null,
fileName: currentSource ? currentSource.fileName : null,
lineNumber: currentSource ? currentSource.lineNumber : null
});
}
while (id) {
var element = ReactComponentTreeHook.getElement(id);
var parentID = ReactComponentTreeHook.getParentID(id);
var ownerID = ReactComponentTreeHook.getOwnerID(id);
var ownerName = ownerID ? ReactComponentTreeHook.getDisplayName(ownerID) : null;
var source = element && element._source;
stack.push({
name: ownerName,
fileName: source ? source.fileName : null,
lineNumber: source ? source.lineNumber : null
});
id = parentID;
}
} catch (err) {
// Internal state is messed up.
// Stop building the stack (it's just a nice to have).
}
console.reactStack(stack);
},
popNonStandardWarningStack: function () {
if (typeof console.reactStackEnd !== 'function') {
return;
}
console.reactStackEnd();
}
};
module.exports = ReactComponentTreeHook;
/***/ }),
/* 7 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2016-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
// Trust the developer to only use ReactInstrumentation with a __DEV__ check
var debugTool = null;
if (true) {
var ReactDebugTool = __webpack_require__(115);
debugTool = ReactDebugTool;
}
module.exports = { debugTool: debugTool };
/***/ }),
/* 8 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
function makeEmptyFunction(arg) {
return function () {
return arg;
};
}
/**
* This function accepts and discards inputs; it has no side effects. This is
* primarily useful idiomatically for overridable function endpoints which
* always need to be callable, since JS lacks a null-call idiom ala Cocoa.
*/
var emptyFunction = function emptyFunction() {};
emptyFunction.thatReturns = makeEmptyFunction;
emptyFunction.thatReturnsFalse = makeEmptyFunction(false);
emptyFunction.thatReturnsTrue = makeEmptyFunction(true);
emptyFunction.thatReturnsNull = makeEmptyFunction(null);
emptyFunction.thatReturnsThis = function () {
return this;
};
emptyFunction.thatReturnsArgument = function (arg) {
return arg;
};
module.exports = emptyFunction;
/***/ }),
/* 9 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
/**
* Keeps track of the current owner.
*
* The current owner is the component who should own any components that are
* currently being constructed.
*/
var ReactCurrentOwner = {
/**
* @internal
* @type {ReactComponent}
*/
current: null
};
module.exports = ReactCurrentOwner;
/***/ }),
/* 10 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _prodInvariant = __webpack_require__(2),
_assign = __webpack_require__(3);
var CallbackQueue = __webpack_require__(63);
var PooledClass = __webpack_require__(15);
var ReactFeatureFlags = __webpack_require__(64);
var ReactReconciler = __webpack_require__(18);
var Transaction = __webpack_require__(29);
var invariant = __webpack_require__(0);
var dirtyComponents = [];
var updateBatchNumber = 0;
var asapCallbackQueue = CallbackQueue.getPooled();
var asapEnqueued = false;
var batchingStrategy = null;
function ensureInjected() {
!(ReactUpdates.ReactReconcileTransaction && batchingStrategy) ? true ? invariant(false, 'ReactUpdates: must inject a reconcile transaction class and batching strategy') : _prodInvariant('123') : void 0;
}
var NESTED_UPDATES = {
initialize: function () {
this.dirtyComponentsLength = dirtyComponents.length;
},
close: function () {
if (this.dirtyComponentsLength !== dirtyComponents.length) {
// Additional updates were enqueued by componentDidUpdate handlers or
// similar; before our own UPDATE_QUEUEING wrapper closes, we want to run
// these new updates so that if A's componentDidUpdate calls setState on
// B, B will update before the callback A's updater provided when calling
// setState.
dirtyComponents.splice(0, this.dirtyComponentsLength);
flushBatchedUpdates();
} else {
dirtyComponents.length = 0;
}
}
};
var UPDATE_QUEUEING = {
initialize: function () {
this.callbackQueue.reset();
},
close: function () {
this.callbackQueue.notifyAll();
}
};
var TRANSACTION_WRAPPERS = [NESTED_UPDATES, UPDATE_QUEUEING];
function ReactUpdatesFlushTransaction() {
this.reinitializeTransaction();
this.dirtyComponentsLength = null;
this.callbackQueue = CallbackQueue.getPooled();
this.reconcileTransaction = ReactUpdates.ReactReconcileTransaction.getPooled(
/* useCreateElement */true);
}
_assign(ReactUpdatesFlushTransaction.prototype, Transaction, {
getTransactionWrappers: function () {
return TRANSACTION_WRAPPERS;
},
destructor: function () {
this.dirtyComponentsLength = null;
CallbackQueue.release(this.callbackQueue);
this.callbackQueue = null;
ReactUpdates.ReactReconcileTransaction.release(this.reconcileTransaction);
this.reconcileTransaction = null;
},
perform: function (method, scope, a) {
// Essentially calls `this.reconcileTransaction.perform(method, scope, a)`
// with this transaction's wrappers around it.
return Transaction.perform.call(this, this.reconcileTransaction.perform, this.reconcileTransaction, method, scope, a);
}
});
PooledClass.addPoolingTo(ReactUpdatesFlushTransaction);
function batchedUpdates(callback, a, b, c, d, e) {
ensureInjected();
return batchingStrategy.batchedUpdates(callback, a, b, c, d, e);
}
/**
* Array comparator for ReactComponents by mount ordering.
*
* @param {ReactComponent} c1 first component you're comparing
* @param {ReactComponent} c2 second component you're comparing
* @return {number} Return value usable by Array.prototype.sort().
*/
function mountOrderComparator(c1, c2) {
return c1._mountOrder - c2._mountOrder;
}
function runBatchedUpdates(transaction) {
var len = transaction.dirtyComponentsLength;
!(len === dirtyComponents.length) ? true ? invariant(false, 'Expected flush transaction\'s stored dirty-components length (%s) to match dirty-components array length (%s).', len, dirtyComponents.length) : _prodInvariant('124', len, dirtyComponents.length) : void 0;
// Since reconciling a component higher in the owner hierarchy usually (not
// always -- see shouldComponentUpdate()) will reconcile children, reconcile
// them before their children by sorting the array.
dirtyComponents.sort(mountOrderComparator);
// Any updates enqueued while reconciling must be performed after this entire
// batch. Otherwise, if dirtyComponents is [A, B] where A has children B and
// C, B could update twice in a single batch if C's render enqueues an update
// to B (since B would have already updated, we should skip it, and the only
// way we can know to do so is by checking the batch counter).
updateBatchNumber++;
for (var i = 0; i < len; i++) {
// If a component is unmounted before pending changes apply, it will still
// be here, but we assume that it has cleared its _pendingCallbacks and
// that performUpdateIfNecessary is a noop.
var component = dirtyComponents[i];
// If performUpdateIfNecessary happens to enqueue any new updates, we
// shouldn't execute the callbacks until the next render happens, so
// stash the callbacks first
var callbacks = component._pendingCallbacks;
component._pendingCallbacks = null;
var markerName;
if (ReactFeatureFlags.logTopLevelRenders) {
var namedComponent = component;
// Duck type TopLevelWrapper. This is probably always true.
if (component._currentElement.type.isReactTopLevelWrapper) {
namedComponent = component._renderedComponent;
}
markerName = 'React update: ' + namedComponent.getName();
console.time(markerName);
}
ReactReconciler.performUpdateIfNecessary(component, transaction.reconcileTransaction, updateBatchNumber);
if (markerName) {
console.timeEnd(markerName);
}
if (callbacks) {
for (var j = 0; j < callbacks.length; j++) {
transaction.callbackQueue.enqueue(callbacks[j], component.getPublicInstance());
}
}
}
}
var flushBatchedUpdates = function () {
// ReactUpdatesFlushTransaction's wrappers will clear the dirtyComponents
// array and perform any updates enqueued by mount-ready handlers (i.e.,
// componentDidUpdate) but we need to check here too in order to catch
// updates enqueued by setState callbacks and asap calls.
while (dirtyComponents.length || asapEnqueued) {
if (dirtyComponents.length) {
var transaction = ReactUpdatesFlushTransaction.getPooled();
transaction.perform(runBatchedUpdates, null, transaction);
ReactUpdatesFlushTransaction.release(transaction);
}
if (asapEnqueued) {
asapEnqueued = false;
var queue = asapCallbackQueue;
asapCallbackQueue = CallbackQueue.getPooled();
queue.notifyAll();
CallbackQueue.release(queue);
}
}
};
/**
* Mark a component as needing a rerender, adding an optional callback to a
* list of functions which will be executed once the rerender occurs.
*/
function enqueueUpdate(component) {
ensureInjected();
// Various parts of our code (such as ReactCompositeComponent's
// _renderValidatedComponent) assume that calls to render aren't nested;
// verify that that's the case. (This is called by each top-level update
// function, like setState, forceUpdate, etc.; creation and
// destruction of top-level components is guarded in ReactMount.)
if (!batchingStrategy.isBatchingUpdates) {
batchingStrategy.batchedUpdates(enqueueUpdate, component);
return;
}
dirtyComponents.push(component);
if (component._updateBatchNumber == null) {
component._updateBatchNumber = updateBatchNumber + 1;
}
}
/**
* Enqueue a callback to be run at the end of the current batching cycle. Throws
* if no updates are currently being performed.
*/
function asap(callback, context) {
invariant(batchingStrategy.isBatchingUpdates, "ReactUpdates.asap: Can't enqueue an asap callback in a context where" + 'updates are not being batched.');
asapCallbackQueue.enqueue(callback, context);
asapEnqueued = true;
}
var ReactUpdatesInjection = {
injectReconcileTransaction: function (ReconcileTransaction) {
!ReconcileTransaction ? true ? invariant(false, 'ReactUpdates: must provide a reconcile transaction class') : _prodInvariant('126') : void 0;
ReactUpdates.ReactReconcileTransaction = ReconcileTransaction;
},
injectBatchingStrategy: function (_batchingStrategy) {
!_batchingStrategy ? true ? invariant(false, 'ReactUpdates: must provide a batching strategy') : _prodInvariant('127') : void 0;
!(typeof _batchingStrategy.batchedUpdates === 'function') ? true ? invariant(false, 'ReactUpdates: must provide a batchedUpdates() function') : _prodInvariant('128') : void 0;
!(typeof _batchingStrategy.isBatchingUpdates === 'boolean') ? true ? invariant(false, 'ReactUpdates: must provide an isBatchingUpdates boolean attribute') : _prodInvariant('129') : void 0;
batchingStrategy = _batchingStrategy;
}
};
var ReactUpdates = {
/**
* React references `ReactReconcileTransaction` using this property in order
* to allow dependency injection.
*
* @internal
*/
ReactReconcileTransaction: null,
batchedUpdates: batchedUpdates,
enqueueUpdate: enqueueUpdate,
flushBatchedUpdates: flushBatchedUpdates,
injection: ReactUpdatesInjection,
asap: asap
};
module.exports = ReactUpdates;
/***/ }),
/* 11 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
module.exports = __webpack_require__(16);
/***/ }),
/* 12 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _assign = __webpack_require__(3);
var PooledClass = __webpack_require__(15);
var emptyFunction = __webpack_require__(8);
var warning = __webpack_require__(1);
var didWarnForAddedNewProperty = false;
var isProxySupported = typeof Proxy === 'function';
var shouldBeReleasedProperties = ['dispatchConfig', '_targetInst', 'nativeEvent', 'isDefaultPrevented', 'isPropagationStopped', '_dispatchListeners', '_dispatchInstances'];
/**
* @interface Event
* @see http://www.w3.org/TR/DOM-Level-3-Events/
*/
var EventInterface = {
type: null,
target: null,
// currentTarget is set when dispatching; no use in copying it here
currentTarget: emptyFunction.thatReturnsNull,
eventPhase: null,
bubbles: null,
cancelable: null,
timeStamp: function (event) {
return event.timeStamp || Date.now();
},
defaultPrevented: null,
isTrusted: null
};
/**
* Synthetic events are dispatched by event plugins, typically in response to a
* top-level event delegation handler.
*
* These systems should generally use pooling to reduce the frequency of garbage
* collection. The system should check `isPersistent` to determine whether the
* event should be released into the pool after being dispatched. Users that
* need a persisted event should invoke `persist`.
*
* Synthetic events (and subclasses) implement the DOM Level 3 Events API by
* normalizing browser quirks. Subclasses do not necessarily have to implement a
* DOM interface; custom application-specific events can also subclass this.
*
* @param {object} dispatchConfig Configuration used to dispatch this event.
* @param {*} targetInst Marker identifying the event target.
* @param {object} nativeEvent Native browser event.
* @param {DOMEventTarget} nativeEventTarget Target node.
*/
function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) {
if (true) {
// these have a getter/setter for warnings
delete this.nativeEvent;
delete this.preventDefault;
delete this.stopPropagation;
}
this.dispatchConfig = dispatchConfig;
this._targetInst = targetInst;
this.nativeEvent = nativeEvent;
var Interface = this.constructor.Interface;
for (var propName in Interface) {
if (!Interface.hasOwnProperty(propName)) {
continue;
}
if (true) {
delete this[propName]; // this has a getter/setter for warnings
}
var normalize = Interface[propName];
if (normalize) {
this[propName] = normalize(nativeEvent);
} else {
if (propName === 'target') {
this.target = nativeEventTarget;
} else {
this[propName] = nativeEvent[propName];
}
}
}
var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
if (defaultPrevented) {
this.isDefaultPrevented = emptyFunction.thatReturnsTrue;
} else {
this.isDefaultPrevented = emptyFunction.thatReturnsFalse;
}
this.isPropagationStopped = emptyFunction.thatReturnsFalse;
return this;
}
_assign(SyntheticEvent.prototype, {
preventDefault: function () {
this.defaultPrevented = true;
var event = this.nativeEvent;
if (!event) {
return;
}
if (event.preventDefault) {
event.preventDefault();
// eslint-disable-next-line valid-typeof
} else if (typeof event.returnValue !== 'unknown') {
event.returnValue = false;
}
this.isDefaultPrevented = emptyFunction.thatReturnsTrue;
},
stopPropagation: function () {
var event = this.nativeEvent;
if (!event) {
return;
}
if (event.stopPropagation) {
event.stopPropagation();
// eslint-disable-next-line valid-typeof
} else if (typeof event.cancelBubble !== 'unknown') {
// The ChangeEventPlugin registers a "propertychange" event for
// IE. This event does not support bubbling or cancelling, and
// any references to cancelBubble throw "Member not found". A
// typeof check of "unknown" circumvents this issue (and is also
// IE specific).
event.cancelBubble = true;
}
this.isPropagationStopped = emptyFunction.thatReturnsTrue;
},
/**
* We release all dispatched `SyntheticEvent`s after each event loop, adding
* them back into the pool. This allows a way to hold onto a reference that
* won't be added back into the pool.
*/
persist: function () {
this.isPersistent = emptyFunction.thatReturnsTrue;
},
/**
* Checks if this event should be released back into the pool.
*
* @return {boolean} True if this should not be released, false otherwise.
*/
isPersistent: emptyFunction.thatReturnsFalse,
/**
* `PooledClass` looks for `destructor` on each instance it releases.
*/
destructor: function () {
var Interface = this.constructor.Interface;
for (var propName in Interface) {
if (true) {
Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName]));
} else {
this[propName] = null;
}
}
for (var i = 0; i < shouldBeReleasedProperties.length; i++) {
this[shouldBeReleasedProperties[i]] = null;
}
if (true) {
Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null));
Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', emptyFunction));
Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', emptyFunction));
}
}
});
SyntheticEvent.Interface = EventInterface;
/**
* Helper to reduce boilerplate when creating subclasses.
*
* @param {function} Class
* @param {?object} Interface
*/
SyntheticEvent.augmentClass = function (Class, Interface) {
var Super = this;
var E = function () {};
E.prototype = Super.prototype;
var prototype = new E();
_assign(prototype, Class.prototype);
Class.prototype = prototype;
Class.prototype.constructor = Class;
Class.Interface = _assign({}, Super.Interface, Interface);
Class.augmentClass = Super.augmentClass;
PooledClass.addPoolingTo(Class, PooledClass.fourArgumentPooler);
};
/** Proxying after everything set on SyntheticEvent
* to resolve Proxy issue on some WebKit browsers
* in which some Event properties are set to undefined (GH#10010)
*/
if (true) {
if (isProxySupported) {
/*eslint-disable no-func-assign */
SyntheticEvent = new Proxy(SyntheticEvent, {
construct: function (target, args) {
return this.apply(target, Object.create(target.prototype), args);
},
apply: function (constructor, that, args) {
return new Proxy(constructor.apply(that, args), {
set: function (target, prop, value) {
if (prop !== 'isPersistent' && !target.constructor.Interface.hasOwnProperty(prop) && shouldBeReleasedProperties.indexOf(prop) === -1) {
true ? warning(didWarnForAddedNewProperty || target.isPersistent(), "This synthetic event is reused for performance reasons. If you're " + "seeing this, you're adding a new property in the synthetic event object. " + 'The property is never released. See ' + 'https://fb.me/react-event-pooling for more information.') : void 0;
didWarnForAddedNewProperty = true;
}
target[prop] = value;
return true;
}
});
}
});
/*eslint-enable no-func-assign */
}
}
PooledClass.addPoolingTo(SyntheticEvent, PooledClass.fourArgumentPooler);
module.exports = SyntheticEvent;
/**
* Helper to nullify syntheticEvent instance properties when destructing
*
* @param {object} SyntheticEvent
* @param {String} propName
* @return {object} defineProperty object
*/
function getPooledWarningPropertyDefinition(propName, getVal) {
var isFunction = typeof getVal === 'function';
return {
configurable: true,
set: set,
get: get
};
function set(val) {
var action = isFunction ? 'setting the method' : 'setting the property';
warn(action, 'This is effectively a no-op');
return val;
}
function get() {
var action = isFunction ? 'accessing the method' : 'accessing the property';
var result = isFunction ? 'This is a no-op function' : 'This is set to null';
warn(action, result);
return getVal;
}
function warn(action, result) {
var warningCondition = false;
true ? warning(warningCondition, "This synthetic event is reused for performance reasons. If you're seeing this, " + "you're %s `%s` on a released/nullified synthetic event. %s. " + 'If you must keep the original synthetic event around, use event.persist(). ' + 'See https://fb.me/react-event-pooling for more information.', action, propName, result) : void 0;
}
}
/***/ }),
/* 13 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _prodInvariant = __webpack_require__(2);
var invariant = __webpack_require__(0);
function checkMask(value, bitmask) {
return (value & bitmask) === bitmask;
}
var DOMPropertyInjection = {
/**
* Mapping from normalized, camelcased property names to a configuration that
* specifies how the associated DOM property should be accessed or rendered.
*/
MUST_USE_PROPERTY: 0x1,
HAS_BOOLEAN_VALUE: 0x4,
HAS_NUMERIC_VALUE: 0x8,
HAS_POSITIVE_NUMERIC_VALUE: 0x10 | 0x8,
HAS_OVERLOADED_BOOLEAN_VALUE: 0x20,
/**
* Inject some specialized knowledge about the DOM. This takes a config object
* with the following properties:
*
* isCustomAttribute: function that given an attribute name will return true
* if it can be inserted into the DOM verbatim. Useful for data-* or aria-*
* attributes where it's impossible to enumerate all of the possible
* attribute names,
*
* Properties: object mapping DOM property name to one of the
* DOMPropertyInjection constants or null. If your attribute isn't in here,
* it won't get written to the DOM.
*
* DOMAttributeNames: object mapping React attribute name to the DOM
* attribute name. Attribute names not specified use the **lowercase**
* normalized name.
*
* DOMAttributeNamespaces: object mapping React attribute name to the DOM
* attribute namespace URL. (Attribute names not specified use no namespace.)
*
* DOMPropertyNames: similar to DOMAttributeNames but for DOM properties.
* Property names not specified use the normalized name.
*
* DOMMutationMethods: Properties that require special mutation methods. If
* `value` is undefined, the mutation method should unset the property.
*
* @param {object} domPropertyConfig the config as described above.
*/
injectDOMPropertyConfig: function (domPropertyConfig) {
var Injection = DOMPropertyInjection;
var Properties = domPropertyConfig.Properties || {};
var DOMAttributeNamespaces = domPropertyConfig.DOMAttributeNamespaces || {};
var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {};
var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {};
var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {};
if (domPropertyConfig.isCustomAttribute) {
DOMProperty._isCustomAttributeFunctions.push(domPropertyConfig.isCustomAttribute);
}
for (var propName in Properties) {
!!DOMProperty.properties.hasOwnProperty(propName) ? true ? invariant(false, 'injectDOMPropertyConfig(...): You\'re trying to inject DOM property \'%s\' which has already been injected. You may be accidentally injecting the same DOM property config twice, or you may be injecting two configs that have conflicting property names.', propName) : _prodInvariant('48', propName) : void 0;
var lowerCased = propName.toLowerCase();
var propConfig = Properties[propName];
var propertyInfo = {
attributeName: lowerCased,
attributeNamespace: null,
propertyName: propName,
mutationMethod: null,
mustUseProperty: checkMask(propConfig, Injection.MUST_USE_PROPERTY),
hasBooleanValue: checkMask(propConfig, Injection.HAS_BOOLEAN_VALUE),
hasNumericValue: checkMask(propConfig, Injection.HAS_NUMERIC_VALUE),
hasPositiveNumericValue: checkMask(propConfig, Injection.HAS_POSITIVE_NUMERIC_VALUE),
hasOverloadedBooleanValue: checkMask(propConfig, Injection.HAS_OVERLOADED_BOOLEAN_VALUE)
};
!(propertyInfo.hasBooleanValue + propertyInfo.hasNumericValue + propertyInfo.hasOverloadedBooleanValue <= 1) ? true ? invariant(false, 'DOMProperty: Value can be one of boolean, overloaded boolean, or numeric value, but not a combination: %s', propName) : _prodInvariant('50', propName) : void 0;
if (true) {
DOMProperty.getPossibleStandardName[lowerCased] = propName;
}
if (DOMAttributeNames.hasOwnProperty(propName)) {
var attributeName = DOMAttributeNames[propName];
propertyInfo.attributeName = attributeName;
if (true) {
DOMProperty.getPossibleStandardName[attributeName] = propName;
}
}
if (DOMAttributeNamespaces.hasOwnProperty(propName)) {
propertyInfo.attributeNamespace = DOMAttributeNamespaces[propName];
}
if (DOMPropertyNames.hasOwnProperty(propName)) {
propertyInfo.propertyName = DOMPropertyNames[propName];
}
if (DOMMutationMethods.hasOwnProperty(propName)) {
propertyInfo.mutationMethod = DOMMutationMethods[propName];
}
DOMProperty.properties[propName] = propertyInfo;
}
}
};
/* eslint-disable max-len */
var ATTRIBUTE_NAME_START_CHAR = ':A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD';
/* eslint-enable max-len */
/**
* DOMProperty exports lookup objects that can be used like functions:
*
* > DOMProperty.isValid['id']
* true
* > DOMProperty.isValid['foobar']
* undefined
*
* Although this may be confusing, it performs better in general.
*
* @see http://jsperf.com/key-exists
* @see http://jsperf.com/key-missing
*/
var DOMProperty = {
ID_ATTRIBUTE_NAME: 'data-reactid',
ROOT_ATTRIBUTE_NAME: 'data-reactroot',
ATTRIBUTE_NAME_START_CHAR: ATTRIBUTE_NAME_START_CHAR,
ATTRIBUTE_NAME_CHAR: ATTRIBUTE_NAME_START_CHAR + '\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040',
/**
* Map from property "standard name" to an object with info about how to set
* the property in the DOM. Each object contains:
*
* attributeName:
* Used when rendering markup or with `*Attribute()`.
* attributeNamespace
* propertyName:
* Used on DOM node instances. (This includes properties that mutate due to
* external factors.)
* mutationMethod:
* If non-null, used instead of the property or `setAttribute()` after
* initial render.
* mustUseProperty:
* Whether the property must be accessed and mutated as an object property.
* hasBooleanValue:
* Whether the property should be removed when set to a falsey value.
* hasNumericValue:
* Whether the property must be numeric or parse as a numeric and should be
* removed when set to a falsey value.
* hasPositiveNumericValue:
* Whether the property must be positive numeric or parse as a positive
* numeric and should be removed when set to a falsey value.
* hasOverloadedBooleanValue:
* Whether the property can be used as a flag as well as with a value.
* Removed when strictly equal to false; present without a value when
* strictly equal to true; present with a value otherwise.
*/
properties: {},
/**
* Mapping from lowercase property names to the properly cased version, used
* to warn in the case of missing properties. Available only in __DEV__.
*
* autofocus is predefined, because adding it to the property whitelist
* causes unintended side effects.
*
* @type {Object}
*/
getPossibleStandardName: true ? { autofocus: 'autoFocus' } : null,
/**
* All of the isCustomAttribute() functions that have been injected.
*/
_isCustomAttributeFunctions: [],
/**
* Checks whether a property name is a custom attribute.
* @method
*/
isCustomAttribute: function (attributeName) {
for (var i = 0; i < DOMProperty._isCustomAttributeFunctions.length; i++) {
var isCustomAttributeFn = DOMProperty._isCustomAttributeFunctions[i];
if (isCustomAttributeFn(attributeName)) {
return true;
}
}
return false;
},
injection: DOMPropertyInjection
};
module.exports = DOMProperty;
/***/ }),
/* 14 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2014-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _assign = __webpack_require__(3);
var ReactCurrentOwner = __webpack_require__(9);
var warning = __webpack_require__(1);
var canDefineProperty = __webpack_require__(26);
var hasOwnProperty = Object.prototype.hasOwnProperty;
var REACT_ELEMENT_TYPE = __webpack_require__(54);
var RESERVED_PROPS = {
key: true,
ref: true,
__self: true,
__source: true
};
var specialPropKeyWarningShown, specialPropRefWarningShown;
function hasValidRef(config) {
if (true) {
if (hasOwnProperty.call(config, 'ref')) {
var getter = Object.getOwnPropertyDescriptor(config, 'ref').get;
if (getter && getter.isReactWarning) {
return false;
}
}
}
return config.ref !== undefined;
}
function hasValidKey(config) {
if (true) {
if (hasOwnProperty.call(config, 'key')) {
var getter = Object.getOwnPropertyDescriptor(config, 'key').get;
if (getter && getter.isReactWarning) {
return false;
}
}
}
return config.key !== undefined;
}
function defineKeyPropWarningGetter(props, displayName) {
var warnAboutAccessingKey = function () {
if (!specialPropKeyWarningShown) {
specialPropKeyWarningShown = true;
true ? warning(false, '%s: `key` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://fb.me/react-special-props)', displayName) : void 0;
}
};
warnAboutAccessingKey.isReactWarning = true;
Object.defineProperty(props, 'key', {
get: warnAboutAccessingKey,
configurable: true
});
}
function defineRefPropWarningGetter(props, displayName) {
var warnAboutAccessingRef = function () {
if (!specialPropRefWarningShown) {
specialPropRefWarningShown = true;
true ? warning(false, '%s: `ref` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://fb.me/react-special-props)', displayName) : void 0;
}
};
warnAboutAccessingRef.isReactWarning = true;
Object.defineProperty(props, 'ref', {
get: warnAboutAccessingRef,
configurable: true
});
}
/**
* Factory method to create a new React element. This no longer adheres to
* the class pattern, so do not use new to call it. Also, no instanceof check
* will work. Instead test $$typeof field against Symbol.for('react.element') to check
* if something is a React Element.
*
* @param {*} type
* @param {*} key
* @param {string|object} ref
* @param {*} self A *temporary* helper to detect places where `this` is
* different from the `owner` when React.createElement is called, so that we
* can warn. We want to get rid of owner and replace string `ref`s with arrow
* functions, and as long as `this` and owner are the same, there will be no
* change in behavior.
* @param {*} source An annotation object (added by a transpiler or otherwise)
* indicating filename, line number, and/or other information.
* @param {*} owner
* @param {*} props
* @internal
*/
var ReactElement = function (type, key, ref, self, source, owner, props) {
var element = {
// This tag allow us to uniquely identify this as a React Element
$$typeof: REACT_ELEMENT_TYPE,
// Built-in properties that belong on the element
type: type,
key: key,
ref: ref,
props: props,
// Record the component responsible for creating this element.
_owner: owner
};
if (true) {
// The validation flag is currently mutative. We put it on
// an external backing store so that we can freeze the whole object.
// This can be replaced with a WeakMap once they are implemented in
// commonly used development environments.
element._store = {};
// To make comparing ReactElements easier for testing purposes, we make
// the validation flag non-enumerable (where possible, which should
// include every environment we run tests in), so the test framework
// ignores it.
if (canDefineProperty) {
Object.defineProperty(element._store, 'validated', {
configurable: false,
enumerable: false,
writable: true,
value: false
});
// self and source are DEV only properties.
Object.defineProperty(element, '_self', {
configurable: false,
enumerable: false,
writable: false,
value: self
});
// Two elements created in two different places should be considered
// equal for testing purposes and therefore we hide it from enumeration.
Object.defineProperty(element, '_source', {
configurable: false,
enumerable: false,
writable: false,
value: source
});
} else {
element._store.validated = false;
element._self = self;
element._source = source;
}
if (Object.freeze) {
Object.freeze(element.props);
Object.freeze(element);
}
}
return element;
};
/**
* Create and return a new ReactElement of the given type.
* See https://facebook.github.io/react/docs/top-level-api.html#react.createelement
*/
ReactElement.createElement = function (type, config, children) {
var propName;
// Reserved names are extracted
var props = {};
var key = null;
var ref = null;
var self = null;
var source = null;
if (config != null) {
if (hasValidRef(config)) {
ref = config.ref;
}
if (hasValidKey(config)) {
key = '' + config.key;
}
self = config.__self === undefined ? null : config.__self;
source = config.__source === undefined ? null : config.__source;
// Remaining properties are added to a new props object
for (propName in config) {
if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {
props[propName] = config[propName];
}
}
}
// Children can be more than one argument, and those are transferred onto
// the newly allocated props object.
var childrenLength = arguments.length - 2;
if (childrenLength === 1) {
props.children = children;
} else if (childrenLength > 1) {
var childArray = Array(childrenLength);
for (var i = 0; i < childrenLength; i++) {
childArray[i] = arguments[i + 2];
}
if (true) {
if (Object.freeze) {
Object.freeze(childArray);
}
}
props.children = childArray;
}
// Resolve default props
if (type && type.defaultProps) {
var defaultProps = type.defaultProps;
for (propName in defaultProps) {
if (props[propName] === undefined) {
props[propName] = defaultProps[propName];
}
}
}
if (true) {
if (key || ref) {
if (typeof props.$$typeof === 'undefined' || props.$$typeof !== REACT_ELEMENT_TYPE) {
var displayName = typeof type === 'function' ? type.displayName || type.name || 'Unknown' : type;
if (key) {
defineKeyPropWarningGetter(props, displayName);
}
if (ref) {
defineRefPropWarningGetter(props, displayName);
}
}
}
}
return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props);
};
/**
* Return a function that produces ReactElements of a given type.
* See https://facebook.github.io/react/docs/top-level-api.html#react.createfactory
*/
ReactElement.createFactory = function (type) {
var factory = ReactElement.createElement.bind(null, type);
// Expose the type on the factory and the prototype so that it can be
// easily accessed on elements. E.g. `<Foo />.type === Foo`.
// This should not be named `constructor` since this may not be the function
// that created the element, and it may not even be a constructor.
// Legacy hook TODO: Warn if this is accessed
factory.type = type;
return factory;
};
ReactElement.cloneAndReplaceKey = function (oldElement, newKey) {
var newElement = ReactElement(oldElement.type, newKey, oldElement.ref, oldElement._self, oldElement._source, oldElement._owner, oldElement.props);
return newElement;
};
/**
* Clone and return a new ReactElement using element as the starting point.
* See https://facebook.github.io/react/docs/top-level-api.html#react.cloneelement
*/
ReactElement.cloneElement = function (element, config, children) {
var propName;
// Original props are copied
var props = _assign({}, element.props);
// Reserved names are extracted
var key = element.key;
var ref = element.ref;
// Self is preserved since the owner is preserved.
var self = element._self;
// Source is preserved since cloneElement is unlikely to be targeted by a
// transpiler, and the original source is probably a better indicator of the
// true owner.
var source = element._source;
// Owner will be preserved, unless ref is overridden
var owner = element._owner;
if (config != null) {
if (hasValidRef(config)) {
// Silently steal the ref from the parent.
ref = config.ref;
owner = ReactCurrentOwner.current;
}
if (hasValidKey(config)) {
key = '' + config.key;
}
// Remaining properties override existing props
var defaultProps;
if (element.type && element.type.defaultProps) {
defaultProps = element.type.defaultProps;
}
for (propName in config) {
if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {
if (config[propName] === undefined && defaultProps !== undefined) {
// Resolve default props
props[propName] = defaultProps[propName];
} else {
props[propName] = config[propName];
}
}
}
}
// Children can be more than one argument, and those are transferred onto
// the newly allocated props object.
var childrenLength = arguments.length - 2;
if (childrenLength === 1) {
props.children = children;
} else if (childrenLength > 1) {
var childArray = Array(childrenLength);
for (var i = 0; i < childrenLength; i++) {
childArray[i] = arguments[i + 2];
}
props.children = childArray;
}
return ReactElement(element.type, key, ref, self, source, owner, props);
};
/**
* Verifies the object is a ReactElement.
* See https://facebook.github.io/react/docs/top-level-api.html#react.isvalidelement
* @param {?object} object
* @return {boolean} True if `object` is a valid component.
* @final
*/
ReactElement.isValidElement = function (object) {
return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;
};
module.exports = ReactElement;
/***/ }),
/* 15 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var _prodInvariant = __webpack_require__(2);
var invariant = __webpack_require__(0);
/**
* Static poolers. Several custom versions for each potential number of
* arguments. A completely generic pooler is easy to implement, but would
* require accessing the `arguments` object. In each of these, `this` refers to
* the Class itself, not an instance. If any others are needed, simply add them
* here, or in their own files.
*/
var oneArgumentPooler = function (copyFieldsFrom) {
var Klass = this;
if (Klass.instancePool.length) {
var instance = Klass.instancePool.pop();
Klass.call(instance, copyFieldsFrom);
return instance;
} else {
return new Klass(copyFieldsFrom);
}
};
var twoArgumentPooler = function (a1, a2) {
var Klass = this;
if (Klass.instancePool.length) {
var instance = Klass.instancePool.pop();
Klass.call(instance, a1, a2);
return instance;
} else {
return new Klass(a1, a2);
}
};
var threeArgumentPooler = function (a1, a2, a3) {
var Klass = this;
if (Klass.instancePool.length) {
var instance = Klass.instancePool.pop();
Klass.call(instance, a1, a2, a3);
return instance;
} else {
return new Klass(a1, a2, a3);
}
};
var fourArgumentPooler = function (a1, a2, a3, a4) {
var Klass = this;
if (Klass.instancePool.length) {
var instance = Klass.instancePool.pop();
Klass.call(instance, a1, a2, a3, a4);
return instance;
} else {
return new Klass(a1, a2, a3, a4);
}
};
var standardReleaser = function (instance) {
var Klass = this;
!(instance instanceof Klass) ? true ? invariant(false, 'Trying to release an instance into a pool of a different type.') : _prodInvariant('25') : void 0;
instance.destructor();
if (Klass.instancePool.length < Klass.poolSize) {
Klass.instancePool.push(instance);
}
};
var DEFAULT_POOL_SIZE = 10;
var DEFAULT_POOLER = oneArgumentPooler;
/**
* Augments `CopyConstructor` to be a poolable class, augmenting only the class
* itself (statically) not adding any prototypical fields. Any CopyConstructor
* you give this may have a `poolSize` property, and will look for a
* prototypical `destructor` on instances.
*
* @param {Function} CopyConstructor Constructor that can be used to reset.
* @param {Function} pooler Customizable pooler.
*/
var addPoolingTo = function (CopyConstructor, pooler) {
// Casting as any so that flow ignores the actual implementation and trusts
// it to match the type we declared
var NewKlass = CopyConstructor;
NewKlass.instancePool = [];
NewKlass.getPooled = pooler || DEFAULT_POOLER;
if (!NewKlass.poolSize) {
NewKlass.poolSize = DEFAULT_POOL_SIZE;
}
NewKlass.release = standardReleaser;
return NewKlass;
};
var PooledClass = {
addPoolingTo: addPoolingTo,
oneArgumentPooler: oneArgumentPooler,
twoArgumentPooler: twoArgumentPooler,
threeArgumentPooler: threeArgumentPooler,
fourArgumentPooler: fourArgumentPooler
};
module.exports = PooledClass;
/***/ }),
/* 16 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _assign = __webpack_require__(3);
var ReactBaseClasses = __webpack_require__(52);
var ReactChildren = __webpack_require__(90);
var ReactDOMFactories = __webpack_require__(94);
var ReactElement = __webpack_require__(14);
var ReactPropTypes = __webpack_require__(98);
var ReactVersion = __webpack_require__(100);
var createReactClass = __webpack_require__(101);
var onlyChild = __webpack_require__(103);
var createElement = ReactElement.createElement;
var createFactory = ReactElement.createFactory;
var cloneElement = ReactElement.cloneElement;
if (true) {
var lowPriorityWarning = __webpack_require__(35);
var canDefineProperty = __webpack_require__(26);
var ReactElementValidator = __webpack_require__(56);
var didWarnPropTypesDeprecated = false;
createElement = ReactElementValidator.createElement;
createFactory = ReactElementValidator.createFactory;
cloneElement = ReactElementValidator.cloneElement;
}
var __spread = _assign;
var createMixin = function (mixin) {
return mixin;
};
if (true) {
var warnedForSpread = false;
var warnedForCreateMixin = false;
__spread = function () {
lowPriorityWarning(warnedForSpread, 'React.__spread is deprecated and should not be used. Use ' + 'Object.assign directly or another helper function with similar ' + 'semantics. You may be seeing this warning due to your compiler. ' + 'See https://fb.me/react-spread-deprecation for more details.');
warnedForSpread = true;
return _assign.apply(null, arguments);
};
createMixin = function (mixin) {
lowPriorityWarning(warnedForCreateMixin, 'React.createMixin is deprecated and should not be used. ' + 'In React v16.0, it will be removed. ' + 'You can use this mixin directly instead. ' + 'See https://fb.me/createmixin-was-never-implemented for more info.');
warnedForCreateMixin = true;
return mixin;
};
}
var React = {
// Modern
Children: {
map: ReactChildren.map,
forEach: ReactChildren.forEach,
count: ReactChildren.count,
toArray: ReactChildren.toArray,
only: onlyChild
},
Component: ReactBaseClasses.Component,
PureComponent: ReactBaseClasses.PureComponent,
createElement: createElement,
cloneElement: cloneElement,
isValidElement: ReactElement.isValidElement,
// Classic
PropTypes: ReactPropTypes,
createClass: createReactClass,
createFactory: createFactory,
createMixin: createMixin,
// This looks DOM specific but these are actually isomorphic helpers
// since they are just generating DOM strings.
DOM: ReactDOMFactories,
version: ReactVersion,
// Deprecated hook for JSX spread, don't use this for anything.
__spread: __spread
};
if (true) {
var warnedForCreateClass = false;
if (canDefineProperty) {
Object.defineProperty(React, 'PropTypes', {
get: function () {
lowPriorityWarning(didWarnPropTypesDeprecated, 'Accessing PropTypes via the main React package is deprecated,' + ' and will be removed in React v16.0.' + ' Use the latest available v15.* prop-types package from npm instead.' + ' For info on usage, compatibility, migration and more, see ' + 'https://fb.me/prop-types-docs');
didWarnPropTypesDeprecated = true;
return ReactPropTypes;
}
});
Object.defineProperty(React, 'createClass', {
get: function () {
lowPriorityWarning(warnedForCreateClass, 'Accessing createClass via the main React package is deprecated,' + ' and will be removed in React v16.0.' + " Use a plain JavaScript class instead. If you're not yet " + 'ready to migrate, create-react-class v15.* is available ' + 'on npm as a temporary, drop-in replacement. ' + 'For more info see https://fb.me/react-create-class');
warnedForCreateClass = true;
return createReactClass;
}
});
}
// React.DOM factories are deprecated. Wrap these methods so that
// invocations of the React.DOM namespace and alert users to switch
// to the `react-dom-factories` package.
React.DOM = {};
var warnedForFactories = false;
Object.keys(ReactDOMFactories).forEach(function (factory) {
React.DOM[factory] = function () {
if (!warnedForFactories) {
lowPriorityWarning(false, 'Accessing factories like React.DOM.%s has been deprecated ' + 'and will be removed in v16.0+. Use the ' + 'react-dom-factories package instead. ' + ' Version 1.0 provides a drop-in replacement.' + ' For more info, see https://fb.me/react-dom-factories', factory);
warnedForFactories = true;
}
return ReactDOMFactories[factory].apply(ReactDOMFactories, arguments);
};
});
}
module.exports = React;
/***/ }),
/* 17 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
/**
* WARNING: DO NOT manually require this module.
* This is a replacement for `invariant(...)` used by the error code system
* and will _only_ be required by the corresponding babel pass.
* It always throws.
*/
function reactProdInvariant(code) {
var argCount = arguments.length - 1;
var message = 'Minified React error #' + code + '; visit ' + 'http://facebook.github.io/react/docs/error-decoder.html?invariant=' + code;
for (var argIdx = 0; argIdx < argCount; argIdx++) {
message += '&args[]=' + encodeURIComponent(arguments[argIdx + 1]);
}
message += ' for the full message or use the non-minified dev environment' + ' for full errors and additional helpful warnings.';
var error = new Error(message);
error.name = 'Invariant Violation';
error.framesToPop = 1; // we don't care about reactProdInvariant's own frame
throw error;
}
module.exports = reactProdInvariant;
/***/ }),
/* 18 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var ReactRef = __webpack_require__(113);
var ReactInstrumentation = __webpack_require__(7);
var warning = __webpack_require__(1);
/**
* Helper to call ReactRef.attachRefs with this composite component, split out
* to avoid allocations in the transaction mount-ready queue.
*/
function attachRefs() {
ReactRef.attachRefs(this, this._currentElement);
}
var ReactReconciler = {
/**
* Initializes the component, renders markup, and registers event listeners.
*
* @param {ReactComponent} internalInstance
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
* @param {?object} the containing host component instance
* @param {?object} info about the host container
* @return {?string} Rendered markup to be inserted into the DOM.
* @final
* @internal
*/
mountComponent: function (internalInstance, transaction, hostParent, hostContainerInfo, context, parentDebugID) // 0 in production and for roots
{
if (true) {
if (internalInstance._debugID !== 0) {
ReactInstrumentation.debugTool.onBeforeMountComponent(internalInstance._debugID, internalInstance._currentElement, parentDebugID);
}
}
var markup = internalInstance.mountComponent(transaction, hostParent, hostContainerInfo, context, parentDebugID);
if (internalInstance._currentElement && internalInstance._currentElement.ref != null) {
transaction.getReactMountReady().enqueue(attachRefs, internalInstance);
}
if (true) {
if (internalInstance._debugID !== 0) {
ReactInstrumentation.debugTool.onMountComponent(internalInstance._debugID);
}
}
return markup;
},
/**
* Returns a value that can be passed to
* ReactComponentEnvironment.replaceNodeWithMarkup.
*/
getHostNode: function (internalInstance) {
return internalInstance.getHostNode();
},
/**
* Releases any resources allocated by `mountComponent`.
*
* @final
* @internal
*/
unmountComponent: function (internalInstance, safely) {
if (true) {
if (internalInstance._debugID !== 0) {
ReactInstrumentation.debugTool.onBeforeUnmountComponent(internalInstance._debugID);
}
}
ReactRef.detachRefs(internalInstance, internalInstance._currentElement);
internalInstance.unmountComponent(safely);
if (true) {
if (internalInstance._debugID !== 0) {
ReactInstrumentation.debugTool.onUnmountComponent(internalInstance._debugID);
}
}
},
/**
* Update a component using a new element.
*
* @param {ReactComponent} internalInstance
* @param {ReactElement} nextElement
* @param {ReactReconcileTransaction} transaction
* @param {object} context
* @internal
*/
receiveComponent: function (internalInstance, nextElement, transaction, context) {
var prevElement = internalInstance._currentElement;
if (nextElement === prevElement && context === internalInstance._context) {
// Since elements are immutable after the owner is rendered,
// we can do a cheap identity compare here to determine if this is a
// superfluous reconcile. It's possible for state to be mutable but such
// change should trigger an update of the owner which would recreate
// the element. We explicitly check for the existence of an owner since
// it's possible for an element created outside a composite to be
// deeply mutated and reused.
// TODO: Bailing out early is just a perf optimization right?
// TODO: Removing the return statement should affect correctness?
return;
}
if (true) {
if (internalInstance._debugID !== 0) {
ReactInstrumentation.debugTool.onBeforeUpdateComponent(internalInstance._debugID, nextElement);
}
}
var refsChanged = ReactRef.shouldUpdateRefs(prevElement, nextElement);
if (refsChanged) {
ReactRef.detachRefs(internalInstance, prevElement);
}
internalInstance.receiveComponent(nextElement, transaction, context);
if (refsChanged && internalInstance._currentElement && internalInstance._currentElement.ref != null) {
transaction.getReactMountReady().enqueue(attachRefs, internalInstance);
}
if (true) {
if (internalInstance._debugID !== 0) {
ReactInstrumentation.debugTool.onUpdateComponent(internalInstance._debugID);
}
}
},
/**
* Flush any dirty changes in a component.
*
* @param {ReactComponent} internalInstance
* @param {ReactReconcileTransaction} transaction
* @internal
*/
performUpdateIfNecessary: function (internalInstance, transaction, updateBatchNumber) {
if (internalInstance._updateBatchNumber !== updateBatchNumber) {
// The component's enqueued batch number should always be the current
// batch or the following one.
true ? warning(internalInstance._updateBatchNumber == null || internalInstance._updateBatchNumber === updateBatchNumber + 1, 'performUpdateIfNecessary: Unexpected batch number (current %s, ' + 'pending %s)', updateBatchNumber, internalInstance._updateBatchNumber) : void 0;
return;
}
if (true) {
if (internalInstance._debugID !== 0) {
ReactInstrumentation.debugTool.onBeforeUpdateComponent(internalInstance._debugID, internalInstance._currentElement);
}
}
internalInstance.performUpdateIfNecessary(transaction);
if (true) {
if (internalInstance._debugID !== 0) {
ReactInstrumentation.debugTool.onUpdateComponent(internalInstance._debugID);
}
}
}
};
module.exports = ReactReconciler;
/***/ }),
/* 19 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var DOMNamespaces = __webpack_require__(42);
var setInnerHTML = __webpack_require__(31);
var createMicrosoftUnsafeLocalFunction = __webpack_require__(43);
var setTextContent = __webpack_require__(68);
var ELEMENT_NODE_TYPE = 1;
var DOCUMENT_FRAGMENT_NODE_TYPE = 11;
/**
* In IE (8-11) and Edge, appending nodes with no children is dramatically
* faster than appending a full subtree, so we essentially queue up the
* .appendChild calls here and apply them so each node is added to its parent
* before any children are added.
*
* In other browsers, doing so is slower or neutral compared to the other order
* (in Firefox, twice as slow) so we only do this inversion in IE.
*
* See https://github.com/spicyj/innerhtml-vs-createelement-vs-clonenode.
*/
var enableLazy = typeof document !== 'undefined' && typeof document.documentMode === 'number' || typeof navigator !== 'undefined' && typeof navigator.userAgent === 'string' && /\bEdge\/\d/.test(navigator.userAgent);
function insertTreeChildren(tree) {
if (!enableLazy) {
return;
}
var node = tree.node;
var children = tree.children;
if (children.length) {
for (var i = 0; i < children.length; i++) {
insertTreeBefore(node, children[i], null);
}
} else if (tree.html != null) {
setInnerHTML(node, tree.html);
} else if (tree.text != null) {
setTextContent(node, tree.text);
}
}
var insertTreeBefore = createMicrosoftUnsafeLocalFunction(function (parentNode, tree, referenceNode) {
// DocumentFragments aren't actually part of the DOM after insertion so
// appending children won't update the DOM. We need to ensure the fragment
// is properly populated first, breaking out of our lazy approach for just
// this level. Also, some <object> plugins (like Flash Player) will read
// <param> nodes immediately upon insertion into the DOM, so <object>
// must also be populated prior to insertion into the DOM.
if (tree.node.nodeType === DOCUMENT_FRAGMENT_NODE_TYPE || tree.node.nodeType === ELEMENT_NODE_TYPE && tree.node.nodeName.toLowerCase() === 'object' && (tree.node.namespaceURI == null || tree.node.namespaceURI === DOMNamespaces.html)) {
insertTreeChildren(tree);
parentNode.insertBefore(tree.node, referenceNode);
} else {
parentNode.insertBefore(tree.node, referenceNode);
insertTreeChildren(tree);
}
});
function replaceChildWithTree(oldNode, newTree) {
oldNode.parentNode.replaceChild(newTree.node, oldNode);
insertTreeChildren(newTree);
}
function queueChild(parentTree, childTree) {
if (enableLazy) {
parentTree.children.push(childTree);
} else {
parentTree.node.appendChild(childTree.node);
}
}
function queueHTML(tree, html) {
if (enableLazy) {
tree.html = html;
} else {
setInnerHTML(tree.node, html);
}
}
function queueText(tree, text) {
if (enableLazy) {
tree.text = text;
} else {
setTextContent(tree.node, text);
}
}
function toString() {
return this.node.nodeName;
}
function DOMLazyTree(node) {
return {
node: node,
children: [],
html: null,
text: null,
toString: toString
};
}
DOMLazyTree.insertTreeBefore = insertTreeBefore;
DOMLazyTree.replaceChildWithTree = replaceChildWithTree;
DOMLazyTree.queueChild = queueChild;
DOMLazyTree.queueHTML = queueHTML;
DOMLazyTree.queueText = queueText;
module.exports = DOMLazyTree;
/***/ }),
/* 20 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var EventPluginHub = __webpack_require__(21);
var EventPluginUtils = __webpack_require__(36);
var accumulateInto = __webpack_require__(60);
var forEachAccumulated = __webpack_require__(61);
var warning = __webpack_require__(1);
var getListener = EventPluginHub.getListener;
/**
* Some event types have a notion of different registration names for different
* "phases" of propagation. This finds listeners by a given phase.
*/
function listenerAtPhase(inst, event, propagationPhase) {
var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase];
return getListener(inst, registrationName);
}
/**
* Tags a `SyntheticEvent` with dispatched listeners. Creating this function
* here, allows us to not have to bind or create functions for each event.
* Mutating the event's members allows us to not have to create a wrapping
* "dispatch" object that pairs the event with the listener.
*/
function accumulateDirectionalDispatches(inst, phase, event) {
if (true) {
true ? warning(inst, 'Dispatching inst must not be null') : void 0;
}
var listener = listenerAtPhase(inst, event, phase);
if (listener) {
event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
}
}
/**
* Collect dispatches (must be entirely collected before dispatching - see unit
* tests). Lazily allocate the array to conserve memory. We must loop through
* each event and perform the traversal for each one. We cannot perform a
* single traversal for the entire collection of events because each event may
* have a different target.
*/
function accumulateTwoPhaseDispatchesSingle(event) {
if (event && event.dispatchConfig.phasedRegistrationNames) {
EventPluginUtils.traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event);
}
}
/**
* Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID.
*/
function accumulateTwoPhaseDispatchesSingleSkipTarget(event) {
if (event && event.dispatchConfig.phasedRegistrationNames) {
var targetInst = event._targetInst;
var parentInst = targetInst ? EventPluginUtils.getParentInstance(targetInst) : null;
EventPluginUtils.traverseTwoPhase(parentInst, accumulateDirectionalDispatches, event);
}
}
/**
* Accumulates without regard to direction, does not look for phased
* registration names. Same as `accumulateDirectDispatchesSingle` but without
* requiring that the `dispatchMarker` be the same as the dispatched ID.
*/
function accumulateDispatches(inst, ignoredDirection, event) {
if (event && event.dispatchConfig.registrationName) {
var registrationName = event.dispatchConfig.registrationName;
var listener = getListener(inst, registrationName);
if (listener) {
event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
}
}
}
/**
* Accumulates dispatches on an `SyntheticEvent`, but only for the
* `dispatchMarker`.
* @param {SyntheticEvent} event
*/
function accumulateDirectDispatchesSingle(event) {
if (event && event.dispatchConfig.registrationName) {
accumulateDispatches(event._targetInst, null, event);
}
}
function accumulateTwoPhaseDispatches(events) {
forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
}
function accumulateTwoPhaseDispatchesSkipTarget(events) {
forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget);
}
function accumulateEnterLeaveDispatches(leave, enter, from, to) {
EventPluginUtils.traverseEnterLeave(from, to, accumulateDispatches, leave, enter);
}
function accumulateDirectDispatches(events) {
forEachAccumulated(events, accumulateDirectDispatchesSingle);
}
/**
* A small set of propagation patterns, each of which will accept a small amount
* of information, and generate a set of "dispatch ready event objects" - which
* are sets of events that have already been annotated with a set of dispatched
* listener functions/ids. The API is designed this way to discourage these
* propagation strategies from actually executing the dispatches, since we
* always want to collect the entire set of dispatches before executing event a
* single one.
*
* @constructor EventPropagators
*/
var EventPropagators = {
accumulateTwoPhaseDispatches: accumulateTwoPhaseDispatches,
accumulateTwoPhaseDispatchesSkipTarget: accumulateTwoPhaseDispatchesSkipTarget,
accumulateDirectDispatches: accumulateDirectDispatches,
accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches
};
module.exports = EventPropagators;
/***/ }),
/* 21 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _prodInvariant = __webpack_require__(2);
var EventPluginRegistry = __webpack_require__(28);
var EventPluginUtils = __webpack_require__(36);
var ReactErrorUtils = __webpack_require__(37);
var accumulateInto = __webpack_require__(60);
var forEachAccumulated = __webpack_require__(61);
var invariant = __webpack_require__(0);
/**
* Internal store for event listeners
*/
var listenerBank = {};
/**
* Internal queue of events that have accumulated their dispatches and are
* waiting to have their dispatches executed.
*/
var eventQueue = null;
/**
* Dispatches an event and releases it back into the pool, unless persistent.
*
* @param {?object} event Synthetic event to be dispatched.
* @param {boolean} simulated If the event is simulated (changes exn behavior)
* @private
*/
var executeDispatchesAndRelease = function (event, simulated) {
if (event) {
EventPluginUtils.executeDispatchesInOrder(event, simulated);
if (!event.isPersistent()) {
event.constructor.release(event);
}
}
};
var executeDispatchesAndReleaseSimulated = function (e) {
return executeDispatchesAndRelease(e, true);
};
var executeDispatchesAndReleaseTopLevel = function (e) {
return executeDispatchesAndRelease(e, false);
};
var getDictionaryKey = function (inst) {
// Prevents V8 performance issue:
// https://github.com/facebook/react/pull/7232
return '.' + inst._rootNodeID;
};
function isInteractive(tag) {
return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';
}
function shouldPreventMouseEvent(name, type, props) {
switch (name) {
case 'onClick':
case 'onClickCapture':
case 'onDoubleClick':
case 'onDoubleClickCapture':
case 'onMouseDown':
case 'onMouseDownCapture':
case 'onMouseMove':
case 'onMouseMoveCapture':
case 'onMouseUp':
case 'onMouseUpCapture':
return !!(props.disabled && isInteractive(type));
default:
return false;
}
}
/**
* This is a unified interface for event plugins to be installed and configured.
*
* Event plugins can implement the following properties:
*
* `extractEvents` {function(string, DOMEventTarget, string, object): *}
* Required. When a top-level event is fired, this method is expected to
* extract synthetic events that will in turn be queued and dispatched.
*
* `eventTypes` {object}
* Optional, plugins that fire events must publish a mapping of registration
* names that are used to register listeners. Values of this mapping must
* be objects that contain `registrationName` or `phasedRegistrationNames`.
*
* `executeDispatch` {function(object, function, string)}
* Optional, allows plugins to override how an event gets dispatched. By
* default, the listener is simply invoked.
*
* Each plugin that is injected into `EventsPluginHub` is immediately operable.
*
* @public
*/
var EventPluginHub = {
/**
* Methods for injecting dependencies.
*/
injection: {
/**
* @param {array} InjectedEventPluginOrder
* @public
*/
injectEventPluginOrder: EventPluginRegistry.injectEventPluginOrder,
/**
* @param {object} injectedNamesToPlugins Map from names to plugin modules.
*/
injectEventPluginsByName: EventPluginRegistry.injectEventPluginsByName
},
/**
* Stores `listener` at `listenerBank[registrationName][key]`. Is idempotent.
*
* @param {object} inst The instance, which is the source of events.
* @param {string} registrationName Name of listener (e.g. `onClick`).
* @param {function} listener The callback to store.
*/
putListener: function (inst, registrationName, listener) {
!(typeof listener === 'function') ? true ? invariant(false, 'Expected %s listener to be a function, instead got type %s', registrationName, typeof listener) : _prodInvariant('94', registrationName, typeof listener) : void 0;
var key = getDictionaryKey(inst);
var bankForRegistrationName = listenerBank[registrationName] || (listenerBank[registrationName] = {});
bankForRegistrationName[key] = listener;
var PluginModule = EventPluginRegistry.registrationNameModules[registrationName];
if (PluginModule && PluginModule.didPutListener) {
PluginModule.didPutListener(inst, registrationName, listener);
}
},
/**
* @param {object} inst The instance, which is the source of events.
* @param {string} registrationName Name of listener (e.g. `onClick`).
* @return {?function} The stored callback.
*/
getListener: function (inst, registrationName) {
// TODO: shouldPreventMouseEvent is DOM-specific and definitely should not
// live here; needs to be moved to a better place soon
var bankForRegistrationName = listenerBank[registrationName];
if (shouldPreventMouseEvent(registrationName, inst._currentElement.type, inst._currentElement.props)) {
return null;
}
var key = getDictionaryKey(inst);
return bankForRegistrationName && bankForRegistrationName[key];
},
/**
* Deletes a listener from the registration bank.
*
* @param {object} inst The instance, which is the source of events.
* @param {string} registrationName Name of listener (e.g. `onClick`).
*/
deleteListener: function (inst, registrationName) {
var PluginModule = EventPluginRegistry.registrationNameModules[registrationName];
if (PluginModule && PluginModule.willDeleteListener) {
PluginModule.willDeleteListener(inst, registrationName);
}
var bankForRegistrationName = listenerBank[registrationName];
// TODO: This should never be null -- when is it?
if (bankForRegistrationName) {
var key = getDictionaryKey(inst);
delete bankForRegistrationName[key];
}
},
/**
* Deletes all listeners for the DOM element with the supplied ID.
*
* @param {object} inst The instance, which is the source of events.
*/
deleteAllListeners: function (inst) {
var key = getDictionaryKey(inst);
for (var registrationName in listenerBank) {
if (!listenerBank.hasOwnProperty(registrationName)) {
continue;
}
if (!listenerBank[registrationName][key]) {
continue;
}
var PluginModule = EventPluginRegistry.registrationNameModules[registrationName];
if (PluginModule && PluginModule.willDeleteListener) {
PluginModule.willDeleteListener(inst, registrationName);
}
delete listenerBank[registrationName][key];
}
},
/**
* Allows registered plugins an opportunity to extract events from top-level
* native browser events.
*
* @return {*} An accumulation of synthetic events.
* @internal
*/
extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
var events;
var plugins = EventPluginRegistry.plugins;
for (var i = 0; i < plugins.length; i++) {
// Not every plugin in the ordering may be loaded at runtime.
var possiblePlugin = plugins[i];
if (possiblePlugin) {
var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget);
if (extractedEvents) {
events = accumulateInto(events, extractedEvents);
}
}
}
return events;
},
/**
* Enqueues a synthetic event that should be dispatched when
* `processEventQueue` is invoked.
*
* @param {*} events An accumulation of synthetic events.
* @internal
*/
enqueueEvents: function (events) {
if (events) {
eventQueue = accumulateInto(eventQueue, events);
}
},
/**
* Dispatches all synthetic events on the event queue.
*
* @internal
*/
processEventQueue: function (simulated) {
// Set `eventQueue` to null before processing it so that we can tell if more
// events get enqueued while processing.
var processingEventQueue = eventQueue;
eventQueue = null;
if (simulated) {
forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseSimulated);
} else {
forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel);
}
!!eventQueue ? true ? invariant(false, 'processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented.') : _prodInvariant('95') : void 0;
// This would be a good time to rethrow if any of the event handlers threw.
ReactErrorUtils.rethrowCaughtError();
},
/**
* These are needed for tests only. Do not use!
*/
__purge: function () {
listenerBank = {};
},
__getListenerBank: function () {
return listenerBank;
}
};
module.exports = EventPluginHub;
/***/ }),
/* 22 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var SyntheticEvent = __webpack_require__(12);
var getEventTarget = __webpack_require__(38);
/**
* @interface UIEvent
* @see http://www.w3.org/TR/DOM-Level-3-Events/
*/
var UIEventInterface = {
view: function (event) {
if (event.view) {
return event.view;
}
var target = getEventTarget(event);
if (target.window === target) {
// target is a window object
return target;
}
var doc = target.ownerDocument;
// TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
if (doc) {
return doc.defaultView || doc.parentWindow;
} else {
return window;
}
},
detail: function (event) {
return event.detail || 0;
}
};
/**
* @param {object} dispatchConfig Configuration used to dispatch this event.
* @param {string} dispatchMarker Marker identifying the event target.
* @param {object} nativeEvent Native browser event.
* @extends {SyntheticEvent}
*/
function SyntheticUIEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {
return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);
}
SyntheticEvent.augmentClass(SyntheticUIEvent, UIEventInterface);
module.exports = SyntheticUIEvent;
/***/ }),
/* 23 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
/**
* `ReactInstanceMap` maintains a mapping from a public facing stateful
* instance (key) and the internal representation (value). This allows public
* methods to accept the user facing instance as an argument and map them back
* to internal methods.
*/
// TODO: Replace this with ES6: var ReactInstanceMap = new Map();
var ReactInstanceMap = {
/**
* This API should be called `delete` but we'd have to make sure to always
* transform these to strings for IE support. When this transform is fully
* supported we can rename it.
*/
remove: function (key) {
key._reactInternalInstance = undefined;
},
get: function (key) {
return key._reactInternalInstance;
},
has: function (key) {
return key._reactInternalInstance !== undefined;
},
set: function (key, value) {
key._reactInternalInstance = value;
}
};
module.exports = ReactInstanceMap;
/***/ }),
/* 24 */
/***/ (function(module, exports) {
// shim for using process in browser
var process = module.exports = {};
// cached from whatever global is present so that test runners that stub it
// don't break things. But we need to wrap it in a try catch in case it is
// wrapped in strict mode code which doesn't define any globals. It's inside a
// function because try/catches deoptimize in certain engines.
var cachedSetTimeout;
var cachedClearTimeout;
function defaultSetTimout() {
throw new Error('setTimeout has not been defined');
}
function defaultClearTimeout () {
throw new Error('clearTimeout has not been defined');
}
(function () {
try {
if (typeof setTimeout === 'function') {
cachedSetTimeout = setTimeout;
} else {
cachedSetTimeout = defaultSetTimout;
}
} catch (e) {
cachedSetTimeout = defaultSetTimout;
}
try {
if (typeof clearTimeout === 'function') {
cachedClearTimeout = clearTimeout;
} else {
cachedClearTimeout = defaultClearTimeout;
}
} catch (e) {
cachedClearTimeout = defaultClearTimeout;
}
} ())
function runTimeout(fun) {
if (cachedSetTimeout === setTimeout) {
//normal enviroments in sane situations
return setTimeout(fun, 0);
}
// if setTimeout wasn't available but was latter defined
if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
cachedSetTimeout = setTimeout;
return setTimeout(fun, 0);
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedSetTimeout(fun, 0);
} catch(e){
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedSetTimeout.call(null, fun, 0);
} catch(e){
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
return cachedSetTimeout.call(this, fun, 0);
}
}
}
function runClearTimeout(marker) {
if (cachedClearTimeout === clearTimeout) {
//normal enviroments in sane situations
return clearTimeout(marker);
}
// if clearTimeout wasn't available but was latter defined
if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
cachedClearTimeout = clearTimeout;
return clearTimeout(marker);
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedClearTimeout(marker);
} catch (e){
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedClearTimeout.call(null, marker);
} catch (e){
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
return cachedClearTimeout.call(this, marker);
}
}
}
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;
function cleanUpNextTick() {
if (!draining || !currentQueue) {
return;
}
draining = false;
if (currentQueue.length) {
queue = currentQueue.concat(queue);
} else {
queueIndex = -1;
}
if (queue.length) {
drainQueue();
}
}
function drainQueue() {
if (draining) {
return;
}
var timeout = runTimeout(cleanUpNextTick);
draining = true;
var len = queue.length;
while(len) {
currentQueue = queue;
queue = [];
while (++queueIndex < len) {
if (currentQueue) {
currentQueue[queueIndex].run();
}
}
queueIndex = -1;
len = queue.length;
}
currentQueue = null;
draining = false;
runClearTimeout(timeout);
}
process.nextTick = function (fun) {
var args = new Array(arguments.length - 1);
if (arguments.length > 1) {
for (var i = 1; i < arguments.length; i++) {
args[i - 1] = arguments[i];
}
}
queue.push(new Item(fun, args));
if (queue.length === 1 && !draining) {
runTimeout(drainQueue);
}
};
// v8 likes predictible objects
function Item(fun, array) {
this.fun = fun;
this.array = array;
}
Item.prototype.run = function () {
this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};
function noop() {}
process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.prependListener = noop;
process.prependOnceListener = noop;
process.listeners = function (name) { return [] }
process.binding = function (name) {
throw new Error('process.binding is not supported');
};
process.cwd = function () { return '/' };
process.chdir = function (dir) {
throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };
/***/ }),
/* 25 */
/***/ (function(module, exports, __webpack_require__) {
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
if (true) {
var REACT_ELEMENT_TYPE = (typeof Symbol === 'function' &&
Symbol.for &&
Symbol.for('react.element')) ||
0xeac7;
var isValidElement = function(object) {
return typeof object === 'object' &&
object !== null &&
object.$$typeof === REACT_ELEMENT_TYPE;
};
// By explicitly using `prop-types` you are opting into new development behavior.
// http://fb.me/prop-types-in-prod
var throwOnDirectAccess = true;
module.exports = __webpack_require__(85)(isValidElement, throwOnDirectAccess);
} else {
// By explicitly using `prop-types` you are opting into new production behavior.
// http://fb.me/prop-types-in-prod
module.exports = require('./factoryWithThrowingShims')();
}
/***/ }),
/* 26 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var canDefineProperty = false;
if (true) {
try {
// $FlowFixMe https://github.com/facebook/flow/issues/285
Object.defineProperty({}, 'x', { get: function () {} });
canDefineProperty = true;
} catch (x) {
// IE will fail on defineProperty
}
}
module.exports = canDefineProperty;
/***/ }),
/* 27 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var emptyObject = {};
if (true) {
Object.freeze(emptyObject);
}
module.exports = emptyObject;
/***/ }),
/* 28 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var _prodInvariant = __webpack_require__(2);
var invariant = __webpack_require__(0);
/**
* Injectable ordering of event plugins.
*/
var eventPluginOrder = null;
/**
* Injectable mapping from names to event plugin modules.
*/
var namesToPlugins = {};
/**
* Recomputes the plugin list using the injected plugins and plugin ordering.
*
* @private
*/
function recomputePluginOrdering() {
if (!eventPluginOrder) {
// Wait until an `eventPluginOrder` is injected.
return;
}
for (var pluginName in namesToPlugins) {
var pluginModule = namesToPlugins[pluginName];
var pluginIndex = eventPluginOrder.indexOf(pluginName);
!(pluginIndex > -1) ? true ? invariant(false, 'EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `%s`.', pluginName) : _prodInvariant('96', pluginName) : void 0;
if (EventPluginRegistry.plugins[pluginIndex]) {
continue;
}
!pluginModule.extractEvents ? true ? invariant(false, 'EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `%s` does not.', pluginName) : _prodInvariant('97', pluginName) : void 0;
EventPluginRegistry.plugins[pluginIndex] = pluginModule;
var publishedEvents = pluginModule.eventTypes;
for (var eventName in publishedEvents) {
!publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName) ? true ? invariant(false, 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', eventName, pluginName) : _prodInvariant('98', eventName, pluginName) : void 0;
}
}
}
/**
* Publishes an event so that it can be dispatched by the supplied plugin.
*
* @param {object} dispatchConfig Dispatch configuration for the event.
* @param {object} PluginModule Plugin publishing the event.
* @return {boolean} True if the event was successfully published.
* @private
*/
function publishEventForPlugin(dispatchConfig, pluginModule, eventName) {
!!EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName) ? true ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same event name, `%s`.', eventName) : _prodInvariant('99', eventName) : void 0;
EventPluginRegistry.eventNameDispatchConfigs[eventName] = dispatchConfig;
var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;
if (phasedRegistrationNames) {
for (var phaseName in phasedRegistrationNames) {
if (phasedRegistrationNames.hasOwnProperty(phaseName)) {
var phasedRegistrationName = phasedRegistrationNames[phaseName];
publishRegistrationName(phasedRegistrationName, pluginModule, eventName);
}
}
return true;
} else if (dispatchConfig.registrationName) {
publishRegistrationName(dispatchConfig.registrationName, pluginModule, eventName);
return true;
}
return false;
}
/**
* Publishes a registration name that is used to identify dispatched events and
* can be used with `EventPluginHub.putListener` to register listeners.
*
* @param {string} registrationName Registration name to add.
* @param {object} PluginModule Plugin publishing the event.
* @private
*/
function publishRegistrationName(registrationName, pluginModule, eventName) {
!!EventPluginRegistry.registrationNameModules[registrationName] ? true ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same registration name, `%s`.', registrationName) : _prodInvariant('100', registrationName) : void 0;
EventPluginRegistry.registrationNameModules[registrationName] = pluginModule;
EventPluginRegistry.registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies;
if (true) {
var lowerCasedName = registrationName.toLowerCase();
EventPluginRegistry.possibleRegistrationNames[lowerCasedName] = registrationName;
if (registrationName === 'onDoubleClick') {
EventPluginRegistry.possibleRegistrationNames.ondblclick = registrationName;
}
}
}
/**
* Registers plugins so that they can extract and dispatch events.
*
* @see {EventPluginHub}
*/
var EventPluginRegistry = {
/**
* Ordered list of injected plugins.
*/
plugins: [],
/**
* Mapping from event name to dispatch config
*/
eventNameDispatchConfigs: {},
/**
* Mapping from registration name to plugin module
*/
registrationNameModules: {},
/**
* Mapping from registration name to event name
*/
registrationNameDependencies: {},
/**
* Mapping from lowercase registration names to the properly cased version,
* used to warn in the case of missing event handlers. Available
* only in __DEV__.
* @type {Object}
*/
possibleRegistrationNames: true ? {} : null,
// Trust the developer to only use possibleRegistrationNames in __DEV__
/**
* Injects an ordering of plugins (by plugin name). This allows the ordering
* to be decoupled from injection of the actual plugins so that ordering is
* always deterministic regardless of packaging, on-the-fly injection, etc.
*
* @param {array} InjectedEventPluginOrder
* @internal
* @see {EventPluginHub.injection.injectEventPluginOrder}
*/
injectEventPluginOrder: function (injectedEventPluginOrder) {
!!eventPluginOrder ? true ? invariant(false, 'EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React.') : _prodInvariant('101') : void 0;
// Clone the ordering so it cannot be dynamically mutated.
eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder);
recomputePluginOrdering();
},
/**
* Injects plugins to be used by `EventPluginHub`. The plugin names must be
* in the ordering injected by `injectEventPluginOrder`.
*
* Plugins can be injected as part of page initialization or on-the-fly.
*
* @param {object} injectedNamesToPlugins Map from names to plugin modules.
* @internal
* @see {EventPluginHub.injection.injectEventPluginsByName}
*/
injectEventPluginsByName: function (injectedNamesToPlugins) {
var isOrderingDirty = false;
for (var pluginName in injectedNamesToPlugins) {
if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {
continue;
}
var pluginModule = injectedNamesToPlugins[pluginName];
if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== pluginModule) {
!!namesToPlugins[pluginName] ? true ? invariant(false, 'EventPluginRegistry: Cannot inject two different event plugins using the same name, `%s`.', pluginName) : _prodInvariant('102', pluginName) : void 0;
namesToPlugins[pluginName] = pluginModule;
isOrderingDirty = true;
}
}
if (isOrderingDirty) {
recomputePluginOrdering();
}
},
/**
* Looks up the plugin for the supplied event.
*
* @param {object} event A synthetic event.
* @return {?object} The plugin that created the supplied event.
* @internal
*/
getPluginModuleForEvent: function (event) {
var dispatchConfig = event.dispatchConfig;
if (dispatchConfig.registrationName) {
return EventPluginRegistry.registrationNameModules[dispatchConfig.registrationName] || null;
}
if (dispatchConfig.phasedRegistrationNames !== undefined) {
// pulling phasedRegistrationNames out of dispatchConfig helps Flow see
// that it is not undefined.
var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;
for (var phase in phasedRegistrationNames) {
if (!phasedRegistrationNames.hasOwnProperty(phase)) {
continue;
}
var pluginModule = EventPluginRegistry.registrationNameModules[phasedRegistrationNames[phase]];
if (pluginModule) {
return pluginModule;
}
}
}
return null;
},
/**
* Exposed for unit testing.
* @private
*/
_resetEventPlugins: function () {
eventPluginOrder = null;
for (var pluginName in namesToPlugins) {
if (namesToPlugins.hasOwnProperty(pluginName)) {
delete namesToPlugins[pluginName];
}
}
EventPluginRegistry.plugins.length = 0;
var eventNameDispatchConfigs = EventPluginRegistry.eventNameDispatchConfigs;
for (var eventName in eventNameDispatchConfigs) {
if (eventNameDispatchConfigs.hasOwnProperty(eventName)) {
delete eventNameDispatchConfigs[eventName];
}
}
var registrationNameModules = EventPluginRegistry.registrationNameModules;
for (var registrationName in registrationNameModules) {
if (registrationNameModules.hasOwnProperty(registrationName)) {
delete registrationNameModules[registrationName];
}
}
if (true) {
var possibleRegistrationNames = EventPluginRegistry.possibleRegistrationNames;
for (var lowerCasedName in possibleRegistrationNames) {
if (possibleRegistrationNames.hasOwnProperty(lowerCasedName)) {
delete possibleRegistrationNames[lowerCasedName];
}
}
}
}
};
module.exports = EventPluginRegistry;
/***/ }),
/* 29 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var _prodInvariant = __webpack_require__(2);
var invariant = __webpack_require__(0);
var OBSERVED_ERROR = {};
/**
* `Transaction` creates a black box that is able to wrap any method such that
* certain invariants are maintained before and after the method is invoked
* (Even if an exception is thrown while invoking the wrapped method). Whoever
* instantiates a transaction can provide enforcers of the invariants at
* creation time. The `Transaction` class itself will supply one additional
* automatic invariant for you - the invariant that any transaction instance
* should not be run while it is already being run. You would typically create a
* single instance of a `Transaction` for reuse multiple times, that potentially
* is used to wrap several different methods. Wrappers are extremely simple -
* they only require implementing two methods.
*
* <pre>
* wrappers (injected at creation time)
* + +
* | |
* +-----------------|--------|--------------+
* | v | |
* | +---------------+ | |
* | +--| wrapper1 |---|----+ |
* | | +---------------+ v | |
* | | +-------------+ | |
* | | +----| wrapper2 |--------+ |
* | | | +-------------+ | | |
* | | | | | |
* | v v v v | wrapper
* | +---+ +---+ +---------+ +---+ +---+ | invariants
* perform(anyMethod) | | | | | | | | | | | | maintained
* +----------------->|-|---|-|---|-->|anyMethod|---|---|-|---|-|-------->
* | | | | | | | | | | | |
* | | | | | | | | | | | |
* | | | | | | | | | | | |
* | +---+ +---+ +---------+ +---+ +---+ |
* | initialize close |
* +-----------------------------------------+
* </pre>
*
* Use cases:
* - Preserving the input selection ranges before/after reconciliation.
* Restoring selection even in the event of an unexpected error.
* - Deactivating events while rearranging the DOM, preventing blurs/focuses,
* while guaranteeing that afterwards, the event system is reactivated.
* - Flushing a queue of collected DOM mutations to the main UI thread after a
* reconciliation takes place in a worker thread.
* - Invoking any collected `componentDidUpdate` callbacks after rendering new
* content.
* - (Future use case): Wrapping particular flushes of the `ReactWorker` queue
* to preserve the `scrollTop` (an automatic scroll aware DOM).
* - (Future use case): Layout calculations before and after DOM updates.
*
* Transactional plugin API:
* - A module that has an `initialize` method that returns any precomputation.
* - and a `close` method that accepts the precomputation. `close` is invoked
* when the wrapped process is completed, or has failed.
*
* @param {Array<TransactionalWrapper>} transactionWrapper Wrapper modules
* that implement `initialize` and `close`.
* @return {Transaction} Single transaction for reuse in thread.
*
* @class Transaction
*/
var TransactionImpl = {
/**
* Sets up this instance so that it is prepared for collecting metrics. Does
* so such that this setup method may be used on an instance that is already
* initialized, in a way that does not consume additional memory upon reuse.
* That can be useful if you decide to make your subclass of this mixin a
* "PooledClass".
*/
reinitializeTransaction: function () {
this.transactionWrappers = this.getTransactionWrappers();
if (this.wrapperInitData) {
this.wrapperInitData.length = 0;
} else {
this.wrapperInitData = [];
}
this._isInTransaction = false;
},
_isInTransaction: false,
/**
* @abstract
* @return {Array<TransactionWrapper>} Array of transaction wrappers.
*/
getTransactionWrappers: null,
isInTransaction: function () {
return !!this._isInTransaction;
},
/* eslint-disable space-before-function-paren */
/**
* Executes the function within a safety window. Use this for the top level
* methods that result in large amounts of computation/mutations that would
* need to be safety checked. The optional arguments helps prevent the need
* to bind in many cases.
*
* @param {function} method Member of scope to call.
* @param {Object} scope Scope to invoke from.
* @param {Object?=} a Argument to pass to the method.
* @param {Object?=} b Argument to pass to the method.
* @param {Object?=} c Argument to pass to the method.
* @param {Object?=} d Argument to pass to the method.
* @param {Object?=} e Argument to pass to the method.
* @param {Object?=} f Argument to pass to the method.
*
* @return {*} Return value from `method`.
*/
perform: function (method, scope, a, b, c, d, e, f) {
/* eslint-enable space-before-function-paren */
!!this.isInTransaction() ? true ? invariant(false, 'Transaction.perform(...): Cannot initialize a transaction when there is already an outstanding transaction.') : _prodInvariant('27') : void 0;
var errorThrown;
var ret;
try {
this._isInTransaction = true;
// Catching errors makes debugging more difficult, so we start with
// errorThrown set to true before setting it to false after calling
// close -- if it's still set to true in the finally block, it means
// one of these calls threw.
errorThrown = true;
this.initializeAll(0);
ret = method.call(scope, a, b, c, d, e, f);
errorThrown = false;
} finally {
try {
if (errorThrown) {
// If `method` throws, prefer to show that stack trace over any thrown
// by invoking `closeAll`.
try {
this.closeAll(0);
} catch (err) {}
} else {
// Since `method` didn't throw, we don't want to silence the exception
// here.
this.closeAll(0);
}
} finally {
this._isInTransaction = false;
}
}
return ret;
},
initializeAll: function (startIndex) {
var transactionWrappers = this.transactionWrappers;
for (var i = startIndex; i < transactionWrappers.length; i++) {
var wrapper = transactionWrappers[i];
try {
// Catching errors makes debugging more difficult, so we start with the
// OBSERVED_ERROR state before overwriting it with the real return value
// of initialize -- if it's still set to OBSERVED_ERROR in the finally
// block, it means wrapper.initialize threw.
this.wrapperInitData[i] = OBSERVED_ERROR;
this.wrapperInitData[i] = wrapper.initialize ? wrapper.initialize.call(this) : null;
} finally {
if (this.wrapperInitData[i] === OBSERVED_ERROR) {
// The initializer for wrapper i threw an error; initialize the
// remaining wrappers but silence any exceptions from them to ensure
// that the first error is the one to bubble up.
try {
this.initializeAll(i + 1);
} catch (err) {}
}
}
}
},
/**
* Invokes each of `this.transactionWrappers.close[i]` functions, passing into
* them the respective return values of `this.transactionWrappers.init[i]`
* (`close`rs that correspond to initializers that failed will not be
* invoked).
*/
closeAll: function (startIndex) {
!this.isInTransaction() ? true ? invariant(false, 'Transaction.closeAll(): Cannot close transaction when none are open.') : _prodInvariant('28') : void 0;
var transactionWrappers = this.transactionWrappers;
for (var i = startIndex; i < transactionWrappers.length; i++) {
var wrapper = transactionWrappers[i];
var initData = this.wrapperInitData[i];
var errorThrown;
try {
// Catching errors makes debugging more difficult, so we start with
// errorThrown set to true before setting it to false after calling
// close -- if it's still set to true in the finally block, it means
// wrapper.close threw.
errorThrown = true;
if (initData !== OBSERVED_ERROR && wrapper.close) {
wrapper.close.call(this, initData);
}
errorThrown = false;
} finally {
if (errorThrown) {
// The closer for wrapper i threw an error; close the remaining
// wrappers but silence any exceptions from them to ensure that the
// first error is the one to bubble up.
try {
this.closeAll(i + 1);
} catch (e) {}
}
}
}
this.wrapperInitData.length = 0;
}
};
module.exports = TransactionImpl;
/***/ }),
/* 30 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var SyntheticUIEvent = __webpack_require__(22);
var ViewportMetrics = __webpack_require__(67);
var getEventModifierState = __webpack_require__(40);
/**
* @interface MouseEvent
* @see http://www.w3.org/TR/DOM-Level-3-Events/
*/
var MouseEventInterface = {
screenX: null,
screenY: null,
clientX: null,
clientY: null,
ctrlKey: null,
shiftKey: null,
altKey: null,
metaKey: null,
getModifierState: getEventModifierState,
button: function (event) {
// Webkit, Firefox, IE9+
// which: 1 2 3
// button: 0 1 2 (standard)
var button = event.button;
if ('which' in event) {
return button;
}
// IE<9
// which: undefined
// button: 0 0 0
// button: 1 4 2 (onmouseup)
return button === 2 ? 2 : button === 4 ? 1 : 0;
},
buttons: null,
relatedTarget: function (event) {
return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement);
},
// "Proprietary" Interface.
pageX: function (event) {
return 'pageX' in event ? event.pageX : event.clientX + ViewportMetrics.currentScrollLeft;
},
pageY: function (event) {
return 'pageY' in event ? event.pageY : event.clientY + ViewportMetrics.currentScrollTop;
}
};
/**
* @param {object} dispatchConfig Configuration used to dispatch this event.
* @param {string} dispatchMarker Marker identifying the event target.
* @param {object} nativeEvent Native browser event.
* @extends {SyntheticUIEvent}
*/
function SyntheticMouseEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {
return SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);
}
SyntheticUIEvent.augmentClass(SyntheticMouseEvent, MouseEventInterface);
module.exports = SyntheticMouseEvent;
/***/ }),
/* 31 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var ExecutionEnvironment = __webpack_require__(5);
var DOMNamespaces = __webpack_require__(42);
var WHITESPACE_TEST = /^[ \r\n\t\f]/;
var NONVISIBLE_TEST = /<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/;
var createMicrosoftUnsafeLocalFunction = __webpack_require__(43);
// SVG temp container for IE lacking innerHTML
var reusableSVGContainer;
/**
* Set the innerHTML property of a node, ensuring that whitespace is preserved
* even in IE8.
*
* @param {DOMElement} node
* @param {string} html
* @internal
*/
var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) {
// IE does not have innerHTML for SVG nodes, so instead we inject the
// new markup in a temp node and then move the child nodes across into
// the target node
if (node.namespaceURI === DOMNamespaces.svg && !('innerHTML' in node)) {
reusableSVGContainer = reusableSVGContainer || document.createElement('div');
reusableSVGContainer.innerHTML = '<svg>' + html + '</svg>';
var svgNode = reusableSVGContainer.firstChild;
while (svgNode.firstChild) {
node.appendChild(svgNode.firstChild);
}
} else {
node.innerHTML = html;
}
});
if (ExecutionEnvironment.canUseDOM) {
// IE8: When updating a just created node with innerHTML only leading
// whitespace is removed. When updating an existing node with innerHTML
// whitespace in root TextNodes is also collapsed.
// @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html
// Feature detection; only IE8 is known to behave improperly like this.
var testElement = document.createElement('div');
testElement.innerHTML = ' ';
if (testElement.innerHTML === '') {
setInnerHTML = function (node, html) {
// Magic theory: IE8 supposedly differentiates between added and updated
// nodes when processing innerHTML, innerHTML on updated nodes suffers
// from worse whitespace behavior. Re-adding a node like this triggers
// the initial and more favorable whitespace behavior.
// TODO: What to do on a detached node?
if (node.parentNode) {
node.parentNode.replaceChild(node, node);
}
// We also implement a workaround for non-visible tags disappearing into
// thin air on IE8, this only happens if there is no visible text
// in-front of the non-visible tags. Piggyback on the whitespace fix
// and simply check if any non-visible tags appear in the source.
if (WHITESPACE_TEST.test(html) || html[0] === '<' && NONVISIBLE_TEST.test(html)) {
// Recover leading whitespace by temporarily prepending any character.
// \uFEFF has the potential advantage of being zero-width/invisible.
// UglifyJS drops U+FEFF chars when parsing, so use String.fromCharCode
// in hopes that this is preserved even if "\uFEFF" is transformed to
// the actual Unicode character (by Babel, for example).
// https://github.com/mishoo/UglifyJS2/blob/v2.4.20/lib/parse.js#L216
node.innerHTML = String.fromCharCode(0xfeff) + html;
// deleteData leaves an empty `TextNode` which offsets the index of all
// children. Definitely want to avoid this.
var textNode = node.firstChild;
if (textNode.data.length === 1) {
node.removeChild(textNode);
} else {
textNode.deleteData(0, 1);
}
} else {
node.innerHTML = html;
}
};
}
testElement = null;
}
module.exports = setInnerHTML;
/***/ }),
/* 32 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2016-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* Based on the escape-html library, which is used under the MIT License below:
*
* Copyright (c) 2012-2013 TJ Holowaychuk
* Copyright (c) 2015 Andreas Lubbe
* Copyright (c) 2015 Tiancheng "Timothy" Gu
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
// code copied and modified from escape-html
/**
* Module variables.
* @private
*/
var matchHtmlRegExp = /["'&<>]/;
/**
* Escape special characters in the given string of html.
*
* @param {string} string The string to escape for inserting into HTML
* @return {string}
* @public
*/
function escapeHtml(string) {
var str = '' + string;
var match = matchHtmlRegExp.exec(str);
if (!match) {
return str;
}
var escape;
var html = '';
var index = 0;
var lastIndex = 0;
for (index = match.index; index < str.length; index++) {
switch (str.charCodeAt(index)) {
case 34:
// "
escape = '"';
break;
case 38:
// &
escape = '&';
break;
case 39:
// '
escape = '''; // modified from escape-html; used to be '''
break;
case 60:
// <
escape = '<';
break;
case 62:
// >
escape = '>';
break;
default:
continue;
}
if (lastIndex !== index) {
html += str.substring(lastIndex, index);
}
lastIndex = index + 1;
html += escape;
}
return lastIndex !== index ? html + str.substring(lastIndex, index) : html;
}
// end code copied and modified from escape-html
/**
* Escapes text to prevent scripting attacks.
*
* @param {*} text Text value to escape.
* @return {string} An escaped string.
*/
function escapeTextContentForBrowser(text) {
if (typeof text === 'boolean' || typeof text === 'number') {
// this shortcircuit helps perf for types that we know will never have
// special characters, especially given that this function is used often
// for numeric dom ids.
return '' + text;
}
return escapeHtml(text);
}
module.exports = escapeTextContentForBrowser;
/***/ }),
/* 33 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _assign = __webpack_require__(3);
var EventPluginRegistry = __webpack_require__(28);
var ReactEventEmitterMixin = __webpack_require__(139);
var ViewportMetrics = __webpack_require__(67);
var getVendorPrefixedEventName = __webpack_require__(140);
var isEventSupported = __webpack_require__(39);
/**
* Summary of `ReactBrowserEventEmitter` event handling:
*
* - Top-level delegation is used to trap most native browser events. This
* may only occur in the main thread and is the responsibility of
* ReactEventListener, which is injected and can therefore support pluggable
* event sources. This is the only work that occurs in the main thread.
*
* - We normalize and de-duplicate events to account for browser quirks. This
* may be done in the worker thread.
*
* - Forward these native events (with the associated top-level type used to
* trap it) to `EventPluginHub`, which in turn will ask plugins if they want
* to extract any synthetic events.
*
* - The `EventPluginHub` will then process each event by annotating them with
* "dispatches", a sequence of listeners and IDs that care about that event.
*
* - The `EventPluginHub` then dispatches the events.
*
* Overview of React and the event system:
*
* +------------+ .
* | DOM | .
* +------------+ .
* | .
* v .
* +------------+ .
* | ReactEvent | .
* | Listener | .
* +------------+ . +-----------+
* | . +--------+|SimpleEvent|
* | . | |Plugin |
* +-----|------+ . v +-----------+
* | | | . +--------------+ +------------+
* | +-----------.--->|EventPluginHub| | Event |
* | | . | | +-----------+ | Propagators|
* | ReactEvent | . | | |TapEvent | |------------|
* | Emitter | . | |<---+|Plugin | |other plugin|
* | | . | | +-----------+ | utilities |
* | +-----------.--->| | +------------+
* | | | . +--------------+
* +-----|------+ . ^ +-----------+
* | . | |Enter/Leave|
* + . +-------+|Plugin |
* +-------------+ . +-----------+
* | application | .
* |-------------| .
* | | .
* | | .
* +-------------+ .
* .
* React Core . General Purpose Event Plugin System
*/
var hasEventPageXY;
var alreadyListeningTo = {};
var isMonitoringScrollValue = false;
var reactTopListenersCounter = 0;
// For events like 'submit' which don't consistently bubble (which we trap at a
// lower node than `document`), binding at `document` would cause duplicate
// events so we don't include them here
var topEventMapping = {
topAbort: 'abort',
topAnimationEnd: getVendorPrefixedEventName('animationend') || 'animationend',
topAnimationIteration: getVendorPrefixedEventName('animationiteration') || 'animationiteration',
topAnimationStart: getVendorPrefixedEventName('animationstart') || 'animationstart',
topBlur: 'blur',
topCanPlay: 'canplay',
topCanPlayThrough: 'canplaythrough',
topChange: 'change',
topClick: 'click',
topCompositionEnd: 'compositionend',
topCompositionStart: 'compositionstart',
topCompositionUpdate: 'compositionupdate',
topContextMenu: 'contextmenu',
topCopy: 'copy',
topCut: 'cut',
topDoubleClick: 'dblclick',
topDrag: 'drag',
topDragEnd: 'dragend',
topDragEnter: 'dragenter',
topDragExit: 'dragexit',
topDragLeave: 'dragleave',
topDragOver: 'dragover',
topDragStart: 'dragstart',
topDrop: 'drop',
topDurationChange: 'durationchange',
topEmptied: 'emptied',
topEncrypted: 'encrypted',
topEnded: 'ended',
topError: 'error',
topFocus: 'focus',
topInput: 'input',
topKeyDown: 'keydown',
topKeyPress: 'keypress',
topKeyUp: 'keyup',
topLoadedData: 'loadeddata',
topLoadedMetadata: 'loadedmetadata',
topLoadStart: 'loadstart',
topMouseDown: 'mousedown',
topMouseMove: 'mousemove',
topMouseOut: 'mouseout',
topMouseOver: 'mouseover',
topMouseUp: 'mouseup',
topPaste: 'paste',
topPause: 'pause',
topPlay: 'play',
topPlaying: 'playing',
topProgress: 'progress',
topRateChange: 'ratechange',
topScroll: 'scroll',
topSeeked: 'seeked',
topSeeking: 'seeking',
topSelectionChange: 'selectionchange',
topStalled: 'stalled',
topSuspend: 'suspend',
topTextInput: 'textInput',
topTimeUpdate: 'timeupdate',
topTouchCancel: 'touchcancel',
topTouchEnd: 'touchend',
topTouchMove: 'touchmove',
topTouchStart: 'touchstart',
topTransitionEnd: getVendorPrefixedEventName('transitionend') || 'transitionend',
topVolumeChange: 'volumechange',
topWaiting: 'waiting',
topWheel: 'wheel'
};
/**
* To ensure no conflicts with other potential React instances on the page
*/
var topListenersIDKey = '_reactListenersID' + String(Math.random()).slice(2);
function getListeningForDocument(mountAt) {
// In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty`
// directly.
if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) {
mountAt[topListenersIDKey] = reactTopListenersCounter++;
alreadyListeningTo[mountAt[topListenersIDKey]] = {};
}
return alreadyListeningTo[mountAt[topListenersIDKey]];
}
/**
* `ReactBrowserEventEmitter` is used to attach top-level event listeners. For
* example:
*
* EventPluginHub.putListener('myID', 'onClick', myFunction);
*
* This would allocate a "registration" of `('onClick', myFunction)` on 'myID'.
*
* @internal
*/
var ReactBrowserEventEmitter = _assign({}, ReactEventEmitterMixin, {
/**
* Injectable event backend
*/
ReactEventListener: null,
injection: {
/**
* @param {object} ReactEventListener
*/
injectReactEventListener: function (ReactEventListener) {
ReactEventListener.setHandleTopLevel(ReactBrowserEventEmitter.handleTopLevel);
ReactBrowserEventEmitter.ReactEventListener = ReactEventListener;
}
},
/**
* Sets whether or not any created callbacks should be enabled.
*
* @param {boolean} enabled True if callbacks should be enabled.
*/
setEnabled: function (enabled) {
if (ReactBrowserEventEmitter.ReactEventListener) {
ReactBrowserEventEmitter.ReactEventListener.setEnabled(enabled);
}
},
/**
* @return {boolean} True if callbacks are enabled.
*/
isEnabled: function () {
return !!(ReactBrowserEventEmitter.ReactEventListener && ReactBrowserEventEmitter.ReactEventListener.isEnabled());
},
/**
* We listen for bubbled touch events on the document object.
*
* Firefox v8.01 (and possibly others) exhibited strange behavior when
* mounting `onmousemove` events at some node that was not the document
* element. The symptoms were that if your mouse is not moving over something
* contained within that mount point (for example on the background) the
* top-level listeners for `onmousemove` won't be called. However, if you
* register the `mousemove` on the document object, then it will of course
* catch all `mousemove`s. This along with iOS quirks, justifies restricting
* top-level listeners to the document object only, at least for these
* movement types of events and possibly all events.
*
* @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
*
* Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but
* they bubble to document.
*
* @param {string} registrationName Name of listener (e.g. `onClick`).
* @param {object} contentDocumentHandle Document which owns the container
*/
listenTo: function (registrationName, contentDocumentHandle) {
var mountAt = contentDocumentHandle;
var isListening = getListeningForDocument(mountAt);
var dependencies = EventPluginRegistry.registrationNameDependencies[registrationName];
for (var i = 0; i < dependencies.length; i++) {
var dependency = dependencies[i];
if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {
if (dependency === 'topWheel') {
if (isEventSupported('wheel')) {
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topWheel', 'wheel', mountAt);
} else if (isEventSupported('mousewheel')) {
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topWheel', 'mousewheel', mountAt);
} else {
// Firefox needs to capture a different mouse scroll event.
// @see http://www.quirksmode.org/dom/events/tests/scroll.html
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topWheel', 'DOMMouseScroll', mountAt);
}
} else if (dependency === 'topScroll') {
if (isEventSupported('scroll', true)) {
ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent('topScroll', 'scroll', mountAt);
} else {
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topScroll', 'scroll', ReactBrowserEventEmitter.ReactEventListener.WINDOW_HANDLE);
}
} else if (dependency === 'topFocus' || dependency === 'topBlur') {
if (isEventSupported('focus', true)) {
ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent('topFocus', 'focus', mountAt);
ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent('topBlur', 'blur', mountAt);
} else if (isEventSupported('focusin')) {
// IE has `focusin` and `focusout` events which bubble.
// @see http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topFocus', 'focusin', mountAt);
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topBlur', 'focusout', mountAt);
}
// to make sure blur and focus event listeners are only attached once
isListening.topBlur = true;
isListening.topFocus = true;
} else if (topEventMapping.hasOwnProperty(dependency)) {
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(dependency, topEventMapping[dependency], mountAt);
}
isListening[dependency] = true;
}
}
},
trapBubbledEvent: function (topLevelType, handlerBaseName, handle) {
return ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelType, handlerBaseName, handle);
},
trapCapturedEvent: function (topLevelType, handlerBaseName, handle) {
return ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(topLevelType, handlerBaseName, handle);
},
/**
* Protect against document.createEvent() returning null
* Some popup blocker extensions appear to do this:
* https://github.com/facebook/react/issues/6887
*/
supportsEventPageXY: function () {
if (!document.createEvent) {
return false;
}
var ev = document.createEvent('MouseEvent');
return ev != null && 'pageX' in ev;
},
/**
* Listens to window scroll and resize events. We cache scroll values so that
* application code can access them without triggering reflows.
*
* ViewportMetrics is only used by SyntheticMouse/TouchEvent and only when
* pageX/pageY isn't supported (legacy browsers).
*
* NOTE: Scroll events do not bubble.
*
* @see http://www.quirksmode.org/dom/events/scroll.html
*/
ensureScrollValueMonitoring: function () {
if (hasEventPageXY === undefined) {
hasEventPageXY = ReactBrowserEventEmitter.supportsEventPageXY();
}
if (!hasEventPageXY && !isMonitoringScrollValue) {
var refresh = ViewportMetrics.refreshScrollValues;
ReactBrowserEventEmitter.ReactEventListener.monitorScrollValue(refresh);
isMonitoringScrollValue = true;
}
}
});
module.exports = ReactBrowserEventEmitter;
/***/ }),
/* 34 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var bind = __webpack_require__(203);
var isBuffer = __webpack_require__(265);
/*global toString:true*/
// utils is a library of generic helper functions non-specific to axios
var toString = Object.prototype.toString;
/**
* Determine if a value is an Array
*
* @param {Object} val The value to test
* @returns {boolean} True if value is an Array, otherwise false
*/
function isArray(val) {
return toString.call(val) === '[object Array]';
}
/**
* Determine if a value is an ArrayBuffer
*
* @param {Object} val The value to test
* @returns {boolean} True if value is an ArrayBuffer, otherwise false
*/
function isArrayBuffer(val) {
return toString.call(val) === '[object ArrayBuffer]';
}
/**
* Determine if a value is a FormData
*
* @param {Object} val The value to test
* @returns {boolean} True if value is an FormData, otherwise false
*/
function isFormData(val) {
return (typeof FormData !== 'undefined') && (val instanceof FormData);
}
/**
* Determine if a value is a view on an ArrayBuffer
*
* @param {Object} val The value to test
* @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false
*/
function isArrayBufferView(val) {
var result;
if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {
result = ArrayBuffer.isView(val);
} else {
result = (val) && (val.buffer) && (val.buffer instanceof ArrayBuffer);
}
return result;
}
/**
* Determine if a value is a String
*
* @param {Object} val The value to test
* @returns {boolean} True if value is a String, otherwise false
*/
function isString(val) {
return typeof val === 'string';
}
/**
* Determine if a value is a Number
*
* @param {Object} val The value to test
* @returns {boolean} True if value is a Number, otherwise false
*/
function isNumber(val) {
return typeof val === 'number';
}
/**
* Determine if a value is undefined
*
* @param {Object} val The value to test
* @returns {boolean} True if the value is undefined, otherwise false
*/
function isUndefined(val) {
return typeof val === 'undefined';
}
/**
* Determine if a value is an Object
*
* @param {Object} val The value to test
* @returns {boolean} True if value is an Object, otherwise false
*/
function isObject(val) {
return val !== null && typeof val === 'object';
}
/**
* Determine if a value is a Date
*
* @param {Object} val The value to test
* @returns {boolean} True if value is a Date, otherwise false
*/
function isDate(val) {
return toString.call(val) === '[object Date]';
}
/**
* Determine if a value is a File
*
* @param {Object} val The value to test
* @returns {boolean} True if value is a File, otherwise false
*/
function isFile(val) {
return toString.call(val) === '[object File]';
}
/**
* Determine if a value is a Blob
*
* @param {Object} val The value to test
* @returns {boolean} True if value is a Blob, otherwise false
*/
function isBlob(val) {
return toString.call(val) === '[object Blob]';
}
/**
* Determine if a value is a Function
*
* @param {Object} val The value to test
* @returns {boolean} True if value is a Function, otherwise false
*/
function isFunction(val) {
return toString.call(val) === '[object Function]';
}
/**
* Determine if a value is a Stream
*
* @param {Object} val The value to test
* @returns {boolean} True if value is a Stream, otherwise false
*/
function isStream(val) {
return isObject(val) && isFunction(val.pipe);
}
/**
* Determine if a value is a URLSearchParams object
*
* @param {Object} val The value to test
* @returns {boolean} True if value is a URLSearchParams object, otherwise false
*/
function isURLSearchParams(val) {
return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams;
}
/**
* Trim excess whitespace off the beginning and end of a string
*
* @param {String} str The String to trim
* @returns {String} The String freed of excess whitespace
*/
function trim(str) {
return str.replace(/^\s*/, '').replace(/\s*$/, '');
}
/**
* Determine if we're running in a standard browser environment
*
* This allows axios to run in a web worker, and react-native.
* Both environments support XMLHttpRequest, but not fully standard globals.
*
* web workers:
* typeof window -> undefined
* typeof document -> undefined
*
* react-native:
* navigator.product -> 'ReactNative'
*/
function isStandardBrowserEnv() {
if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') {
return false;
}
return (
typeof window !== 'undefined' &&
typeof document !== 'undefined'
);
}
/**
* Iterate over an Array or an Object invoking a function for each item.
*
* If `obj` is an Array callback will be called passing
* the value, index, and complete array for each item.
*
* If 'obj' is an Object callback will be called passing
* the value, key, and complete object for each property.
*
* @param {Object|Array} obj The object to iterate
* @param {Function} fn The callback to invoke for each item
*/
function forEach(obj, fn) {
// Don't bother if no value provided
if (obj === null || typeof obj === 'undefined') {
return;
}
// Force an array if not already something iterable
if (typeof obj !== 'object') {
/*eslint no-param-reassign:0*/
obj = [obj];
}
if (isArray(obj)) {
// Iterate over array values
for (var i = 0, l = obj.length; i < l; i++) {
fn.call(null, obj[i], i, obj);
}
} else {
// Iterate over object keys
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
fn.call(null, obj[key], key, obj);
}
}
}
}
/**
* Accepts varargs expecting each argument to be an object, then
* immutably merges the properties of each object and returns result.
*
* When multiple objects contain the same key the later object in
* the arguments list will take precedence.
*
* Example:
*
* ```js
* var result = merge({foo: 123}, {foo: 456});
* console.log(result.foo); // outputs 456
* ```
*
* @param {Object} obj1 Object to merge
* @returns {Object} Result of all merge properties
*/
function merge(/* obj1, obj2, obj3, ... */) {
var result = {};
function assignValue(val, key) {
if (typeof result[key] === 'object' && typeof val === 'object') {
result[key] = merge(result[key], val);
} else {
result[key] = val;
}
}
for (var i = 0, l = arguments.length; i < l; i++) {
forEach(arguments[i], assignValue);
}
return result;
}
/**
* Extends object a by mutably adding to it the properties of object b.
*
* @param {Object} a The object to be extended
* @param {Object} b The object to copy properties from
* @param {Object} thisArg The object to bind function to
* @return {Object} The resulting value of object a
*/
function extend(a, b, thisArg) {
forEach(b, function assignValue(val, key) {
if (thisArg && typeof val === 'function') {
a[key] = bind(val, thisArg);
} else {
a[key] = val;
}
});
return a;
}
module.exports = {
isArray: isArray,
isArrayBuffer: isArrayBuffer,
isBuffer: isBuffer,
isFormData: isFormData,
isArrayBufferView: isArrayBufferView,
isString: isString,
isNumber: isNumber,
isObject: isObject,
isUndefined: isUndefined,
isDate: isDate,
isFile: isFile,
isBlob: isBlob,
isFunction: isFunction,
isStream: isStream,
isURLSearchParams: isURLSearchParams,
isStandardBrowserEnv: isStandardBrowserEnv,
forEach: forEach,
merge: merge,
extend: extend,
trim: trim
};
/***/ }),
/* 35 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2014-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
/**
* Forked from fbjs/warning:
* https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
*
* Only change is we use console.warn instead of console.error,
* and do nothing when 'console' is not supported.
* This really simplifies the code.
* ---
* Similar to invariant but only logs a warning if the condition is not met.
* This can be used to log issues in development environments in critical
* paths. Removing the logging code for production environments will keep the
* same logic and follow the same code paths.
*/
var lowPriorityWarning = function () {};
if (true) {
var printWarning = function (format) {
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
var argIndex = 0;
var message = 'Warning: ' + format.replace(/%s/g, function () {
return args[argIndex++];
});
if (typeof console !== 'undefined') {
console.warn(message);
}
try {
// --- Welcome to debugging React ---
// This error was thrown as a convenience so that you can use this stack
// to find the callsite that caused this warning to fire.
throw new Error(message);
} catch (x) {}
};
lowPriorityWarning = function (condition, format) {
if (format === undefined) {
throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument');
}
if (!condition) {
for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
args[_key2 - 2] = arguments[_key2];
}
printWarning.apply(undefined, [format].concat(args));
}
};
}
module.exports = lowPriorityWarning;
/***/ }),
/* 36 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _prodInvariant = __webpack_require__(2);
var ReactErrorUtils = __webpack_require__(37);
var invariant = __webpack_require__(0);
var warning = __webpack_require__(1);
/**
* Injected dependencies:
*/
/**
* - `ComponentTree`: [required] Module that can convert between React instances
* and actual node references.
*/
var ComponentTree;
var TreeTraversal;
var injection = {
injectComponentTree: function (Injected) {
ComponentTree = Injected;
if (true) {
true ? warning(Injected && Injected.getNodeFromInstance && Injected.getInstanceFromNode, 'EventPluginUtils.injection.injectComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.') : void 0;
}
},
injectTreeTraversal: function (Injected) {
TreeTraversal = Injected;
if (true) {
true ? warning(Injected && Injected.isAncestor && Injected.getLowestCommonAncestor, 'EventPluginUtils.injection.injectTreeTraversal(...): Injected ' + 'module is missing isAncestor or getLowestCommonAncestor.') : void 0;
}
}
};
function isEndish(topLevelType) {
return topLevelType === 'topMouseUp' || topLevelType === 'topTouchEnd' || topLevelType === 'topTouchCancel';
}
function isMoveish(topLevelType) {
return topLevelType === 'topMouseMove' || topLevelType === 'topTouchMove';
}
function isStartish(topLevelType) {
return topLevelType === 'topMouseDown' || topLevelType === 'topTouchStart';
}
var validateEventDispatches;
if (true) {
validateEventDispatches = function (event) {
var dispatchListeners = event._dispatchListeners;
var dispatchInstances = event._dispatchInstances;
var listenersIsArr = Array.isArray(dispatchListeners);
var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0;
var instancesIsArr = Array.isArray(dispatchInstances);
var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0;
true ? warning(instancesIsArr === listenersIsArr && instancesLen === listenersLen, 'EventPluginUtils: Invalid `event`.') : void 0;
};
}
/**
* Dispatch the event to the listener.
* @param {SyntheticEvent} event SyntheticEvent to handle
* @param {boolean} simulated If the event is simulated (changes exn behavior)
* @param {function} listener Application-level callback
* @param {*} inst Internal component instance
*/
function executeDispatch(event, simulated, listener, inst) {
var type = event.type || 'unknown-event';
event.currentTarget = EventPluginUtils.getNodeFromInstance(inst);
if (simulated) {
ReactErrorUtils.invokeGuardedCallbackWithCatch(type, listener, event);
} else {
ReactErrorUtils.invokeGuardedCallback(type, listener, event);
}
event.currentTarget = null;
}
/**
* Standard/simple iteration through an event's collected dispatches.
*/
function executeDispatchesInOrder(event, simulated) {
var dispatchListeners = event._dispatchListeners;
var dispatchInstances = event._dispatchInstances;
if (true) {
validateEventDispatches(event);
}
if (Array.isArray(dispatchListeners)) {
for (var i = 0; i < dispatchListeners.length; i++) {
if (event.isPropagationStopped()) {
break;
}
// Listeners and Instances are two parallel arrays that are always in sync.
executeDispatch(event, simulated, dispatchListeners[i], dispatchInstances[i]);
}
} else if (dispatchListeners) {
executeDispatch(event, simulated, dispatchListeners, dispatchInstances);
}
event._dispatchListeners = null;
event._dispatchInstances = null;
}
/**
* Standard/simple iteration through an event's collected dispatches, but stops
* at the first dispatch execution returning true, and returns that id.
*
* @return {?string} id of the first dispatch execution who's listener returns
* true, or null if no listener returned true.
*/
function executeDispatchesInOrderStopAtTrueImpl(event) {
var dispatchListeners = event._dispatchListeners;
var dispatchInstances = event._dispatchInstances;
if (true) {
validateEventDispatches(event);
}
if (Array.isArray(dispatchListeners)) {
for (var i = 0; i < dispatchListeners.length; i++) {
if (event.isPropagationStopped()) {
break;
}
// Listeners and Instances are two parallel arrays that are always in sync.
if (dispatchListeners[i](event, dispatchInstances[i])) {
return dispatchInstances[i];
}
}
} else if (dispatchListeners) {
if (dispatchListeners(event, dispatchInstances)) {
return dispatchInstances;
}
}
return null;
}
/**
* @see executeDispatchesInOrderStopAtTrueImpl
*/
function executeDispatchesInOrderStopAtTrue(event) {
var ret = executeDispatchesInOrderStopAtTrueImpl(event);
event._dispatchInstances = null;
event._dispatchListeners = null;
return ret;
}
/**
* Execution of a "direct" dispatch - there must be at most one dispatch
* accumulated on the event or it is considered an error. It doesn't really make
* sense for an event with multiple dispatches (bubbled) to keep track of the
* return values at each dispatch execution, but it does tend to make sense when
* dealing with "direct" dispatches.
*
* @return {*} The return value of executing the single dispatch.
*/
function executeDirectDispatch(event) {
if (true) {
validateEventDispatches(event);
}
var dispatchListener = event._dispatchListeners;
var dispatchInstance = event._dispatchInstances;
!!Array.isArray(dispatchListener) ? true ? invariant(false, 'executeDirectDispatch(...): Invalid `event`.') : _prodInvariant('103') : void 0;
event.currentTarget = dispatchListener ? EventPluginUtils.getNodeFromInstance(dispatchInstance) : null;
var res = dispatchListener ? dispatchListener(event) : null;
event.currentTarget = null;
event._dispatchListeners = null;
event._dispatchInstances = null;
return res;
}
/**
* @param {SyntheticEvent} event
* @return {boolean} True iff number of dispatches accumulated is greater than 0.
*/
function hasDispatches(event) {
return !!event._dispatchListeners;
}
/**
* General utilities that are useful in creating custom Event Plugins.
*/
var EventPluginUtils = {
isEndish: isEndish,
isMoveish: isMoveish,
isStartish: isStartish,
executeDirectDispatch: executeDirectDispatch,
executeDispatchesInOrder: executeDispatchesInOrder,
executeDispatchesInOrderStopAtTrue: executeDispatchesInOrderStopAtTrue,
hasDispatches: hasDispatches,
getInstanceFromNode: function (node) {
return ComponentTree.getInstanceFromNode(node);
},
getNodeFromInstance: function (node) {
return ComponentTree.getNodeFromInstance(node);
},
isAncestor: function (a, b) {
return TreeTraversal.isAncestor(a, b);
},
getLowestCommonAncestor: function (a, b) {
return TreeTraversal.getLowestCommonAncestor(a, b);
},
getParentInstance: function (inst) {
return TreeTraversal.getParentInstance(inst);
},
traverseTwoPhase: function (target, fn, arg) {
return TreeTraversal.traverseTwoPhase(target, fn, arg);
},
traverseEnterLeave: function (from, to, fn, argFrom, argTo) {
return TreeTraversal.traverseEnterLeave(from, to, fn, argFrom, argTo);
},
injection: injection
};
module.exports = EventPluginUtils;
/***/ }),
/* 37 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var caughtError = null;
/**
* Call a function while guarding against errors that happens within it.
*
* @param {String} name of the guard to use for logging or debugging
* @param {Function} func The function to invoke
* @param {*} a First argument
* @param {*} b Second argument
*/
function invokeGuardedCallback(name, func, a) {
try {
func(a);
} catch (x) {
if (caughtError === null) {
caughtError = x;
}
}
}
var ReactErrorUtils = {
invokeGuardedCallback: invokeGuardedCallback,
/**
* Invoked by ReactTestUtils.Simulate so that any errors thrown by the event
* handler are sure to be rethrown by rethrowCaughtError.
*/
invokeGuardedCallbackWithCatch: invokeGuardedCallback,
/**
* During execution of guarded functions we will capture the first error which
* we will rethrow to be handled by the top level error handler.
*/
rethrowCaughtError: function () {
if (caughtError) {
var error = caughtError;
caughtError = null;
throw error;
}
}
};
if (true) {
/**
* To help development we can get better devtools integration by simulating a
* real browser event.
*/
if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
var fakeNode = document.createElement('react');
ReactErrorUtils.invokeGuardedCallback = function (name, func, a) {
var boundFunc = function () {
func(a);
};
var evtType = 'react-' + name;
fakeNode.addEventListener(evtType, boundFunc, false);
var evt = document.createEvent('Event');
evt.initEvent(evtType, false, false);
fakeNode.dispatchEvent(evt);
fakeNode.removeEventListener(evtType, boundFunc, false);
};
}
}
module.exports = ReactErrorUtils;
/***/ }),
/* 38 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
/**
* Gets the target node from a native browser event by accounting for
* inconsistencies in browser DOM APIs.
*
* @param {object} nativeEvent Native browser event.
* @return {DOMEventTarget} Target node.
*/
function getEventTarget(nativeEvent) {
var target = nativeEvent.target || nativeEvent.srcElement || window;
// Normalize SVG <use> element events #4963
if (target.correspondingUseElement) {
target = target.correspondingUseElement;
}
// Safari may fire events on text nodes (Node.TEXT_NODE is 3).
// @see http://www.quirksmode.org/js/events_properties.html
return target.nodeType === 3 ? target.parentNode : target;
}
module.exports = getEventTarget;
/***/ }),
/* 39 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var ExecutionEnvironment = __webpack_require__(5);
var useHasFeature;
if (ExecutionEnvironment.canUseDOM) {
useHasFeature = document.implementation && document.implementation.hasFeature &&
// always returns true in newer browsers as per the standard.
// @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature
document.implementation.hasFeature('', '') !== true;
}
/**
* Checks if an event is supported in the current execution environment.
*
* NOTE: This will not work correctly for non-generic events such as `change`,
* `reset`, `load`, `error`, and `select`.
*
* Borrows from Modernizr.
*
* @param {string} eventNameSuffix Event name, e.g. "click".
* @param {?boolean} capture Check if the capture phase is supported.
* @return {boolean} True if the event is supported.
* @internal
* @license Modernizr 3.0.0pre (Custom Build) | MIT
*/
function isEventSupported(eventNameSuffix, capture) {
if (!ExecutionEnvironment.canUseDOM || capture && !('addEventListener' in document)) {
return false;
}
var eventName = 'on' + eventNameSuffix;
var isSupported = eventName in document;
if (!isSupported) {
var element = document.createElement('div');
element.setAttribute(eventName, 'return;');
isSupported = typeof element[eventName] === 'function';
}
if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') {
// This is the only way to test support for the `wheel` event in IE9+.
isSupported = document.implementation.hasFeature('Events.wheel', '3.0');
}
return isSupported;
}
module.exports = isEventSupported;
/***/ }),
/* 40 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
/**
* Translation from modifier key to the associated property in the event.
* @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers
*/
var modifierKeyToProp = {
Alt: 'altKey',
Control: 'ctrlKey',
Meta: 'metaKey',
Shift: 'shiftKey'
};
// IE8 does not implement getModifierState so we simply map it to the only
// modifier keys exposed by the event itself, does not support Lock-keys.
// Currently, all major browsers except Chrome seems to support Lock-keys.
function modifierStateGetter(keyArg) {
var syntheticEvent = this;
var nativeEvent = syntheticEvent.nativeEvent;
if (nativeEvent.getModifierState) {
return nativeEvent.getModifierState(keyArg);
}
var keyProp = modifierKeyToProp[keyArg];
return keyProp ? !!nativeEvent[keyProp] : false;
}
function getEventModifierState(nativeEvent) {
return modifierStateGetter;
}
module.exports = getEventModifierState;
/***/ }),
/* 41 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var DOMLazyTree = __webpack_require__(19);
var Danger = __webpack_require__(124);
var ReactDOMComponentTree = __webpack_require__(4);
var ReactInstrumentation = __webpack_require__(7);
var createMicrosoftUnsafeLocalFunction = __webpack_require__(43);
var setInnerHTML = __webpack_require__(31);
var setTextContent = __webpack_require__(68);
function getNodeAfter(parentNode, node) {
// Special case for text components, which return [open, close] comments
// from getHostNode.
if (Array.isArray(node)) {
node = node[1];
}
return node ? node.nextSibling : parentNode.firstChild;
}
/**
* Inserts `childNode` as a child of `parentNode` at the `index`.
*
* @param {DOMElement} parentNode Parent node in which to insert.
* @param {DOMElement} childNode Child node to insert.
* @param {number} index Index at which to insert the child.
* @internal
*/
var insertChildAt = createMicrosoftUnsafeLocalFunction(function (parentNode, childNode, referenceNode) {
// We rely exclusively on `insertBefore(node, null)` instead of also using
// `appendChild(node)`. (Using `undefined` is not allowed by all browsers so
// we are careful to use `null`.)
parentNode.insertBefore(childNode, referenceNode);
});
function insertLazyTreeChildAt(parentNode, childTree, referenceNode) {
DOMLazyTree.insertTreeBefore(parentNode, childTree, referenceNode);
}
function moveChild(parentNode, childNode, referenceNode) {
if (Array.isArray(childNode)) {
moveDelimitedText(parentNode, childNode[0], childNode[1], referenceNode);
} else {
insertChildAt(parentNode, childNode, referenceNode);
}
}
function removeChild(parentNode, childNode) {
if (Array.isArray(childNode)) {
var closingComment = childNode[1];
childNode = childNode[0];
removeDelimitedText(parentNode, childNode, closingComment);
parentNode.removeChild(closingComment);
}
parentNode.removeChild(childNode);
}
function moveDelimitedText(parentNode, openingComment, closingComment, referenceNode) {
var node = openingComment;
while (true) {
var nextNode = node.nextSibling;
insertChildAt(parentNode, node, referenceNode);
if (node === closingComment) {
break;
}
node = nextNode;
}
}
function removeDelimitedText(parentNode, startNode, closingComment) {
while (true) {
var node = startNode.nextSibling;
if (node === closingComment) {
// The closing comment is removed by ReactMultiChild.
break;
} else {
parentNode.removeChild(node);
}
}
}
function replaceDelimitedText(openingComment, closingComment, stringText) {
var parentNode = openingComment.parentNode;
var nodeAfterComment = openingComment.nextSibling;
if (nodeAfterComment === closingComment) {
// There are no text nodes between the opening and closing comments; insert
// a new one if stringText isn't empty.
if (stringText) {
insertChildAt(parentNode, document.createTextNode(stringText), nodeAfterComment);
}
} else {
if (stringText) {
// Set the text content of the first node after the opening comment, and
// remove all following nodes up until the closing comment.
setTextContent(nodeAfterComment, stringText);
removeDelimitedText(parentNode, nodeAfterComment, closingComment);
} else {
removeDelimitedText(parentNode, openingComment, closingComment);
}
}
if (true) {
ReactInstrumentation.debugTool.onHostOperation({
instanceID: ReactDOMComponentTree.getInstanceFromNode(openingComment)._debugID,
type: 'replace text',
payload: stringText
});
}
}
var dangerouslyReplaceNodeWithMarkup = Danger.dangerouslyReplaceNodeWithMarkup;
if (true) {
dangerouslyReplaceNodeWithMarkup = function (oldChild, markup, prevInstance) {
Danger.dangerouslyReplaceNodeWithMarkup(oldChild, markup);
if (prevInstance._debugID !== 0) {
ReactInstrumentation.debugTool.onHostOperation({
instanceID: prevInstance._debugID,
type: 'replace with',
payload: markup.toString()
});
} else {
var nextInstance = ReactDOMComponentTree.getInstanceFromNode(markup.node);
if (nextInstance._debugID !== 0) {
ReactInstrumentation.debugTool.onHostOperation({
instanceID: nextInstance._debugID,
type: 'mount',
payload: markup.toString()
});
}
}
};
}
/**
* Operations for updating with DOM children.
*/
var DOMChildrenOperations = {
dangerouslyReplaceNodeWithMarkup: dangerouslyReplaceNodeWithMarkup,
replaceDelimitedText: replaceDelimitedText,
/**
* Updates a component's children by processing a series of updates. The
* update configurations are each expected to have a `parentNode` property.
*
* @param {array<object>} updates List of update configurations.
* @internal
*/
processUpdates: function (parentNode, updates) {
if (true) {
var parentNodeDebugID = ReactDOMComponentTree.getInstanceFromNode(parentNode)._debugID;
}
for (var k = 0; k < updates.length; k++) {
var update = updates[k];
switch (update.type) {
case 'INSERT_MARKUP':
insertLazyTreeChildAt(parentNode, update.content, getNodeAfter(parentNode, update.afterNode));
if (true) {
ReactInstrumentation.debugTool.onHostOperation({
instanceID: parentNodeDebugID,
type: 'insert child',
payload: {
toIndex: update.toIndex,
content: update.content.toString()
}
});
}
break;
case 'MOVE_EXISTING':
moveChild(parentNode, update.fromNode, getNodeAfter(parentNode, update.afterNode));
if (true) {
ReactInstrumentation.debugTool.onHostOperation({
instanceID: parentNodeDebugID,
type: 'move child',
payload: { fromIndex: update.fromIndex, toIndex: update.toIndex }
});
}
break;
case 'SET_MARKUP':
setInnerHTML(parentNode, update.content);
if (true) {
ReactInstrumentation.debugTool.onHostOperation({
instanceID: parentNodeDebugID,
type: 'replace children',
payload: update.content.toString()
});
}
break;
case 'TEXT_CONTENT':
setTextContent(parentNode, update.content);
if (true) {
ReactInstrumentation.debugTool.onHostOperation({
instanceID: parentNodeDebugID,
type: 'replace text',
payload: update.content.toString()
});
}
break;
case 'REMOVE_NODE':
removeChild(parentNode, update.fromNode);
if (true) {
ReactInstrumentation.debugTool.onHostOperation({
instanceID: parentNodeDebugID,
type: 'remove child',
payload: { fromIndex: update.fromIndex }
});
}
break;
}
}
}
};
module.exports = DOMChildrenOperations;
/***/ }),
/* 42 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var DOMNamespaces = {
html: 'http://www.w3.org/1999/xhtml',
mathml: 'http://www.w3.org/1998/Math/MathML',
svg: 'http://www.w3.org/2000/svg'
};
module.exports = DOMNamespaces;
/***/ }),
/* 43 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
/* globals MSApp */
/**
* Create a function which has 'unsafe' privileges (required by windows8 apps)
*/
var createMicrosoftUnsafeLocalFunction = function (func) {
if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
return function (arg0, arg1, arg2, arg3) {
MSApp.execUnsafeLocalFunction(function () {
return func(arg0, arg1, arg2, arg3);
});
};
} else {
return func;
}
};
module.exports = createMicrosoftUnsafeLocalFunction;
/***/ }),
/* 44 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _prodInvariant = __webpack_require__(2);
var ReactPropTypesSecret = __webpack_require__(72);
var propTypesFactory = __webpack_require__(57);
var React = __webpack_require__(16);
var PropTypes = propTypesFactory(React.isValidElement);
var invariant = __webpack_require__(0);
var warning = __webpack_require__(1);
var hasReadOnlyValue = {
button: true,
checkbox: true,
image: true,
hidden: true,
radio: true,
reset: true,
submit: true
};
function _assertSingleLink(inputProps) {
!(inputProps.checkedLink == null || inputProps.valueLink == null) ? true ? invariant(false, 'Cannot provide a checkedLink and a valueLink. If you want to use checkedLink, you probably don\'t want to use valueLink and vice versa.') : _prodInvariant('87') : void 0;
}
function _assertValueLink(inputProps) {
_assertSingleLink(inputProps);
!(inputProps.value == null && inputProps.onChange == null) ? true ? invariant(false, 'Cannot provide a valueLink and a value or onChange event. If you want to use value or onChange, you probably don\'t want to use valueLink.') : _prodInvariant('88') : void 0;
}
function _assertCheckedLink(inputProps) {
_assertSingleLink(inputProps);
!(inputProps.checked == null && inputProps.onChange == null) ? true ? invariant(false, 'Cannot provide a checkedLink and a checked property or onChange event. If you want to use checked or onChange, you probably don\'t want to use checkedLink') : _prodInvariant('89') : void 0;
}
var propTypes = {
value: function (props, propName, componentName) {
if (!props[propName] || hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled) {
return null;
}
return new Error('You provided a `value` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultValue`. Otherwise, ' + 'set either `onChange` or `readOnly`.');
},
checked: function (props, propName, componentName) {
if (!props[propName] || props.onChange || props.readOnly || props.disabled) {
return null;
}
return new Error('You provided a `checked` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultChecked`. Otherwise, ' + 'set either `onChange` or `readOnly`.');
},
onChange: PropTypes.func
};
var loggedTypeFailures = {};
function getDeclarationErrorAddendum(owner) {
if (owner) {
var name = owner.getName();
if (name) {
return ' Check the render method of `' + name + '`.';
}
}
return '';
}
/**
* Provide a linked `value` attribute for controlled forms. You should not use
* this outside of the ReactDOM controlled form components.
*/
var LinkedValueUtils = {
checkPropTypes: function (tagName, props, owner) {
for (var propName in propTypes) {
if (propTypes.hasOwnProperty(propName)) {
var error = propTypes[propName](props, propName, tagName, 'prop', null, ReactPropTypesSecret);
}
if (error instanceof Error && !(error.message in loggedTypeFailures)) {
// Only monitor this failure once because there tends to be a lot of the
// same error.
loggedTypeFailures[error.message] = true;
var addendum = getDeclarationErrorAddendum(owner);
true ? warning(false, 'Failed form propType: %s%s', error.message, addendum) : void 0;
}
}
},
/**
* @param {object} inputProps Props for form component
* @return {*} current value of the input either from value prop or link.
*/
getValue: function (inputProps) {
if (inputProps.valueLink) {
_assertValueLink(inputProps);
return inputProps.valueLink.value;
}
return inputProps.value;
},
/**
* @param {object} inputProps Props for form component
* @return {*} current checked status of the input either from checked prop
* or link.
*/
getChecked: function (inputProps) {
if (inputProps.checkedLink) {
_assertCheckedLink(inputProps);
return inputProps.checkedLink.value;
}
return inputProps.checked;
},
/**
* @param {object} inputProps Props for form component
* @param {SyntheticEvent} event change event to handle
*/
executeOnChange: function (inputProps, event) {
if (inputProps.valueLink) {
_assertValueLink(inputProps);
return inputProps.valueLink.requestChange(event.target.value);
} else if (inputProps.checkedLink) {
_assertCheckedLink(inputProps);
return inputProps.checkedLink.requestChange(event.target.checked);
} else if (inputProps.onChange) {
return inputProps.onChange.call(undefined, event);
}
}
};
module.exports = LinkedValueUtils;
/***/ }),
/* 45 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2014-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var _prodInvariant = __webpack_require__(2);
var invariant = __webpack_require__(0);
var injected = false;
var ReactComponentEnvironment = {
/**
* Optionally injectable hook for swapping out mount images in the middle of
* the tree.
*/
replaceNodeWithMarkup: null,
/**
* Optionally injectable hook for processing a queue of child updates. Will
* later move into MultiChildComponents.
*/
processChildrenUpdates: null,
injection: {
injectEnvironment: function (environment) {
!!injected ? true ? invariant(false, 'ReactCompositeComponent: injectEnvironment() can only be called once.') : _prodInvariant('104') : void 0;
ReactComponentEnvironment.replaceNodeWithMarkup = environment.replaceNodeWithMarkup;
ReactComponentEnvironment.processChildrenUpdates = environment.processChildrenUpdates;
injected = true;
}
}
};
module.exports = ReactComponentEnvironment;
/***/ }),
/* 46 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*
*/
/*eslint-disable no-self-compare */
var hasOwnProperty = Object.prototype.hasOwnProperty;
/**
* inlined Object.is polyfill to avoid requiring consumers ship their own
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
*/
function is(x, y) {
// SameValue algorithm
if (x === y) {
// Steps 1-5, 7-10
// Steps 6.b-6.e: +0 != -0
// Added the nonzero y check to make Flow happy, but it is redundant
return x !== 0 || y !== 0 || 1 / x === 1 / y;
} else {
// Step 6.a: NaN == NaN
return x !== x && y !== y;
}
}
/**
* Performs equality by iterating through keys on an object and returning false
* when any key has values which are not strictly equal between the arguments.
* Returns true when the values of all keys are strictly equal.
*/
function shallowEqual(objA, objB) {
if (is(objA, objB)) {
return true;
}
if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
return false;
}
var keysA = Object.keys(objA);
var keysB = Object.keys(objB);
if (keysA.length !== keysB.length) {
return false;
}
// Test for A's keys different from B.
for (var i = 0; i < keysA.length; i++) {
if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
return false;
}
}
return true;
}
module.exports = shallowEqual;
/***/ }),
/* 47 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
/**
* Given a `prevElement` and `nextElement`, determines if the existing
* instance should be updated as opposed to being destroyed or replaced by a new
* instance. Both arguments are elements. This ensures that this logic can
* operate on stateless trees without any backing instance.
*
* @param {?object} prevElement
* @param {?object} nextElement
* @return {boolean} True if the existing instance should be updated.
* @protected
*/
function shouldUpdateReactComponent(prevElement, nextElement) {
var prevEmpty = prevElement === null || prevElement === false;
var nextEmpty = nextElement === null || nextElement === false;
if (prevEmpty || nextEmpty) {
return prevEmpty === nextEmpty;
}
var prevType = typeof prevElement;
var nextType = typeof nextElement;
if (prevType === 'string' || prevType === 'number') {
return nextType === 'string' || nextType === 'number';
} else {
return nextType === 'object' && prevElement.type === nextElement.type && prevElement.key === nextElement.key;
}
}
module.exports = shouldUpdateReactComponent;
/***/ }),
/* 48 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
/**
* Escape and wrap key so it is safe to use as a reactid
*
* @param {string} key to be escaped.
* @return {string} the escaped key.
*/
function escape(key) {
var escapeRegex = /[=:]/g;
var escaperLookup = {
'=': '=0',
':': '=2'
};
var escapedString = ('' + key).replace(escapeRegex, function (match) {
return escaperLookup[match];
});
return '$' + escapedString;
}
/**
* Unescape and unwrap key for human-readable display
*
* @param {string} key to unescape.
* @return {string} the unescaped key.
*/
function unescape(key) {
var unescapeRegex = /(=0|=2)/g;
var unescaperLookup = {
'=0': '=',
'=2': ':'
};
var keySubstring = key[0] === '.' && key[1] === '$' ? key.substring(2) : key.substring(1);
return ('' + keySubstring).replace(unescapeRegex, function (match) {
return unescaperLookup[match];
});
}
var KeyEscapeUtils = {
escape: escape,
unescape: unescape
};
module.exports = KeyEscapeUtils;
/***/ }),
/* 49 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _prodInvariant = __webpack_require__(2);
var ReactCurrentOwner = __webpack_require__(9);
var ReactInstanceMap = __webpack_require__(23);
var ReactInstrumentation = __webpack_require__(7);
var ReactUpdates = __webpack_require__(10);
var invariant = __webpack_require__(0);
var warning = __webpack_require__(1);
function enqueueUpdate(internalInstance) {
ReactUpdates.enqueueUpdate(internalInstance);
}
function formatUnexpectedArgument(arg) {
var type = typeof arg;
if (type !== 'object') {
return type;
}
var displayName = arg.constructor && arg.constructor.name || type;
var keys = Object.keys(arg);
if (keys.length > 0 && keys.length < 20) {
return displayName + ' (keys: ' + keys.join(', ') + ')';
}
return displayName;
}
function getInternalInstanceReadyForUpdate(publicInstance, callerName) {
var internalInstance = ReactInstanceMap.get(publicInstance);
if (!internalInstance) {
if (true) {
var ctor = publicInstance.constructor;
// Only warn when we have a callerName. Otherwise we should be silent.
// We're probably calling from enqueueCallback. We don't want to warn
// there because we already warned for the corresponding lifecycle method.
true ? warning(!callerName, '%s(...): Can only update a mounted or mounting component. ' + 'This usually means you called %s() on an unmounted component. ' + 'This is a no-op. Please check the code for the %s component.', callerName, callerName, ctor && (ctor.displayName || ctor.name) || 'ReactClass') : void 0;
}
return null;
}
if (true) {
true ? warning(ReactCurrentOwner.current == null, '%s(...): Cannot update during an existing state transition (such as ' + "within `render` or another component's constructor). Render methods " + 'should be a pure function of props and state; constructor ' + 'side-effects are an anti-pattern, but can be moved to ' + '`componentWillMount`.', callerName) : void 0;
}
return internalInstance;
}
/**
* ReactUpdateQueue allows for state updates to be scheduled into a later
* reconciliation step.
*/
var ReactUpdateQueue = {
/**
* Checks whether or not this composite component is mounted.
* @param {ReactClass} publicInstance The instance we want to test.
* @return {boolean} True if mounted, false otherwise.
* @protected
* @final
*/
isMounted: function (publicInstance) {
if (true) {
var owner = ReactCurrentOwner.current;
if (owner !== null) {
true ? warning(owner._warnedAboutRefsInRender, '%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', owner.getName() || 'A component') : void 0;
owner._warnedAboutRefsInRender = true;
}
}
var internalInstance = ReactInstanceMap.get(publicInstance);
if (internalInstance) {
// During componentWillMount and render this will still be null but after
// that will always render to something. At least for now. So we can use
// this hack.
return !!internalInstance._renderedComponent;
} else {
return false;
}
},
/**
* Enqueue a callback that will be executed after all the pending updates
* have processed.
*
* @param {ReactClass} publicInstance The instance to use as `this` context.
* @param {?function} callback Called after state is updated.
* @param {string} callerName Name of the calling function in the public API.
* @internal
*/
enqueueCallback: function (publicInstance, callback, callerName) {
ReactUpdateQueue.validateCallback(callback, callerName);
var internalInstance = getInternalInstanceReadyForUpdate(publicInstance);
// Previously we would throw an error if we didn't have an internal
// instance. Since we want to make it a no-op instead, we mirror the same
// behavior we have in other enqueue* methods.
// We also need to ignore callbacks in componentWillMount. See
// enqueueUpdates.
if (!internalInstance) {
return null;
}
if (internalInstance._pendingCallbacks) {
internalInstance._pendingCallbacks.push(callback);
} else {
internalInstance._pendingCallbacks = [callback];
}
// TODO: The callback here is ignored when setState is called from
// componentWillMount. Either fix it or disallow doing so completely in
// favor of getInitialState. Alternatively, we can disallow
// componentWillMount during server-side rendering.
enqueueUpdate(internalInstance);
},
enqueueCallbackInternal: function (internalInstance, callback) {
if (internalInstance._pendingCallbacks) {
internalInstance._pendingCallbacks.push(callback);
} else {
internalInstance._pendingCallbacks = [callback];
}
enqueueUpdate(internalInstance);
},
/**
* Forces an update. This should only be invoked when it is known with
* certainty that we are **not** in a DOM transaction.
*
* You may want to call this when you know that some deeper aspect of the
* component's state has changed but `setState` was not called.
*
* This will not invoke `shouldComponentUpdate`, but it will invoke
* `componentWillUpdate` and `componentDidUpdate`.
*
* @param {ReactClass} publicInstance The instance that should rerender.
* @internal
*/
enqueueForceUpdate: function (publicInstance) {
var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'forceUpdate');
if (!internalInstance) {
return;
}
internalInstance._pendingForceUpdate = true;
enqueueUpdate(internalInstance);
},
/**
* Replaces all of the state. Always use this or `setState` to mutate state.
* You should treat `this.state` as immutable.
*
* There is no guarantee that `this.state` will be immediately updated, so
* accessing `this.state` after calling this method may return the old value.
*
* @param {ReactClass} publicInstance The instance that should rerender.
* @param {object} completeState Next state.
* @internal
*/
enqueueReplaceState: function (publicInstance, completeState, callback) {
var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'replaceState');
if (!internalInstance) {
return;
}
internalInstance._pendingStateQueue = [completeState];
internalInstance._pendingReplaceState = true;
// Future-proof 15.5
if (callback !== undefined && callback !== null) {
ReactUpdateQueue.validateCallback(callback, 'replaceState');
if (internalInstance._pendingCallbacks) {
internalInstance._pendingCallbacks.push(callback);
} else {
internalInstance._pendingCallbacks = [callback];
}
}
enqueueUpdate(internalInstance);
},
/**
* Sets a subset of the state. This only exists because _pendingState is
* internal. This provides a merging strategy that is not available to deep
* properties which is confusing. TODO: Expose pendingState or don't use it
* during the merge.
*
* @param {ReactClass} publicInstance The instance that should rerender.
* @param {object} partialState Next partial state to be merged with state.
* @internal
*/
enqueueSetState: function (publicInstance, partialState) {
if (true) {
ReactInstrumentation.debugTool.onSetState();
true ? warning(partialState != null, 'setState(...): You passed an undefined or null state object; ' + 'instead, use forceUpdate().') : void 0;
}
var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'setState');
if (!internalInstance) {
return;
}
var queue = internalInstance._pendingStateQueue || (internalInstance._pendingStateQueue = []);
queue.push(partialState);
enqueueUpdate(internalInstance);
},
enqueueElementInternal: function (internalInstance, nextElement, nextContext) {
internalInstance._pendingElement = nextElement;
// TODO: introduce _pendingContext instead of setting it directly.
internalInstance._context = nextContext;
enqueueUpdate(internalInstance);
},
validateCallback: function (callback, callerName) {
!(!callback || typeof callback === 'function') ? true ? invariant(false, '%s(...): Expected the last optional `callback` argument to be a function. Instead received: %s.', callerName, formatUnexpectedArgument(callback)) : _prodInvariant('122', callerName, formatUnexpectedArgument(callback)) : void 0;
}
};
module.exports = ReactUpdateQueue;
/***/ }),
/* 50 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _assign = __webpack_require__(3);
var emptyFunction = __webpack_require__(8);
var warning = __webpack_require__(1);
var validateDOMNesting = emptyFunction;
if (true) {
// This validation code was written based on the HTML5 parsing spec:
// https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
//
// Note: this does not catch all invalid nesting, nor does it try to (as it's
// not clear what practical benefit doing so provides); instead, we warn only
// for cases where the parser will give a parse tree differing from what React
// intended. For example, <b><div></div></b> is invalid but we don't warn
// because it still parses correctly; we do warn for other cases like nested
// <p> tags where the beginning of the second element implicitly closes the
// first, causing a confusing mess.
// https://html.spec.whatwg.org/multipage/syntax.html#special
var specialTags = ['address', 'applet', 'area', 'article', 'aside', 'base', 'basefont', 'bgsound', 'blockquote', 'body', 'br', 'button', 'caption', 'center', 'col', 'colgroup', 'dd', 'details', 'dir', 'div', 'dl', 'dt', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'iframe', 'img', 'input', 'isindex', 'li', 'link', 'listing', 'main', 'marquee', 'menu', 'menuitem', 'meta', 'nav', 'noembed', 'noframes', 'noscript', 'object', 'ol', 'p', 'param', 'plaintext', 'pre', 'script', 'section', 'select', 'source', 'style', 'summary', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'track', 'ul', 'wbr', 'xmp'];
// https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template',
// https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
// TODO: Distinguish by namespace here -- for <title>, including it here
// errs on the side of fewer warnings
'foreignObject', 'desc', 'title'];
// https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
var buttonScopeTags = inScopeTags.concat(['button']);
// https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];
var emptyAncestorInfo = {
current: null,
formTag: null,
aTagInScope: null,
buttonTagInScope: null,
nobrTagInScope: null,
pTagInButtonScope: null,
listItemTagAutoclosing: null,
dlItemTagAutoclosing: null
};
var updatedAncestorInfo = function (oldInfo, tag, instance) {
var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo);
var info = { tag: tag, instance: instance };
if (inScopeTags.indexOf(tag) !== -1) {
ancestorInfo.aTagInScope = null;
ancestorInfo.buttonTagInScope = null;
ancestorInfo.nobrTagInScope = null;
}
if (buttonScopeTags.indexOf(tag) !== -1) {
ancestorInfo.pTagInButtonScope = null;
}
// See rules for 'li', 'dd', 'dt' start tags in
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {
ancestorInfo.listItemTagAutoclosing = null;
ancestorInfo.dlItemTagAutoclosing = null;
}
ancestorInfo.current = info;
if (tag === 'form') {
ancestorInfo.formTag = info;
}
if (tag === 'a') {
ancestorInfo.aTagInScope = info;
}
if (tag === 'button') {
ancestorInfo.buttonTagInScope = info;
}
if (tag === 'nobr') {
ancestorInfo.nobrTagInScope = info;
}
if (tag === 'p') {
ancestorInfo.pTagInButtonScope = info;
}
if (tag === 'li') {
ancestorInfo.listItemTagAutoclosing = info;
}
if (tag === 'dd' || tag === 'dt') {
ancestorInfo.dlItemTagAutoclosing = info;
}
return ancestorInfo;
};
/**
* Returns whether
*/
var isTagValidWithParent = function (tag, parentTag) {
// First, let's check if we're in an unusual parsing mode...
switch (parentTag) {
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
case 'select':
return tag === 'option' || tag === 'optgroup' || tag === '#text';
case 'optgroup':
return tag === 'option' || tag === '#text';
// Strictly speaking, seeing an <option> doesn't mean we're in a <select>
// but
case 'option':
return tag === '#text';
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
// No special behavior since these rules fall back to "in body" mode for
// all except special table nodes which cause bad parsing behavior anyway.
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
case 'tr':
return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
case 'tbody':
case 'thead':
case 'tfoot':
return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
case 'colgroup':
return tag === 'col' || tag === 'template';
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
case 'table':
return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
case 'head':
return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';
// https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
case 'html':
return tag === 'head' || tag === 'body';
case '#document':
return tag === 'html';
}
// Probably in the "in body" parsing mode, so we outlaw only tag combos
// where the parsing rules cause implicit opens or closes to be added.
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
switch (tag) {
case 'h1':
case 'h2':
case 'h3':
case 'h4':
case 'h5':
case 'h6':
return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';
case 'rp':
case 'rt':
return impliedEndTags.indexOf(parentTag) === -1;
case 'body':
case 'caption':
case 'col':
case 'colgroup':
case 'frame':
case 'head':
case 'html':
case 'tbody':
case 'td':
case 'tfoot':
case 'th':
case 'thead':
case 'tr':
// These tags are only valid with a few parents that have special child
// parsing rules -- if we're down here, then none of those matched and
// so we allow it only if we don't know what the parent is, as all other
// cases are invalid.
return parentTag == null;
}
return true;
};
/**
* Returns whether
*/
var findInvalidAncestorForTag = function (tag, ancestorInfo) {
switch (tag) {
case 'address':
case 'article':
case 'aside':
case 'blockquote':
case 'center':
case 'details':
case 'dialog':
case 'dir':
case 'div':
case 'dl':
case 'fieldset':
case 'figcaption':
case 'figure':
case 'footer':
case 'header':
case 'hgroup':
case 'main':
case 'menu':
case 'nav':
case 'ol':
case 'p':
case 'section':
case 'summary':
case 'ul':
case 'pre':
case 'listing':
case 'table':
case 'hr':
case 'xmp':
case 'h1':
case 'h2':
case 'h3':
case 'h4':
case 'h5':
case 'h6':
return ancestorInfo.pTagInButtonScope;
case 'form':
return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
case 'li':
return ancestorInfo.listItemTagAutoclosing;
case 'dd':
case 'dt':
return ancestorInfo.dlItemTagAutoclosing;
case 'button':
return ancestorInfo.buttonTagInScope;
case 'a':
// Spec says something about storing a list of markers, but it sounds
// equivalent to this check.
return ancestorInfo.aTagInScope;
case 'nobr':
return ancestorInfo.nobrTagInScope;
}
return null;
};
/**
* Given a ReactCompositeComponent instance, return a list of its recursive
* owners, starting at the root and ending with the instance itself.
*/
var findOwnerStack = function (instance) {
if (!instance) {
return [];
}
var stack = [];
do {
stack.push(instance);
} while (instance = instance._currentElement._owner);
stack.reverse();
return stack;
};
var didWarn = {};
validateDOMNesting = function (childTag, childText, childInstance, ancestorInfo) {
ancestorInfo = ancestorInfo || emptyAncestorInfo;
var parentInfo = ancestorInfo.current;
var parentTag = parentInfo && parentInfo.tag;
if (childText != null) {
true ? warning(childTag == null, 'validateDOMNesting: when childText is passed, childTag should be null') : void 0;
childTag = '#text';
}
var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
var problematic = invalidParent || invalidAncestor;
if (problematic) {
var ancestorTag = problematic.tag;
var ancestorInstance = problematic.instance;
var childOwner = childInstance && childInstance._currentElement._owner;
var ancestorOwner = ancestorInstance && ancestorInstance._currentElement._owner;
var childOwners = findOwnerStack(childOwner);
var ancestorOwners = findOwnerStack(ancestorOwner);
var minStackLen = Math.min(childOwners.length, ancestorOwners.length);
var i;
var deepestCommon = -1;
for (i = 0; i < minStackLen; i++) {
if (childOwners[i] === ancestorOwners[i]) {
deepestCommon = i;
} else {
break;
}
}
var UNKNOWN = '(unknown)';
var childOwnerNames = childOwners.slice(deepestCommon + 1).map(function (inst) {
return inst.getName() || UNKNOWN;
});
var ancestorOwnerNames = ancestorOwners.slice(deepestCommon + 1).map(function (inst) {
return inst.getName() || UNKNOWN;
});
var ownerInfo = [].concat(
// If the parent and child instances have a common owner ancestor, start
// with that -- otherwise we just start with the parent's owners.
deepestCommon !== -1 ? childOwners[deepestCommon].getName() || UNKNOWN : [], ancestorOwnerNames, ancestorTag,
// If we're warning about an invalid (non-parent) ancestry, add '...'
invalidAncestor ? ['...'] : [], childOwnerNames, childTag).join(' > ');
var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + ownerInfo;
if (didWarn[warnKey]) {
return;
}
didWarn[warnKey] = true;
var tagDisplayName = childTag;
var whitespaceInfo = '';
if (childTag === '#text') {
if (/\S/.test(childText)) {
tagDisplayName = 'Text nodes';
} else {
tagDisplayName = 'Whitespace text nodes';
whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.';
}
} else {
tagDisplayName = '<' + childTag + '>';
}
if (invalidParent) {
var info = '';
if (ancestorTag === 'table' && childTag === 'tr') {
info += ' Add a <tbody> to your code to match the DOM tree generated by ' + 'the browser.';
}
true ? warning(false, 'validateDOMNesting(...): %s cannot appear as a child of <%s>.%s ' + 'See %s.%s', tagDisplayName, ancestorTag, whitespaceInfo, ownerInfo, info) : void 0;
} else {
true ? warning(false, 'validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>. See %s.', tagDisplayName, ancestorTag, ownerInfo) : void 0;
}
}
};
validateDOMNesting.updatedAncestorInfo = updatedAncestorInfo;
// For testing
validateDOMNesting.isTagValidInContext = function (tag, ancestorInfo) {
ancestorInfo = ancestorInfo || emptyAncestorInfo;
var parentInfo = ancestorInfo.current;
var parentTag = parentInfo && parentInfo.tag;
return isTagValidWithParent(tag, parentTag) && !findInvalidAncestorForTag(tag, ancestorInfo);
};
}
module.exports = validateDOMNesting;
/***/ }),
/* 51 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
/**
* `charCode` represents the actual "character code" and is safe to use with
* `String.fromCharCode`. As such, only keys that correspond to printable
* characters produce a valid `charCode`, the only exception to this is Enter.
* The Tab-key is considered non-printable and does not have a `charCode`,
* presumably because it does not produce a tab-character in browsers.
*
* @param {object} nativeEvent Native browser event.
* @return {number} Normalized `charCode` property.
*/
function getEventCharCode(nativeEvent) {
var charCode;
var keyCode = nativeEvent.keyCode;
if ('charCode' in nativeEvent) {
charCode = nativeEvent.charCode;
// FF does not set `charCode` for the Enter-key, check against `keyCode`.
if (charCode === 0 && keyCode === 13) {
charCode = 13;
}
} else {
// IE8 does not implement `charCode`, but `keyCode` has the correct value.
charCode = keyCode;
}
// Some non-printable keys are reported in `charCode`/`keyCode`, discard them.
// Must not discard the (non-)printable Enter-key.
if (charCode >= 32 || charCode === 13) {
return charCode;
}
return 0;
}
module.exports = getEventCharCode;
/***/ }),
/* 52 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _prodInvariant = __webpack_require__(17),
_assign = __webpack_require__(3);
var ReactNoopUpdateQueue = __webpack_require__(53);
var canDefineProperty = __webpack_require__(26);
var emptyObject = __webpack_require__(27);
var invariant = __webpack_require__(0);
var lowPriorityWarning = __webpack_require__(35);
/**
* Base class helpers for the updating state of a component.
*/
function ReactComponent(props, context, updater) {
this.props = props;
this.context = context;
this.refs = emptyObject;
// We initialize the default updater but the real one gets injected by the
// renderer.
this.updater = updater || ReactNoopUpdateQueue;
}
ReactComponent.prototype.isReactComponent = {};
/**
* Sets a subset of the state. Always use this to mutate
* state. You should treat `this.state` as immutable.
*
* There is no guarantee that `this.state` will be immediately updated, so
* accessing `this.state` after calling this method may return the old value.
*
* There is no guarantee that calls to `setState` will run synchronously,
* as they may eventually be batched together. You can provide an optional
* callback that will be executed when the call to setState is actually
* completed.
*
* When a function is provided to setState, it will be called at some point in
* the future (not synchronously). It will be called with the up to date
* component arguments (state, props, context). These values can be different
* from this.* because your function may be called after receiveProps but before
* shouldComponentUpdate, and this new state, props, and context will not yet be
* assigned to this.
*
* @param {object|function} partialState Next partial state or function to
* produce next partial state to be merged with current state.
* @param {?function} callback Called after state is updated.
* @final
* @protected
*/
ReactComponent.prototype.setState = function (partialState, callback) {
!(typeof partialState === 'object' || typeof partialState === 'function' || partialState == null) ? true ? invariant(false, 'setState(...): takes an object of state variables to update or a function which returns an object of state variables.') : _prodInvariant('85') : void 0;
this.updater.enqueueSetState(this, partialState);
if (callback) {
this.updater.enqueueCallback(this, callback, 'setState');
}
};
/**
* Forces an update. This should only be invoked when it is known with
* certainty that we are **not** in a DOM transaction.
*
* You may want to call this when you know that some deeper aspect of the
* component's state has changed but `setState` was not called.
*
* This will not invoke `shouldComponentUpdate`, but it will invoke
* `componentWillUpdate` and `componentDidUpdate`.
*
* @param {?function} callback Called after update is complete.
* @final
* @protected
*/
ReactComponent.prototype.forceUpdate = function (callback) {
this.updater.enqueueForceUpdate(this);
if (callback) {
this.updater.enqueueCallback(this, callback, 'forceUpdate');
}
};
/**
* Deprecated APIs. These APIs used to exist on classic React classes but since
* we would like to deprecate them, we're not going to move them over to this
* modern base class. Instead, we define a getter that warns if it's accessed.
*/
if (true) {
var deprecatedAPIs = {
isMounted: ['isMounted', 'Instead, make sure to clean up subscriptions and pending requests in ' + 'componentWillUnmount to prevent memory leaks.'],
replaceState: ['replaceState', 'Refactor your code to use setState instead (see ' + 'https://github.com/facebook/react/issues/3236).']
};
var defineDeprecationWarning = function (methodName, info) {
if (canDefineProperty) {
Object.defineProperty(ReactComponent.prototype, methodName, {
get: function () {
lowPriorityWarning(false, '%s(...) is deprecated in plain JavaScript React classes. %s', info[0], info[1]);
return undefined;
}
});
}
};
for (var fnName in deprecatedAPIs) {
if (deprecatedAPIs.hasOwnProperty(fnName)) {
defineDeprecationWarning(fnName, deprecatedAPIs[fnName]);
}
}
}
/**
* Base class helpers for the updating state of a component.
*/
function ReactPureComponent(props, context, updater) {
// Duplicated from ReactComponent.
this.props = props;
this.context = context;
this.refs = emptyObject;
// We initialize the default updater but the real one gets injected by the
// renderer.
this.updater = updater || ReactNoopUpdateQueue;
}
function ComponentDummy() {}
ComponentDummy.prototype = ReactComponent.prototype;
ReactPureComponent.prototype = new ComponentDummy();
ReactPureComponent.prototype.constructor = ReactPureComponent;
// Avoid an extra prototype jump for these methods.
_assign(ReactPureComponent.prototype, ReactComponent.prototype);
ReactPureComponent.prototype.isPureReactComponent = true;
module.exports = {
Component: ReactComponent,
PureComponent: ReactPureComponent
};
/***/ }),
/* 53 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var warning = __webpack_require__(1);
function warnNoop(publicInstance, callerName) {
if (true) {
var constructor = publicInstance.constructor;
true ? warning(false, '%s(...): Can only update a mounted or mounting component. ' + 'This usually means you called %s() on an unmounted component. ' + 'This is a no-op. Please check the code for the %s component.', callerName, callerName, constructor && (constructor.displayName || constructor.name) || 'ReactClass') : void 0;
}
}
/**
* This is the abstract API for an update queue.
*/
var ReactNoopUpdateQueue = {
/**
* Checks whether or not this composite component is mounted.
* @param {ReactClass} publicInstance The instance we want to test.
* @return {boolean} True if mounted, false otherwise.
* @protected
* @final
*/
isMounted: function (publicInstance) {
return false;
},
/**
* Enqueue a callback that will be executed after all the pending updates
* have processed.
*
* @param {ReactClass} publicInstance The instance to use as `this` context.
* @param {?function} callback Called after state is updated.
* @internal
*/
enqueueCallback: function (publicInstance, callback) {},
/**
* Forces an update. This should only be invoked when it is known with
* certainty that we are **not** in a DOM transaction.
*
* You may want to call this when you know that some deeper aspect of the
* component's state has changed but `setState` was not called.
*
* This will not invoke `shouldComponentUpdate`, but it will invoke
* `componentWillUpdate` and `componentDidUpdate`.
*
* @param {ReactClass} publicInstance The instance that should rerender.
* @internal
*/
enqueueForceUpdate: function (publicInstance) {
warnNoop(publicInstance, 'forceUpdate');
},
/**
* Replaces all of the state. Always use this or `setState` to mutate state.
* You should treat `this.state` as immutable.
*
* There is no guarantee that `this.state` will be immediately updated, so
* accessing `this.state` after calling this method may return the old value.
*
* @param {ReactClass} publicInstance The instance that should rerender.
* @param {object} completeState Next state.
* @internal
*/
enqueueReplaceState: function (publicInstance, completeState) {
warnNoop(publicInstance, 'replaceState');
},
/**
* Sets a subset of the state. This only exists because _pendingState is
* internal. This provides a merging strategy that is not available to deep
* properties which is confusing. TODO: Expose pendingState or don't use it
* during the merge.
*
* @param {ReactClass} publicInstance The instance that should rerender.
* @param {object} partialState Next partial state to be merged with state.
* @internal
*/
enqueueSetState: function (publicInstance, partialState) {
warnNoop(publicInstance, 'setState');
}
};
module.exports = ReactNoopUpdateQueue;
/***/ }),
/* 54 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2014-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
// The Symbol used to tag the ReactElement type. If there is no native Symbol
// nor polyfill, then a plain number is used for performance.
var REACT_ELEMENT_TYPE = typeof Symbol === 'function' && Symbol['for'] && Symbol['for']('react.element') || 0xeac7;
module.exports = REACT_ELEMENT_TYPE;
/***/ }),
/* 55 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
/* global Symbol */
var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec.
/**
* Returns the iterator method function contained on the iterable object.
*
* Be sure to invoke the function with the iterable as context:
*
* var iteratorFn = getIteratorFn(myIterable);
* if (iteratorFn) {
* var iterator = iteratorFn.call(myIterable);
* ...
* }
*
* @param {?object} maybeIterable
* @return {?function}
*/
function getIteratorFn(maybeIterable) {
var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]);
if (typeof iteratorFn === 'function') {
return iteratorFn;
}
}
module.exports = getIteratorFn;
/***/ }),
/* 56 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2014-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
/**
* ReactElementValidator provides a wrapper around a element factory
* which validates the props passed to the element. This is intended to be
* used only in DEV and could be replaced by a static type checker for languages
* that support it.
*/
var ReactCurrentOwner = __webpack_require__(9);
var ReactComponentTreeHook = __webpack_require__(6);
var ReactElement = __webpack_require__(14);
var checkReactTypeSpec = __webpack_require__(95);
var canDefineProperty = __webpack_require__(26);
var getIteratorFn = __webpack_require__(55);
var warning = __webpack_require__(1);
var lowPriorityWarning = __webpack_require__(35);
function getDeclarationErrorAddendum() {
if (ReactCurrentOwner.current) {
var name = ReactCurrentOwner.current.getName();
if (name) {
return ' Check the render method of `' + name + '`.';
}
}
return '';
}
function getSourceInfoErrorAddendum(elementProps) {
if (elementProps !== null && elementProps !== undefined && elementProps.__source !== undefined) {
var source = elementProps.__source;
var fileName = source.fileName.replace(/^.*[\\\/]/, '');
var lineNumber = source.lineNumber;
return ' Check your code at ' + fileName + ':' + lineNumber + '.';
}
return '';
}
/**
* Warn if there's no key explicitly set on dynamic arrays of children or
* object keys are not valid. This allows us to keep track of children between
* updates.
*/
var ownerHasKeyUseWarning = {};
function getCurrentComponentErrorInfo(parentType) {
var info = getDeclarationErrorAddendum();
if (!info) {
var parentName = typeof parentType === 'string' ? parentType : parentType.displayName || parentType.name;
if (parentName) {
info = ' Check the top-level render call using <' + parentName + '>.';
}
}
return info;
}
/**
* Warn if the element doesn't have an explicit key assigned to it.
* This element is in an array. The array could grow and shrink or be
* reordered. All children that haven't already been validated are required to
* have a "key" property assigned to it. Error statuses are cached so a warning
* will only be shown once.
*
* @internal
* @param {ReactElement} element Element that requires a key.
* @param {*} parentType element's parent's type.
*/
function validateExplicitKey(element, parentType) {
if (!element._store || element._store.validated || element.key != null) {
return;
}
element._store.validated = true;
var memoizer = ownerHasKeyUseWarning.uniqueKey || (ownerHasKeyUseWarning.uniqueKey = {});
var currentComponentErrorInfo = getCurrentComponentErrorInfo(parentType);
if (memoizer[currentComponentErrorInfo]) {
return;
}
memoizer[currentComponentErrorInfo] = true;
// Usually the current owner is the offender, but if it accepts children as a
// property, it may be the creator of the child that's responsible for
// assigning it a key.
var childOwner = '';
if (element && element._owner && element._owner !== ReactCurrentOwner.current) {
// Give the component that originally created this child.
childOwner = ' It was passed a child from ' + element._owner.getName() + '.';
}
true ? warning(false, 'Each child in an array or iterator should have a unique "key" prop.' + '%s%s See https://fb.me/react-warning-keys for more information.%s', currentComponentErrorInfo, childOwner, ReactComponentTreeHook.getCurrentStackAddendum(element)) : void 0;
}
/**
* Ensure that every element either is passed in a static location, in an
* array with an explicit keys property defined, or in an object literal
* with valid key property.
*
* @internal
* @param {ReactNode} node Statically passed child of any type.
* @param {*} parentType node's parent's type.
*/
function validateChildKeys(node, parentType) {
if (typeof node !== 'object') {
return;
}
if (Array.isArray(node)) {
for (var i = 0; i < node.length; i++) {
var child = node[i];
if (ReactElement.isValidElement(child)) {
validateExplicitKey(child, parentType);
}
}
} else if (ReactElement.isValidElement(node)) {
// This element was passed in a valid location.
if (node._store) {
node._store.validated = true;
}
} else if (node) {
var iteratorFn = getIteratorFn(node);
// Entry iterators provide implicit keys.
if (iteratorFn) {
if (iteratorFn !== node.entries) {
var iterator = iteratorFn.call(node);
var step;
while (!(step = iterator.next()).done) {
if (ReactElement.isValidElement(step.value)) {
validateExplicitKey(step.value, parentType);
}
}
}
}
}
}
/**
* Given an element, validate that its props follow the propTypes definition,
* provided by the type.
*
* @param {ReactElement} element
*/
function validatePropTypes(element) {
var componentClass = element.type;
if (typeof componentClass !== 'function') {
return;
}
var name = componentClass.displayName || componentClass.name;
if (componentClass.propTypes) {
checkReactTypeSpec(componentClass.propTypes, element.props, 'prop', name, element, null);
}
if (typeof componentClass.getDefaultProps === 'function') {
true ? warning(componentClass.getDefaultProps.isReactClassApproved, 'getDefaultProps is only used on classic React.createClass ' + 'definitions. Use a static property named `defaultProps` instead.') : void 0;
}
}
var ReactElementValidator = {
createElement: function (type, props, children) {
var validType = typeof type === 'string' || typeof type === 'function';
// We warn in this case but don't throw. We expect the element creation to
// succeed and there will likely be errors in render.
if (!validType) {
if (typeof type !== 'function' && typeof type !== 'string') {
var info = '';
if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
info += ' You likely forgot to export your component from the file ' + "it's defined in.";
}
var sourceInfo = getSourceInfoErrorAddendum(props);
if (sourceInfo) {
info += sourceInfo;
} else {
info += getDeclarationErrorAddendum();
}
info += ReactComponentTreeHook.getCurrentStackAddendum();
var currentSource = props !== null && props !== undefined && props.__source !== undefined ? props.__source : null;
ReactComponentTreeHook.pushNonStandardWarningStack(true, currentSource);
true ? warning(false, 'React.createElement: type is invalid -- expected a string (for ' + 'built-in components) or a class/function (for composite ' + 'components) but got: %s.%s', type == null ? type : typeof type, info) : void 0;
ReactComponentTreeHook.popNonStandardWarningStack();
}
}
var element = ReactElement.createElement.apply(this, arguments);
// The result can be nullish if a mock or a custom function is used.
// TODO: Drop this when these are no longer allowed as the type argument.
if (element == null) {
return element;
}
// Skip key warning if the type isn't valid since our key validation logic
// doesn't expect a non-string/function type and can throw confusing errors.
// We don't want exception behavior to differ between dev and prod.
// (Rendering will throw with a helpful message and as soon as the type is
// fixed, the key warnings will appear.)
if (validType) {
for (var i = 2; i < arguments.length; i++) {
validateChildKeys(arguments[i], type);
}
}
validatePropTypes(element);
return element;
},
createFactory: function (type) {
var validatedFactory = ReactElementValidator.createElement.bind(null, type);
// Legacy hook TODO: Warn if this is accessed
validatedFactory.type = type;
if (true) {
if (canDefineProperty) {
Object.defineProperty(validatedFactory, 'type', {
enumerable: false,
get: function () {
lowPriorityWarning(false, 'Factory.type is deprecated. Access the class directly ' + 'before passing it to createFactory.');
Object.defineProperty(this, 'type', {
value: type
});
return type;
}
});
}
}
return validatedFactory;
},
cloneElement: function (element, props, children) {
var newElement = ReactElement.cloneElement.apply(this, arguments);
for (var i = 2; i < arguments.length; i++) {
validateChildKeys(arguments[i], newElement.type);
}
validatePropTypes(newElement);
return newElement;
}
};
module.exports = ReactElementValidator;
/***/ }),
/* 57 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// React 15.5 references this module, and assumes PropTypes are still callable in production.
// Therefore we re-export development-only version with all the PropTypes checks here.
// However if one is migrating to the `prop-types` npm library, they will go through the
// `index.js` entry point, and it will branch depending on the environment.
var factory = __webpack_require__(85);
module.exports = function(isValidElement) {
// It is still allowed in 15.5.
var throwOnDirectAccess = false;
return factory(isValidElement, throwOnDirectAccess);
};
/***/ }),
/* 58 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
module.exports = ReactPropTypesSecret;
/***/ }),
/* 59 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var ReactDOMComponentFlags = {
hasCachedChildNodes: 1 << 0
};
module.exports = ReactDOMComponentFlags;
/***/ }),
/* 60 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2014-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var _prodInvariant = __webpack_require__(2);
var invariant = __webpack_require__(0);
/**
* Accumulates items that must not be null or undefined into the first one. This
* is used to conserve memory by avoiding array allocations, and thus sacrifices
* API cleanness. Since `current` can be null before being passed in and not
* null after this function, make sure to assign it back to `current`:
*
* `a = accumulateInto(a, b);`
*
* This API should be sparingly used. Try `accumulate` for something cleaner.
*
* @return {*|array<*>} An accumulation of items.
*/
function accumulateInto(current, next) {
!(next != null) ? true ? invariant(false, 'accumulateInto(...): Accumulated items must not be null or undefined.') : _prodInvariant('30') : void 0;
if (current == null) {
return next;
}
// Both are not empty. Warning: Never call x.concat(y) when you are not
// certain that x is an Array (x could be a string with concat method).
if (Array.isArray(current)) {
if (Array.isArray(next)) {
current.push.apply(current, next);
return current;
}
current.push(next);
return current;
}
if (Array.isArray(next)) {
// A bit too dangerous to mutate `next`.
return [current].concat(next);
}
return [current, next];
}
module.exports = accumulateInto;
/***/ }),
/* 61 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
/**
* @param {array} arr an "accumulation" of items which is either an Array or
* a single item. Useful when paired with the `accumulate` module. This is a
* simple utility that allows us to reason about a collection of items, but
* handling the case when there is exactly one item (and we do not need to
* allocate an array).
*/
function forEachAccumulated(arr, cb, scope) {
if (Array.isArray(arr)) {
arr.forEach(cb, scope);
} else if (arr) {
cb.call(scope, arr);
}
}
module.exports = forEachAccumulated;
/***/ }),
/* 62 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var ExecutionEnvironment = __webpack_require__(5);
var contentKey = null;
/**
* Gets the key used to access text content on a DOM node.
*
* @return {?string} Key used to access text content.
* @internal
*/
function getTextContentAccessor() {
if (!contentKey && ExecutionEnvironment.canUseDOM) {
// Prefer textContent to innerText because many browsers support both but
// SVG <text> elements don't support innerText even when <div> does.
contentKey = 'textContent' in document.documentElement ? 'textContent' : 'innerText';
}
return contentKey;
}
module.exports = getTextContentAccessor;
/***/ }),
/* 63 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var _prodInvariant = __webpack_require__(2);
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var PooledClass = __webpack_require__(15);
var invariant = __webpack_require__(0);
/**
* A specialized pseudo-event module to help keep track of components waiting to
* be notified when their DOM representations are available for use.
*
* This implements `PooledClass`, so you should never need to instantiate this.
* Instead, use `CallbackQueue.getPooled()`.
*
* @class ReactMountReady
* @implements PooledClass
* @internal
*/
var CallbackQueue = function () {
function CallbackQueue(arg) {
_classCallCheck(this, CallbackQueue);
this._callbacks = null;
this._contexts = null;
this._arg = arg;
}
/**
* Enqueues a callback to be invoked when `notifyAll` is invoked.
*
* @param {function} callback Invoked when `notifyAll` is invoked.
* @param {?object} context Context to call `callback` with.
* @internal
*/
CallbackQueue.prototype.enqueue = function enqueue(callback, context) {
this._callbacks = this._callbacks || [];
this._callbacks.push(callback);
this._contexts = this._contexts || [];
this._contexts.push(context);
};
/**
* Invokes all enqueued callbacks and clears the queue. This is invoked after
* the DOM representation of a component has been created or updated.
*
* @internal
*/
CallbackQueue.prototype.notifyAll = function notifyAll() {
var callbacks = this._callbacks;
var contexts = this._contexts;
var arg = this._arg;
if (callbacks && contexts) {
!(callbacks.length === contexts.length) ? true ? invariant(false, 'Mismatched list of contexts in callback queue') : _prodInvariant('24') : void 0;
this._callbacks = null;
this._contexts = null;
for (var i = 0; i < callbacks.length; i++) {
callbacks[i].call(contexts[i], arg);
}
callbacks.length = 0;
contexts.length = 0;
}
};
CallbackQueue.prototype.checkpoint = function checkpoint() {
return this._callbacks ? this._callbacks.length : 0;
};
CallbackQueue.prototype.rollback = function rollback(len) {
if (this._callbacks && this._contexts) {
this._callbacks.length = len;
this._contexts.length = len;
}
};
/**
* Resets the internal queue.
*
* @internal
*/
CallbackQueue.prototype.reset = function reset() {
this._callbacks = null;
this._contexts = null;
};
/**
* `PooledClass` looks for this.
*/
CallbackQueue.prototype.destructor = function destructor() {
this.reset();
};
return CallbackQueue;
}();
module.exports = PooledClass.addPoolingTo(CallbackQueue);
/***/ }),
/* 64 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var ReactFeatureFlags = {
// When true, call console.time() before and .timeEnd() after each top-level
// render (both initial renders and updates). Useful when looking at prod-mode
// timeline profiles in Chrome, for example.
logTopLevelRenders: false
};
module.exports = ReactFeatureFlags;
/***/ }),
/* 65 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var ReactDOMComponentTree = __webpack_require__(4);
function isCheckable(elem) {
var type = elem.type;
var nodeName = elem.nodeName;
return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio');
}
function getTracker(inst) {
return inst._wrapperState.valueTracker;
}
function attachTracker(inst, tracker) {
inst._wrapperState.valueTracker = tracker;
}
function detachTracker(inst) {
inst._wrapperState.valueTracker = null;
}
function getValueFromNode(node) {
var value;
if (node) {
value = isCheckable(node) ? '' + node.checked : node.value;
}
return value;
}
var inputValueTracking = {
// exposed for testing
_getTrackerFromNode: function (node) {
return getTracker(ReactDOMComponentTree.getInstanceFromNode(node));
},
track: function (inst) {
if (getTracker(inst)) {
return;
}
var node = ReactDOMComponentTree.getNodeFromInstance(inst);
var valueField = isCheckable(node) ? 'checked' : 'value';
var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField);
var currentValue = '' + node[valueField];
// if someone has already defined a value or Safari, then bail
// and don't track value will cause over reporting of changes,
// but it's better then a hard failure
// (needed for certain tests that spyOn input values and Safari)
if (node.hasOwnProperty(valueField) || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') {
return;
}
Object.defineProperty(node, valueField, {
enumerable: descriptor.enumerable,
configurable: true,
get: function () {
return descriptor.get.call(this);
},
set: function (value) {
currentValue = '' + value;
descriptor.set.call(this, value);
}
});
attachTracker(inst, {
getValue: function () {
return currentValue;
},
setValue: function (value) {
currentValue = '' + value;
},
stopTracking: function () {
detachTracker(inst);
delete node[valueField];
}
});
},
updateValueIfChanged: function (inst) {
if (!inst) {
return false;
}
var tracker = getTracker(inst);
if (!tracker) {
inputValueTracking.track(inst);
return true;
}
var lastValue = tracker.getValue();
var nextValue = getValueFromNode(ReactDOMComponentTree.getNodeFromInstance(inst));
if (nextValue !== lastValue) {
tracker.setValue(nextValue);
return true;
}
return false;
},
stopTracking: function (inst) {
var tracker = getTracker(inst);
if (tracker) {
tracker.stopTracking();
}
}
};
module.exports = inputValueTracking;
/***/ }),
/* 66 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
/**
* @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
*/
var supportedInputTypes = {
color: true,
date: true,
datetime: true,
'datetime-local': true,
email: true,
month: true,
number: true,
password: true,
range: true,
search: true,
tel: true,
text: true,
time: true,
url: true,
week: true
};
function isTextInputElement(elem) {
var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
if (nodeName === 'input') {
return !!supportedInputTypes[elem.type];
}
if (nodeName === 'textarea') {
return true;
}
return false;
}
module.exports = isTextInputElement;
/***/ }),
/* 67 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var ViewportMetrics = {
currentScrollLeft: 0,
currentScrollTop: 0,
refreshScrollValues: function (scrollPosition) {
ViewportMetrics.currentScrollLeft = scrollPosition.x;
ViewportMetrics.currentScrollTop = scrollPosition.y;
}
};
module.exports = ViewportMetrics;
/***/ }),
/* 68 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var ExecutionEnvironment = __webpack_require__(5);
var escapeTextContentForBrowser = __webpack_require__(32);
var setInnerHTML = __webpack_require__(31);
/**
* Set the textContent property of a node, ensuring that whitespace is preserved
* even in IE8. innerText is a poor substitute for textContent and, among many
* issues, inserts <br> instead of the literal newline chars. innerHTML behaves
* as it should.
*
* @param {DOMElement} node
* @param {string} text
* @internal
*/
var setTextContent = function (node, text) {
if (text) {
var firstChild = node.firstChild;
if (firstChild && firstChild === node.lastChild && firstChild.nodeType === 3) {
firstChild.nodeValue = text;
return;
}
}
node.textContent = text;
};
if (ExecutionEnvironment.canUseDOM) {
if (!('textContent' in document.documentElement)) {
setTextContent = function (node, text) {
if (node.nodeType === 3) {
node.nodeValue = text;
return;
}
setInnerHTML(node, escapeTextContentForBrowser(text));
};
}
}
module.exports = setTextContent;
/***/ }),
/* 69 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
/**
* @param {DOMElement} node input/textarea to focus
*/
function focusNode(node) {
// IE8 can throw "Can't move focus to the control because it is invisible,
// not enabled, or of a type that does not accept the focus." for all kinds of
// reasons that are too expensive and fragile to test.
try {
node.focus();
} catch (e) {}
}
module.exports = focusNode;
/***/ }),
/* 70 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
/**
* CSS properties which accept numbers but are not in units of "px".
*/
var isUnitlessNumber = {
animationIterationCount: true,
borderImageOutset: true,
borderImageSlice: true,
borderImageWidth: true,
boxFlex: true,
boxFlexGroup: true,
boxOrdinalGroup: true,
columnCount: true,
columns: true,
flex: true,
flexGrow: true,
flexPositive: true,
flexShrink: true,
flexNegative: true,
flexOrder: true,
gridRow: true,
gridRowEnd: true,
gridRowSpan: true,
gridRowStart: true,
gridColumn: true,
gridColumnEnd: true,
gridColumnSpan: true,
gridColumnStart: true,
fontWeight: true,
lineClamp: true,
lineHeight: true,
opacity: true,
order: true,
orphans: true,
tabSize: true,
widows: true,
zIndex: true,
zoom: true,
// SVG-related properties
fillOpacity: true,
floodOpacity: true,
stopOpacity: true,
strokeDasharray: true,
strokeDashoffset: true,
strokeMiterlimit: true,
strokeOpacity: true,
strokeWidth: true
};
/**
* @param {string} prefix vendor-specific prefix, eg: Webkit
* @param {string} key style name, eg: transitionDuration
* @return {string} style name prefixed with `prefix`, properly camelCased, eg:
* WebkitTransitionDuration
*/
function prefixKey(prefix, key) {
return prefix + key.charAt(0).toUpperCase() + key.substring(1);
}
/**
* Support style names that may come passed in prefixed by adding permutations
* of vendor prefixes.
*/
var prefixes = ['Webkit', 'ms', 'Moz', 'O'];
// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
// infinite loop, because it iterates over the newly added props too.
Object.keys(isUnitlessNumber).forEach(function (prop) {
prefixes.forEach(function (prefix) {
isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
});
});
/**
* Most style properties can be unset by doing .style[prop] = '' but IE8
* doesn't like doing that with shorthand properties so for the properties that
* IE8 breaks on, which are listed here, we instead unset each of the
* individual properties. See http://bugs.jquery.com/ticket/12385.
* The 4-value 'clock' properties like margin, padding, border-width seem to
* behave without any problems. Curiously, list-style works too without any
* special prodding.
*/
var shorthandPropertyExpansions = {
background: {
backgroundAttachment: true,
backgroundColor: true,
backgroundImage: true,
backgroundPositionX: true,
backgroundPositionY: true,
backgroundRepeat: true
},
backgroundPosition: {
backgroundPositionX: true,
backgroundPositionY: true
},
border: {
borderWidth: true,
borderStyle: true,
borderColor: true
},
borderBottom: {
borderBottomWidth: true,
borderBottomStyle: true,
borderBottomColor: true
},
borderLeft: {
borderLeftWidth: true,
borderLeftStyle: true,
borderLeftColor: true
},
borderRight: {
borderRightWidth: true,
borderRightStyle: true,
borderRightColor: true
},
borderTop: {
borderTopWidth: true,
borderTopStyle: true,
borderTopColor: true
},
font: {
fontStyle: true,
fontVariant: true,
fontWeight: true,
fontSize: true,
lineHeight: true,
fontFamily: true
},
outline: {
outlineWidth: true,
outlineStyle: true,
outlineColor: true
}
};
var CSSProperty = {
isUnitlessNumber: isUnitlessNumber,
shorthandPropertyExpansions: shorthandPropertyExpansions
};
module.exports = CSSProperty;
/***/ }),
/* 71 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var DOMProperty = __webpack_require__(13);
var ReactDOMComponentTree = __webpack_require__(4);
var ReactInstrumentation = __webpack_require__(7);
var quoteAttributeValueForBrowser = __webpack_require__(138);
var warning = __webpack_require__(1);
var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + DOMProperty.ATTRIBUTE_NAME_START_CHAR + '][' + DOMProperty.ATTRIBUTE_NAME_CHAR + ']*$');
var illegalAttributeNameCache = {};
var validatedAttributeNameCache = {};
function isAttributeNameSafe(attributeName) {
if (validatedAttributeNameCache.hasOwnProperty(attributeName)) {
return true;
}
if (illegalAttributeNameCache.hasOwnProperty(attributeName)) {
return false;
}
if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {
validatedAttributeNameCache[attributeName] = true;
return true;
}
illegalAttributeNameCache[attributeName] = true;
true ? warning(false, 'Invalid attribute name: `%s`', attributeName) : void 0;
return false;
}
function shouldIgnoreValue(propertyInfo, value) {
return value == null || propertyInfo.hasBooleanValue && !value || propertyInfo.hasNumericValue && isNaN(value) || propertyInfo.hasPositiveNumericValue && value < 1 || propertyInfo.hasOverloadedBooleanValue && value === false;
}
/**
* Operations for dealing with DOM properties.
*/
var DOMPropertyOperations = {
/**
* Creates markup for the ID property.
*
* @param {string} id Unescaped ID.
* @return {string} Markup string.
*/
createMarkupForID: function (id) {
return DOMProperty.ID_ATTRIBUTE_NAME + '=' + quoteAttributeValueForBrowser(id);
},
setAttributeForID: function (node, id) {
node.setAttribute(DOMProperty.ID_ATTRIBUTE_NAME, id);
},
createMarkupForRoot: function () {
return DOMProperty.ROOT_ATTRIBUTE_NAME + '=""';
},
setAttributeForRoot: function (node) {
node.setAttribute(DOMProperty.ROOT_ATTRIBUTE_NAME, '');
},
/**
* Creates markup for a property.
*
* @param {string} name
* @param {*} value
* @return {?string} Markup string, or null if the property was invalid.
*/
createMarkupForProperty: function (name, value) {
var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null;
if (propertyInfo) {
if (shouldIgnoreValue(propertyInfo, value)) {
return '';
}
var attributeName = propertyInfo.attributeName;
if (propertyInfo.hasBooleanValue || propertyInfo.hasOverloadedBooleanValue && value === true) {
return attributeName + '=""';
}
return attributeName + '=' + quoteAttributeValueForBrowser(value);
} else if (DOMProperty.isCustomAttribute(name)) {
if (value == null) {
return '';
}
return name + '=' + quoteAttributeValueForBrowser(value);
}
return null;
},
/**
* Creates markup for a custom property.
*
* @param {string} name
* @param {*} value
* @return {string} Markup string, or empty string if the property was invalid.
*/
createMarkupForCustomAttribute: function (name, value) {
if (!isAttributeNameSafe(name) || value == null) {
return '';
}
return name + '=' + quoteAttributeValueForBrowser(value);
},
/**
* Sets the value for a property on a node.
*
* @param {DOMElement} node
* @param {string} name
* @param {*} value
*/
setValueForProperty: function (node, name, value) {
var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null;
if (propertyInfo) {
var mutationMethod = propertyInfo.mutationMethod;
if (mutationMethod) {
mutationMethod(node, value);
} else if (shouldIgnoreValue(propertyInfo, value)) {
this.deleteValueForProperty(node, name);
return;
} else if (propertyInfo.mustUseProperty) {
// Contrary to `setAttribute`, object properties are properly
// `toString`ed by IE8/9.
node[propertyInfo.propertyName] = value;
} else {
var attributeName = propertyInfo.attributeName;
var namespace = propertyInfo.attributeNamespace;
// `setAttribute` with objects becomes only `[object]` in IE8/9,
// ('' + value) makes it output the correct toString()-value.
if (namespace) {
node.setAttributeNS(namespace, attributeName, '' + value);
} else if (propertyInfo.hasBooleanValue || propertyInfo.hasOverloadedBooleanValue && value === true) {
node.setAttribute(attributeName, '');
} else {
node.setAttribute(attributeName, '' + value);
}
}
} else if (DOMProperty.isCustomAttribute(name)) {
DOMPropertyOperations.setValueForAttribute(node, name, value);
return;
}
if (true) {
var payload = {};
payload[name] = value;
ReactInstrumentation.debugTool.onHostOperation({
instanceID: ReactDOMComponentTree.getInstanceFromNode(node)._debugID,
type: 'update attribute',
payload: payload
});
}
},
setValueForAttribute: function (node, name, value) {
if (!isAttributeNameSafe(name)) {
return;
}
if (value == null) {
node.removeAttribute(name);
} else {
node.setAttribute(name, '' + value);
}
if (true) {
var payload = {};
payload[name] = value;
ReactInstrumentation.debugTool.onHostOperation({
instanceID: ReactDOMComponentTree.getInstanceFromNode(node)._debugID,
type: 'update attribute',
payload: payload
});
}
},
/**
* Deletes an attributes from a node.
*
* @param {DOMElement} node
* @param {string} name
*/
deleteValueForAttribute: function (node, name) {
node.removeAttribute(name);
if (true) {
ReactInstrumentation.debugTool.onHostOperation({
instanceID: ReactDOMComponentTree.getInstanceFromNode(node)._debugID,
type: 'remove attribute',
payload: name
});
}
},
/**
* Deletes the value for a property on a node.
*
* @param {DOMElement} node
* @param {string} name
*/
deleteValueForProperty: function (node, name) {
var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null;
if (propertyInfo) {
var mutationMethod = propertyInfo.mutationMethod;
if (mutationMethod) {
mutationMethod(node, undefined);
} else if (propertyInfo.mustUseProperty) {
var propName = propertyInfo.propertyName;
if (propertyInfo.hasBooleanValue) {
node[propName] = false;
} else {
node[propName] = '';
}
} else {
node.removeAttribute(propertyInfo.attributeName);
}
} else if (DOMProperty.isCustomAttribute(name)) {
node.removeAttribute(name);
}
if (true) {
ReactInstrumentation.debugTool.onHostOperation({
instanceID: ReactDOMComponentTree.getInstanceFromNode(node)._debugID,
type: 'remove attribute',
payload: name
});
}
}
};
module.exports = DOMPropertyOperations;
/***/ }),
/* 72 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
module.exports = ReactPropTypesSecret;
/***/ }),
/* 73 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _assign = __webpack_require__(3);
var LinkedValueUtils = __webpack_require__(44);
var ReactDOMComponentTree = __webpack_require__(4);
var ReactUpdates = __webpack_require__(10);
var warning = __webpack_require__(1);
var didWarnValueLink = false;
var didWarnValueDefaultValue = false;
function updateOptionsIfPendingUpdateAndMounted() {
if (this._rootNodeID && this._wrapperState.pendingUpdate) {
this._wrapperState.pendingUpdate = false;
var props = this._currentElement.props;
var value = LinkedValueUtils.getValue(props);
if (value != null) {
updateOptions(this, Boolean(props.multiple), value);
}
}
}
function getDeclarationErrorAddendum(owner) {
if (owner) {
var name = owner.getName();
if (name) {
return ' Check the render method of `' + name + '`.';
}
}
return '';
}
var valuePropNames = ['value', 'defaultValue'];
/**
* Validation function for `value` and `defaultValue`.
* @private
*/
function checkSelectPropTypes(inst, props) {
var owner = inst._currentElement._owner;
LinkedValueUtils.checkPropTypes('select', props, owner);
if (props.valueLink !== undefined && !didWarnValueLink) {
true ? warning(false, '`valueLink` prop on `select` is deprecated; set `value` and `onChange` instead.') : void 0;
didWarnValueLink = true;
}
for (var i = 0; i < valuePropNames.length; i++) {
var propName = valuePropNames[i];
if (props[propName] == null) {
continue;
}
var isArray = Array.isArray(props[propName]);
if (props.multiple && !isArray) {
true ? warning(false, 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum(owner)) : void 0;
} else if (!props.multiple && isArray) {
true ? warning(false, 'The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum(owner)) : void 0;
}
}
}
/**
* @param {ReactDOMComponent} inst
* @param {boolean} multiple
* @param {*} propValue A stringable (with `multiple`, a list of stringables).
* @private
*/
function updateOptions(inst, multiple, propValue) {
var selectedValue, i;
var options = ReactDOMComponentTree.getNodeFromInstance(inst).options;
if (multiple) {
selectedValue = {};
for (i = 0; i < propValue.length; i++) {
selectedValue['' + propValue[i]] = true;
}
for (i = 0; i < options.length; i++) {
var selected = selectedValue.hasOwnProperty(options[i].value);
if (options[i].selected !== selected) {
options[i].selected = selected;
}
}
} else {
// Do not set `select.value` as exact behavior isn't consistent across all
// browsers for all cases.
selectedValue = '' + propValue;
for (i = 0; i < options.length; i++) {
if (options[i].value === selectedValue) {
options[i].selected = true;
return;
}
}
if (options.length) {
options[0].selected = true;
}
}
}
/**
* Implements a <select> host component that allows optionally setting the
* props `value` and `defaultValue`. If `multiple` is false, the prop must be a
* stringable. If `multiple` is true, the prop must be an array of stringables.
*
* If `value` is not supplied (or null/undefined), user actions that change the
* selected option will trigger updates to the rendered options.
*
* If it is supplied (and not null/undefined), the rendered options will not
* update in response to user actions. Instead, the `value` prop must change in
* order for the rendered options to update.
*
* If `defaultValue` is provided, any options with the supplied values will be
* selected.
*/
var ReactDOMSelect = {
getHostProps: function (inst, props) {
return _assign({}, props, {
onChange: inst._wrapperState.onChange,
value: undefined
});
},
mountWrapper: function (inst, props) {
if (true) {
checkSelectPropTypes(inst, props);
}
var value = LinkedValueUtils.getValue(props);
inst._wrapperState = {
pendingUpdate: false,
initialValue: value != null ? value : props.defaultValue,
listeners: null,
onChange: _handleChange.bind(inst),
wasMultiple: Boolean(props.multiple)
};
if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) {
true ? warning(false, 'Select elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled select ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components') : void 0;
didWarnValueDefaultValue = true;
}
},
getSelectValueContext: function (inst) {
// ReactDOMOption looks at this initial value so the initial generated
// markup has correct `selected` attributes
return inst._wrapperState.initialValue;
},
postUpdateWrapper: function (inst) {
var props = inst._currentElement.props;
// After the initial mount, we control selected-ness manually so don't pass
// this value down
inst._wrapperState.initialValue = undefined;
var wasMultiple = inst._wrapperState.wasMultiple;
inst._wrapperState.wasMultiple = Boolean(props.multiple);
var value = LinkedValueUtils.getValue(props);
if (value != null) {
inst._wrapperState.pendingUpdate = false;
updateOptions(inst, Boolean(props.multiple), value);
} else if (wasMultiple !== Boolean(props.multiple)) {
// For simplicity, reapply `defaultValue` if `multiple` is toggled.
if (props.defaultValue != null) {
updateOptions(inst, Boolean(props.multiple), props.defaultValue);
} else {
// Revert the select back to its default unselected state.
updateOptions(inst, Boolean(props.multiple), props.multiple ? [] : '');
}
}
}
};
function _handleChange(event) {
var props = this._currentElement.props;
var returnValue = LinkedValueUtils.executeOnChange(props, event);
if (this._rootNodeID) {
this._wrapperState.pendingUpdate = true;
}
ReactUpdates.asap(updateOptionsIfPendingUpdateAndMounted, this);
return returnValue;
}
module.exports = ReactDOMSelect;
/***/ }),
/* 74 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _prodInvariant = __webpack_require__(2),
_assign = __webpack_require__(3);
var ReactCompositeComponent = __webpack_require__(146);
var ReactEmptyComponent = __webpack_require__(76);
var ReactHostComponent = __webpack_require__(77);
var getNextDebugID = __webpack_require__(149);
var invariant = __webpack_require__(0);
var warning = __webpack_require__(1);
// To avoid a cyclic dependency, we create the final class in this module
var ReactCompositeComponentWrapper = function (element) {
this.construct(element);
};
function getDeclarationErrorAddendum(owner) {
if (owner) {
var name = owner.getName();
if (name) {
return ' Check the render method of `' + name + '`.';
}
}
return '';
}
/**
* Check if the type reference is a known internal type. I.e. not a user
* provided composite type.
*
* @param {function} type
* @return {boolean} Returns true if this is a valid internal type.
*/
function isInternalComponentType(type) {
return typeof type === 'function' && typeof type.prototype !== 'undefined' && typeof type.prototype.mountComponent === 'function' && typeof type.prototype.receiveComponent === 'function';
}
/**
* Given a ReactNode, create an instance that will actually be mounted.
*
* @param {ReactNode} node
* @param {boolean} shouldHaveDebugID
* @return {object} A new instance of the element's constructor.
* @protected
*/
function instantiateReactComponent(node, shouldHaveDebugID) {
var instance;
if (node === null || node === false) {
instance = ReactEmptyComponent.create(instantiateReactComponent);
} else if (typeof node === 'object') {
var element = node;
var type = element.type;
if (typeof type !== 'function' && typeof type !== 'string') {
var info = '';
if (true) {
if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
info += ' You likely forgot to export your component from the file ' + "it's defined in.";
}
}
info += getDeclarationErrorAddendum(element._owner);
true ? true ? invariant(false, 'Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s', type == null ? type : typeof type, info) : _prodInvariant('130', type == null ? type : typeof type, info) : void 0;
}
// Special case string values
if (typeof element.type === 'string') {
instance = ReactHostComponent.createInternalComponent(element);
} else if (isInternalComponentType(element.type)) {
// This is temporarily available for custom components that are not string
// representations. I.e. ART. Once those are updated to use the string
// representation, we can drop this code path.
instance = new element.type(element);
// We renamed this. Allow the old name for compat. :(
if (!instance.getHostNode) {
instance.getHostNode = instance.getNativeNode;
}
} else {
instance = new ReactCompositeComponentWrapper(element);
}
} else if (typeof node === 'string' || typeof node === 'number') {
instance = ReactHostComponent.createInstanceForText(node);
} else {
true ? true ? invariant(false, 'Encountered invalid React node of type %s', typeof node) : _prodInvariant('131', typeof node) : void 0;
}
if (true) {
true ? warning(typeof instance.mountComponent === 'function' && typeof instance.receiveComponent === 'function' && typeof instance.getHostNode === 'function' && typeof instance.unmountComponent === 'function', 'Only React Components can be mounted.') : void 0;
}
// These two fields are used by the DOM and ART diffing algorithms
// respectively. Instead of using expandos on components, we should be
// storing the state needed by the diffing algorithms elsewhere.
instance._mountIndex = 0;
instance._mountImage = null;
if (true) {
instance._debugID = shouldHaveDebugID ? getNextDebugID() : 0;
}
// Internal instances should fully constructed at this point, so they should
// not get any new fields added to them at this point.
if (true) {
if (Object.preventExtensions) {
Object.preventExtensions(instance);
}
}
return instance;
}
_assign(ReactCompositeComponentWrapper.prototype, ReactCompositeComponent, {
_instantiateReactComponent: instantiateReactComponent
});
module.exports = instantiateReactComponent;
/***/ }),
/* 75 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var _prodInvariant = __webpack_require__(2);
var React = __webpack_require__(16);
var invariant = __webpack_require__(0);
var ReactNodeTypes = {
HOST: 0,
COMPOSITE: 1,
EMPTY: 2,
getType: function (node) {
if (node === null || node === false) {
return ReactNodeTypes.EMPTY;
} else if (React.isValidElement(node)) {
if (typeof node.type === 'function') {
return ReactNodeTypes.COMPOSITE;
} else {
return ReactNodeTypes.HOST;
}
}
true ? true ? invariant(false, 'Unexpected node: %s', node) : _prodInvariant('26', node) : void 0;
}
};
module.exports = ReactNodeTypes;
/***/ }),
/* 76 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2014-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var emptyComponentFactory;
var ReactEmptyComponentInjection = {
injectEmptyComponentFactory: function (factory) {
emptyComponentFactory = factory;
}
};
var ReactEmptyComponent = {
create: function (instantiate) {
return emptyComponentFactory(instantiate);
}
};
ReactEmptyComponent.injection = ReactEmptyComponentInjection;
module.exports = ReactEmptyComponent;
/***/ }),
/* 77 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2014-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _prodInvariant = __webpack_require__(2);
var invariant = __webpack_require__(0);
var genericComponentClass = null;
var textComponentClass = null;
var ReactHostComponentInjection = {
// This accepts a class that receives the tag string. This is a catch all
// that can render any kind of tag.
injectGenericComponentClass: function (componentClass) {
genericComponentClass = componentClass;
},
// This accepts a text component class that takes the text string to be
// rendered as props.
injectTextComponentClass: function (componentClass) {
textComponentClass = componentClass;
}
};
/**
* Get a host internal component class for a specific tag.
*
* @param {ReactElement} element The element to create.
* @return {function} The internal class constructor function.
*/
function createInternalComponent(element) {
!genericComponentClass ? true ? invariant(false, 'There is no registered component for the tag %s', element.type) : _prodInvariant('111', element.type) : void 0;
return new genericComponentClass(element);
}
/**
* @param {ReactText} text
* @return {ReactComponent}
*/
function createInstanceForText(text) {
return new textComponentClass(text);
}
/**
* @param {ReactComponent} component
* @return {boolean}
*/
function isTextComponent(component) {
return component instanceof textComponentClass;
}
var ReactHostComponent = {
createInternalComponent: createInternalComponent,
createInstanceForText: createInstanceForText,
isTextComponent: isTextComponent,
injection: ReactHostComponentInjection
};
module.exports = ReactHostComponent;
/***/ }),
/* 78 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _prodInvariant = __webpack_require__(2);
var ReactCurrentOwner = __webpack_require__(9);
var REACT_ELEMENT_TYPE = __webpack_require__(150);
var getIteratorFn = __webpack_require__(151);
var invariant = __webpack_require__(0);
var KeyEscapeUtils = __webpack_require__(48);
var warning = __webpack_require__(1);
var SEPARATOR = '.';
var SUBSEPARATOR = ':';
/**
* This is inlined from ReactElement since this file is shared between
* isomorphic and renderers. We could extract this to a
*
*/
/**
* TODO: Test that a single child and an array with one item have the same key
* pattern.
*/
var didWarnAboutMaps = false;
/**
* Generate a key string that identifies a component within a set.
*
* @param {*} component A component that could contain a manual key.
* @param {number} index Index that is used if a manual key is not provided.
* @return {string}
*/
function getComponentKey(component, index) {
// Do some typechecking here since we call this blindly. We want to ensure
// that we don't block potential future ES APIs.
if (component && typeof component === 'object' && component.key != null) {
// Explicit key
return KeyEscapeUtils.escape(component.key);
}
// Implicit key determined by the index in the set
return index.toString(36);
}
/**
* @param {?*} children Children tree container.
* @param {!string} nameSoFar Name of the key path so far.
* @param {!function} callback Callback to invoke with each child found.
* @param {?*} traverseContext Used to pass information throughout the traversal
* process.
* @return {!number} The number of children in this subtree.
*/
function traverseAllChildrenImpl(children, nameSoFar, callback, traverseContext) {
var type = typeof children;
if (type === 'undefined' || type === 'boolean') {
// All of the above are perceived as null.
children = null;
}
if (children === null || type === 'string' || type === 'number' ||
// The following is inlined from ReactElement. This means we can optimize
// some checks. React Fiber also inlines this logic for similar purposes.
type === 'object' && children.$$typeof === REACT_ELEMENT_TYPE) {
callback(traverseContext, children,
// If it's the only child, treat the name as if it was wrapped in an array
// so that it's consistent if the number of children grows.
nameSoFar === '' ? SEPARATOR + getComponentKey(children, 0) : nameSoFar);
return 1;
}
var child;
var nextName;
var subtreeCount = 0; // Count of children found in the current subtree.
var nextNamePrefix = nameSoFar === '' ? SEPARATOR : nameSoFar + SUBSEPARATOR;
if (Array.isArray(children)) {
for (var i = 0; i < children.length; i++) {
child = children[i];
nextName = nextNamePrefix + getComponentKey(child, i);
subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext);
}
} else {
var iteratorFn = getIteratorFn(children);
if (iteratorFn) {
var iterator = iteratorFn.call(children);
var step;
if (iteratorFn !== children.entries) {
var ii = 0;
while (!(step = iterator.next()).done) {
child = step.value;
nextName = nextNamePrefix + getComponentKey(child, ii++);
subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext);
}
} else {
if (true) {
var mapsAsChildrenAddendum = '';
if (ReactCurrentOwner.current) {
var mapsAsChildrenOwnerName = ReactCurrentOwner.current.getName();
if (mapsAsChildrenOwnerName) {
mapsAsChildrenAddendum = ' Check the render method of `' + mapsAsChildrenOwnerName + '`.';
}
}
true ? warning(didWarnAboutMaps, 'Using Maps as children is not yet fully supported. It is an ' + 'experimental feature that might be removed. Convert it to a ' + 'sequence / iterable of keyed ReactElements instead.%s', mapsAsChildrenAddendum) : void 0;
didWarnAboutMaps = true;
}
// Iterator will provide entry [k,v] tuples rather than values.
while (!(step = iterator.next()).done) {
var entry = step.value;
if (entry) {
child = entry[1];
nextName = nextNamePrefix + KeyEscapeUtils.escape(entry[0]) + SUBSEPARATOR + getComponentKey(child, 0);
subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext);
}
}
}
} else if (type === 'object') {
var addendum = '';
if (true) {
addendum = ' If you meant to render a collection of children, use an array ' + 'instead or wrap the object using createFragment(object) from the ' + 'React add-ons.';
if (children._isReactElement) {
addendum = " It looks like you're using an element created by a different " + 'version of React. Make sure to use only one copy of React.';
}
if (ReactCurrentOwner.current) {
var name = ReactCurrentOwner.current.getName();
if (name) {
addendum += ' Check the render method of `' + name + '`.';
}
}
}
var childrenString = String(children);
true ? true ? invariant(false, 'Objects are not valid as a React child (found: %s).%s', childrenString === '[object Object]' ? 'object with keys {' + Object.keys(children).join(', ') + '}' : childrenString, addendum) : _prodInvariant('31', childrenString === '[object Object]' ? 'object with keys {' + Object.keys(children).join(', ') + '}' : childrenString, addendum) : void 0;
}
}
return subtreeCount;
}
/**
* Traverses children that are typically specified as `props.children`, but
* might also be specified through attributes:
*
* - `traverseAllChildren(this.props.children, ...)`
* - `traverseAllChildren(this.props.leftPanelChildren, ...)`
*
* The `traverseContext` is an optional argument that is passed through the
* entire traversal. It can be used to store accumulations or anything else that
* the callback might find relevant.
*
* @param {?*} children Children tree object.
* @param {!function} callback To invoke upon traversing each child.
* @param {?*} traverseContext Context for traversal.
* @return {!number} The number of children in this subtree.
*/
function traverseAllChildren(children, callback, traverseContext) {
if (children == null) {
return 0;
}
return traverseAllChildrenImpl(children, '', callback, traverseContext);
}
module.exports = traverseAllChildren;
/***/ }),
/* 79 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*/
var emptyFunction = __webpack_require__(8);
/**
* Upstream version of event listener. Does not take into account specific
* nature of platform.
*/
var EventListener = {
/**
* Listen to DOM events during the bubble phase.
*
* @param {DOMEventTarget} target DOM element to register listener on.
* @param {string} eventType Event type, e.g. 'click' or 'mouseover'.
* @param {function} callback Callback function.
* @return {object} Object with a `remove` method.
*/
listen: function listen(target, eventType, callback) {
if (target.addEventListener) {
target.addEventListener(eventType, callback, false);
return {
remove: function remove() {
target.removeEventListener(eventType, callback, false);
}
};
} else if (target.attachEvent) {
target.attachEvent('on' + eventType, callback);
return {
remove: function remove() {
target.detachEvent('on' + eventType, callback);
}
};
}
},
/**
* Listen to DOM events during the capture phase.
*
* @param {DOMEventTarget} target DOM element to register listener on.
* @param {string} eventType Event type, e.g. 'click' or 'mouseover'.
* @param {function} callback Callback function.
* @return {object} Object with a `remove` method.
*/
capture: function capture(target, eventType, callback) {
if (target.addEventListener) {
target.addEventListener(eventType, callback, true);
return {
remove: function remove() {
target.removeEventListener(eventType, callback, true);
}
};
} else {
if (true) {
console.error('Attempted to listen to events during the capture phase on a ' + 'browser that does not support the capture phase. Your application ' + 'will not receive some events.');
}
return {
remove: emptyFunction
};
}
},
registerDefault: function registerDefault() {}
};
module.exports = EventListener;
/***/ }),
/* 80 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var ReactDOMSelection = __webpack_require__(163);
var containsNode = __webpack_require__(165);
var focusNode = __webpack_require__(69);
var getActiveElement = __webpack_require__(81);
function isInDocument(node) {
return containsNode(document.documentElement, node);
}
/**
* @ReactInputSelection: React input selection module. Based on Selection.js,
* but modified to be suitable for react and has a couple of bug fixes (doesn't
* assume buttons have range selections allowed).
* Input selection module for React.
*/
var ReactInputSelection = {
hasSelectionCapabilities: function (elem) {
var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
return nodeName && (nodeName === 'input' && elem.type === 'text' || nodeName === 'textarea' || elem.contentEditable === 'true');
},
getSelectionInformation: function () {
var focusedElem = getActiveElement();
return {
focusedElem: focusedElem,
selectionRange: ReactInputSelection.hasSelectionCapabilities(focusedElem) ? ReactInputSelection.getSelection(focusedElem) : null
};
},
/**
* @restoreSelection: If any selection information was potentially lost,
* restore it. This is useful when performing operations that could remove dom
* nodes and place them back in, resulting in focus being lost.
*/
restoreSelection: function (priorSelectionInformation) {
var curFocusedElem = getActiveElement();
var priorFocusedElem = priorSelectionInformation.focusedElem;
var priorSelectionRange = priorSelectionInformation.selectionRange;
if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {
if (ReactInputSelection.hasSelectionCapabilities(priorFocusedElem)) {
ReactInputSelection.setSelection(priorFocusedElem, priorSelectionRange);
}
focusNode(priorFocusedElem);
}
},
/**
* @getSelection: Gets the selection bounds of a focused textarea, input or
* contentEditable node.
* -@input: Look up selection bounds of this input
* -@return {start: selectionStart, end: selectionEnd}
*/
getSelection: function (input) {
var selection;
if ('selectionStart' in input) {
// Modern browser with input or textarea.
selection = {
start: input.selectionStart,
end: input.selectionEnd
};
} else if (document.selection && input.nodeName && input.nodeName.toLowerCase() === 'input') {
// IE8 input.
var range = document.selection.createRange();
// There can only be one selection per document in IE, so it must
// be in our element.
if (range.parentElement() === input) {
selection = {
start: -range.moveStart('character', -input.value.length),
end: -range.moveEnd('character', -input.value.length)
};
}
} else {
// Content editable or old IE textarea.
selection = ReactDOMSelection.getOffsets(input);
}
return selection || { start: 0, end: 0 };
},
/**
* @setSelection: Sets the selection bounds of a textarea or input and focuses
* the input.
* -@input Set selection bounds of this input or textarea
* -@offsets Object of same form that is returned from get*
*/
setSelection: function (input, offsets) {
var start = offsets.start;
var end = offsets.end;
if (end === undefined) {
end = start;
}
if ('selectionStart' in input) {
input.selectionStart = start;
input.selectionEnd = Math.min(end, input.value.length);
} else if (document.selection && input.nodeName && input.nodeName.toLowerCase() === 'input') {
var range = input.createTextRange();
range.collapse(true);
range.moveStart('character', start);
range.moveEnd('character', end - start);
range.select();
} else {
ReactDOMSelection.setOffsets(input, offsets);
}
}
};
module.exports = ReactInputSelection;
/***/ }),
/* 81 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*/
/* eslint-disable fb-www/typeof-undefined */
/**
* Same as document.activeElement but wraps in a try-catch block. In IE it is
* not safe to call document.activeElement if there is nothing focused.
*
* The activeElement will be null only if the document or document body is not
* yet defined.
*
* @param {?DOMDocument} doc Defaults to current document.
* @return {?DOMElement}
*/
function getActiveElement(doc) /*?DOMElement*/{
doc = doc || (typeof document !== 'undefined' ? document : undefined);
if (typeof doc === 'undefined') {
return null;
}
try {
return doc.activeElement || doc.body;
} catch (e) {
return doc.body;
}
}
module.exports = getActiveElement;
/***/ }),
/* 82 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _prodInvariant = __webpack_require__(2);
var DOMLazyTree = __webpack_require__(19);
var DOMProperty = __webpack_require__(13);
var React = __webpack_require__(16);
var ReactBrowserEventEmitter = __webpack_require__(33);
var ReactCurrentOwner = __webpack_require__(9);
var ReactDOMComponentTree = __webpack_require__(4);
var ReactDOMContainerInfo = __webpack_require__(180);
var ReactDOMFeatureFlags = __webpack_require__(181);
var ReactFeatureFlags = __webpack_require__(64);
var ReactInstanceMap = __webpack_require__(23);
var ReactInstrumentation = __webpack_require__(7);
var ReactMarkupChecksum = __webpack_require__(182);
var ReactReconciler = __webpack_require__(18);
var ReactUpdateQueue = __webpack_require__(49);
var ReactUpdates = __webpack_require__(10);
var emptyObject = __webpack_require__(27);
var instantiateReactComponent = __webpack_require__(74);
var invariant = __webpack_require__(0);
var setInnerHTML = __webpack_require__(31);
var shouldUpdateReactComponent = __webpack_require__(47);
var warning = __webpack_require__(1);
var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME;
var ROOT_ATTR_NAME = DOMProperty.ROOT_ATTRIBUTE_NAME;
var ELEMENT_NODE_TYPE = 1;
var DOC_NODE_TYPE = 9;
var DOCUMENT_FRAGMENT_NODE_TYPE = 11;
var instancesByReactRootID = {};
/**
* Finds the index of the first character
* that's not common between the two given strings.
*
* @return {number} the index of the character where the strings diverge
*/
function firstDifferenceIndex(string1, string2) {
var minLen = Math.min(string1.length, string2.length);
for (var i = 0; i < minLen; i++) {
if (string1.charAt(i) !== string2.charAt(i)) {
return i;
}
}
return string1.length === string2.length ? -1 : minLen;
}
/**
* @param {DOMElement|DOMDocument} container DOM element that may contain
* a React component
* @return {?*} DOM element that may have the reactRoot ID, or null.
*/
function getReactRootElementInContainer(container) {
if (!container) {
return null;
}
if (container.nodeType === DOC_NODE_TYPE) {
return container.documentElement;
} else {
return container.firstChild;
}
}
function internalGetID(node) {
// If node is something like a window, document, or text node, none of
// which support attributes or a .getAttribute method, gracefully return
// the empty string, as if the attribute were missing.
return node.getAttribute && node.getAttribute(ATTR_NAME) || '';
}
/**
* Mounts this component and inserts it into the DOM.
*
* @param {ReactComponent} componentInstance The instance to mount.
* @param {DOMElement} container DOM element to mount into.
* @param {ReactReconcileTransaction} transaction
* @param {boolean} shouldReuseMarkup If true, do not insert markup
*/
function mountComponentIntoNode(wrapperInstance, container, transaction, shouldReuseMarkup, context) {
var markerName;
if (ReactFeatureFlags.logTopLevelRenders) {
var wrappedElement = wrapperInstance._currentElement.props.child;
var type = wrappedElement.type;
markerName = 'React mount: ' + (typeof type === 'string' ? type : type.displayName || type.name);
console.time(markerName);
}
var markup = ReactReconciler.mountComponent(wrapperInstance, transaction, null, ReactDOMContainerInfo(wrapperInstance, container), context, 0 /* parentDebugID */
);
if (markerName) {
console.timeEnd(markerName);
}
wrapperInstance._renderedComponent._topLevelWrapper = wrapperInstance;
ReactMount._mountImageIntoNode(markup, container, wrapperInstance, shouldReuseMarkup, transaction);
}
/**
* Batched mount.
*
* @param {ReactComponent} componentInstance The instance to mount.
* @param {DOMElement} container DOM element to mount into.
* @param {boolean} shouldReuseMarkup If true, do not insert markup
*/
function batchedMountComponentIntoNode(componentInstance, container, shouldReuseMarkup, context) {
var transaction = ReactUpdates.ReactReconcileTransaction.getPooled(
/* useCreateElement */
!shouldReuseMarkup && ReactDOMFeatureFlags.useCreateElement);
transaction.perform(mountComponentIntoNode, null, componentInstance, container, transaction, shouldReuseMarkup, context);
ReactUpdates.ReactReconcileTransaction.release(transaction);
}
/**
* Unmounts a component and removes it from the DOM.
*
* @param {ReactComponent} instance React component instance.
* @param {DOMElement} container DOM element to unmount from.
* @final
* @internal
* @see {ReactMount.unmountComponentAtNode}
*/
function unmountComponentFromNode(instance, container, safely) {
if (true) {
ReactInstrumentation.debugTool.onBeginFlush();
}
ReactReconciler.unmountComponent(instance, safely);
if (true) {
ReactInstrumentation.debugTool.onEndFlush();
}
if (container.nodeType === DOC_NODE_TYPE) {
container = container.documentElement;
}
// http://jsperf.com/emptying-a-node
while (container.lastChild) {
container.removeChild(container.lastChild);
}
}
/**
* True if the supplied DOM node has a direct React-rendered child that is
* not a React root element. Useful for warning in `render`,
* `unmountComponentAtNode`, etc.
*
* @param {?DOMElement} node The candidate DOM node.
* @return {boolean} True if the DOM element contains a direct child that was
* rendered by React but is not a root element.
* @internal
*/
function hasNonRootReactChild(container) {
var rootEl = getReactRootElementInContainer(container);
if (rootEl) {
var inst = ReactDOMComponentTree.getInstanceFromNode(rootEl);
return !!(inst && inst._hostParent);
}
}
/**
* True if the supplied DOM node is a React DOM element and
* it has been rendered by another copy of React.
*
* @param {?DOMElement} node The candidate DOM node.
* @return {boolean} True if the DOM has been rendered by another copy of React
* @internal
*/
function nodeIsRenderedByOtherInstance(container) {
var rootEl = getReactRootElementInContainer(container);
return !!(rootEl && isReactNode(rootEl) && !ReactDOMComponentTree.getInstanceFromNode(rootEl));
}
/**
* True if the supplied DOM node is a valid node element.
*
* @param {?DOMElement} node The candidate DOM node.
* @return {boolean} True if the DOM is a valid DOM node.
* @internal
*/
function isValidContainer(node) {
return !!(node && (node.nodeType === ELEMENT_NODE_TYPE || node.nodeType === DOC_NODE_TYPE || node.nodeType === DOCUMENT_FRAGMENT_NODE_TYPE));
}
/**
* True if the supplied DOM node is a valid React node element.
*
* @param {?DOMElement} node The candidate DOM node.
* @return {boolean} True if the DOM is a valid React DOM node.
* @internal
*/
function isReactNode(node) {
return isValidContainer(node) && (node.hasAttribute(ROOT_ATTR_NAME) || node.hasAttribute(ATTR_NAME));
}
function getHostRootInstanceInContainer(container) {
var rootEl = getReactRootElementInContainer(container);
var prevHostInstance = rootEl && ReactDOMComponentTree.getInstanceFromNode(rootEl);
return prevHostInstance && !prevHostInstance._hostParent ? prevHostInstance : null;
}
function getTopLevelWrapperInContainer(container) {
var root = getHostRootInstanceInContainer(container);
return root ? root._hostContainerInfo._topLevelWrapper : null;
}
/**
* Temporary (?) hack so that we can store all top-level pending updates on
* composites instead of having to worry about different types of components
* here.
*/
var topLevelRootCounter = 1;
var TopLevelWrapper = function () {
this.rootID = topLevelRootCounter++;
};
TopLevelWrapper.prototype.isReactComponent = {};
if (true) {
TopLevelWrapper.displayName = 'TopLevelWrapper';
}
TopLevelWrapper.prototype.render = function () {
return this.props.child;
};
TopLevelWrapper.isReactTopLevelWrapper = true;
/**
* Mounting is the process of initializing a React component by creating its
* representative DOM elements and inserting them into a supplied `container`.
* Any prior content inside `container` is destroyed in the process.
*
* ReactMount.render(
* component,
* document.getElementById('container')
* );
*
* <div id="container"> <-- Supplied `container`.
* <div data-reactid=".3"> <-- Rendered reactRoot of React
* // ... component.
* </div>
* </div>
*
* Inside of `container`, the first element rendered is the "reactRoot".
*/
var ReactMount = {
TopLevelWrapper: TopLevelWrapper,
/**
* Used by devtools. The keys are not important.
*/
_instancesByReactRootID: instancesByReactRootID,
/**
* This is a hook provided to support rendering React components while
* ensuring that the apparent scroll position of its `container` does not
* change.
*
* @param {DOMElement} container The `container` being rendered into.
* @param {function} renderCallback This must be called once to do the render.
*/
scrollMonitor: function (container, renderCallback) {
renderCallback();
},
/**
* Take a component that's already mounted into the DOM and replace its props
* @param {ReactComponent} prevComponent component instance already in the DOM
* @param {ReactElement} nextElement component instance to render
* @param {DOMElement} container container to render into
* @param {?function} callback function triggered on completion
*/
_updateRootComponent: function (prevComponent, nextElement, nextContext, container, callback) {
ReactMount.scrollMonitor(container, function () {
ReactUpdateQueue.enqueueElementInternal(prevComponent, nextElement, nextContext);
if (callback) {
ReactUpdateQueue.enqueueCallbackInternal(prevComponent, callback);
}
});
return prevComponent;
},
/**
* Render a new component into the DOM. Hooked by hooks!
*
* @param {ReactElement} nextElement element to render
* @param {DOMElement} container container to render into
* @param {boolean} shouldReuseMarkup if we should skip the markup insertion
* @return {ReactComponent} nextComponent
*/
_renderNewRootComponent: function (nextElement, container, shouldReuseMarkup, context) {
// Various parts of our code (such as ReactCompositeComponent's
// _renderValidatedComponent) assume that calls to render aren't nested;
// verify that that's the case.
true ? warning(ReactCurrentOwner.current == null, '_renderNewRootComponent(): Render methods should be a pure function ' + 'of props and state; triggering nested component updates from ' + 'render is not allowed. If necessary, trigger nested updates in ' + 'componentDidUpdate. Check the render method of %s.', ReactCurrentOwner.current && ReactCurrentOwner.current.getName() || 'ReactCompositeComponent') : void 0;
!isValidContainer(container) ? true ? invariant(false, '_registerComponent(...): Target container is not a DOM element.') : _prodInvariant('37') : void 0;
ReactBrowserEventEmitter.ensureScrollValueMonitoring();
var componentInstance = instantiateReactComponent(nextElement, false);
// The initial render is synchronous but any updates that happen during
// rendering, in componentWillMount or componentDidMount, will be batched
// according to the current batching strategy.
ReactUpdates.batchedUpdates(batchedMountComponentIntoNode, componentInstance, container, shouldReuseMarkup, context);
var wrapperID = componentInstance._instance.rootID;
instancesByReactRootID[wrapperID] = componentInstance;
return componentInstance;
},
/**
* Renders a React component into the DOM in the supplied `container`.
*
* If the React component was previously rendered into `container`, this will
* perform an update on it and only mutate the DOM as necessary to reflect the
* latest React component.
*
* @param {ReactComponent} parentComponent The conceptual parent of this render tree.
* @param {ReactElement} nextElement Component element to render.
* @param {DOMElement} container DOM element to render into.
* @param {?function} callback function triggered on completion
* @return {ReactComponent} Component instance rendered in `container`.
*/
renderSubtreeIntoContainer: function (parentComponent, nextElement, container, callback) {
!(parentComponent != null && ReactInstanceMap.has(parentComponent)) ? true ? invariant(false, 'parentComponent must be a valid React Component') : _prodInvariant('38') : void 0;
return ReactMount._renderSubtreeIntoContainer(parentComponent, nextElement, container, callback);
},
_renderSubtreeIntoContainer: function (parentComponent, nextElement, container, callback) {
ReactUpdateQueue.validateCallback(callback, 'ReactDOM.render');
!React.isValidElement(nextElement) ? true ? invariant(false, 'ReactDOM.render(): Invalid component element.%s', typeof nextElement === 'string' ? " Instead of passing a string like 'div', pass " + "React.createElement('div') or <div />." : typeof nextElement === 'function' ? ' Instead of passing a class like Foo, pass ' + 'React.createElement(Foo) or <Foo />.' : // Check if it quacks like an element
nextElement != null && nextElement.props !== undefined ? ' This may be caused by unintentionally loading two independent ' + 'copies of React.' : '') : _prodInvariant('39', typeof nextElement === 'string' ? " Instead of passing a string like 'div', pass " + "React.createElement('div') or <div />." : typeof nextElement === 'function' ? ' Instead of passing a class like Foo, pass ' + 'React.createElement(Foo) or <Foo />.' : nextElement != null && nextElement.props !== undefined ? ' This may be caused by unintentionally loading two independent ' + 'copies of React.' : '') : void 0;
true ? warning(!container || !container.tagName || container.tagName.toUpperCase() !== 'BODY', 'render(): Rendering components directly into document.body is ' + 'discouraged, since its children are often manipulated by third-party ' + 'scripts and browser extensions. This may lead to subtle ' + 'reconciliation issues. Try rendering into a container element created ' + 'for your app.') : void 0;
var nextWrappedElement = React.createElement(TopLevelWrapper, {
child: nextElement
});
var nextContext;
if (parentComponent) {
var parentInst = ReactInstanceMap.get(parentComponent);
nextContext = parentInst._processChildContext(parentInst._context);
} else {
nextContext = emptyObject;
}
var prevComponent = getTopLevelWrapperInContainer(container);
if (prevComponent) {
var prevWrappedElement = prevComponent._currentElement;
var prevElement = prevWrappedElement.props.child;
if (shouldUpdateReactComponent(prevElement, nextElement)) {
var publicInst = prevComponent._renderedComponent.getPublicInstance();
var updatedCallback = callback && function () {
callback.call(publicInst);
};
ReactMount._updateRootComponent(prevComponent, nextWrappedElement, nextContext, container, updatedCallback);
return publicInst;
} else {
ReactMount.unmountComponentAtNode(container);
}
}
var reactRootElement = getReactRootElementInContainer(container);
var containerHasReactMarkup = reactRootElement && !!internalGetID(reactRootElement);
var containerHasNonRootReactChild = hasNonRootReactChild(container);
if (true) {
true ? warning(!containerHasNonRootReactChild, 'render(...): Replacing React-rendered children with a new root ' + 'component. If you intended to update the children of this node, ' + 'you should instead have the existing children update their state ' + 'and render the new components instead of calling ReactDOM.render.') : void 0;
if (!containerHasReactMarkup || reactRootElement.nextSibling) {
var rootElementSibling = reactRootElement;
while (rootElementSibling) {
if (internalGetID(rootElementSibling)) {
true ? warning(false, 'render(): Target node has markup rendered by React, but there ' + 'are unrelated nodes as well. This is most commonly caused by ' + 'white-space inserted around server-rendered markup.') : void 0;
break;
}
rootElementSibling = rootElementSibling.nextSibling;
}
}
}
var shouldReuseMarkup = containerHasReactMarkup && !prevComponent && !containerHasNonRootReactChild;
var component = ReactMount._renderNewRootComponent(nextWrappedElement, container, shouldReuseMarkup, nextContext)._renderedComponent.getPublicInstance();
if (callback) {
callback.call(component);
}
return component;
},
/**
* Renders a React component into the DOM in the supplied `container`.
* See https://facebook.github.io/react/docs/top-level-api.html#reactdom.render
*
* If the React component was previously rendered into `container`, this will
* perform an update on it and only mutate the DOM as necessary to reflect the
* latest React component.
*
* @param {ReactElement} nextElement Component element to render.
* @param {DOMElement} container DOM element to render into.
* @param {?function} callback function triggered on completion
* @return {ReactComponent} Component instance rendered in `container`.
*/
render: function (nextElement, container, callback) {
return ReactMount._renderSubtreeIntoContainer(null, nextElement, container, callback);
},
/**
* Unmounts and destroys the React component rendered in the `container`.
* See https://facebook.github.io/react/docs/top-level-api.html#reactdom.unmountcomponentatnode
*
* @param {DOMElement} container DOM element containing a React component.
* @return {boolean} True if a component was found in and unmounted from
* `container`
*/
unmountComponentAtNode: function (container) {
// Various parts of our code (such as ReactCompositeComponent's
// _renderValidatedComponent) assume that calls to render aren't nested;
// verify that that's the case. (Strictly speaking, unmounting won't cause a
// render but we still don't expect to be in a render call here.)
true ? warning(ReactCurrentOwner.current == null, 'unmountComponentAtNode(): Render methods should be a pure function ' + 'of props and state; triggering nested component updates from render ' + 'is not allowed. If necessary, trigger nested updates in ' + 'componentDidUpdate. Check the render method of %s.', ReactCurrentOwner.current && ReactCurrentOwner.current.getName() || 'ReactCompositeComponent') : void 0;
!isValidContainer(container) ? true ? invariant(false, 'unmountComponentAtNode(...): Target container is not a DOM element.') : _prodInvariant('40') : void 0;
if (true) {
true ? warning(!nodeIsRenderedByOtherInstance(container), "unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.') : void 0;
}
var prevComponent = getTopLevelWrapperInContainer(container);
if (!prevComponent) {
// Check if the node being unmounted was rendered by React, but isn't a
// root node.
var containerHasNonRootReactChild = hasNonRootReactChild(container);
// Check if the container itself is a React root node.
var isContainerReactRoot = container.nodeType === 1 && container.hasAttribute(ROOT_ATTR_NAME);
if (true) {
true ? warning(!containerHasNonRootReactChild, "unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by React and is not a top-level container. %s', isContainerReactRoot ? 'You may have accidentally passed in a React root node instead ' + 'of its container.' : 'Instead, have the parent component update its state and ' + 'rerender in order to remove this component.') : void 0;
}
return false;
}
delete instancesByReactRootID[prevComponent._instance.rootID];
ReactUpdates.batchedUpdates(unmountComponentFromNode, prevComponent, container, false);
return true;
},
_mountImageIntoNode: function (markup, container, instance, shouldReuseMarkup, transaction) {
!isValidContainer(container) ? true ? invariant(false, 'mountComponentIntoNode(...): Target container is not valid.') : _prodInvariant('41') : void 0;
if (shouldReuseMarkup) {
var rootElement = getReactRootElementInContainer(container);
if (ReactMarkupChecksum.canReuseMarkup(markup, rootElement)) {
ReactDOMComponentTree.precacheNode(instance, rootElement);
return;
} else {
var checksum = rootElement.getAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME);
rootElement.removeAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME);
var rootMarkup = rootElement.outerHTML;
rootElement.setAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME, checksum);
var normalizedMarkup = markup;
if (true) {
// because rootMarkup is retrieved from the DOM, various normalizations
// will have occurred which will not be present in `markup`. Here,
// insert markup into a <div> or <iframe> depending on the container
// type to perform the same normalizations before comparing.
var normalizer;
if (container.nodeType === ELEMENT_NODE_TYPE) {
normalizer = document.createElement('div');
normalizer.innerHTML = markup;
normalizedMarkup = normalizer.innerHTML;
} else {
normalizer = document.createElement('iframe');
document.body.appendChild(normalizer);
normalizer.contentDocument.write(markup);
normalizedMarkup = normalizer.contentDocument.documentElement.outerHTML;
document.body.removeChild(normalizer);
}
}
var diffIndex = firstDifferenceIndex(normalizedMarkup, rootMarkup);
var difference = ' (client) ' + normalizedMarkup.substring(diffIndex - 20, diffIndex + 20) + '\n (server) ' + rootMarkup.substring(diffIndex - 20, diffIndex + 20);
!(container.nodeType !== DOC_NODE_TYPE) ? true ? invariant(false, 'You\'re trying to render a component to the document using server rendering but the checksum was invalid. This usually means you rendered a different component type or props on the client from the one on the server, or your render() methods are impure. React cannot handle this case due to cross-browser quirks by rendering at the document root. You should look for environment dependent code in your components and ensure the props are the same client and server side:\n%s', difference) : _prodInvariant('42', difference) : void 0;
if (true) {
true ? warning(false, 'React attempted to reuse markup in a container but the ' + 'checksum was invalid. This generally means that you are ' + 'using server rendering and the markup generated on the ' + 'server was not what the client was expecting. React injected ' + 'new markup to compensate which works but you have lost many ' + 'of the benefits of server rendering. Instead, figure out ' + 'why the markup being generated is different on the client ' + 'or server:\n%s', difference) : void 0;
}
}
}
!(container.nodeType !== DOC_NODE_TYPE) ? true ? invariant(false, 'You\'re trying to render a component to the document but you didn\'t use server rendering. We can\'t do this without using server rendering due to cross-browser quirks. See ReactDOMServer.renderToString() for server rendering.') : _prodInvariant('43') : void 0;
if (transaction.useCreateElement) {
while (container.lastChild) {
container.removeChild(container.lastChild);
}
DOMLazyTree.insertTreeBefore(container, markup, null);
} else {
setInnerHTML(container, markup);
ReactDOMComponentTree.precacheNode(instance, container.firstChild);
}
if (true) {
var hostNode = ReactDOMComponentTree.getInstanceFromNode(container.firstChild);
if (hostNode._debugID !== 0) {
ReactInstrumentation.debugTool.onHostOperation({
instanceID: hostNode._debugID,
type: 'mount',
payload: markup.toString()
});
}
}
}
};
module.exports = ReactMount;
/***/ }),
/* 83 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var ReactNodeTypes = __webpack_require__(75);
function getHostComponentFromComposite(inst) {
var type;
while ((type = inst._renderedNodeType) === ReactNodeTypes.COMPOSITE) {
inst = inst._renderedComponent;
}
if (type === ReactNodeTypes.HOST) {
return inst._renderedComponent;
} else if (type === ReactNodeTypes.EMPTY) {
return null;
}
}
module.exports = getHostComponentFromComposite;
/***/ }),
/* 84 */
/***/ (function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
Copyright (c) 2016 Jed Watson.
Licensed under the MIT License (MIT), see
http://jedwatson.github.io/classnames
*/
/* global define */
(function () {
'use strict';
var hasOwn = {}.hasOwnProperty;
function classNames () {
var classes = [];
for (var i = 0; i < arguments.length; i++) {
var arg = arguments[i];
if (!arg) continue;
var argType = typeof arg;
if (argType === 'string' || argType === 'number') {
classes.push(arg);
} else if (Array.isArray(arg)) {
classes.push(classNames.apply(null, arg));
} else if (argType === 'object') {
for (var key in arg) {
if (hasOwn.call(arg, key) && arg[key]) {
classes.push(key);
}
}
}
}
return classes.join(' ');
}
if (typeof module !== 'undefined' && module.exports) {
module.exports = classNames;
} else if (true) {
// register as 'classnames', consistent with npm package name
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function () {
return classNames;
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
} else {
window.classNames = classNames;
}
}());
/***/ }),
/* 85 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var emptyFunction = __webpack_require__(8);
var invariant = __webpack_require__(0);
var warning = __webpack_require__(1);
var assign = __webpack_require__(3);
var ReactPropTypesSecret = __webpack_require__(58);
var checkPropTypes = __webpack_require__(99);
module.exports = function(isValidElement, throwOnDirectAccess) {
/* global Symbol */
var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec.
/**
* Returns the iterator method function contained on the iterable object.
*
* Be sure to invoke the function with the iterable as context:
*
* var iteratorFn = getIteratorFn(myIterable);
* if (iteratorFn) {
* var iterator = iteratorFn.call(myIterable);
* ...
* }
*
* @param {?object} maybeIterable
* @return {?function}
*/
function getIteratorFn(maybeIterable) {
var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]);
if (typeof iteratorFn === 'function') {
return iteratorFn;
}
}
/**
* Collection of methods that allow declaration and validation of props that are
* supplied to React components. Example usage:
*
* var Props = require('ReactPropTypes');
* var MyArticle = React.createClass({
* propTypes: {
* // An optional string prop named "description".
* description: Props.string,
*
* // A required enum prop named "category".
* category: Props.oneOf(['News','Photos']).isRequired,
*
* // A prop named "dialog" that requires an instance of Dialog.
* dialog: Props.instanceOf(Dialog).isRequired
* },
* render: function() { ... }
* });
*
* A more formal specification of how these methods are used:
*
* type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...)
* decl := ReactPropTypes.{type}(.isRequired)?
*
* Each and every declaration produces a function with the same signature. This
* allows the creation of custom validation functions. For example:
*
* var MyLink = React.createClass({
* propTypes: {
* // An optional string or URI prop named "href".
* href: function(props, propName, componentName) {
* var propValue = props[propName];
* if (propValue != null && typeof propValue !== 'string' &&
* !(propValue instanceof URI)) {
* return new Error(
* 'Expected a string or an URI for ' + propName + ' in ' +
* componentName
* );
* }
* }
* },
* render: function() {...}
* });
*
* @internal
*/
var ANONYMOUS = '<<anonymous>>';
// Important!
// Keep this list in sync with production version in `./factoryWithThrowingShims.js`.
var ReactPropTypes = {
array: createPrimitiveTypeChecker('array'),
bool: createPrimitiveTypeChecker('boolean'),
func: createPrimitiveTypeChecker('function'),
number: createPrimitiveTypeChecker('number'),
object: createPrimitiveTypeChecker('object'),
string: createPrimitiveTypeChecker('string'),
symbol: createPrimitiveTypeChecker('symbol'),
any: createAnyTypeChecker(),
arrayOf: createArrayOfTypeChecker,
element: createElementTypeChecker(),
instanceOf: createInstanceTypeChecker,
node: createNodeChecker(),
objectOf: createObjectOfTypeChecker,
oneOf: createEnumTypeChecker,
oneOfType: createUnionTypeChecker,
shape: createShapeTypeChecker,
exact: createStrictShapeTypeChecker,
};
/**
* inlined Object.is polyfill to avoid requiring consumers ship their own
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
*/
/*eslint-disable no-self-compare*/
function is(x, y) {
// SameValue algorithm
if (x === y) {
// Steps 1-5, 7-10
// Steps 6.b-6.e: +0 != -0
return x !== 0 || 1 / x === 1 / y;
} else {
// Step 6.a: NaN == NaN
return x !== x && y !== y;
}
}
/*eslint-enable no-self-compare*/
/**
* We use an Error-like object for backward compatibility as people may call
* PropTypes directly and inspect their output. However, we don't use real
* Errors anymore. We don't inspect their stack anyway, and creating them
* is prohibitively expensive if they are created too often, such as what
* happens in oneOfType() for any type before the one that matched.
*/
function PropTypeError(message) {
this.message = message;
this.stack = '';
}
// Make `instanceof Error` still work for returned errors.
PropTypeError.prototype = Error.prototype;
function createChainableTypeChecker(validate) {
if (true) {
var manualPropTypeCallCache = {};
var manualPropTypeWarningCount = 0;
}
function checkType(isRequired, props, propName, componentName, location, propFullName, secret) {
componentName = componentName || ANONYMOUS;
propFullName = propFullName || propName;
if (secret !== ReactPropTypesSecret) {
if (throwOnDirectAccess) {
// New behavior only for users of `prop-types` package
invariant(
false,
'Calling PropTypes validators directly is not supported by the `prop-types` package. ' +
'Use `PropTypes.checkPropTypes()` to call them. ' +
'Read more at http://fb.me/use-check-prop-types'
);
} else if ("test" !== 'production' && typeof console !== 'undefined') {
// Old behavior for people using React.PropTypes
var cacheKey = componentName + ':' + propName;
if (
!manualPropTypeCallCache[cacheKey] &&
// Avoid spamming the console because they are often not actionable except for lib authors
manualPropTypeWarningCount < 3
) {
warning(
false,
'You are manually calling a React.PropTypes validation ' +
'function for the `%s` prop on `%s`. This is deprecated ' +
'and will throw in the standalone `prop-types` package. ' +
'You may be seeing this warning due to a third-party PropTypes ' +
'library. See https://fb.me/react-warning-dont-call-proptypes ' + 'for details.',
propFullName,
componentName
);
manualPropTypeCallCache[cacheKey] = true;
manualPropTypeWarningCount++;
}
}
}
if (props[propName] == null) {
if (isRequired) {
if (props[propName] === null) {
return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required ' + ('in `' + componentName + '`, but its value is `null`.'));
}
return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required in ' + ('`' + componentName + '`, but its value is `undefined`.'));
}
return null;
} else {
return validate(props, propName, componentName, location, propFullName);
}
}
var chainedCheckType = checkType.bind(null, false);
chainedCheckType.isRequired = checkType.bind(null, true);
return chainedCheckType;
}
function createPrimitiveTypeChecker(expectedType) {
function validate(props, propName, componentName, location, propFullName, secret) {
var propValue = props[propName];
var propType = getPropType(propValue);
if (propType !== expectedType) {
// `propValue` being instance of, say, date/regexp, pass the 'object'
// check, but we can offer a more precise error message here rather than
// 'of type `object`'.
var preciseType = getPreciseType(propValue);
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + preciseType + '` supplied to `' + componentName + '`, expected ') + ('`' + expectedType + '`.'));
}
return null;
}
return createChainableTypeChecker(validate);
}
function createAnyTypeChecker() {
return createChainableTypeChecker(emptyFunction.thatReturnsNull);
}
function createArrayOfTypeChecker(typeChecker) {
function validate(props, propName, componentName, location, propFullName) {
if (typeof typeChecker !== 'function') {
return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside arrayOf.');
}
var propValue = props[propName];
if (!Array.isArray(propValue)) {
var propType = getPropType(propValue);
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an array.'));
}
for (var i = 0; i < propValue.length; i++) {
var error = typeChecker(propValue, i, componentName, location, propFullName + '[' + i + ']', ReactPropTypesSecret);
if (error instanceof Error) {
return error;
}
}
return null;
}
return createChainableTypeChecker(validate);
}
function createElementTypeChecker() {
function validate(props, propName, componentName, location, propFullName) {
var propValue = props[propName];
if (!isValidElement(propValue)) {
var propType = getPropType(propValue);
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement.'));
}
return null;
}
return createChainableTypeChecker(validate);
}
function createInstanceTypeChecker(expectedClass) {
function validate(props, propName, componentName, location, propFullName) {
if (!(props[propName] instanceof expectedClass)) {
var expectedClassName = expectedClass.name || ANONYMOUS;
var actualClassName = getClassName(props[propName]);
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + actualClassName + '` supplied to `' + componentName + '`, expected ') + ('instance of `' + expectedClassName + '`.'));
}
return null;
}
return createChainableTypeChecker(validate);
}
function createEnumTypeChecker(expectedValues) {
if (!Array.isArray(expectedValues)) {
true ? warning(false, 'Invalid argument supplied to oneOf, expected an instance of array.') : void 0;
return emptyFunction.thatReturnsNull;
}
function validate(props, propName, componentName, location, propFullName) {
var propValue = props[propName];
for (var i = 0; i < expectedValues.length; i++) {
if (is(propValue, expectedValues[i])) {
return null;
}
}
var valuesString = JSON.stringify(expectedValues);
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of value `' + propValue + '` ' + ('supplied to `' + componentName + '`, expected one of ' + valuesString + '.'));
}
return createChainableTypeChecker(validate);
}
function createObjectOfTypeChecker(typeChecker) {
function validate(props, propName, componentName, location, propFullName) {
if (typeof typeChecker !== 'function') {
return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside objectOf.');
}
var propValue = props[propName];
var propType = getPropType(propValue);
if (propType !== 'object') {
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an object.'));
}
for (var key in propValue) {
if (propValue.hasOwnProperty(key)) {
var error = typeChecker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret);
if (error instanceof Error) {
return error;
}
}
}
return null;
}
return createChainableTypeChecker(validate);
}
function createUnionTypeChecker(arrayOfTypeCheckers) {
if (!Array.isArray(arrayOfTypeCheckers)) {
true ? warning(false, 'Invalid argument supplied to oneOfType, expected an instance of array.') : void 0;
return emptyFunction.thatReturnsNull;
}
for (var i = 0; i < arrayOfTypeCheckers.length; i++) {
var checker = arrayOfTypeCheckers[i];
if (typeof checker !== 'function') {
warning(
false,
'Invalid argument supplied to oneOfType. Expected an array of check functions, but ' +
'received %s at index %s.',
getPostfixForTypeWarning(checker),
i
);
return emptyFunction.thatReturnsNull;
}
}
function validate(props, propName, componentName, location, propFullName) {
for (var i = 0; i < arrayOfTypeCheckers.length; i++) {
var checker = arrayOfTypeCheckers[i];
if (checker(props, propName, componentName, location, propFullName, ReactPropTypesSecret) == null) {
return null;
}
}
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`.'));
}
return createChainableTypeChecker(validate);
}
function createNodeChecker() {
function validate(props, propName, componentName, location, propFullName) {
if (!isNode(props[propName])) {
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a ReactNode.'));
}
return null;
}
return createChainableTypeChecker(validate);
}
function createShapeTypeChecker(shapeTypes) {
function validate(props, propName, componentName, location, propFullName) {
var propValue = props[propName];
var propType = getPropType(propValue);
if (propType !== 'object') {
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.'));
}
for (var key in shapeTypes) {
var checker = shapeTypes[key];
if (!checker) {
continue;
}
var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret);
if (error) {
return error;
}
}
return null;
}
return createChainableTypeChecker(validate);
}
function createStrictShapeTypeChecker(shapeTypes) {
function validate(props, propName, componentName, location, propFullName) {
var propValue = props[propName];
var propType = getPropType(propValue);
if (propType !== 'object') {
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.'));
}
// We need to check all keys in case some are required but missing from
// props.
var allKeys = assign({}, props[propName], shapeTypes);
for (var key in allKeys) {
var checker = shapeTypes[key];
if (!checker) {
return new PropTypeError(
'Invalid ' + location + ' `' + propFullName + '` key `' + key + '` supplied to `' + componentName + '`.' +
'\nBad object: ' + JSON.stringify(props[propName], null, ' ') +
'\nValid keys: ' + JSON.stringify(Object.keys(shapeTypes), null, ' ')
);
}
var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret);
if (error) {
return error;
}
}
return null;
}
return createChainableTypeChecker(validate);
}
function isNode(propValue) {
switch (typeof propValue) {
case 'number':
case 'string':
case 'undefined':
return true;
case 'boolean':
return !propValue;
case 'object':
if (Array.isArray(propValue)) {
return propValue.every(isNode);
}
if (propValue === null || isValidElement(propValue)) {
return true;
}
var iteratorFn = getIteratorFn(propValue);
if (iteratorFn) {
var iterator = iteratorFn.call(propValue);
var step;
if (iteratorFn !== propValue.entries) {
while (!(step = iterator.next()).done) {
if (!isNode(step.value)) {
return false;
}
}
} else {
// Iterator will provide entry [k,v] tuples rather than values.
while (!(step = iterator.next()).done) {
var entry = step.value;
if (entry) {
if (!isNode(entry[1])) {
return false;
}
}
}
}
} else {
return false;
}
return true;
default:
return false;
}
}
function isSymbol(propType, propValue) {
// Native Symbol.
if (propType === 'symbol') {
return true;
}
// 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol'
if (propValue['@@toStringTag'] === 'Symbol') {
return true;
}
// Fallback for non-spec compliant Symbols which are polyfilled.
if (typeof Symbol === 'function' && propValue instanceof Symbol) {
return true;
}
return false;
}
// Equivalent of `typeof` but with special handling for array and regexp.
function getPropType(propValue) {
var propType = typeof propValue;
if (Array.isArray(propValue)) {
return 'array';
}
if (propValue instanceof RegExp) {
// Old webkits (at least until Android 4.0) return 'function' rather than
// 'object' for typeof a RegExp. We'll normalize this here so that /bla/
// passes PropTypes.object.
return 'object';
}
if (isSymbol(propType, propValue)) {
return 'symbol';
}
return propType;
}
// This handles more types than `getPropType`. Only used for error messages.
// See `createPrimitiveTypeChecker`.
function getPreciseType(propValue) {
if (typeof propValue === 'undefined' || propValue === null) {
return '' + propValue;
}
var propType = getPropType(propValue);
if (propType === 'object') {
if (propValue instanceof Date) {
return 'date';
} else if (propValue instanceof RegExp) {
return 'regexp';
}
}
return propType;
}
// Returns a string that is postfixed to a warning about an invalid type.
// For example, "undefined" or "of type array"
function getPostfixForTypeWarning(value) {
var type = getPreciseType(value);
switch (type) {
case 'array':
case 'object':
return 'an ' + type;
case 'boolean':
case 'date':
case 'regexp':
return 'a ' + type;
default:
return type;
}
}
// Returns class name of the object, if any.
function getClassName(propValue) {
if (!propValue.constructor || !propValue.constructor.name) {
return ANONYMOUS;
}
return propValue.constructor.name;
}
ReactPropTypes.checkPropTypes = checkPropTypes;
ReactPropTypes.PropTypes = ReactPropTypes;
return ReactPropTypes;
};
/***/ }),
/* 86 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.SoundOffIcon = exports.SoundOnIcon = exports.NextIcon = exports.PreviousIcon = exports.PauseIcon = exports.PlayIcon = undefined;
var _react = __webpack_require__(11);
var _react2 = _interopRequireDefault(_react);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Play
*/
var PlayIcon = exports.PlayIcon = function PlayIcon() {
return _react2.default.createElement(
"svg",
{ className: "Icon PlayIcon", viewBox: "0 0 100 100" },
_react2.default.createElement("polygon", { className: "Icon-shape", points: "24 92 24 7 100 49.4955227" })
);
};
/**
* Pause
*/
var PauseIcon = exports.PauseIcon = function PauseIcon() {
return _react2.default.createElement(
"svg",
{ className: "Icon PauseIcon", viewBox: "0 0 100 100" },
_react2.default.createElement(
"g",
{ className: "Icon-group" },
_react2.default.createElement("rect", { className: "Icon-shape", x: "58", y: "11", width: "21", height: "78" }),
_react2.default.createElement("rect", { className: "Icon-shape", x: "22", y: "11", width: "21", height: "78" })
)
);
};
/**
* Previous
*/
var PreviousIcon = exports.PreviousIcon = function PreviousIcon() {
return _react2.default.createElement(
"svg",
{ className: "Icon PreviousIcon", viewBox: "0 0 100 100" },
_react2.default.createElement("polygon", { className: "Icon-shape", points: "85 12.6092632 27.3529412 44.5358947 27.3529412 11 15 11 15 89 27.3529412 89 27.3529412 54.368 85 86.3028421" })
);
};
/**
* Next
*/
var NextIcon = exports.NextIcon = function NextIcon() {
return _react2.default.createElement(
"svg",
{ className: "Icon NextIcon", viewBox: "0 0 100 100" },
_react2.default.createElement("polygon", { className: "Icon-shape", points: "72.6470588 11 72.6470588 44.1141176 15 12.0911765 15 85.9988235 72.6470588 53.9717647 72.6470588 89.2352941 85 89.2352941 85 11" })
);
};
/**
* Sound on
*/
var SoundOnIcon = exports.SoundOnIcon = function SoundOnIcon() {
return _react2.default.createElement(
"svg",
{ className: "Icon SoundOnIcon", viewBox: "0 0 100 100" },
_react2.default.createElement(
"g",
{ className: "Icon-shape" },
_react2.default.createElement("path", { d: "M28.0748663,36.3636364 L0,36.3636364 L0,65.9090909 L30.4812834,65.9090909 L54.5454545,88.6363636 L54.5454545,11.3636364 L28.0748663,36.3636364 Z" }),
_react2.default.createElement("path", { d: "M84.6032335,82.4592965 C94.5340754,74.7600841 100.468182,62.9599381 100.468182,50.1791986 C100.468182,38.1777252 95.2347685,27.0146095 86.3177905,19.2913999 L80.3660059,26.1631456 C87.313543,32.1805749 91.3772727,40.8487007 91.3772727,50.1791986 C91.3772727,60.1143215 86.7696647,69.2766862 79.0331302,75.2746895 L84.6032335,82.4592965 L84.6032335,82.4592965 Z" }),
_react2.default.createElement("path", { d: "M68.6941426,71.5946428 C75.48494,66.3298533 79.5454545,58.2554001 79.5454545,49.5119787 C79.5454545,41.3018627 75.9644339,33.663378 69.8670756,28.382309 L63.9152911,35.2540546 C68.0432084,38.8293434 70.4545455,43.9728382 70.4545455,49.5119787 C70.4545455,55.4097835 67.7205293,60.8464555 63.1240393,64.4100358 L68.6941426,71.5946428 L68.6941426,71.5946428 Z" })
)
);
};
var SoundOffIcon = exports.SoundOffIcon = function SoundOffIcon() {
return _react2.default.createElement(
"svg",
{ className: "Icon SoundOffIcon", viewBox: "0 0 100 100" },
_react2.default.createElement(
"g",
{ className: "Icon-shape" },
_react2.default.createElement("path", { d: "M28.0748663,36.3636364 L0,36.3636364 L0,65.9090909 L30.4812834,65.9090909 L54.5454545,88.6363636 L54.5454545,11.3636364 L28.0748663,36.3636364 Z" }),
_react2.default.createElement("polygon", { points: "69.513151 44.1232126 87.6949692 62.3050308 90.9090909 65.5191526 97.3373344 59.0909091 94.1232126 55.8767874 75.9413945 37.6949692 72.7272727 34.4808474 66.2990293 40.9090909" }),
_react2.default.createElement("polygon", { points: "75.9413945 62.3050308 94.1232126 44.1232126 97.3373344 40.9090909 90.9090909 34.4808474 87.6949692 37.6949692 69.513151 55.8767874 66.2990293 59.0909091 72.7272727 65.5191526" })
)
);
};
/***/ }),
/* 87 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _desc, _value, _class;
var _react = __webpack_require__(11);
var _react2 = _interopRequireDefault(_react);
var _propTypes = __webpack_require__(25);
var _propTypes2 = _interopRequireDefault(_propTypes);
var _classnames = __webpack_require__(84);
var _classnames2 = _interopRequireDefault(_classnames);
var _autobindDecorator = __webpack_require__(89);
var _autobindDecorator2 = _interopRequireDefault(_autobindDecorator);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
var desc = {};
Object['ke' + 'ys'](descriptor).forEach(function (key) {
desc[key] = descriptor[key];
});
desc.enumerable = !!desc.enumerable;
desc.configurable = !!desc.configurable;
if ('value' in desc || desc.initializer) {
desc.writable = true;
}
desc = decorators.slice().reverse().reduce(function (desc, decorator) {
return decorator(target, property, desc) || desc;
}, desc);
if (context && desc.initializer !== void 0) {
desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
desc.initializer = undefined;
}
if (desc.initializer === void 0) {
Object['define' + 'Property'](target, property, desc);
desc = null;
}
return desc;
}
/**
* Base button component
*/
var Button = (_class = function (_Component) {
_inherits(Button, _Component);
function Button() {
_classCallCheck(this, Button);
return _possibleConstructorReturn(this, (Button.__proto__ || Object.getPrototypeOf(Button)).apply(this, arguments));
}
_createClass(Button, [{
key: 'handleClick',
value: function handleClick() {
if (this.props.isEnabled) {
this.props.onClick();
}
}
}, {
key: 'render',
value: function render() {
var _props = this.props,
isEnabled = _props.isEnabled,
className = _props.className,
extraClasses = _props.extraClasses,
style = _props.style,
children = _props.children;
return _react2.default.createElement(
'button',
{
className: (0, _classnames2.default)(className, { isEnabled: isEnabled }, extraClasses),
style: style,
disabled: !isEnabled,
onClick: this.handleClick
},
children
);
}
}]);
return Button;
}(_react.Component), (_applyDecoratedDescriptor(_class.prototype, 'handleClick', [_autobindDecorator2.default], Object.getOwnPropertyDescriptor(_class.prototype, 'handleClick'), _class.prototype)), _class);
Button.propTypes = {
onClick: _propTypes2.default.func.isRequired,
isEnabled: _propTypes2.default.bool,
className: _propTypes2.default.string,
extraClasses: _propTypes2.default.string,
style: _propTypes2.default.object,
children: _propTypes2.default.node
};
Button.defaultProps = {
isEnabled: true,
className: 'Button',
extraClasses: '',
style: {},
children: null
};
exports.default = Button;
/***/ }),
/* 88 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.withChildClasses = exports.withCustomizableClasses = exports.withChildrenStyles = exports.compose = undefined;
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _propTypes = __webpack_require__(25);
var _propTypes2 = _interopRequireDefault(_propTypes);
var _lodash = __webpack_require__(238);
var _lodash2 = _interopRequireDefault(_lodash);
var _lodash3 = __webpack_require__(239);
var _lodash4 = _interopRequireDefault(_lodash3);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* For clarification
*/
var compose = exports.compose = _lodash4.default;
/**
* Adds `childrenStyles` prop type and default prop to
* a component
*/
var withChildrenStyles = exports.withChildrenStyles = (0, _lodash2.default)(function (Component) {
Component.propTypes = _extends({}, Component.propTypes || {}, {
childrenStyles: _propTypes2.default.object
});
Component.defaultProps = _extends({}, Component.defaultProps || {}, {
childrenStyles: {}
});
return Component;
});
/**
*
*/
var withCustomizableClasses = exports.withCustomizableClasses = (0, _lodash2.default)(function (defaultClassName, Component) {
Component.propTypes = _extends({}, Component.propTypes || {}, {
className: _propTypes2.default.string,
extraClasses: _propTypes2.default.string
});
Component.defaultProps = _extends({}, Component.defaultProps || {}, {
className: defaultClassName,
extraClasses: ''
});
return Component;
});
/**
* Adds a `childClasses` prop type definition together with an empty
* defaults object to a provided component.
*/
var withChildClasses = exports.withChildClasses = (0, _lodash2.default)(function (Component) {
Component.propTypes = _extends({}, Component.propTypes || {}, {
childClasses: _propTypes2.default.object
});
Component.defaultProps = _extends({}, Component.defaultProps || {}, {
childClasses: {}
});
return Component;
});
/***/ }),
/* 89 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @copyright 2015, Andrey Popp <8mayday@gmail.com>
*
* The decorator may be used on classes or methods
* ```
* @autobind
* class FullBound {}
*
* class PartBound {
* @autobind
* method () {}
* }
* ```
*/
Object.defineProperty(exports, '__esModule', {
value: true
});
exports['default'] = autobind;
function autobind() {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
if (args.length === 1) {
return boundClass.apply(undefined, args);
} else {
return boundMethod.apply(undefined, args);
}
}
/**
* Use boundMethod to bind all methods on the target.prototype
*/
function boundClass(target) {
// (Using reflect to get all keys including symbols)
var keys = undefined;
// Use Reflect if exists
if (typeof Reflect !== 'undefined' && typeof Reflect.ownKeys === 'function') {
keys = Reflect.ownKeys(target.prototype);
} else {
keys = Object.getOwnPropertyNames(target.prototype);
// use symbols if support is provided
if (typeof Object.getOwnPropertySymbols === 'function') {
keys = keys.concat(Object.getOwnPropertySymbols(target.prototype));
}
}
keys.forEach(function (key) {
// Ignore special case target method
if (key === 'constructor') {
return;
}
var descriptor = Object.getOwnPropertyDescriptor(target.prototype, key);
// Only methods need binding
if (typeof descriptor.value === 'function') {
Object.defineProperty(target.prototype, key, boundMethod(target, key, descriptor));
}
});
return target;
}
/**
* Return a descriptor removing the value and returning a getter
* The getter will return a .bind version of the function
* and memoize the result against a symbol on the instance
*/
function boundMethod(target, key, descriptor) {
var fn = descriptor.value;
if (typeof fn !== 'function') {
throw new Error('@autobind decorator can only be applied to methods not: ' + typeof fn);
}
// In IE11 calling Object.defineProperty has a side-effect of evaluating the
// getter for the property which is being replaced. This causes infinite
// recursion and an "Out of stack space" error.
var definingProperty = false;
return {
configurable: true,
get: function get() {
if (definingProperty || this === target.prototype || this.hasOwnProperty(key)) {
return fn;
}
var boundFn = fn.bind(this);
definingProperty = true;
Object.defineProperty(this, key, {
value: boundFn,
configurable: true,
writable: true
});
definingProperty = false;
return boundFn;
}
};
}
module.exports = exports['default'];
/***/ }),
/* 90 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var PooledClass = __webpack_require__(91);
var ReactElement = __webpack_require__(14);
var emptyFunction = __webpack_require__(8);
var traverseAllChildren = __webpack_require__(92);
var twoArgumentPooler = PooledClass.twoArgumentPooler;
var fourArgumentPooler = PooledClass.fourArgumentPooler;
var userProvidedKeyEscapeRegex = /\/+/g;
function escapeUserProvidedKey(text) {
return ('' + text).replace(userProvidedKeyEscapeRegex, '$&/');
}
/**
* PooledClass representing the bookkeeping associated with performing a child
* traversal. Allows avoiding binding callbacks.
*
* @constructor ForEachBookKeeping
* @param {!function} forEachFunction Function to perform traversal with.
* @param {?*} forEachContext Context to perform context with.
*/
function ForEachBookKeeping(forEachFunction, forEachContext) {
this.func = forEachFunction;
this.context = forEachContext;
this.count = 0;
}
ForEachBookKeeping.prototype.destructor = function () {
this.func = null;
this.context = null;
this.count = 0;
};
PooledClass.addPoolingTo(ForEachBookKeeping, twoArgumentPooler);
function forEachSingleChild(bookKeeping, child, name) {
var func = bookKeeping.func,
context = bookKeeping.context;
func.call(context, child, bookKeeping.count++);
}
/**
* Iterates through children that are typically specified as `props.children`.
*
* See https://facebook.github.io/react/docs/top-level-api.html#react.children.foreach
*
* The provided forEachFunc(child, index) will be called for each
* leaf child.
*
* @param {?*} children Children tree container.
* @param {function(*, int)} forEachFunc
* @param {*} forEachContext Context for forEachContext.
*/
function forEachChildren(children, forEachFunc, forEachContext) {
if (children == null) {
return children;
}
var traverseContext = ForEachBookKeeping.getPooled(forEachFunc, forEachContext);
traverseAllChildren(children, forEachSingleChild, traverseContext);
ForEachBookKeeping.release(traverseContext);
}
/**
* PooledClass representing the bookkeeping associated with performing a child
* mapping. Allows avoiding binding callbacks.
*
* @constructor MapBookKeeping
* @param {!*} mapResult Object containing the ordered map of results.
* @param {!function} mapFunction Function to perform mapping with.
* @param {?*} mapContext Context to perform mapping with.
*/
function MapBookKeeping(mapResult, keyPrefix, mapFunction, mapContext) {
this.result = mapResult;
this.keyPrefix = keyPrefix;
this.func = mapFunction;
this.context = mapContext;
this.count = 0;
}
MapBookKeeping.prototype.destructor = function () {
this.result = null;
this.keyPrefix = null;
this.func = null;
this.context = null;
this.count = 0;
};
PooledClass.addPoolingTo(MapBookKeeping, fourArgumentPooler);
function mapSingleChildIntoContext(bookKeeping, child, childKey) {
var result = bookKeeping.result,
keyPrefix = bookKeeping.keyPrefix,
func = bookKeeping.func,
context = bookKeeping.context;
var mappedChild = func.call(context, child, bookKeeping.count++);
if (Array.isArray(mappedChild)) {
mapIntoWithKeyPrefixInternal(mappedChild, result, childKey, emptyFunction.thatReturnsArgument);
} else if (mappedChild != null) {
if (ReactElement.isValidElement(mappedChild)) {
mappedChild = ReactElement.cloneAndReplaceKey(mappedChild,
// Keep both the (mapped) and old keys if they differ, just as
// traverseAllChildren used to do for objects as children
keyPrefix + (mappedChild.key && (!child || child.key !== mappedChild.key) ? escapeUserProvidedKey(mappedChild.key) + '/' : '') + childKey);
}
result.push(mappedChild);
}
}
function mapIntoWithKeyPrefixInternal(children, array, prefix, func, context) {
var escapedPrefix = '';
if (prefix != null) {
escapedPrefix = escapeUserProvidedKey(prefix) + '/';
}
var traverseContext = MapBookKeeping.getPooled(array, escapedPrefix, func, context);
traverseAllChildren(children, mapSingleChildIntoContext, traverseContext);
MapBookKeeping.release(traverseContext);
}
/**
* Maps children that are typically specified as `props.children`.
*
* See https://facebook.github.io/react/docs/top-level-api.html#react.children.map
*
* The provided mapFunction(child, key, index) will be called for each
* leaf child.
*
* @param {?*} children Children tree container.
* @param {function(*, int)} func The map function.
* @param {*} context Context for mapFunction.
* @return {object} Object containing the ordered map of results.
*/
function mapChildren(children, func, context) {
if (children == null) {
return children;
}
var result = [];
mapIntoWithKeyPrefixInternal(children, result, null, func, context);
return result;
}
function forEachSingleChildDummy(traverseContext, child, name) {
return null;
}
/**
* Count the number of children that are typically specified as
* `props.children`.
*
* See https://facebook.github.io/react/docs/top-level-api.html#react.children.count
*
* @param {?*} children Children tree container.
* @return {number} The number of children.
*/
function countChildren(children, context) {
return traverseAllChildren(children, forEachSingleChildDummy, null);
}
/**
* Flatten a children object (typically specified as `props.children`) and
* return an array with appropriately re-keyed children.
*
* See https://facebook.github.io/react/docs/top-level-api.html#react.children.toarray
*/
function toArray(children) {
var result = [];
mapIntoWithKeyPrefixInternal(children, result, null, emptyFunction.thatReturnsArgument);
return result;
}
var ReactChildren = {
forEach: forEachChildren,
map: mapChildren,
mapIntoWithKeyPrefixInternal: mapIntoWithKeyPrefixInternal,
count: countChildren,
toArray: toArray
};
module.exports = ReactChildren;
/***/ }),
/* 91 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var _prodInvariant = __webpack_require__(17);
var invariant = __webpack_require__(0);
/**
* Static poolers. Several custom versions for each potential number of
* arguments. A completely generic pooler is easy to implement, but would
* require accessing the `arguments` object. In each of these, `this` refers to
* the Class itself, not an instance. If any others are needed, simply add them
* here, or in their own files.
*/
var oneArgumentPooler = function (copyFieldsFrom) {
var Klass = this;
if (Klass.instancePool.length) {
var instance = Klass.instancePool.pop();
Klass.call(instance, copyFieldsFrom);
return instance;
} else {
return new Klass(copyFieldsFrom);
}
};
var twoArgumentPooler = function (a1, a2) {
var Klass = this;
if (Klass.instancePool.length) {
var instance = Klass.instancePool.pop();
Klass.call(instance, a1, a2);
return instance;
} else {
return new Klass(a1, a2);
}
};
var threeArgumentPooler = function (a1, a2, a3) {
var Klass = this;
if (Klass.instancePool.length) {
var instance = Klass.instancePool.pop();
Klass.call(instance, a1, a2, a3);
return instance;
} else {
return new Klass(a1, a2, a3);
}
};
var fourArgumentPooler = function (a1, a2, a3, a4) {
var Klass = this;
if (Klass.instancePool.length) {
var instance = Klass.instancePool.pop();
Klass.call(instance, a1, a2, a3, a4);
return instance;
} else {
return new Klass(a1, a2, a3, a4);
}
};
var standardReleaser = function (instance) {
var Klass = this;
!(instance instanceof Klass) ? true ? invariant(false, 'Trying to release an instance into a pool of a different type.') : _prodInvariant('25') : void 0;
instance.destructor();
if (Klass.instancePool.length < Klass.poolSize) {
Klass.instancePool.push(instance);
}
};
var DEFAULT_POOL_SIZE = 10;
var DEFAULT_POOLER = oneArgumentPooler;
/**
* Augments `CopyConstructor` to be a poolable class, augmenting only the class
* itself (statically) not adding any prototypical fields. Any CopyConstructor
* you give this may have a `poolSize` property, and will look for a
* prototypical `destructor` on instances.
*
* @param {Function} CopyConstructor Constructor that can be used to reset.
* @param {Function} pooler Customizable pooler.
*/
var addPoolingTo = function (CopyConstructor, pooler) {
// Casting as any so that flow ignores the actual implementation and trusts
// it to match the type we declared
var NewKlass = CopyConstructor;
NewKlass.instancePool = [];
NewKlass.getPooled = pooler || DEFAULT_POOLER;
if (!NewKlass.poolSize) {
NewKlass.poolSize = DEFAULT_POOL_SIZE;
}
NewKlass.release = standardReleaser;
return NewKlass;
};
var PooledClass = {
addPoolingTo: addPoolingTo,
oneArgumentPooler: oneArgumentPooler,
twoArgumentPooler: twoArgumentPooler,
threeArgumentPooler: threeArgumentPooler,
fourArgumentPooler: fourArgumentPooler
};
module.exports = PooledClass;
/***/ }),
/* 92 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _prodInvariant = __webpack_require__(17);
var ReactCurrentOwner = __webpack_require__(9);
var REACT_ELEMENT_TYPE = __webpack_require__(54);
var getIteratorFn = __webpack_require__(55);
var invariant = __webpack_require__(0);
var KeyEscapeUtils = __webpack_require__(93);
var warning = __webpack_require__(1);
var SEPARATOR = '.';
var SUBSEPARATOR = ':';
/**
* This is inlined from ReactElement since this file is shared between
* isomorphic and renderers. We could extract this to a
*
*/
/**
* TODO: Test that a single child and an array with one item have the same key
* pattern.
*/
var didWarnAboutMaps = false;
/**
* Generate a key string that identifies a component within a set.
*
* @param {*} component A component that could contain a manual key.
* @param {number} index Index that is used if a manual key is not provided.
* @return {string}
*/
function getComponentKey(component, index) {
// Do some typechecking here since we call this blindly. We want to ensure
// that we don't block potential future ES APIs.
if (component && typeof component === 'object' && component.key != null) {
// Explicit key
return KeyEscapeUtils.escape(component.key);
}
// Implicit key determined by the index in the set
return index.toString(36);
}
/**
* @param {?*} children Children tree container.
* @param {!string} nameSoFar Name of the key path so far.
* @param {!function} callback Callback to invoke with each child found.
* @param {?*} traverseContext Used to pass information throughout the traversal
* process.
* @return {!number} The number of children in this subtree.
*/
function traverseAllChildrenImpl(children, nameSoFar, callback, traverseContext) {
var type = typeof children;
if (type === 'undefined' || type === 'boolean') {
// All of the above are perceived as null.
children = null;
}
if (children === null || type === 'string' || type === 'number' ||
// The following is inlined from ReactElement. This means we can optimize
// some checks. React Fiber also inlines this logic for similar purposes.
type === 'object' && children.$$typeof === REACT_ELEMENT_TYPE) {
callback(traverseContext, children,
// If it's the only child, treat the name as if it was wrapped in an array
// so that it's consistent if the number of children grows.
nameSoFar === '' ? SEPARATOR + getComponentKey(children, 0) : nameSoFar);
return 1;
}
var child;
var nextName;
var subtreeCount = 0; // Count of children found in the current subtree.
var nextNamePrefix = nameSoFar === '' ? SEPARATOR : nameSoFar + SUBSEPARATOR;
if (Array.isArray(children)) {
for (var i = 0; i < children.length; i++) {
child = children[i];
nextName = nextNamePrefix + getComponentKey(child, i);
subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext);
}
} else {
var iteratorFn = getIteratorFn(children);
if (iteratorFn) {
var iterator = iteratorFn.call(children);
var step;
if (iteratorFn !== children.entries) {
var ii = 0;
while (!(step = iterator.next()).done) {
child = step.value;
nextName = nextNamePrefix + getComponentKey(child, ii++);
subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext);
}
} else {
if (true) {
var mapsAsChildrenAddendum = '';
if (ReactCurrentOwner.current) {
var mapsAsChildrenOwnerName = ReactCurrentOwner.current.getName();
if (mapsAsChildrenOwnerName) {
mapsAsChildrenAddendum = ' Check the render method of `' + mapsAsChildrenOwnerName + '`.';
}
}
true ? warning(didWarnAboutMaps, 'Using Maps as children is not yet fully supported. It is an ' + 'experimental feature that might be removed. Convert it to a ' + 'sequence / iterable of keyed ReactElements instead.%s', mapsAsChildrenAddendum) : void 0;
didWarnAboutMaps = true;
}
// Iterator will provide entry [k,v] tuples rather than values.
while (!(step = iterator.next()).done) {
var entry = step.value;
if (entry) {
child = entry[1];
nextName = nextNamePrefix + KeyEscapeUtils.escape(entry[0]) + SUBSEPARATOR + getComponentKey(child, 0);
subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext);
}
}
}
} else if (type === 'object') {
var addendum = '';
if (true) {
addendum = ' If you meant to render a collection of children, use an array ' + 'instead or wrap the object using createFragment(object) from the ' + 'React add-ons.';
if (children._isReactElement) {
addendum = " It looks like you're using an element created by a different " + 'version of React. Make sure to use only one copy of React.';
}
if (ReactCurrentOwner.current) {
var name = ReactCurrentOwner.current.getName();
if (name) {
addendum += ' Check the render method of `' + name + '`.';
}
}
}
var childrenString = String(children);
true ? true ? invariant(false, 'Objects are not valid as a React child (found: %s).%s', childrenString === '[object Object]' ? 'object with keys {' + Object.keys(children).join(', ') + '}' : childrenString, addendum) : _prodInvariant('31', childrenString === '[object Object]' ? 'object with keys {' + Object.keys(children).join(', ') + '}' : childrenString, addendum) : void 0;
}
}
return subtreeCount;
}
/**
* Traverses children that are typically specified as `props.children`, but
* might also be specified through attributes:
*
* - `traverseAllChildren(this.props.children, ...)`
* - `traverseAllChildren(this.props.leftPanelChildren, ...)`
*
* The `traverseContext` is an optional argument that is passed through the
* entire traversal. It can be used to store accumulations or anything else that
* the callback might find relevant.
*
* @param {?*} children Children tree object.
* @param {!function} callback To invoke upon traversing each child.
* @param {?*} traverseContext Context for traversal.
* @return {!number} The number of children in this subtree.
*/
function traverseAllChildren(children, callback, traverseContext) {
if (children == null) {
return 0;
}
return traverseAllChildrenImpl(children, '', callback, traverseContext);
}
module.exports = traverseAllChildren;
/***/ }),
/* 93 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
/**
* Escape and wrap key so it is safe to use as a reactid
*
* @param {string} key to be escaped.
* @return {string} the escaped key.
*/
function escape(key) {
var escapeRegex = /[=:]/g;
var escaperLookup = {
'=': '=0',
':': '=2'
};
var escapedString = ('' + key).replace(escapeRegex, function (match) {
return escaperLookup[match];
});
return '$' + escapedString;
}
/**
* Unescape and unwrap key for human-readable display
*
* @param {string} key to unescape.
* @return {string} the unescaped key.
*/
function unescape(key) {
var unescapeRegex = /(=0|=2)/g;
var unescaperLookup = {
'=0': '=',
'=2': ':'
};
var keySubstring = key[0] === '.' && key[1] === '$' ? key.substring(2) : key.substring(1);
return ('' + keySubstring).replace(unescapeRegex, function (match) {
return unescaperLookup[match];
});
}
var KeyEscapeUtils = {
escape: escape,
unescape: unescape
};
module.exports = KeyEscapeUtils;
/***/ }),
/* 94 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var ReactElement = __webpack_require__(14);
/**
* Create a factory that creates HTML tag elements.
*
* @private
*/
var createDOMFactory = ReactElement.createFactory;
if (true) {
var ReactElementValidator = __webpack_require__(56);
createDOMFactory = ReactElementValidator.createFactory;
}
/**
* Creates a mapping from supported HTML tags to `ReactDOMComponent` classes.
*
* @public
*/
var ReactDOMFactories = {
a: createDOMFactory('a'),
abbr: createDOMFactory('abbr'),
address: createDOMFactory('address'),
area: createDOMFactory('area'),
article: createDOMFactory('article'),
aside: createDOMFactory('aside'),
audio: createDOMFactory('audio'),
b: createDOMFactory('b'),
base: createDOMFactory('base'),
bdi: createDOMFactory('bdi'),
bdo: createDOMFactory('bdo'),
big: createDOMFactory('big'),
blockquote: createDOMFactory('blockquote'),
body: createDOMFactory('body'),
br: createDOMFactory('br'),
button: createDOMFactory('button'),
canvas: createDOMFactory('canvas'),
caption: createDOMFactory('caption'),
cite: createDOMFactory('cite'),
code: createDOMFactory('code'),
col: createDOMFactory('col'),
colgroup: createDOMFactory('colgroup'),
data: createDOMFactory('data'),
datalist: createDOMFactory('datalist'),
dd: createDOMFactory('dd'),
del: createDOMFactory('del'),
details: createDOMFactory('details'),
dfn: createDOMFactory('dfn'),
dialog: createDOMFactory('dialog'),
div: createDOMFactory('div'),
dl: createDOMFactory('dl'),
dt: createDOMFactory('dt'),
em: createDOMFactory('em'),
embed: createDOMFactory('embed'),
fieldset: createDOMFactory('fieldset'),
figcaption: createDOMFactory('figcaption'),
figure: createDOMFactory('figure'),
footer: createDOMFactory('footer'),
form: createDOMFactory('form'),
h1: createDOMFactory('h1'),
h2: createDOMFactory('h2'),
h3: createDOMFactory('h3'),
h4: createDOMFactory('h4'),
h5: createDOMFactory('h5'),
h6: createDOMFactory('h6'),
head: createDOMFactory('head'),
header: createDOMFactory('header'),
hgroup: createDOMFactory('hgroup'),
hr: createDOMFactory('hr'),
html: createDOMFactory('html'),
i: createDOMFactory('i'),
iframe: createDOMFactory('iframe'),
img: createDOMFactory('img'),
input: createDOMFactory('input'),
ins: createDOMFactory('ins'),
kbd: createDOMFactory('kbd'),
keygen: createDOMFactory('keygen'),
label: createDOMFactory('label'),
legend: createDOMFactory('legend'),
li: createDOMFactory('li'),
link: createDOMFactory('link'),
main: createDOMFactory('main'),
map: createDOMFactory('map'),
mark: createDOMFactory('mark'),
menu: createDOMFactory('menu'),
menuitem: createDOMFactory('menuitem'),
meta: createDOMFactory('meta'),
meter: createDOMFactory('meter'),
nav: createDOMFactory('nav'),
noscript: createDOMFactory('noscript'),
object: createDOMFactory('object'),
ol: createDOMFactory('ol'),
optgroup: createDOMFactory('optgroup'),
option: createDOMFactory('option'),
output: createDOMFactory('output'),
p: createDOMFactory('p'),
param: createDOMFactory('param'),
picture: createDOMFactory('picture'),
pre: createDOMFactory('pre'),
progress: createDOMFactory('progress'),
q: createDOMFactory('q'),
rp: createDOMFactory('rp'),
rt: createDOMFactory('rt'),
ruby: createDOMFactory('ruby'),
s: createDOMFactory('s'),
samp: createDOMFactory('samp'),
script: createDOMFactory('script'),
section: createDOMFactory('section'),
select: createDOMFactory('select'),
small: createDOMFactory('small'),
source: createDOMFactory('source'),
span: createDOMFactory('span'),
strong: createDOMFactory('strong'),
style: createDOMFactory('style'),
sub: createDOMFactory('sub'),
summary: createDOMFactory('summary'),
sup: createDOMFactory('sup'),
table: createDOMFactory('table'),
tbody: createDOMFactory('tbody'),
td: createDOMFactory('td'),
textarea: createDOMFactory('textarea'),
tfoot: createDOMFactory('tfoot'),
th: createDOMFactory('th'),
thead: createDOMFactory('thead'),
time: createDOMFactory('time'),
title: createDOMFactory('title'),
tr: createDOMFactory('tr'),
track: createDOMFactory('track'),
u: createDOMFactory('u'),
ul: createDOMFactory('ul'),
'var': createDOMFactory('var'),
video: createDOMFactory('video'),
wbr: createDOMFactory('wbr'),
// SVG
circle: createDOMFactory('circle'),
clipPath: createDOMFactory('clipPath'),
defs: createDOMFactory('defs'),
ellipse: createDOMFactory('ellipse'),
g: createDOMFactory('g'),
image: createDOMFactory('image'),
line: createDOMFactory('line'),
linearGradient: createDOMFactory('linearGradient'),
mask: createDOMFactory('mask'),
path: createDOMFactory('path'),
pattern: createDOMFactory('pattern'),
polygon: createDOMFactory('polygon'),
polyline: createDOMFactory('polyline'),
radialGradient: createDOMFactory('radialGradient'),
rect: createDOMFactory('rect'),
stop: createDOMFactory('stop'),
svg: createDOMFactory('svg'),
text: createDOMFactory('text'),
tspan: createDOMFactory('tspan')
};
module.exports = ReactDOMFactories;
/***/ }),
/* 95 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* WEBPACK VAR INJECTION */(function(process) {/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _prodInvariant = __webpack_require__(17);
var ReactPropTypeLocationNames = __webpack_require__(96);
var ReactPropTypesSecret = __webpack_require__(97);
var invariant = __webpack_require__(0);
var warning = __webpack_require__(1);
var ReactComponentTreeHook;
if (typeof process !== 'undefined' && process.env && "test" === 'test') {
// Temporary hack.
// Inline requires don't work well with Jest:
// https://github.com/facebook/react/issues/7240
// Remove the inline requires when we don't need them anymore:
// https://github.com/facebook/react/pull/7178
ReactComponentTreeHook = __webpack_require__(6);
}
var loggedTypeFailures = {};
/**
* Assert that the values match with the type specs.
* Error messages are memorized and will only be shown once.
*
* @param {object} typeSpecs Map of name to a ReactPropType
* @param {object} values Runtime values that need to be type-checked
* @param {string} location e.g. "prop", "context", "child context"
* @param {string} componentName Name of the component for error messages.
* @param {?object} element The React element that is being type-checked
* @param {?number} debugID The React component instance that is being type-checked
* @private
*/
function checkReactTypeSpec(typeSpecs, values, location, componentName, element, debugID) {
for (var typeSpecName in typeSpecs) {
if (typeSpecs.hasOwnProperty(typeSpecName)) {
var error;
// Prop type validation may throw. In case they do, we don't want to
// fail the render phase where it didn't fail before. So we log it.
// After these have been cleaned up, we'll let them throw.
try {
// This is intentionally an invariant that gets caught. It's the same
// behavior as without this statement except with a better message.
!(typeof typeSpecs[typeSpecName] === 'function') ? true ? invariant(false, '%s: %s type `%s` is invalid; it must be a function, usually from React.PropTypes.', componentName || 'React class', ReactPropTypeLocationNames[location], typeSpecName) : _prodInvariant('84', componentName || 'React class', ReactPropTypeLocationNames[location], typeSpecName) : void 0;
error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);
} catch (ex) {
error = ex;
}
true ? warning(!error || error instanceof Error, '%s: type specification of %s `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', ReactPropTypeLocationNames[location], typeSpecName, typeof error) : void 0;
if (error instanceof Error && !(error.message in loggedTypeFailures)) {
// Only monitor this failure once because there tends to be a lot of the
// same error.
loggedTypeFailures[error.message] = true;
var componentStackInfo = '';
if (true) {
if (!ReactComponentTreeHook) {
ReactComponentTreeHook = __webpack_require__(6);
}
if (debugID !== null) {
componentStackInfo = ReactComponentTreeHook.getStackAddendumByID(debugID);
} else if (element !== null) {
componentStackInfo = ReactComponentTreeHook.getCurrentStackAddendum(element);
}
}
true ? warning(false, 'Failed %s type: %s%s', location, error.message, componentStackInfo) : void 0;
}
}
}
}
module.exports = checkReactTypeSpec;
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(24)))
/***/ }),
/* 96 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var ReactPropTypeLocationNames = {};
if (true) {
ReactPropTypeLocationNames = {
prop: 'prop',
context: 'context',
childContext: 'child context'
};
}
module.exports = ReactPropTypeLocationNames;
/***/ }),
/* 97 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
module.exports = ReactPropTypesSecret;
/***/ }),
/* 98 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _require = __webpack_require__(14),
isValidElement = _require.isValidElement;
var factory = __webpack_require__(57);
module.exports = factory(isValidElement);
/***/ }),
/* 99 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
if (true) {
var invariant = __webpack_require__(0);
var warning = __webpack_require__(1);
var ReactPropTypesSecret = __webpack_require__(58);
var loggedTypeFailures = {};
}
/**
* Assert that the values match with the type specs.
* Error messages are memorized and will only be shown once.
*
* @param {object} typeSpecs Map of name to a ReactPropType
* @param {object} values Runtime values that need to be type-checked
* @param {string} location e.g. "prop", "context", "child context"
* @param {string} componentName Name of the component for error messages.
* @param {?Function} getStack Returns the component stack.
* @private
*/
function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
if (true) {
for (var typeSpecName in typeSpecs) {
if (typeSpecs.hasOwnProperty(typeSpecName)) {
var error;
// Prop type validation may throw. In case they do, we don't want to
// fail the render phase where it didn't fail before. So we log it.
// After these have been cleaned up, we'll let them throw.
try {
// This is intentionally an invariant that gets caught. It's the same
// behavior as without this statement except with a better message.
invariant(typeof typeSpecs[typeSpecName] === 'function', '%s: %s type `%s` is invalid; it must be a function, usually from ' + 'the `prop-types` package, but received `%s`.', componentName || 'React class', location, typeSpecName, typeof typeSpecs[typeSpecName]);
error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);
} catch (ex) {
error = ex;
}
warning(!error || error instanceof Error, '%s: type specification of %s `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', location, typeSpecName, typeof error);
if (error instanceof Error && !(error.message in loggedTypeFailures)) {
// Only monitor this failure once because there tends to be a lot of the
// same error.
loggedTypeFailures[error.message] = true;
var stack = getStack ? getStack() : '';
warning(false, 'Failed %s type: %s%s', location, error.message, stack != null ? stack : '');
}
}
}
}
}
module.exports = checkPropTypes;
/***/ }),
/* 100 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
module.exports = '15.6.2';
/***/ }),
/* 101 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _require = __webpack_require__(52),
Component = _require.Component;
var _require2 = __webpack_require__(14),
isValidElement = _require2.isValidElement;
var ReactNoopUpdateQueue = __webpack_require__(53);
var factory = __webpack_require__(102);
module.exports = factory(Component, isValidElement, ReactNoopUpdateQueue);
/***/ }),
/* 102 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _assign = __webpack_require__(3);
var emptyObject = __webpack_require__(27);
var _invariant = __webpack_require__(0);
if (true) {
var warning = __webpack_require__(1);
}
var MIXINS_KEY = 'mixins';
// Helper function to allow the creation of anonymous functions which do not
// have .name set to the name of the variable being assigned to.
function identity(fn) {
return fn;
}
var ReactPropTypeLocationNames;
if (true) {
ReactPropTypeLocationNames = {
prop: 'prop',
context: 'context',
childContext: 'child context'
};
} else {
ReactPropTypeLocationNames = {};
}
function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
/**
* Policies that describe methods in `ReactClassInterface`.
*/
var injectedMixins = [];
/**
* Composite components are higher-level components that compose other composite
* or host components.
*
* To create a new type of `ReactClass`, pass a specification of
* your new class to `React.createClass`. The only requirement of your class
* specification is that you implement a `render` method.
*
* var MyComponent = React.createClass({
* render: function() {
* return <div>Hello World</div>;
* }
* });
*
* The class specification supports a specific protocol of methods that have
* special meaning (e.g. `render`). See `ReactClassInterface` for
* more the comprehensive protocol. Any other properties and methods in the
* class specification will be available on the prototype.
*
* @interface ReactClassInterface
* @internal
*/
var ReactClassInterface = {
/**
* An array of Mixin objects to include when defining your component.
*
* @type {array}
* @optional
*/
mixins: 'DEFINE_MANY',
/**
* An object containing properties and methods that should be defined on
* the component's constructor instead of its prototype (static methods).
*
* @type {object}
* @optional
*/
statics: 'DEFINE_MANY',
/**
* Definition of prop types for this component.
*
* @type {object}
* @optional
*/
propTypes: 'DEFINE_MANY',
/**
* Definition of context types for this component.
*
* @type {object}
* @optional
*/
contextTypes: 'DEFINE_MANY',
/**
* Definition of context types this component sets for its children.
*
* @type {object}
* @optional
*/
childContextTypes: 'DEFINE_MANY',
// ==== Definition methods ====
/**
* Invoked when the component is mounted. Values in the mapping will be set on
* `this.props` if that prop is not specified (i.e. using an `in` check).
*
* This method is invoked before `getInitialState` and therefore cannot rely
* on `this.state` or use `this.setState`.
*
* @return {object}
* @optional
*/
getDefaultProps: 'DEFINE_MANY_MERGED',
/**
* Invoked once before the component is mounted. The return value will be used
* as the initial value of `this.state`.
*
* getInitialState: function() {
* return {
* isOn: false,
* fooBaz: new BazFoo()
* }
* }
*
* @return {object}
* @optional
*/
getInitialState: 'DEFINE_MANY_MERGED',
/**
* @return {object}
* @optional
*/
getChildContext: 'DEFINE_MANY_MERGED',
/**
* Uses props from `this.props` and state from `this.state` to render the
* structure of the component.
*
* No guarantees are made about when or how often this method is invoked, so
* it must not have side effects.
*
* render: function() {
* var name = this.props.name;
* return <div>Hello, {name}!</div>;
* }
*
* @return {ReactComponent}
* @required
*/
render: 'DEFINE_ONCE',
// ==== Delegate methods ====
/**
* Invoked when the component is initially created and about to be mounted.
* This may have side effects, but any external subscriptions or data created
* by this method must be cleaned up in `componentWillUnmount`.
*
* @optional
*/
componentWillMount: 'DEFINE_MANY',
/**
* Invoked when the component has been mounted and has a DOM representation.
* However, there is no guarantee that the DOM node is in the document.
*
* Use this as an opportunity to operate on the DOM when the component has
* been mounted (initialized and rendered) for the first time.
*
* @param {DOMElement} rootNode DOM element representing the component.
* @optional
*/
componentDidMount: 'DEFINE_MANY',
/**
* Invoked before the component receives new props.
*
* Use this as an opportunity to react to a prop transition by updating the
* state using `this.setState`. Current props are accessed via `this.props`.
*
* componentWillReceiveProps: function(nextProps, nextContext) {
* this.setState({
* likesIncreasing: nextProps.likeCount > this.props.likeCount
* });
* }
*
* NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop
* transition may cause a state change, but the opposite is not true. If you
* need it, you are probably looking for `componentWillUpdate`.
*
* @param {object} nextProps
* @optional
*/
componentWillReceiveProps: 'DEFINE_MANY',
/**
* Invoked while deciding if the component should be updated as a result of
* receiving new props, state and/or context.
*
* Use this as an opportunity to `return false` when you're certain that the
* transition to the new props/state/context will not require a component
* update.
*
* shouldComponentUpdate: function(nextProps, nextState, nextContext) {
* return !equal(nextProps, this.props) ||
* !equal(nextState, this.state) ||
* !equal(nextContext, this.context);
* }
*
* @param {object} nextProps
* @param {?object} nextState
* @param {?object} nextContext
* @return {boolean} True if the component should update.
* @optional
*/
shouldComponentUpdate: 'DEFINE_ONCE',
/**
* Invoked when the component is about to update due to a transition from
* `this.props`, `this.state` and `this.context` to `nextProps`, `nextState`
* and `nextContext`.
*
* Use this as an opportunity to perform preparation before an update occurs.
*
* NOTE: You **cannot** use `this.setState()` in this method.
*
* @param {object} nextProps
* @param {?object} nextState
* @param {?object} nextContext
* @param {ReactReconcileTransaction} transaction
* @optional
*/
componentWillUpdate: 'DEFINE_MANY',
/**
* Invoked when the component's DOM representation has been updated.
*
* Use this as an opportunity to operate on the DOM when the component has
* been updated.
*
* @param {object} prevProps
* @param {?object} prevState
* @param {?object} prevContext
* @param {DOMElement} rootNode DOM element representing the component.
* @optional
*/
componentDidUpdate: 'DEFINE_MANY',
/**
* Invoked when the component is about to be removed from its parent and have
* its DOM representation destroyed.
*
* Use this as an opportunity to deallocate any external resources.
*
* NOTE: There is no `componentDidUnmount` since your component will have been
* destroyed by that point.
*
* @optional
*/
componentWillUnmount: 'DEFINE_MANY',
// ==== Advanced methods ====
/**
* Updates the component's currently mounted DOM representation.
*
* By default, this implements React's rendering and reconciliation algorithm.
* Sophisticated clients may wish to override this.
*
* @param {ReactReconcileTransaction} transaction
* @internal
* @overridable
*/
updateComponent: 'OVERRIDE_BASE'
};
/**
* Mapping from class specification keys to special processing functions.
*
* Although these are declared like instance properties in the specification
* when defining classes using `React.createClass`, they are actually static
* and are accessible on the constructor instead of the prototype. Despite
* being static, they must be defined outside of the "statics" key under
* which all other static methods are defined.
*/
var RESERVED_SPEC_KEYS = {
displayName: function(Constructor, displayName) {
Constructor.displayName = displayName;
},
mixins: function(Constructor, mixins) {
if (mixins) {
for (var i = 0; i < mixins.length; i++) {
mixSpecIntoComponent(Constructor, mixins[i]);
}
}
},
childContextTypes: function(Constructor, childContextTypes) {
if (true) {
validateTypeDef(Constructor, childContextTypes, 'childContext');
}
Constructor.childContextTypes = _assign(
{},
Constructor.childContextTypes,
childContextTypes
);
},
contextTypes: function(Constructor, contextTypes) {
if (true) {
validateTypeDef(Constructor, contextTypes, 'context');
}
Constructor.contextTypes = _assign(
{},
Constructor.contextTypes,
contextTypes
);
},
/**
* Special case getDefaultProps which should move into statics but requires
* automatic merging.
*/
getDefaultProps: function(Constructor, getDefaultProps) {
if (Constructor.getDefaultProps) {
Constructor.getDefaultProps = createMergedResultFunction(
Constructor.getDefaultProps,
getDefaultProps
);
} else {
Constructor.getDefaultProps = getDefaultProps;
}
},
propTypes: function(Constructor, propTypes) {
if (true) {
validateTypeDef(Constructor, propTypes, 'prop');
}
Constructor.propTypes = _assign({}, Constructor.propTypes, propTypes);
},
statics: function(Constructor, statics) {
mixStaticSpecIntoComponent(Constructor, statics);
},
autobind: function() {}
};
function validateTypeDef(Constructor, typeDef, location) {
for (var propName in typeDef) {
if (typeDef.hasOwnProperty(propName)) {
// use a warning instead of an _invariant so components
// don't show up in prod but only in __DEV__
if (true) {
warning(
typeof typeDef[propName] === 'function',
'%s: %s type `%s` is invalid; it must be a function, usually from ' +
'React.PropTypes.',
Constructor.displayName || 'ReactClass',
ReactPropTypeLocationNames[location],
propName
);
}
}
}
}
function validateMethodOverride(isAlreadyDefined, name) {
var specPolicy = ReactClassInterface.hasOwnProperty(name)
? ReactClassInterface[name]
: null;
// Disallow overriding of base class methods unless explicitly allowed.
if (ReactClassMixin.hasOwnProperty(name)) {
_invariant(
specPolicy === 'OVERRIDE_BASE',
'ReactClassInterface: You are attempting to override ' +
'`%s` from your class specification. Ensure that your method names ' +
'do not overlap with React methods.',
name
);
}
// Disallow defining methods more than once unless explicitly allowed.
if (isAlreadyDefined) {
_invariant(
specPolicy === 'DEFINE_MANY' || specPolicy === 'DEFINE_MANY_MERGED',
'ReactClassInterface: You are attempting to define ' +
'`%s` on your component more than once. This conflict may be due ' +
'to a mixin.',
name
);
}
}
/**
* Mixin helper which handles policy validation and reserved
* specification keys when building React classes.
*/
function mixSpecIntoComponent(Constructor, spec) {
if (!spec) {
if (true) {
var typeofSpec = typeof spec;
var isMixinValid = typeofSpec === 'object' && spec !== null;
if (true) {
warning(
isMixinValid,
"%s: You're attempting to include a mixin that is either null " +
'or not an object. Check the mixins included by the component, ' +
'as well as any mixins they include themselves. ' +
'Expected object but got %s.',
Constructor.displayName || 'ReactClass',
spec === null ? null : typeofSpec
);
}
}
return;
}
_invariant(
typeof spec !== 'function',
"ReactClass: You're attempting to " +
'use a component class or function as a mixin. Instead, just use a ' +
'regular object.'
);
_invariant(
!isValidElement(spec),
"ReactClass: You're attempting to " +
'use a component as a mixin. Instead, just use a regular object.'
);
var proto = Constructor.prototype;
var autoBindPairs = proto.__reactAutoBindPairs;
// By handling mixins before any other properties, we ensure the same
// chaining order is applied to methods with DEFINE_MANY policy, whether
// mixins are listed before or after these methods in the spec.
if (spec.hasOwnProperty(MIXINS_KEY)) {
RESERVED_SPEC_KEYS.mixins(Constructor, spec.mixins);
}
for (var name in spec) {
if (!spec.hasOwnProperty(name)) {
continue;
}
if (name === MIXINS_KEY) {
// We have already handled mixins in a special case above.
continue;
}
var property = spec[name];
var isAlreadyDefined = proto.hasOwnProperty(name);
validateMethodOverride(isAlreadyDefined, name);
if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) {
RESERVED_SPEC_KEYS[name](Constructor, property);
} else {
// Setup methods on prototype:
// The following member methods should not be automatically bound:
// 1. Expected ReactClass methods (in the "interface").
// 2. Overridden methods (that were mixed in).
var isReactClassMethod = ReactClassInterface.hasOwnProperty(name);
var isFunction = typeof property === 'function';
var shouldAutoBind =
isFunction &&
!isReactClassMethod &&
!isAlreadyDefined &&
spec.autobind !== false;
if (shouldAutoBind) {
autoBindPairs.push(name, property);
proto[name] = property;
} else {
if (isAlreadyDefined) {
var specPolicy = ReactClassInterface[name];
// These cases should already be caught by validateMethodOverride.
_invariant(
isReactClassMethod &&
(specPolicy === 'DEFINE_MANY_MERGED' ||
specPolicy === 'DEFINE_MANY'),
'ReactClass: Unexpected spec policy %s for key %s ' +
'when mixing in component specs.',
specPolicy,
name
);
// For methods which are defined more than once, call the existing
// methods before calling the new property, merging if appropriate.
if (specPolicy === 'DEFINE_MANY_MERGED') {
proto[name] = createMergedResultFunction(proto[name], property);
} else if (specPolicy === 'DEFINE_MANY') {
proto[name] = createChainedFunction(proto[name], property);
}
} else {
proto[name] = property;
if (true) {
// Add verbose displayName to the function, which helps when looking
// at profiling tools.
if (typeof property === 'function' && spec.displayName) {
proto[name].displayName = spec.displayName + '_' + name;
}
}
}
}
}
}
}
function mixStaticSpecIntoComponent(Constructor, statics) {
if (!statics) {
return;
}
for (var name in statics) {
var property = statics[name];
if (!statics.hasOwnProperty(name)) {
continue;
}
var isReserved = name in RESERVED_SPEC_KEYS;
_invariant(
!isReserved,
'ReactClass: You are attempting to define a reserved ' +
'property, `%s`, that shouldn\'t be on the "statics" key. Define it ' +
'as an instance property instead; it will still be accessible on the ' +
'constructor.',
name
);
var isInherited = name in Constructor;
_invariant(
!isInherited,
'ReactClass: You are attempting to define ' +
'`%s` on your component more than once. This conflict may be ' +
'due to a mixin.',
name
);
Constructor[name] = property;
}
}
/**
* Merge two objects, but throw if both contain the same key.
*
* @param {object} one The first object, which is mutated.
* @param {object} two The second object
* @return {object} one after it has been mutated to contain everything in two.
*/
function mergeIntoWithNoDuplicateKeys(one, two) {
_invariant(
one && two && typeof one === 'object' && typeof two === 'object',
'mergeIntoWithNoDuplicateKeys(): Cannot merge non-objects.'
);
for (var key in two) {
if (two.hasOwnProperty(key)) {
_invariant(
one[key] === undefined,
'mergeIntoWithNoDuplicateKeys(): ' +
'Tried to merge two objects with the same key: `%s`. This conflict ' +
'may be due to a mixin; in particular, this may be caused by two ' +
'getInitialState() or getDefaultProps() methods returning objects ' +
'with clashing keys.',
key
);
one[key] = two[key];
}
}
return one;
}
/**
* Creates a function that invokes two functions and merges their return values.
*
* @param {function} one Function to invoke first.
* @param {function} two Function to invoke second.
* @return {function} Function that invokes the two argument functions.
* @private
*/
function createMergedResultFunction(one, two) {
return function mergedResult() {
var a = one.apply(this, arguments);
var b = two.apply(this, arguments);
if (a == null) {
return b;
} else if (b == null) {
return a;
}
var c = {};
mergeIntoWithNoDuplicateKeys(c, a);
mergeIntoWithNoDuplicateKeys(c, b);
return c;
};
}
/**
* Creates a function that invokes two functions and ignores their return vales.
*
* @param {function} one Function to invoke first.
* @param {function} two Function to invoke second.
* @return {function} Function that invokes the two argument functions.
* @private
*/
function createChainedFunction(one, two) {
return function chainedFunction() {
one.apply(this, arguments);
two.apply(this, arguments);
};
}
/**
* Binds a method to the component.
*
* @param {object} component Component whose method is going to be bound.
* @param {function} method Method to be bound.
* @return {function} The bound method.
*/
function bindAutoBindMethod(component, method) {
var boundMethod = method.bind(component);
if (true) {
boundMethod.__reactBoundContext = component;
boundMethod.__reactBoundMethod = method;
boundMethod.__reactBoundArguments = null;
var componentName = component.constructor.displayName;
var _bind = boundMethod.bind;
boundMethod.bind = function(newThis) {
for (
var _len = arguments.length,
args = Array(_len > 1 ? _len - 1 : 0),
_key = 1;
_key < _len;
_key++
) {
args[_key - 1] = arguments[_key];
}
// User is trying to bind() an autobound method; we effectively will
// ignore the value of "this" that the user is trying to use, so
// let's warn.
if (newThis !== component && newThis !== null) {
if (true) {
warning(
false,
'bind(): React component methods may only be bound to the ' +
'component instance. See %s',
componentName
);
}
} else if (!args.length) {
if (true) {
warning(
false,
'bind(): You are binding a component method to the component. ' +
'React does this for you automatically in a high-performance ' +
'way, so you can safely remove this call. See %s',
componentName
);
}
return boundMethod;
}
var reboundMethod = _bind.apply(boundMethod, arguments);
reboundMethod.__reactBoundContext = component;
reboundMethod.__reactBoundMethod = method;
reboundMethod.__reactBoundArguments = args;
return reboundMethod;
};
}
return boundMethod;
}
/**
* Binds all auto-bound methods in a component.
*
* @param {object} component Component whose method is going to be bound.
*/
function bindAutoBindMethods(component) {
var pairs = component.__reactAutoBindPairs;
for (var i = 0; i < pairs.length; i += 2) {
var autoBindKey = pairs[i];
var method = pairs[i + 1];
component[autoBindKey] = bindAutoBindMethod(component, method);
}
}
var IsMountedPreMixin = {
componentDidMount: function() {
this.__isMounted = true;
}
};
var IsMountedPostMixin = {
componentWillUnmount: function() {
this.__isMounted = false;
}
};
/**
* Add more to the ReactClass base class. These are all legacy features and
* therefore not already part of the modern ReactComponent.
*/
var ReactClassMixin = {
/**
* TODO: This will be deprecated because state should always keep a consistent
* type signature and the only use case for this, is to avoid that.
*/
replaceState: function(newState, callback) {
this.updater.enqueueReplaceState(this, newState, callback);
},
/**
* Checks whether or not this composite component is mounted.
* @return {boolean} True if mounted, false otherwise.
* @protected
* @final
*/
isMounted: function() {
if (true) {
warning(
this.__didWarnIsMounted,
'%s: isMounted is deprecated. Instead, make sure to clean up ' +
'subscriptions and pending requests in componentWillUnmount to ' +
'prevent memory leaks.',
(this.constructor && this.constructor.displayName) ||
this.name ||
'Component'
);
this.__didWarnIsMounted = true;
}
return !!this.__isMounted;
}
};
var ReactClassComponent = function() {};
_assign(
ReactClassComponent.prototype,
ReactComponent.prototype,
ReactClassMixin
);
/**
* Creates a composite component class given a class specification.
* See https://facebook.github.io/react/docs/top-level-api.html#react.createclass
*
* @param {object} spec Class specification (which must define `render`).
* @return {function} Component constructor function.
* @public
*/
function createClass(spec) {
// To keep our warnings more understandable, we'll use a little hack here to
// ensure that Constructor.name !== 'Constructor'. This makes sure we don't
// unnecessarily identify a class without displayName as 'Constructor'.
var Constructor = identity(function(props, context, updater) {
// This constructor gets overridden by mocks. The argument is used
// by mocks to assert on what gets mounted.
if (true) {
warning(
this instanceof Constructor,
'Something is calling a React component directly. Use a factory or ' +
'JSX instead. See: https://fb.me/react-legacyfactory'
);
}
// Wire up auto-binding
if (this.__reactAutoBindPairs.length) {
bindAutoBindMethods(this);
}
this.props = props;
this.context = context;
this.refs = emptyObject;
this.updater = updater || ReactNoopUpdateQueue;
this.state = null;
// ReactClasses doesn't have constructors. Instead, they use the
// getInitialState and componentWillMount methods for initialization.
var initialState = this.getInitialState ? this.getInitialState() : null;
if (true) {
// We allow auto-mocks to proceed as if they're returning null.
if (
initialState === undefined &&
this.getInitialState._isMockFunction
) {
// This is probably bad practice. Consider warning here and
// deprecating this convenience.
initialState = null;
}
}
_invariant(
typeof initialState === 'object' && !Array.isArray(initialState),
'%s.getInitialState(): must return an object or null',
Constructor.displayName || 'ReactCompositeComponent'
);
this.state = initialState;
});
Constructor.prototype = new ReactClassComponent();
Constructor.prototype.constructor = Constructor;
Constructor.prototype.__reactAutoBindPairs = [];
injectedMixins.forEach(mixSpecIntoComponent.bind(null, Constructor));
mixSpecIntoComponent(Constructor, IsMountedPreMixin);
mixSpecIntoComponent(Constructor, spec);
mixSpecIntoComponent(Constructor, IsMountedPostMixin);
// Initialize the defaultProps property after all mixins have been merged.
if (Constructor.getDefaultProps) {
Constructor.defaultProps = Constructor.getDefaultProps();
}
if (true) {
// This is a tag to indicate that the use of these method names is ok,
// since it's used with createClass. If it's not, then it's likely a
// mistake so we'll warn you to use the static property, property
// initializer or constructor respectively.
if (Constructor.getDefaultProps) {
Constructor.getDefaultProps.isReactClassApproved = {};
}
if (Constructor.prototype.getInitialState) {
Constructor.prototype.getInitialState.isReactClassApproved = {};
}
}
_invariant(
Constructor.prototype.render,
'createClass(...): Class specification must implement a `render` method.'
);
if (true) {
warning(
!Constructor.prototype.componentShouldUpdate,
'%s has a method called ' +
'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' +
'The name is phrased as a question because the function is ' +
'expected to return a value.',
spec.displayName || 'A component'
);
warning(
!Constructor.prototype.componentWillRecieveProps,
'%s has a method called ' +
'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?',
spec.displayName || 'A component'
);
}
// Reduce time spent doing lookups by setting these on the prototype.
for (var methodName in ReactClassInterface) {
if (!Constructor.prototype[methodName]) {
Constructor.prototype[methodName] = null;
}
}
return Constructor;
}
return createClass;
}
module.exports = factory;
/***/ }),
/* 103 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _prodInvariant = __webpack_require__(17);
var ReactElement = __webpack_require__(14);
var invariant = __webpack_require__(0);
/**
* Returns the first child in a collection of children and verifies that there
* is only one child in the collection.
*
* See https://facebook.github.io/react/docs/top-level-api.html#react.children.only
*
* The current implementation of this function assumes that a single child gets
* passed without a wrapper, but the purpose of this helper function is to
* abstract away the particular structure of children.
*
* @param {?object} children Child collection structure.
* @return {ReactElement} The first and only `ReactElement` contained in the
* structure.
*/
function onlyChild(children) {
!ReactElement.isValidElement(children) ? true ? invariant(false, 'React.Children.only expected to receive a single React element child.') : _prodInvariant('143') : void 0;
return children;
}
module.exports = onlyChild;
/***/ }),
/* 104 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
module.exports = __webpack_require__(105);
/***/ }),
/* 105 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
/* globals __REACT_DEVTOOLS_GLOBAL_HOOK__*/
var ReactDOMComponentTree = __webpack_require__(4);
var ReactDefaultInjection = __webpack_require__(106);
var ReactMount = __webpack_require__(82);
var ReactReconciler = __webpack_require__(18);
var ReactUpdates = __webpack_require__(10);
var ReactVersion = __webpack_require__(184);
var findDOMNode = __webpack_require__(185);
var getHostComponentFromComposite = __webpack_require__(83);
var renderSubtreeIntoContainer = __webpack_require__(186);
var warning = __webpack_require__(1);
ReactDefaultInjection.inject();
var ReactDOM = {
findDOMNode: findDOMNode,
render: ReactMount.render,
unmountComponentAtNode: ReactMount.unmountComponentAtNode,
version: ReactVersion,
/* eslint-disable camelcase */
unstable_batchedUpdates: ReactUpdates.batchedUpdates,
unstable_renderSubtreeIntoContainer: renderSubtreeIntoContainer
/* eslint-enable camelcase */
};
// Inject the runtime into a devtools global hook regardless of browser.
// Allows for debugging when the hook is injected on the page.
if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject === 'function') {
__REACT_DEVTOOLS_GLOBAL_HOOK__.inject({
ComponentTree: {
getClosestInstanceFromNode: ReactDOMComponentTree.getClosestInstanceFromNode,
getNodeFromInstance: function (inst) {
// inst is an internal instance (but could be a composite)
if (inst._renderedComponent) {
inst = getHostComponentFromComposite(inst);
}
if (inst) {
return ReactDOMComponentTree.getNodeFromInstance(inst);
} else {
return null;
}
}
},
Mount: ReactMount,
Reconciler: ReactReconciler
});
}
if (true) {
var ExecutionEnvironment = __webpack_require__(5);
if (ExecutionEnvironment.canUseDOM && window.top === window.self) {
// First check if devtools is not installed
if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
// If we're in Chrome or Firefox, provide a download link if not installed.
if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
// Firefox does not have the issue with devtools loaded over file://
var showFileUrlMessage = window.location.protocol.indexOf('http') === -1 && navigator.userAgent.indexOf('Firefox') === -1;
console.debug('Download the React DevTools ' + (showFileUrlMessage ? 'and use an HTTP server (instead of a file: URL) ' : '') + 'for a better development experience: ' + 'https://fb.me/react-devtools');
}
}
var testFunc = function testFn() {};
true ? warning((testFunc.name || testFunc.toString()).indexOf('testFn') !== -1, "It looks like you're using a minified copy of the development build " + 'of React. When deploying React apps to production, make sure to use ' + 'the production build which skips development warnings and is faster. ' + 'See https://fb.me/react-minification for more details.') : void 0;
// If we're in IE8, check to see if we are in compatibility mode and provide
// information on preventing compatibility mode
var ieCompatibilityMode = document.documentMode && document.documentMode < 8;
true ? warning(!ieCompatibilityMode, 'Internet Explorer is running in compatibility mode; please add the ' + 'following tag to your HTML to prevent this from happening: ' + '<meta http-equiv="X-UA-Compatible" content="IE=edge" />') : void 0;
var expectedFeatures = [
// shims
Array.isArray, Array.prototype.every, Array.prototype.forEach, Array.prototype.indexOf, Array.prototype.map, Date.now, Function.prototype.bind, Object.keys, String.prototype.trim];
for (var i = 0; i < expectedFeatures.length; i++) {
if (!expectedFeatures[i]) {
true ? warning(false, 'One or more ES5 shims expected by React are not available: ' + 'https://fb.me/react-warning-polyfills') : void 0;
break;
}
}
}
}
if (true) {
var ReactInstrumentation = __webpack_require__(7);
var ReactDOMUnknownPropertyHook = __webpack_require__(187);
var ReactDOMNullInputValuePropHook = __webpack_require__(188);
var ReactDOMInvalidARIAHook = __webpack_require__(189);
ReactInstrumentation.debugTool.addHook(ReactDOMUnknownPropertyHook);
ReactInstrumentation.debugTool.addHook(ReactDOMNullInputValuePropHook);
ReactInstrumentation.debugTool.addHook(ReactDOMInvalidARIAHook);
}
module.exports = ReactDOM;
/***/ }),
/* 106 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var ARIADOMPropertyConfig = __webpack_require__(107);
var BeforeInputEventPlugin = __webpack_require__(108);
var ChangeEventPlugin = __webpack_require__(112);
var DefaultEventPluginOrder = __webpack_require__(120);
var EnterLeaveEventPlugin = __webpack_require__(121);
var HTMLDOMPropertyConfig = __webpack_require__(122);
var ReactComponentBrowserEnvironment = __webpack_require__(123);
var ReactDOMComponent = __webpack_require__(129);
var ReactDOMComponentTree = __webpack_require__(4);
var ReactDOMEmptyComponent = __webpack_require__(155);
var ReactDOMTreeTraversal = __webpack_require__(156);
var ReactDOMTextComponent = __webpack_require__(157);
var ReactDefaultBatchingStrategy = __webpack_require__(158);
var ReactEventListener = __webpack_require__(159);
var ReactInjection = __webpack_require__(161);
var ReactReconcileTransaction = __webpack_require__(162);
var SVGDOMPropertyConfig = __webpack_require__(168);
var SelectEventPlugin = __webpack_require__(169);
var SimpleEventPlugin = __webpack_require__(170);
var alreadyInjected = false;
function inject() {
if (alreadyInjected) {
// TODO: This is currently true because these injections are shared between
// the client and the server package. They should be built independently
// and not share any injection state. Then this problem will be solved.
return;
}
alreadyInjected = true;
ReactInjection.EventEmitter.injectReactEventListener(ReactEventListener);
/**
* Inject modules for resolving DOM hierarchy and plugin ordering.
*/
ReactInjection.EventPluginHub.injectEventPluginOrder(DefaultEventPluginOrder);
ReactInjection.EventPluginUtils.injectComponentTree(ReactDOMComponentTree);
ReactInjection.EventPluginUtils.injectTreeTraversal(ReactDOMTreeTraversal);
/**
* Some important event plugins included by default (without having to require
* them).
*/
ReactInjection.EventPluginHub.injectEventPluginsByName({
SimpleEventPlugin: SimpleEventPlugin,
EnterLeaveEventPlugin: EnterLeaveEventPlugin,
ChangeEventPlugin: ChangeEventPlugin,
SelectEventPlugin: SelectEventPlugin,
BeforeInputEventPlugin: BeforeInputEventPlugin
});
ReactInjection.HostComponent.injectGenericComponentClass(ReactDOMComponent);
ReactInjection.HostComponent.injectTextComponentClass(ReactDOMTextComponent);
ReactInjection.DOMProperty.injectDOMPropertyConfig(ARIADOMPropertyConfig);
ReactInjection.DOMProperty.injectDOMPropertyConfig(HTMLDOMPropertyConfig);
ReactInjection.DOMProperty.injectDOMPropertyConfig(SVGDOMPropertyConfig);
ReactInjection.EmptyComponent.injectEmptyComponentFactory(function (instantiate) {
return new ReactDOMEmptyComponent(instantiate);
});
ReactInjection.Updates.injectReconcileTransaction(ReactReconcileTransaction);
ReactInjection.Updates.injectBatchingStrategy(ReactDefaultBatchingStrategy);
ReactInjection.Component.injectEnvironment(ReactComponentBrowserEnvironment);
}
module.exports = {
inject: inject
};
/***/ }),
/* 107 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var ARIADOMPropertyConfig = {
Properties: {
// Global States and Properties
'aria-current': 0, // state
'aria-details': 0,
'aria-disabled': 0, // state
'aria-hidden': 0, // state
'aria-invalid': 0, // state
'aria-keyshortcuts': 0,
'aria-label': 0,
'aria-roledescription': 0,
// Widget Attributes
'aria-autocomplete': 0,
'aria-checked': 0,
'aria-expanded': 0,
'aria-haspopup': 0,
'aria-level': 0,
'aria-modal': 0,
'aria-multiline': 0,
'aria-multiselectable': 0,
'aria-orientation': 0,
'aria-placeholder': 0,
'aria-pressed': 0,
'aria-readonly': 0,
'aria-required': 0,
'aria-selected': 0,
'aria-sort': 0,
'aria-valuemax': 0,
'aria-valuemin': 0,
'aria-valuenow': 0,
'aria-valuetext': 0,
// Live Region Attributes
'aria-atomic': 0,
'aria-busy': 0,
'aria-live': 0,
'aria-relevant': 0,
// Drag-and-Drop Attributes
'aria-dropeffect': 0,
'aria-grabbed': 0,
// Relationship Attributes
'aria-activedescendant': 0,
'aria-colcount': 0,
'aria-colindex': 0,
'aria-colspan': 0,
'aria-controls': 0,
'aria-describedby': 0,
'aria-errormessage': 0,
'aria-flowto': 0,
'aria-labelledby': 0,
'aria-owns': 0,
'aria-posinset': 0,
'aria-rowcount': 0,
'aria-rowindex': 0,
'aria-rowspan': 0,
'aria-setsize': 0
},
DOMAttributeNames: {},
DOMPropertyNames: {}
};
module.exports = ARIADOMPropertyConfig;
/***/ }),
/* 108 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var EventPropagators = __webpack_require__(20);
var ExecutionEnvironment = __webpack_require__(5);
var FallbackCompositionState = __webpack_require__(109);
var SyntheticCompositionEvent = __webpack_require__(110);
var SyntheticInputEvent = __webpack_require__(111);
var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
var START_KEYCODE = 229;
var canUseCompositionEvent = ExecutionEnvironment.canUseDOM && 'CompositionEvent' in window;
var documentMode = null;
if (ExecutionEnvironment.canUseDOM && 'documentMode' in document) {
documentMode = document.documentMode;
}
// Webkit offers a very useful `textInput` event that can be used to
// directly represent `beforeInput`. The IE `textinput` event is not as
// useful, so we don't use it.
var canUseTextInputEvent = ExecutionEnvironment.canUseDOM && 'TextEvent' in window && !documentMode && !isPresto();
// In IE9+, we have access to composition events, but the data supplied
// by the native compositionend event may be incorrect. Japanese ideographic
// spaces, for instance (\u3000) are not recorded correctly.
var useFallbackCompositionData = ExecutionEnvironment.canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11);
/**
* Opera <= 12 includes TextEvent in window, but does not fire
* text input events. Rely on keypress instead.
*/
function isPresto() {
var opera = window.opera;
return typeof opera === 'object' && typeof opera.version === 'function' && parseInt(opera.version(), 10) <= 12;
}
var SPACEBAR_CODE = 32;
var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);
// Events and their corresponding property names.
var eventTypes = {
beforeInput: {
phasedRegistrationNames: {
bubbled: 'onBeforeInput',
captured: 'onBeforeInputCapture'
},
dependencies: ['topCompositionEnd', 'topKeyPress', 'topTextInput', 'topPaste']
},
compositionEnd: {
phasedRegistrationNames: {
bubbled: 'onCompositionEnd',
captured: 'onCompositionEndCapture'
},
dependencies: ['topBlur', 'topCompositionEnd', 'topKeyDown', 'topKeyPress', 'topKeyUp', 'topMouseDown']
},
compositionStart: {
phasedRegistrationNames: {
bubbled: 'onCompositionStart',
captured: 'onCompositionStartCapture'
},
dependencies: ['topBlur', 'topCompositionStart', 'topKeyDown', 'topKeyPress', 'topKeyUp', 'topMouseDown']
},
compositionUpdate: {
phasedRegistrationNames: {
bubbled: 'onCompositionUpdate',
captured: 'onCompositionUpdateCapture'
},
dependencies: ['topBlur', 'topCompositionUpdate', 'topKeyDown', 'topKeyPress', 'topKeyUp', 'topMouseDown']
}
};
// Track whether we've ever handled a keypress on the space key.
var hasSpaceKeypress = false;
/**
* Return whether a native keypress event is assumed to be a command.
* This is required because Firefox fires `keypress` events for key commands
* (cut, copy, select-all, etc.) even though no character is inserted.
*/
function isKeypressCommand(nativeEvent) {
return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) &&
// ctrlKey && altKey is equivalent to AltGr, and is not a command.
!(nativeEvent.ctrlKey && nativeEvent.altKey);
}
/**
* Translate native top level events into event types.
*
* @param {string} topLevelType
* @return {object}
*/
function getCompositionEventType(topLevelType) {
switch (topLevelType) {
case 'topCompositionStart':
return eventTypes.compositionStart;
case 'topCompositionEnd':
return eventTypes.compositionEnd;
case 'topCompositionUpdate':
return eventTypes.compositionUpdate;
}
}
/**
* Does our fallback best-guess model think this event signifies that
* composition has begun?
*
* @param {string} topLevelType
* @param {object} nativeEvent
* @return {boolean}
*/
function isFallbackCompositionStart(topLevelType, nativeEvent) {
return topLevelType === 'topKeyDown' && nativeEvent.keyCode === START_KEYCODE;
}
/**
* Does our fallback mode think that this event is the end of composition?
*
* @param {string} topLevelType
* @param {object} nativeEvent
* @return {boolean}
*/
function isFallbackCompositionEnd(topLevelType, nativeEvent) {
switch (topLevelType) {
case 'topKeyUp':
// Command keys insert or clear IME input.
return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
case 'topKeyDown':
// Expect IME keyCode on each keydown. If we get any other
// code we must have exited earlier.
return nativeEvent.keyCode !== START_KEYCODE;
case 'topKeyPress':
case 'topMouseDown':
case 'topBlur':
// Events are not possible without cancelling IME.
return true;
default:
return false;
}
}
/**
* Google Input Tools provides composition data via a CustomEvent,
* with the `data` property populated in the `detail` object. If this
* is available on the event object, use it. If not, this is a plain
* composition event and we have nothing special to extract.
*
* @param {object} nativeEvent
* @return {?string}
*/
function getDataFromCustomEvent(nativeEvent) {
var detail = nativeEvent.detail;
if (typeof detail === 'object' && 'data' in detail) {
return detail.data;
}
return null;
}
// Track the current IME composition fallback object, if any.
var currentComposition = null;
/**
* @return {?object} A SyntheticCompositionEvent.
*/
function extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
var eventType;
var fallbackData;
if (canUseCompositionEvent) {
eventType = getCompositionEventType(topLevelType);
} else if (!currentComposition) {
if (isFallbackCompositionStart(topLevelType, nativeEvent)) {
eventType = eventTypes.compositionStart;
}
} else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) {
eventType = eventTypes.compositionEnd;
}
if (!eventType) {
return null;
}
if (useFallbackCompositionData) {
// The current composition is stored statically and must not be
// overwritten while composition continues.
if (!currentComposition && eventType === eventTypes.compositionStart) {
currentComposition = FallbackCompositionState.getPooled(nativeEventTarget);
} else if (eventType === eventTypes.compositionEnd) {
if (currentComposition) {
fallbackData = currentComposition.getData();
}
}
}
var event = SyntheticCompositionEvent.getPooled(eventType, targetInst, nativeEvent, nativeEventTarget);
if (fallbackData) {
// Inject data generated from fallback path into the synthetic event.
// This matches the property of native CompositionEventInterface.
event.data = fallbackData;
} else {
var customData = getDataFromCustomEvent(nativeEvent);
if (customData !== null) {
event.data = customData;
}
}
EventPropagators.accumulateTwoPhaseDispatches(event);
return event;
}
/**
* @param {string} topLevelType Record from `EventConstants`.
* @param {object} nativeEvent Native browser event.
* @return {?string} The string corresponding to this `beforeInput` event.
*/
function getNativeBeforeInputChars(topLevelType, nativeEvent) {
switch (topLevelType) {
case 'topCompositionEnd':
return getDataFromCustomEvent(nativeEvent);
case 'topKeyPress':
/**
* If native `textInput` events are available, our goal is to make
* use of them. However, there is a special case: the spacebar key.
* In Webkit, preventing default on a spacebar `textInput` event
* cancels character insertion, but it *also* causes the browser
* to fall back to its default spacebar behavior of scrolling the
* page.
*
* Tracking at:
* https://code.google.com/p/chromium/issues/detail?id=355103
*
* To avoid this issue, use the keypress event as if no `textInput`
* event is available.
*/
var which = nativeEvent.which;
if (which !== SPACEBAR_CODE) {
return null;
}
hasSpaceKeypress = true;
return SPACEBAR_CHAR;
case 'topTextInput':
// Record the characters to be added to the DOM.
var chars = nativeEvent.data;
// If it's a spacebar character, assume that we have already handled
// it at the keypress level and bail immediately. Android Chrome
// doesn't give us keycodes, so we need to blacklist it.
if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {
return null;
}
return chars;
default:
// For other native event types, do nothing.
return null;
}
}
/**
* For browsers that do not provide the `textInput` event, extract the
* appropriate string to use for SyntheticInputEvent.
*
* @param {string} topLevelType Record from `EventConstants`.
* @param {object} nativeEvent Native browser event.
* @return {?string} The fallback string for this `beforeInput` event.
*/
function getFallbackBeforeInputChars(topLevelType, nativeEvent) {
// If we are currently composing (IME) and using a fallback to do so,
// try to extract the composed characters from the fallback object.
// If composition event is available, we extract a string only at
// compositionevent, otherwise extract it at fallback events.
if (currentComposition) {
if (topLevelType === 'topCompositionEnd' || !canUseCompositionEvent && isFallbackCompositionEnd(topLevelType, nativeEvent)) {
var chars = currentComposition.getData();
FallbackCompositionState.release(currentComposition);
currentComposition = null;
return chars;
}
return null;
}
switch (topLevelType) {
case 'topPaste':
// If a paste event occurs after a keypress, throw out the input
// chars. Paste events should not lead to BeforeInput events.
return null;
case 'topKeyPress':
/**
* As of v27, Firefox may fire keypress events even when no character
* will be inserted. A few possibilities:
*
* - `which` is `0`. Arrow keys, Esc key, etc.
*
* - `which` is the pressed key code, but no char is available.
* Ex: 'AltGr + d` in Polish. There is no modified character for
* this key combination and no character is inserted into the
* document, but FF fires the keypress for char code `100` anyway.
* No `input` event will occur.
*
* - `which` is the pressed key code, but a command combination is
* being used. Ex: `Cmd+C`. No character is inserted, and no
* `input` event will occur.
*/
if (nativeEvent.which && !isKeypressCommand(nativeEvent)) {
return String.fromCharCode(nativeEvent.which);
}
return null;
case 'topCompositionEnd':
return useFallbackCompositionData ? null : nativeEvent.data;
default:
return null;
}
}
/**
* Extract a SyntheticInputEvent for `beforeInput`, based on either native
* `textInput` or fallback behavior.
*
* @return {?object} A SyntheticInputEvent.
*/
function extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
var chars;
if (canUseTextInputEvent) {
chars = getNativeBeforeInputChars(topLevelType, nativeEvent);
} else {
chars = getFallbackBeforeInputChars(topLevelType, nativeEvent);
}
// If no characters are being inserted, no BeforeInput event should
// be fired.
if (!chars) {
return null;
}
var event = SyntheticInputEvent.getPooled(eventTypes.beforeInput, targetInst, nativeEvent, nativeEventTarget);
event.data = chars;
EventPropagators.accumulateTwoPhaseDispatches(event);
return event;
}
/**
* Create an `onBeforeInput` event to match
* http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.
*
* This event plugin is based on the native `textInput` event
* available in Chrome, Safari, Opera, and IE. This event fires after
* `onKeyPress` and `onCompositionEnd`, but before `onInput`.
*
* `beforeInput` is spec'd but not implemented in any browsers, and
* the `input` event does not provide any useful information about what has
* actually been added, contrary to the spec. Thus, `textInput` is the best
* available event to identify the characters that have actually been inserted
* into the target node.
*
* This plugin is also responsible for emitting `composition` events, thus
* allowing us to share composition fallback code for both `beforeInput` and
* `composition` event types.
*/
var BeforeInputEventPlugin = {
eventTypes: eventTypes,
extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
return [extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget), extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget)];
}
};
module.exports = BeforeInputEventPlugin;
/***/ }),
/* 109 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _assign = __webpack_require__(3);
var PooledClass = __webpack_require__(15);
var getTextContentAccessor = __webpack_require__(62);
/**
* This helper class stores information about text content of a target node,
* allowing comparison of content before and after a given event.
*
* Identify the node where selection currently begins, then observe
* both its text content and its current position in the DOM. Since the
* browser may natively replace the target node during composition, we can
* use its position to find its replacement.
*
* @param {DOMEventTarget} root
*/
function FallbackCompositionState(root) {
this._root = root;
this._startText = this.getText();
this._fallbackText = null;
}
_assign(FallbackCompositionState.prototype, {
destructor: function () {
this._root = null;
this._startText = null;
this._fallbackText = null;
},
/**
* Get current text of input.
*
* @return {string}
*/
getText: function () {
if ('value' in this._root) {
return this._root.value;
}
return this._root[getTextContentAccessor()];
},
/**
* Determine the differing substring between the initially stored
* text content and the current content.
*
* @return {string}
*/
getData: function () {
if (this._fallbackText) {
return this._fallbackText;
}
var start;
var startValue = this._startText;
var startLength = startValue.length;
var end;
var endValue = this.getText();
var endLength = endValue.length;
for (start = 0; start < startLength; start++) {
if (startValue[start] !== endValue[start]) {
break;
}
}
var minEnd = startLength - start;
for (end = 1; end <= minEnd; end++) {
if (startValue[startLength - end] !== endValue[endLength - end]) {
break;
}
}
var sliceTail = end > 1 ? 1 - end : undefined;
this._fallbackText = endValue.slice(start, sliceTail);
return this._fallbackText;
}
});
PooledClass.addPoolingTo(FallbackCompositionState);
module.exports = FallbackCompositionState;
/***/ }),
/* 110 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var SyntheticEvent = __webpack_require__(12);
/**
* @interface Event
* @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
*/
var CompositionEventInterface = {
data: null
};
/**
* @param {object} dispatchConfig Configuration used to dispatch this event.
* @param {string} dispatchMarker Marker identifying the event target.
* @param {object} nativeEvent Native browser event.
* @extends {SyntheticUIEvent}
*/
function SyntheticCompositionEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {
return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);
}
SyntheticEvent.augmentClass(SyntheticCompositionEvent, CompositionEventInterface);
module.exports = SyntheticCompositionEvent;
/***/ }),
/* 111 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var SyntheticEvent = __webpack_require__(12);
/**
* @interface Event
* @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
* /#events-inputevents
*/
var InputEventInterface = {
data: null
};
/**
* @param {object} dispatchConfig Configuration used to dispatch this event.
* @param {string} dispatchMarker Marker identifying the event target.
* @param {object} nativeEvent Native browser event.
* @extends {SyntheticUIEvent}
*/
function SyntheticInputEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {
return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);
}
SyntheticEvent.augmentClass(SyntheticInputEvent, InputEventInterface);
module.exports = SyntheticInputEvent;
/***/ }),
/* 112 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var EventPluginHub = __webpack_require__(21);
var EventPropagators = __webpack_require__(20);
var ExecutionEnvironment = __webpack_require__(5);
var ReactDOMComponentTree = __webpack_require__(4);
var ReactUpdates = __webpack_require__(10);
var SyntheticEvent = __webpack_require__(12);
var inputValueTracking = __webpack_require__(65);
var getEventTarget = __webpack_require__(38);
var isEventSupported = __webpack_require__(39);
var isTextInputElement = __webpack_require__(66);
var eventTypes = {
change: {
phasedRegistrationNames: {
bubbled: 'onChange',
captured: 'onChangeCapture'
},
dependencies: ['topBlur', 'topChange', 'topClick', 'topFocus', 'topInput', 'topKeyDown', 'topKeyUp', 'topSelectionChange']
}
};
function createAndAccumulateChangeEvent(inst, nativeEvent, target) {
var event = SyntheticEvent.getPooled(eventTypes.change, inst, nativeEvent, target);
event.type = 'change';
EventPropagators.accumulateTwoPhaseDispatches(event);
return event;
}
/**
* For IE shims
*/
var activeElement = null;
var activeElementInst = null;
/**
* SECTION: handle `change` event
*/
function shouldUseChangeEvent(elem) {
var nodeName = elem.nodeName && elem.nodeName.toLowerCase();
return nodeName === 'select' || nodeName === 'input' && elem.type === 'file';
}
var doesChangeEventBubble = false;
if (ExecutionEnvironment.canUseDOM) {
// See `handleChange` comment below
doesChangeEventBubble = isEventSupported('change') && (!document.documentMode || document.documentMode > 8);
}
function manualDispatchChangeEvent(nativeEvent) {
var event = createAndAccumulateChangeEvent(activeElementInst, nativeEvent, getEventTarget(nativeEvent));
// If change and propertychange bubbled, we'd just bind to it like all the
// other events and have it go through ReactBrowserEventEmitter. Since it
// doesn't, we manually listen for the events and so we have to enqueue and
// process the abstract event manually.
//
// Batching is necessary here in order to ensure that all event handlers run
// before the next rerender (including event handlers attached to ancestor
// elements instead of directly on the input). Without this, controlled
// components don't work properly in conjunction with event bubbling because
// the component is rerendered and the value reverted before all the event
// handlers can run. See https://github.com/facebook/react/issues/708.
ReactUpdates.batchedUpdates(runEventInBatch, event);
}
function runEventInBatch(event) {
EventPluginHub.enqueueEvents(event);
EventPluginHub.processEventQueue(false);
}
function startWatchingForChangeEventIE8(target, targetInst) {
activeElement = target;
activeElementInst = targetInst;
activeElement.attachEvent('onchange', manualDispatchChangeEvent);
}
function stopWatchingForChangeEventIE8() {
if (!activeElement) {
return;
}
activeElement.detachEvent('onchange', manualDispatchChangeEvent);
activeElement = null;
activeElementInst = null;
}
function getInstIfValueChanged(targetInst, nativeEvent) {
var updated = inputValueTracking.updateValueIfChanged(targetInst);
var simulated = nativeEvent.simulated === true && ChangeEventPlugin._allowSimulatedPassThrough;
if (updated || simulated) {
return targetInst;
}
}
function getTargetInstForChangeEvent(topLevelType, targetInst) {
if (topLevelType === 'topChange') {
return targetInst;
}
}
function handleEventsForChangeEventIE8(topLevelType, target, targetInst) {
if (topLevelType === 'topFocus') {
// stopWatching() should be a noop here but we call it just in case we
// missed a blur event somehow.
stopWatchingForChangeEventIE8();
startWatchingForChangeEventIE8(target, targetInst);
} else if (topLevelType === 'topBlur') {
stopWatchingForChangeEventIE8();
}
}
/**
* SECTION: handle `input` event
*/
var isInputEventSupported = false;
if (ExecutionEnvironment.canUseDOM) {
// IE9 claims to support the input event but fails to trigger it when
// deleting text, so we ignore its input events.
isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9);
}
/**
* (For IE <=9) Starts tracking propertychange events on the passed-in element
* and override the value property so that we can distinguish user events from
* value changes in JS.
*/
function startWatchingForValueChange(target, targetInst) {
activeElement = target;
activeElementInst = targetInst;
activeElement.attachEvent('onpropertychange', handlePropertyChange);
}
/**
* (For IE <=9) Removes the event listeners from the currently-tracked element,
* if any exists.
*/
function stopWatchingForValueChange() {
if (!activeElement) {
return;
}
activeElement.detachEvent('onpropertychange', handlePropertyChange);
activeElement = null;
activeElementInst = null;
}
/**
* (For IE <=9) Handles a propertychange event, sending a `change` event if
* the value of the active element has changed.
*/
function handlePropertyChange(nativeEvent) {
if (nativeEvent.propertyName !== 'value') {
return;
}
if (getInstIfValueChanged(activeElementInst, nativeEvent)) {
manualDispatchChangeEvent(nativeEvent);
}
}
function handleEventsForInputEventPolyfill(topLevelType, target, targetInst) {
if (topLevelType === 'topFocus') {
// In IE8, we can capture almost all .value changes by adding a
// propertychange handler and looking for events with propertyName
// equal to 'value'
// In IE9, propertychange fires for most input events but is buggy and
// doesn't fire when text is deleted, but conveniently, selectionchange
// appears to fire in all of the remaining cases so we catch those and
// forward the event if the value has changed
// In either case, we don't want to call the event handler if the value
// is changed from JS so we redefine a setter for `.value` that updates
// our activeElementValue variable, allowing us to ignore those changes
//
// stopWatching() should be a noop here but we call it just in case we
// missed a blur event somehow.
stopWatchingForValueChange();
startWatchingForValueChange(target, targetInst);
} else if (topLevelType === 'topBlur') {
stopWatchingForValueChange();
}
}
// For IE8 and IE9.
function getTargetInstForInputEventPolyfill(topLevelType, targetInst, nativeEvent) {
if (topLevelType === 'topSelectionChange' || topLevelType === 'topKeyUp' || topLevelType === 'topKeyDown') {
// On the selectionchange event, the target is just document which isn't
// helpful for us so just check activeElement instead.
//
// 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
// propertychange on the first input event after setting `value` from a
// script and fires only keydown, keypress, keyup. Catching keyup usually
// gets it and catching keydown lets us fire an event for the first
// keystroke if user does a key repeat (it'll be a little delayed: right
// before the second keystroke). Other input methods (e.g., paste) seem to
// fire selectionchange normally.
return getInstIfValueChanged(activeElementInst, nativeEvent);
}
}
/**
* SECTION: handle `click` event
*/
function shouldUseClickEvent(elem) {
// Use the `click` event to detect changes to checkbox and radio inputs.
// This approach works across all browsers, whereas `change` does not fire
// until `blur` in IE8.
var nodeName = elem.nodeName;
return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio');
}
function getTargetInstForClickEvent(topLevelType, targetInst, nativeEvent) {
if (topLevelType === 'topClick') {
return getInstIfValueChanged(targetInst, nativeEvent);
}
}
function getTargetInstForInputOrChangeEvent(topLevelType, targetInst, nativeEvent) {
if (topLevelType === 'topInput' || topLevelType === 'topChange') {
return getInstIfValueChanged(targetInst, nativeEvent);
}
}
function handleControlledInputBlur(inst, node) {
// TODO: In IE, inst is occasionally null. Why?
if (inst == null) {
return;
}
// Fiber and ReactDOM keep wrapper state in separate places
var state = inst._wrapperState || node._wrapperState;
if (!state || !state.controlled || node.type !== 'number') {
return;
}
// If controlled, assign the value attribute to the current value on blur
var value = '' + node.value;
if (node.getAttribute('value') !== value) {
node.setAttribute('value', value);
}
}
/**
* This plugin creates an `onChange` event that normalizes change events
* across form elements. This event fires at a time when it's possible to
* change the element's value without seeing a flicker.
*
* Supported elements are:
* - input (see `isTextInputElement`)
* - textarea
* - select
*/
var ChangeEventPlugin = {
eventTypes: eventTypes,
_allowSimulatedPassThrough: true,
_isInputEventSupported: isInputEventSupported,
extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
var targetNode = targetInst ? ReactDOMComponentTree.getNodeFromInstance(targetInst) : window;
var getTargetInstFunc, handleEventFunc;
if (shouldUseChangeEvent(targetNode)) {
if (doesChangeEventBubble) {
getTargetInstFunc = getTargetInstForChangeEvent;
} else {
handleEventFunc = handleEventsForChangeEventIE8;
}
} else if (isTextInputElement(targetNode)) {
if (isInputEventSupported) {
getTargetInstFunc = getTargetInstForInputOrChangeEvent;
} else {
getTargetInstFunc = getTargetInstForInputEventPolyfill;
handleEventFunc = handleEventsForInputEventPolyfill;
}
} else if (shouldUseClickEvent(targetNode)) {
getTargetInstFunc = getTargetInstForClickEvent;
}
if (getTargetInstFunc) {
var inst = getTargetInstFunc(topLevelType, targetInst, nativeEvent);
if (inst) {
var event = createAndAccumulateChangeEvent(inst, nativeEvent, nativeEventTarget);
return event;
}
}
if (handleEventFunc) {
handleEventFunc(topLevelType, targetNode, targetInst);
}
// When blurring, set the value attribute for number inputs
if (topLevelType === 'topBlur') {
handleControlledInputBlur(targetInst, targetNode);
}
}
};
module.exports = ChangeEventPlugin;
/***/ }),
/* 113 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var ReactOwner = __webpack_require__(114);
var ReactRef = {};
function attachRef(ref, component, owner) {
if (typeof ref === 'function') {
ref(component.getPublicInstance());
} else {
// Legacy ref
ReactOwner.addComponentAsRefTo(component, ref, owner);
}
}
function detachRef(ref, component, owner) {
if (typeof ref === 'function') {
ref(null);
} else {
// Legacy ref
ReactOwner.removeComponentAsRefFrom(component, ref, owner);
}
}
ReactRef.attachRefs = function (instance, element) {
if (element === null || typeof element !== 'object') {
return;
}
var ref = element.ref;
if (ref != null) {
attachRef(ref, instance, element._owner);
}
};
ReactRef.shouldUpdateRefs = function (prevElement, nextElement) {
// If either the owner or a `ref` has changed, make sure the newest owner
// has stored a reference to `this`, and the previous owner (if different)
// has forgotten the reference to `this`. We use the element instead
// of the public this.props because the post processing cannot determine
// a ref. The ref conceptually lives on the element.
// TODO: Should this even be possible? The owner cannot change because
// it's forbidden by shouldUpdateReactComponent. The ref can change
// if you swap the keys of but not the refs. Reconsider where this check
// is made. It probably belongs where the key checking and
// instantiateReactComponent is done.
var prevRef = null;
var prevOwner = null;
if (prevElement !== null && typeof prevElement === 'object') {
prevRef = prevElement.ref;
prevOwner = prevElement._owner;
}
var nextRef = null;
var nextOwner = null;
if (nextElement !== null && typeof nextElement === 'object') {
nextRef = nextElement.ref;
nextOwner = nextElement._owner;
}
return prevRef !== nextRef ||
// If owner changes but we have an unchanged function ref, don't update refs
typeof nextRef === 'string' && nextOwner !== prevOwner;
};
ReactRef.detachRefs = function (instance, element) {
if (element === null || typeof element !== 'object') {
return;
}
var ref = element.ref;
if (ref != null) {
detachRef(ref, instance, element._owner);
}
};
module.exports = ReactRef;
/***/ }),
/* 114 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var _prodInvariant = __webpack_require__(2);
var invariant = __webpack_require__(0);
/**
* @param {?object} object
* @return {boolean} True if `object` is a valid owner.
* @final
*/
function isValidOwner(object) {
return !!(object && typeof object.attachRef === 'function' && typeof object.detachRef === 'function');
}
/**
* ReactOwners are capable of storing references to owned components.
*
* All components are capable of //being// referenced by owner components, but
* only ReactOwner components are capable of //referencing// owned components.
* The named reference is known as a "ref".
*
* Refs are available when mounted and updated during reconciliation.
*
* var MyComponent = React.createClass({
* render: function() {
* return (
* <div onClick={this.handleClick}>
* <CustomComponent ref="custom" />
* </div>
* );
* },
* handleClick: function() {
* this.refs.custom.handleClick();
* },
* componentDidMount: function() {
* this.refs.custom.initialize();
* }
* });
*
* Refs should rarely be used. When refs are used, they should only be done to
* control data that is not handled by React's data flow.
*
* @class ReactOwner
*/
var ReactOwner = {
/**
* Adds a component by ref to an owner component.
*
* @param {ReactComponent} component Component to reference.
* @param {string} ref Name by which to refer to the component.
* @param {ReactOwner} owner Component on which to record the ref.
* @final
* @internal
*/
addComponentAsRefTo: function (component, ref, owner) {
!isValidOwner(owner) ? true ? invariant(false, 'addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component\'s `render` method, or you have multiple copies of React loaded (details: https://fb.me/react-refs-must-have-owner).') : _prodInvariant('119') : void 0;
owner.attachRef(ref, component);
},
/**
* Removes a component by ref from an owner component.
*
* @param {ReactComponent} component Component to dereference.
* @param {string} ref Name of the ref to remove.
* @param {ReactOwner} owner Component on which the ref is recorded.
* @final
* @internal
*/
removeComponentAsRefFrom: function (component, ref, owner) {
!isValidOwner(owner) ? true ? invariant(false, 'removeComponentAsRefFrom(...): Only a ReactOwner can have refs. You might be removing a ref to a component that was not created inside a component\'s `render` method, or you have multiple copies of React loaded (details: https://fb.me/react-refs-must-have-owner).') : _prodInvariant('120') : void 0;
var ownerPublicInstance = owner.getPublicInstance();
// Check that `component`'s owner is still alive and that `component` is still the current ref
// because we do not want to detach the ref if another component stole it.
if (ownerPublicInstance && ownerPublicInstance.refs[ref] === component.getPublicInstance()) {
owner.detachRef(ref);
}
}
};
module.exports = ReactOwner;
/***/ }),
/* 115 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2016-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var ReactInvalidSetStateWarningHook = __webpack_require__(116);
var ReactHostOperationHistoryHook = __webpack_require__(117);
var ReactComponentTreeHook = __webpack_require__(6);
var ExecutionEnvironment = __webpack_require__(5);
var performanceNow = __webpack_require__(118);
var warning = __webpack_require__(1);
var hooks = [];
var didHookThrowForEvent = {};
function callHook(event, fn, context, arg1, arg2, arg3, arg4, arg5) {
try {
fn.call(context, arg1, arg2, arg3, arg4, arg5);
} catch (e) {
true ? warning(didHookThrowForEvent[event], 'Exception thrown by hook while handling %s: %s', event, e + '\n' + e.stack) : void 0;
didHookThrowForEvent[event] = true;
}
}
function emitEvent(event, arg1, arg2, arg3, arg4, arg5) {
for (var i = 0; i < hooks.length; i++) {
var hook = hooks[i];
var fn = hook[event];
if (fn) {
callHook(event, fn, hook, arg1, arg2, arg3, arg4, arg5);
}
}
}
var isProfiling = false;
var flushHistory = [];
var lifeCycleTimerStack = [];
var currentFlushNesting = 0;
var currentFlushMeasurements = [];
var currentFlushStartTime = 0;
var currentTimerDebugID = null;
var currentTimerStartTime = 0;
var currentTimerNestedFlushDuration = 0;
var currentTimerType = null;
var lifeCycleTimerHasWarned = false;
function clearHistory() {
ReactComponentTreeHook.purgeUnmountedComponents();
ReactHostOperationHistoryHook.clearHistory();
}
function getTreeSnapshot(registeredIDs) {
return registeredIDs.reduce(function (tree, id) {
var ownerID = ReactComponentTreeHook.getOwnerID(id);
var parentID = ReactComponentTreeHook.getParentID(id);
tree[id] = {
displayName: ReactComponentTreeHook.getDisplayName(id),
text: ReactComponentTreeHook.getText(id),
updateCount: ReactComponentTreeHook.getUpdateCount(id),
childIDs: ReactComponentTreeHook.getChildIDs(id),
// Text nodes don't have owners but this is close enough.
ownerID: ownerID || parentID && ReactComponentTreeHook.getOwnerID(parentID) || 0,
parentID: parentID
};
return tree;
}, {});
}
function resetMeasurements() {
var previousStartTime = currentFlushStartTime;
var previousMeasurements = currentFlushMeasurements;
var previousOperations = ReactHostOperationHistoryHook.getHistory();
if (currentFlushNesting === 0) {
currentFlushStartTime = 0;
currentFlushMeasurements = [];
clearHistory();
return;
}
if (previousMeasurements.length || previousOperations.length) {
var registeredIDs = ReactComponentTreeHook.getRegisteredIDs();
flushHistory.push({
duration: performanceNow() - previousStartTime,
measurements: previousMeasurements || [],
operations: previousOperations || [],
treeSnapshot: getTreeSnapshot(registeredIDs)
});
}
clearHistory();
currentFlushStartTime = performanceNow();
currentFlushMeasurements = [];
}
function checkDebugID(debugID) {
var allowRoot = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
if (allowRoot && debugID === 0) {
return;
}
if (!debugID) {
true ? warning(false, 'ReactDebugTool: debugID may not be empty.') : void 0;
}
}
function beginLifeCycleTimer(debugID, timerType) {
if (currentFlushNesting === 0) {
return;
}
if (currentTimerType && !lifeCycleTimerHasWarned) {
true ? warning(false, 'There is an internal error in the React performance measurement code. ' + 'Did not expect %s timer to start while %s timer is still in ' + 'progress for %s instance.', timerType, currentTimerType || 'no', debugID === currentTimerDebugID ? 'the same' : 'another') : void 0;
lifeCycleTimerHasWarned = true;
}
currentTimerStartTime = performanceNow();
currentTimerNestedFlushDuration = 0;
currentTimerDebugID = debugID;
currentTimerType = timerType;
}
function endLifeCycleTimer(debugID, timerType) {
if (currentFlushNesting === 0) {
return;
}
if (currentTimerType !== timerType && !lifeCycleTimerHasWarned) {
true ? warning(false, 'There is an internal error in the React performance measurement code. ' + 'We did not expect %s timer to stop while %s timer is still in ' + 'progress for %s instance. Please report this as a bug in React.', timerType, currentTimerType || 'no', debugID === currentTimerDebugID ? 'the same' : 'another') : void 0;
lifeCycleTimerHasWarned = true;
}
if (isProfiling) {
currentFlushMeasurements.push({
timerType: timerType,
instanceID: debugID,
duration: performanceNow() - currentTimerStartTime - currentTimerNestedFlushDuration
});
}
currentTimerStartTime = 0;
currentTimerNestedFlushDuration = 0;
currentTimerDebugID = null;
currentTimerType = null;
}
function pauseCurrentLifeCycleTimer() {
var currentTimer = {
startTime: currentTimerStartTime,
nestedFlushStartTime: performanceNow(),
debugID: currentTimerDebugID,
timerType: currentTimerType
};
lifeCycleTimerStack.push(currentTimer);
currentTimerStartTime = 0;
currentTimerNestedFlushDuration = 0;
currentTimerDebugID = null;
currentTimerType = null;
}
function resumeCurrentLifeCycleTimer() {
var _lifeCycleTimerStack$ = lifeCycleTimerStack.pop(),
startTime = _lifeCycleTimerStack$.startTime,
nestedFlushStartTime = _lifeCycleTimerStack$.nestedFlushStartTime,
debugID = _lifeCycleTimerStack$.debugID,
timerType = _lifeCycleTimerStack$.timerType;
var nestedFlushDuration = performanceNow() - nestedFlushStartTime;
currentTimerStartTime = startTime;
currentTimerNestedFlushDuration += nestedFlushDuration;
currentTimerDebugID = debugID;
currentTimerType = timerType;
}
var lastMarkTimeStamp = 0;
var canUsePerformanceMeasure = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function';
function shouldMark(debugID) {
if (!isProfiling || !canUsePerformanceMeasure) {
return false;
}
var element = ReactComponentTreeHook.getElement(debugID);
if (element == null || typeof element !== 'object') {
return false;
}
var isHostElement = typeof element.type === 'string';
if (isHostElement) {
return false;
}
return true;
}
function markBegin(debugID, markType) {
if (!shouldMark(debugID)) {
return;
}
var markName = debugID + '::' + markType;
lastMarkTimeStamp = performanceNow();
performance.mark(markName);
}
function markEnd(debugID, markType) {
if (!shouldMark(debugID)) {
return;
}
var markName = debugID + '::' + markType;
var displayName = ReactComponentTreeHook.getDisplayName(debugID) || 'Unknown';
// Chrome has an issue of dropping markers recorded too fast:
// https://bugs.chromium.org/p/chromium/issues/detail?id=640652
// To work around this, we will not report very small measurements.
// I determined the magic number by tweaking it back and forth.
// 0.05ms was enough to prevent the issue, but I set it to 0.1ms to be safe.
// When the bug is fixed, we can `measure()` unconditionally if we want to.
var timeStamp = performanceNow();
if (timeStamp - lastMarkTimeStamp > 0.1) {
var measurementName = displayName + ' [' + markType + ']';
performance.measure(measurementName, markName);
}
performance.clearMarks(markName);
if (measurementName) {
performance.clearMeasures(measurementName);
}
}
var ReactDebugTool = {
addHook: function (hook) {
hooks.push(hook);
},
removeHook: function (hook) {
for (var i = 0; i < hooks.length; i++) {
if (hooks[i] === hook) {
hooks.splice(i, 1);
i--;
}
}
},
isProfiling: function () {
return isProfiling;
},
beginProfiling: function () {
if (isProfiling) {
return;
}
isProfiling = true;
flushHistory.length = 0;
resetMeasurements();
ReactDebugTool.addHook(ReactHostOperationHistoryHook);
},
endProfiling: function () {
if (!isProfiling) {
return;
}
isProfiling = false;
resetMeasurements();
ReactDebugTool.removeHook(ReactHostOperationHistoryHook);
},
getFlushHistory: function () {
return flushHistory;
},
onBeginFlush: function () {
currentFlushNesting++;
resetMeasurements();
pauseCurrentLifeCycleTimer();
emitEvent('onBeginFlush');
},
onEndFlush: function () {
resetMeasurements();
currentFlushNesting--;
resumeCurrentLifeCycleTimer();
emitEvent('onEndFlush');
},
onBeginLifeCycleTimer: function (debugID, timerType) {
checkDebugID(debugID);
emitEvent('onBeginLifeCycleTimer', debugID, timerType);
markBegin(debugID, timerType);
beginLifeCycleTimer(debugID, timerType);
},
onEndLifeCycleTimer: function (debugID, timerType) {
checkDebugID(debugID);
endLifeCycleTimer(debugID, timerType);
markEnd(debugID, timerType);
emitEvent('onEndLifeCycleTimer', debugID, timerType);
},
onBeginProcessingChildContext: function () {
emitEvent('onBeginProcessingChildContext');
},
onEndProcessingChildContext: function () {
emitEvent('onEndProcessingChildContext');
},
onHostOperation: function (operation) {
checkDebugID(operation.instanceID);
emitEvent('onHostOperation', operation);
},
onSetState: function () {
emitEvent('onSetState');
},
onSetChildren: function (debugID, childDebugIDs) {
checkDebugID(debugID);
childDebugIDs.forEach(checkDebugID);
emitEvent('onSetChildren', debugID, childDebugIDs);
},
onBeforeMountComponent: function (debugID, element, parentDebugID) {
checkDebugID(debugID);
checkDebugID(parentDebugID, true);
emitEvent('onBeforeMountComponent', debugID, element, parentDebugID);
markBegin(debugID, 'mount');
},
onMountComponent: function (debugID) {
checkDebugID(debugID);
markEnd(debugID, 'mount');
emitEvent('onMountComponent', debugID);
},
onBeforeUpdateComponent: function (debugID, element) {
checkDebugID(debugID);
emitEvent('onBeforeUpdateComponent', debugID, element);
markBegin(debugID, 'update');
},
onUpdateComponent: function (debugID) {
checkDebugID(debugID);
markEnd(debugID, 'update');
emitEvent('onUpdateComponent', debugID);
},
onBeforeUnmountComponent: function (debugID) {
checkDebugID(debugID);
emitEvent('onBeforeUnmountComponent', debugID);
markBegin(debugID, 'unmount');
},
onUnmountComponent: function (debugID) {
checkDebugID(debugID);
markEnd(debugID, 'unmount');
emitEvent('onUnmountComponent', debugID);
},
onTestEvent: function () {
emitEvent('onTestEvent');
}
};
// TODO remove these when RN/www gets updated
ReactDebugTool.addDevtool = ReactDebugTool.addHook;
ReactDebugTool.removeDevtool = ReactDebugTool.removeHook;
ReactDebugTool.addHook(ReactInvalidSetStateWarningHook);
ReactDebugTool.addHook(ReactComponentTreeHook);
var url = ExecutionEnvironment.canUseDOM && window.location.href || '';
if (/[?&]react_perf\b/.test(url)) {
ReactDebugTool.beginProfiling();
}
module.exports = ReactDebugTool;
/***/ }),
/* 116 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2016-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var warning = __webpack_require__(1);
if (true) {
var processingChildContext = false;
var warnInvalidSetState = function () {
true ? warning(!processingChildContext, 'setState(...): Cannot call setState() inside getChildContext()') : void 0;
};
}
var ReactInvalidSetStateWarningHook = {
onBeginProcessingChildContext: function () {
processingChildContext = true;
},
onEndProcessingChildContext: function () {
processingChildContext = false;
},
onSetState: function () {
warnInvalidSetState();
}
};
module.exports = ReactInvalidSetStateWarningHook;
/***/ }),
/* 117 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2016-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var history = [];
var ReactHostOperationHistoryHook = {
onHostOperation: function (operation) {
history.push(operation);
},
clearHistory: function () {
if (ReactHostOperationHistoryHook._preventClearing) {
// Should only be used for tests.
return;
}
history = [];
},
getHistory: function () {
return history;
}
};
module.exports = ReactHostOperationHistoryHook;
/***/ }),
/* 118 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*/
var performance = __webpack_require__(119);
var performanceNow;
/**
* Detect if we can use `window.performance.now()` and gracefully fallback to
* `Date.now()` if it doesn't exist. We need to support Firefox < 15 for now
* because of Facebook's testing infrastructure.
*/
if (performance.now) {
performanceNow = function performanceNow() {
return performance.now();
};
} else {
performanceNow = function performanceNow() {
return Date.now();
};
}
module.exports = performanceNow;
/***/ }),
/* 119 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*/
var ExecutionEnvironment = __webpack_require__(5);
var performance;
if (ExecutionEnvironment.canUseDOM) {
performance = window.performance || window.msPerformance || window.webkitPerformance;
}
module.exports = performance || {};
/***/ }),
/* 120 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
/**
* Module that is injectable into `EventPluginHub`, that specifies a
* deterministic ordering of `EventPlugin`s. A convenient way to reason about
* plugins, without having to package every one of them. This is better than
* having plugins be ordered in the same order that they are injected because
* that ordering would be influenced by the packaging order.
* `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that
* preventing default on events is convenient in `SimpleEventPlugin` handlers.
*/
var DefaultEventPluginOrder = ['ResponderEventPlugin', 'SimpleEventPlugin', 'TapEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin'];
module.exports = DefaultEventPluginOrder;
/***/ }),
/* 121 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var EventPropagators = __webpack_require__(20);
var ReactDOMComponentTree = __webpack_require__(4);
var SyntheticMouseEvent = __webpack_require__(30);
var eventTypes = {
mouseEnter: {
registrationName: 'onMouseEnter',
dependencies: ['topMouseOut', 'topMouseOver']
},
mouseLeave: {
registrationName: 'onMouseLeave',
dependencies: ['topMouseOut', 'topMouseOver']
}
};
var EnterLeaveEventPlugin = {
eventTypes: eventTypes,
/**
* For almost every interaction we care about, there will be both a top-level
* `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
* we do not extract duplicate events. However, moving the mouse into the
* browser from outside will not fire a `mouseout` event. In this case, we use
* the `mouseover` top-level event.
*/
extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
if (topLevelType === 'topMouseOver' && (nativeEvent.relatedTarget || nativeEvent.fromElement)) {
return null;
}
if (topLevelType !== 'topMouseOut' && topLevelType !== 'topMouseOver') {
// Must not be a mouse in or mouse out - ignoring.
return null;
}
var win;
if (nativeEventTarget.window === nativeEventTarget) {
// `nativeEventTarget` is probably a window object.
win = nativeEventTarget;
} else {
// TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
var doc = nativeEventTarget.ownerDocument;
if (doc) {
win = doc.defaultView || doc.parentWindow;
} else {
win = window;
}
}
var from;
var to;
if (topLevelType === 'topMouseOut') {
from = targetInst;
var related = nativeEvent.relatedTarget || nativeEvent.toElement;
to = related ? ReactDOMComponentTree.getClosestInstanceFromNode(related) : null;
} else {
// Moving to a node from outside the window.
from = null;
to = targetInst;
}
if (from === to) {
// Nothing pertains to our managed components.
return null;
}
var fromNode = from == null ? win : ReactDOMComponentTree.getNodeFromInstance(from);
var toNode = to == null ? win : ReactDOMComponentTree.getNodeFromInstance(to);
var leave = SyntheticMouseEvent.getPooled(eventTypes.mouseLeave, from, nativeEvent, nativeEventTarget);
leave.type = 'mouseleave';
leave.target = fromNode;
leave.relatedTarget = toNode;
var enter = SyntheticMouseEvent.getPooled(eventTypes.mouseEnter, to, nativeEvent, nativeEventTarget);
enter.type = 'mouseenter';
enter.target = toNode;
enter.relatedTarget = fromNode;
EventPropagators.accumulateEnterLeaveDispatches(leave, enter, from, to);
return [leave, enter];
}
};
module.exports = EnterLeaveEventPlugin;
/***/ }),
/* 122 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var DOMProperty = __webpack_require__(13);
var MUST_USE_PROPERTY = DOMProperty.injection.MUST_USE_PROPERTY;
var HAS_BOOLEAN_VALUE = DOMProperty.injection.HAS_BOOLEAN_VALUE;
var HAS_NUMERIC_VALUE = DOMProperty.injection.HAS_NUMERIC_VALUE;
var HAS_POSITIVE_NUMERIC_VALUE = DOMProperty.injection.HAS_POSITIVE_NUMERIC_VALUE;
var HAS_OVERLOADED_BOOLEAN_VALUE = DOMProperty.injection.HAS_OVERLOADED_BOOLEAN_VALUE;
var HTMLDOMPropertyConfig = {
isCustomAttribute: RegExp.prototype.test.bind(new RegExp('^(data|aria)-[' + DOMProperty.ATTRIBUTE_NAME_CHAR + ']*$')),
Properties: {
/**
* Standard Properties
*/
accept: 0,
acceptCharset: 0,
accessKey: 0,
action: 0,
allowFullScreen: HAS_BOOLEAN_VALUE,
allowTransparency: 0,
alt: 0,
// specifies target context for links with `preload` type
as: 0,
async: HAS_BOOLEAN_VALUE,
autoComplete: 0,
// autoFocus is polyfilled/normalized by AutoFocusUtils
// autoFocus: HAS_BOOLEAN_VALUE,
autoPlay: HAS_BOOLEAN_VALUE,
capture: HAS_BOOLEAN_VALUE,
cellPadding: 0,
cellSpacing: 0,
charSet: 0,
challenge: 0,
checked: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
cite: 0,
classID: 0,
className: 0,
cols: HAS_POSITIVE_NUMERIC_VALUE,
colSpan: 0,
content: 0,
contentEditable: 0,
contextMenu: 0,
controls: HAS_BOOLEAN_VALUE,
controlsList: 0,
coords: 0,
crossOrigin: 0,
data: 0, // For `<object />` acts as `src`.
dateTime: 0,
'default': HAS_BOOLEAN_VALUE,
defer: HAS_BOOLEAN_VALUE,
dir: 0,
disabled: HAS_BOOLEAN_VALUE,
download: HAS_OVERLOADED_BOOLEAN_VALUE,
draggable: 0,
encType: 0,
form: 0,
formAction: 0,
formEncType: 0,
formMethod: 0,
formNoValidate: HAS_BOOLEAN_VALUE,
formTarget: 0,
frameBorder: 0,
headers: 0,
height: 0,
hidden: HAS_BOOLEAN_VALUE,
high: 0,
href: 0,
hrefLang: 0,
htmlFor: 0,
httpEquiv: 0,
icon: 0,
id: 0,
inputMode: 0,
integrity: 0,
is: 0,
keyParams: 0,
keyType: 0,
kind: 0,
label: 0,
lang: 0,
list: 0,
loop: HAS_BOOLEAN_VALUE,
low: 0,
manifest: 0,
marginHeight: 0,
marginWidth: 0,
max: 0,
maxLength: 0,
media: 0,
mediaGroup: 0,
method: 0,
min: 0,
minLength: 0,
// Caution; `option.selected` is not updated if `select.multiple` is
// disabled with `removeAttribute`.
multiple: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
muted: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
name: 0,
nonce: 0,
noValidate: HAS_BOOLEAN_VALUE,
open: HAS_BOOLEAN_VALUE,
optimum: 0,
pattern: 0,
placeholder: 0,
playsInline: HAS_BOOLEAN_VALUE,
poster: 0,
preload: 0,
profile: 0,
radioGroup: 0,
readOnly: HAS_BOOLEAN_VALUE,
referrerPolicy: 0,
rel: 0,
required: HAS_BOOLEAN_VALUE,
reversed: HAS_BOOLEAN_VALUE,
role: 0,
rows: HAS_POSITIVE_NUMERIC_VALUE,
rowSpan: HAS_NUMERIC_VALUE,
sandbox: 0,
scope: 0,
scoped: HAS_BOOLEAN_VALUE,
scrolling: 0,
seamless: HAS_BOOLEAN_VALUE,
selected: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
shape: 0,
size: HAS_POSITIVE_NUMERIC_VALUE,
sizes: 0,
span: HAS_POSITIVE_NUMERIC_VALUE,
spellCheck: 0,
src: 0,
srcDoc: 0,
srcLang: 0,
srcSet: 0,
start: HAS_NUMERIC_VALUE,
step: 0,
style: 0,
summary: 0,
tabIndex: 0,
target: 0,
title: 0,
// Setting .type throws on non-<input> tags
type: 0,
useMap: 0,
value: 0,
width: 0,
wmode: 0,
wrap: 0,
/**
* RDFa Properties
*/
about: 0,
datatype: 0,
inlist: 0,
prefix: 0,
// property is also supported for OpenGraph in meta tags.
property: 0,
resource: 0,
'typeof': 0,
vocab: 0,
/**
* Non-standard Properties
*/
// autoCapitalize and autoCorrect are supported in Mobile Safari for
// keyboard hints.
autoCapitalize: 0,
autoCorrect: 0,
// autoSave allows WebKit/Blink to persist values of input fields on page reloads
autoSave: 0,
// color is for Safari mask-icon link
color: 0,
// itemProp, itemScope, itemType are for
// Microdata support. See http://schema.org/docs/gs.html
itemProp: 0,
itemScope: HAS_BOOLEAN_VALUE,
itemType: 0,
// itemID and itemRef are for Microdata support as well but
// only specified in the WHATWG spec document. See
// https://html.spec.whatwg.org/multipage/microdata.html#microdata-dom-api
itemID: 0,
itemRef: 0,
// results show looking glass icon and recent searches on input
// search fields in WebKit/Blink
results: 0,
// IE-only attribute that specifies security restrictions on an iframe
// as an alternative to the sandbox attribute on IE<10
security: 0,
// IE-only attribute that controls focus behavior
unselectable: 0
},
DOMAttributeNames: {
acceptCharset: 'accept-charset',
className: 'class',
htmlFor: 'for',
httpEquiv: 'http-equiv'
},
DOMPropertyNames: {},
DOMMutationMethods: {
value: function (node, value) {
if (value == null) {
return node.removeAttribute('value');
}
// Number inputs get special treatment due to some edge cases in
// Chrome. Let everything else assign the value attribute as normal.
// https://github.com/facebook/react/issues/7253#issuecomment-236074326
if (node.type !== 'number' || node.hasAttribute('value') === false) {
node.setAttribute('value', '' + value);
} else if (node.validity && !node.validity.badInput && node.ownerDocument.activeElement !== node) {
// Don't assign an attribute if validation reports bad
// input. Chrome will clear the value. Additionally, don't
// operate on inputs that have focus, otherwise Chrome might
// strip off trailing decimal places and cause the user's
// cursor position to jump to the beginning of the input.
//
// In ReactDOMInput, we have an onBlur event that will trigger
// this function again when focus is lost.
node.setAttribute('value', '' + value);
}
}
}
};
module.exports = HTMLDOMPropertyConfig;
/***/ }),
/* 123 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var DOMChildrenOperations = __webpack_require__(41);
var ReactDOMIDOperations = __webpack_require__(128);
/**
* Abstracts away all functionality of the reconciler that requires knowledge of
* the browser context. TODO: These callers should be refactored to avoid the
* need for this injection.
*/
var ReactComponentBrowserEnvironment = {
processChildrenUpdates: ReactDOMIDOperations.dangerouslyProcessChildrenUpdates,
replaceNodeWithMarkup: DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup
};
module.exports = ReactComponentBrowserEnvironment;
/***/ }),
/* 124 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _prodInvariant = __webpack_require__(2);
var DOMLazyTree = __webpack_require__(19);
var ExecutionEnvironment = __webpack_require__(5);
var createNodesFromMarkup = __webpack_require__(125);
var emptyFunction = __webpack_require__(8);
var invariant = __webpack_require__(0);
var Danger = {
/**
* Replaces a node with a string of markup at its current position within its
* parent. The markup must render into a single root node.
*
* @param {DOMElement} oldChild Child node to replace.
* @param {string} markup Markup to render in place of the child node.
* @internal
*/
dangerouslyReplaceNodeWithMarkup: function (oldChild, markup) {
!ExecutionEnvironment.canUseDOM ? true ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Cannot render markup in a worker thread. Make sure `window` and `document` are available globally before requiring React when unit testing or use ReactDOMServer.renderToString() for server rendering.') : _prodInvariant('56') : void 0;
!markup ? true ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Missing markup.') : _prodInvariant('57') : void 0;
!(oldChild.nodeName !== 'HTML') ? true ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Cannot replace markup of the <html> node. This is because browser quirks make this unreliable and/or slow. If you want to render to the root you must use server rendering. See ReactDOMServer.renderToString().') : _prodInvariant('58') : void 0;
if (typeof markup === 'string') {
var newChild = createNodesFromMarkup(markup, emptyFunction)[0];
oldChild.parentNode.replaceChild(newChild, oldChild);
} else {
DOMLazyTree.replaceChildWithTree(oldChild, markup);
}
}
};
module.exports = Danger;
/***/ }),
/* 125 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*/
/*eslint-disable fb-www/unsafe-html*/
var ExecutionEnvironment = __webpack_require__(5);
var createArrayFromMixed = __webpack_require__(126);
var getMarkupWrap = __webpack_require__(127);
var invariant = __webpack_require__(0);
/**
* Dummy container used to render all markup.
*/
var dummyNode = ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;
/**
* Pattern used by `getNodeName`.
*/
var nodeNamePattern = /^\s*<(\w+)/;
/**
* Extracts the `nodeName` of the first element in a string of markup.
*
* @param {string} markup String of markup.
* @return {?string} Node name of the supplied markup.
*/
function getNodeName(markup) {
var nodeNameMatch = markup.match(nodeNamePattern);
return nodeNameMatch && nodeNameMatch[1].toLowerCase();
}
/**
* Creates an array containing the nodes rendered from the supplied markup. The
* optionally supplied `handleScript` function will be invoked once for each
* <script> element that is rendered. If no `handleScript` function is supplied,
* an exception is thrown if any <script> elements are rendered.
*
* @param {string} markup A string of valid HTML markup.
* @param {?function} handleScript Invoked once for each rendered <script>.
* @return {array<DOMElement|DOMTextNode>} An array of rendered nodes.
*/
function createNodesFromMarkup(markup, handleScript) {
var node = dummyNode;
!!!dummyNode ? true ? invariant(false, 'createNodesFromMarkup dummy not initialized') : invariant(false) : void 0;
var nodeName = getNodeName(markup);
var wrap = nodeName && getMarkupWrap(nodeName);
if (wrap) {
node.innerHTML = wrap[1] + markup + wrap[2];
var wrapDepth = wrap[0];
while (wrapDepth--) {
node = node.lastChild;
}
} else {
node.innerHTML = markup;
}
var scripts = node.getElementsByTagName('script');
if (scripts.length) {
!handleScript ? true ? invariant(false, 'createNodesFromMarkup(...): Unexpected <script> element rendered.') : invariant(false) : void 0;
createArrayFromMixed(scripts).forEach(handleScript);
}
var nodes = Array.from(node.childNodes);
while (node.lastChild) {
node.removeChild(node.lastChild);
}
return nodes;
}
module.exports = createNodesFromMarkup;
/***/ }),
/* 126 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*/
var invariant = __webpack_require__(0);
/**
* Convert array-like objects to arrays.
*
* This API assumes the caller knows the contents of the data type. For less
* well defined inputs use createArrayFromMixed.
*
* @param {object|function|filelist} obj
* @return {array}
*/
function toArray(obj) {
var length = obj.length;
// Some browsers builtin objects can report typeof 'function' (e.g. NodeList
// in old versions of Safari).
!(!Array.isArray(obj) && (typeof obj === 'object' || typeof obj === 'function')) ? true ? invariant(false, 'toArray: Array-like object expected') : invariant(false) : void 0;
!(typeof length === 'number') ? true ? invariant(false, 'toArray: Object needs a length property') : invariant(false) : void 0;
!(length === 0 || length - 1 in obj) ? true ? invariant(false, 'toArray: Object should have keys for indices') : invariant(false) : void 0;
!(typeof obj.callee !== 'function') ? true ? invariant(false, 'toArray: Object can\'t be `arguments`. Use rest params ' + '(function(...args) {}) or Array.from() instead.') : invariant(false) : void 0;
// Old IE doesn't give collections access to hasOwnProperty. Assume inputs
// without method will throw during the slice call and skip straight to the
// fallback.
if (obj.hasOwnProperty) {
try {
return Array.prototype.slice.call(obj);
} catch (e) {
// IE < 9 does not support Array#slice on collections objects
}
}
// Fall back to copying key by key. This assumes all keys have a value,
// so will not preserve sparsely populated inputs.
var ret = Array(length);
for (var ii = 0; ii < length; ii++) {
ret[ii] = obj[ii];
}
return ret;
}
/**
* Perform a heuristic test to determine if an object is "array-like".
*
* A monk asked Joshu, a Zen master, "Has a dog Buddha nature?"
* Joshu replied: "Mu."
*
* This function determines if its argument has "array nature": it returns
* true if the argument is an actual array, an `arguments' object, or an
* HTMLCollection (e.g. node.childNodes or node.getElementsByTagName()).
*
* It will return false for other array-like objects like Filelist.
*
* @param {*} obj
* @return {boolean}
*/
function hasArrayNature(obj) {
return (
// not null/false
!!obj && (
// arrays are objects, NodeLists are functions in Safari
typeof obj == 'object' || typeof obj == 'function') &&
// quacks like an array
'length' in obj &&
// not window
!('setInterval' in obj) &&
// no DOM node should be considered an array-like
// a 'select' element has 'length' and 'item' properties on IE8
typeof obj.nodeType != 'number' && (
// a real array
Array.isArray(obj) ||
// arguments
'callee' in obj ||
// HTMLCollection/NodeList
'item' in obj)
);
}
/**
* Ensure that the argument is an array by wrapping it in an array if it is not.
* Creates a copy of the argument if it is already an array.
*
* This is mostly useful idiomatically:
*
* var createArrayFromMixed = require('createArrayFromMixed');
*
* function takesOneOrMoreThings(things) {
* things = createArrayFromMixed(things);
* ...
* }
*
* This allows you to treat `things' as an array, but accept scalars in the API.
*
* If you need to convert an array-like object, like `arguments`, into an array
* use toArray instead.
*
* @param {*} obj
* @return {array}
*/
function createArrayFromMixed(obj) {
if (!hasArrayNature(obj)) {
return [obj];
} else if (Array.isArray(obj)) {
return obj.slice();
} else {
return toArray(obj);
}
}
module.exports = createArrayFromMixed;
/***/ }),
/* 127 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
/*eslint-disable fb-www/unsafe-html */
var ExecutionEnvironment = __webpack_require__(5);
var invariant = __webpack_require__(0);
/**
* Dummy container used to detect which wraps are necessary.
*/
var dummyNode = ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;
/**
* Some browsers cannot use `innerHTML` to render certain elements standalone,
* so we wrap them, render the wrapped nodes, then extract the desired node.
*
* In IE8, certain elements cannot render alone, so wrap all elements ('*').
*/
var shouldWrap = {};
var selectWrap = [1, '<select multiple="true">', '</select>'];
var tableWrap = [1, '<table>', '</table>'];
var trWrap = [3, '<table><tbody><tr>', '</tr></tbody></table>'];
var svgWrap = [1, '<svg xmlns="http://www.w3.org/2000/svg">', '</svg>'];
var markupWrap = {
'*': [1, '?<div>', '</div>'],
'area': [1, '<map>', '</map>'],
'col': [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],
'legend': [1, '<fieldset>', '</fieldset>'],
'param': [1, '<object>', '</object>'],
'tr': [2, '<table><tbody>', '</tbody></table>'],
'optgroup': selectWrap,
'option': selectWrap,
'caption': tableWrap,
'colgroup': tableWrap,
'tbody': tableWrap,
'tfoot': tableWrap,
'thead': tableWrap,
'td': trWrap,
'th': trWrap
};
// Initialize the SVG elements since we know they'll always need to be wrapped
// consistently. If they are created inside a <div> they will be initialized in
// the wrong namespace (and will not display).
var svgElements = ['circle', 'clipPath', 'defs', 'ellipse', 'g', 'image', 'line', 'linearGradient', 'mask', 'path', 'pattern', 'polygon', 'polyline', 'radialGradient', 'rect', 'stop', 'text', 'tspan'];
svgElements.forEach(function (nodeName) {
markupWrap[nodeName] = svgWrap;
shouldWrap[nodeName] = true;
});
/**
* Gets the markup wrap configuration for the supplied `nodeName`.
*
* NOTE: This lazily detects which wraps are necessary for the current browser.
*
* @param {string} nodeName Lowercase `nodeName`.
* @return {?array} Markup wrap configuration, if applicable.
*/
function getMarkupWrap(nodeName) {
!!!dummyNode ? true ? invariant(false, 'Markup wrapping node not initialized') : invariant(false) : void 0;
if (!markupWrap.hasOwnProperty(nodeName)) {
nodeName = '*';
}
if (!shouldWrap.hasOwnProperty(nodeName)) {
if (nodeName === '*') {
dummyNode.innerHTML = '<link />';
} else {
dummyNode.innerHTML = '<' + nodeName + '></' + nodeName + '>';
}
shouldWrap[nodeName] = !dummyNode.firstChild;
}
return shouldWrap[nodeName] ? markupWrap[nodeName] : null;
}
module.exports = getMarkupWrap;
/***/ }),
/* 128 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var DOMChildrenOperations = __webpack_require__(41);
var ReactDOMComponentTree = __webpack_require__(4);
/**
* Operations used to process updates to DOM nodes.
*/
var ReactDOMIDOperations = {
/**
* Updates a component's children by processing a series of updates.
*
* @param {array<object>} updates List of update configurations.
* @internal
*/
dangerouslyProcessChildrenUpdates: function (parentInst, updates) {
var node = ReactDOMComponentTree.getNodeFromInstance(parentInst);
DOMChildrenOperations.processUpdates(node, updates);
}
};
module.exports = ReactDOMIDOperations;
/***/ }),
/* 129 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
/* global hasOwnProperty:true */
var _prodInvariant = __webpack_require__(2),
_assign = __webpack_require__(3);
var AutoFocusUtils = __webpack_require__(130);
var CSSPropertyOperations = __webpack_require__(131);
var DOMLazyTree = __webpack_require__(19);
var DOMNamespaces = __webpack_require__(42);
var DOMProperty = __webpack_require__(13);
var DOMPropertyOperations = __webpack_require__(71);
var EventPluginHub = __webpack_require__(21);
var EventPluginRegistry = __webpack_require__(28);
var ReactBrowserEventEmitter = __webpack_require__(33);
var ReactDOMComponentFlags = __webpack_require__(59);
var ReactDOMComponentTree = __webpack_require__(4);
var ReactDOMInput = __webpack_require__(141);
var ReactDOMOption = __webpack_require__(142);
var ReactDOMSelect = __webpack_require__(73);
var ReactDOMTextarea = __webpack_require__(143);
var ReactInstrumentation = __webpack_require__(7);
var ReactMultiChild = __webpack_require__(144);
var ReactServerRenderingTransaction = __webpack_require__(153);
var emptyFunction = __webpack_require__(8);
var escapeTextContentForBrowser = __webpack_require__(32);
var invariant = __webpack_require__(0);
var isEventSupported = __webpack_require__(39);
var shallowEqual = __webpack_require__(46);
var inputValueTracking = __webpack_require__(65);
var validateDOMNesting = __webpack_require__(50);
var warning = __webpack_require__(1);
var Flags = ReactDOMComponentFlags;
var deleteListener = EventPluginHub.deleteListener;
var getNode = ReactDOMComponentTree.getNodeFromInstance;
var listenTo = ReactBrowserEventEmitter.listenTo;
var registrationNameModules = EventPluginRegistry.registrationNameModules;
// For quickly matching children type, to test if can be treated as content.
var CONTENT_TYPES = { string: true, number: true };
var STYLE = 'style';
var HTML = '__html';
var RESERVED_PROPS = {
children: null,
dangerouslySetInnerHTML: null,
suppressContentEditableWarning: null
};
// Node type for document fragments (Node.DOCUMENT_FRAGMENT_NODE).
var DOC_FRAGMENT_TYPE = 11;
function getDeclarationErrorAddendum(internalInstance) {
if (internalInstance) {
var owner = internalInstance._currentElement._owner || null;
if (owner) {
var name = owner.getName();
if (name) {
return ' This DOM node was rendered by `' + name + '`.';
}
}
}
return '';
}
function friendlyStringify(obj) {
if (typeof obj === 'object') {
if (Array.isArray(obj)) {
return '[' + obj.map(friendlyStringify).join(', ') + ']';
} else {
var pairs = [];
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
var keyEscaped = /^[a-z$_][\w$_]*$/i.test(key) ? key : JSON.stringify(key);
pairs.push(keyEscaped + ': ' + friendlyStringify(obj[key]));
}
}
return '{' + pairs.join(', ') + '}';
}
} else if (typeof obj === 'string') {
return JSON.stringify(obj);
} else if (typeof obj === 'function') {
return '[function object]';
}
// Differs from JSON.stringify in that undefined because undefined and that
// inf and nan don't become null
return String(obj);
}
var styleMutationWarning = {};
function checkAndWarnForMutatedStyle(style1, style2, component) {
if (style1 == null || style2 == null) {
return;
}
if (shallowEqual(style1, style2)) {
return;
}
var componentName = component._tag;
var owner = component._currentElement._owner;
var ownerName;
if (owner) {
ownerName = owner.getName();
}
var hash = ownerName + '|' + componentName;
if (styleMutationWarning.hasOwnProperty(hash)) {
return;
}
styleMutationWarning[hash] = true;
true ? warning(false, '`%s` was passed a style object that has previously been mutated. ' + 'Mutating `style` is deprecated. Consider cloning it beforehand. Check ' + 'the `render` %s. Previous style: %s. Mutated style: %s.', componentName, owner ? 'of `' + ownerName + '`' : 'using <' + componentName + '>', friendlyStringify(style1), friendlyStringify(style2)) : void 0;
}
/**
* @param {object} component
* @param {?object} props
*/
function assertValidProps(component, props) {
if (!props) {
return;
}
// Note the use of `==` which checks for null or undefined.
if (voidElementTags[component._tag]) {
!(props.children == null && props.dangerouslySetInnerHTML == null) ? true ? invariant(false, '%s is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`.%s', component._tag, component._currentElement._owner ? ' Check the render method of ' + component._currentElement._owner.getName() + '.' : '') : _prodInvariant('137', component._tag, component._currentElement._owner ? ' Check the render method of ' + component._currentElement._owner.getName() + '.' : '') : void 0;
}
if (props.dangerouslySetInnerHTML != null) {
!(props.children == null) ? true ? invariant(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : _prodInvariant('60') : void 0;
!(typeof props.dangerouslySetInnerHTML === 'object' && HTML in props.dangerouslySetInnerHTML) ? true ? invariant(false, '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. Please visit https://fb.me/react-invariant-dangerously-set-inner-html for more information.') : _prodInvariant('61') : void 0;
}
if (true) {
true ? warning(props.innerHTML == null, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.') : void 0;
true ? warning(props.suppressContentEditableWarning || !props.contentEditable || props.children == null, 'A component is `contentEditable` and contains `children` managed by ' + 'React. It is now your responsibility to guarantee that none of ' + 'those nodes are unexpectedly modified or duplicated. This is ' + 'probably not intentional.') : void 0;
true ? warning(props.onFocusIn == null && props.onFocusOut == null, 'React uses onFocus and onBlur instead of onFocusIn and onFocusOut. ' + 'All React events are normalized to bubble, so onFocusIn and onFocusOut ' + 'are not needed/supported by React.') : void 0;
}
!(props.style == null || typeof props.style === 'object') ? true ? invariant(false, 'The `style` prop expects a mapping from style properties to values, not a string. For example, style={{marginRight: spacing + \'em\'}} when using JSX.%s', getDeclarationErrorAddendum(component)) : _prodInvariant('62', getDeclarationErrorAddendum(component)) : void 0;
}
function enqueuePutListener(inst, registrationName, listener, transaction) {
if (transaction instanceof ReactServerRenderingTransaction) {
return;
}
if (true) {
// IE8 has no API for event capturing and the `onScroll` event doesn't
// bubble.
true ? warning(registrationName !== 'onScroll' || isEventSupported('scroll', true), "This browser doesn't support the `onScroll` event") : void 0;
}
var containerInfo = inst._hostContainerInfo;
var isDocumentFragment = containerInfo._node && containerInfo._node.nodeType === DOC_FRAGMENT_TYPE;
var doc = isDocumentFragment ? containerInfo._node : containerInfo._ownerDocument;
listenTo(registrationName, doc);
transaction.getReactMountReady().enqueue(putListener, {
inst: inst,
registrationName: registrationName,
listener: listener
});
}
function putListener() {
var listenerToPut = this;
EventPluginHub.putListener(listenerToPut.inst, listenerToPut.registrationName, listenerToPut.listener);
}
function inputPostMount() {
var inst = this;
ReactDOMInput.postMountWrapper(inst);
}
function textareaPostMount() {
var inst = this;
ReactDOMTextarea.postMountWrapper(inst);
}
function optionPostMount() {
var inst = this;
ReactDOMOption.postMountWrapper(inst);
}
var setAndValidateContentChildDev = emptyFunction;
if (true) {
setAndValidateContentChildDev = function (content) {
var hasExistingContent = this._contentDebugID != null;
var debugID = this._debugID;
// This ID represents the inlined child that has no backing instance:
var contentDebugID = -debugID;
if (content == null) {
if (hasExistingContent) {
ReactInstrumentation.debugTool.onUnmountComponent(this._contentDebugID);
}
this._contentDebugID = null;
return;
}
validateDOMNesting(null, String(content), this, this._ancestorInfo);
this._contentDebugID = contentDebugID;
if (hasExistingContent) {
ReactInstrumentation.debugTool.onBeforeUpdateComponent(contentDebugID, content);
ReactInstrumentation.debugTool.onUpdateComponent(contentDebugID);
} else {
ReactInstrumentation.debugTool.onBeforeMountComponent(contentDebugID, content, debugID);
ReactInstrumentation.debugTool.onMountComponent(contentDebugID);
ReactInstrumentation.debugTool.onSetChildren(debugID, [contentDebugID]);
}
};
}
// There are so many media events, it makes sense to just
// maintain a list rather than create a `trapBubbledEvent` for each
var mediaEvents = {
topAbort: 'abort',
topCanPlay: 'canplay',
topCanPlayThrough: 'canplaythrough',
topDurationChange: 'durationchange',
topEmptied: 'emptied',
topEncrypted: 'encrypted',
topEnded: 'ended',
topError: 'error',
topLoadedData: 'loadeddata',
topLoadedMetadata: 'loadedmetadata',
topLoadStart: 'loadstart',
topPause: 'pause',
topPlay: 'play',
topPlaying: 'playing',
topProgress: 'progress',
topRateChange: 'ratechange',
topSeeked: 'seeked',
topSeeking: 'seeking',
topStalled: 'stalled',
topSuspend: 'suspend',
topTimeUpdate: 'timeupdate',
topVolumeChange: 'volumechange',
topWaiting: 'waiting'
};
function trackInputValue() {
inputValueTracking.track(this);
}
function trapBubbledEventsLocal() {
var inst = this;
// If a component renders to null or if another component fatals and causes
// the state of the tree to be corrupted, `node` here can be null.
!inst._rootNodeID ? true ? invariant(false, 'Must be mounted to trap events') : _prodInvariant('63') : void 0;
var node = getNode(inst);
!node ? true ? invariant(false, 'trapBubbledEvent(...): Requires node to be rendered.') : _prodInvariant('64') : void 0;
switch (inst._tag) {
case 'iframe':
case 'object':
inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent('topLoad', 'load', node)];
break;
case 'video':
case 'audio':
inst._wrapperState.listeners = [];
// Create listener for each media event
for (var event in mediaEvents) {
if (mediaEvents.hasOwnProperty(event)) {
inst._wrapperState.listeners.push(ReactBrowserEventEmitter.trapBubbledEvent(event, mediaEvents[event], node));
}
}
break;
case 'source':
inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent('topError', 'error', node)];
break;
case 'img':
inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent('topError', 'error', node), ReactBrowserEventEmitter.trapBubbledEvent('topLoad', 'load', node)];
break;
case 'form':
inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent('topReset', 'reset', node), ReactBrowserEventEmitter.trapBubbledEvent('topSubmit', 'submit', node)];
break;
case 'input':
case 'select':
case 'textarea':
inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent('topInvalid', 'invalid', node)];
break;
}
}
function postUpdateSelectWrapper() {
ReactDOMSelect.postUpdateWrapper(this);
}
// For HTML, certain tags should omit their close tag. We keep a whitelist for
// those special-case tags.
var omittedCloseTags = {
area: true,
base: true,
br: true,
col: true,
embed: true,
hr: true,
img: true,
input: true,
keygen: true,
link: true,
meta: true,
param: true,
source: true,
track: true,
wbr: true
// NOTE: menuitem's close tag should be omitted, but that causes problems.
};
var newlineEatingTags = {
listing: true,
pre: true,
textarea: true
};
// For HTML, certain tags cannot have children. This has the same purpose as
// `omittedCloseTags` except that `menuitem` should still have its closing tag.
var voidElementTags = _assign({
menuitem: true
}, omittedCloseTags);
// We accept any tag to be rendered but since this gets injected into arbitrary
// HTML, we want to make sure that it's a safe tag.
// http://www.w3.org/TR/REC-xml/#NT-Name
var VALID_TAG_REGEX = /^[a-zA-Z][a-zA-Z:_\.\-\d]*$/; // Simplified subset
var validatedTagCache = {};
var hasOwnProperty = {}.hasOwnProperty;
function validateDangerousTag(tag) {
if (!hasOwnProperty.call(validatedTagCache, tag)) {
!VALID_TAG_REGEX.test(tag) ? true ? invariant(false, 'Invalid tag: %s', tag) : _prodInvariant('65', tag) : void 0;
validatedTagCache[tag] = true;
}
}
function isCustomComponent(tagName, props) {
return tagName.indexOf('-') >= 0 || props.is != null;
}
var globalIdCounter = 1;
/**
* Creates a new React class that is idempotent and capable of containing other
* React components. It accepts event listeners and DOM properties that are
* valid according to `DOMProperty`.
*
* - Event listeners: `onClick`, `onMouseDown`, etc.
* - DOM properties: `className`, `name`, `title`, etc.
*
* The `style` property functions differently from the DOM API. It accepts an
* object mapping of style properties to values.
*
* @constructor ReactDOMComponent
* @extends ReactMultiChild
*/
function ReactDOMComponent(element) {
var tag = element.type;
validateDangerousTag(tag);
this._currentElement = element;
this._tag = tag.toLowerCase();
this._namespaceURI = null;
this._renderedChildren = null;
this._previousStyle = null;
this._previousStyleCopy = null;
this._hostNode = null;
this._hostParent = null;
this._rootNodeID = 0;
this._domID = 0;
this._hostContainerInfo = null;
this._wrapperState = null;
this._topLevelWrapper = null;
this._flags = 0;
if (true) {
this._ancestorInfo = null;
setAndValidateContentChildDev.call(this, null);
}
}
ReactDOMComponent.displayName = 'ReactDOMComponent';
ReactDOMComponent.Mixin = {
/**
* Generates root tag markup then recurses. This method has side effects and
* is not idempotent.
*
* @internal
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
* @param {?ReactDOMComponent} the parent component instance
* @param {?object} info about the host container
* @param {object} context
* @return {string} The computed markup.
*/
mountComponent: function (transaction, hostParent, hostContainerInfo, context) {
this._rootNodeID = globalIdCounter++;
this._domID = hostContainerInfo._idCounter++;
this._hostParent = hostParent;
this._hostContainerInfo = hostContainerInfo;
var props = this._currentElement.props;
switch (this._tag) {
case 'audio':
case 'form':
case 'iframe':
case 'img':
case 'link':
case 'object':
case 'source':
case 'video':
this._wrapperState = {
listeners: null
};
transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this);
break;
case 'input':
ReactDOMInput.mountWrapper(this, props, hostParent);
props = ReactDOMInput.getHostProps(this, props);
transaction.getReactMountReady().enqueue(trackInputValue, this);
transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this);
break;
case 'option':
ReactDOMOption.mountWrapper(this, props, hostParent);
props = ReactDOMOption.getHostProps(this, props);
break;
case 'select':
ReactDOMSelect.mountWrapper(this, props, hostParent);
props = ReactDOMSelect.getHostProps(this, props);
transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this);
break;
case 'textarea':
ReactDOMTextarea.mountWrapper(this, props, hostParent);
props = ReactDOMTextarea.getHostProps(this, props);
transaction.getReactMountReady().enqueue(trackInputValue, this);
transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this);
break;
}
assertValidProps(this, props);
// We create tags in the namespace of their parent container, except HTML
// tags get no namespace.
var namespaceURI;
var parentTag;
if (hostParent != null) {
namespaceURI = hostParent._namespaceURI;
parentTag = hostParent._tag;
} else if (hostContainerInfo._tag) {
namespaceURI = hostContainerInfo._namespaceURI;
parentTag = hostContainerInfo._tag;
}
if (namespaceURI == null || namespaceURI === DOMNamespaces.svg && parentTag === 'foreignobject') {
namespaceURI = DOMNamespaces.html;
}
if (namespaceURI === DOMNamespaces.html) {
if (this._tag === 'svg') {
namespaceURI = DOMNamespaces.svg;
} else if (this._tag === 'math') {
namespaceURI = DOMNamespaces.mathml;
}
}
this._namespaceURI = namespaceURI;
if (true) {
var parentInfo;
if (hostParent != null) {
parentInfo = hostParent._ancestorInfo;
} else if (hostContainerInfo._tag) {
parentInfo = hostContainerInfo._ancestorInfo;
}
if (parentInfo) {
// parentInfo should always be present except for the top-level
// component when server rendering
validateDOMNesting(this._tag, null, this, parentInfo);
}
this._ancestorInfo = validateDOMNesting.updatedAncestorInfo(parentInfo, this._tag, this);
}
var mountImage;
if (transaction.useCreateElement) {
var ownerDocument = hostContainerInfo._ownerDocument;
var el;
if (namespaceURI === DOMNamespaces.html) {
if (this._tag === 'script') {
// Create the script via .innerHTML so its "parser-inserted" flag is
// set to true and it does not execute
var div = ownerDocument.createElement('div');
var type = this._currentElement.type;
div.innerHTML = '<' + type + '></' + type + '>';
el = div.removeChild(div.firstChild);
} else if (props.is) {
el = ownerDocument.createElement(this._currentElement.type, props.is);
} else {
// Separate else branch instead of using `props.is || undefined` above becuase of a Firefox bug.
// See discussion in https://github.com/facebook/react/pull/6896
// and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
el = ownerDocument.createElement(this._currentElement.type);
}
} else {
el = ownerDocument.createElementNS(namespaceURI, this._currentElement.type);
}
ReactDOMComponentTree.precacheNode(this, el);
this._flags |= Flags.hasCachedChildNodes;
if (!this._hostParent) {
DOMPropertyOperations.setAttributeForRoot(el);
}
this._updateDOMProperties(null, props, transaction);
var lazyTree = DOMLazyTree(el);
this._createInitialChildren(transaction, props, context, lazyTree);
mountImage = lazyTree;
} else {
var tagOpen = this._createOpenTagMarkupAndPutListeners(transaction, props);
var tagContent = this._createContentMarkup(transaction, props, context);
if (!tagContent && omittedCloseTags[this._tag]) {
mountImage = tagOpen + '/>';
} else {
mountImage = tagOpen + '>' + tagContent + '</' + this._currentElement.type + '>';
}
}
switch (this._tag) {
case 'input':
transaction.getReactMountReady().enqueue(inputPostMount, this);
if (props.autoFocus) {
transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this);
}
break;
case 'textarea':
transaction.getReactMountReady().enqueue(textareaPostMount, this);
if (props.autoFocus) {
transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this);
}
break;
case 'select':
if (props.autoFocus) {
transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this);
}
break;
case 'button':
if (props.autoFocus) {
transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this);
}
break;
case 'option':
transaction.getReactMountReady().enqueue(optionPostMount, this);
break;
}
return mountImage;
},
/**
* Creates markup for the open tag and all attributes.
*
* This method has side effects because events get registered.
*
* Iterating over object properties is faster than iterating over arrays.
* @see http://jsperf.com/obj-vs-arr-iteration
*
* @private
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
* @param {object} props
* @return {string} Markup of opening tag.
*/
_createOpenTagMarkupAndPutListeners: function (transaction, props) {
var ret = '<' + this._currentElement.type;
for (var propKey in props) {
if (!props.hasOwnProperty(propKey)) {
continue;
}
var propValue = props[propKey];
if (propValue == null) {
continue;
}
if (registrationNameModules.hasOwnProperty(propKey)) {
if (propValue) {
enqueuePutListener(this, propKey, propValue, transaction);
}
} else {
if (propKey === STYLE) {
if (propValue) {
if (true) {
// See `_updateDOMProperties`. style block
this._previousStyle = propValue;
}
propValue = this._previousStyleCopy = _assign({}, props.style);
}
propValue = CSSPropertyOperations.createMarkupForStyles(propValue, this);
}
var markup = null;
if (this._tag != null && isCustomComponent(this._tag, props)) {
if (!RESERVED_PROPS.hasOwnProperty(propKey)) {
markup = DOMPropertyOperations.createMarkupForCustomAttribute(propKey, propValue);
}
} else {
markup = DOMPropertyOperations.createMarkupForProperty(propKey, propValue);
}
if (markup) {
ret += ' ' + markup;
}
}
}
// For static pages, no need to put React ID and checksum. Saves lots of
// bytes.
if (transaction.renderToStaticMarkup) {
return ret;
}
if (!this._hostParent) {
ret += ' ' + DOMPropertyOperations.createMarkupForRoot();
}
ret += ' ' + DOMPropertyOperations.createMarkupForID(this._domID);
return ret;
},
/**
* Creates markup for the content between the tags.
*
* @private
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
* @param {object} props
* @param {object} context
* @return {string} Content markup.
*/
_createContentMarkup: function (transaction, props, context) {
var ret = '';
// Intentional use of != to avoid catching zero/false.
var innerHTML = props.dangerouslySetInnerHTML;
if (innerHTML != null) {
if (innerHTML.__html != null) {
ret = innerHTML.__html;
}
} else {
var contentToUse = CONTENT_TYPES[typeof props.children] ? props.children : null;
var childrenToUse = contentToUse != null ? null : props.children;
if (contentToUse != null) {
// TODO: Validate that text is allowed as a child of this node
ret = escapeTextContentForBrowser(contentToUse);
if (true) {
setAndValidateContentChildDev.call(this, contentToUse);
}
} else if (childrenToUse != null) {
var mountImages = this.mountChildren(childrenToUse, transaction, context);
ret = mountImages.join('');
}
}
if (newlineEatingTags[this._tag] && ret.charAt(0) === '\n') {
// text/html ignores the first character in these tags if it's a newline
// Prefer to break application/xml over text/html (for now) by adding
// a newline specifically to get eaten by the parser. (Alternately for
// textareas, replacing "^\n" with "\r\n" doesn't get eaten, and the first
// \r is normalized out by HTMLTextAreaElement#value.)
// See: <http://www.w3.org/TR/html-polyglot/#newlines-in-textarea-and-pre>
// See: <http://www.w3.org/TR/html5/syntax.html#element-restrictions>
// See: <http://www.w3.org/TR/html5/syntax.html#newlines>
// See: Parsing of "textarea" "listing" and "pre" elements
// from <http://www.w3.org/TR/html5/syntax.html#parsing-main-inbody>
return '\n' + ret;
} else {
return ret;
}
},
_createInitialChildren: function (transaction, props, context, lazyTree) {
// Intentional use of != to avoid catching zero/false.
var innerHTML = props.dangerouslySetInnerHTML;
if (innerHTML != null) {
if (innerHTML.__html != null) {
DOMLazyTree.queueHTML(lazyTree, innerHTML.__html);
}
} else {
var contentToUse = CONTENT_TYPES[typeof props.children] ? props.children : null;
var childrenToUse = contentToUse != null ? null : props.children;
// TODO: Validate that text is allowed as a child of this node
if (contentToUse != null) {
// Avoid setting textContent when the text is empty. In IE11 setting
// textContent on a text area will cause the placeholder to not
// show within the textarea until it has been focused and blurred again.
// https://github.com/facebook/react/issues/6731#issuecomment-254874553
if (contentToUse !== '') {
if (true) {
setAndValidateContentChildDev.call(this, contentToUse);
}
DOMLazyTree.queueText(lazyTree, contentToUse);
}
} else if (childrenToUse != null) {
var mountImages = this.mountChildren(childrenToUse, transaction, context);
for (var i = 0; i < mountImages.length; i++) {
DOMLazyTree.queueChild(lazyTree, mountImages[i]);
}
}
}
},
/**
* Receives a next element and updates the component.
*
* @internal
* @param {ReactElement} nextElement
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
* @param {object} context
*/
receiveComponent: function (nextElement, transaction, context) {
var prevElement = this._currentElement;
this._currentElement = nextElement;
this.updateComponent(transaction, prevElement, nextElement, context);
},
/**
* Updates a DOM component after it has already been allocated and
* attached to the DOM. Reconciles the root DOM node, then recurses.
*
* @param {ReactReconcileTransaction} transaction
* @param {ReactElement} prevElement
* @param {ReactElement} nextElement
* @internal
* @overridable
*/
updateComponent: function (transaction, prevElement, nextElement, context) {
var lastProps = prevElement.props;
var nextProps = this._currentElement.props;
switch (this._tag) {
case 'input':
lastProps = ReactDOMInput.getHostProps(this, lastProps);
nextProps = ReactDOMInput.getHostProps(this, nextProps);
break;
case 'option':
lastProps = ReactDOMOption.getHostProps(this, lastProps);
nextProps = ReactDOMOption.getHostProps(this, nextProps);
break;
case 'select':
lastProps = ReactDOMSelect.getHostProps(this, lastProps);
nextProps = ReactDOMSelect.getHostProps(this, nextProps);
break;
case 'textarea':
lastProps = ReactDOMTextarea.getHostProps(this, lastProps);
nextProps = ReactDOMTextarea.getHostProps(this, nextProps);
break;
}
assertValidProps(this, nextProps);
this._updateDOMProperties(lastProps, nextProps, transaction);
this._updateDOMChildren(lastProps, nextProps, transaction, context);
switch (this._tag) {
case 'input':
// Update the wrapper around inputs *after* updating props. This has to
// happen after `_updateDOMProperties`. Otherwise HTML5 input validations
// raise warnings and prevent the new value from being assigned.
ReactDOMInput.updateWrapper(this);
// We also check that we haven't missed a value update, such as a
// Radio group shifting the checked value to another named radio input.
inputValueTracking.updateValueIfChanged(this);
break;
case 'textarea':
ReactDOMTextarea.updateWrapper(this);
break;
case 'select':
// <select> value update needs to occur after <option> children
// reconciliation
transaction.getReactMountReady().enqueue(postUpdateSelectWrapper, this);
break;
}
},
/**
* Reconciles the properties by detecting differences in property values and
* updating the DOM as necessary. This function is probably the single most
* critical path for performance optimization.
*
* TODO: Benchmark whether checking for changed values in memory actually
* improves performance (especially statically positioned elements).
* TODO: Benchmark the effects of putting this at the top since 99% of props
* do not change for a given reconciliation.
* TODO: Benchmark areas that can be improved with caching.
*
* @private
* @param {object} lastProps
* @param {object} nextProps
* @param {?DOMElement} node
*/
_updateDOMProperties: function (lastProps, nextProps, transaction) {
var propKey;
var styleName;
var styleUpdates;
for (propKey in lastProps) {
if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) {
continue;
}
if (propKey === STYLE) {
var lastStyle = this._previousStyleCopy;
for (styleName in lastStyle) {
if (lastStyle.hasOwnProperty(styleName)) {
styleUpdates = styleUpdates || {};
styleUpdates[styleName] = '';
}
}
this._previousStyleCopy = null;
} else if (registrationNameModules.hasOwnProperty(propKey)) {
if (lastProps[propKey]) {
// Only call deleteListener if there was a listener previously or
// else willDeleteListener gets called when there wasn't actually a
// listener (e.g., onClick={null})
deleteListener(this, propKey);
}
} else if (isCustomComponent(this._tag, lastProps)) {
if (!RESERVED_PROPS.hasOwnProperty(propKey)) {
DOMPropertyOperations.deleteValueForAttribute(getNode(this), propKey);
}
} else if (DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) {
DOMPropertyOperations.deleteValueForProperty(getNode(this), propKey);
}
}
for (propKey in nextProps) {
var nextProp = nextProps[propKey];
var lastProp = propKey === STYLE ? this._previousStyleCopy : lastProps != null ? lastProps[propKey] : undefined;
if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) {
continue;
}
if (propKey === STYLE) {
if (nextProp) {
if (true) {
checkAndWarnForMutatedStyle(this._previousStyleCopy, this._previousStyle, this);
this._previousStyle = nextProp;
}
nextProp = this._previousStyleCopy = _assign({}, nextProp);
} else {
this._previousStyleCopy = null;
}
if (lastProp) {
// Unset styles on `lastProp` but not on `nextProp`.
for (styleName in lastProp) {
if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
styleUpdates = styleUpdates || {};
styleUpdates[styleName] = '';
}
}
// Update styles that changed since `lastProp`.
for (styleName in nextProp) {
if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
styleUpdates = styleUpdates || {};
styleUpdates[styleName] = nextProp[styleName];
}
}
} else {
// Relies on `updateStylesByID` not mutating `styleUpdates`.
styleUpdates = nextProp;
}
} else if (registrationNameModules.hasOwnProperty(propKey)) {
if (nextProp) {
enqueuePutListener(this, propKey, nextProp, transaction);
} else if (lastProp) {
deleteListener(this, propKey);
}
} else if (isCustomComponent(this._tag, nextProps)) {
if (!RESERVED_PROPS.hasOwnProperty(propKey)) {
DOMPropertyOperations.setValueForAttribute(getNode(this), propKey, nextProp);
}
} else if (DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) {
var node = getNode(this);
// If we're updating to null or undefined, we should remove the property
// from the DOM node instead of inadvertently setting to a string. This
// brings us in line with the same behavior we have on initial render.
if (nextProp != null) {
DOMPropertyOperations.setValueForProperty(node, propKey, nextProp);
} else {
DOMPropertyOperations.deleteValueForProperty(node, propKey);
}
}
}
if (styleUpdates) {
CSSPropertyOperations.setValueForStyles(getNode(this), styleUpdates, this);
}
},
/**
* Reconciles the children with the various properties that affect the
* children content.
*
* @param {object} lastProps
* @param {object} nextProps
* @param {ReactReconcileTransaction} transaction
* @param {object} context
*/
_updateDOMChildren: function (lastProps, nextProps, transaction, context) {
var lastContent = CONTENT_TYPES[typeof lastProps.children] ? lastProps.children : null;
var nextContent = CONTENT_TYPES[typeof nextProps.children] ? nextProps.children : null;
var lastHtml = lastProps.dangerouslySetInnerHTML && lastProps.dangerouslySetInnerHTML.__html;
var nextHtml = nextProps.dangerouslySetInnerHTML && nextProps.dangerouslySetInnerHTML.__html;
// Note the use of `!=` which checks for null or undefined.
var lastChildren = lastContent != null ? null : lastProps.children;
var nextChildren = nextContent != null ? null : nextProps.children;
// If we're switching from children to content/html or vice versa, remove
// the old content
var lastHasContentOrHtml = lastContent != null || lastHtml != null;
var nextHasContentOrHtml = nextContent != null || nextHtml != null;
if (lastChildren != null && nextChildren == null) {
this.updateChildren(null, transaction, context);
} else if (lastHasContentOrHtml && !nextHasContentOrHtml) {
this.updateTextContent('');
if (true) {
ReactInstrumentation.debugTool.onSetChildren(this._debugID, []);
}
}
if (nextContent != null) {
if (lastContent !== nextContent) {
this.updateTextContent('' + nextContent);
if (true) {
setAndValidateContentChildDev.call(this, nextContent);
}
}
} else if (nextHtml != null) {
if (lastHtml !== nextHtml) {
this.updateMarkup('' + nextHtml);
}
if (true) {
ReactInstrumentation.debugTool.onSetChildren(this._debugID, []);
}
} else if (nextChildren != null) {
if (true) {
setAndValidateContentChildDev.call(this, null);
}
this.updateChildren(nextChildren, transaction, context);
}
},
getHostNode: function () {
return getNode(this);
},
/**
* Destroys all event registrations for this instance. Does not remove from
* the DOM. That must be done by the parent.
*
* @internal
*/
unmountComponent: function (safely) {
switch (this._tag) {
case 'audio':
case 'form':
case 'iframe':
case 'img':
case 'link':
case 'object':
case 'source':
case 'video':
var listeners = this._wrapperState.listeners;
if (listeners) {
for (var i = 0; i < listeners.length; i++) {
listeners[i].remove();
}
}
break;
case 'input':
case 'textarea':
inputValueTracking.stopTracking(this);
break;
case 'html':
case 'head':
case 'body':
/**
* Components like <html> <head> and <body> can't be removed or added
* easily in a cross-browser way, however it's valuable to be able to
* take advantage of React's reconciliation for styling and <title>
* management. So we just document it and throw in dangerous cases.
*/
true ? true ? invariant(false, '<%s> tried to unmount. Because of cross-browser quirks it is impossible to unmount some top-level components (eg <html>, <head>, and <body>) reliably and efficiently. To fix this, have a single top-level component that never unmounts render these elements.', this._tag) : _prodInvariant('66', this._tag) : void 0;
break;
}
this.unmountChildren(safely);
ReactDOMComponentTree.uncacheNode(this);
EventPluginHub.deleteAllListeners(this);
this._rootNodeID = 0;
this._domID = 0;
this._wrapperState = null;
if (true) {
setAndValidateContentChildDev.call(this, null);
}
},
getPublicInstance: function () {
return getNode(this);
}
};
_assign(ReactDOMComponent.prototype, ReactDOMComponent.Mixin, ReactMultiChild.Mixin);
module.exports = ReactDOMComponent;
/***/ }),
/* 130 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var ReactDOMComponentTree = __webpack_require__(4);
var focusNode = __webpack_require__(69);
var AutoFocusUtils = {
focusDOMComponent: function () {
focusNode(ReactDOMComponentTree.getNodeFromInstance(this));
}
};
module.exports = AutoFocusUtils;
/***/ }),
/* 131 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var CSSProperty = __webpack_require__(70);
var ExecutionEnvironment = __webpack_require__(5);
var ReactInstrumentation = __webpack_require__(7);
var camelizeStyleName = __webpack_require__(132);
var dangerousStyleValue = __webpack_require__(134);
var hyphenateStyleName = __webpack_require__(135);
var memoizeStringOnly = __webpack_require__(137);
var warning = __webpack_require__(1);
var processStyleName = memoizeStringOnly(function (styleName) {
return hyphenateStyleName(styleName);
});
var hasShorthandPropertyBug = false;
var styleFloatAccessor = 'cssFloat';
if (ExecutionEnvironment.canUseDOM) {
var tempStyle = document.createElement('div').style;
try {
// IE8 throws "Invalid argument." if resetting shorthand style properties.
tempStyle.font = '';
} catch (e) {
hasShorthandPropertyBug = true;
}
// IE8 only supports accessing cssFloat (standard) as styleFloat
if (document.documentElement.style.cssFloat === undefined) {
styleFloatAccessor = 'styleFloat';
}
}
if (true) {
// 'msTransform' is correct, but the other prefixes should be capitalized
var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
// style values shouldn't contain a semicolon
var badStyleValueWithSemicolonPattern = /;\s*$/;
var warnedStyleNames = {};
var warnedStyleValues = {};
var warnedForNaNValue = false;
var warnHyphenatedStyleName = function (name, owner) {
if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
return;
}
warnedStyleNames[name] = true;
true ? warning(false, 'Unsupported style property %s. Did you mean %s?%s', name, camelizeStyleName(name), checkRenderMessage(owner)) : void 0;
};
var warnBadVendoredStyleName = function (name, owner) {
if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
return;
}
warnedStyleNames[name] = true;
true ? warning(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?%s', name, name.charAt(0).toUpperCase() + name.slice(1), checkRenderMessage(owner)) : void 0;
};
var warnStyleValueWithSemicolon = function (name, value, owner) {
if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
return;
}
warnedStyleValues[value] = true;
true ? warning(false, "Style property values shouldn't contain a semicolon.%s " + 'Try "%s: %s" instead.', checkRenderMessage(owner), name, value.replace(badStyleValueWithSemicolonPattern, '')) : void 0;
};
var warnStyleValueIsNaN = function (name, value, owner) {
if (warnedForNaNValue) {
return;
}
warnedForNaNValue = true;
true ? warning(false, '`NaN` is an invalid value for the `%s` css style property.%s', name, checkRenderMessage(owner)) : void 0;
};
var checkRenderMessage = function (owner) {
if (owner) {
var name = owner.getName();
if (name) {
return ' Check the render method of `' + name + '`.';
}
}
return '';
};
/**
* @param {string} name
* @param {*} value
* @param {ReactDOMComponent} component
*/
var warnValidStyle = function (name, value, component) {
var owner;
if (component) {
owner = component._currentElement._owner;
}
if (name.indexOf('-') > -1) {
warnHyphenatedStyleName(name, owner);
} else if (badVendoredStyleNamePattern.test(name)) {
warnBadVendoredStyleName(name, owner);
} else if (badStyleValueWithSemicolonPattern.test(value)) {
warnStyleValueWithSemicolon(name, value, owner);
}
if (typeof value === 'number' && isNaN(value)) {
warnStyleValueIsNaN(name, value, owner);
}
};
}
/**
* Operations for dealing with CSS properties.
*/
var CSSPropertyOperations = {
/**
* Serializes a mapping of style properties for use as inline styles:
*
* > createMarkupForStyles({width: '200px', height: 0})
* "width:200px;height:0;"
*
* Undefined values are ignored so that declarative programming is easier.
* The result should be HTML-escaped before insertion into the DOM.
*
* @param {object} styles
* @param {ReactDOMComponent} component
* @return {?string}
*/
createMarkupForStyles: function (styles, component) {
var serialized = '';
for (var styleName in styles) {
if (!styles.hasOwnProperty(styleName)) {
continue;
}
var isCustomProperty = styleName.indexOf('--') === 0;
var styleValue = styles[styleName];
if (true) {
if (!isCustomProperty) {
warnValidStyle(styleName, styleValue, component);
}
}
if (styleValue != null) {
serialized += processStyleName(styleName) + ':';
serialized += dangerousStyleValue(styleName, styleValue, component, isCustomProperty) + ';';
}
}
return serialized || null;
},
/**
* Sets the value for multiple styles on a node. If a value is specified as
* '' (empty string), the corresponding style property will be unset.
*
* @param {DOMElement} node
* @param {object} styles
* @param {ReactDOMComponent} component
*/
setValueForStyles: function (node, styles, component) {
if (true) {
ReactInstrumentation.debugTool.onHostOperation({
instanceID: component._debugID,
type: 'update styles',
payload: styles
});
}
var style = node.style;
for (var styleName in styles) {
if (!styles.hasOwnProperty(styleName)) {
continue;
}
var isCustomProperty = styleName.indexOf('--') === 0;
if (true) {
if (!isCustomProperty) {
warnValidStyle(styleName, styles[styleName], component);
}
}
var styleValue = dangerousStyleValue(styleName, styles[styleName], component, isCustomProperty);
if (styleName === 'float' || styleName === 'cssFloat') {
styleName = styleFloatAccessor;
}
if (isCustomProperty) {
style.setProperty(styleName, styleValue);
} else if (styleValue) {
style[styleName] = styleValue;
} else {
var expansion = hasShorthandPropertyBug && CSSProperty.shorthandPropertyExpansions[styleName];
if (expansion) {
// Shorthand property that IE8 won't like unsetting, so unset each
// component to placate it
for (var individualStyleName in expansion) {
style[individualStyleName] = '';
}
} else {
style[styleName] = '';
}
}
}
}
};
module.exports = CSSPropertyOperations;
/***/ }),
/* 132 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*/
var camelize = __webpack_require__(133);
var msPattern = /^-ms-/;
/**
* Camelcases a hyphenated CSS property name, for example:
*
* > camelizeStyleName('background-color')
* < "backgroundColor"
* > camelizeStyleName('-moz-transition')
* < "MozTransition"
* > camelizeStyleName('-ms-transition')
* < "msTransition"
*
* As Andi Smith suggests
* (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
* is converted to lowercase `ms`.
*
* @param {string} string
* @return {string}
*/
function camelizeStyleName(string) {
return camelize(string.replace(msPattern, 'ms-'));
}
module.exports = camelizeStyleName;
/***/ }),
/* 133 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*/
var _hyphenPattern = /-(.)/g;
/**
* Camelcases a hyphenated string, for example:
*
* > camelize('background-color')
* < "backgroundColor"
*
* @param {string} string
* @return {string}
*/
function camelize(string) {
return string.replace(_hyphenPattern, function (_, character) {
return character.toUpperCase();
});
}
module.exports = camelize;
/***/ }),
/* 134 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var CSSProperty = __webpack_require__(70);
var warning = __webpack_require__(1);
var isUnitlessNumber = CSSProperty.isUnitlessNumber;
var styleWarnings = {};
/**
* Convert a value into the proper css writable value. The style name `name`
* should be logical (no hyphens), as specified
* in `CSSProperty.isUnitlessNumber`.
*
* @param {string} name CSS property name such as `topMargin`.
* @param {*} value CSS property value such as `10px`.
* @param {ReactDOMComponent} component
* @return {string} Normalized style value with dimensions applied.
*/
function dangerousStyleValue(name, value, component, isCustomProperty) {
// Note that we've removed escapeTextForBrowser() calls here since the
// whole string will be escaped when the attribute is injected into
// the markup. If you provide unsafe user data here they can inject
// arbitrary CSS which may be problematic (I couldn't repro this):
// https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
// http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
// This is not an XSS hole but instead a potential CSS injection issue
// which has lead to a greater discussion about how we're going to
// trust URLs moving forward. See #2115901
var isEmpty = value == null || typeof value === 'boolean' || value === '';
if (isEmpty) {
return '';
}
var isNonNumeric = isNaN(value);
if (isCustomProperty || isNonNumeric || value === 0 || isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name]) {
return '' + value; // cast to string
}
if (typeof value === 'string') {
if (true) {
// Allow '0' to pass through without warning. 0 is already special and
// doesn't require units, so we don't need to warn about it.
if (component && value !== '0') {
var owner = component._currentElement._owner;
var ownerName = owner ? owner.getName() : null;
if (ownerName && !styleWarnings[ownerName]) {
styleWarnings[ownerName] = {};
}
var warned = false;
if (ownerName) {
var warnings = styleWarnings[ownerName];
warned = warnings[name];
if (!warned) {
warnings[name] = true;
}
}
if (!warned) {
true ? warning(false, 'a `%s` tag (owner: `%s`) was passed a numeric string value ' + 'for CSS property `%s` (value: `%s`) which will be treated ' + 'as a unitless number in a future version of React.', component._currentElement.type, ownerName || 'unknown', name, value) : void 0;
}
}
}
value = value.trim();
}
return value + 'px';
}
module.exports = dangerousStyleValue;
/***/ }),
/* 135 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*/
var hyphenate = __webpack_require__(136);
var msPattern = /^ms-/;
/**
* Hyphenates a camelcased CSS property name, for example:
*
* > hyphenateStyleName('backgroundColor')
* < "background-color"
* > hyphenateStyleName('MozTransition')
* < "-moz-transition"
* > hyphenateStyleName('msTransition')
* < "-ms-transition"
*
* As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
* is converted to `-ms-`.
*
* @param {string} string
* @return {string}
*/
function hyphenateStyleName(string) {
return hyphenate(string).replace(msPattern, '-ms-');
}
module.exports = hyphenateStyleName;
/***/ }),
/* 136 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*/
var _uppercasePattern = /([A-Z])/g;
/**
* Hyphenates a camelcased string, for example:
*
* > hyphenate('backgroundColor')
* < "background-color"
*
* For CSS style names, use `hyphenateStyleName` instead which works properly
* with all vendor prefixes, including `ms`.
*
* @param {string} string
* @return {string}
*/
function hyphenate(string) {
return string.replace(_uppercasePattern, '-$1').toLowerCase();
}
module.exports = hyphenate;
/***/ }),
/* 137 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
* @typechecks static-only
*/
/**
* Memoizes the return value of a function that accepts one string argument.
*/
function memoizeStringOnly(callback) {
var cache = {};
return function (string) {
if (!cache.hasOwnProperty(string)) {
cache[string] = callback.call(this, string);
}
return cache[string];
};
}
module.exports = memoizeStringOnly;
/***/ }),
/* 138 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var escapeTextContentForBrowser = __webpack_require__(32);
/**
* Escapes attribute value to prevent scripting attacks.
*
* @param {*} value Value to escape.
* @return {string} An escaped string.
*/
function quoteAttributeValueForBrowser(value) {
return '"' + escapeTextContentForBrowser(value) + '"';
}
module.exports = quoteAttributeValueForBrowser;
/***/ }),
/* 139 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var EventPluginHub = __webpack_require__(21);
function runEventQueueInBatch(events) {
EventPluginHub.enqueueEvents(events);
EventPluginHub.processEventQueue(false);
}
var ReactEventEmitterMixin = {
/**
* Streams a fired top-level event to `EventPluginHub` where plugins have the
* opportunity to create `ReactEvent`s to be dispatched.
*/
handleTopLevel: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
var events = EventPluginHub.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget);
runEventQueueInBatch(events);
}
};
module.exports = ReactEventEmitterMixin;
/***/ }),
/* 140 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var ExecutionEnvironment = __webpack_require__(5);
/**
* Generate a mapping of standard vendor prefixes using the defined style property and event name.
*
* @param {string} styleProp
* @param {string} eventName
* @returns {object}
*/
function makePrefixMap(styleProp, eventName) {
var prefixes = {};
prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();
prefixes['Webkit' + styleProp] = 'webkit' + eventName;
prefixes['Moz' + styleProp] = 'moz' + eventName;
prefixes['ms' + styleProp] = 'MS' + eventName;
prefixes['O' + styleProp] = 'o' + eventName.toLowerCase();
return prefixes;
}
/**
* A list of event names to a configurable list of vendor prefixes.
*/
var vendorPrefixes = {
animationend: makePrefixMap('Animation', 'AnimationEnd'),
animationiteration: makePrefixMap('Animation', 'AnimationIteration'),
animationstart: makePrefixMap('Animation', 'AnimationStart'),
transitionend: makePrefixMap('Transition', 'TransitionEnd')
};
/**
* Event names that have already been detected and prefixed (if applicable).
*/
var prefixedEventNames = {};
/**
* Element to check for prefixes on.
*/
var style = {};
/**
* Bootstrap if a DOM exists.
*/
if (ExecutionEnvironment.canUseDOM) {
style = document.createElement('div').style;
// On some platforms, in particular some releases of Android 4.x,
// the un-prefixed "animation" and "transition" properties are defined on the
// style object but the events that fire will still be prefixed, so we need
// to check if the un-prefixed events are usable, and if not remove them from the map.
if (!('AnimationEvent' in window)) {
delete vendorPrefixes.animationend.animation;
delete vendorPrefixes.animationiteration.animation;
delete vendorPrefixes.animationstart.animation;
}
// Same as above
if (!('TransitionEvent' in window)) {
delete vendorPrefixes.transitionend.transition;
}
}
/**
* Attempts to determine the correct vendor prefixed event name.
*
* @param {string} eventName
* @returns {string}
*/
function getVendorPrefixedEventName(eventName) {
if (prefixedEventNames[eventName]) {
return prefixedEventNames[eventName];
} else if (!vendorPrefixes[eventName]) {
return eventName;
}
var prefixMap = vendorPrefixes[eventName];
for (var styleProp in prefixMap) {
if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) {
return prefixedEventNames[eventName] = prefixMap[styleProp];
}
}
return '';
}
module.exports = getVendorPrefixedEventName;
/***/ }),
/* 141 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _prodInvariant = __webpack_require__(2),
_assign = __webpack_require__(3);
var DOMPropertyOperations = __webpack_require__(71);
var LinkedValueUtils = __webpack_require__(44);
var ReactDOMComponentTree = __webpack_require__(4);
var ReactUpdates = __webpack_require__(10);
var invariant = __webpack_require__(0);
var warning = __webpack_require__(1);
var didWarnValueLink = false;
var didWarnCheckedLink = false;
var didWarnValueDefaultValue = false;
var didWarnCheckedDefaultChecked = false;
var didWarnControlledToUncontrolled = false;
var didWarnUncontrolledToControlled = false;
function forceUpdateIfMounted() {
if (this._rootNodeID) {
// DOM component is still mounted; update
ReactDOMInput.updateWrapper(this);
}
}
function isControlled(props) {
var usesChecked = props.type === 'checkbox' || props.type === 'radio';
return usesChecked ? props.checked != null : props.value != null;
}
/**
* Implements an <input> host component that allows setting these optional
* props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
*
* If `checked` or `value` are not supplied (or null/undefined), user actions
* that affect the checked state or value will trigger updates to the element.
*
* If they are supplied (and not null/undefined), the rendered element will not
* trigger updates to the element. Instead, the props must change in order for
* the rendered element to be updated.
*
* The rendered element will be initialized as unchecked (or `defaultChecked`)
* with an empty value (or `defaultValue`).
*
* @see http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
*/
var ReactDOMInput = {
getHostProps: function (inst, props) {
var value = LinkedValueUtils.getValue(props);
var checked = LinkedValueUtils.getChecked(props);
var hostProps = _assign({
// Make sure we set .type before any other properties (setting .value
// before .type means .value is lost in IE11 and below)
type: undefined,
// Make sure we set .step before .value (setting .value before .step
// means .value is rounded on mount, based upon step precision)
step: undefined,
// Make sure we set .min & .max before .value (to ensure proper order
// in corner cases such as min or max deriving from value, e.g. Issue #7170)
min: undefined,
max: undefined
}, props, {
defaultChecked: undefined,
defaultValue: undefined,
value: value != null ? value : inst._wrapperState.initialValue,
checked: checked != null ? checked : inst._wrapperState.initialChecked,
onChange: inst._wrapperState.onChange
});
return hostProps;
},
mountWrapper: function (inst, props) {
if (true) {
LinkedValueUtils.checkPropTypes('input', props, inst._currentElement._owner);
var owner = inst._currentElement._owner;
if (props.valueLink !== undefined && !didWarnValueLink) {
true ? warning(false, '`valueLink` prop on `input` is deprecated; set `value` and `onChange` instead.') : void 0;
didWarnValueLink = true;
}
if (props.checkedLink !== undefined && !didWarnCheckedLink) {
true ? warning(false, '`checkedLink` prop on `input` is deprecated; set `value` and `onChange` instead.') : void 0;
didWarnCheckedLink = true;
}
if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) {
true ? warning(false, '%s contains an input of type %s with both checked and defaultChecked props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the checked prop, or the defaultChecked prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type) : void 0;
didWarnCheckedDefaultChecked = true;
}
if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) {
true ? warning(false, '%s contains an input of type %s with both value and defaultValue props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type) : void 0;
didWarnValueDefaultValue = true;
}
}
var defaultValue = props.defaultValue;
inst._wrapperState = {
initialChecked: props.checked != null ? props.checked : props.defaultChecked,
initialValue: props.value != null ? props.value : defaultValue,
listeners: null,
onChange: _handleChange.bind(inst),
controlled: isControlled(props)
};
},
updateWrapper: function (inst) {
var props = inst._currentElement.props;
if (true) {
var controlled = isControlled(props);
var owner = inst._currentElement._owner;
if (!inst._wrapperState.controlled && controlled && !didWarnUncontrolledToControlled) {
true ? warning(false, '%s is changing an uncontrolled input of type %s to be controlled. ' + 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type) : void 0;
didWarnUncontrolledToControlled = true;
}
if (inst._wrapperState.controlled && !controlled && !didWarnControlledToUncontrolled) {
true ? warning(false, '%s is changing a controlled input of type %s to be uncontrolled. ' + 'Input elements should not switch from controlled to uncontrolled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type) : void 0;
didWarnControlledToUncontrolled = true;
}
}
// TODO: Shouldn't this be getChecked(props)?
var checked = props.checked;
if (checked != null) {
DOMPropertyOperations.setValueForProperty(ReactDOMComponentTree.getNodeFromInstance(inst), 'checked', checked || false);
}
var node = ReactDOMComponentTree.getNodeFromInstance(inst);
var value = LinkedValueUtils.getValue(props);
if (value != null) {
if (value === 0 && node.value === '') {
node.value = '0';
// Note: IE9 reports a number inputs as 'text', so check props instead.
} else if (props.type === 'number') {
// Simulate `input.valueAsNumber`. IE9 does not support it
var valueAsNumber = parseFloat(node.value, 10) || 0;
if (
// eslint-disable-next-line
value != valueAsNumber ||
// eslint-disable-next-line
value == valueAsNumber && node.value != value) {
// Cast `value` to a string to ensure the value is set correctly. While
// browsers typically do this as necessary, jsdom doesn't.
node.value = '' + value;
}
} else if (node.value !== '' + value) {
// Cast `value` to a string to ensure the value is set correctly. While
// browsers typically do this as necessary, jsdom doesn't.
node.value = '' + value;
}
} else {
if (props.value == null && props.defaultValue != null) {
// In Chrome, assigning defaultValue to certain input types triggers input validation.
// For number inputs, the display value loses trailing decimal points. For email inputs,
// Chrome raises "The specified value <x> is not a valid email address".
//
// Here we check to see if the defaultValue has actually changed, avoiding these problems
// when the user is inputting text
//
// https://github.com/facebook/react/issues/7253
if (node.defaultValue !== '' + props.defaultValue) {
node.defaultValue = '' + props.defaultValue;
}
}
if (props.checked == null && props.defaultChecked != null) {
node.defaultChecked = !!props.defaultChecked;
}
}
},
postMountWrapper: function (inst) {
var props = inst._currentElement.props;
// This is in postMount because we need access to the DOM node, which is not
// available until after the component has mounted.
var node = ReactDOMComponentTree.getNodeFromInstance(inst);
// Detach value from defaultValue. We won't do anything if we're working on
// submit or reset inputs as those values & defaultValues are linked. They
// are not resetable nodes so this operation doesn't matter and actually
// removes browser-default values (eg "Submit Query") when no value is
// provided.
switch (props.type) {
case 'submit':
case 'reset':
break;
case 'color':
case 'date':
case 'datetime':
case 'datetime-local':
case 'month':
case 'time':
case 'week':
// This fixes the no-show issue on iOS Safari and Android Chrome:
// https://github.com/facebook/react/issues/7233
node.value = '';
node.value = node.defaultValue;
break;
default:
node.value = node.value;
break;
}
// Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug
// this is needed to work around a chrome bug where setting defaultChecked
// will sometimes influence the value of checked (even after detachment).
// Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416
// We need to temporarily unset name to avoid disrupting radio button groups.
var name = node.name;
if (name !== '') {
node.name = '';
}
node.defaultChecked = !node.defaultChecked;
node.defaultChecked = !node.defaultChecked;
if (name !== '') {
node.name = name;
}
}
};
function _handleChange(event) {
var props = this._currentElement.props;
var returnValue = LinkedValueUtils.executeOnChange(props, event);
// Here we use asap to wait until all updates have propagated, which
// is important when using controlled components within layers:
// https://github.com/facebook/react/issues/1698
ReactUpdates.asap(forceUpdateIfMounted, this);
var name = props.name;
if (props.type === 'radio' && name != null) {
var rootNode = ReactDOMComponentTree.getNodeFromInstance(this);
var queryRoot = rootNode;
while (queryRoot.parentNode) {
queryRoot = queryRoot.parentNode;
}
// If `rootNode.form` was non-null, then we could try `form.elements`,
// but that sometimes behaves strangely in IE8. We could also try using
// `form.getElementsByName`, but that will only return direct children
// and won't include inputs that use the HTML5 `form=` attribute. Since
// the input might not even be in a form, let's just use the global
// `querySelectorAll` to ensure we don't miss anything.
var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]');
for (var i = 0; i < group.length; i++) {
var otherNode = group[i];
if (otherNode === rootNode || otherNode.form !== rootNode.form) {
continue;
}
// This will throw if radio buttons rendered by different copies of React
// and the same name are rendered into the same form (same as #1939).
// That's probably okay; we don't support it just as we don't support
// mixing React radio buttons with non-React ones.
var otherInstance = ReactDOMComponentTree.getInstanceFromNode(otherNode);
!otherInstance ? true ? invariant(false, 'ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported.') : _prodInvariant('90') : void 0;
// If this is a controlled radio button group, forcing the input that
// was previously checked to update will cause it to be come re-checked
// as appropriate.
ReactUpdates.asap(forceUpdateIfMounted, otherInstance);
}
}
return returnValue;
}
module.exports = ReactDOMInput;
/***/ }),
/* 142 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _assign = __webpack_require__(3);
var React = __webpack_require__(16);
var ReactDOMComponentTree = __webpack_require__(4);
var ReactDOMSelect = __webpack_require__(73);
var warning = __webpack_require__(1);
var didWarnInvalidOptionChildren = false;
function flattenChildren(children) {
var content = '';
// Flatten children and warn if they aren't strings or numbers;
// invalid types are ignored.
React.Children.forEach(children, function (child) {
if (child == null) {
return;
}
if (typeof child === 'string' || typeof child === 'number') {
content += child;
} else if (!didWarnInvalidOptionChildren) {
didWarnInvalidOptionChildren = true;
true ? warning(false, 'Only strings and numbers are supported as <option> children.') : void 0;
}
});
return content;
}
/**
* Implements an <option> host component that warns when `selected` is set.
*/
var ReactDOMOption = {
mountWrapper: function (inst, props, hostParent) {
// TODO (yungsters): Remove support for `selected` in <option>.
if (true) {
true ? warning(props.selected == null, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.') : void 0;
}
// Look up whether this option is 'selected'
var selectValue = null;
if (hostParent != null) {
var selectParent = hostParent;
if (selectParent._tag === 'optgroup') {
selectParent = selectParent._hostParent;
}
if (selectParent != null && selectParent._tag === 'select') {
selectValue = ReactDOMSelect.getSelectValueContext(selectParent);
}
}
// If the value is null (e.g., no specified value or after initial mount)
// or missing (e.g., for <datalist>), we don't change props.selected
var selected = null;
if (selectValue != null) {
var value;
if (props.value != null) {
value = props.value + '';
} else {
value = flattenChildren(props.children);
}
selected = false;
if (Array.isArray(selectValue)) {
// multiple
for (var i = 0; i < selectValue.length; i++) {
if ('' + selectValue[i] === value) {
selected = true;
break;
}
}
} else {
selected = '' + selectValue === value;
}
}
inst._wrapperState = { selected: selected };
},
postMountWrapper: function (inst) {
// value="" should make a value attribute (#6219)
var props = inst._currentElement.props;
if (props.value != null) {
var node = ReactDOMComponentTree.getNodeFromInstance(inst);
node.setAttribute('value', props.value);
}
},
getHostProps: function (inst, props) {
var hostProps = _assign({ selected: undefined, children: undefined }, props);
// Read state only from initial mount because <select> updates value
// manually; we need the initial state only for server rendering
if (inst._wrapperState.selected != null) {
hostProps.selected = inst._wrapperState.selected;
}
var content = flattenChildren(props.children);
if (content) {
hostProps.children = content;
}
return hostProps;
}
};
module.exports = ReactDOMOption;
/***/ }),
/* 143 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _prodInvariant = __webpack_require__(2),
_assign = __webpack_require__(3);
var LinkedValueUtils = __webpack_require__(44);
var ReactDOMComponentTree = __webpack_require__(4);
var ReactUpdates = __webpack_require__(10);
var invariant = __webpack_require__(0);
var warning = __webpack_require__(1);
var didWarnValueLink = false;
var didWarnValDefaultVal = false;
function forceUpdateIfMounted() {
if (this._rootNodeID) {
// DOM component is still mounted; update
ReactDOMTextarea.updateWrapper(this);
}
}
/**
* Implements a <textarea> host component that allows setting `value`, and
* `defaultValue`. This differs from the traditional DOM API because value is
* usually set as PCDATA children.
*
* If `value` is not supplied (or null/undefined), user actions that affect the
* value will trigger updates to the element.
*
* If `value` is supplied (and not null/undefined), the rendered element will
* not trigger updates to the element. Instead, the `value` prop must change in
* order for the rendered element to be updated.
*
* The rendered element will be initialized with an empty value, the prop
* `defaultValue` if specified, or the children content (deprecated).
*/
var ReactDOMTextarea = {
getHostProps: function (inst, props) {
!(props.dangerouslySetInnerHTML == null) ? true ? invariant(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : _prodInvariant('91') : void 0;
// Always set children to the same thing. In IE9, the selection range will
// get reset if `textContent` is mutated. We could add a check in setTextContent
// to only set the value if/when the value differs from the node value (which would
// completely solve this IE9 bug), but Sebastian+Ben seemed to like this solution.
// The value can be a boolean or object so that's why it's forced to be a string.
var hostProps = _assign({}, props, {
value: undefined,
defaultValue: undefined,
children: '' + inst._wrapperState.initialValue,
onChange: inst._wrapperState.onChange
});
return hostProps;
},
mountWrapper: function (inst, props) {
if (true) {
LinkedValueUtils.checkPropTypes('textarea', props, inst._currentElement._owner);
if (props.valueLink !== undefined && !didWarnValueLink) {
true ? warning(false, '`valueLink` prop on `textarea` is deprecated; set `value` and `onChange` instead.') : void 0;
didWarnValueLink = true;
}
if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) {
true ? warning(false, 'Textarea elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled textarea ' + 'and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components') : void 0;
didWarnValDefaultVal = true;
}
}
var value = LinkedValueUtils.getValue(props);
var initialValue = value;
// Only bother fetching default value if we're going to use it
if (value == null) {
var defaultValue = props.defaultValue;
// TODO (yungsters): Remove support for children content in <textarea>.
var children = props.children;
if (children != null) {
if (true) {
true ? warning(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.') : void 0;
}
!(defaultValue == null) ? true ? invariant(false, 'If you supply `defaultValue` on a <textarea>, do not pass children.') : _prodInvariant('92') : void 0;
if (Array.isArray(children)) {
!(children.length <= 1) ? true ? invariant(false, '<textarea> can only have at most one child.') : _prodInvariant('93') : void 0;
children = children[0];
}
defaultValue = '' + children;
}
if (defaultValue == null) {
defaultValue = '';
}
initialValue = defaultValue;
}
inst._wrapperState = {
initialValue: '' + initialValue,
listeners: null,
onChange: _handleChange.bind(inst)
};
},
updateWrapper: function (inst) {
var props = inst._currentElement.props;
var node = ReactDOMComponentTree.getNodeFromInstance(inst);
var value = LinkedValueUtils.getValue(props);
if (value != null) {
// Cast `value` to a string to ensure the value is set correctly. While
// browsers typically do this as necessary, jsdom doesn't.
var newValue = '' + value;
// To avoid side effects (such as losing text selection), only set value if changed
if (newValue !== node.value) {
node.value = newValue;
}
if (props.defaultValue == null) {
node.defaultValue = newValue;
}
}
if (props.defaultValue != null) {
node.defaultValue = props.defaultValue;
}
},
postMountWrapper: function (inst) {
// This is in postMount because we need access to the DOM node, which is not
// available until after the component has mounted.
var node = ReactDOMComponentTree.getNodeFromInstance(inst);
var textContent = node.textContent;
// Only set node.value if textContent is equal to the expected
// initial value. In IE10/IE11 there is a bug where the placeholder attribute
// will populate textContent as well.
// https://developer.microsoft.com/microsoft-edge/platform/issues/101525/
if (textContent === inst._wrapperState.initialValue) {
node.value = textContent;
}
}
};
function _handleChange(event) {
var props = this._currentElement.props;
var returnValue = LinkedValueUtils.executeOnChange(props, event);
ReactUpdates.asap(forceUpdateIfMounted, this);
return returnValue;
}
module.exports = ReactDOMTextarea;
/***/ }),
/* 144 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _prodInvariant = __webpack_require__(2);
var ReactComponentEnvironment = __webpack_require__(45);
var ReactInstanceMap = __webpack_require__(23);
var ReactInstrumentation = __webpack_require__(7);
var ReactCurrentOwner = __webpack_require__(9);
var ReactReconciler = __webpack_require__(18);
var ReactChildReconciler = __webpack_require__(145);
var emptyFunction = __webpack_require__(8);
var flattenChildren = __webpack_require__(152);
var invariant = __webpack_require__(0);
/**
* Make an update for markup to be rendered and inserted at a supplied index.
*
* @param {string} markup Markup that renders into an element.
* @param {number} toIndex Destination index.
* @private
*/
function makeInsertMarkup(markup, afterNode, toIndex) {
// NOTE: Null values reduce hidden classes.
return {
type: 'INSERT_MARKUP',
content: markup,
fromIndex: null,
fromNode: null,
toIndex: toIndex,
afterNode: afterNode
};
}
/**
* Make an update for moving an existing element to another index.
*
* @param {number} fromIndex Source index of the existing element.
* @param {number} toIndex Destination index of the element.
* @private
*/
function makeMove(child, afterNode, toIndex) {
// NOTE: Null values reduce hidden classes.
return {
type: 'MOVE_EXISTING',
content: null,
fromIndex: child._mountIndex,
fromNode: ReactReconciler.getHostNode(child),
toIndex: toIndex,
afterNode: afterNode
};
}
/**
* Make an update for removing an element at an index.
*
* @param {number} fromIndex Index of the element to remove.
* @private
*/
function makeRemove(child, node) {
// NOTE: Null values reduce hidden classes.
return {
type: 'REMOVE_NODE',
content: null,
fromIndex: child._mountIndex,
fromNode: node,
toIndex: null,
afterNode: null
};
}
/**
* Make an update for setting the markup of a node.
*
* @param {string} markup Markup that renders into an element.
* @private
*/
function makeSetMarkup(markup) {
// NOTE: Null values reduce hidden classes.
return {
type: 'SET_MARKUP',
content: markup,
fromIndex: null,
fromNode: null,
toIndex: null,
afterNode: null
};
}
/**
* Make an update for setting the text content.
*
* @param {string} textContent Text content to set.
* @private
*/
function makeTextContent(textContent) {
// NOTE: Null values reduce hidden classes.
return {
type: 'TEXT_CONTENT',
content: textContent,
fromIndex: null,
fromNode: null,
toIndex: null,
afterNode: null
};
}
/**
* Push an update, if any, onto the queue. Creates a new queue if none is
* passed and always returns the queue. Mutative.
*/
function enqueue(queue, update) {
if (update) {
queue = queue || [];
queue.push(update);
}
return queue;
}
/**
* Processes any enqueued updates.
*
* @private
*/
function processQueue(inst, updateQueue) {
ReactComponentEnvironment.processChildrenUpdates(inst, updateQueue);
}
var setChildrenForInstrumentation = emptyFunction;
if (true) {
var getDebugID = function (inst) {
if (!inst._debugID) {
// Check for ART-like instances. TODO: This is silly/gross.
var internal;
if (internal = ReactInstanceMap.get(inst)) {
inst = internal;
}
}
return inst._debugID;
};
setChildrenForInstrumentation = function (children) {
var debugID = getDebugID(this);
// TODO: React Native empty components are also multichild.
// This means they still get into this method but don't have _debugID.
if (debugID !== 0) {
ReactInstrumentation.debugTool.onSetChildren(debugID, children ? Object.keys(children).map(function (key) {
return children[key]._debugID;
}) : []);
}
};
}
/**
* ReactMultiChild are capable of reconciling multiple children.
*
* @class ReactMultiChild
* @internal
*/
var ReactMultiChild = {
/**
* Provides common functionality for components that must reconcile multiple
* children. This is used by `ReactDOMComponent` to mount, update, and
* unmount child components.
*
* @lends {ReactMultiChild.prototype}
*/
Mixin: {
_reconcilerInstantiateChildren: function (nestedChildren, transaction, context) {
if (true) {
var selfDebugID = getDebugID(this);
if (this._currentElement) {
try {
ReactCurrentOwner.current = this._currentElement._owner;
return ReactChildReconciler.instantiateChildren(nestedChildren, transaction, context, selfDebugID);
} finally {
ReactCurrentOwner.current = null;
}
}
}
return ReactChildReconciler.instantiateChildren(nestedChildren, transaction, context);
},
_reconcilerUpdateChildren: function (prevChildren, nextNestedChildrenElements, mountImages, removedNodes, transaction, context) {
var nextChildren;
var selfDebugID = 0;
if (true) {
selfDebugID = getDebugID(this);
if (this._currentElement) {
try {
ReactCurrentOwner.current = this._currentElement._owner;
nextChildren = flattenChildren(nextNestedChildrenElements, selfDebugID);
} finally {
ReactCurrentOwner.current = null;
}
ReactChildReconciler.updateChildren(prevChildren, nextChildren, mountImages, removedNodes, transaction, this, this._hostContainerInfo, context, selfDebugID);
return nextChildren;
}
}
nextChildren = flattenChildren(nextNestedChildrenElements, selfDebugID);
ReactChildReconciler.updateChildren(prevChildren, nextChildren, mountImages, removedNodes, transaction, this, this._hostContainerInfo, context, selfDebugID);
return nextChildren;
},
/**
* Generates a "mount image" for each of the supplied children. In the case
* of `ReactDOMComponent`, a mount image is a string of markup.
*
* @param {?object} nestedChildren Nested child maps.
* @return {array} An array of mounted representations.
* @internal
*/
mountChildren: function (nestedChildren, transaction, context) {
var children = this._reconcilerInstantiateChildren(nestedChildren, transaction, context);
this._renderedChildren = children;
var mountImages = [];
var index = 0;
for (var name in children) {
if (children.hasOwnProperty(name)) {
var child = children[name];
var selfDebugID = 0;
if (true) {
selfDebugID = getDebugID(this);
}
var mountImage = ReactReconciler.mountComponent(child, transaction, this, this._hostContainerInfo, context, selfDebugID);
child._mountIndex = index++;
mountImages.push(mountImage);
}
}
if (true) {
setChildrenForInstrumentation.call(this, children);
}
return mountImages;
},
/**
* Replaces any rendered children with a text content string.
*
* @param {string} nextContent String of content.
* @internal
*/
updateTextContent: function (nextContent) {
var prevChildren = this._renderedChildren;
// Remove any rendered children.
ReactChildReconciler.unmountChildren(prevChildren, false);
for (var name in prevChildren) {
if (prevChildren.hasOwnProperty(name)) {
true ? true ? invariant(false, 'updateTextContent called on non-empty component.') : _prodInvariant('118') : void 0;
}
}
// Set new text content.
var updates = [makeTextContent(nextContent)];
processQueue(this, updates);
},
/**
* Replaces any rendered children with a markup string.
*
* @param {string} nextMarkup String of markup.
* @internal
*/
updateMarkup: function (nextMarkup) {
var prevChildren = this._renderedChildren;
// Remove any rendered children.
ReactChildReconciler.unmountChildren(prevChildren, false);
for (var name in prevChildren) {
if (prevChildren.hasOwnProperty(name)) {
true ? true ? invariant(false, 'updateTextContent called on non-empty component.') : _prodInvariant('118') : void 0;
}
}
var updates = [makeSetMarkup(nextMarkup)];
processQueue(this, updates);
},
/**
* Updates the rendered children with new children.
*
* @param {?object} nextNestedChildrenElements Nested child element maps.
* @param {ReactReconcileTransaction} transaction
* @internal
*/
updateChildren: function (nextNestedChildrenElements, transaction, context) {
// Hook used by React ART
this._updateChildren(nextNestedChildrenElements, transaction, context);
},
/**
* @param {?object} nextNestedChildrenElements Nested child element maps.
* @param {ReactReconcileTransaction} transaction
* @final
* @protected
*/
_updateChildren: function (nextNestedChildrenElements, transaction, context) {
var prevChildren = this._renderedChildren;
var removedNodes = {};
var mountImages = [];
var nextChildren = this._reconcilerUpdateChildren(prevChildren, nextNestedChildrenElements, mountImages, removedNodes, transaction, context);
if (!nextChildren && !prevChildren) {
return;
}
var updates = null;
var name;
// `nextIndex` will increment for each child in `nextChildren`, but
// `lastIndex` will be the last index visited in `prevChildren`.
var nextIndex = 0;
var lastIndex = 0;
// `nextMountIndex` will increment for each newly mounted child.
var nextMountIndex = 0;
var lastPlacedNode = null;
for (name in nextChildren) {
if (!nextChildren.hasOwnProperty(name)) {
continue;
}
var prevChild = prevChildren && prevChildren[name];
var nextChild = nextChildren[name];
if (prevChild === nextChild) {
updates = enqueue(updates, this.moveChild(prevChild, lastPlacedNode, nextIndex, lastIndex));
lastIndex = Math.max(prevChild._mountIndex, lastIndex);
prevChild._mountIndex = nextIndex;
} else {
if (prevChild) {
// Update `lastIndex` before `_mountIndex` gets unset by unmounting.
lastIndex = Math.max(prevChild._mountIndex, lastIndex);
// The `removedNodes` loop below will actually remove the child.
}
// The child must be instantiated before it's mounted.
updates = enqueue(updates, this._mountChildAtIndex(nextChild, mountImages[nextMountIndex], lastPlacedNode, nextIndex, transaction, context));
nextMountIndex++;
}
nextIndex++;
lastPlacedNode = ReactReconciler.getHostNode(nextChild);
}
// Remove children that are no longer present.
for (name in removedNodes) {
if (removedNodes.hasOwnProperty(name)) {
updates = enqueue(updates, this._unmountChild(prevChildren[name], removedNodes[name]));
}
}
if (updates) {
processQueue(this, updates);
}
this._renderedChildren = nextChildren;
if (true) {
setChildrenForInstrumentation.call(this, nextChildren);
}
},
/**
* Unmounts all rendered children. This should be used to clean up children
* when this component is unmounted. It does not actually perform any
* backend operations.
*
* @internal
*/
unmountChildren: function (safely) {
var renderedChildren = this._renderedChildren;
ReactChildReconciler.unmountChildren(renderedChildren, safely);
this._renderedChildren = null;
},
/**
* Moves a child component to the supplied index.
*
* @param {ReactComponent} child Component to move.
* @param {number} toIndex Destination index of the element.
* @param {number} lastIndex Last index visited of the siblings of `child`.
* @protected
*/
moveChild: function (child, afterNode, toIndex, lastIndex) {
// If the index of `child` is less than `lastIndex`, then it needs to
// be moved. Otherwise, we do not need to move it because a child will be
// inserted or moved before `child`.
if (child._mountIndex < lastIndex) {
return makeMove(child, afterNode, toIndex);
}
},
/**
* Creates a child component.
*
* @param {ReactComponent} child Component to create.
* @param {string} mountImage Markup to insert.
* @protected
*/
createChild: function (child, afterNode, mountImage) {
return makeInsertMarkup(mountImage, afterNode, child._mountIndex);
},
/**
* Removes a child component.
*
* @param {ReactComponent} child Child to remove.
* @protected
*/
removeChild: function (child, node) {
return makeRemove(child, node);
},
/**
* Mounts a child with the supplied name.
*
* NOTE: This is part of `updateChildren` and is here for readability.
*
* @param {ReactComponent} child Component to mount.
* @param {string} name Name of the child.
* @param {number} index Index at which to insert the child.
* @param {ReactReconcileTransaction} transaction
* @private
*/
_mountChildAtIndex: function (child, mountImage, afterNode, index, transaction, context) {
child._mountIndex = index;
return this.createChild(child, afterNode, mountImage);
},
/**
* Unmounts a rendered child.
*
* NOTE: This is part of `updateChildren` and is here for readability.
*
* @param {ReactComponent} child Component to unmount.
* @private
*/
_unmountChild: function (child, node) {
var update = this.removeChild(child, node);
child._mountIndex = null;
return update;
}
}
};
module.exports = ReactMultiChild;
/***/ }),
/* 145 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* WEBPACK VAR INJECTION */(function(process) {/**
* Copyright (c) 2014-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var ReactReconciler = __webpack_require__(18);
var instantiateReactComponent = __webpack_require__(74);
var KeyEscapeUtils = __webpack_require__(48);
var shouldUpdateReactComponent = __webpack_require__(47);
var traverseAllChildren = __webpack_require__(78);
var warning = __webpack_require__(1);
var ReactComponentTreeHook;
if (typeof process !== 'undefined' && process.env && "test" === 'test') {
// Temporary hack.
// Inline requires don't work well with Jest:
// https://github.com/facebook/react/issues/7240
// Remove the inline requires when we don't need them anymore:
// https://github.com/facebook/react/pull/7178
ReactComponentTreeHook = __webpack_require__(6);
}
function instantiateChild(childInstances, child, name, selfDebugID) {
// We found a component instance.
var keyUnique = childInstances[name] === undefined;
if (true) {
if (!ReactComponentTreeHook) {
ReactComponentTreeHook = __webpack_require__(6);
}
if (!keyUnique) {
true ? warning(false, 'flattenChildren(...): Encountered two children with the same key, ' + '`%s`. Child keys must be unique; when two children share a key, only ' + 'the first child will be used.%s', KeyEscapeUtils.unescape(name), ReactComponentTreeHook.getStackAddendumByID(selfDebugID)) : void 0;
}
}
if (child != null && keyUnique) {
childInstances[name] = instantiateReactComponent(child, true);
}
}
/**
* ReactChildReconciler provides helpers for initializing or updating a set of
* children. Its output is suitable for passing it onto ReactMultiChild which
* does diffed reordering and insertion.
*/
var ReactChildReconciler = {
/**
* Generates a "mount image" for each of the supplied children. In the case
* of `ReactDOMComponent`, a mount image is a string of markup.
*
* @param {?object} nestedChildNodes Nested child maps.
* @return {?object} A set of child instances.
* @internal
*/
instantiateChildren: function (nestedChildNodes, transaction, context, selfDebugID) // 0 in production and for roots
{
if (nestedChildNodes == null) {
return null;
}
var childInstances = {};
if (true) {
traverseAllChildren(nestedChildNodes, function (childInsts, child, name) {
return instantiateChild(childInsts, child, name, selfDebugID);
}, childInstances);
} else {
traverseAllChildren(nestedChildNodes, instantiateChild, childInstances);
}
return childInstances;
},
/**
* Updates the rendered children and returns a new set of children.
*
* @param {?object} prevChildren Previously initialized set of children.
* @param {?object} nextChildren Flat child element maps.
* @param {ReactReconcileTransaction} transaction
* @param {object} context
* @return {?object} A new set of child instances.
* @internal
*/
updateChildren: function (prevChildren, nextChildren, mountImages, removedNodes, transaction, hostParent, hostContainerInfo, context, selfDebugID) // 0 in production and for roots
{
// We currently don't have a way to track moves here but if we use iterators
// instead of for..in we can zip the iterators and check if an item has
// moved.
// TODO: If nothing has changed, return the prevChildren object so that we
// can quickly bailout if nothing has changed.
if (!nextChildren && !prevChildren) {
return;
}
var name;
var prevChild;
for (name in nextChildren) {
if (!nextChildren.hasOwnProperty(name)) {
continue;
}
prevChild = prevChildren && prevChildren[name];
var prevElement = prevChild && prevChild._currentElement;
var nextElement = nextChildren[name];
if (prevChild != null && shouldUpdateReactComponent(prevElement, nextElement)) {
ReactReconciler.receiveComponent(prevChild, nextElement, transaction, context);
nextChildren[name] = prevChild;
} else {
if (prevChild) {
removedNodes[name] = ReactReconciler.getHostNode(prevChild);
ReactReconciler.unmountComponent(prevChild, false);
}
// The child must be instantiated before it's mounted.
var nextChildInstance = instantiateReactComponent(nextElement, true);
nextChildren[name] = nextChildInstance;
// Creating mount image now ensures refs are resolved in right order
// (see https://github.com/facebook/react/pull/7101 for explanation).
var nextChildMountImage = ReactReconciler.mountComponent(nextChildInstance, transaction, hostParent, hostContainerInfo, context, selfDebugID);
mountImages.push(nextChildMountImage);
}
}
// Unmount children that are no longer present.
for (name in prevChildren) {
if (prevChildren.hasOwnProperty(name) && !(nextChildren && nextChildren.hasOwnProperty(name))) {
prevChild = prevChildren[name];
removedNodes[name] = ReactReconciler.getHostNode(prevChild);
ReactReconciler.unmountComponent(prevChild, false);
}
}
},
/**
* Unmounts all rendered children. This should be used to clean up children
* when this component is unmounted.
*
* @param {?object} renderedChildren Previously initialized set of children.
* @internal
*/
unmountChildren: function (renderedChildren, safely) {
for (var name in renderedChildren) {
if (renderedChildren.hasOwnProperty(name)) {
var renderedChild = renderedChildren[name];
ReactReconciler.unmountComponent(renderedChild, safely);
}
}
}
};
module.exports = ReactChildReconciler;
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(24)))
/***/ }),
/* 146 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _prodInvariant = __webpack_require__(2),
_assign = __webpack_require__(3);
var React = __webpack_require__(16);
var ReactComponentEnvironment = __webpack_require__(45);
var ReactCurrentOwner = __webpack_require__(9);
var ReactErrorUtils = __webpack_require__(37);
var ReactInstanceMap = __webpack_require__(23);
var ReactInstrumentation = __webpack_require__(7);
var ReactNodeTypes = __webpack_require__(75);
var ReactReconciler = __webpack_require__(18);
if (true) {
var checkReactTypeSpec = __webpack_require__(147);
}
var emptyObject = __webpack_require__(27);
var invariant = __webpack_require__(0);
var shallowEqual = __webpack_require__(46);
var shouldUpdateReactComponent = __webpack_require__(47);
var warning = __webpack_require__(1);
var CompositeTypes = {
ImpureClass: 0,
PureClass: 1,
StatelessFunctional: 2
};
function StatelessComponent(Component) {}
StatelessComponent.prototype.render = function () {
var Component = ReactInstanceMap.get(this)._currentElement.type;
var element = Component(this.props, this.context, this.updater);
warnIfInvalidElement(Component, element);
return element;
};
function warnIfInvalidElement(Component, element) {
if (true) {
true ? warning(element === null || element === false || React.isValidElement(element), '%s(...): A valid React element (or null) must be returned. You may have ' + 'returned undefined, an array or some other invalid object.', Component.displayName || Component.name || 'Component') : void 0;
true ? warning(!Component.childContextTypes, '%s(...): childContextTypes cannot be defined on a functional component.', Component.displayName || Component.name || 'Component') : void 0;
}
}
function shouldConstruct(Component) {
return !!(Component.prototype && Component.prototype.isReactComponent);
}
function isPureComponent(Component) {
return !!(Component.prototype && Component.prototype.isPureReactComponent);
}
// Separated into a function to contain deoptimizations caused by try/finally.
function measureLifeCyclePerf(fn, debugID, timerType) {
if (debugID === 0) {
// Top-level wrappers (see ReactMount) and empty components (see
// ReactDOMEmptyComponent) are invisible to hooks and devtools.
// Both are implementation details that should go away in the future.
return fn();
}
ReactInstrumentation.debugTool.onBeginLifeCycleTimer(debugID, timerType);
try {
return fn();
} finally {
ReactInstrumentation.debugTool.onEndLifeCycleTimer(debugID, timerType);
}
}
/**
* ------------------ The Life-Cycle of a Composite Component ------------------
*
* - constructor: Initialization of state. The instance is now retained.
* - componentWillMount
* - render
* - [children's constructors]
* - [children's componentWillMount and render]
* - [children's componentDidMount]
* - componentDidMount
*
* Update Phases:
* - componentWillReceiveProps (only called if parent updated)
* - shouldComponentUpdate
* - componentWillUpdate
* - render
* - [children's constructors or receive props phases]
* - componentDidUpdate
*
* - componentWillUnmount
* - [children's componentWillUnmount]
* - [children destroyed]
* - (destroyed): The instance is now blank, released by React and ready for GC.
*
* -----------------------------------------------------------------------------
*/
/**
* An incrementing ID assigned to each component when it is mounted. This is
* used to enforce the order in which `ReactUpdates` updates dirty components.
*
* @private
*/
var nextMountID = 1;
/**
* @lends {ReactCompositeComponent.prototype}
*/
var ReactCompositeComponent = {
/**
* Base constructor for all composite component.
*
* @param {ReactElement} element
* @final
* @internal
*/
construct: function (element) {
this._currentElement = element;
this._rootNodeID = 0;
this._compositeType = null;
this._instance = null;
this._hostParent = null;
this._hostContainerInfo = null;
// See ReactUpdateQueue
this._updateBatchNumber = null;
this._pendingElement = null;
this._pendingStateQueue = null;
this._pendingReplaceState = false;
this._pendingForceUpdate = false;
this._renderedNodeType = null;
this._renderedComponent = null;
this._context = null;
this._mountOrder = 0;
this._topLevelWrapper = null;
// See ReactUpdates and ReactUpdateQueue.
this._pendingCallbacks = null;
// ComponentWillUnmount shall only be called once
this._calledComponentWillUnmount = false;
if (true) {
this._warnedAboutRefsInRender = false;
}
},
/**
* Initializes the component, renders markup, and registers event listeners.
*
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
* @param {?object} hostParent
* @param {?object} hostContainerInfo
* @param {?object} context
* @return {?string} Rendered markup to be inserted into the DOM.
* @final
* @internal
*/
mountComponent: function (transaction, hostParent, hostContainerInfo, context) {
var _this = this;
this._context = context;
this._mountOrder = nextMountID++;
this._hostParent = hostParent;
this._hostContainerInfo = hostContainerInfo;
var publicProps = this._currentElement.props;
var publicContext = this._processContext(context);
var Component = this._currentElement.type;
var updateQueue = transaction.getUpdateQueue();
// Initialize the public class
var doConstruct = shouldConstruct(Component);
var inst = this._constructComponent(doConstruct, publicProps, publicContext, updateQueue);
var renderedElement;
// Support functional components
if (!doConstruct && (inst == null || inst.render == null)) {
renderedElement = inst;
warnIfInvalidElement(Component, renderedElement);
!(inst === null || inst === false || React.isValidElement(inst)) ? true ? invariant(false, '%s(...): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.', Component.displayName || Component.name || 'Component') : _prodInvariant('105', Component.displayName || Component.name || 'Component') : void 0;
inst = new StatelessComponent(Component);
this._compositeType = CompositeTypes.StatelessFunctional;
} else {
if (isPureComponent(Component)) {
this._compositeType = CompositeTypes.PureClass;
} else {
this._compositeType = CompositeTypes.ImpureClass;
}
}
if (true) {
// This will throw later in _renderValidatedComponent, but add an early
// warning now to help debugging
if (inst.render == null) {
true ? warning(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', Component.displayName || Component.name || 'Component') : void 0;
}
var propsMutated = inst.props !== publicProps;
var componentName = Component.displayName || Component.name || 'Component';
true ? warning(inst.props === undefined || !propsMutated, '%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", componentName, componentName) : void 0;
}
// These should be set up in the constructor, but as a convenience for
// simpler class abstractions, we set them up after the fact.
inst.props = publicProps;
inst.context = publicContext;
inst.refs = emptyObject;
inst.updater = updateQueue;
this._instance = inst;
// Store a reference from the instance back to the internal representation
ReactInstanceMap.set(inst, this);
if (true) {
// Since plain JS classes are defined without any special initialization
// logic, we can not catch common errors early. Therefore, we have to
// catch them here, at initialization time, instead.
true ? warning(!inst.getInitialState || inst.getInitialState.isReactClassApproved || inst.state, 'getInitialState was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Did you mean to define a state property instead?', this.getName() || 'a component') : void 0;
true ? warning(!inst.getDefaultProps || inst.getDefaultProps.isReactClassApproved, 'getDefaultProps was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Use a static property to define defaultProps instead.', this.getName() || 'a component') : void 0;
true ? warning(!inst.propTypes, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', this.getName() || 'a component') : void 0;
true ? warning(!inst.contextTypes, 'contextTypes was defined as an instance property on %s. Use a ' + 'static property to define contextTypes instead.', this.getName() || 'a component') : void 0;
true ? warning(typeof inst.componentShouldUpdate !== 'function', '%s has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + 'expected to return a value.', this.getName() || 'A component') : void 0;
true ? warning(typeof inst.componentDidUnmount !== 'function', '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', this.getName() || 'A component') : void 0;
true ? warning(typeof inst.componentWillRecieveProps !== 'function', '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', this.getName() || 'A component') : void 0;
}
var initialState = inst.state;
if (initialState === undefined) {
inst.state = initialState = null;
}
!(typeof initialState === 'object' && !Array.isArray(initialState)) ? true ? invariant(false, '%s.state: must be set to an object or null', this.getName() || 'ReactCompositeComponent') : _prodInvariant('106', this.getName() || 'ReactCompositeComponent') : void 0;
this._pendingStateQueue = null;
this._pendingReplaceState = false;
this._pendingForceUpdate = false;
var markup;
if (inst.unstable_handleError) {
markup = this.performInitialMountWithErrorHandling(renderedElement, hostParent, hostContainerInfo, transaction, context);
} else {
markup = this.performInitialMount(renderedElement, hostParent, hostContainerInfo, transaction, context);
}
if (inst.componentDidMount) {
if (true) {
transaction.getReactMountReady().enqueue(function () {
measureLifeCyclePerf(function () {
return inst.componentDidMount();
}, _this._debugID, 'componentDidMount');
});
} else {
transaction.getReactMountReady().enqueue(inst.componentDidMount, inst);
}
}
return markup;
},
_constructComponent: function (doConstruct, publicProps, publicContext, updateQueue) {
if ("test" !== 'production' && !doConstruct) {
ReactCurrentOwner.current = this;
try {
return this._constructComponentWithoutOwner(doConstruct, publicProps, publicContext, updateQueue);
} finally {
ReactCurrentOwner.current = null;
}
} else {
return this._constructComponentWithoutOwner(doConstruct, publicProps, publicContext, updateQueue);
}
},
_constructComponentWithoutOwner: function (doConstruct, publicProps, publicContext, updateQueue) {
var Component = this._currentElement.type;
if (doConstruct) {
if (true) {
return measureLifeCyclePerf(function () {
return new Component(publicProps, publicContext, updateQueue);
}, this._debugID, 'ctor');
} else {
return new Component(publicProps, publicContext, updateQueue);
}
}
// This can still be an instance in case of factory components
// but we'll count this as time spent rendering as the more common case.
if (true) {
return measureLifeCyclePerf(function () {
return Component(publicProps, publicContext, updateQueue);
}, this._debugID, 'render');
} else {
return Component(publicProps, publicContext, updateQueue);
}
},
performInitialMountWithErrorHandling: function (renderedElement, hostParent, hostContainerInfo, transaction, context) {
var markup;
var checkpoint = transaction.checkpoint();
try {
markup = this.performInitialMount(renderedElement, hostParent, hostContainerInfo, transaction, context);
} catch (e) {
// Roll back to checkpoint, handle error (which may add items to the transaction), and take a new checkpoint
transaction.rollback(checkpoint);
this._instance.unstable_handleError(e);
if (this._pendingStateQueue) {
this._instance.state = this._processPendingState(this._instance.props, this._instance.context);
}
checkpoint = transaction.checkpoint();
this._renderedComponent.unmountComponent(true);
transaction.rollback(checkpoint);
// Try again - we've informed the component about the error, so they can render an error message this time.
// If this throws again, the error will bubble up (and can be caught by a higher error boundary).
markup = this.performInitialMount(renderedElement, hostParent, hostContainerInfo, transaction, context);
}
return markup;
},
performInitialMount: function (renderedElement, hostParent, hostContainerInfo, transaction, context) {
var inst = this._instance;
var debugID = 0;
if (true) {
debugID = this._debugID;
}
if (inst.componentWillMount) {
if (true) {
measureLifeCyclePerf(function () {
return inst.componentWillMount();
}, debugID, 'componentWillMount');
} else {
inst.componentWillMount();
}
// When mounting, calls to `setState` by `componentWillMount` will set
// `this._pendingStateQueue` without triggering a re-render.
if (this._pendingStateQueue) {
inst.state = this._processPendingState(inst.props, inst.context);
}
}
// If not a stateless component, we now render
if (renderedElement === undefined) {
renderedElement = this._renderValidatedComponent();
}
var nodeType = ReactNodeTypes.getType(renderedElement);
this._renderedNodeType = nodeType;
var child = this._instantiateReactComponent(renderedElement, nodeType !== ReactNodeTypes.EMPTY /* shouldHaveDebugID */
);
this._renderedComponent = child;
var markup = ReactReconciler.mountComponent(child, transaction, hostParent, hostContainerInfo, this._processChildContext(context), debugID);
if (true) {
if (debugID !== 0) {
var childDebugIDs = child._debugID !== 0 ? [child._debugID] : [];
ReactInstrumentation.debugTool.onSetChildren(debugID, childDebugIDs);
}
}
return markup;
},
getHostNode: function () {
return ReactReconciler.getHostNode(this._renderedComponent);
},
/**
* Releases any resources allocated by `mountComponent`.
*
* @final
* @internal
*/
unmountComponent: function (safely) {
if (!this._renderedComponent) {
return;
}
var inst = this._instance;
if (inst.componentWillUnmount && !inst._calledComponentWillUnmount) {
inst._calledComponentWillUnmount = true;
if (safely) {
var name = this.getName() + '.componentWillUnmount()';
ReactErrorUtils.invokeGuardedCallback(name, inst.componentWillUnmount.bind(inst));
} else {
if (true) {
measureLifeCyclePerf(function () {
return inst.componentWillUnmount();
}, this._debugID, 'componentWillUnmount');
} else {
inst.componentWillUnmount();
}
}
}
if (this._renderedComponent) {
ReactReconciler.unmountComponent(this._renderedComponent, safely);
this._renderedNodeType = null;
this._renderedComponent = null;
this._instance = null;
}
// Reset pending fields
// Even if this component is scheduled for another update in ReactUpdates,
// it would still be ignored because these fields are reset.
this._pendingStateQueue = null;
this._pendingReplaceState = false;
this._pendingForceUpdate = false;
this._pendingCallbacks = null;
this._pendingElement = null;
// These fields do not really need to be reset since this object is no
// longer accessible.
this._context = null;
this._rootNodeID = 0;
this._topLevelWrapper = null;
// Delete the reference from the instance to this internal representation
// which allow the internals to be properly cleaned up even if the user
// leaks a reference to the public instance.
ReactInstanceMap.remove(inst);
// Some existing components rely on inst.props even after they've been
// destroyed (in event handlers).
// TODO: inst.props = null;
// TODO: inst.state = null;
// TODO: inst.context = null;
},
/**
* Filters the context object to only contain keys specified in
* `contextTypes`
*
* @param {object} context
* @return {?object}
* @private
*/
_maskContext: function (context) {
var Component = this._currentElement.type;
var contextTypes = Component.contextTypes;
if (!contextTypes) {
return emptyObject;
}
var maskedContext = {};
for (var contextName in contextTypes) {
maskedContext[contextName] = context[contextName];
}
return maskedContext;
},
/**
* Filters the context object to only contain keys specified in
* `contextTypes`, and asserts that they are valid.
*
* @param {object} context
* @return {?object}
* @private
*/
_processContext: function (context) {
var maskedContext = this._maskContext(context);
if (true) {
var Component = this._currentElement.type;
if (Component.contextTypes) {
this._checkContextTypes(Component.contextTypes, maskedContext, 'context');
}
}
return maskedContext;
},
/**
* @param {object} currentContext
* @return {object}
* @private
*/
_processChildContext: function (currentContext) {
var Component = this._currentElement.type;
var inst = this._instance;
var childContext;
if (inst.getChildContext) {
if (true) {
ReactInstrumentation.debugTool.onBeginProcessingChildContext();
try {
childContext = inst.getChildContext();
} finally {
ReactInstrumentation.debugTool.onEndProcessingChildContext();
}
} else {
childContext = inst.getChildContext();
}
}
if (childContext) {
!(typeof Component.childContextTypes === 'object') ? true ? invariant(false, '%s.getChildContext(): childContextTypes must be defined in order to use getChildContext().', this.getName() || 'ReactCompositeComponent') : _prodInvariant('107', this.getName() || 'ReactCompositeComponent') : void 0;
if (true) {
this._checkContextTypes(Component.childContextTypes, childContext, 'child context');
}
for (var name in childContext) {
!(name in Component.childContextTypes) ? true ? invariant(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', this.getName() || 'ReactCompositeComponent', name) : _prodInvariant('108', this.getName() || 'ReactCompositeComponent', name) : void 0;
}
return _assign({}, currentContext, childContext);
}
return currentContext;
},
/**
* Assert that the context types are valid
*
* @param {object} typeSpecs Map of context field to a ReactPropType
* @param {object} values Runtime values that need to be type-checked
* @param {string} location e.g. "prop", "context", "child context"
* @private
*/
_checkContextTypes: function (typeSpecs, values, location) {
if (true) {
checkReactTypeSpec(typeSpecs, values, location, this.getName(), null, this._debugID);
}
},
receiveComponent: function (nextElement, transaction, nextContext) {
var prevElement = this._currentElement;
var prevContext = this._context;
this._pendingElement = null;
this.updateComponent(transaction, prevElement, nextElement, prevContext, nextContext);
},
/**
* If any of `_pendingElement`, `_pendingStateQueue`, or `_pendingForceUpdate`
* is set, update the component.
*
* @param {ReactReconcileTransaction} transaction
* @internal
*/
performUpdateIfNecessary: function (transaction) {
if (this._pendingElement != null) {
ReactReconciler.receiveComponent(this, this._pendingElement, transaction, this._context);
} else if (this._pendingStateQueue !== null || this._pendingForceUpdate) {
this.updateComponent(transaction, this._currentElement, this._currentElement, this._context, this._context);
} else {
this._updateBatchNumber = null;
}
},
/**
* Perform an update to a mounted component. The componentWillReceiveProps and
* shouldComponentUpdate methods are called, then (assuming the update isn't
* skipped) the remaining update lifecycle methods are called and the DOM
* representation is updated.
*
* By default, this implements React's rendering and reconciliation algorithm.
* Sophisticated clients may wish to override this.
*
* @param {ReactReconcileTransaction} transaction
* @param {ReactElement} prevParentElement
* @param {ReactElement} nextParentElement
* @internal
* @overridable
*/
updateComponent: function (transaction, prevParentElement, nextParentElement, prevUnmaskedContext, nextUnmaskedContext) {
var inst = this._instance;
!(inst != null) ? true ? invariant(false, 'Attempted to update component `%s` that has already been unmounted (or failed to mount).', this.getName() || 'ReactCompositeComponent') : _prodInvariant('136', this.getName() || 'ReactCompositeComponent') : void 0;
var willReceive = false;
var nextContext;
// Determine if the context has changed or not
if (this._context === nextUnmaskedContext) {
nextContext = inst.context;
} else {
nextContext = this._processContext(nextUnmaskedContext);
willReceive = true;
}
var prevProps = prevParentElement.props;
var nextProps = nextParentElement.props;
// Not a simple state update but a props update
if (prevParentElement !== nextParentElement) {
willReceive = true;
}
// An update here will schedule an update but immediately set
// _pendingStateQueue which will ensure that any state updates gets
// immediately reconciled instead of waiting for the next batch.
if (willReceive && inst.componentWillReceiveProps) {
if (true) {
measureLifeCyclePerf(function () {
return inst.componentWillReceiveProps(nextProps, nextContext);
}, this._debugID, 'componentWillReceiveProps');
} else {
inst.componentWillReceiveProps(nextProps, nextContext);
}
}
var nextState = this._processPendingState(nextProps, nextContext);
var shouldUpdate = true;
if (!this._pendingForceUpdate) {
if (inst.shouldComponentUpdate) {
if (true) {
shouldUpdate = measureLifeCyclePerf(function () {
return inst.shouldComponentUpdate(nextProps, nextState, nextContext);
}, this._debugID, 'shouldComponentUpdate');
} else {
shouldUpdate = inst.shouldComponentUpdate(nextProps, nextState, nextContext);
}
} else {
if (this._compositeType === CompositeTypes.PureClass) {
shouldUpdate = !shallowEqual(prevProps, nextProps) || !shallowEqual(inst.state, nextState);
}
}
}
if (true) {
true ? warning(shouldUpdate !== undefined, '%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', this.getName() || 'ReactCompositeComponent') : void 0;
}
this._updateBatchNumber = null;
if (shouldUpdate) {
this._pendingForceUpdate = false;
// Will set `this.props`, `this.state` and `this.context`.
this._performComponentUpdate(nextParentElement, nextProps, nextState, nextContext, transaction, nextUnmaskedContext);
} else {
// If it's determined that a component should not update, we still want
// to set props and state but we shortcut the rest of the update.
this._currentElement = nextParentElement;
this._context = nextUnmaskedContext;
inst.props = nextProps;
inst.state = nextState;
inst.context = nextContext;
}
},
_processPendingState: function (props, context) {
var inst = this._instance;
var queue = this._pendingStateQueue;
var replace = this._pendingReplaceState;
this._pendingReplaceState = false;
this._pendingStateQueue = null;
if (!queue) {
return inst.state;
}
if (replace && queue.length === 1) {
return queue[0];
}
var nextState = _assign({}, replace ? queue[0] : inst.state);
for (var i = replace ? 1 : 0; i < queue.length; i++) {
var partial = queue[i];
_assign(nextState, typeof partial === 'function' ? partial.call(inst, nextState, props, context) : partial);
}
return nextState;
},
/**
* Merges new props and state, notifies delegate methods of update and
* performs update.
*
* @param {ReactElement} nextElement Next element
* @param {object} nextProps Next public object to set as properties.
* @param {?object} nextState Next object to set as state.
* @param {?object} nextContext Next public object to set as context.
* @param {ReactReconcileTransaction} transaction
* @param {?object} unmaskedContext
* @private
*/
_performComponentUpdate: function (nextElement, nextProps, nextState, nextContext, transaction, unmaskedContext) {
var _this2 = this;
var inst = this._instance;
var hasComponentDidUpdate = Boolean(inst.componentDidUpdate);
var prevProps;
var prevState;
var prevContext;
if (hasComponentDidUpdate) {
prevProps = inst.props;
prevState = inst.state;
prevContext = inst.context;
}
if (inst.componentWillUpdate) {
if (true) {
measureLifeCyclePerf(function () {
return inst.componentWillUpdate(nextProps, nextState, nextContext);
}, this._debugID, 'componentWillUpdate');
} else {
inst.componentWillUpdate(nextProps, nextState, nextContext);
}
}
this._currentElement = nextElement;
this._context = unmaskedContext;
inst.props = nextProps;
inst.state = nextState;
inst.context = nextContext;
this._updateRenderedComponent(transaction, unmaskedContext);
if (hasComponentDidUpdate) {
if (true) {
transaction.getReactMountReady().enqueue(function () {
measureLifeCyclePerf(inst.componentDidUpdate.bind(inst, prevProps, prevState, prevContext), _this2._debugID, 'componentDidUpdate');
});
} else {
transaction.getReactMountReady().enqueue(inst.componentDidUpdate.bind(inst, prevProps, prevState, prevContext), inst);
}
}
},
/**
* Call the component's `render` method and update the DOM accordingly.
*
* @param {ReactReconcileTransaction} transaction
* @internal
*/
_updateRenderedComponent: function (transaction, context) {
var prevComponentInstance = this._renderedComponent;
var prevRenderedElement = prevComponentInstance._currentElement;
var nextRenderedElement = this._renderValidatedComponent();
var debugID = 0;
if (true) {
debugID = this._debugID;
}
if (shouldUpdateReactComponent(prevRenderedElement, nextRenderedElement)) {
ReactReconciler.receiveComponent(prevComponentInstance, nextRenderedElement, transaction, this._processChildContext(context));
} else {
var oldHostNode = ReactReconciler.getHostNode(prevComponentInstance);
ReactReconciler.unmountComponent(prevComponentInstance, false);
var nodeType = ReactNodeTypes.getType(nextRenderedElement);
this._renderedNodeType = nodeType;
var child = this._instantiateReactComponent(nextRenderedElement, nodeType !== ReactNodeTypes.EMPTY /* shouldHaveDebugID */
);
this._renderedComponent = child;
var nextMarkup = ReactReconciler.mountComponent(child, transaction, this._hostParent, this._hostContainerInfo, this._processChildContext(context), debugID);
if (true) {
if (debugID !== 0) {
var childDebugIDs = child._debugID !== 0 ? [child._debugID] : [];
ReactInstrumentation.debugTool.onSetChildren(debugID, childDebugIDs);
}
}
this._replaceNodeWithMarkup(oldHostNode, nextMarkup, prevComponentInstance);
}
},
/**
* Overridden in shallow rendering.
*
* @protected
*/
_replaceNodeWithMarkup: function (oldHostNode, nextMarkup, prevInstance) {
ReactComponentEnvironment.replaceNodeWithMarkup(oldHostNode, nextMarkup, prevInstance);
},
/**
* @protected
*/
_renderValidatedComponentWithoutOwnerOrContext: function () {
var inst = this._instance;
var renderedElement;
if (true) {
renderedElement = measureLifeCyclePerf(function () {
return inst.render();
}, this._debugID, 'render');
} else {
renderedElement = inst.render();
}
if (true) {
// We allow auto-mocks to proceed as if they're returning null.
if (renderedElement === undefined && inst.render._isMockFunction) {
// This is probably bad practice. Consider warning here and
// deprecating this convenience.
renderedElement = null;
}
}
return renderedElement;
},
/**
* @private
*/
_renderValidatedComponent: function () {
var renderedElement;
if (true) {
ReactCurrentOwner.current = this;
try {
renderedElement = this._renderValidatedComponentWithoutOwnerOrContext();
} finally {
ReactCurrentOwner.current = null;
}
} else {
renderedElement = this._renderValidatedComponentWithoutOwnerOrContext();
}
!(
// TODO: An `isValidNode` function would probably be more appropriate
renderedElement === null || renderedElement === false || React.isValidElement(renderedElement)) ? true ? invariant(false, '%s.render(): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.', this.getName() || 'ReactCompositeComponent') : _prodInvariant('109', this.getName() || 'ReactCompositeComponent') : void 0;
return renderedElement;
},
/**
* Lazily allocates the refs object and stores `component` as `ref`.
*
* @param {string} ref Reference name.
* @param {component} component Component to store as `ref`.
* @final
* @private
*/
attachRef: function (ref, component) {
var inst = this.getPublicInstance();
!(inst != null) ? true ? invariant(false, 'Stateless function components cannot have refs.') : _prodInvariant('110') : void 0;
var publicComponentInstance = component.getPublicInstance();
if (true) {
var componentName = component && component.getName ? component.getName() : 'a component';
true ? warning(publicComponentInstance != null || component._compositeType !== CompositeTypes.StatelessFunctional, 'Stateless function components cannot be given refs ' + '(See ref "%s" in %s created by %s). ' + 'Attempts to access this ref will fail.', ref, componentName, this.getName()) : void 0;
}
var refs = inst.refs === emptyObject ? inst.refs = {} : inst.refs;
refs[ref] = publicComponentInstance;
},
/**
* Detaches a reference name.
*
* @param {string} ref Name to dereference.
* @final
* @private
*/
detachRef: function (ref) {
var refs = this.getPublicInstance().refs;
delete refs[ref];
},
/**
* Get a text description of the component that can be used to identify it
* in error messages.
* @return {string} The name or null.
* @internal
*/
getName: function () {
var type = this._currentElement.type;
var constructor = this._instance && this._instance.constructor;
return type.displayName || constructor && constructor.displayName || type.name || constructor && constructor.name || null;
},
/**
* Get the publicly accessible representation of this component - i.e. what
* is exposed by refs and returned by render. Can be null for stateless
* components.
*
* @return {ReactComponent} the public component instance.
* @internal
*/
getPublicInstance: function () {
var inst = this._instance;
if (this._compositeType === CompositeTypes.StatelessFunctional) {
return null;
}
return inst;
},
// Stub
_instantiateReactComponent: null
};
module.exports = ReactCompositeComponent;
/***/ }),
/* 147 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* WEBPACK VAR INJECTION */(function(process) {/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _prodInvariant = __webpack_require__(2);
var ReactPropTypeLocationNames = __webpack_require__(148);
var ReactPropTypesSecret = __webpack_require__(72);
var invariant = __webpack_require__(0);
var warning = __webpack_require__(1);
var ReactComponentTreeHook;
if (typeof process !== 'undefined' && process.env && "test" === 'test') {
// Temporary hack.
// Inline requires don't work well with Jest:
// https://github.com/facebook/react/issues/7240
// Remove the inline requires when we don't need them anymore:
// https://github.com/facebook/react/pull/7178
ReactComponentTreeHook = __webpack_require__(6);
}
var loggedTypeFailures = {};
/**
* Assert that the values match with the type specs.
* Error messages are memorized and will only be shown once.
*
* @param {object} typeSpecs Map of name to a ReactPropType
* @param {object} values Runtime values that need to be type-checked
* @param {string} location e.g. "prop", "context", "child context"
* @param {string} componentName Name of the component for error messages.
* @param {?object} element The React element that is being type-checked
* @param {?number} debugID The React component instance that is being type-checked
* @private
*/
function checkReactTypeSpec(typeSpecs, values, location, componentName, element, debugID) {
for (var typeSpecName in typeSpecs) {
if (typeSpecs.hasOwnProperty(typeSpecName)) {
var error;
// Prop type validation may throw. In case they do, we don't want to
// fail the render phase where it didn't fail before. So we log it.
// After these have been cleaned up, we'll let them throw.
try {
// This is intentionally an invariant that gets caught. It's the same
// behavior as without this statement except with a better message.
!(typeof typeSpecs[typeSpecName] === 'function') ? true ? invariant(false, '%s: %s type `%s` is invalid; it must be a function, usually from React.PropTypes.', componentName || 'React class', ReactPropTypeLocationNames[location], typeSpecName) : _prodInvariant('84', componentName || 'React class', ReactPropTypeLocationNames[location], typeSpecName) : void 0;
error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);
} catch (ex) {
error = ex;
}
true ? warning(!error || error instanceof Error, '%s: type specification of %s `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', ReactPropTypeLocationNames[location], typeSpecName, typeof error) : void 0;
if (error instanceof Error && !(error.message in loggedTypeFailures)) {
// Only monitor this failure once because there tends to be a lot of the
// same error.
loggedTypeFailures[error.message] = true;
var componentStackInfo = '';
if (true) {
if (!ReactComponentTreeHook) {
ReactComponentTreeHook = __webpack_require__(6);
}
if (debugID !== null) {
componentStackInfo = ReactComponentTreeHook.getStackAddendumByID(debugID);
} else if (element !== null) {
componentStackInfo = ReactComponentTreeHook.getCurrentStackAddendum(element);
}
}
true ? warning(false, 'Failed %s type: %s%s', location, error.message, componentStackInfo) : void 0;
}
}
}
}
module.exports = checkReactTypeSpec;
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(24)))
/***/ }),
/* 148 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var ReactPropTypeLocationNames = {};
if (true) {
ReactPropTypeLocationNames = {
prop: 'prop',
context: 'context',
childContext: 'child context'
};
}
module.exports = ReactPropTypeLocationNames;
/***/ }),
/* 149 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var nextDebugID = 1;
function getNextDebugID() {
return nextDebugID++;
}
module.exports = getNextDebugID;
/***/ }),
/* 150 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2014-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
// The Symbol used to tag the ReactElement type. If there is no native Symbol
// nor polyfill, then a plain number is used for performance.
var REACT_ELEMENT_TYPE = typeof Symbol === 'function' && Symbol['for'] && Symbol['for']('react.element') || 0xeac7;
module.exports = REACT_ELEMENT_TYPE;
/***/ }),
/* 151 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
/* global Symbol */
var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec.
/**
* Returns the iterator method function contained on the iterable object.
*
* Be sure to invoke the function with the iterable as context:
*
* var iteratorFn = getIteratorFn(myIterable);
* if (iteratorFn) {
* var iterator = iteratorFn.call(myIterable);
* ...
* }
*
* @param {?object} maybeIterable
* @return {?function}
*/
function getIteratorFn(maybeIterable) {
var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]);
if (typeof iteratorFn === 'function') {
return iteratorFn;
}
}
module.exports = getIteratorFn;
/***/ }),
/* 152 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* WEBPACK VAR INJECTION */(function(process) {/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var KeyEscapeUtils = __webpack_require__(48);
var traverseAllChildren = __webpack_require__(78);
var warning = __webpack_require__(1);
var ReactComponentTreeHook;
if (typeof process !== 'undefined' && process.env && "test" === 'test') {
// Temporary hack.
// Inline requires don't work well with Jest:
// https://github.com/facebook/react/issues/7240
// Remove the inline requires when we don't need them anymore:
// https://github.com/facebook/react/pull/7178
ReactComponentTreeHook = __webpack_require__(6);
}
/**
* @param {function} traverseContext Context passed through traversal.
* @param {?ReactComponent} child React child component.
* @param {!string} name String name of key path to child.
* @param {number=} selfDebugID Optional debugID of the current internal instance.
*/
function flattenSingleChildIntoContext(traverseContext, child, name, selfDebugID) {
// We found a component instance.
if (traverseContext && typeof traverseContext === 'object') {
var result = traverseContext;
var keyUnique = result[name] === undefined;
if (true) {
if (!ReactComponentTreeHook) {
ReactComponentTreeHook = __webpack_require__(6);
}
if (!keyUnique) {
true ? warning(false, 'flattenChildren(...): Encountered two children with the same key, ' + '`%s`. Child keys must be unique; when two children share a key, only ' + 'the first child will be used.%s', KeyEscapeUtils.unescape(name), ReactComponentTreeHook.getStackAddendumByID(selfDebugID)) : void 0;
}
}
if (keyUnique && child != null) {
result[name] = child;
}
}
}
/**
* Flattens children that are typically specified as `props.children`. Any null
* children will not be included in the resulting object.
* @return {!object} flattened children keyed by name.
*/
function flattenChildren(children, selfDebugID) {
if (children == null) {
return children;
}
var result = {};
if (true) {
traverseAllChildren(children, function (traverseContext, child, name) {
return flattenSingleChildIntoContext(traverseContext, child, name, selfDebugID);
}, result);
} else {
traverseAllChildren(children, flattenSingleChildIntoContext, result);
}
return result;
}
module.exports = flattenChildren;
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(24)))
/***/ }),
/* 153 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2014-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _assign = __webpack_require__(3);
var PooledClass = __webpack_require__(15);
var Transaction = __webpack_require__(29);
var ReactInstrumentation = __webpack_require__(7);
var ReactServerUpdateQueue = __webpack_require__(154);
/**
* Executed within the scope of the `Transaction` instance. Consider these as
* being member methods, but with an implied ordering while being isolated from
* each other.
*/
var TRANSACTION_WRAPPERS = [];
if (true) {
TRANSACTION_WRAPPERS.push({
initialize: ReactInstrumentation.debugTool.onBeginFlush,
close: ReactInstrumentation.debugTool.onEndFlush
});
}
var noopCallbackQueue = {
enqueue: function () {}
};
/**
* @class ReactServerRenderingTransaction
* @param {boolean} renderToStaticMarkup
*/
function ReactServerRenderingTransaction(renderToStaticMarkup) {
this.reinitializeTransaction();
this.renderToStaticMarkup = renderToStaticMarkup;
this.useCreateElement = false;
this.updateQueue = new ReactServerUpdateQueue(this);
}
var Mixin = {
/**
* @see Transaction
* @abstract
* @final
* @return {array} Empty list of operation wrap procedures.
*/
getTransactionWrappers: function () {
return TRANSACTION_WRAPPERS;
},
/**
* @return {object} The queue to collect `onDOMReady` callbacks with.
*/
getReactMountReady: function () {
return noopCallbackQueue;
},
/**
* @return {object} The queue to collect React async events.
*/
getUpdateQueue: function () {
return this.updateQueue;
},
/**
* `PooledClass` looks for this, and will invoke this before allowing this
* instance to be reused.
*/
destructor: function () {},
checkpoint: function () {},
rollback: function () {}
};
_assign(ReactServerRenderingTransaction.prototype, Transaction, Mixin);
PooledClass.addPoolingTo(ReactServerRenderingTransaction);
module.exports = ReactServerRenderingTransaction;
/***/ }),
/* 154 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var ReactUpdateQueue = __webpack_require__(49);
var warning = __webpack_require__(1);
function warnNoop(publicInstance, callerName) {
if (true) {
var constructor = publicInstance.constructor;
true ? warning(false, '%s(...): Can only update a mounting component. ' + 'This usually means you called %s() outside componentWillMount() on the server. ' + 'This is a no-op. Please check the code for the %s component.', callerName, callerName, constructor && (constructor.displayName || constructor.name) || 'ReactClass') : void 0;
}
}
/**
* This is the update queue used for server rendering.
* It delegates to ReactUpdateQueue while server rendering is in progress and
* switches to ReactNoopUpdateQueue after the transaction has completed.
* @class ReactServerUpdateQueue
* @param {Transaction} transaction
*/
var ReactServerUpdateQueue = function () {
function ReactServerUpdateQueue(transaction) {
_classCallCheck(this, ReactServerUpdateQueue);
this.transaction = transaction;
}
/**
* Checks whether or not this composite component is mounted.
* @param {ReactClass} publicInstance The instance we want to test.
* @return {boolean} True if mounted, false otherwise.
* @protected
* @final
*/
ReactServerUpdateQueue.prototype.isMounted = function isMounted(publicInstance) {
return false;
};
/**
* Enqueue a callback that will be executed after all the pending updates
* have processed.
*
* @param {ReactClass} publicInstance The instance to use as `this` context.
* @param {?function} callback Called after state is updated.
* @internal
*/
ReactServerUpdateQueue.prototype.enqueueCallback = function enqueueCallback(publicInstance, callback, callerName) {
if (this.transaction.isInTransaction()) {
ReactUpdateQueue.enqueueCallback(publicInstance, callback, callerName);
}
};
/**
* Forces an update. This should only be invoked when it is known with
* certainty that we are **not** in a DOM transaction.
*
* You may want to call this when you know that some deeper aspect of the
* component's state has changed but `setState` was not called.
*
* This will not invoke `shouldComponentUpdate`, but it will invoke
* `componentWillUpdate` and `componentDidUpdate`.
*
* @param {ReactClass} publicInstance The instance that should rerender.
* @internal
*/
ReactServerUpdateQueue.prototype.enqueueForceUpdate = function enqueueForceUpdate(publicInstance) {
if (this.transaction.isInTransaction()) {
ReactUpdateQueue.enqueueForceUpdate(publicInstance);
} else {
warnNoop(publicInstance, 'forceUpdate');
}
};
/**
* Replaces all of the state. Always use this or `setState` to mutate state.
* You should treat `this.state` as immutable.
*
* There is no guarantee that `this.state` will be immediately updated, so
* accessing `this.state` after calling this method may return the old value.
*
* @param {ReactClass} publicInstance The instance that should rerender.
* @param {object|function} completeState Next state.
* @internal
*/
ReactServerUpdateQueue.prototype.enqueueReplaceState = function enqueueReplaceState(publicInstance, completeState) {
if (this.transaction.isInTransaction()) {
ReactUpdateQueue.enqueueReplaceState(publicInstance, completeState);
} else {
warnNoop(publicInstance, 'replaceState');
}
};
/**
* Sets a subset of the state. This only exists because _pendingState is
* internal. This provides a merging strategy that is not available to deep
* properties which is confusing. TODO: Expose pendingState or don't use it
* during the merge.
*
* @param {ReactClass} publicInstance The instance that should rerender.
* @param {object|function} partialState Next partial state to be merged with state.
* @internal
*/
ReactServerUpdateQueue.prototype.enqueueSetState = function enqueueSetState(publicInstance, partialState) {
if (this.transaction.isInTransaction()) {
ReactUpdateQueue.enqueueSetState(publicInstance, partialState);
} else {
warnNoop(publicInstance, 'setState');
}
};
return ReactServerUpdateQueue;
}();
module.exports = ReactServerUpdateQueue;
/***/ }),
/* 155 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2014-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _assign = __webpack_require__(3);
var DOMLazyTree = __webpack_require__(19);
var ReactDOMComponentTree = __webpack_require__(4);
var ReactDOMEmptyComponent = function (instantiate) {
// ReactCompositeComponent uses this:
this._currentElement = null;
// ReactDOMComponentTree uses these:
this._hostNode = null;
this._hostParent = null;
this._hostContainerInfo = null;
this._domID = 0;
};
_assign(ReactDOMEmptyComponent.prototype, {
mountComponent: function (transaction, hostParent, hostContainerInfo, context) {
var domID = hostContainerInfo._idCounter++;
this._domID = domID;
this._hostParent = hostParent;
this._hostContainerInfo = hostContainerInfo;
var nodeValue = ' react-empty: ' + this._domID + ' ';
if (transaction.useCreateElement) {
var ownerDocument = hostContainerInfo._ownerDocument;
var node = ownerDocument.createComment(nodeValue);
ReactDOMComponentTree.precacheNode(this, node);
return DOMLazyTree(node);
} else {
if (transaction.renderToStaticMarkup) {
// Normally we'd insert a comment node, but since this is a situation
// where React won't take over (static pages), we can simply return
// nothing.
return '';
}
return '<!--' + nodeValue + '-->';
}
},
receiveComponent: function () {},
getHostNode: function () {
return ReactDOMComponentTree.getNodeFromInstance(this);
},
unmountComponent: function () {
ReactDOMComponentTree.uncacheNode(this);
}
});
module.exports = ReactDOMEmptyComponent;
/***/ }),
/* 156 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _prodInvariant = __webpack_require__(2);
var invariant = __webpack_require__(0);
/**
* Return the lowest common ancestor of A and B, or null if they are in
* different trees.
*/
function getLowestCommonAncestor(instA, instB) {
!('_hostNode' in instA) ? true ? invariant(false, 'getNodeFromInstance: Invalid argument.') : _prodInvariant('33') : void 0;
!('_hostNode' in instB) ? true ? invariant(false, 'getNodeFromInstance: Invalid argument.') : _prodInvariant('33') : void 0;
var depthA = 0;
for (var tempA = instA; tempA; tempA = tempA._hostParent) {
depthA++;
}
var depthB = 0;
for (var tempB = instB; tempB; tempB = tempB._hostParent) {
depthB++;
}
// If A is deeper, crawl up.
while (depthA - depthB > 0) {
instA = instA._hostParent;
depthA--;
}
// If B is deeper, crawl up.
while (depthB - depthA > 0) {
instB = instB._hostParent;
depthB--;
}
// Walk in lockstep until we find a match.
var depth = depthA;
while (depth--) {
if (instA === instB) {
return instA;
}
instA = instA._hostParent;
instB = instB._hostParent;
}
return null;
}
/**
* Return if A is an ancestor of B.
*/
function isAncestor(instA, instB) {
!('_hostNode' in instA) ? true ? invariant(false, 'isAncestor: Invalid argument.') : _prodInvariant('35') : void 0;
!('_hostNode' in instB) ? true ? invariant(false, 'isAncestor: Invalid argument.') : _prodInvariant('35') : void 0;
while (instB) {
if (instB === instA) {
return true;
}
instB = instB._hostParent;
}
return false;
}
/**
* Return the parent instance of the passed-in instance.
*/
function getParentInstance(inst) {
!('_hostNode' in inst) ? true ? invariant(false, 'getParentInstance: Invalid argument.') : _prodInvariant('36') : void 0;
return inst._hostParent;
}
/**
* Simulates the traversal of a two-phase, capture/bubble event dispatch.
*/
function traverseTwoPhase(inst, fn, arg) {
var path = [];
while (inst) {
path.push(inst);
inst = inst._hostParent;
}
var i;
for (i = path.length; i-- > 0;) {
fn(path[i], 'captured', arg);
}
for (i = 0; i < path.length; i++) {
fn(path[i], 'bubbled', arg);
}
}
/**
* Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that
* should would receive a `mouseEnter` or `mouseLeave` event.
*
* Does not invoke the callback on the nearest common ancestor because nothing
* "entered" or "left" that element.
*/
function traverseEnterLeave(from, to, fn, argFrom, argTo) {
var common = from && to ? getLowestCommonAncestor(from, to) : null;
var pathFrom = [];
while (from && from !== common) {
pathFrom.push(from);
from = from._hostParent;
}
var pathTo = [];
while (to && to !== common) {
pathTo.push(to);
to = to._hostParent;
}
var i;
for (i = 0; i < pathFrom.length; i++) {
fn(pathFrom[i], 'bubbled', argFrom);
}
for (i = pathTo.length; i-- > 0;) {
fn(pathTo[i], 'captured', argTo);
}
}
module.exports = {
isAncestor: isAncestor,
getLowestCommonAncestor: getLowestCommonAncestor,
getParentInstance: getParentInstance,
traverseTwoPhase: traverseTwoPhase,
traverseEnterLeave: traverseEnterLeave
};
/***/ }),
/* 157 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _prodInvariant = __webpack_require__(2),
_assign = __webpack_require__(3);
var DOMChildrenOperations = __webpack_require__(41);
var DOMLazyTree = __webpack_require__(19);
var ReactDOMComponentTree = __webpack_require__(4);
var escapeTextContentForBrowser = __webpack_require__(32);
var invariant = __webpack_require__(0);
var validateDOMNesting = __webpack_require__(50);
/**
* Text nodes violate a couple assumptions that React makes about components:
*
* - When mounting text into the DOM, adjacent text nodes are merged.
* - Text nodes cannot be assigned a React root ID.
*
* This component is used to wrap strings between comment nodes so that they
* can undergo the same reconciliation that is applied to elements.
*
* TODO: Investigate representing React components in the DOM with text nodes.
*
* @class ReactDOMTextComponent
* @extends ReactComponent
* @internal
*/
var ReactDOMTextComponent = function (text) {
// TODO: This is really a ReactText (ReactNode), not a ReactElement
this._currentElement = text;
this._stringText = '' + text;
// ReactDOMComponentTree uses these:
this._hostNode = null;
this._hostParent = null;
// Properties
this._domID = 0;
this._mountIndex = 0;
this._closingComment = null;
this._commentNodes = null;
};
_assign(ReactDOMTextComponent.prototype, {
/**
* Creates the markup for this text node. This node is not intended to have
* any features besides containing text content.
*
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
* @return {string} Markup for this text node.
* @internal
*/
mountComponent: function (transaction, hostParent, hostContainerInfo, context) {
if (true) {
var parentInfo;
if (hostParent != null) {
parentInfo = hostParent._ancestorInfo;
} else if (hostContainerInfo != null) {
parentInfo = hostContainerInfo._ancestorInfo;
}
if (parentInfo) {
// parentInfo should always be present except for the top-level
// component when server rendering
validateDOMNesting(null, this._stringText, this, parentInfo);
}
}
var domID = hostContainerInfo._idCounter++;
var openingValue = ' react-text: ' + domID + ' ';
var closingValue = ' /react-text ';
this._domID = domID;
this._hostParent = hostParent;
if (transaction.useCreateElement) {
var ownerDocument = hostContainerInfo._ownerDocument;
var openingComment = ownerDocument.createComment(openingValue);
var closingComment = ownerDocument.createComment(closingValue);
var lazyTree = DOMLazyTree(ownerDocument.createDocumentFragment());
DOMLazyTree.queueChild(lazyTree, DOMLazyTree(openingComment));
if (this._stringText) {
DOMLazyTree.queueChild(lazyTree, DOMLazyTree(ownerDocument.createTextNode(this._stringText)));
}
DOMLazyTree.queueChild(lazyTree, DOMLazyTree(closingComment));
ReactDOMComponentTree.precacheNode(this, openingComment);
this._closingComment = closingComment;
return lazyTree;
} else {
var escapedText = escapeTextContentForBrowser(this._stringText);
if (transaction.renderToStaticMarkup) {
// Normally we'd wrap this between comment nodes for the reasons stated
// above, but since this is a situation where React won't take over
// (static pages), we can simply return the text as it is.
return escapedText;
}
return '<!--' + openingValue + '-->' + escapedText + '<!--' + closingValue + '-->';
}
},
/**
* Updates this component by updating the text content.
*
* @param {ReactText} nextText The next text content
* @param {ReactReconcileTransaction} transaction
* @internal
*/
receiveComponent: function (nextText, transaction) {
if (nextText !== this._currentElement) {
this._currentElement = nextText;
var nextStringText = '' + nextText;
if (nextStringText !== this._stringText) {
// TODO: Save this as pending props and use performUpdateIfNecessary
// and/or updateComponent to do the actual update for consistency with
// other component types?
this._stringText = nextStringText;
var commentNodes = this.getHostNode();
DOMChildrenOperations.replaceDelimitedText(commentNodes[0], commentNodes[1], nextStringText);
}
}
},
getHostNode: function () {
var hostNode = this._commentNodes;
if (hostNode) {
return hostNode;
}
if (!this._closingComment) {
var openingComment = ReactDOMComponentTree.getNodeFromInstance(this);
var node = openingComment.nextSibling;
while (true) {
!(node != null) ? true ? invariant(false, 'Missing closing comment for text component %s', this._domID) : _prodInvariant('67', this._domID) : void 0;
if (node.nodeType === 8 && node.nodeValue === ' /react-text ') {
this._closingComment = node;
break;
}
node = node.nextSibling;
}
}
hostNode = [this._hostNode, this._closingComment];
this._commentNodes = hostNode;
return hostNode;
},
unmountComponent: function () {
this._closingComment = null;
this._commentNodes = null;
ReactDOMComponentTree.uncacheNode(this);
}
});
module.exports = ReactDOMTextComponent;
/***/ }),
/* 158 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _assign = __webpack_require__(3);
var ReactUpdates = __webpack_require__(10);
var Transaction = __webpack_require__(29);
var emptyFunction = __webpack_require__(8);
var RESET_BATCHED_UPDATES = {
initialize: emptyFunction,
close: function () {
ReactDefaultBatchingStrategy.isBatchingUpdates = false;
}
};
var FLUSH_BATCHED_UPDATES = {
initialize: emptyFunction,
close: ReactUpdates.flushBatchedUpdates.bind(ReactUpdates)
};
var TRANSACTION_WRAPPERS = [FLUSH_BATCHED_UPDATES, RESET_BATCHED_UPDATES];
function ReactDefaultBatchingStrategyTransaction() {
this.reinitializeTransaction();
}
_assign(ReactDefaultBatchingStrategyTransaction.prototype, Transaction, {
getTransactionWrappers: function () {
return TRANSACTION_WRAPPERS;
}
});
var transaction = new ReactDefaultBatchingStrategyTransaction();
var ReactDefaultBatchingStrategy = {
isBatchingUpdates: false,
/**
* Call the provided function in a context within which calls to `setState`
* and friends are batched such that components aren't updated unnecessarily.
*/
batchedUpdates: function (callback, a, b, c, d, e) {
var alreadyBatchingUpdates = ReactDefaultBatchingStrategy.isBatchingUpdates;
ReactDefaultBatchingStrategy.isBatchingUpdates = true;
// The code is written this way to avoid extra allocations
if (alreadyBatchingUpdates) {
return callback(a, b, c, d, e);
} else {
return transaction.perform(callback, null, a, b, c, d, e);
}
}
};
module.exports = ReactDefaultBatchingStrategy;
/***/ }),
/* 159 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _assign = __webpack_require__(3);
var EventListener = __webpack_require__(79);
var ExecutionEnvironment = __webpack_require__(5);
var PooledClass = __webpack_require__(15);
var ReactDOMComponentTree = __webpack_require__(4);
var ReactUpdates = __webpack_require__(10);
var getEventTarget = __webpack_require__(38);
var getUnboundedScrollPosition = __webpack_require__(160);
/**
* Find the deepest React component completely containing the root of the
* passed-in instance (for use when entire React trees are nested within each
* other). If React trees are not nested, returns null.
*/
function findParent(inst) {
// TODO: It may be a good idea to cache this to prevent unnecessary DOM
// traversal, but caching is difficult to do correctly without using a
// mutation observer to listen for all DOM changes.
while (inst._hostParent) {
inst = inst._hostParent;
}
var rootNode = ReactDOMComponentTree.getNodeFromInstance(inst);
var container = rootNode.parentNode;
return ReactDOMComponentTree.getClosestInstanceFromNode(container);
}
// Used to store ancestor hierarchy in top level callback
function TopLevelCallbackBookKeeping(topLevelType, nativeEvent) {
this.topLevelType = topLevelType;
this.nativeEvent = nativeEvent;
this.ancestors = [];
}
_assign(TopLevelCallbackBookKeeping.prototype, {
destructor: function () {
this.topLevelType = null;
this.nativeEvent = null;
this.ancestors.length = 0;
}
});
PooledClass.addPoolingTo(TopLevelCallbackBookKeeping, PooledClass.twoArgumentPooler);
function handleTopLevelImpl(bookKeeping) {
var nativeEventTarget = getEventTarget(bookKeeping.nativeEvent);
var targetInst = ReactDOMComponentTree.getClosestInstanceFromNode(nativeEventTarget);
// Loop through the hierarchy, in case there's any nested components.
// It's important that we build the array of ancestors before calling any
// event handlers, because event handlers can modify the DOM, leading to
// inconsistencies with ReactMount's node cache. See #1105.
var ancestor = targetInst;
do {
bookKeeping.ancestors.push(ancestor);
ancestor = ancestor && findParent(ancestor);
} while (ancestor);
for (var i = 0; i < bookKeeping.ancestors.length; i++) {
targetInst = bookKeeping.ancestors[i];
ReactEventListener._handleTopLevel(bookKeeping.topLevelType, targetInst, bookKeeping.nativeEvent, getEventTarget(bookKeeping.nativeEvent));
}
}
function scrollValueMonitor(cb) {
var scrollPosition = getUnboundedScrollPosition(window);
cb(scrollPosition);
}
var ReactEventListener = {
_enabled: true,
_handleTopLevel: null,
WINDOW_HANDLE: ExecutionEnvironment.canUseDOM ? window : null,
setHandleTopLevel: function (handleTopLevel) {
ReactEventListener._handleTopLevel = handleTopLevel;
},
setEnabled: function (enabled) {
ReactEventListener._enabled = !!enabled;
},
isEnabled: function () {
return ReactEventListener._enabled;
},
/**
* Traps top-level events by using event bubbling.
*
* @param {string} topLevelType Record from `EventConstants`.
* @param {string} handlerBaseName Event name (e.g. "click").
* @param {object} element Element on which to attach listener.
* @return {?object} An object with a remove function which will forcefully
* remove the listener.
* @internal
*/
trapBubbledEvent: function (topLevelType, handlerBaseName, element) {
if (!element) {
return null;
}
return EventListener.listen(element, handlerBaseName, ReactEventListener.dispatchEvent.bind(null, topLevelType));
},
/**
* Traps a top-level event by using event capturing.
*
* @param {string} topLevelType Record from `EventConstants`.
* @param {string} handlerBaseName Event name (e.g. "click").
* @param {object} element Element on which to attach listener.
* @return {?object} An object with a remove function which will forcefully
* remove the listener.
* @internal
*/
trapCapturedEvent: function (topLevelType, handlerBaseName, element) {
if (!element) {
return null;
}
return EventListener.capture(element, handlerBaseName, ReactEventListener.dispatchEvent.bind(null, topLevelType));
},
monitorScrollValue: function (refresh) {
var callback = scrollValueMonitor.bind(null, refresh);
EventListener.listen(window, 'scroll', callback);
},
dispatchEvent: function (topLevelType, nativeEvent) {
if (!ReactEventListener._enabled) {
return;
}
var bookKeeping = TopLevelCallbackBookKeeping.getPooled(topLevelType, nativeEvent);
try {
// Event queue being processed in the same cycle allows
// `preventDefault`.
ReactUpdates.batchedUpdates(handleTopLevelImpl, bookKeeping);
} finally {
TopLevelCallbackBookKeeping.release(bookKeeping);
}
}
};
module.exports = ReactEventListener;
/***/ }),
/* 160 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*/
/**
* Gets the scroll position of the supplied element or window.
*
* The return values are unbounded, unlike `getScrollPosition`. This means they
* may be negative or exceed the element boundaries (which is possible using
* inertial scrolling).
*
* @param {DOMWindow|DOMElement} scrollable
* @return {object} Map with `x` and `y` keys.
*/
function getUnboundedScrollPosition(scrollable) {
if (scrollable.Window && scrollable instanceof scrollable.Window) {
return {
x: scrollable.pageXOffset || scrollable.document.documentElement.scrollLeft,
y: scrollable.pageYOffset || scrollable.document.documentElement.scrollTop
};
}
return {
x: scrollable.scrollLeft,
y: scrollable.scrollTop
};
}
module.exports = getUnboundedScrollPosition;
/***/ }),
/* 161 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var DOMProperty = __webpack_require__(13);
var EventPluginHub = __webpack_require__(21);
var EventPluginUtils = __webpack_require__(36);
var ReactComponentEnvironment = __webpack_require__(45);
var ReactEmptyComponent = __webpack_require__(76);
var ReactBrowserEventEmitter = __webpack_require__(33);
var ReactHostComponent = __webpack_require__(77);
var ReactUpdates = __webpack_require__(10);
var ReactInjection = {
Component: ReactComponentEnvironment.injection,
DOMProperty: DOMProperty.injection,
EmptyComponent: ReactEmptyComponent.injection,
EventPluginHub: EventPluginHub.injection,
EventPluginUtils: EventPluginUtils.injection,
EventEmitter: ReactBrowserEventEmitter.injection,
HostComponent: ReactHostComponent.injection,
Updates: ReactUpdates.injection
};
module.exports = ReactInjection;
/***/ }),
/* 162 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _assign = __webpack_require__(3);
var CallbackQueue = __webpack_require__(63);
var PooledClass = __webpack_require__(15);
var ReactBrowserEventEmitter = __webpack_require__(33);
var ReactInputSelection = __webpack_require__(80);
var ReactInstrumentation = __webpack_require__(7);
var Transaction = __webpack_require__(29);
var ReactUpdateQueue = __webpack_require__(49);
/**
* Ensures that, when possible, the selection range (currently selected text
* input) is not disturbed by performing the transaction.
*/
var SELECTION_RESTORATION = {
/**
* @return {Selection} Selection information.
*/
initialize: ReactInputSelection.getSelectionInformation,
/**
* @param {Selection} sel Selection information returned from `initialize`.
*/
close: ReactInputSelection.restoreSelection
};
/**
* Suppresses events (blur/focus) that could be inadvertently dispatched due to
* high level DOM manipulations (like temporarily removing a text input from the
* DOM).
*/
var EVENT_SUPPRESSION = {
/**
* @return {boolean} The enabled status of `ReactBrowserEventEmitter` before
* the reconciliation.
*/
initialize: function () {
var currentlyEnabled = ReactBrowserEventEmitter.isEnabled();
ReactBrowserEventEmitter.setEnabled(false);
return currentlyEnabled;
},
/**
* @param {boolean} previouslyEnabled Enabled status of
* `ReactBrowserEventEmitter` before the reconciliation occurred. `close`
* restores the previous value.
*/
close: function (previouslyEnabled) {
ReactBrowserEventEmitter.setEnabled(previouslyEnabled);
}
};
/**
* Provides a queue for collecting `componentDidMount` and
* `componentDidUpdate` callbacks during the transaction.
*/
var ON_DOM_READY_QUEUEING = {
/**
* Initializes the internal `onDOMReady` queue.
*/
initialize: function () {
this.reactMountReady.reset();
},
/**
* After DOM is flushed, invoke all registered `onDOMReady` callbacks.
*/
close: function () {
this.reactMountReady.notifyAll();
}
};
/**
* Executed within the scope of the `Transaction` instance. Consider these as
* being member methods, but with an implied ordering while being isolated from
* each other.
*/
var TRANSACTION_WRAPPERS = [SELECTION_RESTORATION, EVENT_SUPPRESSION, ON_DOM_READY_QUEUEING];
if (true) {
TRANSACTION_WRAPPERS.push({
initialize: ReactInstrumentation.debugTool.onBeginFlush,
close: ReactInstrumentation.debugTool.onEndFlush
});
}
/**
* Currently:
* - The order that these are listed in the transaction is critical:
* - Suppresses events.
* - Restores selection range.
*
* Future:
* - Restore document/overflow scroll positions that were unintentionally
* modified via DOM insertions above the top viewport boundary.
* - Implement/integrate with customized constraint based layout system and keep
* track of which dimensions must be remeasured.
*
* @class ReactReconcileTransaction
*/
function ReactReconcileTransaction(useCreateElement) {
this.reinitializeTransaction();
// Only server-side rendering really needs this option (see
// `ReactServerRendering`), but server-side uses
// `ReactServerRenderingTransaction` instead. This option is here so that it's
// accessible and defaults to false when `ReactDOMComponent` and
// `ReactDOMTextComponent` checks it in `mountComponent`.`
this.renderToStaticMarkup = false;
this.reactMountReady = CallbackQueue.getPooled(null);
this.useCreateElement = useCreateElement;
}
var Mixin = {
/**
* @see Transaction
* @abstract
* @final
* @return {array<object>} List of operation wrap procedures.
* TODO: convert to array<TransactionWrapper>
*/
getTransactionWrappers: function () {
return TRANSACTION_WRAPPERS;
},
/**
* @return {object} The queue to collect `onDOMReady` callbacks with.
*/
getReactMountReady: function () {
return this.reactMountReady;
},
/**
* @return {object} The queue to collect React async events.
*/
getUpdateQueue: function () {
return ReactUpdateQueue;
},
/**
* Save current transaction state -- if the return value from this method is
* passed to `rollback`, the transaction will be reset to that state.
*/
checkpoint: function () {
// reactMountReady is the our only stateful wrapper
return this.reactMountReady.checkpoint();
},
rollback: function (checkpoint) {
this.reactMountReady.rollback(checkpoint);
},
/**
* `PooledClass` looks for this, and will invoke this before allowing this
* instance to be reused.
*/
destructor: function () {
CallbackQueue.release(this.reactMountReady);
this.reactMountReady = null;
}
};
_assign(ReactReconcileTransaction.prototype, Transaction, Mixin);
PooledClass.addPoolingTo(ReactReconcileTransaction);
module.exports = ReactReconcileTransaction;
/***/ }),
/* 163 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var ExecutionEnvironment = __webpack_require__(5);
var getNodeForCharacterOffset = __webpack_require__(164);
var getTextContentAccessor = __webpack_require__(62);
/**
* While `isCollapsed` is available on the Selection object and `collapsed`
* is available on the Range object, IE11 sometimes gets them wrong.
* If the anchor/focus nodes and offsets are the same, the range is collapsed.
*/
function isCollapsed(anchorNode, anchorOffset, focusNode, focusOffset) {
return anchorNode === focusNode && anchorOffset === focusOffset;
}
/**
* Get the appropriate anchor and focus node/offset pairs for IE.
*
* The catch here is that IE's selection API doesn't provide information
* about whether the selection is forward or backward, so we have to
* behave as though it's always forward.
*
* IE text differs from modern selection in that it behaves as though
* block elements end with a new line. This means character offsets will
* differ between the two APIs.
*
* @param {DOMElement} node
* @return {object}
*/
function getIEOffsets(node) {
var selection = document.selection;
var selectedRange = selection.createRange();
var selectedLength = selectedRange.text.length;
// Duplicate selection so we can move range without breaking user selection.
var fromStart = selectedRange.duplicate();
fromStart.moveToElementText(node);
fromStart.setEndPoint('EndToStart', selectedRange);
var startOffset = fromStart.text.length;
var endOffset = startOffset + selectedLength;
return {
start: startOffset,
end: endOffset
};
}
/**
* @param {DOMElement} node
* @return {?object}
*/
function getModernOffsets(node) {
var selection = window.getSelection && window.getSelection();
if (!selection || selection.rangeCount === 0) {
return null;
}
var anchorNode = selection.anchorNode;
var anchorOffset = selection.anchorOffset;
var focusNode = selection.focusNode;
var focusOffset = selection.focusOffset;
var currentRange = selection.getRangeAt(0);
// In Firefox, range.startContainer and range.endContainer can be "anonymous
// divs", e.g. the up/down buttons on an <input type="number">. Anonymous
// divs do not seem to expose properties, triggering a "Permission denied
// error" if any of its properties are accessed. The only seemingly possible
// way to avoid erroring is to access a property that typically works for
// non-anonymous divs and catch any error that may otherwise arise. See
// https://bugzilla.mozilla.org/show_bug.cgi?id=208427
try {
/* eslint-disable no-unused-expressions */
currentRange.startContainer.nodeType;
currentRange.endContainer.nodeType;
/* eslint-enable no-unused-expressions */
} catch (e) {
return null;
}
// If the node and offset values are the same, the selection is collapsed.
// `Selection.isCollapsed` is available natively, but IE sometimes gets
// this value wrong.
var isSelectionCollapsed = isCollapsed(selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset);
var rangeLength = isSelectionCollapsed ? 0 : currentRange.toString().length;
var tempRange = currentRange.cloneRange();
tempRange.selectNodeContents(node);
tempRange.setEnd(currentRange.startContainer, currentRange.startOffset);
var isTempRangeCollapsed = isCollapsed(tempRange.startContainer, tempRange.startOffset, tempRange.endContainer, tempRange.endOffset);
var start = isTempRangeCollapsed ? 0 : tempRange.toString().length;
var end = start + rangeLength;
// Detect whether the selection is backward.
var detectionRange = document.createRange();
detectionRange.setStart(anchorNode, anchorOffset);
detectionRange.setEnd(focusNode, focusOffset);
var isBackward = detectionRange.collapsed;
return {
start: isBackward ? end : start,
end: isBackward ? start : end
};
}
/**
* @param {DOMElement|DOMTextNode} node
* @param {object} offsets
*/
function setIEOffsets(node, offsets) {
var range = document.selection.createRange().duplicate();
var start, end;
if (offsets.end === undefined) {
start = offsets.start;
end = start;
} else if (offsets.start > offsets.end) {
start = offsets.end;
end = offsets.start;
} else {
start = offsets.start;
end = offsets.end;
}
range.moveToElementText(node);
range.moveStart('character', start);
range.setEndPoint('EndToStart', range);
range.moveEnd('character', end - start);
range.select();
}
/**
* In modern non-IE browsers, we can support both forward and backward
* selections.
*
* Note: IE10+ supports the Selection object, but it does not support
* the `extend` method, which means that even in modern IE, it's not possible
* to programmatically create a backward selection. Thus, for all IE
* versions, we use the old IE API to create our selections.
*
* @param {DOMElement|DOMTextNode} node
* @param {object} offsets
*/
function setModernOffsets(node, offsets) {
if (!window.getSelection) {
return;
}
var selection = window.getSelection();
var length = node[getTextContentAccessor()].length;
var start = Math.min(offsets.start, length);
var end = offsets.end === undefined ? start : Math.min(offsets.end, length);
// IE 11 uses modern selection, but doesn't support the extend method.
// Flip backward selections, so we can set with a single range.
if (!selection.extend && start > end) {
var temp = end;
end = start;
start = temp;
}
var startMarker = getNodeForCharacterOffset(node, start);
var endMarker = getNodeForCharacterOffset(node, end);
if (startMarker && endMarker) {
var range = document.createRange();
range.setStart(startMarker.node, startMarker.offset);
selection.removeAllRanges();
if (start > end) {
selection.addRange(range);
selection.extend(endMarker.node, endMarker.offset);
} else {
range.setEnd(endMarker.node, endMarker.offset);
selection.addRange(range);
}
}
}
var useIEOffsets = ExecutionEnvironment.canUseDOM && 'selection' in document && !('getSelection' in window);
var ReactDOMSelection = {
/**
* @param {DOMElement} node
*/
getOffsets: useIEOffsets ? getIEOffsets : getModernOffsets,
/**
* @param {DOMElement|DOMTextNode} node
* @param {object} offsets
*/
setOffsets: useIEOffsets ? setIEOffsets : setModernOffsets
};
module.exports = ReactDOMSelection;
/***/ }),
/* 164 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
/**
* Given any node return the first leaf node without children.
*
* @param {DOMElement|DOMTextNode} node
* @return {DOMElement|DOMTextNode}
*/
function getLeafNode(node) {
while (node && node.firstChild) {
node = node.firstChild;
}
return node;
}
/**
* Get the next sibling within a container. This will walk up the
* DOM if a node's siblings have been exhausted.
*
* @param {DOMElement|DOMTextNode} node
* @return {?DOMElement|DOMTextNode}
*/
function getSiblingNode(node) {
while (node) {
if (node.nextSibling) {
return node.nextSibling;
}
node = node.parentNode;
}
}
/**
* Get object describing the nodes which contain characters at offset.
*
* @param {DOMElement|DOMTextNode} root
* @param {number} offset
* @return {?object}
*/
function getNodeForCharacterOffset(root, offset) {
var node = getLeafNode(root);
var nodeStart = 0;
var nodeEnd = 0;
while (node) {
if (node.nodeType === 3) {
nodeEnd = nodeStart + node.textContent.length;
if (nodeStart <= offset && nodeEnd >= offset) {
return {
node: node,
offset: offset - nodeStart
};
}
nodeStart = nodeEnd;
}
node = getLeafNode(getSiblingNode(node));
}
}
module.exports = getNodeForCharacterOffset;
/***/ }),
/* 165 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var isTextNode = __webpack_require__(166);
/*eslint-disable no-bitwise */
/**
* Checks if a given DOM node contains or is another DOM node.
*/
function containsNode(outerNode, innerNode) {
if (!outerNode || !innerNode) {
return false;
} else if (outerNode === innerNode) {
return true;
} else if (isTextNode(outerNode)) {
return false;
} else if (isTextNode(innerNode)) {
return containsNode(outerNode, innerNode.parentNode);
} else if ('contains' in outerNode) {
return outerNode.contains(innerNode);
} else if (outerNode.compareDocumentPosition) {
return !!(outerNode.compareDocumentPosition(innerNode) & 16);
} else {
return false;
}
}
module.exports = containsNode;
/***/ }),
/* 166 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*/
var isNode = __webpack_require__(167);
/**
* @param {*} object The object to check.
* @return {boolean} Whether or not the object is a DOM text node.
*/
function isTextNode(object) {
return isNode(object) && object.nodeType == 3;
}
module.exports = isTextNode;
/***/ }),
/* 167 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*/
/**
* @param {*} object The object to check.
* @return {boolean} Whether or not the object is a DOM node.
*/
function isNode(object) {
var doc = object ? object.ownerDocument || object : document;
var defaultView = doc.defaultView || window;
return !!(object && (typeof defaultView.Node === 'function' ? object instanceof defaultView.Node : typeof object === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string'));
}
module.exports = isNode;
/***/ }),
/* 168 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var NS = {
xlink: 'http://www.w3.org/1999/xlink',
xml: 'http://www.w3.org/XML/1998/namespace'
};
// We use attributes for everything SVG so let's avoid some duplication and run
// code instead.
// The following are all specified in the HTML config already so we exclude here.
// - class (as className)
// - color
// - height
// - id
// - lang
// - max
// - media
// - method
// - min
// - name
// - style
// - target
// - type
// - width
var ATTRS = {
accentHeight: 'accent-height',
accumulate: 0,
additive: 0,
alignmentBaseline: 'alignment-baseline',
allowReorder: 'allowReorder',
alphabetic: 0,
amplitude: 0,
arabicForm: 'arabic-form',
ascent: 0,
attributeName: 'attributeName',
attributeType: 'attributeType',
autoReverse: 'autoReverse',
azimuth: 0,
baseFrequency: 'baseFrequency',
baseProfile: 'baseProfile',
baselineShift: 'baseline-shift',
bbox: 0,
begin: 0,
bias: 0,
by: 0,
calcMode: 'calcMode',
capHeight: 'cap-height',
clip: 0,
clipPath: 'clip-path',
clipRule: 'clip-rule',
clipPathUnits: 'clipPathUnits',
colorInterpolation: 'color-interpolation',
colorInterpolationFilters: 'color-interpolation-filters',
colorProfile: 'color-profile',
colorRendering: 'color-rendering',
contentScriptType: 'contentScriptType',
contentStyleType: 'contentStyleType',
cursor: 0,
cx: 0,
cy: 0,
d: 0,
decelerate: 0,
descent: 0,
diffuseConstant: 'diffuseConstant',
direction: 0,
display: 0,
divisor: 0,
dominantBaseline: 'dominant-baseline',
dur: 0,
dx: 0,
dy: 0,
edgeMode: 'edgeMode',
elevation: 0,
enableBackground: 'enable-background',
end: 0,
exponent: 0,
externalResourcesRequired: 'externalResourcesRequired',
fill: 0,
fillOpacity: 'fill-opacity',
fillRule: 'fill-rule',
filter: 0,
filterRes: 'filterRes',
filterUnits: 'filterUnits',
floodColor: 'flood-color',
floodOpacity: 'flood-opacity',
focusable: 0,
fontFamily: 'font-family',
fontSize: 'font-size',
fontSizeAdjust: 'font-size-adjust',
fontStretch: 'font-stretch',
fontStyle: 'font-style',
fontVariant: 'font-variant',
fontWeight: 'font-weight',
format: 0,
from: 0,
fx: 0,
fy: 0,
g1: 0,
g2: 0,
glyphName: 'glyph-name',
glyphOrientationHorizontal: 'glyph-orientation-horizontal',
glyphOrientationVertical: 'glyph-orientation-vertical',
glyphRef: 'glyphRef',
gradientTransform: 'gradientTransform',
gradientUnits: 'gradientUnits',
hanging: 0,
horizAdvX: 'horiz-adv-x',
horizOriginX: 'horiz-origin-x',
ideographic: 0,
imageRendering: 'image-rendering',
'in': 0,
in2: 0,
intercept: 0,
k: 0,
k1: 0,
k2: 0,
k3: 0,
k4: 0,
kernelMatrix: 'kernelMatrix',
kernelUnitLength: 'kernelUnitLength',
kerning: 0,
keyPoints: 'keyPoints',
keySplines: 'keySplines',
keyTimes: 'keyTimes',
lengthAdjust: 'lengthAdjust',
letterSpacing: 'letter-spacing',
lightingColor: 'lighting-color',
limitingConeAngle: 'limitingConeAngle',
local: 0,
markerEnd: 'marker-end',
markerMid: 'marker-mid',
markerStart: 'marker-start',
markerHeight: 'markerHeight',
markerUnits: 'markerUnits',
markerWidth: 'markerWidth',
mask: 0,
maskContentUnits: 'maskContentUnits',
maskUnits: 'maskUnits',
mathematical: 0,
mode: 0,
numOctaves: 'numOctaves',
offset: 0,
opacity: 0,
operator: 0,
order: 0,
orient: 0,
orientation: 0,
origin: 0,
overflow: 0,
overlinePosition: 'overline-position',
overlineThickness: 'overline-thickness',
paintOrder: 'paint-order',
panose1: 'panose-1',
pathLength: 'pathLength',
patternContentUnits: 'patternContentUnits',
patternTransform: 'patternTransform',
patternUnits: 'patternUnits',
pointerEvents: 'pointer-events',
points: 0,
pointsAtX: 'pointsAtX',
pointsAtY: 'pointsAtY',
pointsAtZ: 'pointsAtZ',
preserveAlpha: 'preserveAlpha',
preserveAspectRatio: 'preserveAspectRatio',
primitiveUnits: 'primitiveUnits',
r: 0,
radius: 0,
refX: 'refX',
refY: 'refY',
renderingIntent: 'rendering-intent',
repeatCount: 'repeatCount',
repeatDur: 'repeatDur',
requiredExtensions: 'requiredExtensions',
requiredFeatures: 'requiredFeatures',
restart: 0,
result: 0,
rotate: 0,
rx: 0,
ry: 0,
scale: 0,
seed: 0,
shapeRendering: 'shape-rendering',
slope: 0,
spacing: 0,
specularConstant: 'specularConstant',
specularExponent: 'specularExponent',
speed: 0,
spreadMethod: 'spreadMethod',
startOffset: 'startOffset',
stdDeviation: 'stdDeviation',
stemh: 0,
stemv: 0,
stitchTiles: 'stitchTiles',
stopColor: 'stop-color',
stopOpacity: 'stop-opacity',
strikethroughPosition: 'strikethrough-position',
strikethroughThickness: 'strikethrough-thickness',
string: 0,
stroke: 0,
strokeDasharray: 'stroke-dasharray',
strokeDashoffset: 'stroke-dashoffset',
strokeLinecap: 'stroke-linecap',
strokeLinejoin: 'stroke-linejoin',
strokeMiterlimit: 'stroke-miterlimit',
strokeOpacity: 'stroke-opacity',
strokeWidth: 'stroke-width',
surfaceScale: 'surfaceScale',
systemLanguage: 'systemLanguage',
tableValues: 'tableValues',
targetX: 'targetX',
targetY: 'targetY',
textAnchor: 'text-anchor',
textDecoration: 'text-decoration',
textRendering: 'text-rendering',
textLength: 'textLength',
to: 0,
transform: 0,
u1: 0,
u2: 0,
underlinePosition: 'underline-position',
underlineThickness: 'underline-thickness',
unicode: 0,
unicodeBidi: 'unicode-bidi',
unicodeRange: 'unicode-range',
unitsPerEm: 'units-per-em',
vAlphabetic: 'v-alphabetic',
vHanging: 'v-hanging',
vIdeographic: 'v-ideographic',
vMathematical: 'v-mathematical',
values: 0,
vectorEffect: 'vector-effect',
version: 0,
vertAdvY: 'vert-adv-y',
vertOriginX: 'vert-origin-x',
vertOriginY: 'vert-origin-y',
viewBox: 'viewBox',
viewTarget: 'viewTarget',
visibility: 0,
widths: 0,
wordSpacing: 'word-spacing',
writingMode: 'writing-mode',
x: 0,
xHeight: 'x-height',
x1: 0,
x2: 0,
xChannelSelector: 'xChannelSelector',
xlinkActuate: 'xlink:actuate',
xlinkArcrole: 'xlink:arcrole',
xlinkHref: 'xlink:href',
xlinkRole: 'xlink:role',
xlinkShow: 'xlink:show',
xlinkTitle: 'xlink:title',
xlinkType: 'xlink:type',
xmlBase: 'xml:base',
xmlns: 0,
xmlnsXlink: 'xmlns:xlink',
xmlLang: 'xml:lang',
xmlSpace: 'xml:space',
y: 0,
y1: 0,
y2: 0,
yChannelSelector: 'yChannelSelector',
z: 0,
zoomAndPan: 'zoomAndPan'
};
var SVGDOMPropertyConfig = {
Properties: {},
DOMAttributeNamespaces: {
xlinkActuate: NS.xlink,
xlinkArcrole: NS.xlink,
xlinkHref: NS.xlink,
xlinkRole: NS.xlink,
xlinkShow: NS.xlink,
xlinkTitle: NS.xlink,
xlinkType: NS.xlink,
xmlBase: NS.xml,
xmlLang: NS.xml,
xmlSpace: NS.xml
},
DOMAttributeNames: {}
};
Object.keys(ATTRS).forEach(function (key) {
SVGDOMPropertyConfig.Properties[key] = 0;
if (ATTRS[key]) {
SVGDOMPropertyConfig.DOMAttributeNames[key] = ATTRS[key];
}
});
module.exports = SVGDOMPropertyConfig;
/***/ }),
/* 169 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var EventPropagators = __webpack_require__(20);
var ExecutionEnvironment = __webpack_require__(5);
var ReactDOMComponentTree = __webpack_require__(4);
var ReactInputSelection = __webpack_require__(80);
var SyntheticEvent = __webpack_require__(12);
var getActiveElement = __webpack_require__(81);
var isTextInputElement = __webpack_require__(66);
var shallowEqual = __webpack_require__(46);
var skipSelectionChangeEvent = ExecutionEnvironment.canUseDOM && 'documentMode' in document && document.documentMode <= 11;
var eventTypes = {
select: {
phasedRegistrationNames: {
bubbled: 'onSelect',
captured: 'onSelectCapture'
},
dependencies: ['topBlur', 'topContextMenu', 'topFocus', 'topKeyDown', 'topKeyUp', 'topMouseDown', 'topMouseUp', 'topSelectionChange']
}
};
var activeElement = null;
var activeElementInst = null;
var lastSelection = null;
var mouseDown = false;
// Track whether a listener exists for this plugin. If none exist, we do
// not extract events. See #3639.
var hasListener = false;
/**
* Get an object which is a unique representation of the current selection.
*
* The return value will not be consistent across nodes or browsers, but
* two identical selections on the same node will return identical objects.
*
* @param {DOMElement} node
* @return {object}
*/
function getSelection(node) {
if ('selectionStart' in node && ReactInputSelection.hasSelectionCapabilities(node)) {
return {
start: node.selectionStart,
end: node.selectionEnd
};
} else if (window.getSelection) {
var selection = window.getSelection();
return {
anchorNode: selection.anchorNode,
anchorOffset: selection.anchorOffset,
focusNode: selection.focusNode,
focusOffset: selection.focusOffset
};
} else if (document.selection) {
var range = document.selection.createRange();
return {
parentElement: range.parentElement(),
text: range.text,
top: range.boundingTop,
left: range.boundingLeft
};
}
}
/**
* Poll selection to see whether it's changed.
*
* @param {object} nativeEvent
* @return {?SyntheticEvent}
*/
function constructSelectEvent(nativeEvent, nativeEventTarget) {
// Ensure we have the right element, and that the user is not dragging a
// selection (this matches native `select` event behavior). In HTML5, select
// fires only on input and textarea thus if there's no focused element we
// won't dispatch.
if (mouseDown || activeElement == null || activeElement !== getActiveElement()) {
return null;
}
// Only fire when selection has actually changed.
var currentSelection = getSelection(activeElement);
if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {
lastSelection = currentSelection;
var syntheticEvent = SyntheticEvent.getPooled(eventTypes.select, activeElementInst, nativeEvent, nativeEventTarget);
syntheticEvent.type = 'select';
syntheticEvent.target = activeElement;
EventPropagators.accumulateTwoPhaseDispatches(syntheticEvent);
return syntheticEvent;
}
return null;
}
/**
* This plugin creates an `onSelect` event that normalizes select events
* across form elements.
*
* Supported elements are:
* - input (see `isTextInputElement`)
* - textarea
* - contentEditable
*
* This differs from native browser implementations in the following ways:
* - Fires on contentEditable fields as well as inputs.
* - Fires for collapsed selection.
* - Fires after user input.
*/
var SelectEventPlugin = {
eventTypes: eventTypes,
extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
if (!hasListener) {
return null;
}
var targetNode = targetInst ? ReactDOMComponentTree.getNodeFromInstance(targetInst) : window;
switch (topLevelType) {
// Track the input node that has focus.
case 'topFocus':
if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') {
activeElement = targetNode;
activeElementInst = targetInst;
lastSelection = null;
}
break;
case 'topBlur':
activeElement = null;
activeElementInst = null;
lastSelection = null;
break;
// Don't fire the event while the user is dragging. This matches the
// semantics of the native select event.
case 'topMouseDown':
mouseDown = true;
break;
case 'topContextMenu':
case 'topMouseUp':
mouseDown = false;
return constructSelectEvent(nativeEvent, nativeEventTarget);
// Chrome and IE fire non-standard event when selection is changed (and
// sometimes when it hasn't). IE's event fires out of order with respect
// to key and input events on deletion, so we discard it.
//
// Firefox doesn't support selectionchange, so check selection status
// after each key entry. The selection changes after keydown and before
// keyup, but we check on keydown as well in the case of holding down a
// key, when multiple keydown events are fired but only one keyup is.
// This is also our approach for IE handling, for the reason above.
case 'topSelectionChange':
if (skipSelectionChangeEvent) {
break;
}
// falls through
case 'topKeyDown':
case 'topKeyUp':
return constructSelectEvent(nativeEvent, nativeEventTarget);
}
return null;
},
didPutListener: function (inst, registrationName, listener) {
if (registrationName === 'onSelect') {
hasListener = true;
}
}
};
module.exports = SelectEventPlugin;
/***/ }),
/* 170 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var _prodInvariant = __webpack_require__(2);
var EventListener = __webpack_require__(79);
var EventPropagators = __webpack_require__(20);
var ReactDOMComponentTree = __webpack_require__(4);
var SyntheticAnimationEvent = __webpack_require__(171);
var SyntheticClipboardEvent = __webpack_require__(172);
var SyntheticEvent = __webpack_require__(12);
var SyntheticFocusEvent = __webpack_require__(173);
var SyntheticKeyboardEvent = __webpack_require__(174);
var SyntheticMouseEvent = __webpack_require__(30);
var SyntheticDragEvent = __webpack_require__(176);
var SyntheticTouchEvent = __webpack_require__(177);
var SyntheticTransitionEvent = __webpack_require__(178);
var SyntheticUIEvent = __webpack_require__(22);
var SyntheticWheelEvent = __webpack_require__(179);
var emptyFunction = __webpack_require__(8);
var getEventCharCode = __webpack_require__(51);
var invariant = __webpack_require__(0);
/**
* Turns
* ['abort', ...]
* into
* eventTypes = {
* 'abort': {
* phasedRegistrationNames: {
* bubbled: 'onAbort',
* captured: 'onAbortCapture',
* },
* dependencies: ['topAbort'],
* },
* ...
* };
* topLevelEventsToDispatchConfig = {
* 'topAbort': { sameConfig }
* };
*/
var eventTypes = {};
var topLevelEventsToDispatchConfig = {};
['abort', 'animationEnd', 'animationIteration', 'animationStart', 'blur', 'canPlay', 'canPlayThrough', 'click', 'contextMenu', 'copy', 'cut', 'doubleClick', 'drag', 'dragEnd', 'dragEnter', 'dragExit', 'dragLeave', 'dragOver', 'dragStart', 'drop', 'durationChange', 'emptied', 'encrypted', 'ended', 'error', 'focus', 'input', 'invalid', 'keyDown', 'keyPress', 'keyUp', 'load', 'loadedData', 'loadedMetadata', 'loadStart', 'mouseDown', 'mouseMove', 'mouseOut', 'mouseOver', 'mouseUp', 'paste', 'pause', 'play', 'playing', 'progress', 'rateChange', 'reset', 'scroll', 'seeked', 'seeking', 'stalled', 'submit', 'suspend', 'timeUpdate', 'touchCancel', 'touchEnd', 'touchMove', 'touchStart', 'transitionEnd', 'volumeChange', 'waiting', 'wheel'].forEach(function (event) {
var capitalizedEvent = event[0].toUpperCase() + event.slice(1);
var onEvent = 'on' + capitalizedEvent;
var topEvent = 'top' + capitalizedEvent;
var type = {
phasedRegistrationNames: {
bubbled: onEvent,
captured: onEvent + 'Capture'
},
dependencies: [topEvent]
};
eventTypes[event] = type;
topLevelEventsToDispatchConfig[topEvent] = type;
});
var onClickListeners = {};
function getDictionaryKey(inst) {
// Prevents V8 performance issue:
// https://github.com/facebook/react/pull/7232
return '.' + inst._rootNodeID;
}
function isInteractive(tag) {
return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';
}
var SimpleEventPlugin = {
eventTypes: eventTypes,
extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType];
if (!dispatchConfig) {
return null;
}
var EventConstructor;
switch (topLevelType) {
case 'topAbort':
case 'topCanPlay':
case 'topCanPlayThrough':
case 'topDurationChange':
case 'topEmptied':
case 'topEncrypted':
case 'topEnded':
case 'topError':
case 'topInput':
case 'topInvalid':
case 'topLoad':
case 'topLoadedData':
case 'topLoadedMetadata':
case 'topLoadStart':
case 'topPause':
case 'topPlay':
case 'topPlaying':
case 'topProgress':
case 'topRateChange':
case 'topReset':
case 'topSeeked':
case 'topSeeking':
case 'topStalled':
case 'topSubmit':
case 'topSuspend':
case 'topTimeUpdate':
case 'topVolumeChange':
case 'topWaiting':
// HTML Events
// @see http://www.w3.org/TR/html5/index.html#events-0
EventConstructor = SyntheticEvent;
break;
case 'topKeyPress':
// Firefox creates a keypress event for function keys too. This removes
// the unwanted keypress events. Enter is however both printable and
// non-printable. One would expect Tab to be as well (but it isn't).
if (getEventCharCode(nativeEvent) === 0) {
return null;
}
/* falls through */
case 'topKeyDown':
case 'topKeyUp':
EventConstructor = SyntheticKeyboardEvent;
break;
case 'topBlur':
case 'topFocus':
EventConstructor = SyntheticFocusEvent;
break;
case 'topClick':
// Firefox creates a click event on right mouse clicks. This removes the
// unwanted click events.
if (nativeEvent.button === 2) {
return null;
}
/* falls through */
case 'topDoubleClick':
case 'topMouseDown':
case 'topMouseMove':
case 'topMouseUp':
// TODO: Disabled elements should not respond to mouse events
/* falls through */
case 'topMouseOut':
case 'topMouseOver':
case 'topContextMenu':
EventConstructor = SyntheticMouseEvent;
break;
case 'topDrag':
case 'topDragEnd':
case 'topDragEnter':
case 'topDragExit':
case 'topDragLeave':
case 'topDragOver':
case 'topDragStart':
case 'topDrop':
EventConstructor = SyntheticDragEvent;
break;
case 'topTouchCancel':
case 'topTouchEnd':
case 'topTouchMove':
case 'topTouchStart':
EventConstructor = SyntheticTouchEvent;
break;
case 'topAnimationEnd':
case 'topAnimationIteration':
case 'topAnimationStart':
EventConstructor = SyntheticAnimationEvent;
break;
case 'topTransitionEnd':
EventConstructor = SyntheticTransitionEvent;
break;
case 'topScroll':
EventConstructor = SyntheticUIEvent;
break;
case 'topWheel':
EventConstructor = SyntheticWheelEvent;
break;
case 'topCopy':
case 'topCut':
case 'topPaste':
EventConstructor = SyntheticClipboardEvent;
break;
}
!EventConstructor ? true ? invariant(false, 'SimpleEventPlugin: Unhandled event type, `%s`.', topLevelType) : _prodInvariant('86', topLevelType) : void 0;
var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget);
EventPropagators.accumulateTwoPhaseDispatches(event);
return event;
},
didPutListener: function (inst, registrationName, listener) {
// Mobile Safari does not fire properly bubble click events on
// non-interactive elements, which means delegated click listeners do not
// fire. The workaround for this bug involves attaching an empty click
// listener on the target node.
// http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
if (registrationName === 'onClick' && !isInteractive(inst._tag)) {
var key = getDictionaryKey(inst);
var node = ReactDOMComponentTree.getNodeFromInstance(inst);
if (!onClickListeners[key]) {
onClickListeners[key] = EventListener.listen(node, 'click', emptyFunction);
}
}
},
willDeleteListener: function (inst, registrationName) {
if (registrationName === 'onClick' && !isInteractive(inst._tag)) {
var key = getDictionaryKey(inst);
onClickListeners[key].remove();
delete onClickListeners[key];
}
}
};
module.exports = SimpleEventPlugin;
/***/ }),
/* 171 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var SyntheticEvent = __webpack_require__(12);
/**
* @interface Event
* @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface
* @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent
*/
var AnimationEventInterface = {
animationName: null,
elapsedTime: null,
pseudoElement: null
};
/**
* @param {object} dispatchConfig Configuration used to dispatch this event.
* @param {string} dispatchMarker Marker identifying the event target.
* @param {object} nativeEvent Native browser event.
* @extends {SyntheticEvent}
*/
function SyntheticAnimationEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {
return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);
}
SyntheticEvent.augmentClass(SyntheticAnimationEvent, AnimationEventInterface);
module.exports = SyntheticAnimationEvent;
/***/ }),
/* 172 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var SyntheticEvent = __webpack_require__(12);
/**
* @interface Event
* @see http://www.w3.org/TR/clipboard-apis/
*/
var ClipboardEventInterface = {
clipboardData: function (event) {
return 'clipboardData' in event ? event.clipboardData : window.clipboardData;
}
};
/**
* @param {object} dispatchConfig Configuration used to dispatch this event.
* @param {string} dispatchMarker Marker identifying the event target.
* @param {object} nativeEvent Native browser event.
* @extends {SyntheticUIEvent}
*/
function SyntheticClipboardEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {
return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);
}
SyntheticEvent.augmentClass(SyntheticClipboardEvent, ClipboardEventInterface);
module.exports = SyntheticClipboardEvent;
/***/ }),
/* 173 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var SyntheticUIEvent = __webpack_require__(22);
/**
* @interface FocusEvent
* @see http://www.w3.org/TR/DOM-Level-3-Events/
*/
var FocusEventInterface = {
relatedTarget: null
};
/**
* @param {object} dispatchConfig Configuration used to dispatch this event.
* @param {string} dispatchMarker Marker identifying the event target.
* @param {object} nativeEvent Native browser event.
* @extends {SyntheticUIEvent}
*/
function SyntheticFocusEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {
return SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);
}
SyntheticUIEvent.augmentClass(SyntheticFocusEvent, FocusEventInterface);
module.exports = SyntheticFocusEvent;
/***/ }),
/* 174 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var SyntheticUIEvent = __webpack_require__(22);
var getEventCharCode = __webpack_require__(51);
var getEventKey = __webpack_require__(175);
var getEventModifierState = __webpack_require__(40);
/**
* @interface KeyboardEvent
* @see http://www.w3.org/TR/DOM-Level-3-Events/
*/
var KeyboardEventInterface = {
key: getEventKey,
location: null,
ctrlKey: null,
shiftKey: null,
altKey: null,
metaKey: null,
repeat: null,
locale: null,
getModifierState: getEventModifierState,
// Legacy Interface
charCode: function (event) {
// `charCode` is the result of a KeyPress event and represents the value of
// the actual printable character.
// KeyPress is deprecated, but its replacement is not yet final and not
// implemented in any major browser. Only KeyPress has charCode.
if (event.type === 'keypress') {
return getEventCharCode(event);
}
return 0;
},
keyCode: function (event) {
// `keyCode` is the result of a KeyDown/Up event and represents the value of
// physical keyboard key.
// The actual meaning of the value depends on the users' keyboard layout
// which cannot be detected. Assuming that it is a US keyboard layout
// provides a surprisingly accurate mapping for US and European users.
// Due to this, it is left to the user to implement at this time.
if (event.type === 'keydown' || event.type === 'keyup') {
return event.keyCode;
}
return 0;
},
which: function (event) {
// `which` is an alias for either `keyCode` or `charCode` depending on the
// type of the event.
if (event.type === 'keypress') {
return getEventCharCode(event);
}
if (event.type === 'keydown' || event.type === 'keyup') {
return event.keyCode;
}
return 0;
}
};
/**
* @param {object} dispatchConfig Configuration used to dispatch this event.
* @param {string} dispatchMarker Marker identifying the event target.
* @param {object} nativeEvent Native browser event.
* @extends {SyntheticUIEvent}
*/
function SyntheticKeyboardEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {
return SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);
}
SyntheticUIEvent.augmentClass(SyntheticKeyboardEvent, KeyboardEventInterface);
module.exports = SyntheticKeyboardEvent;
/***/ }),
/* 175 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var getEventCharCode = __webpack_require__(51);
/**
* Normalization of deprecated HTML5 `key` values
* @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
*/
var normalizeKey = {
Esc: 'Escape',
Spacebar: ' ',
Left: 'ArrowLeft',
Up: 'ArrowUp',
Right: 'ArrowRight',
Down: 'ArrowDown',
Del: 'Delete',
Win: 'OS',
Menu: 'ContextMenu',
Apps: 'ContextMenu',
Scroll: 'ScrollLock',
MozPrintableKey: 'Unidentified'
};
/**
* Translation from legacy `keyCode` to HTML5 `key`
* Only special keys supported, all others depend on keyboard layout or browser
* @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
*/
var translateToKey = {
8: 'Backspace',
9: 'Tab',
12: 'Clear',
13: 'Enter',
16: 'Shift',
17: 'Control',
18: 'Alt',
19: 'Pause',
20: 'CapsLock',
27: 'Escape',
32: ' ',
33: 'PageUp',
34: 'PageDown',
35: 'End',
36: 'Home',
37: 'ArrowLeft',
38: 'ArrowUp',
39: 'ArrowRight',
40: 'ArrowDown',
45: 'Insert',
46: 'Delete',
112: 'F1',
113: 'F2',
114: 'F3',
115: 'F4',
116: 'F5',
117: 'F6',
118: 'F7',
119: 'F8',
120: 'F9',
121: 'F10',
122: 'F11',
123: 'F12',
144: 'NumLock',
145: 'ScrollLock',
224: 'Meta'
};
/**
* @param {object} nativeEvent Native browser event.
* @return {string} Normalized `key` property.
*/
function getEventKey(nativeEvent) {
if (nativeEvent.key) {
// Normalize inconsistent values reported by browsers due to
// implementations of a working draft specification.
// FireFox implements `key` but returns `MozPrintableKey` for all
// printable characters (normalized to `Unidentified`), ignore it.
var key = normalizeKey[nativeEvent.key] || nativeEvent.key;
if (key !== 'Unidentified') {
return key;
}
}
// Browser does not implement `key`, polyfill as much of it as we can.
if (nativeEvent.type === 'keypress') {
var charCode = getEventCharCode(nativeEvent);
// The enter-key is technically both printable and non-printable and can
// thus be captured by `keypress`, no other non-printable key should.
return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);
}
if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {
// While user keyboard layout determines the actual meaning of each
// `keyCode` value, almost all function keys have a universal value.
return translateToKey[nativeEvent.keyCode] || 'Unidentified';
}
return '';
}
module.exports = getEventKey;
/***/ }),
/* 176 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var SyntheticMouseEvent = __webpack_require__(30);
/**
* @interface DragEvent
* @see http://www.w3.org/TR/DOM-Level-3-Events/
*/
var DragEventInterface = {
dataTransfer: null
};
/**
* @param {object} dispatchConfig Configuration used to dispatch this event.
* @param {string} dispatchMarker Marker identifying the event target.
* @param {object} nativeEvent Native browser event.
* @extends {SyntheticUIEvent}
*/
function SyntheticDragEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {
return SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);
}
SyntheticMouseEvent.augmentClass(SyntheticDragEvent, DragEventInterface);
module.exports = SyntheticDragEvent;
/***/ }),
/* 177 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var SyntheticUIEvent = __webpack_require__(22);
var getEventModifierState = __webpack_require__(40);
/**
* @interface TouchEvent
* @see http://www.w3.org/TR/touch-events/
*/
var TouchEventInterface = {
touches: null,
targetTouches: null,
changedTouches: null,
altKey: null,
metaKey: null,
ctrlKey: null,
shiftKey: null,
getModifierState: getEventModifierState
};
/**
* @param {object} dispatchConfig Configuration used to dispatch this event.
* @param {string} dispatchMarker Marker identifying the event target.
* @param {object} nativeEvent Native browser event.
* @extends {SyntheticUIEvent}
*/
function SyntheticTouchEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {
return SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);
}
SyntheticUIEvent.augmentClass(SyntheticTouchEvent, TouchEventInterface);
module.exports = SyntheticTouchEvent;
/***/ }),
/* 178 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var SyntheticEvent = __webpack_require__(12);
/**
* @interface Event
* @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events-
* @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent
*/
var TransitionEventInterface = {
propertyName: null,
elapsedTime: null,
pseudoElement: null
};
/**
* @param {object} dispatchConfig Configuration used to dispatch this event.
* @param {string} dispatchMarker Marker identifying the event target.
* @param {object} nativeEvent Native browser event.
* @extends {SyntheticEvent}
*/
function SyntheticTransitionEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {
return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);
}
SyntheticEvent.augmentClass(SyntheticTransitionEvent, TransitionEventInterface);
module.exports = SyntheticTransitionEvent;
/***/ }),
/* 179 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var SyntheticMouseEvent = __webpack_require__(30);
/**
* @interface WheelEvent
* @see http://www.w3.org/TR/DOM-Level-3-Events/
*/
var WheelEventInterface = {
deltaX: function (event) {
return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
'wheelDeltaX' in event ? -event.wheelDeltaX : 0;
},
deltaY: function (event) {
return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
'wheelDelta' in event ? -event.wheelDelta : 0;
},
deltaZ: null,
// Browsers without "deltaMode" is reporting in raw wheel delta where one
// notch on the scroll is always +/- 120, roughly equivalent to pixels.
// A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
// ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
deltaMode: null
};
/**
* @param {object} dispatchConfig Configuration used to dispatch this event.
* @param {string} dispatchMarker Marker identifying the event target.
* @param {object} nativeEvent Native browser event.
* @extends {SyntheticMouseEvent}
*/
function SyntheticWheelEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {
return SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);
}
SyntheticMouseEvent.augmentClass(SyntheticWheelEvent, WheelEventInterface);
module.exports = SyntheticWheelEvent;
/***/ }),
/* 180 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var validateDOMNesting = __webpack_require__(50);
var DOC_NODE_TYPE = 9;
function ReactDOMContainerInfo(topLevelWrapper, node) {
var info = {
_topLevelWrapper: topLevelWrapper,
_idCounter: 1,
_ownerDocument: node ? node.nodeType === DOC_NODE_TYPE ? node : node.ownerDocument : null,
_node: node,
_tag: node ? node.nodeName.toLowerCase() : null,
_namespaceURI: node ? node.namespaceURI : null
};
if (true) {
info._ancestorInfo = node ? validateDOMNesting.updatedAncestorInfo(null, info._tag, null) : null;
}
return info;
}
module.exports = ReactDOMContainerInfo;
/***/ }),
/* 181 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var ReactDOMFeatureFlags = {
useCreateElement: true,
useFiber: false
};
module.exports = ReactDOMFeatureFlags;
/***/ }),
/* 182 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var adler32 = __webpack_require__(183);
var TAG_END = /\/?>/;
var COMMENT_START = /^<\!\-\-/;
var ReactMarkupChecksum = {
CHECKSUM_ATTR_NAME: 'data-react-checksum',
/**
* @param {string} markup Markup string
* @return {string} Markup string with checksum attribute attached
*/
addChecksumToMarkup: function (markup) {
var checksum = adler32(markup);
// Add checksum (handle both parent tags, comments and self-closing tags)
if (COMMENT_START.test(markup)) {
return markup;
} else {
return markup.replace(TAG_END, ' ' + ReactMarkupChecksum.CHECKSUM_ATTR_NAME + '="' + checksum + '"$&');
}
},
/**
* @param {string} markup to use
* @param {DOMElement} element root React element
* @returns {boolean} whether or not the markup is the same
*/
canReuseMarkup: function (markup, element) {
var existingChecksum = element.getAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME);
existingChecksum = existingChecksum && parseInt(existingChecksum, 10);
var markupChecksum = adler32(markup);
return markupChecksum === existingChecksum;
}
};
module.exports = ReactMarkupChecksum;
/***/ }),
/* 183 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var MOD = 65521;
// adler32 is not cryptographically strong, and is only used to sanity check that
// markup generated on the server matches the markup generated on the client.
// This implementation (a modified version of the SheetJS version) has been optimized
// for our use case, at the expense of conforming to the adler32 specification
// for non-ascii inputs.
function adler32(data) {
var a = 1;
var b = 0;
var i = 0;
var l = data.length;
var m = l & ~0x3;
while (i < m) {
var n = Math.min(i + 4096, m);
for (; i < n; i += 4) {
b += (a += data.charCodeAt(i)) + (a += data.charCodeAt(i + 1)) + (a += data.charCodeAt(i + 2)) + (a += data.charCodeAt(i + 3));
}
a %= MOD;
b %= MOD;
}
for (; i < l; i++) {
b += a += data.charCodeAt(i);
}
a %= MOD;
b %= MOD;
return a | b << 16;
}
module.exports = adler32;
/***/ }),
/* 184 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
module.exports = '15.6.2';
/***/ }),
/* 185 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var _prodInvariant = __webpack_require__(2);
var ReactCurrentOwner = __webpack_require__(9);
var ReactDOMComponentTree = __webpack_require__(4);
var ReactInstanceMap = __webpack_require__(23);
var getHostComponentFromComposite = __webpack_require__(83);
var invariant = __webpack_require__(0);
var warning = __webpack_require__(1);
/**
* Returns the DOM node rendered by this element.
*
* See https://facebook.github.io/react/docs/top-level-api.html#reactdom.finddomnode
*
* @param {ReactComponent|DOMElement} componentOrElement
* @return {?DOMElement} The root node of this element.
*/
function findDOMNode(componentOrElement) {
if (true) {
var owner = ReactCurrentOwner.current;
if (owner !== null) {
true ? warning(owner._warnedAboutRefsInRender, '%s is accessing findDOMNode inside its render(). ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', owner.getName() || 'A component') : void 0;
owner._warnedAboutRefsInRender = true;
}
}
if (componentOrElement == null) {
return null;
}
if (componentOrElement.nodeType === 1) {
return componentOrElement;
}
var inst = ReactInstanceMap.get(componentOrElement);
if (inst) {
inst = getHostComponentFromComposite(inst);
return inst ? ReactDOMComponentTree.getNodeFromInstance(inst) : null;
}
if (typeof componentOrElement.render === 'function') {
true ? true ? invariant(false, 'findDOMNode was called on an unmounted component.') : _prodInvariant('44') : void 0;
} else {
true ? true ? invariant(false, 'Element appears to be neither ReactComponent nor DOMNode (keys: %s)', Object.keys(componentOrElement)) : _prodInvariant('45', Object.keys(componentOrElement)) : void 0;
}
}
module.exports = findDOMNode;
/***/ }),
/* 186 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var ReactMount = __webpack_require__(82);
module.exports = ReactMount.renderSubtreeIntoContainer;
/***/ }),
/* 187 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var DOMProperty = __webpack_require__(13);
var EventPluginRegistry = __webpack_require__(28);
var ReactComponentTreeHook = __webpack_require__(6);
var warning = __webpack_require__(1);
if (true) {
var reactProps = {
children: true,
dangerouslySetInnerHTML: true,
key: true,
ref: true,
autoFocus: true,
defaultValue: true,
valueLink: true,
defaultChecked: true,
checkedLink: true,
innerHTML: true,
suppressContentEditableWarning: true,
onFocusIn: true,
onFocusOut: true
};
var warnedProperties = {};
var validateProperty = function (tagName, name, debugID) {
if (DOMProperty.properties.hasOwnProperty(name) || DOMProperty.isCustomAttribute(name)) {
return true;
}
if (reactProps.hasOwnProperty(name) && reactProps[name] || warnedProperties.hasOwnProperty(name) && warnedProperties[name]) {
return true;
}
if (EventPluginRegistry.registrationNameModules.hasOwnProperty(name)) {
return true;
}
warnedProperties[name] = true;
var lowerCasedName = name.toLowerCase();
// data-* attributes should be lowercase; suggest the lowercase version
var standardName = DOMProperty.isCustomAttribute(lowerCasedName) ? lowerCasedName : DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? DOMProperty.getPossibleStandardName[lowerCasedName] : null;
var registrationName = EventPluginRegistry.possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? EventPluginRegistry.possibleRegistrationNames[lowerCasedName] : null;
if (standardName != null) {
true ? warning(false, 'Unknown DOM property %s. Did you mean %s?%s', name, standardName, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0;
return true;
} else if (registrationName != null) {
true ? warning(false, 'Unknown event handler property %s. Did you mean `%s`?%s', name, registrationName, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0;
return true;
} else {
// We were unable to guess which prop the user intended.
// It is likely that the user was just blindly spreading/forwarding props
// Components should be careful to only render valid props/attributes.
// Warning will be invoked in warnUnknownProperties to allow grouping.
return false;
}
};
}
var warnUnknownProperties = function (debugID, element) {
var unknownProps = [];
for (var key in element.props) {
var isValid = validateProperty(element.type, key, debugID);
if (!isValid) {
unknownProps.push(key);
}
}
var unknownPropString = unknownProps.map(function (prop) {
return '`' + prop + '`';
}).join(', ');
if (unknownProps.length === 1) {
true ? warning(false, 'Unknown prop %s on <%s> tag. Remove this prop from the element. ' + 'For details, see https://fb.me/react-unknown-prop%s', unknownPropString, element.type, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0;
} else if (unknownProps.length > 1) {
true ? warning(false, 'Unknown props %s on <%s> tag. Remove these props from the element. ' + 'For details, see https://fb.me/react-unknown-prop%s', unknownPropString, element.type, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0;
}
};
function handleElement(debugID, element) {
if (element == null || typeof element.type !== 'string') {
return;
}
if (element.type.indexOf('-') >= 0 || element.props.is) {
return;
}
warnUnknownProperties(debugID, element);
}
var ReactDOMUnknownPropertyHook = {
onBeforeMountComponent: function (debugID, element) {
handleElement(debugID, element);
},
onBeforeUpdateComponent: function (debugID, element) {
handleElement(debugID, element);
}
};
module.exports = ReactDOMUnknownPropertyHook;
/***/ }),
/* 188 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var ReactComponentTreeHook = __webpack_require__(6);
var warning = __webpack_require__(1);
var didWarnValueNull = false;
function handleElement(debugID, element) {
if (element == null) {
return;
}
if (element.type !== 'input' && element.type !== 'textarea' && element.type !== 'select') {
return;
}
if (element.props != null && element.props.value === null && !didWarnValueNull) {
true ? warning(false, '`value` prop on `%s` should not be null. ' + 'Consider using the empty string to clear the component or `undefined` ' + 'for uncontrolled components.%s', element.type, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0;
didWarnValueNull = true;
}
}
var ReactDOMNullInputValuePropHook = {
onBeforeMountComponent: function (debugID, element) {
handleElement(debugID, element);
},
onBeforeUpdateComponent: function (debugID, element) {
handleElement(debugID, element);
}
};
module.exports = ReactDOMNullInputValuePropHook;
/***/ }),
/* 189 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var DOMProperty = __webpack_require__(13);
var ReactComponentTreeHook = __webpack_require__(6);
var warning = __webpack_require__(1);
var warnedProperties = {};
var rARIA = new RegExp('^(aria)-[' + DOMProperty.ATTRIBUTE_NAME_CHAR + ']*$');
function validateProperty(tagName, name, debugID) {
if (warnedProperties.hasOwnProperty(name) && warnedProperties[name]) {
return true;
}
if (rARIA.test(name)) {
var lowerCasedName = name.toLowerCase();
var standardName = DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? DOMProperty.getPossibleStandardName[lowerCasedName] : null;
// If this is an aria-* attribute, but is not listed in the known DOM
// DOM properties, then it is an invalid aria-* attribute.
if (standardName == null) {
warnedProperties[name] = true;
return false;
}
// aria-* attributes should be lowercase; suggest the lowercase version.
if (name !== standardName) {
true ? warning(false, 'Unknown ARIA attribute %s. Did you mean %s?%s', name, standardName, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0;
warnedProperties[name] = true;
return true;
}
}
return true;
}
function warnInvalidARIAProps(debugID, element) {
var invalidProps = [];
for (var key in element.props) {
var isValid = validateProperty(element.type, key, debugID);
if (!isValid) {
invalidProps.push(key);
}
}
var unknownPropString = invalidProps.map(function (prop) {
return '`' + prop + '`';
}).join(', ');
if (invalidProps.length === 1) {
true ? warning(false, 'Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop%s', unknownPropString, element.type, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0;
} else if (invalidProps.length > 1) {
true ? warning(false, 'Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop%s', unknownPropString, element.type, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0;
}
}
function handleElement(debugID, element) {
if (element == null || typeof element.type !== 'string') {
return;
}
if (element.type.indexOf('-') >= 0 || element.props.is) {
return;
}
warnInvalidARIAProps(debugID, element);
}
var ReactDOMInvalidARIAHook = {
onBeforeMountComponent: function (debugID, element) {
if (true) {
handleElement(debugID, element);
}
},
onBeforeUpdateComponent: function (debugID, element) {
if (true) {
handleElement(debugID, element);
}
}
};
module.exports = ReactDOMInvalidARIAHook;
/***/ }),
/* 190 */
/***/ (function(module, exports) {
var g;
// This works in non-strict mode
g = (function() {
return this;
})();
try {
// This works if eval is allowed (see CSP)
g = g || Function("return this")() || (1,eval)("this");
} catch(e) {
// This works if the window reference is available
if(typeof window === "object")
g = window;
}
// g can still be undefined, but nothing to do about it...
// We return undefined, instead of nothing here, so it's
// easier to handle this case. if(!global) { ...}
module.exports = g;
/***/ }),
/* 191 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* WEBPACK VAR INJECTION */(function(process) {
var utils = __webpack_require__(34);
var normalizeHeaderName = __webpack_require__(267);
var DEFAULT_CONTENT_TYPE = {
'Content-Type': 'application/x-www-form-urlencoded'
};
function setContentTypeIfUnset(headers, value) {
if (!utils.isUndefined(headers) && utils.isUndefined(headers['Content-Type'])) {
headers['Content-Type'] = value;
}
}
function getDefaultAdapter() {
var adapter;
if (typeof XMLHttpRequest !== 'undefined') {
// For browsers use XHR adapter
adapter = __webpack_require__(204);
} else if (typeof process !== 'undefined') {
// For node use HTTP adapter
adapter = __webpack_require__(204);
}
return adapter;
}
var defaults = {
adapter: getDefaultAdapter(),
transformRequest: [function transformRequest(data, headers) {
normalizeHeaderName(headers, 'Content-Type');
if (utils.isFormData(data) ||
utils.isArrayBuffer(data) ||
utils.isBuffer(data) ||
utils.isStream(data) ||
utils.isFile(data) ||
utils.isBlob(data)
) {
return data;
}
if (utils.isArrayBufferView(data)) {
return data.buffer;
}
if (utils.isURLSearchParams(data)) {
setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8');
return data.toString();
}
if (utils.isObject(data)) {
setContentTypeIfUnset(headers, 'application/json;charset=utf-8');
return JSON.stringify(data);
}
return data;
}],
transformResponse: [function transformResponse(data) {
/*eslint no-param-reassign:0*/
if (typeof data === 'string') {
try {
data = JSON.parse(data);
} catch (e) { /* Ignore */ }
}
return data;
}],
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: function validateStatus(status) {
return status >= 200 && status < 300;
}
};
defaults.headers = {
common: {
'Accept': 'application/json, text/plain, */*'
}
};
utils.forEach(['delete', 'get', 'head'], function forEachMethodNoData(method) {
defaults.headers[method] = {};
});
utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE);
});
module.exports = defaults;
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(24)))
/***/ }),
/* 192 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebGLRenderTargetCube", function() { return WebGLRenderTargetCube; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebGLRenderTarget", function() { return WebGLRenderTarget; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebGLRenderer", function() { return WebGLRenderer; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShaderLib", function() { return ShaderLib; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "UniformsLib", function() { return UniformsLib; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "UniformsUtils", function() { return UniformsUtils; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShaderChunk", function() { return ShaderChunk; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FogExp2", function() { return FogExp2; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Fog", function() { return Fog; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Scene", function() { return Scene; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LensFlare", function() { return LensFlare; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Sprite", function() { return Sprite; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LOD", function() { return LOD; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SkinnedMesh", function() { return SkinnedMesh; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Skeleton", function() { return Skeleton; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Bone", function() { return Bone; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Mesh", function() { return Mesh; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LineSegments", function() { return LineSegments; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LineLoop", function() { return LineLoop; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Line", function() { return Line; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Points", function() { return Points; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Group", function() { return Group; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VideoTexture", function() { return VideoTexture; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DataTexture", function() { return DataTexture; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CompressedTexture", function() { return CompressedTexture; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CubeTexture", function() { return CubeTexture; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CanvasTexture", function() { return CanvasTexture; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DepthTexture", function() { return DepthTexture; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Texture", function() { return Texture; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CompressedTextureLoader", function() { return CompressedTextureLoader; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DataTextureLoader", function() { return DataTextureLoader; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CubeTextureLoader", function() { return CubeTextureLoader; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextureLoader", function() { return TextureLoader; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ObjectLoader", function() { return ObjectLoader; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MaterialLoader", function() { return MaterialLoader; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BufferGeometryLoader", function() { return BufferGeometryLoader; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DefaultLoadingManager", function() { return DefaultLoadingManager; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LoadingManager", function() { return LoadingManager; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "JSONLoader", function() { return JSONLoader; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ImageLoader", function() { return ImageLoader; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FontLoader", function() { return FontLoader; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FileLoader", function() { return FileLoader; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Loader", function() { return Loader; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Cache", function() { return Cache; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AudioLoader", function() { return AudioLoader; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SpotLightShadow", function() { return SpotLightShadow; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SpotLight", function() { return SpotLight; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PointLight", function() { return PointLight; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RectAreaLight", function() { return RectAreaLight; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HemisphereLight", function() { return HemisphereLight; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DirectionalLightShadow", function() { return DirectionalLightShadow; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DirectionalLight", function() { return DirectionalLight; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AmbientLight", function() { return AmbientLight; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LightShadow", function() { return LightShadow; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Light", function() { return Light; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StereoCamera", function() { return StereoCamera; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PerspectiveCamera", function() { return PerspectiveCamera; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OrthographicCamera", function() { return OrthographicCamera; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CubeCamera", function() { return CubeCamera; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ArrayCamera", function() { return ArrayCamera; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Camera", function() { return Camera; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AudioListener", function() { return AudioListener; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PositionalAudio", function() { return PositionalAudio; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AudioContext", function() { return AudioContext; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AudioAnalyser", function() { return AudioAnalyser; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Audio", function() { return Audio; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VectorKeyframeTrack", function() { return VectorKeyframeTrack; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StringKeyframeTrack", function() { return StringKeyframeTrack; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "QuaternionKeyframeTrack", function() { return QuaternionKeyframeTrack; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NumberKeyframeTrack", function() { return NumberKeyframeTrack; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ColorKeyframeTrack", function() { return ColorKeyframeTrack; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BooleanKeyframeTrack", function() { return BooleanKeyframeTrack; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PropertyMixer", function() { return PropertyMixer; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PropertyBinding", function() { return PropertyBinding; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KeyframeTrack", function() { return KeyframeTrack; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AnimationUtils", function() { return AnimationUtils; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AnimationObjectGroup", function() { return AnimationObjectGroup; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AnimationMixer", function() { return AnimationMixer; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AnimationClip", function() { return AnimationClip; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Uniform", function() { return Uniform; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InstancedBufferGeometry", function() { return InstancedBufferGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BufferGeometry", function() { return BufferGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GeometryIdCount", function() { return GeometryIdCount; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Geometry", function() { return Geometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InterleavedBufferAttribute", function() { return InterleavedBufferAttribute; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InstancedInterleavedBuffer", function() { return InstancedInterleavedBuffer; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InterleavedBuffer", function() { return InterleavedBuffer; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InstancedBufferAttribute", function() { return InstancedBufferAttribute; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Face3", function() { return Face3; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Object3D", function() { return Object3D; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Raycaster", function() { return Raycaster; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Layers", function() { return Layers; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EventDispatcher", function() { return EventDispatcher; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Clock", function() { return Clock; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "QuaternionLinearInterpolant", function() { return QuaternionLinearInterpolant; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LinearInterpolant", function() { return LinearInterpolant; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DiscreteInterpolant", function() { return DiscreteInterpolant; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CubicInterpolant", function() { return CubicInterpolant; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Interpolant", function() { return Interpolant; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Triangle", function() { return Triangle; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Math", function() { return _Math; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Spherical", function() { return Spherical; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Cylindrical", function() { return Cylindrical; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Plane", function() { return Plane; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Frustum", function() { return Frustum; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Sphere", function() { return Sphere; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Ray", function() { return Ray; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Matrix4", function() { return Matrix4; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Matrix3", function() { return Matrix3; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Box3", function() { return Box3; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Box2", function() { return Box2; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Line3", function() { return Line3; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Euler", function() { return Euler; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Vector4", function() { return Vector4; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Vector3", function() { return Vector3; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Vector2", function() { return Vector2; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Quaternion", function() { return Quaternion; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Color", function() { return Color; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MorphBlendMesh", function() { return MorphBlendMesh; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ImmediateRenderObject", function() { return ImmediateRenderObject; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VertexNormalsHelper", function() { return VertexNormalsHelper; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SpotLightHelper", function() { return SpotLightHelper; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SkeletonHelper", function() { return SkeletonHelper; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PointLightHelper", function() { return PointLightHelper; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RectAreaLightHelper", function() { return RectAreaLightHelper; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HemisphereLightHelper", function() { return HemisphereLightHelper; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GridHelper", function() { return GridHelper; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PolarGridHelper", function() { return PolarGridHelper; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FaceNormalsHelper", function() { return FaceNormalsHelper; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DirectionalLightHelper", function() { return DirectionalLightHelper; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CameraHelper", function() { return CameraHelper; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BoxHelper", function() { return BoxHelper; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ArrowHelper", function() { return ArrowHelper; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AxisHelper", function() { return AxisHelper; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CatmullRomCurve3", function() { return CatmullRomCurve3; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CubicBezierCurve3", function() { return CubicBezierCurve3; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "QuadraticBezierCurve3", function() { return QuadraticBezierCurve3; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LineCurve3", function() { return LineCurve3; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ArcCurve", function() { return ArcCurve; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EllipseCurve", function() { return EllipseCurve; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SplineCurve", function() { return SplineCurve; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CubicBezierCurve", function() { return CubicBezierCurve; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "QuadraticBezierCurve", function() { return QuadraticBezierCurve; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LineCurve", function() { return LineCurve; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Shape", function() { return Shape; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Path", function() { return Path; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShapePath", function() { return ShapePath; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Font", function() { return Font; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CurvePath", function() { return CurvePath; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Curve", function() { return Curve; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShapeUtils", function() { return ShapeUtils; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SceneUtils", function() { return SceneUtils; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WireframeGeometry", function() { return WireframeGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ParametricGeometry", function() { return ParametricGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ParametricBufferGeometry", function() { return ParametricBufferGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TetrahedronGeometry", function() { return TetrahedronGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TetrahedronBufferGeometry", function() { return TetrahedronBufferGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OctahedronGeometry", function() { return OctahedronGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OctahedronBufferGeometry", function() { return OctahedronBufferGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "IcosahedronGeometry", function() { return IcosahedronGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "IcosahedronBufferGeometry", function() { return IcosahedronBufferGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DodecahedronGeometry", function() { return DodecahedronGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DodecahedronBufferGeometry", function() { return DodecahedronBufferGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PolyhedronGeometry", function() { return PolyhedronGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PolyhedronBufferGeometry", function() { return PolyhedronBufferGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TubeGeometry", function() { return TubeGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TubeBufferGeometry", function() { return TubeBufferGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TorusKnotGeometry", function() { return TorusKnotGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TorusKnotBufferGeometry", function() { return TorusKnotBufferGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TorusGeometry", function() { return TorusGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TorusBufferGeometry", function() { return TorusBufferGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextGeometry", function() { return TextGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextBufferGeometry", function() { return TextBufferGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SphereGeometry", function() { return SphereGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SphereBufferGeometry", function() { return SphereBufferGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RingGeometry", function() { return RingGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RingBufferGeometry", function() { return RingBufferGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PlaneGeometry", function() { return PlaneGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PlaneBufferGeometry", function() { return PlaneBufferGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LatheGeometry", function() { return LatheGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LatheBufferGeometry", function() { return LatheBufferGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShapeGeometry", function() { return ShapeGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShapeBufferGeometry", function() { return ShapeBufferGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ExtrudeGeometry", function() { return ExtrudeGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ExtrudeBufferGeometry", function() { return ExtrudeBufferGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EdgesGeometry", function() { return EdgesGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ConeGeometry", function() { return ConeGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ConeBufferGeometry", function() { return ConeBufferGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CylinderGeometry", function() { return CylinderGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CylinderBufferGeometry", function() { return CylinderBufferGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CircleGeometry", function() { return CircleGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CircleBufferGeometry", function() { return CircleBufferGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BoxGeometry", function() { return BoxGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BoxBufferGeometry", function() { return BoxBufferGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShadowMaterial", function() { return ShadowMaterial; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SpriteMaterial", function() { return SpriteMaterial; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RawShaderMaterial", function() { return RawShaderMaterial; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShaderMaterial", function() { return ShaderMaterial; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PointsMaterial", function() { return PointsMaterial; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MeshPhysicalMaterial", function() { return MeshPhysicalMaterial; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MeshStandardMaterial", function() { return MeshStandardMaterial; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MeshPhongMaterial", function() { return MeshPhongMaterial; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MeshToonMaterial", function() { return MeshToonMaterial; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MeshNormalMaterial", function() { return MeshNormalMaterial; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MeshLambertMaterial", function() { return MeshLambertMaterial; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MeshDepthMaterial", function() { return MeshDepthMaterial; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MeshBasicMaterial", function() { return MeshBasicMaterial; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LineDashedMaterial", function() { return LineDashedMaterial; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LineBasicMaterial", function() { return LineBasicMaterial; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Material", function() { return Material; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Float64BufferAttribute", function() { return Float64BufferAttribute; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Float32BufferAttribute", function() { return Float32BufferAttribute; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Uint32BufferAttribute", function() { return Uint32BufferAttribute; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Int32BufferAttribute", function() { return Int32BufferAttribute; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Uint16BufferAttribute", function() { return Uint16BufferAttribute; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Int16BufferAttribute", function() { return Int16BufferAttribute; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Uint8ClampedBufferAttribute", function() { return Uint8ClampedBufferAttribute; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Uint8BufferAttribute", function() { return Uint8BufferAttribute; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Int8BufferAttribute", function() { return Int8BufferAttribute; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BufferAttribute", function() { return BufferAttribute; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "REVISION", function() { return REVISION; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MOUSE", function() { return MOUSE; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CullFaceNone", function() { return CullFaceNone; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CullFaceBack", function() { return CullFaceBack; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CullFaceFront", function() { return CullFaceFront; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CullFaceFrontBack", function() { return CullFaceFrontBack; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FrontFaceDirectionCW", function() { return FrontFaceDirectionCW; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FrontFaceDirectionCCW", function() { return FrontFaceDirectionCCW; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BasicShadowMap", function() { return BasicShadowMap; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PCFShadowMap", function() { return PCFShadowMap; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PCFSoftShadowMap", function() { return PCFSoftShadowMap; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FrontSide", function() { return FrontSide; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BackSide", function() { return BackSide; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DoubleSide", function() { return DoubleSide; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FlatShading", function() { return FlatShading; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SmoothShading", function() { return SmoothShading; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NoColors", function() { return NoColors; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FaceColors", function() { return FaceColors; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VertexColors", function() { return VertexColors; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NoBlending", function() { return NoBlending; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NormalBlending", function() { return NormalBlending; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AdditiveBlending", function() { return AdditiveBlending; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SubtractiveBlending", function() { return SubtractiveBlending; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MultiplyBlending", function() { return MultiplyBlending; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CustomBlending", function() { return CustomBlending; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AddEquation", function() { return AddEquation; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SubtractEquation", function() { return SubtractEquation; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ReverseSubtractEquation", function() { return ReverseSubtractEquation; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MinEquation", function() { return MinEquation; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MaxEquation", function() { return MaxEquation; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ZeroFactor", function() { return ZeroFactor; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OneFactor", function() { return OneFactor; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SrcColorFactor", function() { return SrcColorFactor; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OneMinusSrcColorFactor", function() { return OneMinusSrcColorFactor; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SrcAlphaFactor", function() { return SrcAlphaFactor; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OneMinusSrcAlphaFactor", function() { return OneMinusSrcAlphaFactor; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DstAlphaFactor", function() { return DstAlphaFactor; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OneMinusDstAlphaFactor", function() { return OneMinusDstAlphaFactor; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DstColorFactor", function() { return DstColorFactor; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OneMinusDstColorFactor", function() { return OneMinusDstColorFactor; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SrcAlphaSaturateFactor", function() { return SrcAlphaSaturateFactor; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NeverDepth", function() { return NeverDepth; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AlwaysDepth", function() { return AlwaysDepth; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LessDepth", function() { return LessDepth; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LessEqualDepth", function() { return LessEqualDepth; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EqualDepth", function() { return EqualDepth; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GreaterEqualDepth", function() { return GreaterEqualDepth; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GreaterDepth", function() { return GreaterDepth; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NotEqualDepth", function() { return NotEqualDepth; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MultiplyOperation", function() { return MultiplyOperation; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MixOperation", function() { return MixOperation; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AddOperation", function() { return AddOperation; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NoToneMapping", function() { return NoToneMapping; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LinearToneMapping", function() { return LinearToneMapping; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ReinhardToneMapping", function() { return ReinhardToneMapping; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Uncharted2ToneMapping", function() { return Uncharted2ToneMapping; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CineonToneMapping", function() { return CineonToneMapping; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "UVMapping", function() { return UVMapping; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CubeReflectionMapping", function() { return CubeReflectionMapping; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CubeRefractionMapping", function() { return CubeRefractionMapping; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EquirectangularReflectionMapping", function() { return EquirectangularReflectionMapping; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EquirectangularRefractionMapping", function() { return EquirectangularRefractionMapping; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SphericalReflectionMapping", function() { return SphericalReflectionMapping; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CubeUVReflectionMapping", function() { return CubeUVReflectionMapping; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CubeUVRefractionMapping", function() { return CubeUVRefractionMapping; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RepeatWrapping", function() { return RepeatWrapping; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ClampToEdgeWrapping", function() { return ClampToEdgeWrapping; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MirroredRepeatWrapping", function() { return MirroredRepeatWrapping; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NearestFilter", function() { return NearestFilter; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NearestMipMapNearestFilter", function() { return NearestMipMapNearestFilter; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NearestMipMapLinearFilter", function() { return NearestMipMapLinearFilter; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LinearFilter", function() { return LinearFilter; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LinearMipMapNearestFilter", function() { return LinearMipMapNearestFilter; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LinearMipMapLinearFilter", function() { return LinearMipMapLinearFilter; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "UnsignedByteType", function() { return UnsignedByteType; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ByteType", function() { return ByteType; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShortType", function() { return ShortType; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "UnsignedShortType", function() { return UnsignedShortType; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "IntType", function() { return IntType; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "UnsignedIntType", function() { return UnsignedIntType; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FloatType", function() { return FloatType; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HalfFloatType", function() { return HalfFloatType; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "UnsignedShort4444Type", function() { return UnsignedShort4444Type; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "UnsignedShort5551Type", function() { return UnsignedShort5551Type; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "UnsignedShort565Type", function() { return UnsignedShort565Type; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "UnsignedInt248Type", function() { return UnsignedInt248Type; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AlphaFormat", function() { return AlphaFormat; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RGBFormat", function() { return RGBFormat; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RGBAFormat", function() { return RGBAFormat; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LuminanceFormat", function() { return LuminanceFormat; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LuminanceAlphaFormat", function() { return LuminanceAlphaFormat; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RGBEFormat", function() { return RGBEFormat; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DepthFormat", function() { return DepthFormat; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DepthStencilFormat", function() { return DepthStencilFormat; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RGB_S3TC_DXT1_Format", function() { return RGB_S3TC_DXT1_Format; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RGBA_S3TC_DXT1_Format", function() { return RGBA_S3TC_DXT1_Format; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RGBA_S3TC_DXT3_Format", function() { return RGBA_S3TC_DXT3_Format; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RGBA_S3TC_DXT5_Format", function() { return RGBA_S3TC_DXT5_Format; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RGB_PVRTC_4BPPV1_Format", function() { return RGB_PVRTC_4BPPV1_Format; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RGB_PVRTC_2BPPV1_Format", function() { return RGB_PVRTC_2BPPV1_Format; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RGBA_PVRTC_4BPPV1_Format", function() { return RGBA_PVRTC_4BPPV1_Format; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RGBA_PVRTC_2BPPV1_Format", function() { return RGBA_PVRTC_2BPPV1_Format; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RGB_ETC1_Format", function() { return RGB_ETC1_Format; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LoopOnce", function() { return LoopOnce; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LoopRepeat", function() { return LoopRepeat; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LoopPingPong", function() { return LoopPingPong; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InterpolateDiscrete", function() { return InterpolateDiscrete; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InterpolateLinear", function() { return InterpolateLinear; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InterpolateSmooth", function() { return InterpolateSmooth; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ZeroCurvatureEnding", function() { return ZeroCurvatureEnding; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ZeroSlopeEnding", function() { return ZeroSlopeEnding; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WrapAroundEnding", function() { return WrapAroundEnding; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TrianglesDrawMode", function() { return TrianglesDrawMode; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TriangleStripDrawMode", function() { return TriangleStripDrawMode; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TriangleFanDrawMode", function() { return TriangleFanDrawMode; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LinearEncoding", function() { return LinearEncoding; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sRGBEncoding", function() { return sRGBEncoding; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GammaEncoding", function() { return GammaEncoding; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RGBEEncoding", function() { return RGBEEncoding; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LogLuvEncoding", function() { return LogLuvEncoding; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RGBM7Encoding", function() { return RGBM7Encoding; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RGBM16Encoding", function() { return RGBM16Encoding; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RGBDEncoding", function() { return RGBDEncoding; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BasicDepthPacking", function() { return BasicDepthPacking; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RGBADepthPacking", function() { return RGBADepthPacking; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CubeGeometry", function() { return BoxGeometry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Face4", function() { return Face4; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LineStrip", function() { return LineStrip; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LinePieces", function() { return LinePieces; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MeshFaceMaterial", function() { return MeshFaceMaterial; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MultiMaterial", function() { return MultiMaterial; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PointCloud", function() { return PointCloud; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Particle", function() { return Particle; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ParticleSystem", function() { return ParticleSystem; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PointCloudMaterial", function() { return PointCloudMaterial; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ParticleBasicMaterial", function() { return ParticleBasicMaterial; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ParticleSystemMaterial", function() { return ParticleSystemMaterial; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Vertex", function() { return Vertex; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DynamicBufferAttribute", function() { return DynamicBufferAttribute; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Int8Attribute", function() { return Int8Attribute; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Uint8Attribute", function() { return Uint8Attribute; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Uint8ClampedAttribute", function() { return Uint8ClampedAttribute; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Int16Attribute", function() { return Int16Attribute; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Uint16Attribute", function() { return Uint16Attribute; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Int32Attribute", function() { return Int32Attribute; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Uint32Attribute", function() { return Uint32Attribute; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Float32Attribute", function() { return Float32Attribute; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Float64Attribute", function() { return Float64Attribute; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ClosedSplineCurve3", function() { return ClosedSplineCurve3; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SplineCurve3", function() { return SplineCurve3; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Spline", function() { return Spline; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BoundingBoxHelper", function() { return BoundingBoxHelper; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EdgesHelper", function() { return EdgesHelper; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WireframeHelper", function() { return WireframeHelper; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "XHRLoader", function() { return XHRLoader; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BinaryTextureLoader", function() { return BinaryTextureLoader; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GeometryUtils", function() { return GeometryUtils; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ImageUtils", function() { return ImageUtils; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Projector", function() { return Projector; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CanvasRenderer", function() { return CanvasRenderer; });
// Polyfills
if ( Number.EPSILON === undefined ) {
Number.EPSILON = Math.pow( 2, - 52 );
}
if ( Number.isInteger === undefined ) {
// Missing in IE
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger
Number.isInteger = function ( value ) {
return typeof value === 'number' && isFinite( value ) && Math.floor( value ) === value;
};
}
//
if ( Math.sign === undefined ) {
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign
Math.sign = function ( x ) {
return ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : + x;
};
}
if ( Function.prototype.name === undefined ) {
// Missing in IE
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name
Object.defineProperty( Function.prototype, 'name', {
get: function () {
return this.toString().match( /^\s*function\s*([^\(\s]*)/ )[ 1 ];
}
} );
}
if ( Object.assign === undefined ) {
// Missing in IE
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
( function () {
Object.assign = function ( target ) {
'use strict';
if ( target === undefined || target === null ) {
throw new TypeError( 'Cannot convert undefined or null to object' );
}
var output = Object( target );
for ( var index = 1; index < arguments.length; index ++ ) {
var source = arguments[ index ];
if ( source !== undefined && source !== null ) {
for ( var nextKey in source ) {
if ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) {
output[ nextKey ] = source[ nextKey ];
}
}
}
}
return output;
};
} )();
}
/**
* https://github.com/mrdoob/eventdispatcher.js/
*/
function EventDispatcher() {}
Object.assign( EventDispatcher.prototype, {
addEventListener: function ( type, listener ) {
if ( this._listeners === undefined ) this._listeners = {};
var listeners = this._listeners;
if ( listeners[ type ] === undefined ) {
listeners[ type ] = [];
}
if ( listeners[ type ].indexOf( listener ) === - 1 ) {
listeners[ type ].push( listener );
}
},
hasEventListener: function ( type, listener ) {
if ( this._listeners === undefined ) return false;
var listeners = this._listeners;
return listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1;
},
removeEventListener: function ( type, listener ) {
if ( this._listeners === undefined ) return;
var listeners = this._listeners;
var listenerArray = listeners[ type ];
if ( listenerArray !== undefined ) {
var index = listenerArray.indexOf( listener );
if ( index !== - 1 ) {
listenerArray.splice( index, 1 );
}
}
},
dispatchEvent: function ( event ) {
if ( this._listeners === undefined ) return;
var listeners = this._listeners;
var listenerArray = listeners[ event.type ];
if ( listenerArray !== undefined ) {
event.target = this;
var array = listenerArray.slice( 0 );
for ( var i = 0, l = array.length; i < l; i ++ ) {
array[ i ].call( this, event );
}
}
}
} );
var REVISION = '86';
var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };
var CullFaceNone = 0;
var CullFaceBack = 1;
var CullFaceFront = 2;
var CullFaceFrontBack = 3;
var FrontFaceDirectionCW = 0;
var FrontFaceDirectionCCW = 1;
var BasicShadowMap = 0;
var PCFShadowMap = 1;
var PCFSoftShadowMap = 2;
var FrontSide = 0;
var BackSide = 1;
var DoubleSide = 2;
var FlatShading = 1;
var SmoothShading = 2;
var NoColors = 0;
var FaceColors = 1;
var VertexColors = 2;
var NoBlending = 0;
var NormalBlending = 1;
var AdditiveBlending = 2;
var SubtractiveBlending = 3;
var MultiplyBlending = 4;
var CustomBlending = 5;
var AddEquation = 100;
var SubtractEquation = 101;
var ReverseSubtractEquation = 102;
var MinEquation = 103;
var MaxEquation = 104;
var ZeroFactor = 200;
var OneFactor = 201;
var SrcColorFactor = 202;
var OneMinusSrcColorFactor = 203;
var SrcAlphaFactor = 204;
var OneMinusSrcAlphaFactor = 205;
var DstAlphaFactor = 206;
var OneMinusDstAlphaFactor = 207;
var DstColorFactor = 208;
var OneMinusDstColorFactor = 209;
var SrcAlphaSaturateFactor = 210;
var NeverDepth = 0;
var AlwaysDepth = 1;
var LessDepth = 2;
var LessEqualDepth = 3;
var EqualDepth = 4;
var GreaterEqualDepth = 5;
var GreaterDepth = 6;
var NotEqualDepth = 7;
var MultiplyOperation = 0;
var MixOperation = 1;
var AddOperation = 2;
var NoToneMapping = 0;
var LinearToneMapping = 1;
var ReinhardToneMapping = 2;
var Uncharted2ToneMapping = 3;
var CineonToneMapping = 4;
var UVMapping = 300;
var CubeReflectionMapping = 301;
var CubeRefractionMapping = 302;
var EquirectangularReflectionMapping = 303;
var EquirectangularRefractionMapping = 304;
var SphericalReflectionMapping = 305;
var CubeUVReflectionMapping = 306;
var CubeUVRefractionMapping = 307;
var RepeatWrapping = 1000;
var ClampToEdgeWrapping = 1001;
var MirroredRepeatWrapping = 1002;
var NearestFilter = 1003;
var NearestMipMapNearestFilter = 1004;
var NearestMipMapLinearFilter = 1005;
var LinearFilter = 1006;
var LinearMipMapNearestFilter = 1007;
var LinearMipMapLinearFilter = 1008;
var UnsignedByteType = 1009;
var ByteType = 1010;
var ShortType = 1011;
var UnsignedShortType = 1012;
var IntType = 1013;
var UnsignedIntType = 1014;
var FloatType = 1015;
var HalfFloatType = 1016;
var UnsignedShort4444Type = 1017;
var UnsignedShort5551Type = 1018;
var UnsignedShort565Type = 1019;
var UnsignedInt248Type = 1020;
var AlphaFormat = 1021;
var RGBFormat = 1022;
var RGBAFormat = 1023;
var LuminanceFormat = 1024;
var LuminanceAlphaFormat = 1025;
var RGBEFormat = RGBAFormat;
var DepthFormat = 1026;
var DepthStencilFormat = 1027;
var RGB_S3TC_DXT1_Format = 2001;
var RGBA_S3TC_DXT1_Format = 2002;
var RGBA_S3TC_DXT3_Format = 2003;
var RGBA_S3TC_DXT5_Format = 2004;
var RGB_PVRTC_4BPPV1_Format = 2100;
var RGB_PVRTC_2BPPV1_Format = 2101;
var RGBA_PVRTC_4BPPV1_Format = 2102;
var RGBA_PVRTC_2BPPV1_Format = 2103;
var RGB_ETC1_Format = 2151;
var LoopOnce = 2200;
var LoopRepeat = 2201;
var LoopPingPong = 2202;
var InterpolateDiscrete = 2300;
var InterpolateLinear = 2301;
var InterpolateSmooth = 2302;
var ZeroCurvatureEnding = 2400;
var ZeroSlopeEnding = 2401;
var WrapAroundEnding = 2402;
var TrianglesDrawMode = 0;
var TriangleStripDrawMode = 1;
var TriangleFanDrawMode = 2;
var LinearEncoding = 3000;
var sRGBEncoding = 3001;
var GammaEncoding = 3007;
var RGBEEncoding = 3002;
var LogLuvEncoding = 3003;
var RGBM7Encoding = 3004;
var RGBM16Encoding = 3005;
var RGBDEncoding = 3006;
var BasicDepthPacking = 3200;
var RGBADepthPacking = 3201;
/**
* @author alteredq / http://alteredqualia.com/
* @author mrdoob / http://mrdoob.com/
*/
var _Math = {
DEG2RAD: Math.PI / 180,
RAD2DEG: 180 / Math.PI,
generateUUID: function () {
// http://www.broofa.com/Tools/Math.uuid.htm
var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split( '' );
var uuid = new Array( 36 );
var rnd = 0, r;
return function generateUUID() {
for ( var i = 0; i < 36; i ++ ) {
if ( i === 8 || i === 13 || i === 18 || i === 23 ) {
uuid[ i ] = '-';
} else if ( i === 14 ) {
uuid[ i ] = '4';
} else {
if ( rnd <= 0x02 ) rnd = 0x2000000 + ( Math.random() * 0x1000000 ) | 0;
r = rnd & 0xf;
rnd = rnd >> 4;
uuid[ i ] = chars[ ( i === 19 ) ? ( r & 0x3 ) | 0x8 : r ];
}
}
return uuid.join( '' );
};
}(),
clamp: function ( value, min, max ) {
return Math.max( min, Math.min( max, value ) );
},
// compute euclidian modulo of m % n
// https://en.wikipedia.org/wiki/Modulo_operation
euclideanModulo: function ( n, m ) {
return ( ( n % m ) + m ) % m;
},
// Linear mapping from range <a1, a2> to range <b1, b2>
mapLinear: function ( x, a1, a2, b1, b2 ) {
return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );
},
// https://en.wikipedia.org/wiki/Linear_interpolation
lerp: function ( x, y, t ) {
return ( 1 - t ) * x + t * y;
},
// http://en.wikipedia.org/wiki/Smoothstep
smoothstep: function ( x, min, max ) {
if ( x <= min ) return 0;
if ( x >= max ) return 1;
x = ( x - min ) / ( max - min );
return x * x * ( 3 - 2 * x );
},
smootherstep: function ( x, min, max ) {
if ( x <= min ) return 0;
if ( x >= max ) return 1;
x = ( x - min ) / ( max - min );
return x * x * x * ( x * ( x * 6 - 15 ) + 10 );
},
// Random integer from <low, high> interval
randInt: function ( low, high ) {
return low + Math.floor( Math.random() * ( high - low + 1 ) );
},
// Random float from <low, high> interval
randFloat: function ( low, high ) {
return low + Math.random() * ( high - low );
},
// Random float from <-range/2, range/2> interval
randFloatSpread: function ( range ) {
return range * ( 0.5 - Math.random() );
},
degToRad: function ( degrees ) {
return degrees * _Math.DEG2RAD;
},
radToDeg: function ( radians ) {
return radians * _Math.RAD2DEG;
},
isPowerOfTwo: function ( value ) {
return ( value & ( value - 1 ) ) === 0 && value !== 0;
},
nearestPowerOfTwo: function ( value ) {
return Math.pow( 2, Math.round( Math.log( value ) / Math.LN2 ) );
},
nextPowerOfTwo: function ( value ) {
value --;
value |= value >> 1;
value |= value >> 2;
value |= value >> 4;
value |= value >> 8;
value |= value >> 16;
value ++;
return value;
}
};
/**
* @author mrdoob / http://mrdoob.com/
* @author philogb / http://blog.thejit.org/
* @author egraether / http://egraether.com/
* @author zz85 / http://www.lab4games.net/zz85/blog
*/
function Vector2( x, y ) {
this.x = x || 0;
this.y = y || 0;
}
Object.defineProperties( Vector2.prototype, {
"width" : {
get: function () {
return this.x;
},
set: function ( value ) {
this.x = value;
}
},
"height" : {
get: function () {
return this.y;
},
set: function ( value ) {
this.y = value;
}
}
} );
Object.assign( Vector2.prototype, {
isVector2: true,
set: function ( x, y ) {
this.x = x;
this.y = y;
return this;
},
setScalar: function ( scalar ) {
this.x = scalar;
this.y = scalar;
return this;
},
setX: function ( x ) {
this.x = x;
return this;
},
setY: function ( y ) {
this.y = y;
return this;
},
setComponent: function ( index, value ) {
switch ( index ) {
case 0: this.x = value; break;
case 1: this.y = value; break;
default: throw new Error( 'index is out of range: ' + index );
}
return this;
},
getComponent: function ( index ) {
switch ( index ) {
case 0: return this.x;
case 1: return this.y;
default: throw new Error( 'index is out of range: ' + index );
}
},
clone: function () {
return new this.constructor( this.x, this.y );
},
copy: function ( v ) {
this.x = v.x;
this.y = v.y;
return this;
},
add: function ( v, w ) {
if ( w !== undefined ) {
console.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
return this.addVectors( v, w );
}
this.x += v.x;
this.y += v.y;
return this;
},
addScalar: function ( s ) {
this.x += s;
this.y += s;
return this;
},
addVectors: function ( a, b ) {
this.x = a.x + b.x;
this.y = a.y + b.y;
return this;
},
addScaledVector: function ( v, s ) {
this.x += v.x * s;
this.y += v.y * s;
return this;
},
sub: function ( v, w ) {
if ( w !== undefined ) {
console.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
return this.subVectors( v, w );
}
this.x -= v.x;
this.y -= v.y;
return this;
},
subScalar: function ( s ) {
this.x -= s;
this.y -= s;
return this;
},
subVectors: function ( a, b ) {
this.x = a.x - b.x;
this.y = a.y - b.y;
return this;
},
multiply: function ( v ) {
this.x *= v.x;
this.y *= v.y;
return this;
},
multiplyScalar: function ( scalar ) {
this.x *= scalar;
this.y *= scalar;
return this;
},
divide: function ( v ) {
this.x /= v.x;
this.y /= v.y;
return this;
},
divideScalar: function ( scalar ) {
return this.multiplyScalar( 1 / scalar );
},
min: function ( v ) {
this.x = Math.min( this.x, v.x );
this.y = Math.min( this.y, v.y );
return this;
},
max: function ( v ) {
this.x = Math.max( this.x, v.x );
this.y = Math.max( this.y, v.y );
return this;
},
clamp: function ( min, max ) {
// assumes min < max, componentwise
this.x = Math.max( min.x, Math.min( max.x, this.x ) );
this.y = Math.max( min.y, Math.min( max.y, this.y ) );
return this;
},
clampScalar: function () {
var min = new Vector2();
var max = new Vector2();
return function clampScalar( minVal, maxVal ) {
min.set( minVal, minVal );
max.set( maxVal, maxVal );
return this.clamp( min, max );
};
}(),
clampLength: function ( min, max ) {
var length = this.length();
return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) );
},
floor: function () {
this.x = Math.floor( this.x );
this.y = Math.floor( this.y );
return this;
},
ceil: function () {
this.x = Math.ceil( this.x );
this.y = Math.ceil( this.y );
return this;
},
round: function () {
this.x = Math.round( this.x );
this.y = Math.round( this.y );
return this;
},
roundToZero: function () {
this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );
this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );
return this;
},
negate: function () {
this.x = - this.x;
this.y = - this.y;
return this;
},
dot: function ( v ) {
return this.x * v.x + this.y * v.y;
},
lengthSq: function () {
return this.x * this.x + this.y * this.y;
},
length: function () {
return Math.sqrt( this.x * this.x + this.y * this.y );
},
lengthManhattan: function() {
return Math.abs( this.x ) + Math.abs( this.y );
},
normalize: function () {
return this.divideScalar( this.length() || 1 );
},
angle: function () {
// computes the angle in radians with respect to the positive x-axis
var angle = Math.atan2( this.y, this.x );
if ( angle < 0 ) angle += 2 * Math.PI;
return angle;
},
distanceTo: function ( v ) {
return Math.sqrt( this.distanceToSquared( v ) );
},
distanceToSquared: function ( v ) {
var dx = this.x - v.x, dy = this.y - v.y;
return dx * dx + dy * dy;
},
distanceToManhattan: function ( v ) {
return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y );
},
setLength: function ( length ) {
return this.normalize().multiplyScalar( length );
},
lerp: function ( v, alpha ) {
this.x += ( v.x - this.x ) * alpha;
this.y += ( v.y - this.y ) * alpha;
return this;
},
lerpVectors: function ( v1, v2, alpha ) {
return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );
},
equals: function ( v ) {
return ( ( v.x === this.x ) && ( v.y === this.y ) );
},
fromArray: function ( array, offset ) {
if ( offset === undefined ) offset = 0;
this.x = array[ offset ];
this.y = array[ offset + 1 ];
return this;
},
toArray: function ( array, offset ) {
if ( array === undefined ) array = [];
if ( offset === undefined ) offset = 0;
array[ offset ] = this.x;
array[ offset + 1 ] = this.y;
return array;
},
fromBufferAttribute: function ( attribute, index, offset ) {
if ( offset !== undefined ) {
console.warn( 'THREE.Vector2: offset has been removed from .fromBufferAttribute().' );
}
this.x = attribute.getX( index );
this.y = attribute.getY( index );
return this;
},
rotateAround: function ( center, angle ) {
var c = Math.cos( angle ), s = Math.sin( angle );
var x = this.x - center.x;
var y = this.y - center.y;
this.x = x * c - y * s + center.x;
this.y = x * s + y * c + center.y;
return this;
}
} );
/**
* @author mrdoob / http://mrdoob.com/
* @author alteredq / http://alteredqualia.com/
* @author szimek / https://github.com/szimek/
*/
var textureId = 0;
function Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {
Object.defineProperty( this, 'id', { value: textureId ++ } );
this.uuid = _Math.generateUUID();
this.name = '';
this.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;
this.mipmaps = [];
this.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING;
this.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping;
this.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping;
this.magFilter = magFilter !== undefined ? magFilter : LinearFilter;
this.minFilter = minFilter !== undefined ? minFilter : LinearMipMapLinearFilter;
this.anisotropy = anisotropy !== undefined ? anisotropy : 1;
this.format = format !== undefined ? format : RGBAFormat;
this.type = type !== undefined ? type : UnsignedByteType;
this.offset = new Vector2( 0, 0 );
this.repeat = new Vector2( 1, 1 );
this.generateMipmaps = true;
this.premultiplyAlpha = false;
this.flipY = true;
this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)
// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.
//
// Also changing the encoding after already used by a Material will not automatically make the Material
// update. You need to explicitly call Material.needsUpdate to trigger it to recompile.
this.encoding = encoding !== undefined ? encoding : LinearEncoding;
this.version = 0;
this.onUpdate = null;
}
Texture.DEFAULT_IMAGE = undefined;
Texture.DEFAULT_MAPPING = UVMapping;
Object.defineProperty( Texture.prototype, "needsUpdate", {
set: function ( value ) {
if ( value === true ) this.version ++;
}
} );
Object.assign( Texture.prototype, EventDispatcher.prototype, {
constructor: Texture,
isTexture: true,
clone: function () {
return new this.constructor().copy( this );
},
copy: function ( source ) {
this.name = source.name;
this.image = source.image;
this.mipmaps = source.mipmaps.slice( 0 );
this.mapping = source.mapping;
this.wrapS = source.wrapS;
this.wrapT = source.wrapT;
this.magFilter = source.magFilter;
this.minFilter = source.minFilter;
this.anisotropy = source.anisotropy;
this.format = source.format;
this.type = source.type;
this.offset.copy( source.offset );
this.repeat.copy( source.repeat );
this.generateMipmaps = source.generateMipmaps;
this.premultiplyAlpha = source.premultiplyAlpha;
this.flipY = source.flipY;
this.unpackAlignment = source.unpackAlignment;
this.encoding = source.encoding;
return this;
},
toJSON: function ( meta ) {
if ( meta.textures[ this.uuid ] !== undefined ) {
return meta.textures[ this.uuid ];
}
function getDataURL( image ) {
var canvas;
if ( image.toDataURL !== undefined ) {
canvas = image;
} else {
canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );
canvas.width = image.width;
canvas.height = image.height;
canvas.getContext( '2d' ).drawImage( image, 0, 0, image.width, image.height );
}
if ( canvas.width > 2048 || canvas.height > 2048 ) {
return canvas.toDataURL( 'image/jpeg', 0.6 );
} else {
return canvas.toDataURL( 'image/png' );
}
}
var output = {
metadata: {
version: 4.5,
type: 'Texture',
generator: 'Texture.toJSON'
},
uuid: this.uuid,
name: this.name,
mapping: this.mapping,
repeat: [ this.repeat.x, this.repeat.y ],
offset: [ this.offset.x, this.offset.y ],
wrap: [ this.wrapS, this.wrapT ],
minFilter: this.minFilter,
magFilter: this.magFilter,
anisotropy: this.anisotropy,
flipY: this.flipY
};
if ( this.image !== undefined ) {
// TODO: Move to THREE.Image
var image = this.image;
if ( image.uuid === undefined ) {
image.uuid = _Math.generateUUID(); // UGH
}
if ( meta.images[ image.uuid ] === undefined ) {
meta.images[ image.uuid ] = {
uuid: image.uuid,
url: getDataURL( image )
};
}
output.image = image.uuid;
}
meta.textures[ this.uuid ] = output;
return output;
},
dispose: function () {
this.dispatchEvent( { type: 'dispose' } );
},
transformUv: function ( uv ) {
if ( this.mapping !== UVMapping ) return;
uv.multiply( this.repeat );
uv.add( this.offset );
if ( uv.x < 0 || uv.x > 1 ) {
switch ( this.wrapS ) {
case RepeatWrapping:
uv.x = uv.x - Math.floor( uv.x );
break;
case ClampToEdgeWrapping:
uv.x = uv.x < 0 ? 0 : 1;
break;
case MirroredRepeatWrapping:
if ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {
uv.x = Math.ceil( uv.x ) - uv.x;
} else {
uv.x = uv.x - Math.floor( uv.x );
}
break;
}
}
if ( uv.y < 0 || uv.y > 1 ) {
switch ( this.wrapT ) {
case RepeatWrapping:
uv.y = uv.y - Math.floor( uv.y );
break;
case ClampToEdgeWrapping:
uv.y = uv.y < 0 ? 0 : 1;
break;
case MirroredRepeatWrapping:
if ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {
uv.y = Math.ceil( uv.y ) - uv.y;
} else {
uv.y = uv.y - Math.floor( uv.y );
}
break;
}
}
if ( this.flipY ) {
uv.y = 1 - uv.y;
}
}
} );
/**
* @author supereggbert / http://www.paulbrunt.co.uk/
* @author philogb / http://blog.thejit.org/
* @author mikael emtinger / http://gomo.se/
* @author egraether / http://egraether.com/
* @author WestLangley / http://github.com/WestLangley
*/
function Vector4( x, y, z, w ) {
this.x = x || 0;
this.y = y || 0;
this.z = z || 0;
this.w = ( w !== undefined ) ? w : 1;
}
Object.assign( Vector4.prototype, {
isVector4: true,
set: function ( x, y, z, w ) {
this.x = x;
this.y = y;
this.z = z;
this.w = w;
return this;
},
setScalar: function ( scalar ) {
this.x = scalar;
this.y = scalar;
this.z = scalar;
this.w = scalar;
return this;
},
setX: function ( x ) {
this.x = x;
return this;
},
setY: function ( y ) {
this.y = y;
return this;
},
setZ: function ( z ) {
this.z = z;
return this;
},
setW: function ( w ) {
this.w = w;
return this;
},
setComponent: function ( index, value ) {
switch ( index ) {
case 0: this.x = value; break;
case 1: this.y = value; break;
case 2: this.z = value; break;
case 3: this.w = value; break;
default: throw new Error( 'index is out of range: ' + index );
}
return this;
},
getComponent: function ( index ) {
switch ( index ) {
case 0: return this.x;
case 1: return this.y;
case 2: return this.z;
case 3: return this.w;
default: throw new Error( 'index is out of range: ' + index );
}
},
clone: function () {
return new this.constructor( this.x, this.y, this.z, this.w );
},
copy: function ( v ) {
this.x = v.x;
this.y = v.y;
this.z = v.z;
this.w = ( v.w !== undefined ) ? v.w : 1;
return this;
},
add: function ( v, w ) {
if ( w !== undefined ) {
console.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
return this.addVectors( v, w );
}
this.x += v.x;
this.y += v.y;
this.z += v.z;
this.w += v.w;
return this;
},
addScalar: function ( s ) {
this.x += s;
this.y += s;
this.z += s;
this.w += s;
return this;
},
addVectors: function ( a, b ) {
this.x = a.x + b.x;
this.y = a.y + b.y;
this.z = a.z + b.z;
this.w = a.w + b.w;
return this;
},
addScaledVector: function ( v, s ) {
this.x += v.x * s;
this.y += v.y * s;
this.z += v.z * s;
this.w += v.w * s;
return this;
},
sub: function ( v, w ) {
if ( w !== undefined ) {
console.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
return this.subVectors( v, w );
}
this.x -= v.x;
this.y -= v.y;
this.z -= v.z;
this.w -= v.w;
return this;
},
subScalar: function ( s ) {
this.x -= s;
this.y -= s;
this.z -= s;
this.w -= s;
return this;
},
subVectors: function ( a, b ) {
this.x = a.x - b.x;
this.y = a.y - b.y;
this.z = a.z - b.z;
this.w = a.w - b.w;
return this;
},
multiplyScalar: function ( scalar ) {
this.x *= scalar;
this.y *= scalar;
this.z *= scalar;
this.w *= scalar;
return this;
},
applyMatrix4: function ( m ) {
var x = this.x, y = this.y, z = this.z, w = this.w;
var e = m.elements;
this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w;
this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w;
this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w;
this.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w;
return this;
},
divideScalar: function ( scalar ) {
return this.multiplyScalar( 1 / scalar );
},
setAxisAngleFromQuaternion: function ( q ) {
// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm
// q is assumed to be normalized
this.w = 2 * Math.acos( q.w );
var s = Math.sqrt( 1 - q.w * q.w );
if ( s < 0.0001 ) {
this.x = 1;
this.y = 0;
this.z = 0;
} else {
this.x = q.x / s;
this.y = q.y / s;
this.z = q.z / s;
}
return this;
},
setAxisAngleFromRotationMatrix: function ( m ) {
// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm
// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
var angle, x, y, z, // variables for result
epsilon = 0.01, // margin to allow for rounding errors
epsilon2 = 0.1, // margin to distinguish between 0 and 180 degrees
te = m.elements,
m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],
m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],
m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];
if ( ( Math.abs( m12 - m21 ) < epsilon ) &&
( Math.abs( m13 - m31 ) < epsilon ) &&
( Math.abs( m23 - m32 ) < epsilon ) ) {
// singularity found
// first check for identity matrix which must have +1 for all terms
// in leading diagonal and zero in other terms
if ( ( Math.abs( m12 + m21 ) < epsilon2 ) &&
( Math.abs( m13 + m31 ) < epsilon2 ) &&
( Math.abs( m23 + m32 ) < epsilon2 ) &&
( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {
// this singularity is identity matrix so angle = 0
this.set( 1, 0, 0, 0 );
return this; // zero angle, arbitrary axis
}
// otherwise this singularity is angle = 180
angle = Math.PI;
var xx = ( m11 + 1 ) / 2;
var yy = ( m22 + 1 ) / 2;
var zz = ( m33 + 1 ) / 2;
var xy = ( m12 + m21 ) / 4;
var xz = ( m13 + m31 ) / 4;
var yz = ( m23 + m32 ) / 4;
if ( ( xx > yy ) && ( xx > zz ) ) {
// m11 is the largest diagonal term
if ( xx < epsilon ) {
x = 0;
y = 0.707106781;
z = 0.707106781;
} else {
x = Math.sqrt( xx );
y = xy / x;
z = xz / x;
}
} else if ( yy > zz ) {
// m22 is the largest diagonal term
if ( yy < epsilon ) {
x = 0.707106781;
y = 0;
z = 0.707106781;
} else {
y = Math.sqrt( yy );
x = xy / y;
z = yz / y;
}
} else {
// m33 is the largest diagonal term so base result on this
if ( zz < epsilon ) {
x = 0.707106781;
y = 0.707106781;
z = 0;
} else {
z = Math.sqrt( zz );
x = xz / z;
y = yz / z;
}
}
this.set( x, y, z, angle );
return this; // return 180 deg rotation
}
// as we have reached here there are no singularities so we can handle normally
var s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) +
( m13 - m31 ) * ( m13 - m31 ) +
( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize
if ( Math.abs( s ) < 0.001 ) s = 1;
// prevent divide by zero, should not happen if matrix is orthogonal and should be
// caught by singularity test above, but I've left it in just in case
this.x = ( m32 - m23 ) / s;
this.y = ( m13 - m31 ) / s;
this.z = ( m21 - m12 ) / s;
this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );
return this;
},
min: function ( v ) {
this.x = Math.min( this.x, v.x );
this.y = Math.min( this.y, v.y );
this.z = Math.min( this.z, v.z );
this.w = Math.min( this.w, v.w );
return this;
},
max: function ( v ) {
this.x = Math.max( this.x, v.x );
this.y = Math.max( this.y, v.y );
this.z = Math.max( this.z, v.z );
this.w = Math.max( this.w, v.w );
return this;
},
clamp: function ( min, max ) {
// assumes min < max, componentwise
this.x = Math.max( min.x, Math.min( max.x, this.x ) );
this.y = Math.max( min.y, Math.min( max.y, this.y ) );
this.z = Math.max( min.z, Math.min( max.z, this.z ) );
this.w = Math.max( min.w, Math.min( max.w, this.w ) );
return this;
},
clampScalar: function () {
var min, max;
return function clampScalar( minVal, maxVal ) {
if ( min === undefined ) {
min = new Vector4();
max = new Vector4();
}
min.set( minVal, minVal, minVal, minVal );
max.set( maxVal, maxVal, maxVal, maxVal );
return this.clamp( min, max );
};
}(),
clampLength: function ( min, max ) {
var length = this.length();
return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) );
},
floor: function () {
this.x = Math.floor( this.x );
this.y = Math.floor( this.y );
this.z = Math.floor( this.z );
this.w = Math.floor( this.w );
return this;
},
ceil: function () {
this.x = Math.ceil( this.x );
this.y = Math.ceil( this.y );
this.z = Math.ceil( this.z );
this.w = Math.ceil( this.w );
return this;
},
round: function () {
this.x = Math.round( this.x );
this.y = Math.round( this.y );
this.z = Math.round( this.z );
this.w = Math.round( this.w );
return this;
},
roundToZero: function () {
this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );
this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );
this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );
this.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w );
return this;
},
negate: function () {
this.x = - this.x;
this.y = - this.y;
this.z = - this.z;
this.w = - this.w;
return this;
},
dot: function ( v ) {
return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;
},
lengthSq: function () {
return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;
},
length: function () {
return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );
},
lengthManhattan: function () {
return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );
},
normalize: function () {
return this.divideScalar( this.length() || 1 );
},
setLength: function ( length ) {
return this.normalize().multiplyScalar( length );
},
lerp: function ( v, alpha ) {
this.x += ( v.x - this.x ) * alpha;
this.y += ( v.y - this.y ) * alpha;
this.z += ( v.z - this.z ) * alpha;
this.w += ( v.w - this.w ) * alpha;
return this;
},
lerpVectors: function ( v1, v2, alpha ) {
return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );
},
equals: function ( v ) {
return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) );
},
fromArray: function ( array, offset ) {
if ( offset === undefined ) offset = 0;
this.x = array[ offset ];
this.y = array[ offset + 1 ];
this.z = array[ offset + 2 ];
this.w = array[ offset + 3 ];
return this;
},
toArray: function ( array, offset ) {
if ( array === undefined ) array = [];
if ( offset === undefined ) offset = 0;
array[ offset ] = this.x;
array[ offset + 1 ] = this.y;
array[ offset + 2 ] = this.z;
array[ offset + 3 ] = this.w;
return array;
},
fromBufferAttribute: function ( attribute, index, offset ) {
if ( offset !== undefined ) {
console.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' );
}
this.x = attribute.getX( index );
this.y = attribute.getY( index );
this.z = attribute.getZ( index );
this.w = attribute.getW( index );
return this;
}
} );
/**
* @author szimek / https://github.com/szimek/
* @author alteredq / http://alteredqualia.com/
* @author Marius Kintel / https://github.com/kintel
*/
/*
In options, we can specify:
* Texture parameters for an auto-generated target texture
* depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers
*/
function WebGLRenderTarget( width, height, options ) {
this.uuid = _Math.generateUUID();
this.width = width;
this.height = height;
this.scissor = new Vector4( 0, 0, width, height );
this.scissorTest = false;
this.viewport = new Vector4( 0, 0, width, height );
options = options || {};
if ( options.minFilter === undefined ) options.minFilter = LinearFilter;
this.texture = new Texture( undefined, undefined, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );
this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;
this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true;
this.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;
}
Object.assign( WebGLRenderTarget.prototype, EventDispatcher.prototype, {
isWebGLRenderTarget: true,
setSize: function ( width, height ) {
if ( this.width !== width || this.height !== height ) {
this.width = width;
this.height = height;
this.dispose();
}
this.viewport.set( 0, 0, width, height );
this.scissor.set( 0, 0, width, height );
},
clone: function () {
return new this.constructor().copy( this );
},
copy: function ( source ) {
this.width = source.width;
this.height = source.height;
this.viewport.copy( source.viewport );
this.texture = source.texture.clone();
this.depthBuffer = source.depthBuffer;
this.stencilBuffer = source.stencilBuffer;
this.depthTexture = source.depthTexture;
return this;
},
dispose: function () {
this.dispatchEvent( { type: 'dispose' } );
}
} );
/**
* @author alteredq / http://alteredqualia.com
*/
function WebGLRenderTargetCube( width, height, options ) {
WebGLRenderTarget.call( this, width, height, options );
this.activeCubeFace = 0; // PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5
this.activeMipMapLevel = 0;
}
WebGLRenderTargetCube.prototype = Object.create( WebGLRenderTarget.prototype );
WebGLRenderTargetCube.prototype.constructor = WebGLRenderTargetCube;
WebGLRenderTargetCube.prototype.isWebGLRenderTargetCube = true;
/**
* @author mikael emtinger / http://gomo.se/
* @author alteredq / http://alteredqualia.com/
* @author WestLangley / http://github.com/WestLangley
* @author bhouston / http://clara.io
*/
function Quaternion( x, y, z, w ) {
this._x = x || 0;
this._y = y || 0;
this._z = z || 0;
this._w = ( w !== undefined ) ? w : 1;
}
Object.assign( Quaternion, {
slerp: function ( qa, qb, qm, t ) {
return qm.copy( qa ).slerp( qb, t );
},
slerpFlat: function ( dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) {
// fuzz-free, array-based Quaternion SLERP operation
var x0 = src0[ srcOffset0 + 0 ],
y0 = src0[ srcOffset0 + 1 ],
z0 = src0[ srcOffset0 + 2 ],
w0 = src0[ srcOffset0 + 3 ],
x1 = src1[ srcOffset1 + 0 ],
y1 = src1[ srcOffset1 + 1 ],
z1 = src1[ srcOffset1 + 2 ],
w1 = src1[ srcOffset1 + 3 ];
if ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) {
var s = 1 - t,
cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,
dir = ( cos >= 0 ? 1 : - 1 ),
sqrSin = 1 - cos * cos;
// Skip the Slerp for tiny steps to avoid numeric problems:
if ( sqrSin > Number.EPSILON ) {
var sin = Math.sqrt( sqrSin ),
len = Math.atan2( sin, cos * dir );
s = Math.sin( s * len ) / sin;
t = Math.sin( t * len ) / sin;
}
var tDir = t * dir;
x0 = x0 * s + x1 * tDir;
y0 = y0 * s + y1 * tDir;
z0 = z0 * s + z1 * tDir;
w0 = w0 * s + w1 * tDir;
// Normalize in case we just did a lerp:
if ( s === 1 - t ) {
var f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 );
x0 *= f;
y0 *= f;
z0 *= f;
w0 *= f;
}
}
dst[ dstOffset ] = x0;
dst[ dstOffset + 1 ] = y0;
dst[ dstOffset + 2 ] = z0;
dst[ dstOffset + 3 ] = w0;
}
} );
Object.defineProperties( Quaternion.prototype, {
x: {
get: function () {
return this._x;
},
set: function ( value ) {
this._x = value;
this.onChangeCallback();
}
},
y: {
get: function () {
return this._y;
},
set: function ( value ) {
this._y = value;
this.onChangeCallback();
}
},
z: {
get: function () {
return this._z;
},
set: function ( value ) {
this._z = value;
this.onChangeCallback();
}
},
w: {
get: function () {
return this._w;
},
set: function ( value ) {
this._w = value;
this.onChangeCallback();
}
}
} );
Object.assign( Quaternion.prototype, {
set: function ( x, y, z, w ) {
this._x = x;
this._y = y;
this._z = z;
this._w = w;
this.onChangeCallback();
return this;
},
clone: function () {
return new this.constructor( this._x, this._y, this._z, this._w );
},
copy: function ( quaternion ) {
this._x = quaternion.x;
this._y = quaternion.y;
this._z = quaternion.z;
this._w = quaternion.w;
this.onChangeCallback();
return this;
},
setFromEuler: function ( euler, update ) {
if ( ! ( euler && euler.isEuler ) ) {
throw new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' );
}
var x = euler._x, y = euler._y, z = euler._z, order = euler.order;
// http://www.mathworks.com/matlabcentral/fileexchange/
// 20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/
// content/SpinCalc.m
var cos = Math.cos;
var sin = Math.sin;
var c1 = cos( x / 2 );
var c2 = cos( y / 2 );
var c3 = cos( z / 2 );
var s1 = sin( x / 2 );
var s2 = sin( y / 2 );
var s3 = sin( z / 2 );
if ( order === 'XYZ' ) {
this._x = s1 * c2 * c3 + c1 * s2 * s3;
this._y = c1 * s2 * c3 - s1 * c2 * s3;
this._z = c1 * c2 * s3 + s1 * s2 * c3;
this._w = c1 * c2 * c3 - s1 * s2 * s3;
} else if ( order === 'YXZ' ) {
this._x = s1 * c2 * c3 + c1 * s2 * s3;
this._y = c1 * s2 * c3 - s1 * c2 * s3;
this._z = c1 * c2 * s3 - s1 * s2 * c3;
this._w = c1 * c2 * c3 + s1 * s2 * s3;
} else if ( order === 'ZXY' ) {
this._x = s1 * c2 * c3 - c1 * s2 * s3;
this._y = c1 * s2 * c3 + s1 * c2 * s3;
this._z = c1 * c2 * s3 + s1 * s2 * c3;
this._w = c1 * c2 * c3 - s1 * s2 * s3;
} else if ( order === 'ZYX' ) {
this._x = s1 * c2 * c3 - c1 * s2 * s3;
this._y = c1 * s2 * c3 + s1 * c2 * s3;
this._z = c1 * c2 * s3 - s1 * s2 * c3;
this._w = c1 * c2 * c3 + s1 * s2 * s3;
} else if ( order === 'YZX' ) {
this._x = s1 * c2 * c3 + c1 * s2 * s3;
this._y = c1 * s2 * c3 + s1 * c2 * s3;
this._z = c1 * c2 * s3 - s1 * s2 * c3;
this._w = c1 * c2 * c3 - s1 * s2 * s3;
} else if ( order === 'XZY' ) {
this._x = s1 * c2 * c3 - c1 * s2 * s3;
this._y = c1 * s2 * c3 - s1 * c2 * s3;
this._z = c1 * c2 * s3 + s1 * s2 * c3;
this._w = c1 * c2 * c3 + s1 * s2 * s3;
}
if ( update !== false ) this.onChangeCallback();
return this;
},
setFromAxisAngle: function ( axis, angle ) {
// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm
// assumes axis is normalized
var halfAngle = angle / 2, s = Math.sin( halfAngle );
this._x = axis.x * s;
this._y = axis.y * s;
this._z = axis.z * s;
this._w = Math.cos( halfAngle );
this.onChangeCallback();
return this;
},
setFromRotationMatrix: function ( m ) {
// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
var te = m.elements,
m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],
m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],
m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ],
trace = m11 + m22 + m33,
s;
if ( trace > 0 ) {
s = 0.5 / Math.sqrt( trace + 1.0 );
this._w = 0.25 / s;
this._x = ( m32 - m23 ) * s;
this._y = ( m13 - m31 ) * s;
this._z = ( m21 - m12 ) * s;
} else if ( m11 > m22 && m11 > m33 ) {
s = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );
this._w = ( m32 - m23 ) / s;
this._x = 0.25 * s;
this._y = ( m12 + m21 ) / s;
this._z = ( m13 + m31 ) / s;
} else if ( m22 > m33 ) {
s = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );
this._w = ( m13 - m31 ) / s;
this._x = ( m12 + m21 ) / s;
this._y = 0.25 * s;
this._z = ( m23 + m32 ) / s;
} else {
s = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );
this._w = ( m21 - m12 ) / s;
this._x = ( m13 + m31 ) / s;
this._y = ( m23 + m32 ) / s;
this._z = 0.25 * s;
}
this.onChangeCallback();
return this;
},
setFromUnitVectors: function () {
// assumes direction vectors vFrom and vTo are normalized
var v1 = new Vector3();
var r;
var EPS = 0.000001;
return function setFromUnitVectors( vFrom, vTo ) {
if ( v1 === undefined ) v1 = new Vector3();
r = vFrom.dot( vTo ) + 1;
if ( r < EPS ) {
r = 0;
if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {
v1.set( - vFrom.y, vFrom.x, 0 );
} else {
v1.set( 0, - vFrom.z, vFrom.y );
}
} else {
v1.crossVectors( vFrom, vTo );
}
this._x = v1.x;
this._y = v1.y;
this._z = v1.z;
this._w = r;
return this.normalize();
};
}(),
inverse: function () {
return this.conjugate().normalize();
},
conjugate: function () {
this._x *= - 1;
this._y *= - 1;
this._z *= - 1;
this.onChangeCallback();
return this;
},
dot: function ( v ) {
return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;
},
lengthSq: function () {
return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;
},
length: function () {
return Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w );
},
normalize: function () {
var l = this.length();
if ( l === 0 ) {
this._x = 0;
this._y = 0;
this._z = 0;
this._w = 1;
} else {
l = 1 / l;
this._x = this._x * l;
this._y = this._y * l;
this._z = this._z * l;
this._w = this._w * l;
}
this.onChangeCallback();
return this;
},
multiply: function ( q, p ) {
if ( p !== undefined ) {
console.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' );
return this.multiplyQuaternions( q, p );
}
return this.multiplyQuaternions( this, q );
},
premultiply: function ( q ) {
return this.multiplyQuaternions( q, this );
},
multiplyQuaternions: function ( a, b ) {
// from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm
var qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;
var qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;
this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;
this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;
this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;
this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;
this.onChangeCallback();
return this;
},
slerp: function ( qb, t ) {
if ( t === 0 ) return this;
if ( t === 1 ) return this.copy( qb );
var x = this._x, y = this._y, z = this._z, w = this._w;
// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/
var cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;
if ( cosHalfTheta < 0 ) {
this._w = - qb._w;
this._x = - qb._x;
this._y = - qb._y;
this._z = - qb._z;
cosHalfTheta = - cosHalfTheta;
} else {
this.copy( qb );
}
if ( cosHalfTheta >= 1.0 ) {
this._w = w;
this._x = x;
this._y = y;
this._z = z;
return this;
}
var sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );
if ( Math.abs( sinHalfTheta ) < 0.001 ) {
this._w = 0.5 * ( w + this._w );
this._x = 0.5 * ( x + this._x );
this._y = 0.5 * ( y + this._y );
this._z = 0.5 * ( z + this._z );
return this;
}
var halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );
var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,
ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;
this._w = ( w * ratioA + this._w * ratioB );
this._x = ( x * ratioA + this._x * ratioB );
this._y = ( y * ratioA + this._y * ratioB );
this._z = ( z * ratioA + this._z * ratioB );
this.onChangeCallback();
return this;
},
equals: function ( quaternion ) {
return ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w );
},
fromArray: function ( array, offset ) {
if ( offset === undefined ) offset = 0;
this._x = array[ offset ];
this._y = array[ offset + 1 ];
this._z = array[ offset + 2 ];
this._w = array[ offset + 3 ];
this.onChangeCallback();
return this;
},
toArray: function ( array, offset ) {
if ( array === undefined ) array = [];
if ( offset === undefined ) offset = 0;
array[ offset ] = this._x;
array[ offset + 1 ] = this._y;
array[ offset + 2 ] = this._z;
array[ offset + 3 ] = this._w;
return array;
},
onChange: function ( callback ) {
this.onChangeCallback = callback;
return this;
},
onChangeCallback: function () {}
} );
/**
* @author mrdoob / http://mrdoob.com/
* @author kile / http://kile.stravaganza.org/
* @author philogb / http://blog.thejit.org/
* @author mikael emtinger / http://gomo.se/
* @author egraether / http://egraether.com/
* @author WestLangley / http://github.com/WestLangley
*/
function Vector3( x, y, z ) {
this.x = x || 0;
this.y = y || 0;
this.z = z || 0;
}
Object.assign( Vector3.prototype, {
isVector3: true,
set: function ( x, y, z ) {
this.x = x;
this.y = y;
this.z = z;
return this;
},
setScalar: function ( scalar ) {
this.x = scalar;
this.y = scalar;
this.z = scalar;
return this;
},
setX: function ( x ) {
this.x = x;
return this;
},
setY: function ( y ) {
this.y = y;
return this;
},
setZ: function ( z ) {
this.z = z;
return this;
},
setComponent: function ( index, value ) {
switch ( index ) {
case 0: this.x = value; break;
case 1: this.y = value; break;
case 2: this.z = value; break;
default: throw new Error( 'index is out of range: ' + index );
}
return this;
},
getComponent: function ( index ) {
switch ( index ) {
case 0: return this.x;
case 1: return this.y;
case 2: return this.z;
default: throw new Error( 'index is out of range: ' + index );
}
},
clone: function () {
return new this.constructor( this.x, this.y, this.z );
},
copy: function ( v ) {
this.x = v.x;
this.y = v.y;
this.z = v.z;
return this;
},
add: function ( v, w ) {
if ( w !== undefined ) {
console.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
return this.addVectors( v, w );
}
this.x += v.x;
this.y += v.y;
this.z += v.z;
return this;
},
addScalar: function ( s ) {
this.x += s;
this.y += s;
this.z += s;
return this;
},
addVectors: function ( a, b ) {
this.x = a.x + b.x;
this.y = a.y + b.y;
this.z = a.z + b.z;
return this;
},
addScaledVector: function ( v, s ) {
this.x += v.x * s;
this.y += v.y * s;
this.z += v.z * s;
return this;
},
sub: function ( v, w ) {
if ( w !== undefined ) {
console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
return this.subVectors( v, w );
}
this.x -= v.x;
this.y -= v.y;
this.z -= v.z;
return this;
},
subScalar: function ( s ) {
this.x -= s;
this.y -= s;
this.z -= s;
return this;
},
subVectors: function ( a, b ) {
this.x = a.x - b.x;
this.y = a.y - b.y;
this.z = a.z - b.z;
return this;
},
multiply: function ( v, w ) {
if ( w !== undefined ) {
console.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );
return this.multiplyVectors( v, w );
}
this.x *= v.x;
this.y *= v.y;
this.z *= v.z;
return this;
},
multiplyScalar: function ( scalar ) {
this.x *= scalar;
this.y *= scalar;
this.z *= scalar;
return this;
},
multiplyVectors: function ( a, b ) {
this.x = a.x * b.x;
this.y = a.y * b.y;
this.z = a.z * b.z;
return this;
},
applyEuler: function () {
var quaternion = new Quaternion();
return function applyEuler( euler ) {
if ( ! ( euler && euler.isEuler ) ) {
console.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' );
}
return this.applyQuaternion( quaternion.setFromEuler( euler ) );
};
}(),
applyAxisAngle: function () {
var quaternion = new Quaternion();
return function applyAxisAngle( axis, angle ) {
return this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) );
};
}(),
applyMatrix3: function ( m ) {
var x = this.x, y = this.y, z = this.z;
var e = m.elements;
this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;
this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;
this.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;
return this;
},
applyMatrix4: function ( m ) {
var x = this.x, y = this.y, z = this.z;
var e = m.elements;
var w = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] );
this.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * w;
this.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * w;
this.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * w;
return this;
},
applyQuaternion: function ( q ) {
var x = this.x, y = this.y, z = this.z;
var qx = q.x, qy = q.y, qz = q.z, qw = q.w;
// calculate quat * vector
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
this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;
this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;
this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;
return this;
},
project: function () {
var matrix = new Matrix4();
return function project( camera ) {
matrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) );
return this.applyMatrix4( matrix );
};
}(),
unproject: function () {
var matrix = new Matrix4();
return function unproject( camera ) {
matrix.multiplyMatrices( camera.matrixWorld, matrix.getInverse( camera.projectionMatrix ) );
return this.applyMatrix4( matrix );
};
}(),
transformDirection: function ( m ) {
// input: THREE.Matrix4 affine matrix
// vector interpreted as a direction
var x = this.x, y = this.y, z = this.z;
var e = m.elements;
this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;
this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;
this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;
return this.normalize();
},
divide: function ( v ) {
this.x /= v.x;
this.y /= v.y;
this.z /= v.z;
return this;
},
divideScalar: function ( scalar ) {
return this.multiplyScalar( 1 / scalar );
},
min: function ( v ) {
this.x = Math.min( this.x, v.x );
this.y = Math.min( this.y, v.y );
this.z = Math.min( this.z, v.z );
return this;
},
max: function ( v ) {
this.x = Math.max( this.x, v.x );
this.y = Math.max( this.y, v.y );
this.z = Math.max( this.z, v.z );
return this;
},
clamp: function ( min, max ) {
// assumes min < max, componentwise
this.x = Math.max( min.x, Math.min( max.x, this.x ) );
this.y = Math.max( min.y, Math.min( max.y, this.y ) );
this.z = Math.max( min.z, Math.min( max.z, this.z ) );
return this;
},
clampScalar: function () {
var min = new Vector3();
var max = new Vector3();
return function clampScalar( minVal, maxVal ) {
min.set( minVal, minVal, minVal );
max.set( maxVal, maxVal, maxVal );
return this.clamp( min, max );
};
}(),
clampLength: function ( min, max ) {
var length = this.length();
return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) );
},
floor: function () {
this.x = Math.floor( this.x );
this.y = Math.floor( this.y );
this.z = Math.floor( this.z );
return this;
},
ceil: function () {
this.x = Math.ceil( this.x );
this.y = Math.ceil( this.y );
this.z = Math.ceil( this.z );
return this;
},
round: function () {
this.x = Math.round( this.x );
this.y = Math.round( this.y );
this.z = Math.round( this.z );
return this;
},
roundToZero: function () {
this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );
this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );
this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );
return this;
},
negate: function () {
this.x = - this.x;
this.y = - this.y;
this.z = - this.z;
return this;
},
dot: function ( v ) {
return this.x * v.x + this.y * v.y + this.z * v.z;
},
// TODO lengthSquared?
lengthSq: function () {
return this.x * this.x + this.y * this.y + this.z * this.z;
},
length: function () {
return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );
},
lengthManhattan: function () {
return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );
},
normalize: function () {
return this.divideScalar( this.length() || 1 );
},
setLength: function ( length ) {
return this.normalize().multiplyScalar( length );
},
lerp: function ( v, alpha ) {
this.x += ( v.x - this.x ) * alpha;
this.y += ( v.y - this.y ) * alpha;
this.z += ( v.z - this.z ) * alpha;
return this;
},
lerpVectors: function ( v1, v2, alpha ) {
return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );
},
cross: function ( v, w ) {
if ( w !== undefined ) {
console.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );
return this.crossVectors( v, w );
}
var x = this.x, y = this.y, z = this.z;
this.x = y * v.z - z * v.y;
this.y = z * v.x - x * v.z;
this.z = x * v.y - y * v.x;
return this;
},
crossVectors: function ( a, b ) {
var ax = a.x, ay = a.y, az = a.z;
var bx = b.x, by = b.y, bz = b.z;
this.x = ay * bz - az * by;
this.y = az * bx - ax * bz;
this.z = ax * by - ay * bx;
return this;
},
projectOnVector: function ( vector ) {
var scalar = vector.dot( this ) / vector.lengthSq();
return this.copy( vector ).multiplyScalar( scalar );
},
projectOnPlane: function () {
var v1 = new Vector3();
return function projectOnPlane( planeNormal ) {
v1.copy( this ).projectOnVector( planeNormal );
return this.sub( v1 );
};
}(),
reflect: function () {
// reflect incident vector off plane orthogonal to normal
// normal is assumed to have unit length
var v1 = new Vector3();
return function reflect( normal ) {
return this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );
};
}(),
angleTo: function ( v ) {
var theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) );
// clamp, to handle numerical problems
return Math.acos( _Math.clamp( theta, - 1, 1 ) );
},
distanceTo: function ( v ) {
return Math.sqrt( this.distanceToSquared( v ) );
},
distanceToSquared: function ( v ) {
var dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;
return dx * dx + dy * dy + dz * dz;
},
distanceToManhattan: function ( v ) {
return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z );
},
setFromSpherical: function ( s ) {
var sinPhiRadius = Math.sin( s.phi ) * s.radius;
this.x = sinPhiRadius * Math.sin( s.theta );
this.y = Math.cos( s.phi ) * s.radius;
this.z = sinPhiRadius * Math.cos( s.theta );
return this;
},
setFromCylindrical: function ( c ) {
this.x = c.radius * Math.sin( c.theta );
this.y = c.y;
this.z = c.radius * Math.cos( c.theta );
return this;
},
setFromMatrixPosition: function ( m ) {
var e = m.elements;
this.x = e[ 12 ];
this.y = e[ 13 ];
this.z = e[ 14 ];
return this;
},
setFromMatrixScale: function ( m ) {
var sx = this.setFromMatrixColumn( m, 0 ).length();
var sy = this.setFromMatrixColumn( m, 1 ).length();
var sz = this.setFromMatrixColumn( m, 2 ).length();
this.x = sx;
this.y = sy;
this.z = sz;
return this;
},
setFromMatrixColumn: function ( m, index ) {
return this.fromArray( m.elements, index * 4 );
},
equals: function ( v ) {
return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );
},
fromArray: function ( array, offset ) {
if ( offset === undefined ) offset = 0;
this.x = array[ offset ];
this.y = array[ offset + 1 ];
this.z = array[ offset + 2 ];
return this;
},
toArray: function ( array, offset ) {
if ( array === undefined ) array = [];
if ( offset === undefined ) offset = 0;
array[ offset ] = this.x;
array[ offset + 1 ] = this.y;
array[ offset + 2 ] = this.z;
return array;
},
fromBufferAttribute: function ( attribute, index, offset ) {
if ( offset !== undefined ) {
console.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' );
}
this.x = attribute.getX( index );
this.y = attribute.getY( index );
this.z = attribute.getZ( index );
return this;
}
} );
/**
* @author mrdoob / http://mrdoob.com/
* @author supereggbert / http://www.paulbrunt.co.uk/
* @author philogb / http://blog.thejit.org/
* @author jordi_ros / http://plattsoft.com
* @author D1plo1d / http://github.com/D1plo1d
* @author alteredq / http://alteredqualia.com/
* @author mikael emtinger / http://gomo.se/
* @author timknip / http://www.floorplanner.com/
* @author bhouston / http://clara.io
* @author WestLangley / http://github.com/WestLangley
*/
function Matrix4() {
this.elements = [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
];
if ( arguments.length > 0 ) {
console.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );
}
}
Object.assign( Matrix4.prototype, {
isMatrix4: true,
set: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
var te = this.elements;
te[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;
te[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;
te[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;
te[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;
return this;
},
identity: function () {
this.set(
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
);
return this;
},
clone: function () {
return new Matrix4().fromArray( this.elements );
},
copy: function ( m ) {
var te = this.elements;
var me = m.elements;
te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; te[ 3 ] = me[ 3 ];
te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ];
te[ 8 ] = me[ 8 ]; te[ 9 ] = me[ 9 ]; te[ 10 ] = me[ 10 ]; te[ 11 ] = me[ 11 ];
te[ 12 ] = me[ 12 ]; te[ 13 ] = me[ 13 ]; te[ 14 ] = me[ 14 ]; te[ 15 ] = me[ 15 ];
return this;
},
copyPosition: function ( m ) {
var te = this.elements, me = m.elements;
te[ 12 ] = me[ 12 ];
te[ 13 ] = me[ 13 ];
te[ 14 ] = me[ 14 ];
return this;
},
extractBasis: function ( xAxis, yAxis, zAxis ) {
xAxis.setFromMatrixColumn( this, 0 );
yAxis.setFromMatrixColumn( this, 1 );
zAxis.setFromMatrixColumn( this, 2 );
return this;
},
makeBasis: function ( xAxis, yAxis, zAxis ) {
this.set(
xAxis.x, yAxis.x, zAxis.x, 0,
xAxis.y, yAxis.y, zAxis.y, 0,
xAxis.z, yAxis.z, zAxis.z, 0,
0, 0, 0, 1
);
return this;
},
extractRotation: function () {
var v1 = new Vector3();
return function extractRotation( m ) {
var te = this.elements;
var me = m.elements;
var scaleX = 1 / v1.setFromMatrixColumn( m, 0 ).length();
var scaleY = 1 / v1.setFromMatrixColumn( m, 1 ).length();
var scaleZ = 1 / v1.setFromMatrixColumn( m, 2 ).length();
te[ 0 ] = me[ 0 ] * scaleX;
te[ 1 ] = me[ 1 ] * scaleX;
te[ 2 ] = me[ 2 ] * scaleX;
te[ 4 ] = me[ 4 ] * scaleY;
te[ 5 ] = me[ 5 ] * scaleY;
te[ 6 ] = me[ 6 ] * scaleY;
te[ 8 ] = me[ 8 ] * scaleZ;
te[ 9 ] = me[ 9 ] * scaleZ;
te[ 10 ] = me[ 10 ] * scaleZ;
return this;
};
}(),
makeRotationFromEuler: function ( euler ) {
if ( ! ( euler && euler.isEuler ) ) {
console.error( 'THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );
}
var te = this.elements;
var x = euler.x, y = euler.y, z = euler.z;
var a = Math.cos( x ), b = Math.sin( x );
var c = Math.cos( y ), d = Math.sin( y );
var e = Math.cos( z ), f = Math.sin( z );
if ( euler.order === 'XYZ' ) {
var ae = a * e, af = a * f, be = b * e, bf = b * f;
te[ 0 ] = c * e;
te[ 4 ] = - c * f;
te[ 8 ] = d;
te[ 1 ] = af + be * d;
te[ 5 ] = ae - bf * d;
te[ 9 ] = - b * c;
te[ 2 ] = bf - ae * d;
te[ 6 ] = be + af * d;
te[ 10 ] = a * c;
} else if ( euler.order === 'YXZ' ) {
var ce = c * e, cf = c * f, de = d * e, df = d * f;
te[ 0 ] = ce + df * b;
te[ 4 ] = de * b - cf;
te[ 8 ] = a * d;
te[ 1 ] = a * f;
te[ 5 ] = a * e;
te[ 9 ] = - b;
te[ 2 ] = cf * b - de;
te[ 6 ] = df + ce * b;
te[ 10 ] = a * c;
} else if ( euler.order === 'ZXY' ) {
var ce = c * e, cf = c * f, de = d * e, df = d * f;
te[ 0 ] = ce - df * b;
te[ 4 ] = - a * f;
te[ 8 ] = de + cf * b;
te[ 1 ] = cf + de * b;
te[ 5 ] = a * e;
te[ 9 ] = df - ce * b;
te[ 2 ] = - a * d;
te[ 6 ] = b;
te[ 10 ] = a * c;
} else if ( euler.order === 'ZYX' ) {
var ae = a * e, af = a * f, be = b * e, bf = b * f;
te[ 0 ] = c * e;
te[ 4 ] = be * d - af;
te[ 8 ] = ae * d + bf;
te[ 1 ] = c * f;
te[ 5 ] = bf * d + ae;
te[ 9 ] = af * d - be;
te[ 2 ] = - d;
te[ 6 ] = b * c;
te[ 10 ] = a * c;
} else if ( euler.order === 'YZX' ) {
var ac = a * c, ad = a * d, bc = b * c, bd = b * d;
te[ 0 ] = c * e;
te[ 4 ] = bd - ac * f;
te[ 8 ] = bc * f + ad;
te[ 1 ] = f;
te[ 5 ] = a * e;
te[ 9 ] = - b * e;
te[ 2 ] = - d * e;
te[ 6 ] = ad * f + bc;
te[ 10 ] = ac - bd * f;
} else if ( euler.order === 'XZY' ) {
var ac = a * c, ad = a * d, bc = b * c, bd = b * d;
te[ 0 ] = c * e;
te[ 4 ] = - f;
te[ 8 ] = d * e;
te[ 1 ] = ac * f + bd;
te[ 5 ] = a * e;
te[ 9 ] = ad * f - bc;
te[ 2 ] = bc * f - ad;
te[ 6 ] = b * e;
te[ 10 ] = bd * f + ac;
}
// last column
te[ 3 ] = 0;
te[ 7 ] = 0;
te[ 11 ] = 0;
// bottom row
te[ 12 ] = 0;
te[ 13 ] = 0;
te[ 14 ] = 0;
te[ 15 ] = 1;
return this;
},
makeRotationFromQuaternion: function ( q ) {
var te = this.elements;
var x = q._x, y = q._y, z = q._z, w = q._w;
var x2 = x + x, y2 = y + y, z2 = z + z;
var xx = x * x2, xy = x * y2, xz = x * z2;
var yy = y * y2, yz = y * z2, zz = z * z2;
var wx = w * x2, wy = w * y2, wz = w * z2;
te[ 0 ] = 1 - ( yy + zz );
te[ 4 ] = xy - wz;
te[ 8 ] = xz + wy;
te[ 1 ] = xy + wz;
te[ 5 ] = 1 - ( xx + zz );
te[ 9 ] = yz - wx;
te[ 2 ] = xz - wy;
te[ 6 ] = yz + wx;
te[ 10 ] = 1 - ( xx + yy );
// last column
te[ 3 ] = 0;
te[ 7 ] = 0;
te[ 11 ] = 0;
// bottom row
te[ 12 ] = 0;
te[ 13 ] = 0;
te[ 14 ] = 0;
te[ 15 ] = 1;
return this;
},
lookAt: function () {
var x = new Vector3();
var y = new Vector3();
var z = new Vector3();
return function lookAt( eye, target, up ) {
var te = this.elements;
z.subVectors( eye, target );
if ( z.lengthSq() === 0 ) {
// eye and target are in the same position
z.z = 1;
}
z.normalize();
x.crossVectors( up, z );
if ( x.lengthSq() === 0 ) {
// up and z are parallel
if ( Math.abs( up.z ) === 1 ) {
z.x += 0.0001;
} else {
z.z += 0.0001;
}
z.normalize();
x.crossVectors( up, z );
}
x.normalize();
y.crossVectors( z, x );
te[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x;
te[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y;
te[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z;
return this;
};
}(),
multiply: function ( m, n ) {
if ( n !== undefined ) {
console.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );
return this.multiplyMatrices( m, n );
}
return this.multiplyMatrices( this, m );
},
premultiply: function ( m ) {
return this.multiplyMatrices( m, this );
},
multiplyMatrices: function ( a, b ) {
var ae = a.elements;
var be = b.elements;
var te = this.elements;
var a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ];
var a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ];
var a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ];
var a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ];
var b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ];
var b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ];
var b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ];
var b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ];
te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
te[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
te[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
te[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
te[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
te[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
te[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
te[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
te[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
te[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
te[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
te[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
te[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
te[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
return this;
},
multiplyScalar: function ( s ) {
var te = this.elements;
te[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s;
te[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s;
te[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s;
te[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s;
return this;
},
applyToBufferAttribute: function () {
var v1 = new Vector3();
return function applyToBufferAttribute( attribute ) {
for ( var i = 0, l = attribute.count; i < l; i ++ ) {
v1.x = attribute.getX( i );
v1.y = attribute.getY( i );
v1.z = attribute.getZ( i );
v1.applyMatrix4( this );
attribute.setXYZ( i, v1.x, v1.y, v1.z );
}
return attribute;
};
}(),
determinant: function () {
var te = this.elements;
var n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ];
var n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ];
var n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ];
var n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ];
//TODO: make this more efficient
//( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )
return (
n41 * (
+ n14 * n23 * n32
- n13 * n24 * n32
- n14 * n22 * n33
+ n12 * n24 * n33
+ n13 * n22 * n34
- n12 * n23 * n34
) +
n42 * (
+ n11 * n23 * n34
- n11 * n24 * n33
+ n14 * n21 * n33
- n13 * n21 * n34
+ n13 * n24 * n31
- n14 * n23 * n31
) +
n43 * (
+ n11 * n24 * n32
- n11 * n22 * n34
- n14 * n21 * n32
+ n12 * n21 * n34
+ n14 * n22 * n31
- n12 * n24 * n31
) +
n44 * (
- n13 * n22 * n31
- n11 * n23 * n32
+ n11 * n22 * n33
+ n13 * n21 * n32
- n12 * n21 * n33
+ n12 * n23 * n31
)
);
},
transpose: function () {
var te = this.elements;
var tmp;
tmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp;
tmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp;
tmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp;
tmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp;
tmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp;
tmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp;
return this;
},
setPosition: function ( v ) {
var te = this.elements;
te[ 12 ] = v.x;
te[ 13 ] = v.y;
te[ 14 ] = v.z;
return this;
},
getInverse: function ( m, throwOnDegenerate ) {
// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
var te = this.elements,
me = m.elements,
n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ],
n12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ],
n13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ],
n14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ],
t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,
t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,
t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,
t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;
var det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;
if ( det === 0 ) {
var msg = "THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0";
if ( throwOnDegenerate === true ) {
throw new Error( msg );
} else {
console.warn( msg );
}
return this.identity();
}
var detInv = 1 / det;
te[ 0 ] = t11 * detInv;
te[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv;
te[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv;
te[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv;
te[ 4 ] = t12 * detInv;
te[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv;
te[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv;
te[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv;
te[ 8 ] = t13 * detInv;
te[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv;
te[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv;
te[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv;
te[ 12 ] = t14 * detInv;
te[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv;
te[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv;
te[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv;
return this;
},
scale: function ( v ) {
var te = this.elements;
var x = v.x, y = v.y, z = v.z;
te[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z;
te[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z;
te[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z;
te[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z;
return this;
},
getMaxScaleOnAxis: function () {
var te = this.elements;
var scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ];
var scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ];
var scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ];
return Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) );
},
makeTranslation: function ( x, y, z ) {
this.set(
1, 0, 0, x,
0, 1, 0, y,
0, 0, 1, z,
0, 0, 0, 1
);
return this;
},
makeRotationX: function ( theta ) {
var c = Math.cos( theta ), s = Math.sin( theta );
this.set(
1, 0, 0, 0,
0, c, - s, 0,
0, s, c, 0,
0, 0, 0, 1
);
return this;
},
makeRotationY: function ( theta ) {
var c = Math.cos( theta ), s = Math.sin( theta );
this.set(
c, 0, s, 0,
0, 1, 0, 0,
- s, 0, c, 0,
0, 0, 0, 1
);
return this;
},
makeRotationZ: function ( theta ) {
var c = Math.cos( theta ), s = Math.sin( theta );
this.set(
c, - s, 0, 0,
s, c, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
);
return this;
},
makeRotationAxis: function ( axis, angle ) {
// Based on http://www.gamedev.net/reference/articles/article1199.asp
var c = Math.cos( angle );
var s = Math.sin( angle );
var t = 1 - c;
var x = axis.x, y = axis.y, z = axis.z;
var tx = t * x, ty = t * y;
this.set(
tx * x + c, tx * y - s * z, tx * z + s * y, 0,
tx * y + s * z, ty * y + c, ty * z - s * x, 0,
tx * z - s * y, ty * z + s * x, t * z * z + c, 0,
0, 0, 0, 1
);
return this;
},
makeScale: function ( x, y, z ) {
this.set(
x, 0, 0, 0,
0, y, 0, 0,
0, 0, z, 0,
0, 0, 0, 1
);
return this;
},
makeShear: function ( x, y, z ) {
this.set(
1, y, z, 0,
x, 1, z, 0,
x, y, 1, 0,
0, 0, 0, 1
);
return this;
},
compose: function ( position, quaternion, scale ) {
this.makeRotationFromQuaternion( quaternion );
this.scale( scale );
this.setPosition( position );
return this;
},
decompose: function () {
var vector = new Vector3();
var matrix = new Matrix4();
return function decompose( position, quaternion, scale ) {
var te = this.elements;
var sx = vector.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length();
var sy = vector.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length();
var sz = vector.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length();
// if determine is negative, we need to invert one scale
var det = this.determinant();
if ( det < 0 ) sx = - sx;
position.x = te[ 12 ];
position.y = te[ 13 ];
position.z = te[ 14 ];
// scale the rotation part
matrix.copy( this );
var invSX = 1 / sx;
var invSY = 1 / sy;
var invSZ = 1 / sz;
matrix.elements[ 0 ] *= invSX;
matrix.elements[ 1 ] *= invSX;
matrix.elements[ 2 ] *= invSX;
matrix.elements[ 4 ] *= invSY;
matrix.elements[ 5 ] *= invSY;
matrix.elements[ 6 ] *= invSY;
matrix.elements[ 8 ] *= invSZ;
matrix.elements[ 9 ] *= invSZ;
matrix.elements[ 10 ] *= invSZ;
quaternion.setFromRotationMatrix( matrix );
scale.x = sx;
scale.y = sy;
scale.z = sz;
return this;
};
}(),
makePerspective: function ( left, right, top, bottom, near, far ) {
if ( far === undefined ) {
console.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.' );
}
var te = this.elements;
var x = 2 * near / ( right - left );
var y = 2 * near / ( top - bottom );
var a = ( right + left ) / ( right - left );
var b = ( top + bottom ) / ( top - bottom );
var c = - ( far + near ) / ( far - near );
var d = - 2 * far * near / ( far - near );
te[ 0 ] = x; te[ 4 ] = 0; te[ 8 ] = a; te[ 12 ] = 0;
te[ 1 ] = 0; te[ 5 ] = y; te[ 9 ] = b; te[ 13 ] = 0;
te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = c; te[ 14 ] = d;
te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = - 1; te[ 15 ] = 0;
return this;
},
makeOrthographic: function ( left, right, top, bottom, near, far ) {
var te = this.elements;
var w = 1.0 / ( right - left );
var h = 1.0 / ( top - bottom );
var p = 1.0 / ( far - near );
var x = ( right + left ) * w;
var y = ( top + bottom ) * h;
var z = ( far + near ) * p;
te[ 0 ] = 2 * w; te[ 4 ] = 0; te[ 8 ] = 0; te[ 12 ] = - x;
te[ 1 ] = 0; te[ 5 ] = 2 * h; te[ 9 ] = 0; te[ 13 ] = - y;
te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = - 2 * p; te[ 14 ] = - z;
te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = 0; te[ 15 ] = 1;
return this;
},
equals: function ( matrix ) {
var te = this.elements;
var me = matrix.elements;
for ( var i = 0; i < 16; i ++ ) {
if ( te[ i ] !== me[ i ] ) return false;
}
return true;
},
fromArray: function ( array, offset ) {
if ( offset === undefined ) offset = 0;
for ( var i = 0; i < 16; i ++ ) {
this.elements[ i ] = array[ i + offset ];
}
return this;
},
toArray: function ( array, offset ) {
if ( array === undefined ) array = [];
if ( offset === undefined ) offset = 0;
var te = this.elements;
array[ offset ] = te[ 0 ];
array[ offset + 1 ] = te[ 1 ];
array[ offset + 2 ] = te[ 2 ];
array[ offset + 3 ] = te[ 3 ];
array[ offset + 4 ] = te[ 4 ];
array[ offset + 5 ] = te[ 5 ];
array[ offset + 6 ] = te[ 6 ];
array[ offset + 7 ] = te[ 7 ];
array[ offset + 8 ] = te[ 8 ];
array[ offset + 9 ] = te[ 9 ];
array[ offset + 10 ] = te[ 10 ];
array[ offset + 11 ] = te[ 11 ];
array[ offset + 12 ] = te[ 12 ];
array[ offset + 13 ] = te[ 13 ];
array[ offset + 14 ] = te[ 14 ];
array[ offset + 15 ] = te[ 15 ];
return array;
}
} );
/**
* @author alteredq / http://alteredqualia.com/
*/
function DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {
Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );
this.image = { data: data, width: width, height: height };
this.magFilter = magFilter !== undefined ? magFilter : NearestFilter;
this.minFilter = minFilter !== undefined ? minFilter : NearestFilter;
this.generateMipmaps = false;
this.flipY = false;
this.unpackAlignment = 1;
}
DataTexture.prototype = Object.create( Texture.prototype );
DataTexture.prototype.constructor = DataTexture;
DataTexture.prototype.isDataTexture = true;
/**
* @author mrdoob / http://mrdoob.com/
*/
function CubeTexture( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {
images = images !== undefined ? images : [];
mapping = mapping !== undefined ? mapping : CubeReflectionMapping;
Texture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );
this.flipY = false;
}
CubeTexture.prototype = Object.create( Texture.prototype );
CubeTexture.prototype.constructor = CubeTexture;
CubeTexture.prototype.isCubeTexture = true;
Object.defineProperty( CubeTexture.prototype, 'images', {
get: function () {
return this.image;
},
set: function ( value ) {
this.image = value;
}
} );
/**
* @author tschw
*
* Uniforms of a program.
* Those form a tree structure with a special top-level container for the root,
* which you get by calling 'new WebGLUniforms( gl, program, renderer )'.
*
*
* Properties of inner nodes including the top-level container:
*
* .seq - array of nested uniforms
* .map - nested uniforms by name
*
*
* Methods of all nodes except the top-level container:
*
* .setValue( gl, value, [renderer] )
*
* uploads a uniform value(s)
* the 'renderer' parameter is needed for sampler uniforms
*
*
* Static methods of the top-level container (renderer factorizations):
*
* .upload( gl, seq, values, renderer )
*
* sets uniforms in 'seq' to 'values[id].value'
*
* .seqWithValue( seq, values ) : filteredSeq
*
* filters 'seq' entries with corresponding entry in values
*
*
* Methods of the top-level container (renderer factorizations):
*
* .setValue( gl, name, value )
*
* sets uniform with name 'name' to 'value'
*
* .set( gl, obj, prop )
*
* sets uniform from object and property with same name than uniform
*
* .setOptional( gl, obj, prop )
*
* like .set for an optional property of the object
*
*/
var emptyTexture = new Texture();
var emptyCubeTexture = new CubeTexture();
// --- Base for inner nodes (including the root) ---
function UniformContainer() {
this.seq = [];
this.map = {};
}
// --- Utilities ---
// Array Caches (provide typed arrays for temporary by size)
var arrayCacheF32 = [];
var arrayCacheI32 = [];
// Float32Array caches used for uploading Matrix uniforms
var mat4array = new Float32Array( 16 );
var mat3array = new Float32Array( 9 );
// Flattening for arrays of vectors and matrices
function flatten( array, nBlocks, blockSize ) {
var firstElem = array[ 0 ];
if ( firstElem <= 0 || firstElem > 0 ) return array;
// unoptimized: ! isNaN( firstElem )
// see http://jacksondunstan.com/articles/983
var n = nBlocks * blockSize,
r = arrayCacheF32[ n ];
if ( r === undefined ) {
r = new Float32Array( n );
arrayCacheF32[ n ] = r;
}
if ( nBlocks !== 0 ) {
firstElem.toArray( r, 0 );
for ( var i = 1, offset = 0; i !== nBlocks; ++ i ) {
offset += blockSize;
array[ i ].toArray( r, offset );
}
}
return r;
}
// Texture unit allocation
function allocTexUnits( renderer, n ) {
var r = arrayCacheI32[ n ];
if ( r === undefined ) {
r = new Int32Array( n );
arrayCacheI32[ n ] = r;
}
for ( var i = 0; i !== n; ++ i )
r[ i ] = renderer.allocTextureUnit();
return r;
}
// --- Setters ---
// Note: Defining these methods externally, because they come in a bunch
// and this way their names minify.
// Single scalar
function setValue1f( gl, v ) { gl.uniform1f( this.addr, v ); }
function setValue1i( gl, v ) { gl.uniform1i( this.addr, v ); }
// Single float vector (from flat array or THREE.VectorN)
function setValue2fv( gl, v ) {
if ( v.x === undefined ) gl.uniform2fv( this.addr, v );
else gl.uniform2f( this.addr, v.x, v.y );
}
function setValue3fv( gl, v ) {
if ( v.x !== undefined )
gl.uniform3f( this.addr, v.x, v.y, v.z );
else if ( v.r !== undefined )
gl.uniform3f( this.addr, v.r, v.g, v.b );
else
gl.uniform3fv( this.addr, v );
}
function setValue4fv( gl, v ) {
if ( v.x === undefined ) gl.uniform4fv( this.addr, v );
else gl.uniform4f( this.addr, v.x, v.y, v.z, v.w );
}
// Single matrix (from flat array or MatrixN)
function setValue2fm( gl, v ) {
gl.uniformMatrix2fv( this.addr, false, v.elements || v );
}
function setValue3fm( gl, v ) {
if ( v.elements === undefined ) {
gl.uniformMatrix3fv( this.addr, false, v );
} else {
mat3array.set( v.elements );
gl.uniformMatrix3fv( this.addr, false, mat3array );
}
}
function setValue4fm( gl, v ) {
if ( v.elements === undefined ) {
gl.uniformMatrix4fv( this.addr, false, v );
} else {
mat4array.set( v.elements );
gl.uniformMatrix4fv( this.addr, false, mat4array );
}
}
// Single texture (2D / Cube)
function setValueT1( gl, v, renderer ) {
var unit = renderer.allocTextureUnit();
gl.uniform1i( this.addr, unit );
renderer.setTexture2D( v || emptyTexture, unit );
}
function setValueT6( gl, v, renderer ) {
var unit = renderer.allocTextureUnit();
gl.uniform1i( this.addr, unit );
renderer.setTextureCube( v || emptyCubeTexture, unit );
}
// Integer / Boolean vectors or arrays thereof (always flat arrays)
function setValue2iv( gl, v ) { gl.uniform2iv( this.addr, v ); }
function setValue3iv( gl, v ) { gl.uniform3iv( this.addr, v ); }
function setValue4iv( gl, v ) { gl.uniform4iv( this.addr, v ); }
// Helper to pick the right setter for the singular case
function getSingularSetter( type ) {
switch ( type ) {
case 0x1406: return setValue1f; // FLOAT
case 0x8b50: return setValue2fv; // _VEC2
case 0x8b51: return setValue3fv; // _VEC3
case 0x8b52: return setValue4fv; // _VEC4
case 0x8b5a: return setValue2fm; // _MAT2
case 0x8b5b: return setValue3fm; // _MAT3
case 0x8b5c: return setValue4fm; // _MAT4
case 0x8b5e: case 0x8d66: return setValueT1; // SAMPLER_2D, SAMPLER_EXTERNAL_OES
case 0x8b60: return setValueT6; // SAMPLER_CUBE
case 0x1404: case 0x8b56: return setValue1i; // INT, BOOL
case 0x8b53: case 0x8b57: return setValue2iv; // _VEC2
case 0x8b54: case 0x8b58: return setValue3iv; // _VEC3
case 0x8b55: case 0x8b59: return setValue4iv; // _VEC4
}
}
// Array of scalars
function setValue1fv( gl, v ) { gl.uniform1fv( this.addr, v ); }
function setValue1iv( gl, v ) { gl.uniform1iv( this.addr, v ); }
// Array of vectors (flat or from THREE classes)
function setValueV2a( gl, v ) {
gl.uniform2fv( this.addr, flatten( v, this.size, 2 ) );
}
function setValueV3a( gl, v ) {
gl.uniform3fv( this.addr, flatten( v, this.size, 3 ) );
}
function setValueV4a( gl, v ) {
gl.uniform4fv( this.addr, flatten( v, this.size, 4 ) );
}
// Array of matrices (flat or from THREE clases)
function setValueM2a( gl, v ) {
gl.uniformMatrix2fv( this.addr, false, flatten( v, this.size, 4 ) );
}
function setValueM3a( gl, v ) {
gl.uniformMatrix3fv( this.addr, false, flatten( v, this.size, 9 ) );
}
function setValueM4a( gl, v ) {
gl.uniformMatrix4fv( this.addr, false, flatten( v, this.size, 16 ) );
}
// Array of textures (2D / Cube)
function setValueT1a( gl, v, renderer ) {
var n = v.length,
units = allocTexUnits( renderer, n );
gl.uniform1iv( this.addr, units );
for ( var i = 0; i !== n; ++ i ) {
renderer.setTexture2D( v[ i ] || emptyTexture, units[ i ] );
}
}
function setValueT6a( gl, v, renderer ) {
var n = v.length,
units = allocTexUnits( renderer, n );
gl.uniform1iv( this.addr, units );
for ( var i = 0; i !== n; ++ i ) {
renderer.setTextureCube( v[ i ] || emptyCubeTexture, units[ i ] );
}
}
// Helper to pick the right setter for a pure (bottom-level) array
function getPureArraySetter( type ) {
switch ( type ) {
case 0x1406: return setValue1fv; // FLOAT
case 0x8b50: return setValueV2a; // _VEC2
case 0x8b51: return setValueV3a; // _VEC3
case 0x8b52: return setValueV4a; // _VEC4
case 0x8b5a: return setValueM2a; // _MAT2
case 0x8b5b: return setValueM3a; // _MAT3
case 0x8b5c: return setValueM4a; // _MAT4
case 0x8b5e: return setValueT1a; // SAMPLER_2D
case 0x8b60: return setValueT6a; // SAMPLER_CUBE
case 0x1404: case 0x8b56: return setValue1iv; // INT, BOOL
case 0x8b53: case 0x8b57: return setValue2iv; // _VEC2
case 0x8b54: case 0x8b58: return setValue3iv; // _VEC3
case 0x8b55: case 0x8b59: return setValue4iv; // _VEC4
}
}
// --- Uniform Classes ---
function SingleUniform( id, activeInfo, addr ) {
this.id = id;
this.addr = addr;
this.setValue = getSingularSetter( activeInfo.type );
// this.path = activeInfo.name; // DEBUG
}
function PureArrayUniform( id, activeInfo, addr ) {
this.id = id;
this.addr = addr;
this.size = activeInfo.size;
this.setValue = getPureArraySetter( activeInfo.type );
// this.path = activeInfo.name; // DEBUG
}
function StructuredUniform( id ) {
this.id = id;
UniformContainer.call( this ); // mix-in
}
StructuredUniform.prototype.setValue = function ( gl, value ) {
// Note: Don't need an extra 'renderer' parameter, since samplers
// are not allowed in structured uniforms.
var seq = this.seq;
for ( var i = 0, n = seq.length; i !== n; ++ i ) {
var u = seq[ i ];
u.setValue( gl, value[ u.id ] );
}
};
// --- Top-level ---
// Parser - builds up the property tree from the path strings
var RePathPart = /([\w\d_]+)(\])?(\[|\.)?/g;
// extracts
// - the identifier (member name or array index)
// - followed by an optional right bracket (found when array index)
// - followed by an optional left bracket or dot (type of subscript)
//
// Note: These portions can be read in a non-overlapping fashion and
// allow straightforward parsing of the hierarchy that WebGL encodes
// in the uniform names.
function addUniform( container, uniformObject ) {
container.seq.push( uniformObject );
container.map[ uniformObject.id ] = uniformObject;
}
function parseUniform( activeInfo, addr, container ) {
var path = activeInfo.name,
pathLength = path.length;
// reset RegExp object, because of the early exit of a previous run
RePathPart.lastIndex = 0;
for ( ; ; ) {
var match = RePathPart.exec( path ),
matchEnd = RePathPart.lastIndex,
id = match[ 1 ],
idIsIndex = match[ 2 ] === ']',
subscript = match[ 3 ];
if ( idIsIndex ) id = id | 0; // convert to integer
if ( subscript === undefined || subscript === '[' && matchEnd + 2 === pathLength ) {
// bare name or "pure" bottom-level array "[0]" suffix
addUniform( container, subscript === undefined ?
new SingleUniform( id, activeInfo, addr ) :
new PureArrayUniform( id, activeInfo, addr ) );
break;
} else {
// step into inner node / create it in case it doesn't exist
var map = container.map, next = map[ id ];
if ( next === undefined ) {
next = new StructuredUniform( id );
addUniform( container, next );
}
container = next;
}
}
}
// Root Container
function WebGLUniforms( gl, program, renderer ) {
UniformContainer.call( this );
this.renderer = renderer;
var n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS );
for ( var i = 0; i < n; ++ i ) {
var info = gl.getActiveUniform( program, i ),
path = info.name,
addr = gl.getUniformLocation( program, path );
parseUniform( info, addr, this );
}
}
WebGLUniforms.prototype.setValue = function ( gl, name, value ) {
var u = this.map[ name ];
if ( u !== undefined ) u.setValue( gl, value, this.renderer );
};
WebGLUniforms.prototype.setOptional = function ( gl, object, name ) {
var v = object[ name ];
if ( v !== undefined ) this.setValue( gl, name, v );
};
// Static interface
WebGLUniforms.upload = function ( gl, seq, values, renderer ) {
for ( var i = 0, n = seq.length; i !== n; ++ i ) {
var u = seq[ i ],
v = values[ u.id ];
if ( v.needsUpdate !== false ) {
// note: always updating when .needsUpdate is undefined
u.setValue( gl, v.value, renderer );
}
}
};
WebGLUniforms.seqWithValue = function ( seq, values ) {
var r = [];
for ( var i = 0, n = seq.length; i !== n; ++ i ) {
var u = seq[ i ];
if ( u.id in values ) r.push( u );
}
return r;
};
/**
* @author mrdoob / http://mrdoob.com/
*/
var ColorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,
'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,
'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,
'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,
'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,
'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,
'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,
'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,
'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,
'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,
'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,
'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,
'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,
'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,
'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,
'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,
'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,
'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,
'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,
'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,
'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,
'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,
'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,
'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };
function Color( r, g, b ) {
if ( g === undefined && b === undefined ) {
// r is THREE.Color, hex or string
return this.set( r );
}
return this.setRGB( r, g, b );
}
Object.assign( Color.prototype, {
isColor: true,
r: 1, g: 1, b: 1,
set: function ( value ) {
if ( value && value.isColor ) {
this.copy( value );
} else if ( typeof value === 'number' ) {
this.setHex( value );
} else if ( typeof value === 'string' ) {
this.setStyle( value );
}
return this;
},
setScalar: function ( scalar ) {
this.r = scalar;
this.g = scalar;
this.b = scalar;
return this;
},
setHex: function ( hex ) {
hex = Math.floor( hex );
this.r = ( hex >> 16 & 255 ) / 255;
this.g = ( hex >> 8 & 255 ) / 255;
this.b = ( hex & 255 ) / 255;
return this;
},
setRGB: function ( r, g, b ) {
this.r = r;
this.g = g;
this.b = b;
return this;
},
setHSL: function () {
function hue2rgb( p, q, t ) {
if ( t < 0 ) t += 1;
if ( t > 1 ) t -= 1;
if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;
if ( t < 1 / 2 ) return q;
if ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t );
return p;
}
return function setHSL( h, s, l ) {
// h,s,l ranges are in 0.0 - 1.0
h = _Math.euclideanModulo( h, 1 );
s = _Math.clamp( s, 0, 1 );
l = _Math.clamp( l, 0, 1 );
if ( s === 0 ) {
this.r = this.g = this.b = l;
} else {
var p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );
var q = ( 2 * l ) - p;
this.r = hue2rgb( q, p, h + 1 / 3 );
this.g = hue2rgb( q, p, h );
this.b = hue2rgb( q, p, h - 1 / 3 );
}
return this;
};
}(),
setStyle: function ( style ) {
function handleAlpha( string ) {
if ( string === undefined ) return;
if ( parseFloat( string ) < 1 ) {
console.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );
}
}
var m;
if ( m = /^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec( style ) ) {
// rgb / hsl
var color;
var name = m[ 1 ];
var components = m[ 2 ];
switch ( name ) {
case 'rgb':
case 'rgba':
if ( color = /^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) {
// rgb(255,0,0) rgba(255,0,0,0.5)
this.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255;
this.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;
this.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;
handleAlpha( color[ 5 ] );
return this;
}
if ( color = /^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) {
// rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)
this.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100;
this.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;
this.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;
handleAlpha( color[ 5 ] );
return this;
}
break;
case 'hsl':
case 'hsla':
if ( color = /^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) {
// hsl(120,50%,50%) hsla(120,50%,50%,0.5)
var h = parseFloat( color[ 1 ] ) / 360;
var s = parseInt( color[ 2 ], 10 ) / 100;
var l = parseInt( color[ 3 ], 10 ) / 100;
handleAlpha( color[ 5 ] );
return this.setHSL( h, s, l );
}
break;
}
} else if ( m = /^\#([A-Fa-f0-9]+)$/.exec( style ) ) {
// hex color
var hex = m[ 1 ];
var size = hex.length;
if ( size === 3 ) {
// #ff0
this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255;
this.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255;
this.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255;
return this;
} else if ( size === 6 ) {
// #ff0000
this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255;
this.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255;
this.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255;
return this;
}
}
if ( style && style.length > 0 ) {
// color keywords
var hex = ColorKeywords[ style ];
if ( hex !== undefined ) {
// red
this.setHex( hex );
} else {
// unknown color
console.warn( 'THREE.Color: Unknown color ' + style );
}
}
return this;
},
clone: function () {
return new this.constructor( this.r, this.g, this.b );
},
copy: function ( color ) {
this.r = color.r;
this.g = color.g;
this.b = color.b;
return this;
},
copyGammaToLinear: function ( color, gammaFactor ) {
if ( gammaFactor === undefined ) gammaFactor = 2.0;
this.r = Math.pow( color.r, gammaFactor );
this.g = Math.pow( color.g, gammaFactor );
this.b = Math.pow( color.b, gammaFactor );
return this;
},
copyLinearToGamma: function ( color, gammaFactor ) {
if ( gammaFactor === undefined ) gammaFactor = 2.0;
var safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0;
this.r = Math.pow( color.r, safeInverse );
this.g = Math.pow( color.g, safeInverse );
this.b = Math.pow( color.b, safeInverse );
return this;
},
convertGammaToLinear: function () {
var r = this.r, g = this.g, b = this.b;
this.r = r * r;
this.g = g * g;
this.b = b * b;
return this;
},
convertLinearToGamma: function () {
this.r = Math.sqrt( this.r );
this.g = Math.sqrt( this.g );
this.b = Math.sqrt( this.b );
return this;
},
getHex: function () {
return ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0;
},
getHexString: function () {
return ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 );
},
getHSL: function ( optionalTarget ) {
// h,s,l ranges are in 0.0 - 1.0
var hsl = optionalTarget || { h: 0, s: 0, l: 0 };
var r = this.r, g = this.g, b = this.b;
var max = Math.max( r, g, b );
var min = Math.min( r, g, b );
var hue, saturation;
var lightness = ( min + max ) / 2.0;
if ( min === max ) {
hue = 0;
saturation = 0;
} else {
var delta = max - min;
saturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );
switch ( max ) {
case r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;
case g: hue = ( b - r ) / delta + 2; break;
case b: hue = ( r - g ) / delta + 4; break;
}
hue /= 6;
}
hsl.h = hue;
hsl.s = saturation;
hsl.l = lightness;
return hsl;
},
getStyle: function () {
return 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')';
},
offsetHSL: function ( h, s, l ) {
var hsl = this.getHSL();
hsl.h += h; hsl.s += s; hsl.l += l;
this.setHSL( hsl.h, hsl.s, hsl.l );
return this;
},
add: function ( color ) {
this.r += color.r;
this.g += color.g;
this.b += color.b;
return this;
},
addColors: function ( color1, color2 ) {
this.r = color1.r + color2.r;
this.g = color1.g + color2.g;
this.b = color1.b + color2.b;
return this;
},
addScalar: function ( s ) {
this.r += s;
this.g += s;
this.b += s;
return this;
},
sub: function( color ) {
this.r = Math.max( 0, this.r - color.r );
this.g = Math.max( 0, this.g - color.g );
this.b = Math.max( 0, this.b - color.b );
return this;
},
multiply: function ( color ) {
this.r *= color.r;
this.g *= color.g;
this.b *= color.b;
return this;
},
multiplyScalar: function ( s ) {
this.r *= s;
this.g *= s;
this.b *= s;
return this;
},
lerp: function ( color, alpha ) {
this.r += ( color.r - this.r ) * alpha;
this.g += ( color.g - this.g ) * alpha;
this.b += ( color.b - this.b ) * alpha;
return this;
},
equals: function ( c ) {
return ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );
},
fromArray: function ( array, offset ) {
if ( offset === undefined ) offset = 0;
this.r = array[ offset ];
this.g = array[ offset + 1 ];
this.b = array[ offset + 2 ];
return this;
},
toArray: function ( array, offset ) {
if ( array === undefined ) array = [];
if ( offset === undefined ) offset = 0;
array[ offset ] = this.r;
array[ offset + 1 ] = this.g;
array[ offset + 2 ] = this.b;
return array;
},
toJSON: function () {
return this.getHex();
}
} );
/**
* Uniforms library for shared webgl shaders
*/
var UniformsLib = {
common: {
diffuse: { value: new Color( 0xeeeeee ) },
opacity: { value: 1.0 },
map: { value: null },
offsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) },
specularMap: { value: null },
alphaMap: { value: null },
envMap: { value: null },
flipEnvMap: { value: - 1 },
reflectivity: { value: 1.0 },
refractionRatio: { value: 0.98 }
},
aomap: {
aoMap: { value: null },
aoMapIntensity: { value: 1 }
},
lightmap: {
lightMap: { value: null },
lightMapIntensity: { value: 1 }
},
emissivemap: {
emissiveMap: { value: null }
},
bumpmap: {
bumpMap: { value: null },
bumpScale: { value: 1 }
},
normalmap: {
normalMap: { value: null },
normalScale: { value: new Vector2( 1, 1 ) }
},
displacementmap: {
displacementMap: { value: null },
displacementScale: { value: 1 },
displacementBias: { value: 0 }
},
roughnessmap: {
roughnessMap: { value: null }
},
metalnessmap: {
metalnessMap: { value: null }
},
gradientmap: {
gradientMap: { value: null }
},
fog: {
fogDensity: { value: 0.00025 },
fogNear: { value: 1 },
fogFar: { value: 2000 },
fogColor: { value: new Color( 0xffffff ) }
},
lights: {
ambientLightColor: { value: [] },
directionalLights: { value: [], properties: {
direction: {},
color: {},
shadow: {},
shadowBias: {},
shadowRadius: {},
shadowMapSize: {}
} },
directionalShadowMap: { value: [] },
directionalShadowMatrix: { value: [] },
spotLights: { value: [], properties: {
color: {},
position: {},
direction: {},
distance: {},
coneCos: {},
penumbraCos: {},
decay: {},
shadow: {},
shadowBias: {},
shadowRadius: {},
shadowMapSize: {}
} },
spotShadowMap: { value: [] },
spotShadowMatrix: { value: [] },
pointLights: { value: [], properties: {
color: {},
position: {},
decay: {},
distance: {},
shadow: {},
shadowBias: {},
shadowRadius: {},
shadowMapSize: {}
} },
pointShadowMap: { value: [] },
pointShadowMatrix: { value: [] },
hemisphereLights: { value: [], properties: {
direction: {},
skyColor: {},
groundColor: {}
} },
// TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src
rectAreaLights: { value: [], properties: {
color: {},
position: {},
width: {},
height: {}
} }
},
points: {
diffuse: { value: new Color( 0xeeeeee ) },
opacity: { value: 1.0 },
size: { value: 1.0 },
scale: { value: 1.0 },
map: { value: null },
offsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) }
}
};
/**
* Uniform Utilities
*/
var UniformsUtils = {
merge: function ( uniforms ) {
var merged = {};
for ( var u = 0; u < uniforms.length; u ++ ) {
var tmp = this.clone( uniforms[ u ] );
for ( var p in tmp ) {
merged[ p ] = tmp[ p ];
}
}
return merged;
},
clone: function ( uniforms_src ) {
var uniforms_dst = {};
for ( var u in uniforms_src ) {
uniforms_dst[ u ] = {};
for ( var p in uniforms_src[ u ] ) {
var parameter_src = uniforms_src[ u ][ p ];
if ( parameter_src && ( parameter_src.isColor ||
parameter_src.isMatrix3 || parameter_src.isMatrix4 ||
parameter_src.isVector2 || parameter_src.isVector3 || parameter_src.isVector4 ||
parameter_src.isTexture ) ) {
uniforms_dst[ u ][ p ] = parameter_src.clone();
} else if ( Array.isArray( parameter_src ) ) {
uniforms_dst[ u ][ p ] = parameter_src.slice();
} else {
uniforms_dst[ u ][ p ] = parameter_src;
}
}
}
return uniforms_dst;
}
};
var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif\n";
var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif\n";
var alphatest_fragment = "#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif\n";
var aomap_fragment = "#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif\n";
var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif";
var begin_vertex = "\nvec3 transformed = vec3( position );\n";
var beginnormal_vertex = "\nvec3 objectNormal = vec3( normal );\n";
var bsdfs = "float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n\tif( decayExponent > 0.0 ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\t\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\t\tfloat maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t\treturn distanceFalloff * maxDistanceCutoffFactor;\n#else\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n#endif\n\t}\n\treturn 1.0;\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat theta = acos( dot( N, V ) );\n\tvec2 uv = vec2(\n\t\tsqrt( saturate( roughness ) ),\n\t\tsaturate( theta / ( 0.5 * PI ) ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.86267 + (0.49788 + 0.01436 * y ) * y;\n\tfloat b = 3.45068 + (4.18814 + y) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = (x > 0.0) ? v : 0.5 * inversesqrt( 1.0 - x * x ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transpose( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tvec3 result = vec3( LTC_ClippedSphereFormFactor( vectorFormFactor ) );\n\treturn result;\n}\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\tvec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;\n\treturn specularColor * AB.x + AB.y;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}\n";
var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif\n";
var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; ++ i ) {\n\t\tvec4 plane = clippingPlanes[ i ];\n\t\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t\t\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; ++ i ) {\n\t\t\tvec4 plane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\tif ( clipped ) discard;\n\t\n\t#endif\n#endif\n";
var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\t#if ! defined( PHYSICAL ) && ! defined( PHONG )\n\t\tvarying vec3 vViewPosition;\n\t#endif\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif\n";
var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\n\tvarying vec3 vViewPosition;\n#endif\n";
var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n";
var color_fragment = "#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif";
var color_pars_fragment = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif\n";
var color_pars_vertex = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif";
var color_vertex = "#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif";
var common = "#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI_HALF 1.5707963267949\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transpose( const in mat3 v ) {\n\tmat3 tmp;\n\ttmp[0] = vec3(v[0].x, v[1].x, v[2].x);\n\ttmp[1] = vec3(v[0].y, v[1].y, v[2].y);\n\ttmp[2] = vec3(v[0].z, v[1].z, v[2].z);\n\treturn tmp;\n}\n";
var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n#define cubeUV_textureSize (1024.0)\nint getFaceFromDirection(vec3 direction) {\n\tvec3 absDirection = abs(direction);\n\tint face = -1;\n\tif( absDirection.x > absDirection.z ) {\n\t\tif(absDirection.x > absDirection.y )\n\t\t\tface = direction.x > 0.0 ? 0 : 3;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\telse {\n\t\tif(absDirection.z > absDirection.y )\n\t\t\tface = direction.z > 0.0 ? 2 : 5;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\treturn face;\n}\n#define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0)\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\n\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\n\tfloat dxRoughness = dFdx(roughness);\n\tfloat dyRoughness = dFdy(roughness);\n\tvec3 dx = dFdx( vec * scale * dxRoughness );\n\tvec3 dy = dFdy( vec * scale * dyRoughness );\n\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\n\td = clamp(d, 1.0, cubeUV_rangeClamp);\n\tfloat mipLevel = 0.5 * log2(d);\n\treturn vec2(floor(mipLevel), fract(mipLevel));\n}\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\n\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\n\tfloat a = 16.0 * cubeUV_rcpTextureSize;\n\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\n\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\n\tfloat powScale = exp2_packed.x * exp2_packed.y;\n\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\n\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\n\tbool bRes = mipLevel == 0.0;\n\tscale = bRes && (scale < a) ? a : scale;\n\tvec3 r;\n\tvec2 offset;\n\tint face = getFaceFromDirection(direction);\n\tfloat rcpPowScale = 1.0 / powScale;\n\tif( face == 0) {\n\t\tr = vec3(direction.x, -direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 1) {\n\t\tr = vec3(direction.y, direction.x, direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 2) {\n\t\tr = vec3(direction.z, direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 3) {\n\t\tr = vec3(direction.x, direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse if( face == 4) {\n\t\tr = vec3(direction.y, direction.x, -direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse {\n\t\tr = vec3(direction.z, -direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\tr = normalize(r);\n\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\n\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\n\tvec2 base = offset + vec2( texelOffset );\n\treturn base + s * ( scale - 2.0 * texelOffset );\n}\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\nvec4 textureCubeUV(vec3 reflectedDirection, float roughness ) {\n\tfloat roughnessVal = roughness* cubeUV_maxLods3;\n\tfloat r1 = floor(roughnessVal);\n\tfloat r2 = r1 + 1.0;\n\tfloat t = fract(roughnessVal);\n\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\n\tfloat s = mipInfo.y;\n\tfloat level0 = mipInfo.x;\n\tfloat level1 = level0 + 1.0;\n\tlevel1 = level1 > 5.0 ? 5.0 : level1;\n\tlevel0 += min( floor( s + 0.5 ), 5.0 );\n\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\n\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\n\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\n\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\n\tvec4 result = mix(color10, color20, t);\n\treturn vec4(result.rgb, 1.0);\n}\n#endif\n";
var defaultnormal_vertex = "vec3 transformedNormal = normalMatrix * objectNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n";
var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif\n";
var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\n#endif\n";
var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif\n";
var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif\n";
var encodings_fragment = " gl_FragColor = linearToOutputTexel( gl_FragColor );\n";
var encodings_pars_fragment = "\nvec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.w );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.w );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n\tfloat maxComponent = max( max( value.r, value.g ), value.b );\n\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.xyz * value.w * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\n\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n\tM = ceil( M * 255.0 ) / 255.0;\n\treturn vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\n\tfloat D = max( maxRange / maxRGB, 1.0 );\n\tD = min( floor( D ) / 255.0, 1.0 );\n\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\n}\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\nvec4 LinearToLogLuv( in vec4 value ) {\n\tvec3 Xp_Y_XYZp = value.rgb * cLogLuvM;\n\tXp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));\n\tvec4 vResult;\n\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n\tvResult.w = fract(Le);\n\tvResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;\n\treturn vResult;\n}\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\nvec4 LogLuvToLinear( in vec4 value ) {\n\tfloat Le = value.z * 255.0 + value.w;\n\tvec3 Xp_Y_XYZp;\n\tXp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);\n\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n\tvec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;\n\treturn vec4( max(vRGB, 0.0), 1.0 );\n}\n";
var envmap_fragment = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\tsampleUV.y = asin( flipNormal * reflectVec.y ) * RECIPROCAL_PI + 0.5;\n\t\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\tvec3 reflectView = flipNormal * normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\tenvColor = envMapTexelToLinear( envColor );\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif\n";
var envmap_pars_fragment = "#if defined( USE_ENVMAP ) || defined( PHYSICAL )\n\tuniform float reflectivity;\n\tuniform float envMapIntensity;\n#endif\n#ifdef USE_ENVMAP\n\t#if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) )\n\t\tvarying vec3 vWorldPosition;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\tuniform float flipEnvMap;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif\n";
var envmap_pars_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif\n";
var envmap_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif\n";
var fog_vertex = "\n#ifdef USE_FOG\nfogDepth = -mvPosition.z;\n#endif";
var fog_pars_vertex = "#ifdef USE_FOG\n varying float fogDepth;\n#endif\n";
var fog_fragment = "#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif\n";
var fog_pars_fragment = "#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float fogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif\n";
var gradientmap_pars_fragment = "#ifdef TOON\n\tuniform sampler2D gradientMap;\n\tvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\t\tfloat dotNL = dot( normal, lightDirection );\n\t\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t\t#ifdef USE_GRADIENTMAP\n\t\t\treturn texture2D( gradientMap, coord ).rgb;\n\t\t#else\n\t\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t\t#endif\n\t}\n#endif\n";
var lightmap_fragment = "#ifdef USE_LIGHTMAP\n\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n#endif\n";
var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif";
var lights_lambert_vertex = "vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\n#if NUM_POINT_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_DIR_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvLightFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n\t\t#endif\n\t}\n#endif\n";
var lights_pars = "uniform vec3 ambientLightColor;\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treturn irradiance;\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tdirectLight.color = directionalLight.color;\n\t\tdirectLight.direction = directionalLight.direction;\n\t\tdirectLight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tdirectLight.color = pointLight.color;\n\t\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\n\t\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( directLight.direction, spotLight.direction );\n\t\tif ( angleCos > spotLight.coneCos ) {\n\t\t\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\t\tdirectLight.color = spotLight.color;\n\t\t\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tdirectLight.visible = true;\n\t\t} else {\n\t\t\tdirectLight.color = vec3( 0.0 );\n\t\t\tdirectLight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltcMat;\tuniform sampler2D ltcMag;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n\t\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tirradiance *= PI;\n\t\t#endif\n\t\treturn irradiance;\n\t}\n#endif\n#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( queryVec, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar - 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\tvec4 envMapColor = textureCubeUV(queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent));\n\t\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\t\tvec2 sampleUV;\n\t\t\tsampleUV.y = saturate( reflectVec.y * 0.5 + 0.5 );\n\t\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif\n";
var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;\n";
var lights_phong_pars_fragment = "varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifdef TOON\n\t\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\t#else\n\t\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\t\tvec3 irradiance = dotNL * directLight.color;\n\t#endif\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)\n";
var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\n#ifdef STANDARD\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.clearCoat = saturate( clearCoat );\tmaterial.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 );\n#endif\n";
var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3\tdiffuseColor;\n\tfloat\tspecularRoughness;\n\tvec3\tspecularColor;\n\t#ifndef STANDARD\n\t\tfloat clearCoat;\n\t\tfloat clearCoatRoughness;\n\t#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearCoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos - halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos + halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos + halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos - halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tfloat norm = texture2D( ltcMag, uv ).a;\n\t\tvec4 t = texture2D( ltcMat, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( 1, 0, t.y ),\n\t\t\tvec3( 0, t.z, 0 ),\n\t\t\tvec3( t.w, 0, t.x )\n\t\t);\n\t\treflectedLight.directSpecular += lightColor * material.specularColor * norm * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifndef STANDARD\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\treflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );\n\treflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\t#ifndef STANDARD\n\t\treflectedLight.directSpecular += irradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#endif\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifndef STANDARD\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\tfloat dotNL = dotNV;\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\treflectedLight.indirectSpecular += ( 1.0 - clearCoatDHR ) * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );\n\t#ifndef STANDARD\n\t\treflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#endif\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\n#define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness )\n#define Material_ClearCoat_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.clearCoatRoughness )\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}\n";
var lights_template = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = normalize( vViewPosition );\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\t#ifdef USE_LIGHTMAP\n\t\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tirradiance += getLightProbeIndirectIrradiance( geometry, 8 );\n\t#endif\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tvec3 radiance = getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), 8 );\n\t#ifndef STANDARD\n\t\tvec3 clearCoatRadiance = getLightProbeIndirectRadiance( geometry, Material_ClearCoat_BlinnShininessExponent( material ), 8 );\n\t#else\n\t\tvec3 clearCoatRadiance = vec3( 0.0 );\n\t#endif\n\tRE_IndirectSpecular( radiance, clearCoatRadiance, geometry, material, reflectedLight );\n#endif\n";
var logdepthbuf_fragment = "#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)\n\tgl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;\n#endif";
var logdepthbuf_pars_fragment = "#ifdef USE_LOGDEPTHBUF\n\tuniform float logDepthBufFC;\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t#endif\n#endif\n";
var logdepthbuf_pars_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t#endif\n\tuniform float logDepthBufFC;\n#endif";
var logdepthbuf_vertex = "#ifdef USE_LOGDEPTHBUF\n\tgl_Position.z = log2(max( EPSILON, gl_Position.w + 1.0 )) * logDepthBufFC;\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t#else\n\t\tgl_Position.z = (gl_Position.z - 1.0) * gl_Position.w;\n\t#endif\n#endif\n";
var map_fragment = "#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif\n";
var map_pars_fragment = "#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n";
var map_particle_fragment = "#ifdef USE_MAP\n\tvec4 mapTexel = texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) * offsetRepeat.zw + offsetRepeat.xy );\n\tdiffuseColor *= mapTexelToLinear( mapTexel );\n#endif\n";
var map_particle_pars_fragment = "#ifdef USE_MAP\n\tuniform vec4 offsetRepeat;\n\tuniform sampler2D map;\n#endif\n";
var metalnessmap_fragment = "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif\n";
var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif";
var morphnormal_vertex = "#ifdef USE_MORPHNORMALS\n\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\n\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\n\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\n\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\n#endif\n";
var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n\t#ifndef USE_MORPHNORMALS\n\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif";
var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\n\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\n\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\n\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\n\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\n\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\n\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n\t#endif\n#endif\n";
var normal_flip = "#ifdef DOUBLE_SIDED\n\tfloat flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n#else\n\tfloat flipNormal = 1.0;\n#endif\n";
var normal_fragment = "#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal ) * flipNormal;\n#endif\n#ifdef USE_NORMALMAP\n\tnormal = perturbNormal2Arb( -vViewPosition, normal );\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif\n";
var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\n\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tvec3 S = normalize( q0 * st1.t - q1 * st0.t );\n\t\tvec3 T = normalize( -q0 * st1.s + q1 * st0.s );\n\t\tvec3 N = normalize( surf_norm );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy = normalScale * mapN.xy;\n\t\tmat3 tsn = mat3( S, T, N );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif\n";
var packing = "vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 1.0 - 2.0 * rgb.xyz;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}\n";
var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif\n";
var project_vertex = "vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\ngl_Position = projectionMatrix * mvPosition;\n";
var dithering_fragment = "#if defined( DITHERING )\n gl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif\n";
var dithering_pars_fragment = "#if defined( DITHERING )\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif\n";
var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif\n";
var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif";
var shadowmap_pars_fragment = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\n\t\tconst vec2 offset = vec2( 0.0, 1.0 );\n\t\tvec2 texelSize = vec2( 1.0 ) / size;\n\t\tvec2 centroidUV = floor( uv * size + 0.5 ) / size;\n\t\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\n\t\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\n\t\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\n\t\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\n\t\tvec2 f = fract( uv * size + 0.5 );\n\t\tfloat a = mix( lb, lt, f.y );\n\t\tfloat b = mix( rb, rt, f.y );\n\t\tfloat c = mix( a, b, f.x );\n\t\treturn c;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\tfloat dp = ( length( lightToPosition ) - shadowBias ) / 1000.0;\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif\n";
var shadowmap_pars_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n#endif\n";
var shadowmap_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n#endif\n";
var shadowmask_pars_fragment = "float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\tDirectionalLight directionalLight;\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\tSpotLight spotLight;\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\tPointLight pointLight;\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#endif\n\treturn shadow;\n}\n";
var skinbase_vertex = "#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif";
var skinning_pars_vertex = "#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\t#ifdef BONE_TEXTURE\n\t\tuniform sampler2D boneTexture;\n\t\tuniform int boneTextureSize;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\t\ty = dy * ( y + 0.5 );\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\t\treturn bone;\n\t\t}\n\t#else\n\t\tuniform mat4 boneMatrices[ MAX_BONES ];\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tmat4 bone = boneMatrices[ int(i) ];\n\t\t\treturn bone;\n\t\t}\n\t#endif\n#endif\n";
var skinning_vertex = "#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif\n";
var skinnormal_vertex = "#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n#endif\n";
var specularmap_fragment = "float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif";
var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif";
var tonemapping_fragment = "#if defined( TONE_MAPPING )\n gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif\n";
var tonemapping_pars_fragment = "#define saturate(a) clamp( a, 0.0, 1.0 )\nuniform float toneMappingExposure;\nuniform float toneMappingWhitePoint;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\nvec3 Uncharted2ToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\n";
var uv_pars_fragment = "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n#endif";
var uv_pars_vertex = "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n\tuniform vec4 offsetRepeat;\n#endif\n";
var uv_vertex = "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvUv = uv * offsetRepeat.zw + offsetRepeat.xy;\n#endif";
var uv2_pars_fragment = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif";
var uv2_pars_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n#endif";
var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = uv2;\n#endif";
var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( PHYSICAL ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\n#endif\n";
var cube_frag = "uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\n\tgl_FragColor.a *= opacity;\n}\n";
var cube_vert = "varying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}\n";
var depth_frag = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <logdepthbuf_fragment>\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( gl_FragCoord.z ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\n\t#endif\n}\n";
var depth_vert = "#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n}\n";
var distanceRGBA_frag = "uniform vec3 lightPos;\nvarying vec4 vWorldPosition;\n#include <common>\n#include <packing>\n#include <clipping_planes_pars_fragment>\nvoid main () {\n\t#include <clipping_planes_fragment>\n\tgl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );\n}\n";
var distanceRGBA_vert = "varying vec4 vWorldPosition;\n#include <common>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <skinbase_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\tvWorldPosition = worldPosition;\n}\n";
var equirect_frag = "uniform sampler2D tEquirect;\nuniform float tFlip;\nvarying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvec3 direction = normalize( vWorldPosition );\n\tvec2 sampleUV;\n\tsampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n}\n";
var equirect_vert = "varying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}\n";
var linedashed_frag = "uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <color_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <premultiplied_alpha_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}\n";
var linedashed_vert = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <color_vertex>\n\tvLineDistance = scale * lineDistance;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n}\n";
var meshbasic_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <envmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include <aomap_fragment>\n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include <normal_flip>\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <premultiplied_alpha_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}\n";
var meshbasic_vert = "#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_ENVMAP\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <envmap_vertex>\n\t#include <fog_vertex>\n}\n";
var meshlambert_frag = "uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_pars_fragment>\n#include <bsdfs>\n#include <lights_pars>\n#include <fog_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <emissivemap_fragment>\n\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\n\t#include <lightmap_fragment>\n\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include <normal_flip>\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}\n";
var meshlambert_vert = "#define LAMBERT\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <envmap_pars_vertex>\n#include <bsdfs>\n#include <lights_pars>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <lights_lambert_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}\n";
var meshphong_frag = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_pars_fragment>\n#include <gradientmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars>\n#include <lights_phong_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <normal_flip>\n\t#include <normal_fragment>\n\t#include <emissivemap_fragment>\n\t#include <lights_phong_fragment>\n\t#include <lights_template>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}\n";
var meshphong_vert = "#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}\n";
var meshphysical_frag = "#define PHYSICAL\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifndef STANDARD\n\tuniform float clearCoat;\n\tuniform float clearCoatRoughness;\n#endif\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <cube_uv_reflection_fragment>\n#include <lights_pars>\n#include <lights_physical_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <roughnessmap_pars_fragment>\n#include <metalnessmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <roughnessmap_fragment>\n\t#include <metalnessmap_fragment>\n\t#include <normal_flip>\n\t#include <normal_fragment>\n\t#include <emissivemap_fragment>\n\t#include <lights_physical_fragment>\n\t#include <lights_template>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}\n";
var meshphysical_vert = "#define PHYSICAL\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}\n";
var normal_frag = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <packing>\n#include <uv_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\nvoid main() {\n\t#include <logdepthbuf_fragment>\n\t#include <normal_flip>\n\t#include <normal_fragment>\n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}\n";
var normal_vert = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}\n";
var points_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <color_pars_fragment>\n#include <map_particle_pars_fragment>\n#include <fog_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_particle_fragment>\n\t#include <color_fragment>\n\t#include <alphatest_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <premultiplied_alpha_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}\n";
var points_vert = "uniform float size;\nuniform float scale;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <color_vertex>\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\t#ifdef USE_SIZEATTENUATION\n\t\tgl_PointSize = size * ( scale / - mvPosition.z );\n\t#else\n\t\tgl_PointSize = size;\n\t#endif\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}\n";
var shadow_frag = "uniform float opacity;\n#include <common>\n#include <packing>\n#include <bsdfs>\n#include <lights_pars>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\nvoid main() {\n\tgl_FragColor = vec4( 0.0, 0.0, 0.0, opacity * ( 1.0 - getShadowMask() ) );\n}\n";
var shadow_vert = "#include <shadowmap_pars_vertex>\nvoid main() {\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n}\n";
var ShaderChunk = {
alphamap_fragment: alphamap_fragment,
alphamap_pars_fragment: alphamap_pars_fragment,
alphatest_fragment: alphatest_fragment,
aomap_fragment: aomap_fragment,
aomap_pars_fragment: aomap_pars_fragment,
begin_vertex: begin_vertex,
beginnormal_vertex: beginnormal_vertex,
bsdfs: bsdfs,
bumpmap_pars_fragment: bumpmap_pars_fragment,
clipping_planes_fragment: clipping_planes_fragment,
clipping_planes_pars_fragment: clipping_planes_pars_fragment,
clipping_planes_pars_vertex: clipping_planes_pars_vertex,
clipping_planes_vertex: clipping_planes_vertex,
color_fragment: color_fragment,
color_pars_fragment: color_pars_fragment,
color_pars_vertex: color_pars_vertex,
color_vertex: color_vertex,
common: common,
cube_uv_reflection_fragment: cube_uv_reflection_fragment,
defaultnormal_vertex: defaultnormal_vertex,
displacementmap_pars_vertex: displacementmap_pars_vertex,
displacementmap_vertex: displacementmap_vertex,
emissivemap_fragment: emissivemap_fragment,
emissivemap_pars_fragment: emissivemap_pars_fragment,
encodings_fragment: encodings_fragment,
encodings_pars_fragment: encodings_pars_fragment,
envmap_fragment: envmap_fragment,
envmap_pars_fragment: envmap_pars_fragment,
envmap_pars_vertex: envmap_pars_vertex,
envmap_vertex: envmap_vertex,
fog_vertex: fog_vertex,
fog_pars_vertex: fog_pars_vertex,
fog_fragment: fog_fragment,
fog_pars_fragment: fog_pars_fragment,
gradientmap_pars_fragment: gradientmap_pars_fragment,
lightmap_fragment: lightmap_fragment,
lightmap_pars_fragment: lightmap_pars_fragment,
lights_lambert_vertex: lights_lambert_vertex,
lights_pars: lights_pars,
lights_phong_fragment: lights_phong_fragment,
lights_phong_pars_fragment: lights_phong_pars_fragment,
lights_physical_fragment: lights_physical_fragment,
lights_physical_pars_fragment: lights_physical_pars_fragment,
lights_template: lights_template,
logdepthbuf_fragment: logdepthbuf_fragment,
logdepthbuf_pars_fragment: logdepthbuf_pars_fragment,
logdepthbuf_pars_vertex: logdepthbuf_pars_vertex,
logdepthbuf_vertex: logdepthbuf_vertex,
map_fragment: map_fragment,
map_pars_fragment: map_pars_fragment,
map_particle_fragment: map_particle_fragment,
map_particle_pars_fragment: map_particle_pars_fragment,
metalnessmap_fragment: metalnessmap_fragment,
metalnessmap_pars_fragment: metalnessmap_pars_fragment,
morphnormal_vertex: morphnormal_vertex,
morphtarget_pars_vertex: morphtarget_pars_vertex,
morphtarget_vertex: morphtarget_vertex,
normal_flip: normal_flip,
normal_fragment: normal_fragment,
normalmap_pars_fragment: normalmap_pars_fragment,
packing: packing,
premultiplied_alpha_fragment: premultiplied_alpha_fragment,
project_vertex: project_vertex,
dithering_fragment: dithering_fragment,
dithering_pars_fragment: dithering_pars_fragment,
roughnessmap_fragment: roughnessmap_fragment,
roughnessmap_pars_fragment: roughnessmap_pars_fragment,
shadowmap_pars_fragment: shadowmap_pars_fragment,
shadowmap_pars_vertex: shadowmap_pars_vertex,
shadowmap_vertex: shadowmap_vertex,
shadowmask_pars_fragment: shadowmask_pars_fragment,
skinbase_vertex: skinbase_vertex,
skinning_pars_vertex: skinning_pars_vertex,
skinning_vertex: skinning_vertex,
skinnormal_vertex: skinnormal_vertex,
specularmap_fragment: specularmap_fragment,
specularmap_pars_fragment: specularmap_pars_fragment,
tonemapping_fragment: tonemapping_fragment,
tonemapping_pars_fragment: tonemapping_pars_fragment,
uv_pars_fragment: uv_pars_fragment,
uv_pars_vertex: uv_pars_vertex,
uv_vertex: uv_vertex,
uv2_pars_fragment: uv2_pars_fragment,
uv2_pars_vertex: uv2_pars_vertex,
uv2_vertex: uv2_vertex,
worldpos_vertex: worldpos_vertex,
cube_frag: cube_frag,
cube_vert: cube_vert,
depth_frag: depth_frag,
depth_vert: depth_vert,
distanceRGBA_frag: distanceRGBA_frag,
distanceRGBA_vert: distanceRGBA_vert,
equirect_frag: equirect_frag,
equirect_vert: equirect_vert,
linedashed_frag: linedashed_frag,
linedashed_vert: linedashed_vert,
meshbasic_frag: meshbasic_frag,
meshbasic_vert: meshbasic_vert,
meshlambert_frag: meshlambert_frag,
meshlambert_vert: meshlambert_vert,
meshphong_frag: meshphong_frag,
meshphong_vert: meshphong_vert,
meshphysical_frag: meshphysical_frag,
meshphysical_vert: meshphysical_vert,
normal_frag: normal_frag,
normal_vert: normal_vert,
points_frag: points_frag,
points_vert: points_vert,
shadow_frag: shadow_frag,
shadow_vert: shadow_vert
};
/**
* @author alteredq / http://alteredqualia.com/
* @author mrdoob / http://mrdoob.com/
* @author mikael emtinger / http://gomo.se/
*/
var ShaderLib = {
basic: {
uniforms: UniformsUtils.merge( [
UniformsLib.common,
UniformsLib.aomap,
UniformsLib.lightmap,
UniformsLib.fog
] ),
vertexShader: ShaderChunk.meshbasic_vert,
fragmentShader: ShaderChunk.meshbasic_frag
},
lambert: {
uniforms: UniformsUtils.merge( [
UniformsLib.common,
UniformsLib.aomap,
UniformsLib.lightmap,
UniformsLib.emissivemap,
UniformsLib.fog,
UniformsLib.lights,
{
emissive: { value: new Color( 0x000000 ) }
}
] ),
vertexShader: ShaderChunk.meshlambert_vert,
fragmentShader: ShaderChunk.meshlambert_frag
},
phong: {
uniforms: UniformsUtils.merge( [
UniformsLib.common,
UniformsLib.aomap,
UniformsLib.lightmap,
UniformsLib.emissivemap,
UniformsLib.bumpmap,
UniformsLib.normalmap,
UniformsLib.displacementmap,
UniformsLib.gradientmap,
UniformsLib.fog,
UniformsLib.lights,
{
emissive: { value: new Color( 0x000000 ) },
specular: { value: new Color( 0x111111 ) },
shininess: { value: 30 }
}
] ),
vertexShader: ShaderChunk.meshphong_vert,
fragmentShader: ShaderChunk.meshphong_frag
},
standard: {
uniforms: UniformsUtils.merge( [
UniformsLib.common,
UniformsLib.aomap,
UniformsLib.lightmap,
UniformsLib.emissivemap,
UniformsLib.bumpmap,
UniformsLib.normalmap,
UniformsLib.displacementmap,
UniformsLib.roughnessmap,
UniformsLib.metalnessmap,
UniformsLib.fog,
UniformsLib.lights,
{
emissive: { value: new Color( 0x000000 ) },
roughness: { value: 0.5 },
metalness: { value: 0.5 },
envMapIntensity: { value: 1 } // temporary
}
] ),
vertexShader: ShaderChunk.meshphysical_vert,
fragmentShader: ShaderChunk.meshphysical_frag
},
points: {
uniforms: UniformsUtils.merge( [
UniformsLib.points,
UniformsLib.fog
] ),
vertexShader: ShaderChunk.points_vert,
fragmentShader: ShaderChunk.points_frag
},
dashed: {
uniforms: UniformsUtils.merge( [
UniformsLib.common,
UniformsLib.fog,
{
scale: { value: 1 },
dashSize: { value: 1 },
totalSize: { value: 2 }
}
] ),
vertexShader: ShaderChunk.linedashed_vert,
fragmentShader: ShaderChunk.linedashed_frag
},
depth: {
uniforms: UniformsUtils.merge( [
UniformsLib.common,
UniformsLib.displacementmap
] ),
vertexShader: ShaderChunk.depth_vert,
fragmentShader: ShaderChunk.depth_frag
},
normal: {
uniforms: UniformsUtils.merge( [
UniformsLib.common,
UniformsLib.bumpmap,
UniformsLib.normalmap,
UniformsLib.displacementmap,
{
opacity: { value: 1.0 }
}
] ),
vertexShader: ShaderChunk.normal_vert,
fragmentShader: ShaderChunk.normal_frag
},
/* -------------------------------------------------------------------------
// Cube map shader
------------------------------------------------------------------------- */
cube: {
uniforms: {
tCube: { value: null },
tFlip: { value: - 1 },
opacity: { value: 1.0 }
},
vertexShader: ShaderChunk.cube_vert,
fragmentShader: ShaderChunk.cube_frag
},
/* -------------------------------------------------------------------------
// Cube map shader
------------------------------------------------------------------------- */
equirect: {
uniforms: {
tEquirect: { value: null },
tFlip: { value: - 1 }
},
vertexShader: ShaderChunk.equirect_vert,
fragmentShader: ShaderChunk.equirect_frag
},
distanceRGBA: {
uniforms: {
lightPos: { value: new Vector3() }
},
vertexShader: ShaderChunk.distanceRGBA_vert,
fragmentShader: ShaderChunk.distanceRGBA_frag
}
};
ShaderLib.physical = {
uniforms: UniformsUtils.merge( [
ShaderLib.standard.uniforms,
{
clearCoat: { value: 0 },
clearCoatRoughness: { value: 0 }
}
] ),
vertexShader: ShaderChunk.meshphysical_vert,
fragmentShader: ShaderChunk.meshphysical_frag
};
/**
* @author bhouston / http://clara.io
*/
function Box2( min, max ) {
this.min = ( min !== undefined ) ? min : new Vector2( + Infinity, + Infinity );
this.max = ( max !== undefined ) ? max : new Vector2( - Infinity, - Infinity );
}
Object.assign( Box2.prototype, {
set: function ( min, max ) {
this.min.copy( min );
this.max.copy( max );
return this;
},
setFromPoints: function ( points ) {
this.makeEmpty();
for ( var i = 0, il = points.length; i < il; i ++ ) {
this.expandByPoint( points[ i ] );
}
return this;
},
setFromCenterAndSize: function () {
var v1 = new Vector2();
return function setFromCenterAndSize( center, size ) {
var halfSize = v1.copy( size ).multiplyScalar( 0.5 );
this.min.copy( center ).sub( halfSize );
this.max.copy( center ).add( halfSize );
return this;
};
}(),
clone: function () {
return new this.constructor().copy( this );
},
copy: function ( box ) {
this.min.copy( box.min );
this.max.copy( box.max );
return this;
},
makeEmpty: function () {
this.min.x = this.min.y = + Infinity;
this.max.x = this.max.y = - Infinity;
return this;
},
isEmpty: function () {
// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes
return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y );
},
getCenter: function ( optionalTarget ) {
var result = optionalTarget || new Vector2();
return this.isEmpty() ? result.set( 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );
},
getSize: function ( optionalTarget ) {
var result = optionalTarget || new Vector2();
return this.isEmpty() ? result.set( 0, 0 ) : result.subVectors( this.max, this.min );
},
expandByPoint: function ( point ) {
this.min.min( point );
this.max.max( point );
return this;
},
expandByVector: function ( vector ) {
this.min.sub( vector );
this.max.add( vector );
return this;
},
expandByScalar: function ( scalar ) {
this.min.addScalar( - scalar );
this.max.addScalar( scalar );
return this;
},
containsPoint: function ( point ) {
return point.x < this.min.x || point.x > this.max.x ||
point.y < this.min.y || point.y > this.max.y ? false : true;
},
containsBox: function ( box ) {
return this.min.x <= box.min.x && box.max.x <= this.max.x &&
this.min.y <= box.min.y && box.max.y <= this.max.y;
},
getParameter: function ( point, optionalTarget ) {
// This can potentially have a divide by zero if the box
// has a size dimension of 0.
var result = optionalTarget || new Vector2();
return result.set(
( point.x - this.min.x ) / ( this.max.x - this.min.x ),
( point.y - this.min.y ) / ( this.max.y - this.min.y )
);
},
intersectsBox: function ( box ) {
// using 4 splitting planes to rule out intersections
return box.max.x < this.min.x || box.min.x > this.max.x ||
box.max.y < this.min.y || box.min.y > this.max.y ? false : true;
},
clampPoint: function ( point, optionalTarget ) {
var result = optionalTarget || new Vector2();
return result.copy( point ).clamp( this.min, this.max );
},
distanceToPoint: function () {
var v1 = new Vector2();
return function distanceToPoint( point ) {
var clampedPoint = v1.copy( point ).clamp( this.min, this.max );
return clampedPoint.sub( point ).length();
};
}(),
intersect: function ( box ) {
this.min.max( box.min );
this.max.min( box.max );
return this;
},
union: function ( box ) {
this.min.min( box.min );
this.max.max( box.max );
return this;
},
translate: function ( offset ) {
this.min.add( offset );
this.max.add( offset );
return this;
},
equals: function ( box ) {
return box.min.equals( this.min ) && box.max.equals( this.max );
}
} );
/**
* @author mikael emtinger / http://gomo.se/
* @author alteredq / http://alteredqualia.com/
*/
function LensFlarePlugin( renderer, flares ) {
var gl = renderer.context;
var state = renderer.state;
var vertexBuffer, elementBuffer;
var shader, program, attributes, uniforms;
var tempTexture, occlusionTexture;
function init() {
var vertices = new Float32Array( [
- 1, - 1, 0, 0,
1, - 1, 1, 0,
1, 1, 1, 1,
- 1, 1, 0, 1
] );
var faces = new Uint16Array( [
0, 1, 2,
0, 2, 3
] );
// buffers
vertexBuffer = gl.createBuffer();
elementBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );
gl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );
gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );
gl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );
// textures
tempTexture = gl.createTexture();
occlusionTexture = gl.createTexture();
state.bindTexture( gl.TEXTURE_2D, tempTexture );
gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGB, 16, 16, 0, gl.RGB, gl.UNSIGNED_BYTE, null );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );
state.bindTexture( gl.TEXTURE_2D, occlusionTexture );
gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );
shader = {
vertexShader: [
"uniform lowp int renderType;",
"uniform vec3 screenPosition;",
"uniform vec2 scale;",
"uniform float rotation;",
"uniform sampler2D occlusionMap;",
"attribute vec2 position;",
"attribute vec2 uv;",
"varying vec2 vUV;",
"varying float vVisibility;",
"void main() {",
"vUV = uv;",
"vec2 pos = position;",
"if ( renderType == 2 ) {",
"vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );",
"visibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );",
"visibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );",
"visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );",
"visibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );",
"visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );",
"visibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );",
"visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );",
"visibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );",
"vVisibility = visibility.r / 9.0;",
"vVisibility *= 1.0 - visibility.g / 9.0;",
"vVisibility *= visibility.b / 9.0;",
"vVisibility *= 1.0 - visibility.a / 9.0;",
"pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;",
"pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;",
"}",
"gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );",
"}"
].join( "\n" ),
fragmentShader: [
"uniform lowp int renderType;",
"uniform sampler2D map;",
"uniform float opacity;",
"uniform vec3 color;",
"varying vec2 vUV;",
"varying float vVisibility;",
"void main() {",
// pink square
"if ( renderType == 0 ) {",
"gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );",
// restore
"} else if ( renderType == 1 ) {",
"gl_FragColor = texture2D( map, vUV );",
// flare
"} else {",
"vec4 texture = texture2D( map, vUV );",
"texture.a *= opacity * vVisibility;",
"gl_FragColor = texture;",
"gl_FragColor.rgb *= color;",
"}",
"}"
].join( "\n" )
};
program = createProgram( shader );
attributes = {
vertex: gl.getAttribLocation ( program, "position" ),
uv: gl.getAttribLocation ( program, "uv" )
};
uniforms = {
renderType: gl.getUniformLocation( program, "renderType" ),
map: gl.getUniformLocation( program, "map" ),
occlusionMap: gl.getUniformLocation( program, "occlusionMap" ),
opacity: gl.getUniformLocation( program, "opacity" ),
color: gl.getUniformLocation( program, "color" ),
scale: gl.getUniformLocation( program, "scale" ),
rotation: gl.getUniformLocation( program, "rotation" ),
screenPosition: gl.getUniformLocation( program, "screenPosition" )
};
}
/*
* Render lens flares
* Method: renders 16x16 0xff00ff-colored points scattered over the light source area,
* reads these back and calculates occlusion.
*/
this.render = function ( scene, camera, viewport ) {
if ( flares.length === 0 ) return;
var tempPosition = new Vector3();
var invAspect = viewport.w / viewport.z,
halfViewportWidth = viewport.z * 0.5,
halfViewportHeight = viewport.w * 0.5;
var size = 16 / viewport.w,
scale = new Vector2( size * invAspect, size );
var screenPosition = new Vector3( 1, 1, 0 ),
screenPositionPixels = new Vector2( 1, 1 );
var validArea = new Box2();
validArea.min.set( viewport.x, viewport.y );
validArea.max.set( viewport.x + ( viewport.z - 16 ), viewport.y + ( viewport.w - 16 ) );
if ( program === undefined ) {
init();
}
gl.useProgram( program );
state.initAttributes();
state.enableAttribute( attributes.vertex );
state.enableAttribute( attributes.uv );
state.disableUnusedAttributes();
// loop through all lens flares to update their occlusion and positions
// setup gl and common used attribs/uniforms
gl.uniform1i( uniforms.occlusionMap, 0 );
gl.uniform1i( uniforms.map, 1 );
gl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );
gl.vertexAttribPointer( attributes.vertex, 2, gl.FLOAT, false, 2 * 8, 0 );
gl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );
gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );
state.disable( gl.CULL_FACE );
state.buffers.depth.setMask( false );
for ( var i = 0, l = flares.length; i < l; i ++ ) {
size = 16 / viewport.w;
scale.set( size * invAspect, size );
// calc object screen position
var flare = flares[ i ];
tempPosition.set( flare.matrixWorld.elements[ 12 ], flare.matrixWorld.elements[ 13 ], flare.matrixWorld.elements[ 14 ] );
tempPosition.applyMatrix4( camera.matrixWorldInverse );
tempPosition.applyMatrix4( camera.projectionMatrix );
// setup arrays for gl programs
screenPosition.copy( tempPosition );
// horizontal and vertical coordinate of the lower left corner of the pixels to copy
screenPositionPixels.x = viewport.x + ( screenPosition.x * halfViewportWidth ) + halfViewportWidth - 8;
screenPositionPixels.y = viewport.y + ( screenPosition.y * halfViewportHeight ) + halfViewportHeight - 8;
// screen cull
if ( validArea.containsPoint( screenPositionPixels ) === true ) {
// save current RGB to temp texture
state.activeTexture( gl.TEXTURE0 );
state.bindTexture( gl.TEXTURE_2D, null );
state.activeTexture( gl.TEXTURE1 );
state.bindTexture( gl.TEXTURE_2D, tempTexture );
gl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGB, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );
// render pink quad
gl.uniform1i( uniforms.renderType, 0 );
gl.uniform2f( uniforms.scale, scale.x, scale.y );
gl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );
state.disable( gl.BLEND );
state.enable( gl.DEPTH_TEST );
gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );
// copy result to occlusionMap
state.activeTexture( gl.TEXTURE0 );
state.bindTexture( gl.TEXTURE_2D, occlusionTexture );
gl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );
// restore graphics
gl.uniform1i( uniforms.renderType, 1 );
state.disable( gl.DEPTH_TEST );
state.activeTexture( gl.TEXTURE1 );
state.bindTexture( gl.TEXTURE_2D, tempTexture );
gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );
// update object positions
flare.positionScreen.copy( screenPosition );
if ( flare.customUpdateCallback ) {
flare.customUpdateCallback( flare );
} else {
flare.updateLensFlares();
}
// render flares
gl.uniform1i( uniforms.renderType, 2 );
state.enable( gl.BLEND );
for ( var j = 0, jl = flare.lensFlares.length; j < jl; j ++ ) {
var sprite = flare.lensFlares[ j ];
if ( sprite.opacity > 0.001 && sprite.scale > 0.001 ) {
screenPosition.x = sprite.x;
screenPosition.y = sprite.y;
screenPosition.z = sprite.z;
size = sprite.size * sprite.scale / viewport.w;
scale.x = size * invAspect;
scale.y = size;
gl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );
gl.uniform2f( uniforms.scale, scale.x, scale.y );
gl.uniform1f( uniforms.rotation, sprite.rotation );
gl.uniform1f( uniforms.opacity, sprite.opacity );
gl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );
state.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );
renderer.setTexture2D( sprite.texture, 1 );
gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );
}
}
}
}
// restore gl
state.enable( gl.CULL_FACE );
state.enable( gl.DEPTH_TEST );
state.buffers.depth.setMask( true );
renderer.resetGLState();
};
function createProgram( shader ) {
var program = gl.createProgram();
var fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );
var vertexShader = gl.createShader( gl.VERTEX_SHADER );
var prefix = "precision " + renderer.getPrecision() + " float;\n";
gl.shaderSource( fragmentShader, prefix + shader.fragmentShader );
gl.shaderSource( vertexShader, prefix + shader.vertexShader );
gl.compileShader( fragmentShader );
gl.compileShader( vertexShader );
gl.attachShader( program, fragmentShader );
gl.attachShader( program, vertexShader );
gl.linkProgram( program );
return program;
}
}
/**
* @author mikael emtinger / http://gomo.se/
* @author alteredq / http://alteredqualia.com/
*/
function SpritePlugin( renderer, sprites ) {
var gl = renderer.context;
var state = renderer.state;
var vertexBuffer, elementBuffer;
var program, attributes, uniforms;
var texture;
// decompose matrixWorld
var spritePosition = new Vector3();
var spriteRotation = new Quaternion();
var spriteScale = new Vector3();
function init() {
var vertices = new Float32Array( [
- 0.5, - 0.5, 0, 0,
0.5, - 0.5, 1, 0,
0.5, 0.5, 1, 1,
- 0.5, 0.5, 0, 1
] );
var faces = new Uint16Array( [
0, 1, 2,
0, 2, 3
] );
vertexBuffer = gl.createBuffer();
elementBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );
gl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );
gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );
gl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );
program = createProgram();
attributes = {
position: gl.getAttribLocation ( program, 'position' ),
uv: gl.getAttribLocation ( program, 'uv' )
};
uniforms = {
uvOffset: gl.getUniformLocation( program, 'uvOffset' ),
uvScale: gl.getUniformLocation( program, 'uvScale' ),
rotation: gl.getUniformLocation( program, 'rotation' ),
scale: gl.getUniformLocation( program, 'scale' ),
color: gl.getUniformLocation( program, 'color' ),
map: gl.getUniformLocation( program, 'map' ),
opacity: gl.getUniformLocation( program, 'opacity' ),
modelViewMatrix: gl.getUniformLocation( program, 'modelViewMatrix' ),
projectionMatrix: gl.getUniformLocation( program, 'projectionMatrix' ),
fogType: gl.getUniformLocation( program, 'fogType' ),
fogDensity: gl.getUniformLocation( program, 'fogDensity' ),
fogNear: gl.getUniformLocation( program, 'fogNear' ),
fogFar: gl.getUniformLocation( program, 'fogFar' ),
fogColor: gl.getUniformLocation( program, 'fogColor' ),
alphaTest: gl.getUniformLocation( program, 'alphaTest' )
};
var canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );
canvas.width = 8;
canvas.height = 8;
var context = canvas.getContext( '2d' );
context.fillStyle = 'white';
context.fillRect( 0, 0, 8, 8 );
texture = new Texture( canvas );
texture.needsUpdate = true;
}
this.render = function ( scene, camera ) {
if ( sprites.length === 0 ) return;
// setup gl
if ( program === undefined ) {
init();
}
gl.useProgram( program );
state.initAttributes();
state.enableAttribute( attributes.position );
state.enableAttribute( attributes.uv );
state.disableUnusedAttributes();
state.disable( gl.CULL_FACE );
state.enable( gl.BLEND );
gl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );
gl.vertexAttribPointer( attributes.position, 2, gl.FLOAT, false, 2 * 8, 0 );
gl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );
gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );
gl.uniformMatrix4fv( uniforms.projectionMatrix, false, camera.projectionMatrix.elements );
state.activeTexture( gl.TEXTURE0 );
gl.uniform1i( uniforms.map, 0 );
var oldFogType = 0;
var sceneFogType = 0;
var fog = scene.fog;
if ( fog ) {
gl.uniform3f( uniforms.fogColor, fog.color.r, fog.color.g, fog.color.b );
if ( fog.isFog ) {
gl.uniform1f( uniforms.fogNear, fog.near );
gl.uniform1f( uniforms.fogFar, fog.far );
gl.uniform1i( uniforms.fogType, 1 );
oldFogType = 1;
sceneFogType = 1;
} else if ( fog.isFogExp2 ) {
gl.uniform1f( uniforms.fogDensity, fog.density );
gl.uniform1i( uniforms.fogType, 2 );
oldFogType = 2;
sceneFogType = 2;
}
} else {
gl.uniform1i( uniforms.fogType, 0 );
oldFogType = 0;
sceneFogType = 0;
}
// update positions and sort
for ( var i = 0, l = sprites.length; i < l; i ++ ) {
var sprite = sprites[ i ];
sprite.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, sprite.matrixWorld );
sprite.z = - sprite.modelViewMatrix.elements[ 14 ];
}
sprites.sort( painterSortStable );
// render all sprites
var scale = [];
for ( var i = 0, l = sprites.length; i < l; i ++ ) {
var sprite = sprites[ i ];
var material = sprite.material;
if ( material.visible === false ) continue;
sprite.onBeforeRender( renderer, scene, camera, undefined, material, undefined );
gl.uniform1f( uniforms.alphaTest, material.alphaTest );
gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, sprite.modelViewMatrix.elements );
sprite.matrixWorld.decompose( spritePosition, spriteRotation, spriteScale );
scale[ 0 ] = spriteScale.x;
scale[ 1 ] = spriteScale.y;
var fogType = 0;
if ( scene.fog && material.fog ) {
fogType = sceneFogType;
}
if ( oldFogType !== fogType ) {
gl.uniform1i( uniforms.fogType, fogType );
oldFogType = fogType;
}
if ( material.map !== null ) {
gl.uniform2f( uniforms.uvOffset, material.map.offset.x, material.map.offset.y );
gl.uniform2f( uniforms.uvScale, material.map.repeat.x, material.map.repeat.y );
} else {
gl.uniform2f( uniforms.uvOffset, 0, 0 );
gl.uniform2f( uniforms.uvScale, 1, 1 );
}
gl.uniform1f( uniforms.opacity, material.opacity );
gl.uniform3f( uniforms.color, material.color.r, material.color.g, material.color.b );
gl.uniform1f( uniforms.rotation, material.rotation );
gl.uniform2fv( uniforms.scale, scale );
state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha );
state.buffers.depth.setTest( material.depthTest );
state.buffers.depth.setMask( material.depthWrite );
if ( material.map ) {
renderer.setTexture2D( material.map, 0 );
} else {
renderer.setTexture2D( texture, 0 );
}
gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );
sprite.onAfterRender( renderer, scene, camera, undefined, material, undefined );
}
// restore gl
state.enable( gl.CULL_FACE );
renderer.resetGLState();
};
function createProgram() {
var program = gl.createProgram();
var vertexShader = gl.createShader( gl.VERTEX_SHADER );
var fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );
gl.shaderSource( vertexShader, [
'precision ' + renderer.getPrecision() + ' float;',
'#define SHADER_NAME ' + 'SpriteMaterial',
'uniform mat4 modelViewMatrix;',
'uniform mat4 projectionMatrix;',
'uniform float rotation;',
'uniform vec2 scale;',
'uniform vec2 uvOffset;',
'uniform vec2 uvScale;',
'attribute vec2 position;',
'attribute vec2 uv;',
'varying vec2 vUV;',
'void main() {',
'vUV = uvOffset + uv * uvScale;',
'vec2 alignedPosition = position * scale;',
'vec2 rotatedPosition;',
'rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;',
'rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;',
'vec4 finalPosition;',
'finalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );',
'finalPosition.xy += rotatedPosition;',
'finalPosition = projectionMatrix * finalPosition;',
'gl_Position = finalPosition;',
'}'
].join( '\n' ) );
gl.shaderSource( fragmentShader, [
'precision ' + renderer.getPrecision() + ' float;',
'#define SHADER_NAME ' + 'SpriteMaterial',
'uniform vec3 color;',
'uniform sampler2D map;',
'uniform float opacity;',
'uniform int fogType;',
'uniform vec3 fogColor;',
'uniform float fogDensity;',
'uniform float fogNear;',
'uniform float fogFar;',
'uniform float alphaTest;',
'varying vec2 vUV;',
'void main() {',
'vec4 texture = texture2D( map, vUV );',
'if ( texture.a < alphaTest ) discard;',
'gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );',
'if ( fogType > 0 ) {',
'float depth = gl_FragCoord.z / gl_FragCoord.w;',
'float fogFactor = 0.0;',
'if ( fogType == 1 ) {',
'fogFactor = smoothstep( fogNear, fogFar, depth );',
'} else {',
'const float LOG2 = 1.442695;',
'fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );',
'fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );',
'}',
'gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );',
'}',
'}'
].join( '\n' ) );
gl.compileShader( vertexShader );
gl.compileShader( fragmentShader );
gl.attachShader( program, vertexShader );
gl.attachShader( program, fragmentShader );
gl.linkProgram( program );
return program;
}
function painterSortStable( a, b ) {
if ( a.renderOrder !== b.renderOrder ) {
return a.renderOrder - b.renderOrder;
} else if ( a.z !== b.z ) {
return b.z - a.z;
} else {
return b.id - a.id;
}
}
}
/**
* @author mrdoob / http://mrdoob.com/
* @author alteredq / http://alteredqualia.com/
*/
var materialId = 0;
function Material() {
Object.defineProperty( this, 'id', { value: materialId ++ } );
this.uuid = _Math.generateUUID();
this.name = '';
this.type = 'Material';
this.fog = true;
this.lights = true;
this.blending = NormalBlending;
this.side = FrontSide;
this.shading = SmoothShading; // THREE.FlatShading, THREE.SmoothShading
this.vertexColors = NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors
this.opacity = 1;
this.transparent = false;
this.blendSrc = SrcAlphaFactor;
this.blendDst = OneMinusSrcAlphaFactor;
this.blendEquation = AddEquation;
this.blendSrcAlpha = null;
this.blendDstAlpha = null;
this.blendEquationAlpha = null;
this.depthFunc = LessEqualDepth;
this.depthTest = true;
this.depthWrite = true;
this.clippingPlanes = null;
this.clipIntersection = false;
this.clipShadows = false;
this.colorWrite = true;
this.precision = null; // override the renderer's default precision for this material
this.polygonOffset = false;
this.polygonOffsetFactor = 0;
this.polygonOffsetUnits = 0;
this.dithering = false;
this.alphaTest = 0;
this.premultipliedAlpha = false;
this.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing antialiasing gaps in CanvasRenderer
this.visible = true;
this.needsUpdate = true;
}
Object.assign( Material.prototype, EventDispatcher.prototype, {
isMaterial: true,
onBeforeCompile: function () {},
setValues: function ( values ) {
if ( values === undefined ) return;
for ( var key in values ) {
var newValue = values[ key ];
if ( newValue === undefined ) {
console.warn( "THREE.Material: '" + key + "' parameter is undefined." );
continue;
}
var currentValue = this[ key ];
if ( currentValue === undefined ) {
console.warn( "THREE." + this.type + ": '" + key + "' is not a property of this material." );
continue;
}
if ( currentValue && currentValue.isColor ) {
currentValue.set( newValue );
} else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) {
currentValue.copy( newValue );
} else if ( key === 'overdraw' ) {
// ensure overdraw is backwards-compatible with legacy boolean type
this[ key ] = Number( newValue );
} else {
this[ key ] = newValue;
}
}
},
toJSON: function ( meta ) {
var isRoot = meta === undefined;
if ( isRoot ) {
meta = {
textures: {},
images: {}
};
}
var data = {
metadata: {
version: 4.5,
type: 'Material',
generator: 'Material.toJSON'
}
};
// standard Material serialization
data.uuid = this.uuid;
data.type = this.type;
if ( this.name !== '' ) data.name = this.name;
if ( this.color && this.color.isColor ) data.color = this.color.getHex();
if ( this.roughness !== undefined ) data.roughness = this.roughness;
if ( this.metalness !== undefined ) data.metalness = this.metalness;
if ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex();
if ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex();
if ( this.shininess !== undefined ) data.shininess = this.shininess;
if ( this.clearCoat !== undefined ) data.clearCoat = this.clearCoat;
if ( this.clearCoatRoughness !== undefined ) data.clearCoatRoughness = this.clearCoatRoughness;
if ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid;
if ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;
if ( this.lightMap && this.lightMap.isTexture ) data.lightMap = this.lightMap.toJSON( meta ).uuid;
if ( this.bumpMap && this.bumpMap.isTexture ) {
data.bumpMap = this.bumpMap.toJSON( meta ).uuid;
data.bumpScale = this.bumpScale;
}
if ( this.normalMap && this.normalMap.isTexture ) {
data.normalMap = this.normalMap.toJSON( meta ).uuid;
data.normalScale = this.normalScale.toArray();
}
if ( this.displacementMap && this.displacementMap.isTexture ) {
data.displacementMap = this.displacementMap.toJSON( meta ).uuid;
data.displacementScale = this.displacementScale;
data.displacementBias = this.displacementBias;
}
if ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;
if ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;
if ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;
if ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid;
if ( this.envMap && this.envMap.isTexture ) {
data.envMap = this.envMap.toJSON( meta ).uuid;
data.reflectivity = this.reflectivity; // Scale behind envMap
}
if ( this.gradientMap && this.gradientMap.isTexture ) {
data.gradientMap = this.gradientMap.toJSON( meta ).uuid;
}
if ( this.size !== undefined ) data.size = this.size;
if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;
if ( this.blending !== NormalBlending ) data.blending = this.blending;
if ( this.shading !== SmoothShading ) data.shading = this.shading;
if ( this.side !== FrontSide ) data.side = this.side;
if ( this.vertexColors !== NoColors ) data.vertexColors = this.vertexColors;
if ( this.opacity < 1 ) data.opacity = this.opacity;
if ( this.transparent === true ) data.transparent = this.transparent;
data.depthFunc = this.depthFunc;
data.depthTest = this.depthTest;
data.depthWrite = this.depthWrite;
if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;
if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha;
if ( this.wireframe === true ) data.wireframe = this.wireframe;
if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;
if ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;
if ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;
data.skinning = this.skinning;
data.morphTargets = this.morphTargets;
data.dithering = this.dithering;
// TODO: Copied from Object3D.toJSON
function extractFromCache( cache ) {
var values = [];
for ( var key in cache ) {
var data = cache[ key ];
delete data.metadata;
values.push( data );
}
return values;
}
if ( isRoot ) {
var textures = extractFromCache( meta.textures );
var images = extractFromCache( meta.images );
if ( textures.length > 0 ) data.textures = textures;
if ( images.length > 0 ) data.images = images;
}
return data;
},
clone: function () {
return new this.constructor().copy( this );
},
copy: function ( source ) {
this.name = source.name;
this.fog = source.fog;
this.lights = source.lights;
this.blending = source.blending;
this.side = source.side;
this.shading = source.shading;
this.vertexColors = source.vertexColors;
this.opacity = source.opacity;
this.transparent = source.transparent;
this.blendSrc = source.blendSrc;
this.blendDst = source.blendDst;
this.blendEquation = source.blendEquation;
this.blendSrcAlpha = source.blendSrcAlpha;
this.blendDstAlpha = source.blendDstAlpha;
this.blendEquationAlpha = source.blendEquationAlpha;
this.depthFunc = source.depthFunc;
this.depthTest = source.depthTest;
this.depthWrite = source.depthWrite;
this.colorWrite = source.colorWrite;
this.precision = source.precision;
this.polygonOffset = source.polygonOffset;
this.polygonOffsetFactor = source.polygonOffsetFactor;
this.polygonOffsetUnits = source.polygonOffsetUnits;
this.dithering = source.dithering;
this.alphaTest = source.alphaTest;
this.premultipliedAlpha = source.premultipliedAlpha;
this.overdraw = source.overdraw;
this.visible = source.visible;
this.clipShadows = source.clipShadows;
this.clipIntersection = source.clipIntersection;
var srcPlanes = source.clippingPlanes,
dstPlanes = null;
if ( srcPlanes !== null ) {
var n = srcPlanes.length;
dstPlanes = new Array( n );
for ( var i = 0; i !== n; ++ i )
dstPlanes[ i ] = srcPlanes[ i ].clone();
}
this.clippingPlanes = dstPlanes;
return this;
},
dispose: function () {
this.dispatchEvent( { type: 'dispose' } );
}
} );
/**
* @author alteredq / http://alteredqualia.com/
*
* parameters = {
* defines: { "label" : "value" },
* uniforms: { "parameter1": { value: 1.0 }, "parameter2": { value2: 2 } },
*
* fragmentShader: <string>,
* vertexShader: <string>,
*
* wireframe: <boolean>,
* wireframeLinewidth: <float>,
*
* lights: <bool>,
*
* skinning: <bool>,
* morphTargets: <bool>,
* morphNormals: <bool>
* }
*/
function ShaderMaterial( parameters ) {
Material.call( this );
this.type = 'ShaderMaterial';
this.defines = {};
this.uniforms = {};
this.vertexShader = 'void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}';
this.fragmentShader = 'void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}';
this.linewidth = 1;
this.wireframe = false;
this.wireframeLinewidth = 1;
this.fog = false; // set to use scene fog
this.lights = false; // set to use scene lights
this.clipping = false; // set to use user-defined clipping planes
this.skinning = false; // set to use skinning attribute streams
this.morphTargets = false; // set to use morph targets
this.morphNormals = false; // set to use morph normals
this.extensions = {
derivatives: false, // set to use derivatives
fragDepth: false, // set to use fragment depth values
drawBuffers: false, // set to use draw buffers
shaderTextureLOD: false // set to use shader texture LOD
};
// When rendered geometry doesn't include these attributes but the material does,
// use these default values in WebGL. This avoids errors when buffer data is missing.
this.defaultAttributeValues = {
'color': [ 1, 1, 1 ],
'uv': [ 0, 0 ],
'uv2': [ 0, 0 ]
};
this.index0AttributeName = undefined;
if ( parameters !== undefined ) {
if ( parameters.attributes !== undefined ) {
console.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' );
}
this.setValues( parameters );
}
}
ShaderMaterial.prototype = Object.create( Material.prototype );
ShaderMaterial.prototype.constructor = ShaderMaterial;
ShaderMaterial.prototype.isShaderMaterial = true;
ShaderMaterial.prototype.copy = function ( source ) {
Material.prototype.copy.call( this, source );
this.fragmentShader = source.fragmentShader;
this.vertexShader = source.vertexShader;
this.uniforms = UniformsUtils.clone( source.uniforms );
this.defines = source.defines;
this.wireframe = source.wireframe;
this.wireframeLinewidth = source.wireframeLinewidth;
this.lights = source.lights;
this.clipping = source.clipping;
this.skinning = source.skinning;
this.morphTargets = source.morphTargets;
this.morphNormals = source.morphNormals;
this.extensions = source.extensions;
return this;
};
ShaderMaterial.prototype.toJSON = function ( meta ) {
var data = Material.prototype.toJSON.call( this, meta );
data.uniforms = this.uniforms;
data.vertexShader = this.vertexShader;
data.fragmentShader = this.fragmentShader;
return data;
};
/**
* @author mrdoob / http://mrdoob.com/
* @author alteredq / http://alteredqualia.com/
* @author bhouston / https://clara.io
* @author WestLangley / http://github.com/WestLangley
*
* parameters = {
*
* opacity: <float>,
*
* map: new THREE.Texture( <Image> ),
*
* alphaMap: new THREE.Texture( <Image> ),
*
* displacementMap: new THREE.Texture( <Image> ),
* displacementScale: <float>,
* displacementBias: <float>,
*
* wireframe: <boolean>,
* wireframeLinewidth: <float>
* }
*/
function MeshDepthMaterial( parameters ) {
Material.call( this );
this.type = 'MeshDepthMaterial';
this.depthPacking = BasicDepthPacking;
this.skinning = false;
this.morphTargets = false;
this.map = null;
this.alphaMap = null;
this.displacementMap = null;
this.displacementScale = 1;
this.displacementBias = 0;
this.wireframe = false;
this.wireframeLinewidth = 1;
this.fog = false;
this.lights = false;
this.setValues( parameters );
}
MeshDepthMaterial.prototype = Object.create( Material.prototype );
MeshDepthMaterial.prototype.constructor = MeshDepthMaterial;
MeshDepthMaterial.prototype.isMeshDepthMaterial = true;
MeshDepthMaterial.prototype.copy = function ( source ) {
Material.prototype.copy.call( this, source );
this.depthPacking = source.depthPacking;
this.skinning = source.skinning;
this.morphTargets = source.morphTargets;
this.map = source.map;
this.alphaMap = source.alphaMap;
this.displacementMap = source.displacementMap;
this.displacementScale = source.displacementScale;
this.displacementBias = source.displacementBias;
this.wireframe = source.wireframe;
this.wireframeLinewidth = source.wireframeLinewidth;
return this;
};
/**
* @author bhouston / http://clara.io
* @author WestLangley / http://github.com/WestLangley
*/
function Box3( min, max ) {
this.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity );
this.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity );
}
Object.assign( Box3.prototype, {
isBox3: true,
set: function ( min, max ) {
this.min.copy( min );
this.max.copy( max );
return this;
},
setFromArray: function ( array ) {
var minX = + Infinity;
var minY = + Infinity;
var minZ = + Infinity;
var maxX = - Infinity;
var maxY = - Infinity;
var maxZ = - Infinity;
for ( var i = 0, l = array.length; i < l; i += 3 ) {
var x = array[ i ];
var y = array[ i + 1 ];
var z = array[ i + 2 ];
if ( x < minX ) minX = x;
if ( y < minY ) minY = y;
if ( z < minZ ) minZ = z;
if ( x > maxX ) maxX = x;
if ( y > maxY ) maxY = y;
if ( z > maxZ ) maxZ = z;
}
this.min.set( minX, minY, minZ );
this.max.set( maxX, maxY, maxZ );
return this;
},
setFromBufferAttribute: function ( attribute ) {
var minX = + Infinity;
var minY = + Infinity;
var minZ = + Infinity;
var maxX = - Infinity;
var maxY = - Infinity;
var maxZ = - Infinity;
for ( var i = 0, l = attribute.count; i < l; i ++ ) {
var x = attribute.getX( i );
var y = attribute.getY( i );
var z = attribute.getZ( i );
if ( x < minX ) minX = x;
if ( y < minY ) minY = y;
if ( z < minZ ) minZ = z;
if ( x > maxX ) maxX = x;
if ( y > maxY ) maxY = y;
if ( z > maxZ ) maxZ = z;
}
this.min.set( minX, minY, minZ );
this.max.set( maxX, maxY, maxZ );
return this;
},
setFromPoints: function ( points ) {
this.makeEmpty();
for ( var i = 0, il = points.length; i < il; i ++ ) {
this.expandByPoint( points[ i ] );
}
return this;
},
setFromCenterAndSize: function () {
var v1 = new Vector3();
return function setFromCenterAndSize( center, size ) {
var halfSize = v1.copy( size ).multiplyScalar( 0.5 );
this.min.copy( center ).sub( halfSize );
this.max.copy( center ).add( halfSize );
return this;
};
}(),
setFromObject: function ( object ) {
this.makeEmpty();
return this.expandByObject( object );
},
clone: function () {
return new this.constructor().copy( this );
},
copy: function ( box ) {
this.min.copy( box.min );
this.max.copy( box.max );
return this;
},
makeEmpty: function () {
this.min.x = this.min.y = this.min.z = + Infinity;
this.max.x = this.max.y = this.max.z = - Infinity;
return this;
},
isEmpty: function () {
// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes
return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z );
},
getCenter: function ( optionalTarget ) {
var result = optionalTarget || new Vector3();
return this.isEmpty() ? result.set( 0, 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );
},
getSize: function ( optionalTarget ) {
var result = optionalTarget || new Vector3();
return this.isEmpty() ? result.set( 0, 0, 0 ) : result.subVectors( this.max, this.min );
},
expandByPoint: function ( point ) {
this.min.min( point );
this.max.max( point );
return this;
},
expandByVector: function ( vector ) {
this.min.sub( vector );
this.max.add( vector );
return this;
},
expandByScalar: function ( scalar ) {
this.min.addScalar( - scalar );
this.max.addScalar( scalar );
return this;
},
expandByObject: function () {
// Computes the world-axis-aligned bounding box of an object (including its children),
// accounting for both the object's, and children's, world transforms
var v1 = new Vector3();
return function expandByObject( object ) {
var scope = this;
object.updateMatrixWorld( true );
object.traverse( function ( node ) {
var i, l;
var geometry = node.geometry;
if ( geometry !== undefined ) {
if ( geometry.isGeometry ) {
var vertices = geometry.vertices;
for ( i = 0, l = vertices.length; i < l; i ++ ) {
v1.copy( vertices[ i ] );
v1.applyMatrix4( node.matrixWorld );
scope.expandByPoint( v1 );
}
} else if ( geometry.isBufferGeometry ) {
var attribute = geometry.attributes.position;
if ( attribute !== undefined ) {
for ( i = 0, l = attribute.count; i < l; i ++ ) {
v1.fromBufferAttribute( attribute, i ).applyMatrix4( node.matrixWorld );
scope.expandByPoint( v1 );
}
}
}
}
} );
return this;
};
}(),
containsPoint: function ( point ) {
return point.x < this.min.x || point.x > this.max.x ||
point.y < this.min.y || point.y > this.max.y ||
point.z < this.min.z || point.z > this.max.z ? false : true;
},
containsBox: function ( box ) {
return this.min.x <= box.min.x && box.max.x <= this.max.x &&
this.min.y <= box.min.y && box.max.y <= this.max.y &&
this.min.z <= box.min.z && box.max.z <= this.max.z;
},
getParameter: function ( point, optionalTarget ) {
// This can potentially have a divide by zero if the box
// has a size dimension of 0.
var result = optionalTarget || new Vector3();
return result.set(
( point.x - this.min.x ) / ( this.max.x - this.min.x ),
( point.y - this.min.y ) / ( this.max.y - this.min.y ),
( point.z - this.min.z ) / ( this.max.z - this.min.z )
);
},
intersectsBox: function ( box ) {
// using 6 splitting planes to rule out intersections.
return box.max.x < this.min.x || box.min.x > this.max.x ||
box.max.y < this.min.y || box.min.y > this.max.y ||
box.max.z < this.min.z || box.min.z > this.max.z ? false : true;
},
intersectsSphere: ( function () {
var closestPoint = new Vector3();
return function intersectsSphere( sphere ) {
// Find the point on the AABB closest to the sphere center.
this.clampPoint( sphere.center, closestPoint );
// If that point is inside the sphere, the AABB and sphere intersect.
return closestPoint.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );
};
} )(),
intersectsPlane: function ( plane ) {
// We compute the minimum and maximum dot product values. If those values
// are on the same side (back or front) of the plane, then there is no intersection.
var min, max;
if ( plane.normal.x > 0 ) {
min = plane.normal.x * this.min.x;
max = plane.normal.x * this.max.x;
} else {
min = plane.normal.x * this.max.x;
max = plane.normal.x * this.min.x;
}
if ( plane.normal.y > 0 ) {
min += plane.normal.y * this.min.y;
max += plane.normal.y * this.max.y;
} else {
min += plane.normal.y * this.max.y;
max += plane.normal.y * this.min.y;
}
if ( plane.normal.z > 0 ) {
min += plane.normal.z * this.min.z;
max += plane.normal.z * this.max.z;
} else {
min += plane.normal.z * this.max.z;
max += plane.normal.z * this.min.z;
}
return ( min <= plane.constant && max >= plane.constant );
},
clampPoint: function ( point, optionalTarget ) {
var result = optionalTarget || new Vector3();
return result.copy( point ).clamp( this.min, this.max );
},
distanceToPoint: function () {
var v1 = new Vector3();
return function distanceToPoint( point ) {
var clampedPoint = v1.copy( point ).clamp( this.min, this.max );
return clampedPoint.sub( point ).length();
};
}(),
getBoundingSphere: function () {
var v1 = new Vector3();
return function getBoundingSphere( optionalTarget ) {
var result = optionalTarget || new Sphere();
this.getCenter( result.center );
result.radius = this.getSize( v1 ).length() * 0.5;
return result;
};
}(),
intersect: function ( box ) {
this.min.max( box.min );
this.max.min( box.max );
// ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values.
if( this.isEmpty() ) this.makeEmpty();
return this;
},
union: function ( box ) {
this.min.min( box.min );
this.max.max( box.max );
return this;
},
applyMatrix4: function () {
var points = [
new Vector3(),
new Vector3(),
new Vector3(),
new Vector3(),
new Vector3(),
new Vector3(),
new Vector3(),
new Vector3()
];
return function applyMatrix4( matrix ) {
// transform of empty box is an empty box.
if( this.isEmpty() ) return this;
// NOTE: I am using a binary pattern to specify all 2^3 combinations below
points[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000
points[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001
points[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010
points[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011
points[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100
points[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101
points[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110
points[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 111
this.setFromPoints( points );
return this;
};
}(),
translate: function ( offset ) {
this.min.add( offset );
this.max.add( offset );
return this;
},
equals: function ( box ) {
return box.min.equals( this.min ) && box.max.equals( this.max );
}
} );
/**
* @author bhouston / http://clara.io
* @author mrdoob / http://mrdoob.com/
*/
function Sphere( center, radius ) {
this.center = ( center !== undefined ) ? center : new Vector3();
this.radius = ( radius !== undefined ) ? radius : 0;
}
Object.assign( Sphere.prototype, {
set: function ( center, radius ) {
this.center.copy( center );
this.radius = radius;
return this;
},
setFromPoints: function () {
var box = new Box3();
return function setFromPoints( points, optionalCenter ) {
var center = this.center;
if ( optionalCenter !== undefined ) {
center.copy( optionalCenter );
} else {
box.setFromPoints( points ).getCenter( center );
}
var maxRadiusSq = 0;
for ( var i = 0, il = points.length; i < il; i ++ ) {
maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );
}
this.radius = Math.sqrt( maxRadiusSq );
return this;
};
}(),
clone: function () {
return new this.constructor().copy( this );
},
copy: function ( sphere ) {
this.center.copy( sphere.center );
this.radius = sphere.radius;
return this;
},
empty: function () {
return ( this.radius <= 0 );
},
containsPoint: function ( point ) {
return ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) );
},
distanceToPoint: function ( point ) {
return ( point.distanceTo( this.center ) - this.radius );
},
intersectsSphere: function ( sphere ) {
var radiusSum = this.radius + sphere.radius;
return sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum );
},
intersectsBox: function ( box ) {
return box.intersectsSphere( this );
},
intersectsPlane: function ( plane ) {
// We use the following equation to compute the signed distance from
// the center of the sphere to the plane.
//
// distance = q * n - d
//
// If this distance is greater than the radius of the sphere,
// then there is no intersection.
return Math.abs( this.center.dot( plane.normal ) - plane.constant ) <= this.radius;
},
clampPoint: function ( point, optionalTarget ) {
var deltaLengthSq = this.center.distanceToSquared( point );
var result = optionalTarget || new Vector3();
result.copy( point );
if ( deltaLengthSq > ( this.radius * this.radius ) ) {
result.sub( this.center ).normalize();
result.multiplyScalar( this.radius ).add( this.center );
}
return result;
},
getBoundingBox: function ( optionalTarget ) {
var box = optionalTarget || new Box3();
box.set( this.center, this.center );
box.expandByScalar( this.radius );
return box;
},
applyMatrix4: function ( matrix ) {
this.center.applyMatrix4( matrix );
this.radius = this.radius * matrix.getMaxScaleOnAxis();
return this;
},
translate: function ( offset ) {
this.center.add( offset );
return this;
},
equals: function ( sphere ) {
return sphere.center.equals( this.center ) && ( sphere.radius === this.radius );
}
} );
/**
* @author alteredq / http://alteredqualia.com/
* @author WestLangley / http://github.com/WestLangley
* @author bhouston / http://clara.io
* @author tschw
*/
function Matrix3() {
this.elements = [
1, 0, 0,
0, 1, 0,
0, 0, 1
];
if ( arguments.length > 0 ) {
console.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );
}
}
Object.assign( Matrix3.prototype, {
isMatrix3: true,
set: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {
var te = this.elements;
te[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;
te[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;
te[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;
return this;
},
identity: function () {
this.set(
1, 0, 0,
0, 1, 0,
0, 0, 1
);
return this;
},
clone: function () {
return new this.constructor().fromArray( this.elements );
},
copy: function ( m ) {
var te = this.elements;
var me = m.elements;
te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ];
te[ 3 ] = me[ 3 ]; te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ];
te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; te[ 8 ] = me[ 8 ];
return this;
},
setFromMatrix4: function ( m ) {
var me = m.elements;
this.set(
me[ 0 ], me[ 4 ], me[ 8 ],
me[ 1 ], me[ 5 ], me[ 9 ],
me[ 2 ], me[ 6 ], me[ 10 ]
);
return this;
},
applyToBufferAttribute: function () {
var v1 = new Vector3();
return function applyToBufferAttribute( attribute ) {
for ( var i = 0, l = attribute.count; i < l; i ++ ) {
v1.x = attribute.getX( i );
v1.y = attribute.getY( i );
v1.z = attribute.getZ( i );
v1.applyMatrix3( this );
attribute.setXYZ( i, v1.x, v1.y, v1.z );
}
return attribute;
};
}(),
multiply: function ( m ) {
return this.multiplyMatrices( this, m );
},
premultiply: function ( m ) {
return this.multiplyMatrices( m, this );
},
multiplyMatrices: function ( a, b ) {
var ae = a.elements;
var be = b.elements;
var te = this.elements;
var a11 = ae[ 0 ], a12 = ae[ 3 ], a13 = ae[ 6 ];
var a21 = ae[ 1 ], a22 = ae[ 4 ], a23 = ae[ 7 ];
var a31 = ae[ 2 ], a32 = ae[ 5 ], a33 = ae[ 8 ];
var b11 = be[ 0 ], b12 = be[ 3 ], b13 = be[ 6 ];
var b21 = be[ 1 ], b22 = be[ 4 ], b23 = be[ 7 ];
var b31 = be[ 2 ], b32 = be[ 5 ], b33 = be[ 8 ];
te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31;
te[ 3 ] = a11 * b12 + a12 * b22 + a13 * b32;
te[ 6 ] = a11 * b13 + a12 * b23 + a13 * b33;
te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31;
te[ 4 ] = a21 * b12 + a22 * b22 + a23 * b32;
te[ 7 ] = a21 * b13 + a22 * b23 + a23 * b33;
te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31;
te[ 5 ] = a31 * b12 + a32 * b22 + a33 * b32;
te[ 8 ] = a31 * b13 + a32 * b23 + a33 * b33;
return this;
},
multiplyScalar: function ( s ) {
var te = this.elements;
te[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;
te[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;
te[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;
return this;
},
determinant: function () {
var te = this.elements;
var a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],
d = te[ 3 ], e = te[ 4 ], f = te[ 5 ],
g = te[ 6 ], h = te[ 7 ], i = te[ 8 ];
return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;
},
getInverse: function ( matrix, throwOnDegenerate ) {
if ( matrix && matrix.isMatrix4 ) {
console.error( "THREE.Matrix3.getInverse no longer takes a Matrix4 argument." );
}
var me = matrix.elements,
te = this.elements,
n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ],
n12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ],
n13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ],
t11 = n33 * n22 - n32 * n23,
t12 = n32 * n13 - n33 * n12,
t13 = n23 * n12 - n22 * n13,
det = n11 * t11 + n21 * t12 + n31 * t13;
if ( det === 0 ) {
var msg = "THREE.Matrix3.getInverse(): can't invert matrix, determinant is 0";
if ( throwOnDegenerate === true ) {
throw new Error( msg );
} else {
console.warn( msg );
}
return this.identity();
}
var detInv = 1 / det;
te[ 0 ] = t11 * detInv;
te[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv;
te[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv;
te[ 3 ] = t12 * detInv;
te[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv;
te[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv;
te[ 6 ] = t13 * detInv;
te[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv;
te[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv;
return this;
},
transpose: function () {
var tmp, m = this.elements;
tmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;
tmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;
tmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;
return this;
},
getNormalMatrix: function ( matrix4 ) {
return this.setFromMatrix4( matrix4 ).getInverse( this ).transpose();
},
transposeIntoArray: function ( r ) {
var m = this.elements;
r[ 0 ] = m[ 0 ];
r[ 1 ] = m[ 3 ];
r[ 2 ] = m[ 6 ];
r[ 3 ] = m[ 1 ];
r[ 4 ] = m[ 4 ];
r[ 5 ] = m[ 7 ];
r[ 6 ] = m[ 2 ];
r[ 7 ] = m[ 5 ];
r[ 8 ] = m[ 8 ];
return this;
},
equals: function ( matrix ) {
var te = this.elements;
var me = matrix.elements;
for ( var i = 0; i < 9; i ++ ) {
if ( te[ i ] !== me[ i ] ) return false;
}
return true;
},
fromArray: function ( array, offset ) {
if ( offset === undefined ) offset = 0;
for ( var i = 0; i < 9; i ++ ) {
this.elements[ i ] = array[ i + offset ];
}
return this;
},
toArray: function ( array, offset ) {
if ( array === undefined ) array = [];
if ( offset === undefined ) offset = 0;
var te = this.elements;
array[ offset ] = te[ 0 ];
array[ offset + 1 ] = te[ 1 ];
array[ offset + 2 ] = te[ 2 ];
array[ offset + 3 ] = te[ 3 ];
array[ offset + 4 ] = te[ 4 ];
array[ offset + 5 ] = te[ 5 ];
array[ offset + 6 ] = te[ 6 ];
array[ offset + 7 ] = te[ 7 ];
array[ offset + 8 ] = te[ 8 ];
return array;
}
} );
/**
* @author bhouston / http://clara.io
*/
function Plane( normal, constant ) {
this.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 );
this.constant = ( constant !== undefined ) ? constant : 0;
}
Object.assign( Plane.prototype, {
set: function ( normal, constant ) {
this.normal.copy( normal );
this.constant = constant;
return this;
},
setComponents: function ( x, y, z, w ) {
this.normal.set( x, y, z );
this.constant = w;
return this;
},
setFromNormalAndCoplanarPoint: function ( normal, point ) {
this.normal.copy( normal );
this.constant = - point.dot( this.normal ); // must be this.normal, not normal, as this.normal is normalized
return this;
},
setFromCoplanarPoints: function () {
var v1 = new Vector3();
var v2 = new Vector3();
return function setFromCoplanarPoints( a, b, c ) {
var normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize();
// Q: should an error be thrown if normal is zero (e.g. degenerate plane)?
this.setFromNormalAndCoplanarPoint( normal, a );
return this;
};
}(),
clone: function () {
return new this.constructor().copy( this );
},
copy: function ( plane ) {
this.normal.copy( plane.normal );
this.constant = plane.constant;
return this;
},
normalize: function () {
// Note: will lead to a divide by zero if the plane is invalid.
var inverseNormalLength = 1.0 / this.normal.length();
this.normal.multiplyScalar( inverseNormalLength );
this.constant *= inverseNormalLength;
return this;
},
negate: function () {
this.constant *= - 1;
this.normal.negate();
return this;
},
distanceToPoint: function ( point ) {
return this.normal.dot( point ) + this.constant;
},
distanceToSphere: function ( sphere ) {
return this.distanceToPoint( sphere.center ) - sphere.radius;
},
projectPoint: function ( point, optionalTarget ) {
return this.orthoPoint( point, optionalTarget ).sub( point ).negate();
},
orthoPoint: function ( point, optionalTarget ) {
var perpendicularMagnitude = this.distanceToPoint( point );
var result = optionalTarget || new Vector3();
return result.copy( this.normal ).multiplyScalar( perpendicularMagnitude );
},
intersectLine: function () {
var v1 = new Vector3();
return function intersectLine( line, optionalTarget ) {
var result = optionalTarget || new Vector3();
var direction = line.delta( v1 );
var denominator = this.normal.dot( direction );
if ( denominator === 0 ) {
// line is coplanar, return origin
if ( this.distanceToPoint( line.start ) === 0 ) {
return result.copy( line.start );
}
// Unsure if this is the correct method to handle this case.
return undefined;
}
var t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;
if ( t < 0 || t > 1 ) {
return undefined;
}
return result.copy( direction ).multiplyScalar( t ).add( line.start );
};
}(),
intersectsLine: function ( line ) {
// Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.
var startSign = this.distanceToPoint( line.start );
var endSign = this.distanceToPoint( line.end );
return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );
},
intersectsBox: function ( box ) {
return box.intersectsPlane( this );
},
intersectsSphere: function ( sphere ) {
return sphere.intersectsPlane( this );
},
coplanarPoint: function ( optionalTarget ) {
var result = optionalTarget || new Vector3();
return result.copy( this.normal ).multiplyScalar( - this.constant );
},
applyMatrix4: function () {
var v1 = new Vector3();
var m1 = new Matrix3();
return function applyMatrix4( matrix, optionalNormalMatrix ) {
var referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix );
// transform normal based on theory here:
// http://www.songho.ca/opengl/gl_normaltransform.html
var normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix );
var normal = this.normal.applyMatrix3( normalMatrix ).normalize();
// recalculate constant (like in setFromNormalAndCoplanarPoint)
this.constant = - referencePoint.dot( normal );
return this;
};
}(),
translate: function ( offset ) {
this.constant = this.constant - offset.dot( this.normal );
return this;
},
equals: function ( plane ) {
return plane.normal.equals( this.normal ) && ( plane.constant === this.constant );
}
} );
/**
* @author mrdoob / http://mrdoob.com/
* @author alteredq / http://alteredqualia.com/
* @author bhouston / http://clara.io
*/
function Frustum( p0, p1, p2, p3, p4, p5 ) {
this.planes = [
( p0 !== undefined ) ? p0 : new Plane(),
( p1 !== undefined ) ? p1 : new Plane(),
( p2 !== undefined ) ? p2 : new Plane(),
( p3 !== undefined ) ? p3 : new Plane(),
( p4 !== undefined ) ? p4 : new Plane(),
( p5 !== undefined ) ? p5 : new Plane()
];
}
Object.assign( Frustum.prototype, {
set: function ( p0, p1, p2, p3, p4, p5 ) {
var planes = this.planes;
planes[ 0 ].copy( p0 );
planes[ 1 ].copy( p1 );
planes[ 2 ].copy( p2 );
planes[ 3 ].copy( p3 );
planes[ 4 ].copy( p4 );
planes[ 5 ].copy( p5 );
return this;
},
clone: function () {
return new this.constructor().copy( this );
},
copy: function ( frustum ) {
var planes = this.planes;
for ( var i = 0; i < 6; i ++ ) {
planes[ i ].copy( frustum.planes[ i ] );
}
return this;
},
setFromMatrix: function ( m ) {
var planes = this.planes;
var me = m.elements;
var me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ];
var me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ];
var me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ];
var me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ];
planes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize();
planes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize();
planes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize();
planes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize();
planes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize();
planes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize();
return this;
},
intersectsObject: function () {
var sphere = new Sphere();
return function intersectsObject( object ) {
var geometry = object.geometry;
if ( geometry.boundingSphere === null )
geometry.computeBoundingSphere();
sphere.copy( geometry.boundingSphere )
.applyMatrix4( object.matrixWorld );
return this.intersectsSphere( sphere );
};
}(),
intersectsSprite: function () {
var sphere = new Sphere();
return function intersectsSprite( sprite ) {
sphere.center.set( 0, 0, 0 );
sphere.radius = 0.7071067811865476;
sphere.applyMatrix4( sprite.matrixWorld );
return this.intersectsSphere( sphere );
};
}(),
intersectsSphere: function ( sphere ) {
var planes = this.planes;
var center = sphere.center;
var negRadius = - sphere.radius;
for ( var i = 0; i < 6; i ++ ) {
var distance = planes[ i ].distanceToPoint( center );
if ( distance < negRadius ) {
return false;
}
}
return true;
},
intersectsBox: function () {
var p1 = new Vector3(),
p2 = new Vector3();
return function intersectsBox( box ) {
var planes = this.planes;
for ( var i = 0; i < 6; i ++ ) {
var plane = planes[ i ];
p1.x = plane.normal.x > 0 ? box.min.x : box.max.x;
p2.x = plane.normal.x > 0 ? box.max.x : box.min.x;
p1.y = plane.normal.y > 0 ? box.min.y : box.max.y;
p2.y = plane.normal.y > 0 ? box.max.y : box.min.y;
p1.z = plane.normal.z > 0 ? box.min.z : box.max.z;
p2.z = plane.normal.z > 0 ? box.max.z : box.min.z;
var d1 = plane.distanceToPoint( p1 );
var d2 = plane.distanceToPoint( p2 );
// if both outside plane, no intersection
if ( d1 < 0 && d2 < 0 ) {
return false;
}
}
return true;
};
}(),
containsPoint: function ( point ) {
var planes = this.planes;
for ( var i = 0; i < 6; i ++ ) {
if ( planes[ i ].distanceToPoint( point ) < 0 ) {
return false;
}
}
return true;
}
} );
/**
* @author alteredq / http://alteredqualia.com/
* @author mrdoob / http://mrdoob.com/
*/
function WebGLShadowMap( _renderer, _lights, _objects, capabilities ) {
var _gl = _renderer.context,
_state = _renderer.state,
_frustum = new Frustum(),
_projScreenMatrix = new Matrix4(),
_lightShadows = _lights.shadows,
_shadowMapSize = new Vector2(),
_maxShadowMapSize = new Vector2( capabilities.maxTextureSize, capabilities.maxTextureSize ),
_lookTarget = new Vector3(),
_lightPositionWorld = new Vector3(),
_MorphingFlag = 1,
_SkinningFlag = 2,
_NumberOfMaterialVariants = ( _MorphingFlag | _SkinningFlag ) + 1,
_depthMaterials = new Array( _NumberOfMaterialVariants ),
_distanceMaterials = new Array( _NumberOfMaterialVariants ),
_materialCache = {};
var cubeDirections = [
new Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ),
new Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 )
];
var cubeUps = [
new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ),
new Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ), new Vector3( 0, 0, - 1 )
];
var cube2DViewPorts = [
new Vector4(), new Vector4(), new Vector4(),
new Vector4(), new Vector4(), new Vector4()
];
// init
var depthMaterialTemplate = new MeshDepthMaterial();
depthMaterialTemplate.depthPacking = RGBADepthPacking;
depthMaterialTemplate.clipping = true;
var distanceShader = ShaderLib[ "distanceRGBA" ];
var distanceUniforms = UniformsUtils.clone( distanceShader.uniforms );
for ( var i = 0; i !== _NumberOfMaterialVariants; ++ i ) {
var useMorphing = ( i & _MorphingFlag ) !== 0;
var useSkinning = ( i & _SkinningFlag ) !== 0;
var depthMaterial = depthMaterialTemplate.clone();
depthMaterial.morphTargets = useMorphing;
depthMaterial.skinning = useSkinning;
_depthMaterials[ i ] = depthMaterial;
var distanceMaterial = new ShaderMaterial( {
defines: {
'USE_SHADOWMAP': ''
},
uniforms: distanceUniforms,
vertexShader: distanceShader.vertexShader,
fragmentShader: distanceShader.fragmentShader,
morphTargets: useMorphing,
skinning: useSkinning,
clipping: true
} );
_distanceMaterials[ i ] = distanceMaterial;
}
//
var scope = this;
this.enabled = false;
this.autoUpdate = true;
this.needsUpdate = false;
this.type = PCFShadowMap;
this.renderReverseSided = true;
this.renderSingleSided = true;
this.render = function ( scene, camera ) {
if ( scope.enabled === false ) return;
if ( scope.autoUpdate === false && scope.needsUpdate === false ) return;
if ( _lightShadows.length === 0 ) return;
// Set GL state for depth map.
_state.disable( _gl.BLEND );
_state.buffers.color.setClear( 1, 1, 1, 1 );
_state.buffers.depth.setTest( true );
_state.setScissorTest( false );
// render depth map
var faceCount;
for ( var i = 0, il = _lightShadows.length; i < il; i ++ ) {
var light = _lightShadows[ i ];
var shadow = light.shadow;
var isPointLight = light && light.isPointLight;
if ( shadow === undefined ) {
console.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' );
continue;
}
var shadowCamera = shadow.camera;
_shadowMapSize.copy( shadow.mapSize );
_shadowMapSize.min( _maxShadowMapSize );
if ( isPointLight ) {
var vpWidth = _shadowMapSize.x;
var vpHeight = _shadowMapSize.y;
// These viewports map a cube-map onto a 2D texture with the
// following orientation:
//
// xzXZ
// y Y
//
// X - Positive x direction
// x - Negative x direction
// Y - Positive y direction
// y - Negative y direction
// Z - Positive z direction
// z - Negative z direction
// positive X
cube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight );
// negative X
cube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight );
// positive Z
cube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight );
// negative Z
cube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight );
// positive Y
cube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight );
// negative Y
cube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight );
_shadowMapSize.x *= 4.0;
_shadowMapSize.y *= 2.0;
}
if ( shadow.map === null ) {
var pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat };
shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );
shadow.map.texture.name = light.name + ".shadowMap";
shadowCamera.updateProjectionMatrix();
}
if ( shadow.isSpotLightShadow ) {
shadow.update( light );
}
var shadowMap = shadow.map;
var shadowMatrix = shadow.matrix;
_lightPositionWorld.setFromMatrixPosition( light.matrixWorld );
shadowCamera.position.copy( _lightPositionWorld );
if ( isPointLight ) {
faceCount = 6;
// for point lights we set the shadow matrix to be a translation-only matrix
// equal to inverse of the light's position
shadowMatrix.makeTranslation( - _lightPositionWorld.x, - _lightPositionWorld.y, - _lightPositionWorld.z );
} else {
faceCount = 1;
_lookTarget.setFromMatrixPosition( light.target.matrixWorld );
shadowCamera.lookAt( _lookTarget );
shadowCamera.updateMatrixWorld();
// compute shadow matrix
shadowMatrix.set(
0.5, 0.0, 0.0, 0.5,
0.0, 0.5, 0.0, 0.5,
0.0, 0.0, 0.5, 0.5,
0.0, 0.0, 0.0, 1.0
);
shadowMatrix.multiply( shadowCamera.projectionMatrix );
shadowMatrix.multiply( shadowCamera.matrixWorldInverse );
}
_renderer.setRenderTarget( shadowMap );
_renderer.clear();
// render shadow map for each cube face (if omni-directional) or
// run a single pass if not
for ( var face = 0; face < faceCount; face ++ ) {
if ( isPointLight ) {
_lookTarget.copy( shadowCamera.position );
_lookTarget.add( cubeDirections[ face ] );
shadowCamera.up.copy( cubeUps[ face ] );
shadowCamera.lookAt( _lookTarget );
shadowCamera.updateMatrixWorld();
var vpDimensions = cube2DViewPorts[ face ];
_state.viewport( vpDimensions );
}
// update camera matrices and frustum
_projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );
_frustum.setFromMatrix( _projScreenMatrix );
// set object matrices & frustum culling
renderObject( scene, camera, shadowCamera, isPointLight );
}
}
// Restore GL state.
var clearColor = _renderer.getClearColor();
var clearAlpha = _renderer.getClearAlpha();
_renderer.setClearColor( clearColor, clearAlpha );
scope.needsUpdate = false;
};
function getDepthMaterial( object, material, isPointLight, lightPositionWorld ) {
var geometry = object.geometry;
var result = null;
var materialVariants = _depthMaterials;
var customMaterial = object.customDepthMaterial;
if ( isPointLight ) {
materialVariants = _distanceMaterials;
customMaterial = object.customDistanceMaterial;
}
if ( ! customMaterial ) {
var useMorphing = false;
if ( material.morphTargets ) {
if ( geometry && geometry.isBufferGeometry ) {
useMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0;
} else if ( geometry && geometry.isGeometry ) {
useMorphing = geometry.morphTargets && geometry.morphTargets.length > 0;
}
}
if ( object.isSkinnedMesh && material.skinning === false ) {
console.warn( 'THREE.WebGLShadowMap: THREE.SkinnedMesh with material.skinning set to false:', object );
}
var useSkinning = object.isSkinnedMesh && material.skinning;
var variantIndex = 0;
if ( useMorphing ) variantIndex |= _MorphingFlag;
if ( useSkinning ) variantIndex |= _SkinningFlag;
result = materialVariants[ variantIndex ];
} else {
result = customMaterial;
}
if ( _renderer.localClippingEnabled &&
material.clipShadows === true &&
material.clippingPlanes.length !== 0 ) {
// in this case we need a unique material instance reflecting the
// appropriate state
var keyA = result.uuid, keyB = material.uuid;
var materialsForVariant = _materialCache[ keyA ];
if ( materialsForVariant === undefined ) {
materialsForVariant = {};
_materialCache[ keyA ] = materialsForVariant;
}
var cachedMaterial = materialsForVariant[ keyB ];
if ( cachedMaterial === undefined ) {
cachedMaterial = result.clone();
materialsForVariant[ keyB ] = cachedMaterial;
}
result = cachedMaterial;
}
result.visible = material.visible;
result.wireframe = material.wireframe;
var side = material.side;
if ( scope.renderSingleSided && side == DoubleSide ) {
side = FrontSide;
}
if ( scope.renderReverseSided ) {
if ( side === FrontSide ) side = BackSide;
else if ( side === BackSide ) side = FrontSide;
}
result.side = side;
result.clipShadows = material.clipShadows;
result.clippingPlanes = material.clippingPlanes;
result.wireframeLinewidth = material.wireframeLinewidth;
result.linewidth = material.linewidth;
if ( isPointLight && result.uniforms.lightPos !== undefined ) {
result.uniforms.lightPos.value.copy( lightPositionWorld );
}
return result;
}
function renderObject( object, camera, shadowCamera, isPointLight ) {
if ( object.visible === false ) return;
var visible = object.layers.test( camera.layers );
if ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) {
if ( object.castShadow && ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) ) {
object.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );
var geometry = _objects.update( object );
var material = object.material;
if ( Array.isArray( material ) ) {
var groups = geometry.groups;
for ( var k = 0, kl = groups.length; k < kl; k ++ ) {
var group = groups[ k ];
var groupMaterial = material[ group.materialIndex ];
if ( groupMaterial && groupMaterial.visible ) {
var depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld );
_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group );
}
}
} else if ( material.visible ) {
var depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld );
_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null );
}
}
}
var children = object.children;
for ( var i = 0, l = children.length; i < l; i ++ ) {
renderObject( children[ i ], camera, shadowCamera, isPointLight );
}
}
}
/**
* @author mrdoob / http://mrdoob.com/
*/
function WebGLAttributes( gl ) {
var buffers = {};
function createBuffer( attribute, bufferType ) {
var array = attribute.array;
var usage = attribute.dynamic ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW;
var buffer = gl.createBuffer();
gl.bindBuffer( bufferType, buffer );
gl.bufferData( bufferType, array, usage );
attribute.onUploadCallback();
var type = gl.FLOAT;
if ( array instanceof Float32Array ) {
type = gl.FLOAT;
} else if ( array instanceof Float64Array ) {
console.warn( 'THREE.WebGLAttributes: Unsupported data buffer format: Float64Array.' );
} else if ( array instanceof Uint16Array ) {
type = gl.UNSIGNED_SHORT;
} else if ( array instanceof Int16Array ) {
type = gl.SHORT;
} else if ( array instanceof Uint32Array ) {
type = gl.UNSIGNED_INT;
} else if ( array instanceof Int32Array ) {
type = gl.INT;
} else if ( array instanceof Int8Array ) {
type = gl.BYTE;
} else if ( array instanceof Uint8Array ) {
type = gl.UNSIGNED_BYTE;
}
return {
buffer: buffer,
type: type,
bytesPerElement: array.BYTES_PER_ELEMENT,
version: attribute.version
};
}
function updateBuffer( buffer, attribute, bufferType ) {
var array = attribute.array;
var updateRange = attribute.updateRange;
gl.bindBuffer( bufferType, buffer );
if ( attribute.dynamic === false ) {
gl.bufferData( bufferType, array, gl.STATIC_DRAW );
} else if ( updateRange.count === - 1 ) {
// Not using update ranges
gl.bufferSubData( bufferType, 0, array );
} else if ( updateRange.count === 0 ) {
console.error( 'THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually.' );
} else {
gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT,
array.subarray( updateRange.offset, updateRange.offset + updateRange.count ) );
updateRange.count = -1; // reset range
}
}
//
function get( attribute ) {
if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;
return buffers[ attribute.uuid ];
}
function remove( attribute ) {
if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;
var data = buffers[ attribute.uuid ];
if ( data ) {
gl.deleteBuffer( data.buffer );
delete buffers[ attribute.uuid ];
}
}
function update( attribute, bufferType ) {
if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;
var data = buffers[ attribute.uuid ];
if ( data === undefined ) {
buffers[ attribute.uuid ] = createBuffer( attribute, bufferType );
} else if ( data.version < attribute.version ) {
updateBuffer( data.buffer, attribute, bufferType );
data.version = attribute.version;
}
}
return {
get: get,
remove: remove,
update: update
};
}
/**
* @author mrdoob / http://mrdoob.com/
* @author WestLangley / http://github.com/WestLangley
* @author bhouston / http://clara.io
*/
function Euler( x, y, z, order ) {
this._x = x || 0;
this._y = y || 0;
this._z = z || 0;
this._order = order || Euler.DefaultOrder;
}
Euler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ];
Euler.DefaultOrder = 'XYZ';
Object.defineProperties( Euler.prototype, {
x: {
get: function () {
return this._x;
},
set: function ( value ) {
this._x = value;
this.onChangeCallback();
}
},
y: {
get: function () {
return this._y;
},
set: function ( value ) {
this._y = value;
this.onChangeCallback();
}
},
z: {
get: function () {
return this._z;
},
set: function ( value ) {
this._z = value;
this.onChangeCallback();
}
},
order: {
get: function () {
return this._order;
},
set: function ( value ) {
this._order = value;
this.onChangeCallback();
}
}
} );
Object.assign( Euler.prototype, {
isEuler: true,
set: function ( x, y, z, order ) {
this._x = x;
this._y = y;
this._z = z;
this._order = order || this._order;
this.onChangeCallback();
return this;
},
clone: function () {
return new this.constructor( this._x, this._y, this._z, this._order );
},
copy: function ( euler ) {
this._x = euler._x;
this._y = euler._y;
this._z = euler._z;
this._order = euler._order;
this.onChangeCallback();
return this;
},
setFromRotationMatrix: function ( m, order, update ) {
var clamp = _Math.clamp;
// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
var te = m.elements;
var m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];
var m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];
var m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];
order = order || this._order;
if ( order === 'XYZ' ) {
this._y = Math.asin( clamp( m13, - 1, 1 ) );
if ( Math.abs( m13 ) < 0.99999 ) {
this._x = Math.atan2( - m23, m33 );
this._z = Math.atan2( - m12, m11 );
} else {
this._x = Math.atan2( m32, m22 );
this._z = 0;
}
} else if ( order === 'YXZ' ) {
this._x = Math.asin( - clamp( m23, - 1, 1 ) );
if ( Math.abs( m23 ) < 0.99999 ) {
this._y = Math.atan2( m13, m33 );
this._z = Math.atan2( m21, m22 );
} else {
this._y = Math.atan2( - m31, m11 );
this._z = 0;
}
} else if ( order === 'ZXY' ) {
this._x = Math.asin( clamp( m32, - 1, 1 ) );
if ( Math.abs( m32 ) < 0.99999 ) {
this._y = Math.atan2( - m31, m33 );
this._z = Math.atan2( - m12, m22 );
} else {
this._y = 0;
this._z = Math.atan2( m21, m11 );
}
} else if ( order === 'ZYX' ) {
this._y = Math.asin( - clamp( m31, - 1, 1 ) );
if ( Math.abs( m31 ) < 0.99999 ) {
this._x = Math.atan2( m32, m33 );
this._z = Math.atan2( m21, m11 );
} else {
this._x = 0;
this._z = Math.atan2( - m12, m22 );
}
} else if ( order === 'YZX' ) {
this._z = Math.asin( clamp( m21, - 1, 1 ) );
if ( Math.abs( m21 ) < 0.99999 ) {
this._x = Math.atan2( - m23, m22 );
this._y = Math.atan2( - m31, m11 );
} else {
this._x = 0;
this._y = Math.atan2( m13, m33 );
}
} else if ( order === 'XZY' ) {
this._z = Math.asin( - clamp( m12, - 1, 1 ) );
if ( Math.abs( m12 ) < 0.99999 ) {
this._x = Math.atan2( m32, m22 );
this._y = Math.atan2( m13, m11 );
} else {
this._x = Math.atan2( - m23, m33 );
this._y = 0;
}
} else {
console.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order );
}
this._order = order;
if ( update !== false ) this.onChangeCallback();
return this;
},
setFromQuaternion: function () {
var matrix = new Matrix4();
return function setFromQuaternion( q, order, update ) {
matrix.makeRotationFromQuaternion( q );
return this.setFromRotationMatrix( matrix, order, update );
};
}(),
setFromVector3: function ( v, order ) {
return this.set( v.x, v.y, v.z, order || this._order );
},
reorder: function () {
// WARNING: this discards revolution information -bhouston
var q = new Quaternion();
return function reorder( newOrder ) {
q.setFromEuler( this );
return this.setFromQuaternion( q, newOrder );
};
}(),
equals: function ( euler ) {
return ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );
},
fromArray: function ( array ) {
this._x = array[ 0 ];
this._y = array[ 1 ];
this._z = array[ 2 ];
if ( array[ 3 ] !== undefined ) this._order = array[ 3 ];
this.onChangeCallback();
return this;
},
toArray: function ( array, offset ) {
if ( array === undefined ) array = [];
if ( offset === undefined ) offset = 0;
array[ offset ] = this._x;
array[ offset + 1 ] = this._y;
array[ offset + 2 ] = this._z;
array[ offset + 3 ] = this._order;
return array;
},
toVector3: function ( optionalResult ) {
if ( optionalResult ) {
return optionalResult.set( this._x, this._y, this._z );
} else {
return new Vector3( this._x, this._y, this._z );
}
},
onChange: function ( callback ) {
this.onChangeCallback = callback;
return this;
},
onChangeCallback: function () {}
} );
/**
* @author mrdoob / http://mrdoob.com/
*/
function Layers() {
this.mask = 1 | 0;
}
Object.assign( Layers.prototype, {
set: function ( channel ) {
this.mask = 1 << channel | 0;
},
enable: function ( channel ) {
this.mask |= 1 << channel | 0;
},
toggle: function ( channel ) {
this.mask ^= 1 << channel | 0;
},
disable: function ( channel ) {
this.mask &= ~ ( 1 << channel | 0 );
},
test: function ( layers ) {
return ( this.mask & layers.mask ) !== 0;
}
} );
/**
* @author mrdoob / http://mrdoob.com/
* @author mikael emtinger / http://gomo.se/
* @author alteredq / http://alteredqualia.com/
* @author WestLangley / http://github.com/WestLangley
* @author elephantatwork / www.elephantatwork.ch
*/
var object3DId = 0;
function Object3D() {
Object.defineProperty( this, 'id', { value: object3DId ++ } );
this.uuid = _Math.generateUUID();
this.name = '';
this.type = 'Object3D';
this.parent = null;
this.children = [];
this.up = Object3D.DefaultUp.clone();
var position = new Vector3();
var rotation = new Euler();
var quaternion = new Quaternion();
var scale = new Vector3( 1, 1, 1 );
function onRotationChange() {
quaternion.setFromEuler( rotation, false );
}
function onQuaternionChange() {
rotation.setFromQuaternion( quaternion, undefined, false );
}
rotation.onChange( onRotationChange );
quaternion.onChange( onQuaternionChange );
Object.defineProperties( this, {
position: {
enumerable: true,
value: position
},
rotation: {
enumerable: true,
value: rotation
},
quaternion: {
enumerable: true,
value: quaternion
},
scale: {
enumerable: true,
value: scale
},
modelViewMatrix: {
value: new Matrix4()
},
normalMatrix: {
value: new Matrix3()
}
} );
this.matrix = new Matrix4();
this.matrixWorld = new Matrix4();
this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;
this.matrixWorldNeedsUpdate = false;
this.layers = new Layers();
this.visible = true;
this.castShadow = false;
this.receiveShadow = false;
this.frustumCulled = true;
this.renderOrder = 0;
this.userData = {};
}
Object3D.DefaultUp = new Vector3( 0, 1, 0 );
Object3D.DefaultMatrixAutoUpdate = true;
Object.assign( Object3D.prototype, EventDispatcher.prototype, {
isObject3D: true,
onBeforeRender: function () {},
onAfterRender: function () {},
applyMatrix: function ( matrix ) {
this.matrix.multiplyMatrices( matrix, this.matrix );
this.matrix.decompose( this.position, this.quaternion, this.scale );
},
applyQuaternion: function ( q ) {
this.quaternion.premultiply( q );
return this;
},
setRotationFromAxisAngle: function ( axis, angle ) {
// assumes axis is normalized
this.quaternion.setFromAxisAngle( axis, angle );
},
setRotationFromEuler: function ( euler ) {
this.quaternion.setFromEuler( euler, true );
},
setRotationFromMatrix: function ( m ) {
// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
this.quaternion.setFromRotationMatrix( m );
},
setRotationFromQuaternion: function ( q ) {
// assumes q is normalized
this.quaternion.copy( q );
},
rotateOnAxis: function () {
// rotate object on axis in object space
// axis is assumed to be normalized
var q1 = new Quaternion();
return function rotateOnAxis( axis, angle ) {
q1.setFromAxisAngle( axis, angle );
this.quaternion.multiply( q1 );
return this;
};
}(),
rotateX: function () {
var v1 = new Vector3( 1, 0, 0 );
return function rotateX( angle ) {
return this.rotateOnAxis( v1, angle );
};
}(),
rotateY: function () {
var v1 = new Vector3( 0, 1, 0 );
return function rotateY( angle ) {
return this.rotateOnAxis( v1, angle );
};
}(),
rotateZ: function () {
var v1 = new Vector3( 0, 0, 1 );
return function rotateZ( angle ) {
return this.rotateOnAxis( v1, angle );
};
}(),
translateOnAxis: function () {
// translate object by distance along axis in object space
// axis is assumed to be normalized
var v1 = new Vector3();
return function translateOnAxis( axis, distance ) {
v1.copy( axis ).applyQuaternion( this.quaternion );
this.position.add( v1.multiplyScalar( distance ) );
return this;
};
}(),
translateX: function () {
var v1 = new Vector3( 1, 0, 0 );
return function translateX( distance ) {
return this.translateOnAxis( v1, distance );
};
}(),
translateY: function () {
var v1 = new Vector3( 0, 1, 0 );
return function translateY( distance ) {
return this.translateOnAxis( v1, distance );
};
}(),
translateZ: function () {
var v1 = new Vector3( 0, 0, 1 );
return function translateZ( distance ) {
return this.translateOnAxis( v1, distance );
};
}(),
localToWorld: function ( vector ) {
return vector.applyMatrix4( this.matrixWorld );
},
worldToLocal: function () {
var m1 = new Matrix4();
return function worldToLocal( vector ) {
return vector.applyMatrix4( m1.getInverse( this.matrixWorld ) );
};
}(),
lookAt: function () {
// This method does not support objects with rotated and/or translated parent(s)
var m1 = new Matrix4();
return function lookAt( vector ) {
if ( this.isCamera ) {
m1.lookAt( this.position, vector, this.up );
} else {
m1.lookAt( vector, this.position, this.up );
}
this.quaternion.setFromRotationMatrix( m1 );
};
}(),
add: function ( object ) {
if ( arguments.length > 1 ) {
for ( var i = 0; i < arguments.length; i ++ ) {
this.add( arguments[ i ] );
}
return this;
}
if ( object === this ) {
console.error( "THREE.Object3D.add: object can't be added as a child of itself.", object );
return this;
}
if ( ( object && object.isObject3D ) ) {
if ( object.parent !== null ) {
object.parent.remove( object );
}
object.parent = this;
object.dispatchEvent( { type: 'added' } );
this.children.push( object );
} else {
console.error( "THREE.Object3D.add: object not an instance of THREE.Object3D.", object );
}
return this;
},
remove: function ( object ) {
if ( arguments.length > 1 ) {
for ( var i = 0; i < arguments.length; i ++ ) {
this.remove( arguments[ i ] );
}
return this;
}
var index = this.children.indexOf( object );
if ( index !== - 1 ) {
object.parent = null;
object.dispatchEvent( { type: 'removed' } );
this.children.splice( index, 1 );
}
return this;
},
getObjectById: function ( id ) {
return this.getObjectByProperty( 'id', id );
},
getObjectByName: function ( name ) {
return this.getObjectByProperty( 'name', name );
},
getObjectByProperty: function ( name, value ) {
if ( this[ name ] === value ) return this;
for ( var i = 0, l = this.children.length; i < l; i ++ ) {
var child = this.children[ i ];
var object = child.getObjectByProperty( name, value );
if ( object !== undefined ) {
return object;
}
}
return undefined;
},
getWorldPosition: function ( optionalTarget ) {
var result = optionalTarget || new Vector3();
this.updateMatrixWorld( true );
return result.setFromMatrixPosition( this.matrixWorld );
},
getWorldQuaternion: function () {
var position = new Vector3();
var scale = new Vector3();
return function getWorldQuaternion( optionalTarget ) {
var result = optionalTarget || new Quaternion();
this.updateMatrixWorld( true );
this.matrixWorld.decompose( position, result, scale );
return result;
};
}(),
getWorldRotation: function () {
var quaternion = new Quaternion();
return function getWorldRotation( optionalTarget ) {
var result = optionalTarget || new Euler();
this.getWorldQuaternion( quaternion );
return result.setFromQuaternion( quaternion, this.rotation.order, false );
};
}(),
getWorldScale: function () {
var position = new Vector3();
var quaternion = new Quaternion();
return function getWorldScale( optionalTarget ) {
var result = optionalTarget || new Vector3();
this.updateMatrixWorld( true );
this.matrixWorld.decompose( position, quaternion, result );
return result;
};
}(),
getWorldDirection: function () {
var quaternion = new Quaternion();
return function getWorldDirection( optionalTarget ) {
var result = optionalTarget || new Vector3();
this.getWorldQuaternion( quaternion );
return result.set( 0, 0, 1 ).applyQuaternion( quaternion );
};
}(),
raycast: function () {},
traverse: function ( callback ) {
callback( this );
var children = this.children;
for ( var i = 0, l = children.length; i < l; i ++ ) {
children[ i ].traverse( callback );
}
},
traverseVisible: function ( callback ) {
if ( this.visible === false ) return;
callback( this );
var children = this.children;
for ( var i = 0, l = children.length; i < l; i ++ ) {
children[ i ].traverseVisible( callback );
}
},
traverseAncestors: function ( callback ) {
var parent = this.parent;
if ( parent !== null ) {
callback( parent );
parent.traverseAncestors( callback );
}
},
updateMatrix: function () {
this.matrix.compose( this.position, this.quaternion, this.scale );
this.matrixWorldNeedsUpdate = true;
},
updateMatrixWorld: function ( force ) {
if ( this.matrixAutoUpdate ) this.updateMatrix();
if ( this.matrixWorldNeedsUpdate || force ) {
if ( this.parent === null ) {
this.matrixWorld.copy( this.matrix );
} else {
this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
}
this.matrixWorldNeedsUpdate = false;
force = true;
}
// update children
var children = this.children;
for ( var i = 0, l = children.length; i < l; i ++ ) {
children[ i ].updateMatrixWorld( force );
}
},
toJSON: function ( meta ) {
// meta is '' when called from JSON.stringify
var isRootObject = ( meta === undefined || meta === '' );
var output = {};
// meta is a hash used to collect geometries, materials.
// not providing it implies that this is the root object
// being serialized.
if ( isRootObject ) {
// initialize meta obj
meta = {
geometries: {},
materials: {},
textures: {},
images: {}
};
output.metadata = {
version: 4.5,
type: 'Object',
generator: 'Object3D.toJSON'
};
}
// standard Object3D serialization
var object = {};
object.uuid = this.uuid;
object.type = this.type;
if ( this.name !== '' ) object.name = this.name;
if ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData;
if ( this.castShadow === true ) object.castShadow = true;
if ( this.receiveShadow === true ) object.receiveShadow = true;
if ( this.visible === false ) object.visible = false;
object.matrix = this.matrix.toArray();
//
function serialize( library, element ) {
if ( library[ element.uuid ] === undefined ) {
library[ element.uuid ] = element.toJSON( meta );
}
return element.uuid;
}
if ( this.geometry !== undefined ) {
object.geometry = serialize( meta.geometries, this.geometry );
}
if ( this.material !== undefined ) {
if ( Array.isArray( this.material ) ) {
var uuids = [];
for ( var i = 0, l = this.material.length; i < l; i ++ ) {
uuids.push( serialize( meta.materials, this.material[ i ] ) );
}
object.material = uuids;
} else {
object.material = serialize( meta.materials, this.material );
}
}
//
if ( this.children.length > 0 ) {
object.children = [];
for ( var i = 0; i < this.children.length; i ++ ) {
object.children.push( this.children[ i ].toJSON( meta ).object );
}
}
if ( isRootObject ) {
var geometries = extractFromCache( meta.geometries );
var materials = extractFromCache( meta.materials );
var textures = extractFromCache( meta.textures );
var images = extractFromCache( meta.images );
if ( geometries.length > 0 ) output.geometries = geometries;
if ( materials.length > 0 ) output.materials = materials;
if ( textures.length > 0 ) output.textures = textures;
if ( images.length > 0 ) output.images = images;
}
output.object = object;
return output;
// extract data from the cache hash
// remove metadata on each item
// and return as array
function extractFromCache( cache ) {
var values = [];
for ( var key in cache ) {
var data = cache[ key ];
delete data.metadata;
values.push( data );
}
return values;
}
},
clone: function ( recursive ) {
return new this.constructor().copy( this, recursive );
},
copy: function ( source, recursive ) {
if ( recursive === undefined ) recursive = true;
this.name = source.name;
this.up.copy( source.up );
this.position.copy( source.position );
this.quaternion.copy( source.quaternion );
this.scale.copy( source.scale );
this.matrix.copy( source.matrix );
this.matrixWorld.copy( source.matrixWorld );
this.matrixAutoUpdate = source.matrixAutoUpdate;
this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;
this.layers.mask = source.layers.mask;
this.visible = source.visible;
this.castShadow = source.castShadow;
this.receiveShadow = source.receiveShadow;
this.frustumCulled = source.frustumCulled;
this.renderOrder = source.renderOrder;
this.userData = JSON.parse( JSON.stringify( source.userData ) );
if ( recursive === true ) {
for ( var i = 0; i < source.children.length; i ++ ) {
var child = source.children[ i ];
this.add( child.clone() );
}
}
return this;
}
} );
/**
* @author mrdoob / http://mrdoob.com/
* @author mikael emtinger / http://gomo.se/
* @author WestLangley / http://github.com/WestLangley
*/
function Camera() {
Object3D.call( this );
this.type = 'Camera';
this.matrixWorldInverse = new Matrix4();
this.projectionMatrix = new Matrix4();
}
Camera.prototype = Object.assign( Object.create( Object3D.prototype ), {
constructor: Camera,
isCamera: true,
copy: function ( source, recursive ) {
Object3D.prototype.copy.call( this, source, recursive );
this.matrixWorldInverse.copy( source.matrixWorldInverse );
this.projectionMatrix.copy( source.projectionMatrix );
return this;
},
getWorldDirection: function () {
var quaternion = new Quaternion();
return function getWorldDirection( optionalTarget ) {
var result = optionalTarget || new Vector3();
this.getWorldQuaternion( quaternion );
return result.set( 0, 0, - 1 ).applyQuaternion( quaternion );
};
}(),
updateMatrixWorld: function ( force ) {
Object3D.prototype.updateMatrixWorld.call( this, force );
this.matrixWorldInverse.getInverse( this.matrixWorld );
},
clone: function () {
return new this.constructor().copy( this );
}
} );
/**
* @author alteredq / http://alteredqualia.com/
* @author arose / http://github.com/arose
*/
function OrthographicCamera( left, right, top, bottom, near, far ) {
Camera.call( this );
this.type = 'OrthographicCamera';
this.zoom = 1;
this.view = null;
this.left = left;
this.right = right;
this.top = top;
this.bottom = bottom;
this.near = ( near !== undefined ) ? near : 0.1;
this.far = ( far !== undefined ) ? far : 2000;
this.updateProjectionMatrix();
}
OrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), {
constructor: OrthographicCamera,
isOrthographicCamera: true,
copy: function ( source, recursive ) {
Camera.prototype.copy.call( this, source, recursive );
this.left = source.left;
this.right = source.right;
this.top = source.top;
this.bottom = source.bottom;
this.near = source.near;
this.far = source.far;
this.zoom = source.zoom;
this.view = source.view === null ? null : Object.assign( {}, source.view );
return this;
},
setViewOffset: function( fullWidth, fullHeight, x, y, width, height ) {
this.view = {
fullWidth: fullWidth,
fullHeight: fullHeight,
offsetX: x,
offsetY: y,
width: width,
height: height
};
this.updateProjectionMatrix();
},
clearViewOffset: function() {
this.view = null;
this.updateProjectionMatrix();
},
updateProjectionMatrix: function () {
var dx = ( this.right - this.left ) / ( 2 * this.zoom );
var dy = ( this.top - this.bottom ) / ( 2 * this.zoom );
var cx = ( this.right + this.left ) / 2;
var cy = ( this.top + this.bottom ) / 2;
var left = cx - dx;
var right = cx + dx;
var top = cy + dy;
var bottom = cy - dy;
if ( this.view !== null ) {
var zoomW = this.zoom / ( this.view.width / this.view.fullWidth );
var zoomH = this.zoom / ( this.view.height / this.view.fullHeight );
var scaleW = ( this.right - this.left ) / this.view.width;
var scaleH = ( this.top - this.bottom ) / this.view.height;
left += scaleW * ( this.view.offsetX / zoomW );
right = left + scaleW * ( this.view.width / zoomW );
top -= scaleH * ( this.view.offsetY / zoomH );
bottom = top - scaleH * ( this.view.height / zoomH );
}
this.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far );
},
toJSON: function ( meta ) {
var data = Object3D.prototype.toJSON.call( this, meta );
data.object.zoom = this.zoom;
data.object.left = this.left;
data.object.right = this.right;
data.object.top = this.top;
data.object.bottom = this.bottom;
data.object.near = this.near;
data.object.far = this.far;
if ( this.view !== null ) data.object.view = Object.assign( {}, this.view );
return data;
}
} );
/**
* @author mrdoob / http://mrdoob.com/
* @author greggman / http://games.greggman.com/
* @author zz85 / http://www.lab4games.net/zz85/blog
* @author tschw
*/
function PerspectiveCamera( fov, aspect, near, far ) {
Camera.call( this );
this.type = 'PerspectiveCamera';
this.fov = fov !== undefined ? fov : 50;
this.zoom = 1;
this.near = near !== undefined ? near : 0.1;
this.far = far !== undefined ? far : 2000;
this.focus = 10;
this.aspect = aspect !== undefined ? aspect : 1;
this.view = null;
this.filmGauge = 35; // width of the film (default in millimeters)
this.filmOffset = 0; // horizontal film offset (same unit as gauge)
this.updateProjectionMatrix();
}
PerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), {
constructor: PerspectiveCamera,
isPerspectiveCamera: true,
copy: function ( source, recursive ) {
Camera.prototype.copy.call( this, source, recursive );
this.fov = source.fov;
this.zoom = source.zoom;
this.near = source.near;
this.far = source.far;
this.focus = source.focus;
this.aspect = source.aspect;
this.view = source.view === null ? null : Object.assign( {}, source.view );
this.filmGauge = source.filmGauge;
this.filmOffset = source.filmOffset;
return this;
},
/**
* Sets the FOV by focal length in respect to the current .filmGauge.
*
* The default film gauge is 35, so that the focal length can be specified for
* a 35mm (full frame) camera.
*
* Values for focal length and film gauge must have the same unit.
*/
setFocalLength: function ( focalLength ) {
// see http://www.bobatkins.com/photography/technical/field_of_view.html
var vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;
this.fov = _Math.RAD2DEG * 2 * Math.atan( vExtentSlope );
this.updateProjectionMatrix();
},
/**
* Calculates the focal length from the current .fov and .filmGauge.
*/
getFocalLength: function () {
var vExtentSlope = Math.tan( _Math.DEG2RAD * 0.5 * this.fov );
return 0.5 * this.getFilmHeight() / vExtentSlope;
},
getEffectiveFOV: function () {
return _Math.RAD2DEG * 2 * Math.atan(
Math.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom );
},
getFilmWidth: function () {
// film not completely covered in portrait format (aspect < 1)
return this.filmGauge * Math.min( this.aspect, 1 );
},
getFilmHeight: function () {
// film not completely covered in landscape format (aspect > 1)
return this.filmGauge / Math.max( this.aspect, 1 );
},
/**
* Sets an offset in a larger frustum. This is useful for multi-window or
* multi-monitor/multi-machine setups.
*
* For example, if you have 3x2 monitors and each monitor is 1920x1080 and
* the monitors are in grid like this
*
* +---+---+---+
* | A | B | C |
* +---+---+---+
* | D | E | F |
* +---+---+---+
*
* then for each monitor you would call it like this
*
* var w = 1920;
* var h = 1080;
* var fullWidth = w * 3;
* var fullHeight = h * 2;
*
* --A--
* camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );
* --B--
* camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );
* --C--
* camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );
* --D--
* camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );
* --E--
* camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );
* --F--
* camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
*
* Note there is no reason monitors have to be the same size or in a grid.
*/
setViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) {
this.aspect = fullWidth / fullHeight;
this.view = {
fullWidth: fullWidth,
fullHeight: fullHeight,
offsetX: x,
offsetY: y,
width: width,
height: height
};
this.updateProjectionMatrix();
},
clearViewOffset: function () {
this.view = null;
this.updateProjectionMatrix();
},
updateProjectionMatrix: function () {
var near = this.near,
top = near * Math.tan(
_Math.DEG2RAD * 0.5 * this.fov ) / this.zoom,
height = 2 * top,
width = this.aspect * height,
left = - 0.5 * width,
view = this.view;
if ( view !== null ) {
var fullWidth = view.fullWidth,
fullHeight = view.fullHeight;
left += view.offsetX * width / fullWidth;
top -= view.offsetY * height / fullHeight;
width *= view.width / fullWidth;
height *= view.height / fullHeight;
}
var skew = this.filmOffset;
if ( skew !== 0 ) left += near * skew / this.getFilmWidth();
this.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far );
},
toJSON: function ( meta ) {
var data = Object3D.prototype.toJSON.call( this, meta );
data.object.fov = this.fov;
data.object.zoom = this.zoom;
data.object.near = this.near;
data.object.far = this.far;
data.object.focus = this.focus;
data.object.aspect = this.aspect;
if ( this.view !== null ) data.object.view = Object.assign( {}, this.view );
data.object.filmGauge = this.filmGauge;
data.object.filmOffset = this.filmOffset;
return data;
}
} );
/**
* @author mrdoob / http://mrdoob.com/
* @author alteredq / http://alteredqualia.com/
*/
function Face3( a, b, c, normal, color, materialIndex ) {
this.a = a;
this.b = b;
this.c = c;
this.normal = ( normal && normal.isVector3 ) ? normal : new Vector3();
this.vertexNormals = Array.isArray( normal ) ? normal : [];
this.color = ( color && color.isColor ) ? color : new Color();
this.vertexColors = Array.isArray( color ) ? color : [];
this.materialIndex = materialIndex !== undefined ? materialIndex : 0;
}
Object.assign( Face3.prototype, {
clone: function () {
return new this.constructor().copy( this );
},
copy: function ( source ) {
this.a = source.a;
this.b = source.b;
this.c = source.c;
this.normal.copy( source.normal );
this.color.copy( source.color );
this.materialIndex = source.materialIndex;
for ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) {
this.vertexNormals[ i ] = source.vertexNormals[ i ].clone();
}
for ( var i = 0, il = source.vertexColors.length; i < il; i ++ ) {
this.vertexColors[ i ] = source.vertexColors[ i ].clone();
}
return this;
}
} );
/**
* @author mrdoob / http://mrdoob.com/
* @author kile / http://kile.stravaganza.org/
* @author alteredq / http://alteredqualia.com/
* @author mikael emtinger / http://gomo.se/
* @author zz85 / http://www.lab4games.net/zz85/blog
* @author bhouston / http://clara.io
*/
var count = 0;
function GeometryIdCount() { return count++; }
function Geometry() {
Object.defineProperty( this, 'id', { value: GeometryIdCount() } );
this.uuid = _Math.generateUUID();
this.name = '';
this.type = 'Geometry';
this.vertices = [];
this.colors = [];
this.faces = [];
this.faceVertexUvs = [[]];
this.morphTargets = [];
this.morphNormals = [];
this.skinWeights = [];
this.skinIndices = [];
this.lineDistances = [];
this.boundingBox = null;
this.boundingSphere = null;
// update flags
this.elementsNeedUpdate = false;
this.verticesNeedUpdate = false;
this.uvsNeedUpdate = false;
this.normalsNeedUpdate = false;
this.colorsNeedUpdate = false;
this.lineDistancesNeedUpdate = false;
this.groupsNeedUpdate = false;
}
Object.assign( Geometry.prototype, EventDispatcher.prototype, {
isGeometry: true,
applyMatrix: function ( matrix ) {
var normalMatrix = new Matrix3().getNormalMatrix( matrix );
for ( var i = 0, il = this.vertices.length; i < il; i ++ ) {
var vertex = this.vertices[ i ];
vertex.applyMatrix4( matrix );
}
for ( var i = 0, il = this.faces.length; i < il; i ++ ) {
var face = this.faces[ i ];
face.normal.applyMatrix3( normalMatrix ).normalize();
for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {
face.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize();
}
}
if ( this.boundingBox !== null ) {
this.computeBoundingBox();
}
if ( this.boundingSphere !== null ) {
this.computeBoundingSphere();
}
this.verticesNeedUpdate = true;
this.normalsNeedUpdate = true;
return this;
},
rotateX: function () {
// rotate geometry around world x-axis
var m1 = new Matrix4();
return function rotateX( angle ) {
m1.makeRotationX( angle );
this.applyMatrix( m1 );
return this;
};
}(),
rotateY: function () {
// rotate geometry around world y-axis
var m1 = new Matrix4();
return function rotateY( angle ) {
m1.makeRotationY( angle );
this.applyMatrix( m1 );
return this;
};
}(),
rotateZ: function () {
// rotate geometry around world z-axis
var m1 = new Matrix4();
return function rotateZ( angle ) {
m1.makeRotationZ( angle );
this.applyMatrix( m1 );
return this;
};
}(),
translate: function () {
// translate geometry
var m1 = new Matrix4();
return function translate( x, y, z ) {
m1.makeTranslation( x, y, z );
this.applyMatrix( m1 );
return this;
};
}(),
scale: function () {
// scale geometry
var m1 = new Matrix4();
return function scale( x, y, z ) {
m1.makeScale( x, y, z );
this.applyMatrix( m1 );
return this;
};
}(),
lookAt: function () {
var obj = new Object3D();
return function lookAt( vector ) {
obj.lookAt( vector );
obj.updateMatrix();
this.applyMatrix( obj.matrix );
};
}(),
fromBufferGeometry: function ( geometry ) {
var scope = this;
var indices = geometry.index !== null ? geometry.index.array : undefined;
var attributes = geometry.attributes;
var positions = attributes.position.array;
var normals = attributes.normal !== undefined ? attributes.normal.array : undefined;
var colors = attributes.color !== undefined ? attributes.color.array : undefined;
var uvs = attributes.uv !== undefined ? attributes.uv.array : undefined;
var uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined;
if ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = [];
var tempNormals = [];
var tempUVs = [];
var tempUVs2 = [];
for ( var i = 0, j = 0; i < positions.length; i += 3, j += 2 ) {
scope.vertices.push( new Vector3( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] ) );
if ( normals !== undefined ) {
tempNormals.push( new Vector3( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] ) );
}
if ( colors !== undefined ) {
scope.colors.push( new Color( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ) );
}
if ( uvs !== undefined ) {
tempUVs.push( new Vector2( uvs[ j ], uvs[ j + 1 ] ) );
}
if ( uvs2 !== undefined ) {
tempUVs2.push( new Vector2( uvs2[ j ], uvs2[ j + 1 ] ) );
}
}
function addFace( a, b, c, materialIndex ) {
var vertexNormals = normals !== undefined ? [ tempNormals[ a ].clone(), tempNormals[ b ].clone(), tempNormals[ c ].clone() ] : [];
var vertexColors = colors !== undefined ? [ scope.colors[ a ].clone(), scope.colors[ b ].clone(), scope.colors[ c ].clone() ] : [];
var face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex );
scope.faces.push( face );
if ( uvs !== undefined ) {
scope.faceVertexUvs[ 0 ].push( [ tempUVs[ a ].clone(), tempUVs[ b ].clone(), tempUVs[ c ].clone() ] );
}
if ( uvs2 !== undefined ) {
scope.faceVertexUvs[ 1 ].push( [ tempUVs2[ a ].clone(), tempUVs2[ b ].clone(), tempUVs2[ c ].clone() ] );
}
}
var groups = geometry.groups;
if ( groups.length > 0 ) {
for ( var i = 0; i < groups.length; i ++ ) {
var group = groups[ i ];
var start = group.start;
var count = group.count;
for ( var j = start, jl = start + count; j < jl; j += 3 ) {
if ( indices !== undefined ) {
addFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ], group.materialIndex );
} else {
addFace( j, j + 1, j + 2, group.materialIndex );
}
}
}
} else {
if ( indices !== undefined ) {
for ( var i = 0; i < indices.length; i += 3 ) {
addFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] );
}
} else {
for ( var i = 0; i < positions.length / 3; i += 3 ) {
addFace( i, i + 1, i + 2 );
}
}
}
this.computeFaceNormals();
if ( geometry.boundingBox !== null ) {
this.boundingBox = geometry.boundingBox.clone();
}
if ( geometry.boundingSphere !== null ) {
this.boundingSphere = geometry.boundingSphere.clone();
}
return this;
},
center: function () {
this.computeBoundingBox();
var offset = this.boundingBox.getCenter().negate();
this.translate( offset.x, offset.y, offset.z );
return offset;
},
normalize: function () {
this.computeBoundingSphere();
var center = this.boundingSphere.center;
var radius = this.boundingSphere.radius;
var s = radius === 0 ? 1 : 1.0 / radius;
var matrix = new Matrix4();
matrix.set(
s, 0, 0, - s * center.x,
0, s, 0, - s * center.y,
0, 0, s, - s * center.z,
0, 0, 0, 1
);
this.applyMatrix( matrix );
return this;
},
computeFaceNormals: function () {
var cb = new Vector3(), ab = new Vector3();
for ( var f = 0, fl = this.faces.length; f < fl; f ++ ) {
var face = this.faces[ f ];
var vA = this.vertices[ face.a ];
var vB = this.vertices[ face.b ];
var vC = this.vertices[ face.c ];
cb.subVectors( vC, vB );
ab.subVectors( vA, vB );
cb.cross( ab );
cb.normalize();
face.normal.copy( cb );
}
},
computeVertexNormals: function ( areaWeighted ) {
if ( areaWeighted === undefined ) areaWeighted = true;
var v, vl, f, fl, face, vertices;
vertices = new Array( this.vertices.length );
for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
vertices[ v ] = new Vector3();
}
if ( areaWeighted ) {
// vertex normals weighted by triangle areas
// http://www.iquilezles.org/www/articles/normals/normals.htm
var vA, vB, vC;
var cb = new Vector3(), ab = new Vector3();
for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
face = this.faces[ f ];
vA = this.vertices[ face.a ];
vB = this.vertices[ face.b ];
vC = this.vertices[ face.c ];
cb.subVectors( vC, vB );
ab.subVectors( vA, vB );
cb.cross( ab );
vertices[ face.a ].add( cb );
vertices[ face.b ].add( cb );
vertices[ face.c ].add( cb );
}
} else {
this.computeFaceNormals();
for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
face = this.faces[ f ];
vertices[ face.a ].add( face.normal );
vertices[ face.b ].add( face.normal );
vertices[ face.c ].add( face.normal );
}
}
for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
vertices[ v ].normalize();
}
for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
face = this.faces[ f ];
var vertexNormals = face.vertexNormals;
if ( vertexNormals.length === 3 ) {
vertexNormals[ 0 ].copy( vertices[ face.a ] );
vertexNormals[ 1 ].copy( vertices[ face.b ] );
vertexNormals[ 2 ].copy( vertices[ face.c ] );
} else {
vertexNormals[ 0 ] = vertices[ face.a ].clone();
vertexNormals[ 1 ] = vertices[ face.b ].clone();
vertexNormals[ 2 ] = vertices[ face.c ].clone();
}
}
if ( this.faces.length > 0 ) {
this.normalsNeedUpdate = true;
}
},
computeFlatVertexNormals: function () {
var f, fl, face;
this.computeFaceNormals();
for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
face = this.faces[ f ];
var vertexNormals = face.vertexNormals;
if ( vertexNormals.length === 3 ) {
vertexNormals[ 0 ].copy( face.normal );
vertexNormals[ 1 ].copy( face.normal );
vertexNormals[ 2 ].copy( face.normal );
} else {
vertexNormals[ 0 ] = face.normal.clone();
vertexNormals[ 1 ] = face.normal.clone();
vertexNormals[ 2 ] = face.normal.clone();
}
}
if ( this.faces.length > 0 ) {
this.normalsNeedUpdate = true;
}
},
computeMorphNormals: function () {
var i, il, f, fl, face;
// save original normals
// - create temp variables on first access
// otherwise just copy (for faster repeated calls)
for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
face = this.faces[ f ];
if ( ! face.__originalFaceNormal ) {
face.__originalFaceNormal = face.normal.clone();
} else {
face.__originalFaceNormal.copy( face.normal );
}
if ( ! face.__originalVertexNormals ) face.__originalVertexNormals = [];
for ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) {
if ( ! face.__originalVertexNormals[ i ] ) {
face.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();
} else {
face.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );
}
}
}
// use temp geometry to compute face and vertex normals for each morph
var tmpGeo = new Geometry();
tmpGeo.faces = this.faces;
for ( i = 0, il = this.morphTargets.length; i < il; i ++ ) {
// create on first access
if ( ! this.morphNormals[ i ] ) {
this.morphNormals[ i ] = {};
this.morphNormals[ i ].faceNormals = [];
this.morphNormals[ i ].vertexNormals = [];
var dstNormalsFace = this.morphNormals[ i ].faceNormals;
var dstNormalsVertex = this.morphNormals[ i ].vertexNormals;
var faceNormal, vertexNormals;
for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
faceNormal = new Vector3();
vertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() };
dstNormalsFace.push( faceNormal );
dstNormalsVertex.push( vertexNormals );
}
}
var morphNormals = this.morphNormals[ i ];
// set vertices to morph target
tmpGeo.vertices = this.morphTargets[ i ].vertices;
// compute morph normals
tmpGeo.computeFaceNormals();
tmpGeo.computeVertexNormals();
// store morph normals
var faceNormal, vertexNormals;
for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
face = this.faces[ f ];
faceNormal = morphNormals.faceNormals[ f ];
vertexNormals = morphNormals.vertexNormals[ f ];
faceNormal.copy( face.normal );
vertexNormals.a.copy( face.vertexNormals[ 0 ] );
vertexNormals.b.copy( face.vertexNormals[ 1 ] );
vertexNormals.c.copy( face.vertexNormals[ 2 ] );
}
}
// restore original normals
for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
face = this.faces[ f ];
face.normal = face.__originalFaceNormal;
face.vertexNormals = face.__originalVertexNormals;
}
},
computeLineDistances: function () {
var d = 0;
var vertices = this.vertices;
for ( var i = 0, il = vertices.length; i < il; i ++ ) {
if ( i > 0 ) {
d += vertices[ i ].distanceTo( vertices[ i - 1 ] );
}
this.lineDistances[ i ] = d;
}
},
computeBoundingBox: function () {
if ( this.boundingBox === null ) {
this.boundingBox = new Box3();
}
this.boundingBox.setFromPoints( this.vertices );
},
computeBoundingSphere: function () {
if ( this.boundingSphere === null ) {
this.boundingSphere = new Sphere();
}
this.boundingSphere.setFromPoints( this.vertices );
},
merge: function ( geometry, matrix, materialIndexOffset ) {
if ( ! ( geometry && geometry.isGeometry ) ) {
console.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry );
return;
}
var normalMatrix,
vertexOffset = this.vertices.length,
vertices1 = this.vertices,
vertices2 = geometry.vertices,
faces1 = this.faces,
faces2 = geometry.faces,
uvs1 = this.faceVertexUvs[ 0 ],
uvs2 = geometry.faceVertexUvs[ 0 ],
colors1 = this.colors,
colors2 = geometry.colors;
if ( materialIndexOffset === undefined ) materialIndexOffset = 0;
if ( matrix !== undefined ) {
normalMatrix = new Matrix3().getNormalMatrix( matrix );
}
// vertices
for ( var i = 0, il = vertices2.length; i < il; i ++ ) {
var vertex = vertices2[ i ];
var vertexCopy = vertex.clone();
if ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix );
vertices1.push( vertexCopy );
}
// colors
for ( var i = 0, il = colors2.length; i < il; i ++ ) {
colors1.push( colors2[ i ].clone() );
}
// faces
for ( i = 0, il = faces2.length; i < il; i ++ ) {
var face = faces2[ i ], faceCopy, normal, color,
faceVertexNormals = face.vertexNormals,
faceVertexColors = face.vertexColors;
faceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset );
faceCopy.normal.copy( face.normal );
if ( normalMatrix !== undefined ) {
faceCopy.normal.applyMatrix3( normalMatrix ).normalize();
}
for ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {
normal = faceVertexNormals[ j ].clone();
if ( normalMatrix !== undefined ) {
normal.applyMatrix3( normalMatrix ).normalize();
}
faceCopy.vertexNormals.push( normal );
}
faceCopy.color.copy( face.color );
for ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) {
color = faceVertexColors[ j ];
faceCopy.vertexColors.push( color.clone() );
}
faceCopy.materialIndex = face.materialIndex + materialIndexOffset;
faces1.push( faceCopy );
}
// uvs
for ( i = 0, il = uvs2.length; i < il; i ++ ) {
var uv = uvs2[ i ], uvCopy = [];
if ( uv === undefined ) {
continue;
}
for ( var j = 0, jl = uv.length; j < jl; j ++ ) {
uvCopy.push( uv[ j ].clone() );
}
uvs1.push( uvCopy );
}
},
mergeMesh: function ( mesh ) {
if ( ! ( mesh && mesh.isMesh ) ) {
console.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh );
return;
}
mesh.matrixAutoUpdate && mesh.updateMatrix();
this.merge( mesh.geometry, mesh.matrix );
},
/*
* Checks for duplicate vertices with hashmap.
* Duplicated vertices are removed
* and faces' vertices are updated.
*/
mergeVertices: function () {
var verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)
var unique = [], changes = [];
var v, key;
var precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001
var precision = Math.pow( 10, precisionPoints );
var i, il, face;
var indices, j, jl;
for ( i = 0, il = this.vertices.length; i < il; i ++ ) {
v = this.vertices[ i ];
key = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision );
if ( verticesMap[ key ] === undefined ) {
verticesMap[ key ] = i;
unique.push( this.vertices[ i ] );
changes[ i ] = unique.length - 1;
} else {
//console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);
changes[ i ] = changes[ verticesMap[ key ] ];
}
}
// if faces are completely degenerate after merging vertices, we
// have to remove them from the geometry.
var faceIndicesToRemove = [];
for ( i = 0, il = this.faces.length; i < il; i ++ ) {
face = this.faces[ i ];
face.a = changes[ face.a ];
face.b = changes[ face.b ];
face.c = changes[ face.c ];
indices = [ face.a, face.b, face.c ];
// if any duplicate vertices are found in a Face3
// we have to remove the face as nothing can be saved
for ( var n = 0; n < 3; n ++ ) {
if ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) {
faceIndicesToRemove.push( i );
break;
}
}
}
for ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) {
var idx = faceIndicesToRemove[ i ];
this.faces.splice( idx, 1 );
for ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {
this.faceVertexUvs[ j ].splice( idx, 1 );
}
}
// Use unique set of vertices
var diff = this.vertices.length - unique.length;
this.vertices = unique;
return diff;
},
sortFacesByMaterialIndex: function () {
var faces = this.faces;
var length = faces.length;
// tag faces
for ( var i = 0; i < length; i ++ ) {
faces[ i ]._id = i;
}
// sort faces
function materialIndexSort( a, b ) {
return a.materialIndex - b.materialIndex;
}
faces.sort( materialIndexSort );
// sort uvs
var uvs1 = this.faceVertexUvs[ 0 ];
var uvs2 = this.faceVertexUvs[ 1 ];
var newUvs1, newUvs2;
if ( uvs1 && uvs1.length === length ) newUvs1 = [];
if ( uvs2 && uvs2.length === length ) newUvs2 = [];
for ( var i = 0; i < length; i ++ ) {
var id = faces[ i ]._id;
if ( newUvs1 ) newUvs1.push( uvs1[ id ] );
if ( newUvs2 ) newUvs2.push( uvs2[ id ] );
}
if ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1;
if ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2;
},
toJSON: function () {
var data = {
metadata: {
version: 4.5,
type: 'Geometry',
generator: 'Geometry.toJSON'
}
};
// standard Geometry serialization
data.uuid = this.uuid;
data.type = this.type;
if ( this.name !== '' ) data.name = this.name;
if ( this.parameters !== undefined ) {
var parameters = this.parameters;
for ( var key in parameters ) {
if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];
}
return data;
}
var vertices = [];
for ( var i = 0; i < this.vertices.length; i ++ ) {
var vertex = this.vertices[ i ];
vertices.push( vertex.x, vertex.y, vertex.z );
}
var faces = [];
var normals = [];
var normalsHash = {};
var colors = [];
var colorsHash = {};
var uvs = [];
var uvsHash = {};
for ( var i = 0; i < this.faces.length; i ++ ) {
var face = this.faces[ i ];
var hasMaterial = true;
var hasFaceUv = false; // deprecated
var hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined;
var hasFaceNormal = face.normal.length() > 0;
var hasFaceVertexNormal = face.vertexNormals.length > 0;
var hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1;
var hasFaceVertexColor = face.vertexColors.length > 0;
var faceType = 0;
faceType = setBit( faceType, 0, 0 ); // isQuad
faceType = setBit( faceType, 1, hasMaterial );
faceType = setBit( faceType, 2, hasFaceUv );
faceType = setBit( faceType, 3, hasFaceVertexUv );
faceType = setBit( faceType, 4, hasFaceNormal );
faceType = setBit( faceType, 5, hasFaceVertexNormal );
faceType = setBit( faceType, 6, hasFaceColor );
faceType = setBit( faceType, 7, hasFaceVertexColor );
faces.push( faceType );
faces.push( face.a, face.b, face.c );
faces.push( face.materialIndex );
if ( hasFaceVertexUv ) {
var faceVertexUvs = this.faceVertexUvs[ 0 ][ i ];
faces.push(
getUvIndex( faceVertexUvs[ 0 ] ),
getUvIndex( faceVertexUvs[ 1 ] ),
getUvIndex( faceVertexUvs[ 2 ] )
);
}
if ( hasFaceNormal ) {
faces.push( getNormalIndex( face.normal ) );
}
if ( hasFaceVertexNormal ) {
var vertexNormals = face.vertexNormals;
faces.push(
getNormalIndex( vertexNormals[ 0 ] ),
getNormalIndex( vertexNormals[ 1 ] ),
getNormalIndex( vertexNormals[ 2 ] )
);
}
if ( hasFaceColor ) {
faces.push( getColorIndex( face.color ) );
}
if ( hasFaceVertexColor ) {
var vertexColors = face.vertexColors;
faces.push(
getColorIndex( vertexColors[ 0 ] ),
getColorIndex( vertexColors[ 1 ] ),
getColorIndex( vertexColors[ 2 ] )
);
}
}
function setBit( value, position, enabled ) {
return enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) );
}
function getNormalIndex( normal ) {
var hash = normal.x.toString() + normal.y.toString() + normal.z.toString();
if ( normalsHash[ hash ] !== undefined ) {
return normalsHash[ hash ];
}
normalsHash[ hash ] = normals.length / 3;
normals.push( normal.x, normal.y, normal.z );
return normalsHash[ hash ];
}
function getColorIndex( color ) {
var hash = color.r.toString() + color.g.toString() + color.b.toString();
if ( colorsHash[ hash ] !== undefined ) {
return colorsHash[ hash ];
}
colorsHash[ hash ] = colors.length;
colors.push( color.getHex() );
return colorsHash[ hash ];
}
function getUvIndex( uv ) {
var hash = uv.x.toString() + uv.y.toString();
if ( uvsHash[ hash ] !== undefined ) {
return uvsHash[ hash ];
}
uvsHash[ hash ] = uvs.length / 2;
uvs.push( uv.x, uv.y );
return uvsHash[ hash ];
}
data.data = {};
data.data.vertices = vertices;
data.data.normals = normals;
if ( colors.length > 0 ) data.data.colors = colors;
if ( uvs.length > 0 ) data.data.uvs = [ uvs ]; // temporal backward compatibility
data.data.faces = faces;
return data;
},
clone: function () {
/*
// Handle primitives
var parameters = this.parameters;
if ( parameters !== undefined ) {
var values = [];
for ( var key in parameters ) {
values.push( parameters[ key ] );
}
var geometry = Object.create( this.constructor.prototype );
this.constructor.apply( geometry, values );
return geometry;
}
return new this.constructor().copy( this );
*/
return new Geometry().copy( this );
},
copy: function ( source ) {
var i, il, j, jl, k, kl;
// reset
this.vertices = [];
this.colors = [];
this.faces = [];
this.faceVertexUvs = [[]];
this.morphTargets = [];
this.morphNormals = [];
this.skinWeights = [];
this.skinIndices = [];
this.lineDistances = [];
this.boundingBox = null;
this.boundingSphere = null;
// name
this.name = source.name;
// vertices
var vertices = source.vertices;
for ( i = 0, il = vertices.length; i < il; i ++ ) {
this.vertices.push( vertices[ i ].clone() );
}
// colors
var colors = source.colors;
for ( i = 0, il = colors.length; i < il; i ++ ) {
this.colors.push( colors[ i ].clone() );
}
// faces
var faces = source.faces;
for ( i = 0, il = faces.length; i < il; i ++ ) {
this.faces.push( faces[ i ].clone() );
}
// face vertex uvs
for ( i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) {
var faceVertexUvs = source.faceVertexUvs[ i ];
if ( this.faceVertexUvs[ i ] === undefined ) {
this.faceVertexUvs[ i ] = [];
}
for ( j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) {
var uvs = faceVertexUvs[ j ], uvsCopy = [];
for ( k = 0, kl = uvs.length; k < kl; k ++ ) {
var uv = uvs[ k ];
uvsCopy.push( uv.clone() );
}
this.faceVertexUvs[ i ].push( uvsCopy );
}
}
// morph targets
var morphTargets = source.morphTargets;
for ( i = 0, il = morphTargets.length; i < il; i ++ ) {
var morphTarget = {};
morphTarget.name = morphTargets[ i ].name;
// vertices
if ( morphTargets[ i ].vertices !== undefined ) {
morphTarget.vertices = [];
for ( j = 0, jl = morphTargets[ i ].vertices.length; j < jl; j ++ ) {
morphTarget.vertices.push( morphTargets[ i ].vertices[ j ].clone() );
}
}
// normals
if ( morphTargets[ i ].normals !== undefined ) {
morphTarget.normals = [];
for ( j = 0, jl = morphTargets[ i ].normals.length; j < jl; j ++ ) {
morphTarget.normals.push( morphTargets[ i ].normals[ j ].clone() );
}
}
this.morphTargets.push( morphTarget );
}
// morph normals
var morphNormals = source.morphNormals;
for ( i = 0, il = morphNormals.length; i < il; i ++ ) {
var morphNormal = {};
// vertex normals
if ( morphNormals[ i ].vertexNormals !== undefined ) {
morphNormal.vertexNormals = [];
for ( j = 0, jl = morphNormals[ i ].vertexNormals.length; j < jl; j ++ ) {
var srcVertexNormal = morphNormals[ i ].vertexNormals[ j ];
var destVertexNormal = {};
destVertexNormal.a = srcVertexNormal.a.clone();
destVertexNormal.b = srcVertexNormal.b.clone();
destVertexNormal.c = srcVertexNormal.c.clone();
morphNormal.vertexNormals.push( destVertexNormal );
}
}
// face normals
if ( morphNormals[ i ].faceNormals !== undefined ) {
morphNormal.faceNormals = [];
for ( j = 0, jl = morphNormals[ i ].faceNormals.length; j < jl; j ++ ) {
morphNormal.faceNormals.push( morphNormals[ i ].faceNormals[ j ].clone() );
}
}
this.morphNormals.push( morphNormal );
}
// skin weights
var skinWeights = source.skinWeights;
for ( i = 0, il = skinWeights.length; i < il; i ++ ) {
this.skinWeights.push( skinWeights[ i ].clone() );
}
// skin indices
var skinIndices = source.skinIndices;
for ( i = 0, il = skinIndices.length; i < il; i ++ ) {
this.skinIndices.push( skinIndices[ i ].clone() );
}
// line distances
var lineDistances = source.lineDistances;
for ( i = 0, il = lineDistances.length; i < il; i ++ ) {
this.lineDistances.push( lineDistances[ i ] );
}
// bounding box
var boundingBox = source.boundingBox;
if ( boundingBox !== null ) {
this.boundingBox = boundingBox.clone();
}
// bounding sphere
var boundingSphere = source.boundingSphere;
if ( boundingSphere !== null ) {
this.boundingSphere = boundingSphere.clone();
}
// update flags
this.elementsNeedUpdate = source.elementsNeedUpdate;
this.verticesNeedUpdate = source.verticesNeedUpdate;
this.uvsNeedUpdate = source.uvsNeedUpdate;
this.normalsNeedUpdate = source.normalsNeedUpdate;
this.colorsNeedUpdate = source.colorsNeedUpdate;
this.lineDistancesNeedUpdate = source.lineDistancesNeedUpdate;
this.groupsNeedUpdate = source.groupsNeedUpdate;
return this;
},
dispose: function () {
this.dispatchEvent( { type: 'dispose' } );
}
} );
/**
* @author mrdoob / http://mrdoob.com/
*/
function BufferAttribute( array, itemSize, normalized ) {
if ( Array.isArray( array ) ) {
throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );
}
this.uuid = _Math.generateUUID();
this.name = '';
this.array = array;
this.itemSize = itemSize;
this.count = array !== undefined ? array.length / itemSize : 0;
this.normalized = normalized === true;
this.dynamic = false;
this.updateRange = { offset: 0, count: - 1 };
this.onUploadCallback = function () {};
this.version = 0;
}
Object.defineProperty( BufferAttribute.prototype, 'needsUpdate', {
set: function ( value ) {
if ( value === true ) this.version ++;
}
} );
Object.assign( BufferAttribute.prototype, {
isBufferAttribute: true,
setArray: function ( array ) {
if ( Array.isArray( array ) ) {
throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );
}
this.count = array !== undefined ? array.length / this.itemSize : 0;
this.array = array;
},
setDynamic: function ( value ) {
this.dynamic = value;
return this;
},
copy: function ( source ) {
this.array = new source.array.constructor( source.array );
this.itemSize = source.itemSize;
this.count = source.count;
this.normalized = source.normalized;
this.dynamic = source.dynamic;
return this;
},
copyAt: function ( index1, attribute, index2 ) {
index1 *= this.itemSize;
index2 *= attribute.itemSize;
for ( var i = 0, l = this.itemSize; i < l; i ++ ) {
this.array[ index1 + i ] = attribute.array[ index2 + i ];
}
return this;
},
copyArray: function ( array ) {
this.array.set( array );
return this;
},
copyColorsArray: function ( colors ) {
var array = this.array, offset = 0;
for ( var i = 0, l = colors.length; i < l; i ++ ) {
var color = colors[ i ];
if ( color === undefined ) {
console.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i );
color = new Color();
}
array[ offset ++ ] = color.r;
array[ offset ++ ] = color.g;
array[ offset ++ ] = color.b;
}
return this;
},
copyIndicesArray: function ( indices ) {
var array = this.array, offset = 0;
for ( var i = 0, l = indices.length; i < l; i ++ ) {
var index = indices[ i ];
array[ offset ++ ] = index.a;
array[ offset ++ ] = index.b;
array[ offset ++ ] = index.c;
}
return this;
},
copyVector2sArray: function ( vectors ) {
var array = this.array, offset = 0;
for ( var i = 0, l = vectors.length; i < l; i ++ ) {
var vector = vectors[ i ];
if ( vector === undefined ) {
console.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i );
vector = new Vector2();
}
array[ offset ++ ] = vector.x;
array[ offset ++ ] = vector.y;
}
return this;
},
copyVector3sArray: function ( vectors ) {
var array = this.array, offset = 0;
for ( var i = 0, l = vectors.length; i < l; i ++ ) {
var vector = vectors[ i ];
if ( vector === undefined ) {
console.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i );
vector = new Vector3();
}
array[ offset ++ ] = vector.x;
array[ offset ++ ] = vector.y;
array[ offset ++ ] = vector.z;
}
return this;
},
copyVector4sArray: function ( vectors ) {
var array = this.array, offset = 0;
for ( var i = 0, l = vectors.length; i < l; i ++ ) {
var vector = vectors[ i ];
if ( vector === undefined ) {
console.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i );
vector = new Vector4();
}
array[ offset ++ ] = vector.x;
array[ offset ++ ] = vector.y;
array[ offset ++ ] = vector.z;
array[ offset ++ ] = vector.w;
}
return this;
},
set: function ( value, offset ) {
if ( offset === undefined ) offset = 0;
this.array.set( value, offset );
return this;
},
getX: function ( index ) {
return this.array[ index * this.itemSize ];
},
setX: function ( index, x ) {
this.array[ index * this.itemSize ] = x;
return this;
},
getY: function ( index ) {
return this.array[ index * this.itemSize + 1 ];
},
setY: function ( index, y ) {
this.array[ index * this.itemSize + 1 ] = y;
return this;
},
getZ: function ( index ) {
return this.array[ index * this.itemSize + 2 ];
},
setZ: function ( index, z ) {
this.array[ index * this.itemSize + 2 ] = z;
return this;
},
getW: function ( index ) {
return this.array[ index * this.itemSize + 3 ];
},
setW: function ( index, w ) {
this.array[ index * this.itemSize + 3 ] = w;
return this;
},
setXY: function ( index, x, y ) {
index *= this.itemSize;
this.array[ index + 0 ] = x;
this.array[ index + 1 ] = y;
return this;
},
setXYZ: function ( index, x, y, z ) {
index *= this.itemSize;
this.array[ index + 0 ] = x;
this.array[ index + 1 ] = y;
this.array[ index + 2 ] = z;
return this;
},
setXYZW: function ( index, x, y, z, w ) {
index *= this.itemSize;
this.array[ index + 0 ] = x;
this.array[ index + 1 ] = y;
this.array[ index + 2 ] = z;
this.array[ index + 3 ] = w;
return this;
},
onUpload: function ( callback ) {
this.onUploadCallback = callback;
return this;
},
clone: function () {
return new this.constructor( this.array, this.itemSize ).copy( this );
}
} );
//
function Int8BufferAttribute( array, itemSize ) {
BufferAttribute.call( this, new Int8Array( array ), itemSize );
}
Int8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
Int8BufferAttribute.prototype.constructor = Int8BufferAttribute;
function Uint8BufferAttribute( array, itemSize ) {
BufferAttribute.call( this, new Uint8Array( array ), itemSize );
}
Uint8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
Uint8BufferAttribute.prototype.constructor = Uint8BufferAttribute;
function Uint8ClampedBufferAttribute( array, itemSize ) {
BufferAttribute.call( this, new Uint8ClampedArray( array ), itemSize );
}
Uint8ClampedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );
Uint8ClampedBufferAttribute.prototype.constructor = Uint8ClampedBufferAttribute;
function Int16BufferAttribute( array, itemSize ) {
BufferAttribute.call( this, new Int16Array( array ), itemSize );
}
Int16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
Int16BufferAttribute.prototype.constructor = Int16BufferAttribute;
function Uint16BufferAttribute( array, itemSize ) {
BufferAttribute.call( this, new Uint16Array( array ), itemSize );
}
Uint16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
Uint16BufferAttribute.prototype.constructor = Uint16BufferAttribute;
function Int32BufferAttribute( array, itemSize ) {
BufferAttribute.call( this, new Int32Array( array ), itemSize );
}
Int32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
Int32BufferAttribute.prototype.constructor = Int32BufferAttribute;
function Uint32BufferAttribute( array, itemSize ) {
BufferAttribute.call( this, new Uint32Array( array ), itemSize );
}
Uint32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
Uint32BufferAttribute.prototype.constructor = Uint32BufferAttribute;
function Float32BufferAttribute( array, itemSize ) {
BufferAttribute.call( this, new Float32Array( array ), itemSize );
}
Float32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
Float32BufferAttribute.prototype.constructor = Float32BufferAttribute;
function Float64BufferAttribute( array, itemSize ) {
BufferAttribute.call( this, new Float64Array( array ), itemSize );
}
Float64BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
Float64BufferAttribute.prototype.constructor = Float64BufferAttribute;
/**
* @author mrdoob / http://mrdoob.com/
*/
function DirectGeometry() {
this.indices = [];
this.vertices = [];
this.normals = [];
this.colors = [];
this.uvs = [];
this.uvs2 = [];
this.groups = [];
this.morphTargets = {};
this.skinWeights = [];
this.skinIndices = [];
// this.lineDistances = [];
this.boundingBox = null;
this.boundingSphere = null;
// update flags
this.verticesNeedUpdate = false;
this.normalsNeedUpdate = false;
this.colorsNeedUpdate = false;
this.uvsNeedUpdate = false;
this.groupsNeedUpdate = false;
}
Object.assign( DirectGeometry.prototype, {
computeGroups: function ( geometry ) {
var group;
var groups = [];
var materialIndex = undefined;
var faces = geometry.faces;
for ( var i = 0; i < faces.length; i ++ ) {
var face = faces[ i ];
// materials
if ( face.materialIndex !== materialIndex ) {
materialIndex = face.materialIndex;
if ( group !== undefined ) {
group.count = ( i * 3 ) - group.start;
groups.push( group );
}
group = {
start: i * 3,
materialIndex: materialIndex
};
}
}
if ( group !== undefined ) {
group.count = ( i * 3 ) - group.start;
groups.push( group );
}
this.groups = groups;
},
fromGeometry: function ( geometry ) {
var faces = geometry.faces;
var vertices = geometry.vertices;
var faceVertexUvs = geometry.faceVertexUvs;
var hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0;
var hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0;
// morphs
var morphTargets = geometry.morphTargets;
var morphTargetsLength = morphTargets.length;
var morphTargetsPosition;
if ( morphTargetsLength > 0 ) {
morphTargetsPosition = [];
for ( var i = 0; i < morphTargetsLength; i ++ ) {
morphTargetsPosition[ i ] = [];
}
this.morphTargets.position = morphTargetsPosition;
}
var morphNormals = geometry.morphNormals;
var morphNormalsLength = morphNormals.length;
var morphTargetsNormal;
if ( morphNormalsLength > 0 ) {
morphTargetsNormal = [];
for ( var i = 0; i < morphNormalsLength; i ++ ) {
morphTargetsNormal[ i ] = [];
}
this.morphTargets.normal = morphTargetsNormal;
}
// skins
var skinIndices = geometry.skinIndices;
var skinWeights = geometry.skinWeights;
var hasSkinIndices = skinIndices.length === vertices.length;
var hasSkinWeights = skinWeights.length === vertices.length;
//
for ( var i = 0; i < faces.length; i ++ ) {
var face = faces[ i ];
this.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] );
var vertexNormals = face.vertexNormals;
if ( vertexNormals.length === 3 ) {
this.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] );
} else {
var normal = face.normal;
this.normals.push( normal, normal, normal );
}
var vertexColors = face.vertexColors;
if ( vertexColors.length === 3 ) {
this.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] );
} else {
var color = face.color;
this.colors.push( color, color, color );
}
if ( hasFaceVertexUv === true ) {
var vertexUvs = faceVertexUvs[ 0 ][ i ];
if ( vertexUvs !== undefined ) {
this.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );
} else {
console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i );
this.uvs.push( new Vector2(), new Vector2(), new Vector2() );
}
}
if ( hasFaceVertexUv2 === true ) {
var vertexUvs = faceVertexUvs[ 1 ][ i ];
if ( vertexUvs !== undefined ) {
this.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );
} else {
console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i );
this.uvs2.push( new Vector2(), new Vector2(), new Vector2() );
}
}
// morphs
for ( var j = 0; j < morphTargetsLength; j ++ ) {
var morphTarget = morphTargets[ j ].vertices;
morphTargetsPosition[ j ].push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] );
}
for ( var j = 0; j < morphNormalsLength; j ++ ) {
var morphNormal = morphNormals[ j ].vertexNormals[ i ];
morphTargetsNormal[ j ].push( morphNormal.a, morphNormal.b, morphNormal.c );
}
// skins
if ( hasSkinIndices ) {
this.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] );
}
if ( hasSkinWeights ) {
this.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] );
}
}
this.computeGroups( geometry );
this.verticesNeedUpdate = geometry.verticesNeedUpdate;
this.normalsNeedUpdate = geometry.normalsNeedUpdate;
this.colorsNeedUpdate = geometry.colorsNeedUpdate;
this.uvsNeedUpdate = geometry.uvsNeedUpdate;
this.groupsNeedUpdate = geometry.groupsNeedUpdate;
return this;
}
} );
function arrayMax( array ) {
if ( array.length === 0 ) return - Infinity;
var max = array[ 0 ];
for ( var i = 1, l = array.length; i < l; ++ i ) {
if ( array[ i ] > max ) max = array[ i ];
}
return max;
}
/**
* @author alteredq / http://alteredqualia.com/
* @author mrdoob / http://mrdoob.com/
*/
function BufferGeometry() {
Object.defineProperty( this, 'id', { value: GeometryIdCount() } );
this.uuid = _Math.generateUUID();
this.name = '';
this.type = 'BufferGeometry';
this.index = null;
this.attributes = {};
this.morphAttributes = {};
this.groups = [];
this.boundingBox = null;
this.boundingSphere = null;
this.drawRange = { start: 0, count: Infinity };
}
BufferGeometry.MaxIndex = 65535;
Object.assign( BufferGeometry.prototype, EventDispatcher.prototype, {
isBufferGeometry: true,
getIndex: function () {
return this.index;
},
setIndex: function ( index ) {
if ( Array.isArray( index ) ) {
this.index = new ( arrayMax( index ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 );
} else {
this.index = index;
}
},
addAttribute: function ( name, attribute ) {
if ( ! ( attribute && attribute.isBufferAttribute ) && ! ( attribute && attribute.isInterleavedBufferAttribute ) ) {
console.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' );
this.addAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) );
return;
}
if ( name === 'index' ) {
console.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' );
this.setIndex( attribute );
return;
}
this.attributes[ name ] = attribute;
return this;
},
getAttribute: function ( name ) {
return this.attributes[ name ];
},
removeAttribute: function ( name ) {
delete this.attributes[ name ];
return this;
},
addGroup: function ( start, count, materialIndex ) {
this.groups.push( {
start: start,
count: count,
materialIndex: materialIndex !== undefined ? materialIndex : 0
} );
},
clearGroups: function () {
this.groups = [];
},
setDrawRange: function ( start, count ) {
this.drawRange.start = start;
this.drawRange.count = count;
},
applyMatrix: function ( matrix ) {
var position = this.attributes.position;
if ( position !== undefined ) {
matrix.applyToBufferAttribute( position );
position.needsUpdate = true;
}
var normal = this.attributes.normal;
if ( normal !== undefined ) {
var normalMatrix = new Matrix3().getNormalMatrix( matrix );
normalMatrix.applyToBufferAttribute( normal );
normal.needsUpdate = true;
}
if ( this.boundingBox !== null ) {
this.computeBoundingBox();
}
if ( this.boundingSphere !== null ) {
this.computeBoundingSphere();
}
return this;
},
rotateX: function () {
// rotate geometry around world x-axis
var m1 = new Matrix4();
return function rotateX( angle ) {
m1.makeRotationX( angle );
this.applyMatrix( m1 );
return this;
};
}(),
rotateY: function () {
// rotate geometry around world y-axis
var m1 = new Matrix4();
return function rotateY( angle ) {
m1.makeRotationY( angle );
this.applyMatrix( m1 );
return this;
};
}(),
rotateZ: function () {
// rotate geometry around world z-axis
var m1 = new Matrix4();
return function rotateZ( angle ) {
m1.makeRotationZ( angle );
this.applyMatrix( m1 );
return this;
};
}(),
translate: function () {
// translate geometry
var m1 = new Matrix4();
return function translate( x, y, z ) {
m1.makeTranslation( x, y, z );
this.applyMatrix( m1 );
return this;
};
}(),
scale: function () {
// scale geometry
var m1 = new Matrix4();
return function scale( x, y, z ) {
m1.makeScale( x, y, z );
this.applyMatrix( m1 );
return this;
};
}(),
lookAt: function () {
var obj = new Object3D();
return function lookAt( vector ) {
obj.lookAt( vector );
obj.updateMatrix();
this.applyMatrix( obj.matrix );
};
}(),
center: function () {
this.computeBoundingBox();
var offset = this.boundingBox.getCenter().negate();
this.translate( offset.x, offset.y, offset.z );
return offset;
},
setFromObject: function ( object ) {
// console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this );
var geometry = object.geometry;
if ( object.isPoints || object.isLine ) {
var positions = new Float32BufferAttribute( geometry.vertices.length * 3, 3 );
var colors = new Float32BufferAttribute( geometry.colors.length * 3, 3 );
this.addAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) );
this.addAttribute( 'color', colors.copyColorsArray( geometry.colors ) );
if ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) {
var lineDistances = new Float32BufferAttribute( geometry.lineDistances.length, 1 );
this.addAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) );
}
if ( geometry.boundingSphere !== null ) {
this.boundingSphere = geometry.boundingSphere.clone();
}
if ( geometry.boundingBox !== null ) {
this.boundingBox = geometry.boundingBox.clone();
}
} else if ( object.isMesh ) {
if ( geometry && geometry.isGeometry ) {
this.fromGeometry( geometry );
}
}
return this;
},
updateFromObject: function ( object ) {
var geometry = object.geometry;
if ( object.isMesh ) {
var direct = geometry.__directGeometry;
if ( geometry.elementsNeedUpdate === true ) {
direct = undefined;
geometry.elementsNeedUpdate = false;
}
if ( direct === undefined ) {
return this.fromGeometry( geometry );
}
direct.verticesNeedUpdate = geometry.verticesNeedUpdate;
direct.normalsNeedUpdate = geometry.normalsNeedUpdate;
direct.colorsNeedUpdate = geometry.colorsNeedUpdate;
direct.uvsNeedUpdate = geometry.uvsNeedUpdate;
direct.groupsNeedUpdate = geometry.groupsNeedUpdate;
geometry.verticesNeedUpdate = false;
geometry.normalsNeedUpdate = false;
geometry.colorsNeedUpdate = false;
geometry.uvsNeedUpdate = false;
geometry.groupsNeedUpdate = false;
geometry = direct;
}
var attribute;
if ( geometry.verticesNeedUpdate === true ) {
attribute = this.attributes.position;
if ( attribute !== undefined ) {
attribute.copyVector3sArray( geometry.vertices );
attribute.needsUpdate = true;
}
geometry.verticesNeedUpdate = false;
}
if ( geometry.normalsNeedUpdate === true ) {
attribute = this.attributes.normal;
if ( attribute !== undefined ) {
attribute.copyVector3sArray( geometry.normals );
attribute.needsUpdate = true;
}
geometry.normalsNeedUpdate = false;
}
if ( geometry.colorsNeedUpdate === true ) {
attribute = this.attributes.color;
if ( attribute !== undefined ) {
attribute.copyColorsArray( geometry.colors );
attribute.needsUpdate = true;
}
geometry.colorsNeedUpdate = false;
}
if ( geometry.uvsNeedUpdate ) {
attribute = this.attributes.uv;
if ( attribute !== undefined ) {
attribute.copyVector2sArray( geometry.uvs );
attribute.needsUpdate = true;
}
geometry.uvsNeedUpdate = false;
}
if ( geometry.lineDistancesNeedUpdate ) {
attribute = this.attributes.lineDistance;
if ( attribute !== undefined ) {
attribute.copyArray( geometry.lineDistances );
attribute.needsUpdate = true;
}
geometry.lineDistancesNeedUpdate = false;
}
if ( geometry.groupsNeedUpdate ) {
geometry.computeGroups( object.geometry );
this.groups = geometry.groups;
geometry.groupsNeedUpdate = false;
}
return this;
},
fromGeometry: function ( geometry ) {
geometry.__directGeometry = new DirectGeometry().fromGeometry( geometry );
return this.fromDirectGeometry( geometry.__directGeometry );
},
fromDirectGeometry: function ( geometry ) {
var positions = new Float32Array( geometry.vertices.length * 3 );
this.addAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) );
if ( geometry.normals.length > 0 ) {
var normals = new Float32Array( geometry.normals.length * 3 );
this.addAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) );
}
if ( geometry.colors.length > 0 ) {
var colors = new Float32Array( geometry.colors.length * 3 );
this.addAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) );
}
if ( geometry.uvs.length > 0 ) {
var uvs = new Float32Array( geometry.uvs.length * 2 );
this.addAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) );
}
if ( geometry.uvs2.length > 0 ) {
var uvs2 = new Float32Array( geometry.uvs2.length * 2 );
this.addAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) );
}
if ( geometry.indices.length > 0 ) {
var TypeArray = arrayMax( geometry.indices ) > 65535 ? Uint32Array : Uint16Array;
var indices = new TypeArray( geometry.indices.length * 3 );
this.setIndex( new BufferAttribute( indices, 1 ).copyIndicesArray( geometry.indices ) );
}
// groups
this.groups = geometry.groups;
// morphs
for ( var name in geometry.morphTargets ) {
var array = [];
var morphTargets = geometry.morphTargets[ name ];
for ( var i = 0, l = morphTargets.length; i < l; i ++ ) {
var morphTarget = morphTargets[ i ];
var attribute = new Float32BufferAttribute( morphTarget.length * 3, 3 );
array.push( attribute.copyVector3sArray( morphTarget ) );
}
this.morphAttributes[ name ] = array;
}
// skinning
if ( geometry.skinIndices.length > 0 ) {
var skinIndices = new Float32BufferAttribute( geometry.skinIndices.length * 4, 4 );
this.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) );
}
if ( geometry.skinWeights.length > 0 ) {
var skinWeights = new Float32BufferAttribute( geometry.skinWeights.length * 4, 4 );
this.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) );
}
//
if ( geometry.boundingSphere !== null ) {
this.boundingSphere = geometry.boundingSphere.clone();
}
if ( geometry.boundingBox !== null ) {
this.boundingBox = geometry.boundingBox.clone();
}
return this;
},
computeBoundingBox: function () {
if ( this.boundingBox === null ) {
this.boundingBox = new Box3();
}
var position = this.attributes.position;
if ( position !== undefined ) {
this.boundingBox.setFromBufferAttribute( position );
} else {
this.boundingBox.makeEmpty();
}
if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {
console.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this );
}
},
computeBoundingSphere: function () {
var box = new Box3();
var vector = new Vector3();
return function computeBoundingSphere() {
if ( this.boundingSphere === null ) {
this.boundingSphere = new Sphere();
}
var position = this.attributes.position;
if ( position ) {
var center = this.boundingSphere.center;
box.setFromBufferAttribute( position );
box.getCenter( center );
// hoping to find a boundingSphere with a radius smaller than the
// boundingSphere of the boundingBox: sqrt(3) smaller in the best case
var maxRadiusSq = 0;
for ( var i = 0, il = position.count; i < il; i ++ ) {
vector.x = position.getX( i );
vector.y = position.getY( i );
vector.z = position.getZ( i );
maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );
}
this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
if ( isNaN( this.boundingSphere.radius ) ) {
console.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this );
}
}
};
}(),
computeFaceNormals: function () {
// backwards compatibility
},
computeVertexNormals: function () {
var index = this.index;
var attributes = this.attributes;
var groups = this.groups;
if ( attributes.position ) {
var positions = attributes.position.array;
if ( attributes.normal === undefined ) {
this.addAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) );
} else {
// reset existing normals to zero
var array = attributes.normal.array;
for ( var i = 0, il = array.length; i < il; i ++ ) {
array[ i ] = 0;
}
}
var normals = attributes.normal.array;
var vA, vB, vC;
var pA = new Vector3(), pB = new Vector3(), pC = new Vector3();
var cb = new Vector3(), ab = new Vector3();
// indexed elements
if ( index ) {
var indices = index.array;
if ( groups.length === 0 ) {
this.addGroup( 0, indices.length );
}
for ( var j = 0, jl = groups.length; j < jl; ++ j ) {
var group = groups[ j ];
var start = group.start;
var count = group.count;
for ( var i = start, il = start + count; i < il; i += 3 ) {
vA = indices[ i + 0 ] * 3;
vB = indices[ i + 1 ] * 3;
vC = indices[ i + 2 ] * 3;
pA.fromArray( positions, vA );
pB.fromArray( positions, vB );
pC.fromArray( positions, vC );
cb.subVectors( pC, pB );
ab.subVectors( pA, pB );
cb.cross( ab );
normals[ vA ] += cb.x;
normals[ vA + 1 ] += cb.y;
normals[ vA + 2 ] += cb.z;
normals[ vB ] += cb.x;
normals[ vB + 1 ] += cb.y;
normals[ vB + 2 ] += cb.z;
normals[ vC ] += cb.x;
normals[ vC + 1 ] += cb.y;
normals[ vC + 2 ] += cb.z;
}
}
} else {
// non-indexed elements (unconnected triangle soup)
for ( var i = 0, il = positions.length; i < il; i += 9 ) {
pA.fromArray( positions, i );
pB.fromArray( positions, i + 3 );
pC.fromArray( positions, i + 6 );
cb.subVectors( pC, pB );
ab.subVectors( pA, pB );
cb.cross( ab );
normals[ i ] = cb.x;
normals[ i + 1 ] = cb.y;
normals[ i + 2 ] = cb.z;
normals[ i + 3 ] = cb.x;
normals[ i + 4 ] = cb.y;
normals[ i + 5 ] = cb.z;
normals[ i + 6 ] = cb.x;
normals[ i + 7 ] = cb.y;
normals[ i + 8 ] = cb.z;
}
}
this.normalizeNormals();
attributes.normal.needsUpdate = true;
}
},
merge: function ( geometry, offset ) {
if ( ! ( geometry && geometry.isBufferGeometry ) ) {
console.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry );
return;
}
if ( offset === undefined ) offset = 0;
var attributes = this.attributes;
for ( var key in attributes ) {
if ( geometry.attributes[ key ] === undefined ) continue;
var attribute1 = attributes[ key ];
var attributeArray1 = attribute1.array;
var attribute2 = geometry.attributes[ key ];
var attributeArray2 = attribute2.array;
var attributeSize = attribute2.itemSize;
for ( var i = 0, j = attributeSize * offset; i < attributeArray2.length; i ++, j ++ ) {
attributeArray1[ j ] = attributeArray2[ i ];
}
}
return this;
},
normalizeNormals: function () {
var normals = this.attributes.normal;
var x, y, z, n;
for ( var i = 0, il = normals.count; i < il; i ++ ) {
x = normals.getX( i );
y = normals.getY( i );
z = normals.getZ( i );
n = 1.0 / Math.sqrt( x * x + y * y + z * z );
normals.setXYZ( i, x * n, y * n, z * n );
}
},
toNonIndexed: function () {
if ( this.index === null ) {
console.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' );
return this;
}
var geometry2 = new BufferGeometry();
var indices = this.index.array;
var attributes = this.attributes;
for ( var name in attributes ) {
var attribute = attributes[ name ];
var array = attribute.array;
var itemSize = attribute.itemSize;
var array2 = new array.constructor( indices.length * itemSize );
var index = 0, index2 = 0;
for ( var i = 0, l = indices.length; i < l; i ++ ) {
index = indices[ i ] * itemSize;
for ( var j = 0; j < itemSize; j ++ ) {
array2[ index2 ++ ] = array[ index ++ ];
}
}
geometry2.addAttribute( name, new BufferAttribute( array2, itemSize ) );
}
return geometry2;
},
toJSON: function () {
var data = {
metadata: {
version: 4.5,
type: 'BufferGeometry',
generator: 'BufferGeometry.toJSON'
}
};
// standard BufferGeometry serialization
data.uuid = this.uuid;
data.type = this.type;
if ( this.name !== '' ) data.name = this.name;
if ( this.parameters !== undefined ) {
var parameters = this.parameters;
for ( var key in parameters ) {
if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];
}
return data;
}
data.data = { attributes: {} };
var index = this.index;
if ( index !== null ) {
var array = Array.prototype.slice.call( index.array );
data.data.index = {
type: index.array.constructor.name,
array: array
};
}
var attributes = this.attributes;
for ( var key in attributes ) {
var attribute = attributes[ key ];
var array = Array.prototype.slice.call( attribute.array );
data.data.attributes[ key ] = {
itemSize: attribute.itemSize,
type: attribute.array.constructor.name,
array: array,
normalized: attribute.normalized
};
}
var groups = this.groups;
if ( groups.length > 0 ) {
data.data.groups = JSON.parse( JSON.stringify( groups ) );
}
var boundingSphere = this.boundingSphere;
if ( boundingSphere !== null ) {
data.data.boundingSphere = {
center: boundingSphere.center.toArray(),
radius: boundingSphere.radius
};
}
return data;
},
clone: function () {
/*
// Handle primitives
var parameters = this.parameters;
if ( parameters !== undefined ) {
var values = [];
for ( var key in parameters ) {
values.push( parameters[ key ] );
}
var geometry = Object.create( this.constructor.prototype );
this.constructor.apply( geometry, values );
return geometry;
}
return new this.constructor().copy( this );
*/
return new BufferGeometry().copy( this );
},
copy: function ( source ) {
var name, i, l;
// reset
this.index = null;
this.attributes = {};
this.morphAttributes = {};
this.groups = [];
this.boundingBox = null;
this.boundingSphere = null;
// name
this.name = source.name;
// index
var index = source.index;
if ( index !== null ) {
this.setIndex( index.clone() );
}
// attributes
var attributes = source.attributes;
for ( name in attributes ) {
var attribute = attributes[ name ];
this.addAttribute( name, attribute.clone() );
}
// morph attributes
var morphAttributes = source.morphAttributes;
for ( name in morphAttributes ) {
var array = [];
var morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes
for ( i = 0, l = morphAttribute.length; i < l; i ++ ) {
array.push( morphAttribute[ i ].clone() );
}
this.morphAttributes[ name ] = array;
}
// groups
var groups = source.groups;
for ( i = 0, l = groups.length; i < l; i ++ ) {
var group = groups[ i ];
this.addGroup( group.start, group.count, group.materialIndex );
}
// bounding box
var boundingBox = source.boundingBox;
if ( boundingBox !== null ) {
this.boundingBox = boundingBox.clone();
}
// bounding sphere
var boundingSphere = source.boundingSphere;
if ( boundingSphere !== null ) {
this.boundingSphere = boundingSphere.clone();
}
// draw range
this.drawRange.start = source.drawRange.start;
this.drawRange.count = source.drawRange.count;
return this;
},
dispose: function () {
this.dispatchEvent( { type: 'dispose' } );
}
} );
/**
* @author mrdoob / http://mrdoob.com/
* @author Mugen87 / https://github.com/Mugen87
*/
// BoxGeometry
function BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {
Geometry.call( this );
this.type = 'BoxGeometry';
this.parameters = {
width: width,
height: height,
depth: depth,
widthSegments: widthSegments,
heightSegments: heightSegments,
depthSegments: depthSegments
};
this.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) );
this.mergeVertices();
}
BoxGeometry.prototype = Object.create( Geometry.prototype );
BoxGeometry.prototype.constructor = BoxGeometry;
// BoxBufferGeometry
function BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {
BufferGeometry.call( this );
this.type = 'BoxBufferGeometry';
this.parameters = {
width: width,
height: height,
depth: depth,
widthSegments: widthSegments,
heightSegments: heightSegments,
depthSegments: depthSegments
};
var scope = this;
// segments
widthSegments = Math.floor( widthSegments ) || 1;
heightSegments = Math.floor( heightSegments ) || 1;
depthSegments = Math.floor( depthSegments ) || 1;
// buffers
var indices = [];
var vertices = [];
var normals = [];
var uvs = [];
// helper variables
var numberOfVertices = 0;
var groupStart = 0;
// build each side of the box geometry
buildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px
buildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx
buildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py
buildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny
buildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz
buildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz
// build geometry
this.setIndex( indices );
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
function buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) {
var segmentWidth = width / gridX;
var segmentHeight = height / gridY;
var widthHalf = width / 2;
var heightHalf = height / 2;
var depthHalf = depth / 2;
var gridX1 = gridX + 1;
var gridY1 = gridY + 1;
var vertexCounter = 0;
var groupCount = 0;
var ix, iy;
var vector = new Vector3();
// generate vertices, normals and uvs
for ( iy = 0; iy < gridY1; iy ++ ) {
var y = iy * segmentHeight - heightHalf;
for ( ix = 0; ix < gridX1; ix ++ ) {
var x = ix * segmentWidth - widthHalf;
// set values to correct vector component
vector[ u ] = x * udir;
vector[ v ] = y * vdir;
vector[ w ] = depthHalf;
// now apply vector to vertex buffer
vertices.push( vector.x, vector.y, vector.z );
// set values to correct vector component
vector[ u ] = 0;
vector[ v ] = 0;
vector[ w ] = depth > 0 ? 1 : - 1;
// now apply vector to normal buffer
normals.push( vector.x, vector.y, vector.z );
// uvs
uvs.push( ix / gridX );
uvs.push( 1 - ( iy / gridY ) );
// counters
vertexCounter += 1;
}
}
// indices
// 1. you need three indices to draw a single face
// 2. a single segment consists of two faces
// 3. so we need to generate six (2*3) indices per segment
for ( iy = 0; iy < gridY; iy ++ ) {
for ( ix = 0; ix < gridX; ix ++ ) {
var a = numberOfVertices + ix + gridX1 * iy;
var b = numberOfVertices + ix + gridX1 * ( iy + 1 );
var c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 );
var d = numberOfVertices + ( ix + 1 ) + gridX1 * iy;
// faces
indices.push( a, b, d );
indices.push( b, c, d );
// increase counter
groupCount += 6;
}
}
// add a group to the geometry. this will ensure multi material support
scope.addGroup( groupStart, groupCount, materialIndex );
// calculate new start value for groups
groupStart += groupCount;
// update total number of vertices
numberOfVertices += vertexCounter;
}
}
BoxBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
BoxBufferGeometry.prototype.constructor = BoxBufferGeometry;
/**
* @author mrdoob / http://mrdoob.com/
* @author Mugen87 / https://github.com/Mugen87
*/
// PlaneGeometry
function PlaneGeometry( width, height, widthSegments, heightSegments ) {
Geometry.call( this );
this.type = 'PlaneGeometry';
this.parameters = {
width: width,
height: height,
widthSegments: widthSegments,
heightSegments: heightSegments
};
this.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) );
this.mergeVertices();
}
PlaneGeometry.prototype = Object.create( Geometry.prototype );
PlaneGeometry.prototype.constructor = PlaneGeometry;
// PlaneBufferGeometry
function PlaneBufferGeometry( width, height, widthSegments, heightSegments ) {
BufferGeometry.call( this );
this.type = 'PlaneBufferGeometry';
this.parameters = {
width: width,
height: height,
widthSegments: widthSegments,
heightSegments: heightSegments
};
var width_half = width / 2;
var height_half = height / 2;
var gridX = Math.floor( widthSegments ) || 1;
var gridY = Math.floor( heightSegments ) || 1;
var gridX1 = gridX + 1;
var gridY1 = gridY + 1;
var segment_width = width / gridX;
var segment_height = height / gridY;
var ix, iy;
// buffers
var indices = [];
var vertices = [];
var normals = [];
var uvs = [];
// generate vertices, normals and uvs
for ( iy = 0; iy < gridY1; iy ++ ) {
var y = iy * segment_height - height_half;
for ( ix = 0; ix < gridX1; ix ++ ) {
var x = ix * segment_width - width_half;
vertices.push( x, - y, 0 );
normals.push( 0, 0, 1 );
uvs.push( ix / gridX );
uvs.push( 1 - ( iy / gridY ) );
}
}
// indices
for ( iy = 0; iy < gridY; iy ++ ) {
for ( ix = 0; ix < gridX; ix ++ ) {
var a = ix + gridX1 * iy;
var b = ix + gridX1 * ( iy + 1 );
var c = ( ix + 1 ) + gridX1 * ( iy + 1 );
var d = ( ix + 1 ) + gridX1 * iy;
// faces
indices.push( a, b, d );
indices.push( b, c, d );
}
}
// build geometry
this.setIndex( indices );
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
}
PlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
PlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry;
/**
* @author mrdoob / http://mrdoob.com/
* @author alteredq / http://alteredqualia.com/
*
* parameters = {
* color: <hex>,
* opacity: <float>,
* map: new THREE.Texture( <Image> ),
*
* lightMap: new THREE.Texture( <Image> ),
* lightMapIntensity: <float>
*
* aoMap: new THREE.Texture( <Image> ),
* aoMapIntensity: <float>
*
* specularMap: new THREE.Texture( <Image> ),
*
* alphaMap: new THREE.Texture( <Image> ),
*
* envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),
* combine: THREE.Multiply,
* reflectivity: <float>,
* refractionRatio: <float>,
*
* shading: THREE.SmoothShading,
* depthTest: <bool>,
* depthWrite: <bool>,
*
* wireframe: <boolean>,
* wireframeLinewidth: <float>,
*
* skinning: <bool>,
* morphTargets: <bool>
* }
*/
function MeshBasicMaterial( parameters ) {
Material.call( this );
this.type = 'MeshBasicMaterial';
this.color = new Color( 0xffffff ); // emissive
this.map = null;
this.lightMap = null;
this.lightMapIntensity = 1.0;
this.aoMap = null;
this.aoMapIntensity = 1.0;
this.specularMap = null;
this.alphaMap = null;
this.envMap = null;
this.combine = MultiplyOperation;
this.reflectivity = 1;
this.refractionRatio = 0.98;
this.wireframe = false;
this.wireframeLinewidth = 1;
this.wireframeLinecap = 'round';
this.wireframeLinejoin = 'round';
this.skinning = false;
this.morphTargets = false;
this.lights = false;
this.setValues( parameters );
}
MeshBasicMaterial.prototype = Object.create( Material.prototype );
MeshBasicMaterial.prototype.constructor = MeshBasicMaterial;
MeshBasicMaterial.prototype.isMeshBasicMaterial = true;
MeshBasicMaterial.prototype.copy = function ( source ) {
Material.prototype.copy.call( this, source );
this.color.copy( source.color );
this.map = source.map;
this.lightMap = source.lightMap;
this.lightMapIntensity = source.lightMapIntensity;
this.aoMap = source.aoMap;
this.aoMapIntensity = source.aoMapIntensity;
this.specularMap = source.specularMap;
this.alphaMap = source.alphaMap;
this.envMap = source.envMap;
this.combine = source.combine;
this.reflectivity = source.reflectivity;
this.refractionRatio = source.refractionRatio;
this.wireframe = source.wireframe;
this.wireframeLinewidth = source.wireframeLinewidth;
this.wireframeLinecap = source.wireframeLinecap;
this.wireframeLinejoin = source.wireframeLinejoin;
this.skinning = source.skinning;
this.morphTargets = source.morphTargets;
return this;
};
/**
* @author bhouston / http://clara.io
*/
function Ray( origin, direction ) {
this.origin = ( origin !== undefined ) ? origin : new Vector3();
this.direction = ( direction !== undefined ) ? direction : new Vector3();
}
Object.assign( Ray.prototype, {
set: function ( origin, direction ) {
this.origin.copy( origin );
this.direction.copy( direction );
return this;
},
clone: function () {
return new this.constructor().copy( this );
},
copy: function ( ray ) {
this.origin.copy( ray.origin );
this.direction.copy( ray.direction );
return this;
},
at: function ( t, optionalTarget ) {
var result = optionalTarget || new Vector3();
return result.copy( this.direction ).multiplyScalar( t ).add( this.origin );
},
lookAt: function ( v ) {
this.direction.copy( v ).sub( this.origin ).normalize();
return this;
},
recast: function () {
var v1 = new Vector3();
return function recast( t ) {
this.origin.copy( this.at( t, v1 ) );
return this;
};
}(),
closestPointToPoint: function ( point, optionalTarget ) {
var result = optionalTarget || new Vector3();
result.subVectors( point, this.origin );
var directionDistance = result.dot( this.direction );
if ( directionDistance < 0 ) {
return result.copy( this.origin );
}
return result.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );
},
distanceToPoint: function ( point ) {
return Math.sqrt( this.distanceSqToPoint( point ) );
},
distanceSqToPoint: function () {
var v1 = new Vector3();
return function distanceSqToPoint( point ) {
var directionDistance = v1.subVectors( point, this.origin ).dot( this.direction );
// point behind the ray
if ( directionDistance < 0 ) {
return this.origin.distanceToSquared( point );
}
v1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );
return v1.distanceToSquared( point );
};
}(),
distanceSqToSegment: function () {
var segCenter = new Vector3();
var segDir = new Vector3();
var diff = new Vector3();
return function distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) {
// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h
// It returns the min distance between the ray and the segment
// defined by v0 and v1
// It can also set two optional targets :
// - The closest point on the ray
// - The closest point on the segment
segCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 );
segDir.copy( v1 ).sub( v0 ).normalize();
diff.copy( this.origin ).sub( segCenter );
var segExtent = v0.distanceTo( v1 ) * 0.5;
var a01 = - this.direction.dot( segDir );
var b0 = diff.dot( this.direction );
var b1 = - diff.dot( segDir );
var c = diff.lengthSq();
var det = Math.abs( 1 - a01 * a01 );
var s0, s1, sqrDist, extDet;
if ( det > 0 ) {
// The ray and segment are not parallel.
s0 = a01 * b1 - b0;
s1 = a01 * b0 - b1;
extDet = segExtent * det;
if ( s0 >= 0 ) {
if ( s1 >= - extDet ) {
if ( s1 <= extDet ) {
// region 0
// Minimum at interior points of ray and segment.
var invDet = 1 / det;
s0 *= invDet;
s1 *= invDet;
sqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;
} else {
// region 1
s1 = segExtent;
s0 = Math.max( 0, - ( a01 * s1 + b0 ) );
sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
}
} else {
// region 5
s1 = - segExtent;
s0 = Math.max( 0, - ( a01 * s1 + b0 ) );
sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
}
} else {
if ( s1 <= - extDet ) {
// region 4
s0 = Math.max( 0, - ( - a01 * segExtent + b0 ) );
s1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );
sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
} else if ( s1 <= extDet ) {
// region 3
s0 = 0;
s1 = Math.min( Math.max( - segExtent, - b1 ), segExtent );
sqrDist = s1 * ( s1 + 2 * b1 ) + c;
} else {
// region 2
s0 = Math.max( 0, - ( a01 * segExtent + b0 ) );
s1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );
sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
}
}
} else {
// Ray and segment are parallel.
s1 = ( a01 > 0 ) ? - segExtent : segExtent;
s0 = Math.max( 0, - ( a01 * s1 + b0 ) );
sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
}
if ( optionalPointOnRay ) {
optionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin );
}
if ( optionalPointOnSegment ) {
optionalPointOnSegment.copy( segDir ).multiplyScalar( s1 ).add( segCenter );
}
return sqrDist;
};
}(),
intersectSphere: function () {
var v1 = new Vector3();
return function intersectSphere( sphere, optionalTarget ) {
v1.subVectors( sphere.center, this.origin );
var tca = v1.dot( this.direction );
var d2 = v1.dot( v1 ) - tca * tca;
var radius2 = sphere.radius * sphere.radius;
if ( d2 > radius2 ) return null;
var thc = Math.sqrt( radius2 - d2 );
// t0 = first intersect point - entrance on front of sphere
var t0 = tca - thc;
// t1 = second intersect point - exit point on back of sphere
var t1 = tca + thc;
// test to see if both t0 and t1 are behind the ray - if so, return null
if ( t0 < 0 && t1 < 0 ) return null;
// test to see if t0 is behind the ray:
// if it is, the ray is inside the sphere, so return the second exit point scaled by t1,
// in order to always return an intersect point that is in front of the ray.
if ( t0 < 0 ) return this.at( t1, optionalTarget );
// else t0 is in front of the ray, so return the first collision point scaled by t0
return this.at( t0, optionalTarget );
};
}(),
intersectsSphere: function ( sphere ) {
return this.distanceToPoint( sphere.center ) <= sphere.radius;
},
distanceToPlane: function ( plane ) {
var denominator = plane.normal.dot( this.direction );
if ( denominator === 0 ) {
// line is coplanar, return origin
if ( plane.distanceToPoint( this.origin ) === 0 ) {
return 0;
}
// Null is preferable to undefined since undefined means.... it is undefined
return null;
}
var t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator;
// Return if the ray never intersects the plane
return t >= 0 ? t : null;
},
intersectPlane: function ( plane, optionalTarget ) {
var t = this.distanceToPlane( plane );
if ( t === null ) {
return null;
}
return this.at( t, optionalTarget );
},
intersectsPlane: function ( plane ) {
// check if the ray lies on the plane first
var distToPoint = plane.distanceToPoint( this.origin );
if ( distToPoint === 0 ) {
return true;
}
var denominator = plane.normal.dot( this.direction );
if ( denominator * distToPoint < 0 ) {
return true;
}
// ray origin is behind the plane (and is pointing behind it)
return false;
},
intersectBox: function ( box, optionalTarget ) {
var tmin, tmax, tymin, tymax, tzmin, tzmax;
var invdirx = 1 / this.direction.x,
invdiry = 1 / this.direction.y,
invdirz = 1 / this.direction.z;
var origin = this.origin;
if ( invdirx >= 0 ) {
tmin = ( box.min.x - origin.x ) * invdirx;
tmax = ( box.max.x - origin.x ) * invdirx;
} else {
tmin = ( box.max.x - origin.x ) * invdirx;
tmax = ( box.min.x - origin.x ) * invdirx;
}
if ( invdiry >= 0 ) {
tymin = ( box.min.y - origin.y ) * invdiry;
tymax = ( box.max.y - origin.y ) * invdiry;
} else {
tymin = ( box.max.y - origin.y ) * invdiry;
tymax = ( box.min.y - origin.y ) * invdiry;
}
if ( ( tmin > tymax ) || ( tymin > tmax ) ) return null;
// These lines also handle the case where tmin or tmax is NaN
// (result of 0 * Infinity). x !== x returns true if x is NaN
if ( tymin > tmin || tmin !== tmin ) tmin = tymin;
if ( tymax < tmax || tmax !== tmax ) tmax = tymax;
if ( invdirz >= 0 ) {
tzmin = ( box.min.z - origin.z ) * invdirz;
tzmax = ( box.max.z - origin.z ) * invdirz;
} else {
tzmin = ( box.max.z - origin.z ) * invdirz;
tzmax = ( box.min.z - origin.z ) * invdirz;
}
if ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null;
if ( tzmin > tmin || tmin !== tmin ) tmin = tzmin;
if ( tzmax < tmax || tmax !== tmax ) tmax = tzmax;
//return point closest to the ray (positive side)
if ( tmax < 0 ) return null;
return this.at( tmin >= 0 ? tmin : tmax, optionalTarget );
},
intersectsBox: ( function () {
var v = new Vector3();
return function intersectsBox( box ) {
return this.intersectBox( box, v ) !== null;
};
} )(),
intersectTriangle: function () {
// Compute the offset origin, edges, and normal.
var diff = new Vector3();
var edge1 = new Vector3();
var edge2 = new Vector3();
var normal = new Vector3();
return function intersectTriangle( a, b, c, backfaceCulling, optionalTarget ) {
// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h
edge1.subVectors( b, a );
edge2.subVectors( c, a );
normal.crossVectors( edge1, edge2 );
// Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,
// E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by
// |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))
// |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))
// |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)
var DdN = this.direction.dot( normal );
var sign;
if ( DdN > 0 ) {
if ( backfaceCulling ) return null;
sign = 1;
} else if ( DdN < 0 ) {
sign = - 1;
DdN = - DdN;
} else {
return null;
}
diff.subVectors( this.origin, a );
var DdQxE2 = sign * this.direction.dot( edge2.crossVectors( diff, edge2 ) );
// b1 < 0, no intersection
if ( DdQxE2 < 0 ) {
return null;
}
var DdE1xQ = sign * this.direction.dot( edge1.cross( diff ) );
// b2 < 0, no intersection
if ( DdE1xQ < 0 ) {
return null;
}
// b1+b2 > 1, no intersection
if ( DdQxE2 + DdE1xQ > DdN ) {
return null;
}
// Line intersects triangle, check if ray does.
var QdN = - sign * diff.dot( normal );
// t < 0, no intersection
if ( QdN < 0 ) {
return null;
}
// Ray intersects triangle.
return this.at( QdN / DdN, optionalTarget );
};
}(),
applyMatrix4: function ( matrix4 ) {
this.origin.applyMatrix4( matrix4 );
this.direction.transformDirection( matrix4 );
return this;
},
equals: function ( ray ) {
return ray.origin.equals( this.origin ) && ray.direction.equals( this.direction );
}
} );
/**
* @author bhouston / http://clara.io
*/
function Line3( start, end ) {
this.start = ( start !== undefined ) ? start : new Vector3();
this.end = ( end !== undefined ) ? end : new Vector3();
}
Object.assign( Line3.prototype, {
set: function ( start, end ) {
this.start.copy( start );
this.end.copy( end );
return this;
},
clone: function () {
return new this.constructor().copy( this );
},
copy: function ( line ) {
this.start.copy( line.start );
this.end.copy( line.end );
return this;
},
getCenter: function ( optionalTarget ) {
var result = optionalTarget || new Vector3();
return result.addVectors( this.start, this.end ).multiplyScalar( 0.5 );
},
delta: function ( optionalTarget ) {
var result = optionalTarget || new Vector3();
return result.subVectors( this.end, this.start );
},
distanceSq: function () {
return this.start.distanceToSquared( this.end );
},
distance: function () {
return this.start.distanceTo( this.end );
},
at: function ( t, optionalTarget ) {
var result = optionalTarget || new Vector3();
return this.delta( result ).multiplyScalar( t ).add( this.start );
},
closestPointToPointParameter: function () {
var startP = new Vector3();
var startEnd = new Vector3();
return function closestPointToPointParameter( point, clampToLine ) {
startP.subVectors( point, this.start );
startEnd.subVectors( this.end, this.start );
var startEnd2 = startEnd.dot( startEnd );
var startEnd_startP = startEnd.dot( startP );
var t = startEnd_startP / startEnd2;
if ( clampToLine ) {
t = _Math.clamp( t, 0, 1 );
}
return t;
};
}(),
closestPointToPoint: function ( point, clampToLine, optionalTarget ) {
var t = this.closestPointToPointParameter( point, clampToLine );
var result = optionalTarget || new Vector3();
return this.delta( result ).multiplyScalar( t ).add( this.start );
},
applyMatrix4: function ( matrix ) {
this.start.applyMatrix4( matrix );
this.end.applyMatrix4( matrix );
return this;
},
equals: function ( line ) {
return line.start.equals( this.start ) && line.end.equals( this.end );
}
} );
/**
* @author bhouston / http://clara.io
* @author mrdoob / http://mrdoob.com/
*/
function Triangle( a, b, c ) {
this.a = ( a !== undefined ) ? a : new Vector3();
this.b = ( b !== undefined ) ? b : new Vector3();
this.c = ( c !== undefined ) ? c : new Vector3();
}
Object.assign( Triangle, {
normal: function () {
var v0 = new Vector3();
return function normal( a, b, c, optionalTarget ) {
var result = optionalTarget || new Vector3();
result.subVectors( c, b );
v0.subVectors( a, b );
result.cross( v0 );
var resultLengthSq = result.lengthSq();
if ( resultLengthSq > 0 ) {
return result.multiplyScalar( 1 / Math.sqrt( resultLengthSq ) );
}
return result.set( 0, 0, 0 );
};
}(),
// static/instance method to calculate barycentric coordinates
// based on: http://www.blackpawn.com/texts/pointinpoly/default.html
barycoordFromPoint: function () {
var v0 = new Vector3();
var v1 = new Vector3();
var v2 = new Vector3();
return function barycoordFromPoint( point, a, b, c, optionalTarget ) {
v0.subVectors( c, a );
v1.subVectors( b, a );
v2.subVectors( point, a );
var dot00 = v0.dot( v0 );
var dot01 = v0.dot( v1 );
var dot02 = v0.dot( v2 );
var dot11 = v1.dot( v1 );
var dot12 = v1.dot( v2 );
var denom = ( dot00 * dot11 - dot01 * dot01 );
var result = optionalTarget || new Vector3();
// collinear or singular triangle
if ( denom === 0 ) {
// arbitrary location outside of triangle?
// not sure if this is the best idea, maybe should be returning undefined
return result.set( - 2, - 1, - 1 );
}
var invDenom = 1 / denom;
var u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
var v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;
// barycentric coordinates must always sum to 1
return result.set( 1 - u - v, v, u );
};
}(),
containsPoint: function () {
var v1 = new Vector3();
return function containsPoint( point, a, b, c ) {
var result = Triangle.barycoordFromPoint( point, a, b, c, v1 );
return ( result.x >= 0 ) && ( result.y >= 0 ) && ( ( result.x + result.y ) <= 1 );
};
}()
} );
Object.assign( Triangle.prototype, {
set: function ( a, b, c ) {
this.a.copy( a );
this.b.copy( b );
this.c.copy( c );
return this;
},
setFromPointsAndIndices: function ( points, i0, i1, i2 ) {
this.a.copy( points[ i0 ] );
this.b.copy( points[ i1 ] );
this.c.copy( points[ i2 ] );
return this;
},
clone: function () {
return new this.constructor().copy( this );
},
copy: function ( triangle ) {
this.a.copy( triangle.a );
this.b.copy( triangle.b );
this.c.copy( triangle.c );
return this;
},
area: function () {
var v0 = new Vector3();
var v1 = new Vector3();
return function area() {
v0.subVectors( this.c, this.b );
v1.subVectors( this.a, this.b );
return v0.cross( v1 ).length() * 0.5;
};
}(),
midpoint: function ( optionalTarget ) {
var result = optionalTarget || new Vector3();
return result.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 );
},
normal: function ( optionalTarget ) {
return Triangle.normal( this.a, this.b, this.c, optionalTarget );
},
plane: function ( optionalTarget ) {
var result = optionalTarget || new Plane();
return result.setFromCoplanarPoints( this.a, this.b, this.c );
},
barycoordFromPoint: function ( point, optionalTarget ) {
return Triangle.barycoordFromPoint( point, this.a, this.b, this.c, optionalTarget );
},
containsPoint: function ( point ) {
return Triangle.containsPoint( point, this.a, this.b, this.c );
},
closestPointToPoint: function () {
var plane = new Plane();
var edgeList = [ new Line3(), new Line3(), new Line3() ];
var projectedPoint = new Vector3();
var closestPoint = new Vector3();
return function closestPointToPoint( point, optionalTarget ) {
var result = optionalTarget || new Vector3();
var minDistance = Infinity;
// project the point onto the plane of the triangle
plane.setFromCoplanarPoints( this.a, this.b, this.c );
plane.projectPoint( point, projectedPoint );
// check if the projection lies within the triangle
if( this.containsPoint( projectedPoint ) === true ) {
// if so, this is the closest point
result.copy( projectedPoint );
} else {
// if not, the point falls outside the triangle. the result is the closest point to the triangle's edges or vertices
edgeList[ 0 ].set( this.a, this.b );
edgeList[ 1 ].set( this.b, this.c );
edgeList[ 2 ].set( this.c, this.a );
for( var i = 0; i < edgeList.length; i ++ ) {
edgeList[ i ].closestPointToPoint( projectedPoint, true, closestPoint );
var distance = projectedPoint.distanceToSquared( closestPoint );
if( distance < minDistance ) {
minDistance = distance;
result.copy( closestPoint );
}
}
}
return result;
};
}(),
equals: function ( triangle ) {
return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );
}
} );
/**
* @author mrdoob / http://mrdoob.com/
* @author alteredq / http://alteredqualia.com/
* @author mikael emtinger / http://gomo.se/
* @author jonobr1 / http://jonobr1.com/
*/
function Mesh( geometry, material ) {
Object3D.call( this );
this.type = 'Mesh';
this.geometry = geometry !== undefined ? geometry : new BufferGeometry();
this.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } );
this.drawMode = TrianglesDrawMode;
this.updateMorphTargets();
}
Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), {
constructor: Mesh,
isMesh: true,
setDrawMode: function ( value ) {
this.drawMode = value;
},
copy: function ( source ) {
Object3D.prototype.copy.call( this, source );
this.drawMode = source.drawMode;
return this;
},
updateMorphTargets: function () {
var geometry = this.geometry;
var m, ml, name;
if ( geometry.isBufferGeometry ) {
var morphAttributes = geometry.morphAttributes;
var keys = Object.keys( morphAttributes );
if ( keys.length > 0 ) {
var morphAttribute = morphAttributes[ keys[ 0 ] ];
if ( morphAttribute !== undefined ) {
this.morphTargetInfluences = [];
this.morphTargetDictionary = {};
for ( m = 0, ml = morphAttribute.length; m < ml; m ++ ) {
name = morphAttribute[ m ].name || String( m );
this.morphTargetInfluences.push( 0 );
this.morphTargetDictionary[ name ] = m;
}
}
}
} else {
var morphTargets = geometry.morphTargets;
if ( morphTargets !== undefined && morphTargets.length > 0 ) {
this.morphTargetInfluences = [];
this.morphTargetDictionary = {};
for ( m = 0, ml = morphTargets.length; m < ml; m ++ ) {
name = morphTargets[ m ].name || String( m );
this.morphTargetInfluences.push( 0 );
this.morphTargetDictionary[ name ] = m;
}
}
}
},
raycast: ( function () {
var inverseMatrix = new Matrix4();
var ray = new Ray();
var sphere = new Sphere();
var vA = new Vector3();
var vB = new Vector3();
var vC = new Vector3();
var tempA = new Vector3();
var tempB = new Vector3();
var tempC = new Vector3();
var uvA = new Vector2();
var uvB = new Vector2();
var uvC = new Vector2();
var barycoord = new Vector3();
var intersectionPoint = new Vector3();
var intersectionPointWorld = new Vector3();
function uvIntersection( point, p1, p2, p3, uv1, uv2, uv3 ) {
Triangle.barycoordFromPoint( point, p1, p2, p3, barycoord );
uv1.multiplyScalar( barycoord.x );
uv2.multiplyScalar( barycoord.y );
uv3.multiplyScalar( barycoord.z );
uv1.add( uv2 ).add( uv3 );
return uv1.clone();
}
function checkIntersection( object, raycaster, ray, pA, pB, pC, point ) {
var intersect;
var material = object.material;
if ( material.side === BackSide ) {
intersect = ray.intersectTriangle( pC, pB, pA, true, point );
} else {
intersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point );
}
if ( intersect === null ) return null;
intersectionPointWorld.copy( point );
intersectionPointWorld.applyMatrix4( object.matrixWorld );
var distance = raycaster.ray.origin.distanceTo( intersectionPointWorld );
if ( distance < raycaster.near || distance > raycaster.far ) return null;
return {
distance: distance,
point: intersectionPointWorld.clone(),
object: object
};
}
function checkBufferGeometryIntersection( object, raycaster, ray, position, uv, a, b, c ) {
vA.fromBufferAttribute( position, a );
vB.fromBufferAttribute( position, b );
vC.fromBufferAttribute( position, c );
var intersection = checkIntersection( object, raycaster, ray, vA, vB, vC, intersectionPoint );
if ( intersection ) {
if ( uv ) {
uvA.fromBufferAttribute( uv, a );
uvB.fromBufferAttribute( uv, b );
uvC.fromBufferAttribute( uv, c );
intersection.uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC );
}
intersection.face = new Face3( a, b, c, Triangle.normal( vA, vB, vC ) );
intersection.faceIndex = a;
}
return intersection;
}
return function raycast( raycaster, intersects ) {
var geometry = this.geometry;
var material = this.material;
var matrixWorld = this.matrixWorld;
if ( material === undefined ) return;
// Checking boundingSphere distance to ray
if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
sphere.copy( geometry.boundingSphere );
sphere.applyMatrix4( matrixWorld );
if ( raycaster.ray.intersectsSphere( sphere ) === false ) return;
//
inverseMatrix.getInverse( matrixWorld );
ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );
// Check boundingBox before continuing
if ( geometry.boundingBox !== null ) {
if ( ray.intersectsBox( geometry.boundingBox ) === false ) return;
}
var intersection;
if ( geometry.isBufferGeometry ) {
var a, b, c;
var index = geometry.index;
var position = geometry.attributes.position;
var uv = geometry.attributes.uv;
var i, l;
if ( index !== null ) {
// indexed buffer geometry
for ( i = 0, l = index.count; i < l; i += 3 ) {
a = index.getX( i );
b = index.getX( i + 1 );
c = index.getX( i + 2 );
intersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c );
if ( intersection ) {
intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indices buffer semantics
intersects.push( intersection );
}
}
} else {
// non-indexed buffer geometry
for ( i = 0, l = position.count; i < l; i += 3 ) {
a = i;
b = i + 1;
c = i + 2;
intersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c );
if ( intersection ) {
intersection.index = a; // triangle number in positions buffer semantics
intersects.push( intersection );
}
}
}
} else if ( geometry.isGeometry ) {
var fvA, fvB, fvC;
var isMultiMaterial = Array.isArray( material );
var vertices = geometry.vertices;
var faces = geometry.faces;
var uvs;
var faceVertexUvs = geometry.faceVertexUvs[ 0 ];
if ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs;
for ( var f = 0, fl = faces.length; f < fl; f ++ ) {
var face = faces[ f ];
var faceMaterial = isMultiMaterial ? material[ face.materialIndex ] : material;
if ( faceMaterial === undefined ) continue;
fvA = vertices[ face.a ];
fvB = vertices[ face.b ];
fvC = vertices[ face.c ];
if ( faceMaterial.morphTargets === true ) {
var morphTargets = geometry.morphTargets;
var morphInfluences = this.morphTargetInfluences;
vA.set( 0, 0, 0 );
vB.set( 0, 0, 0 );
vC.set( 0, 0, 0 );
for ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) {
var influence = morphInfluences[ t ];
if ( influence === 0 ) continue;
var targets = morphTargets[ t ].vertices;
vA.addScaledVector( tempA.subVectors( targets[ face.a ], fvA ), influence );
vB.addScaledVector( tempB.subVectors( targets[ face.b ], fvB ), influence );
vC.addScaledVector( tempC.subVectors( targets[ face.c ], fvC ), influence );
}
vA.add( fvA );
vB.add( fvB );
vC.add( fvC );
fvA = vA;
fvB = vB;
fvC = vC;
}
intersection = checkIntersection( this, raycaster, ray, fvA, fvB, fvC, intersectionPoint );
if ( intersection ) {
if ( uvs && uvs[ f ] ) {
var uvs_f = uvs[ f ];
uvA.copy( uvs_f[ 0 ] );
uvB.copy( uvs_f[ 1 ] );
uvC.copy( uvs_f[ 2 ] );
intersection.uv = uvIntersection( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC );
}
intersection.face = face;
intersection.faceIndex = f;
intersects.push( intersection );
}
}
}
};
}() ),
clone: function () {
return new this.constructor( this.geometry, this.material ).copy( this );
}
} );
/**
* @author mrdoob / http://mrdoob.com/
*/
function WebGLBackground( renderer, state, objects, premultipliedAlpha ) {
var clearColor = new Color( 0x000000 );
var clearAlpha = 0;
var planeCamera, planeMesh;
var boxCamera, boxMesh;
function render( scene, camera, forceClear ) {
var background = scene.background;
if ( background === null ) {
setClear( clearColor, clearAlpha );
} else if ( background && background.isColor ) {
setClear( background, 1 );
forceClear = true;
}
if ( renderer.autoClear || forceClear ) {
renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );
}
if ( background && background.isCubeTexture ) {
if ( boxCamera === undefined ) {
boxCamera = new PerspectiveCamera();
boxMesh = new Mesh(
new BoxBufferGeometry( 5, 5, 5 ),
new ShaderMaterial( {
uniforms: ShaderLib.cube.uniforms,
vertexShader: ShaderLib.cube.vertexShader,
fragmentShader: ShaderLib.cube.fragmentShader,
side: BackSide,
depthTest: false,
depthWrite: false,
fog: false
} )
);
}
boxCamera.projectionMatrix.copy( camera.projectionMatrix );
boxCamera.matrixWorld.extractRotation( camera.matrixWorld );
boxCamera.matrixWorldInverse.getInverse( boxCamera.matrixWorld );
boxMesh.material.uniforms[ "tCube" ].value = background;
boxMesh.modelViewMatrix.multiplyMatrices( boxCamera.matrixWorldInverse, boxMesh.matrixWorld );
objects.update( boxMesh );
renderer.renderBufferDirect( boxCamera, null, boxMesh.geometry, boxMesh.material, boxMesh, null );
} else if ( background && background.isTexture ) {
if ( planeCamera === undefined ) {
planeCamera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
planeMesh = new Mesh(
new PlaneBufferGeometry( 2, 2 ),
new MeshBasicMaterial( { depthTest: false, depthWrite: false, fog: false } )
);
}
planeMesh.material.map = background;
objects.update( planeMesh );
renderer.renderBufferDirect( planeCamera, null, planeMesh.geometry, planeMesh.material, planeMesh, null );
}
}
function setClear( color, alpha ) {
state.buffers.color.setClear( color.r, color.g, color.b, alpha, premultipliedAlpha );
}
return {
getClearColor: function () {
return clearColor;
},
setClearColor: function ( color, alpha ) {
clearColor.set( color );
clearAlpha = alpha !== undefined ? alpha : 1;
setClear( clearColor, clearAlpha );
},
getClearAlpha: function () {
return clearAlpha;
},
setClearAlpha: function ( alpha ) {
clearAlpha = alpha;
setClear( clearColor, clearAlpha );
},
render: render
};
}
/**
* @author mrdoob / http://mrdoob.com/
*/
function painterSortStable( a, b ) {
if ( a.renderOrder !== b.renderOrder ) {
return a.renderOrder - b.renderOrder;
} else if ( a.program && b.program && a.program !== b.program ) {
return a.program.id - b.program.id;
} else if ( a.material.id !== b.material.id ) {
return a.material.id - b.material.id;
} else if ( a.z !== b.z ) {
return a.z - b.z;
} else {
return a.id - b.id;
}
}
function reversePainterSortStable( a, b ) {
if ( a.renderOrder !== b.renderOrder ) {
return a.renderOrder - b.renderOrder;
} if ( a.z !== b.z ) {
return b.z - a.z;
} else {
return a.id - b.id;
}
}
function WebGLRenderList() {
var opaque = [];
var opaqueLastIndex = - 1;
var transparent = [];
var transparentLastIndex = - 1;
function init() {
opaqueLastIndex = - 1;
transparentLastIndex = - 1;
}
function push( object, geometry, material, z, group ) {
var array, index;
// allocate the next position in the appropriate array
if ( material.transparent ) {
array = transparent;
index = ++ transparentLastIndex;
} else {
array = opaque;
index = ++ opaqueLastIndex;
}
// recycle existing render item or grow the array
var renderItem = array[ index ];
if ( renderItem ) {
renderItem.id = object.id;
renderItem.object = object;
renderItem.geometry = geometry;
renderItem.material = material;
renderItem.program = material.program;
renderItem.renderOrder = object.renderOrder;
renderItem.z = z;
renderItem.group = group;
} else {
renderItem = {
id: object.id,
object: object,
geometry: geometry,
material: material,
program: material.program,
renderOrder: object.renderOrder,
z: z,
group: group
};
// assert( index === array.length );
array.push( renderItem );
}
}
function finish() {
opaque.length = opaqueLastIndex + 1;
transparent.length = transparentLastIndex + 1;
}
function sort() {
opaque.sort( painterSortStable );
transparent.sort( reversePainterSortStable );
}
return {
opaque: opaque,
transparent: transparent,
init: init,
push: push,
finish: finish,
sort: sort
};
}
function WebGLRenderLists() {
var lists = {};
function get( scene, camera ) {
var hash = scene.id + ',' + camera.id;
var list = lists[ hash ];
if ( list === undefined ) {
// console.log( 'THREE.WebGLRenderLists:', hash );
list = new WebGLRenderList();
lists[ hash ] = list;
}
return list;
}
function dispose() {
lists = {};
}
return {
get: get,
dispose: dispose
};
}
/**
* @author mrdoob / http://mrdoob.com/
*/
function WebGLIndexedBufferRenderer( gl, extensions, infoRender ) {
var mode;
function setMode( value ) {
mode = value;
}
var type, bytesPerElement;
function setIndex( value ) {
type = value.type;
bytesPerElement = value.bytesPerElement;
}
function render( start, count ) {
gl.drawElements( mode, count, type, start * bytesPerElement );
infoRender.calls ++;
infoRender.vertices += count;
if ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;
}
function renderInstances( geometry, start, count ) {
var extension = extensions.get( 'ANGLE_instanced_arrays' );
if ( extension === null ) {
console.error( 'THREE.WebGLIndexedBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
return;
}
extension.drawElementsInstancedANGLE( mode, count, type, start * bytesPerElement, geometry.maxInstancedCount );
infoRender.calls ++;
infoRender.vertices += count * geometry.maxInstancedCount;
if ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;
}
//
this.setMode = setMode;
this.setIndex = setIndex;
this.render = render;
this.renderInstances = renderInstances;
}
/**
* @author mrdoob / http://mrdoob.com/
*/
function WebGLBufferRenderer( gl, extensions, infoRender ) {
var mode;
function setMode( value ) {
mode = value;
}
function render( start, count ) {
gl.drawArrays( mode, start, count );
infoRender.calls ++;
infoRender.vertices += count;
if ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;
}
function renderInstances( geometry, start, count ) {
var extension = extensions.get( 'ANGLE_instanced_arrays' );
if ( extension === null ) {
console.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
return;
}
var position = geometry.attributes.position;
if ( position.isInterleavedBufferAttribute ) {
count = position.data.count;
extension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );
} else {
extension.drawArraysInstancedANGLE( mode, start, count, geometry.maxInstancedCount );
}
infoRender.calls ++;
infoRender.vertices += count * geometry.maxInstancedCount;
if ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;
}
//
this.setMode = setMode;
this.render = render;
this.renderInstances = renderInstances;
}
/**
* @author mrdoob / http://mrdoob.com/
*/
function WebGLGeometries( gl, attributes, infoMemory ) {
var geometries = {};
var wireframeAttributes = {};
function onGeometryDispose( event ) {
var geometry = event.target;
var buffergeometry = geometries[ geometry.id ];
if ( buffergeometry.index !== null ) {
attributes.remove( buffergeometry.index );
}
for ( var name in buffergeometry.attributes ) {
attributes.remove( buffergeometry.attributes[ name ] );
}
geometry.removeEventListener( 'dispose', onGeometryDispose );
delete geometries[ geometry.id ];
// TODO Remove duplicate code
var attribute = wireframeAttributes[ geometry.id ];
if ( attribute ) {
attributes.remove( attribute );
delete wireframeAttributes[ geometry.id ];
}
attribute = wireframeAttributes[ buffergeometry.id ];
if ( attribute ) {
attributes.remove( attribute );
delete wireframeAttributes[ buffergeometry.id ];
}
//
infoMemory.geometries --;
}
function get( object, geometry ) {
var buffergeometry = geometries[ geometry.id ];
if ( buffergeometry ) return buffergeometry;
geometry.addEventListener( 'dispose', onGeometryDispose );
if ( geometry.isBufferGeometry ) {
buffergeometry = geometry;
} else if ( geometry.isGeometry ) {
if ( geometry._bufferGeometry === undefined ) {
geometry._bufferGeometry = new BufferGeometry().setFromObject( object );
}
buffergeometry = geometry._bufferGeometry;
}
geometries[ geometry.id ] = buffergeometry;
infoMemory.geometries ++;
return buffergeometry;
}
function update( geometry ) {
var index = geometry.index;
var geometryAttributes = geometry.attributes;
if ( index !== null ) {
attributes.update( index, gl.ELEMENT_ARRAY_BUFFER );
}
for ( var name in geometryAttributes ) {
attributes.update( geometryAttributes[ name ], gl.ARRAY_BUFFER );
}
// morph targets
var morphAttributes = geometry.morphAttributes;
for ( var name in morphAttributes ) {
var array = morphAttributes[ name ];
for ( var i = 0, l = array.length; i < l; i ++ ) {
attributes.update( array[ i ], gl.ARRAY_BUFFER );
}
}
}
function getWireframeAttribute( geometry ) {
var attribute = wireframeAttributes[ geometry.id ];
if ( attribute ) return attribute;
var indices = [];
var geometryIndex = geometry.index;
var geometryAttributes = geometry.attributes;
// console.time( 'wireframe' );
if ( geometryIndex !== null ) {
var array = geometryIndex.array;
for ( var i = 0, l = array.length; i < l; i += 3 ) {
var a = array[ i + 0 ];
var b = array[ i + 1 ];
var c = array[ i + 2 ];
indices.push( a, b, b, c, c, a );
}
} else {
var array = geometryAttributes.position.array;
for ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {
var a = i + 0;
var b = i + 1;
var c = i + 2;
indices.push( a, b, b, c, c, a );
}
}
// console.timeEnd( 'wireframe' );
attribute = new ( arrayMax( indices ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 );
attributes.update( attribute, gl.ELEMENT_ARRAY_BUFFER );
wireframeAttributes[ geometry.id ] = attribute;
return attribute;
}
return {
get: get,
update: update,
getWireframeAttribute: getWireframeAttribute
};
}
/**
* @author mrdoob / http://mrdoob.com/
*/
function WebGLLights() {
var lights = {};
return {
get: function ( light ) {
if ( lights[ light.id ] !== undefined ) {
return lights[ light.id ];
}
var uniforms;
switch ( light.type ) {
case 'DirectionalLight':
uniforms = {
direction: new Vector3(),
color: new Color(),
shadow: false,
shadowBias: 0,
shadowRadius: 1,
shadowMapSize: new Vector2()
};
break;
case 'SpotLight':
uniforms = {
position: new Vector3(),
direction: new Vector3(),
color: new Color(),
distance: 0,
coneCos: 0,
penumbraCos: 0,
decay: 0,
shadow: false,
shadowBias: 0,
shadowRadius: 1,
shadowMapSize: new Vector2()
};
break;
case 'PointLight':
uniforms = {
position: new Vector3(),
color: new Color(),
distance: 0,
decay: 0,
shadow: false,
shadowBias: 0,
shadowRadius: 1,
shadowMapSize: new Vector2()
};
break;
case 'HemisphereLight':
uniforms = {
direction: new Vector3(),
skyColor: new Color(),
groundColor: new Color()
};
break;
case 'RectAreaLight':
uniforms = {
color: new Color(),
position: new Vector3(),
halfWidth: new Vector3(),
halfHeight: new Vector3()
// TODO (abelnation): set RectAreaLight shadow uniforms
};
break;
}
lights[ light.id ] = uniforms;
return uniforms;
}
};
}
/**
* @author mrdoob / http://mrdoob.com/
*/
function WebGLObjects( gl, geometries, infoRender ) {
var updateList = {};
function update( object ) {
var frame = infoRender.frame;
var geometry = object.geometry;
var buffergeometry = geometries.get( object, geometry );
// Update once per frame
if ( updateList[ buffergeometry.id ] !== frame ) {
if ( geometry.isGeometry ) {
buffergeometry.updateFromObject( object );
}
geometries.update( buffergeometry );
updateList[ buffergeometry.id ] = frame;
}
return buffergeometry;
}
function clear() {
updateList = {};
}
return {
update: update,
clear: clear
};
}
/**
* @author mrdoob / http://mrdoob.com/
*/
function addLineNumbers( string ) {
var lines = string.split( '\n' );
for ( var i = 0; i < lines.length; i ++ ) {
lines[ i ] = ( i + 1 ) + ': ' + lines[ i ];
}
return lines.join( '\n' );
}
function WebGLShader( gl, type, string ) {
var shader = gl.createShader( type );
gl.shaderSource( shader, string );
gl.compileShader( shader );
if ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) {
console.error( 'THREE.WebGLShader: Shader couldn\'t compile.' );
}
if ( gl.getShaderInfoLog( shader ) !== '' ) {
console.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', type === gl.VERTEX_SHADER ? 'vertex' : 'fragment', gl.getShaderInfoLog( shader ), addLineNumbers( string ) );
}
// --enable-privileged-webgl-extension
// console.log( type, gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) );
return shader;
}
/**
* @author mrdoob / http://mrdoob.com/
*/
var programIdCount = 0;
function getEncodingComponents( encoding ) {
switch ( encoding ) {
case LinearEncoding:
return [ 'Linear','( value )' ];
case sRGBEncoding:
return [ 'sRGB','( value )' ];
case RGBEEncoding:
return [ 'RGBE','( value )' ];
case RGBM7Encoding:
return [ 'RGBM','( value, 7.0 )' ];
case RGBM16Encoding:
return [ 'RGBM','( value, 16.0 )' ];
case RGBDEncoding:
return [ 'RGBD','( value, 256.0 )' ];
case GammaEncoding:
return [ 'Gamma','( value, float( GAMMA_FACTOR ) )' ];
default:
throw new Error( 'unsupported encoding: ' + encoding );
}
}
function getTexelDecodingFunction( functionName, encoding ) {
var components = getEncodingComponents( encoding );
return "vec4 " + functionName + "( vec4 value ) { return " + components[ 0 ] + "ToLinear" + components[ 1 ] + "; }";
}
function getTexelEncodingFunction( functionName, encoding ) {
var components = getEncodingComponents( encoding );
return "vec4 " + functionName + "( vec4 value ) { return LinearTo" + components[ 0 ] + components[ 1 ] + "; }";
}
function getToneMappingFunction( functionName, toneMapping ) {
var toneMappingName;
switch ( toneMapping ) {
case LinearToneMapping:
toneMappingName = "Linear";
break;
case ReinhardToneMapping:
toneMappingName = "Reinhard";
break;
case Uncharted2ToneMapping:
toneMappingName = "Uncharted2";
break;
case CineonToneMapping:
toneMappingName = "OptimizedCineon";
break;
default:
throw new Error( 'unsupported toneMapping: ' + toneMapping );
}
return "vec3 " + functionName + "( vec3 color ) { return " + toneMappingName + "ToneMapping( color ); }";
}
function generateExtensions( extensions, parameters, rendererExtensions ) {
extensions = extensions || {};
var chunks = [
( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.normalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '',
( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '',
( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '',
( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : ''
];
return chunks.filter( filterEmptyLine ).join( '\n' );
}
function generateDefines( defines ) {
var chunks = [];
for ( var name in defines ) {
var value = defines[ name ];
if ( value === false ) continue;
chunks.push( '#define ' + name + ' ' + value );
}
return chunks.join( '\n' );
}
function fetchAttributeLocations( gl, program, identifiers ) {
var attributes = {};
var n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES );
for ( var i = 0; i < n; i ++ ) {
var info = gl.getActiveAttrib( program, i );
var name = info.name;
// console.log("THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:", name, i );
attributes[ name ] = gl.getAttribLocation( program, name );
}
return attributes;
}
function filterEmptyLine( string ) {
return string !== '';
}
function replaceLightNums( string, parameters ) {
return string
.replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights )
.replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights )
.replace( /NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights )
.replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights )
.replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights );
}
function parseIncludes( string ) {
var pattern = /^[ \t]*#include +<([\w\d.]+)>/gm;
function replace( match, include ) {
var replace = ShaderChunk[ include ];
if ( replace === undefined ) {
throw new Error( 'Can not resolve #include <' + include + '>' );
}
return parseIncludes( replace );
}
return string.replace( pattern, replace );
}
function unrollLoops( string ) {
var pattern = /for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g;
function replace( match, start, end, snippet ) {
var unroll = '';
for ( var i = parseInt( start ); i < parseInt( end ); i ++ ) {
unroll += snippet.replace( /\[ i \]/g, '[ ' + i + ' ]' );
}
return unroll;
}
return string.replace( pattern, replace );
}
function WebGLProgram( renderer, code, material, shader, parameters ) {
var gl = renderer.context;
var extensions = material.extensions;
var defines = material.defines;
var vertexShader = shader.vertexShader;
var fragmentShader = shader.fragmentShader;
var shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';
if ( parameters.shadowMapType === PCFShadowMap ) {
shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';
} else if ( parameters.shadowMapType === PCFSoftShadowMap ) {
shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';
}
var envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
var envMapModeDefine = 'ENVMAP_MODE_REFLECTION';
var envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
if ( parameters.envMap ) {
switch ( material.envMap.mapping ) {
case CubeReflectionMapping:
case CubeRefractionMapping:
envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
break;
case CubeUVReflectionMapping:
case CubeUVRefractionMapping:
envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';
break;
case EquirectangularReflectionMapping:
case EquirectangularRefractionMapping:
envMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';
break;
case SphericalReflectionMapping:
envMapTypeDefine = 'ENVMAP_TYPE_SPHERE';
break;
}
switch ( material.envMap.mapping ) {
case CubeRefractionMapping:
case EquirectangularRefractionMapping:
envMapModeDefine = 'ENVMAP_MODE_REFRACTION';
break;
}
switch ( material.combine ) {
case MultiplyOperation:
envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
break;
case MixOperation:
envMapBlendingDefine = 'ENVMAP_BLENDING_MIX';
break;
case AddOperation:
envMapBlendingDefine = 'ENVMAP_BLENDING_ADD';
break;
}
}
var gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0;
// console.log( 'building new program ' );
//
var customExtensions = generateExtensions( extensions, parameters, renderer.extensions );
var customDefines = generateDefines( defines );
//
var program = gl.createProgram();
var prefixVertex, prefixFragment;
if ( material.isRawShaderMaterial ) {
prefixVertex = [
customDefines,
'\n'
].filter( filterEmptyLine ).join( '\n' );
prefixFragment = [
customExtensions,
customDefines,
'\n'
].filter( filterEmptyLine ).join( '\n' );
} else {
prefixVertex = [
'precision ' + parameters.precision + ' float;',
'precision ' + parameters.precision + ' int;',
'#define SHADER_NAME ' + shader.name,
customDefines,
parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',
'#define GAMMA_FACTOR ' + gammaFactorDefine,
'#define MAX_BONES ' + parameters.maxBones,
( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',
( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',
parameters.map ? '#define USE_MAP' : '',
parameters.envMap ? '#define USE_ENVMAP' : '',
parameters.envMap ? '#define ' + envMapModeDefine : '',
parameters.lightMap ? '#define USE_LIGHTMAP' : '',
parameters.aoMap ? '#define USE_AOMAP' : '',
parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',
parameters.bumpMap ? '#define USE_BUMPMAP' : '',
parameters.normalMap ? '#define USE_NORMALMAP' : '',
parameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '',
parameters.specularMap ? '#define USE_SPECULARMAP' : '',
parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
parameters.vertexColors ? '#define USE_COLOR' : '',
parameters.flatShading ? '#define FLAT_SHADED' : '',
parameters.skinning ? '#define USE_SKINNING' : '',
parameters.useVertexTexture ? '#define BONE_TEXTURE' : '',
parameters.morphTargets ? '#define USE_MORPHTARGETS' : '',
parameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',
parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
parameters.flipSided ? '#define FLIP_SIDED' : '',
'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,
parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',
parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
parameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
'uniform mat4 modelMatrix;',
'uniform mat4 modelViewMatrix;',
'uniform mat4 projectionMatrix;',
'uniform mat4 viewMatrix;',
'uniform mat3 normalMatrix;',
'uniform vec3 cameraPosition;',
'attribute vec3 position;',
'attribute vec3 normal;',
'attribute vec2 uv;',
'#ifdef USE_COLOR',
' attribute vec3 color;',
'#endif',
'#ifdef USE_MORPHTARGETS',
' attribute vec3 morphTarget0;',
' attribute vec3 morphTarget1;',
' attribute vec3 morphTarget2;',
' attribute vec3 morphTarget3;',
' #ifdef USE_MORPHNORMALS',
' attribute vec3 morphNormal0;',
' attribute vec3 morphNormal1;',
' attribute vec3 morphNormal2;',
' attribute vec3 morphNormal3;',
' #else',
' attribute vec3 morphTarget4;',
' attribute vec3 morphTarget5;',
' attribute vec3 morphTarget6;',
' attribute vec3 morphTarget7;',
' #endif',
'#endif',
'#ifdef USE_SKINNING',
' attribute vec4 skinIndex;',
' attribute vec4 skinWeight;',
'#endif',
'\n'
].filter( filterEmptyLine ).join( '\n' );
prefixFragment = [
customExtensions,
'precision ' + parameters.precision + ' float;',
'precision ' + parameters.precision + ' int;',
'#define SHADER_NAME ' + shader.name,
customDefines,
parameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '',
'#define GAMMA_FACTOR ' + gammaFactorDefine,
( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',
( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',
parameters.map ? '#define USE_MAP' : '',
parameters.envMap ? '#define USE_ENVMAP' : '',
parameters.envMap ? '#define ' + envMapTypeDefine : '',
parameters.envMap ? '#define ' + envMapModeDefine : '',
parameters.envMap ? '#define ' + envMapBlendingDefine : '',
parameters.lightMap ? '#define USE_LIGHTMAP' : '',
parameters.aoMap ? '#define USE_AOMAP' : '',
parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',
parameters.bumpMap ? '#define USE_BUMPMAP' : '',
parameters.normalMap ? '#define USE_NORMALMAP' : '',
parameters.specularMap ? '#define USE_SPECULARMAP' : '',
parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
parameters.vertexColors ? '#define USE_COLOR' : '',
parameters.gradientMap ? '#define USE_GRADIENTMAP' : '',
parameters.flatShading ? '#define FLAT_SHADED' : '',
parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
parameters.flipSided ? '#define FLIP_SIDED' : '',
'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,
'#define UNION_CLIPPING_PLANES ' + (parameters.numClippingPlanes - parameters.numClipIntersection),
parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
parameters.premultipliedAlpha ? "#define PREMULTIPLIED_ALPHA" : '',
parameters.physicallyCorrectLights ? "#define PHYSICALLY_CORRECT_LIGHTS" : '',
parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
parameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
parameters.envMap && renderer.extensions.get( 'EXT_shader_texture_lod' ) ? '#define TEXTURE_LOD_EXT' : '',
'uniform mat4 viewMatrix;',
'uniform vec3 cameraPosition;',
( parameters.toneMapping !== NoToneMapping ) ? "#define TONE_MAPPING" : '',
( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below
( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( "toneMapping", parameters.toneMapping ) : '',
parameters.dithering ? '#define DITHERING' : '',
( parameters.outputEncoding || parameters.mapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding ) ? ShaderChunk[ 'encodings_pars_fragment' ] : '', // this code is required here because it is used by the various encoding/decoding function defined below
parameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',
parameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',
parameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',
parameters.outputEncoding ? getTexelEncodingFunction( "linearToOutputTexel", parameters.outputEncoding ) : '',
parameters.depthPacking ? "#define DEPTH_PACKING " + material.depthPacking : '',
'\n'
].filter( filterEmptyLine ).join( '\n' );
}
vertexShader = parseIncludes( vertexShader );
vertexShader = replaceLightNums( vertexShader, parameters );
fragmentShader = parseIncludes( fragmentShader );
fragmentShader = replaceLightNums( fragmentShader, parameters );
if ( ! material.isShaderMaterial ) {
vertexShader = unrollLoops( vertexShader );
fragmentShader = unrollLoops( fragmentShader );
}
var vertexGlsl = prefixVertex + vertexShader;
var fragmentGlsl = prefixFragment + fragmentShader;
// console.log( '*VERTEX*', vertexGlsl );
// console.log( '*FRAGMENT*', fragmentGlsl );
var glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );
var glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );
gl.attachShader( program, glVertexShader );
gl.attachShader( program, glFragmentShader );
// Force a particular attribute to index 0.
if ( material.index0AttributeName !== undefined ) {
gl.bindAttribLocation( program, 0, material.index0AttributeName );
} else if ( parameters.morphTargets === true ) {
// programs with morphTargets displace position out of attribute 0
gl.bindAttribLocation( program, 0, 'position' );
}
gl.linkProgram( program );
var programLog = gl.getProgramInfoLog( program );
var vertexLog = gl.getShaderInfoLog( glVertexShader );
var fragmentLog = gl.getShaderInfoLog( glFragmentShader );
var runnable = true;
var haveDiagnostics = true;
// console.log( '**VERTEX**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) );
// console.log( '**FRAGMENT**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) );
if ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {
runnable = false;
console.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexLog, fragmentLog );
} else if ( programLog !== '' ) {
console.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );
} else if ( vertexLog === '' || fragmentLog === '' ) {
haveDiagnostics = false;
}
if ( haveDiagnostics ) {
this.diagnostics = {
runnable: runnable,
material: material,
programLog: programLog,
vertexShader: {
log: vertexLog,
prefix: prefixVertex
},
fragmentShader: {
log: fragmentLog,
prefix: prefixFragment
}
};
}
// clean up
gl.deleteShader( glVertexShader );
gl.deleteShader( glFragmentShader );
// set up caching for uniform locations
var cachedUniforms;
this.getUniforms = function() {
if ( cachedUniforms === undefined ) {
cachedUniforms =
new WebGLUniforms( gl, program, renderer );
}
return cachedUniforms;
};
// set up caching for attribute locations
var cachedAttributes;
this.getAttributes = function() {
if ( cachedAttributes === undefined ) {
cachedAttributes = fetchAttributeLocations( gl, program );
}
return cachedAttributes;
};
// free resource
this.destroy = function() {
gl.deleteProgram( program );
this.program = undefined;
};
// DEPRECATED
Object.defineProperties( this, {
uniforms: {
get: function() {
console.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' );
return this.getUniforms();
}
},
attributes: {
get: function() {
console.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' );
return this.getAttributes();
}
}
} );
//
this.id = programIdCount ++;
this.code = code;
this.usedTimes = 1;
this.program = program;
this.vertexShader = glVertexShader;
this.fragmentShader = glFragmentShader;
return this;
}
/**
* @author mrdoob / http://mrdoob.com/
*/
function WebGLPrograms( renderer, capabilities ) {
var programs = [];
var shaderIDs = {
MeshDepthMaterial: 'depth',
MeshNormalMaterial: 'normal',
MeshBasicMaterial: 'basic',
MeshLambertMaterial: 'lambert',
MeshPhongMaterial: 'phong',
MeshToonMaterial: 'phong',
MeshStandardMaterial: 'physical',
MeshPhysicalMaterial: 'physical',
LineBasicMaterial: 'basic',
LineDashedMaterial: 'dashed',
PointsMaterial: 'points'
};
var parameterNames = [
"precision", "supportsVertexTextures", "map", "mapEncoding", "envMap", "envMapMode", "envMapEncoding",
"lightMap", "aoMap", "emissiveMap", "emissiveMapEncoding", "bumpMap", "normalMap", "displacementMap", "specularMap",
"roughnessMap", "metalnessMap", "gradientMap",
"alphaMap", "combine", "vertexColors", "fog", "useFog", "fogExp",
"flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning",
"maxBones", "useVertexTexture", "morphTargets", "morphNormals",
"maxMorphTargets", "maxMorphNormals", "premultipliedAlpha",
"numDirLights", "numPointLights", "numSpotLights", "numHemiLights", "numRectAreaLights",
"shadowMapEnabled", "shadowMapType", "toneMapping", 'physicallyCorrectLights',
"alphaTest", "doubleSided", "flipSided", "numClippingPlanes", "numClipIntersection", "depthPacking", "dithering"
];
function allocateBones( object ) {
var skeleton = object.skeleton;
var bones = skeleton.bones;
if ( capabilities.floatVertexTextures ) {
return 1024;
} else {
// default for when object is not specified
// ( for example when prebuilding shader to be used with multiple objects )
//
// - leave some extra space for other uniforms
// - limit here is ANGLE's 254 max uniform vectors
// (up to 54 should be safe)
var nVertexUniforms = capabilities.maxVertexUniforms;
var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );
var maxBones = Math.min( nVertexMatrices, bones.length );
if ( maxBones < bones.length ) {
console.warn( 'THREE.WebGLRenderer: Skeleton has ' + bones.length + ' bones. This GPU supports ' + maxBones + '.' );
return 0;
}
return maxBones;
}
}
function getTextureEncodingFromMap( map, gammaOverrideLinear ) {
var encoding;
if ( ! map ) {
encoding = LinearEncoding;
} else if ( map.isTexture ) {
encoding = map.encoding;
} else if ( map.isWebGLRenderTarget ) {
console.warn( "THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead." );
encoding = map.texture.encoding;
}
// add backwards compatibility for WebGLRenderer.gammaInput/gammaOutput parameter, should probably be removed at some point.
if ( encoding === LinearEncoding && gammaOverrideLinear ) {
encoding = GammaEncoding;
}
return encoding;
}
this.getParameters = function ( material, lights, fog, nClipPlanes, nClipIntersection, object ) {
var shaderID = shaderIDs[ material.type ];
// heuristics to create shader parameters according to lights in the scene
// (not to blow over maxLights budget)
var maxBones = object.isSkinnedMesh ? allocateBones( object ) : 0;
var precision = renderer.getPrecision();
if ( material.precision !== null ) {
precision = capabilities.getMaxPrecision( material.precision );
if ( precision !== material.precision ) {
console.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' );
}
}
var currentRenderTarget = renderer.getRenderTarget();
var parameters = {
shaderID: shaderID,
precision: precision,
supportsVertexTextures: capabilities.vertexTextures,
outputEncoding: getTextureEncodingFromMap( ( ! currentRenderTarget ) ? null : currentRenderTarget.texture, renderer.gammaOutput ),
map: !! material.map,
mapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ),
envMap: !! material.envMap,
envMapMode: material.envMap && material.envMap.mapping,
envMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ),
envMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === CubeUVReflectionMapping ) || ( material.envMap.mapping === CubeUVRefractionMapping ) ),
lightMap: !! material.lightMap,
aoMap: !! material.aoMap,
emissiveMap: !! material.emissiveMap,
emissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ),
bumpMap: !! material.bumpMap,
normalMap: !! material.normalMap,
displacementMap: !! material.displacementMap,
roughnessMap: !! material.roughnessMap,
metalnessMap: !! material.metalnessMap,
specularMap: !! material.specularMap,
alphaMap: !! material.alphaMap,
gradientMap: !! material.gradientMap,
combine: material.combine,
vertexColors: material.vertexColors,
fog: !! fog,
useFog: material.fog,
fogExp: ( fog && fog.isFogExp2 ),
flatShading: material.shading === FlatShading,
sizeAttenuation: material.sizeAttenuation,
logarithmicDepthBuffer: capabilities.logarithmicDepthBuffer,
skinning: material.skinning && maxBones > 0,
maxBones: maxBones,
useVertexTexture: capabilities.floatVertexTextures,
morphTargets: material.morphTargets,
morphNormals: material.morphNormals,
maxMorphTargets: renderer.maxMorphTargets,
maxMorphNormals: renderer.maxMorphNormals,
numDirLights: lights.directional.length,
numPointLights: lights.point.length,
numSpotLights: lights.spot.length,
numRectAreaLights: lights.rectArea.length,
numHemiLights: lights.hemi.length,
numClippingPlanes: nClipPlanes,
numClipIntersection: nClipIntersection,
dithering: material.dithering,
shadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && lights.shadows.length > 0,
shadowMapType: renderer.shadowMap.type,
toneMapping: renderer.toneMapping,
physicallyCorrectLights: renderer.physicallyCorrectLights,
premultipliedAlpha: material.premultipliedAlpha,
alphaTest: material.alphaTest,
doubleSided: material.side === DoubleSide,
flipSided: material.side === BackSide,
depthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false
};
return parameters;
};
this.getProgramCode = function ( material, parameters ) {
var array = [];
if ( parameters.shaderID ) {
array.push( parameters.shaderID );
} else {
array.push( material.fragmentShader );
array.push( material.vertexShader );
}
if ( material.defines !== undefined ) {
for ( var name in material.defines ) {
array.push( name );
array.push( material.defines[ name ] );
}
}
for ( var i = 0; i < parameterNames.length; i ++ ) {
array.push( parameters[ parameterNames[ i ] ] );
}
array.push( material.onBeforeCompile.toString() );
array.push( renderer.gammaOutput );
return array.join();
};
this.acquireProgram = function ( material, shader, parameters, code ) {
var program;
// Check if code has been already compiled
for ( var p = 0, pl = programs.length; p < pl; p ++ ) {
var programInfo = programs[ p ];
if ( programInfo.code === code ) {
program = programInfo;
++ program.usedTimes;
break;
}
}
if ( program === undefined ) {
program = new WebGLProgram( renderer, code, material, shader, parameters );
programs.push( program );
}
return program;
};
this.releaseProgram = function ( program ) {
if ( -- program.usedTimes === 0 ) {
// Remove from unordered set
var i = programs.indexOf( program );
programs[ i ] = programs[ programs.length - 1 ];
programs.pop();
// Free WebGL resources
program.destroy();
}
};
// Exposed for resource monitoring & error feedback via renderer.info:
this.programs = programs;
}
/**
* @author mrdoob / http://mrdoob.com/
*/
function WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, infoMemory ) {
var _isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && _gl instanceof WebGL2RenderingContext );
//
function clampToMaxSize( image, maxSize ) {
if ( image.width > maxSize || image.height > maxSize ) {
// Warning: Scaling through the canvas will only work with images that use
// premultiplied alpha.
var scale = maxSize / Math.max( image.width, image.height );
var canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );
canvas.width = Math.floor( image.width * scale );
canvas.height = Math.floor( image.height * scale );
var context = canvas.getContext( '2d' );
context.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height );
console.warn( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );
return canvas;
}
return image;
}
function isPowerOfTwo( image ) {
return _Math.isPowerOfTwo( image.width ) && _Math.isPowerOfTwo( image.height );
}
function makePowerOfTwo( image ) {
if ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement ) {
var canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );
canvas.width = _Math.nearestPowerOfTwo( image.width );
canvas.height = _Math.nearestPowerOfTwo( image.height );
var context = canvas.getContext( '2d' );
context.drawImage( image, 0, 0, canvas.width, canvas.height );
console.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );
return canvas;
}
return image;
}
function textureNeedsPowerOfTwo( texture ) {
return ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) ||
( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter );
}
function textureNeedsGenerateMipmaps( texture, isPowerOfTwo ) {
return texture.generateMipmaps && isPowerOfTwo &&
texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter;
}
// Fallback filters for non-power-of-2 textures
function filterFallback( f ) {
if ( f === NearestFilter || f === NearestMipMapNearestFilter || f === NearestMipMapLinearFilter ) {
return _gl.NEAREST;
}
return _gl.LINEAR;
}
//
function onTextureDispose( event ) {
var texture = event.target;
texture.removeEventListener( 'dispose', onTextureDispose );
deallocateTexture( texture );
infoMemory.textures --;
}
function onRenderTargetDispose( event ) {
var renderTarget = event.target;
renderTarget.removeEventListener( 'dispose', onRenderTargetDispose );
deallocateRenderTarget( renderTarget );
infoMemory.textures --;
}
//
function deallocateTexture( texture ) {
var textureProperties = properties.get( texture );
if ( texture.image && textureProperties.__image__webglTextureCube ) {
// cube texture
_gl.deleteTexture( textureProperties.__image__webglTextureCube );
} else {
// 2D texture
if ( textureProperties.__webglInit === undefined ) return;
_gl.deleteTexture( textureProperties.__webglTexture );
}
// remove all webgl properties
properties.remove( texture );
}
function deallocateRenderTarget( renderTarget ) {
var renderTargetProperties = properties.get( renderTarget );
var textureProperties = properties.get( renderTarget.texture );
if ( ! renderTarget ) return;
if ( textureProperties.__webglTexture !== undefined ) {
_gl.deleteTexture( textureProperties.__webglTexture );
}
if ( renderTarget.depthTexture ) {
renderTarget.depthTexture.dispose();
}
if ( renderTarget.isWebGLRenderTargetCube ) {
for ( var i = 0; i < 6; i ++ ) {
_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );
if ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] );
}
} else {
_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );
if ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer );
}
properties.remove( renderTarget.texture );
properties.remove( renderTarget );
}
//
function setTexture2D( texture, slot ) {
var textureProperties = properties.get( texture );
if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
var image = texture.image;
if ( image === undefined ) {
console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );
} else if ( image.complete === false ) {
console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );
} else {
uploadTexture( textureProperties, texture, slot );
return;
}
}
state.activeTexture( _gl.TEXTURE0 + slot );
state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
}
function setTextureCube( texture, slot ) {
var textureProperties = properties.get( texture );
if ( texture.image.length === 6 ) {
if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
if ( ! textureProperties.__image__webglTextureCube ) {
texture.addEventListener( 'dispose', onTextureDispose );
textureProperties.__image__webglTextureCube = _gl.createTexture();
infoMemory.textures ++;
}
state.activeTexture( _gl.TEXTURE0 + slot );
state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );
_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
var isCompressed = ( texture && texture.isCompressedTexture );
var isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture );
var cubeImage = [];
for ( var i = 0; i < 6; i ++ ) {
if ( ! isCompressed && ! isDataTexture ) {
cubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );
} else {
cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];
}
}
var image = cubeImage[ 0 ],
isPowerOfTwoImage = isPowerOfTwo( image ),
glFormat = paramThreeToGL( texture.format ),
glType = paramThreeToGL( texture.type );
setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage );
for ( var i = 0; i < 6; i ++ ) {
if ( ! isCompressed ) {
if ( isDataTexture ) {
state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data );
} else {
state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );
}
} else {
var mipmap, mipmaps = cubeImage[ i ].mipmaps;
for ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {
mipmap = mipmaps[ j ];
if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {
if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {
state.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );
} else {
console.warn( "THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()" );
}
} else {
state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
}
}
}
}
if ( textureNeedsGenerateMipmaps( texture, isPowerOfTwoImage ) ) {
_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
}
textureProperties.__version = texture.version;
if ( texture.onUpdate ) texture.onUpdate( texture );
} else {
state.activeTexture( _gl.TEXTURE0 + slot );
state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );
}
}
}
function setTextureCubeDynamic( texture, slot ) {
state.activeTexture( _gl.TEXTURE0 + slot );
state.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture );
}
function setTextureParameters( textureType, texture, isPowerOfTwoImage ) {
var extension;
if ( isPowerOfTwoImage ) {
_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
} else {
_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
if ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) {
console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.', texture );
}
_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
if ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) {
console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.', texture );
}
}
extension = extensions.get( 'EXT_texture_filter_anisotropic' );
if ( extension ) {
if ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;
if ( texture.type === HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return;
if ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {
_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) );
properties.get( texture ).__currentAnisotropy = texture.anisotropy;
}
}
}
function uploadTexture( textureProperties, texture, slot ) {
if ( textureProperties.__webglInit === undefined ) {
textureProperties.__webglInit = true;
texture.addEventListener( 'dispose', onTextureDispose );
textureProperties.__webglTexture = _gl.createTexture();
infoMemory.textures ++;
}
state.activeTexture( _gl.TEXTURE0 + slot );
state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );
var image = clampToMaxSize( texture.image, capabilities.maxTextureSize );
if ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( image ) === false ) {
image = makePowerOfTwo( image );
}
var isPowerOfTwoImage = isPowerOfTwo( image ),
glFormat = paramThreeToGL( texture.format ),
glType = paramThreeToGL( texture.type );
setTextureParameters( _gl.TEXTURE_2D, texture, isPowerOfTwoImage );
var mipmap, mipmaps = texture.mipmaps;
if ( texture.isDepthTexture ) {
// populate depth texture with dummy data
var internalFormat = _gl.DEPTH_COMPONENT;
if ( texture.type === FloatType ) {
if ( !_isWebGL2 ) throw new Error('Float Depth Texture only supported in WebGL2.0');
internalFormat = _gl.DEPTH_COMPONENT32F;
} else if ( _isWebGL2 ) {
// WebGL 2.0 requires signed internalformat for glTexImage2D
internalFormat = _gl.DEPTH_COMPONENT16;
}
if ( texture.format === DepthFormat && internalFormat === _gl.DEPTH_COMPONENT ) {
// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are
// DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT
// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)
if ( texture.type !== UnsignedShortType && texture.type !== UnsignedIntType ) {
console.warn( 'THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.' );
texture.type = UnsignedShortType;
glType = paramThreeToGL( texture.type );
}
}
// Depth stencil textures need the DEPTH_STENCIL internal format
// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)
if ( texture.format === DepthStencilFormat ) {
internalFormat = _gl.DEPTH_STENCIL;
// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are
// DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL.
// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)
if ( texture.type !== UnsignedInt248Type ) {
console.warn( 'THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.' );
texture.type = UnsignedInt248Type;
glType = paramThreeToGL( texture.type );
}
}
state.texImage2D( _gl.TEXTURE_2D, 0, internalFormat, image.width, image.height, 0, glFormat, glType, null );
} else if ( texture.isDataTexture ) {
// use manually created mipmaps if available
// if there are no manual mipmaps
// set 0 level mipmap and then use GL to generate other mipmap levels
if ( mipmaps.length > 0 && isPowerOfTwoImage ) {
for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {
mipmap = mipmaps[ i ];
state.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
}
texture.generateMipmaps = false;
} else {
state.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );
}
} else if ( texture.isCompressedTexture ) {
for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {
mipmap = mipmaps[ i ];
if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {
if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {
state.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );
} else {
console.warn( "THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()" );
}
} else {
state.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
}
}
} else {
// regular Texture (image, video, canvas)
// use manually created mipmaps if available
// if there are no manual mipmaps
// set 0 level mipmap and then use GL to generate other mipmap levels
if ( mipmaps.length > 0 && isPowerOfTwoImage ) {
for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {
mipmap = mipmaps[ i ];
state.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );
}
texture.generateMipmaps = false;
} else {
state.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, image );
}
}
if ( textureNeedsGenerateMipmaps( texture, isPowerOfTwoImage ) ) _gl.generateMipmap( _gl.TEXTURE_2D );
textureProperties.__version = texture.version;
if ( texture.onUpdate ) texture.onUpdate( texture );
}
// Render targets
// Setup storage for target texture and bind it to correct framebuffer
function setupFrameBufferTexture( framebuffer, renderTarget, attachment, textureTarget ) {
var glFormat = paramThreeToGL( renderTarget.texture.format );
var glType = paramThreeToGL( renderTarget.texture.type );
state.texImage2D( textureTarget, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );
_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
}
// Setup storage for internal depth/stencil buffers and bind to correct framebuffer
function setupRenderBufferStorage( renderbuffer, renderTarget ) {
_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
} else {
// FIXME: We don't support !depth !stencil
_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );
}
_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
}
// Setup resources for a Depth Texture for a FBO (needs an extension)
function setupDepthTexture( framebuffer, renderTarget ) {
var isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );
if ( isCube ) throw new Error('Depth Texture with cube render targets is not supported!');
_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
if ( !( renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture ) ) {
throw new Error('renderTarget.depthTexture must be an instance of THREE.DepthTexture');
}
// upload an empty depth texture with framebuffer size
if ( !properties.get( renderTarget.depthTexture ).__webglTexture ||
renderTarget.depthTexture.image.width !== renderTarget.width ||
renderTarget.depthTexture.image.height !== renderTarget.height ) {
renderTarget.depthTexture.image.width = renderTarget.width;
renderTarget.depthTexture.image.height = renderTarget.height;
renderTarget.depthTexture.needsUpdate = true;
}
setTexture2D( renderTarget.depthTexture, 0 );
var webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture;
if ( renderTarget.depthTexture.format === DepthFormat ) {
_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );
} else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {
_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );
} else {
throw new Error('Unknown depthTexture format')
}
}
// Setup GL resources for a non-texture depth buffer
function setupDepthRenderbuffer( renderTarget ) {
var renderTargetProperties = properties.get( renderTarget );
var isCube = ( renderTarget.isWebGLRenderTargetCube === true );
if ( renderTarget.depthTexture ) {
if ( isCube ) throw new Error('target.depthTexture not supported in Cube render targets');
setupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget );
} else {
if ( isCube ) {
renderTargetProperties.__webglDepthbuffer = [];
for ( var i = 0; i < 6; i ++ ) {
_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );
renderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();
setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );
}
} else {
_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );
renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();
setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );
}
}
_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
}
// Set up GL resources for the render target
function setupRenderTarget( renderTarget ) {
var renderTargetProperties = properties.get( renderTarget );
var textureProperties = properties.get( renderTarget.texture );
renderTarget.addEventListener( 'dispose', onRenderTargetDispose );
textureProperties.__webglTexture = _gl.createTexture();
infoMemory.textures ++;
var isCube = ( renderTarget.isWebGLRenderTargetCube === true );
var isTargetPowerOfTwo = isPowerOfTwo( renderTarget );
// Setup framebuffer
if ( isCube ) {
renderTargetProperties.__webglFramebuffer = [];
for ( var i = 0; i < 6; i ++ ) {
renderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();
}
} else {
renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();
}
// Setup color buffer
if ( isCube ) {
state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );
setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );
for ( var i = 0; i < 6; i ++ ) {
setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
}
if ( textureNeedsGenerateMipmaps( renderTarget.texture, isTargetPowerOfTwo ) ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
state.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
} else {
state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
setTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo );
setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D );
if ( textureNeedsGenerateMipmaps( renderTarget.texture, isTargetPowerOfTwo ) ) _gl.generateMipmap( _gl.TEXTURE_2D );
state.bindTexture( _gl.TEXTURE_2D, null );
}
// Setup depth and stencil buffers
if ( renderTarget.depthBuffer ) {
setupDepthRenderbuffer( renderTarget );
}
}
function updateRenderTargetMipmap( renderTarget ) {
var texture = renderTarget.texture;
var isTargetPowerOfTwo = isPowerOfTwo( renderTarget );
if ( textureNeedsGenerateMipmaps( texture, isTargetPowerOfTwo ) ) {
var target = renderTarget.isWebGLRenderTargetCube ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;
var webglTexture = properties.get( texture ).__webglTexture;
state.bindTexture( target, webglTexture );
_gl.generateMipmap( target );
state.bindTexture( target, null );
}
}
this.setTexture2D = setTexture2D;
this.setTextureCube = setTextureCube;
this.setTextureCubeDynamic = setTextureCubeDynamic;
this.setupRenderTarget = setupRenderTarget;
this.updateRenderTargetMipmap = updateRenderTargetMipmap;
}
/**
* @author fordacious / fordacious.github.io
*/
function WebGLProperties() {
var properties = {};
function get( object ) {
var uuid = object.uuid;
var map = properties[ uuid ];
if ( map === undefined ) {
map = {};
properties[ uuid ] = map;
}
return map;
}
function remove( object ) {
delete properties[ object.uuid ];
}
function clear() {
properties = {};
}
return {
get: get,
remove: remove,
clear: clear
};
}
/**
* @author mrdoob / http://mrdoob.com/
*/
function WebGLState( gl, extensions, paramThreeToGL ) {
function ColorBuffer() {
var locked = false;
var color = new Vector4();
var currentColorMask = null;
var currentColorClear = new Vector4();
return {
setMask: function ( colorMask ) {
if ( currentColorMask !== colorMask && ! locked ) {
gl.colorMask( colorMask, colorMask, colorMask, colorMask );
currentColorMask = colorMask;
}
},
setLocked: function ( lock ) {
locked = lock;
},
setClear: function ( r, g, b, a, premultipliedAlpha ) {
if ( premultipliedAlpha === true ) {
r *= a; g *= a; b *= a;
}
color.set( r, g, b, a );
if ( currentColorClear.equals( color ) === false ) {
gl.clearColor( r, g, b, a );
currentColorClear.copy( color );
}
},
reset: function () {
locked = false;
currentColorMask = null;
currentColorClear.set( 0, 0, 0, 1 );
}
};
}
function DepthBuffer() {
var locked = false;
var currentDepthMask = null;
var currentDepthFunc = null;
var currentDepthClear = null;
return {
setTest: function ( depthTest ) {
if ( depthTest ) {
enable( gl.DEPTH_TEST );
} else {
disable( gl.DEPTH_TEST );
}
},
setMask: function ( depthMask ) {
if ( currentDepthMask !== depthMask && ! locked ) {
gl.depthMask( depthMask );
currentDepthMask = depthMask;
}
},
setFunc: function ( depthFunc ) {
if ( currentDepthFunc !== depthFunc ) {
if ( depthFunc ) {
switch ( depthFunc ) {
case NeverDepth:
gl.depthFunc( gl.NEVER );
break;
case AlwaysDepth:
gl.depthFunc( gl.ALWAYS );
break;
case LessDepth:
gl.depthFunc( gl.LESS );
break;
case LessEqualDepth:
gl.depthFunc( gl.LEQUAL );
break;
case EqualDepth:
gl.depthFunc( gl.EQUAL );
break;
case GreaterEqualDepth:
gl.depthFunc( gl.GEQUAL );
break;
case GreaterDepth:
gl.depthFunc( gl.GREATER );
break;
case NotEqualDepth:
gl.depthFunc( gl.NOTEQUAL );
break;
default:
gl.depthFunc( gl.LEQUAL );
}
} else {
gl.depthFunc( gl.LEQUAL );
}
currentDepthFunc = depthFunc;
}
},
setLocked: function ( lock ) {
locked = lock;
},
setClear: function ( depth ) {
if ( currentDepthClear !== depth ) {
gl.clearDepth( depth );
currentDepthClear = depth;
}
},
reset: function () {
locked = false;
currentDepthMask = null;
currentDepthFunc = null;
currentDepthClear = null;
}
};
}
function StencilBuffer() {
var locked = false;
var currentStencilMask = null;
var currentStencilFunc = null;
var currentStencilRef = null;
var currentStencilFuncMask = null;
var currentStencilFail = null;
var currentStencilZFail = null;
var currentStencilZPass = null;
var currentStencilClear = null;
return {
setTest: function ( stencilTest ) {
if ( stencilTest ) {
enable( gl.STENCIL_TEST );
} else {
disable( gl.STENCIL_TEST );
}
},
setMask: function ( stencilMask ) {
if ( currentStencilMask !== stencilMask && ! locked ) {
gl.stencilMask( stencilMask );
currentStencilMask = stencilMask;
}
},
setFunc: function ( stencilFunc, stencilRef, stencilMask ) {
if ( currentStencilFunc !== stencilFunc ||
currentStencilRef !== stencilRef ||
currentStencilFuncMask !== stencilMask ) {
gl.stencilFunc( stencilFunc, stencilRef, stencilMask );
currentStencilFunc = stencilFunc;
currentStencilRef = stencilRef;
currentStencilFuncMask = stencilMask;
}
},
setOp: function ( stencilFail, stencilZFail, stencilZPass ) {
if ( currentStencilFail !== stencilFail ||
currentStencilZFail !== stencilZFail ||
currentStencilZPass !== stencilZPass ) {
gl.stencilOp( stencilFail, stencilZFail, stencilZPass );
currentStencilFail = stencilFail;
currentStencilZFail = stencilZFail;
currentStencilZPass = stencilZPass;
}
},
setLocked: function ( lock ) {
locked = lock;
},
setClear: function ( stencil ) {
if ( currentStencilClear !== stencil ) {
gl.clearStencil( stencil );
currentStencilClear = stencil;
}
},
reset: function () {
locked = false;
currentStencilMask = null;
currentStencilFunc = null;
currentStencilRef = null;
currentStencilFuncMask = null;
currentStencilFail = null;
currentStencilZFail = null;
currentStencilZPass = null;
currentStencilClear = null;
}
};
}
//
var colorBuffer = new ColorBuffer();
var depthBuffer = new DepthBuffer();
var stencilBuffer = new StencilBuffer();
var maxVertexAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );
var newAttributes = new Uint8Array( maxVertexAttributes );
var enabledAttributes = new Uint8Array( maxVertexAttributes );
var attributeDivisors = new Uint8Array( maxVertexAttributes );
var capabilities = {};
var compressedTextureFormats = null;
var currentBlending = null;
var currentBlendEquation = null;
var currentBlendSrc = null;
var currentBlendDst = null;
var currentBlendEquationAlpha = null;
var currentBlendSrcAlpha = null;
var currentBlendDstAlpha = null;
var currentPremultipledAlpha = false;
var currentFlipSided = null;
var currentCullFace = null;
var currentLineWidth = null;
var currentPolygonOffsetFactor = null;
var currentPolygonOffsetUnits = null;
var currentScissorTest = null;
var maxTextures = gl.getParameter( gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS );
var version = parseFloat( /^WebGL\ ([0-9])/.exec( gl.getParameter( gl.VERSION ) )[ 1 ] );
var lineWidthAvailable = parseFloat( version ) >= 1.0;
var currentTextureSlot = null;
var currentBoundTextures = {};
var currentScissor = new Vector4();
var currentViewport = new Vector4();
function createTexture( type, target, count ) {
var data = new Uint8Array( 4 ); // 4 is required to match default unpack alignment of 4.
var texture = gl.createTexture();
gl.bindTexture( type, texture );
gl.texParameteri( type, gl.TEXTURE_MIN_FILTER, gl.NEAREST );
gl.texParameteri( type, gl.TEXTURE_MAG_FILTER, gl.NEAREST );
for ( var i = 0; i < count; i ++ ) {
gl.texImage2D( target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data );
}
return texture;
}
var emptyTextures = {};
emptyTextures[ gl.TEXTURE_2D ] = createTexture( gl.TEXTURE_2D, gl.TEXTURE_2D, 1 );
emptyTextures[ gl.TEXTURE_CUBE_MAP ] = createTexture( gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6 );
//
function init() {
colorBuffer.setClear( 0, 0, 0, 1 );
depthBuffer.setClear( 1 );
stencilBuffer.setClear( 0 );
enable( gl.DEPTH_TEST );
depthBuffer.setFunc( LessEqualDepth );
setFlipSided( false );
setCullFace( CullFaceBack );
enable( gl.CULL_FACE );
enable( gl.BLEND );
setBlending( NormalBlending );
}
function initAttributes() {
for ( var i = 0, l = newAttributes.length; i < l; i ++ ) {
newAttributes[ i ] = 0;
}
}
function enableAttribute( attribute ) {
newAttributes[ attribute ] = 1;
if ( enabledAttributes[ attribute ] === 0 ) {
gl.enableVertexAttribArray( attribute );
enabledAttributes[ attribute ] = 1;
}
if ( attributeDivisors[ attribute ] !== 0 ) {
var extension = extensions.get( 'ANGLE_instanced_arrays' );
extension.vertexAttribDivisorANGLE( attribute, 0 );
attributeDivisors[ attribute ] = 0;
}
}
function enableAttributeAndDivisor( attribute, meshPerAttribute ) {
newAttributes[ attribute ] = 1;
if ( enabledAttributes[ attribute ] === 0 ) {
gl.enableVertexAttribArray( attribute );
enabledAttributes[ attribute ] = 1;
}
if ( attributeDivisors[ attribute ] !== meshPerAttribute ) {
var extension = extensions.get( 'ANGLE_instanced_arrays' );
extension.vertexAttribDivisorANGLE( attribute, meshPerAttribute );
attributeDivisors[ attribute ] = meshPerAttribute;
}
}
function disableUnusedAttributes() {
for ( var i = 0, l = enabledAttributes.length; i !== l; ++ i ) {
if ( enabledAttributes[ i ] !== newAttributes[ i ] ) {
gl.disableVertexAttribArray( i );
enabledAttributes[ i ] = 0;
}
}
}
function enable( id ) {
if ( capabilities[ id ] !== true ) {
gl.enable( id );
capabilities[ id ] = true;
}
}
function disable( id ) {
if ( capabilities[ id ] !== false ) {
gl.disable( id );
capabilities[ id ] = false;
}
}
function getCompressedTextureFormats() {
if ( compressedTextureFormats === null ) {
compressedTextureFormats = [];
if ( extensions.get( 'WEBGL_compressed_texture_pvrtc' ) ||
extensions.get( 'WEBGL_compressed_texture_s3tc' ) ||
extensions.get( 'WEBGL_compressed_texture_etc1' ) ) {
var formats = gl.getParameter( gl.COMPRESSED_TEXTURE_FORMATS );
for ( var i = 0; i < formats.length; i ++ ) {
compressedTextureFormats.push( formats[ i ] );
}
}
}
return compressedTextureFormats;
}
function setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) {
if ( blending !== NoBlending ) {
enable( gl.BLEND );
} else {
disable( gl.BLEND );
}
if ( ( blending !== CustomBlending ) && ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) ) {
if ( blending === AdditiveBlending ) {
if ( premultipliedAlpha ) {
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 ( blending === SubtractiveBlending ) {
if ( premultipliedAlpha ) {
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 ( blending === MultiplyBlending ) {
if ( premultipliedAlpha ) {
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 ( premultipliedAlpha ) {
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 );
}
}
currentBlending = blending;
currentPremultipledAlpha = premultipliedAlpha;
}
if ( blending === CustomBlending ) {
blendEquationAlpha = blendEquationAlpha || blendEquation;
blendSrcAlpha = blendSrcAlpha || blendSrc;
blendDstAlpha = blendDstAlpha || blendDst;
if ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) {
gl.blendEquationSeparate( paramThreeToGL( blendEquation ), paramThreeToGL( blendEquationAlpha ) );
currentBlendEquation = blendEquation;
currentBlendEquationAlpha = blendEquationAlpha;
}
if ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) {
gl.blendFuncSeparate( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ), paramThreeToGL( blendSrcAlpha ), paramThreeToGL( blendDstAlpha ) );
currentBlendSrc = blendSrc;
currentBlendDst = blendDst;
currentBlendSrcAlpha = blendSrcAlpha;
currentBlendDstAlpha = blendDstAlpha;
}
} else {
currentBlendEquation = null;
currentBlendSrc = null;
currentBlendDst = null;
currentBlendEquationAlpha = null;
currentBlendSrcAlpha = null;
currentBlendDstAlpha = null;
}
}
function setMaterial( material ) {
material.side === DoubleSide
? disable( gl.CULL_FACE )
: enable( gl.CULL_FACE );
setFlipSided( material.side === BackSide );
material.transparent === true
? setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha )
: setBlending( NoBlending );
depthBuffer.setFunc( material.depthFunc );
depthBuffer.setTest( material.depthTest );
depthBuffer.setMask( material.depthWrite );
colorBuffer.setMask( material.colorWrite );
setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
}
//
function setFlipSided( flipSided ) {
if ( currentFlipSided !== flipSided ) {
if ( flipSided ) {
gl.frontFace( gl.CW );
} else {
gl.frontFace( gl.CCW );
}
currentFlipSided = flipSided;
}
}
function setCullFace( cullFace ) {
if ( cullFace !== CullFaceNone ) {
enable( gl.CULL_FACE );
if ( cullFace !== currentCullFace ) {
if ( cullFace === CullFaceBack ) {
gl.cullFace( gl.BACK );
} else if ( cullFace === CullFaceFront ) {
gl.cullFace( gl.FRONT );
} else {
gl.cullFace( gl.FRONT_AND_BACK );
}
}
} else {
disable( gl.CULL_FACE );
}
currentCullFace = cullFace;
}
function setLineWidth( width ) {
if ( width !== currentLineWidth ) {
if ( lineWidthAvailable ) gl.lineWidth( width );
currentLineWidth = width;
}
}
function setPolygonOffset( polygonOffset, factor, units ) {
if ( polygonOffset ) {
enable( gl.POLYGON_OFFSET_FILL );
if ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) {
gl.polygonOffset( factor, units );
currentPolygonOffsetFactor = factor;
currentPolygonOffsetUnits = units;
}
} else {
disable( gl.POLYGON_OFFSET_FILL );
}
}
function getScissorTest() {
return currentScissorTest;
}
function setScissorTest( scissorTest ) {
currentScissorTest = scissorTest;
if ( scissorTest ) {
enable( gl.SCISSOR_TEST );
} else {
disable( gl.SCISSOR_TEST );
}
}
// texture
function activeTexture( webglSlot ) {
if ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1;
if ( currentTextureSlot !== webglSlot ) {
gl.activeTexture( webglSlot );
currentTextureSlot = webglSlot;
}
}
function bindTexture( webglType, webglTexture ) {
if ( currentTextureSlot === null ) {
activeTexture();
}
var boundTexture = currentBoundTextures[ currentTextureSlot ];
if ( boundTexture === undefined ) {
boundTexture = { type: undefined, texture: undefined };
currentBoundTextures[ currentTextureSlot ] = boundTexture;
}
if ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) {
gl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] );
boundTexture.type = webglType;
boundTexture.texture = webglTexture;
}
}
function compressedTexImage2D() {
try {
gl.compressedTexImage2D.apply( gl, arguments );
} catch ( error ) {
console.error( 'THREE.WebGLState:', error );
}
}
function texImage2D() {
try {
gl.texImage2D.apply( gl, arguments );
} catch ( error ) {
console.error( 'THREE.WebGLState:', error );
}
}
//
function scissor( scissor ) {
if ( currentScissor.equals( scissor ) === false ) {
gl.scissor( scissor.x, scissor.y, scissor.z, scissor.w );
currentScissor.copy( scissor );
}
}
function viewport( viewport ) {
if ( currentViewport.equals( viewport ) === false ) {
gl.viewport( viewport.x, viewport.y, viewport.z, viewport.w );
currentViewport.copy( viewport );
}
}
//
function reset() {
for ( var i = 0; i < enabledAttributes.length; i ++ ) {
if ( enabledAttributes[ i ] === 1 ) {
gl.disableVertexAttribArray( i );
enabledAttributes[ i ] = 0;
}
}
capabilities = {};
compressedTextureFormats = null;
currentTextureSlot = null;
currentBoundTextures = {};
currentBlending = null;
currentFlipSided = null;
currentCullFace = null;
colorBuffer.reset();
depthBuffer.reset();
stencilBuffer.reset();
}
return {
buffers: {
color: colorBuffer,
depth: depthBuffer,
stencil: stencilBuffer
},
init: init,
initAttributes: initAttributes,
enableAttribute: enableAttribute,
enableAttributeAndDivisor: enableAttributeAndDivisor,
disableUnusedAttributes: disableUnusedAttributes,
enable: enable,
disable: disable,
getCompressedTextureFormats: getCompressedTextureFormats,
setBlending: setBlending,
setMaterial: setMaterial,
setFlipSided: setFlipSided,
setCullFace: setCullFace,
setLineWidth: setLineWidth,
setPolygonOffset: setPolygonOffset,
getScissorTest: getScissorTest,
setScissorTest: setScissorTest,
activeTexture: activeTexture,
bindTexture: bindTexture,
compressedTexImage2D: compressedTexImage2D,
texImage2D: texImage2D,
scissor: scissor,
viewport: viewport,
reset: reset
};
}
/**
* @author mrdoob / http://mrdoob.com/
*/
function WebGLCapabilities( gl, extensions, parameters ) {
var maxAnisotropy;
function getMaxAnisotropy() {
if ( maxAnisotropy !== undefined ) return maxAnisotropy;
var extension = extensions.get( 'EXT_texture_filter_anisotropic' );
if ( extension !== null ) {
maxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );
} else {
maxAnisotropy = 0;
}
return maxAnisotropy;
}
function getMaxPrecision( precision ) {
if ( precision === 'highp' ) {
if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 &&
gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) {
return 'highp';
}
precision = 'mediump';
}
if ( precision === 'mediump' ) {
if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 &&
gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) {
return 'mediump';
}
}
return 'lowp';
}
var precision = parameters.precision !== undefined ? parameters.precision : 'highp';
var maxPrecision = getMaxPrecision( precision );
if ( maxPrecision !== precision ) {
console.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' );
precision = maxPrecision;
}
var logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true && !! extensions.get( 'EXT_frag_depth' );
var maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );
var maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );
var maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE );
var maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE );
var maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );
var maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS );
var maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS );
var maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS );
var vertexTextures = maxVertexTextures > 0;
var floatFragmentTextures = !! extensions.get( 'OES_texture_float' );
var floatVertexTextures = vertexTextures && floatFragmentTextures;
return {
getMaxAnisotropy: getMaxAnisotropy,
getMaxPrecision: getMaxPrecision,
precision: precision,
logarithmicDepthBuffer: logarithmicDepthBuffer,
maxTextures: maxTextures,
maxVertexTextures: maxVertexTextures,
maxTextureSize: maxTextureSize,
maxCubemapSize: maxCubemapSize,
maxAttributes: maxAttributes,
maxVertexUniforms: maxVertexUniforms,
maxVaryings: maxVaryings,
maxFragmentUniforms: maxFragmentUniforms,
vertexTextures: vertexTextures,
floatFragmentTextures: floatFragmentTextures,
floatVertexTextures: floatVertexTextures
};
}
/**
* @author mrdoob / http://mrdoob.com/
*/
function ArrayCamera( array ) {
PerspectiveCamera.call( this );
this.cameras = array || [];
}
ArrayCamera.prototype = Object.assign( Object.create( PerspectiveCamera.prototype ), {
constructor: ArrayCamera,
isArrayCamera: true
} );
/**
* @author mrdoob / http://mrdoob.com/
*/
function WebVRManager( renderer ) {
var scope = this;
var device = null;
var frameData = null;
if ( 'VRFrameData' in window ) {
frameData = new window.VRFrameData();
}
var matrixWorldInverse = new Matrix4();
var standingMatrix = new Matrix4();
var standingMatrixInverse = new Matrix4();
var cameraL = new PerspectiveCamera();
cameraL.bounds = new Vector4( 0.0, 0.0, 0.5, 1.0 );
cameraL.layers.enable( 1 );
var cameraR = new PerspectiveCamera();
cameraR.bounds = new Vector4( 0.5, 0.0, 0.5, 1.0 );
cameraR.layers.enable( 2 );
var cameraVR = new ArrayCamera( [ cameraL, cameraR ] );
cameraVR.layers.enable( 1 );
cameraVR.layers.enable( 2 );
//
var currentSize, currentPixelRatio;
function onVRDisplayPresentChange() {
if ( device.isPresenting ) {
var eyeParameters = device.getEyeParameters( 'left' );
var renderWidth = eyeParameters.renderWidth;
var renderHeight = eyeParameters.renderHeight;
currentPixelRatio = renderer.getPixelRatio();
currentSize = renderer.getSize();
renderer.setDrawingBufferSize( renderWidth * 2, renderHeight, 1 );
} else if ( scope.enabled ) {
renderer.setDrawingBufferSize( currentSize.width, currentSize.height, currentPixelRatio );
}
}
window.addEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange, false );
//
this.enabled = false;
this.standing = false;
this.getDevice = function () {
return device;
};
this.setDevice = function ( value ) {
if ( value !== undefined ) device = value;
};
this.getCamera = function ( camera ) {
if ( device === null ) return camera;
device.depthNear = camera.near;
device.depthFar = camera.far;
device.getFrameData( frameData );
//
var pose = frameData.pose;
if ( pose.position !== null ) {
camera.position.fromArray( pose.position );
} else {
camera.position.set( 0, 0, 0 );
}
if ( pose.orientation !== null ) {
camera.quaternion.fromArray( pose.orientation );
}
camera.updateMatrixWorld();
var stageParameters = device.stageParameters;
if ( this.standing && stageParameters ) {
standingMatrix.fromArray( stageParameters.sittingToStandingTransform );
standingMatrixInverse.getInverse( standingMatrix );
camera.matrixWorld.multiply( standingMatrix );
camera.matrixWorldInverse.multiply( standingMatrixInverse );
}
if ( device.isPresenting === false ) return camera;
//
cameraVR.matrixWorld.copy( camera.matrixWorld );
cameraVR.matrixWorldInverse.copy( camera.matrixWorldInverse );
cameraL.matrixWorldInverse.fromArray( frameData.leftViewMatrix );
cameraR.matrixWorldInverse.fromArray( frameData.rightViewMatrix );
if ( this.standing && stageParameters ) {
cameraL.matrixWorldInverse.multiply( standingMatrixInverse );
cameraR.matrixWorldInverse.multiply( standingMatrixInverse );
}
var parent = camera.parent;
if ( parent !== null ) {
matrixWorldInverse.getInverse( parent.matrixWorld );
cameraL.matrixWorldInverse.multiply( matrixWorldInverse );
cameraR.matrixWorldInverse.multiply( matrixWorldInverse );
}
// envMap and Mirror needs camera.matrixWorld
cameraL.matrixWorld.getInverse( cameraL.matrixWorldInverse );
cameraR.matrixWorld.getInverse( cameraR.matrixWorldInverse );
cameraL.projectionMatrix.fromArray( frameData.leftProjectionMatrix );
cameraR.projectionMatrix.fromArray( frameData.rightProjectionMatrix );
// HACK @mrdoob
// https://github.com/w3c/webvr/issues/203
cameraVR.projectionMatrix.copy( cameraL.projectionMatrix );
//
var layers = device.getLayers();
if ( layers.length ) {
var layer = layers[ 0 ];
if ( layer.leftBounds !== null && layer.leftBounds.length === 4 ) {
cameraL.bounds.fromArray( layer.leftBounds );
}
if ( layer.rightBounds !== null && layer.rightBounds.length === 4 ) {
cameraR.bounds.fromArray( layer.rightBounds );
}
}
return cameraVR;
};
this.getStandingMatrix = function () {
return standingMatrix;
};
this.submitFrame = function () {
if ( device && device.isPresenting ) device.submitFrame();
};
}
/**
* @author mrdoob / http://mrdoob.com/
*/
function WebGLExtensions( gl ) {
var extensions = {};
return {
get: function ( name ) {
if ( extensions[ name ] !== undefined ) {
return extensions[ name ];
}
var extension;
switch ( name ) {
case 'WEBGL_depth_texture':
extension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' );
break;
case 'EXT_texture_filter_anisotropic':
extension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );
break;
case 'WEBGL_compressed_texture_s3tc':
extension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );
break;
case 'WEBGL_compressed_texture_pvrtc':
extension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' );
break;
case 'WEBGL_compressed_texture_etc1':
extension = gl.getExtension( 'WEBGL_compressed_texture_etc1' );
break;
default:
extension = gl.getExtension( name );
}
if ( extension === null ) {
console.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' );
}
extensions[ name ] = extension;
return extension;
}
};
}
/**
* @author tschw
*/
function WebGLClipping() {
var scope = this,
globalState = null,
numGlobalPlanes = 0,
localClippingEnabled = false,
renderingShadows = false,
plane = new Plane(),
viewNormalMatrix = new Matrix3(),
uniform = { value: null, needsUpdate: false };
this.uniform = uniform;
this.numPlanes = 0;
this.numIntersection = 0;
this.init = function( planes, enableLocalClipping, camera ) {
var enabled =
planes.length !== 0 ||
enableLocalClipping ||
// enable state of previous frame - the clipping code has to
// run another frame in order to reset the state:
numGlobalPlanes !== 0 ||
localClippingEnabled;
localClippingEnabled = enableLocalClipping;
globalState = projectPlanes( planes, camera, 0 );
numGlobalPlanes = planes.length;
return enabled;
};
this.beginShadows = function() {
renderingShadows = true;
projectPlanes( null );
};
this.endShadows = function() {
renderingShadows = false;
resetGlobalState();
};
this.setState = function( planes, clipIntersection, clipShadows, camera, cache, fromCache ) {
if ( ! localClippingEnabled ||
planes === null || planes.length === 0 ||
renderingShadows && ! clipShadows ) {
// there's no local clipping
if ( renderingShadows ) {
// there's no global clipping
projectPlanes( null );
} else {
resetGlobalState();
}
} else {
var nGlobal = renderingShadows ? 0 : numGlobalPlanes,
lGlobal = nGlobal * 4,
dstArray = cache.clippingState || null;
uniform.value = dstArray; // ensure unique state
dstArray = projectPlanes( planes, camera, lGlobal, fromCache );
for ( var i = 0; i !== lGlobal; ++ i ) {
dstArray[ i ] = globalState[ i ];
}
cache.clippingState = dstArray;
this.numIntersection = clipIntersection ? this.numPlanes : 0;
this.numPlanes += nGlobal;
}
};
function resetGlobalState() {
if ( uniform.value !== globalState ) {
uniform.value = globalState;
uniform.needsUpdate = numGlobalPlanes > 0;
}
scope.numPlanes = numGlobalPlanes;
scope.numIntersection = 0;
}
function projectPlanes( planes, camera, dstOffset, skipTransform ) {
var nPlanes = planes !== null ? planes.length : 0,
dstArray = null;
if ( nPlanes !== 0 ) {
dstArray = uniform.value;
if ( skipTransform !== true || dstArray === null ) {
var flatSize = dstOffset + nPlanes * 4,
viewMatrix = camera.matrixWorldInverse;
viewNormalMatrix.getNormalMatrix( viewMatrix );
if ( dstArray === null || dstArray.length < flatSize ) {
dstArray = new Float32Array( flatSize );
}
for ( var i = 0, i4 = dstOffset;
i !== nPlanes; ++ i, i4 += 4 ) {
plane.copy( planes[ i ] ).
applyMatrix4( viewMatrix, viewNormalMatrix );
plane.normal.toArray( dstArray, i4 );
dstArray[ i4 + 3 ] = plane.constant;
}
}
uniform.value = dstArray;
uniform.needsUpdate = true;
}
scope.numPlanes = nPlanes;
return dstArray;
}
}
// import { Sphere } from '../math/Sphere';
/**
* @author supereggbert / http://www.paulbrunt.co.uk/
* @author mrdoob / http://mrdoob.com/
* @author alteredq / http://alteredqualia.com/
* @author szimek / https://github.com/szimek/
* @author tschw
*/
function WebGLRenderer( parameters ) {
console.log( 'THREE.WebGLRenderer', REVISION );
parameters = parameters || {};
var _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ),
_context = parameters.context !== undefined ? parameters.context : null,
_alpha = parameters.alpha !== undefined ? parameters.alpha : false,
_depth = parameters.depth !== undefined ? parameters.depth : true,
_stencil = parameters.stencil !== undefined ? parameters.stencil : true,
_antialias = parameters.antialias !== undefined ? parameters.antialias : false,
_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,
_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false;
var lights = [];
var currentRenderList = null;
var morphInfluences = new Float32Array( 8 );
var sprites = [];
var lensFlares = [];
// public properties
this.domElement = _canvas;
this.context = null;
// clearing
this.autoClear = true;
this.autoClearColor = true;
this.autoClearDepth = true;
this.autoClearStencil = true;
// scene graph
this.sortObjects = true;
// user-defined clipping
this.clippingPlanes = [];
this.localClippingEnabled = false;
// physically based shading
this.gammaFactor = 2.0; // for backwards compatibility
this.gammaInput = false;
this.gammaOutput = false;
// physical lights
this.physicallyCorrectLights = false;
// tone mapping
this.toneMapping = LinearToneMapping;
this.toneMappingExposure = 1.0;
this.toneMappingWhitePoint = 1.0;
// morphs
this.maxMorphTargets = 8;
this.maxMorphNormals = 4;
// internal properties
var _this = this,
// internal state cache
_currentProgram = null,
_currentRenderTarget = null,
_currentFramebuffer = null,
_currentMaterialId = - 1,
_currentGeometryProgram = '',
_currentCamera = null,
_currentArrayCamera = null,
_currentScissor = new Vector4(),
_currentScissorTest = null,
_currentViewport = new Vector4(),
//
_usedTextureUnits = 0,
//
_width = _canvas.width,
_height = _canvas.height,
_pixelRatio = 1,
_scissor = new Vector4( 0, 0, _width, _height ),
_scissorTest = false,
_viewport = new Vector4( 0, 0, _width, _height ),
// frustum
_frustum = new Frustum(),
// clipping
_clipping = new WebGLClipping(),
_clippingEnabled = false,
_localClippingEnabled = false,
// camera matrices cache
_projScreenMatrix = new Matrix4(),
_vector3 = new Vector3(),
_matrix4 = new Matrix4(),
_matrix42 = new Matrix4(),
// light arrays cache
_lights = {
hash: '',
ambient: [ 0, 0, 0 ],
directional: [],
directionalShadowMap: [],
directionalShadowMatrix: [],
spot: [],
spotShadowMap: [],
spotShadowMatrix: [],
rectArea: [],
point: [],
pointShadowMap: [],
pointShadowMatrix: [],
hemi: [],
shadows: []
},
// info
_infoMemory = {
geometries: 0,
textures: 0
},
_infoRender = {
frame: 0,
calls: 0,
vertices: 0,
faces: 0,
points: 0
};
this.info = {
render: _infoRender,
memory: _infoMemory,
programs: null
};
// initialize
var _gl;
try {
var contextAttributes = {
alpha: _alpha,
depth: _depth,
stencil: _stencil,
antialias: _antialias,
premultipliedAlpha: _premultipliedAlpha,
preserveDrawingBuffer: _preserveDrawingBuffer
};
_gl = _context || _canvas.getContext( 'webgl', contextAttributes ) || _canvas.getContext( 'experimental-webgl', contextAttributes );
if ( _gl === null ) {
if ( _canvas.getContext( 'webgl' ) !== null ) {
throw 'Error creating WebGL context with your selected attributes.';
} else {
throw 'Error creating WebGL context.';
}
}
// Some experimental-webgl implementations do not have getShaderPrecisionFormat
if ( _gl.getShaderPrecisionFormat === undefined ) {
_gl.getShaderPrecisionFormat = function () {
return { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 };
};
}
_canvas.addEventListener( 'webglcontextlost', onContextLost, false );
} catch ( error ) {
console.error( 'THREE.WebGLRenderer: ' + error );
}
var extensions = new WebGLExtensions( _gl );
extensions.get( 'WEBGL_depth_texture' );
extensions.get( 'OES_texture_float' );
extensions.get( 'OES_texture_float_linear' );
extensions.get( 'OES_texture_half_float' );
extensions.get( 'OES_texture_half_float_linear' );
extensions.get( 'OES_standard_derivatives' );
extensions.get( 'ANGLE_instanced_arrays' );
if ( extensions.get( 'OES_element_index_uint' ) ) {
BufferGeometry.MaxIndex = 4294967296;
}
var capabilities = new WebGLCapabilities( _gl, extensions, parameters );
var state = new WebGLState( _gl, extensions, paramThreeToGL );
var properties = new WebGLProperties();
var textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, _infoMemory );
var attributes = new WebGLAttributes( _gl );
var geometries = new WebGLGeometries( _gl, attributes, _infoMemory );
var objects = new WebGLObjects( _gl, geometries, _infoRender );
var programCache = new WebGLPrograms( this, capabilities );
var lightCache = new WebGLLights();
var renderLists = new WebGLRenderLists();
var background = new WebGLBackground( this, state, objects, _premultipliedAlpha );
var vr = new WebVRManager( this );
this.info.programs = programCache.programs;
var bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender );
var indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );
//
function getTargetPixelRatio() {
return _currentRenderTarget === null ? _pixelRatio : 1;
}
function setDefaultGLState() {
state.init();
state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
}
function resetGLState() {
_currentProgram = null;
_currentCamera = null;
_currentGeometryProgram = '';
_currentMaterialId = - 1;
state.reset();
}
setDefaultGLState();
this.context = _gl;
this.capabilities = capabilities;
this.extensions = extensions;
this.properties = properties;
this.renderLists = renderLists;
this.state = state;
this.vr = vr;
// shadow map
var shadowMap = new WebGLShadowMap( this, _lights, objects, capabilities );
this.shadowMap = shadowMap;
// Plugins
var spritePlugin = new SpritePlugin( this, sprites );
var lensFlarePlugin = new LensFlarePlugin( this, lensFlares );
// API
this.getContext = function () {
return _gl;
};
this.getContextAttributes = function () {
return _gl.getContextAttributes();
};
this.forceContextLoss = function () {
var extension = extensions.get( 'WEBGL_lose_context' );
if ( extension ) extension.loseContext();
};
this.getMaxAnisotropy = function () {
return capabilities.getMaxAnisotropy();
};
this.getPrecision = function () {
return capabilities.precision;
};
this.getPixelRatio = function () {
return _pixelRatio;
};
this.setPixelRatio = function ( value ) {
if ( value === undefined ) return;
_pixelRatio = value;
this.setSize( _width, _height, false );
};
this.getSize = function () {
return {
width: _width,
height: _height
};
};
this.setSize = function ( width, height, updateStyle ) {
var device = vr.getDevice();
if ( device && device.isPresenting ) {
console.warn( 'THREE.WebGLRenderer: Can\'t change size while VR device is presenting.' );
return;
}
_width = width;
_height = height;
_canvas.width = width * _pixelRatio;
_canvas.height = height * _pixelRatio;
if ( updateStyle !== false ) {
_canvas.style.width = width + 'px';
_canvas.style.height = height + 'px';
}
this.setViewport( 0, 0, width, height );
};
this.getDrawingBufferSize = function () {
return {
width: _width * _pixelRatio,
height: _height * _pixelRatio
};
};
this.setDrawingBufferSize = function ( width, height, pixelRatio ) {
_width = width;
_height = height;
_pixelRatio = pixelRatio;
_canvas.width = width * pixelRatio;
_canvas.height = height * pixelRatio;
this.setViewport( 0, 0, width, height );
};
this.setViewport = function ( x, y, width, height ) {
_viewport.set( x, _height - y - height, width, height );
state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
};
this.setScissor = function ( x, y, width, height ) {
_scissor.set( x, _height - y - height, width, height );
state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
};
this.setScissorTest = function ( boolean ) {
state.setScissorTest( _scissorTest = boolean );
};
// Clearing
this.getClearColor = background.getClearColor;
this.setClearColor = background.setClearColor;
this.getClearAlpha = background.getClearAlpha;
this.setClearAlpha = background.setClearAlpha;
this.clear = function ( color, depth, stencil ) {
var bits = 0;
if ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;
if ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;
if ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;
_gl.clear( bits );
};
this.clearColor = function () {
this.clear( true, false, false );
};
this.clearDepth = function () {
this.clear( false, true, false );
};
this.clearStencil = function () {
this.clear( false, false, true );
};
this.clearTarget = function ( renderTarget, color, depth, stencil ) {
this.setRenderTarget( renderTarget );
this.clear( color, depth, stencil );
};
// Reset
this.resetGLState = resetGLState;
this.dispose = function () {
_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );
renderLists.dispose();
};
// Events
function onContextLost( event ) {
event.preventDefault();
resetGLState();
setDefaultGLState();
properties.clear();
objects.clear();
}
function onMaterialDispose( event ) {
var material = event.target;
material.removeEventListener( 'dispose', onMaterialDispose );
deallocateMaterial( material );
}
// Buffer deallocation
function deallocateMaterial( material ) {
releaseMaterialProgramReference( material );
properties.remove( material );
}
function releaseMaterialProgramReference( material ) {
var programInfo = properties.get( material ).program;
material.program = undefined;
if ( programInfo !== undefined ) {
programCache.releaseProgram( programInfo );
}
}
// Buffer rendering
function renderObjectImmediate( object, program, material ) {
object.render( function ( object ) {
_this.renderBufferImmediate( object, program, material );
} );
}
this.renderBufferImmediate = function ( object, program, material ) {
state.initAttributes();
var buffers = properties.get( object );
if ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer();
if ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer();
if ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer();
if ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer();
var programAttributes = program.getAttributes();
if ( object.hasPositions ) {
_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );
_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
state.enableAttribute( programAttributes.position );
_gl.vertexAttribPointer( programAttributes.position, 3, _gl.FLOAT, false, 0, 0 );
}
if ( object.hasNormals ) {
_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal );
if ( ! material.isMeshPhongMaterial &&
! material.isMeshStandardMaterial &&
! material.isMeshNormalMaterial &&
material.shading === FlatShading ) {
for ( var i = 0, l = object.count * 3; i < l; i += 9 ) {
var array = object.normalArray;
var nx = ( array[ i + 0 ] + array[ i + 3 ] + array[ i + 6 ] ) / 3;
var ny = ( array[ i + 1 ] + array[ i + 4 ] + array[ i + 7 ] ) / 3;
var nz = ( array[ i + 2 ] + array[ i + 5 ] + array[ i + 8 ] ) / 3;
array[ i + 0 ] = nx;
array[ i + 1 ] = ny;
array[ i + 2 ] = nz;
array[ i + 3 ] = nx;
array[ i + 4 ] = ny;
array[ i + 5 ] = nz;
array[ i + 6 ] = nx;
array[ i + 7 ] = ny;
array[ i + 8 ] = nz;
}
}
_gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );
state.enableAttribute( programAttributes.normal );
_gl.vertexAttribPointer( programAttributes.normal, 3, _gl.FLOAT, false, 0, 0 );
}
if ( object.hasUvs && material.map ) {
_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );
_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
state.enableAttribute( programAttributes.uv );
_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
}
if ( object.hasColors && material.vertexColors !== NoColors ) {
_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );
_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
state.enableAttribute( programAttributes.color );
_gl.vertexAttribPointer( programAttributes.color, 3, _gl.FLOAT, false, 0, 0 );
}
state.disableUnusedAttributes();
_gl.drawArrays( _gl.TRIANGLES, 0, object.count );
object.count = 0;
};
function absNumericalSort( a, b ) {
return Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );
}
this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
state.setMaterial( material );
var program = setProgram( camera, fog, material, object );
var geometryProgram = geometry.id + '_' + program.id + '_' + ( material.wireframe === true );
var updateBuffers = false;
if ( geometryProgram !== _currentGeometryProgram ) {
_currentGeometryProgram = geometryProgram;
updateBuffers = true;
}
// morph targets
var morphTargetInfluences = object.morphTargetInfluences;
if ( morphTargetInfluences !== undefined ) {
// TODO Remove allocations
var activeInfluences = [];
for ( var i = 0, l = morphTargetInfluences.length; i < l; i ++ ) {
var influence = morphTargetInfluences[ i ];
activeInfluences.push( [ influence, i ] );
}
activeInfluences.sort( absNumericalSort );
if ( activeInfluences.length > 8 ) {
activeInfluences.length = 8;
}
var morphAttributes = geometry.morphAttributes;
for ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {
var influence = activeInfluences[ i ];
morphInfluences[ i ] = influence[ 0 ];
if ( influence[ 0 ] !== 0 ) {
var index = influence[ 1 ];
if ( material.morphTargets === true && morphAttributes.position ) geometry.addAttribute( 'morphTarget' + i, morphAttributes.position[ index ] );
if ( material.morphNormals === true && morphAttributes.normal ) geometry.addAttribute( 'morphNormal' + i, morphAttributes.normal[ index ] );
} else {
if ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );
if ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );
}
}
for ( var i = activeInfluences.length, il = morphInfluences.length; i < il; i ++ ) {
morphInfluences[ i ] = 0.0;
}
program.getUniforms().setValue( _gl, 'morphTargetInfluences', morphInfluences );
updateBuffers = true;
}
//
var index = geometry.index;
var position = geometry.attributes.position;
var rangeFactor = 1;
if ( material.wireframe === true ) {
index = geometries.getWireframeAttribute( geometry );
rangeFactor = 2;
}
var attribute;
var renderer = bufferRenderer;
if ( index !== null ) {
attribute = attributes.get( index );
renderer = indexedBufferRenderer;
renderer.setIndex( attribute );
}
if ( updateBuffers ) {
setupVertexAttributes( material, program, geometry );
if ( index !== null ) {
_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, attribute.buffer );
}
}
//
var dataCount = 0;
if ( index !== null ) {
dataCount = index.count;
} else if ( position !== undefined ) {
dataCount = position.count;
}
var rangeStart = geometry.drawRange.start * rangeFactor;
var rangeCount = geometry.drawRange.count * rangeFactor;
var groupStart = group !== null ? group.start * rangeFactor : 0;
var groupCount = group !== null ? group.count * rangeFactor : Infinity;
var drawStart = Math.max( rangeStart, groupStart );
var drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;
var drawCount = Math.max( 0, drawEnd - drawStart + 1 );
if ( drawCount === 0 ) return;
//
if ( object.isMesh ) {
if ( material.wireframe === true ) {
state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
renderer.setMode( _gl.LINES );
} else {
switch ( object.drawMode ) {
case TrianglesDrawMode:
renderer.setMode( _gl.TRIANGLES );
break;
case TriangleStripDrawMode:
renderer.setMode( _gl.TRIANGLE_STRIP );
break;
case TriangleFanDrawMode:
renderer.setMode( _gl.TRIANGLE_FAN );
break;
}
}
} else if ( object.isLine ) {
var lineWidth = material.linewidth;
if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
state.setLineWidth( lineWidth * getTargetPixelRatio() );
if ( object.isLineSegments ) {
renderer.setMode( _gl.LINES );
} else if ( object.isLineLoop ) {
renderer.setMode( _gl.LINE_LOOP );
} else {
renderer.setMode( _gl.LINE_STRIP );
}
} else if ( object.isPoints ) {
renderer.setMode( _gl.POINTS );
}
if ( geometry && geometry.isInstancedBufferGeometry ) {
if ( geometry.maxInstancedCount > 0 ) {
renderer.renderInstances( geometry, drawStart, drawCount );
}
} else {
renderer.render( drawStart, drawCount );
}
};
function setupVertexAttributes( material, program, geometry, startIndex ) {
if ( geometry && geometry.isInstancedBufferGeometry ) {
if ( extensions.get( 'ANGLE_instanced_arrays' ) === null ) {
console.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
return;
}
}
if ( startIndex === undefined ) startIndex = 0;
state.initAttributes();
var geometryAttributes = geometry.attributes;
var programAttributes = program.getAttributes();
var materialDefaultAttributeValues = material.defaultAttributeValues;
for ( var name in programAttributes ) {
var programAttribute = programAttributes[ name ];
if ( programAttribute >= 0 ) {
var geometryAttribute = geometryAttributes[ name ];
if ( geometryAttribute !== undefined ) {
var normalized = geometryAttribute.normalized;
var size = geometryAttribute.itemSize;
var attribute = attributes.get( geometryAttribute );
var buffer = attribute.buffer;
var type = attribute.type;
var bytesPerElement = attribute.bytesPerElement;
if ( geometryAttribute.isInterleavedBufferAttribute ) {
var data = geometryAttribute.data;
var stride = data.stride;
var offset = geometryAttribute.offset;
if ( data && data.isInstancedInterleavedBuffer ) {
state.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute );
if ( geometry.maxInstancedCount === undefined ) {
geometry.maxInstancedCount = data.meshPerAttribute * data.count;
}
} else {
state.enableAttribute( programAttribute );
}
_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
_gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, ( startIndex * stride + offset ) * bytesPerElement );
} else {
if ( geometryAttribute.isInstancedBufferAttribute ) {
state.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute );
if ( geometry.maxInstancedCount === undefined ) {
geometry.maxInstancedCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;
}
} else {
state.enableAttribute( programAttribute );
}
_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, startIndex * size * bytesPerElement );
}
} else if ( materialDefaultAttributeValues !== undefined ) {
var value = materialDefaultAttributeValues[ name ];
if ( value !== undefined ) {
switch ( value.length ) {
case 2:
_gl.vertexAttrib2fv( programAttribute, value );
break;
case 3:
_gl.vertexAttrib3fv( programAttribute, value );
break;
case 4:
_gl.vertexAttrib4fv( programAttribute, value );
break;
default:
_gl.vertexAttrib1fv( programAttribute, value );
}
}
}
}
}
state.disableUnusedAttributes();
}
// Compile
this.compile = function ( scene, camera ) {
lights = [];
scene.traverse( function ( object ) {
if ( object.isLight ) {
lights.push( object );
}
} );
setupLights( lights, camera );
scene.traverse( function ( object ) {
if ( object.material ) {
if ( Array.isArray( object.material ) ) {
for ( var i = 0; i < object.material.length; i ++ ) {
initMaterial( object.material[ i ], scene.fog, object );
}
} else {
initMaterial( object.material, scene.fog, object );
}
}
} );
};
// Rendering
this.animate = function ( callback ) {
function onFrame() {
callback();
( vr.getDevice() || window ).requestAnimationFrame( onFrame );
}
( vr.getDevice() || window ).requestAnimationFrame( onFrame );
};
this.render = function ( scene, camera, renderTarget, forceClear ) {
if ( ! ( camera && camera.isCamera ) ) {
console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
return;
}
// reset caching for this frame
_currentGeometryProgram = '';
_currentMaterialId = - 1;
_currentCamera = null;
// update scene graph
if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
// update camera matrices and frustum
if ( camera.parent === null ) camera.updateMatrixWorld();
if ( vr.enabled ) {
camera = vr.getCamera( camera );
}
_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
_frustum.setFromMatrix( _projScreenMatrix );
lights.length = 0;
sprites.length = 0;
lensFlares.length = 0;
_localClippingEnabled = this.localClippingEnabled;
_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );
currentRenderList = renderLists.get( scene, camera );
currentRenderList.init();
projectObject( scene, camera, _this.sortObjects );
currentRenderList.finish();
if ( _this.sortObjects === true ) {
currentRenderList.sort();
}
//
if ( _clippingEnabled ) _clipping.beginShadows();
setupShadows( lights );
shadowMap.render( scene, camera );
setupLights( lights, camera );
if ( _clippingEnabled ) _clipping.endShadows();
//
_infoRender.frame ++;
_infoRender.calls = 0;
_infoRender.vertices = 0;
_infoRender.faces = 0;
_infoRender.points = 0;
if ( renderTarget === undefined ) {
renderTarget = null;
}
this.setRenderTarget( renderTarget );
//
background.render( scene, camera, forceClear );
// render scene
var opaqueObjects = currentRenderList.opaque;
var transparentObjects = currentRenderList.transparent;
if ( scene.overrideMaterial ) {
var overrideMaterial = scene.overrideMaterial;
if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera, overrideMaterial );
if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera, overrideMaterial );
} else {
// opaque pass (front-to-back order)
if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera );
// transparent pass (back-to-front order)
if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera );
}
// custom render plugins (post pass)
spritePlugin.render( scene, camera );
lensFlarePlugin.render( scene, camera, _currentViewport );
// Generate mipmap if we're using any kind of mipmap filtering
if ( renderTarget ) {
textures.updateRenderTargetMipmap( renderTarget );
}
// Ensure depth buffer writing is enabled so it can be cleared on next render
state.buffers.depth.setTest( true );
state.buffers.depth.setMask( true );
state.buffers.color.setMask( true );
if ( camera.isArrayCamera ) {
_this.setScissorTest( false );
}
if ( vr.enabled ) {
vr.submitFrame();
}
// _gl.finish();
};
/*
// TODO Duplicated code (Frustum)
var _sphere = new Sphere();
function isObjectViewable( object ) {
var geometry = object.geometry;
if ( geometry.boundingSphere === null )
geometry.computeBoundingSphere();
_sphere.copy( geometry.boundingSphere ).
applyMatrix4( object.matrixWorld );
return isSphereViewable( _sphere );
}
function isSpriteViewable( sprite ) {
_sphere.center.set( 0, 0, 0 );
_sphere.radius = 0.7071067811865476;
_sphere.applyMatrix4( sprite.matrixWorld );
return isSphereViewable( _sphere );
}
function isSphereViewable( sphere ) {
if ( ! _frustum.intersectsSphere( sphere ) ) return false;
var numPlanes = _clipping.numPlanes;
if ( numPlanes === 0 ) return true;
var planes = _this.clippingPlanes,
center = sphere.center,
negRad = - sphere.radius,
i = 0;
do {
// out when deeper than radius in the negative halfspace
if ( planes[ i ].distanceToPoint( center ) < negRad ) return false;
} while ( ++ i !== numPlanes );
return true;
}
*/
function projectObject( object, camera, sortObjects ) {
if ( ! object.visible ) return;
var visible = object.layers.test( camera.layers );
if ( visible ) {
if ( object.isLight ) {
lights.push( object );
} else if ( object.isSprite ) {
if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) {
sprites.push( object );
}
} else if ( object.isLensFlare ) {
lensFlares.push( object );
} else if ( object.isImmediateRenderObject ) {
if ( sortObjects ) {
_vector3.setFromMatrixPosition( object.matrixWorld )
.applyMatrix4( _projScreenMatrix );
}
currentRenderList.push( object, null, object.material, _vector3.z, null );
} else if ( object.isMesh || object.isLine || object.isPoints ) {
if ( object.isSkinnedMesh ) {
object.skeleton.update();
}
if ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) {
if ( sortObjects ) {
_vector3.setFromMatrixPosition( object.matrixWorld )
.applyMatrix4( _projScreenMatrix );
}
var geometry = objects.update( object );
var material = object.material;
if ( Array.isArray( material ) ) {
var groups = geometry.groups;
for ( var i = 0, l = groups.length; i < l; i ++ ) {
var group = groups[ i ];
var groupMaterial = material[ group.materialIndex ];
if ( groupMaterial && groupMaterial.visible ) {
currentRenderList.push( object, geometry, groupMaterial, _vector3.z, group );
}
}
} else if ( material.visible ) {
currentRenderList.push( object, geometry, material, _vector3.z, null );
}
}
}
}
var children = object.children;
for ( var i = 0, l = children.length; i < l; i ++ ) {
projectObject( children[ i ], camera, sortObjects );
}
}
function renderObjects( renderList, scene, camera, overrideMaterial ) {
for ( var i = 0, l = renderList.length; i < l; i ++ ) {
var renderItem = renderList[ i ];
var object = renderItem.object;
var geometry = renderItem.geometry;
var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
var group = renderItem.group;
if ( camera.isArrayCamera ) {
_currentArrayCamera = camera;
var cameras = camera.cameras;
for ( var j = 0, jl = cameras.length; j < jl; j ++ ) {
var camera2 = cameras[ j ];
if ( object.layers.test( camera2.layers ) ) {
var bounds = camera2.bounds;
var x = bounds.x * _width;
var y = bounds.y * _height;
var width = bounds.z * _width;
var height = bounds.w * _height;
_this.setViewport( x, y, width, height );
_this.setScissor( x, y, width, height );
_this.setScissorTest( true );
renderObject( object, scene, camera2, geometry, material, group );
}
}
} else {
_currentArrayCamera = null;
renderObject( object, scene, camera, geometry, material, group );
}
}
}
function renderObject( object, scene, camera, geometry, material, group ) {
object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
object.onBeforeRender( _this, scene, camera, geometry, material, group );
if ( object.isImmediateRenderObject ) {
state.setMaterial( material );
var program = setProgram( camera, scene.fog, material, object );
_currentGeometryProgram = '';
renderObjectImmediate( object, program, material );
} else {
_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );
}
object.onAfterRender( _this, scene, camera, geometry, material, group );
}
function initMaterial( material, fog, object ) {
var materialProperties = properties.get( material );
var parameters = programCache.getParameters(
material, _lights, fog, _clipping.numPlanes, _clipping.numIntersection, object );
var code = programCache.getProgramCode( material, parameters );
var program = materialProperties.program;
var programChange = true;
if ( program === undefined ) {
// new material
material.addEventListener( 'dispose', onMaterialDispose );
} else if ( program.code !== code ) {
// changed glsl or parameters
releaseMaterialProgramReference( material );
} else if ( parameters.shaderID !== undefined ) {
// same glsl and uniform list
return;
} else {
// only rebuild uniform list
programChange = false;
}
if ( programChange ) {
if ( parameters.shaderID ) {
var shader = ShaderLib[ parameters.shaderID ];
materialProperties.shader = {
name: material.type,
uniforms: UniformsUtils.clone( shader.uniforms ),
vertexShader: shader.vertexShader,
fragmentShader: shader.fragmentShader
};
} else {
materialProperties.shader = {
name: material.type,
uniforms: material.uniforms,
vertexShader: material.vertexShader,
fragmentShader: material.fragmentShader
};
}
material.onBeforeCompile( materialProperties.shader );
program = programCache.acquireProgram( material, materialProperties.shader, parameters, code );
materialProperties.program = program;
material.program = program;
}
var programAttributes = program.getAttributes();
if ( material.morphTargets ) {
material.numSupportedMorphTargets = 0;
for ( var i = 0; i < _this.maxMorphTargets; i ++ ) {
if ( programAttributes[ 'morphTarget' + i ] >= 0 ) {
material.numSupportedMorphTargets ++;
}
}
}
if ( material.morphNormals ) {
material.numSupportedMorphNormals = 0;
for ( var i = 0; i < _this.maxMorphNormals; i ++ ) {
if ( programAttributes[ 'morphNormal' + i ] >= 0 ) {
material.numSupportedMorphNormals ++;
}
}
}
var uniforms = materialProperties.shader.uniforms;
if ( ! material.isShaderMaterial &&
! material.isRawShaderMaterial ||
material.clipping === true ) {
materialProperties.numClippingPlanes = _clipping.numPlanes;
materialProperties.numIntersection = _clipping.numIntersection;
uniforms.clippingPlanes = _clipping.uniform;
}
materialProperties.fog = fog;
// store the light setup it was created for
materialProperties.lightsHash = _lights.hash;
if ( material.lights ) {
// wire up the material to this renderer's lighting state
uniforms.ambientLightColor.value = _lights.ambient;
uniforms.directionalLights.value = _lights.directional;
uniforms.spotLights.value = _lights.spot;
uniforms.rectAreaLights.value = _lights.rectArea;
uniforms.pointLights.value = _lights.point;
uniforms.hemisphereLights.value = _lights.hemi;
uniforms.directionalShadowMap.value = _lights.directionalShadowMap;
uniforms.directionalShadowMatrix.value = _lights.directionalShadowMatrix;
uniforms.spotShadowMap.value = _lights.spotShadowMap;
uniforms.spotShadowMatrix.value = _lights.spotShadowMatrix;
uniforms.pointShadowMap.value = _lights.pointShadowMap;
uniforms.pointShadowMatrix.value = _lights.pointShadowMatrix;
// TODO (abelnation): add area lights shadow info to uniforms
}
var progUniforms = materialProperties.program.getUniforms(),
uniformsList =
WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );
materialProperties.uniformsList = uniformsList;
}
function setProgram( camera, fog, material, object ) {
_usedTextureUnits = 0;
var materialProperties = properties.get( material );
if ( _clippingEnabled ) {
if ( _localClippingEnabled || camera !== _currentCamera ) {
var useCache =
camera === _currentCamera &&
material.id === _currentMaterialId;
// we might want to call this function with some ClippingGroup
// object instead of the material, once it becomes feasible
// (#8465, #8379)
_clipping.setState(
material.clippingPlanes, material.clipIntersection, material.clipShadows,
camera, materialProperties, useCache );
}
}
if ( material.needsUpdate === false ) {
if ( materialProperties.program === undefined ) {
material.needsUpdate = true;
} else if ( material.fog && materialProperties.fog !== fog ) {
material.needsUpdate = true;
} else if ( material.lights && materialProperties.lightsHash !== _lights.hash ) {
material.needsUpdate = true;
} else if ( materialProperties.numClippingPlanes !== undefined &&
( materialProperties.numClippingPlanes !== _clipping.numPlanes ||
materialProperties.numIntersection !== _clipping.numIntersection ) ) {
material.needsUpdate = true;
}
}
if ( material.needsUpdate ) {
initMaterial( material, fog, object );
material.needsUpdate = false;
}
var refreshProgram = false;
var refreshMaterial = false;
var refreshLights = false;
var program = materialProperties.program,
p_uniforms = program.getUniforms(),
m_uniforms = materialProperties.shader.uniforms;
if ( program.id !== _currentProgram ) {
_gl.useProgram( program.program );
_currentProgram = program.id;
refreshProgram = true;
refreshMaterial = true;
refreshLights = true;
}
if ( material.id !== _currentMaterialId ) {
_currentMaterialId = material.id;
refreshMaterial = true;
}
if ( refreshProgram || camera !== _currentCamera ) {
p_uniforms.setValue( _gl, 'projectionMatrix', camera.projectionMatrix );
if ( capabilities.logarithmicDepthBuffer ) {
p_uniforms.setValue( _gl, 'logDepthBufFC',
2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
}
// Avoid unneeded uniform updates per ArrayCamera's sub-camera
if ( _currentCamera !== ( _currentArrayCamera || camera ) ) {
_currentCamera = ( _currentArrayCamera || camera );
// lighting uniforms depend on the camera so enforce an update
// now, in case this material supports lights - or later, when
// the next material that does gets activated:
refreshMaterial = true; // set to true on material change
refreshLights = true; // remains set until update done
}
// load material specific uniforms
// (shader material also gets them for the sake of genericity)
if ( material.isShaderMaterial ||
material.isMeshPhongMaterial ||
material.isMeshStandardMaterial ||
material.envMap ) {
var uCamPos = p_uniforms.map.cameraPosition;
if ( uCamPos !== undefined ) {
uCamPos.setValue( _gl,
_vector3.setFromMatrixPosition( camera.matrixWorld ) );
}
}
if ( material.isMeshPhongMaterial ||
material.isMeshLambertMaterial ||
material.isMeshBasicMaterial ||
material.isMeshStandardMaterial ||
material.isShaderMaterial ||
material.skinning ) {
p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
}
}
// skinning uniforms must be set even if material didn't change
// auto-setting of texture unit for bone texture must go before other textures
// not sure why, but otherwise weird things happen
if ( material.skinning ) {
p_uniforms.setOptional( _gl, object, 'bindMatrix' );
p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );
var skeleton = object.skeleton;
if ( skeleton ) {
var bones = skeleton.bones;
if ( capabilities.floatVertexTextures ) {
if ( skeleton.boneTexture === undefined ) {
// layout (1 matrix = 4 pixels)
// RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)
// with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8)
// 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16)
// 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32)
// 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)
var size = Math.sqrt( bones.length * 4 ); // 4 pixels needed for 1 matrix
size = _Math.nextPowerOfTwo( Math.ceil( size ) );
size = Math.max( size, 4 );
var boneMatrices = new Float32Array( size * size * 4 ); // 4 floats per RGBA pixel
boneMatrices.set( skeleton.boneMatrices ); // copy current values
var boneTexture = new DataTexture( boneMatrices, size, size, RGBAFormat, FloatType );
skeleton.boneMatrices = boneMatrices;
skeleton.boneTexture = boneTexture;
skeleton.boneTextureSize = size;
}
p_uniforms.setValue( _gl, 'boneTexture', skeleton.boneTexture );
p_uniforms.setValue( _gl, 'boneTextureSize', skeleton.boneTextureSize );
} else {
p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );
}
}
}
if ( refreshMaterial ) {
p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure );
p_uniforms.setValue( _gl, 'toneMappingWhitePoint', _this.toneMappingWhitePoint );
if ( material.lights ) {
// the current material requires lighting info
// note: all lighting uniforms are always set correctly
// they simply reference the renderer's state for their
// values
//
// use the current material's .needsUpdate flags to set
// the GL state when required
markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
}
// refresh uniforms common to several materials
if ( fog && material.fog ) {
refreshUniformsFog( m_uniforms, fog );
}
if ( material.isMeshBasicMaterial ||
material.isMeshLambertMaterial ||
material.isMeshPhongMaterial ||
material.isMeshStandardMaterial ||
material.isMeshNormalMaterial ||
material.isMeshDepthMaterial ) {
refreshUniformsCommon( m_uniforms, material );
}
// refresh single material specific uniforms
if ( material.isLineBasicMaterial ) {
refreshUniformsLine( m_uniforms, material );
} else if ( material.isLineDashedMaterial ) {
refreshUniformsLine( m_uniforms, material );
refreshUniformsDash( m_uniforms, material );
} else if ( material.isPointsMaterial ) {
refreshUniformsPoints( m_uniforms, material );
} else if ( material.isMeshLambertMaterial ) {
refreshUniformsLambert( m_uniforms, material );
} else if ( material.isMeshToonMaterial ) {
refreshUniformsToon( m_uniforms, material );
} else if ( material.isMeshPhongMaterial ) {
refreshUniformsPhong( m_uniforms, material );
} else if ( material.isMeshPhysicalMaterial ) {
refreshUniformsPhysical( m_uniforms, material );
} else if ( material.isMeshStandardMaterial ) {
refreshUniformsStandard( m_uniforms, material );
} else if ( material.isMeshDepthMaterial ) {
if ( material.displacementMap ) {
m_uniforms.displacementMap.value = material.displacementMap;
m_uniforms.displacementScale.value = material.displacementScale;
m_uniforms.displacementBias.value = material.displacementBias;
}
} else if ( material.isMeshNormalMaterial ) {
refreshUniformsNormal( m_uniforms, material );
}
// RectAreaLight Texture
// TODO (mrdoob): Find a nicer implementation
if ( m_uniforms.ltcMat !== undefined ) m_uniforms.ltcMat.value = UniformsLib.LTC_MAT_TEXTURE;
if ( m_uniforms.ltcMag !== undefined ) m_uniforms.ltcMag.value = UniformsLib.LTC_MAG_TEXTURE;
WebGLUniforms.upload(
_gl, materialProperties.uniformsList, m_uniforms, _this );
}
// common matrices
p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix );
p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix );
p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
return program;
}
// Uniforms (refresh uniforms objects)
function refreshUniformsCommon( uniforms, material ) {
uniforms.opacity.value = material.opacity;
uniforms.diffuse.value = material.color;
if ( material.emissive ) {
uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
}
uniforms.map.value = material.map;
uniforms.specularMap.value = material.specularMap;
uniforms.alphaMap.value = material.alphaMap;
if ( material.lightMap ) {
uniforms.lightMap.value = material.lightMap;
uniforms.lightMapIntensity.value = material.lightMapIntensity;
}
if ( material.aoMap ) {
uniforms.aoMap.value = material.aoMap;
uniforms.aoMapIntensity.value = material.aoMapIntensity;
}
// uv repeat and offset setting priorities
// 1. color map
// 2. specular map
// 3. normal map
// 4. bump map
// 5. alpha map
// 6. emissive map
var uvScaleMap;
if ( material.map ) {
uvScaleMap = material.map;
} else if ( material.specularMap ) {
uvScaleMap = material.specularMap;
} else if ( material.displacementMap ) {
uvScaleMap = material.displacementMap;
} else if ( material.normalMap ) {
uvScaleMap = material.normalMap;
} else if ( material.bumpMap ) {
uvScaleMap = material.bumpMap;
} else if ( material.roughnessMap ) {
uvScaleMap = material.roughnessMap;
} else if ( material.metalnessMap ) {
uvScaleMap = material.metalnessMap;
} else if ( material.alphaMap ) {
uvScaleMap = material.alphaMap;
} else if ( material.emissiveMap ) {
uvScaleMap = material.emissiveMap;
}
if ( uvScaleMap !== undefined ) {
// backwards compatibility
if ( uvScaleMap.isWebGLRenderTarget ) {
uvScaleMap = uvScaleMap.texture;
}
var offset = uvScaleMap.offset;
var repeat = uvScaleMap.repeat;
uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );
}
uniforms.envMap.value = material.envMap;
// don't flip CubeTexture envMaps, flip everything else:
// WebGLRenderTargetCube will be flipped for backwards compatibility
// WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture
// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future
uniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1;
uniforms.reflectivity.value = material.reflectivity;
uniforms.refractionRatio.value = material.refractionRatio;
}
function refreshUniformsLine( uniforms, material ) {
uniforms.diffuse.value = material.color;
uniforms.opacity.value = material.opacity;
}
function refreshUniformsDash( uniforms, material ) {
uniforms.dashSize.value = material.dashSize;
uniforms.totalSize.value = material.dashSize + material.gapSize;
uniforms.scale.value = material.scale;
}
function refreshUniformsPoints( uniforms, material ) {
uniforms.diffuse.value = material.color;
uniforms.opacity.value = material.opacity;
uniforms.size.value = material.size * _pixelRatio;
uniforms.scale.value = _height * 0.5;
uniforms.map.value = material.map;
if ( material.map !== null ) {
var offset = material.map.offset;
var repeat = material.map.repeat;
uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );
}
}
function refreshUniformsFog( uniforms, fog ) {
uniforms.fogColor.value = fog.color;
if ( fog.isFog ) {
uniforms.fogNear.value = fog.near;
uniforms.fogFar.value = fog.far;
} else if ( fog.isFogExp2 ) {
uniforms.fogDensity.value = fog.density;
}
}
function refreshUniformsLambert( uniforms, material ) {
if ( material.emissiveMap ) {
uniforms.emissiveMap.value = material.emissiveMap;
}
}
function refreshUniformsPhong( uniforms, material ) {
uniforms.specular.value = material.specular;
uniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )
if ( material.emissiveMap ) {
uniforms.emissiveMap.value = material.emissiveMap;
}
if ( material.bumpMap ) {
uniforms.bumpMap.value = material.bumpMap;
uniforms.bumpScale.value = material.bumpScale;
}
if ( material.normalMap ) {
uniforms.normalMap.value = material.normalMap;
uniforms.normalScale.value.copy( material.normalScale );
}
if ( material.displacementMap ) {
uniforms.displacementMap.value = material.displacementMap;
uniforms.displacementScale.value = material.displacementScale;
uniforms.displacementBias.value = material.displacementBias;
}
}
function refreshUniformsToon( uniforms, material ) {
refreshUniformsPhong( uniforms, material );
if ( material.gradientMap ) {
uniforms.gradientMap.value = material.gradientMap;
}
}
function refreshUniformsStandard( uniforms, material ) {
uniforms.roughness.value = material.roughness;
uniforms.metalness.value = material.metalness;
if ( material.roughnessMap ) {
uniforms.roughnessMap.value = material.roughnessMap;
}
if ( material.metalnessMap ) {
uniforms.metalnessMap.value = material.metalnessMap;
}
if ( material.emissiveMap ) {
uniforms.emissiveMap.value = material.emissiveMap;
}
if ( material.bumpMap ) {
uniforms.bumpMap.value = material.bumpMap;
uniforms.bumpScale.value = material.bumpScale;
}
if ( material.normalMap ) {
uniforms.normalMap.value = material.normalMap;
uniforms.normalScale.value.copy( material.normalScale );
}
if ( material.displacementMap ) {
uniforms.displacementMap.value = material.displacementMap;
uniforms.displacementScale.value = material.displacementScale;
uniforms.displacementBias.value = material.displacementBias;
}
if ( material.envMap ) {
//uniforms.envMap.value = material.envMap; // part of uniforms common
uniforms.envMapIntensity.value = material.envMapIntensity;
}
}
function refreshUniformsPhysical( uniforms, material ) {
uniforms.clearCoat.value = material.clearCoat;
uniforms.clearCoatRoughness.value = material.clearCoatRoughness;
refreshUniformsStandard( uniforms, material );
}
function refreshUniformsNormal( uniforms, material ) {
if ( material.bumpMap ) {
uniforms.bumpMap.value = material.bumpMap;
uniforms.bumpScale.value = material.bumpScale;
}
if ( material.normalMap ) {
uniforms.normalMap.value = material.normalMap;
uniforms.normalScale.value.copy( material.normalScale );
}
if ( material.displacementMap ) {
uniforms.displacementMap.value = material.displacementMap;
uniforms.displacementScale.value = material.displacementScale;
uniforms.displacementBias.value = material.displacementBias;
}
}
// If uniforms are marked as clean, they don't need to be loaded to the GPU.
function markUniformsLightsNeedsUpdate( uniforms, value ) {
uniforms.ambientLightColor.needsUpdate = value;
uniforms.directionalLights.needsUpdate = value;
uniforms.pointLights.needsUpdate = value;
uniforms.spotLights.needsUpdate = value;
uniforms.rectAreaLights.needsUpdate = value;
uniforms.hemisphereLights.needsUpdate = value;
}
// Lighting
function setupShadows( lights ) {
var lightShadowsLength = 0;
for ( var i = 0, l = lights.length; i < l; i ++ ) {
var light = lights[ i ];
if ( light.castShadow ) {
_lights.shadows[ lightShadowsLength ] = light;
lightShadowsLength ++;
}
}
_lights.shadows.length = lightShadowsLength;
}
function setupLights( lights, camera ) {
var l, ll, light, shadow,
r = 0, g = 0, b = 0,
color,
intensity,
distance,
shadowMap,
viewMatrix = camera.matrixWorldInverse,
directionalLength = 0,
pointLength = 0,
spotLength = 0,
rectAreaLength = 0,
hemiLength = 0;
for ( l = 0, ll = lights.length; l < ll; l ++ ) {
light = lights[ l ];
color = light.color;
intensity = light.intensity;
distance = light.distance;
shadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;
if ( light.isAmbientLight ) {
r += color.r * intensity;
g += color.g * intensity;
b += color.b * intensity;
} else if ( light.isDirectionalLight ) {
var uniforms = lightCache.get( light );
uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
uniforms.direction.setFromMatrixPosition( light.matrixWorld );
_vector3.setFromMatrixPosition( light.target.matrixWorld );
uniforms.direction.sub( _vector3 );
uniforms.direction.transformDirection( viewMatrix );
uniforms.shadow = light.castShadow;
if ( light.castShadow ) {
shadow = light.shadow;
uniforms.shadowBias = shadow.bias;
uniforms.shadowRadius = shadow.radius;
uniforms.shadowMapSize = shadow.mapSize;
}
_lights.directionalShadowMap[ directionalLength ] = shadowMap;
_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;
_lights.directional[ directionalLength ] = uniforms;
directionalLength ++;
} else if ( light.isSpotLight ) {
var uniforms = lightCache.get( light );
uniforms.position.setFromMatrixPosition( light.matrixWorld );
uniforms.position.applyMatrix4( viewMatrix );
uniforms.color.copy( color ).multiplyScalar( intensity );
uniforms.distance = distance;
uniforms.direction.setFromMatrixPosition( light.matrixWorld );
_vector3.setFromMatrixPosition( light.target.matrixWorld );
uniforms.direction.sub( _vector3 );
uniforms.direction.transformDirection( viewMatrix );
uniforms.coneCos = Math.cos( light.angle );
uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );
uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
uniforms.shadow = light.castShadow;
if ( light.castShadow ) {
shadow = light.shadow;
uniforms.shadowBias = shadow.bias;
uniforms.shadowRadius = shadow.radius;
uniforms.shadowMapSize = shadow.mapSize;
}
_lights.spotShadowMap[ spotLength ] = shadowMap;
_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;
_lights.spot[ spotLength ] = uniforms;
spotLength ++;
} else if ( light.isRectAreaLight ) {
var uniforms = lightCache.get( light );
// (a) intensity controls irradiance of entire light
uniforms.color
.copy( color )
.multiplyScalar( intensity / ( light.width * light.height ) );
// (b) intensity controls the radiance per light area
// uniforms.color.copy( color ).multiplyScalar( intensity );
uniforms.position.setFromMatrixPosition( light.matrixWorld );
uniforms.position.applyMatrix4( viewMatrix );
// extract local rotation of light to derive width/height half vectors
_matrix42.identity();
_matrix4.copy( light.matrixWorld );
_matrix4.premultiply( viewMatrix );
_matrix42.extractRotation( _matrix4 );
uniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 );
uniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 );
uniforms.halfWidth.applyMatrix4( _matrix42 );
uniforms.halfHeight.applyMatrix4( _matrix42 );
// TODO (abelnation): RectAreaLight distance?
// uniforms.distance = distance;
_lights.rectArea[ rectAreaLength ] = uniforms;
rectAreaLength ++;
} else if ( light.isPointLight ) {
var uniforms = lightCache.get( light );
uniforms.position.setFromMatrixPosition( light.matrixWorld );
uniforms.position.applyMatrix4( viewMatrix );
uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
uniforms.distance = light.distance;
uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
uniforms.shadow = light.castShadow;
if ( light.castShadow ) {
shadow = light.shadow;
uniforms.shadowBias = shadow.bias;
uniforms.shadowRadius = shadow.radius;
uniforms.shadowMapSize = shadow.mapSize;
}
_lights.pointShadowMap[ pointLength ] = shadowMap;
_lights.pointShadowMatrix[ pointLength ] = light.shadow.matrix;
_lights.point[ pointLength ] = uniforms;
pointLength ++;
} else if ( light.isHemisphereLight ) {
var uniforms = lightCache.get( light );
uniforms.direction.setFromMatrixPosition( light.matrixWorld );
uniforms.direction.transformDirection( viewMatrix );
uniforms.direction.normalize();
uniforms.skyColor.copy( light.color ).multiplyScalar( intensity );
uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );
_lights.hemi[ hemiLength ] = uniforms;
hemiLength ++;
}
}
_lights.ambient[ 0 ] = r;
_lights.ambient[ 1 ] = g;
_lights.ambient[ 2 ] = b;
_lights.directional.length = directionalLength;
_lights.spot.length = spotLength;
_lights.rectArea.length = rectAreaLength;
_lights.point.length = pointLength;
_lights.hemi.length = hemiLength;
// TODO (sam-g-steel) why aren't we using join
_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + rectAreaLength + ',' + hemiLength + ',' + _lights.shadows.length;
}
// GL state setting
this.setFaceCulling = function ( cullFace, frontFaceDirection ) {
state.setCullFace( cullFace );
state.setFlipSided( frontFaceDirection === FrontFaceDirectionCW );
};
// Textures
function allocTextureUnit() {
var textureUnit = _usedTextureUnits;
if ( textureUnit >= capabilities.maxTextures ) {
console.warn( 'THREE.WebGLRenderer: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );
}
_usedTextureUnits += 1;
return textureUnit;
}
this.allocTextureUnit = allocTextureUnit;
// this.setTexture2D = setTexture2D;
this.setTexture2D = ( function () {
var warned = false;
// backwards compatibility: peel texture.texture
return function setTexture2D( texture, slot ) {
if ( texture && texture.isWebGLRenderTarget ) {
if ( ! warned ) {
console.warn( "THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead." );
warned = true;
}
texture = texture.texture;
}
textures.setTexture2D( texture, slot );
};
}() );
this.setTexture = ( function () {
var warned = false;
return function setTexture( texture, slot ) {
if ( ! warned ) {
console.warn( "THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead." );
warned = true;
}
textures.setTexture2D( texture, slot );
};
}() );
this.setTextureCube = ( function () {
var warned = false;
return function setTextureCube( texture, slot ) {
// backwards compatibility: peel texture.texture
if ( texture && texture.isWebGLRenderTargetCube ) {
if ( ! warned ) {
console.warn( "THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead." );
warned = true;
}
texture = texture.texture;
}
// currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture
// TODO: unify these code paths
if ( ( texture && texture.isCubeTexture ) ||
( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {
// CompressedTexture can have Array in image :/
// this function alone should take care of cube textures
textures.setTextureCube( texture, slot );
} else {
// assumed: texture property of THREE.WebGLRenderTargetCube
textures.setTextureCubeDynamic( texture, slot );
}
};
}() );
this.getRenderTarget = function () {
return _currentRenderTarget;
};
this.setRenderTarget = function ( renderTarget ) {
_currentRenderTarget = renderTarget;
if ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {
textures.setupRenderTarget( renderTarget );
}
var isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );
var framebuffer;
if ( renderTarget ) {
var renderTargetProperties = properties.get( renderTarget );
if ( isCube ) {
framebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];
} else {
framebuffer = renderTargetProperties.__webglFramebuffer;
}
_currentScissor.copy( renderTarget.scissor );
_currentScissorTest = renderTarget.scissorTest;
_currentViewport.copy( renderTarget.viewport );
} else {
framebuffer = null;
_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
_currentScissorTest = _scissorTest;
_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
}
if ( _currentFramebuffer !== framebuffer ) {
_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
_currentFramebuffer = framebuffer;
}
state.scissor( _currentScissor );
state.setScissorTest( _currentScissorTest );
state.viewport( _currentViewport );
if ( isCube ) {
var textureProperties = properties.get( renderTarget.texture );
_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );
}
};
this.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer ) {
if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) {
console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
return;
}
var framebuffer = properties.get( renderTarget ).__webglFramebuffer;
if ( framebuffer ) {
var restore = false;
if ( framebuffer !== _currentFramebuffer ) {
_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
restore = true;
}
try {
var texture = renderTarget.texture;
var textureFormat = texture.format;
var textureType = texture.type;
if ( textureFormat !== RGBAFormat && paramThreeToGL( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );
return;
}
if ( textureType !== UnsignedByteType && paramThreeToGL( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)
! ( textureType === FloatType && ( extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox
! ( textureType === HalfFloatType && extensions.get( 'EXT_color_buffer_half_float' ) ) ) {
console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );
return;
}
if ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) {
// the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)
if ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {
_gl.readPixels( x, y, width, height, paramThreeToGL( textureFormat ), paramThreeToGL( textureType ), buffer );
}
} else {
console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );
}
} finally {
if ( restore ) {
_gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer );
}
}
}
};
// Map three.js constants to WebGL constants
function paramThreeToGL( p ) {
var extension;
if ( p === RepeatWrapping ) return _gl.REPEAT;
if ( p === ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;
if ( p === MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;
if ( p === NearestFilter ) return _gl.NEAREST;
if ( p === NearestMipMapNearestFilter ) return _gl.NEAREST_MIPMAP_NEAREST;
if ( p === NearestMipMapLinearFilter ) return _gl.NEAREST_MIPMAP_LINEAR;
if ( p === LinearFilter ) return _gl.LINEAR;
if ( p === LinearMipMapNearestFilter ) return _gl.LINEAR_MIPMAP_NEAREST;
if ( p === LinearMipMapLinearFilter ) return _gl.LINEAR_MIPMAP_LINEAR;
if ( p === UnsignedByteType ) return _gl.UNSIGNED_BYTE;
if ( p === UnsignedShort4444Type ) return _gl.UNSIGNED_SHORT_4_4_4_4;
if ( p === UnsignedShort5551Type ) return _gl.UNSIGNED_SHORT_5_5_5_1;
if ( p === UnsignedShort565Type ) return _gl.UNSIGNED_SHORT_5_6_5;
if ( p === ByteType ) return _gl.BYTE;
if ( p === ShortType ) return _gl.SHORT;
if ( p === UnsignedShortType ) return _gl.UNSIGNED_SHORT;
if ( p === IntType ) return _gl.INT;
if ( p === UnsignedIntType ) return _gl.UNSIGNED_INT;
if ( p === FloatType ) return _gl.FLOAT;
if ( p === HalfFloatType ) {
extension = extensions.get( 'OES_texture_half_float' );
if ( extension !== null ) return extension.HALF_FLOAT_OES;
}
if ( p === AlphaFormat ) return _gl.ALPHA;
if ( p === RGBFormat ) return _gl.RGB;
if ( p === RGBAFormat ) return _gl.RGBA;
if ( p === LuminanceFormat ) return _gl.LUMINANCE;
if ( p === LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA;
if ( p === DepthFormat ) return _gl.DEPTH_COMPONENT;
if ( p === DepthStencilFormat ) return _gl.DEPTH_STENCIL;
if ( p === AddEquation ) return _gl.FUNC_ADD;
if ( p === SubtractEquation ) return _gl.FUNC_SUBTRACT;
if ( p === ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT;
if ( p === ZeroFactor ) return _gl.ZERO;
if ( p === OneFactor ) return _gl.ONE;
if ( p === SrcColorFactor ) return _gl.SRC_COLOR;
if ( p === OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR;
if ( p === SrcAlphaFactor ) return _gl.SRC_ALPHA;
if ( p === OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA;
if ( p === DstAlphaFactor ) return _gl.DST_ALPHA;
if ( p === OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA;
if ( p === DstColorFactor ) return _gl.DST_COLOR;
if ( p === OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR;
if ( p === SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE;
if ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||
p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {
extension = extensions.get( 'WEBGL_compressed_texture_s3tc' );
if ( extension !== null ) {
if ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;
if ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;
if ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;
if ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;
}
}
if ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format ||
p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {
extension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );
if ( extension !== null ) {
if ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
if ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
if ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
if ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
}
}
if ( p === RGB_ETC1_Format ) {
extension = extensions.get( 'WEBGL_compressed_texture_etc1' );
if ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL;
}
if ( p === MinEquation || p === MaxEquation ) {
extension = extensions.get( 'EXT_blend_minmax' );
if ( extension !== null ) {
if ( p === MinEquation ) return extension.MIN_EXT;
if ( p === MaxEquation ) return extension.MAX_EXT;
}
}
if ( p === UnsignedInt248Type ) {
extension = extensions.get( 'WEBGL_depth_texture' );
if ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL;
}
return 0;
}
}
/**
* @author mrdoob / http://mrdoob.com/
* @author alteredq / http://alteredqualia.com/
*/
function FogExp2 ( color, density ) {
this.name = '';
this.color = new Color( color );
this.density = ( density !== undefined ) ? density : 0.00025;
}
FogExp2.prototype.isFogExp2 = true;
FogExp2.prototype.clone = function () {
return new FogExp2( this.color.getHex(), this.density );
};
FogExp2.prototype.toJSON = function ( meta ) {
return {
type: 'FogExp2',
color: this.color.getHex(),
density: this.density
};
};
/**
* @author mrdoob / http://mrdoob.com/
* @author alteredq / http://alteredqualia.com/
*/
function Fog ( color, near, far ) {
this.name = '';
this.color = new Color( color );
this.near = ( near !== undefined ) ? near : 1;
this.far = ( far !== undefined ) ? far : 1000;
}
Fog.prototype.isFog = true;
Fog.prototype.clone = function () {
return new Fog( this.color.getHex(), this.near, this.far );
};
Fog.prototype.toJSON = function ( meta ) {
return {
type: 'Fog',
color: this.color.getHex(),
near: this.near,
far: this.far
};
};
/**
* @author mrdoob / http://mrdoob.com/
*/
function Scene () {
Object3D.call( this );
this.type = 'Scene';
this.background = null;
this.fog = null;
this.overrideMaterial = null;
this.autoUpdate = true; // checked by the renderer
}
Scene.prototype = Object.assign( Object.create( Object3D.prototype ), {
constructor: Scene,
copy: function ( source, recursive ) {
Object3D.prototype.copy.call( this, source, recursive );
if ( source.background !== null ) this.background = source.background.clone();
if ( source.fog !== null ) this.fog = source.fog.clone();
if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();
this.autoUpdate = source.autoUpdate;
this.matrixAutoUpdate = source.matrixAutoUpdate;
return this;
},
toJSON: function ( meta ) {
var data = Object3D.prototype.toJSON.call( this, meta );
if ( this.background !== null ) data.object.background = this.background.toJSON( meta );
if ( this.fog !== null ) data.object.fog = this.fog.toJSON();
return data;
}
} );
/**
* @author mikael emtinger / http://gomo.se/
* @author alteredq / http://alteredqualia.com/
*/
function LensFlare( texture, size, distance, blending, color ) {
Object3D.call( this );
this.lensFlares = [];
this.positionScreen = new Vector3();
this.customUpdateCallback = undefined;
if ( texture !== undefined ) {
this.add( texture, size, distance, blending, color );
}
}
LensFlare.prototype = Object.assign( Object.create( Object3D.prototype ), {
constructor: LensFlare,
isLensFlare: true,
copy: function ( source ) {
Object3D.prototype.copy.call( this, source );
this.positionScreen.copy( source.positionScreen );
this.customUpdateCallback = source.customUpdateCallback;
for ( var i = 0, l = source.lensFlares.length; i < l; i ++ ) {
this.lensFlares.push( source.lensFlares[ i ] );
}
return this;
},
add: function ( texture, size, distance, blending, color, opacity ) {
if ( size === undefined ) size = - 1;
if ( distance === undefined ) distance = 0;
if ( opacity === undefined ) opacity = 1;
if ( color === undefined ) color = new Color( 0xffffff );
if ( blending === undefined ) blending = NormalBlending;
distance = Math.min( distance, Math.max( 0, distance ) );
this.lensFlares.push( {
texture: texture, // THREE.Texture
size: size, // size in pixels (-1 = use texture.width)
distance: distance, // distance (0-1) from light source (0=at light source)
x: 0, y: 0, z: 0, // screen position (-1 => 1) z = 0 is in front z = 1 is back
scale: 1, // scale
rotation: 0, // rotation
opacity: opacity, // opacity
color: color, // color
blending: blending // blending
} );
},
/*
* Update lens flares update positions on all flares based on the screen position
* Set myLensFlare.customUpdateCallback to alter the flares in your project specific way.
*/
updateLensFlares: function () {
var f, fl = this.lensFlares.length;
var flare;
var vecX = - this.positionScreen.x * 2;
var vecY = - this.positionScreen.y * 2;
for ( f = 0; f < fl; f ++ ) {
flare = this.lensFlares[ f ];
flare.x = this.positionScreen.x + vecX * flare.distance;
flare.y = this.positionScreen.y + vecY * flare.distance;
flare.wantedRotation = flare.x * Math.PI * 0.25;
flare.rotation += ( flare.wantedRotation - flare.rotation ) * 0.25;
}
}
} );
/**
* @author alteredq / http://alteredqualia.com/
*
* parameters = {
* color: <hex>,
* opacity: <float>,
* map: new THREE.Texture( <Image> ),
*
* uvOffset: new THREE.Vector2(),
* uvScale: new THREE.Vector2()
* }
*/
function SpriteMaterial( parameters ) {
Material.call( this );
this.type = 'SpriteMaterial';
this.color = new Color( 0xffffff );
this.map = null;
this.rotation = 0;
this.fog = false;
this.lights = false;
this.setValues( parameters );
}
SpriteMaterial.prototype = Object.create( Material.prototype );
SpriteMaterial.prototype.constructor = SpriteMaterial;
SpriteMaterial.prototype.isSpriteMaterial = true;
SpriteMaterial.prototype.copy = function ( source ) {
Material.prototype.copy.call( this, source );
this.color.copy( source.color );
this.map = source.map;
this.rotation = source.rotation;
return this;
};
/**
* @author mikael emtinger / http://gomo.se/
* @author alteredq / http://alteredqualia.com/
*/
function Sprite( material ) {
Object3D.call( this );
this.type = 'Sprite';
this.material = ( material !== undefined ) ? material : new SpriteMaterial();
}
Sprite.prototype = Object.assign( Object.create( Object3D.prototype ), {
constructor: Sprite,
isSprite: true,
raycast: ( function () {
var intersectPoint = new Vector3();
var worldPosition = new Vector3();
var worldScale = new Vector3();
return function raycast( raycaster, intersects ) {
worldPosition.setFromMatrixPosition( this.matrixWorld );
raycaster.ray.closestPointToPoint( worldPosition, intersectPoint );
worldScale.setFromMatrixScale( this.matrixWorld );
var guessSizeSq = worldScale.x * worldScale.y / 4;
if ( worldPosition.distanceToSquared( intersectPoint ) > guessSizeSq ) return;
var distance = raycaster.ray.origin.distanceTo( intersectPoint );
if ( distance < raycaster.near || distance > raycaster.far ) return;
intersects.push( {
distance: distance,
point: intersectPoint.clone(),
face: null,
object: this
} );
};
}() ),
clone: function () {
return new this.constructor( this.material ).copy( this );
}
} );
/**
* @author mikael emtinger / http://gomo.se/
* @author alteredq / http://alteredqualia.com/
* @author mrdoob / http://mrdoob.com/
*/
function LOD() {
Object3D.call( this );
this.type = 'LOD';
Object.defineProperties( this, {
levels: {
enumerable: true,
value: []
}
} );
}
LOD.prototype = Object.assign( Object.create( Object3D.prototype ), {
constructor: LOD,
copy: function ( source ) {
Object3D.prototype.copy.call( this, source, false );
var levels = source.levels;
for ( var i = 0, l = levels.length; i < l; i ++ ) {
var level = levels[ i ];
this.addLevel( level.object.clone(), level.distance );
}
return this;
},
addLevel: function ( object, distance ) {
if ( distance === undefined ) distance = 0;
distance = Math.abs( distance );
var levels = this.levels;
for ( var l = 0; l < levels.length; l ++ ) {
if ( distance < levels[ l ].distance ) {
break;
}
}
levels.splice( l, 0, { distance: distance, object: object } );
this.add( object );
},
getObjectForDistance: function ( distance ) {
var levels = this.levels;
for ( var i = 1, l = levels.length; i < l; i ++ ) {
if ( distance < levels[ i ].distance ) {
break;
}
}
return levels[ i - 1 ].object;
},
raycast: ( function () {
var matrixPosition = new Vector3();
return function raycast( raycaster, intersects ) {
matrixPosition.setFromMatrixPosition( this.matrixWorld );
var distance = raycaster.ray.origin.distanceTo( matrixPosition );
this.getObjectForDistance( distance ).raycast( raycaster, intersects );
};
}() ),
update: function () {
var v1 = new Vector3();
var v2 = new Vector3();
return function update( camera ) {
var levels = this.levels;
if ( levels.length > 1 ) {
v1.setFromMatrixPosition( camera.matrixWorld );
v2.setFromMatrixPosition( this.matrixWorld );
var distance = v1.distanceTo( v2 );
levels[ 0 ].object.visible = true;
for ( var i = 1, l = levels.length; i < l; i ++ ) {
if ( distance >= levels[ i ].distance ) {
levels[ i - 1 ].object.visible = false;
levels[ i ].object.visible = true;
} else {
break;
}
}
for ( ; i < l; i ++ ) {
levels[ i ].object.visible = false;
}
}
};
}(),
toJSON: function ( meta ) {
var data = Object3D.prototype.toJSON.call( this, meta );
data.object.levels = [];
var levels = this.levels;
for ( var i = 0, l = levels.length; i < l; i ++ ) {
var level = levels[ i ];
data.object.levels.push( {
object: level.object.uuid,
distance: level.distance
} );
}
return data;
}
} );
/**
* @author mikael emtinger / http://gomo.se/
* @author alteredq / http://alteredqualia.com/
* @author michael guerrero / http://realitymeltdown.com
* @author ikerr / http://verold.com
*/
function Skeleton( bones, boneInverses ) {
// copy the bone array
bones = bones || [];
this.bones = bones.slice( 0 );
this.boneMatrices = new Float32Array( this.bones.length * 16 );
// use the supplied bone inverses or calculate the inverses
if ( boneInverses === undefined ) {
this.calculateInverses();
} else {
if ( this.bones.length === boneInverses.length ) {
this.boneInverses = boneInverses.slice( 0 );
} else {
console.warn( 'THREE.Skeleton boneInverses is the wrong length.' );
this.boneInverses = [];
for ( var i = 0, il = this.bones.length; i < il; i ++ ) {
this.boneInverses.push( new Matrix4() );
}
}
}
}
Object.assign( Skeleton.prototype, {
calculateInverses: function () {
this.boneInverses = [];
for ( var i = 0, il = this.bones.length; i < il; i ++ ) {
var inverse = new Matrix4();
if ( this.bones[ i ] ) {
inverse.getInverse( this.bones[ i ].matrixWorld );
}
this.boneInverses.push( inverse );
}
},
pose: function () {
var bone, i, il;
// recover the bind-time world matrices
for ( i = 0, il = this.bones.length; i < il; i ++ ) {
bone = this.bones[ i ];
if ( bone ) {
bone.matrixWorld.getInverse( this.boneInverses[ i ] );
}
}
// compute the local matrices, positions, rotations and scales
for ( i = 0, il = this.bones.length; i < il; i ++ ) {
bone = this.bones[ i ];
if ( bone ) {
if ( bone.parent && bone.parent.isBone ) {
bone.matrix.getInverse( bone.parent.matrixWorld );
bone.matrix.multiply( bone.matrixWorld );
} else {
bone.matrix.copy( bone.matrixWorld );
}
bone.matrix.decompose( bone.position, bone.quaternion, bone.scale );
}
}
},
update: ( function () {
var offsetMatrix = new Matrix4();
var identityMatrix = new Matrix4();
return function update() {
var bones = this.bones;
var boneInverses = this.boneInverses;
var boneMatrices = this.boneMatrices;
var boneTexture = this.boneTexture;
// flatten bone matrices to array
for ( var i = 0, il = bones.length; i < il; i ++ ) {
// compute the offset between the current and the original transform
var matrix = bones[ i ] ? bones[ i ].matrixWorld : identityMatrix;
offsetMatrix.multiplyMatrices( matrix, boneInverses[ i ] );
offsetMatrix.toArray( boneMatrices, i * 16 );
}
if ( boneTexture !== undefined ) {
boneTexture.needsUpdate = true;
}
};
} )(),
clone: function () {
return new Skeleton( this.bones, this.boneInverses );
}
} );
/**
* @author mikael emtinger / http://gomo.se/
* @author alteredq / http://alteredqualia.com/
* @author ikerr / http://verold.com
*/
function Bone() {
Object3D.call( this );
this.type = 'Bone';
}
Bone.prototype = Object.assign( Object.create( Object3D.prototype ), {
constructor: Bone,
isBone: true
} );
/**
* @author mikael emtinger / http://gomo.se/
* @author alteredq / http://alteredqualia.com/
* @author ikerr / http://verold.com
*/
function SkinnedMesh( geometry, material ) {
Mesh.call( this, geometry, material );
this.type = 'SkinnedMesh';
this.bindMode = 'attached';
this.bindMatrix = new Matrix4();
this.bindMatrixInverse = new Matrix4();
var bones = this.initBones();
var skeleton = new Skeleton( bones );
this.bind( skeleton, this.matrixWorld );
this.normalizeSkinWeights();
}
SkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
constructor: SkinnedMesh,
isSkinnedMesh: true,
initBones: function () {
var bones = [], bone, gbone;
var i, il;
if ( this.geometry && this.geometry.bones !== undefined ) {
// first, create array of 'Bone' objects from geometry data
for ( i = 0, il = this.geometry.bones.length; i < il; i ++ ) {
gbone = this.geometry.bones[ i ];
// create new 'Bone' object
bone = new Bone();
bones.push( bone );
// apply values
bone.name = gbone.name;
bone.position.fromArray( gbone.pos );
bone.quaternion.fromArray( gbone.rotq );
if ( gbone.scl !== undefined ) bone.scale.fromArray( gbone.scl );
}
// second, create bone hierarchy
for ( i = 0, il = this.geometry.bones.length; i < il; i ++ ) {
gbone = this.geometry.bones[ i ];
if ( ( gbone.parent !== - 1 ) && ( gbone.parent !== null ) && ( bones[ gbone.parent ] !== undefined ) ) {
// subsequent bones in the hierarchy
bones[ gbone.parent ].add( bones[ i ] );
} else {
// topmost bone, immediate child of the skinned mesh
this.add( bones[ i ] );
}
}
}
// now the bones are part of the scene graph and children of the skinned mesh.
// let's update the corresponding matrices
this.updateMatrixWorld( true );
return bones;
},
bind: function ( skeleton, bindMatrix ) {
this.skeleton = skeleton;
if ( bindMatrix === undefined ) {
this.updateMatrixWorld( true );
this.skeleton.calculateInverses();
bindMatrix = this.matrixWorld;
}
this.bindMatrix.copy( bindMatrix );
this.bindMatrixInverse.getInverse( bindMatrix );
},
pose: function () {
this.skeleton.pose();
},
normalizeSkinWeights: function () {
var scale, i;
if ( this.geometry && this.geometry.isGeometry ) {
for ( i = 0; i < this.geometry.skinWeights.length; i ++ ) {
var sw = this.geometry.skinWeights[ i ];
scale = 1.0 / sw.lengthManhattan();
if ( scale !== Infinity ) {
sw.multiplyScalar( scale );
} else {
sw.set( 1, 0, 0, 0 ); // do something reasonable
}
}
} else if ( this.geometry && this.geometry.isBufferGeometry ) {
var vec = new Vector4();
var skinWeight = this.geometry.attributes.skinWeight;
for ( i = 0; i < skinWeight.count; i ++ ) {
vec.x = skinWeight.getX( i );
vec.y = skinWeight.getY( i );
vec.z = skinWeight.getZ( i );
vec.w = skinWeight.getW( i );
scale = 1.0 / vec.lengthManhattan();
if ( scale !== Infinity ) {
vec.multiplyScalar( scale );
} else {
vec.set( 1, 0, 0, 0 ); // do something reasonable
}
skinWeight.setXYZW( i, vec.x, vec.y, vec.z, vec.w );
}
}
},
updateMatrixWorld: function ( force ) {
Mesh.prototype.updateMatrixWorld.call( this, force );
if ( this.bindMode === 'attached' ) {
this.bindMatrixInverse.getInverse( this.matrixWorld );
} else if ( this.bindMode === 'detached' ) {
this.bindMatrixInverse.getInverse( this.bindMatrix );
} else {
console.warn( 'THREE.SkinnedMesh: Unrecognized bindMode: ' + this.bindMode );
}
},
clone: function () {
return new this.constructor( this.geometry, this.material ).copy( this );
}
} );
/**
* @author mrdoob / http://mrdoob.com/
* @author alteredq / http://alteredqualia.com/
*
* parameters = {
* color: <hex>,
* opacity: <float>,
*
* linewidth: <float>,
* linecap: "round",
* linejoin: "round"
* }
*/
function LineBasicMaterial( parameters ) {
Material.call( this );
this.type = 'LineBasicMaterial';
this.color = new Color( 0xffffff );
this.linewidth = 1;
this.linecap = 'round';
this.linejoin = 'round';
this.lights = false;
this.setValues( parameters );
}
LineBasicMaterial.prototype = Object.create( Material.prototype );
LineBasicMaterial.prototype.constructor = LineBasicMaterial;
LineBasicMaterial.prototype.isLineBasicMaterial = true;
LineBasicMaterial.prototype.copy = function ( source ) {
Material.prototype.copy.call( this, source );
this.color.copy( source.color );
this.linewidth = source.linewidth;
this.linecap = source.linecap;
this.linejoin = source.linejoin;
return this;
};
/**
* @author mrdoob / http://mrdoob.com/
*/
function Line( geometry, material, mode ) {
if ( mode === 1 ) {
console.warn( 'THREE.Line: parameter THREE.LinePieces no longer supported. Created THREE.LineSegments instead.' );
return new LineSegments( geometry, material );
}
Object3D.call( this );
this.type = 'Line';
this.geometry = geometry !== undefined ? geometry : new BufferGeometry();
this.material = material !== undefined ? material : new LineBasicMaterial( { color: Math.random() * 0xffffff } );
}
Line.prototype = Object.assign( Object.create( Object3D.prototype ), {
constructor: Line,
isLine: true,
raycast: ( function () {
var inverseMatrix = new Matrix4();
var ray = new Ray();
var sphere = new Sphere();
return function raycast( raycaster, intersects ) {
var precision = raycaster.linePrecision;
var precisionSq = precision * precision;
var geometry = this.geometry;
var matrixWorld = this.matrixWorld;
// Checking boundingSphere distance to ray
if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
sphere.copy( geometry.boundingSphere );
sphere.applyMatrix4( matrixWorld );
if ( raycaster.ray.intersectsSphere( sphere ) === false ) return;
//
inverseMatrix.getInverse( matrixWorld );
ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );
var vStart = new Vector3();
var vEnd = new Vector3();
var interSegment = new Vector3();
var interRay = new Vector3();
var step = (this && this.isLineSegments) ? 2 : 1;
if ( geometry.isBufferGeometry ) {
var index = geometry.index;
var attributes = geometry.attributes;
var positions = attributes.position.array;
if ( index !== null ) {
var indices = index.array;
for ( var i = 0, l = indices.length - 1; i < l; i += step ) {
var a = indices[ i ];
var b = indices[ i + 1 ];
vStart.fromArray( positions, a * 3 );
vEnd.fromArray( positions, b * 3 );
var distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );
if ( distSq > precisionSq ) continue;
interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation
var distance = raycaster.ray.origin.distanceTo( interRay );
if ( distance < raycaster.near || distance > raycaster.far ) continue;
intersects.push( {
distance: distance,
// What do we want? intersection point on the ray or on the segment??
// point: raycaster.ray.at( distance ),
point: interSegment.clone().applyMatrix4( this.matrixWorld ),
index: i,
face: null,
faceIndex: null,
object: this
} );
}
} else {
for ( var i = 0, l = positions.length / 3 - 1; i < l; i += step ) {
vStart.fromArray( positions, 3 * i );
vEnd.fromArray( positions, 3 * i + 3 );
var distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );
if ( distSq > precisionSq ) continue;
interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation
var distance = raycaster.ray.origin.distanceTo( interRay );
if ( distance < raycaster.near || distance > raycaster.far ) continue;
intersects.push( {
distance: distance,
// What do we want? intersection point on the ray or on the segment??
// point: raycaster.ray.at( distance ),
point: interSegment.clone().applyMatrix4( this.matrixWorld ),
index: i,
face: null,
faceIndex: null,
object: this
} );
}
}
} else if ( geometry.isGeometry ) {
var vertices = geometry.vertices;
var nbVertices = vertices.length;
for ( var i = 0; i < nbVertices - 1; i += step ) {
var distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );
if ( distSq > precisionSq ) continue;
interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation
var distance = raycaster.ray.origin.distanceTo( interRay );
if ( distance < raycaster.near || distance > raycaster.far ) continue;
intersects.push( {
distance: distance,
// What do we want? intersection point on the ray or on the segment??
// point: raycaster.ray.at( distance ),
point: interSegment.clone().applyMatrix4( this.matrixWorld ),
index: i,
face: null,
faceIndex: null,
object: this
} );
}
}
};
}() ),
clone: function () {
return new this.constructor( this.geometry, this.material ).copy( this );
}
} );
/**
* @author mrdoob / http://mrdoob.com/
*/
function LineSegments( geometry, material ) {
Line.call( this, geometry, material );
this.type = 'LineSegments';
}
LineSegments.prototype = Object.assign( Object.create( Line.prototype ), {
constructor: LineSegments,
isLineSegments: true
} );
/**
* @author mgreter / http://github.com/mgreter
*/
function LineLoop( geometry, material ) {
Line.call( this, geometry, material );
this.type = 'LineLoop';
}
LineLoop.prototype = Object.assign( Object.create( Line.prototype ), {
constructor: LineLoop,
isLineLoop: true,
} );
/**
* @author mrdoob / http://mrdoob.com/
* @author alteredq / http://alteredqualia.com/
*
* parameters = {
* color: <hex>,
* opacity: <float>,
* map: new THREE.Texture( <Image> ),
*
* size: <float>,
* sizeAttenuation: <bool>
* }
*/
function PointsMaterial( parameters ) {
Material.call( this );
this.type = 'PointsMaterial';
this.color = new Color( 0xffffff );
this.map = null;
this.size = 1;
this.sizeAttenuation = true;
this.lights = false;
this.setValues( parameters );
}
PointsMaterial.prototype = Object.create( Material.prototype );
PointsMaterial.prototype.constructor = PointsMaterial;
PointsMaterial.prototype.isPointsMaterial = true;
PointsMaterial.prototype.copy = function ( source ) {
Material.prototype.copy.call( this, source );
this.color.copy( source.color );
this.map = source.map;
this.size = source.size;
this.sizeAttenuation = source.sizeAttenuation;
return this;
};
/**
* @author alteredq / http://alteredqualia.com/
*/
function Points( geometry, material ) {
Object3D.call( this );
this.type = 'Points';
this.geometry = geometry !== undefined ? geometry : new BufferGeometry();
this.material = material !== undefined ? material : new PointsMaterial( { color: Math.random() * 0xffffff } );
}
Points.prototype = Object.assign( Object.create( Object3D.prototype ), {
constructor: Points,
isPoints: true,
raycast: ( function () {
var inverseMatrix = new Matrix4();
var ray = new Ray();
var sphere = new Sphere();
return function raycast( raycaster, intersects ) {
var object = this;
var geometry = this.geometry;
var matrixWorld = this.matrixWorld;
var threshold = raycaster.params.Points.threshold;
// Checking boundingSphere distance to ray
if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
sphere.copy( geometry.boundingSphere );
sphere.applyMatrix4( matrixWorld );
sphere.radius += threshold;
if ( raycaster.ray.intersectsSphere( sphere ) === false ) return;
//
inverseMatrix.getInverse( matrixWorld );
ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );
var localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );
var localThresholdSq = localThreshold * localThreshold;
var position = new Vector3();
function testPoint( point, index ) {
var rayPointDistanceSq = ray.distanceSqToPoint( point );
if ( rayPointDistanceSq < localThresholdSq ) {
var intersectPoint = ray.closestPointToPoint( point );
intersectPoint.applyMatrix4( matrixWorld );
var distance = raycaster.ray.origin.distanceTo( intersectPoint );
if ( distance < raycaster.near || distance > raycaster.far ) return;
intersects.push( {
distance: distance,
distanceToRay: Math.sqrt( rayPointDistanceSq ),
point: intersectPoint.clone(),
index: index,
face: null,
object: object
} );
}
}
if ( geometry.isBufferGeometry ) {
var index = geometry.index;
var attributes = geometry.attributes;
var positions = attributes.position.array;
if ( index !== null ) {
var indices = index.array;
for ( var i = 0, il = indices.length; i < il; i ++ ) {
var a = indices[ i ];
position.fromArray( positions, a * 3 );
testPoint( position, a );
}
} else {
for ( var i = 0, l = positions.length / 3; i < l; i ++ ) {
position.fromArray( positions, i * 3 );
testPoint( position, i );
}
}
} else {
var vertices = geometry.vertices;
for ( var i = 0, l = vertices.length; i < l; i ++ ) {
testPoint( vertices[ i ], i );
}
}
};
}() ),
clone: function () {
return new this.constructor( this.geometry, this.material ).copy( this );
}
} );
/**
* @author mrdoob / http://mrdoob.com/
*/
function Group() {
Object3D.call( this );
this.type = 'Group';
}
Group.prototype = Object.assign( Object.create( Object3D.prototype ), {
constructor: Group
} );
/**
* @author mrdoob / http://mrdoob.com/
*/
function VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
Texture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
this.generateMipmaps = false;
var scope = this;
function update() {
requestAnimationFrame( update );
if ( video.readyState >= video.HAVE_CURRENT_DATA ) {
scope.needsUpdate = true;
}
}
update();
}
VideoTexture.prototype = Object.create( Texture.prototype );
VideoTexture.prototype.constructor = VideoTexture;
/**
* @author alteredq / http://alteredqualia.com/
*/
function CompressedTexture( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {
Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );
this.image = { width: width, height: height };
this.mipmaps = mipmaps;
// no flipping for cube textures
// (also flipping doesn't work for compressed textures )
this.flipY = false;
// can't generate mipmaps for compressed textures
// mips must be embedded in DDS files
this.generateMipmaps = false;
}
CompressedTexture.prototype = Object.create( Texture.prototype );
CompressedTexture.prototype.constructor = CompressedTexture;
CompressedTexture.prototype.isCompressedTexture = true;
/**
* @author mrdoob / http://mrdoob.com/
*/
function CanvasTexture( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
Texture.call( this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
this.needsUpdate = true;
}
CanvasTexture.prototype = Object.create( Texture.prototype );
CanvasTexture.prototype.constructor = CanvasTexture;
/**
* @author Matt DesLauriers / @mattdesl
* @author atix / arthursilber.de
*/
function DepthTexture( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) {
format = format !== undefined ? format : DepthFormat;
if ( format !== DepthFormat && format !== DepthStencilFormat ) {
throw new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' )
}
if ( type === undefined && format === DepthFormat ) type = UnsignedShortType;
if ( type === undefined && format === DepthStencilFormat ) type = UnsignedInt248Type;
Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
this.image = { width: width, height: height };
this.magFilter = magFilter !== undefined ? magFilter : NearestFilter;
this.minFilter = minFilter !== undefined ? minFilter : NearestFilter;
this.flipY = false;
this.generateMipmaps = false;
}
DepthTexture.prototype = Object.create( Texture.prototype );
DepthTexture.prototype.constructor = DepthTexture;
DepthTexture.prototype.isDepthTexture = true;
/**
* @author mrdoob / http://mrdoob.com/
* @author Mugen87 / https://github.com/Mugen87
*/
function WireframeGeometry( geometry ) {
BufferGeometry.call( this );
this.type = 'WireframeGeometry';
// buffer
var vertices = [];
// helper variables
var i, j, l, o, ol;
var edge = [ 0, 0 ], edges = {}, e, edge1, edge2;
var key, keys = [ 'a', 'b', 'c' ];
var vertex;
// different logic for Geometry and BufferGeometry
if ( geometry && geometry.isGeometry ) {
// create a data structure that contains all edges without duplicates
var faces = geometry.faces;
for ( i = 0, l = faces.length; i < l; i ++ ) {
var face = faces[ i ];
for ( j = 0; j < 3; j ++ ) {
edge1 = face[ keys[ j ] ];
edge2 = face[ keys[ ( j + 1 ) % 3 ] ];
edge[ 0 ] = Math.min( edge1, edge2 ); // sorting prevents duplicates
edge[ 1 ] = Math.max( edge1, edge2 );
key = edge[ 0 ] + ',' + edge[ 1 ];
if ( edges[ key ] === undefined ) {
edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };
}
}
}
// generate vertices
for ( key in edges ) {
e = edges[ key ];
vertex = geometry.vertices[ e.index1 ];
vertices.push( vertex.x, vertex.y, vertex.z );
vertex = geometry.vertices[ e.index2 ];
vertices.push( vertex.x, vertex.y, vertex.z );
}
} else if ( geometry && geometry.isBufferGeometry ) {
var position, indices, groups;
var group, start, count;
var index1, index2;
vertex = new Vector3();
if ( geometry.index !== null ) {
// indexed BufferGeometry
position = geometry.attributes.position;
indices = geometry.index;
groups = geometry.groups;
if ( groups.length === 0 ) {
groups = [ { start: 0, count: indices.count, materialIndex: 0 } ];
}
// create a data structure that contains all eges without duplicates
for ( o = 0, ol = groups.length; o < ol; ++ o ) {
group = groups[ o ];
start = group.start;
count = group.count;
for ( i = start, l = ( start + count ); i < l; i += 3 ) {
for ( j = 0; j < 3; j ++ ) {
edge1 = indices.getX( i + j );
edge2 = indices.getX( i + ( j + 1 ) % 3 );
edge[ 0 ] = Math.min( edge1, edge2 ); // sorting prevents duplicates
edge[ 1 ] = Math.max( edge1, edge2 );
key = edge[ 0 ] + ',' + edge[ 1 ];
if ( edges[ key ] === undefined ) {
edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };
}
}
}
}
// generate vertices
for ( key in edges ) {
e = edges[ key ];
vertex.fromBufferAttribute( position, e.index1 );
vertices.push( vertex.x, vertex.y, vertex.z );
vertex.fromBufferAttribute( position, e.index2 );
vertices.push( vertex.x, vertex.y, vertex.z );
}
} else {
// non-indexed BufferGeometry
position = geometry.attributes.position;
for ( i = 0, l = ( position.count / 3 ); i < l; i ++ ) {
for ( j = 0; j < 3; j ++ ) {
// three edges per triangle, an edge is represented as (index1, index2)
// e.g. the first triangle has the following edges: (0,1),(1,2),(2,0)
index1 = 3 * i + j;
vertex.fromBufferAttribute( position, index1 );
vertices.push( vertex.x, vertex.y, vertex.z );
index2 = 3 * i + ( ( j + 1 ) % 3 );
vertex.fromBufferAttribute( position, index2 );
vertices.push( vertex.x, vertex.y, vertex.z );
}
}
}
}
// build geometry
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
}
WireframeGeometry.prototype = Object.create( BufferGeometry.prototype );
WireframeGeometry.prototype.constructor = WireframeGeometry;
/**
* @author zz85 / https://github.com/zz85
* @author Mugen87 / https://github.com/Mugen87
*
* Parametric Surfaces Geometry
* based on the brilliant article by @prideout http://prideout.net/blog/?p=44
*/
// ParametricGeometry
function ParametricGeometry( func, slices, stacks ) {
Geometry.call( this );
this.type = 'ParametricGeometry';
this.parameters = {
func: func,
slices: slices,
stacks: stacks
};
this.fromBufferGeometry( new ParametricBufferGeometry( func, slices, stacks ) );
this.mergeVertices();
}
ParametricGeometry.prototype = Object.create( Geometry.prototype );
ParametricGeometry.prototype.constructor = ParametricGeometry;
// ParametricBufferGeometry
function ParametricBufferGeometry( func, slices, stacks ) {
BufferGeometry.call( this );
this.type = 'ParametricBufferGeometry';
this.parameters = {
func: func,
slices: slices,
stacks: stacks
};
// buffers
var indices = [];
var vertices = [];
var normals = [];
var uvs = [];
var EPS = 0.00001;
var normal = new Vector3();
var p0 = new Vector3(), p1 = new Vector3();
var pu = new Vector3(), pv = new Vector3();
var i, j;
// generate vertices, normals and uvs
var sliceCount = slices + 1;
for ( i = 0; i <= stacks; i ++ ) {
var v = i / stacks;
for ( j = 0; j <= slices; j ++ ) {
var u = j / slices;
// vertex
p0 = func( u, v, p0 );
vertices.push( p0.x, p0.y, p0.z );
// normal
// approximate tangent vectors via finite differences
if ( u - EPS >= 0 ) {
p1 = func( u - EPS, v, p1 );
pu.subVectors( p0, p1 );
} else {
p1 = func( u + EPS, v, p1 );
pu.subVectors( p1, p0 );
}
if ( v - EPS >= 0 ) {
p1 = func( u, v - EPS, p1 );
pv.subVectors( p0, p1 );
} else {
p1 = func( u, v + EPS, p1 );
pv.subVectors( p1, p0 );
}
// cross product of tangent vectors returns surface normal
normal.crossVectors( pu, pv ).normalize();
normals.push( normal.x, normal.y, normal.z );
// uv
uvs.push( u, v );
}
}
// generate indices
for ( i = 0; i < stacks; i ++ ) {
for ( j = 0; j < slices; j ++ ) {
var a = i * sliceCount + j;
var b = i * sliceCount + j + 1;
var c = ( i + 1 ) * sliceCount + j + 1;
var d = ( i + 1 ) * sliceCount + j;
// faces one and two
indices.push( a, b, d );
indices.push( b, c, d );
}
}
// build geometry
this.setIndex( indices );
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
}
ParametricBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
ParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry;
/**
* @author clockworkgeek / https://github.com/clockworkgeek
* @author timothypratley / https://github.com/timothypratley
* @author WestLangley / http://github.com/WestLangley
* @author Mugen87 / https://github.com/Mugen87
*/
// PolyhedronGeometry
function PolyhedronGeometry( vertices, indices, radius, detail ) {
Geometry.call( this );
this.type = 'PolyhedronGeometry';
this.parameters = {
vertices: vertices,
indices: indices,
radius: radius,
detail: detail
};
this.fromBufferGeometry( new PolyhedronBufferGeometry( vertices, indices, radius, detail ) );
this.mergeVertices();
}
PolyhedronGeometry.prototype = Object.create( Geometry.prototype );
PolyhedronGeometry.prototype.constructor = PolyhedronGeometry;
// PolyhedronBufferGeometry
function PolyhedronBufferGeometry( vertices, indices, radius, detail ) {
BufferGeometry.call( this );
this.type = 'PolyhedronBufferGeometry';
this.parameters = {
vertices: vertices,
indices: indices,
radius: radius,
detail: detail
};
radius = radius || 1;
detail = detail || 0;
// default buffer data
var vertexBuffer = [];
var uvBuffer = [];
// the subdivision creates the vertex buffer data
subdivide( detail );
// all vertices should lie on a conceptual sphere with a given radius
appplyRadius( radius );
// finally, create the uv data
generateUVs();
// build non-indexed geometry
this.addAttribute( 'position', new Float32BufferAttribute( vertexBuffer, 3 ) );
this.addAttribute( 'normal', new Float32BufferAttribute( vertexBuffer.slice(), 3 ) );
this.addAttribute( 'uv', new Float32BufferAttribute( uvBuffer, 2 ) );
if ( detail === 0 ) {
this.computeVertexNormals(); // flat normals
} else {
this.normalizeNormals(); // smooth normals
}
// helper functions
function subdivide( detail ) {
var a = new Vector3();
var b = new Vector3();
var c = new Vector3();
// iterate over all faces and apply a subdivison with the given detail value
for ( var i = 0; i < indices.length; i += 3 ) {
// get the vertices of the face
getVertexByIndex( indices[ i + 0 ], a );
getVertexByIndex( indices[ i + 1 ], b );
getVertexByIndex( indices[ i + 2 ], c );
// perform subdivision
subdivideFace( a, b, c, detail );
}
}
function subdivideFace( a, b, c, detail ) {
var cols = Math.pow( 2, detail );
// we use this multidimensional array as a data structure for creating the subdivision
var v = [];
var i, j;
// construct all of the vertices for this subdivision
for ( i = 0; i <= cols; i ++ ) {
v[ i ] = [];
var aj = a.clone().lerp( c, i / cols );
var bj = b.clone().lerp( c, i / cols );
var rows = cols - i;
for ( j = 0; j <= rows; j ++ ) {
if ( j === 0 && i === cols ) {
v[ i ][ j ] = aj;
} else {
v[ i ][ j ] = aj.clone().lerp( bj, j / rows );
}
}
}
// construct all of the faces
for ( i = 0; i < cols; i ++ ) {
for ( j = 0; j < 2 * ( cols - i ) - 1; j ++ ) {
var k = Math.floor( j / 2 );
if ( j % 2 === 0 ) {
pushVertex( v[ i ][ k + 1 ] );
pushVertex( v[ i + 1 ][ k ] );
pushVertex( v[ i ][ k ] );
} else {
pushVertex( v[ i ][ k + 1 ] );
pushVertex( v[ i + 1 ][ k + 1 ] );
pushVertex( v[ i + 1 ][ k ] );
}
}
}
}
function appplyRadius( radius ) {
var vertex = new Vector3();
// iterate over the entire buffer and apply the radius to each vertex
for ( var i = 0; i < vertexBuffer.length; i += 3 ) {
vertex.x = vertexBuffer[ i + 0 ];
vertex.y = vertexBuffer[ i + 1 ];
vertex.z = vertexBuffer[ i + 2 ];
vertex.normalize().multiplyScalar( radius );
vertexBuffer[ i + 0 ] = vertex.x;
vertexBuffer[ i + 1 ] = vertex.y;
vertexBuffer[ i + 2 ] = vertex.z;
}
}
function generateUVs() {
var vertex = new Vector3();
for ( var i = 0; i < vertexBuffer.length; i += 3 ) {
vertex.x = vertexBuffer[ i + 0 ];
vertex.y = vertexBuffer[ i + 1 ];
vertex.z = vertexBuffer[ i + 2 ];
var u = azimuth( vertex ) / 2 / Math.PI + 0.5;
var v = inclination( vertex ) / Math.PI + 0.5;
uvBuffer.push( u, 1 - v );
}
correctUVs();
correctSeam();
}
function correctSeam() {
// handle case when face straddles the seam, see #3269
for ( var i = 0; i < uvBuffer.length; i += 6 ) {
// uv data of a single face
var x0 = uvBuffer[ i + 0 ];
var x1 = uvBuffer[ i + 2 ];
var x2 = uvBuffer[ i + 4 ];
var max = Math.max( x0, x1, x2 );
var min = Math.min( x0, x1, x2 );
// 0.9 is somewhat arbitrary
if ( max > 0.9 && min < 0.1 ) {
if ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1;
if ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1;
if ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1;
}
}
}
function pushVertex( vertex ) {
vertexBuffer.push( vertex.x, vertex.y, vertex.z );
}
function getVertexByIndex( index, vertex ) {
var stride = index * 3;
vertex.x = vertices[ stride + 0 ];
vertex.y = vertices[ stride + 1 ];
vertex.z = vertices[ stride + 2 ];
}
function correctUVs() {
var a = new Vector3();
var b = new Vector3();
var c = new Vector3();
var centroid = new Vector3();
var uvA = new Vector2();
var uvB = new Vector2();
var uvC = new Vector2();
for ( var i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6 ) {
a.set( vertexBuffer[ i + 0 ], vertexBuffer[ i + 1 ], vertexBuffer[ i + 2 ] );
b.set( vertexBuffer[ i + 3 ], vertexBuffer[ i + 4 ], vertexBuffer[ i + 5 ] );
c.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] );
uvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] );
uvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] );
uvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] );
centroid.copy( a ).add( b ).add( c ).divideScalar( 3 );
var azi = azimuth( centroid );
correctUV( uvA, j + 0, a, azi );
correctUV( uvB, j + 2, b, azi );
correctUV( uvC, j + 4, c, azi );
}
}
function correctUV( uv, stride, vector, azimuth ) {
if ( ( azimuth < 0 ) && ( uv.x === 1 ) ) {
uvBuffer[ stride ] = uv.x - 1;
}
if ( ( vector.x === 0 ) && ( vector.z === 0 ) ) {
uvBuffer[ stride ] = azimuth / 2 / Math.PI + 0.5;
}
}
// Angle around the Y axis, counter-clockwise when looking from above.
function azimuth( vector ) {
return Math.atan2( vector.z, - vector.x );
}
// Angle above the XZ plane.
function inclination( vector ) {
return Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );
}
}
PolyhedronBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
PolyhedronBufferGeometry.prototype.constructor = PolyhedronBufferGeometry;
/**
* @author timothypratley / https://github.com/timothypratley
* @author Mugen87 / https://github.com/Mugen87
*/
// TetrahedronGeometry
function TetrahedronGeometry( radius, detail ) {
Geometry.call( this );
this.type = 'TetrahedronGeometry';
this.parameters = {
radius: radius,
detail: detail
};
this.fromBufferGeometry( new TetrahedronBufferGeometry( radius, detail ) );
this.mergeVertices();
}
TetrahedronGeometry.prototype = Object.create( Geometry.prototype );
TetrahedronGeometry.prototype.constructor = TetrahedronGeometry;
// TetrahedronBufferGeometry
function TetrahedronBufferGeometry( radius, detail ) {
var vertices = [
1, 1, 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, - 1
];
var indices = [
2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1
];
PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );
this.type = 'TetrahedronBufferGeometry';
this.parameters = {
radius: radius,
detail: detail
};
}
TetrahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );
TetrahedronBufferGeometry.prototype.constructor = TetrahedronBufferGeometry;
/**
* @author timothypratley / https://github.com/timothypratley
* @author Mugen87 / https://github.com/Mugen87
*/
// OctahedronGeometry
function OctahedronGeometry( radius, detail ) {
Geometry.call( this );
this.type = 'OctahedronGeometry';
this.parameters = {
radius: radius,
detail: detail
};
this.fromBufferGeometry( new OctahedronBufferGeometry( radius, detail ) );
this.mergeVertices();
}
OctahedronGeometry.prototype = Object.create( Geometry.prototype );
OctahedronGeometry.prototype.constructor = OctahedronGeometry;
// OctahedronBufferGeometry
function OctahedronBufferGeometry( radius, detail ) {
var vertices = [
1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1
];
var indices = [
0, 2, 4, 0, 4, 3, 0, 3, 5, 0, 5, 2, 1, 2, 5, 1, 5, 3, 1, 3, 4, 1, 4, 2
];
PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );
this.type = 'OctahedronBufferGeometry';
this.parameters = {
radius: radius,
detail: detail
};
}
OctahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );
OctahedronBufferGeometry.prototype.constructor = OctahedronBufferGeometry;
/**
* @author timothypratley / https://github.com/timothypratley
* @author Mugen87 / https://github.com/Mugen87
*/
// IcosahedronGeometry
function IcosahedronGeometry( radius, detail ) {
Geometry.call( this );
this.type = 'IcosahedronGeometry';
this.parameters = {
radius: radius,
detail: detail
};
this.fromBufferGeometry( new IcosahedronBufferGeometry( radius, detail ) );
this.mergeVertices();
}
IcosahedronGeometry.prototype = Object.create( Geometry.prototype );
IcosahedronGeometry.prototype.constructor = IcosahedronGeometry;
// IcosahedronBufferGeometry
function IcosahedronBufferGeometry( radius, detail ) {
var t = ( 1 + Math.sqrt( 5 ) ) / 2;
var vertices = [
- 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0,
0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t,
t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1
];
var indices = [
0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11,
1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8,
3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9,
4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1
];
PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );
this.type = 'IcosahedronBufferGeometry';
this.parameters = {
radius: radius,
detail: detail
};
}
IcosahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );
IcosahedronBufferGeometry.prototype.constructor = IcosahedronBufferGeometry;
/**
* @author Abe Pazos / https://hamoid.com
* @author Mugen87 / https://github.com/Mugen87
*/
// DodecahedronGeometry
function DodecahedronGeometry( radius, detail ) {
Geometry.call( this );
this.type = 'DodecahedronGeometry';
this.parameters = {
radius: radius,
detail: detail
};
this.fromBufferGeometry( new DodecahedronBufferGeometry( radius, detail ) );
this.mergeVertices();
}
DodecahedronGeometry.prototype = Object.create( Geometry.prototype );
DodecahedronGeometry.prototype.constructor = DodecahedronGeometry;
// DodecahedronBufferGeometry
function DodecahedronBufferGeometry( radius, detail ) {
var t = ( 1 + Math.sqrt( 5 ) ) / 2;
var r = 1 / t;
var 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,
// (0, ±1/φ, ±φ)
0, - r, - t, 0, - r, t,
0, r, - t, 0, r, t,
// (±1/φ, ±φ, 0)
- r, - t, 0, - r, t, 0,
r, - t, 0, r, t, 0,
// (±φ, 0, ±1/φ)
- t, 0, - r, t, 0, - r,
- t, 0, r, t, 0, r
];
var indices = [
3, 11, 7, 3, 7, 15, 3, 15, 13,
7, 19, 17, 7, 17, 6, 7, 6, 15,
17, 4, 8, 17, 8, 10, 17, 10, 6,
8, 0, 16, 8, 16, 2, 8, 2, 10,
0, 12, 1, 0, 1, 18, 0, 18, 16,
6, 10, 2, 6, 2, 13, 6, 13, 15,
2, 16, 18, 2, 18, 3, 2, 3, 13,
18, 1, 9, 18, 9, 11, 18, 11, 3,
4, 14, 12, 4, 12, 0, 4, 0, 8,
11, 9, 5, 11, 5, 19, 11, 19, 7,
19, 5, 14, 19, 14, 4, 19, 4, 17,
1, 12, 14, 1, 14, 5, 1, 5, 9
];
PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );
this.type = 'DodecahedronBufferGeometry';
this.parameters = {
radius: radius,
detail: detail
};
}
DodecahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );
DodecahedronBufferGeometry.prototype.constructor = DodecahedronBufferGeometry;
/**
* @author oosmoxiecode / https://github.com/oosmoxiecode
* @author WestLangley / https://github.com/WestLangley
* @author zz85 / https://github.com/zz85
* @author miningold / https://github.com/miningold
* @author jonobr1 / https://github.com/jonobr1
* @author Mugen87 / https://github.com/Mugen87
*
*/
// TubeGeometry
function TubeGeometry( path, tubularSegments, radius, radialSegments, closed, taper ) {
Geometry.call( this );
this.type = 'TubeGeometry';
this.parameters = {
path: path,
tubularSegments: tubularSegments,
radius: radius,
radialSegments: radialSegments,
closed: closed
};
if ( taper !== undefined ) console.warn( 'THREE.TubeGeometry: taper has been removed.' );
var bufferGeometry = new TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed );
// expose internals
this.tangents = bufferGeometry.tangents;
this.normals = bufferGeometry.normals;
this.binormals = bufferGeometry.binormals;
// create geometry
this.fromBufferGeometry( bufferGeometry );
this.mergeVertices();
}
TubeGeometry.prototype = Object.create( Geometry.prototype );
TubeGeometry.prototype.constructor = TubeGeometry;
// TubeBufferGeometry
function TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ) {
BufferGeometry.call( this );
this.type = 'TubeBufferGeometry';
this.parameters = {
path: path,
tubularSegments: tubularSegments,
radius: radius,
radialSegments: radialSegments,
closed: closed
};
tubularSegments = tubularSegments || 64;
radius = radius || 1;
radialSegments = radialSegments || 8;
closed = closed || false;
var frames = path.computeFrenetFrames( tubularSegments, closed );
// expose internals
this.tangents = frames.tangents;
this.normals = frames.normals;
this.binormals = frames.binormals;
// helper variables
var vertex = new Vector3();
var normal = new Vector3();
var uv = new Vector2();
var i, j;
// buffer
var vertices = [];
var normals = [];
var uvs = [];
var indices = [];
// create buffer data
generateBufferData();
// build geometry
this.setIndex( indices );
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
// functions
function generateBufferData() {
for ( i = 0; i < tubularSegments; i ++ ) {
generateSegment( i );
}
// if the geometry is not closed, generate the last row of vertices and normals
// at the regular position on the given path
//
// if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ)
generateSegment( ( closed === false ) ? tubularSegments : 0 );
// uvs are generated in a separate function.
// this makes it easy compute correct values for closed geometries
generateUVs();
// finally create faces
generateIndices();
}
function generateSegment( i ) {
// we use getPointAt to sample evenly distributed points from the given path
var P = path.getPointAt( i / tubularSegments );
// retrieve corresponding normal and binormal
var N = frames.normals[ i ];
var B = frames.binormals[ i ];
// generate normals and vertices for the current segment
for ( j = 0; j <= radialSegments; j ++ ) {
var v = j / radialSegments * Math.PI * 2;
var sin = Math.sin( v );
var cos = - Math.cos( v );
// normal
normal.x = ( cos * N.x + sin * B.x );
normal.y = ( cos * N.y + sin * B.y );
normal.z = ( cos * N.z + sin * B.z );
normal.normalize();
normals.push( normal.x, normal.y, normal.z );
// vertex
vertex.x = P.x + radius * normal.x;
vertex.y = P.y + radius * normal.y;
vertex.z = P.z + radius * normal.z;
vertices.push( vertex.x, vertex.y, vertex.z );
}
}
function generateIndices() {
for ( j = 1; j <= tubularSegments; j ++ ) {
for ( i = 1; i <= radialSegments; i ++ ) {
var a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );
var b = ( radialSegments + 1 ) * j + ( i - 1 );
var c = ( radialSegments + 1 ) * j + i;
var d = ( radialSegments + 1 ) * ( j - 1 ) + i;
// faces
indices.push( a, b, d );
indices.push( b, c, d );
}
}
}
function generateUVs() {
for ( i = 0; i <= tubularSegments; i ++ ) {
for ( j = 0; j <= radialSegments; j ++ ) {
uv.x = i / tubularSegments;
uv.y = j / radialSegments;
uvs.push( uv.x, uv.y );
}
}
}
}
TubeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
TubeBufferGeometry.prototype.constructor = TubeBufferGeometry;
/**
* @author oosmoxiecode
* @author Mugen87 / https://github.com/Mugen87
*
* based on http://www.blackpawn.com/texts/pqtorus/
*/
// TorusKnotGeometry
function TorusKnotGeometry( radius, tube, tubularSegments, radialSegments, p, q, heightScale ) {
Geometry.call( this );
this.type = 'TorusKnotGeometry';
this.parameters = {
radius: radius,
tube: tube,
tubularSegments: tubularSegments,
radialSegments: radialSegments,
p: p,
q: q
};
if ( heightScale !== undefined ) console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' );
this.fromBufferGeometry( new TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) );
this.mergeVertices();
}
TorusKnotGeometry.prototype = Object.create( Geometry.prototype );
TorusKnotGeometry.prototype.constructor = TorusKnotGeometry;
// TorusKnotBufferGeometry
function TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) {
BufferGeometry.call( this );
this.type = 'TorusKnotBufferGeometry';
this.parameters = {
radius: radius,
tube: tube,
tubularSegments: tubularSegments,
radialSegments: radialSegments,
p: p,
q: q
};
radius = radius || 100;
tube = tube || 40;
tubularSegments = Math.floor( tubularSegments ) || 64;
radialSegments = Math.floor( radialSegments ) || 8;
p = p || 2;
q = q || 3;
// buffers
var indices = [];
var vertices = [];
var normals = [];
var uvs = [];
// helper variables
var i, j;
var vertex = new Vector3();
var normal = new Vector3();
var P1 = new Vector3();
var P2 = new Vector3();
var B = new Vector3();
var T = new Vector3();
var N = new Vector3();
// generate vertices, normals and uvs
for ( i = 0; i <= tubularSegments; ++ i ) {
// the radian "u" is used to calculate the position on the torus curve of the current tubular segement
var u = i / tubularSegments * p * Math.PI * 2;
// now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead.
// these points are used to create a special "coordinate space", which is necessary to calculate the correct vertex positions
calculatePositionOnCurve( u, p, q, radius, P1 );
calculatePositionOnCurve( u + 0.01, p, q, radius, P2 );
// calculate orthonormal basis
T.subVectors( P2, P1 );
N.addVectors( P2, P1 );
B.crossVectors( T, N );
N.crossVectors( B, T );
// normalize B, N. T can be ignored, we don't use it
B.normalize();
N.normalize();
for ( j = 0; j <= radialSegments; ++ j ) {
// now calculate the vertices. they are nothing more than an extrusion of the torus curve.
// because we extrude a shape in the xy-plane, there is no need to calculate a z-value.
var v = j / radialSegments * Math.PI * 2;
var cx = - tube * Math.cos( v );
var cy = tube * Math.sin( v );
// now calculate the final vertex position.
// first we orient the extrusion with our basis vectos, then we add it to the current position on the curve
vertex.x = P1.x + ( cx * N.x + cy * B.x );
vertex.y = P1.y + ( cx * N.y + cy * B.y );
vertex.z = P1.z + ( cx * N.z + cy * B.z );
vertices.push( vertex.x, vertex.y, vertex.z );
// normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal)
normal.subVectors( vertex, P1 ).normalize();
normals.push( normal.x, normal.y, normal.z );
// uv
uvs.push( i / tubularSegments );
uvs.push( j / radialSegments );
}
}
// generate indices
for ( j = 1; j <= tubularSegments; j ++ ) {
for ( i = 1; i <= radialSegments; i ++ ) {
// indices
var a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );
var b = ( radialSegments + 1 ) * j + ( i - 1 );
var c = ( radialSegments + 1 ) * j + i;
var d = ( radialSegments + 1 ) * ( j - 1 ) + i;
// faces
indices.push( a, b, d );
indices.push( b, c, d );
}
}
// build geometry
this.setIndex( indices );
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
// this function calculates the current position on the torus curve
function calculatePositionOnCurve( u, p, q, radius, position ) {
var cu = Math.cos( u );
var su = Math.sin( u );
var quOverP = q / p * u;
var cs = Math.cos( quOverP );
position.x = radius * ( 2 + cs ) * 0.5 * cu;
position.y = radius * ( 2 + cs ) * su * 0.5;
position.z = radius * Math.sin( quOverP ) * 0.5;
}
}
TorusKnotBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
TorusKnotBufferGeometry.prototype.constructor = TorusKnotBufferGeometry;
/**
* @author oosmoxiecode
* @author mrdoob / http://mrdoob.com/
* @author Mugen87 / https://github.com/Mugen87
*/
// TorusGeometry
function TorusGeometry( radius, tube, radialSegments, tubularSegments, arc ) {
Geometry.call( this );
this.type = 'TorusGeometry';
this.parameters = {
radius: radius,
tube: tube,
radialSegments: radialSegments,
tubularSegments: tubularSegments,
arc: arc
};
this.fromBufferGeometry( new TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) );
this.mergeVertices();
}
TorusGeometry.prototype = Object.create( Geometry.prototype );
TorusGeometry.prototype.constructor = TorusGeometry;
// TorusBufferGeometry
function TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) {
BufferGeometry.call( this );
this.type = 'TorusBufferGeometry';
this.parameters = {
radius: radius,
tube: tube,
radialSegments: radialSegments,
tubularSegments: tubularSegments,
arc: arc
};
radius = radius || 100;
tube = tube || 40;
radialSegments = Math.floor( radialSegments ) || 8;
tubularSegments = Math.floor( tubularSegments ) || 6;
arc = arc || Math.PI * 2;
// buffers
var indices = [];
var vertices = [];
var normals = [];
var uvs = [];
// helper variables
var center = new Vector3();
var vertex = new Vector3();
var normal = new Vector3();
var j, i;
// generate vertices, normals and uvs
for ( j = 0; j <= radialSegments; j ++ ) {
for ( i = 0; i <= tubularSegments; i ++ ) {
var u = i / tubularSegments * arc;
var v = j / radialSegments * Math.PI * 2;
// vertex
vertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u );
vertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u );
vertex.z = tube * Math.sin( v );
vertices.push( vertex.x, vertex.y, vertex.z );
// normal
center.x = radius * Math.cos( u );
center.y = radius * Math.sin( u );
normal.subVectors( vertex, center ).normalize();
normals.push( normal.x, normal.y, normal.z );
// uv
uvs.push( i / tubularSegments );
uvs.push( j / radialSegments );
}
}
// generate indices
for ( j = 1; j <= radialSegments; j ++ ) {
for ( i = 1; i <= tubularSegments; i ++ ) {
// indices
var a = ( tubularSegments + 1 ) * j + i - 1;
var b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1;
var c = ( tubularSegments + 1 ) * ( j - 1 ) + i;
var d = ( tubularSegments + 1 ) * j + i;
// faces
indices.push( a, b, d );
indices.push( b, c, d );
}
}
// build geometry
this.setIndex( indices );
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
}
TorusBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
TorusBufferGeometry.prototype.constructor = TorusBufferGeometry;
/**
* @author zz85 / http://www.lab4games.net/zz85/blog
*/
var ShapeUtils = {
// calculate area of the contour polygon
area: function ( contour ) {
var n = contour.length;
var a = 0.0;
for ( var p = n - 1, q = 0; q < n; p = q ++ ) {
a += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;
}
return a * 0.5;
},
triangulate: ( function () {
/**
* This code is a quick port of code written in C++ which was submitted to
* flipcode.com by John W. Ratcliff // July 22, 2000
* See original code and more information here:
* http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml
*
* ported to actionscript by Zevan Rosser
* www.actionsnippet.com
*
* ported to javascript by Joshua Koo
* http://www.lab4games.net/zz85/blog
*
*/
function snip( contour, u, v, w, n, verts ) {
var p;
var ax, ay, bx, by;
var cx, cy, px, py;
ax = contour[ verts[ u ] ].x;
ay = contour[ verts[ u ] ].y;
bx = contour[ verts[ v ] ].x;
by = contour[ verts[ v ] ].y;
cx = contour[ verts[ w ] ].x;
cy = contour[ verts[ w ] ].y;
if ( ( bx - ax ) * ( cy - ay ) - ( by - ay ) * ( cx - ax ) <= 0 ) return false;
var aX, aY, bX, bY, cX, cY;
var apx, apy, bpx, bpy, cpx, cpy;
var cCROSSap, bCROSScp, aCROSSbp;
aX = cx - bx; aY = cy - by;
bX = ax - cx; bY = ay - cy;
cX = bx - ax; cY = by - ay;
for ( p = 0; p < n; p ++ ) {
px = contour[ verts[ p ] ].x;
py = contour[ verts[ p ] ].y;
if ( ( ( px === ax ) && ( py === ay ) ) ||
( ( px === bx ) && ( py === by ) ) ||
( ( px === cx ) && ( py === cy ) ) ) continue;
apx = px - ax; apy = py - ay;
bpx = px - bx; bpy = py - by;
cpx = px - cx; cpy = py - cy;
// see if p is inside triangle abc
aCROSSbp = aX * bpy - aY * bpx;
cCROSSap = cX * apy - cY * apx;
bCROSScp = bX * cpy - bY * cpx;
if ( ( aCROSSbp >= - Number.EPSILON ) && ( bCROSScp >= - Number.EPSILON ) && ( cCROSSap >= - Number.EPSILON ) ) return false;
}
return true;
}
// takes in an contour array and returns
return function triangulate( contour, indices ) {
var n = contour.length;
if ( n < 3 ) return null;
var result = [],
verts = [],
vertIndices = [];
/* we want a counter-clockwise polygon in verts */
var u, v, w;
if ( ShapeUtils.area( contour ) > 0.0 ) {
for ( v = 0; v < n; v ++ ) verts[ v ] = v;
} else {
for ( v = 0; v < n; v ++ ) verts[ v ] = ( n - 1 ) - v;
}
var nv = n;
/* remove nv - 2 vertices, creating 1 triangle every time */
var count = 2 * nv; /* error detection */
for ( v = nv - 1; nv > 2; ) {
/* if we loop, it is probably a non-simple polygon */
if ( ( count -- ) <= 0 ) {
//** Triangulate: ERROR - probable bad polygon!
//throw ( "Warning, unable to triangulate polygon!" );
//return null;
// Sometimes warning is fine, especially polygons are triangulated in reverse.
console.warn( 'THREE.ShapeUtils: Unable to triangulate polygon! in triangulate()' );
if ( indices ) return vertIndices;
return result;
}
/* three consecutive vertices in current polygon, <u,v,w> */
u = v; if ( nv <= u ) u = 0; /* previous */
v = u + 1; if ( nv <= v ) v = 0; /* new v */
w = v + 1; if ( nv <= w ) w = 0; /* next */
if ( snip( contour, u, v, w, nv, verts ) ) {
var a, b, c, s, t;
/* true names of the vertices */
a = verts[ u ];
b = verts[ v ];
c = verts[ w ];
/* output Triangle */
result.push( [ contour[ a ],
contour[ b ],
contour[ c ] ] );
vertIndices.push( [ verts[ u ], verts[ v ], verts[ w ] ] );
/* remove v from the remaining polygon */
for ( s = v, t = v + 1; t < nv; s ++, t ++ ) {
verts[ s ] = verts[ t ];
}
nv --;
/* reset error detection counter */
count = 2 * nv;
}
}
if ( indices ) return vertIndices;
return result;
}
} )(),
triangulateShape: function ( contour, holes ) {
function removeDupEndPts(points) {
var l = points.length;
if ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) {
points.pop();
}
}
removeDupEndPts( contour );
holes.forEach( removeDupEndPts );
function point_in_segment_2D_colin( inSegPt1, inSegPt2, inOtherPt ) {
// inOtherPt needs to be collinear to the inSegment
if ( inSegPt1.x !== inSegPt2.x ) {
if ( inSegPt1.x < inSegPt2.x ) {
return ( ( inSegPt1.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt2.x ) );
} else {
return ( ( inSegPt2.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt1.x ) );
}
} else {
if ( inSegPt1.y < inSegPt2.y ) {
return ( ( inSegPt1.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt2.y ) );
} else {
return ( ( inSegPt2.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt1.y ) );
}
}
}
function intersect_segments_2D( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1, inSeg2Pt2, inExcludeAdjacentSegs ) {
var seg1dx = inSeg1Pt2.x - inSeg1Pt1.x, seg1dy = inSeg1Pt2.y - inSeg1Pt1.y;
var seg2dx = inSeg2Pt2.x - inSeg2Pt1.x, seg2dy = inSeg2Pt2.y - inSeg2Pt1.y;
var seg1seg2dx = inSeg1Pt1.x - inSeg2Pt1.x;
var seg1seg2dy = inSeg1Pt1.y - inSeg2Pt1.y;
var limit = seg1dy * seg2dx - seg1dx * seg2dy;
var perpSeg1 = seg1dy * seg1seg2dx - seg1dx * seg1seg2dy;
if ( Math.abs( limit ) > Number.EPSILON ) {
// not parallel
var perpSeg2;
if ( limit > 0 ) {
if ( ( perpSeg1 < 0 ) || ( perpSeg1 > limit ) ) return [];
perpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;
if ( ( perpSeg2 < 0 ) || ( perpSeg2 > limit ) ) return [];
} else {
if ( ( perpSeg1 > 0 ) || ( perpSeg1 < limit ) ) return [];
perpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;
if ( ( perpSeg2 > 0 ) || ( perpSeg2 < limit ) ) return [];
}
// i.e. to reduce rounding errors
// intersection at endpoint of segment#1?
if ( perpSeg2 === 0 ) {
if ( ( inExcludeAdjacentSegs ) &&
( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) ) return [];
return [ inSeg1Pt1 ];
}
if ( perpSeg2 === limit ) {
if ( ( inExcludeAdjacentSegs ) &&
( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) ) return [];
return [ inSeg1Pt2 ];
}
// intersection at endpoint of segment#2?
if ( perpSeg1 === 0 ) return [ inSeg2Pt1 ];
if ( perpSeg1 === limit ) return [ inSeg2Pt2 ];
// return real intersection point
var factorSeg1 = perpSeg2 / limit;
return [ { x: inSeg1Pt1.x + factorSeg1 * seg1dx,
y: inSeg1Pt1.y + factorSeg1 * seg1dy } ];
} else {
// parallel or collinear
if ( ( perpSeg1 !== 0 ) ||
( seg2dy * seg1seg2dx !== seg2dx * seg1seg2dy ) ) return [];
// they are collinear or degenerate
var seg1Pt = ( ( seg1dx === 0 ) && ( seg1dy === 0 ) ); // segment1 is just a point?
var seg2Pt = ( ( seg2dx === 0 ) && ( seg2dy === 0 ) ); // segment2 is just a point?
// both segments are points
if ( seg1Pt && seg2Pt ) {
if ( ( inSeg1Pt1.x !== inSeg2Pt1.x ) ||
( inSeg1Pt1.y !== inSeg2Pt1.y ) ) return []; // they are distinct points
return [ inSeg1Pt1 ]; // they are the same point
}
// segment#1 is a single point
if ( seg1Pt ) {
if ( ! point_in_segment_2D_colin( inSeg2Pt1, inSeg2Pt2, inSeg1Pt1 ) ) return []; // but not in segment#2
return [ inSeg1Pt1 ];
}
// segment#2 is a single point
if ( seg2Pt ) {
if ( ! point_in_segment_2D_colin( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1 ) ) return []; // but not in segment#1
return [ inSeg2Pt1 ];
}
// they are collinear segments, which might overlap
var seg1min, seg1max, seg1minVal, seg1maxVal;
var seg2min, seg2max, seg2minVal, seg2maxVal;
if ( seg1dx !== 0 ) {
// the segments are NOT on a vertical line
if ( inSeg1Pt1.x < inSeg1Pt2.x ) {
seg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.x;
seg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.x;
} else {
seg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.x;
seg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.x;
}
if ( inSeg2Pt1.x < inSeg2Pt2.x ) {
seg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.x;
seg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.x;
} else {
seg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.x;
seg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.x;
}
} else {
// the segments are on a vertical line
if ( inSeg1Pt1.y < inSeg1Pt2.y ) {
seg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.y;
seg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.y;
} else {
seg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.y;
seg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.y;
}
if ( inSeg2Pt1.y < inSeg2Pt2.y ) {
seg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.y;
seg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.y;
} else {
seg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.y;
seg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.y;
}
}
if ( seg1minVal <= seg2minVal ) {
if ( seg1maxVal < seg2minVal ) return [];
if ( seg1maxVal === seg2minVal ) {
if ( inExcludeAdjacentSegs ) return [];
return [ seg2min ];
}
if ( seg1maxVal <= seg2maxVal ) return [ seg2min, seg1max ];
return [ seg2min, seg2max ];
} else {
if ( seg1minVal > seg2maxVal ) return [];
if ( seg1minVal === seg2maxVal ) {
if ( inExcludeAdjacentSegs ) return [];
return [ seg1min ];
}
if ( seg1maxVal <= seg2maxVal ) return [ seg1min, seg1max ];
return [ seg1min, seg2max ];
}
}
}
function isPointInsideAngle( inVertex, inLegFromPt, inLegToPt, inOtherPt ) {
// The order of legs is important
// translation of all points, so that Vertex is at (0,0)
var legFromPtX = inLegFromPt.x - inVertex.x, legFromPtY = inLegFromPt.y - inVertex.y;
var legToPtX = inLegToPt.x - inVertex.x, legToPtY = inLegToPt.y - inVertex.y;
var otherPtX = inOtherPt.x - inVertex.x, otherPtY = inOtherPt.y - inVertex.y;
// main angle >0: < 180 deg.; 0: 180 deg.; <0: > 180 deg.
var from2toAngle = legFromPtX * legToPtY - legFromPtY * legToPtX;
var from2otherAngle = legFromPtX * otherPtY - legFromPtY * otherPtX;
if ( Math.abs( from2toAngle ) > Number.EPSILON ) {
// angle != 180 deg.
var other2toAngle = otherPtX * legToPtY - otherPtY * legToPtX;
// console.log( "from2to: " + from2toAngle + ", from2other: " + from2otherAngle + ", other2to: " + other2toAngle );
if ( from2toAngle > 0 ) {
// main angle < 180 deg.
return ( ( from2otherAngle >= 0 ) && ( other2toAngle >= 0 ) );
} else {
// main angle > 180 deg.
return ( ( from2otherAngle >= 0 ) || ( other2toAngle >= 0 ) );
}
} else {
// angle == 180 deg.
// console.log( "from2to: 180 deg., from2other: " + from2otherAngle );
return ( from2otherAngle > 0 );
}
}
function removeHoles( contour, holes ) {
var shape = contour.concat(); // work on this shape
var hole;
function isCutLineInsideAngles( inShapeIdx, inHoleIdx ) {
// Check if hole point lies within angle around shape point
var lastShapeIdx = shape.length - 1;
var prevShapeIdx = inShapeIdx - 1;
if ( prevShapeIdx < 0 ) prevShapeIdx = lastShapeIdx;
var nextShapeIdx = inShapeIdx + 1;
if ( nextShapeIdx > lastShapeIdx ) nextShapeIdx = 0;
var insideAngle = isPointInsideAngle( shape[ inShapeIdx ], shape[ prevShapeIdx ], shape[ nextShapeIdx ], hole[ inHoleIdx ] );
if ( ! insideAngle ) {
// console.log( "Vertex (Shape): " + inShapeIdx + ", Point: " + hole[inHoleIdx].x + "/" + hole[inHoleIdx].y );
return false;
}
// Check if shape point lies within angle around hole point
var lastHoleIdx = hole.length - 1;
var prevHoleIdx = inHoleIdx - 1;
if ( prevHoleIdx < 0 ) prevHoleIdx = lastHoleIdx;
var nextHoleIdx = inHoleIdx + 1;
if ( nextHoleIdx > lastHoleIdx ) nextHoleIdx = 0;
insideAngle = isPointInsideAngle( hole[ inHoleIdx ], hole[ prevHoleIdx ], hole[ nextHoleIdx ], shape[ inShapeIdx ] );
if ( ! insideAngle ) {
// console.log( "Vertex (Hole): " + inHoleIdx + ", Point: " + shape[inShapeIdx].x + "/" + shape[inShapeIdx].y );
return false;
}
return true;
}
function intersectsShapeEdge( inShapePt, inHolePt ) {
// checks for intersections with shape edges
var sIdx, nextIdx, intersection;
for ( sIdx = 0; sIdx < shape.length; sIdx ++ ) {
nextIdx = sIdx + 1; nextIdx %= shape.length;
intersection = intersect_segments_2D( inShapePt, inHolePt, shape[ sIdx ], shape[ nextIdx ], true );
if ( intersection.length > 0 ) return true;
}
return false;
}
var indepHoles = [];
function intersectsHoleEdge( inShapePt, inHolePt ) {
// checks for intersections with hole edges
var ihIdx, chkHole,
hIdx, nextIdx, intersection;
for ( ihIdx = 0; ihIdx < indepHoles.length; ihIdx ++ ) {
chkHole = holes[ indepHoles[ ihIdx ]];
for ( hIdx = 0; hIdx < chkHole.length; hIdx ++ ) {
nextIdx = hIdx + 1; nextIdx %= chkHole.length;
intersection = intersect_segments_2D( inShapePt, inHolePt, chkHole[ hIdx ], chkHole[ nextIdx ], true );
if ( intersection.length > 0 ) return true;
}
}
return false;
}
var holeIndex, shapeIndex,
shapePt, holePt,
holeIdx, cutKey, failedCuts = [],
tmpShape1, tmpShape2,
tmpHole1, tmpHole2;
for ( var h = 0, hl = holes.length; h < hl; h ++ ) {
indepHoles.push( h );
}
var minShapeIndex = 0;
var counter = indepHoles.length * 2;
while ( indepHoles.length > 0 ) {
counter --;
if ( counter < 0 ) {
console.log( "Infinite Loop! Holes left:" + indepHoles.length + ", Probably Hole outside Shape!" );
break;
}
// search for shape-vertex and hole-vertex,
// which can be connected without intersections
for ( shapeIndex = minShapeIndex; shapeIndex < shape.length; shapeIndex ++ ) {
shapePt = shape[ shapeIndex ];
holeIndex = - 1;
// search for hole which can be reached without intersections
for ( var h = 0; h < indepHoles.length; h ++ ) {
holeIdx = indepHoles[ h ];
// prevent multiple checks
cutKey = shapePt.x + ":" + shapePt.y + ":" + holeIdx;
if ( failedCuts[ cutKey ] !== undefined ) continue;
hole = holes[ holeIdx ];
for ( var h2 = 0; h2 < hole.length; h2 ++ ) {
holePt = hole[ h2 ];
if ( ! isCutLineInsideAngles( shapeIndex, h2 ) ) continue;
if ( intersectsShapeEdge( shapePt, holePt ) ) continue;
if ( intersectsHoleEdge( shapePt, holePt ) ) continue;
holeIndex = h2;
indepHoles.splice( h, 1 );
tmpShape1 = shape.slice( 0, shapeIndex + 1 );
tmpShape2 = shape.slice( shapeIndex );
tmpHole1 = hole.slice( holeIndex );
tmpHole2 = hole.slice( 0, holeIndex + 1 );
shape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 );
minShapeIndex = shapeIndex;
// Debug only, to show the selected cuts
// glob_CutLines.push( [ shapePt, holePt ] );
break;
}
if ( holeIndex >= 0 ) break; // hole-vertex found
failedCuts[ cutKey ] = true; // remember failure
}
if ( holeIndex >= 0 ) break; // hole-vertex found
}
}
return shape; /* shape with no holes */
}
var i, il, f, face,
key, index,
allPointsMap = {};
// To maintain reference to old shape, one must match coordinates, or offset the indices from original arrays. It's probably easier to do the first.
var allpoints = contour.concat();
for ( var h = 0, hl = holes.length; h < hl; h ++ ) {
Array.prototype.push.apply( allpoints, holes[ h ] );
}
//console.log( "allpoints",allpoints, allpoints.length );
// prepare all points map
for ( i = 0, il = allpoints.length; i < il; i ++ ) {
key = allpoints[ i ].x + ":" + allpoints[ i ].y;
if ( allPointsMap[ key ] !== undefined ) {
console.warn( "THREE.ShapeUtils: Duplicate point", key, i );
}
allPointsMap[ key ] = i;
}
// remove holes by cutting paths to holes and adding them to the shape
var shapeWithoutHoles = removeHoles( contour, holes );
var triangles = ShapeUtils.triangulate( shapeWithoutHoles, false ); // True returns indices for points of spooled shape
//console.log( "triangles",triangles, triangles.length );
// check all face vertices against all points map
for ( i = 0, il = triangles.length; i < il; i ++ ) {
face = triangles[ i ];
for ( f = 0; f < 3; f ++ ) {
key = face[ f ].x + ":" + face[ f ].y;
index = allPointsMap[ key ];
if ( index !== undefined ) {
face[ f ] = index;
}
}
}
return triangles.concat();
},
isClockWise: function ( pts ) {
return ShapeUtils.area( pts ) < 0;
}
};
/**
* @author zz85 / http://www.lab4games.net/zz85/blog
*
* Creates extruded geometry from a path shape.
*
* parameters = {
*
* curveSegments: <int>, // number of points on the curves
* steps: <int>, // number of points for z-side extrusions / used for subdividing segments of extrude spline too
* amount: <int>, // Depth to extrude the shape
*
* bevelEnabled: <bool>, // turn on bevel
* bevelThickness: <float>, // how deep into the original shape bevel goes
* bevelSize: <float>, // how far from shape outline is bevel
* bevelSegments: <int>, // number of bevel layers
*
* extrudePath: <THREE.Curve> // curve to extrude shape along
* frames: <Object> // containing arrays of tangents, normals, binormals
*
* UVGenerator: <Object> // object that provides UV generator functions
*
* }
*/
// ExtrudeGeometry
function ExtrudeGeometry( shapes, options ) {
Geometry.call( this );
this.type = 'ExtrudeGeometry';
this.parameters = {
shapes: shapes,
options: options
};
this.fromBufferGeometry( new ExtrudeBufferGeometry( shapes, options ) );
this.mergeVertices();
}
ExtrudeGeometry.prototype = Object.create( Geometry.prototype );
ExtrudeGeometry.prototype.constructor = ExtrudeGeometry;
// ExtrudeBufferGeometry
function ExtrudeBufferGeometry( shapes, options ) {
if ( typeof ( shapes ) === "undefined" ) {
return;
}
BufferGeometry.call( this );
this.type = 'ExtrudeBufferGeometry';
shapes = Array.isArray( shapes ) ? shapes : [ shapes ];
this.addShapeList( shapes, options );
this.computeVertexNormals();
// can't really use automatic vertex normals
// as then front and back sides get smoothed too
// should do separate smoothing just for sides
//this.computeVertexNormals();
//console.log( "took", ( Date.now() - startTime ) );
}
ExtrudeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
ExtrudeBufferGeometry.prototype.constructor = ExtrudeBufferGeometry;
ExtrudeBufferGeometry.prototype.getArrays = function () {
var positionAttribute = this.getAttribute( "position" );
var verticesArray = positionAttribute ? Array.prototype.slice.call( positionAttribute.array ) : [];
var uvAttribute = this.getAttribute( "uv" );
var uvArray = uvAttribute ? Array.prototype.slice.call( uvAttribute.array ) : [];
var IndexAttribute = this.index;
var indicesArray = IndexAttribute ? Array.prototype.slice.call( IndexAttribute.array ) : [];
return {
position: verticesArray,
uv: uvArray,
index: indicesArray
};
};
ExtrudeBufferGeometry.prototype.addShapeList = function ( shapes, options ) {
var sl = shapes.length;
options.arrays = this.getArrays();
for ( var s = 0; s < sl; s ++ ) {
var shape = shapes[ s ];
this.addShape( shape, options );
}
this.setIndex( options.arrays.index );
this.addAttribute( 'position', new Float32BufferAttribute( options.arrays.position, 3 ) );
this.addAttribute( 'uv', new Float32BufferAttribute( options.arrays.uv, 2 ) );
};
ExtrudeBufferGeometry.prototype.addShape = function ( shape, options ) {
var arrays = options.arrays ? options.arrays : this.getArrays();
var verticesArray = arrays.position;
var indicesArray = arrays.index;
var uvArray = arrays.uv;
var placeholder = [];
var amount = options.amount !== undefined ? options.amount : 100;
var bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6; // 10
var bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; // 8
var bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;
var bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; // false
var curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;
var steps = options.steps !== undefined ? options.steps : 1;
var extrudePath = options.extrudePath;
var extrudePts, extrudeByPath = false;
// Use default WorldUVGenerator if no UV generators are specified.
var uvgen = options.UVGenerator !== undefined ? options.UVGenerator : ExtrudeGeometry.WorldUVGenerator;
var splineTube, binormal, normal, position2;
if ( extrudePath ) {
extrudePts = extrudePath.getSpacedPoints( steps );
extrudeByPath = true;
bevelEnabled = false; // bevels not supported for path extrusion
// SETUP TNB variables
// TODO1 - have a .isClosed in spline?
splineTube = options.frames !== undefined ? options.frames : extrudePath.computeFrenetFrames( steps, false );
// console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);
binormal = new Vector3();
normal = new Vector3();
position2 = new Vector3();
}
// Safeguards if bevels are not enabled
if ( ! bevelEnabled ) {
bevelSegments = 0;
bevelThickness = 0;
bevelSize = 0;
}
// Variables initialization
var ahole, h, hl; // looping of holes
var scope = this;
var shapePoints = shape.extractPoints( curveSegments );
var vertices = shapePoints.shape;
var holes = shapePoints.holes;
var reverse = ! ShapeUtils.isClockWise( vertices );
if ( reverse ) {
vertices = vertices.reverse();
// Maybe we should also check if holes are in the opposite direction, just to be safe ...
for ( h = 0, hl = holes.length; h < hl; h ++ ) {
ahole = holes[ h ];
if ( ShapeUtils.isClockWise( ahole ) ) {
holes[ h ] = ahole.reverse();
}
}
}
var faces = ShapeUtils.triangulateShape( vertices, holes );
/* Vertices */
var contour = vertices; // vertices has all points but contour has only points of circumference
for ( h = 0, hl = holes.length; h < hl; h ++ ) {
ahole = holes[ h ];
vertices = vertices.concat( ahole );
}
function scalePt2( pt, vec, size ) {
if ( ! vec ) console.error( "THREE.ExtrudeGeometry: vec does not exist" );
return vec.clone().multiplyScalar( size ).add( pt );
}
var b, bs, t, z,
vert, vlen = vertices.length,
face, flen = faces.length;
// Find directions for point movement
function getBevelVec( inPt, inPrev, inNext ) {
// computes for inPt the corresponding point inPt' on a new contour
// shifted by 1 unit (length of normalized vector) to the left
// if we walk along contour clockwise, this new contour is outside the old one
//
// inPt' is the intersection of the two lines parallel to the two
// adjacent edges of inPt at a distance of 1 unit on the left side.
var v_trans_x, v_trans_y, shrink_by; // resulting translation vector for inPt
// good reading for geometry algorithms (here: line-line intersection)
// http://geomalgorithms.com/a05-_intersect-1.html
var v_prev_x = inPt.x - inPrev.x,
v_prev_y = inPt.y - inPrev.y;
var v_next_x = inNext.x - inPt.x,
v_next_y = inNext.y - inPt.y;
var v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y );
// check for collinear edges
var collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x );
if ( Math.abs( collinear0 ) > Number.EPSILON ) {
// not collinear
// length of vectors for normalizing
var v_prev_len = Math.sqrt( v_prev_lensq );
var v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y );
// shift adjacent points by unit vectors to the left
var ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len );
var ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len );
var ptNextShift_x = ( inNext.x - v_next_y / v_next_len );
var ptNextShift_y = ( inNext.y + v_next_x / v_next_len );
// scaling factor for v_prev to intersection point
var sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y -
( ptNextShift_y - ptPrevShift_y ) * v_next_x ) /
( v_prev_x * v_next_y - v_prev_y * v_next_x );
// vector from inPt to intersection point
v_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x );
v_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y );
// Don't normalize!, otherwise sharp corners become ugly
// but prevent crazy spikes
var v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y );
if ( v_trans_lensq <= 2 ) {
return new Vector2( v_trans_x, v_trans_y );
} else {
shrink_by = Math.sqrt( v_trans_lensq / 2 );
}
} else {
// handle special case of collinear edges
var direction_eq = false; // assumes: opposite
if ( v_prev_x > Number.EPSILON ) {
if ( v_next_x > Number.EPSILON ) {
direction_eq = true;
}
} else {
if ( v_prev_x < - Number.EPSILON ) {
if ( v_next_x < - Number.EPSILON ) {
direction_eq = true;
}
} else {
if ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) {
direction_eq = true;
}
}
}
if ( direction_eq ) {
// console.log("Warning: lines are a straight sequence");
v_trans_x = - v_prev_y;
v_trans_y = v_prev_x;
shrink_by = Math.sqrt( v_prev_lensq );
} else {
// console.log("Warning: lines are a straight spike");
v_trans_x = v_prev_x;
v_trans_y = v_prev_y;
shrink_by = Math.sqrt( v_prev_lensq / 2 );
}
}
return new Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by );
}
var contourMovements = [];
for ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {
if ( j === il ) j = 0;
if ( k === il ) k = 0;
// (j)---(i)---(k)
// console.log('i,j,k', i, j , k)
contourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] );
}
var holesMovements = [],
oneHoleMovements, verticesMovements = contourMovements.concat();
for ( h = 0, hl = holes.length; h < hl; h ++ ) {
ahole = holes[ h ];
oneHoleMovements = [];
for ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {
if ( j === il ) j = 0;
if ( k === il ) k = 0;
// (j)---(i)---(k)
oneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] );
}
holesMovements.push( oneHoleMovements );
verticesMovements = verticesMovements.concat( oneHoleMovements );
}
// Loop bevelSegments, 1 for the front, 1 for the back
for ( b = 0; b < bevelSegments; b ++ ) {
//for ( b = bevelSegments; b > 0; b -- ) {
t = b / bevelSegments;
z = bevelThickness * Math.cos( t * Math.PI / 2 );
bs = bevelSize * Math.sin( t * Math.PI / 2 );
// contract shape
for ( i = 0, il = contour.length; i < il; i ++ ) {
vert = scalePt2( contour[ i ], contourMovements[ i ], bs );
v( vert.x, vert.y, - z );
}
// expand holes
for ( h = 0, hl = holes.length; h < hl; h ++ ) {
ahole = holes[ h ];
oneHoleMovements = holesMovements[ h ];
for ( i = 0, il = ahole.length; i < il; i ++ ) {
vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );
v( vert.x, vert.y, - z );
}
}
}
bs = bevelSize;
// Back facing vertices
for ( i = 0; i < vlen; i ++ ) {
vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];
if ( ! extrudeByPath ) {
v( vert.x, vert.y, 0 );
} else {
// v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );
normal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x );
binormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y );
position2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal );
v( position2.x, position2.y, position2.z );
}
}
// Add stepped vertices...
// Including front facing vertices
var s;
for ( s = 1; s <= steps; s ++ ) {
for ( i = 0; i < vlen; i ++ ) {
vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];
if ( ! extrudeByPath ) {
v( vert.x, vert.y, amount / steps * s );
} else {
// v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );
normal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x );
binormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y );
position2.copy( extrudePts[ s ] ).add( normal ).add( binormal );
v( position2.x, position2.y, position2.z );
}
}
}
// Add bevel segments planes
//for ( b = 1; b <= bevelSegments; b ++ ) {
for ( b = bevelSegments - 1; b >= 0; b -- ) {
t = b / bevelSegments;
z = bevelThickness * Math.cos( t * Math.PI / 2 );
bs = bevelSize * Math.sin( t * Math.PI / 2 );
// contract shape
for ( i = 0, il = contour.length; i < il; i ++ ) {
vert = scalePt2( contour[ i ], contourMovements[ i ], bs );
v( vert.x, vert.y, amount + z );
}
// expand holes
for ( h = 0, hl = holes.length; h < hl; h ++ ) {
ahole = holes[ h ];
oneHoleMovements = holesMovements[ h ];
for ( i = 0, il = ahole.length; i < il; i ++ ) {
vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );
if ( ! extrudeByPath ) {
v( vert.x, vert.y, amount + z );
} else {
v( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z );
}
}
}
}
/* Faces */
// Top and bottom faces
buildLidFaces();
// Sides faces
buildSideFaces();
///// Internal functions
function buildLidFaces() {
var start = verticesArray.length/3;
if ( bevelEnabled ) {
var layer = 0; // steps + 1
var offset = vlen * layer;
// Bottom faces
for ( i = 0; i < flen; i ++ ) {
face = faces[ i ];
f3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset );
}
layer = steps + bevelSegments * 2;
offset = vlen * layer;
// Top faces
for ( i = 0; i < flen; i ++ ) {
face = faces[ i ];
f3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset );
}
} else {
// Bottom faces
for ( i = 0; i < flen; i ++ ) {
face = faces[ i ];
f3( face[ 2 ], face[ 1 ], face[ 0 ] );
}
// Top faces
for ( i = 0; i < flen; i ++ ) {
face = faces[ i ];
f3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps );
}
}
scope.addGroup( start, verticesArray.length/3 -start, options.material !== undefined ? options.material : 0);
}
// Create faces for the z-sides of the shape
function buildSideFaces() {
var start = verticesArray.length/3;
var layeroffset = 0;
sidewalls( contour, layeroffset );
layeroffset += contour.length;
for ( h = 0, hl = holes.length; h < hl; h ++ ) {
ahole = holes[ h ];
sidewalls( ahole, layeroffset );
//, true
layeroffset += ahole.length;
}
scope.addGroup( start, verticesArray.length/3 -start, options.extrudeMaterial !== undefined ? options.extrudeMaterial : 1);
}
function sidewalls( contour, layeroffset ) {
var j, k;
i = contour.length;
while ( -- i >= 0 ) {
j = i;
k = i - 1;
if ( k < 0 ) k = contour.length - 1;
//console.log('b', i,j, i-1, k,vertices.length);
var s = 0,
sl = steps + bevelSegments * 2;
for ( s = 0; s < sl; s ++ ) {
var slen1 = vlen * s;
var slen2 = vlen * ( s + 1 );
var a = layeroffset + j + slen1,
b = layeroffset + k + slen1,
c = layeroffset + k + slen2,
d = layeroffset + j + slen2;
f4( a, b, c, d, contour, s, sl, j, k );
}
}
}
function v( x, y, z ) {
placeholder.push( x );
placeholder.push( y );
placeholder.push( z );
}
function f3( a, b, c ) {
addVertex( a );
addVertex( b );
addVertex( c );
var nextIndex = verticesArray.length / 3;
var uvs = uvgen.generateTopUV( scope, verticesArray, nextIndex - 3, nextIndex - 2, nextIndex - 1 );
addUV( uvs[ 0 ] );
addUV( uvs[ 1 ] );
addUV( uvs[ 2 ] );
}
function f4( a, b, c, d, wallContour, stepIndex, stepsLength, contourIndex1, contourIndex2 ) {
addVertex( a );
addVertex( b );
addVertex( d );
addVertex( b );
addVertex( c );
addVertex( d );
var nextIndex = verticesArray.length / 3;
var uvs = uvgen.generateSideWallUV( scope, verticesArray, nextIndex - 6, nextIndex - 3, nextIndex - 2, nextIndex - 1 );
addUV( uvs[ 0 ] );
addUV( uvs[ 1 ] );
addUV( uvs[ 3 ] );
addUV( uvs[ 1 ] );
addUV( uvs[ 2 ] );
addUV( uvs[ 3 ] );
}
function addVertex( index ) {
indicesArray.push( verticesArray.length / 3 );
verticesArray.push( placeholder[ index * 3 + 0 ] );
verticesArray.push( placeholder[ index * 3 + 1 ] );
verticesArray.push( placeholder[ index * 3 + 2 ] );
}
function addUV( vector2 ) {
uvArray.push( vector2.x );
uvArray.push( vector2.y );
}
if ( ! options.arrays ) {
this.setIndex( indicesArray );
this.addAttribute( 'position', new Float32BufferAttribute( verticesArray, 3 ) );
this.addAttribute( 'uv', new Float32BufferAttribute( options.arrays.uv, 2 ) );
}
};
ExtrudeGeometry.WorldUVGenerator = {
generateTopUV: function ( geometry, vertices, indexA, indexB, indexC ) {
var a_x = vertices[ indexA * 3 ];
var a_y = vertices[ indexA * 3 + 1 ];
var b_x = vertices[ indexB * 3 ];
var b_y = vertices[ indexB * 3 + 1 ];
var c_x = vertices[ indexC * 3 ];
var c_y = vertices[ indexC * 3 + 1 ];
return [
new Vector2( a_x, a_y ),
new Vector2( b_x, b_y ),
new Vector2( c_x, c_y )
];
},
generateSideWallUV: function ( geometry, vertices, indexA, indexB, indexC, indexD ) {
var a_x = vertices[ indexA * 3 ];
var a_y = vertices[ indexA * 3 + 1 ];
var a_z = vertices[ indexA * 3 + 2 ];
var b_x = vertices[ indexB * 3 ];
var b_y = vertices[ indexB * 3 + 1 ];
var b_z = vertices[ indexB * 3 + 2 ];
var c_x = vertices[ indexC * 3 ];
var c_y = vertices[ indexC * 3 + 1 ];
var c_z = vertices[ indexC * 3 + 2 ];
var d_x = vertices[ indexD * 3 ];
var d_y = vertices[ indexD * 3 + 1 ];
var d_z = vertices[ indexD * 3 + 2 ];
if ( Math.abs( a_y - b_y ) < 0.01 ) {
return [
new Vector2( a_x, 1 - a_z ),
new Vector2( b_x, 1 - b_z ),
new Vector2( c_x, 1 - c_z ),
new Vector2( d_x, 1 - d_z )
];
} else {
return [
new Vector2( a_y, 1 - a_z ),
new Vector2( b_y, 1 - b_z ),
new Vector2( c_y, 1 - c_z ),
new Vector2( d_y, 1 - d_z )
];
}
}
};
/**
* @author zz85 / http://www.lab4games.net/zz85/blog
* @author alteredq / http://alteredqualia.com/
*
* Text = 3D Text
*
* parameters = {
* font: <THREE.Font>, // font
*
* size: <float>, // size of the text
* height: <float>, // thickness to extrude text
* curveSegments: <int>, // number of points on the curves
*
* bevelEnabled: <bool>, // turn on bevel
* bevelThickness: <float>, // how deep into text bevel goes
* bevelSize: <float> // how far from text outline is bevel
* }
*/
// TextGeometry
function TextGeometry( text, parameters ) {
Geometry.call( this );
this.type = 'TextGeometry';
this.parameters = {
text: text,
parameters: parameters
};
this.fromBufferGeometry( new TextBufferGeometry( text, parameters ) );
this.mergeVertices();
}
TextGeometry.prototype = Object.create( Geometry.prototype );
TextGeometry.prototype.constructor = TextGeometry;
// TextBufferGeometry
function TextBufferGeometry( text, parameters ) {
parameters = parameters || {};
var font = parameters.font;
if ( ! ( font && font.isFont ) ) {
console.error( 'THREE.TextGeometry: font parameter is not an instance of THREE.Font.' );
return new Geometry();
}
var shapes = font.generateShapes( text, parameters.size, parameters.curveSegments );
// translate parameters to ExtrudeGeometry API
parameters.amount = parameters.height !== undefined ? parameters.height : 50;
// defaults
if ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10;
if ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;
if ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;
ExtrudeBufferGeometry.call( this, shapes, parameters );
this.type = 'TextBufferGeometry';
}
TextBufferGeometry.prototype = Object.create( ExtrudeBufferGeometry.prototype );
TextBufferGeometry.prototype.constructor = TextBufferGeometry;
/**
* @author mrdoob / http://mrdoob.com/
* @author benaadams / https://twitter.com/ben_a_adams
* @author Mugen87 / https://github.com/Mugen87
*/
// SphereGeometry
function SphereGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {
Geometry.call( this );
this.type = 'SphereGeometry';
this.parameters = {
radius: radius,
widthSegments: widthSegments,
heightSegments: heightSegments,
phiStart: phiStart,
phiLength: phiLength,
thetaStart: thetaStart,
thetaLength: thetaLength
};
this.fromBufferGeometry( new SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) );
this.mergeVertices();
}
SphereGeometry.prototype = Object.create( Geometry.prototype );
SphereGeometry.prototype.constructor = SphereGeometry;
// SphereBufferGeometry
function SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {
BufferGeometry.call( this );
this.type = 'SphereBufferGeometry';
this.parameters = {
radius: radius,
widthSegments: widthSegments,
heightSegments: heightSegments,
phiStart: phiStart,
phiLength: phiLength,
thetaStart: thetaStart,
thetaLength: thetaLength
};
radius = radius || 50;
widthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 );
heightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 );
phiStart = phiStart !== undefined ? phiStart : 0;
phiLength = phiLength !== undefined ? phiLength : Math.PI * 2;
thetaStart = thetaStart !== undefined ? thetaStart : 0;
thetaLength = thetaLength !== undefined ? thetaLength : Math.PI;
var thetaEnd = thetaStart + thetaLength;
var ix, iy;
var index = 0;
var grid = [];
var vertex = new Vector3();
var normal = new Vector3();
// buffers
var indices = [];
var vertices = [];
var normals = [];
var uvs = [];
// generate vertices, normals and uvs
for ( iy = 0; iy <= heightSegments; iy ++ ) {
var verticesRow = [];
var v = iy / heightSegments;
for ( ix = 0; ix <= widthSegments; ix ++ ) {
var u = ix / widthSegments;
// vertex
vertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
vertex.y = radius * Math.cos( thetaStart + v * thetaLength );
vertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
vertices.push( vertex.x, vertex.y, vertex.z );
// normal
normal.set( vertex.x, vertex.y, vertex.z ).normalize();
normals.push( normal.x, normal.y, normal.z );
// uv
uvs.push( u, 1 - v );
verticesRow.push( index ++ );
}
grid.push( verticesRow );
}
// indices
for ( iy = 0; iy < heightSegments; iy ++ ) {
for ( ix = 0; ix < widthSegments; ix ++ ) {
var a = grid[ iy ][ ix + 1 ];
var b = grid[ iy ][ ix ];
var c = grid[ iy + 1 ][ ix ];
var d = grid[ iy + 1 ][ ix + 1 ];
if ( iy !== 0 || thetaStart > 0 ) indices.push( a, b, d );
if ( iy !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( b, c, d );
}
}
// build geometry
this.setIndex( indices );
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
}
SphereBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
SphereBufferGeometry.prototype.constructor = SphereBufferGeometry;
/**
* @author Kaleb Murphy
* @author Mugen87 / https://github.com/Mugen87
*/
// RingGeometry
function RingGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {
Geometry.call( this );
this.type = 'RingGeometry';
this.parameters = {
innerRadius: innerRadius,
outerRadius: outerRadius,
thetaSegments: thetaSegments,
phiSegments: phiSegments,
thetaStart: thetaStart,
thetaLength: thetaLength
};
this.fromBufferGeometry( new RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) );
this.mergeVertices();
}
RingGeometry.prototype = Object.create( Geometry.prototype );
RingGeometry.prototype.constructor = RingGeometry;
// RingBufferGeometry
function RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {
BufferGeometry.call( this );
this.type = 'RingBufferGeometry';
this.parameters = {
innerRadius: innerRadius,
outerRadius: outerRadius,
thetaSegments: thetaSegments,
phiSegments: phiSegments,
thetaStart: thetaStart,
thetaLength: thetaLength
};
innerRadius = innerRadius || 20;
outerRadius = outerRadius || 50;
thetaStart = thetaStart !== undefined ? thetaStart : 0;
thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;
thetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8;
phiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 1;
// buffers
var indices = [];
var vertices = [];
var normals = [];
var uvs = [];
// some helper variables
var segment;
var radius = innerRadius;
var radiusStep = ( ( outerRadius - innerRadius ) / phiSegments );
var vertex = new Vector3();
var uv = new Vector2();
var j, i;
// generate vertices, normals and uvs
for ( j = 0; j <= phiSegments; j ++ ) {
for ( i = 0; i <= thetaSegments; i ++ ) {
// values are generate from the inside of the ring to the outside
segment = thetaStart + i / thetaSegments * thetaLength;
// vertex
vertex.x = radius * Math.cos( segment );
vertex.y = radius * Math.sin( segment );
vertices.push( vertex.x, vertex.y, vertex.z );
// normal
normals.push( 0, 0, 1 );
// uv
uv.x = ( vertex.x / outerRadius + 1 ) / 2;
uv.y = ( vertex.y / outerRadius + 1 ) / 2;
uvs.push( uv.x, uv.y );
}
// increase the radius for next row of vertices
radius += radiusStep;
}
// indices
for ( j = 0; j < phiSegments; j ++ ) {
var thetaSegmentLevel = j * ( thetaSegments + 1 );
for ( i = 0; i < thetaSegments; i ++ ) {
segment = i + thetaSegmentLevel;
var a = segment;
var b = segment + thetaSegments + 1;
var c = segment + thetaSegments + 2;
var d = segment + 1;
// faces
indices.push( a, b, d );
indices.push( b, c, d );
}
}
// build geometry
this.setIndex( indices );
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
}
RingBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
RingBufferGeometry.prototype.constructor = RingBufferGeometry;
/**
* @author astrodud / http://astrodud.isgreat.org/
* @author zz85 / https://github.com/zz85
* @author bhouston / http://clara.io
* @author Mugen87 / https://github.com/Mugen87
*/
// LatheGeometry
function LatheGeometry( points, segments, phiStart, phiLength ) {
Geometry.call( this );
this.type = 'LatheGeometry';
this.parameters = {
points: points,
segments: segments,
phiStart: phiStart,
phiLength: phiLength
};
this.fromBufferGeometry( new LatheBufferGeometry( points, segments, phiStart, phiLength ) );
this.mergeVertices();
}
LatheGeometry.prototype = Object.create( Geometry.prototype );
LatheGeometry.prototype.constructor = LatheGeometry;
// LatheBufferGeometry
function LatheBufferGeometry( points, segments, phiStart, phiLength ) {
BufferGeometry.call( this );
this.type = 'LatheBufferGeometry';
this.parameters = {
points: points,
segments: segments,
phiStart: phiStart,
phiLength: phiLength
};
segments = Math.floor( segments ) || 12;
phiStart = phiStart || 0;
phiLength = phiLength || Math.PI * 2;
// clamp phiLength so it's in range of [ 0, 2PI ]
phiLength = _Math.clamp( phiLength, 0, Math.PI * 2 );
// buffers
var indices = [];
var vertices = [];
var uvs = [];
// helper variables
var base;
var inverseSegments = 1.0 / segments;
var vertex = new Vector3();
var uv = new Vector2();
var i, j;
// generate vertices and uvs
for ( i = 0; i <= segments; i ++ ) {
var phi = phiStart + i * inverseSegments * phiLength;
var sin = Math.sin( phi );
var cos = Math.cos( phi );
for ( j = 0; j <= ( points.length - 1 ); j ++ ) {
// vertex
vertex.x = points[ j ].x * sin;
vertex.y = points[ j ].y;
vertex.z = points[ j ].x * cos;
vertices.push( vertex.x, vertex.y, vertex.z );
// uv
uv.x = i / segments;
uv.y = j / ( points.length - 1 );
uvs.push( uv.x, uv.y );
}
}
// indices
for ( i = 0; i < segments; i ++ ) {
for ( j = 0; j < ( points.length - 1 ); j ++ ) {
base = j + i * points.length;
var a = base;
var b = base + points.length;
var c = base + points.length + 1;
var d = base + 1;
// faces
indices.push( a, b, d );
indices.push( b, c, d );
}
}
// build geometry
this.setIndex( indices );
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
// generate normals
this.computeVertexNormals();
// if the geometry is closed, we need to average the normals along the seam.
// because the corresponding vertices are identical (but still have different UVs).
if ( phiLength === Math.PI * 2 ) {
var normals = this.attributes.normal.array;
var n1 = new Vector3();
var n2 = new Vector3();
var n = new Vector3();
// this is the buffer offset for the last line of vertices
base = segments * points.length * 3;
for ( i = 0, j = 0; i < points.length; i ++, j += 3 ) {
// select the normal of the vertex in the first line
n1.x = normals[ j + 0 ];
n1.y = normals[ j + 1 ];
n1.z = normals[ j + 2 ];
// select the normal of the vertex in the last line
n2.x = normals[ base + j + 0 ];
n2.y = normals[ base + j + 1 ];
n2.z = normals[ base + j + 2 ];
// average normals
n.addVectors( n1, n2 ).normalize();
// assign the new values to both normals
normals[ j + 0 ] = normals[ base + j + 0 ] = n.x;
normals[ j + 1 ] = normals[ base + j + 1 ] = n.y;
normals[ j + 2 ] = normals[ base + j + 2 ] = n.z;
}
}
}
LatheBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
LatheBufferGeometry.prototype.constructor = LatheBufferGeometry;
/**
* @author jonobr1 / http://jonobr1.com
* @author Mugen87 / https://github.com/Mugen87
*/
// ShapeGeometry
function ShapeGeometry( shapes, curveSegments ) {
Geometry.call( this );
this.type = 'ShapeGeometry';
if ( typeof curveSegments === 'object' ) {
console.warn( 'THREE.ShapeGeometry: Options parameter has been removed.' );
curveSegments = curveSegments.curveSegments;
}
this.parameters = {
shapes: shapes,
curveSegments: curveSegments
};
this.fromBufferGeometry( new ShapeBufferGeometry( shapes, curveSegments ) );
this.mergeVertices();
}
ShapeGeometry.prototype = Object.create( Geometry.prototype );
ShapeGeometry.prototype.constructor = ShapeGeometry;
// ShapeBufferGeometry
function ShapeBufferGeometry( shapes, curveSegments ) {
BufferGeometry.call( this );
this.type = 'ShapeBufferGeometry';
this.parameters = {
shapes: shapes,
curveSegments: curveSegments
};
curveSegments = curveSegments || 12;
// buffers
var indices = [];
var vertices = [];
var normals = [];
var uvs = [];
// helper variables
var groupStart = 0;
var groupCount = 0;
// allow single and array values for "shapes" parameter
if ( Array.isArray( shapes ) === false ) {
addShape( shapes );
} else {
for ( var i = 0; i < shapes.length; i ++ ) {
addShape( shapes[ i ] );
this.addGroup( groupStart, groupCount, i ); // enables MultiMaterial support
groupStart += groupCount;
groupCount = 0;
}
}
// build geometry
this.setIndex( indices );
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
// helper functions
function addShape( shape ) {
var i, l, shapeHole;
var indexOffset = vertices.length / 3;
var points = shape.extractPoints( curveSegments );
var shapeVertices = points.shape;
var shapeHoles = points.holes;
// check direction of vertices
if ( ShapeUtils.isClockWise( shapeVertices ) === false ) {
shapeVertices = shapeVertices.reverse();
// also check if holes are in the opposite direction
for ( i = 0, l = shapeHoles.length; i < l; i ++ ) {
shapeHole = shapeHoles[ i ];
if ( ShapeUtils.isClockWise( shapeHole ) === true ) {
shapeHoles[ i ] = shapeHole.reverse();
}
}
}
var faces = ShapeUtils.triangulateShape( shapeVertices, shapeHoles );
// join vertices of inner and outer paths to a single array
for ( i = 0, l = shapeHoles.length; i < l; i ++ ) {
shapeHole = shapeHoles[ i ];
shapeVertices = shapeVertices.concat( shapeHole );
}
// vertices, normals, uvs
for ( i = 0, l = shapeVertices.length; i < l; i ++ ) {
var vertex = shapeVertices[ i ];
vertices.push( vertex.x, vertex.y, 0 );
normals.push( 0, 0, 1 );
uvs.push( vertex.x, vertex.y ); // world uvs
}
// incides
for ( i = 0, l = faces.length; i < l; i ++ ) {
var face = faces[ i ];
var a = face[ 0 ] + indexOffset;
var b = face[ 1 ] + indexOffset;
var c = face[ 2 ] + indexOffset;
indices.push( a, b, c );
groupCount += 3;
}
}
}
ShapeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
ShapeBufferGeometry.prototype.constructor = ShapeBufferGeometry;
/**
* @author WestLangley / http://github.com/WestLangley
* @author Mugen87 / https://github.com/Mugen87
*/
function EdgesGeometry( geometry, thresholdAngle ) {
BufferGeometry.call( this );
this.type = 'EdgesGeometry';
this.parameters = {
thresholdAngle: thresholdAngle
};
thresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1;
// buffer
var vertices = [];
// helper variables
var thresholdDot = Math.cos( _Math.DEG2RAD * thresholdAngle );
var edge = [ 0, 0 ], edges = {}, edge1, edge2;
var key, keys = [ 'a', 'b', 'c' ];
// prepare source geometry
var geometry2;
if ( geometry.isBufferGeometry ) {
geometry2 = new Geometry();
geometry2.fromBufferGeometry( geometry );
} else {
geometry2 = geometry.clone();
}
geometry2.mergeVertices();
geometry2.computeFaceNormals();
var sourceVertices = geometry2.vertices;
var faces = geometry2.faces;
// now create a data structure where each entry represents an edge with its adjoining faces
for ( var i = 0, l = faces.length; i < l; i ++ ) {
var face = faces[ i ];
for ( var j = 0; j < 3; j ++ ) {
edge1 = face[ keys[ j ] ];
edge2 = face[ keys[ ( j + 1 ) % 3 ] ];
edge[ 0 ] = Math.min( edge1, edge2 );
edge[ 1 ] = Math.max( edge1, edge2 );
key = edge[ 0 ] + ',' + edge[ 1 ];
if ( edges[ key ] === undefined ) {
edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ], face1: i, face2: undefined };
} else {
edges[ key ].face2 = i;
}
}
}
// generate vertices
for ( key in edges ) {
var e = edges[ key ];
// an edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. default = 1 degree.
if ( e.face2 === undefined || faces[ e.face1 ].normal.dot( faces[ e.face2 ].normal ) <= thresholdDot ) {
var vertex = sourceVertices[ e.index1 ];
vertices.push( vertex.x, vertex.y, vertex.z );
vertex = sourceVertices[ e.index2 ];
vertices.push( vertex.x, vertex.y, vertex.z );
}
}
// build geometry
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
}
EdgesGeometry.prototype = Object.create( BufferGeometry.prototype );
EdgesGeometry.prototype.constructor = EdgesGeometry;
/**
* @author mrdoob / http://mrdoob.com/
* @author Mugen87 / https://github.com/Mugen87
*/
// CylinderGeometry
function CylinderGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {
Geometry.call( this );
this.type = 'CylinderGeometry';
this.parameters = {
radiusTop: radiusTop,
radiusBottom: radiusBottom,
height: height,
radialSegments: radialSegments,
heightSegments: heightSegments,
openEnded: openEnded,
thetaStart: thetaStart,
thetaLength: thetaLength
};
this.fromBufferGeometry( new CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) );
this.mergeVertices();
}
CylinderGeometry.prototype = Object.create( Geometry.prototype );
CylinderGeometry.prototype.constructor = CylinderGeometry;
// CylinderBufferGeometry
function CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {
BufferGeometry.call( this );
this.type = 'CylinderBufferGeometry';
this.parameters = {
radiusTop: radiusTop,
radiusBottom: radiusBottom,
height: height,
radialSegments: radialSegments,
heightSegments: heightSegments,
openEnded: openEnded,
thetaStart: thetaStart,
thetaLength: thetaLength
};
var scope = this;
radiusTop = radiusTop !== undefined ? radiusTop : 20;
radiusBottom = radiusBottom !== undefined ? radiusBottom : 20;
height = height !== undefined ? height : 100;
radialSegments = Math.floor( radialSegments ) || 8;
heightSegments = Math.floor( heightSegments ) || 1;
openEnded = openEnded !== undefined ? openEnded : false;
thetaStart = thetaStart !== undefined ? thetaStart : 0.0;
thetaLength = thetaLength !== undefined ? thetaLength : 2.0 * Math.PI;
// buffers
var indices = [];
var vertices = [];
var normals = [];
var uvs = [];
// helper variables
var index = 0;
var indexArray = [];
var halfHeight = height / 2;
var groupStart = 0;
// generate geometry
generateTorso();
if ( openEnded === false ) {
if ( radiusTop > 0 ) generateCap( true );
if ( radiusBottom > 0 ) generateCap( false );
}
// build geometry
this.setIndex( indices );
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
function generateTorso() {
var x, y;
var normal = new Vector3();
var vertex = new Vector3();
var groupCount = 0;
// this will be used to calculate the normal
var slope = ( radiusBottom - radiusTop ) / height;
// generate vertices, normals and uvs
for ( y = 0; y <= heightSegments; y ++ ) {
var indexRow = [];
var v = y / heightSegments;
// calculate the radius of the current row
var radius = v * ( radiusBottom - radiusTop ) + radiusTop;
for ( x = 0; x <= radialSegments; x ++ ) {
var u = x / radialSegments;
var theta = u * thetaLength + thetaStart;
var sinTheta = Math.sin( theta );
var cosTheta = Math.cos( theta );
// vertex
vertex.x = radius * sinTheta;
vertex.y = - v * height + halfHeight;
vertex.z = radius * cosTheta;
vertices.push( vertex.x, vertex.y, vertex.z );
// normal
normal.set( sinTheta, slope, cosTheta ).normalize();
normals.push( normal.x, normal.y, normal.z );
// uv
uvs.push( u, 1 - v );
// save index of vertex in respective row
indexRow.push( index ++ );
}
// now save vertices of the row in our index array
indexArray.push( indexRow );
}
// generate indices
for ( x = 0; x < radialSegments; x ++ ) {
for ( y = 0; y < heightSegments; y ++ ) {
// we use the index array to access the correct indices
var a = indexArray[ y ][ x ];
var b = indexArray[ y + 1 ][ x ];
var c = indexArray[ y + 1 ][ x + 1 ];
var d = indexArray[ y ][ x + 1 ];
// faces
indices.push( a, b, d );
indices.push( b, c, d );
// update group counter
groupCount += 6;
}
}
// add a group to the geometry. this will ensure multi material support
scope.addGroup( groupStart, groupCount, 0 );
// calculate new start value for groups
groupStart += groupCount;
}
function generateCap( top ) {
var x, centerIndexStart, centerIndexEnd;
var uv = new Vector2();
var vertex = new Vector3();
var groupCount = 0;
var radius = ( top === true ) ? radiusTop : radiusBottom;
var sign = ( top === true ) ? 1 : - 1;
// save the index of the first center vertex
centerIndexStart = index;
// first we generate the center vertex data of the cap.
// because the geometry needs one set of uvs per face,
// we must generate a center vertex per face/segment
for ( x = 1; x <= radialSegments; x ++ ) {
// vertex
vertices.push( 0, halfHeight * sign, 0 );
// normal
normals.push( 0, sign, 0 );
// uv
uvs.push( 0.5, 0.5 );
// increase index
index ++;
}
// save the index of the last center vertex
centerIndexEnd = index;
// now we generate the surrounding vertices, normals and uvs
for ( x = 0; x <= radialSegments; x ++ ) {
var u = x / radialSegments;
var theta = u * thetaLength + thetaStart;
var cosTheta = Math.cos( theta );
var sinTheta = Math.sin( theta );
// vertex
vertex.x = radius * sinTheta;
vertex.y = halfHeight * sign;
vertex.z = radius * cosTheta;
vertices.push( vertex.x, vertex.y, vertex.z );
// normal
normals.push( 0, sign, 0 );
// uv
uv.x = ( cosTheta * 0.5 ) + 0.5;
uv.y = ( sinTheta * 0.5 * sign ) + 0.5;
uvs.push( uv.x, uv.y );
// increase index
index ++;
}
// generate indices
for ( x = 0; x < radialSegments; x ++ ) {
var c = centerIndexStart + x;
var i = centerIndexEnd + x;
if ( top === true ) {
// face top
indices.push( i, i + 1, c );
} else {
// face bottom
indices.push( i + 1, i, c );
}
groupCount += 3;
}
// add a group to the geometry. this will ensure multi material support
scope.addGroup( groupStart, groupCount, top === true ? 1 : 2 );
// calculate new start value for groups
groupStart += groupCount;
}
}
CylinderBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
CylinderBufferGeometry.prototype.constructor = CylinderBufferGeometry;
/**
* @author abelnation / http://github.com/abelnation
*/
// ConeGeometry
function ConeGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {
CylinderGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );
this.type = 'ConeGeometry';
this.parameters = {
radius: radius,
height: height,
radialSegments: radialSegments,
heightSegments: heightSegments,
openEnded: openEnded,
thetaStart: thetaStart,
thetaLength: thetaLength
};
}
ConeGeometry.prototype = Object.create( CylinderGeometry.prototype );
ConeGeometry.prototype.constructor = ConeGeometry;
// ConeBufferGeometry
function ConeBufferGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {
CylinderBufferGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );
this.type = 'ConeBufferGeometry';
this.parameters = {
radius: radius,
height: height,
radialSegments: radialSegments,
heightSegments: heightSegments,
openEnded: openEnded,
thetaStart: thetaStart,
thetaLength: thetaLength
};
}
ConeBufferGeometry.prototype = Object.create( CylinderBufferGeometry.prototype );
ConeBufferGeometry.prototype.constructor = ConeBufferGeometry;
/**
* @author benaadams / https://twitter.com/ben_a_adams
* @author Mugen87 / https://github.com/Mugen87
* @author hughes
*/
// CircleGeometry
function CircleGeometry( radius, segments, thetaStart, thetaLength ) {
Geometry.call( this );
this.type = 'CircleGeometry';
this.parameters = {
radius: radius,
segments: segments,
thetaStart: thetaStart,
thetaLength: thetaLength
};
this.fromBufferGeometry( new CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) );
this.mergeVertices();
}
CircleGeometry.prototype = Object.create( Geometry.prototype );
CircleGeometry.prototype.constructor = CircleGeometry;
// CircleBufferGeometry
function CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) {
BufferGeometry.call( this );
this.type = 'CircleBufferGeometry';
this.parameters = {
radius: radius,
segments: segments,
thetaStart: thetaStart,
thetaLength: thetaLength
};
radius = radius || 50;
segments = segments !== undefined ? Math.max( 3, segments ) : 8;
thetaStart = thetaStart !== undefined ? thetaStart : 0;
thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;
// buffers
var indices = [];
var vertices = [];
var normals = [];
var uvs = [];
// helper variables
var i, s;
var vertex = new Vector3();
var uv = new Vector2();
// center point
vertices.push( 0, 0, 0 );
normals.push( 0, 0, 1 );
uvs.push( 0.5, 0.5 );
for ( s = 0, i = 3; s <= segments; s ++, i += 3 ) {
var segment = thetaStart + s / segments * thetaLength;
// vertex
vertex.x = radius * Math.cos( segment );
vertex.y = radius * Math.sin( segment );
vertices.push( vertex.x, vertex.y, vertex.z );
// normal
normals.push( 0, 0, 1 );
// uvs
uv.x = ( vertices[ i ] / radius + 1 ) / 2;
uv.y = ( vertices[ i + 1 ] / radius + 1 ) / 2;
uvs.push( uv.x, uv.y );
}
// indices
for ( i = 1; i <= segments; i ++ ) {
indices.push( i, i + 1, 0 );
}
// build geometry
this.setIndex( indices );
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
}
CircleBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
CircleBufferGeometry.prototype.constructor = CircleBufferGeometry;
var Geometries = Object.freeze({
WireframeGeometry: WireframeGeometry,
ParametricGeometry: ParametricGeometry,
ParametricBufferGeometry: ParametricBufferGeometry,
TetrahedronGeometry: TetrahedronGeometry,
TetrahedronBufferGeometry: TetrahedronBufferGeometry,
OctahedronGeometry: OctahedronGeometry,
OctahedronBufferGeometry: OctahedronBufferGeometry,
IcosahedronGeometry: IcosahedronGeometry,
IcosahedronBufferGeometry: IcosahedronBufferGeometry,
DodecahedronGeometry: DodecahedronGeometry,
DodecahedronBufferGeometry: DodecahedronBufferGeometry,
PolyhedronGeometry: PolyhedronGeometry,
PolyhedronBufferGeometry: PolyhedronBufferGeometry,
TubeGeometry: TubeGeometry,
TubeBufferGeometry: TubeBufferGeometry,
TorusKnotGeometry: TorusKnotGeometry,
TorusKnotBufferGeometry: TorusKnotBufferGeometry,
TorusGeometry: TorusGeometry,
TorusBufferGeometry: TorusBufferGeometry,
TextGeometry: TextGeometry,
TextBufferGeometry: TextBufferGeometry,
SphereGeometry: SphereGeometry,
SphereBufferGeometry: SphereBufferGeometry,
RingGeometry: RingGeometry,
RingBufferGeometry: RingBufferGeometry,
PlaneGeometry: PlaneGeometry,
PlaneBufferGeometry: PlaneBufferGeometry,
LatheGeometry: LatheGeometry,
LatheBufferGeometry: LatheBufferGeometry,
ShapeGeometry: ShapeGeometry,
ShapeBufferGeometry: ShapeBufferGeometry,
ExtrudeGeometry: ExtrudeGeometry,
ExtrudeBufferGeometry: ExtrudeBufferGeometry,
EdgesGeometry: EdgesGeometry,
ConeGeometry: ConeGeometry,
ConeBufferGeometry: ConeBufferGeometry,
CylinderGeometry: CylinderGeometry,
CylinderBufferGeometry: CylinderBufferGeometry,
CircleGeometry: CircleGeometry,
CircleBufferGeometry: CircleBufferGeometry,
BoxGeometry: BoxGeometry,
BoxBufferGeometry: BoxBufferGeometry
});
/**
* @author mrdoob / http://mrdoob.com/
*
* parameters = {
* opacity: <float>
* }
*/
function ShadowMaterial( parameters ) {
ShaderMaterial.call( this, {
uniforms: UniformsUtils.merge( [
UniformsLib.lights,
{
opacity: { value: 1.0 }
}
] ),
vertexShader: ShaderChunk[ 'shadow_vert' ],
fragmentShader: ShaderChunk[ 'shadow_frag' ]
} );
this.lights = true;
this.transparent = true;
Object.defineProperties( this, {
opacity: {
enumerable: true,
get: function () {
return this.uniforms.opacity.value;
},
set: function ( value ) {
this.uniforms.opacity.value = value;
}
}
} );
this.setValues( parameters );
}
ShadowMaterial.prototype = Object.create( ShaderMaterial.prototype );
ShadowMaterial.prototype.constructor = ShadowMaterial;
ShadowMaterial.prototype.isShadowMaterial = true;
/**
* @author mrdoob / http://mrdoob.com/
*/
function RawShaderMaterial( parameters ) {
ShaderMaterial.call( this, parameters );
this.type = 'RawShaderMaterial';
}
RawShaderMaterial.prototype = Object.create( ShaderMaterial.prototype );
RawShaderMaterial.prototype.constructor = RawShaderMaterial;
RawShaderMaterial.prototype.isRawShaderMaterial = true;
/**
* @author WestLangley / http://github.com/WestLangley
*
* parameters = {
* color: <hex>,
* roughness: <float>,
* metalness: <float>,
* opacity: <float>,
*
* map: new THREE.Texture( <Image> ),
*
* lightMap: new THREE.Texture( <Image> ),
* lightMapIntensity: <float>
*
* aoMap: new THREE.Texture( <Image> ),
* aoMapIntensity: <float>
*
* emissive: <hex>,
* emissiveIntensity: <float>
* emissiveMap: new THREE.Texture( <Image> ),
*
* bumpMap: new THREE.Texture( <Image> ),
* bumpScale: <float>,
*
* normalMap: new THREE.Texture( <Image> ),
* normalScale: <Vector2>,
*
* displacementMap: new THREE.Texture( <Image> ),
* displacementScale: <float>,
* displacementBias: <float>,
*
* roughnessMap: new THREE.Texture( <Image> ),
*
* metalnessMap: new THREE.Texture( <Image> ),
*
* alphaMap: new THREE.Texture( <Image> ),
*
* envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),
* envMapIntensity: <float>
*
* refractionRatio: <float>,
*
* wireframe: <boolean>,
* wireframeLinewidth: <float>,
*
* skinning: <bool>,
* morphTargets: <bool>,
* morphNormals: <bool>
* }
*/
function MeshStandardMaterial( parameters ) {
Material.call( this );
this.defines = { 'STANDARD': '' };
this.type = 'MeshStandardMaterial';
this.color = new Color( 0xffffff ); // diffuse
this.roughness = 0.5;
this.metalness = 0.5;
this.map = null;
this.lightMap = null;
this.lightMapIntensity = 1.0;
this.aoMap = null;
this.aoMapIntensity = 1.0;
this.emissive = new Color( 0x000000 );
this.emissiveIntensity = 1.0;
this.emissiveMap = null;
this.bumpMap = null;
this.bumpScale = 1;
this.normalMap = null;
this.normalScale = new Vector2( 1, 1 );
this.displacementMap = null;
this.displacementScale = 1;
this.displacementBias = 0;
this.roughnessMap = null;
this.metalnessMap = null;
this.alphaMap = null;
this.envMap = null;
this.envMapIntensity = 1.0;
this.refractionRatio = 0.98;
this.wireframe = false;
this.wireframeLinewidth = 1;
this.wireframeLinecap = 'round';
this.wireframeLinejoin = 'round';
this.skinning = false;
this.morphTargets = false;
this.morphNormals = false;
this.setValues( parameters );
}
MeshStandardMaterial.prototype = Object.create( Material.prototype );
MeshStandardMaterial.prototype.constructor = MeshStandardMaterial;
MeshStandardMaterial.prototype.isMeshStandardMaterial = true;
MeshStandardMaterial.prototype.copy = function ( source ) {
Material.prototype.copy.call( this, source );
this.defines = { 'STANDARD': '' };
this.color.copy( source.color );
this.roughness = source.roughness;
this.metalness = source.metalness;
this.map = source.map;
this.lightMap = source.lightMap;
this.lightMapIntensity = source.lightMapIntensity;
this.aoMap = source.aoMap;
this.aoMapIntensity = source.aoMapIntensity;
this.emissive.copy( source.emissive );
this.emissiveMap = source.emissiveMap;
this.emissiveIntensity = source.emissiveIntensity;
this.bumpMap = source.bumpMap;
this.bumpScale = source.bumpScale;
this.normalMap = source.normalMap;
this.normalScale.copy( source.normalScale );
this.displacementMap = source.displacementMap;
this.displacementScale = source.displacementScale;
this.displacementBias = source.displacementBias;
this.roughnessMap = source.roughnessMap;
this.metalnessMap = source.metalnessMap;
this.alphaMap = source.alphaMap;
this.envMap = source.envMap;
this.envMapIntensity = source.envMapIntensity;
this.refractionRatio = source.refractionRatio;
this.wireframe = source.wireframe;
this.wireframeLinewidth = source.wireframeLinewidth;
this.wireframeLinecap = source.wireframeLinecap;
this.wireframeLinejoin = source.wireframeLinejoin;
this.skinning = source.skinning;
this.morphTargets = source.morphTargets;
this.morphNormals = source.morphNormals;
return this;
};
/**
* @author WestLangley / http://github.com/WestLangley
*
* parameters = {
* reflectivity: <float>
* }
*/
function MeshPhysicalMaterial( parameters ) {
MeshStandardMaterial.call( this );
this.defines = { 'PHYSICAL': '' };
this.type = 'MeshPhysicalMaterial';
this.reflectivity = 0.5; // maps to F0 = 0.04
this.clearCoat = 0.0;
this.clearCoatRoughness = 0.0;
this.setValues( parameters );
}
MeshPhysicalMaterial.prototype = Object.create( MeshStandardMaterial.prototype );
MeshPhysicalMaterial.prototype.constructor = MeshPhysicalMaterial;
MeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true;
MeshPhysicalMaterial.prototype.copy = function ( source ) {
MeshStandardMaterial.prototype.copy.call( this, source );
this.defines = { 'PHYSICAL': '' };
this.reflectivity = source.reflectivity;
this.clearCoat = source.clearCoat;
this.clearCoatRoughness = source.clearCoatRoughness;
return this;
};
/**
* @author mrdoob / http://mrdoob.com/
* @author alteredq / http://alteredqualia.com/
*
* parameters = {
* color: <hex>,
* specular: <hex>,
* shininess: <float>,
* opacity: <float>,
*
* map: new THREE.Texture( <Image> ),
*
* lightMap: new THREE.Texture( <Image> ),
* lightMapIntensity: <float>
*
* aoMap: new THREE.Texture( <Image> ),
* aoMapIntensity: <float>
*
* emissive: <hex>,
* emissiveIntensity: <float>
* emissiveMap: new THREE.Texture( <Image> ),
*
* bumpMap: new THREE.Texture( <Image> ),
* bumpScale: <float>,
*
* normalMap: new THREE.Texture( <Image> ),
* normalScale: <Vector2>,
*
* displacementMap: new THREE.Texture( <Image> ),
* displacementScale: <float>,
* displacementBias: <float>,
*
* specularMap: new THREE.Texture( <Image> ),
*
* alphaMap: new THREE.Texture( <Image> ),
*
* envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),
* combine: THREE.Multiply,
* reflectivity: <float>,
* refractionRatio: <float>,
*
* wireframe: <boolean>,
* wireframeLinewidth: <float>,
*
* skinning: <bool>,
* morphTargets: <bool>,
* morphNormals: <bool>
* }
*/
function MeshPhongMaterial( parameters ) {
Material.call( this );
this.type = 'MeshPhongMaterial';
this.color = new Color( 0xffffff ); // diffuse
this.specular = new Color( 0x111111 );
this.shininess = 30;
this.map = null;
this.lightMap = null;
this.lightMapIntensity = 1.0;
this.aoMap = null;
this.aoMapIntensity = 1.0;
this.emissive = new Color( 0x000000 );
this.emissiveIntensity = 1.0;
this.emissiveMap = null;
this.bumpMap = null;
this.bumpScale = 1;
this.normalMap = null;
this.normalScale = new Vector2( 1, 1 );
this.displacementMap = null;
this.displacementScale = 1;
this.displacementBias = 0;
this.specularMap = null;
this.alphaMap = null;
this.envMap = null;
this.combine = MultiplyOperation;
this.reflectivity = 1;
this.refractionRatio = 0.98;
this.wireframe = false;
this.wireframeLinewidth = 1;
this.wireframeLinecap = 'round';
this.wireframeLinejoin = 'round';
this.skinning = false;
this.morphTargets = false;
this.morphNormals = false;
this.setValues( parameters );
}
MeshPhongMaterial.prototype = Object.create( Material.prototype );
MeshPhongMaterial.prototype.constructor = MeshPhongMaterial;
MeshPhongMaterial.prototype.isMeshPhongMaterial = true;
MeshPhongMaterial.prototype.copy = function ( source ) {
Material.prototype.copy.call( this, source );
this.color.copy( source.color );
this.specular.copy( source.specular );
this.shininess = source.shininess;
this.map = source.map;
this.lightMap = source.lightMap;
this.lightMapIntensity = source.lightMapIntensity;
this.aoMap = source.aoMap;
this.aoMapIntensity = source.aoMapIntensity;
this.emissive.copy( source.emissive );
this.emissiveMap = source.emissiveMap;
this.emissiveIntensity = source.emissiveIntensity;
this.bumpMap = source.bumpMap;
this.bumpScale = source.bumpScale;
this.normalMap = source.normalMap;
this.normalScale.copy( source.normalScale );
this.displacementMap = source.displacementMap;
this.displacementScale = source.displacementScale;
this.displacementBias = source.displacementBias;
this.specularMap = source.specularMap;
this.alphaMap = source.alphaMap;
this.envMap = source.envMap;
this.combine = source.combine;
this.reflectivity = source.reflectivity;
this.refractionRatio = source.refractionRatio;
this.wireframe = source.wireframe;
this.wireframeLinewidth = source.wireframeLinewidth;
this.wireframeLinecap = source.wireframeLinecap;
this.wireframeLinejoin = source.wireframeLinejoin;
this.skinning = source.skinning;
this.morphTargets = source.morphTargets;
this.morphNormals = source.morphNormals;
return this;
};
/**
* @author takahirox / http://github.com/takahirox
*
* parameters = {
* gradientMap: new THREE.Texture( <Image> )
* }
*/
function MeshToonMaterial( parameters ) {
MeshPhongMaterial.call( this );
this.defines = { 'TOON': '' };
this.type = 'MeshToonMaterial';
this.gradientMap = null;
this.setValues( parameters );
}
MeshToonMaterial.prototype = Object.create( MeshPhongMaterial.prototype );
MeshToonMaterial.prototype.constructor = MeshToonMaterial;
MeshToonMaterial.prototype.isMeshToonMaterial = true;
MeshToonMaterial.prototype.copy = function ( source ) {
MeshPhongMaterial.prototype.copy.call( this, source );
this.gradientMap = source.gradientMap;
return this;
};
/**
* @author mrdoob / http://mrdoob.com/
* @author WestLangley / http://github.com/WestLangley
*
* parameters = {
* opacity: <float>,
*
* bumpMap: new THREE.Texture( <Image> ),
* bumpScale: <float>,
*
* normalMap: new THREE.Texture( <Image> ),
* normalScale: <Vector2>,
*
* displacementMap: new THREE.Texture( <Image> ),
* displacementScale: <float>,
* displacementBias: <float>,
*
* wireframe: <boolean>,
* wireframeLinewidth: <float>
*
* skinning: <bool>,
* morphTargets: <bool>,
* morphNormals: <bool>
* }
*/
function MeshNormalMaterial( parameters ) {
Material.call( this );
this.type = 'MeshNormalMaterial';
this.bumpMap = null;
this.bumpScale = 1;
this.normalMap = null;
this.normalScale = new Vector2( 1, 1 );
this.displacementMap = null;
this.displacementScale = 1;
this.displacementBias = 0;
this.wireframe = false;
this.wireframeLinewidth = 1;
this.fog = false;
this.lights = false;
this.skinning = false;
this.morphTargets = false;
this.morphNormals = false;
this.setValues( parameters );
}
MeshNormalMaterial.prototype = Object.create( Material.prototype );
MeshNormalMaterial.prototype.constructor = MeshNormalMaterial;
MeshNormalMaterial.prototype.isMeshNormalMaterial = true;
MeshNormalMaterial.prototype.copy = function ( source ) {
Material.prototype.copy.call( this, source );
this.bumpMap = source.bumpMap;
this.bumpScale = source.bumpScale;
this.normalMap = source.normalMap;
this.normalScale.copy( source.normalScale );
this.displacementMap = source.displacementMap;
this.displacementScale = source.displacementScale;
this.displacementBias = source.displacementBias;
this.wireframe = source.wireframe;
this.wireframeLinewidth = source.wireframeLinewidth;
this.skinning = source.skinning;
this.morphTargets = source.morphTargets;
this.morphNormals = source.morphNormals;
return this;
};
/**
* @author mrdoob / http://mrdoob.com/
* @author alteredq / http://alteredqualia.com/
*
* parameters = {
* color: <hex>,
* opacity: <float>,
*
* map: new THREE.Texture( <Image> ),
*
* lightMap: new THREE.Texture( <Image> ),
* lightMapIntensity: <float>
*
* aoMap: new THREE.Texture( <Image> ),
* aoMapIntensity: <float>
*
* emissive: <hex>,
* emissiveIntensity: <float>
* emissiveMap: new THREE.Texture( <Image> ),
*
* specularMap: new THREE.Texture( <Image> ),
*
* alphaMap: new THREE.Texture( <Image> ),
*
* envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),
* combine: THREE.Multiply,
* reflectivity: <float>,
* refractionRatio: <float>,
*
* wireframe: <boolean>,
* wireframeLinewidth: <float>,
*
* skinning: <bool>,
* morphTargets: <bool>,
* morphNormals: <bool>
* }
*/
function MeshLambertMaterial( parameters ) {
Material.call( this );
this.type = 'MeshLambertMaterial';
this.color = new Color( 0xffffff ); // diffuse
this.map = null;
this.lightMap = null;
this.lightMapIntensity = 1.0;
this.aoMap = null;
this.aoMapIntensity = 1.0;
this.emissive = new Color( 0x000000 );
this.emissiveIntensity = 1.0;
this.emissiveMap = null;
this.specularMap = null;
this.alphaMap = null;
this.envMap = null;
this.combine = MultiplyOperation;
this.reflectivity = 1;
this.refractionRatio = 0.98;
this.wireframe = false;
this.wireframeLinewidth = 1;
this.wireframeLinecap = 'round';
this.wireframeLinejoin = 'round';
this.skinning = false;
this.morphTargets = false;
this.morphNormals = false;
this.setValues( parameters );
}
MeshLambertMaterial.prototype = Object.create( Material.prototype );
MeshLambertMaterial.prototype.constructor = MeshLambertMaterial;
MeshLambertMaterial.prototype.isMeshLambertMaterial = true;
MeshLambertMaterial.prototype.copy = function ( source ) {
Material.prototype.copy.call( this, source );
this.color.copy( source.color );
this.map = source.map;
this.lightMap = source.lightMap;
this.lightMapIntensity = source.lightMapIntensity;
this.aoMap = source.aoMap;
this.aoMapIntensity = source.aoMapIntensity;
this.emissive.copy( source.emissive );
this.emissiveMap = source.emissiveMap;
this.emissiveIntensity = source.emissiveIntensity;
this.specularMap = source.specularMap;
this.alphaMap = source.alphaMap;
this.envMap = source.envMap;
this.combine = source.combine;
this.reflectivity = source.reflectivity;
this.refractionRatio = source.refractionRatio;
this.wireframe = source.wireframe;
this.wireframeLinewidth = source.wireframeLinewidth;
this.wireframeLinecap = source.wireframeLinecap;
this.wireframeLinejoin = source.wireframeLinejoin;
this.skinning = source.skinning;
this.morphTargets = source.morphTargets;
this.morphNormals = source.morphNormals;
return this;
};
/**
* @author alteredq / http://alteredqualia.com/
*
* parameters = {
* color: <hex>,
* opacity: <float>,
*
* linewidth: <float>,
*
* scale: <float>,
* dashSize: <float>,
* gapSize: <float>
* }
*/
function LineDashedMaterial( parameters ) {
Material.call( this );
this.type = 'LineDashedMaterial';
this.color = new Color( 0xffffff );
this.linewidth = 1;
this.scale = 1;
this.dashSize = 3;
this.gapSize = 1;
this.lights = false;
this.setValues( parameters );
}
LineDashedMaterial.prototype = Object.create( Material.prototype );
LineDashedMaterial.prototype.constructor = LineDashedMaterial;
LineDashedMaterial.prototype.isLineDashedMaterial = true;
LineDashedMaterial.prototype.copy = function ( source ) {
Material.prototype.copy.call( this, source );
this.color.copy( source.color );
this.linewidth = source.linewidth;
this.scale = source.scale;
this.dashSize = source.dashSize;
this.gapSize = source.gapSize;
return this;
};
var Materials = Object.freeze({
ShadowMaterial: ShadowMaterial,
SpriteMaterial: SpriteMaterial,
RawShaderMaterial: RawShaderMaterial,
ShaderMaterial: ShaderMaterial,
PointsMaterial: PointsMaterial,
MeshPhysicalMaterial: MeshPhysicalMaterial,
MeshStandardMaterial: MeshStandardMaterial,
MeshPhongMaterial: MeshPhongMaterial,
MeshToonMaterial: MeshToonMaterial,
MeshNormalMaterial: MeshNormalMaterial,
MeshLambertMaterial: MeshLambertMaterial,
MeshDepthMaterial: MeshDepthMaterial,
MeshBasicMaterial: MeshBasicMaterial,
LineDashedMaterial: LineDashedMaterial,
LineBasicMaterial: LineBasicMaterial,
Material: Material
});
/**
* @author mrdoob / http://mrdoob.com/
*/
var Cache = {
enabled: false,
files: {},
add: function ( key, file ) {
if ( this.enabled === false ) return;
// console.log( 'THREE.Cache', 'Adding key:', key );
this.files[ key ] = file;
},
get: function ( key ) {
if ( this.enabled === false ) return;
// console.log( 'THREE.Cache', 'Checking key:', key );
return this.files[ key ];
},
remove: function ( key ) {
delete this.files[ key ];
},
clear: function () {
this.files = {};
}
};
/**
* @author mrdoob / http://mrdoob.com/
*/
function LoadingManager( onLoad, onProgress, onError ) {
var scope = this;
var isLoading = false, itemsLoaded = 0, itemsTotal = 0;
this.onStart = undefined;
this.onLoad = onLoad;
this.onProgress = onProgress;
this.onError = onError;
this.itemStart = function ( url ) {
itemsTotal ++;
if ( isLoading === false ) {
if ( scope.onStart !== undefined ) {
scope.onStart( url, itemsLoaded, itemsTotal );
}
}
isLoading = true;
};
this.itemEnd = function ( url ) {
itemsLoaded ++;
if ( scope.onProgress !== undefined ) {
scope.onProgress( url, itemsLoaded, itemsTotal );
}
if ( itemsLoaded === itemsTotal ) {
isLoading = false;
if ( scope.onLoad !== undefined ) {
scope.onLoad();
}
}
};
this.itemError = function ( url ) {
if ( scope.onError !== undefined ) {
scope.onError( url );
}
};
}
var DefaultLoadingManager = new LoadingManager();
/**
* @author mrdoob / http://mrdoob.com/
*/
function FileLoader( manager ) {
this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
}
Object.assign( FileLoader.prototype, {
load: function ( url, onLoad, onProgress, onError ) {
if ( url === undefined ) url = '';
if ( this.path !== undefined ) url = this.path + url;
var scope = this;
var cached = Cache.get( url );
if ( cached !== undefined ) {
scope.manager.itemStart( url );
setTimeout( function () {
if ( onLoad ) onLoad( cached );
scope.manager.itemEnd( url );
}, 0 );
return cached;
}
// Check for data: URI
var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;
var dataUriRegexResult = url.match( dataUriRegex );
// Safari can not handle Data URIs through XMLHttpRequest so process manually
if ( dataUriRegexResult ) {
var mimeType = dataUriRegexResult[ 1 ];
var isBase64 = !! dataUriRegexResult[ 2 ];
var data = dataUriRegexResult[ 3 ];
data = window.decodeURIComponent( data );
if ( isBase64 ) data = window.atob( data );
try {
var response;
var responseType = ( this.responseType || '' ).toLowerCase();
switch ( responseType ) {
case 'arraybuffer':
case 'blob':
response = new ArrayBuffer( data.length );
var view = new Uint8Array( response );
for ( var i = 0; i < data.length; i ++ ) {
view[ i ] = data.charCodeAt( i );
}
if ( responseType === 'blob' ) {
response = new Blob( [ response ], { type: mimeType } );
}
break;
case 'document':
var parser = new DOMParser();
response = parser.parseFromString( data, mimeType );
break;
case 'json':
response = JSON.parse( data );
break;
default: // 'text' or other
response = data;
break;
}
// Wait for next browser tick
window.setTimeout( function () {
if ( onLoad ) onLoad( response );
scope.manager.itemEnd( url );
}, 0 );
} catch ( error ) {
// Wait for next browser tick
window.setTimeout( function () {
if ( onError ) onError( error );
scope.manager.itemEnd( url );
scope.manager.itemError( url );
}, 0 );
}
} else {
var request = new XMLHttpRequest();
request.open( 'GET', url, true );
request.addEventListener( 'load', function ( event ) {
var response = event.target.response;
Cache.add( url, response );
if ( this.status === 200 ) {
if ( onLoad ) onLoad( response );
scope.manager.itemEnd( url );
} else if ( this.status === 0 ) {
// Some browsers return HTTP Status 0 when using non-http protocol
// e.g. 'file://' or 'data://'. Handle as success.
console.warn( 'THREE.FileLoader: HTTP Status 0 received.' );
if ( onLoad ) onLoad( response );
scope.manager.itemEnd( url );
} else {
if ( onError ) onError( event );
scope.manager.itemEnd( url );
scope.manager.itemError( url );
}
}, false );
if ( onProgress !== undefined ) {
request.addEventListener( 'progress', function ( event ) {
onProgress( event );
}, false );
}
request.addEventListener( 'error', function ( event ) {
if ( onError ) onError( event );
scope.manager.itemEnd( url );
scope.manager.itemError( url );
}, false );
if ( this.responseType !== undefined ) request.responseType = this.responseType;
if ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials;
if ( request.overrideMimeType ) request.overrideMimeType( this.mimeType !== undefined ? this.mimeType : 'text/plain' );
for ( var header in this.requestHeader ) {
request.setRequestHeader( header, this.requestHeader[ header ] );
}
request.send( null );
}
scope.manager.itemStart( url );
return request;
},
setPath: function ( value ) {
this.path = value;
return this;
},
setResponseType: function ( value ) {
this.responseType = value;
return this;
},
setWithCredentials: function ( value ) {
this.withCredentials = value;
return this;
},
setMimeType: function ( value ) {
this.mimeType = value;
return this;
},
setRequestHeader: function ( value ) {
this.requestHeader = value;
return this;
}
} );
/**
* @author mrdoob / http://mrdoob.com/
*
* Abstract Base class to block based textures loader (dds, pvr, ...)
*/
function CompressedTextureLoader( manager ) {
this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
// override in sub classes
this._parser = null;
}
Object.assign( CompressedTextureLoader.prototype, {
load: function ( url, onLoad, onProgress, onError ) {
var scope = this;
var images = [];
var texture = new CompressedTexture();
texture.image = images;
var loader = new FileLoader( this.manager );
loader.setPath( this.path );
loader.setResponseType( 'arraybuffer' );
function loadTexture( i ) {
loader.load( url[ i ], function ( buffer ) {
var texDatas = scope._parser( buffer, true );
images[ i ] = {
width: texDatas.width,
height: texDatas.height,
format: texDatas.format,
mipmaps: texDatas.mipmaps
};
loaded += 1;
if ( loaded === 6 ) {
if ( texDatas.mipmapCount === 1 )
texture.minFilter = LinearFilter;
texture.format = texDatas.format;
texture.needsUpdate = true;
if ( onLoad ) onLoad( texture );
}
}, onProgress, onError );
}
if ( Array.isArray( url ) ) {
var loaded = 0;
for ( var i = 0, il = url.length; i < il; ++ i ) {
loadTexture( i );
}
} else {
// compressed cubemap texture stored in a single DDS file
loader.load( url, function ( buffer ) {
var texDatas = scope._parser( buffer, true );
if ( texDatas.isCubemap ) {
var faces = texDatas.mipmaps.length / texDatas.mipmapCount;
for ( var f = 0; f < faces; f ++ ) {
images[ f ] = { mipmaps : [] };
for ( var i = 0; i < texDatas.mipmapCount; i ++ ) {
images[ f ].mipmaps.push( texDatas.mipmaps[ f * texDatas.mipmapCount + i ] );
images[ f ].format = texDatas.format;
images[ f ].width = texDatas.width;
images[ f ].height = texDatas.height;
}
}
} else {
texture.image.width = texDatas.width;
texture.image.height = texDatas.height;
texture.mipmaps = texDatas.mipmaps;
}
if ( texDatas.mipmapCount === 1 ) {
texture.minFilter = LinearFilter;
}
texture.format = texDatas.format;
texture.needsUpdate = true;
if ( onLoad ) onLoad( texture );
}, onProgress, onError );
}
return texture;
},
setPath: function ( value ) {
this.path = value;
return this;
}
} );
/**
* @author Nikos M. / https://github.com/foo123/
*
* Abstract Base class to load generic binary textures formats (rgbe, hdr, ...)
*/
function DataTextureLoader( manager ) {
this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
// override in sub classes
this._parser = null;
}
Object.assign( DataTextureLoader.prototype, {
load: function ( url, onLoad, onProgress, onError ) {
var scope = this;
var texture = new DataTexture();
var loader = new FileLoader( this.manager );
loader.setResponseType( 'arraybuffer' );
loader.load( url, function ( buffer ) {
var texData = scope._parser( buffer );
if ( ! texData ) return;
if ( undefined !== texData.image ) {
texture.image = texData.image;
} else if ( undefined !== texData.data ) {
texture.image.width = texData.width;
texture.image.height = texData.height;
texture.image.data = texData.data;
}
texture.wrapS = undefined !== texData.wrapS ? texData.wrapS : ClampToEdgeWrapping;
texture.wrapT = undefined !== texData.wrapT ? texData.wrapT : ClampToEdgeWrapping;
texture.magFilter = undefined !== texData.magFilter ? texData.magFilter : LinearFilter;
texture.minFilter = undefined !== texData.minFilter ? texData.minFilter : LinearMipMapLinearFilter;
texture.anisotropy = undefined !== texData.anisotropy ? texData.anisotropy : 1;
if ( undefined !== texData.format ) {
texture.format = texData.format;
}
if ( undefined !== texData.type ) {
texture.type = texData.type;
}
if ( undefined !== texData.mipmaps ) {
texture.mipmaps = texData.mipmaps;
}
if ( 1 === texData.mipmapCount ) {
texture.minFilter = LinearFilter;
}
texture.needsUpdate = true;
if ( onLoad ) onLoad( texture, texData );
}, onProgress, onError );
return texture;
}
} );
/**
* @author mrdoob / http://mrdoob.com/
*/
function ImageLoader( manager ) {
this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
}
Object.assign( ImageLoader.prototype, {
load: function ( url, onLoad, onProgress, onError ) {
if ( url === undefined ) url = '';
if ( this.path !== undefined ) url = this.path + url;
var scope = this;
var cached = Cache.get( url );
if ( cached !== undefined ) {
scope.manager.itemStart( url );
setTimeout( function () {
if ( onLoad ) onLoad( cached );
scope.manager.itemEnd( url );
}, 0 );
return cached;
}
var image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' );
image.addEventListener( 'load', function () {
Cache.add( url, this );
if ( onLoad ) onLoad( this );
scope.manager.itemEnd( url );
}, false );
/*
image.addEventListener( 'progress', function ( event ) {
if ( onProgress ) onProgress( event );
}, false );
*/
image.addEventListener( 'error', function ( event ) {
if ( onError ) onError( event );
scope.manager.itemEnd( url );
scope.manager.itemError( url );
}, false );
if ( url.substr( 0, 5 ) !== 'data:' ) {
if ( this.crossOrigin !== undefined ) image.crossOrigin = this.crossOrigin;
}
scope.manager.itemStart( url );
image.src = url;
return image;
},
setCrossOrigin: function ( value ) {
this.crossOrigin = value;
return this;
},
setPath: function ( value ) {
this.path = value;
return this;
}
} );
/**
* @author mrdoob / http://mrdoob.com/
*/
function CubeTextureLoader( manager ) {
this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
}
Object.assign( CubeTextureLoader.prototype, {
load: function ( urls, onLoad, onProgress, onError ) {
var texture = new CubeTexture();
var loader = new ImageLoader( this.manager );
loader.setCrossOrigin( this.crossOrigin );
loader.setPath( this.path );
var loaded = 0;
function loadTexture( i ) {
loader.load( urls[ i ], function ( image ) {
texture.images[ i ] = image;
loaded ++;
if ( loaded === 6 ) {
texture.needsUpdate = true;
if ( onLoad ) onLoad( texture );
}
}, undefined, onError );
}
for ( var i = 0; i < urls.length; ++ i ) {
loadTexture( i );
}
return texture;
},
setCrossOrigin: function ( value ) {
this.crossOrigin = value;
return this;
},
setPath: function ( value ) {
this.path = value;
return this;
}
} );
/**
* @author mrdoob / http://mrdoob.com/
*/
function TextureLoader( manager ) {
this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
}
Object.assign( TextureLoader.prototype, {
load: function ( url, onLoad, onProgress, onError ) {
var loader = new ImageLoader( this.manager );
loader.setCrossOrigin( this.crossOrigin );
loader.setPath( this.path );
var texture = new Texture();
texture.image = loader.load( url, function () {
// JPEGs can't have an alpha channel, so memory can be saved by storing them as RGB.
var isJPEG = url.search( /\.(jpg|jpeg)$/ ) > 0 || url.search( /^data\:image\/jpeg/ ) === 0;
texture.format = isJPEG ? RGBFormat : RGBAFormat;
texture.needsUpdate = true;
if ( onLoad !== undefined ) {
onLoad( texture );
}
}, onProgress, onError );
return texture;
},
setCrossOrigin: function ( value ) {
this.crossOrigin = value;
return this;
},
setPath: function ( value ) {
this.path = value;
return this;
}
} );
/**
* @author mrdoob / http://mrdoob.com/
* @author alteredq / http://alteredqualia.com/
*/
function Light( color, intensity ) {
Object3D.call( this );
this.type = 'Light';
this.color = new Color( color );
this.intensity = intensity !== undefined ? intensity : 1;
this.receiveShadow = undefined;
}
Light.prototype = Object.assign( Object.create( Object3D.prototype ), {
constructor: Light,
isLight: true,
copy: function ( source ) {
Object3D.prototype.copy.call( this, source );
this.color.copy( source.color );
this.intensity = source.intensity;
return this;
},
toJSON: function ( meta ) {
var data = Object3D.prototype.toJSON.call( this, meta );
data.object.color = this.color.getHex();
data.object.intensity = this.intensity;
if ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex();
if ( this.distance !== undefined ) data.object.distance = this.distance;
if ( this.angle !== undefined ) data.object.angle = this.angle;
if ( this.decay !== undefined ) data.object.decay = this.decay;
if ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra;
if ( this.shadow !== undefined ) data.object.shadow = this.shadow.toJSON();
return data;
}
} );
/**
* @author alteredq / http://alteredqualia.com/
*/
function HemisphereLight( skyColor, groundColor, intensity ) {
Light.call( this, skyColor, intensity );
this.type = 'HemisphereLight';
this.castShadow = undefined;
this.position.copy( Object3D.DefaultUp );
this.updateMatrix();
this.groundColor = new Color( groundColor );
}
HemisphereLight.prototype = Object.assign( Object.create( Light.prototype ), {
constructor: HemisphereLight,
isHemisphereLight: true,
copy: function ( source ) {
Light.prototype.copy.call( this, source );
this.groundColor.copy( source.groundColor );
return this;
}
} );
/**
* @author mrdoob / http://mrdoob.com/
*/
function LightShadow( camera ) {
this.camera = camera;
this.bias = 0;
this.radius = 1;
this.mapSize = new Vector2( 512, 512 );
this.map = null;
this.matrix = new Matrix4();
}
Object.assign( LightShadow.prototype, {
copy: function ( source ) {
this.camera = source.camera.clone();
this.bias = source.bias;
this.radius = source.radius;
this.mapSize.copy( source.mapSize );
return this;
},
clone: function () {
return new this.constructor().copy( this );
},
toJSON: function () {
var object = {};
if ( this.bias !== 0 ) object.bias = this.bias;
if ( this.radius !== 1 ) object.radius = this.radius;
if ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) object.mapSize = this.mapSize.toArray();
object.camera = this.camera.toJSON( false ).object;
delete object.camera.matrix;
return object;
}
} );
/**
* @author mrdoob / http://mrdoob.com/
*/
function SpotLightShadow() {
LightShadow.call( this, new PerspectiveCamera( 50, 1, 0.5, 500 ) );
}
SpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {
constructor: SpotLightShadow,
isSpotLightShadow: true,
update: function ( light ) {
var camera = this.camera;
var fov = _Math.RAD2DEG * 2 * light.angle;
var aspect = this.mapSize.width / this.mapSize.height;
var far = light.distance || camera.far;
if ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) {
camera.fov = fov;
camera.aspect = aspect;
camera.far = far;
camera.updateProjectionMatrix();
}
}
} );
/**
* @author alteredq / http://alteredqualia.com/
*/
function SpotLight( color, intensity, distance, angle, penumbra, decay ) {
Light.call( this, color, intensity );
this.type = 'SpotLight';
this.position.copy( Object3D.DefaultUp );
this.updateMatrix();
this.target = new Object3D();
Object.defineProperty( this, 'power', {
get: function () {
// intensity = power per solid angle.
// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf
return this.intensity * Math.PI;
},
set: function ( power ) {
// intensity = power per solid angle.
// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf
this.intensity = power / Math.PI;
}
} );
this.distance = ( distance !== undefined ) ? distance : 0;
this.angle = ( angle !== undefined ) ? angle : Math.PI / 3;
this.penumbra = ( penumbra !== undefined ) ? penumbra : 0;
this.decay = ( decay !== undefined ) ? decay : 1; // for physically correct lights, should be 2.
this.shadow = new SpotLightShadow();
}
SpotLight.prototype = Object.assign( Object.create( Light.prototype ), {
constructor: SpotLight,
isSpotLight: true,
copy: function ( source ) {
Light.prototype.copy.call( this, source );
this.distance = source.distance;
this.angle = source.angle;
this.penumbra = source.penumbra;
this.decay = source.decay;
this.target = source.target.clone();
this.shadow = source.shadow.clone();
return this;
}
} );
/**
* @author mrdoob / http://mrdoob.com/
*/
function PointLight( color, intensity, distance, decay ) {
Light.call( this, color, intensity );
this.type = 'PointLight';
Object.defineProperty( this, 'power', {
get: function () {
// intensity = power per solid angle.
// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf
return this.intensity * 4 * Math.PI;
},
set: function ( power ) {
// intensity = power per solid angle.
// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf
this.intensity = power / ( 4 * Math.PI );
}
} );
this.distance = ( distance !== undefined ) ? distance : 0;
this.decay = ( decay !== undefined ) ? decay : 1; // for physically correct lights, should be 2.
this.shadow = new LightShadow( new PerspectiveCamera( 90, 1, 0.5, 500 ) );
}
PointLight.prototype = Object.assign( Object.create( Light.prototype ), {
constructor: PointLight,
isPointLight: true,
copy: function ( source ) {
Light.prototype.copy.call( this, source );
this.distance = source.distance;
this.decay = source.decay;
this.shadow = source.shadow.clone();
return this;
}
} );
/**
* @author mrdoob / http://mrdoob.com/
*/
function DirectionalLightShadow( ) {
LightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) );
}
DirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {
constructor: DirectionalLightShadow
} );
/**
* @author mrdoob / http://mrdoob.com/
* @author alteredq / http://alteredqualia.com/
*/
function DirectionalLight( color, intensity ) {
Light.call( this, color, intensity );
this.type = 'DirectionalLight';
this.position.copy( Object3D.DefaultUp );
this.updateMatrix();
this.target = new Object3D();
this.shadow = new DirectionalLightShadow();
}
DirectionalLight.prototype = Object.assign( Object.create( Light.prototype ), {
constructor: DirectionalLight,
isDirectionalLight: true,
copy: function ( source ) {
Light.prototype.copy.call( this, source );
this.target = source.target.clone();
this.shadow = source.shadow.clone();
return this;
}
} );
/**
* @author mrdoob / http://mrdoob.com/
*/
function AmbientLight( color, intensity ) {
Light.call( this, color, intensity );
this.type = 'AmbientLight';
this.castShadow = undefined;
}
AmbientLight.prototype = Object.assign( Object.create( Light.prototype ), {
constructor: AmbientLight,
isAmbientLight: true
} );
/**
* @author abelnation / http://github.com/abelnation
*/
function RectAreaLight( color, intensity, width, height ) {
Light.call( this, color, intensity );
this.type = 'RectAreaLight';
this.position.set( 0, 1, 0 );
this.updateMatrix();
this.width = ( width !== undefined ) ? width : 10;
this.height = ( height !== undefined ) ? height : 10;
// TODO (abelnation): distance/decay
// TODO (abelnation): update method for RectAreaLight to update transform to lookat target
// TODO (abelnation): shadows
}
// TODO (abelnation): RectAreaLight update when light shape is changed
RectAreaLight.prototype = Object.assign( Object.create( Light.prototype ), {
constructor: RectAreaLight,
isRectAreaLight: true,
copy: function ( source ) {
Light.prototype.copy.call( this, source );
this.width = source.width;
this.height = source.height;
return this;
},
toJSON: function ( meta ) {
var data = Light.prototype.toJSON.call( this, meta );
data.object.width = this.width;
data.object.height = this.height;
return data;
}
} );
/**
* @author tschw
* @author Ben Houston / http://clara.io/
* @author David Sarno / http://lighthaus.us/
*/
var AnimationUtils = {
// same as Array.prototype.slice, but also works on typed arrays
arraySlice: function ( array, from, to ) {
if ( AnimationUtils.isTypedArray( array ) ) {
// in ios9 array.subarray(from, undefined) will return empty array
// but array.subarray(from) or array.subarray(from, len) is correct
return new array.constructor( array.subarray( from, to !== undefined ? to : array.length ) );
}
return array.slice( from, to );
},
// converts an array to a specific type
convertArray: function ( array, type, forceClone ) {
if ( ! array || // let 'undefined' and 'null' pass
! forceClone && array.constructor === type ) return array;
if ( typeof type.BYTES_PER_ELEMENT === 'number' ) {
return new type( array ); // create typed array
}
return Array.prototype.slice.call( array ); // create Array
},
isTypedArray: function ( object ) {
return ArrayBuffer.isView( object ) &&
! ( object instanceof DataView );
},
// returns an array by which times and values can be sorted
getKeyframeOrder: function ( times ) {
function compareTime( i, j ) {
return times[ i ] - times[ j ];
}
var n = times.length;
var result = new Array( n );
for ( var i = 0; i !== n; ++ i ) result[ i ] = i;
result.sort( compareTime );
return result;
},
// uses the array previously returned by 'getKeyframeOrder' to sort data
sortedArray: function ( values, stride, order ) {
var nValues = values.length;
var result = new values.constructor( nValues );
for ( var i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) {
var srcOffset = order[ i ] * stride;
for ( var j = 0; j !== stride; ++ j ) {
result[ dstOffset ++ ] = values[ srcOffset + j ];
}
}
return result;
},
// function for parsing AOS keyframe formats
flattenJSON: function ( jsonKeys, times, values, valuePropertyName ) {
var i = 1, key = jsonKeys[ 0 ];
while ( key !== undefined && key[ valuePropertyName ] === undefined ) {
key = jsonKeys[ i ++ ];
}
if ( key === undefined ) return; // no data
var value = key[ valuePropertyName ];
if ( value === undefined ) return; // no data
if ( Array.isArray( value ) ) {
do {
value = key[ valuePropertyName ];
if ( value !== undefined ) {
times.push( key.time );
values.push.apply( values, value ); // push all elements
}
key = jsonKeys[ i ++ ];
} while ( key !== undefined );
} else if ( value.toArray !== undefined ) {
// ...assume THREE.Math-ish
do {
value = key[ valuePropertyName ];
if ( value !== undefined ) {
times.push( key.time );
value.toArray( values, values.length );
}
key = jsonKeys[ i ++ ];
} while ( key !== undefined );
} else {
// otherwise push as-is
do {
value = key[ valuePropertyName ];
if ( value !== undefined ) {
times.push( key.time );
values.push( value );
}
key = jsonKeys[ i ++ ];
} while ( key !== undefined );
}
}
};
/**
* Abstract base class of interpolants over parametric samples.
*
* The parameter domain is one dimensional, typically the time or a path
* along a curve defined by the data.
*
* The sample values can have any dimensionality and derived classes may
* apply special interpretations to the data.
*
* This class provides the interval seek in a Template Method, deferring
* the actual interpolation to derived classes.
*
* Time complexity is O(1) for linear access crossing at most two points
* and O(log N) for random access, where N is the number of positions.
*
* References:
*
* http://www.oodesign.com/template-method-pattern.html
*
* @author tschw
*/
function Interpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
this.parameterPositions = parameterPositions;
this._cachedIndex = 0;
this.resultBuffer = resultBuffer !== undefined ?
resultBuffer : new sampleValues.constructor( sampleSize );
this.sampleValues = sampleValues;
this.valueSize = sampleSize;
}
Object.assign( Interpolant.prototype, {
evaluate: function( t ) {
var pp = this.parameterPositions,
i1 = this._cachedIndex,
t1 = pp[ i1 ],
t0 = pp[ i1 - 1 ];
validate_interval: {
seek: {
var right;
linear_scan: {
//- See http://jsperf.com/comparison-to-undefined/3
//- slower code:
//-
//- if ( t >= t1 || t1 === undefined ) {
forward_scan: if ( ! ( t < t1 ) ) {
for ( var giveUpAt = i1 + 2; ;) {
if ( t1 === undefined ) {
if ( t < t0 ) break forward_scan;
// after end
i1 = pp.length;
this._cachedIndex = i1;
return this.afterEnd_( i1 - 1, t, t0 );
}
if ( i1 === giveUpAt ) break; // this loop
t0 = t1;
t1 = pp[ ++ i1 ];
if ( t < t1 ) {
// we have arrived at the sought interval
break seek;
}
}
// prepare binary search on the right side of the index
right = pp.length;
break linear_scan;
}
//- slower code:
//- if ( t < t0 || t0 === undefined ) {
if ( ! ( t >= t0 ) ) {
// looping?
var t1global = pp[ 1 ];
if ( t < t1global ) {
i1 = 2; // + 1, using the scan for the details
t0 = t1global;
}
// linear reverse scan
for ( var giveUpAt = i1 - 2; ;) {
if ( t0 === undefined ) {
// before start
this._cachedIndex = 0;
return this.beforeStart_( 0, t, t1 );
}
if ( i1 === giveUpAt ) break; // this loop
t1 = t0;
t0 = pp[ -- i1 - 1 ];
if ( t >= t0 ) {
// we have arrived at the sought interval
break seek;
}
}
// prepare binary search on the left side of the index
right = i1;
i1 = 0;
break linear_scan;
}
// the interval is valid
break validate_interval;
} // linear scan
// binary search
while ( i1 < right ) {
var mid = ( i1 + right ) >>> 1;
if ( t < pp[ mid ] ) {
right = mid;
} else {
i1 = mid + 1;
}
}
t1 = pp[ i1 ];
t0 = pp[ i1 - 1 ];
// check boundary cases, again
if ( t0 === undefined ) {
this._cachedIndex = 0;
return this.beforeStart_( 0, t, t1 );
}
if ( t1 === undefined ) {
i1 = pp.length;
this._cachedIndex = i1;
return this.afterEnd_( i1 - 1, t0, t );
}
} // seek
this._cachedIndex = i1;
this.intervalChanged_( i1, t0, t1 );
} // validate_interval
return this.interpolate_( i1, t0, t, t1 );
},
settings: null, // optional, subclass-specific settings structure
// Note: The indirection allows central control of many interpolants.
// --- Protected interface
DefaultSettings_: {},
getSettings_: function() {
return this.settings || this.DefaultSettings_;
},
copySampleValue_: function( index ) {
// copies a sample value to the result buffer
var result = this.resultBuffer,
values = this.sampleValues,
stride = this.valueSize,
offset = index * stride;
for ( var i = 0; i !== stride; ++ i ) {
result[ i ] = values[ offset + i ];
}
return result;
},
// Template methods for derived classes:
interpolate_: function( i1, t0, t, t1 ) {
throw new Error( "call to abstract method" );
// implementations shall return this.resultBuffer
},
intervalChanged_: function( i1, t0, t1 ) {
// empty
}
} );
//!\ DECLARE ALIAS AFTER assign prototype !
Object.assign( Interpolant.prototype, {
//( 0, t, t0 ), returns this.resultBuffer
beforeStart_: Interpolant.prototype.copySampleValue_,
//( N-1, tN-1, t ), returns this.resultBuffer
afterEnd_: Interpolant.prototype.copySampleValue_,
} );
/**
* Fast and simple cubic spline interpolant.
*
* It was derived from a Hermitian construction setting the first derivative
* at each sample position to the linear slope between neighboring positions
* over their parameter interval.
*
* @author tschw
*/
function CubicInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
Interpolant.call(
this, parameterPositions, sampleValues, sampleSize, resultBuffer );
this._weightPrev = -0;
this._offsetPrev = -0;
this._weightNext = -0;
this._offsetNext = -0;
}
CubicInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), {
constructor: CubicInterpolant,
DefaultSettings_: {
endingStart: ZeroCurvatureEnding,
endingEnd: ZeroCurvatureEnding
},
intervalChanged_: function( i1, t0, t1 ) {
var pp = this.parameterPositions,
iPrev = i1 - 2,
iNext = i1 + 1,
tPrev = pp[ iPrev ],
tNext = pp[ iNext ];
if ( tPrev === undefined ) {
switch ( this.getSettings_().endingStart ) {
case ZeroSlopeEnding:
// f'(t0) = 0
iPrev = i1;
tPrev = 2 * t0 - t1;
break;
case WrapAroundEnding:
// use the other end of the curve
iPrev = pp.length - 2;
tPrev = t0 + pp[ iPrev ] - pp[ iPrev + 1 ];
break;
default: // ZeroCurvatureEnding
// f''(t0) = 0 a.k.a. Natural Spline
iPrev = i1;
tPrev = t1;
}
}
if ( tNext === undefined ) {
switch ( this.getSettings_().endingEnd ) {
case ZeroSlopeEnding:
// f'(tN) = 0
iNext = i1;
tNext = 2 * t1 - t0;
break;
case WrapAroundEnding:
// use the other end of the curve
iNext = 1;
tNext = t1 + pp[ 1 ] - pp[ 0 ];
break;
default: // ZeroCurvatureEnding
// f''(tN) = 0, a.k.a. Natural Spline
iNext = i1 - 1;
tNext = t0;
}
}
var halfDt = ( t1 - t0 ) * 0.5,
stride = this.valueSize;
this._weightPrev = halfDt / ( t0 - tPrev );
this._weightNext = halfDt / ( tNext - t1 );
this._offsetPrev = iPrev * stride;
this._offsetNext = iNext * stride;
},
interpolate_: function( i1, t0, t, t1 ) {
var result = this.resultBuffer,
values = this.sampleValues,
stride = this.valueSize,
o1 = i1 * stride, o0 = o1 - stride,
oP = this._offsetPrev, oN = this._offsetNext,
wP = this._weightPrev, wN = this._weightNext,
p = ( t - t0 ) / ( t1 - t0 ),
pp = p * p,
ppp = pp * p;
// evaluate polynomials
var sP = - wP * ppp + 2 * wP * pp - wP * p;
var s0 = ( 1 + wP ) * ppp + (-1.5 - 2 * wP ) * pp + ( -0.5 + wP ) * p + 1;
var s1 = (-1 - wN ) * ppp + ( 1.5 + wN ) * pp + 0.5 * p;
var sN = wN * ppp - wN * pp;
// combine data linearly
for ( var i = 0; i !== stride; ++ i ) {
result[ i ] =
sP * values[ oP + i ] +
s0 * values[ o0 + i ] +
s1 * values[ o1 + i ] +
sN * values[ oN + i ];
}
return result;
}
} );
/**
* @author tschw
*/
function LinearInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );
}
LinearInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), {
constructor: LinearInterpolant,
interpolate_: function( i1, t0, t, t1 ) {
var result = this.resultBuffer,
values = this.sampleValues,
stride = this.valueSize,
offset1 = i1 * stride,
offset0 = offset1 - stride,
weight1 = ( t - t0 ) / ( t1 - t0 ),
weight0 = 1 - weight1;
for ( var i = 0; i !== stride; ++ i ) {
result[ i ] =
values[ offset0 + i ] * weight0 +
values[ offset1 + i ] * weight1;
}
return result;
}
} );
/**
*
* Interpolant that evaluates to the sample value at the position preceeding
* the parameter.
*
* @author tschw
*/
function DiscreteInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );
}
DiscreteInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), {
constructor: DiscreteInterpolant,
interpolate_: function( i1, t0, t, t1 ) {
return this.copySampleValue_( i1 - 1 );
}
} );
var KeyframeTrackPrototype;
KeyframeTrackPrototype = {
TimeBufferType: Float32Array,
ValueBufferType: Float32Array,
DefaultInterpolation: InterpolateLinear,
InterpolantFactoryMethodDiscrete: function ( result ) {
return new DiscreteInterpolant(
this.times, this.values, this.getValueSize(), result );
},
InterpolantFactoryMethodLinear: function ( result ) {
return new LinearInterpolant(
this.times, this.values, this.getValueSize(), result );
},
InterpolantFactoryMethodSmooth: function ( result ) {
return new CubicInterpolant(
this.times, this.values, this.getValueSize(), result );
},
setInterpolation: function ( interpolation ) {
var factoryMethod;
switch ( interpolation ) {
case InterpolateDiscrete:
factoryMethod = this.InterpolantFactoryMethodDiscrete;
break;
case InterpolateLinear:
factoryMethod = this.InterpolantFactoryMethodLinear;
break;
case InterpolateSmooth:
factoryMethod = this.InterpolantFactoryMethodSmooth;
break;
}
if ( factoryMethod === undefined ) {
var message = "unsupported interpolation for " +
this.ValueTypeName + " keyframe track named " + this.name;
if ( this.createInterpolant === undefined ) {
// fall back to default, unless the default itself is messed up
if ( interpolation !== this.DefaultInterpolation ) {
this.setInterpolation( this.DefaultInterpolation );
} else {
throw new Error( message ); // fatal, in this case
}
}
console.warn( 'THREE.KeyframeTrackPrototype:', message );
return;
}
this.createInterpolant = factoryMethod;
},
getInterpolation: function () {
switch ( this.createInterpolant ) {
case this.InterpolantFactoryMethodDiscrete:
return InterpolateDiscrete;
case this.InterpolantFactoryMethodLinear:
return InterpolateLinear;
case this.InterpolantFactoryMethodSmooth:
return InterpolateSmooth;
}
},
getValueSize: function () {
return this.values.length / this.times.length;
},
// move all keyframes either forwards or backwards in time
shift: function ( timeOffset ) {
if ( timeOffset !== 0.0 ) {
var times = this.times;
for ( var i = 0, n = times.length; i !== n; ++ i ) {
times[ i ] += timeOffset;
}
}
return this;
},
// scale all keyframe times by a factor (useful for frame <-> seconds conversions)
scale: function ( timeScale ) {
if ( timeScale !== 1.0 ) {
var times = this.times;
for ( var i = 0, n = times.length; i !== n; ++ i ) {
times[ i ] *= timeScale;
}
}
return this;
},
// removes keyframes before and after animation without changing any values within the range [startTime, endTime].
// IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values
trim: function ( startTime, endTime ) {
var times = this.times,
nKeys = times.length,
from = 0,
to = nKeys - 1;
while ( from !== nKeys && times[ from ] < startTime ) ++ from;
while ( to !== - 1 && times[ to ] > endTime ) -- to;
++ to; // inclusive -> exclusive bound
if ( from !== 0 || to !== nKeys ) {
// empty tracks are forbidden, so keep at least one keyframe
if ( from >= to ) to = Math.max( to, 1 ), from = to - 1;
var stride = this.getValueSize();
this.times = AnimationUtils.arraySlice( times, from, to );
this.values = AnimationUtils.
arraySlice( this.values, from * stride, to * stride );
}
return this;
},
// ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable
validate: function () {
var valid = true;
var valueSize = this.getValueSize();
if ( valueSize - Math.floor( valueSize ) !== 0 ) {
console.error( 'THREE.KeyframeTrackPrototype: Invalid value size in track.', this );
valid = false;
}
var times = this.times,
values = this.values,
nKeys = times.length;
if ( nKeys === 0 ) {
console.error( 'THREE.KeyframeTrackPrototype: Track is empty.', this );
valid = false;
}
var prevTime = null;
for ( var i = 0; i !== nKeys; i ++ ) {
var currTime = times[ i ];
if ( typeof currTime === 'number' && isNaN( currTime ) ) {
console.error( 'THREE.KeyframeTrackPrototype: Time is not a valid number.', this, i, currTime );
valid = false;
break;
}
if ( prevTime !== null && prevTime > currTime ) {
console.error( 'THREE.KeyframeTrackPrototype: Out of order keys.', this, i, currTime, prevTime );
valid = false;
break;
}
prevTime = currTime;
}
if ( values !== undefined ) {
if ( AnimationUtils.isTypedArray( values ) ) {
for ( var i = 0, n = values.length; i !== n; ++ i ) {
var value = values[ i ];
if ( isNaN( value ) ) {
console.error( 'THREE.KeyframeTrackPrototype: Value is not a valid number.', this, i, value );
valid = false;
break;
}
}
}
}
return valid;
},
// removes equivalent sequential keys as common in morph target sequences
// (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0)
optimize: function () {
var times = this.times,
values = this.values,
stride = this.getValueSize(),
smoothInterpolation = this.getInterpolation() === InterpolateSmooth,
writeIndex = 1,
lastIndex = times.length - 1;
for ( var i = 1; i < lastIndex; ++ i ) {
var keep = false;
var time = times[ i ];
var timeNext = times[ i + 1 ];
// remove adjacent keyframes scheduled at the same time
if ( time !== timeNext && ( i !== 1 || time !== time[ 0 ] ) ) {
if ( ! smoothInterpolation ) {
// remove unnecessary keyframes same as their neighbors
var offset = i * stride,
offsetP = offset - stride,
offsetN = offset + stride;
for ( var j = 0; j !== stride; ++ j ) {
var value = values[ offset + j ];
if ( value !== values[ offsetP + j ] ||
value !== values[ offsetN + j ] ) {
keep = true;
break;
}
}
} else keep = true;
}
// in-place compaction
if ( keep ) {
if ( i !== writeIndex ) {
times[ writeIndex ] = times[ i ];
var readOffset = i * stride,
writeOffset = writeIndex * stride;
for ( var j = 0; j !== stride; ++ j )
values[ writeOffset + j ] = values[ readOffset + j ];
}
++ writeIndex;
}
}
// flush last keyframe (compaction looks ahead)
if ( lastIndex > 0 ) {
times[ writeIndex ] = times[ lastIndex ];
for ( var readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++ j )
values[ writeOffset + j ] = values[ readOffset + j ];
++ writeIndex;
}
if ( writeIndex !== times.length ) {
this.times = AnimationUtils.arraySlice( times, 0, writeIndex );
this.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride );
}
return this;
}
};
function KeyframeTrackConstructor( name, times, values, interpolation ) {
if ( name === undefined ) throw new Error( "track name is undefined" );
if ( times === undefined || times.length === 0 ) {
throw new Error( "no keyframes in track named " + name );
}
this.name = name;
this.times = AnimationUtils.convertArray( times, this.TimeBufferType );
this.values = AnimationUtils.convertArray( values, this.ValueBufferType );
this.setInterpolation( interpolation || this.DefaultInterpolation );
this.validate();
this.optimize();
}
/**
*
* A Track of vectored keyframe values.
*
*
* @author Ben Houston / http://clara.io/
* @author David Sarno / http://lighthaus.us/
* @author tschw
*/
function VectorKeyframeTrack( name, times, values, interpolation ) {
KeyframeTrackConstructor.call( this, name, times, values, interpolation );
}
VectorKeyframeTrack.prototype =
Object.assign( Object.create( KeyframeTrackPrototype ), {
constructor: VectorKeyframeTrack,
ValueTypeName: 'vector'
// ValueBufferType is inherited
// DefaultInterpolation is inherited
} );
/**
* Spherical linear unit quaternion interpolant.
*
* @author tschw
*/
function QuaternionLinearInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );
}
QuaternionLinearInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), {
constructor: QuaternionLinearInterpolant,
interpolate_: function( i1, t0, t, t1 ) {
var result = this.resultBuffer,
values = this.sampleValues,
stride = this.valueSize,
offset = i1 * stride,
alpha = ( t - t0 ) / ( t1 - t0 );
for ( var end = offset + stride; offset !== end; offset += 4 ) {
Quaternion.slerpFlat( result, 0,
values, offset - stride, values, offset, alpha );
}
return result;
}
} );
/**
*
* A Track of quaternion keyframe values.
*
* @author Ben Houston / http://clara.io/
* @author David Sarno / http://lighthaus.us/
* @author tschw
*/
function QuaternionKeyframeTrack( name, times, values, interpolation ) {
KeyframeTrackConstructor.call( this, name, times, values, interpolation );
}
QuaternionKeyframeTrack.prototype =
Object.assign( Object.create( KeyframeTrackPrototype ), {
constructor: QuaternionKeyframeTrack,
ValueTypeName: 'quaternion',
// ValueBufferType is inherited
DefaultInterpolation: InterpolateLinear,
InterpolantFactoryMethodLinear: function( result ) {
return new QuaternionLinearInterpolant(
this.times, this.values, this.getValueSize(), result );
},
InterpolantFactoryMethodSmooth: undefined // not yet implemented
} );
/**
*
* A Track of numeric keyframe values.
*
* @author Ben Houston / http://clara.io/
* @author David Sarno / http://lighthaus.us/
* @author tschw
*/
function NumberKeyframeTrack( name, times, values, interpolation ) {
KeyframeTrackConstructor.call( this, name, times, values, interpolation );
}
NumberKeyframeTrack.prototype =
Object.assign( Object.create( KeyframeTrackPrototype ), {
constructor: NumberKeyframeTrack,
ValueTypeName: 'number'
// ValueBufferType is inherited
// DefaultInterpolation is inherited
} );
/**
*
* A Track that interpolates Strings
*
*
* @author Ben Houston / http://clara.io/
* @author David Sarno / http://lighthaus.us/
* @author tschw
*/
function StringKeyframeTrack( name, times, values, interpolation ) {
KeyframeTrackConstructor.call( this, name, times, values, interpolation );
}
StringKeyframeTrack.prototype =
Object.assign( Object.create( KeyframeTrackPrototype ), {
constructor: StringKeyframeTrack,
ValueTypeName: 'string',
ValueBufferType: Array,
DefaultInterpolation: InterpolateDiscrete,
InterpolantFactoryMethodLinear: undefined,
InterpolantFactoryMethodSmooth: undefined
} );
/**
*
* A Track of Boolean keyframe values.
*
*
* @author Ben Houston / http://clara.io/
* @author David Sarno / http://lighthaus.us/
* @author tschw
*/
function BooleanKeyframeTrack( name, times, values ) {
KeyframeTrackConstructor.call( this, name, times, values );
}
BooleanKeyframeTrack.prototype =
Object.assign( Object.create( KeyframeTrackPrototype ), {
constructor: BooleanKeyframeTrack,
ValueTypeName: 'bool',
ValueBufferType: Array,
DefaultInterpolation: InterpolateDiscrete,
InterpolantFactoryMethodLinear: undefined,
InterpolantFactoryMethodSmooth: undefined
// Note: Actually this track could have a optimized / compressed
// representation of a single value and a custom interpolant that
// computes "firstValue ^ isOdd( index )".
} );
/**
*
* A Track of keyframe values that represent color.
*
*
* @author Ben Houston / http://clara.io/
* @author David Sarno / http://lighthaus.us/
* @author tschw
*/
function ColorKeyframeTrack( name, times, values, interpolation ) {
KeyframeTrackConstructor.call( this, name, times, values, interpolation );
}
ColorKeyframeTrack.prototype =
Object.assign( Object.create( KeyframeTrackPrototype ), {
constructor: ColorKeyframeTrack,
ValueTypeName: 'color'
// ValueBufferType is inherited
// DefaultInterpolation is inherited
// Note: Very basic implementation and nothing special yet.
// However, this is the place for color space parameterization.
} );
/**
*
* A timed sequence of keyframes for a specific property.
*
*
* @author Ben Houston / http://clara.io/
* @author David Sarno / http://lighthaus.us/
* @author tschw
*/
function KeyframeTrack( name, times, values, interpolation ) {
KeyframeTrackConstructor.apply( this, arguments );
}
KeyframeTrack.prototype = KeyframeTrackPrototype;
KeyframeTrackPrototype.constructor = KeyframeTrack;
// Static methods:
Object.assign( KeyframeTrack, {
// Serialization (in static context, because of constructor invocation
// and automatic invocation of .toJSON):
parse: function( json ) {
if( json.type === undefined ) {
throw new Error( "track type undefined, can not parse" );
}
var trackType = KeyframeTrack._getTrackTypeForValueTypeName( json.type );
if ( json.times === undefined ) {
var times = [], values = [];
AnimationUtils.flattenJSON( json.keys, times, values, 'value' );
json.times = times;
json.values = values;
}
// derived classes can define a static parse method
if ( trackType.parse !== undefined ) {
return trackType.parse( json );
} else {
// by default, we asssume a constructor compatible with the base
return new trackType(
json.name, json.times, json.values, json.interpolation );
}
},
toJSON: function( track ) {
var trackType = track.constructor;
var json;
// derived classes can define a static toJSON method
if ( trackType.toJSON !== undefined ) {
json = trackType.toJSON( track );
} else {
// by default, we assume the data can be serialized as-is
json = {
'name': track.name,
'times': AnimationUtils.convertArray( track.times, Array ),
'values': AnimationUtils.convertArray( track.values, Array )
};
var interpolation = track.getInterpolation();
if ( interpolation !== track.DefaultInterpolation ) {
json.interpolation = interpolation;
}
}
json.type = track.ValueTypeName; // mandatory
return json;
},
_getTrackTypeForValueTypeName: function( typeName ) {
switch( typeName.toLowerCase() ) {
case "scalar":
case "double":
case "float":
case "number":
case "integer":
return NumberKeyframeTrack;
case "vector":
case "vector2":
case "vector3":
case "vector4":
return VectorKeyframeTrack;
case "color":
return ColorKeyframeTrack;
case "quaternion":
return QuaternionKeyframeTrack;
case "bool":
case "boolean":
return BooleanKeyframeTrack;
case "string":
return StringKeyframeTrack;
}
throw new Error( "Unsupported typeName: " + typeName );
}
} );
/**
*
* Reusable set of Tracks that represent an animation.
*
* @author Ben Houston / http://clara.io/
* @author David Sarno / http://lighthaus.us/
*/
function AnimationClip( name, duration, tracks ) {
this.name = name;
this.tracks = tracks;
this.duration = ( duration !== undefined ) ? duration : - 1;
this.uuid = _Math.generateUUID();
// this means it should figure out its duration by scanning the tracks
if ( this.duration < 0 ) {
this.resetDuration();
}
this.optimize();
}
Object.assign( AnimationClip, {
parse: function ( json ) {
var tracks = [],
jsonTracks = json.tracks,
frameTime = 1.0 / ( json.fps || 1.0 );
for ( var i = 0, n = jsonTracks.length; i !== n; ++ i ) {
tracks.push( KeyframeTrack.parse( jsonTracks[ i ] ).scale( frameTime ) );
}
return new AnimationClip( json.name, json.duration, tracks );
},
toJSON: function ( clip ) {
var tracks = [],
clipTracks = clip.tracks;
var json = {
'name': clip.name,
'duration': clip.duration,
'tracks': tracks
};
for ( var i = 0, n = clipTracks.length; i !== n; ++ i ) {
tracks.push( KeyframeTrack.toJSON( clipTracks[ i ] ) );
}
return json;
},
CreateFromMorphTargetSequence: function ( name, morphTargetSequence, fps, noLoop ) {
var numMorphTargets = morphTargetSequence.length;
var tracks = [];
for ( var i = 0; i < numMorphTargets; i ++ ) {
var times = [];
var values = [];
times.push(
( i + numMorphTargets - 1 ) % numMorphTargets,
i,
( i + 1 ) % numMorphTargets );
values.push( 0, 1, 0 );
var order = AnimationUtils.getKeyframeOrder( times );
times = AnimationUtils.sortedArray( times, 1, order );
values = AnimationUtils.sortedArray( values, 1, order );
// if there is a key at the first frame, duplicate it as the
// last frame as well for perfect loop.
if ( ! noLoop && times[ 0 ] === 0 ) {
times.push( numMorphTargets );
values.push( values[ 0 ] );
}
tracks.push(
new NumberKeyframeTrack(
'.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']',
times, values
).scale( 1.0 / fps ) );
}
return new AnimationClip( name, - 1, tracks );
},
findByName: function ( objectOrClipArray, name ) {
var clipArray = objectOrClipArray;
if ( ! Array.isArray( objectOrClipArray ) ) {
var o = objectOrClipArray;
clipArray = o.geometry && o.geometry.animations || o.animations;
}
for ( var i = 0; i < clipArray.length; i ++ ) {
if ( clipArray[ i ].name === name ) {
return clipArray[ i ];
}
}
return null;
},
CreateClipsFromMorphTargetSequences: function ( morphTargets, fps, noLoop ) {
var animationToMorphTargets = {};
// tested with https://regex101.com/ on trick sequences
// such flamingo_flyA_003, flamingo_run1_003, crdeath0059
var pattern = /^([\w-]*?)([\d]+)$/;
// sort morph target names into animation groups based
// patterns like Walk_001, Walk_002, Run_001, Run_002
for ( var i = 0, il = morphTargets.length; i < il; i ++ ) {
var morphTarget = morphTargets[ i ];
var parts = morphTarget.name.match( pattern );
if ( parts && parts.length > 1 ) {
var name = parts[ 1 ];
var animationMorphTargets = animationToMorphTargets[ name ];
if ( ! animationMorphTargets ) {
animationToMorphTargets[ name ] = animationMorphTargets = [];
}
animationMorphTargets.push( morphTarget );
}
}
var clips = [];
for ( var name in animationToMorphTargets ) {
clips.push( AnimationClip.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps, noLoop ) );
}
return clips;
},
// parse the animation.hierarchy format
parseAnimation: function ( animation, bones ) {
if ( ! animation ) {
console.error( 'THREE.AnimationClip: No animation in JSONLoader data.' );
return null;
}
var addNonemptyTrack = function ( trackType, trackName, animationKeys, propertyName, destTracks ) {
// only return track if there are actually keys.
if ( animationKeys.length !== 0 ) {
var times = [];
var values = [];
AnimationUtils.flattenJSON( animationKeys, times, values, propertyName );
// empty keys are filtered out, so check again
if ( times.length !== 0 ) {
destTracks.push( new trackType( trackName, times, values ) );
}
}
};
var tracks = [];
var clipName = animation.name || 'default';
// automatic length determination in AnimationClip.
var duration = animation.length || - 1;
var fps = animation.fps || 30;
var hierarchyTracks = animation.hierarchy || [];
for ( var h = 0; h < hierarchyTracks.length; h ++ ) {
var animationKeys = hierarchyTracks[ h ].keys;
// skip empty tracks
if ( ! animationKeys || animationKeys.length === 0 ) continue;
// process morph targets
if ( animationKeys[ 0 ].morphTargets ) {
// figure out all morph targets used in this track
var morphTargetNames = {};
for ( var k = 0; k < animationKeys.length; k ++ ) {
if ( animationKeys[ k ].morphTargets ) {
for ( var m = 0; m < animationKeys[ k ].morphTargets.length; m ++ ) {
morphTargetNames[ animationKeys[ k ].morphTargets[ m ] ] = - 1;
}
}
}
// create a track for each morph target with all zero
// morphTargetInfluences except for the keys in which
// the morphTarget is named.
for ( var morphTargetName in morphTargetNames ) {
var times = [];
var values = [];
for ( var m = 0; m !== animationKeys[ k ].morphTargets.length; ++ m ) {
var animationKey = animationKeys[ k ];
times.push( animationKey.time );
values.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 );
}
tracks.push( new NumberKeyframeTrack( '.morphTargetInfluence[' + morphTargetName + ']', times, values ) );
}
duration = morphTargetNames.length * ( fps || 1.0 );
} else {
// ...assume skeletal animation
var boneName = '.bones[' + bones[ h ].name + ']';
addNonemptyTrack(
VectorKeyframeTrack, boneName + '.position',
animationKeys, 'pos', tracks );
addNonemptyTrack(
QuaternionKeyframeTrack, boneName + '.quaternion',
animationKeys, 'rot', tracks );
addNonemptyTrack(
VectorKeyframeTrack, boneName + '.scale',
animationKeys, 'scl', tracks );
}
}
if ( tracks.length === 0 ) {
return null;
}
var clip = new AnimationClip( clipName, duration, tracks );
return clip;
}
} );
Object.assign( AnimationClip.prototype, {
resetDuration: function () {
var tracks = this.tracks, duration = 0;
for ( var i = 0, n = tracks.length; i !== n; ++ i ) {
var track = this.tracks[ i ];
duration = Math.max( duration, track.times[ track.times.length - 1 ] );
}
this.duration = duration;
},
trim: function () {
for ( var i = 0; i < this.tracks.length; i ++ ) {
this.tracks[ i ].trim( 0, this.duration );
}
return this;
},
optimize: function () {
for ( var i = 0; i < this.tracks.length; i ++ ) {
this.tracks[ i ].optimize();
}
return this;
}
} );
/**
* @author mrdoob / http://mrdoob.com/
*/
function MaterialLoader( manager ) {
this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
this.textures = {};
}
Object.assign( MaterialLoader.prototype, {
load: function ( url, onLoad, onProgress, onError ) {
var scope = this;
var loader = new FileLoader( scope.manager );
loader.load( url, function ( text ) {
onLoad( scope.parse( JSON.parse( text ) ) );
}, onProgress, onError );
},
setTextures: function ( value ) {
this.textures = value;
},
parse: function ( json ) {
var textures = this.textures;
function getTexture( name ) {
if ( textures[ name ] === undefined ) {
console.warn( 'THREE.MaterialLoader: Undefined texture', name );
}
return textures[ name ];
}
var material = new Materials[ json.type ]();
if ( json.uuid !== undefined ) material.uuid = json.uuid;
if ( json.name !== undefined ) material.name = json.name;
if ( json.color !== undefined ) material.color.setHex( json.color );
if ( json.roughness !== undefined ) material.roughness = json.roughness;
if ( json.metalness !== undefined ) material.metalness = json.metalness;
if ( json.emissive !== undefined ) material.emissive.setHex( json.emissive );
if ( json.specular !== undefined ) material.specular.setHex( json.specular );
if ( json.shininess !== undefined ) material.shininess = json.shininess;
if ( json.clearCoat !== undefined ) material.clearCoat = json.clearCoat;
if ( json.clearCoatRoughness !== undefined ) material.clearCoatRoughness = json.clearCoatRoughness;
if ( json.uniforms !== undefined ) material.uniforms = json.uniforms;
if ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader;
if ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader;
if ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors;
if ( json.fog !== undefined ) material.fog = json.fog;
if ( json.shading !== undefined ) material.shading = json.shading;
if ( json.blending !== undefined ) material.blending = json.blending;
if ( json.side !== undefined ) material.side = json.side;
if ( json.opacity !== undefined ) material.opacity = json.opacity;
if ( json.transparent !== undefined ) material.transparent = json.transparent;
if ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest;
if ( json.depthTest !== undefined ) material.depthTest = json.depthTest;
if ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite;
if ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite;
if ( json.wireframe !== undefined ) material.wireframe = json.wireframe;
if ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth;
if ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap;
if ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin;
if ( json.skinning !== undefined ) material.skinning = json.skinning;
if ( json.morphTargets !== undefined ) material.morphTargets = json.morphTargets;
// for PointsMaterial
if ( json.size !== undefined ) material.size = json.size;
if ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation;
// maps
if ( json.map !== undefined ) material.map = getTexture( json.map );
if ( json.alphaMap !== undefined ) {
material.alphaMap = getTexture( json.alphaMap );
material.transparent = true;
}
if ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap );
if ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale;
if ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap );
if ( json.normalScale !== undefined ) {
var normalScale = json.normalScale;
if ( Array.isArray( normalScale ) === false ) {
// Blender exporter used to export a scalar. See #7459
normalScale = [ normalScale, normalScale ];
}
material.normalScale = new Vector2().fromArray( normalScale );
}
if ( json.displacementMap !== undefined ) material.displacementMap = getTexture( json.displacementMap );
if ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale;
if ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias;
if ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap );
if ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap );
if ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap );
if ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity;
if ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap );
if ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap );
if ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity;
if ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap );
if ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity;
if ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap );
if ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity;
if ( json.gradientMap !== undefined ) material.gradientMap = getTexture( json.gradientMap );
return material;
}
} );
/**
* @author mrdoob / http://mrdoob.com/
*/
function BufferGeometryLoader( manager ) {
this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
}
Object.assign( BufferGeometryLoader.prototype, {
load: function ( url, onLoad, onProgress, onError ) {
var scope = this;
var loader = new FileLoader( scope.manager );
loader.load( url, function ( text ) {
onLoad( scope.parse( JSON.parse( text ) ) );
}, onProgress, onError );
},
parse: function ( json ) {
var geometry = new BufferGeometry();
var index = json.data.index;
if ( index !== undefined ) {
var typedArray = new TYPED_ARRAYS[ index.type ]( index.array );
geometry.setIndex( new BufferAttribute( typedArray, 1 ) );
}
var attributes = json.data.attributes;
for ( var key in attributes ) {
var attribute = attributes[ key ];
var typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array );
geometry.addAttribute( key, new BufferAttribute( typedArray, attribute.itemSize, attribute.normalized ) );
}
var groups = json.data.groups || json.data.drawcalls || json.data.offsets;
if ( groups !== undefined ) {
for ( var i = 0, n = groups.length; i !== n; ++ i ) {
var group = groups[ i ];
geometry.addGroup( group.start, group.count, group.materialIndex );
}
}
var boundingSphere = json.data.boundingSphere;
if ( boundingSphere !== undefined ) {
var center = new Vector3();
if ( boundingSphere.center !== undefined ) {
center.fromArray( boundingSphere.center );
}
geometry.boundingSphere = new Sphere( center, boundingSphere.radius );
}
return geometry;
}
} );
var TYPED_ARRAYS = {
Int8Array: Int8Array,
Uint8Array: Uint8Array,
// Workaround for IE11 pre KB2929437. See #11440
Uint8ClampedArray: typeof Uint8ClampedArray !== 'undefined' ? Uint8ClampedArray : Uint8Array,
Int16Array: Int16Array,
Uint16Array: Uint16Array,
Int32Array: Int32Array,
Uint32Array: Uint32Array,
Float32Array: Float32Array,
Float64Array: Float64Array
};
/**
* @author alteredq / http://alteredqualia.com/
*/
function Loader() {
this.onLoadStart = function () {};
this.onLoadProgress = function () {};
this.onLoadComplete = function () {};
}
Loader.Handlers = {
handlers: [],
add: function ( regex, loader ) {
this.handlers.push( regex, loader );
},
get: function ( file ) {
var handlers = this.handlers;
for ( var i = 0, l = handlers.length; i < l; i += 2 ) {
var regex = handlers[ i ];
var loader = handlers[ i + 1 ];
if ( regex.test( file ) ) {
return loader;
}
}
return null;
}
};
Object.assign( Loader.prototype, {
crossOrigin: undefined,
extractUrlBase: function ( url ) {
var parts = url.split( '/' );
if ( parts.length === 1 ) return './';
parts.pop();
return parts.join( '/' ) + '/';
},
initMaterials: function ( materials, texturePath, crossOrigin ) {
var array = [];
for ( var i = 0; i < materials.length; ++ i ) {
array[ i ] = this.createMaterial( materials[ i ], texturePath, crossOrigin );
}
return array;
},
createMaterial: ( function () {
var BlendingMode = {
NoBlending: NoBlending,
NormalBlending: NormalBlending,
AdditiveBlending: AdditiveBlending,
SubtractiveBlending: SubtractiveBlending,
MultiplyBlending: MultiplyBlending,
CustomBlending: CustomBlending
};
var color = new Color();
var textureLoader = new TextureLoader();
var materialLoader = new MaterialLoader();
return function createMaterial( m, texturePath, crossOrigin ) {
// convert from old material format
var textures = {};
function loadTexture( path, repeat, offset, wrap, anisotropy ) {
var fullPath = texturePath + path;
var loader = Loader.Handlers.get( fullPath );
var texture;
if ( loader !== null ) {
texture = loader.load( fullPath );
} else {
textureLoader.setCrossOrigin( crossOrigin );
texture = textureLoader.load( fullPath );
}
if ( repeat !== undefined ) {
texture.repeat.fromArray( repeat );
if ( repeat[ 0 ] !== 1 ) texture.wrapS = RepeatWrapping;
if ( repeat[ 1 ] !== 1 ) texture.wrapT = RepeatWrapping;
}
if ( offset !== undefined ) {
texture.offset.fromArray( offset );
}
if ( wrap !== undefined ) {
if ( wrap[ 0 ] === 'repeat' ) texture.wrapS = RepeatWrapping;
if ( wrap[ 0 ] === 'mirror' ) texture.wrapS = MirroredRepeatWrapping;
if ( wrap[ 1 ] === 'repeat' ) texture.wrapT = RepeatWrapping;
if ( wrap[ 1 ] === 'mirror' ) texture.wrapT = MirroredRepeatWrapping;
}
if ( anisotropy !== undefined ) {
texture.anisotropy = anisotropy;
}
var uuid = _Math.generateUUID();
textures[ uuid ] = texture;
return uuid;
}
//
var json = {
uuid: _Math.generateUUID(),
type: 'MeshLambertMaterial'
};
for ( var name in m ) {
var value = m[ name ];
switch ( name ) {
case 'DbgColor':
case 'DbgIndex':
case 'opticalDensity':
case 'illumination':
break;
case 'DbgName':
json.name = value;
break;
case 'blending':
json.blending = BlendingMode[ value ];
break;
case 'colorAmbient':
case 'mapAmbient':
console.warn( 'THREE.Loader.createMaterial:', name, 'is no longer supported.' );
break;
case 'colorDiffuse':
json.color = color.fromArray( value ).getHex();
break;
case 'colorSpecular':
json.specular = color.fromArray( value ).getHex();
break;
case 'colorEmissive':
json.emissive = color.fromArray( value ).getHex();
break;
case 'specularCoef':
json.shininess = value;
break;
case 'shading':
if ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial';
if ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial';
if ( value.toLowerCase() === 'standard' ) json.type = 'MeshStandardMaterial';
break;
case 'mapDiffuse':
json.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy );
break;
case 'mapDiffuseRepeat':
case 'mapDiffuseOffset':
case 'mapDiffuseWrap':
case 'mapDiffuseAnisotropy':
break;
case 'mapEmissive':
json.emissiveMap = loadTexture( value, m.mapEmissiveRepeat, m.mapEmissiveOffset, m.mapEmissiveWrap, m.mapEmissiveAnisotropy );
break;
case 'mapEmissiveRepeat':
case 'mapEmissiveOffset':
case 'mapEmissiveWrap':
case 'mapEmissiveAnisotropy':
break;
case 'mapLight':
json.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy );
break;
case 'mapLightRepeat':
case 'mapLightOffset':
case 'mapLightWrap':
case 'mapLightAnisotropy':
break;
case 'mapAO':
json.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy );
break;
case 'mapAORepeat':
case 'mapAOOffset':
case 'mapAOWrap':
case 'mapAOAnisotropy':
break;
case 'mapBump':
json.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy );
break;
case 'mapBumpScale':
json.bumpScale = value;
break;
case 'mapBumpRepeat':
case 'mapBumpOffset':
case 'mapBumpWrap':
case 'mapBumpAnisotropy':
break;
case 'mapNormal':
json.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy );
break;
case 'mapNormalFactor':
json.normalScale = [ value, value ];
break;
case 'mapNormalRepeat':
case 'mapNormalOffset':
case 'mapNormalWrap':
case 'mapNormalAnisotropy':
break;
case 'mapSpecular':
json.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy );
break;
case 'mapSpecularRepeat':
case 'mapSpecularOffset':
case 'mapSpecularWrap':
case 'mapSpecularAnisotropy':
break;
case 'mapMetalness':
json.metalnessMap = loadTexture( value, m.mapMetalnessRepeat, m.mapMetalnessOffset, m.mapMetalnessWrap, m.mapMetalnessAnisotropy );
break;
case 'mapMetalnessRepeat':
case 'mapMetalnessOffset':
case 'mapMetalnessWrap':
case 'mapMetalnessAnisotropy':
break;
case 'mapRoughness':
json.roughnessMap = loadTexture( value, m.mapRoughnessRepeat, m.mapRoughnessOffset, m.mapRoughnessWrap, m.mapRoughnessAnisotropy );
break;
case 'mapRoughnessRepeat':
case 'mapRoughnessOffset':
case 'mapRoughnessWrap':
case 'mapRoughnessAnisotropy':
break;
case 'mapAlpha':
json.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy );
break;
case 'mapAlphaRepeat':
case 'mapAlphaOffset':
case 'mapAlphaWrap':
case 'mapAlphaAnisotropy':
break;
case 'flipSided':
json.side = BackSide;
break;
case 'doubleSided':
json.side = DoubleSide;
break;
case 'transparency':
console.warn( 'THREE.Loader.createMaterial: transparency has been renamed to opacity' );
json.opacity = value;
break;
case 'depthTest':
case 'depthWrite':
case 'colorWrite':
case 'opacity':
case 'reflectivity':
case 'transparent':
case 'visible':
case 'wireframe':
json[ name ] = value;
break;
case 'vertexColors':
if ( value === true ) json.vertexColors = VertexColors;
if ( value === 'face' ) json.vertexColors = FaceColors;
break;
default:
console.error( 'THREE.Loader.createMaterial: Unsupported', name, value );
break;
}
}
if ( json.type === 'MeshBasicMaterial' ) delete json.emissive;
if ( json.type !== 'MeshPhongMaterial' ) delete json.specular;
if ( json.opacity < 1 ) json.transparent = true;
materialLoader.setTextures( textures );
return materialLoader.parse( json );
};
} )()
} );
/**
* @author mrdoob / http://mrdoob.com/
* @author alteredq / http://alteredqualia.com/
*/
function JSONLoader( manager ) {
if ( typeof manager === 'boolean' ) {
console.warn( 'THREE.JSONLoader: showStatus parameter has been removed from constructor.' );
manager = undefined;
}
this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
this.withCredentials = false;
}
Object.assign( JSONLoader.prototype, {
load: function ( url, onLoad, onProgress, onError ) {
var scope = this;
var texturePath = this.texturePath && ( typeof this.texturePath === "string" ) ? this.texturePath : Loader.prototype.extractUrlBase( url );
var loader = new FileLoader( this.manager );
loader.setWithCredentials( this.withCredentials );
loader.load( url, function ( text ) {
var json = JSON.parse( text );
var metadata = json.metadata;
if ( metadata !== undefined ) {
var type = metadata.type;
if ( type !== undefined ) {
if ( type.toLowerCase() === 'object' ) {
console.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' );
return;
}
if ( type.toLowerCase() === 'scene' ) {
console.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.SceneLoader instead.' );
return;
}
}
}
var object = scope.parse( json, texturePath );
onLoad( object.geometry, object.materials );
}, onProgress, onError );
},
setTexturePath: function ( value ) {
this.texturePath = value;
},
parse: ( function () {
function parseModel( json, geometry ) {
function isBitSet( value, position ) {
return value & ( 1 << position );
}
var i, j, fi,
offset, zLength,
colorIndex, normalIndex, uvIndex, materialIndex,
type,
isQuad,
hasMaterial,
hasFaceVertexUv,
hasFaceNormal, hasFaceVertexNormal,
hasFaceColor, hasFaceVertexColor,
vertex, face, faceA, faceB, hex, normal,
uvLayer, uv, u, v,
faces = json.faces,
vertices = json.vertices,
normals = json.normals,
colors = json.colors,
scale = json.scale,
nUvLayers = 0;
if ( json.uvs !== undefined ) {
// disregard empty arrays
for ( i = 0; i < json.uvs.length; i ++ ) {
if ( json.uvs[ i ].length ) nUvLayers ++;
}
for ( i = 0; i < nUvLayers; i ++ ) {
geometry.faceVertexUvs[ i ] = [];
}
}
offset = 0;
zLength = vertices.length;
while ( offset < zLength ) {
vertex = new Vector3();
vertex.x = vertices[ offset ++ ] * scale;
vertex.y = vertices[ offset ++ ] * scale;
vertex.z = vertices[ offset ++ ] * scale;
geometry.vertices.push( vertex );
}
offset = 0;
zLength = faces.length;
while ( offset < zLength ) {
type = faces[ offset ++ ];
isQuad = isBitSet( type, 0 );
hasMaterial = isBitSet( type, 1 );
hasFaceVertexUv = isBitSet( type, 3 );
hasFaceNormal = isBitSet( type, 4 );
hasFaceVertexNormal = isBitSet( type, 5 );
hasFaceColor = isBitSet( type, 6 );
hasFaceVertexColor = isBitSet( type, 7 );
// console.log("type", type, "bits", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);
if ( isQuad ) {
faceA = new Face3();
faceA.a = faces[ offset ];
faceA.b = faces[ offset + 1 ];
faceA.c = faces[ offset + 3 ];
faceB = new Face3();
faceB.a = faces[ offset + 1 ];
faceB.b = faces[ offset + 2 ];
faceB.c = faces[ offset + 3 ];
offset += 4;
if ( hasMaterial ) {
materialIndex = faces[ offset ++ ];
faceA.materialIndex = materialIndex;
faceB.materialIndex = materialIndex;
}
// to get face <=> uv index correspondence
fi = geometry.faces.length;
if ( hasFaceVertexUv ) {
for ( i = 0; i < nUvLayers; i ++ ) {
uvLayer = json.uvs[ i ];
geometry.faceVertexUvs[ i ][ fi ] = [];
geometry.faceVertexUvs[ i ][ fi + 1 ] = [];
for ( j = 0; j < 4; j ++ ) {
uvIndex = faces[ offset ++ ];
u = uvLayer[ uvIndex * 2 ];
v = uvLayer[ uvIndex * 2 + 1 ];
uv = new Vector2( u, v );
if ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );
if ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );
}
}
}
if ( hasFaceNormal ) {
normalIndex = faces[ offset ++ ] * 3;
faceA.normal.set(
normals[ normalIndex ++ ],
normals[ normalIndex ++ ],
normals[ normalIndex ]
);
faceB.normal.copy( faceA.normal );
}
if ( hasFaceVertexNormal ) {
for ( i = 0; i < 4; i ++ ) {
normalIndex = faces[ offset ++ ] * 3;
normal = new Vector3(
normals[ normalIndex ++ ],
normals[ normalIndex ++ ],
normals[ normalIndex ]
);
if ( i !== 2 ) faceA.vertexNormals.push( normal );
if ( i !== 0 ) faceB.vertexNormals.push( normal );
}
}
if ( hasFaceColor ) {
colorIndex = faces[ offset ++ ];
hex = colors[ colorIndex ];
faceA.color.setHex( hex );
faceB.color.setHex( hex );
}
if ( hasFaceVertexColor ) {
for ( i = 0; i < 4; i ++ ) {
colorIndex = faces[ offset ++ ];
hex = colors[ colorIndex ];
if ( i !== 2 ) faceA.vertexColors.push( new Color( hex ) );
if ( i !== 0 ) faceB.vertexColors.push( new Color( hex ) );
}
}
geometry.faces.push( faceA );
geometry.faces.push( faceB );
} else {
face = new Face3();
face.a = faces[ offset ++ ];
face.b = faces[ offset ++ ];
face.c = faces[ offset ++ ];
if ( hasMaterial ) {
materialIndex = faces[ offset ++ ];
face.materialIndex = materialIndex;
}
// to get face <=> uv index correspondence
fi = geometry.faces.length;
if ( hasFaceVertexUv ) {
for ( i = 0; i < nUvLayers; i ++ ) {
uvLayer = json.uvs[ i ];
geometry.faceVertexUvs[ i ][ fi ] = [];
for ( j = 0; j < 3; j ++ ) {
uvIndex = faces[ offset ++ ];
u = uvLayer[ uvIndex * 2 ];
v = uvLayer[ uvIndex * 2 + 1 ];
uv = new Vector2( u, v );
geometry.faceVertexUvs[ i ][ fi ].push( uv );
}
}
}
if ( hasFaceNormal ) {
normalIndex = faces[ offset ++ ] * 3;
face.normal.set(
normals[ normalIndex ++ ],
normals[ normalIndex ++ ],
normals[ normalIndex ]
);
}
if ( hasFaceVertexNormal ) {
for ( i = 0; i < 3; i ++ ) {
normalIndex = faces[ offset ++ ] * 3;
normal = new Vector3(
normals[ normalIndex ++ ],
normals[ normalIndex ++ ],
normals[ normalIndex ]
);
face.vertexNormals.push( normal );
}
}
if ( hasFaceColor ) {
colorIndex = faces[ offset ++ ];
face.color.setHex( colors[ colorIndex ] );
}
if ( hasFaceVertexColor ) {
for ( i = 0; i < 3; i ++ ) {
colorIndex = faces[ offset ++ ];
face.vertexColors.push( new Color( colors[ colorIndex ] ) );
}
}
geometry.faces.push( face );
}
}
}
function parseSkin( json, geometry ) {
var influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2;
if ( json.skinWeights ) {
for ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) {
var x = json.skinWeights[ i ];
var y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0;
var z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0;
var w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0;
geometry.skinWeights.push( new Vector4( x, y, z, w ) );
}
}
if ( json.skinIndices ) {
for ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) {
var a = json.skinIndices[ i ];
var b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0;
var c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0;
var d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0;
geometry.skinIndices.push( new Vector4( a, b, c, d ) );
}
}
geometry.bones = json.bones;
if ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) {
console.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' +
geometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' );
}
}
function parseMorphing( json, geometry ) {
var scale = json.scale;
if ( json.morphTargets !== undefined ) {
for ( var i = 0, l = json.morphTargets.length; i < l; i ++ ) {
geometry.morphTargets[ i ] = {};
geometry.morphTargets[ i ].name = json.morphTargets[ i ].name;
geometry.morphTargets[ i ].vertices = [];
var dstVertices = geometry.morphTargets[ i ].vertices;
var srcVertices = json.morphTargets[ i ].vertices;
for ( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) {
var vertex = new Vector3();
vertex.x = srcVertices[ v ] * scale;
vertex.y = srcVertices[ v + 1 ] * scale;
vertex.z = srcVertices[ v + 2 ] * scale;
dstVertices.push( vertex );
}
}
}
if ( json.morphColors !== undefined && json.morphColors.length > 0 ) {
console.warn( 'THREE.JSONLoader: "morphColors" no longer supported. Using them as face colors.' );
var faces = geometry.faces;
var morphColors = json.morphColors[ 0 ].colors;
for ( var i = 0, l = faces.length; i < l; i ++ ) {
faces[ i ].color.fromArray( morphColors, i * 3 );
}
}
}
function parseAnimations( json, geometry ) {
var outputAnimations = [];
// parse old style Bone/Hierarchy animations
var animations = [];
if ( json.animation !== undefined ) {
animations.push( json.animation );
}
if ( json.animations !== undefined ) {
if ( json.animations.length ) {
animations = animations.concat( json.animations );
} else {
animations.push( json.animations );
}
}
for ( var i = 0; i < animations.length; i ++ ) {
var clip = AnimationClip.parseAnimation( animations[ i ], geometry.bones );
if ( clip ) outputAnimations.push( clip );
}
// parse implicit morph animations
if ( geometry.morphTargets ) {
// TODO: Figure out what an appropraite FPS is for morph target animations -- defaulting to 10, but really it is completely arbitrary.
var morphAnimationClips = AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 );
outputAnimations = outputAnimations.concat( morphAnimationClips );
}
if ( outputAnimations.length > 0 ) geometry.animations = outputAnimations;
}
return function ( json, texturePath ) {
if ( json.data !== undefined ) {
// Geometry 4.0 spec
json = json.data;
}
if ( json.scale !== undefined ) {
json.scale = 1.0 / json.scale;
} else {
json.scale = 1.0;
}
var geometry = new Geometry();
parseModel( json, geometry );
parseSkin( json, geometry );
parseMorphing( json, geometry );
parseAnimations( json, geometry );
geometry.computeFaceNormals();
geometry.computeBoundingSphere();
if ( json.materials === undefined || json.materials.length === 0 ) {
return { geometry: geometry };
} else {
var materials = Loader.prototype.initMaterials( json.materials, texturePath, this.crossOrigin );
return { geometry: geometry, materials: materials };
}
};
} )()
} );
/**
* @author mrdoob / http://mrdoob.com/
*/
function ObjectLoader( manager ) {
this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
this.texturePath = '';
}
Object.assign( ObjectLoader.prototype, {
load: function ( url, onLoad, onProgress, onError ) {
if ( this.texturePath === '' ) {
this.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 );
}
var scope = this;
var loader = new FileLoader( scope.manager );
loader.load( url, function ( text ) {
var json = null;
try {
json = JSON.parse( text );
} catch ( error ) {
if ( onError !== undefined ) onError( error );
console.error( 'THREE:ObjectLoader: Can\'t parse ' + url + '.', error.message );
return;
}
var metadata = json.metadata;
if ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) {
console.error( 'THREE.ObjectLoader: Can\'t load ' + url + '. Use THREE.JSONLoader instead.' );
return;
}
scope.parse( json, onLoad );
}, onProgress, onError );
},
setTexturePath: function ( value ) {
this.texturePath = value;
},
setCrossOrigin: function ( value ) {
this.crossOrigin = value;
},
parse: function ( json, onLoad ) {
var geometries = this.parseGeometries( json.geometries );
var images = this.parseImages( json.images, function () {
if ( onLoad !== undefined ) onLoad( object );
} );
var textures = this.parseTextures( json.textures, images );
var materials = this.parseMaterials( json.materials, textures );
var object = this.parseObject( json.object, geometries, materials );
if ( json.animations ) {
object.animations = this.parseAnimations( json.animations );
}
if ( json.images === undefined || json.images.length === 0 ) {
if ( onLoad !== undefined ) onLoad( object );
}
return object;
},
parseGeometries: function ( json ) {
var geometries = {};
if ( json !== undefined ) {
var geometryLoader = new JSONLoader();
var bufferGeometryLoader = new BufferGeometryLoader();
for ( var i = 0, l = json.length; i < l; i ++ ) {
var geometry;
var data = json[ i ];
switch ( data.type ) {
case 'PlaneGeometry':
case 'PlaneBufferGeometry':
geometry = new Geometries[ data.type ](
data.width,
data.height,
data.widthSegments,
data.heightSegments
);
break;
case 'BoxGeometry':
case 'BoxBufferGeometry':
case 'CubeGeometry': // backwards compatible
geometry = new Geometries[ data.type ](
data.width,
data.height,
data.depth,
data.widthSegments,
data.heightSegments,
data.depthSegments
);
break;
case 'CircleGeometry':
case 'CircleBufferGeometry':
geometry = new Geometries[ data.type ](
data.radius,
data.segments,
data.thetaStart,
data.thetaLength
);
break;
case 'CylinderGeometry':
case 'CylinderBufferGeometry':
geometry = new Geometries[ data.type ](
data.radiusTop,
data.radiusBottom,
data.height,
data.radialSegments,
data.heightSegments,
data.openEnded,
data.thetaStart,
data.thetaLength
);
break;
case 'ConeGeometry':
case 'ConeBufferGeometry':
geometry = new Geometries[ data.type ](
data.radius,
data.height,
data.radialSegments,
data.heightSegments,
data.openEnded,
data.thetaStart,
data.thetaLength
);
break;
case 'SphereGeometry':
case 'SphereBufferGeometry':
geometry = new Geometries[ data.type ](
data.radius,
data.widthSegments,
data.heightSegments,
data.phiStart,
data.phiLength,
data.thetaStart,
data.thetaLength
);
break;
case 'DodecahedronGeometry':
case 'IcosahedronGeometry':
case 'OctahedronGeometry':
case 'TetrahedronGeometry':
geometry = new Geometries[ data.type ](
data.radius,
data.detail
);
break;
case 'RingGeometry':
case 'RingBufferGeometry':
geometry = new Geometries[ data.type ](
data.innerRadius,
data.outerRadius,
data.thetaSegments,
data.phiSegments,
data.thetaStart,
data.thetaLength
);
break;
case 'TorusGeometry':
case 'TorusBufferGeometry':
geometry = new Geometries[ data.type ](
data.radius,
data.tube,
data.radialSegments,
data.tubularSegments,
data.arc
);
break;
case 'TorusKnotGeometry':
case 'TorusKnotBufferGeometry':
geometry = new Geometries[ data.type ](
data.radius,
data.tube,
data.tubularSegments,
data.radialSegments,
data.p,
data.q
);
break;
case 'LatheGeometry':
case 'LatheBufferGeometry':
geometry = new Geometries[ data.type ](
data.points,
data.segments,
data.phiStart,
data.phiLength
);
break;
case 'BufferGeometry':
geometry = bufferGeometryLoader.parse( data );
break;
case 'Geometry':
geometry = geometryLoader.parse( data, this.texturePath ).geometry;
break;
default:
console.warn( 'THREE.ObjectLoader: Unsupported geometry type "' + data.type + '"' );
continue;
}
geometry.uuid = data.uuid;
if ( data.name !== undefined ) geometry.name = data.name;
geometries[ data.uuid ] = geometry;
}
}
return geometries;
},
parseMaterials: function ( json, textures ) {
var materials = {};
if ( json !== undefined ) {
var loader = new MaterialLoader();
loader.setTextures( textures );
for ( var i = 0, l = json.length; i < l; i ++ ) {
var data = json[ i ];
if ( data.type === 'MultiMaterial' ) {
// Deprecated
var array = [];
for ( var j = 0; j < data.materials.length; j ++ ) {
array.push( loader.parse( data.materials[ j ] ) );
}
materials[ data.uuid ] = array;
} else {
materials[ data.uuid ] = loader.parse( data );
}
}
}
return materials;
},
parseAnimations: function ( json ) {
var animations = [];
for ( var i = 0; i < json.length; i ++ ) {
var clip = AnimationClip.parse( json[ i ] );
animations.push( clip );
}
return animations;
},
parseImages: function ( json, onLoad ) {
var scope = this;
var images = {};
function loadImage( url ) {
scope.manager.itemStart( url );
return loader.load( url, function () {
scope.manager.itemEnd( url );
}, undefined, function () {
scope.manager.itemEnd( url );
scope.manager.itemError( url );
} );
}
if ( json !== undefined && json.length > 0 ) {
var manager = new LoadingManager( onLoad );
var loader = new ImageLoader( manager );
loader.setCrossOrigin( this.crossOrigin );
for ( var i = 0, l = json.length; i < l; i ++ ) {
var image = json[ i ];
var path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( image.url ) ? image.url : scope.texturePath + image.url;
images[ image.uuid ] = loadImage( path );
}
}
return images;
},
parseTextures: function ( json, images ) {
function parseConstant( value, type ) {
if ( typeof( value ) === 'number' ) return value;
console.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );
return type[ value ];
}
var textures = {};
if ( json !== undefined ) {
for ( var i = 0, l = json.length; i < l; i ++ ) {
var data = json[ i ];
if ( data.image === undefined ) {
console.warn( 'THREE.ObjectLoader: No "image" specified for', data.uuid );
}
if ( images[ data.image ] === undefined ) {
console.warn( 'THREE.ObjectLoader: Undefined image', data.image );
}
var texture = new Texture( images[ data.image ] );
texture.needsUpdate = true;
texture.uuid = data.uuid;
if ( data.name !== undefined ) texture.name = data.name;
if ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TEXTURE_MAPPING );
if ( data.offset !== undefined ) texture.offset.fromArray( data.offset );
if ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat );
if ( data.wrap !== undefined ) {
texture.wrapS = parseConstant( data.wrap[ 0 ], TEXTURE_WRAPPING );
texture.wrapT = parseConstant( data.wrap[ 1 ], TEXTURE_WRAPPING );
}
if ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TEXTURE_FILTER );
if ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TEXTURE_FILTER );
if ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;
if ( data.flipY !== undefined ) texture.flipY = data.flipY;
textures[ data.uuid ] = texture;
}
}
return textures;
},
parseObject: function () {
var matrix = new Matrix4();
return function parseObject( data, geometries, materials ) {
var object;
function getGeometry( name ) {
if ( geometries[ name ] === undefined ) {
console.warn( 'THREE.ObjectLoader: Undefined geometry', name );
}
return geometries[ name ];
}
function getMaterial( name ) {
if ( name === undefined ) return undefined;
if ( Array.isArray( name ) ) {
var array = [];
for ( var i = 0, l = name.length; i < l; i ++ ) {
var uuid = name[ i ];
if ( materials[ uuid ] === undefined ) {
console.warn( 'THREE.ObjectLoader: Undefined material', uuid );
}
array.push( materials[ uuid ] );
}
return array;
}
if ( materials[ name ] === undefined ) {
console.warn( 'THREE.ObjectLoader: Undefined material', name );
}
return materials[ name ];
}
switch ( data.type ) {
case 'Scene':
object = new Scene();
if ( data.background !== undefined ) {
if ( Number.isInteger( data.background ) ) {
object.background = new Color( data.background );
}
}
if ( data.fog !== undefined ) {
if ( data.fog.type === 'Fog' ) {
object.fog = new Fog( data.fog.color, data.fog.near, data.fog.far );
} else if ( data.fog.type === 'FogExp2' ) {
object.fog = new FogExp2( data.fog.color, data.fog.density );
}
}
break;
case 'PerspectiveCamera':
object = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far );
if ( data.focus !== undefined ) object.focus = data.focus;
if ( data.zoom !== undefined ) object.zoom = data.zoom;
if ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge;
if ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset;
if ( data.view !== undefined ) object.view = Object.assign( {}, data.view );
break;
case 'OrthographicCamera':
object = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );
break;
case 'AmbientLight':
object = new AmbientLight( data.color, data.intensity );
break;
case 'DirectionalLight':
object = new DirectionalLight( data.color, data.intensity );
break;
case 'PointLight':
object = new PointLight( data.color, data.intensity, data.distance, data.decay );
break;
case 'RectAreaLight':
object = new RectAreaLight( data.color, data.intensity, data.width, data.height );
break;
case 'SpotLight':
object = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay );
break;
case 'HemisphereLight':
object = new HemisphereLight( data.color, data.groundColor, data.intensity );
break;
case 'SkinnedMesh':
console.warn( 'THREE.ObjectLoader.parseObject() does not support SkinnedMesh yet.' );
case 'Mesh':
var geometry = getGeometry( data.geometry );
var material = getMaterial( data.material );
if ( geometry.bones && geometry.bones.length > 0 ) {
object = new SkinnedMesh( geometry, material );
} else {
object = new Mesh( geometry, material );
}
break;
case 'LOD':
object = new LOD();
break;
case 'Line':
object = new Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );
break;
case 'LineLoop':
object = new LineLoop( getGeometry( data.geometry ), getMaterial( data.material ) );
break;
case 'LineSegments':
object = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) );
break;
case 'PointCloud':
case 'Points':
object = new Points( getGeometry( data.geometry ), getMaterial( data.material ) );
break;
case 'Sprite':
object = new Sprite( getMaterial( data.material ) );
break;
case 'Group':
object = new Group();
break;
default:
object = new Object3D();
}
object.uuid = data.uuid;
if ( data.name !== undefined ) object.name = data.name;
if ( data.matrix !== undefined ) {
matrix.fromArray( data.matrix );
matrix.decompose( object.position, object.quaternion, object.scale );
} else {
if ( data.position !== undefined ) object.position.fromArray( data.position );
if ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation );
if ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion );
if ( data.scale !== undefined ) object.scale.fromArray( data.scale );
}
if ( data.castShadow !== undefined ) object.castShadow = data.castShadow;
if ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;
if ( data.shadow ) {
if ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias;
if ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius;
if ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize );
if ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera );
}
if ( data.visible !== undefined ) object.visible = data.visible;
if ( data.userData !== undefined ) object.userData = data.userData;
if ( data.children !== undefined ) {
for ( var child in data.children ) {
object.add( this.parseObject( data.children[ child ], geometries, materials ) );
}
}
if ( data.type === 'LOD' ) {
var levels = data.levels;
for ( var l = 0; l < levels.length; l ++ ) {
var level = levels[ l ];
var child = object.getObjectByProperty( 'uuid', level.object );
if ( child !== undefined ) {
object.addLevel( child, level.distance );
}
}
}
return object;
};
}()
} );
var TEXTURE_MAPPING = {
UVMapping: UVMapping,
CubeReflectionMapping: CubeReflectionMapping,
CubeRefractionMapping: CubeRefractionMapping,
EquirectangularReflectionMapping: EquirectangularReflectionMapping,
EquirectangularRefractionMapping: EquirectangularRefractionMapping,
SphericalReflectionMapping: SphericalReflectionMapping,
CubeUVReflectionMapping: CubeUVReflectionMapping,
CubeUVRefractionMapping: CubeUVRefractionMapping
};
var TEXTURE_WRAPPING = {
RepeatWrapping: RepeatWrapping,
ClampToEdgeWrapping: ClampToEdgeWrapping,
MirroredRepeatWrapping: MirroredRepeatWrapping
};
var TEXTURE_FILTER = {
NearestFilter: NearestFilter,
NearestMipMapNearestFilter: NearestMipMapNearestFilter,
NearestMipMapLinearFilter: NearestMipMapLinearFilter,
LinearFilter: LinearFilter,
LinearMipMapNearestFilter: LinearMipMapNearestFilter,
LinearMipMapLinearFilter: LinearMipMapLinearFilter
};
/**
* @author zz85 / http://www.lab4games.net/zz85/blog
*
* Bezier Curves formulas obtained from
* http://en.wikipedia.org/wiki/Bézier_curve
*/
function CatmullRom( t, p0, p1, p2, p3 ) {
var v0 = ( p2 - p0 ) * 0.5;
var v1 = ( p3 - p1 ) * 0.5;
var t2 = t * t;
var t3 = t * t2;
return ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;
}
//
function QuadraticBezierP0( t, p ) {
var k = 1 - t;
return k * k * p;
}
function QuadraticBezierP1( t, p ) {
return 2 * ( 1 - t ) * t * p;
}
function QuadraticBezierP2( t, p ) {
return t * t * p;
}
function QuadraticBezier( t, p0, p1, p2 ) {
return QuadraticBezierP0( t, p0 ) + QuadraticBezierP1( t, p1 ) +
QuadraticBezierP2( t, p2 );
}
//
function CubicBezierP0( t, p ) {
var k = 1 - t;
return k * k * k * p;
}
function CubicBezierP1( t, p ) {
var k = 1 - t;
return 3 * k * k * t * p;
}
function CubicBezierP2( t, p ) {
return 3 * ( 1 - t ) * t * t * p;
}
function CubicBezierP3( t, p ) {
return t * t * t * p;
}
function CubicBezier( t, p0, p1, p2, p3 ) {
return CubicBezierP0( t, p0 ) + CubicBezierP1( t, p1 ) + CubicBezierP2( t, p2 ) +
CubicBezierP3( t, p3 );
}
/**
* @author zz85 / http://www.lab4games.net/zz85/blog
* Extensible curve object
*
* Some common of curve methods:
* .getPoint(t), getTangent(t)
* .getPointAt(u), getTangentAt(u)
* .getPoints(), .getSpacedPoints()
* .getLength()
* .updateArcLengths()
*
* This following curves inherit from THREE.Curve:
*
* -- 2D curves --
* THREE.ArcCurve
* THREE.CubicBezierCurve
* THREE.EllipseCurve
* THREE.LineCurve
* THREE.QuadraticBezierCurve
* THREE.SplineCurve
*
* -- 3D curves --
* THREE.CatmullRomCurve3
* THREE.CubicBezierCurve3
* THREE.LineCurve3
* THREE.QuadraticBezierCurve3
*
* A series of curves can be represented as a THREE.CurvePath.
*
**/
/**************************************************************
* Abstract Curve base class
**************************************************************/
function Curve() {
this.arcLengthDivisions = 200;
}
Object.assign( Curve.prototype, {
// Virtual base class method to overwrite and implement in subclasses
// - t [0 .. 1]
getPoint: function () {
console.warn( 'THREE.Curve: .getPoint() not implemented.' );
return null;
},
// Get point at relative position in curve according to arc length
// - u [0 .. 1]
getPointAt: function ( u ) {
var t = this.getUtoTmapping( u );
return this.getPoint( t );
},
// Get sequence of points using getPoint( t )
getPoints: function ( divisions ) {
if ( divisions === undefined ) divisions = 5;
var points = [];
for ( var d = 0; d <= divisions; d ++ ) {
points.push( this.getPoint( d / divisions ) );
}
return points;
},
// Get sequence of points using getPointAt( u )
getSpacedPoints: function ( divisions ) {
if ( divisions === undefined ) divisions = 5;
var points = [];
for ( var d = 0; d <= divisions; d ++ ) {
points.push( this.getPointAt( d / divisions ) );
}
return points;
},
// Get total curve arc length
getLength: function () {
var lengths = this.getLengths();
return lengths[ lengths.length - 1 ];
},
// Get list of cumulative segment lengths
getLengths: function ( divisions ) {
if ( divisions === undefined ) divisions = this.arcLengthDivisions;
if ( this.cacheArcLengths &&
( this.cacheArcLengths.length === divisions + 1 ) &&
! this.needsUpdate ) {
return this.cacheArcLengths;
}
this.needsUpdate = false;
var cache = [];
var current, last = this.getPoint( 0 );
var p, sum = 0;
cache.push( 0 );
for ( p = 1; p <= divisions; p ++ ) {
current = this.getPoint( p / divisions );
sum += current.distanceTo( last );
cache.push( sum );
last = current;
}
this.cacheArcLengths = cache;
return cache; // { sums: cache, sum: sum }; Sum is in the last element.
},
updateArcLengths: function () {
this.needsUpdate = true;
this.getLengths();
},
// Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant
getUtoTmapping: function ( u, distance ) {
var arcLengths = this.getLengths();
var i = 0, il = arcLengths.length;
var targetArcLength; // The targeted u distance value to get
if ( distance ) {
targetArcLength = distance;
} else {
targetArcLength = u * arcLengths[ il - 1 ];
}
// binary search for the index with largest value smaller than target u distance
var low = 0, high = il - 1, comparison;
while ( low <= high ) {
i = Math.floor( low + ( high - low ) / 2 ); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats
comparison = arcLengths[ i ] - targetArcLength;
if ( comparison < 0 ) {
low = i + 1;
} else if ( comparison > 0 ) {
high = i - 1;
} else {
high = i;
break;
// DONE
}
}
i = high;
if ( arcLengths[ i ] === targetArcLength ) {
return i / ( il - 1 );
}
// we could get finer grain at lengths, or use simple interpolation between two points
var lengthBefore = arcLengths[ i ];
var lengthAfter = arcLengths[ i + 1 ];
var segmentLength = lengthAfter - lengthBefore;
// determine where we are between the 'before' and 'after' points
var segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;
// add that fractional amount to t
var t = ( i + segmentFraction ) / ( il - 1 );
return t;
},
// Returns a unit vector tangent at t
// In case any sub curve does not implement its tangent derivation,
// 2 points a small delta apart will be used to find its gradient
// which seems to give a reasonable approximation
getTangent: function ( t ) {
var delta = 0.0001;
var t1 = t - delta;
var t2 = t + delta;
// Capping in case of danger
if ( t1 < 0 ) t1 = 0;
if ( t2 > 1 ) t2 = 1;
var pt1 = this.getPoint( t1 );
var pt2 = this.getPoint( t2 );
var vec = pt2.clone().sub( pt1 );
return vec.normalize();
},
getTangentAt: function ( u ) {
var t = this.getUtoTmapping( u );
return this.getTangent( t );
},
computeFrenetFrames: function ( segments, closed ) {
// see http://www.cs.indiana.edu/pub/techreports/TR425.pdf
var normal = new Vector3();
var tangents = [];
var normals = [];
var binormals = [];
var vec = new Vector3();
var mat = new Matrix4();
var i, u, theta;
// compute the tangent vectors for each segment on the curve
for ( i = 0; i <= segments; i ++ ) {
u = i / segments;
tangents[ i ] = this.getTangentAt( u );
tangents[ i ].normalize();
}
// select an initial normal vector perpendicular to the first tangent vector,
// and in the direction of the minimum tangent xyz component
normals[ 0 ] = new Vector3();
binormals[ 0 ] = new Vector3();
var min = Number.MAX_VALUE;
var tx = Math.abs( tangents[ 0 ].x );
var ty = Math.abs( tangents[ 0 ].y );
var tz = Math.abs( tangents[ 0 ].z );
if ( tx <= min ) {
min = tx;
normal.set( 1, 0, 0 );
}
if ( ty <= min ) {
min = ty;
normal.set( 0, 1, 0 );
}
if ( tz <= min ) {
normal.set( 0, 0, 1 );
}
vec.crossVectors( tangents[ 0 ], normal ).normalize();
normals[ 0 ].crossVectors( tangents[ 0 ], vec );
binormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] );
// compute the slowly-varying normal and binormal vectors for each segment on the curve
for ( i = 1; i <= segments; i ++ ) {
normals[ i ] = normals[ i - 1 ].clone();
binormals[ i ] = binormals[ i - 1 ].clone();
vec.crossVectors( tangents[ i - 1 ], tangents[ i ] );
if ( vec.length() > Number.EPSILON ) {
vec.normalize();
theta = Math.acos( _Math.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors
normals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) );
}
binormals[ i ].crossVectors( tangents[ i ], normals[ i ] );
}
// if the curve is closed, postprocess the vectors so the first and last normal vectors are the same
if ( closed === true ) {
theta = Math.acos( _Math.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) );
theta /= segments;
if ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) {
theta = - theta;
}
for ( i = 1; i <= segments; i ++ ) {
// twist a little...
normals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) );
binormals[ i ].crossVectors( tangents[ i ], normals[ i ] );
}
}
return {
tangents: tangents,
normals: normals,
binormals: binormals
};
}
} );
function LineCurve( v1, v2 ) {
Curve.call( this );
this.v1 = v1;
this.v2 = v2;
}
LineCurve.prototype = Object.create( Curve.prototype );
LineCurve.prototype.constructor = LineCurve;
LineCurve.prototype.isLineCurve = true;
LineCurve.prototype.getPoint = function ( t ) {
if ( t === 1 ) {
return this.v2.clone();
}
var point = this.v2.clone().sub( this.v1 );
point.multiplyScalar( t ).add( this.v1 );
return point;
};
// Line curve is linear, so we can overwrite default getPointAt
LineCurve.prototype.getPointAt = function ( u ) {
return this.getPoint( u );
};
LineCurve.prototype.getTangent = function ( t ) {
var tangent = this.v2.clone().sub( this.v1 );
return tangent.normalize();
};
/**
* @author zz85 / http://www.lab4games.net/zz85/blog
*
**/
/**************************************************************
* Curved Path - a curve path is simply a array of connected
* curves, but retains the api of a curve
**************************************************************/
function CurvePath() {
Curve.call( this );
this.curves = [];
this.autoClose = false; // Automatically closes the path
}
CurvePath.prototype = Object.assign( Object.create( Curve.prototype ), {
constructor: CurvePath,
add: function ( curve ) {
this.curves.push( curve );
},
closePath: function () {
// Add a line curve if start and end of lines are not connected
var startPoint = this.curves[ 0 ].getPoint( 0 );
var endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 );
if ( ! startPoint.equals( endPoint ) ) {
this.curves.push( new LineCurve( endPoint, startPoint ) );
}
},
// To get accurate point with reference to
// entire path distance at time t,
// following has to be done:
// 1. Length of each sub path have to be known
// 2. Locate and identify type of curve
// 3. Get t for the curve
// 4. Return curve.getPointAt(t')
getPoint: function ( t ) {
var d = t * this.getLength();
var curveLengths = this.getCurveLengths();
var i = 0;
// To think about boundaries points.
while ( i < curveLengths.length ) {
if ( curveLengths[ i ] >= d ) {
var diff = curveLengths[ i ] - d;
var curve = this.curves[ i ];
var segmentLength = curve.getLength();
var u = segmentLength === 0 ? 0 : 1 - diff / segmentLength;
return curve.getPointAt( u );
}
i ++;
}
return null;
// loop where sum != 0, sum > d , sum+1 <d
},
// We cannot use the default THREE.Curve getPoint() with getLength() because in
// THREE.Curve, getLength() depends on getPoint() but in THREE.CurvePath
// getPoint() depends on getLength
getLength: function () {
var lens = this.getCurveLengths();
return lens[ lens.length - 1 ];
},
// cacheLengths must be recalculated.
updateArcLengths: function () {
this.needsUpdate = true;
this.cacheLengths = null;
this.getCurveLengths();
},
// Compute lengths and cache them
// We cannot overwrite getLengths() because UtoT mapping uses it.
getCurveLengths: function () {
// We use cache values if curves and cache array are same length
if ( this.cacheLengths && this.cacheLengths.length === this.curves.length ) {
return this.cacheLengths;
}
// Get length of sub-curve
// Push sums into cached array
var lengths = [], sums = 0;
for ( var i = 0, l = this.curves.length; i < l; i ++ ) {
sums += this.curves[ i ].getLength();
lengths.push( sums );
}
this.cacheLengths = lengths;
return lengths;
},
getSpacedPoints: function ( divisions ) {
if ( divisions === undefined ) divisions = 40;
var points = [];
for ( var i = 0; i <= divisions; i ++ ) {
points.push( this.getPoint( i / divisions ) );
}
if ( this.autoClose ) {
points.push( points[ 0 ] );
}
return points;
},
getPoints: function ( divisions ) {
divisions = divisions || 12;
var points = [], last;
for ( var i = 0, curves = this.curves; i < curves.length; i ++ ) {
var curve = curves[ i ];
var resolution = (curve && curve.isEllipseCurve) ? divisions * 2
: (curve && curve.isLineCurve) ? 1
: (curve && curve.isSplineCurve) ? divisions * curve.points.length
: divisions;
var pts = curve.getPoints( resolution );
for ( var j = 0; j < pts.length; j++ ) {
var point = pts[ j ];
if ( last && last.equals( point ) ) continue; // ensures no consecutive points are duplicates
points.push( point );
last = point;
}
}
if ( this.autoClose && points.length > 1 && !points[ points.length - 1 ].equals( points[ 0 ] ) ) {
points.push( points[ 0 ] );
}
return points;
},
/**************************************************************
* Create Geometries Helpers
**************************************************************/
/// Generate geometry from path points (for Line or Points objects)
createPointsGeometry: function ( divisions ) {
var pts = this.getPoints( divisions );
return this.createGeometry( pts );
},
// Generate geometry from equidistant sampling along the path
createSpacedPointsGeometry: function ( divisions ) {
var pts = this.getSpacedPoints( divisions );
return this.createGeometry( pts );
},
createGeometry: function ( points ) {
var geometry = new Geometry();
for ( var i = 0, l = points.length; i < l; i ++ ) {
var point = points[ i ];
geometry.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) );
}
return geometry;
}
} );
function EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {
Curve.call( this );
this.aX = aX;
this.aY = aY;
this.xRadius = xRadius;
this.yRadius = yRadius;
this.aStartAngle = aStartAngle;
this.aEndAngle = aEndAngle;
this.aClockwise = aClockwise;
this.aRotation = aRotation || 0;
}
EllipseCurve.prototype = Object.create( Curve.prototype );
EllipseCurve.prototype.constructor = EllipseCurve;
EllipseCurve.prototype.isEllipseCurve = true;
EllipseCurve.prototype.getPoint = function ( t ) {
var twoPi = Math.PI * 2;
var deltaAngle = this.aEndAngle - this.aStartAngle;
var samePoints = Math.abs( deltaAngle ) < Number.EPSILON;
// ensures that deltaAngle is 0 .. 2 PI
while ( deltaAngle < 0 ) deltaAngle += twoPi;
while ( deltaAngle > twoPi ) deltaAngle -= twoPi;
if ( deltaAngle < Number.EPSILON ) {
if ( samePoints ) {
deltaAngle = 0;
} else {
deltaAngle = twoPi;
}
}
if ( this.aClockwise === true && ! samePoints ) {
if ( deltaAngle === twoPi ) {
deltaAngle = - twoPi;
} else {
deltaAngle = deltaAngle - twoPi;
}
}
var angle = this.aStartAngle + t * deltaAngle;
var x = this.aX + this.xRadius * Math.cos( angle );
var y = this.aY + this.yRadius * Math.sin( angle );
if ( this.aRotation !== 0 ) {
var cos = Math.cos( this.aRotation );
var sin = Math.sin( this.aRotation );
var tx = x - this.aX;
var ty = y - this.aY;
// Rotate the point about the center of the ellipse.
x = tx * cos - ty * sin + this.aX;
y = tx * sin + ty * cos + this.aY;
}
return new Vector2( x, y );
};
function SplineCurve( points /* array of Vector2 */ ) {
Curve.call( this );
this.points = ( points === undefined ) ? [] : points;
}
SplineCurve.prototype = Object.create( Curve.prototype );
SplineCurve.prototype.constructor = SplineCurve;
SplineCurve.prototype.isSplineCurve = true;
SplineCurve.prototype.getPoint = function ( t ) {
var points = this.points;
var point = ( points.length - 1 ) * t;
var intPoint = Math.floor( point );
var weight = point - intPoint;
var point0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ];
var point1 = points[ intPoint ];
var point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];
var point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];
return new Vector2(
CatmullRom( weight, point0.x, point1.x, point2.x, point3.x ),
CatmullRom( weight, point0.y, point1.y, point2.y, point3.y )
);
};
function CubicBezierCurve( v0, v1, v2, v3 ) {
Curve.call( this );
this.v0 = v0;
this.v1 = v1;
this.v2 = v2;
this.v3 = v3;
}
CubicBezierCurve.prototype = Object.create( Curve.prototype );
CubicBezierCurve.prototype.constructor = CubicBezierCurve;
CubicBezierCurve.prototype.getPoint = function ( t ) {
var v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;
return new Vector2(
CubicBezier( t, v0.x, v1.x, v2.x, v3.x ),
CubicBezier( t, v0.y, v1.y, v2.y, v3.y )
);
};
function QuadraticBezierCurve( v0, v1, v2 ) {
Curve.call( this );
this.v0 = v0;
this.v1 = v1;
this.v2 = v2;
}
QuadraticBezierCurve.prototype = Object.create( Curve.prototype );
QuadraticBezierCurve.prototype.constructor = QuadraticBezierCurve;
QuadraticBezierCurve.prototype.getPoint = function ( t ) {
var v0 = this.v0, v1 = this.v1, v2 = this.v2;
return new Vector2(
QuadraticBezier( t, v0.x, v1.x, v2.x ),
QuadraticBezier( t, v0.y, v1.y, v2.y )
);
};
var PathPrototype = Object.assign( Object.create( CurvePath.prototype ), {
fromPoints: function ( vectors ) {
this.moveTo( vectors[ 0 ].x, vectors[ 0 ].y );
for ( var i = 1, l = vectors.length; i < l; i ++ ) {
this.lineTo( vectors[ i ].x, vectors[ i ].y );
}
},
moveTo: function ( x, y ) {
this.currentPoint.set( x, y ); // TODO consider referencing vectors instead of copying?
},
lineTo: function ( x, y ) {
var curve = new LineCurve( this.currentPoint.clone(), new Vector2( x, y ) );
this.curves.push( curve );
this.currentPoint.set( x, y );
},
quadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {
var curve = new QuadraticBezierCurve(
this.currentPoint.clone(),
new Vector2( aCPx, aCPy ),
new Vector2( aX, aY )
);
this.curves.push( curve );
this.currentPoint.set( aX, aY );
},
bezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {
var curve = new CubicBezierCurve(
this.currentPoint.clone(),
new Vector2( aCP1x, aCP1y ),
new Vector2( aCP2x, aCP2y ),
new Vector2( aX, aY )
);
this.curves.push( curve );
this.currentPoint.set( aX, aY );
},
splineThru: function ( pts /*Array of Vector*/ ) {
var npts = [ this.currentPoint.clone() ].concat( pts );
var curve = new SplineCurve( npts );
this.curves.push( curve );
this.currentPoint.copy( pts[ pts.length - 1 ] );
},
arc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {
var x0 = this.currentPoint.x;
var y0 = this.currentPoint.y;
this.absarc( aX + x0, aY + y0, aRadius,
aStartAngle, aEndAngle, aClockwise );
},
absarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {
this.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );
},
ellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {
var x0 = this.currentPoint.x;
var y0 = this.currentPoint.y;
this.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );
},
absellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {
var curve = new EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );
if ( this.curves.length > 0 ) {
// if a previous curve is present, attempt to join
var firstPoint = curve.getPoint( 0 );
if ( ! firstPoint.equals( this.currentPoint ) ) {
this.lineTo( firstPoint.x, firstPoint.y );
}
}
this.curves.push( curve );
var lastPoint = curve.getPoint( 1 );
this.currentPoint.copy( lastPoint );
}
} );
/**
* @author zz85 / http://www.lab4games.net/zz85/blog
* Creates free form 2d path using series of points, lines or curves.
**/
function Path( points ) {
CurvePath.call( this );
this.currentPoint = new Vector2();
if ( points ) {
this.fromPoints( points );
}
}
Path.prototype = PathPrototype;
PathPrototype.constructor = Path;
/**
* @author zz85 / http://www.lab4games.net/zz85/blog
* Defines a 2d shape plane using paths.
**/
// STEP 1 Create a path.
// STEP 2 Turn path into shape.
// STEP 3 ExtrudeGeometry takes in Shape/Shapes
// STEP 3a - Extract points from each shape, turn to vertices
// STEP 3b - Triangulate each shape, add faces.
function Shape() {
Path.apply( this, arguments );
this.holes = [];
}
Shape.prototype = Object.assign( Object.create( PathPrototype ), {
constructor: Shape,
getPointsHoles: function ( divisions ) {
var holesPts = [];
for ( var i = 0, l = this.holes.length; i < l; i ++ ) {
holesPts[ i ] = this.holes[ i ].getPoints( divisions );
}
return holesPts;
},
// Get points of shape and holes (keypoints based on segments parameter)
extractAllPoints: function ( divisions ) {
return {
shape: this.getPoints( divisions ),
holes: this.getPointsHoles( divisions )
};
},
extractPoints: function ( divisions ) {
return this.extractAllPoints( divisions );
}
} );
/**
* @author zz85 / http://www.lab4games.net/zz85/blog
* minimal class for proxing functions to Path. Replaces old "extractSubpaths()"
**/
function ShapePath() {
this.subPaths = [];
this.currentPath = null;
}
Object.assign( ShapePath.prototype, {
moveTo: function ( x, y ) {
this.currentPath = new Path();
this.subPaths.push( this.currentPath );
this.currentPath.moveTo( x, y );
},
lineTo: function ( x, y ) {
this.currentPath.lineTo( x, y );
},
quadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {
this.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY );
},
bezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {
this.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY );
},
splineThru: function ( pts ) {
this.currentPath.splineThru( pts );
},
toShapes: function ( isCCW, noHoles ) {
function toShapesNoHoles( inSubpaths ) {
var shapes = [];
for ( var i = 0, l = inSubpaths.length; i < l; i ++ ) {
var tmpPath = inSubpaths[ i ];
var tmpShape = new Shape();
tmpShape.curves = tmpPath.curves;
shapes.push( tmpShape );
}
return shapes;
}
function isPointInsidePolygon( inPt, inPolygon ) {
var polyLen = inPolygon.length;
// inPt on polygon contour => immediate success or
// toggling of inside/outside at every single! intersection point of an edge
// with the horizontal line through inPt, left of inPt
// not counting lowerY endpoints of edges and whole edges on that line
var inside = false;
for ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) {
var edgeLowPt = inPolygon[ p ];
var edgeHighPt = inPolygon[ q ];
var edgeDx = edgeHighPt.x - edgeLowPt.x;
var edgeDy = edgeHighPt.y - edgeLowPt.y;
if ( Math.abs( edgeDy ) > Number.EPSILON ) {
// not parallel
if ( edgeDy < 0 ) {
edgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx;
edgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy;
}
if ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) continue;
if ( inPt.y === edgeLowPt.y ) {
if ( inPt.x === edgeLowPt.x ) return true; // inPt is on contour ?
// continue; // no intersection or edgeLowPt => doesn't count !!!
} else {
var perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y );
if ( perpEdge === 0 ) return true; // inPt is on contour ?
if ( perpEdge < 0 ) continue;
inside = ! inside; // true intersection left of inPt
}
} else {
// parallel or collinear
if ( inPt.y !== edgeLowPt.y ) continue; // parallel
// edge lies on the same horizontal line as inPt
if ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) ||
( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) ) return true; // inPt: Point on contour !
// continue;
}
}
return inside;
}
var isClockWise = ShapeUtils.isClockWise;
var subPaths = this.subPaths;
if ( subPaths.length === 0 ) return [];
if ( noHoles === true ) return toShapesNoHoles( subPaths );
var solid, tmpPath, tmpShape, shapes = [];
if ( subPaths.length === 1 ) {
tmpPath = subPaths[ 0 ];
tmpShape = new Shape();
tmpShape.curves = tmpPath.curves;
shapes.push( tmpShape );
return shapes;
}
var holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() );
holesFirst = isCCW ? ! holesFirst : holesFirst;
// console.log("Holes first", holesFirst);
var betterShapeHoles = [];
var newShapes = [];
var newShapeHoles = [];
var mainIdx = 0;
var tmpPoints;
newShapes[ mainIdx ] = undefined;
newShapeHoles[ mainIdx ] = [];
for ( var i = 0, l = subPaths.length; i < l; i ++ ) {
tmpPath = subPaths[ i ];
tmpPoints = tmpPath.getPoints();
solid = isClockWise( tmpPoints );
solid = isCCW ? ! solid : solid;
if ( solid ) {
if ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) ) mainIdx ++;
newShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints };
newShapes[ mainIdx ].s.curves = tmpPath.curves;
if ( holesFirst ) mainIdx ++;
newShapeHoles[ mainIdx ] = [];
//console.log('cw', i);
} else {
newShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } );
//console.log('ccw', i);
}
}
// only Holes? -> probably all Shapes with wrong orientation
if ( ! newShapes[ 0 ] ) return toShapesNoHoles( subPaths );
if ( newShapes.length > 1 ) {
var ambiguous = false;
var toChange = [];
for ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {
betterShapeHoles[ sIdx ] = [];
}
for ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {
var sho = newShapeHoles[ sIdx ];
for ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) {
var ho = sho[ hIdx ];
var hole_unassigned = true;
for ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) {
if ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) {
if ( sIdx !== s2Idx ) toChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } );
if ( hole_unassigned ) {
hole_unassigned = false;
betterShapeHoles[ s2Idx ].push( ho );
} else {
ambiguous = true;
}
}
}
if ( hole_unassigned ) {
betterShapeHoles[ sIdx ].push( ho );
}
}
}
// console.log("ambiguous: ", ambiguous);
if ( toChange.length > 0 ) {
// console.log("to change: ", toChange);
if ( ! ambiguous ) newShapeHoles = betterShapeHoles;
}
}
var tmpHoles;
for ( var i = 0, il = newShapes.length; i < il; i ++ ) {
tmpShape = newShapes[ i ].s;
shapes.push( tmpShape );
tmpHoles = newShapeHoles[ i ];
for ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) {
tmpShape.holes.push( tmpHoles[ j ].h );
}
}
//console.log("shape", shapes);
return shapes;
}
} );
/**
* @author zz85 / http://www.lab4games.net/zz85/blog
* @author mrdoob / http://mrdoob.com/
*/
function Font( data ) {
this.data = data;
}
Object.assign( Font.prototype, {
isFont: true,
generateShapes: function ( text, size, divisions ) {
function createPaths( text ) {
var chars = String( text ).split( '' );
var scale = size / data.resolution;
var line_height = ( data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness ) * scale;
var offsetX = 0, offsetY = 0;
var paths = [];
for ( var i = 0; i < chars.length; i ++ ) {
var char = chars[ i ];
if ( char === '\n' ) {
offsetX = 0;
offsetY -= line_height;
} else {
var ret = createPath( char, scale, offsetX, offsetY );
offsetX += ret.offsetX;
paths.push( ret.path );
}
}
return paths;
}
function createPath( c, scale, offsetX, offsetY ) {
var glyph = data.glyphs[ c ] || data.glyphs[ '?' ];
if ( ! glyph ) return;
var path = new ShapePath();
var pts = [];
var x, y, cpx, cpy, cpx0, cpy0, cpx1, cpy1, cpx2, cpy2, laste;
if ( glyph.o ) {
var outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );
for ( var i = 0, l = outline.length; i < l; ) {
var action = outline[ i ++ ];
switch ( action ) {
case 'm': // moveTo
x = outline[ i ++ ] * scale + offsetX;
y = outline[ i ++ ] * scale + offsetY;
path.moveTo( x, y );
break;
case 'l': // lineTo
x = outline[ i ++ ] * scale + offsetX;
y = outline[ i ++ ] * scale + offsetY;
path.lineTo( x, y );
break;
case 'q': // quadraticCurveTo
cpx = outline[ i ++ ] * scale + offsetX;
cpy = outline[ i ++ ] * scale + offsetY;
cpx1 = outline[ i ++ ] * scale + offsetX;
cpy1 = outline[ i ++ ] * scale + offsetY;
path.quadraticCurveTo( cpx1, cpy1, cpx, cpy );
laste = pts[ pts.length - 1 ];
if ( laste ) {
cpx0 = laste.x;
cpy0 = laste.y;
for ( var i2 = 1; i2 <= divisions; i2 ++ ) {
var t = i2 / divisions;
QuadraticBezier( t, cpx0, cpx1, cpx );
QuadraticBezier( t, cpy0, cpy1, cpy );
}
}
break;
case 'b': // bezierCurveTo
cpx = outline[ i ++ ] * scale + offsetX;
cpy = outline[ i ++ ] * scale + offsetY;
cpx1 = outline[ i ++ ] * scale + offsetX;
cpy1 = outline[ i ++ ] * scale + offsetY;
cpx2 = outline[ i ++ ] * scale + offsetX;
cpy2 = outline[ i ++ ] * scale + offsetY;
path.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );
laste = pts[ pts.length - 1 ];
if ( laste ) {
cpx0 = laste.x;
cpy0 = laste.y;
for ( var i2 = 1; i2 <= divisions; i2 ++ ) {
var t = i2 / divisions;
CubicBezier( t, cpx0, cpx1, cpx2, cpx );
CubicBezier( t, cpy0, cpy1, cpy2, cpy );
}
}
break;
}
}
}
return { offsetX: glyph.ha * scale, path: path };
}
//
if ( size === undefined ) size = 100;
if ( divisions === undefined ) divisions = 4;
var data = this.data;
var paths = createPaths( text );
var shapes = [];
for ( var p = 0, pl = paths.length; p < pl; p ++ ) {
Array.prototype.push.apply( shapes, paths[ p ].toShapes() );
}
return shapes;
}
} );
/**
* @author mrdoob / http://mrdoob.com/
*/
function FontLoader( manager ) {
this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
}
Object.assign( FontLoader.prototype, {
load: function ( url, onLoad, onProgress, onError ) {
var scope = this;
var loader = new FileLoader( this.manager );
loader.load( url, function ( text ) {
var json;
try {
json = JSON.parse( text );
} catch ( e ) {
console.warn( 'THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.' );
json = JSON.parse( text.substring( 65, text.length - 2 ) );
}
var font = scope.parse( json );
if ( onLoad ) onLoad( font );
}, onProgress, onError );
},
parse: function ( json ) {
return new Font( json );
}
} );
var context;
var AudioContext = {
getContext: function () {
if ( context === undefined ) {
context = new ( window.AudioContext || window.webkitAudioContext )();
}
return context;
},
setContext: function ( value ) {
context = value;
}
};
/**
* @author Reece Aaron Lecrivain / http://reecenotes.com/
*/
function AudioLoader( manager ) {
this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
}
Object.assign( AudioLoader.prototype, {
load: function ( url, onLoad, onProgress, onError ) {
var loader = new FileLoader( this.manager );
loader.setResponseType( 'arraybuffer' );
loader.load( url, function ( buffer ) {
var context = AudioContext.getContext();
context.decodeAudioData( buffer, function ( audioBuffer ) {
onLoad( audioBuffer );
} );
}, onProgress, onError );
}
} );
/**
* @author mrdoob / http://mrdoob.com/
*/
function StereoCamera() {
this.type = 'StereoCamera';
this.aspect = 1;
this.eyeSep = 0.064;
this.cameraL = new PerspectiveCamera();
this.cameraL.layers.enable( 1 );
this.cameraL.matrixAutoUpdate = false;
this.cameraR = new PerspectiveCamera();
this.cameraR.layers.enable( 2 );
this.cameraR.matrixAutoUpdate = false;
}
Object.assign( StereoCamera.prototype, {
update: ( function () {
var instance, focus, fov, aspect, near, far, zoom, eyeSep;
var eyeRight = new Matrix4();
var eyeLeft = new Matrix4();
return function update( camera ) {
var needsUpdate = instance !== this || focus !== camera.focus || fov !== camera.fov ||
aspect !== camera.aspect * this.aspect || near !== camera.near ||
far !== camera.far || zoom !== camera.zoom || eyeSep !== this.eyeSep;
if ( needsUpdate ) {
instance = this;
focus = camera.focus;
fov = camera.fov;
aspect = camera.aspect * this.aspect;
near = camera.near;
far = camera.far;
zoom = camera.zoom;
// Off-axis stereoscopic effect based on
// http://paulbourke.net/stereographics/stereorender/
var projectionMatrix = camera.projectionMatrix.clone();
eyeSep = this.eyeSep / 2;
var eyeSepOnProjection = eyeSep * near / focus;
var ymax = ( near * Math.tan( _Math.DEG2RAD * fov * 0.5 ) ) / zoom;
var xmin, xmax;
// translate xOffset
eyeLeft.elements[ 12 ] = - eyeSep;
eyeRight.elements[ 12 ] = eyeSep;
// for left eye
xmin = - ymax * aspect + eyeSepOnProjection;
xmax = ymax * aspect + eyeSepOnProjection;
projectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );
projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );
this.cameraL.projectionMatrix.copy( projectionMatrix );
// for right eye
xmin = - ymax * aspect - eyeSepOnProjection;
xmax = ymax * aspect - eyeSepOnProjection;
projectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );
projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );
this.cameraR.projectionMatrix.copy( projectionMatrix );
}
this.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( eyeLeft );
this.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( eyeRight );
};
} )()
} );
/**
* Camera for rendering cube maps
* - renders scene into axis-aligned cube
*
* @author alteredq / http://alteredqualia.com/
*/
function CubeCamera( near, far, cubeResolution ) {
Object3D.call( this );
this.type = 'CubeCamera';
var fov = 90, aspect = 1;
var cameraPX = new PerspectiveCamera( fov, aspect, near, far );
cameraPX.up.set( 0, - 1, 0 );
cameraPX.lookAt( new Vector3( 1, 0, 0 ) );
this.add( cameraPX );
var cameraNX = new PerspectiveCamera( fov, aspect, near, far );
cameraNX.up.set( 0, - 1, 0 );
cameraNX.lookAt( new Vector3( - 1, 0, 0 ) );
this.add( cameraNX );
var cameraPY = new PerspectiveCamera( fov, aspect, near, far );
cameraPY.up.set( 0, 0, 1 );
cameraPY.lookAt( new Vector3( 0, 1, 0 ) );
this.add( cameraPY );
var cameraNY = new PerspectiveCamera( fov, aspect, near, far );
cameraNY.up.set( 0, 0, - 1 );
cameraNY.lookAt( new Vector3( 0, - 1, 0 ) );
this.add( cameraNY );
var cameraPZ = new PerspectiveCamera( fov, aspect, near, far );
cameraPZ.up.set( 0, - 1, 0 );
cameraPZ.lookAt( new Vector3( 0, 0, 1 ) );
this.add( cameraPZ );
var cameraNZ = new PerspectiveCamera( fov, aspect, near, far );
cameraNZ.up.set( 0, - 1, 0 );
cameraNZ.lookAt( new Vector3( 0, 0, - 1 ) );
this.add( cameraNZ );
var options = { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter };
this.renderTarget = new WebGLRenderTargetCube( cubeResolution, cubeResolution, options );
this.renderTarget.texture.name = "CubeCamera";
this.updateCubeMap = function ( renderer, scene ) {
if ( this.parent === null ) this.updateMatrixWorld();
var renderTarget = this.renderTarget;
var generateMipmaps = renderTarget.texture.generateMipmaps;
renderTarget.texture.generateMipmaps = false;
renderTarget.activeCubeFace = 0;
renderer.render( scene, cameraPX, renderTarget );
renderTarget.activeCubeFace = 1;
renderer.render( scene, cameraNX, renderTarget );
renderTarget.activeCubeFace = 2;
renderer.render( scene, cameraPY, renderTarget );
renderTarget.activeCubeFace = 3;
renderer.render( scene, cameraNY, renderTarget );
renderTarget.activeCubeFace = 4;
renderer.render( scene, cameraPZ, renderTarget );
renderTarget.texture.generateMipmaps = generateMipmaps;
renderTarget.activeCubeFace = 5;
renderer.render( scene, cameraNZ, renderTarget );
renderer.setRenderTarget( null );
};
}
CubeCamera.prototype = Object.create( Object3D.prototype );
CubeCamera.prototype.constructor = CubeCamera;
/**
* @author mrdoob / http://mrdoob.com/
*/
function AudioListener() {
Object3D.call( this );
this.type = 'AudioListener';
this.context = AudioContext.getContext();
this.gain = this.context.createGain();
this.gain.connect( this.context.destination );
this.filter = null;
}
AudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), {
constructor: AudioListener,
getInput: function () {
return this.gain;
},
removeFilter: function ( ) {
if ( this.filter !== null ) {
this.gain.disconnect( this.filter );
this.filter.disconnect( this.context.destination );
this.gain.connect( this.context.destination );
this.filter = null;
}
},
getFilter: function () {
return this.filter;
},
setFilter: function ( value ) {
if ( this.filter !== null ) {
this.gain.disconnect( this.filter );
this.filter.disconnect( this.context.destination );
} else {
this.gain.disconnect( this.context.destination );
}
this.filter = value;
this.gain.connect( this.filter );
this.filter.connect( this.context.destination );
},
getMasterVolume: function () {
return this.gain.gain.value;
},
setMasterVolume: function ( value ) {
this.gain.gain.value = value;
},
updateMatrixWorld: ( function () {
var position = new Vector3();
var quaternion = new Quaternion();
var scale = new Vector3();
var orientation = new Vector3();
return function updateMatrixWorld( force ) {
Object3D.prototype.updateMatrixWorld.call( this, force );
var listener = this.context.listener;
var up = this.up;
this.matrixWorld.decompose( position, quaternion, scale );
orientation.set( 0, 0, - 1 ).applyQuaternion( quaternion );
if ( listener.positionX ) {
listener.positionX.setValueAtTime( position.x, this.context.currentTime );
listener.positionY.setValueAtTime( position.y, this.context.currentTime );
listener.positionZ.setValueAtTime( position.z, this.context.currentTime );
listener.forwardX.setValueAtTime( orientation.x, this.context.currentTime );
listener.forwardY.setValueAtTime( orientation.y, this.context.currentTime );
listener.forwardZ.setValueAtTime( orientation.z, this.context.currentTime );
listener.upX.setValueAtTime( up.x, this.context.currentTime );
listener.upY.setValueAtTime( up.y, this.context.currentTime );
listener.upZ.setValueAtTime( up.z, this.context.currentTime );
} else {
listener.setPosition( position.x, position.y, position.z );
listener.setOrientation( orientation.x, orientation.y, orientation.z, up.x, up.y, up.z );
}
};
} )()
} );
/**
* @author mrdoob / http://mrdoob.com/
* @author Reece Aaron Lecrivain / http://reecenotes.com/
*/
function Audio( listener ) {
Object3D.call( this );
this.type = 'Audio';
this.context = listener.context;
this.gain = this.context.createGain();
this.gain.connect( listener.getInput() );
this.autoplay = false;
this.buffer = null;
this.loop = false;
this.startTime = 0;
this.playbackRate = 1;
this.isPlaying = false;
this.hasPlaybackControl = true;
this.sourceType = 'empty';
this.filters = [];
}
Audio.prototype = Object.assign( Object.create( Object3D.prototype ), {
constructor: Audio,
getOutput: function () {
return this.gain;
},
setNodeSource: function ( audioNode ) {
this.hasPlaybackControl = false;
this.sourceType = 'audioNode';
this.source = audioNode;
this.connect();
return this;
},
setBuffer: function ( audioBuffer ) {
this.buffer = audioBuffer;
this.sourceType = 'buffer';
if ( this.autoplay ) this.play();
return this;
},
play: function () {
if ( this.isPlaying === true ) {
console.warn( 'THREE.Audio: Audio is already playing.' );
return;
}
if ( this.hasPlaybackControl === false ) {
console.warn( 'THREE.Audio: this Audio has no playback control.' );
return;
}
var source = this.context.createBufferSource();
source.buffer = this.buffer;
source.loop = this.loop;
source.onended = this.onEnded.bind( this );
source.playbackRate.setValueAtTime( this.playbackRate, this.startTime );
source.start( 0, this.startTime );
this.isPlaying = true;
this.source = source;
return this.connect();
},
pause: function () {
if ( this.hasPlaybackControl === false ) {
console.warn( 'THREE.Audio: this Audio has no playback control.' );
return;
}
this.source.stop();
this.startTime = this.context.currentTime;
this.isPlaying = false;
return this;
},
stop: function () {
if ( this.hasPlaybackControl === false ) {
console.warn( 'THREE.Audio: this Audio has no playback control.' );
return;
}
this.source.stop();
this.startTime = 0;
this.isPlaying = false;
return this;
},
connect: function () {
if ( this.filters.length > 0 ) {
this.source.connect( this.filters[ 0 ] );
for ( var i = 1, l = this.filters.length; i < l; i ++ ) {
this.filters[ i - 1 ].connect( this.filters[ i ] );
}
this.filters[ this.filters.length - 1 ].connect( this.getOutput() );
} else {
this.source.connect( this.getOutput() );
}
return this;
},
disconnect: function () {
if ( this.filters.length > 0 ) {
this.source.disconnect( this.filters[ 0 ] );
for ( var i = 1, l = this.filters.length; i < l; i ++ ) {
this.filters[ i - 1 ].disconnect( this.filters[ i ] );
}
this.filters[ this.filters.length - 1 ].disconnect( this.getOutput() );
} else {
this.source.disconnect( this.getOutput() );
}
return this;
},
getFilters: function () {
return this.filters;
},
setFilters: function ( value ) {
if ( ! value ) value = [];
if ( this.isPlaying === true ) {
this.disconnect();
this.filters = value;
this.connect();
} else {
this.filters = value;
}
return this;
},
getFilter: function () {
return this.getFilters()[ 0 ];
},
setFilter: function ( filter ) {
return this.setFilters( filter ? [ filter ] : [] );
},
setPlaybackRate: function ( value ) {
if ( this.hasPlaybackControl === false ) {
console.warn( 'THREE.Audio: this Audio has no playback control.' );
return;
}
this.playbackRate = value;
if ( this.isPlaying === true ) {
this.source.playbackRate.setValueAtTime( this.playbackRate, this.context.currentTime );
}
return this;
},
getPlaybackRate: function () {
return this.playbackRate;
},
onEnded: function () {
this.isPlaying = false;
},
getLoop: function () {
if ( this.hasPlaybackControl === false ) {
console.warn( 'THREE.Audio: this Audio has no playback control.' );
return false;
}
return this.loop;
},
setLoop: function ( value ) {
if ( this.hasPlaybackControl === false ) {
console.warn( 'THREE.Audio: this Audio has no playback control.' );
return;
}
this.loop = value;
if ( this.isPlaying === true ) {
this.source.loop = this.loop;
}
return this;
},
getVolume: function () {
return this.gain.gain.value;
},
setVolume: function ( value ) {
this.gain.gain.value = value;
return this;
}
} );
/**
* @author mrdoob / http://mrdoob.com/
*/
function PositionalAudio( listener ) {
Audio.call( this, listener );
this.panner = this.context.createPanner();
this.panner.connect( this.gain );
}
PositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), {
constructor: PositionalAudio,
getOutput: function () {
return this.panner;
},
getRefDistance: function () {
return this.panner.refDistance;
},
setRefDistance: function ( value ) {
this.panner.refDistance = value;
},
getRolloffFactor: function () {
return this.panner.rolloffFactor;
},
setRolloffFactor: function ( value ) {
this.panner.rolloffFactor = value;
},
getDistanceModel: function () {
return this.panner.distanceModel;
},
setDistanceModel: function ( value ) {
this.panner.distanceModel = value;
},
getMaxDistance: function () {
return this.panner.maxDistance;
},
setMaxDistance: function ( value ) {
this.panner.maxDistance = value;
},
updateMatrixWorld: ( function () {
var position = new Vector3();
return function updateMatrixWorld( force ) {
Object3D.prototype.updateMatrixWorld.call( this, force );
position.setFromMatrixPosition( this.matrixWorld );
this.panner.setPosition( position.x, position.y, position.z );
};
} )()
} );
/**
* @author mrdoob / http://mrdoob.com/
*/
function AudioAnalyser( audio, fftSize ) {
this.analyser = audio.context.createAnalyser();
this.analyser.fftSize = fftSize !== undefined ? fftSize : 2048;
this.data = new Uint8Array( this.analyser.frequencyBinCount );
audio.getOutput().connect( this.analyser );
}
Object.assign( AudioAnalyser.prototype, {
getFrequencyData: function () {
this.analyser.getByteFrequencyData( this.data );
return this.data;
},
getAverageFrequency: function () {
var value = 0, data = this.getFrequencyData();
for ( var i = 0; i < data.length; i ++ ) {
value += data[ i ];
}
return value / data.length;
}
} );
/**
*
* Buffered scene graph property that allows weighted accumulation.
*
*
* @author Ben Houston / http://clara.io/
* @author David Sarno / http://lighthaus.us/
* @author tschw
*/
function PropertyMixer( binding, typeName, valueSize ) {
this.binding = binding;
this.valueSize = valueSize;
var bufferType = Float64Array,
mixFunction;
switch ( typeName ) {
case 'quaternion':
mixFunction = this._slerp;
break;
case 'string':
case 'bool':
bufferType = Array;
mixFunction = this._select;
break;
default:
mixFunction = this._lerp;
}
this.buffer = new bufferType( valueSize * 4 );
// layout: [ incoming | accu0 | accu1 | orig ]
//
// interpolators can use .buffer as their .result
// the data then goes to 'incoming'
//
// 'accu0' and 'accu1' are used frame-interleaved for
// the cumulative result and are compared to detect
// changes
//
// 'orig' stores the original state of the property
this._mixBufferRegion = mixFunction;
this.cumulativeWeight = 0;
this.useCount = 0;
this.referenceCount = 0;
}
Object.assign( PropertyMixer.prototype, {
// accumulate data in the 'incoming' region into 'accu<i>'
accumulate: function ( accuIndex, weight ) {
// note: happily accumulating nothing when weight = 0, the caller knows
// the weight and shouldn't have made the call in the first place
var buffer = this.buffer,
stride = this.valueSize,
offset = accuIndex * stride + stride,
currentWeight = this.cumulativeWeight;
if ( currentWeight === 0 ) {
// accuN := incoming * weight
for ( var i = 0; i !== stride; ++ i ) {
buffer[ offset + i ] = buffer[ i ];
}
currentWeight = weight;
} else {
// accuN := accuN + incoming * weight
currentWeight += weight;
var mix = weight / currentWeight;
this._mixBufferRegion( buffer, offset, 0, mix, stride );
}
this.cumulativeWeight = currentWeight;
},
// apply the state of 'accu<i>' to the binding when accus differ
apply: function ( accuIndex ) {
var stride = this.valueSize,
buffer = this.buffer,
offset = accuIndex * stride + stride,
weight = this.cumulativeWeight,
binding = this.binding;
this.cumulativeWeight = 0;
if ( weight < 1 ) {
// accuN := accuN + original * ( 1 - cumulativeWeight )
var originalValueOffset = stride * 3;
this._mixBufferRegion(
buffer, offset, originalValueOffset, 1 - weight, stride );
}
for ( var i = stride, e = stride + stride; i !== e; ++ i ) {
if ( buffer[ i ] !== buffer[ i + stride ] ) {
// value has changed -> update scene graph
binding.setValue( buffer, offset );
break;
}
}
},
// remember the state of the bound property and copy it to both accus
saveOriginalState: function () {
var binding = this.binding;
var buffer = this.buffer,
stride = this.valueSize,
originalValueOffset = stride * 3;
binding.getValue( buffer, originalValueOffset );
// accu[0..1] := orig -- initially detect changes against the original
for ( var i = stride, e = originalValueOffset; i !== e; ++ i ) {
buffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ];
}
this.cumulativeWeight = 0;
},
// apply the state previously taken via 'saveOriginalState' to the binding
restoreOriginalState: function () {
var originalValueOffset = this.valueSize * 3;
this.binding.setValue( this.buffer, originalValueOffset );
},
// mix functions
_select: function ( buffer, dstOffset, srcOffset, t, stride ) {
if ( t >= 0.5 ) {
for ( var i = 0; i !== stride; ++ i ) {
buffer[ dstOffset + i ] = buffer[ srcOffset + i ];
}
}
},
_slerp: function ( buffer, dstOffset, srcOffset, t ) {
Quaternion.slerpFlat( buffer, dstOffset, buffer, dstOffset, buffer, srcOffset, t );
},
_lerp: function ( buffer, dstOffset, srcOffset, t, stride ) {
var s = 1 - t;
for ( var i = 0; i !== stride; ++ i ) {
var j = dstOffset + i;
buffer[ j ] = buffer[ j ] * s + buffer[ srcOffset + i ] * t;
}
}
} );
/**
*
* A reference to a real property in the scene graph.
*
*
* @author Ben Houston / http://clara.io/
* @author David Sarno / http://lighthaus.us/
* @author tschw
*/
function Composite( targetGroup, path, optionalParsedPath ) {
var parsedPath = optionalParsedPath || PropertyBinding.parseTrackName( path );
this._targetGroup = targetGroup;
this._bindings = targetGroup.subscribe_( path, parsedPath );
}
Object.assign( Composite.prototype, {
getValue: function ( array, offset ) {
this.bind(); // bind all binding
var firstValidIndex = this._targetGroup.nCachedObjects_,
binding = this._bindings[ firstValidIndex ];
// and only call .getValue on the first
if ( binding !== undefined ) binding.getValue( array, offset );
},
setValue: function ( array, offset ) {
var bindings = this._bindings;
for ( var i = this._targetGroup.nCachedObjects_,
n = bindings.length; i !== n; ++ i ) {
bindings[ i ].setValue( array, offset );
}
},
bind: function () {
var bindings = this._bindings;
for ( var i = this._targetGroup.nCachedObjects_,
n = bindings.length; i !== n; ++ i ) {
bindings[ i ].bind();
}
},
unbind: function () {
var bindings = this._bindings;
for ( var i = this._targetGroup.nCachedObjects_,
n = bindings.length; i !== n; ++ i ) {
bindings[ i ].unbind();
}
}
} );
function PropertyBinding( rootNode, path, parsedPath ) {
this.path = path;
this.parsedPath = parsedPath || PropertyBinding.parseTrackName( path );
this.node = PropertyBinding.findNode( rootNode, this.parsedPath.nodeName ) || rootNode;
this.rootNode = rootNode;
}
Object.assign( PropertyBinding, {
Composite: Composite,
create: function ( root, path, parsedPath ) {
if ( ! ( root && root.isAnimationObjectGroup ) ) {
return new PropertyBinding( root, path, parsedPath );
} else {
return new PropertyBinding.Composite( root, path, parsedPath );
}
},
/**
* Replaces spaces with underscores and removes unsupported characters from
* node names, to ensure compatibility with parseTrackName().
*
* @param {string} name Node name to be sanitized.
* @return {string}
*/
sanitizeNodeName: function ( name ) {
return name.replace( /\s/g, '_' ).replace( /[^\w-]/g, '' );
},
parseTrackName: function () {
// Parent directories, delimited by '/' or ':'. Currently unused, but must
// be matched to parse the rest of the track name.
var directoryRe = /((?:[\w-]+[\/:])*)/;
// Target node. May contain word characters (a-zA-Z0-9_) and '.' or '-'.
var nodeRe = /([\w-\.]+)?/;
// Object on target node, and accessor. Name may contain only word
// characters. Accessor may contain any character except closing bracket.
var objectRe = /(?:\.([\w-]+)(?:\[(.+)\])?)?/;
// Property and accessor. May contain only word characters. Accessor may
// contain any non-bracket characters.
var propertyRe = /\.([\w-]+)(?:\[(.+)\])?/;
var trackRe = new RegExp(''
+ '^'
+ directoryRe.source
+ nodeRe.source
+ objectRe.source
+ propertyRe.source
+ '$'
);
var supportedObjectNames = [ 'material', 'materials', 'bones' ];
return function ( trackName ) {
var matches = trackRe.exec( trackName );
if ( ! matches ) {
throw new Error( 'PropertyBinding: Cannot parse trackName: ' + trackName );
}
var results = {
// directoryName: matches[ 1 ], // (tschw) currently unused
nodeName: matches[ 2 ],
objectName: matches[ 3 ],
objectIndex: matches[ 4 ],
propertyName: matches[ 5 ], // required
propertyIndex: matches[ 6 ]
};
var lastDot = results.nodeName && results.nodeName.lastIndexOf( '.' );
if ( lastDot !== undefined && lastDot !== -1 ) {
var objectName = results.nodeName.substring( lastDot + 1 );
// Object names must be checked against a whitelist. Otherwise, there
// is no way to parse 'foo.bar.baz': 'baz' must be a property, but
// 'bar' could be the objectName, or part of a nodeName (which can
// include '.' characters).
if ( supportedObjectNames.indexOf( objectName ) !== -1 ) {
results.nodeName = results.nodeName.substring( 0, lastDot );
results.objectName = objectName;
}
}
if ( results.propertyName === null || results.propertyName.length === 0 ) {
throw new Error( 'PropertyBinding: can not parse propertyName from trackName: ' + trackName );
}
return results;
};
}(),
findNode: function ( root, nodeName ) {
if ( ! nodeName || nodeName === "" || nodeName === "root" || nodeName === "." || nodeName === - 1 || nodeName === root.name || nodeName === root.uuid ) {
return root;
}
// search into skeleton bones.
if ( root.skeleton ) {
var searchSkeleton = function ( skeleton ) {
for ( var i = 0; i < skeleton.bones.length; i ++ ) {
var bone = skeleton.bones[ i ];
if ( bone.name === nodeName ) {
return bone;
}
}
return null;
};
var bone = searchSkeleton( root.skeleton );
if ( bone ) {
return bone;
}
}
// search into node subtree.
if ( root.children ) {
var searchNodeSubtree = function ( children ) {
for ( var i = 0; i < children.length; i ++ ) {
var childNode = children[ i ];
if ( childNode.name === nodeName || childNode.uuid === nodeName ) {
return childNode;
}
var result = searchNodeSubtree( childNode.children );
if ( result ) return result;
}
return null;
};
var subTreeNode = searchNodeSubtree( root.children );
if ( subTreeNode ) {
return subTreeNode;
}
}
return null;
}
} );
Object.assign( PropertyBinding.prototype, { // prototype, continued
// these are used to "bind" a nonexistent property
_getValue_unavailable: function () {},
_setValue_unavailable: function () {},
BindingType: {
Direct: 0,
EntireArray: 1,
ArrayElement: 2,
HasFromToArray: 3
},
Versioning: {
None: 0,
NeedsUpdate: 1,
MatrixWorldNeedsUpdate: 2
},
GetterByBindingType: [
function getValue_direct( buffer, offset ) {
buffer[ offset ] = this.node[ this.propertyName ];
},
function getValue_array( buffer, offset ) {
var source = this.resolvedProperty;
for ( var i = 0, n = source.length; i !== n; ++ i ) {
buffer[ offset ++ ] = source[ i ];
}
},
function getValue_arrayElement( buffer, offset ) {
buffer[ offset ] = this.resolvedProperty[ this.propertyIndex ];
},
function getValue_toArray( buffer, offset ) {
this.resolvedProperty.toArray( buffer, offset );
}
],
SetterByBindingTypeAndVersioning: [
[
// Direct
function setValue_direct( buffer, offset ) {
this.node[ this.propertyName ] = buffer[ offset ];
},
function setValue_direct_setNeedsUpdate( buffer, offset ) {
this.node[ this.propertyName ] = buffer[ offset ];
this.targetObject.needsUpdate = true;
},
function setValue_direct_setMatrixWorldNeedsUpdate( buffer, offset ) {
this.node[ this.propertyName ] = buffer[ offset ];
this.targetObject.matrixWorldNeedsUpdate = true;
}
], [
// EntireArray
function setValue_array( buffer, offset ) {
var dest = this.resolvedProperty;
for ( var i = 0, n = dest.length; i !== n; ++ i ) {
dest[ i ] = buffer[ offset ++ ];
}
},
function setValue_array_setNeedsUpdate( buffer, offset ) {
var dest = this.resolvedProperty;
for ( var i = 0, n = dest.length; i !== n; ++ i ) {
dest[ i ] = buffer[ offset ++ ];
}
this.targetObject.needsUpdate = true;
},
function setValue_array_setMatrixWorldNeedsUpdate( buffer, offset ) {
var dest = this.resolvedProperty;
for ( var i = 0, n = dest.length; i !== n; ++ i ) {
dest[ i ] = buffer[ offset ++ ];
}
this.targetObject.matrixWorldNeedsUpdate = true;
}
], [
// ArrayElement
function setValue_arrayElement( buffer, offset ) {
this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];
},
function setValue_arrayElement_setNeedsUpdate( buffer, offset ) {
this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];
this.targetObject.needsUpdate = true;
},
function setValue_arrayElement_setMatrixWorldNeedsUpdate( buffer, offset ) {
this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];
this.targetObject.matrixWorldNeedsUpdate = true;
}
], [
// HasToFromArray
function setValue_fromArray( buffer, offset ) {
this.resolvedProperty.fromArray( buffer, offset );
},
function setValue_fromArray_setNeedsUpdate( buffer, offset ) {
this.resolvedProperty.fromArray( buffer, offset );
this.targetObject.needsUpdate = true;
},
function setValue_fromArray_setMatrixWorldNeedsUpdate( buffer, offset ) {
this.resolvedProperty.fromArray( buffer, offset );
this.targetObject.matrixWorldNeedsUpdate = true;
}
]
],
getValue: function getValue_unbound( targetArray, offset ) {
this.bind();
this.getValue( targetArray, offset );
// Note: This class uses a State pattern on a per-method basis:
// 'bind' sets 'this.getValue' / 'setValue' and shadows the
// prototype version of these methods with one that represents
// the bound state. When the property is not found, the methods
// become no-ops.
},
setValue: function getValue_unbound( sourceArray, offset ) {
this.bind();
this.setValue( sourceArray, offset );
},
// create getter / setter pair for a property in the scene graph
bind: function () {
var targetObject = this.node,
parsedPath = this.parsedPath,
objectName = parsedPath.objectName,
propertyName = parsedPath.propertyName,
propertyIndex = parsedPath.propertyIndex;
if ( ! targetObject ) {
targetObject = PropertyBinding.findNode(
this.rootNode, parsedPath.nodeName ) || this.rootNode;
this.node = targetObject;
}
// set fail state so we can just 'return' on error
this.getValue = this._getValue_unavailable;
this.setValue = this._setValue_unavailable;
// ensure there is a value node
if ( ! targetObject ) {
console.error( 'THREE.PropertyBinding: Trying to update node for track: ' + this.path + ' but it wasn\'t found.' );
return;
}
if ( objectName ) {
var objectIndex = parsedPath.objectIndex;
// special cases were we need to reach deeper into the hierarchy to get the face materials....
switch ( objectName ) {
case 'materials':
if ( ! targetObject.material ) {
console.error( 'THREE.PropertyBinding: Can not bind to material as node does not have a material.', this );
return;
}
if ( ! targetObject.material.materials ) {
console.error( 'THREE.PropertyBinding: Can not bind to material.materials as node.material does not have a materials array.', this );
return;
}
targetObject = targetObject.material.materials;
break;
case 'bones':
if ( ! targetObject.skeleton ) {
console.error( 'THREE.PropertyBinding: Can not bind to bones as node does not have a skeleton.', this );
return;
}
// potential future optimization: skip this if propertyIndex is already an integer
// and convert the integer string to a true integer.
targetObject = targetObject.skeleton.bones;
// support resolving morphTarget names into indices.
for ( var i = 0; i < targetObject.length; i ++ ) {
if ( targetObject[ i ].name === objectIndex ) {
objectIndex = i;
break;
}
}
break;
default:
if ( targetObject[ objectName ] === undefined ) {
console.error( 'THREE.PropertyBinding: Can not bind to objectName of node undefined.', this );
return;
}
targetObject = targetObject[ objectName ];
}
if ( objectIndex !== undefined ) {
if ( targetObject[ objectIndex ] === undefined ) {
console.error( 'THREE.PropertyBinding: Trying to bind to objectIndex of objectName, but is undefined.', this, targetObject );
return;
}
targetObject = targetObject[ objectIndex ];
}
}
// resolve property
var nodeProperty = targetObject[ propertyName ];
if ( nodeProperty === undefined ) {
var nodeName = parsedPath.nodeName;
console.error( 'THREE.PropertyBinding: Trying to update property for track: ' + nodeName +
'.' + propertyName + ' but it wasn\'t found.', targetObject );
return;
}
// determine versioning scheme
var versioning = this.Versioning.None;
if ( targetObject.needsUpdate !== undefined ) { // material
versioning = this.Versioning.NeedsUpdate;
this.targetObject = targetObject;
} else if ( targetObject.matrixWorldNeedsUpdate !== undefined ) { // node transform
versioning = this.Versioning.MatrixWorldNeedsUpdate;
this.targetObject = targetObject;
}
// determine how the property gets bound
var bindingType = this.BindingType.Direct;
if ( propertyIndex !== undefined ) {
// access a sub element of the property array (only primitives are supported right now)
if ( propertyName === "morphTargetInfluences" ) {
// potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer.
// support resolving morphTarget names into indices.
if ( ! targetObject.geometry ) {
console.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.', this );
return;
}
if ( targetObject.geometry.isBufferGeometry ) {
if ( ! targetObject.geometry.morphAttributes ) {
console.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphAttributes.', this );
return;
}
for ( var i = 0; i < this.node.geometry.morphAttributes.position.length; i ++ ) {
if ( targetObject.geometry.morphAttributes.position[ i ].name === propertyIndex ) {
propertyIndex = i;
break;
}
}
} else {
if ( ! targetObject.geometry.morphTargets ) {
console.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphTargets.', this );
return;
}
for ( var i = 0; i < this.node.geometry.morphTargets.length; i ++ ) {
if ( targetObject.geometry.morphTargets[ i ].name === propertyIndex ) {
propertyIndex = i;
break;
}
}
}
}
bindingType = this.BindingType.ArrayElement;
this.resolvedProperty = nodeProperty;
this.propertyIndex = propertyIndex;
} else if ( nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined ) {
// must use copy for Object3D.Euler/Quaternion
bindingType = this.BindingType.HasFromToArray;
this.resolvedProperty = nodeProperty;
} else if ( Array.isArray( nodeProperty ) ) {
bindingType = this.BindingType.EntireArray;
this.resolvedProperty = nodeProperty;
} else {
this.propertyName = propertyName;
}
// select getter / setter
this.getValue = this.GetterByBindingType[ bindingType ];
this.setValue = this.SetterByBindingTypeAndVersioning[ bindingType ][ versioning ];
},
unbind: function () {
this.node = null;
// back to the prototype version of getValue / setValue
// note: avoiding to mutate the shape of 'this' via 'delete'
this.getValue = this._getValue_unbound;
this.setValue = this._setValue_unbound;
}
} );
//!\ DECLARE ALIAS AFTER assign prototype !
Object.assign( PropertyBinding.prototype, {
// initial state of these methods that calls 'bind'
_getValue_unbound: PropertyBinding.prototype.getValue,
_setValue_unbound: PropertyBinding.prototype.setValue,
} );
/**
*
* A group of objects that receives a shared animation state.
*
* Usage:
*
* - Add objects you would otherwise pass as 'root' to the
* constructor or the .clipAction method of AnimationMixer.
*
* - Instead pass this object as 'root'.
*
* - You can also add and remove objects later when the mixer
* is running.
*
* Note:
*
* Objects of this class appear as one object to the mixer,
* so cache control of the individual objects must be done
* on the group.
*
* Limitation:
*
* - The animated properties must be compatible among the
* all objects in the group.
*
* - A single property can either be controlled through a
* target group or directly, but not both.
*
* @author tschw
*/
function AnimationObjectGroup( var_args ) {
this.uuid = _Math.generateUUID();
// cached objects followed by the active ones
this._objects = Array.prototype.slice.call( arguments );
this.nCachedObjects_ = 0; // threshold
// note: read by PropertyBinding.Composite
var indices = {};
this._indicesByUUID = indices; // for bookkeeping
for ( var i = 0, n = arguments.length; i !== n; ++ i ) {
indices[ arguments[ i ].uuid ] = i;
}
this._paths = []; // inside: string
this._parsedPaths = []; // inside: { we don't care, here }
this._bindings = []; // inside: Array< PropertyBinding >
this._bindingsIndicesByPath = {}; // inside: indices in these arrays
var scope = this;
this.stats = {
objects: {
get total() { return scope._objects.length; },
get inUse() { return this.total - scope.nCachedObjects_; }
},
get bindingsPerObject() { return scope._bindings.length; }
};
}
Object.assign( AnimationObjectGroup.prototype, {
isAnimationObjectGroup: true,
add: function( var_args ) {
var objects = this._objects,
nObjects = objects.length,
nCachedObjects = this.nCachedObjects_,
indicesByUUID = this._indicesByUUID,
paths = this._paths,
parsedPaths = this._parsedPaths,
bindings = this._bindings,
nBindings = bindings.length;
for ( var i = 0, n = arguments.length; i !== n; ++ i ) {
var object = arguments[ i ],
uuid = object.uuid,
index = indicesByUUID[ uuid ],
knownObject = undefined;
if ( index === undefined ) {
// unknown object -> add it to the ACTIVE region
index = nObjects ++;
indicesByUUID[ uuid ] = index;
objects.push( object );
// accounting is done, now do the same for all bindings
for ( var j = 0, m = nBindings; j !== m; ++ j ) {
bindings[ j ].push(
new PropertyBinding(
object, paths[ j ], parsedPaths[ j ] ) );
}
} else if ( index < nCachedObjects ) {
knownObject = objects[ index ];
// move existing object to the ACTIVE region
var firstActiveIndex = -- nCachedObjects,
lastCachedObject = objects[ firstActiveIndex ];
indicesByUUID[ lastCachedObject.uuid ] = index;
objects[ index ] = lastCachedObject;
indicesByUUID[ uuid ] = firstActiveIndex;
objects[ firstActiveIndex ] = object;
// accounting is done, now do the same for all bindings
for ( var j = 0, m = nBindings; j !== m; ++ j ) {
var bindingsForPath = bindings[ j ],
lastCached = bindingsForPath[ firstActiveIndex ],
binding = bindingsForPath[ index ];
bindingsForPath[ index ] = lastCached;
if ( binding === undefined ) {
// since we do not bother to create new bindings
// for objects that are cached, the binding may
// or may not exist
binding = new PropertyBinding(
object, paths[ j ], parsedPaths[ j ] );
}
bindingsForPath[ firstActiveIndex ] = binding;
}
} else if ( objects[ index ] !== knownObject ) {
console.error( 'THREE.AnimationObjectGroup: Different objects with the same UUID ' +
'detected. Clean the caches or recreate your infrastructure when reloading scenes.' );
} // else the object is already where we want it to be
} // for arguments
this.nCachedObjects_ = nCachedObjects;
},
remove: function( var_args ) {
var objects = this._objects,
nCachedObjects = this.nCachedObjects_,
indicesByUUID = this._indicesByUUID,
bindings = this._bindings,
nBindings = bindings.length;
for ( var i = 0, n = arguments.length; i !== n; ++ i ) {
var object = arguments[ i ],
uuid = object.uuid,
index = indicesByUUID[ uuid ];
if ( index !== undefined && index >= nCachedObjects ) {
// move existing object into the CACHED region
var lastCachedIndex = nCachedObjects ++,
firstActiveObject = objects[ lastCachedIndex ];
indicesByUUID[ firstActiveObject.uuid ] = index;
objects[ index ] = firstActiveObject;
indicesByUUID[ uuid ] = lastCachedIndex;
objects[ lastCachedIndex ] = object;
// accounting is done, now do the same for all bindings
for ( var j = 0, m = nBindings; j !== m; ++ j ) {
var bindingsForPath = bindings[ j ],
firstActive = bindingsForPath[ lastCachedIndex ],
binding = bindingsForPath[ index ];
bindingsForPath[ index ] = firstActive;
bindingsForPath[ lastCachedIndex ] = binding;
}
}
} // for arguments
this.nCachedObjects_ = nCachedObjects;
},
// remove & forget
uncache: function( var_args ) {
var objects = this._objects,
nObjects = objects.length,
nCachedObjects = this.nCachedObjects_,
indicesByUUID = this._indicesByUUID,
bindings = this._bindings,
nBindings = bindings.length;
for ( var i = 0, n = arguments.length; i !== n; ++ i ) {
var object = arguments[ i ],
uuid = object.uuid,
index = indicesByUUID[ uuid ];
if ( index !== undefined ) {
delete indicesByUUID[ uuid ];
if ( index < nCachedObjects ) {
// object is cached, shrink the CACHED region
var firstActiveIndex = -- nCachedObjects,
lastCachedObject = objects[ firstActiveIndex ],
lastIndex = -- nObjects,
lastObject = objects[ lastIndex ];
// last cached object takes this object's place
indicesByUUID[ lastCachedObject.uuid ] = index;
objects[ index ] = lastCachedObject;
// last object goes to the activated slot and pop
indicesByUUID[ lastObject.uuid ] = firstActiveIndex;
objects[ firstActiveIndex ] = lastObject;
objects.pop();
// accounting is done, now do the same for all bindings
for ( var j = 0, m = nBindings; j !== m; ++ j ) {
var bindingsForPath = bindings[ j ],
lastCached = bindingsForPath[ firstActiveIndex ],
last = bindingsForPath[ lastIndex ];
bindingsForPath[ index ] = lastCached;
bindingsForPath[ firstActiveIndex ] = last;
bindingsForPath.pop();
}
} else {
// object is active, just swap with the last and pop
var lastIndex = -- nObjects,
lastObject = objects[ lastIndex ];
indicesByUUID[ lastObject.uuid ] = index;
objects[ index ] = lastObject;
objects.pop();
// accounting is done, now do the same for all bindings
for ( var j = 0, m = nBindings; j !== m; ++ j ) {
var bindingsForPath = bindings[ j ];
bindingsForPath[ index ] = bindingsForPath[ lastIndex ];
bindingsForPath.pop();
}
} // cached or active
} // if object is known
} // for arguments
this.nCachedObjects_ = nCachedObjects;
},
// Internal interface used by befriended PropertyBinding.Composite:
subscribe_: function ( path, parsedPath ) {
// returns an array of bindings for the given path that is changed
// according to the contained objects in the group
var indicesByPath = this._bindingsIndicesByPath,
index = indicesByPath[ path ],
bindings = this._bindings;
if ( index !== undefined ) return bindings[ index ];
var paths = this._paths,
parsedPaths = this._parsedPaths,
objects = this._objects,
nObjects = objects.length,
nCachedObjects = this.nCachedObjects_,
bindingsForPath = new Array( nObjects );
index = bindings.length;
indicesByPath[ path ] = index;
paths.push( path );
parsedPaths.push( parsedPath );
bindings.push( bindingsForPath );
for ( var i = nCachedObjects, n = objects.length; i !== n; ++ i ) {
var object = objects[ i ];
bindingsForPath[ i ] = new PropertyBinding( object, path, parsedPath );
}
return bindingsForPath;
},
unsubscribe_: function ( path ) {
// tells the group to forget about a property path and no longer
// update the array previously obtained with 'subscribe_'
var indicesByPath = this._bindingsIndicesByPath,
index = indicesByPath[ path ];
if ( index !== undefined ) {
var paths = this._paths,
parsedPaths = this._parsedPaths,
bindings = this._bindings,
lastBindingsIndex = bindings.length - 1,
lastBindings = bindings[ lastBindingsIndex ],
lastBindingsPath = path[ lastBindingsIndex ];
indicesByPath[ lastBindingsPath ] = index;
bindings[ index ] = lastBindings;
bindings.pop();
parsedPaths[ index ] = parsedPaths[ lastBindingsIndex ];
parsedPaths.pop();
paths[ index ] = paths[ lastBindingsIndex ];
paths.pop();
}
}
} );
/**
*
* Action provided by AnimationMixer for scheduling clip playback on specific
* objects.
*
* @author Ben Houston / http://clara.io/
* @author David Sarno / http://lighthaus.us/
* @author tschw
*
*/
function AnimationAction( mixer, clip, localRoot ) {
this._mixer = mixer;
this._clip = clip;
this._localRoot = localRoot || null;
var tracks = clip.tracks,
nTracks = tracks.length,
interpolants = new Array( nTracks );
var interpolantSettings = {
endingStart: ZeroCurvatureEnding,
endingEnd: ZeroCurvatureEnding
};
for ( var i = 0; i !== nTracks; ++ i ) {
var interpolant = tracks[ i ].createInterpolant( null );
interpolants[ i ] = interpolant;
interpolant.settings = interpolantSettings;
}
this._interpolantSettings = interpolantSettings;
this._interpolants = interpolants; // bound by the mixer
// inside: PropertyMixer (managed by the mixer)
this._propertyBindings = new Array( nTracks );
this._cacheIndex = null; // for the memory manager
this._byClipCacheIndex = null; // for the memory manager
this._timeScaleInterpolant = null;
this._weightInterpolant = null;
this.loop = LoopRepeat;
this._loopCount = -1;
// global mixer time when the action is to be started
// it's set back to 'null' upon start of the action
this._startTime = null;
// scaled local time of the action
// gets clamped or wrapped to 0..clip.duration according to loop
this.time = 0;
this.timeScale = 1;
this._effectiveTimeScale = 1;
this.weight = 1;
this._effectiveWeight = 1;
this.repetitions = Infinity; // no. of repetitions when looping
this.paused = false; // true -> zero effective time scale
this.enabled = true; // false -> zero effective weight
this.clampWhenFinished = false; // keep feeding the last frame?
this.zeroSlopeAtStart = true; // for smooth interpolation w/o separate
this.zeroSlopeAtEnd = true; // clips for start, loop and end
}
Object.assign( AnimationAction.prototype, {
// State & Scheduling
play: function() {
this._mixer._activateAction( this );
return this;
},
stop: function() {
this._mixer._deactivateAction( this );
return this.reset();
},
reset: function() {
this.paused = false;
this.enabled = true;
this.time = 0; // restart clip
this._loopCount = -1; // forget previous loops
this._startTime = null; // forget scheduling
return this.stopFading().stopWarping();
},
isRunning: function() {
return this.enabled && ! this.paused && this.timeScale !== 0 &&
this._startTime === null && this._mixer._isActiveAction( this );
},
// return true when play has been called
isScheduled: function() {
return this._mixer._isActiveAction( this );
},
startAt: function( time ) {
this._startTime = time;
return this;
},
setLoop: function( mode, repetitions ) {
this.loop = mode;
this.repetitions = repetitions;
return this;
},
// Weight
// set the weight stopping any scheduled fading
// although .enabled = false yields an effective weight of zero, this
// method does *not* change .enabled, because it would be confusing
setEffectiveWeight: function( weight ) {
this.weight = weight;
// note: same logic as when updated at runtime
this._effectiveWeight = this.enabled ? weight : 0;
return this.stopFading();
},
// return the weight considering fading and .enabled
getEffectiveWeight: function() {
return this._effectiveWeight;
},
fadeIn: function( duration ) {
return this._scheduleFading( duration, 0, 1 );
},
fadeOut: function( duration ) {
return this._scheduleFading( duration, 1, 0 );
},
crossFadeFrom: function( fadeOutAction, duration, warp ) {
fadeOutAction.fadeOut( duration );
this.fadeIn( duration );
if( warp ) {
var fadeInDuration = this._clip.duration,
fadeOutDuration = fadeOutAction._clip.duration,
startEndRatio = fadeOutDuration / fadeInDuration,
endStartRatio = fadeInDuration / fadeOutDuration;
fadeOutAction.warp( 1.0, startEndRatio, duration );
this.warp( endStartRatio, 1.0, duration );
}
return this;
},
crossFadeTo: function( fadeInAction, duration, warp ) {
return fadeInAction.crossFadeFrom( this, duration, warp );
},
stopFading: function() {
var weightInterpolant = this._weightInterpolant;
if ( weightInterpolant !== null ) {
this._weightInterpolant = null;
this._mixer._takeBackControlInterpolant( weightInterpolant );
}
return this;
},
// Time Scale Control
// set the time scale stopping any scheduled warping
// although .paused = true yields an effective time scale of zero, this
// method does *not* change .paused, because it would be confusing
setEffectiveTimeScale: function( timeScale ) {
this.timeScale = timeScale;
this._effectiveTimeScale = this.paused ? 0 :timeScale;
return this.stopWarping();
},
// return the time scale considering warping and .paused
getEffectiveTimeScale: function() {
return this._effectiveTimeScale;
},
setDuration: function( duration ) {
this.timeScale = this._clip.duration / duration;
return this.stopWarping();
},
syncWith: function( action ) {
this.time = action.time;
this.timeScale = action.timeScale;
return this.stopWarping();
},
halt: function( duration ) {
return this.warp( this._effectiveTimeScale, 0, duration );
},
warp: function( startTimeScale, endTimeScale, duration ) {
var mixer = this._mixer, now = mixer.time,
interpolant = this._timeScaleInterpolant,
timeScale = this.timeScale;
if ( interpolant === null ) {
interpolant = mixer._lendControlInterpolant();
this._timeScaleInterpolant = interpolant;
}
var times = interpolant.parameterPositions,
values = interpolant.sampleValues;
times[ 0 ] = now;
times[ 1 ] = now + duration;
values[ 0 ] = startTimeScale / timeScale;
values[ 1 ] = endTimeScale / timeScale;
return this;
},
stopWarping: function() {
var timeScaleInterpolant = this._timeScaleInterpolant;
if ( timeScaleInterpolant !== null ) {
this._timeScaleInterpolant = null;
this._mixer._takeBackControlInterpolant( timeScaleInterpolant );
}
return this;
},
// Object Accessors
getMixer: function() {
return this._mixer;
},
getClip: function() {
return this._clip;
},
getRoot: function() {
return this._localRoot || this._mixer._root;
},
// Interna
_update: function( time, deltaTime, timeDirection, accuIndex ) {
// called by the mixer
if ( ! this.enabled ) {
// call ._updateWeight() to update ._effectiveWeight
this._updateWeight( time );
return;
}
var startTime = this._startTime;
if ( startTime !== null ) {
// check for scheduled start of action
var timeRunning = ( time - startTime ) * timeDirection;
if ( timeRunning < 0 || timeDirection === 0 ) {
return; // yet to come / don't decide when delta = 0
}
// start
this._startTime = null; // unschedule
deltaTime = timeDirection * timeRunning;
}
// apply time scale and advance time
deltaTime *= this._updateTimeScale( time );
var clipTime = this._updateTime( deltaTime );
// note: _updateTime may disable the action resulting in
// an effective weight of 0
var weight = this._updateWeight( time );
if ( weight > 0 ) {
var interpolants = this._interpolants;
var propertyMixers = this._propertyBindings;
for ( var j = 0, m = interpolants.length; j !== m; ++ j ) {
interpolants[ j ].evaluate( clipTime );
propertyMixers[ j ].accumulate( accuIndex, weight );
}
}
},
_updateWeight: function( time ) {
var weight = 0;
if ( this.enabled ) {
weight = this.weight;
var interpolant = this._weightInterpolant;
if ( interpolant !== null ) {
var interpolantValue = interpolant.evaluate( time )[ 0 ];
weight *= interpolantValue;
if ( time > interpolant.parameterPositions[ 1 ] ) {
this.stopFading();
if ( interpolantValue === 0 ) {
// faded out, disable
this.enabled = false;
}
}
}
}
this._effectiveWeight = weight;
return weight;
},
_updateTimeScale: function( time ) {
var timeScale = 0;
if ( ! this.paused ) {
timeScale = this.timeScale;
var interpolant = this._timeScaleInterpolant;
if ( interpolant !== null ) {
var interpolantValue = interpolant.evaluate( time )[ 0 ];
timeScale *= interpolantValue;
if ( time > interpolant.parameterPositions[ 1 ] ) {
this.stopWarping();
if ( timeScale === 0 ) {
// motion has halted, pause
this.paused = true;
} else {
// warp done - apply final time scale
this.timeScale = timeScale;
}
}
}
}
this._effectiveTimeScale = timeScale;
return timeScale;
},
_updateTime: function( deltaTime ) {
var time = this.time + deltaTime;
if ( deltaTime === 0 ) return time;
var duration = this._clip.duration,
loop = this.loop,
loopCount = this._loopCount;
if ( loop === LoopOnce ) {
if ( loopCount === -1 ) {
// just started
this._loopCount = 0;
this._setEndings( true, true, false );
}
handle_stop: {
if ( time >= duration ) {
time = duration;
} else if ( time < 0 ) {
time = 0;
} else break handle_stop;
if ( this.clampWhenFinished ) this.paused = true;
else this.enabled = false;
this._mixer.dispatchEvent( {
type: 'finished', action: this,
direction: deltaTime < 0 ? -1 : 1
} );
}
} else { // repetitive Repeat or PingPong
var pingPong = ( loop === LoopPingPong );
if ( loopCount === -1 ) {
// just started
if ( deltaTime >= 0 ) {
loopCount = 0;
this._setEndings(
true, this.repetitions === 0, pingPong );
} else {
// when looping in reverse direction, the initial
// transition through zero counts as a repetition,
// so leave loopCount at -1
this._setEndings(
this.repetitions === 0, true, pingPong );
}
}
if ( time >= duration || time < 0 ) {
// wrap around
var loopDelta = Math.floor( time / duration ); // signed
time -= duration * loopDelta;
loopCount += Math.abs( loopDelta );
var pending = this.repetitions - loopCount;
if ( pending < 0 ) {
// have to stop (switch state, clamp time, fire event)
if ( this.clampWhenFinished ) this.paused = true;
else this.enabled = false;
time = deltaTime > 0 ? duration : 0;
this._mixer.dispatchEvent( {
type: 'finished', action: this,
direction: deltaTime > 0 ? 1 : -1
} );
} else {
// keep running
if ( pending === 0 ) {
// entering the last round
var atStart = deltaTime < 0;
this._setEndings( atStart, ! atStart, pingPong );
} else {
this._setEndings( false, false, pingPong );
}
this._loopCount = loopCount;
this._mixer.dispatchEvent( {
type: 'loop', action: this, loopDelta: loopDelta
} );
}
}
if ( pingPong && ( loopCount & 1 ) === 1 ) {
// invert time for the "pong round"
this.time = time;
return duration - time;
}
}
this.time = time;
return time;
},
_setEndings: function( atStart, atEnd, pingPong ) {
var settings = this._interpolantSettings;
if ( pingPong ) {
settings.endingStart = ZeroSlopeEnding;
settings.endingEnd = ZeroSlopeEnding;
} else {
// assuming for LoopOnce atStart == atEnd == true
if ( atStart ) {
settings.endingStart = this.zeroSlopeAtStart ?
ZeroSlopeEnding : ZeroCurvatureEnding;
} else {
settings.endingStart = WrapAroundEnding;
}
if ( atEnd ) {
settings.endingEnd = this.zeroSlopeAtEnd ?
ZeroSlopeEnding : ZeroCurvatureEnding;
} else {
settings.endingEnd = WrapAroundEnding;
}
}
},
_scheduleFading: function( duration, weightNow, weightThen ) {
var mixer = this._mixer, now = mixer.time,
interpolant = this._weightInterpolant;
if ( interpolant === null ) {
interpolant = mixer._lendControlInterpolant();
this._weightInterpolant = interpolant;
}
var times = interpolant.parameterPositions,
values = interpolant.sampleValues;
times[ 0 ] = now; values[ 0 ] = weightNow;
times[ 1 ] = now + duration; values[ 1 ] = weightThen;
return this;
}
} );
/**
*
* Player for AnimationClips.
*
*
* @author Ben Houston / http://clara.io/
* @author David Sarno / http://lighthaus.us/
* @author tschw
*/
function AnimationMixer( root ) {
this._root = root;
this._initMemoryManager();
this._accuIndex = 0;
this.time = 0;
this.timeScale = 1.0;
}
Object.assign( AnimationMixer.prototype, EventDispatcher.prototype, {
_bindAction: function ( action, prototypeAction ) {
var root = action._localRoot || this._root,
tracks = action._clip.tracks,
nTracks = tracks.length,
bindings = action._propertyBindings,
interpolants = action._interpolants,
rootUuid = root.uuid,
bindingsByRoot = this._bindingsByRootAndName,
bindingsByName = bindingsByRoot[ rootUuid ];
if ( bindingsByName === undefined ) {
bindingsByName = {};
bindingsByRoot[ rootUuid ] = bindingsByName;
}
for ( var i = 0; i !== nTracks; ++ i ) {
var track = tracks[ i ],
trackName = track.name,
binding = bindingsByName[ trackName ];
if ( binding !== undefined ) {
bindings[ i ] = binding;
} else {
binding = bindings[ i ];
if ( binding !== undefined ) {
// existing binding, make sure the cache knows
if ( binding._cacheIndex === null ) {
++ binding.referenceCount;
this._addInactiveBinding( binding, rootUuid, trackName );
}
continue;
}
var path = prototypeAction && prototypeAction.
_propertyBindings[ i ].binding.parsedPath;
binding = new PropertyMixer(
PropertyBinding.create( root, trackName, path ),
track.ValueTypeName, track.getValueSize() );
++ binding.referenceCount;
this._addInactiveBinding( binding, rootUuid, trackName );
bindings[ i ] = binding;
}
interpolants[ i ].resultBuffer = binding.buffer;
}
},
_activateAction: function ( action ) {
if ( ! this._isActiveAction( action ) ) {
if ( action._cacheIndex === null ) {
// this action has been forgotten by the cache, but the user
// appears to be still using it -> rebind
var rootUuid = ( action._localRoot || this._root ).uuid,
clipUuid = action._clip.uuid,
actionsForClip = this._actionsByClip[ clipUuid ];
this._bindAction( action,
actionsForClip && actionsForClip.knownActions[ 0 ] );
this._addInactiveAction( action, clipUuid, rootUuid );
}
var bindings = action._propertyBindings;
// increment reference counts / sort out state
for ( var i = 0, n = bindings.length; i !== n; ++ i ) {
var binding = bindings[ i ];
if ( binding.useCount ++ === 0 ) {
this._lendBinding( binding );
binding.saveOriginalState();
}
}
this._lendAction( action );
}
},
_deactivateAction: function ( action ) {
if ( this._isActiveAction( action ) ) {
var bindings = action._propertyBindings;
// decrement reference counts / sort out state
for ( var i = 0, n = bindings.length; i !== n; ++ i ) {
var binding = bindings[ i ];
if ( -- binding.useCount === 0 ) {
binding.restoreOriginalState();
this._takeBackBinding( binding );
}
}
this._takeBackAction( action );
}
},
// Memory manager
_initMemoryManager: function () {
this._actions = []; // 'nActiveActions' followed by inactive ones
this._nActiveActions = 0;
this._actionsByClip = {};
// inside:
// {
// knownActions: Array< AnimationAction > - used as prototypes
// actionByRoot: AnimationAction - lookup
// }
this._bindings = []; // 'nActiveBindings' followed by inactive ones
this._nActiveBindings = 0;
this._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer >
this._controlInterpolants = []; // same game as above
this._nActiveControlInterpolants = 0;
var scope = this;
this.stats = {
actions: {
get total() { return scope._actions.length; },
get inUse() { return scope._nActiveActions; }
},
bindings: {
get total() { return scope._bindings.length; },
get inUse() { return scope._nActiveBindings; }
},
controlInterpolants: {
get total() { return scope._controlInterpolants.length; },
get inUse() { return scope._nActiveControlInterpolants; }
}
};
},
// Memory management for AnimationAction objects
_isActiveAction: function ( action ) {
var index = action._cacheIndex;
return index !== null && index < this._nActiveActions;
},
_addInactiveAction: function ( action, clipUuid, rootUuid ) {
var actions = this._actions,
actionsByClip = this._actionsByClip,
actionsForClip = actionsByClip[ clipUuid ];
if ( actionsForClip === undefined ) {
actionsForClip = {
knownActions: [ action ],
actionByRoot: {}
};
action._byClipCacheIndex = 0;
actionsByClip[ clipUuid ] = actionsForClip;
} else {
var knownActions = actionsForClip.knownActions;
action._byClipCacheIndex = knownActions.length;
knownActions.push( action );
}
action._cacheIndex = actions.length;
actions.push( action );
actionsForClip.actionByRoot[ rootUuid ] = action;
},
_removeInactiveAction: function ( action ) {
var actions = this._actions,
lastInactiveAction = actions[ actions.length - 1 ],
cacheIndex = action._cacheIndex;
lastInactiveAction._cacheIndex = cacheIndex;
actions[ cacheIndex ] = lastInactiveAction;
actions.pop();
action._cacheIndex = null;
var clipUuid = action._clip.uuid,
actionsByClip = this._actionsByClip,
actionsForClip = actionsByClip[ clipUuid ],
knownActionsForClip = actionsForClip.knownActions,
lastKnownAction =
knownActionsForClip[ knownActionsForClip.length - 1 ],
byClipCacheIndex = action._byClipCacheIndex;
lastKnownAction._byClipCacheIndex = byClipCacheIndex;
knownActionsForClip[ byClipCacheIndex ] = lastKnownAction;
knownActionsForClip.pop();
action._byClipCacheIndex = null;
var actionByRoot = actionsForClip.actionByRoot,
rootUuid = ( action._localRoot || this._root ).uuid;
delete actionByRoot[ rootUuid ];
if ( knownActionsForClip.length === 0 ) {
delete actionsByClip[ clipUuid ];
}
this._removeInactiveBindingsForAction( action );
},
_removeInactiveBindingsForAction: function ( action ) {
var bindings = action._propertyBindings;
for ( var i = 0, n = bindings.length; i !== n; ++ i ) {
var binding = bindings[ i ];
if ( -- binding.referenceCount === 0 ) {
this._removeInactiveBinding( binding );
}
}
},
_lendAction: function ( action ) {
// [ active actions | inactive actions ]
// [ active actions >| inactive actions ]
// s a
// <-swap->
// a s
var actions = this._actions,
prevIndex = action._cacheIndex,
lastActiveIndex = this._nActiveActions ++,
firstInactiveAction = actions[ lastActiveIndex ];
action._cacheIndex = lastActiveIndex;
actions[ lastActiveIndex ] = action;
firstInactiveAction._cacheIndex = prevIndex;
actions[ prevIndex ] = firstInactiveAction;
},
_takeBackAction: function ( action ) {
// [ active actions | inactive actions ]
// [ active actions |< inactive actions ]
// a s
// <-swap->
// s a
var actions = this._actions,
prevIndex = action._cacheIndex,
firstInactiveIndex = -- this._nActiveActions,
lastActiveAction = actions[ firstInactiveIndex ];
action._cacheIndex = firstInactiveIndex;
actions[ firstInactiveIndex ] = action;
lastActiveAction._cacheIndex = prevIndex;
actions[ prevIndex ] = lastActiveAction;
},
// Memory management for PropertyMixer objects
_addInactiveBinding: function ( binding, rootUuid, trackName ) {
var bindingsByRoot = this._bindingsByRootAndName,
bindingByName = bindingsByRoot[ rootUuid ],
bindings = this._bindings;
if ( bindingByName === undefined ) {
bindingByName = {};
bindingsByRoot[ rootUuid ] = bindingByName;
}
bindingByName[ trackName ] = binding;
binding._cacheIndex = bindings.length;
bindings.push( binding );
},
_removeInactiveBinding: function ( binding ) {
var bindings = this._bindings,
propBinding = binding.binding,
rootUuid = propBinding.rootNode.uuid,
trackName = propBinding.path,
bindingsByRoot = this._bindingsByRootAndName,
bindingByName = bindingsByRoot[ rootUuid ],
lastInactiveBinding = bindings[ bindings.length - 1 ],
cacheIndex = binding._cacheIndex;
lastInactiveBinding._cacheIndex = cacheIndex;
bindings[ cacheIndex ] = lastInactiveBinding;
bindings.pop();
delete bindingByName[ trackName ];
remove_empty_map: {
for ( var _ in bindingByName ) break remove_empty_map;
delete bindingsByRoot[ rootUuid ];
}
},
_lendBinding: function ( binding ) {
var bindings = this._bindings,
prevIndex = binding._cacheIndex,
lastActiveIndex = this._nActiveBindings ++,
firstInactiveBinding = bindings[ lastActiveIndex ];
binding._cacheIndex = lastActiveIndex;
bindings[ lastActiveIndex ] = binding;
firstInactiveBinding._cacheIndex = prevIndex;
bindings[ prevIndex ] = firstInactiveBinding;
},
_takeBackBinding: function ( binding ) {
var bindings = this._bindings,
prevIndex = binding._cacheIndex,
firstInactiveIndex = -- this._nActiveBindings,
lastActiveBinding = bindings[ firstInactiveIndex ];
binding._cacheIndex = firstInactiveIndex;
bindings[ firstInactiveIndex ] = binding;
lastActiveBinding._cacheIndex = prevIndex;
bindings[ prevIndex ] = lastActiveBinding;
},
// Memory management of Interpolants for weight and time scale
_lendControlInterpolant: function () {
var interpolants = this._controlInterpolants,
lastActiveIndex = this._nActiveControlInterpolants ++,
interpolant = interpolants[ lastActiveIndex ];
if ( interpolant === undefined ) {
interpolant = new LinearInterpolant(
new Float32Array( 2 ), new Float32Array( 2 ),
1, this._controlInterpolantsResultBuffer );
interpolant.__cacheIndex = lastActiveIndex;
interpolants[ lastActiveIndex ] = interpolant;
}
return interpolant;
},
_takeBackControlInterpolant: function ( interpolant ) {
var interpolants = this._controlInterpolants,
prevIndex = interpolant.__cacheIndex,
firstInactiveIndex = -- this._nActiveControlInterpolants,
lastActiveInterpolant = interpolants[ firstInactiveIndex ];
interpolant.__cacheIndex = firstInactiveIndex;
interpolants[ firstInactiveIndex ] = interpolant;
lastActiveInterpolant.__cacheIndex = prevIndex;
interpolants[ prevIndex ] = lastActiveInterpolant;
},
_controlInterpolantsResultBuffer: new Float32Array( 1 ),
// return an action for a clip optionally using a custom root target
// object (this method allocates a lot of dynamic memory in case a
// previously unknown clip/root combination is specified)
clipAction: function ( clip, optionalRoot ) {
var root = optionalRoot || this._root,
rootUuid = root.uuid,
clipObject = typeof clip === 'string' ?
AnimationClip.findByName( root, clip ) : clip,
clipUuid = clipObject !== null ? clipObject.uuid : clip,
actionsForClip = this._actionsByClip[ clipUuid ],
prototypeAction = null;
if ( actionsForClip !== undefined ) {
var existingAction =
actionsForClip.actionByRoot[ rootUuid ];
if ( existingAction !== undefined ) {
return existingAction;
}
// we know the clip, so we don't have to parse all
// the bindings again but can just copy
prototypeAction = actionsForClip.knownActions[ 0 ];
// also, take the clip from the prototype action
if ( clipObject === null )
clipObject = prototypeAction._clip;
}
// clip must be known when specified via string
if ( clipObject === null ) return null;
// allocate all resources required to run it
var newAction = new AnimationAction( this, clipObject, optionalRoot );
this._bindAction( newAction, prototypeAction );
// and make the action known to the memory manager
this._addInactiveAction( newAction, clipUuid, rootUuid );
return newAction;
},
// get an existing action
existingAction: function ( clip, optionalRoot ) {
var root = optionalRoot || this._root,
rootUuid = root.uuid,
clipObject = typeof clip === 'string' ?
AnimationClip.findByName( root, clip ) : clip,
clipUuid = clipObject ? clipObject.uuid : clip,
actionsForClip = this._actionsByClip[ clipUuid ];
if ( actionsForClip !== undefined ) {
return actionsForClip.actionByRoot[ rootUuid ] || null;
}
return null;
},
// deactivates all previously scheduled actions
stopAllAction: function () {
var actions = this._actions,
nActions = this._nActiveActions,
bindings = this._bindings,
nBindings = this._nActiveBindings;
this._nActiveActions = 0;
this._nActiveBindings = 0;
for ( var i = 0; i !== nActions; ++ i ) {
actions[ i ].reset();
}
for ( var i = 0; i !== nBindings; ++ i ) {
bindings[ i ].useCount = 0;
}
return this;
},
// advance the time and update apply the animation
update: function ( deltaTime ) {
deltaTime *= this.timeScale;
var actions = this._actions,
nActions = this._nActiveActions,
time = this.time += deltaTime,
timeDirection = Math.sign( deltaTime ),
accuIndex = this._accuIndex ^= 1;
// run active actions
for ( var i = 0; i !== nActions; ++ i ) {
var action = actions[ i ];
action._update( time, deltaTime, timeDirection, accuIndex );
}
// update scene graph
var bindings = this._bindings,
nBindings = this._nActiveBindings;
for ( var i = 0; i !== nBindings; ++ i ) {
bindings[ i ].apply( accuIndex );
}
return this;
},
// return this mixer's root target object
getRoot: function () {
return this._root;
},
// free all resources specific to a particular clip
uncacheClip: function ( clip ) {
var actions = this._actions,
clipUuid = clip.uuid,
actionsByClip = this._actionsByClip,
actionsForClip = actionsByClip[ clipUuid ];
if ( actionsForClip !== undefined ) {
// note: just calling _removeInactiveAction would mess up the
// iteration state and also require updating the state we can
// just throw away
var actionsToRemove = actionsForClip.knownActions;
for ( var i = 0, n = actionsToRemove.length; i !== n; ++ i ) {
var action = actionsToRemove[ i ];
this._deactivateAction( action );
var cacheIndex = action._cacheIndex,
lastInactiveAction = actions[ actions.length - 1 ];
action._cacheIndex = null;
action._byClipCacheIndex = null;
lastInactiveAction._cacheIndex = cacheIndex;
actions[ cacheIndex ] = lastInactiveAction;
actions.pop();
this._removeInactiveBindingsForAction( action );
}
delete actionsByClip[ clipUuid ];
}
},
// free all resources specific to a particular root target object
uncacheRoot: function ( root ) {
var rootUuid = root.uuid,
actionsByClip = this._actionsByClip;
for ( var clipUuid in actionsByClip ) {
var actionByRoot = actionsByClip[ clipUuid ].actionByRoot,
action = actionByRoot[ rootUuid ];
if ( action !== undefined ) {
this._deactivateAction( action );
this._removeInactiveAction( action );
}
}
var bindingsByRoot = this._bindingsByRootAndName,
bindingByName = bindingsByRoot[ rootUuid ];
if ( bindingByName !== undefined ) {
for ( var trackName in bindingByName ) {
var binding = bindingByName[ trackName ];
binding.restoreOriginalState();
this._removeInactiveBinding( binding );
}
}
},
// remove a targeted clip from the cache
uncacheAction: function ( clip, optionalRoot ) {
var action = this.existingAction( clip, optionalRoot );
if ( action !== null ) {
this._deactivateAction( action );
this._removeInactiveAction( action );
}
}
} );
/**
* @author mrdoob / http://mrdoob.com/
*/
function Uniform( value ) {
if ( typeof value === 'string' ) {
console.warn( 'THREE.Uniform: Type parameter is no longer needed.' );
value = arguments[ 1 ];
}
this.value = value;
}
Uniform.prototype.clone = function () {
return new Uniform( this.value.clone === undefined ? this.value : this.value.clone() );
};
/**
* @author benaadams / https://twitter.com/ben_a_adams
*/
function InstancedBufferGeometry() {
BufferGeometry.call( this );
this.type = 'InstancedBufferGeometry';
this.maxInstancedCount = undefined;
}
InstancedBufferGeometry.prototype = Object.assign( Object.create( BufferGeometry.prototype ), {
constructor: InstancedBufferGeometry,
isInstancedBufferGeometry: true,
addGroup: function ( start, count, materialIndex ) {
this.groups.push( {
start: start,
count: count,
materialIndex: materialIndex
} );
},
copy: function ( source ) {
var index = source.index;
if ( index !== null ) {
this.setIndex( index.clone() );
}
var attributes = source.attributes;
for ( var name in attributes ) {
var attribute = attributes[ name ];
this.addAttribute( name, attribute.clone() );
}
var groups = source.groups;
for ( var i = 0, l = groups.length; i < l; i ++ ) {
var group = groups[ i ];
this.addGroup( group.start, group.count, group.materialIndex );
}
return this;
}
} );
/**
* @author benaadams / https://twitter.com/ben_a_adams
*/
function InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized ) {
this.uuid = _Math.generateUUID();
this.data = interleavedBuffer;
this.itemSize = itemSize;
this.offset = offset;
this.normalized = normalized === true;
}
Object.defineProperties( InterleavedBufferAttribute.prototype, {
count: {
get: function () {
return this.data.count;
}
},
array: {
get: function () {
return this.data.array;
}
}
} );
Object.assign( InterleavedBufferAttribute.prototype, {
isInterleavedBufferAttribute: true,
setX: function ( index, x ) {
this.data.array[ index * this.data.stride + this.offset ] = x;
return this;
},
setY: function ( index, y ) {
this.data.array[ index * this.data.stride + this.offset + 1 ] = y;
return this;
},
setZ: function ( index, z ) {
this.data.array[ index * this.data.stride + this.offset + 2 ] = z;
return this;
},
setW: function ( index, w ) {
this.data.array[ index * this.data.stride + this.offset + 3 ] = w;
return this;
},
getX: function ( index ) {
return this.data.array[ index * this.data.stride + this.offset ];
},
getY: function ( index ) {
return this.data.array[ index * this.data.stride + this.offset + 1 ];
},
getZ: function ( index ) {
return this.data.array[ index * this.data.stride + this.offset + 2 ];
},
getW: function ( index ) {
return this.data.array[ index * this.data.stride + this.offset + 3 ];
},
setXY: function ( index, x, y ) {
index = index * this.data.stride + this.offset;
this.data.array[ index + 0 ] = x;
this.data.array[ index + 1 ] = y;
return this;
},
setXYZ: function ( index, x, y, z ) {
index = index * this.data.stride + this.offset;
this.data.array[ index + 0 ] = x;
this.data.array[ index + 1 ] = y;
this.data.array[ index + 2 ] = z;
return this;
},
setXYZW: function ( index, x, y, z, w ) {
index = index * this.data.stride + this.offset;
this.data.array[ index + 0 ] = x;
this.data.array[ index + 1 ] = y;
this.data.array[ index + 2 ] = z;
this.data.array[ index + 3 ] = w;
return this;
}
} );
/**
* @author benaadams / https://twitter.com/ben_a_adams
*/
function InterleavedBuffer( array, stride ) {
this.uuid = _Math.generateUUID();
this.array = array;
this.stride = stride;
this.count = array !== undefined ? array.length / stride : 0;
this.dynamic = false;
this.updateRange = { offset: 0, count: - 1 };
this.onUploadCallback = function () {};
this.version = 0;
}
Object.defineProperty( InterleavedBuffer.prototype, 'needsUpdate', {
set: function ( value ) {
if ( value === true ) this.version ++;
}
} );
Object.assign( InterleavedBuffer.prototype, {
isInterleavedBuffer: true,
setArray: function ( array ) {
if ( Array.isArray( array ) ) {
throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );
}
this.count = array !== undefined ? array.length / this.stride : 0;
this.array = array;
},
setDynamic: function ( value ) {
this.dynamic = value;
return this;
},
copy: function ( source ) {
this.array = new source.array.constructor( source.array );
this.count = source.count;
this.stride = source.stride;
this.dynamic = source.dynamic;
return this;
},
copyAt: function ( index1, attribute, index2 ) {
index1 *= this.stride;
index2 *= attribute.stride;
for ( var i = 0, l = this.stride; i < l; i ++ ) {
this.array[ index1 + i ] = attribute.array[ index2 + i ];
}
return this;
},
set: function ( value, offset ) {
if ( offset === undefined ) offset = 0;
this.array.set( value, offset );
return this;
},
clone: function () {
return new this.constructor().copy( this );
},
onUpload: function ( callback ) {
this.onUploadCallback = callback;
return this;
}
} );
/**
* @author benaadams / https://twitter.com/ben_a_adams
*/
function InstancedInterleavedBuffer( array, stride, meshPerAttribute ) {
InterleavedBuffer.call( this, array, stride );
this.meshPerAttribute = meshPerAttribute || 1;
}
InstancedInterleavedBuffer.prototype = Object.assign( Object.create( InterleavedBuffer.prototype ), {
constructor: InstancedInterleavedBuffer,
isInstancedInterleavedBuffer: true,
copy: function ( source ) {
InterleavedBuffer.prototype.copy.call( this, source );
this.meshPerAttribute = source.meshPerAttribute;
return this;
}
} );
/**
* @author benaadams / https://twitter.com/ben_a_adams
*/
function InstancedBufferAttribute( array, itemSize, meshPerAttribute ) {
BufferAttribute.call( this, array, itemSize );
this.meshPerAttribute = meshPerAttribute || 1;
}
InstancedBufferAttribute.prototype = Object.assign( Object.create( BufferAttribute.prototype ), {
constructor: InstancedBufferAttribute,
isInstancedBufferAttribute: true,
copy: function ( source ) {
BufferAttribute.prototype.copy.call( this, source );
this.meshPerAttribute = source.meshPerAttribute;
return this;
}
} );
/**
* @author mrdoob / http://mrdoob.com/
* @author bhouston / http://clara.io/
* @author stephomi / http://stephaneginier.com/
*/
function Raycaster( origin, direction, near, far ) {
this.ray = new Ray( origin, direction );
// direction is assumed to be normalized (for accurate distance calculations)
this.near = near || 0;
this.far = far || Infinity;
this.params = {
Mesh: {},
Line: {},
LOD: {},
Points: { threshold: 1 },
Sprite: {}
};
Object.defineProperties( this.params, {
PointCloud: {
get: function () {
console.warn( 'THREE.Raycaster: params.PointCloud has been renamed to params.Points.' );
return this.Points;
}
}
} );
}
function ascSort( a, b ) {
return a.distance - b.distance;
}
function intersectObject( object, raycaster, intersects, recursive ) {
if ( object.visible === false ) return;
object.raycast( raycaster, intersects );
if ( recursive === true ) {
var children = object.children;
for ( var i = 0, l = children.length; i < l; i ++ ) {
intersectObject( children[ i ], raycaster, intersects, true );
}
}
}
Object.assign( Raycaster.prototype, {
linePrecision: 1,
set: function ( origin, direction ) {
// direction is assumed to be normalized (for accurate distance calculations)
this.ray.set( origin, direction );
},
setFromCamera: function ( coords, camera ) {
if ( ( camera && camera.isPerspectiveCamera ) ) {
this.ray.origin.setFromMatrixPosition( camera.matrixWorld );
this.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();
} else if ( ( camera && camera.isOrthographicCamera ) ) {
this.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera
this.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );
} else {
console.error( 'THREE.Raycaster: Unsupported camera type.' );
}
},
intersectObject: function ( object, recursive ) {
var intersects = [];
intersectObject( object, this, intersects, recursive );
intersects.sort( ascSort );
return intersects;
},
intersectObjects: function ( objects, recursive ) {
var intersects = [];
if ( Array.isArray( objects ) === false ) {
console.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' );
return intersects;
}
for ( var i = 0, l = objects.length; i < l; i ++ ) {
intersectObject( objects[ i ], this, intersects, recursive );
}
intersects.sort( ascSort );
return intersects;
}
} );
/**
* @author alteredq / http://alteredqualia.com/
*/
function Clock( autoStart ) {
this.autoStart = ( autoStart !== undefined ) ? autoStart : true;
this.startTime = 0;
this.oldTime = 0;
this.elapsedTime = 0;
this.running = false;
}
Object.assign( Clock.prototype, {
start: function () {
this.startTime = ( typeof performance === 'undefined' ? Date : performance ).now(); // see #10732
this.oldTime = this.startTime;
this.elapsedTime = 0;
this.running = true;
},
stop: function () {
this.getElapsedTime();
this.running = false;
this.autoStart = false;
},
getElapsedTime: function () {
this.getDelta();
return this.elapsedTime;
},
getDelta: function () {
var diff = 0;
if ( this.autoStart && ! this.running ) {
this.start();
return 0;
}
if ( this.running ) {
var newTime = ( typeof performance === 'undefined' ? Date : performance ).now();
diff = ( newTime - this.oldTime ) / 1000;
this.oldTime = newTime;
this.elapsedTime += diff;
}
return diff;
}
} );
/**
* @author bhouston / http://clara.io
* @author WestLangley / http://github.com/WestLangley
*
* Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system
*
* The poles (phi) are at the positive and negative y axis.
* The equator starts at positive z.
*/
function Spherical( radius, phi, theta ) {
this.radius = ( radius !== undefined ) ? radius : 1.0;
this.phi = ( phi !== undefined ) ? phi : 0; // up / down towards top and bottom pole
this.theta = ( theta !== undefined ) ? theta : 0; // around the equator of the sphere
return this;
}
Object.assign( Spherical.prototype, {
set: function ( radius, phi, theta ) {
this.radius = radius;
this.phi = phi;
this.theta = theta;
return this;
},
clone: function () {
return new this.constructor().copy( this );
},
copy: function ( other ) {
this.radius = other.radius;
this.phi = other.phi;
this.theta = other.theta;
return this;
},
// restrict phi to be betwee EPS and PI-EPS
makeSafe: function() {
var EPS = 0.000001;
this.phi = Math.max( EPS, Math.min( Math.PI - EPS, this.phi ) );
return this;
},
setFromVector3: function( vec3 ) {
this.radius = vec3.length();
if ( this.radius === 0 ) {
this.theta = 0;
this.phi = 0;
} else {
this.theta = Math.atan2( vec3.x, vec3.z ); // equator angle around y-up axis
this.phi = Math.acos( _Math.clamp( vec3.y / this.radius, - 1, 1 ) ); // polar angle
}
return this;
}
} );
/**
* @author Mugen87 / https://github.com/Mugen87
*
* Ref: https://en.wikipedia.org/wiki/Cylindrical_coordinate_system
*
*/
function Cylindrical( radius, theta, y ) {
this.radius = ( radius !== undefined ) ? radius : 1.0; // distance from the origin to a point in the x-z plane
this.theta = ( theta !== undefined ) ? theta : 0; // counterclockwise angle in the x-z plane measured in radians from the positive z-axis
this.y = ( y !== undefined ) ? y : 0; // height above the x-z plane
return this;
}
Object.assign( Cylindrical.prototype, {
set: function ( radius, theta, y ) {
this.radius = radius;
this.theta = theta;
this.y = y;
return this;
},
clone: function () {
return new this.constructor().copy( this );
},
copy: function ( other ) {
this.radius = other.radius;
this.theta = other.theta;
this.y = other.y;
return this;
},
setFromVector3: function( vec3 ) {
this.radius = Math.sqrt( vec3.x * vec3.x + vec3.z * vec3.z );
this.theta = Math.atan2( vec3.x, vec3.z );
this.y = vec3.y;
return this;
}
} );
/**
* @author alteredq / http://alteredqualia.com/
*/
function MorphBlendMesh( geometry, material ) {
Mesh.call( this, geometry, material );
this.animationsMap = {};
this.animationsList = [];
// prepare default animation
// (all frames played together in 1 second)
var numFrames = this.geometry.morphTargets.length;
var name = "__default";
var startFrame = 0;
var endFrame = numFrames - 1;
var fps = numFrames / 1;
this.createAnimation( name, startFrame, endFrame, fps );
this.setAnimationWeight( name, 1 );
}
MorphBlendMesh.prototype = Object.create( Mesh.prototype );
MorphBlendMesh.prototype.constructor = MorphBlendMesh;
MorphBlendMesh.prototype.createAnimation = function ( name, start, end, fps ) {
var animation = {
start: start,
end: end,
length: end - start + 1,
fps: fps,
duration: ( end - start ) / fps,
lastFrame: 0,
currentFrame: 0,
active: false,
time: 0,
direction: 1,
weight: 1,
directionBackwards: false,
mirroredLoop: false
};
this.animationsMap[ name ] = animation;
this.animationsList.push( animation );
};
MorphBlendMesh.prototype.autoCreateAnimations = function ( fps ) {
var pattern = /([a-z]+)_?(\d+)/i;
var firstAnimation, frameRanges = {};
var geometry = this.geometry;
for ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {
var morph = geometry.morphTargets[ i ];
var chunks = morph.name.match( pattern );
if ( chunks && chunks.length > 1 ) {
var name = chunks[ 1 ];
if ( ! frameRanges[ name ] ) frameRanges[ name ] = { start: Infinity, end: - Infinity };
var range = frameRanges[ name ];
if ( i < range.start ) range.start = i;
if ( i > range.end ) range.end = i;
if ( ! firstAnimation ) firstAnimation = name;
}
}
for ( var name in frameRanges ) {
var range = frameRanges[ name ];
this.createAnimation( name, range.start, range.end, fps );
}
this.firstAnimation = firstAnimation;
};
MorphBlendMesh.prototype.setAnimationDirectionForward = function ( name ) {
var animation = this.animationsMap[ name ];
if ( animation ) {
animation.direction = 1;
animation.directionBackwards = false;
}
};
MorphBlendMesh.prototype.setAnimationDirectionBackward = function ( name ) {
var animation = this.animationsMap[ name ];
if ( animation ) {
animation.direction = - 1;
animation.directionBackwards = true;
}
};
MorphBlendMesh.prototype.setAnimationFPS = function ( name, fps ) {
var animation = this.animationsMap[ name ];
if ( animation ) {
animation.fps = fps;
animation.duration = ( animation.end - animation.start ) / animation.fps;
}
};
MorphBlendMesh.prototype.setAnimationDuration = function ( name, duration ) {
var animation = this.animationsMap[ name ];
if ( animation ) {
animation.duration = duration;
animation.fps = ( animation.end - animation.start ) / animation.duration;
}
};
MorphBlendMesh.prototype.setAnimationWeight = function ( name, weight ) {
var animation = this.animationsMap[ name ];
if ( animation ) {
animation.weight = weight;
}
};
MorphBlendMesh.prototype.setAnimationTime = function ( name, time ) {
var animation = this.animationsMap[ name ];
if ( animation ) {
animation.time = time;
}
};
MorphBlendMesh.prototype.getAnimationTime = function ( name ) {
var time = 0;
var animation = this.animationsMap[ name ];
if ( animation ) {
time = animation.time;
}
return time;
};
MorphBlendMesh.prototype.getAnimationDuration = function ( name ) {
var duration = - 1;
var animation = this.animationsMap[ name ];
if ( animation ) {
duration = animation.duration;
}
return duration;
};
MorphBlendMesh.prototype.playAnimation = function ( name ) {
var animation = this.animationsMap[ name ];
if ( animation ) {
animation.time = 0;
animation.active = true;
} else {
console.warn( "THREE.MorphBlendMesh: animation[" + name + "] undefined in .playAnimation()" );
}
};
MorphBlendMesh.prototype.stopAnimation = function ( name ) {
var animation = this.animationsMap[ name ];
if ( animation ) {
animation.active = false;
}
};
MorphBlendMesh.prototype.update = function ( delta ) {
for ( var i = 0, il = this.animationsList.length; i < il; i ++ ) {
var animation = this.animationsList[ i ];
if ( ! animation.active ) continue;
var frameTime = animation.duration / animation.length;
animation.time += animation.direction * delta;
if ( animation.mirroredLoop ) {
if ( animation.time > animation.duration || animation.time < 0 ) {
animation.direction *= - 1;
if ( animation.time > animation.duration ) {
animation.time = animation.duration;
animation.directionBackwards = true;
}
if ( animation.time < 0 ) {
animation.time = 0;
animation.directionBackwards = false;
}
}
} else {
animation.time = animation.time % animation.duration;
if ( animation.time < 0 ) animation.time += animation.duration;
}
var keyframe = animation.start + _Math.clamp( Math.floor( animation.time / frameTime ), 0, animation.length - 1 );
var weight = animation.weight;
if ( keyframe !== animation.currentFrame ) {
this.morphTargetInfluences[ animation.lastFrame ] = 0;
this.morphTargetInfluences[ animation.currentFrame ] = 1 * weight;
this.morphTargetInfluences[ keyframe ] = 0;
animation.lastFrame = animation.currentFrame;
animation.currentFrame = keyframe;
}
var mix = ( animation.time % frameTime ) / frameTime;
if ( animation.directionBackwards ) mix = 1 - mix;
if ( animation.currentFrame !== animation.lastFrame ) {
this.morphTargetInfluences[ animation.currentFrame ] = mix * weight;
this.morphTargetInfluences[ animation.lastFrame ] = ( 1 - mix ) * weight;
} else {
this.morphTargetInfluences[ animation.currentFrame ] = weight;
}
}
};
/**
* @author alteredq / http://alteredqualia.com/
*/
function ImmediateRenderObject( material ) {
Object3D.call( this );
this.material = material;
this.render = function ( renderCallback ) {};
}
ImmediateRenderObject.prototype = Object.create( Object3D.prototype );
ImmediateRenderObject.prototype.constructor = ImmediateRenderObject;
ImmediateRenderObject.prototype.isImmediateRenderObject = true;
/**
* @author mrdoob / http://mrdoob.com/
* @author WestLangley / http://github.com/WestLangley
*/
function VertexNormalsHelper( object, size, hex, linewidth ) {
this.object = object;
this.size = ( size !== undefined ) ? size : 1;
var color = ( hex !== undefined ) ? hex : 0xff0000;
var width = ( linewidth !== undefined ) ? linewidth : 1;
//
var nNormals = 0;
var objGeometry = this.object.geometry;
if ( objGeometry && objGeometry.isGeometry ) {
nNormals = objGeometry.faces.length * 3;
} else if ( objGeometry && objGeometry.isBufferGeometry ) {
nNormals = objGeometry.attributes.normal.count;
}
//
var geometry = new BufferGeometry();
var positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 );
geometry.addAttribute( 'position', positions );
LineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );
//
this.matrixAutoUpdate = false;
this.update();
}
VertexNormalsHelper.prototype = Object.create( LineSegments.prototype );
VertexNormalsHelper.prototype.constructor = VertexNormalsHelper;
VertexNormalsHelper.prototype.update = ( function () {
var v1 = new Vector3();
var v2 = new Vector3();
var normalMatrix = new Matrix3();
return function update() {
var keys = [ 'a', 'b', 'c' ];
this.object.updateMatrixWorld( true );
normalMatrix.getNormalMatrix( this.object.matrixWorld );
var matrixWorld = this.object.matrixWorld;
var position = this.geometry.attributes.position;
//
var objGeometry = this.object.geometry;
if ( objGeometry && objGeometry.isGeometry ) {
var vertices = objGeometry.vertices;
var faces = objGeometry.faces;
var idx = 0;
for ( var i = 0, l = faces.length; i < l; i ++ ) {
var face = faces[ i ];
for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {
var vertex = vertices[ face[ keys[ j ] ] ];
var normal = face.vertexNormals[ j ];
v1.copy( vertex ).applyMatrix4( matrixWorld );
v2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );
position.setXYZ( idx, v1.x, v1.y, v1.z );
idx = idx + 1;
position.setXYZ( idx, v2.x, v2.y, v2.z );
idx = idx + 1;
}
}
} else if ( objGeometry && objGeometry.isBufferGeometry ) {
var objPos = objGeometry.attributes.position;
var objNorm = objGeometry.attributes.normal;
var idx = 0;
// for simplicity, ignore index and drawcalls, and render every normal
for ( var j = 0, jl = objPos.count; j < jl; j ++ ) {
v1.set( objPos.getX( j ), objPos.getY( j ), objPos.getZ( j ) ).applyMatrix4( matrixWorld );
v2.set( objNorm.getX( j ), objNorm.getY( j ), objNorm.getZ( j ) );
v2.applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );
position.setXYZ( idx, v1.x, v1.y, v1.z );
idx = idx + 1;
position.setXYZ( idx, v2.x, v2.y, v2.z );
idx = idx + 1;
}
}
position.needsUpdate = true;
};
}() );
/**
* @author alteredq / http://alteredqualia.com/
* @author mrdoob / http://mrdoob.com/
* @author WestLangley / http://github.com/WestLangley
*/
function SpotLightHelper( light ) {
Object3D.call( this );
this.light = light;
this.light.updateMatrixWorld();
this.matrix = light.matrixWorld;
this.matrixAutoUpdate = false;
var geometry = new BufferGeometry();
var positions = [
0, 0, 0, 0, 0, 1,
0, 0, 0, 1, 0, 1,
0, 0, 0, - 1, 0, 1,
0, 0, 0, 0, 1, 1,
0, 0, 0, 0, - 1, 1
];
for ( var i = 0, j = 1, l = 32; i < l; i ++, j ++ ) {
var p1 = ( i / l ) * Math.PI * 2;
var p2 = ( j / l ) * Math.PI * 2;
positions.push(
Math.cos( p1 ), Math.sin( p1 ), 1,
Math.cos( p2 ), Math.sin( p2 ), 1
);
}
geometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
var material = new LineBasicMaterial( { fog: false } );
this.cone = new LineSegments( geometry, material );
this.add( this.cone );
this.update();
}
SpotLightHelper.prototype = Object.create( Object3D.prototype );
SpotLightHelper.prototype.constructor = SpotLightHelper;
SpotLightHelper.prototype.dispose = function () {
this.cone.geometry.dispose();
this.cone.material.dispose();
};
SpotLightHelper.prototype.update = function () {
var vector = new Vector3();
var vector2 = new Vector3();
return function update() {
this.light.updateMatrixWorld();
var coneLength = this.light.distance ? this.light.distance : 1000;
var coneWidth = coneLength * Math.tan( this.light.angle );
this.cone.scale.set( coneWidth, coneWidth, coneLength );
vector.setFromMatrixPosition( this.light.matrixWorld );
vector2.setFromMatrixPosition( this.light.target.matrixWorld );
this.cone.lookAt( vector2.sub( vector ) );
this.cone.material.color.copy( this.light.color );
};
}();
/**
* @author Sean Griffin / http://twitter.com/sgrif
* @author Michael Guerrero / http://realitymeltdown.com
* @author mrdoob / http://mrdoob.com/
* @author ikerr / http://verold.com
* @author Mugen87 / https://github.com/Mugen87
*/
function getBoneList( object ) {
var boneList = [];
if ( object && object.isBone ) {
boneList.push( object );
}
for ( var i = 0; i < object.children.length; i ++ ) {
boneList.push.apply( boneList, getBoneList( object.children[ i ] ) );
}
return boneList;
}
function SkeletonHelper( object ) {
var bones = getBoneList( object );
var geometry = new BufferGeometry();
var vertices = [];
var colors = [];
var color1 = new Color( 0, 0, 1 );
var color2 = new Color( 0, 1, 0 );
for ( var i = 0; i < bones.length; i ++ ) {
var bone = bones[ i ];
if ( bone.parent && bone.parent.isBone ) {
vertices.push( 0, 0, 0 );
vertices.push( 0, 0, 0 );
colors.push( color1.r, color1.g, color1.b );
colors.push( color2.r, color2.g, color2.b );
}
}
geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
var material = new LineBasicMaterial( { vertexColors: VertexColors, depthTest: false, depthWrite: false, transparent: true } );
LineSegments.call( this, geometry, material );
this.root = object;
this.bones = bones;
this.matrix = object.matrixWorld;
this.matrixAutoUpdate = false;
this.onBeforeRender();
}
SkeletonHelper.prototype = Object.create( LineSegments.prototype );
SkeletonHelper.prototype.constructor = SkeletonHelper;
SkeletonHelper.prototype.onBeforeRender = function () {
var vector = new Vector3();
var boneMatrix = new Matrix4();
var matrixWorldInv = new Matrix4();
return function onBeforeRender() {
var bones = this.bones;
var geometry = this.geometry;
var position = geometry.getAttribute( 'position' );
matrixWorldInv.getInverse( this.root.matrixWorld );
for ( var i = 0, j = 0; i < bones.length; i ++ ) {
var bone = bones[ i ];
if ( bone.parent && bone.parent.isBone ) {
boneMatrix.multiplyMatrices( matrixWorldInv, bone.matrixWorld );
vector.setFromMatrixPosition( boneMatrix );
position.setXYZ( j, vector.x, vector.y, vector.z );
boneMatrix.multiplyMatrices( matrixWorldInv, bone.parent.matrixWorld );
vector.setFromMatrixPosition( boneMatrix );
position.setXYZ( j + 1, vector.x, vector.y, vector.z );
j += 2;
}
}
geometry.getAttribute( 'position' ).needsUpdate = true;
};
}();
/**
* @author alteredq / http://alteredqualia.com/
* @author mrdoob / http://mrdoob.com/
*/
function PointLightHelper( light, sphereSize ) {
this.light = light;
this.light.updateMatrixWorld();
var geometry = new SphereBufferGeometry( sphereSize, 4, 2 );
var material = new MeshBasicMaterial( { wireframe: true, fog: false } );
material.color.copy( this.light.color );
Mesh.call( this, geometry, material );
this.matrix = this.light.matrixWorld;
this.matrixAutoUpdate = false;
/*
var distanceGeometry = new THREE.IcosahedronGeometry( 1, 2 );
var distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } );
this.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial );
this.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial );
var d = light.distance;
if ( d === 0.0 ) {
this.lightDistance.visible = false;
} else {
this.lightDistance.scale.set( d, d, d );
}
this.add( this.lightDistance );
*/
}
PointLightHelper.prototype = Object.create( Mesh.prototype );
PointLightHelper.prototype.constructor = PointLightHelper;
PointLightHelper.prototype.dispose = function () {
this.geometry.dispose();
this.material.dispose();
};
PointLightHelper.prototype.update = function () {
this.material.color.copy( this.light.color );
/*
var d = this.light.distance;
if ( d === 0.0 ) {
this.lightDistance.visible = false;
} else {
this.lightDistance.visible = true;
this.lightDistance.scale.set( d, d, d );
}
*/
};
/**
* @author abelnation / http://github.com/abelnation
* @author Mugen87 / http://github.com/Mugen87
* @author WestLangley / http://github.com/WestLangley
*/
function RectAreaLightHelper( light ) {
Object3D.call( this );
this.light = light;
this.light.updateMatrixWorld();
this.matrix = light.matrixWorld;
this.matrixAutoUpdate = false;
var material = new LineBasicMaterial( { color: light.color } );
var geometry = new BufferGeometry();
geometry.addAttribute( 'position', new BufferAttribute( new Float32Array( 5 * 3 ), 3 ) );
this.add( new Line( geometry, material ) );
this.update();
}
RectAreaLightHelper.prototype = Object.create( Object3D.prototype );
RectAreaLightHelper.prototype.constructor = RectAreaLightHelper;
RectAreaLightHelper.prototype.dispose = function () {
this.children[ 0 ].geometry.dispose();
this.children[ 0 ].material.dispose();
};
RectAreaLightHelper.prototype.update = function () {
var line = this.children[ 0 ];
// update material
line.material.color.copy( this.light.color );
// calculate new dimensions of the helper
var hx = this.light.width * 0.5;
var hy = this.light.height * 0.5;
var position = line.geometry.attributes.position;
var array = position.array;
// update vertices
array[ 0 ] = hx; array[ 1 ] = - hy; array[ 2 ] = 0;
array[ 3 ] = hx; array[ 4 ] = hy; array[ 5 ] = 0;
array[ 6 ] = - hx; array[ 7 ] = hy; array[ 8 ] = 0;
array[ 9 ] = - hx; array[ 10 ] = - hy; array[ 11 ] = 0;
array[ 12 ] = hx; array[ 13 ] = - hy; array[ 14 ] = 0;
position.needsUpdate = true;
};
/**
* @author alteredq / http://alteredqualia.com/
* @author mrdoob / http://mrdoob.com/
* @author Mugen87 / https://github.com/Mugen87
*/
function HemisphereLightHelper( light, size ) {
Object3D.call( this );
this.light = light;
this.light.updateMatrixWorld();
this.matrix = light.matrixWorld;
this.matrixAutoUpdate = false;
var geometry = new OctahedronBufferGeometry( size );
geometry.rotateY( Math.PI * 0.5 );
var material = new MeshBasicMaterial( { vertexColors: VertexColors, wireframe: true } );
var position = geometry.getAttribute( 'position' );
var colors = new Float32Array( position.count * 3 );
geometry.addAttribute( 'color', new BufferAttribute( colors, 3 ) );
this.add( new Mesh( geometry, material ) );
this.update();
}
HemisphereLightHelper.prototype = Object.create( Object3D.prototype );
HemisphereLightHelper.prototype.constructor = HemisphereLightHelper;
HemisphereLightHelper.prototype.dispose = function () {
this.children[ 0 ].geometry.dispose();
this.children[ 0 ].material.dispose();
};
HemisphereLightHelper.prototype.update = function () {
var vector = new Vector3();
var color1 = new Color();
var color2 = new Color();
return function update() {
var mesh = this.children[ 0 ];
var colors = mesh.geometry.getAttribute( 'color' );
color1.copy( this.light.color );
color2.copy( this.light.groundColor );
for ( var i = 0, l = colors.count; i < l; i ++ ) {
var color = ( i < ( l / 2 ) ) ? color1 : color2;
colors.setXYZ( i, color.r, color.g, color.b );
}
mesh.lookAt( vector.setFromMatrixPosition( this.light.matrixWorld ).negate() );
colors.needsUpdate = true;
};
}();
/**
* @author mrdoob / http://mrdoob.com/
*/
function GridHelper( size, divisions, color1, color2 ) {
size = size || 10;
divisions = divisions || 10;
color1 = new Color( color1 !== undefined ? color1 : 0x444444 );
color2 = new Color( color2 !== undefined ? color2 : 0x888888 );
var center = divisions / 2;
var step = size / divisions;
var halfSize = size / 2;
var vertices = [], colors = [];
for ( var i = 0, j = 0, k = - halfSize; i <= divisions; i ++, k += step ) {
vertices.push( - halfSize, 0, k, halfSize, 0, k );
vertices.push( k, 0, - halfSize, k, 0, halfSize );
var color = i === center ? color1 : color2;
color.toArray( colors, j ); j += 3;
color.toArray( colors, j ); j += 3;
color.toArray( colors, j ); j += 3;
color.toArray( colors, j ); j += 3;
}
var geometry = new BufferGeometry();
geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
var material = new LineBasicMaterial( { vertexColors: VertexColors } );
LineSegments.call( this, geometry, material );
}
GridHelper.prototype = Object.create( LineSegments.prototype );
GridHelper.prototype.constructor = GridHelper;
/**
* @author mrdoob / http://mrdoob.com/
* @author Mugen87 / http://github.com/Mugen87
* @author Hectate / http://www.github.com/Hectate
*/
function PolarGridHelper( radius, radials, circles, divisions, color1, color2 ) {
radius = radius || 10;
radials = radials || 16;
circles = circles || 8;
divisions = divisions || 64;
color1 = new Color( color1 !== undefined ? color1 : 0x444444 );
color2 = new Color( color2 !== undefined ? color2 : 0x888888 );
var vertices = [];
var colors = [];
var x, z;
var v, i, j, r, color;
// create the radials
for ( i = 0; i <= radials; i ++ ) {
v = ( i / radials ) * ( Math.PI * 2 );
x = Math.sin( v ) * radius;
z = Math.cos( v ) * radius;
vertices.push( 0, 0, 0 );
vertices.push( x, 0, z );
color = ( i & 1 ) ? color1 : color2;
colors.push( color.r, color.g, color.b );
colors.push( color.r, color.g, color.b );
}
// create the circles
for ( i = 0; i <= circles; i ++ ) {
color = ( i & 1 ) ? color1 : color2;
r = radius - ( radius / circles * i );
for ( j = 0; j < divisions; j ++ ) {
// first vertex
v = ( j / divisions ) * ( Math.PI * 2 );
x = Math.sin( v ) * r;
z = Math.cos( v ) * r;
vertices.push( x, 0, z );
colors.push( color.r, color.g, color.b );
// second vertex
v = ( ( j + 1 ) / divisions ) * ( Math.PI * 2 );
x = Math.sin( v ) * r;
z = Math.cos( v ) * r;
vertices.push( x, 0, z );
colors.push( color.r, color.g, color.b );
}
}
var geometry = new BufferGeometry();
geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
var material = new LineBasicMaterial( { vertexColors: VertexColors } );
LineSegments.call( this, geometry, material );
}
PolarGridHelper.prototype = Object.create( LineSegments.prototype );
PolarGridHelper.prototype.constructor = PolarGridHelper;
/**
* @author mrdoob / http://mrdoob.com/
* @author WestLangley / http://github.com/WestLangley
*/
function FaceNormalsHelper( object, size, hex, linewidth ) {
// FaceNormalsHelper only supports THREE.Geometry
this.object = object;
this.size = ( size !== undefined ) ? size : 1;
var color = ( hex !== undefined ) ? hex : 0xffff00;
var width = ( linewidth !== undefined ) ? linewidth : 1;
//
var nNormals = 0;
var objGeometry = this.object.geometry;
if ( objGeometry && objGeometry.isGeometry ) {
nNormals = objGeometry.faces.length;
} else {
console.warn( 'THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.' );
}
//
var geometry = new BufferGeometry();
var positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 );
geometry.addAttribute( 'position', positions );
LineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );
//
this.matrixAutoUpdate = false;
this.update();
}
FaceNormalsHelper.prototype = Object.create( LineSegments.prototype );
FaceNormalsHelper.prototype.constructor = FaceNormalsHelper;
FaceNormalsHelper.prototype.update = ( function () {
var v1 = new Vector3();
var v2 = new Vector3();
var normalMatrix = new Matrix3();
return function update() {
this.object.updateMatrixWorld( true );
normalMatrix.getNormalMatrix( this.object.matrixWorld );
var matrixWorld = this.object.matrixWorld;
var position = this.geometry.attributes.position;
//
var objGeometry = this.object.geometry;
var vertices = objGeometry.vertices;
var faces = objGeometry.faces;
var idx = 0;
for ( var i = 0, l = faces.length; i < l; i ++ ) {
var face = faces[ i ];
var normal = face.normal;
v1.copy( vertices[ face.a ] )
.add( vertices[ face.b ] )
.add( vertices[ face.c ] )
.divideScalar( 3 )
.applyMatrix4( matrixWorld );
v2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );
position.setXYZ( idx, v1.x, v1.y, v1.z );
idx = idx + 1;
position.setXYZ( idx, v2.x, v2.y, v2.z );
idx = idx + 1;
}
position.needsUpdate = true;
};
}() );
/**
* @author alteredq / http://alteredqualia.com/
* @author mrdoob / http://mrdoob.com/
* @author WestLangley / http://github.com/WestLangley
*/
function DirectionalLightHelper( light, size ) {
Object3D.call( this );
this.light = light;
this.light.updateMatrixWorld();
this.matrix = light.matrixWorld;
this.matrixAutoUpdate = false;
if ( size === undefined ) size = 1;
var geometry = new BufferGeometry();
geometry.addAttribute( 'position', new Float32BufferAttribute( [
- size, size, 0,
size, size, 0,
size, - size, 0,
- size, - size, 0,
- size, size, 0
], 3 ) );
var material = new LineBasicMaterial( { fog: false } );
this.add( new Line( geometry, material ) );
geometry = new BufferGeometry();
geometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) );
this.add( new Line( geometry, material ));
this.update();
}
DirectionalLightHelper.prototype = Object.create( Object3D.prototype );
DirectionalLightHelper.prototype.constructor = DirectionalLightHelper;
DirectionalLightHelper.prototype.dispose = function () {
var lightPlane = this.children[ 0 ];
var targetLine = this.children[ 1 ];
lightPlane.geometry.dispose();
lightPlane.material.dispose();
targetLine.geometry.dispose();
targetLine.material.dispose();
};
DirectionalLightHelper.prototype.update = function () {
var v1 = new Vector3();
var v2 = new Vector3();
var v3 = new Vector3();
return function update() {
v1.setFromMatrixPosition( this.light.matrixWorld );
v2.setFromMatrixPosition( this.light.target.matrixWorld );
v3.subVectors( v2, v1 );
var lightPlane = this.children[ 0 ];
var targetLine = this.children[ 1 ];
lightPlane.lookAt( v3 );
lightPlane.material.color.copy( this.light.color );
targetLine.lookAt( v3 );
targetLine.scale.z = v3.length();
};
}();
/**
* @author alteredq / http://alteredqualia.com/
* @author Mugen87 / https://github.com/Mugen87
*
* - shows frustum, line of sight and up of the camera
* - suitable for fast updates
* - based on frustum visualization in lightgl.js shadowmap example
* http://evanw.github.com/lightgl.js/tests/shadowmap.html
*/
function CameraHelper( camera ) {
var geometry = new BufferGeometry();
var material = new LineBasicMaterial( { color: 0xffffff, vertexColors: FaceColors } );
var vertices = [];
var colors = [];
var pointMap = {};
// colors
var colorFrustum = new Color( 0xffaa00 );
var colorCone = new Color( 0xff0000 );
var colorUp = new Color( 0x00aaff );
var colorTarget = new Color( 0xffffff );
var colorCross = new Color( 0x333333 );
// near
addLine( "n1", "n2", colorFrustum );
addLine( "n2", "n4", colorFrustum );
addLine( "n4", "n3", colorFrustum );
addLine( "n3", "n1", colorFrustum );
// far
addLine( "f1", "f2", colorFrustum );
addLine( "f2", "f4", colorFrustum );
addLine( "f4", "f3", colorFrustum );
addLine( "f3", "f1", colorFrustum );
// sides
addLine( "n1", "f1", colorFrustum );
addLine( "n2", "f2", colorFrustum );
addLine( "n3", "f3", colorFrustum );
addLine( "n4", "f4", colorFrustum );
// cone
addLine( "p", "n1", colorCone );
addLine( "p", "n2", colorCone );
addLine( "p", "n3", colorCone );
addLine( "p", "n4", colorCone );
// up
addLine( "u1", "u2", colorUp );
addLine( "u2", "u3", colorUp );
addLine( "u3", "u1", colorUp );
// target
addLine( "c", "t", colorTarget );
addLine( "p", "c", colorCross );
// cross
addLine( "cn1", "cn2", colorCross );
addLine( "cn3", "cn4", colorCross );
addLine( "cf1", "cf2", colorCross );
addLine( "cf3", "cf4", colorCross );
function addLine( a, b, color ) {
addPoint( a, color );
addPoint( b, color );
}
function addPoint( id, color ) {
vertices.push( 0, 0, 0 );
colors.push( color.r, color.g, color.b );
if ( pointMap[ id ] === undefined ) {
pointMap[ id ] = [];
}
pointMap[ id ].push( ( vertices.length / 3 ) - 1 );
}
geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
LineSegments.call( this, geometry, material );
this.camera = camera;
if ( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix();
this.matrix = camera.matrixWorld;
this.matrixAutoUpdate = false;
this.pointMap = pointMap;
this.update();
}
CameraHelper.prototype = Object.create( LineSegments.prototype );
CameraHelper.prototype.constructor = CameraHelper;
CameraHelper.prototype.update = function () {
var geometry, pointMap;
var vector = new Vector3();
var camera = new Camera();
function setPoint( point, x, y, z ) {
vector.set( x, y, z ).unproject( camera );
var points = pointMap[ point ];
if ( points !== undefined ) {
var position = geometry.getAttribute( 'position' );
for ( var i = 0, l = points.length; i < l; i ++ ) {
position.setXYZ( points[ i ], vector.x, vector.y, vector.z );
}
}
}
return function update() {
geometry = this.geometry;
pointMap = this.pointMap;
var w = 1, h = 1;
// we need just camera projection matrix
// world matrix must be identity
camera.projectionMatrix.copy( this.camera.projectionMatrix );
// center / target
setPoint( "c", 0, 0, - 1 );
setPoint( "t", 0, 0, 1 );
// near
setPoint( "n1", - w, - h, - 1 );
setPoint( "n2", w, - h, - 1 );
setPoint( "n3", - w, h, - 1 );
setPoint( "n4", w, h, - 1 );
// far
setPoint( "f1", - w, - h, 1 );
setPoint( "f2", w, - h, 1 );
setPoint( "f3", - w, h, 1 );
setPoint( "f4", w, h, 1 );
// up
setPoint( "u1", w * 0.7, h * 1.1, - 1 );
setPoint( "u2", - w * 0.7, h * 1.1, - 1 );
setPoint( "u3", 0, h * 2, - 1 );
// cross
setPoint( "cf1", - w, 0, 1 );
setPoint( "cf2", w, 0, 1 );
setPoint( "cf3", 0, - h, 1 );
setPoint( "cf4", 0, h, 1 );
setPoint( "cn1", - w, 0, - 1 );
setPoint( "cn2", w, 0, - 1 );
setPoint( "cn3", 0, - h, - 1 );
setPoint( "cn4", 0, h, - 1 );
geometry.getAttribute( 'position' ).needsUpdate = true;
};
}();
/**
* @author mrdoob / http://mrdoob.com/
* @author Mugen87 / http://github.com/Mugen87
*/
function BoxHelper( object, color ) {
this.object = object;
if ( color === undefined ) color = 0xffff00;
var indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] );
var positions = new Float32Array( 8 * 3 );
var geometry = new BufferGeometry();
geometry.setIndex( new BufferAttribute( indices, 1 ) );
geometry.addAttribute( 'position', new BufferAttribute( positions, 3 ) );
LineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) );
this.matrixAutoUpdate = false;
this.update();
}
BoxHelper.prototype = Object.create( LineSegments.prototype );
BoxHelper.prototype.constructor = BoxHelper;
BoxHelper.prototype.update = ( function () {
var box = new Box3();
return function update( object ) {
if ( object !== undefined ) {
console.warn( 'THREE.BoxHelper: .update() has no longer arguments.' );
}
if ( this.object !== undefined ) {
box.setFromObject( this.object );
}
if ( box.isEmpty() ) return;
var min = box.min;
var max = box.max;
/*
5____4
1/___0/|
| 6__|_7
2/___3/
0: max.x, max.y, max.z
1: min.x, max.y, max.z
2: min.x, min.y, max.z
3: max.x, min.y, max.z
4: max.x, max.y, min.z
5: min.x, max.y, min.z
6: min.x, min.y, min.z
7: max.x, min.y, min.z
*/
var position = this.geometry.attributes.position;
var array = position.array;
array[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z;
array[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z;
array[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z;
array[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z;
array[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z;
array[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z;
array[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z;
array[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z;
position.needsUpdate = true;
this.geometry.computeBoundingSphere();
};
} )();
BoxHelper.prototype.setFromObject = function ( object ) {
this.object = object;
this.update();
return this;
};
/**
* @author WestLangley / http://github.com/WestLangley
* @author zz85 / http://github.com/zz85
* @author bhouston / http://clara.io
*
* Creates an arrow for visualizing directions
*
* Parameters:
* dir - Vector3
* origin - Vector3
* length - Number
* color - color in hex value
* headLength - Number
* headWidth - Number
*/
var lineGeometry;
var coneGeometry;
function ArrowHelper( dir, origin, length, color, headLength, headWidth ) {
// dir is assumed to be normalized
Object3D.call( this );
if ( color === undefined ) color = 0xffff00;
if ( length === undefined ) length = 1;
if ( headLength === undefined ) headLength = 0.2 * length;
if ( headWidth === undefined ) headWidth = 0.2 * headLength;
if ( lineGeometry === undefined ) {
lineGeometry = new BufferGeometry();
lineGeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) );
coneGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 );
coneGeometry.translate( 0, - 0.5, 0 );
}
this.position.copy( origin );
this.line = new Line( lineGeometry, new LineBasicMaterial( { color: color } ) );
this.line.matrixAutoUpdate = false;
this.add( this.line );
this.cone = new Mesh( coneGeometry, new MeshBasicMaterial( { color: color } ) );
this.cone.matrixAutoUpdate = false;
this.add( this.cone );
this.setDirection( dir );
this.setLength( length, headLength, headWidth );
}
ArrowHelper.prototype = Object.create( Object3D.prototype );
ArrowHelper.prototype.constructor = ArrowHelper;
ArrowHelper.prototype.setDirection = ( function () {
var axis = new Vector3();
var radians;
return function setDirection( dir ) {
// dir is assumed to be normalized
if ( dir.y > 0.99999 ) {
this.quaternion.set( 0, 0, 0, 1 );
} else if ( dir.y < - 0.99999 ) {
this.quaternion.set( 1, 0, 0, 0 );
} else {
axis.set( dir.z, 0, - dir.x ).normalize();
radians = Math.acos( dir.y );
this.quaternion.setFromAxisAngle( axis, radians );
}
};
}() );
ArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) {
if ( headLength === undefined ) headLength = 0.2 * length;
if ( headWidth === undefined ) headWidth = 0.2 * headLength;
this.line.scale.set( 1, Math.max( 0, length - headLength ), 1 );
this.line.updateMatrix();
this.cone.scale.set( headWidth, headLength, headWidth );
this.cone.position.y = length;
this.cone.updateMatrix();
};
ArrowHelper.prototype.setColor = function ( color ) {
this.line.material.color.copy( color );
this.cone.material.color.copy( color );
};
/**
* @author sroucheray / http://sroucheray.org/
* @author mrdoob / http://mrdoob.com/
*/
function AxisHelper( size ) {
size = size || 1;
var vertices = [
0, 0, 0, size, 0, 0,
0, 0, 0, 0, size, 0,
0, 0, 0, 0, 0, size
];
var colors = [
1, 0, 0, 1, 0.6, 0,
0, 1, 0, 0.6, 1, 0,
0, 0, 1, 0, 0.6, 1
];
var geometry = new BufferGeometry();
geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
var material = new LineBasicMaterial( { vertexColors: VertexColors } );
LineSegments.call( this, geometry, material );
}
AxisHelper.prototype = Object.create( LineSegments.prototype );
AxisHelper.prototype.constructor = AxisHelper;
/**
* @author zz85 https://github.com/zz85
*
* Centripetal CatmullRom Curve - which is useful for avoiding
* cusps and self-intersections in non-uniform catmull rom curves.
* http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf
*
* curve.type accepts centripetal(default), chordal and catmullrom
* curve.tension is used for catmullrom which defaults to 0.5
*/
/*
Based on an optimized c++ solution in
- http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/
- http://ideone.com/NoEbVM
This CubicPoly class could be used for reusing some variables and calculations,
but for three.js curve use, it could be possible inlined and flatten into a single function call
which can be placed in CurveUtils.
*/
function CubicPoly() {
var c0 = 0, c1 = 0, c2 = 0, c3 = 0;
/*
* Compute coefficients for a cubic polynomial
* p(s) = c0 + c1*s + c2*s^2 + c3*s^3
* such that
* p(0) = x0, p(1) = x1
* and
* p'(0) = t0, p'(1) = t1.
*/
function init( x0, x1, t0, t1 ) {
c0 = x0;
c1 = t0;
c2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1;
c3 = 2 * x0 - 2 * x1 + t0 + t1;
}
return {
initCatmullRom: function ( x0, x1, x2, x3, tension ) {
init( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) );
},
initNonuniformCatmullRom: function ( x0, x1, x2, x3, dt0, dt1, dt2 ) {
// compute tangents when parameterized in [t1,t2]
var t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1;
var t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2;
// rescale tangents for parametrization in [0,1]
t1 *= dt1;
t2 *= dt1;
init( x1, x2, t1, t2 );
},
calc: function ( t ) {
var t2 = t * t;
var t3 = t2 * t;
return c0 + c1 * t + c2 * t2 + c3 * t3;
}
};
}
//
var tmp = new Vector3();
var px = new CubicPoly();
var py = new CubicPoly();
var pz = new CubicPoly();
function CatmullRomCurve3( points ) {
Curve.call( this );
if ( points.length < 2 ) console.warn( 'THREE.CatmullRomCurve3: Points array needs at least two entries.' );
this.points = points || [];
this.closed = false;
}
CatmullRomCurve3.prototype = Object.create( Curve.prototype );
CatmullRomCurve3.prototype.constructor = CatmullRomCurve3;
CatmullRomCurve3.prototype.getPoint = function ( t ) {
var points = this.points;
var l = points.length;
var point = ( l - ( this.closed ? 0 : 1 ) ) * t;
var intPoint = Math.floor( point );
var weight = point - intPoint;
if ( this.closed ) {
intPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / points.length ) + 1 ) * points.length;
} else if ( weight === 0 && intPoint === l - 1 ) {
intPoint = l - 2;
weight = 1;
}
var p0, p1, p2, p3; // 4 points
if ( this.closed || intPoint > 0 ) {
p0 = points[ ( intPoint - 1 ) % l ];
} else {
// extrapolate first point
tmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );
p0 = tmp;
}
p1 = points[ intPoint % l ];
p2 = points[ ( intPoint + 1 ) % l ];
if ( this.closed || intPoint + 2 < l ) {
p3 = points[ ( intPoint + 2 ) % l ];
} else {
// extrapolate last point
tmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] );
p3 = tmp;
}
if ( this.type === undefined || this.type === 'centripetal' || this.type === 'chordal' ) {
// init Centripetal / Chordal Catmull-Rom
var pow = this.type === 'chordal' ? 0.5 : 0.25;
var dt0 = Math.pow( p0.distanceToSquared( p1 ), pow );
var dt1 = Math.pow( p1.distanceToSquared( p2 ), pow );
var dt2 = Math.pow( p2.distanceToSquared( p3 ), pow );
// safety check for repeated points
if ( dt1 < 1e-4 ) dt1 = 1.0;
if ( dt0 < 1e-4 ) dt0 = dt1;
if ( dt2 < 1e-4 ) dt2 = dt1;
px.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 );
py.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 );
pz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 );
} else if ( this.type === 'catmullrom' ) {
var tension = this.tension !== undefined ? this.tension : 0.5;
px.initCatmullRom( p0.x, p1.x, p2.x, p3.x, tension );
py.initCatmullRom( p0.y, p1.y, p2.y, p3.y, tension );
pz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, tension );
}
return new Vector3( px.calc( weight ), py.calc( weight ), pz.calc( weight ) );
};
function CubicBezierCurve3( v0, v1, v2, v3 ) {
Curve.call( this );
this.v0 = v0;
this.v1 = v1;
this.v2 = v2;
this.v3 = v3;
}
CubicBezierCurve3.prototype = Object.create( Curve.prototype );
CubicBezierCurve3.prototype.constructor = CubicBezierCurve3;
CubicBezierCurve3.prototype.getPoint = function ( t ) {
var v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;
return new Vector3(
CubicBezier( t, v0.x, v1.x, v2.x, v3.x ),
CubicBezier( t, v0.y, v1.y, v2.y, v3.y ),
CubicBezier( t, v0.z, v1.z, v2.z, v3.z )
);
};
function QuadraticBezierCurve3( v0, v1, v2 ) {
Curve.call( this );
this.v0 = v0;
this.v1 = v1;
this.v2 = v2;
}
QuadraticBezierCurve3.prototype = Object.create( Curve.prototype );
QuadraticBezierCurve3.prototype.constructor = QuadraticBezierCurve3;
QuadraticBezierCurve3.prototype.getPoint = function ( t ) {
var v0 = this.v0, v1 = this.v1, v2 = this.v2;
return new Vector3(
QuadraticBezier( t, v0.x, v1.x, v2.x ),
QuadraticBezier( t, v0.y, v1.y, v2.y ),
QuadraticBezier( t, v0.z, v1.z, v2.z )
);
};
function LineCurve3( v1, v2 ) {
Curve.call( this );
this.v1 = v1;
this.v2 = v2;
}
LineCurve3.prototype = Object.create( Curve.prototype );
LineCurve3.prototype.constructor = LineCurve3;
LineCurve3.prototype.getPoint = function ( t ) {
if ( t === 1 ) {
return this.v2.clone();
}
var vector = new Vector3();
vector.subVectors( this.v2, this.v1 ); // diff
vector.multiplyScalar( t );
vector.add( this.v1 );
return vector;
};
function ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {
EllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );
}
ArcCurve.prototype = Object.create( EllipseCurve.prototype );
ArcCurve.prototype.constructor = ArcCurve;
/**
* @author alteredq / http://alteredqualia.com/
*/
var SceneUtils = {
createMultiMaterialObject: function ( geometry, materials ) {
var group = new Group();
for ( var i = 0, l = materials.length; i < l; i ++ ) {
group.add( new Mesh( geometry, materials[ i ] ) );
}
return group;
},
detach: function ( child, parent, scene ) {
child.applyMatrix( parent.matrixWorld );
parent.remove( child );
scene.add( child );
},
attach: function ( child, scene, parent ) {
child.applyMatrix( new Matrix4().getInverse( parent.matrixWorld ) );
scene.remove( child );
parent.add( child );
}
};
/**
* @author mrdoob / http://mrdoob.com/
*/
function Face4( a, b, c, d, normal, color, materialIndex ) {
console.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' );
return new Face3( a, b, c, normal, color, materialIndex );
}
var LineStrip = 0;
var LinePieces = 1;
function MeshFaceMaterial( materials ) {
console.warn( 'THREE.MeshFaceMaterial has been removed. Use an Array instead.' );
return materials;
}
function MultiMaterial( materials ) {
if ( materials === undefined ) materials = [];
console.warn( 'THREE.MultiMaterial has been removed. Use an Array instead.' );
materials.isMultiMaterial = true;
materials.materials = materials;
materials.clone = function () {
return materials.slice();
};
return materials;
}
function PointCloud( geometry, material ) {
console.warn( 'THREE.PointCloud has been renamed to THREE.Points.' );
return new Points( geometry, material );
}
function Particle( material ) {
console.warn( 'THREE.Particle has been renamed to THREE.Sprite.' );
return new Sprite( material );
}
function ParticleSystem( geometry, material ) {
console.warn( 'THREE.ParticleSystem has been renamed to THREE.Points.' );
return new Points( geometry, material );
}
function PointCloudMaterial( parameters ) {
console.warn( 'THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.' );
return new PointsMaterial( parameters );
}
function ParticleBasicMaterial( parameters ) {
console.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.' );
return new PointsMaterial( parameters );
}
function ParticleSystemMaterial( parameters ) {
console.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.' );
return new PointsMaterial( parameters );
}
function Vertex( x, y, z ) {
console.warn( 'THREE.Vertex has been removed. Use THREE.Vector3 instead.' );
return new Vector3( x, y, z );
}
//
function DynamicBufferAttribute( array, itemSize ) {
console.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setDynamic( true ) instead.' );
return new BufferAttribute( array, itemSize ).setDynamic( true );
}
function Int8Attribute( array, itemSize ) {
console.warn( 'THREE.Int8Attribute has been removed. Use new THREE.Int8BufferAttribute() instead.' );
return new Int8BufferAttribute( array, itemSize );
}
function Uint8Attribute( array, itemSize ) {
console.warn( 'THREE.Uint8Attribute has been removed. Use new THREE.Uint8BufferAttribute() instead.' );
return new Uint8BufferAttribute( array, itemSize );
}
function Uint8ClampedAttribute( array, itemSize ) {
console.warn( 'THREE.Uint8ClampedAttribute has been removed. Use new THREE.Uint8ClampedBufferAttribute() instead.' );
return new Uint8ClampedBufferAttribute( array, itemSize );
}
function Int16Attribute( array, itemSize ) {
console.warn( 'THREE.Int16Attribute has been removed. Use new THREE.Int16BufferAttribute() instead.' );
return new Int16BufferAttribute( array, itemSize );
}
function Uint16Attribute( array, itemSize ) {
console.warn( 'THREE.Uint16Attribute has been removed. Use new THREE.Uint16BufferAttribute() instead.' );
return new Uint16BufferAttribute( array, itemSize );
}
function Int32Attribute( array, itemSize ) {
console.warn( 'THREE.Int32Attribute has been removed. Use new THREE.Int32BufferAttribute() instead.' );
return new Int32BufferAttribute( array, itemSize );
}
function Uint32Attribute( array, itemSize ) {
console.warn( 'THREE.Uint32Attribute has been removed. Use new THREE.Uint32BufferAttribute() instead.' );
return new Uint32BufferAttribute( array, itemSize );
}
function Float32Attribute( array, itemSize ) {
console.warn( 'THREE.Float32Attribute has been removed. Use new THREE.Float32BufferAttribute() instead.' );
return new Float32BufferAttribute( array, itemSize );
}
function Float64Attribute( array, itemSize ) {
console.warn( 'THREE.Float64Attribute has been removed. Use new THREE.Float64BufferAttribute() instead.' );
return new Float64BufferAttribute( array, itemSize );
}
//
Curve.create = function ( construct, getPoint ) {
console.log( 'THREE.Curve.create() has been deprecated' );
construct.prototype = Object.create( Curve.prototype );
construct.prototype.constructor = construct;
construct.prototype.getPoint = getPoint;
return construct;
};
//
function ClosedSplineCurve3( points ) {
console.warn( 'THREE.ClosedSplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );
CatmullRomCurve3.call( this, points );
this.type = 'catmullrom';
this.closed = true;
}
ClosedSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );
//
function SplineCurve3( points ) {
console.warn( 'THREE.SplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );
CatmullRomCurve3.call( this, points );
this.type = 'catmullrom';
}
SplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );
//
function Spline( points ) {
console.warn( 'THREE.Spline has been removed. Use THREE.CatmullRomCurve3 instead.' );
CatmullRomCurve3.call( this, points );
this.type = 'catmullrom';
}
Spline.prototype = Object.create( CatmullRomCurve3.prototype );
Object.assign( Spline.prototype, {
initFromArray: function ( a ) {
console.error( 'THREE.Spline: .initFromArray() has been removed.' );
},
getControlPointsArray: function ( optionalTarget ) {
console.error( 'THREE.Spline: .getControlPointsArray() has been removed.' );
},
reparametrizeByArcLength: function ( samplingCoef ) {
console.error( 'THREE.Spline: .reparametrizeByArcLength() has been removed.' );
}
} );
//
function BoundingBoxHelper( object, color ) {
console.warn( 'THREE.BoundingBoxHelper has been deprecated. Creating a THREE.BoxHelper instead.' );
return new BoxHelper( object, color );
}
function EdgesHelper( object, hex ) {
console.warn( 'THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.' );
return new LineSegments( new EdgesGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );
}
GridHelper.prototype.setColors = function () {
console.error( 'THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.' );
};
SkeletonHelper.prototype.update = function () {
console.error( 'THREE.SkeletonHelper: update() no longer needs to be called.' );
};
function WireframeHelper( object, hex ) {
console.warn( 'THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.' );
return new LineSegments( new WireframeGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );
}
//
function XHRLoader( manager ) {
console.warn( 'THREE.XHRLoader has been renamed to THREE.FileLoader.' );
return new FileLoader( manager );
}
function BinaryTextureLoader( manager ) {
console.warn( 'THREE.BinaryTextureLoader has been renamed to THREE.DataTextureLoader.' );
return new DataTextureLoader( manager );
}
//
Object.assign( Box2.prototype, {
center: function ( optionalTarget ) {
console.warn( 'THREE.Box2: .center() has been renamed to .getCenter().' );
return this.getCenter( optionalTarget );
},
empty: function () {
console.warn( 'THREE.Box2: .empty() has been renamed to .isEmpty().' );
return this.isEmpty();
},
isIntersectionBox: function ( box ) {
console.warn( 'THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().' );
return this.intersectsBox( box );
},
size: function ( optionalTarget ) {
console.warn( 'THREE.Box2: .size() has been renamed to .getSize().' );
return this.getSize( optionalTarget );
}
} );
Object.assign( Box3.prototype, {
center: function ( optionalTarget ) {
console.warn( 'THREE.Box3: .center() has been renamed to .getCenter().' );
return this.getCenter( optionalTarget );
},
empty: function () {
console.warn( 'THREE.Box3: .empty() has been renamed to .isEmpty().' );
return this.isEmpty();
},
isIntersectionBox: function ( box ) {
console.warn( 'THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().' );
return this.intersectsBox( box );
},
isIntersectionSphere: function ( sphere ) {
console.warn( 'THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().' );
return this.intersectsSphere( sphere );
},
size: function ( optionalTarget ) {
console.warn( 'THREE.Box3: .size() has been renamed to .getSize().' );
return this.getSize( optionalTarget );
}
} );
Line3.prototype.center = function ( optionalTarget ) {
console.warn( 'THREE.Line3: .center() has been renamed to .getCenter().' );
return this.getCenter( optionalTarget );
};
_Math.random16 = function () {
console.warn( 'THREE.Math.random16() has been deprecated. Use Math.random() instead.' );
return Math.random();
};
Object.assign( Matrix3.prototype, {
flattenToArrayOffset: function ( array, offset ) {
console.warn( "THREE.Matrix3: .flattenToArrayOffset() has been deprecated. Use .toArray() instead." );
return this.toArray( array, offset );
},
multiplyVector3: function ( vector ) {
console.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' );
return vector.applyMatrix3( this );
},
multiplyVector3Array: function ( a ) {
console.error( 'THREE.Matrix3: .multiplyVector3Array() has been removed.' );
},
applyToBuffer: function( buffer, offset, length ) {
console.warn( 'THREE.Matrix3: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' );
return this.applyToBufferAttribute( buffer );
},
applyToVector3Array: function( array, offset, length ) {
console.error( 'THREE.Matrix3: .applyToVector3Array() has been removed.' );
}
} );
Object.assign( Matrix4.prototype, {
extractPosition: function ( m ) {
console.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' );
return this.copyPosition( m );
},
flattenToArrayOffset: function ( array, offset ) {
console.warn( "THREE.Matrix4: .flattenToArrayOffset() has been deprecated. Use .toArray() instead." );
return this.toArray( array, offset );
},
getPosition: function () {
var v1;
return function getPosition() {
if ( v1 === undefined ) v1 = new Vector3();
console.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' );
return v1.setFromMatrixColumn( this, 3 );
};
}(),
setRotationFromQuaternion: function ( q ) {
console.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' );
return this.makeRotationFromQuaternion( q );
},
multiplyToArray: function () {
console.warn( 'THREE.Matrix4: .multiplyToArray() has been removed.' );
},
multiplyVector3: function ( vector ) {
console.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) instead.' );
return vector.applyMatrix4( this );
},
multiplyVector4: function ( vector ) {
console.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' );
return vector.applyMatrix4( this );
},
multiplyVector3Array: function ( a ) {
console.error( 'THREE.Matrix4: .multiplyVector3Array() has been removed.' );
},
rotateAxis: function ( v ) {
console.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' );
v.transformDirection( this );
},
crossVector: function ( vector ) {
console.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' );
return vector.applyMatrix4( this );
},
translate: function () {
console.error( 'THREE.Matrix4: .translate() has been removed.' );
},
rotateX: function () {
console.error( 'THREE.Matrix4: .rotateX() has been removed.' );
},
rotateY: function () {
console.error( 'THREE.Matrix4: .rotateY() has been removed.' );
},
rotateZ: function () {
console.error( 'THREE.Matrix4: .rotateZ() has been removed.' );
},
rotateByAxis: function () {
console.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' );
},
applyToBuffer: function( buffer, offset, length ) {
console.warn( 'THREE.Matrix4: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' );
return this.applyToBufferAttribute( buffer );
},
applyToVector3Array: function( array, offset, length ) {
console.error( 'THREE.Matrix4: .applyToVector3Array() has been removed.' );
},
makeFrustum: function( left, right, bottom, top, near, far ) {
console.warn( 'THREE.Matrix4: .makeFrustum() has been removed. Use .makePerspective( left, right, top, bottom, near, far ) instead.' );
return this.makePerspective( left, right, top, bottom, near, far );
}
} );
Plane.prototype.isIntersectionLine = function ( line ) {
console.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' );
return this.intersectsLine( line );
};
Quaternion.prototype.multiplyVector3 = function ( vector ) {
console.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' );
return vector.applyQuaternion( this );
};
Object.assign( Ray.prototype, {
isIntersectionBox: function ( box ) {
console.warn( 'THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().' );
return this.intersectsBox( box );
},
isIntersectionPlane: function ( plane ) {
console.warn( 'THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().' );
return this.intersectsPlane( plane );
},
isIntersectionSphere: function ( sphere ) {
console.warn( 'THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().' );
return this.intersectsSphere( sphere );
}
} );
Object.assign( Shape.prototype, {
extrude: function ( options ) {
console.warn( 'THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.' );
return new ExtrudeGeometry( this, options );
},
makeGeometry: function ( options ) {
console.warn( 'THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.' );
return new ShapeGeometry( this, options );
}
} );
Object.assign( Vector2.prototype, {
fromAttribute: function ( attribute, index, offset ) {
console.error( 'THREE.Vector2: .fromAttribute() has been renamed to .fromBufferAttribute().' );
return this.fromBufferAttribute( attribute, index, offset );
}
} );
Object.assign( Vector3.prototype, {
setEulerFromRotationMatrix: function () {
console.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' );
},
setEulerFromQuaternion: function () {
console.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' );
},
getPositionFromMatrix: function ( m ) {
console.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' );
return this.setFromMatrixPosition( m );
},
getScaleFromMatrix: function ( m ) {
console.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' );
return this.setFromMatrixScale( m );
},
getColumnFromMatrix: function ( index, matrix ) {
console.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' );
return this.setFromMatrixColumn( matrix, index );
},
applyProjection: function ( m ) {
console.warn( 'THREE.Vector3: .applyProjection() has been removed. Use .applyMatrix4( m ) instead.' );
return this.applyMatrix4( m );
},
fromAttribute: function ( attribute, index, offset ) {
console.error( 'THREE.Vector3: .fromAttribute() has been renamed to .fromBufferAttribute().' );
return this.fromBufferAttribute( attribute, index, offset );
}
} );
Object.assign( Vector4.prototype, {
fromAttribute: function ( attribute, index, offset ) {
console.error( 'THREE.Vector4: .fromAttribute() has been renamed to .fromBufferAttribute().' );
return this.fromBufferAttribute( attribute, index, offset );
}
} );
//
Geometry.prototype.computeTangents = function () {
console.warn( 'THREE.Geometry: .computeTangents() has been removed.' );
};
Object.assign( Object3D.prototype, {
getChildByName: function ( name ) {
console.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' );
return this.getObjectByName( name );
},
renderDepth: function () {
console.warn( 'THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.' );
},
translate: function ( distance, axis ) {
console.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' );
return this.translateOnAxis( axis, distance );
}
} );
Object.defineProperties( Object3D.prototype, {
eulerOrder: {
get: function () {
console.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );
return this.rotation.order;
},
set: function ( value ) {
console.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );
this.rotation.order = value;
}
},
useQuaternion: {
get: function () {
console.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );
},
set: function () {
console.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );
}
}
} );
Object.defineProperties( LOD.prototype, {
objects: {
get: function () {
console.warn( 'THREE.LOD: .objects has been renamed to .levels.' );
return this.levels;
}
}
} );
Object.defineProperty( Skeleton.prototype, 'useVertexTexture', {
get: function () {
console.warn( 'THREE.Skeleton: useVertexTexture has been removed.' );
},
set: function () {
console.warn( 'THREE.Skeleton: useVertexTexture has been removed.' );
}
} );
Object.defineProperty( Curve.prototype, '__arcLengthDivisions', {
get: function () {
console.warn( 'THREE.Curve: .__arcLengthDivisions is now .arcLengthDivisions.' );
return this.arcLengthDivisions;
},
set: function ( value ) {
console.warn( 'THREE.Curve: .__arcLengthDivisions is now .arcLengthDivisions.' );
this.arcLengthDivisions = value;
}
} );
//
PerspectiveCamera.prototype.setLens = function ( focalLength, filmGauge ) {
console.warn( "THREE.PerspectiveCamera.setLens is deprecated. " +
"Use .setFocalLength and .filmGauge for a photographic setup." );
if ( filmGauge !== undefined ) this.filmGauge = filmGauge;
this.setFocalLength( focalLength );
};
//
Object.defineProperties( Light.prototype, {
onlyShadow: {
set: function () {
console.warn( 'THREE.Light: .onlyShadow has been removed.' );
}
},
shadowCameraFov: {
set: function ( value ) {
console.warn( 'THREE.Light: .shadowCameraFov is now .shadow.camera.fov.' );
this.shadow.camera.fov = value;
}
},
shadowCameraLeft: {
set: function ( value ) {
console.warn( 'THREE.Light: .shadowCameraLeft is now .shadow.camera.left.' );
this.shadow.camera.left = value;
}
},
shadowCameraRight: {
set: function ( value ) {
console.warn( 'THREE.Light: .shadowCameraRight is now .shadow.camera.right.' );
this.shadow.camera.right = value;
}
},
shadowCameraTop: {
set: function ( value ) {
console.warn( 'THREE.Light: .shadowCameraTop is now .shadow.camera.top.' );
this.shadow.camera.top = value;
}
},
shadowCameraBottom: {
set: function ( value ) {
console.warn( 'THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.' );
this.shadow.camera.bottom = value;
}
},
shadowCameraNear: {
set: function ( value ) {
console.warn( 'THREE.Light: .shadowCameraNear is now .shadow.camera.near.' );
this.shadow.camera.near = value;
}
},
shadowCameraFar: {
set: function ( value ) {
console.warn( 'THREE.Light: .shadowCameraFar is now .shadow.camera.far.' );
this.shadow.camera.far = value;
}
},
shadowCameraVisible: {
set: function () {
console.warn( 'THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.' );
}
},
shadowBias: {
set: function ( value ) {
console.warn( 'THREE.Light: .shadowBias is now .shadow.bias.' );
this.shadow.bias = value;
}
},
shadowDarkness: {
set: function () {
console.warn( 'THREE.Light: .shadowDarkness has been removed.' );
}
},
shadowMapWidth: {
set: function ( value ) {
console.warn( 'THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.' );
this.shadow.mapSize.width = value;
}
},
shadowMapHeight: {
set: function ( value ) {
console.warn( 'THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.' );
this.shadow.mapSize.height = value;
}
}
} );
//
Object.defineProperties( BufferAttribute.prototype, {
length: {
get: function () {
console.warn( 'THREE.BufferAttribute: .length has been deprecated. Use .count instead.' );
return this.array.length;
}
}
} );
Object.assign( BufferGeometry.prototype, {
addIndex: function ( index ) {
console.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' );
this.setIndex( index );
},
addDrawCall: function ( start, count, indexOffset ) {
if ( indexOffset !== undefined ) {
console.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' );
}
console.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' );
this.addGroup( start, count );
},
clearDrawCalls: function () {
console.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' );
this.clearGroups();
},
computeTangents: function () {
console.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' );
},
computeOffsets: function () {
console.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' );
}
} );
Object.defineProperties( BufferGeometry.prototype, {
drawcalls: {
get: function () {
console.error( 'THREE.BufferGeometry: .drawcalls has been renamed to .groups.' );
return this.groups;
}
},
offsets: {
get: function () {
console.warn( 'THREE.BufferGeometry: .offsets has been renamed to .groups.' );
return this.groups;
}
}
} );
//
Object.defineProperties( Uniform.prototype, {
dynamic: {
set: function () {
console.warn( 'THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.' );
}
},
onUpdate: {
value: function () {
console.warn( 'THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.' );
return this;
}
}
} );
//
Object.defineProperties( Material.prototype, {
wrapAround: {
get: function () {
console.warn( 'THREE.Material: .wrapAround has been removed.' );
},
set: function () {
console.warn( 'THREE.Material: .wrapAround has been removed.' );
}
},
wrapRGB: {
get: function () {
console.warn( 'THREE.Material: .wrapRGB has been removed.' );
return new Color();
}
}
} );
Object.defineProperties( MeshPhongMaterial.prototype, {
metal: {
get: function () {
console.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.' );
return false;
},
set: function () {
console.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead' );
}
}
} );
Object.defineProperties( ShaderMaterial.prototype, {
derivatives: {
get: function () {
console.warn( 'THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );
return this.extensions.derivatives;
},
set: function ( value ) {
console.warn( 'THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );
this.extensions.derivatives = value;
}
}
} );
//
Object.assign( WebGLRenderer.prototype, {
getCurrentRenderTarget: function () {
console.warn( 'THREE.WebGLRenderer: .getCurrentRenderTarget() is now .getRenderTarget().' );
return this.getRenderTarget();
},
supportsFloatTextures: function () {
console.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \'OES_texture_float\' ).' );
return this.extensions.get( 'OES_texture_float' );
},
supportsHalfFloatTextures: function () {
console.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \'OES_texture_half_float\' ).' );
return this.extensions.get( 'OES_texture_half_float' );
},
supportsStandardDerivatives: function () {
console.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \'OES_standard_derivatives\' ).' );
return this.extensions.get( 'OES_standard_derivatives' );
},
supportsCompressedTextureS3TC: function () {
console.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \'WEBGL_compressed_texture_s3tc\' ).' );
return this.extensions.get( 'WEBGL_compressed_texture_s3tc' );
},
supportsCompressedTexturePVRTC: function () {
console.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \'WEBGL_compressed_texture_pvrtc\' ).' );
return this.extensions.get( 'WEBGL_compressed_texture_pvrtc' );
},
supportsBlendMinMax: function () {
console.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \'EXT_blend_minmax\' ).' );
return this.extensions.get( 'EXT_blend_minmax' );
},
supportsVertexTextures: function () {
console.warn( 'THREE.WebGLRenderer: .supportsVertexTextures() is now .capabilities.vertexTextures.' );
return this.capabilities.vertexTextures;
},
supportsInstancedArrays: function () {
console.warn( 'THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \'ANGLE_instanced_arrays\' ).' );
return this.extensions.get( 'ANGLE_instanced_arrays' );
},
enableScissorTest: function ( boolean ) {
console.warn( 'THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().' );
this.setScissorTest( boolean );
},
initMaterial: function () {
console.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' );
},
addPrePlugin: function () {
console.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' );
},
addPostPlugin: function () {
console.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' );
},
updateShadowMap: function () {
console.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' );
}
} );
Object.defineProperties( WebGLRenderer.prototype, {
shadowMapEnabled: {
get: function () {
return this.shadowMap.enabled;
},
set: function ( value ) {
console.warn( 'THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.' );
this.shadowMap.enabled = value;
}
},
shadowMapType: {
get: function () {
return this.shadowMap.type;
},
set: function ( value ) {
console.warn( 'THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.' );
this.shadowMap.type = value;
}
},
shadowMapCullFace: {
get: function () {
return this.shadowMap.cullFace;
},
set: function ( value ) {
console.warn( 'THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.' );
this.shadowMap.cullFace = value;
}
}
} );
Object.defineProperties( WebGLShadowMap.prototype, {
cullFace: {
get: function () {
return this.renderReverseSided ? CullFaceFront : CullFaceBack;
},
set: function ( cullFace ) {
var value = ( cullFace !== CullFaceBack );
console.warn( "WebGLRenderer: .shadowMap.cullFace is deprecated. Set .shadowMap.renderReverseSided to " + value + "." );
this.renderReverseSided = value;
}
}
} );
//
Object.defineProperties( WebGLRenderTarget.prototype, {
wrapS: {
get: function () {
console.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );
return this.texture.wrapS;
},
set: function ( value ) {
console.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );
this.texture.wrapS = value;
}
},
wrapT: {
get: function () {
console.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );
return this.texture.wrapT;
},
set: function ( value ) {
console.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );
this.texture.wrapT = value;
}
},
magFilter: {
get: function () {
console.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );
return this.texture.magFilter;
},
set: function ( value ) {
console.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );
this.texture.magFilter = value;
}
},
minFilter: {
get: function () {
console.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );
return this.texture.minFilter;
},
set: function ( value ) {
console.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );
this.texture.minFilter = value;
}
},
anisotropy: {
get: function () {
console.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );
return this.texture.anisotropy;
},
set: function ( value ) {
console.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );
this.texture.anisotropy = value;
}
},
offset: {
get: function () {
console.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );
return this.texture.offset;
},
set: function ( value ) {
console.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );
this.texture.offset = value;
}
},
repeat: {
get: function () {
console.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );
return this.texture.repeat;
},
set: function ( value ) {
console.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );
this.texture.repeat = value;
}
},
format: {
get: function () {
console.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );
return this.texture.format;
},
set: function ( value ) {
console.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );
this.texture.format = value;
}
},
type: {
get: function () {
console.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );
return this.texture.type;
},
set: function ( value ) {
console.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );
this.texture.type = value;
}
},
generateMipmaps: {
get: function () {
console.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );
return this.texture.generateMipmaps;
},
set: function ( value ) {
console.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );
this.texture.generateMipmaps = value;
}
}
} );
//
Audio.prototype.load = function ( file ) {
console.warn( 'THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.' );
var scope = this;
var audioLoader = new AudioLoader();
audioLoader.load( file, function ( buffer ) {
scope.setBuffer( buffer );
} );
return this;
};
AudioAnalyser.prototype.getData = function () {
console.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' );
return this.getFrequencyData();
};
//
var GeometryUtils = {
merge: function ( geometry1, geometry2, materialIndexOffset ) {
console.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' );
var matrix;
if ( geometry2.isMesh ) {
geometry2.matrixAutoUpdate && geometry2.updateMatrix();
matrix = geometry2.matrix;
geometry2 = geometry2.geometry;
}
geometry1.merge( geometry2, matrix, materialIndexOffset );
},
center: function ( geometry ) {
console.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' );
return geometry.center();
}
};
var ImageUtils = {
crossOrigin: undefined,
loadTexture: function ( url, mapping, onLoad, onError ) {
console.warn( 'THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.' );
var loader = new TextureLoader();
loader.setCrossOrigin( this.crossOrigin );
var texture = loader.load( url, onLoad, undefined, onError );
if ( mapping ) texture.mapping = mapping;
return texture;
},
loadTextureCube: function ( urls, mapping, onLoad, onError ) {
console.warn( 'THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.' );
var loader = new CubeTextureLoader();
loader.setCrossOrigin( this.crossOrigin );
var texture = loader.load( urls, onLoad, undefined, onError );
if ( mapping ) texture.mapping = mapping;
return texture;
},
loadCompressedTexture: function () {
console.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' );
},
loadCompressedTextureCube: function () {
console.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' );
}
};
//
function Projector() {
console.error( 'THREE.Projector has been moved to /examples/js/renderers/Projector.js.' );
this.projectVector = function ( vector, camera ) {
console.warn( 'THREE.Projector: .projectVector() is now vector.project().' );
vector.project( camera );
};
this.unprojectVector = function ( vector, camera ) {
console.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' );
vector.unproject( camera );
};
this.pickingRay = function () {
console.error( 'THREE.Projector: .pickingRay() is now raycaster.setFromCamera().' );
};
}
//
function CanvasRenderer() {
console.error( 'THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js' );
this.domElement = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );
this.clear = function () {};
this.render = function () {};
this.setClearColor = function () {};
this.setSize = function () {};
}
/***/ }),
/* 193 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _react = __webpack_require__(11);
var _react2 = _interopRequireDefault(_react);
var _Button2 = __webpack_require__(87);
var _Button3 = _interopRequireDefault(_Button2);
var _icons = __webpack_require__(86);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
/**
* Play button
*/
var PlayButton = function (_Button) {
_inherits(PlayButton, _Button);
function PlayButton() {
_classCallCheck(this, PlayButton);
return _possibleConstructorReturn(this, (PlayButton.__proto__ || Object.getPrototypeOf(PlayButton)).apply(this, arguments));
}
return PlayButton;
}(_Button3.default);
PlayButton.defaultProps = _extends({}, _Button3.default.defaultProps, {
className: 'PlayButton',
children: _react2.default.createElement(_icons.PlayIcon, null),
isEnabled: false
});
exports.default = PlayButton;
/***/ }),
/* 194 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _react = __webpack_require__(11);
var _react2 = _interopRequireDefault(_react);
var _Button2 = __webpack_require__(87);
var _Button3 = _interopRequireDefault(_Button2);
var _icons = __webpack_require__(86);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
/**
* Pause button
*/
var PauseButton = function (_Button) {
_inherits(PauseButton, _Button);
function PauseButton() {
_classCallCheck(this, PauseButton);
return _possibleConstructorReturn(this, (PauseButton.__proto__ || Object.getPrototypeOf(PauseButton)).apply(this, arguments));
}
return PauseButton;
}(_Button3.default);
PauseButton.defaultProps = _extends({}, _Button3.default.defaultProps, {
className: 'PauseButton',
children: _react2.default.createElement(_icons.PauseIcon, null)
});
exports.default = PauseButton;
/***/ }),
/* 195 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _react = __webpack_require__(11);
var _react2 = _interopRequireDefault(_react);
var _Button2 = __webpack_require__(87);
var _Button3 = _interopRequireDefault(_Button2);
var _icons = __webpack_require__(86);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
/**
* Previous button
*/
var PrevButton = function (_Button) {
_inherits(PrevButton, _Button);
function PrevButton() {
_classCallCheck(this, PrevButton);
return _possibleConstructorReturn(this, (PrevButton.__proto__ || Object.getPrototypeOf(PrevButton)).apply(this, arguments));
}
return PrevButton;
}(_Button3.default);
PrevButton.defaultProps = _extends({}, _Button3.default.defaultProps, {
className: 'PrevButton',
children: _react2.default.createElement(_icons.PreviousIcon, null),
isEnabled: false
});
exports.default = PrevButton;
/***/ }),
/* 196 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _react = __webpack_require__(11);
var _react2 = _interopRequireDefault(_react);
var _Button2 = __webpack_require__(87);
var _Button3 = _interopRequireDefault(_Button2);
var _icons = __webpack_require__(86);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
/**
* Next button
*/
var NextButton = function (_Button) {
_inherits(NextButton, _Button);
function NextButton() {
_classCallCheck(this, NextButton);
return _possibleConstructorReturn(this, (NextButton.__proto__ || Object.getPrototypeOf(NextButton)).apply(this, arguments));
}
return NextButton;
}(_Button3.default);
NextButton.defaultProps = _extends({}, _Button3.default.defaultProps, {
className: 'NextButton',
children: _react2.default.createElement(_icons.NextIcon, null),
isEnabled: false
});
exports.default = NextButton;
/***/ }),
/* 197 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ControlDirection = undefined;
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _desc, _value, _class;
var _react = __webpack_require__(11);
var _react2 = _interopRequireDefault(_react);
var _propTypes = __webpack_require__(25);
var _propTypes2 = _interopRequireDefault(_propTypes);
var _autobindDecorator = __webpack_require__(89);
var _autobindDecorator2 = _interopRequireDefault(_autobindDecorator);
var _classnames = __webpack_require__(84);
var _classnames2 = _interopRequireDefault(_classnames);
var _composers = __webpack_require__(88);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
var desc = {};
Object['ke' + 'ys'](descriptor).forEach(function (key) {
desc[key] = descriptor[key];
});
desc.enumerable = !!desc.enumerable;
desc.configurable = !!desc.configurable;
if ('value' in desc || desc.initializer) {
desc.writable = true;
}
desc = decorators.slice().reverse().reduce(function (desc, decorator) {
return decorator(target, property, desc) || desc;
}, desc);
if (context && desc.initializer !== void 0) {
desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
desc.initializer = undefined;
}
if (desc.initializer === void 0) {
Object['define' + 'Property'](target, property, desc);
desc = null;
}
return desc;
}
var oneOfType = _propTypes2.default.oneOfType,
shape = _propTypes2.default.shape,
func = _propTypes2.default.func,
number = _propTypes2.default.number,
oneOf = _propTypes2.default.oneOf,
object = _propTypes2.default.object;
// Range control directions
var ControlDirection = exports.ControlDirection = {
HORIZONTAL: 'HORIZONTAL',
VERTICAL: 'VERTICAL'
/**
* An invisible overlay that acts as a range mouse control
* within a specified bounds.
*/
};var RangeControlOverlay = (_class = function (_Component) {
_inherits(RangeControlOverlay, _Component);
function RangeControlOverlay(props) {
_classCallCheck(this, RangeControlOverlay);
var _this = _possibleConstructorReturn(this, (RangeControlOverlay.__proto__ || Object.getPrototypeOf(RangeControlOverlay)).call(this, props));
_this.state = {
isDragging: false
};
return _this;
}
_createClass(RangeControlOverlay, [{
key: 'componentWillUnmount',
value: function componentWillUnmount() {
this.endDrag();
}
}, {
key: 'startDrag',
value: function startDrag(evt) {
this.setState({ isDragging: true });
window.addEventListener('mousemove', this.triggerRangeChange);
window.addEventListener('mouseup', this.endDrag);
this.toggleSelection('none');
var startValue = evt ? this.getValueFromMouseEvent(evt) : null;
this.props.onChangeStart(startValue);
}
}, {
key: 'endDrag',
value: function endDrag(evt) {
if (evt) {
this.triggerRangeChange(evt);
}
this.setState({ isDragging: false });
window.removeEventListener('mousemove', this.triggerRangeChange);
window.removeEventListener('mouseup', this.endDrag);
this.toggleSelection('');
var endValue = evt ? this.getValueFromMouseEvent(evt) : null;
this.props.onChangeEnd(endValue);
}
}, {
key: 'toggleSelection',
value: function toggleSelection(value) {
var body = document.getElementsByTagName('body')[0];
body.style['user-select'] = value;
body.style['-webkit-user-select'] = value;
body.style['-moz-user-select'] = value;
body.style['-ms-user-select'] = value;
}
}, {
key: 'getValueFromMouseEvent',
value: function getValueFromMouseEvent(mouseEvent) {
return this.props.direction === ControlDirection.VERTICAL ? this.getVerticalValue(mouseEvent.pageY) : this.getHorizontalValue(mouseEvent.pageX);
}
}, {
key: 'triggerRangeChange',
value: function triggerRangeChange(mouseEvent) {
this.props.onValue(this.getValueFromMouseEvent(mouseEvent));
}
}, {
key: 'handleIntentMove',
value: function handleIntentMove(evt) {
if (!this.state.isDragging) {
this.triggerIntent(evt);
}
}
}, {
key: 'triggerIntent',
value: function triggerIntent(mouseEvent) {
var _props = this.props,
direction = _props.direction,
onIntent = _props.onIntent;
var value = direction === ControlDirection.VERTICAL ? this.getVerticalValue(mouseEvent.pageY) : this.getHorizontalValue(mouseEvent.pageX);
onIntent(value);
}
}, {
key: 'getRectFromBounds',
value: function getRectFromBounds() {
var bounds = this.props.bounds;
return typeof bounds === 'function' ? bounds() : bounds;
}
}, {
key: 'getHorizontalValue',
value: function getHorizontalValue(mouseX) {
var rect = this.getRectFromBounds();
var scrollX = window.pageXOffset !== undefined ? window.pageXOffset : (document.documentElement || document.body.parentNode || document.body).scrollLeft;
var dLeft = mouseX - (rect.left + scrollX);
dLeft = Math.max(dLeft, 0);
dLeft = Math.min(dLeft, rect.width);
return dLeft / rect.width;
}
}, {
key: 'getVerticalValue',
value: function getVerticalValue(mouseY) {
var rect = this.getRectFromBounds();
var scrollY = window.pageYOffset !== undefined ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
var dTop = mouseY - (rect.top + scrollY);
dTop = Math.max(dTop, 0);
dTop = Math.min(dTop, rect.height);
return 1 - dTop / rect.height;
}
}, {
key: 'render',
value: function render() {
var _props2 = this.props,
className = _props2.className,
extraClasses = _props2.extraClasses,
style = _props2.style;
var isDragging = this.state.isDragging;
return _react2.default.createElement('div', {
className: (0, _classnames2.default)(className, extraClasses, { isDragging: isDragging }),
style: style,
onMouseDown: this.startDrag,
onMouseMove: this.handleIntentMove
});
}
}]);
return RangeControlOverlay;
}(_react.Component), (_applyDecoratedDescriptor(_class.prototype, 'startDrag', [_autobindDecorator2.default], Object.getOwnPropertyDescriptor(_class.prototype, 'startDrag'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'endDrag', [_autobindDecorator2.default], Object.getOwnPropertyDescriptor(_class.prototype, 'endDrag'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'triggerRangeChange', [_autobindDecorator2.default], Object.getOwnPropertyDescriptor(_class.prototype, 'triggerRangeChange'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'handleIntentMove', [_autobindDecorator2.default], Object.getOwnPropertyDescriptor(_class.prototype, 'handleIntentMove'), _class.prototype)), _class);
RangeControlOverlay.propTypes = {
bounds: oneOfType([func, shape({
width: number.isRequired,
left: number.isRequired
}), shape({
height: number.isRequired,
top: number.isRequired
})]).isRequired,
onValue: func.isRequired,
onChangeStart: func,
onChangeEnd: func,
onIntent: func,
direction: oneOf([ControlDirection.HORIZONTAL, ControlDirection.VERTICAL]),
style: object
};
RangeControlOverlay.defaultProps = {
onChangeStart: function onChangeStart() {},
onChangeEnd: function onChangeEnd() {},
onIntent: function onIntent() {},
direction: ControlDirection.HORIZONTAL,
style: {}
};
exports.default = (0, _composers.withCustomizableClasses)('RangeControlOverlay')(RangeControlOverlay);
/***/ }),
/* 198 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(11);
var _react2 = _interopRequireDefault(_react);
var _propTypes = __webpack_require__(25);
var _propTypes2 = _interopRequireDefault(_propTypes);
var _classnames = __webpack_require__(84);
var _classnames2 = _interopRequireDefault(_classnames);
var _composers = __webpack_require__(88);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var number = _propTypes2.default.number,
object = _propTypes2.default.object;
var padZero = function padZero(digit) {
return '' + (digit < 10 ? '0' : '') + digit;
};
/**
* Time formatter that turns seconds into h:mm:ss
*/
var FormattedTime = function (_Component) {
_inherits(FormattedTime, _Component);
function FormattedTime() {
_classCallCheck(this, FormattedTime);
return _possibleConstructorReturn(this, (FormattedTime.__proto__ || Object.getPrototypeOf(FormattedTime)).apply(this, arguments));
}
_createClass(FormattedTime, [{
key: 'getFormattedTime',
value: function getFormattedTime() {
var numSeconds = this.props.numSeconds;
var prefix = numSeconds < 0 ? '-' : '';
var absNumSeconds = Math.abs(numSeconds);
var hours = Math.floor(absNumSeconds / 3600);
var minutes = Math.floor(absNumSeconds % 3600 / 60);
var seconds = Math.floor(absNumSeconds) % 60;
return hours > 0 ? '' + prefix + hours + ':' + padZero(minutes) + ':' + padZero(seconds) : '' + prefix + minutes + ':' + padZero(seconds);
}
}, {
key: 'render',
value: function render() {
var _props = this.props,
style = _props.style,
className = _props.className,
extraClasses = _props.extraClasses;
return _react2.default.createElement(
'span',
{ className: (0, _classnames2.default)(className, extraClasses), style: style },
this.getFormattedTime()
);
}
}]);
return FormattedTime;
}(_react.Component);
FormattedTime.propTypes = {
numSeconds: number,
style: object
};
FormattedTime.defaultProps = {
numSeconds: 0,
style: {}
};
exports.default = (0, _composers.withCustomizableClasses)('FormattedTime', FormattedTime);
/***/ }),
/* 199 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _react = __webpack_require__(11);
var _react2 = _interopRequireDefault(_react);
var _Button2 = __webpack_require__(87);
var _Button3 = _interopRequireDefault(_Button2);
var _icons = __webpack_require__(86);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
/**
* Sound on button
*/
var SoundOnButton = function (_Button) {
_inherits(SoundOnButton, _Button);
function SoundOnButton() {
_classCallCheck(this, SoundOnButton);
return _possibleConstructorReturn(this, (SoundOnButton.__proto__ || Object.getPrototypeOf(SoundOnButton)).apply(this, arguments));
}
return SoundOnButton;
}(_Button3.default);
SoundOnButton.defaultProps = _extends({}, _Button3.default.defaultProps, {
className: 'SoundOnButton',
children: _react2.default.createElement(_icons.SoundOnIcon, null)
});
exports.default = SoundOnButton;
/***/ }),
/* 200 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _react = __webpack_require__(11);
var _react2 = _interopRequireDefault(_react);
var _Button2 = __webpack_require__(87);
var _Button3 = _interopRequireDefault(_Button2);
var _icons = __webpack_require__(86);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
/**
* Sound off button
*/
var SoundOffButton = function (_Button) {
_inherits(SoundOffButton, _Button);
function SoundOffButton() {
_classCallCheck(this, SoundOffButton);
return _possibleConstructorReturn(this, (SoundOffButton.__proto__ || Object.getPrototypeOf(SoundOffButton)).apply(this, arguments));
}
return SoundOffButton;
}(_Button3.default);
SoundOffButton.defaultProps = _extends({}, _Button3.default.defaultProps, {
className: 'SoundOffButton',
children: _react2.default.createElement(_icons.SoundOffIcon, null)
});
exports.default = SoundOffButton;
/***/ }),
/* 201 */
/***/ (function(module, exports, __webpack_require__) {
!function(r,c){ true?module.exports=c(__webpack_require__(11)):"function"==typeof define&&define.amd?define(["react"],c):"object"==typeof exports?exports["react-simple-flex-grid"]=c(require("react")):r["react-simple-flex-grid"]=c(r.React)}(this,function(r){return function(r){function c(t){if(o[t])return o[t].exports;var d=o[t]={i:t,l:!1,exports:{}};return r[t].call(d.exports,d,d.exports,c),d.l=!0,d.exports}var o={};return c.m=r,c.c=o,c.i=function(r){return r},c.d=function(r,o,t){c.o(r,o)||Object.defineProperty(r,o,{configurable:!1,enumerable:!0,get:t})},c.n=function(r){var o=r&&r.__esModule?function(){return r.default}:function(){return r};return c.d(o,"a",o),o},c.o=function(r,c){return Object.prototype.hasOwnProperty.call(r,c)},c.p="",c(c.s=11)}([function(r,c,o){"use strict";function t(r){return r&&r.__esModule?r:{default:r}}Object.defineProperty(c,"__esModule",{value:!0}),c.Row=c.Col=void 0;var d=o(5),l=t(d),e=o(6),i=t(e);c.Col=l.default,c.Row=i.default},function(r,c,o){var t,d;!function(){"use strict";function o(){for(var r=[],c=0;c<arguments.length;c++){var t=arguments[c];if(t){var d=typeof t;if("string"===d||"number"===d)r.push(t);else if(Array.isArray(t))r.push(o.apply(null,t));else if("object"===d)for(var e in t)l.call(t,e)&&t[e]&&r.push(e)}}return r.join(" ")}var l={}.hasOwnProperty;void 0!==r&&r.exports?r.exports=o:(t=[],void 0!==(d=function(){return o}.apply(c,t))&&(r.exports=d))}()},function(r,c){r.exports={"rct-grid-row":"rct-grid-row","rct-grid-row-start":"rct-grid-row-start","rct-grid-row-center":"rct-grid-row-center","rct-grid-row-end":"rct-grid-row-end","rct-grid-row-space-between":"rct-grid-row-space-between","rct-grid-row-space-around":"rct-grid-row-space-around","rct-grid-row-top":"rct-grid-row-top","rct-grid-row-middle":"rct-grid-row-middle","rct-grid-row-bottom":"rct-grid-row-bottom","rct-grid-col-1":"rct-grid-col-1","rct-grid-col-xs-1":"rct-grid-col-xs-1","rct-grid-col-sm-1":"rct-grid-col-sm-1","rct-grid-col-md-1":"rct-grid-col-md-1","rct-grid-col-lg-1":"rct-grid-col-lg-1","rct-grid-col-2":"rct-grid-col-2","rct-grid-col-xs-2":"rct-grid-col-xs-2","rct-grid-col-sm-2":"rct-grid-col-sm-2","rct-grid-col-md-2":"rct-grid-col-md-2","rct-grid-col-lg-2":"rct-grid-col-lg-2","rct-grid-col-3":"rct-grid-col-3","rct-grid-col-xs-3":"rct-grid-col-xs-3","rct-grid-col-sm-3":"rct-grid-col-sm-3","rct-grid-col-md-3":"rct-grid-col-md-3","rct-grid-col-lg-3":"rct-grid-col-lg-3","rct-grid-col-4":"rct-grid-col-4","rct-grid-col-xs-4":"rct-grid-col-xs-4","rct-grid-col-sm-4":"rct-grid-col-sm-4","rct-grid-col-md-4":"rct-grid-col-md-4","rct-grid-col-lg-4":"rct-grid-col-lg-4","rct-grid-col-5":"rct-grid-col-5","rct-grid-col-xs-5":"rct-grid-col-xs-5","rct-grid-col-sm-5":"rct-grid-col-sm-5","rct-grid-col-md-5":"rct-grid-col-md-5","rct-grid-col-lg-5":"rct-grid-col-lg-5","rct-grid-col-6":"rct-grid-col-6","rct-grid-col-xs-6":"rct-grid-col-xs-6","rct-grid-col-sm-6":"rct-grid-col-sm-6","rct-grid-col-md-6":"rct-grid-col-md-6","rct-grid-col-lg-6":"rct-grid-col-lg-6","rct-grid-col-7":"rct-grid-col-7","rct-grid-col-xs-7":"rct-grid-col-xs-7","rct-grid-col-sm-7":"rct-grid-col-sm-7","rct-grid-col-md-7":"rct-grid-col-md-7","rct-grid-col-lg-7":"rct-grid-col-lg-7","rct-grid-col-8":"rct-grid-col-8","rct-grid-col-xs-8":"rct-grid-col-xs-8","rct-grid-col-sm-8":"rct-grid-col-sm-8","rct-grid-col-md-8":"rct-grid-col-md-8","rct-grid-col-lg-8":"rct-grid-col-lg-8","rct-grid-col-9":"rct-grid-col-9","rct-grid-col-xs-9":"rct-grid-col-xs-9","rct-grid-col-sm-9":"rct-grid-col-sm-9","rct-grid-col-md-9":"rct-grid-col-md-9","rct-grid-col-lg-9":"rct-grid-col-lg-9","rct-grid-col-10":"rct-grid-col-10","rct-grid-col-xs-10":"rct-grid-col-xs-10","rct-grid-col-sm-10":"rct-grid-col-sm-10","rct-grid-col-md-10":"rct-grid-col-md-10","rct-grid-col-lg-10":"rct-grid-col-lg-10","rct-grid-col-11":"rct-grid-col-11","rct-grid-col-xs-11":"rct-grid-col-xs-11","rct-grid-col-sm-11":"rct-grid-col-sm-11","rct-grid-col-md-11":"rct-grid-col-md-11","rct-grid-col-lg-11":"rct-grid-col-lg-11","rct-grid-col-12":"rct-grid-col-12","rct-grid-col-xs-12":"rct-grid-col-xs-12","rct-grid-col-sm-12":"rct-grid-col-sm-12","rct-grid-col-md-12":"rct-grid-col-md-12","rct-grid-col-lg-12":"rct-grid-col-lg-12","rct-grid-col-offset-1":"rct-grid-col-offset-1","rct-grid-col-order-1":"rct-grid-col-order-1","rct-grid-col-offset-2":"rct-grid-col-offset-2","rct-grid-col-order-2":"rct-grid-col-order-2","rct-grid-col-offset-3":"rct-grid-col-offset-3","rct-grid-col-order-3":"rct-grid-col-order-3","rct-grid-col-offset-4":"rct-grid-col-offset-4","rct-grid-col-order-4":"rct-grid-col-order-4","rct-grid-col-offset-5":"rct-grid-col-offset-5","rct-grid-col-order-5":"rct-grid-col-order-5","rct-grid-col-offset-6":"rct-grid-col-offset-6","rct-grid-col-order-6":"rct-grid-col-order-6","rct-grid-col-offset-7":"rct-grid-col-offset-7","rct-grid-col-order-7":"rct-grid-col-order-7","rct-grid-col-offset-8":"rct-grid-col-offset-8","rct-grid-col-order-8":"rct-grid-col-order-8","rct-grid-col-offset-9":"rct-grid-col-offset-9","rct-grid-col-order-9":"rct-grid-col-order-9","rct-grid-col-offset-10":"rct-grid-col-offset-10","rct-grid-col-order-10":"rct-grid-col-order-10","rct-grid-col-offset-11":"rct-grid-col-offset-11","rct-grid-col-order-11":"rct-grid-col-order-11","rct-grid-col-offset-12":"rct-grid-col-offset-12","rct-grid-col-order-12":"rct-grid-col-order-12","rct-grid-col-xs-offset-1":"rct-grid-col-xs-offset-1","rct-grid-col-xs-order-1":"rct-grid-col-xs-order-1","rct-grid-col-xs-offset-2":"rct-grid-col-xs-offset-2","rct-grid-col-xs-order-2":"rct-grid-col-xs-order-2","rct-grid-col-xs-offset-3":"rct-grid-col-xs-offset-3","rct-grid-col-xs-order-3":"rct-grid-col-xs-order-3","rct-grid-col-xs-offset-4":"rct-grid-col-xs-offset-4","rct-grid-col-xs-order-4":"rct-grid-col-xs-order-4","rct-grid-col-xs-offset-5":"rct-grid-col-xs-offset-5","rct-grid-col-xs-order-5":"rct-grid-col-xs-order-5","rct-grid-col-xs-offset-6":"rct-grid-col-xs-offset-6","rct-grid-col-xs-order-6":"rct-grid-col-xs-order-6","rct-grid-col-xs-offset-7":"rct-grid-col-xs-offset-7","rct-grid-col-xs-order-7":"rct-grid-col-xs-order-7","rct-grid-col-xs-offset-8":"rct-grid-col-xs-offset-8","rct-grid-col-xs-order-8":"rct-grid-col-xs-order-8","rct-grid-col-xs-offset-9":"rct-grid-col-xs-offset-9","rct-grid-col-xs-order-9":"rct-grid-col-xs-order-9","rct-grid-col-xs-offset-10":"rct-grid-col-xs-offset-10","rct-grid-col-xs-order-10":"rct-grid-col-xs-order-10","rct-grid-col-xs-offset-11":"rct-grid-col-xs-offset-11","rct-grid-col-xs-order-11":"rct-grid-col-xs-order-11","rct-grid-col-xs-offset-12":"rct-grid-col-xs-offset-12","rct-grid-col-xs-order-12":"rct-grid-col-xs-order-12","rct-grid-col-sm-offset-1":"rct-grid-col-sm-offset-1","rct-grid-col-sm-order-1":"rct-grid-col-sm-order-1","rct-grid-col-sm-offset-2":"rct-grid-col-sm-offset-2","rct-grid-col-sm-order-2":"rct-grid-col-sm-order-2","rct-grid-col-sm-offset-3":"rct-grid-col-sm-offset-3","rct-grid-col-sm-order-3":"rct-grid-col-sm-order-3","rct-grid-col-sm-offset-4":"rct-grid-col-sm-offset-4","rct-grid-col-sm-order-4":"rct-grid-col-sm-order-4","rct-grid-col-sm-offset-5":"rct-grid-col-sm-offset-5","rct-grid-col-sm-order-5":"rct-grid-col-sm-order-5","rct-grid-col-sm-offset-6":"rct-grid-col-sm-offset-6","rct-grid-col-sm-order-6":"rct-grid-col-sm-order-6","rct-grid-col-sm-offset-7":"rct-grid-col-sm-offset-7","rct-grid-col-sm-order-7":"rct-grid-col-sm-order-7","rct-grid-col-sm-offset-8":"rct-grid-col-sm-offset-8","rct-grid-col-sm-order-8":"rct-grid-col-sm-order-8","rct-grid-col-sm-offset-9":"rct-grid-col-sm-offset-9","rct-grid-col-sm-order-9":"rct-grid-col-sm-order-9","rct-grid-col-sm-offset-10":"rct-grid-col-sm-offset-10","rct-grid-col-sm-order-10":"rct-grid-col-sm-order-10","rct-grid-col-sm-offset-11":"rct-grid-col-sm-offset-11","rct-grid-col-sm-order-11":"rct-grid-col-sm-order-11","rct-grid-col-sm-offset-12":"rct-grid-col-sm-offset-12","rct-grid-col-sm-order-12":"rct-grid-col-sm-order-12","rct-grid-col-md-offset-1":"rct-grid-col-md-offset-1","rct-grid-col-md-order-1":"rct-grid-col-md-order-1","rct-grid-col-md-offset-2":"rct-grid-col-md-offset-2","rct-grid-col-md-order-2":"rct-grid-col-md-order-2","rct-grid-col-md-offset-3":"rct-grid-col-md-offset-3","rct-grid-col-md-order-3":"rct-grid-col-md-order-3","rct-grid-col-md-offset-4":"rct-grid-col-md-offset-4","rct-grid-col-md-order-4":"rct-grid-col-md-order-4","rct-grid-col-md-offset-5":"rct-grid-col-md-offset-5","rct-grid-col-md-order-5":"rct-grid-col-md-order-5","rct-grid-col-md-offset-6":"rct-grid-col-md-offset-6","rct-grid-col-md-order-6":"rct-grid-col-md-order-6","rct-grid-col-md-offset-7":"rct-grid-col-md-offset-7","rct-grid-col-md-order-7":"rct-grid-col-md-order-7","rct-grid-col-md-offset-8":"rct-grid-col-md-offset-8","rct-grid-col-md-order-8":"rct-grid-col-md-order-8","rct-grid-col-md-offset-9":"rct-grid-col-md-offset-9","rct-grid-col-md-order-9":"rct-grid-col-md-order-9","rct-grid-col-md-offset-10":"rct-grid-col-md-offset-10","rct-grid-col-md-order-10":"rct-grid-col-md-order-10","rct-grid-col-md-offset-11":"rct-grid-col-md-offset-11","rct-grid-col-md-order-11":"rct-grid-col-md-order-11","rct-grid-col-md-offset-12":"rct-grid-col-md-offset-12","rct-grid-col-md-order-12":"rct-grid-col-md-order-12","rct-grid-col-lg-offset-1":"rct-grid-col-lg-offset-1","rct-grid-col-lg-order-1":"rct-grid-col-lg-order-1","rct-grid-col-lg-offset-2":"rct-grid-col-lg-offset-2","rct-grid-col-lg-order-2":"rct-grid-col-lg-order-2","rct-grid-col-lg-offset-3":"rct-grid-col-lg-offset-3","rct-grid-col-lg-order-3":"rct-grid-col-lg-order-3","rct-grid-col-lg-offset-4":"rct-grid-col-lg-offset-4","rct-grid-col-lg-order-4":"rct-grid-col-lg-order-4","rct-grid-col-lg-offset-5":"rct-grid-col-lg-offset-5","rct-grid-col-lg-order-5":"rct-grid-col-lg-order-5","rct-grid-col-lg-offset-6":"rct-grid-col-lg-offset-6","rct-grid-col-lg-order-6":"rct-grid-col-lg-order-6","rct-grid-col-lg-offset-7":"rct-grid-col-lg-offset-7","rct-grid-col-lg-order-7":"rct-grid-col-lg-order-7","rct-grid-col-lg-offset-8":"rct-grid-col-lg-offset-8","rct-grid-col-lg-order-8":"rct-grid-col-lg-order-8","rct-grid-col-lg-offset-9":"rct-grid-col-lg-offset-9","rct-grid-col-lg-order-9":"rct-grid-col-lg-order-9","rct-grid-col-lg-offset-10":"rct-grid-col-lg-offset-10","rct-grid-col-lg-order-10":"rct-grid-col-lg-order-10","rct-grid-col-lg-offset-11":"rct-grid-col-lg-offset-11","rct-grid-col-lg-order-11":"rct-grid-col-lg-order-11","rct-grid-col-lg-offset-12":"rct-grid-col-lg-offset-12","rct-grid-col-lg-order-12":"rct-grid-col-lg-order-12","rct-grid-col-xl-1":"rct-grid-col-xl-1","rct-grid-col-xl-2":"rct-grid-col-xl-2","rct-grid-col-xl-3":"rct-grid-col-xl-3","rct-grid-col-xl-4":"rct-grid-col-xl-4","rct-grid-col-xl-5":"rct-grid-col-xl-5","rct-grid-col-xl-6":"rct-grid-col-xl-6","rct-grid-col-xl-7":"rct-grid-col-xl-7","rct-grid-col-xl-8":"rct-grid-col-xl-8","rct-grid-col-xl-9":"rct-grid-col-xl-9","rct-grid-col-xl-10":"rct-grid-col-xl-10","rct-grid-col-xl-11":"rct-grid-col-xl-11","rct-grid-col-xl-12":"rct-grid-col-xl-12","rct-grid-col-xl-offset-1":"rct-grid-col-xl-offset-1","rct-grid-col-xl-order-1":"rct-grid-col-xl-order-1","rct-grid-col-xl-offset-2":"rct-grid-col-xl-offset-2","rct-grid-col-xl-order-2":"rct-grid-col-xl-order-2","rct-grid-col-xl-offset-3":"rct-grid-col-xl-offset-3","rct-grid-col-xl-order-3":"rct-grid-col-xl-order-3","rct-grid-col-xl-offset-4":"rct-grid-col-xl-offset-4","rct-grid-col-xl-order-4":"rct-grid-col-xl-order-4","rct-grid-col-xl-offset-5":"rct-grid-col-xl-offset-5","rct-grid-col-xl-order-5":"rct-grid-col-xl-order-5","rct-grid-col-xl-offset-6":"rct-grid-col-xl-offset-6","rct-grid-col-xl-order-6":"rct-grid-col-xl-order-6","rct-grid-col-xl-offset-7":"rct-grid-col-xl-offset-7","rct-grid-col-xl-order-7":"rct-grid-col-xl-order-7","rct-grid-col-xl-offset-8":"rct-grid-col-xl-offset-8","rct-grid-col-xl-order-8":"rct-grid-col-xl-order-8","rct-grid-col-xl-offset-9":"rct-grid-col-xl-offset-9","rct-grid-col-xl-order-9":"rct-grid-col-xl-order-9","rct-grid-col-xl-offset-10":"rct-grid-col-xl-offset-10","rct-grid-col-xl-order-10":"rct-grid-col-xl-order-10","rct-grid-col-xl-offset-11":"rct-grid-col-xl-offset-11","rct-grid-col-xl-order-11":"rct-grid-col-xl-order-11","rct-grid-col-xl-offset-12":"rct-grid-col-xl-offset-12","rct-grid-col-xl-order-12":"rct-grid-col-xl-order-12"}},function(r,c,o){r.exports=o(7)()},function(c,o){c.exports=r},function(r,c,o){"use strict";function t(r){return r&&r.__esModule?r:{default:r}}function d(r,c,o){return c in r?Object.defineProperty(r,c,{value:o,enumerable:!0,configurable:!0,writable:!0}):r[c]=o,r}function l(r,c){var o={};for(var t in r)c.indexOf(t)>=0||Object.prototype.hasOwnProperty.call(r,t)&&(o[t]=r[t]);return o}function e(r){var c,o=r.span,t=r.offset,e=r.className,f=r.children,n=r.prefix,u=void 0===n?"rct-grid-col":n,a=r.order,x=l(r,["span","offset","className","children","prefix","order"]),y={};["xs","sm","md","lg","xl"].forEach(function(r){if(x[r]){var c,o={};"number"==typeof x[r]?o.span=x[r]:"object"===g(x[r])&&(o=x[r]||{}),delete x[r],y=Object.assign({},y,(c={},d(c,p.default[u+"-"+r+"-"+o.span],o.span),d(c,p.default[u+"-"+r+"-offset-"+o.offset],o.offset||0===o.offset),d(c,p.default[u+"-"+r+"-order-"+o.order],o.order||0===o.order),c))}});var b=(0,m.default)((c={},d(c,p.default[u+"-"+o],void 0!==o),d(c,p.default[u+"-offset-"+t],t),d(c,p.default[u+"-order-"+a],a),c),e,y);return s.default.createElement("div",i({},x,{className:b}),f)}Object.defineProperty(c,"__esModule",{value:!0});var i=Object.assign||function(r){for(var c=1;c<arguments.length;c++){var o=arguments[c];for(var t in o)Object.prototype.hasOwnProperty.call(o,t)&&(r[t]=o[t])}return r},g="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(r){return typeof r}:function(r){return r&&"function"==typeof Symbol&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},f=o(4),s=t(f),n=o(3),u=t(n),a=o(1),m=t(a),x=o(2),p=t(x);u.default.oneOfType([u.default.string,u.default.number]),u.default.oneOfType([u.default.number,u.default.object]);e.defaultProps={offset:0},c.default=e},function(r,c,o){"use strict";function t(r){return r&&r.__esModule?r:{default:r}}function d(r,c,o){return c in r?Object.defineProperty(r,c,{value:o,enumerable:!0,configurable:!0,writable:!0}):r[c]=o,r}function l(r,c){var o={};for(var t in r)c.indexOf(t)>=0||Object.prototype.hasOwnProperty.call(r,t)&&(o[t]=r[t]);return o}function e(r,c){if(!(r instanceof c))throw new TypeError("Cannot call a class as a function")}function i(r,c){if(!r)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!c||"object"!=typeof c&&"function"!=typeof c?r:c}function g(r,c){if("function"!=typeof c&&null!==c)throw new TypeError("Super expression must either be null or a function, not "+typeof c);r.prototype=Object.create(c&&c.prototype,{constructor:{value:r,enumerable:!1,writable:!0,configurable:!0}}),c&&(Object.setPrototypeOf?Object.setPrototypeOf(r,c):r.__proto__=c)}Object.defineProperty(c,"__esModule",{value:!0});var f=Object.assign||function(r){for(var c=1;c<arguments.length;c++){var o=arguments[c];for(var t in o)Object.prototype.hasOwnProperty.call(o,t)&&(r[t]=o[t])}return r},s=function(){function r(r,c){for(var o=0;o<c.length;o++){var t=c[o];t.enumerable=t.enumerable||!1,t.configurable=!0,"value"in t&&(t.writable=!0),Object.defineProperty(r,t.key,t)}}return function(c,o,t){return o&&r(c.prototype,o),t&&r(c,t),c}}(),n=o(4),u=t(n),a=o(3),m=(t(a),o(1)),x=t(m),p=o(2),y=t(p),b=function(r){function c(){return e(this,c),i(this,(c.__proto__||Object.getPrototypeOf(c)).apply(this,arguments))}return g(c,r),s(c,[{key:"render",value:function(){var r,c=this.props,o=c.justify,t=c.align,e=c.className,i=c.gutter,g=c.style,s=c.children,n=c.prefix,a=void 0===n?"rct-grid-row":n,m=l(c,["justify","align","className","gutter","style","children","prefix"]),p=(0,x.default)(y.default[""+a],(r={},d(r,y.default[a+"-"+o],o),d(r,y.default[a+"-"+t],t),r),e),b=i>0?Object.assign({},{marginLeft:i/-2,marginRight:i/-2},g):g,v=u.default.Children.map(s,function(r){return r?r.props&&i>0?u.default.cloneElement(r,{style:Object.assign({},{paddingLeft:i/2,paddingRight:i/2},r.props.style)}):r:null});return u.default.createElement("div",f({},m,{className:p,style:b}),v)}}]),c}(u.default.Component);b.defaultProps={gutter:0,justify:"start",align:"top"},c.default=b},function(r,c,o){"use strict";var t=o(9),d=o(10),l=o(8);r.exports=function(){function r(r,c,o,t,e,i){i!==l&&d(!1,"Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types")}function c(){return r}r.isRequired=r;var o={array:r,bool:r,func:r,number:r,object:r,string:r,symbol:r,any:r,arrayOf:c,element:r,instanceOf:c,node:r,objectOf:c,oneOf:c,oneOfType:c,shape:c,exact:c};return o.checkPropTypes=t,o.PropTypes=o,o}},function(r,c,o){"use strict";r.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},function(r,c,o){"use strict";function t(r){return function(){return r}}var d=function(){};d.thatReturns=t,d.thatReturnsFalse=t(!1),d.thatReturnsTrue=t(!0),d.thatReturnsNull=t(null),d.thatReturnsThis=function(){return this},d.thatReturnsArgument=function(r){return r},r.exports=d},function(r,c,o){"use strict";function t(r,c,o,t,l,e,i,g){if(d(c),!r){var f;if(void 0===c)f=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var s=[o,t,l,e,i,g],n=0;f=new Error(c.replace(/%s/g,function(){return s[n++]})),f.name="Invariant Violation"}throw f.framesToPop=1,f}}var d=function(r){};r.exports=t},function(r,c,o){o(0),r.exports=o(0)}])});
/***/ }),
/* 202 */
/***/ (function(module, exports) {
// removed by extract-text-webpack-plugin
/***/ }),
/* 203 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
module.exports = function bind(fn, thisArg) {
return function wrap() {
var args = new Array(arguments.length);
for (var i = 0; i < args.length; i++) {
args[i] = arguments[i];
}
return fn.apply(thisArg, args);
};
};
/***/ }),
/* 204 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var utils = __webpack_require__(34);
var settle = __webpack_require__(268);
var buildURL = __webpack_require__(270);
var parseHeaders = __webpack_require__(271);
var isURLSameOrigin = __webpack_require__(272);
var createError = __webpack_require__(205);
var btoa = (typeof window !== 'undefined' && window.btoa && window.btoa.bind(window)) || __webpack_require__(273);
module.exports = function xhrAdapter(config) {
return new Promise(function dispatchXhrRequest(resolve, reject) {
var requestData = config.data;
var requestHeaders = config.headers;
if (utils.isFormData(requestData)) {
delete requestHeaders['Content-Type']; // Let the browser set it
}
var request = new XMLHttpRequest();
var loadEvent = 'onreadystatechange';
var xDomain = false;
// For IE 8/9 CORS support
// Only supports POST and GET calls and doesn't returns the response headers.
// DON'T do this for testing b/c XMLHttpRequest is mocked, not XDomainRequest.
if (false) {
request = new window.XDomainRequest();
loadEvent = 'onload';
xDomain = true;
request.onprogress = function handleProgress() {};
request.ontimeout = function handleTimeout() {};
}
// HTTP basic authentication
if (config.auth) {
var username = config.auth.username || '';
var password = config.auth.password || '';
requestHeaders.Authorization = 'Basic ' + btoa(username + ':' + password);
}
request.open(config.method.toUpperCase(), buildURL(config.url, config.params, config.paramsSerializer), true);
// Set the request timeout in MS
request.timeout = config.timeout;
// Listen for ready state
request[loadEvent] = function handleLoad() {
if (!request || (request.readyState !== 4 && !xDomain)) {
return;
}
// The request errored out and we didn't get a response, this will be
// handled by onerror instead
// With one exception: request that using file: protocol, most browsers
// will return status as 0 even though it's a successful request
if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {
return;
}
// Prepare the response
var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(request.getAllResponseHeaders()) : null;
var responseData = !config.responseType || config.responseType === 'text' ? request.responseText : request.response;
var response = {
data: responseData,
// IE sends 1223 instead of 204 (https://github.com/axios/axios/issues/201)
status: request.status === 1223 ? 204 : request.status,
statusText: request.status === 1223 ? 'No Content' : request.statusText,
headers: responseHeaders,
config: config,
request: request
};
settle(resolve, reject, response);
// Clean up request
request = null;
};
// Handle low level network errors
request.onerror = function handleError() {
// Real errors are hidden from us by the browser
// onerror should only fire if it's a network error
reject(createError('Network Error', config, null, request));
// Clean up request
request = null;
};
// Handle timeout
request.ontimeout = function handleTimeout() {
reject(createError('timeout of ' + config.timeout + 'ms exceeded', config, 'ECONNABORTED',
request));
// Clean up request
request = null;
};
// Add xsrf header
// This is only done if running in a standard browser environment.
// Specifically not if we're in a web worker, or react-native.
if (utils.isStandardBrowserEnv()) {
var cookies = __webpack_require__(274);
// Add xsrf header
var xsrfValue = (config.withCredentials || isURLSameOrigin(config.url)) && config.xsrfCookieName ?
cookies.read(config.xsrfCookieName) :
undefined;
if (xsrfValue) {
requestHeaders[config.xsrfHeaderName] = xsrfValue;
}
}
// Add headers to the request
if ('setRequestHeader' in request) {
utils.forEach(requestHeaders, function setRequestHeader(val, key) {
if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') {
// Remove Content-Type if data is undefined
delete requestHeaders[key];
} else {
// Otherwise add header to the request
request.setRequestHeader(key, val);
}
});
}
// Add withCredentials to request if needed
if (config.withCredentials) {
request.withCredentials = true;
}
// Add responseType to request if needed
if (config.responseType) {
try {
request.responseType = config.responseType;
} catch (e) {
// Expected DOMException thrown by browsers not compatible XMLHttpRequest Level 2.
// But, this can be suppressed for 'json' type as it can be parsed by default 'transformResponse' function.
if (config.responseType !== 'json') {
throw e;
}
}
}
// Handle progress if needed
if (typeof config.onDownloadProgress === 'function') {
request.addEventListener('progress', config.onDownloadProgress);
}
// Not all browsers support upload events
if (typeof config.onUploadProgress === 'function' && request.upload) {
request.upload.addEventListener('progress', config.onUploadProgress);
}
if (config.cancelToken) {
// Handle cancellation
config.cancelToken.promise.then(function onCanceled(cancel) {
if (!request) {
return;
}
request.abort();
reject(cancel);
// Clean up request
request = null;
});
}
if (requestData === undefined) {
requestData = null;
}
// Send the request
request.send(requestData);
});
};
/***/ }),
/* 205 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var enhanceError = __webpack_require__(269);
/**
* Create an Error with the specified message, config, error code, request and response.
*
* @param {string} message The error message.
* @param {Object} config The config.
* @param {string} [code] The error code (for example, 'ECONNABORTED').
* @param {Object} [request] The request.
* @param {Object} [response] The response.
* @returns {Error} The created error.
*/
module.exports = function createError(message, config, code, request, response) {
var error = new Error(message);
return enhanceError(error, config, code, request, response);
};
/***/ }),
/* 206 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
module.exports = function isCancel(value) {
return !!(value && value.__CANCEL__);
};
/***/ }),
/* 207 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* A `Cancel` is an object that is thrown when an operation is canceled.
*
* @class
* @param {string=} message The message.
*/
function Cancel(message) {
this.message = message;
}
Cancel.prototype.toString = function toString() {
return 'Cancel' + (this.message ? ': ' + this.message : '');
};
Cancel.prototype.__CANCEL__ = true;
module.exports = Cancel;
/***/ }),
/* 208 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(11);
var _react2 = _interopRequireDefault(_react);
var _propTypes = __webpack_require__(25);
var _propTypes2 = _interopRequireDefault(_propTypes);
var _styles = __webpack_require__(284);
var _styles2 = _interopRequireDefault(_styles);
var _assign = __webpack_require__(285);
var _assign2 = _interopRequireDefault(_assign);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var SkyLightStateless = function (_React$Component) {
_inherits(SkyLightStateless, _React$Component);
function SkyLightStateless() {
_classCallCheck(this, SkyLightStateless);
return _possibleConstructorReturn(this, (SkyLightStateless.__proto__ || Object.getPrototypeOf(SkyLightStateless)).apply(this, arguments));
}
_createClass(SkyLightStateless, [{
key: 'componentWillMount',
value: function componentWillMount() {
document.addEventListener("keydown", this._handlerEsc.bind(this));
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
document.removeEventListener("keydown", this._handlerEsc.bind(this));
}
}, {
key: '_handlerEsc',
value: function _handlerEsc(evt) {
var isEscape = false;
if ("key" in evt) {
isEscape = evt.key == "Escape" || evt.key == "Esc";
} else {
isEscape = evt.keyCode == 27;
}
if (isEscape && this.props.closeOnEsc && this.props.isVisible) {
this.props.onCloseClicked();
}
}
}, {
key: 'onOverlayClicked',
value: function onOverlayClicked() {
if (this.props.onOverlayClicked) {
this.props.onOverlayClicked();
}
}
}, {
key: 'onCloseClicked',
value: function onCloseClicked() {
if (this.props.onCloseClicked) {
this.props.onCloseClicked();
}
}
}, {
key: 'render',
value: function render() {
var _this2 = this;
var mergeStyles = function mergeStyles(key) {
return (0, _assign2.default)({}, _styles2.default[key], _this2.props[key]);
};
var isVisible = this.props.isVisible;
var dialogStyles = mergeStyles('dialogStyles');
var overlayStyles = mergeStyles('overlayStyles');
var closeButtonStyle = mergeStyles('closeButtonStyle');
var titleStyle = mergeStyles('titleStyle');
var finalStyle = void 0;
if (isVisible) {
finalStyle = (0, _assign2.default)({}, dialogStyles, _styles2.default.animationOpen);
overlayStyles.display = 'block';
} else {
finalStyle = (0, _assign2.default)({}, dialogStyles, _styles2.default.animationBase);
overlayStyles.display = 'none';
}
finalStyle.transitionDuration = this.props.transitionDuration + 'ms';
overlayStyles.transitionDuration = this.props.transitionDuration + 'ms';
var overlay = void 0;
if (this.props.showOverlay) {
overlay = _react2.default.createElement('div', { className: 'skylight-overlay',
onClick: function onClick() {
return _this2.onOverlayClicked();
},
style: overlayStyles
});
}
var title = void 0;
if (_react2.default.isValidElement(this.props.title)) {
title = this.props.title;
} else {
title = this.props.title ? _react2.default.createElement(
'h2',
{ style: titleStyle },
this.props.title
) : null;
}
return _react2.default.createElement(
'section',
{ className: 'skylight-wrapper' },
overlay,
_react2.default.createElement(
'div',
{ className: 'skylight-dialog', style: finalStyle },
_react2.default.createElement(
'a',
{
role: 'button',
className: 'skylight-close-button',
onClick: function onClick() {
return _this2.onCloseClicked();
},
style: closeButtonStyle
},
'\xD7'
),
title,
this.props.children
)
);
}
}]);
return SkyLightStateless;
}(_react2.default.Component);
exports.default = SkyLightStateless;
SkyLightStateless.displayName = 'SkyLightStateless';
SkyLightStateless.sharedPropTypes = {
closeButtonStyle: _propTypes2.default.object,
dialogStyles: _propTypes2.default.object,
onCloseClicked: _propTypes2.default.func,
onOverlayClicked: _propTypes2.default.func,
overlayStyles: _propTypes2.default.object,
showOverlay: _propTypes2.default.bool,
title: _propTypes2.default.any,
transitionDuration: _propTypes2.default.number,
titleStyle: _propTypes2.default.object,
closeOnEsc: _propTypes2.default.bool
};
SkyLightStateless.propTypes = _extends({}, SkyLightStateless.sharedPropTypes, {
isVisible: _propTypes2.default.bool
});
SkyLightStateless.defaultProps = {
title: '',
showOverlay: true,
overlayStyles: _styles2.default.overlayStyles,
dialogStyles: _styles2.default.dialogStyles,
closeButtonStyle: _styles2.default.closeButtonStyle,
transitionDuration: 200,
closeOnEsc: true
};
/***/ }),
/* 209 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_react__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_react__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_react_dom__ = __webpack_require__(104);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_react_dom___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_react_dom__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_crowdai_music_evaluation_interface__ = __webpack_require__(210);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_crowdai_music_evaluation_interface___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_crowdai_music_evaluation_interface__);
/* eslint no-console:0 */
// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.
//
// To reference this file, add <%= javascript_pack_tag 'application' %> to the appropriate
// layout file, like app/views/layouts/application.html.erb
console.log('Hello World from Webpacker');
/*
document.addEventListener('DOMContentLoaded', () => {
render(
<CrowdAIMusicEvaluationInterface name="React" />
)
}
)
*/
document.addEventListener('turbolinks:load', function () {
var musicRoot = document.getElementById('music-root2');
if (musicRoot) {
var participantId = musicRoot.dataset.participantId;
Object(__WEBPACK_IMPORTED_MODULE_1_react_dom__["render"])(__WEBPACK_IMPORTED_MODULE_0_react___default.a.createElement(__WEBPACK_IMPORTED_MODULE_2_crowdai_music_evaluation_interface__["CrowdAIMusicEvaluationInterface"], {
name: 'React', participantId: participantId
}), musicRoot);
}
});
/***/ }),
/* 210 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _CrowdAIMusicEvaluationInterface = __webpack_require__(211);
Object.defineProperty(exports, 'CrowdAIMusicEvaluationInterface', {
enumerable: true,
get: function get() {
return _interopRequireDefault(_CrowdAIMusicEvaluationInterface).default;
}
});
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/***/ }),
/* 211 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(11);
var _react2 = _interopRequireDefault(_react);
var _PianoComponent = __webpack_require__(212);
var _PianoComponent2 = _interopRequireDefault(_PianoComponent);
var _MidiPlayerComponent = __webpack_require__(214);
var _MidiPlayerComponent2 = _interopRequireDefault(_MidiPlayerComponent);
__webpack_require__(260);
var _reactSimpleFlexGrid = __webpack_require__(201);
__webpack_require__(202);
var _reactHint = __webpack_require__(261);
var _reactHint2 = _interopRequireDefault(_reactHint);
__webpack_require__(262);
var _axios = __webpack_require__(263);
var _axios2 = _interopRequireDefault(_axios);
var _reactSkylight = __webpack_require__(282);
var _reactSkylight2 = _interopRequireDefault(_reactSkylight);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var ReactHint = (0, _reactHint2.default)(_react2.default);
var CrowdAIMusicEvaluationInterface = function (_Component) {
_inherits(CrowdAIMusicEvaluationInterface, _Component);
function CrowdAIMusicEvaluationInterface(props) {
_classCallCheck(this, CrowdAIMusicEvaluationInterface);
var _this = _possibleConstructorReturn(this, (CrowdAIMusicEvaluationInterface.__proto__ || Object.getPrototypeOf(CrowdAIMusicEvaluationInterface)).call(this, props));
_this.state = {};
_this.octave = 2;
_this.max_number_of_piano_keys = 80;
_this.resetKeyBoard = _this.resetKeyBoard.bind(_this);
_this.reloadData = _this.reloadData.bind(_this);
_this.heartClicked = _this.heartClicked.bind(_this);
_this.OnPlay = _this.OnPlay.bind(_this);
_this.renderModal = _this.renderModal.bind(_this);
_this.resetKeyBoard();
//Modal States
_this.state.modalLoading = true;
_this.state.modalWinProbability = 0.5;
return _this;
}
_createClass(CrowdAIMusicEvaluationInterface, [{
key: 'componentDidMount',
value: function componentDidMount() {
this.reloadData();
}
}, {
key: 'heartClicked',
value: function heartClicked(id) {
var THIS = this;
this.setState({ modalLoading: true });
THIS.simpleDialog.show();
_axios2.default.post(this.props.base_api_url + "/match/" + this.state.match_id, {
winner: id
}).then(function (response) {
if (response.status === 200) {
// Pause both the players if they are playing
if (THIS.refs.midiplayer1.state.hasPlayedOnce) {
THIS.refs.midiplayer1.pauseSong();
}
THIS.refs.midiplayer1.setState({
isHeartEnabled: false,
isPlayEnabled: false
});
if (THIS.refs.midiplayer0.state.hasPlayedOnce) {
THIS.refs.midiplayer0.pauseSong();
}
THIS.refs.midiplayer0.setState({
isHeartEnabled: false,
isPlayEnabled: false
});
//Reset Keyboard
THIS.resetKeyBoard();
THIS.reloadData();
THIS.setState({ modalWinProbability: response.data.prob_win, modalLoading: false });
console.log(response);
} else {
// TODO : Add error handling
}
}).catch(function (error) {
console.log(error);
});
}
}, {
key: 'reloadData',
value: function reloadData() {
var THIS = this;
this.loadingData = true;
// THIS.refs.midiplayer0.setState({isLoading: true});
// THIS.refs.midiplayer1.setState({isLoading: true});
var _state = this.state;
_state.song1 = false;
_state.song2 = false;
_axios2.default.get(this.props.base_api_url + "/match").then(function (response) {
THIS.loadingData = false;
THIS.setState({ match_id: response.data.match_id });
var candidate_1 = response.data.candidate_1;
_axios2.default.get(candidate_1).then(function (response) {
THIS.refs.midiplayer0.setState({ submission_id: response.data.key });
THIS.refs.midiplayer0.load_data_uri(response.data.dataUri);
});
var candidate_2 = response.data.candidate_2;
_axios2.default.get(candidate_2).then(function (response) {
THIS.refs.midiplayer1.setState({ submission_id: response.data.key });
THIS.refs.midiplayer1.load_data_uri(response.data.dataUri);
});
}).catch(function (error) {
console.log(error);
});
}
}, {
key: 'resetKeyBoard',
value: function resetKeyBoard() {
var _new_state = {};
for (var i = 0; i < this.max_number_of_piano_keys; i++) {
_new_state["key_" + i] = 0;
}
this.setState(_new_state);
}
}, {
key: 'OnNoteOn',
value: function OnNoteOn(noteNumber) {
if (noteNumber > this.octave * 2 + this.max_number_of_piano_keys) {
return;
}
var key = "key_" + (noteNumber - this.octave * 12);
var _new_state = {};
_new_state[key] = 1;
this.setState(_new_state);
}
}, {
key: 'OnNoteOff',
value: function OnNoteOff(noteNumber) {
if (noteNumber > this.octave * 2 + this.max_number_of_piano_keys) {
return;
}
var key = "key_" + (noteNumber - this.octave * 12);
var _new_state = {};
_new_state[key] = 0;
this.setState(_new_state);
}
}, {
key: 'OnPlay',
value: function OnPlay(playerName) {
if (playerName === 0) {
if (this.refs.midiplayer1.state.hasPlayedOnce) {
this.refs.midiplayer1.pauseSong();
}
this.refs.midiplayer0.playSong();
} else {
if (this.refs.midiplayer0.state.hasPlayedOnce) {
this.refs.midiplayer0.pauseSong();
}
this.refs.midiplayer1.playSong();
}
//Stop all instances
// this.refs.midiplayer0.pauseSong();
// this.refs.midiplayer1.pauseSong();
// midiplayer.playSong();
}
}, {
key: 'renderModal',
value: function renderModal() {
var _this2 = this;
var THIS = this;
if (this.state.modalLoading) {
return _react2.default.createElement(
_reactSimpleFlexGrid.Row,
{ gutter: 10, align: 'middle', justify: 'center' },
_react2.default.createElement('div', { className: 'crowdai_interface_loader' })
);
} else {
return _react2.default.createElement(
'div',
null,
_react2.default.createElement(
_reactSimpleFlexGrid.Row,
{ gutter: 10, align: 'middle', justify: 'center' },
_react2.default.createElement(
'div',
{ style: { textAlign: "center" } },
'Your choice had a probability of ',
_react2.default.createElement(
'strong',
null,
' ',
this.state.modalWinProbability,
' '
),
' to be chosen over the other song. ',
_react2.default.createElement('br', null)
)
),
_react2.default.createElement(
_reactSimpleFlexGrid.Row,
{ gutter: 10, align: 'middle', justify: 'center' },
_react2.default.createElement(
'button',
{ className: 'crowdai_music_challenge_btns', onClick: function onClick() {
_this2.simpleDialog.hide();
} },
'Load More Songs'
)
)
);
}
}
}, {
key: 'render',
value: function render() {
var _this3 = this;
return _react2.default.createElement(
'div',
null,
_react2.default.createElement(
_reactSkylight2.default,
{
hideOnOverlayClicked: true,
ref: function ref(_ref) {
return _this3.simpleDialog = _ref;
},
title: '' },
this.renderModal()
),
_react2.default.createElement(ReactHint, { events: true, delay: 100 }),
_react2.default.createElement(
_reactSimpleFlexGrid.Row,
{ className: 'CrowdAIMusicEvaluationInterfaceWrapper', justify: 'left' },
_react2.default.createElement(
_reactSimpleFlexGrid.Col,
{ span: 10, offset: 1 },
_react2.default.createElement(
_reactSimpleFlexGrid.Row,
{ gutter: 10, align: 'middle', justify: 'center' },
_react2.default.createElement(
_reactSimpleFlexGrid.Col,
{ xs: 11, sm: 6, md: 6, lg: 6, xl: 6 },
_react2.default.createElement(_MidiPlayerComponent2.default, {
ref: 'midiplayer0',
playerName: 0,
dataUri: this.props.song1,
onNoteOn: this.OnNoteOn.bind(this),
onNoteOff: this.OnNoteOff.bind(this),
onPlay: this.OnPlay,
onHeartClicked: this.heartClicked,
resetKeyBoard: this.resetKeyBoard
})
),
_react2.default.createElement(
_reactSimpleFlexGrid.Col,
{ xs: 11, sm: 6, md: 6, lg: 6, xl: 6 },
_react2.default.createElement(_MidiPlayerComponent2.default, {
ref: 'midiplayer1',
playerName: 1,
dataUri: this.props.song1,
onNoteOn: this.OnNoteOn.bind(this),
onNoteOff: this.OnNoteOff.bind(this),
onPlay: this.OnPlay,
onHeartClicked: this.heartClicked,
resetKeyBoard: this.resetKeyBoard
})
)
),
_react2.default.createElement(
_reactSimpleFlexGrid.Row,
{ align: 'middle', justify: 'center' },
_react2.default.createElement(
_reactSimpleFlexGrid.Col,
{ span: 12 },
_react2.default.createElement(_PianoComponent2.default, { key_states: this.state, noFloor: true })
)
)
)
)
);
}
}]);
return CrowdAIMusicEvaluationInterface;
}(_react.Component);
CrowdAIMusicEvaluationInterface.defaultProps = {
base_api_url: "https://grader.crowdai.org"
};
exports.default = CrowdAIMusicEvaluationInterface;
/***/ }),
/* 212 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(11);
var _react2 = _interopRequireDefault(_react);
var _three = __webpack_require__(192);
var THREE = _interopRequireWildcard(_three);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
// var OrbitControls = require('three-orbit-controls')(THREE)
var ColladaLoader = __webpack_require__(213);
var getCompoundBoundingBox = function getCompoundBoundingBox(object3D) {
var box = null;
object3D.traverse(function (obj3D) {
var geometry = obj3D.geometry;
if (geometry === undefined) return;
geometry.computeBoundingBox();
if (box === null) {
box = geometry.boundingBox;
} else {
box.union(geometry.boundingBox);
}
});
return box;
};
var PianoComponent = function (_React$Component) {
_inherits(PianoComponent, _React$Component);
function PianoComponent(props) {
_classCallCheck(this, PianoComponent);
var _this = _possibleConstructorReturn(this, (PianoComponent.__proto__ || Object.getPrototypeOf(PianoComponent)).call(this, props));
_this.props = props;
_this.state = {
key_states: _this.props.key_states,
key_attack_time: _this.props.key_attack_time,
key_max_rotation: _this.props.key_max_rotation,
octave: _this.props.octave,
canvas_id: "canvas_" + parseInt(Math.random() * 10000000, 10)
};
_this.init_lights = _this.init_lights.bind(_this);
_this.prepare_scene = _this.prepare_scene.bind(_this);
_this.initialize_keys = _this.initialize_keys.bind(_this);
_this.frame = _this.frame.bind(_this);
_this.update = _this.update.bind(_this);
_this.render = _this.render.bind(_this);
_this.update_key = _this.update_key.bind(_this);
_this.on_window_resize = _this.on_window_resize.bind(_this);
_this.smoothstep = _this.smoothstep.bind(_this);
_this.mix = _this.mix.bind(_this);
_this.key_status = _this.key_status.bind(_this);
// this.song = "game_of_thrones.mid";
_this._noteOnColor = [255, 0, 0, 1.0];
_this.noteOnColor = new THREE.Color().setRGB(_this._noteOnColor[0] / 256.0, _this._noteOnColor[1] / 256.0, _this._noteOnColor[2] / 256.0);
_this.keyState = Object.freeze({ unpressed: {}, note_on: {}, pressed: {}, note_off: {} });
return _this;
}
_createClass(PianoComponent, [{
key: 'frame',
value: function frame() {
var delta = this.clock.getDelta();
this.update(delta);
this.renderer.render(this.scene, this.camera);
requestAnimationFrame(this.frame);
// console.log(this.camera);
}
}, {
key: 'componentDidMount',
value: function componentDidMount() {
this.scene = new THREE.Scene();
this.camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 2.0, 5000);
window.camera = this.camera;
this.keys_down = [];
this.keys_obj = [];
window.keys_obj = this.keys_obj;
// window.keyState = this.keyState;
var canvas = document.getElementById(this.state.canvas_id);
this.renderer = new THREE.WebGLRenderer({
antialias: true,
canvas: canvas
});
// this.renderer.setSize( window.innerWidth, window.innerHeight );
this.renderer.setSize(document.getElementsByClassName("piano_renderer")[0].clientWidth, document.getElementsByClassName("piano_renderer")[0].clientHeight);
this.renderer.shadowMapEnabled = true;
this.renderer.shadowMapSoft = true;
this.renderer.shadowMapType = THREE.PCFSoftShadowMap;
this.renderer.gammaInput = true;
this.renderer.gammaOutput = true;
this.renderer.physicallyBasedShading = true;
this.renderer.setClearColor(this.props.backgroundColor, 1);
// window.THREE = THREE;
// var axisHelper = new THREE.AxisHelper( 100 );
// this.scene.add( axisHelper );
//document.body.appendChild( this.renderer.domElement );
document.getElementsByClassName("piano_renderer")[0].appendChild(this.renderer.domElement);
this.material = new THREE.MeshLambertMaterial({ color: 0x606060 });
if (!this.props.noFloor) {
this.floor = new THREE.Mesh(new THREE.PlaneBufferGeometry(8000, 8000), new THREE.MeshStandardMaterial({ color: 0xf0f0f0 }));
// this.floor = new THREE.Mesh( new THREE.PlaneGeometry( 8000, 8000 ), new THREE.MeshBasicMaterial( { color: 0xff00 } ) );
// this.floor.rotation.x = -90 * ( Math.PI / 180 );
this.floor.rotation.x = -1 * (Math.PI / 4) - Math.PI / 2;
this.floor.rotation.y = 0;
this.floor.rotation.z = 0;
this.floor.position.y = -0.25;
this.floor.receiveShadow = true;
this.floor.castShadow = true;
this.scene.add(this.floor);
}
// this.scene.fog = new THREE.Fog( 0xffffff, 40, 50 );
var loader = new ColladaLoader();
loader.load('https://raw.githubusercontent.com/crowdAI/crowdai-music-evaluation-interface/master/src/node_modules/components/PianoComponent/piano.dae', this.prepare_scene);
this.camera.position.x = 5.802896539348776;
this.camera.position.y = 13.57757356945138;
this.camera.position.z = 5.295353133208058;
this.camera.rotation._x = -1.4064383850715876;
this.camera.rotation._y = -0.0006859108065163399;
this.camera.rotation._z = -0.004135604449280542;
this.camera.quaternion._w = 0.7627631500194035;
this.camera.quaternion._x = -0.6466745576834863;
this.camera.quaternion._y = -0.0015987917100707147;
this.camera.quaternion._z = -0.0013554639102737241;
this.camera.updateProjectionMatrix();
// this.cameraControls = new OrbitControls(this.camera);
this.clock = new THREE.Clock();
this.init_lights();
this.frame();
window.addEventListener('resize', this.on_window_resize, true);
this.on_window_resize();
}
}, {
key: 'on_window_resize',
value: function on_window_resize() {
this.camera.aspect = document.getElementsByClassName("piano_renderer")[0].clientWidth / document.getElementsByClassName("piano_renderer")[0].clientHeight;
this.renderer.setSize(document.getElementsByClassName("piano_renderer")[0].clientWidth, document.getElementsByClassName("piano_renderer")[0].clientHeight);
this.camera.updateProjectionMatrix();
}
}, {
key: 'update',
value: function update(delta) {
window.camera = this.camera;
for (var i in this.keys_obj) {
this.update_key(this.keys_obj[i], delta);
}
}
}, {
key: 'smoothstep',
value: function smoothstep(a, b, x) {
if (x < a) return 0.0;
if (x > b) return 1.0;
var y = (x - a) / (b - a);
return y * y * (3.0 - 2.0 * y);
}
}, {
key: 'mix',
value: function mix(a, b, x) {
return a + (b - a) * Math.min(Math.max(x, 0.0), 1.0);
}
}, {
key: 'update_key',
value: function update_key(obj, delta) {
if (obj.keyState === this.keyState.note_on) {
obj.rotation.x = this.mix(-Math.PI / 4.0, -this.state.key_max_rotation, this.smoothstep(0.0, 1.0, this.state.key_attack_time * obj.clock.getElapsedTime()));
if (obj.rotation.x >= -this.state.key_max_rotation) {
obj.keyState = this.keyState.pressed;
obj.clock.elapsedTime = 0;
}
if (obj.children.length > 0) {
obj.children[0].material.color = this.noteOnColor;
}
} else if (obj.keyState === this.keyState.note_off) {
obj.rotation.x = this.mix(-this.state.key_max_rotation, -Math.PI / 4.0, this.smoothstep(0.0, 1.0, this.state.key_attack_time * obj.clock.getElapsedTime()));
if (obj.rotation.x <= -Math.PI / 4.0) {
obj.keyState = this.keyState.unpressed;
obj.clock.elapsedTime = 0;
}
if (obj.children.length > 0) {
obj.children[0].material.color = obj.children[0].material.note_off;
}
}
}
}, {
key: 'key_status',
value: function key_status(keyName, status) {
if (this.scene) {
var obj = this.scene.getObjectByName(keyName, true);
if (obj !== undefined) {
obj.clock.start();
obj.clock.elapsedTime = 0;
obj.keyState = status;
}
}
}
}, {
key: 'initialize_keys',
value: function initialize_keys(obj) {
this.keys_obj.push(obj);
obj.castShadow = true;
obj.receiveShadow = true;
obj.rotation.x = -Math.PI / 4.0;
// obj.rotation.x = 0;
obj.rotation.y = 0;
obj.rotation.z = 0;
obj.keyState = this.keyState.unpressed;
obj.clock = new THREE.Clock(false);
obj.castShadow = true;
obj.receiveShadow = true;
// only add meshes in the material redefinition (to make keys change their color when pressed)
if (obj instanceof THREE.Mesh) {
var old_material = obj.material;
obj.material = new THREE.MeshPhongMaterial({ color: old_material.color });
obj.material.shininess = 100.0;
obj.material.specular = new THREE.Color().setRGB(0.25, 0.25, 0.25);;
obj.material.note_off = obj.material.color.clone();
}
}
}, {
key: 'fix_zoom',
value: function fix_zoom() {
var boundingBox = getCompoundBoundingBox(this.collada_scene);
this.camera.zoom = 10;
this.camera.updateMatrix();
for (var i = 0; i < 1000; i += 1) {
if (this.camera.zoom <= 0.5) {
break;
}
this.camera.zoom -= 0.1;
this.camera.updateProjectionMatrix();
var frustum = new THREE.Frustum();
frustum.setFromMatrix(new THREE.Matrix4().multiplyMatrices(this.camera.projectionMatrix, this.camera.matrixWorldInverse));
var pos_min = new THREE.Vector3(boundingBox.min.x, boundingBox.min.y, boundingBox.min.z);
var pos_max = new THREE.Vector3(boundingBox.min.x, boundingBox.min.y, boundingBox.min.z);
if (frustum.containsPoint(pos_min) && frustum.containsPoint(pos_max)) {
break;
}
}
}
}, {
key: 'prepare_scene',
value: function prepare_scene(collada) {
collada.scene.traverse(this.initialize_keys);
this.collada_scene = collada.scene;
this.scene.add(collada.scene);
// this.fix_zoom();
}
}, {
key: 'init_lights',
value: function init_lights() {
//var spotlight = new THREE.SpotLight(0xffffff);
var spotlight = new THREE.DirectionalLight(0xffffff);
// spotlight.position.set(-10,10,-20);
spotlight.position.set(-1, 1, -2);
var targetObject = new THREE.Object3D();
targetObject.position.x = 10;
targetObject.position.y = 0;
targetObject.position.z = 4;
spotlight.target = targetObject;
this.scene.add(targetObject);
// window.keys_obj = this.keys_obj
// spotlight.target.position.set(10, 10, -10);
spotlight.shadowCameraVisible = true;
spotlight.shadowDarkness = 0.75;
spotlight.intensity = 1;
spotlight.castShadow = true;
spotlight.shadowMapWidth = 2048;
spotlight.shadowMapHeight = 2048;
// spotlight.shadowCameraNear = 5.0;
// spotlight.shadowCameraFar = 20.0;
spotlight.shadowBias = 0.0025;
window.scene = this.scene;
// spotlight.shadowCameraLeft = -8.85;
// spotlight.shadowCameraRight = 5.5;
// spotlight.shadowCameraTop = 4;
// spotlight.shadowCameraBottom = 0;
this.scene.add(spotlight);
// var helper = new THREE.CameraHelper( spotlight.shadow.camera );
// this.scene.add( helper );
var light1 = new THREE.DirectionalLight(0xddffff, 1);
light1.position.set(1, 1, -1).normalize();
this.scene.add(light1);
var light3 = new THREE.AmbientLight(0xffffff, 0.1);
light3.position.set(0, 0, 10).normalize();
this.scene.add(light3);
}
}, {
key: 'render',
value: function render() {
var _this2 = this;
var _temp = {};
Object.keys(this.props.key_states).map(function (i) {
if (i.startsWith("key_")) {
if (_this2.last_state) {
if (_this2.last_state[i] === 0 && _this2.props.key_states[i] === 1) {
_this2.key_status("_" + i.replace("key_", ""), _this2.keyState.note_on);
} else if (_this2.last_state[i] === 1 && _this2.props.key_states[i] === 0) {
_this2.key_status("_" + i.replace("key_", ""), _this2.keyState.note_off);
}
}
_temp[i] = _this2.props.key_states[i];
}
return _this2.props.key_states;
});
this.last_state = _temp;
return _react2.default.createElement(
'div',
{ className: 'piano_renderer' },
_react2.default.createElement('canvas', { id: this.state.canvas_id, style: { width: "100%", height: "100%" } })
);
}
}]);
return PianoComponent;
}(_react2.default.Component);
PianoComponent.defaultProps = {
key_states: {},
key_attack_time: 9.0,
key_max_rotation: 0.72,
octave: 2,
noFloor: false,
backgroundColor: 0xffffff
};
exports.default = PianoComponent;
/***/ }),
/* 213 */
/***/ (function(module, exports, __webpack_require__) {
var THREE = __webpack_require__( 192 );
/**
* @author Tim Knip / http://www.floorplanner.com/ / tim at floorplanner.com
* @author Tony Parisi / http://www.tonyparisi.com/
*/
var ColladaLoader = function () {
var COLLADA = null;
var scene = null;
var visualScene;
var kinematicsModel;
var readyCallbackFunc = null;
var sources = {};
var images = {};
var animations = {};
var controllers = {};
var geometries = {};
var materials = {};
var effects = {};
var cameras = {};
var lights = {};
var animData;
var kinematics;
var visualScenes;
var kinematicsModels;
var baseUrl;
var morphs;
var skins;
var flip_uv = true;
var preferredShading = THREE.SmoothShading;
var options = {
// Force Geometry to always be centered at the local origin of the
// containing Mesh.
centerGeometry: false,
// Axis conversion is done for geometries, animations, and controllers.
// If we ever pull cameras or lights out of the COLLADA file, they'll
// need extra work.
convertUpAxis: false,
subdivideFaces: true,
upAxis: 'Y',
// For reflective or refractive materials we'll use this cubemap
defaultEnvMap: null
};
var colladaUnit = 1.0;
var colladaUp = 'Y';
var upConversion = null;
function load ( url, readyCallback, progressCallback, failCallback ) {
var length = 0;
if ( document.implementation && document.implementation.createDocument ) {
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if ( request.readyState === 4 ) {
if ( request.status === 0 || request.status === 200 ) {
if ( request.response ) {
readyCallbackFunc = readyCallback;
parse( request.response, undefined, url );
} else {
if ( failCallback ) {
failCallback();
} else {
console.error( "ColladaLoader: Empty or non-existing file (" + url + ")" );
}
}
}
} else if ( request.readyState === 3 ) {
if ( progressCallback ) {
if ( length === 0 ) {
length = request.getResponseHeader( "Content-Length" );
}
progressCallback( { total: length, loaded: request.responseText.length } );
}
}
};
request.open( "GET", url, true );
request.send( null );
} else {
alert( "Don't know how to parse XML!" );
}
}
function parse( text, callBack, url ) {
COLLADA = new DOMParser().parseFromString( text, 'text/xml' );
callBack = callBack || readyCallbackFunc;
if ( url !== undefined ) {
var parts = url.split( '/' );
parts.pop();
baseUrl = ( parts.length < 1 ? '.' : parts.join( '/' ) ) + '/';
}
parseAsset();
setUpConversion();
images = parseLib( "library_images image", _Image, "image" );
materials = parseLib( "library_materials material", Material, "material" );
effects = parseLib( "library_effects effect", Effect, "effect" );
geometries = parseLib( "library_geometries geometry", Geometry, "geometry" );
cameras = parseLib( "library_cameras camera", Camera, "camera" );
lights = parseLib( "library_lights light", Light, "light" );
controllers = parseLib( "library_controllers controller", Controller, "controller" );
animations = parseLib( "library_animations animation", Animation, "animation" );
visualScenes = parseLib( "library_visual_scenes visual_scene", VisualScene, "visual_scene" );
kinematicsModels = parseLib( "library_kinematics_models kinematics_model", KinematicsModel, "kinematics_model" );
morphs = [];
skins = [];
visualScene = parseScene();
scene = new THREE.Group();
for ( var i = 0; i < visualScene.nodes.length; i ++ ) {
scene.add( createSceneGraph( visualScene.nodes[ i ] ) );
}
// unit conversion
scene.scale.multiplyScalar( colladaUnit );
createAnimations();
kinematicsModel = parseKinematicsModel();
createKinematics();
var result = {
scene: scene,
morphs: morphs,
skins: skins,
animations: animData,
kinematics: kinematics,
dae: {
images: images,
materials: materials,
cameras: cameras,
lights: lights,
effects: effects,
geometries: geometries,
controllers: controllers,
animations: animations,
visualScenes: visualScenes,
visualScene: visualScene,
scene: visualScene,
kinematicsModels: kinematicsModels,
kinematicsModel: kinematicsModel
}
};
if ( callBack ) {
callBack( result );
}
return result;
}
function setPreferredShading ( shading ) {
preferredShading = shading;
}
function parseAsset () {
var elements = COLLADA.querySelectorAll('asset');
var element = elements[0];
if ( element && element.childNodes ) {
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
switch ( child.nodeName ) {
case 'unit':
var meter = child.getAttribute( 'meter' );
if ( meter ) {
colladaUnit = parseFloat( meter );
}
break;
case 'up_axis':
colladaUp = child.textContent.charAt(0);
break;
}
}
}
}
function parseLib ( q, classSpec, prefix ) {
var elements = COLLADA.querySelectorAll(q);
var lib = {};
var i = 0;
var elementsLength = elements.length;
for ( var j = 0; j < elementsLength; j ++ ) {
var element = elements[j];
var daeElement = ( new classSpec() ).parse( element );
if ( !daeElement.id || daeElement.id.length === 0 ) daeElement.id = prefix + ( i ++ );
lib[ daeElement.id ] = daeElement;
}
return lib;
}
function parseScene() {
var sceneElement = COLLADA.querySelectorAll('scene instance_visual_scene')[0];
if ( sceneElement ) {
var url = sceneElement.getAttribute( 'url' ).replace( /^#/, '' );
return visualScenes[ url.length > 0 ? url : 'visual_scene0' ];
} else {
return null;
}
}
function parseKinematicsModel() {
var kinematicsModelElement = COLLADA.querySelectorAll('instance_kinematics_model')[0];
if ( kinematicsModelElement ) {
var url = kinematicsModelElement.getAttribute( 'url' ).replace(/^#/, '');
return kinematicsModels[ url.length > 0 ? url : 'kinematics_model0' ];
} else {
return null;
}
}
function createAnimations() {
animData = [];
// fill in the keys
recurseHierarchy( scene );
}
function recurseHierarchy( node ) {
var n = visualScene.getChildById( node.colladaId, true ),
newData = null;
if ( n && n.keys ) {
newData = {
fps: 60,
hierarchy: [ {
node: n,
keys: n.keys,
sids: n.sids
} ],
node: node,
name: 'animation_' + node.name,
length: 0
};
animData.push(newData);
for ( var i = 0, il = n.keys.length; i < il; i ++ ) {
newData.length = Math.max( newData.length, n.keys[i].time );
}
} else {
newData = {
hierarchy: [ {
keys: [],
sids: []
} ]
}
}
for ( var i = 0, il = node.children.length; i < il; i ++ ) {
var d = recurseHierarchy( node.children[i] );
for ( var j = 0, jl = d.hierarchy.length; j < jl; j ++ ) {
newData.hierarchy.push( {
keys: [],
sids: []
} );
}
}
return newData;
}
function calcAnimationBounds () {
var start = 1000000;
var end = -start;
var frames = 0;
var ID;
for ( var id in animations ) {
var animation = animations[ id ];
ID = ID || animation.id;
for ( var i = 0; i < animation.sampler.length; i ++ ) {
var sampler = animation.sampler[ i ];
sampler.create();
start = Math.min( start, sampler.startTime );
end = Math.max( end, sampler.endTime );
frames = Math.max( frames, sampler.input.length );
}
}
return { start:start, end:end, frames:frames,ID:ID };
}
function createMorph ( geometry, ctrl ) {
var morphCtrl = ctrl instanceof InstanceController ? controllers[ ctrl.url ] : ctrl;
if ( !morphCtrl || !morphCtrl.morph ) {
console.log("could not find morph controller!");
return;
}
var morph = morphCtrl.morph;
for ( var i = 0; i < morph.targets.length; i ++ ) {
var target_id = morph.targets[ i ];
var daeGeometry = geometries[ target_id ];
if ( !daeGeometry.mesh ||
!daeGeometry.mesh.primitives ||
!daeGeometry.mesh.primitives.length ) {
continue;
}
var target = daeGeometry.mesh.primitives[ 0 ].geometry;
if ( target.vertices.length === geometry.vertices.length ) {
geometry.morphTargets.push( { name: "target_1", vertices: target.vertices } );
}
}
geometry.morphTargets.push( { name: "target_Z", vertices: geometry.vertices } );
}
function createSkin ( geometry, ctrl, applyBindShape ) {
var skinCtrl = controllers[ ctrl.url ];
if ( !skinCtrl || !skinCtrl.skin ) {
console.log( "could not find skin controller!" );
return;
}
if ( !ctrl.skeleton || !ctrl.skeleton.length ) {
console.log( "could not find the skeleton for the skin!" );
return;
}
var skin = skinCtrl.skin;
var skeleton = visualScene.getChildById( ctrl.skeleton[ 0 ] );
var hierarchy = [];
applyBindShape = applyBindShape !== undefined ? applyBindShape : true;
var bones = [];
geometry.skinWeights = [];
geometry.skinIndices = [];
//createBones( geometry.bones, skin, hierarchy, skeleton, null, -1 );
//createWeights( skin, geometry.bones, geometry.skinIndices, geometry.skinWeights );
/*
geometry.animation = {
name: 'take_001',
fps: 30,
length: 2,
JIT: true,
hierarchy: hierarchy
};
*/
if ( applyBindShape ) {
for ( var i = 0; i < geometry.vertices.length; i ++ ) {
geometry.vertices[ i ].applyMatrix4( skin.bindShapeMatrix );
}
}
}
function setupSkeleton ( node, bones, frame, parent ) {
node.world = node.world || new THREE.Matrix4();
node.localworld = node.localworld || new THREE.Matrix4();
node.world.copy( node.matrix );
node.localworld.copy( node.matrix );
if ( node.channels && node.channels.length ) {
var channel = node.channels[ 0 ];
var m = channel.sampler.output[ frame ];
if ( m instanceof THREE.Matrix4 ) {
node.world.copy( m );
node.localworld.copy(m);
if (frame === 0)
node.matrix.copy(m);
}
}
if ( parent ) {
node.world.multiplyMatrices( parent, node.world );
}
bones.push( node );
for ( var i = 0; i < node.nodes.length; i ++ ) {
setupSkeleton( node.nodes[ i ], bones, frame, node.world );
}
}
function setupSkinningMatrices ( bones, skin ) {
// FIXME: this is dumb...
for ( var i = 0; i < bones.length; i ++ ) {
var bone = bones[ i ];
var found = -1;
if ( bone.type != 'JOINT' ) continue;
for ( var j = 0; j < skin.joints.length; j ++ ) {
if ( bone.sid === skin.joints[ j ] ) {
found = j;
break;
}
}
if ( found >= 0 ) {
var inv = skin.invBindMatrices[ found ];
bone.invBindMatrix = inv;
bone.skinningMatrix = new THREE.Matrix4();
bone.skinningMatrix.multiplyMatrices(bone.world, inv); // (IBMi * JMi)
bone.animatrix = new THREE.Matrix4();
bone.animatrix.copy(bone.localworld);
bone.weights = [];
for ( var j = 0; j < skin.weights.length; j ++ ) {
for (var k = 0; k < skin.weights[ j ].length; k ++ ) {
var w = skin.weights[ j ][ k ];
if ( w.joint === found ) {
bone.weights.push( w );
}
}
}
} else {
console.warn( "ColladaLoader: Could not find joint '" + bone.sid + "'." );
bone.skinningMatrix = new THREE.Matrix4();
bone.weights = [];
}
}
}
//Walk the Collada tree and flatten the bones into a list, extract the position, quat and scale from the matrix
function flattenSkeleton(skeleton) {
var list = [];
var walk = function(parentid, node, list) {
var bone = {};
bone.name = node.sid;
bone.parent = parentid;
bone.matrix = node.matrix;
var data = [ new THREE.Vector3(),new THREE.Quaternion(),new THREE.Vector3() ];
bone.matrix.decompose(data[0], data[1], data[2]);
bone.pos = [ data[0].x,data[0].y,data[0].z ];
bone.scl = [ data[2].x,data[2].y,data[2].z ];
bone.rotq = [ data[1].x,data[1].y,data[1].z,data[1].w ];
list.push(bone);
for (var i in node.nodes) {
walk(node.sid, node.nodes[i], list);
}
};
walk(-1, skeleton, list);
return list;
}
//Move the vertices into the pose that is proper for the start of the animation
function skinToBindPose(geometry,skeleton,skinController) {
var bones = [];
setupSkeleton( skeleton, bones, -1 );
setupSkinningMatrices( bones, skinController.skin );
var v = new THREE.Vector3();
var skinned = [];
for (var i = 0; i < geometry.vertices.length; i ++) {
skinned.push(new THREE.Vector3());
}
for ( i = 0; i < bones.length; i ++ ) {
if ( bones[ i ].type != 'JOINT' ) continue;
for ( var j = 0; j < bones[ i ].weights.length; j ++ ) {
var w = bones[ i ].weights[ j ];
var vidx = w.index;
var weight = w.weight;
var o = geometry.vertices[vidx];
var s = skinned[vidx];
v.x = o.x;
v.y = o.y;
v.z = o.z;
v.applyMatrix4( bones[i].skinningMatrix );
s.x += (v.x * weight);
s.y += (v.y * weight);
s.z += (v.z * weight);
}
}
for (var i = 0; i < geometry.vertices.length; i ++) {
geometry.vertices[i] = skinned[i];
}
}
function applySkin ( geometry, instanceCtrl, frame ) {
var skinController = controllers[ instanceCtrl.url ];
frame = frame !== undefined ? frame : 40;
if ( !skinController || !skinController.skin ) {
console.log( 'ColladaLoader: Could not find skin controller.' );
return;
}
if ( !instanceCtrl.skeleton || !instanceCtrl.skeleton.length ) {
console.log( 'ColladaLoader: Could not find the skeleton for the skin. ' );
return;
}
var animationBounds = calcAnimationBounds();
var skeleton = visualScene.getChildById( instanceCtrl.skeleton[0], true ) || visualScene.getChildBySid( instanceCtrl.skeleton[0], true );
//flatten the skeleton into a list of bones
var bonelist = flattenSkeleton(skeleton);
var joints = skinController.skin.joints;
//sort that list so that the order reflects the order in the joint list
var sortedbones = [];
for (var i = 0; i < joints.length; i ++) {
for (var j = 0; j < bonelist.length; j ++) {
if (bonelist[j].name === joints[i]) {
sortedbones[i] = bonelist[j];
}
}
}
//hook up the parents by index instead of name
for (var i = 0; i < sortedbones.length; i ++) {
for (var j = 0; j < sortedbones.length; j ++) {
if (sortedbones[i].parent === sortedbones[j].name) {
sortedbones[i].parent = j;
}
}
}
var i, j, w, vidx, weight;
var v = new THREE.Vector3(), o, s;
// move vertices to bind shape
for ( i = 0; i < geometry.vertices.length; i ++ ) {
geometry.vertices[i].applyMatrix4( skinController.skin.bindShapeMatrix );
}
var skinIndices = [];
var skinWeights = [];
var weights = skinController.skin.weights;
// hook up the skin weights
// TODO - this might be a good place to choose greatest 4 weights
for ( var i =0; i < weights.length; i ++ ) {
var indicies = new THREE.Vector4(weights[i][0] ? weights[i][0].joint : 0,weights[i][1] ? weights[i][1].joint : 0,weights[i][2] ? weights[i][2].joint : 0,weights[i][3] ? weights[i][3].joint : 0);
var weight = new THREE.Vector4(weights[i][0] ? weights[i][0].weight : 0,weights[i][1] ? weights[i][1].weight : 0,weights[i][2] ? weights[i][2].weight : 0,weights[i][3] ? weights[i][3].weight : 0);
skinIndices.push(indicies);
skinWeights.push(weight);
}
geometry.skinIndices = skinIndices;
geometry.skinWeights = skinWeights;
geometry.bones = sortedbones;
// process animation, or simply pose the rig if no animation
//create an animation for the animated bones
//NOTE: this has no effect when using morphtargets
var animationdata = { "name":animationBounds.ID,"fps":30,"length":animationBounds.frames / 30,"hierarchy":[] };
for (var j = 0; j < sortedbones.length; j ++) {
animationdata.hierarchy.push({ parent:sortedbones[j].parent, name:sortedbones[j].name, keys:[] });
}
console.log( 'ColladaLoader:', animationBounds.ID + ' has ' + sortedbones.length + ' bones.' );
skinToBindPose(geometry, skeleton, skinController);
for ( frame = 0; frame < animationBounds.frames; frame ++ ) {
var bones = [];
var skinned = [];
// process the frame and setup the rig with a fresh
// transform, possibly from the bone's animation channel(s)
setupSkeleton( skeleton, bones, frame );
setupSkinningMatrices( bones, skinController.skin );
for (var i = 0; i < bones.length; i ++) {
for (var j = 0; j < animationdata.hierarchy.length; j ++) {
if (animationdata.hierarchy[j].name === bones[i].sid) {
var key = {};
key.time = (frame / 30);
key.matrix = bones[i].animatrix;
if (frame === 0)
bones[i].matrix = key.matrix;
var data = [ new THREE.Vector3(),new THREE.Quaternion(),new THREE.Vector3() ];
key.matrix.decompose(data[0], data[1], data[2]);
key.pos = [ data[0].x,data[0].y,data[0].z ];
key.scl = [ data[2].x,data[2].y,data[2].z ];
key.rot = data[1];
animationdata.hierarchy[j].keys.push(key);
}
}
}
geometry.animation = animationdata;
}
}
function createKinematics() {
if ( kinematicsModel && kinematicsModel.joints.length === 0 ) {
kinematics = undefined;
return;
}
var jointMap = {};
var _addToMap = function( jointIndex, parentVisualElement ) {
var parentVisualElementId = parentVisualElement.getAttribute( 'id' );
var colladaNode = visualScene.getChildById( parentVisualElementId, true );
var joint = kinematicsModel.joints[ jointIndex ];
scene.traverse(function( node ) {
if ( node.colladaId == parentVisualElementId ) {
jointMap[ jointIndex ] = {
node: node,
transforms: colladaNode.transforms,
joint: joint,
position: joint.zeroPosition
};
}
});
};
kinematics = {
joints: kinematicsModel && kinematicsModel.joints,
getJointValue: function( jointIndex ) {
var jointData = jointMap[ jointIndex ];
if ( jointData ) {
return jointData.position;
} else {
console.log( 'getJointValue: joint ' + jointIndex + ' doesn\'t exist' );
}
},
setJointValue: function( jointIndex, value ) {
var jointData = jointMap[ jointIndex ];
if ( jointData ) {
var joint = jointData.joint;
if ( value > joint.limits.max || value < joint.limits.min ) {
console.log( 'setJointValue: joint ' + jointIndex + ' value ' + value + ' outside of limits (min: ' + joint.limits.min + ', max: ' + joint.limits.max + ')' );
} else if ( joint.static ) {
console.log( 'setJointValue: joint ' + jointIndex + ' is static' );
} else {
var threejsNode = jointData.node;
var axis = joint.axis;
var transforms = jointData.transforms;
var matrix = new THREE.Matrix4();
for (i = 0; i < transforms.length; i ++ ) {
var transform = transforms[ i ];
// kinda ghetto joint detection
if ( transform.sid && transform.sid.indexOf( 'joint' + jointIndex ) !== -1 ) {
// apply actual joint value here
switch ( joint.type ) {
case 'revolute':
matrix.multiply( m1.makeRotationAxis( axis, THREE.Math.degToRad(value) ) );
break;
case 'prismatic':
matrix.multiply( m1.makeTranslation(axis.x * value, axis.y * value, axis.z * value ) );
break;
default:
console.warn( 'setJointValue: unknown joint type: ' + joint.type );
break;
}
} else {
var m1 = new THREE.Matrix4();
switch ( transform.type ) {
case 'matrix':
matrix.multiply( transform.obj );
break;
case 'translate':
matrix.multiply( m1.makeTranslation( transform.obj.x, transform.obj.y, transform.obj.z ) );
break;
case 'rotate':
matrix.multiply( m1.makeRotationAxis( transform.obj, transform.angle ) );
break;
}
}
}
// apply the matrix to the threejs node
var elementsFloat32Arr = matrix.elements;
var elements = Array.prototype.slice.call( elementsFloat32Arr );
var elementsRowMajor = [
elements[ 0 ],
elements[ 4 ],
elements[ 8 ],
elements[ 12 ],
elements[ 1 ],
elements[ 5 ],
elements[ 9 ],
elements[ 13 ],
elements[ 2 ],
elements[ 6 ],
elements[ 10 ],
elements[ 14 ],
elements[ 3 ],
elements[ 7 ],
elements[ 11 ],
elements[ 15 ]
];
threejsNode.matrix.set.apply( threejsNode.matrix, elementsRowMajor );
threejsNode.matrix.decompose( threejsNode.position, threejsNode.quaternion, threejsNode.scale );
}
} else {
console.log( 'setJointValue: joint ' + jointIndex + ' doesn\'t exist' );
}
}
};
var element = COLLADA.querySelector('scene instance_kinematics_scene');
if ( element ) {
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
if ( child.nodeType != 1 ) continue;
switch ( child.nodeName ) {
case 'bind_joint_axis':
var visualTarget = child.getAttribute( 'target' ).split( '/' ).pop();
var axis = child.querySelector('axis param').textContent;
var jointIndex = parseInt( axis.split( 'joint' ).pop().split( '.' )[0] );
var visualTargetElement = COLLADA.querySelector( '[sid="' + visualTarget + '"]' );
if ( visualTargetElement ) {
var parentVisualElement = visualTargetElement.parentElement;
_addToMap(jointIndex, parentVisualElement);
}
break;
default:
break;
}
}
}
}
function createSceneGraph ( node, parent ) {
var obj = new THREE.Object3D();
var skinned = false;
var skinController;
var morphController;
var i, j;
// FIXME: controllers
for ( i = 0; i < node.controllers.length; i ++ ) {
var controller = controllers[ node.controllers[ i ].url ];
switch ( controller.type ) {
case 'skin':
if ( geometries[ controller.skin.source ] ) {
var inst_geom = new InstanceGeometry();
inst_geom.url = controller.skin.source;
inst_geom.instance_material = node.controllers[ i ].instance_material;
node.geometries.push( inst_geom );
skinned = true;
skinController = node.controllers[ i ];
} else if ( controllers[ controller.skin.source ] ) {
// urgh: controller can be chained
// handle the most basic case...
var second = controllers[ controller.skin.source ];
morphController = second;
// skinController = node.controllers[i];
if ( second.morph && geometries[ second.morph.source ] ) {
var inst_geom = new InstanceGeometry();
inst_geom.url = second.morph.source;
inst_geom.instance_material = node.controllers[ i ].instance_material;
node.geometries.push( inst_geom );
}
}
break;
case 'morph':
if ( geometries[ controller.morph.source ] ) {
var inst_geom = new InstanceGeometry();
inst_geom.url = controller.morph.source;
inst_geom.instance_material = node.controllers[ i ].instance_material;
node.geometries.push( inst_geom );
morphController = node.controllers[ i ];
}
console.log( 'ColladaLoader: Morph-controller partially supported.' );
default:
break;
}
}
// geometries
var double_sided_materials = {};
for ( i = 0; i < node.geometries.length; i ++ ) {
var instance_geometry = node.geometries[i];
var instance_materials = instance_geometry.instance_material;
var geometry = geometries[ instance_geometry.url ];
var used_materials = {};
var used_materials_array = [];
var num_materials = 0;
var first_material;
if ( geometry ) {
if ( !geometry.mesh || !geometry.mesh.primitives )
continue;
if ( obj.name.length === 0 ) {
obj.name = geometry.id;
}
// collect used fx for this geometry-instance
if ( instance_materials ) {
for ( j = 0; j < instance_materials.length; j ++ ) {
var instance_material = instance_materials[ j ];
var mat = materials[ instance_material.target ];
var effect_id = mat.instance_effect.url;
var shader = effects[ effect_id ].shader;
var material3js = shader.material;
if ( geometry.doubleSided ) {
if ( !( instance_material.symbol in double_sided_materials ) ) {
var _copied_material = material3js.clone();
_copied_material.side = THREE.DoubleSide;
double_sided_materials[ instance_material.symbol ] = _copied_material;
}
material3js = double_sided_materials[ instance_material.symbol ];
}
material3js.opacity = !material3js.opacity ? 1 : material3js.opacity;
used_materials[ instance_material.symbol ] = num_materials;
used_materials_array.push( material3js );
first_material = material3js;
first_material.name = mat.name === null || mat.name === '' ? mat.id : mat.name;
num_materials ++;
}
}
var mesh;
var material = first_material || new THREE.MeshLambertMaterial( { color: 0xdddddd, side: geometry.doubleSided ? THREE.DoubleSide : THREE.FrontSide } );
var geom = geometry.mesh.geometry3js;
if ( num_materials > 1 ) {
material = new THREE.MultiMaterial( used_materials_array );
}
if ( skinController !== undefined ) {
applySkin( geom, skinController );
if ( geom.morphTargets.length > 0 ) {
material.morphTargets = true;
material.skinning = false;
} else {
material.morphTargets = false;
material.skinning = true;
}
mesh = new THREE.SkinnedMesh( geom, material, false );
//mesh.skeleton = skinController.skeleton;
//mesh.skinController = controllers[ skinController.url ];
//mesh.skinInstanceController = skinController;
mesh.name = 'skin_' + skins.length;
//mesh.animationHandle.setKey(0);
skins.push( mesh );
} else if ( morphController !== undefined ) {
createMorph( geom, morphController );
material.morphTargets = true;
mesh = new THREE.Mesh( geom, material );
mesh.name = 'morph_' + morphs.length;
morphs.push( mesh );
} else {
if ( geom.isLineStrip === true ) {
mesh = new THREE.Line( geom );
} else {
mesh = new THREE.Mesh( geom, material );
}
}
obj.add(mesh);
}
}
for ( i = 0; i < node.cameras.length; i ++ ) {
var instance_camera = node.cameras[i];
var cparams = cameras[instance_camera.url];
var cam = new THREE.PerspectiveCamera(cparams.yfov, parseFloat(cparams.aspect_ratio),
parseFloat(cparams.znear), parseFloat(cparams.zfar));
obj.add(cam);
}
for ( i = 0; i < node.lights.length; i ++ ) {
var light = null;
var instance_light = node.lights[i];
var lparams = lights[instance_light.url];
if ( lparams && lparams.technique ) {
var color = lparams.color.getHex();
var intensity = lparams.intensity;
var distance = lparams.distance;
var angle = lparams.falloff_angle;
switch ( lparams.technique ) {
case 'directional':
light = new THREE.DirectionalLight( color, intensity, distance );
light.position.set(0, 0, 1);
break;
case 'point':
light = new THREE.PointLight( color, intensity, distance );
break;
case 'spot':
light = new THREE.SpotLight( color, intensity, distance, angle );
light.position.set(0, 0, 1);
break;
case 'ambient':
light = new THREE.AmbientLight( color );
break;
}
}
if (light) {
obj.add(light);
}
}
obj.name = node.name || node.id || "";
obj.colladaId = node.id || "";
obj.layer = node.layer || "";
obj.matrix = node.matrix;
obj.matrix.decompose( obj.position, obj.quaternion, obj.scale );
if ( options.centerGeometry && obj.geometry ) {
var delta = obj.geometry.center();
delta.multiply( obj.scale );
delta.applyQuaternion( obj.quaternion );
obj.position.sub( delta );
}
for ( i = 0; i < node.nodes.length; i ++ ) {
obj.add( createSceneGraph( node.nodes[i], node ) );
}
return obj;
}
function getJointId( skin, id ) {
for ( var i = 0; i < skin.joints.length; i ++ ) {
if ( skin.joints[ i ] === id ) {
return i;
}
}
}
function getLibraryNode( id ) {
var nodes = COLLADA.querySelectorAll('library_nodes node');
for ( var i = 0; i < nodes.length; i++ ) {
var attObj = nodes[i].attributes.getNamedItem('id');
if ( attObj && attObj.value === id ) {
return nodes[i];
}
}
return undefined;
}
function getChannelsForNode ( node ) {
var channels = [];
var startTime = 1000000;
var endTime = -1000000;
for ( var id in animations ) {
var animation = animations[id];
for ( var i = 0; i < animation.channel.length; i ++ ) {
var channel = animation.channel[i];
var sampler = animation.sampler[i];
var id = channel.target.split('/')[0];
if ( id == node.id ) {
sampler.create();
channel.sampler = sampler;
startTime = Math.min(startTime, sampler.startTime);
endTime = Math.max(endTime, sampler.endTime);
channels.push(channel);
}
}
}
if ( channels.length ) {
node.startTime = startTime;
node.endTime = endTime;
}
return channels;
}
function calcFrameDuration( node ) {
var minT = 10000000;
for ( var i = 0; i < node.channels.length; i ++ ) {
var sampler = node.channels[i].sampler;
for ( var j = 0; j < sampler.input.length - 1; j ++ ) {
var t0 = sampler.input[ j ];
var t1 = sampler.input[ j + 1 ];
minT = Math.min( minT, t1 - t0 );
}
}
return minT;
}
function calcMatrixAt( node, t ) {
var animated = {};
var i, j;
for ( i = 0; i < node.channels.length; i ++ ) {
var channel = node.channels[ i ];
animated[ channel.sid ] = channel;
}
var matrix = new THREE.Matrix4();
for ( i = 0; i < node.transforms.length; i ++ ) {
var transform = node.transforms[ i ];
var channel = animated[ transform.sid ];
if ( channel !== undefined ) {
var sampler = channel.sampler;
var value;
for ( j = 0; j < sampler.input.length - 1; j ++ ) {
if ( sampler.input[ j + 1 ] > t ) {
value = sampler.output[ j ];
//console.log(value.flatten)
break;
}
}
if ( value !== undefined ) {
if ( value instanceof THREE.Matrix4 ) {
matrix.multiplyMatrices( matrix, value );
} else {
// FIXME: handle other types
matrix.multiplyMatrices( matrix, transform.matrix );
}
} else {
matrix.multiplyMatrices( matrix, transform.matrix );
}
} else {
matrix.multiplyMatrices( matrix, transform.matrix );
}
}
return matrix;
}
function bakeAnimations ( node ) {
if ( node.channels && node.channels.length ) {
var keys = [],
sids = [];
for ( var i = 0, il = node.channels.length; i < il; i ++ ) {
var channel = node.channels[i],
fullSid = channel.fullSid,
sampler = channel.sampler,
input = sampler.input,
transform = node.getTransformBySid( channel.sid ),
member;
if ( channel.arrIndices ) {
member = [];
for ( var j = 0, jl = channel.arrIndices.length; j < jl; j ++ ) {
member[ j ] = getConvertedIndex( channel.arrIndices[ j ] );
}
} else {
member = getConvertedMember( channel.member );
}
if ( transform ) {
if ( sids.indexOf( fullSid ) === -1 ) {
sids.push( fullSid );
}
for ( var j = 0, jl = input.length; j < jl; j ++ ) {
var time = input[j],
data = sampler.getData( transform.type, j, member ),
key = findKey( keys, time );
if ( !key ) {
key = new Key( time );
var timeNdx = findTimeNdx( keys, time );
keys.splice( timeNdx === -1 ? keys.length : timeNdx, 0, key );
}
key.addTarget( fullSid, transform, member, data );
}
} else {
console.log( 'Could not find transform "' + channel.sid + '" in node ' + node.id );
}
}
// post process
for ( var i = 0; i < sids.length; i ++ ) {
var sid = sids[ i ];
for ( var j = 0; j < keys.length; j ++ ) {
var key = keys[ j ];
if ( !key.hasTarget( sid ) ) {
interpolateKeys( keys, key, j, sid );
}
}
}
node.keys = keys;
node.sids = sids;
}
}
function findKey ( keys, time) {
var retVal = null;
for ( var i = 0, il = keys.length; i < il && retVal === null; i ++ ) {
var key = keys[i];
if ( key.time === time ) {
retVal = key;
} else if ( key.time > time ) {
break;
}
}
return retVal;
}
function findTimeNdx ( keys, time) {
var ndx = -1;
for ( var i = 0, il = keys.length; i < il && ndx === -1; i ++ ) {
var key = keys[i];
if ( key.time >= time ) {
ndx = i;
}
}
return ndx;
}
function interpolateKeys ( keys, key, ndx, fullSid ) {
var prevKey = getPrevKeyWith( keys, fullSid, ndx ? ndx - 1 : 0 ),
nextKey = getNextKeyWith( keys, fullSid, ndx + 1 );
if ( prevKey && nextKey ) {
var scale = (key.time - prevKey.time) / (nextKey.time - prevKey.time),
prevTarget = prevKey.getTarget( fullSid ),
nextData = nextKey.getTarget( fullSid ).data,
prevData = prevTarget.data,
data;
if ( prevTarget.type === 'matrix' ) {
data = prevData;
} else if ( prevData.length ) {
data = [];
for ( var i = 0; i < prevData.length; ++ i ) {
data[ i ] = prevData[ i ] + ( nextData[ i ] - prevData[ i ] ) * scale;
}
} else {
data = prevData + ( nextData - prevData ) * scale;
}
key.addTarget( fullSid, prevTarget.transform, prevTarget.member, data );
}
}
// Get next key with given sid
function getNextKeyWith( keys, fullSid, ndx ) {
for ( ; ndx < keys.length; ndx ++ ) {
var key = keys[ ndx ];
if ( key.hasTarget( fullSid ) ) {
return key;
}
}
return null;
}
// Get previous key with given sid
function getPrevKeyWith( keys, fullSid, ndx ) {
ndx = ndx >= 0 ? ndx : ndx + keys.length;
for ( ; ndx >= 0; ndx -- ) {
var key = keys[ ndx ];
if ( key.hasTarget( fullSid ) ) {
return key;
}
}
return null;
}
function _Image() {
this.id = "";
this.init_from = "";
}
_Image.prototype.parse = function(element) {
this.id = element.getAttribute('id');
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
if ( child.nodeName === 'init_from' ) {
this.init_from = child.textContent;
}
}
return this;
};
function Controller() {
this.id = "";
this.name = "";
this.type = "";
this.skin = null;
this.morph = null;
}
Controller.prototype.parse = function( element ) {
this.id = element.getAttribute('id');
this.name = element.getAttribute('name');
this.type = "none";
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
switch ( child.nodeName ) {
case 'skin':
this.skin = (new Skin()).parse(child);
this.type = child.nodeName;
break;
case 'morph':
this.morph = (new Morph()).parse(child);
this.type = child.nodeName;
break;
default:
break;
}
}
return this;
};
function Morph() {
this.method = null;
this.source = null;
this.targets = null;
this.weights = null;
}
Morph.prototype.parse = function( element ) {
var sources = {};
var inputs = [];
var i;
this.method = element.getAttribute( 'method' );
this.source = element.getAttribute( 'source' ).replace( /^#/, '' );
for ( i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
if ( child.nodeType != 1 ) continue;
switch ( child.nodeName ) {
case 'source':
var source = ( new Source() ).parse( child );
sources[ source.id ] = source;
break;
case 'targets':
inputs = this.parseInputs( child );
break;
default:
console.log( child.nodeName );
break;
}
}
for ( i = 0; i < inputs.length; i ++ ) {
var input = inputs[ i ];
var source = sources[ input.source ];
switch ( input.semantic ) {
case 'MORPH_TARGET':
this.targets = source.read();
break;
case 'MORPH_WEIGHT':
this.weights = source.read();
break;
default:
break;
}
}
return this;
};
Morph.prototype.parseInputs = function(element) {
var inputs = [];
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[i];
if ( child.nodeType != 1) continue;
switch ( child.nodeName ) {
case 'input':
inputs.push( (new Input()).parse(child) );
break;
default:
break;
}
}
return inputs;
};
function Skin() {
this.source = "";
this.bindShapeMatrix = null;
this.invBindMatrices = [];
this.joints = [];
this.weights = [];
}
Skin.prototype.parse = function( element ) {
var sources = {};
var joints, weights;
this.source = element.getAttribute( 'source' ).replace( /^#/, '' );
this.invBindMatrices = [];
this.joints = [];
this.weights = [];
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[i];
if ( child.nodeType != 1 ) continue;
switch ( child.nodeName ) {
case 'bind_shape_matrix':
var f = _floats(child.textContent);
this.bindShapeMatrix = getConvertedMat4( f );
break;
case 'source':
var src = new Source().parse(child);
sources[ src.id ] = src;
break;
case 'joints':
joints = child;
break;
case 'vertex_weights':
weights = child;
break;
default:
console.log( child.nodeName );
break;
}
}
this.parseJoints( joints, sources );
this.parseWeights( weights, sources );
return this;
};
Skin.prototype.parseJoints = function ( element, sources ) {
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
if ( child.nodeType != 1 ) continue;
switch ( child.nodeName ) {
case 'input':
var input = ( new Input() ).parse( child );
var source = sources[ input.source ];
if ( input.semantic === 'JOINT' ) {
this.joints = source.read();
} else if ( input.semantic === 'INV_BIND_MATRIX' ) {
this.invBindMatrices = source.read();
}
break;
default:
break;
}
}
};
Skin.prototype.parseWeights = function ( element, sources ) {
var v, vcount, inputs = [];
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
if ( child.nodeType != 1 ) continue;
switch ( child.nodeName ) {
case 'input':
inputs.push( ( new Input() ).parse( child ) );
break;
case 'v':
v = _ints( child.textContent );
break;
case 'vcount':
vcount = _ints( child.textContent );
break;
default:
break;
}
}
var index = 0;
for ( var i = 0; i < vcount.length; i ++ ) {
var numBones = vcount[i];
var vertex_weights = [];
for ( var j = 0; j < numBones; j ++ ) {
var influence = {};
for ( var k = 0; k < inputs.length; k ++ ) {
var input = inputs[ k ];
var value = v[ index + input.offset ];
switch ( input.semantic ) {
case 'JOINT':
influence.joint = value;//this.joints[value];
break;
case 'WEIGHT':
influence.weight = sources[ input.source ].data[ value ];
break;
default:
break;
}
}
vertex_weights.push( influence );
index += inputs.length;
}
for ( var j = 0; j < vertex_weights.length; j ++ ) {
vertex_weights[ j ].index = i;
}
this.weights.push( vertex_weights );
}
};
function VisualScene () {
this.id = "";
this.name = "";
this.nodes = [];
this.scene = new THREE.Group();
}
VisualScene.prototype.getChildById = function( id, recursive ) {
for ( var i = 0; i < this.nodes.length; i ++ ) {
var node = this.nodes[ i ].getChildById( id, recursive );
if ( node ) {
return node;
}
}
return null;
};
VisualScene.prototype.getChildBySid = function( sid, recursive ) {
for ( var i = 0; i < this.nodes.length; i ++ ) {
var node = this.nodes[ i ].getChildBySid( sid, recursive );
if ( node ) {
return node;
}
}
return null;
};
VisualScene.prototype.parse = function( element ) {
this.id = element.getAttribute( 'id' );
this.name = element.getAttribute( 'name' );
this.nodes = [];
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
if ( child.nodeType != 1 ) continue;
switch ( child.nodeName ) {
case 'node':
this.nodes.push( ( new Node() ).parse( child ) );
break;
default:
break;
}
}
return this;
};
function Node() {
this.id = "";
this.name = "";
this.sid = "";
this.nodes = [];
this.controllers = [];
this.transforms = [];
this.geometries = [];
this.channels = [];
this.matrix = new THREE.Matrix4();
}
Node.prototype.getChannelForTransform = function( transformSid ) {
for ( var i = 0; i < this.channels.length; i ++ ) {
var channel = this.channels[i];
var parts = channel.target.split('/');
var id = parts.shift();
var sid = parts.shift();
var dotSyntax = (sid.indexOf(".") >= 0);
var arrSyntax = (sid.indexOf("(") >= 0);
var arrIndices;
var member;
if ( dotSyntax ) {
parts = sid.split(".");
sid = parts.shift();
member = parts.shift();
} else if ( arrSyntax ) {
arrIndices = sid.split("(");
sid = arrIndices.shift();
for ( var j = 0; j < arrIndices.length; j ++ ) {
arrIndices[ j ] = parseInt( arrIndices[ j ].replace( /\)/, '' ) );
}
}
if ( sid === transformSid ) {
channel.info = { sid: sid, dotSyntax: dotSyntax, arrSyntax: arrSyntax, arrIndices: arrIndices };
return channel;
}
}
return null;
};
Node.prototype.getChildById = function ( id, recursive ) {
if ( this.id === id ) {
return this;
}
if ( recursive ) {
for ( var i = 0; i < this.nodes.length; i ++ ) {
var n = this.nodes[ i ].getChildById( id, recursive );
if ( n ) {
return n;
}
}
}
return null;
};
Node.prototype.getChildBySid = function ( sid, recursive ) {
if ( this.sid === sid ) {
return this;
}
if ( recursive ) {
for ( var i = 0; i < this.nodes.length; i ++ ) {
var n = this.nodes[ i ].getChildBySid( sid, recursive );
if ( n ) {
return n;
}
}
}
return null;
};
Node.prototype.getTransformBySid = function ( sid ) {
for ( var i = 0; i < this.transforms.length; i ++ ) {
if ( this.transforms[ i ].sid === sid ) return this.transforms[ i ];
}
return null;
};
Node.prototype.parse = function( element ) {
var url;
this.id = element.getAttribute('id');
this.sid = element.getAttribute('sid');
this.name = element.getAttribute('name');
this.type = element.getAttribute('type');
this.layer = element.getAttribute('layer');
this.type = this.type === 'JOINT' ? this.type : 'NODE';
this.nodes = [];
this.transforms = [];
this.geometries = [];
this.cameras = [];
this.lights = [];
this.controllers = [];
this.matrix = new THREE.Matrix4();
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
if ( child.nodeType != 1 ) continue;
switch ( child.nodeName ) {
case 'node':
this.nodes.push( ( new Node() ).parse( child ) );
break;
case 'instance_camera':
this.cameras.push( ( new InstanceCamera() ).parse( child ) );
break;
case 'instance_controller':
this.controllers.push( ( new InstanceController() ).parse( child ) );
break;
case 'instance_geometry':
this.geometries.push( ( new InstanceGeometry() ).parse( child ) );
break;
case 'instance_light':
this.lights.push( ( new InstanceLight() ).parse( child ) );
break;
case 'instance_node':
url = child.getAttribute( 'url' ).replace( /^#/, '' );
var iNode = getLibraryNode( url );
if ( iNode ) {
this.nodes.push( ( new Node() ).parse( iNode )) ;
}
break;
case 'rotate':
case 'translate':
case 'scale':
case 'matrix':
case 'lookat':
case 'skew':
this.transforms.push( ( new Transform() ).parse( child ) );
break;
case 'extra':
break;
default:
console.log( child.nodeName );
break;
}
}
this.channels = getChannelsForNode( this );
bakeAnimations( this );
this.updateMatrix();
return this;
};
Node.prototype.updateMatrix = function () {
this.matrix.identity();
for ( var i = 0; i < this.transforms.length; i ++ ) {
this.transforms[ i ].apply( this.matrix );
}
};
function Transform () {
this.sid = "";
this.type = "";
this.data = [];
this.obj = null;
}
Transform.prototype.parse = function ( element ) {
this.sid = element.getAttribute( 'sid' );
this.type = element.nodeName;
this.data = _floats( element.textContent );
this.convert();
return this;
};
Transform.prototype.convert = function () {
switch ( this.type ) {
case 'matrix':
this.obj = getConvertedMat4( this.data );
break;
case 'rotate':
this.angle = THREE.Math.degToRad( this.data[3] );
case 'translate':
fixCoords( this.data, -1 );
this.obj = new THREE.Vector3( this.data[ 0 ], this.data[ 1 ], this.data[ 2 ] );
break;
case 'scale':
fixCoords( this.data, 1 );
this.obj = new THREE.Vector3( this.data[ 0 ], this.data[ 1 ], this.data[ 2 ] );
break;
default:
console.log( 'Can not convert Transform of type ' + this.type );
break;
}
};
Transform.prototype.apply = function () {
var m1 = new THREE.Matrix4();
return function ( matrix ) {
switch ( this.type ) {
case 'matrix':
matrix.multiply( this.obj );
break;
case 'translate':
matrix.multiply( m1.makeTranslation( this.obj.x, this.obj.y, this.obj.z ) );
break;
case 'rotate':
matrix.multiply( m1.makeRotationAxis( this.obj, this.angle ) );
break;
case 'scale':
matrix.scale( this.obj );
break;
}
};
}();
Transform.prototype.update = function ( data, member ) {
var members = [ 'X', 'Y', 'Z', 'ANGLE' ];
switch ( this.type ) {
case 'matrix':
if ( ! member ) {
this.obj.copy( data );
} else if ( member.length === 1 ) {
switch ( member[ 0 ] ) {
case 0:
this.obj.n11 = data[ 0 ];
this.obj.n21 = data[ 1 ];
this.obj.n31 = data[ 2 ];
this.obj.n41 = data[ 3 ];
break;
case 1:
this.obj.n12 = data[ 0 ];
this.obj.n22 = data[ 1 ];
this.obj.n32 = data[ 2 ];
this.obj.n42 = data[ 3 ];
break;
case 2:
this.obj.n13 = data[ 0 ];
this.obj.n23 = data[ 1 ];
this.obj.n33 = data[ 2 ];
this.obj.n43 = data[ 3 ];
break;
case 3:
this.obj.n14 = data[ 0 ];
this.obj.n24 = data[ 1 ];
this.obj.n34 = data[ 2 ];
this.obj.n44 = data[ 3 ];
break;
}
} else if ( member.length === 2 ) {
var propName = 'n' + ( member[ 0 ] + 1 ) + ( member[ 1 ] + 1 );
this.obj[ propName ] = data;
} else {
console.log('Incorrect addressing of matrix in transform.');
}
break;
case 'translate':
case 'scale':
if ( Object.prototype.toString.call( member ) === '[object Array]' ) {
member = members[ member[ 0 ] ];
}
switch ( member ) {
case 'X':
this.obj.x = data;
break;
case 'Y':
this.obj.y = data;
break;
case 'Z':
this.obj.z = data;
break;
default:
this.obj.x = data[ 0 ];
this.obj.y = data[ 1 ];
this.obj.z = data[ 2 ];
break;
}
break;
case 'rotate':
if ( Object.prototype.toString.call( member ) === '[object Array]' ) {
member = members[ member[ 0 ] ];
}
switch ( member ) {
case 'X':
this.obj.x = data;
break;
case 'Y':
this.obj.y = data;
break;
case 'Z':
this.obj.z = data;
break;
case 'ANGLE':
this.angle = THREE.Math.degToRad( data );
break;
default:
this.obj.x = data[ 0 ];
this.obj.y = data[ 1 ];
this.obj.z = data[ 2 ];
this.angle = THREE.Math.degToRad( data[ 3 ] );
break;
}
break;
}
};
function InstanceController() {
this.url = "";
this.skeleton = [];
this.instance_material = [];
}
InstanceController.prototype.parse = function ( element ) {
this.url = element.getAttribute('url').replace(/^#/, '');
this.skeleton = [];
this.instance_material = [];
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
if ( child.nodeType !== 1 ) continue;
switch ( child.nodeName ) {
case 'skeleton':
this.skeleton.push( child.textContent.replace(/^#/, '') );
break;
case 'bind_material':
var instances = child.querySelectorAll('instance_material');
for ( var j = 0; j < instances.length; j ++ ) {
var instance = instances[j];
this.instance_material.push( (new InstanceMaterial()).parse(instance) );
}
break;
case 'extra':
break;
default:
break;
}
}
return this;
};
function InstanceMaterial () {
this.symbol = "";
this.target = "";
}
InstanceMaterial.prototype.parse = function ( element ) {
this.symbol = element.getAttribute('symbol');
this.target = element.getAttribute('target').replace(/^#/, '');
return this;
};
function InstanceGeometry() {
this.url = "";
this.instance_material = [];
}
InstanceGeometry.prototype.parse = function ( element ) {
this.url = element.getAttribute('url').replace(/^#/, '');
this.instance_material = [];
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[i];
if ( child.nodeType != 1 ) continue;
if ( child.nodeName === 'bind_material' ) {
var instances = child.querySelectorAll('instance_material');
for ( var j = 0; j < instances.length; j ++ ) {
var instance = instances[j];
this.instance_material.push( (new InstanceMaterial()).parse(instance) );
}
break;
}
}
return this;
};
function Geometry() {
this.id = "";
this.mesh = null;
}
Geometry.prototype.parse = function ( element ) {
this.id = element.getAttribute('id');
extractDoubleSided( this, element );
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[i];
switch ( child.nodeName ) {
case 'mesh':
this.mesh = (new Mesh(this)).parse(child);
break;
case 'extra':
// console.log( child );
break;
default:
break;
}
}
return this;
};
function Mesh( geometry ) {
this.geometry = geometry.id;
this.primitives = [];
this.vertices = null;
this.geometry3js = null;
}
Mesh.prototype.parse = function ( element ) {
this.primitives = [];
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
switch ( child.nodeName ) {
case 'source':
_source( child );
break;
case 'vertices':
this.vertices = ( new Vertices() ).parse( child );
break;
case 'linestrips':
this.primitives.push( ( new LineStrips().parse( child ) ) );
break;
case 'triangles':
this.primitives.push( ( new Triangles().parse( child ) ) );
break;
case 'polygons':
this.primitives.push( ( new Polygons().parse( child ) ) );
break;
case 'polylist':
this.primitives.push( ( new Polylist().parse( child ) ) );
break;
default:
break;
}
}
this.geometry3js = new THREE.Geometry();
if ( this.vertices === null ) {
// TODO (mrdoob): Study case when this is null (carrier.dae)
return this;
}
var vertexData = sources[ this.vertices.input['POSITION'].source ].data;
for ( var i = 0; i < vertexData.length; i += 3 ) {
this.geometry3js.vertices.push( getConvertedVec3( vertexData, i ).clone() );
}
for ( var i = 0; i < this.primitives.length; i ++ ) {
var primitive = this.primitives[ i ];
primitive.setVertices( this.vertices );
this.handlePrimitive( primitive, this.geometry3js );
}
if ( this.geometry3js.calcNormals ) {
this.geometry3js.computeVertexNormals();
delete this.geometry3js.calcNormals;
}
return this;
};
Mesh.prototype.handlePrimitive = function ( primitive, geom ) {
if ( primitive instanceof LineStrips ) {
// TODO: Handle indices. Maybe easier with BufferGeometry?
geom.isLineStrip = true;
return;
}
var j, k, pList = primitive.p, inputs = primitive.inputs;
var input, index, idx32;
var source, numParams;
var vcIndex = 0, vcount = 3, maxOffset = 0;
var texture_sets = [];
for ( j = 0; j < inputs.length; j ++ ) {
input = inputs[ j ];
var offset = input.offset + 1;
maxOffset = (maxOffset < offset) ? offset : maxOffset;
switch ( input.semantic ) {
case 'TEXCOORD':
texture_sets.push( input.set );
break;
}
}
for ( var pCount = 0; pCount < pList.length; ++ pCount ) {
var p = pList[ pCount ], i = 0;
while ( i < p.length ) {
var vs = [];
var ns = [];
var ts = null;
var cs = [];
if ( primitive.vcount ) {
vcount = primitive.vcount.length ? primitive.vcount[ vcIndex ++ ] : primitive.vcount;
} else {
vcount = p.length / maxOffset;
}
for ( j = 0; j < vcount; j ++ ) {
for ( k = 0; k < inputs.length; k ++ ) {
input = inputs[ k ];
source = sources[ input.source ];
index = p[ i + ( j * maxOffset ) + input.offset ];
numParams = source.accessor.params.length;
idx32 = index * numParams;
switch ( input.semantic ) {
case 'VERTEX':
vs.push( index );
break;
case 'NORMAL':
ns.push( getConvertedVec3( source.data, idx32 ) );
break;
case 'TEXCOORD':
ts = ts || { };
if ( ts[ input.set ] === undefined ) ts[ input.set ] = [];
// invert the V
ts[ input.set ].push( new THREE.Vector2( source.data[ idx32 ], source.data[ idx32 + 1 ] ) );
break;
case 'COLOR':
cs.push( new THREE.Color().setRGB( source.data[ idx32 ], source.data[ idx32 + 1 ], source.data[ idx32 + 2 ] ) );
break;
default:
break;
}
}
}
if ( ns.length === 0 ) {
// check the vertices inputs
input = this.vertices.input.NORMAL;
if ( input ) {
source = sources[ input.source ];
numParams = source.accessor.params.length;
for ( var ndx = 0, len = vs.length; ndx < len; ndx ++ ) {
ns.push( getConvertedVec3( source.data, vs[ ndx ] * numParams ) );
}
} else {
geom.calcNormals = true;
}
}
if ( !ts ) {
ts = { };
// check the vertices inputs
input = this.vertices.input.TEXCOORD;
if ( input ) {
texture_sets.push( input.set );
source = sources[ input.source ];
numParams = source.accessor.params.length;
for ( var ndx = 0, len = vs.length; ndx < len; ndx ++ ) {
idx32 = vs[ ndx ] * numParams;
if ( ts[ input.set ] === undefined ) ts[ input.set ] = [ ];
// invert the V
ts[ input.set ].push( new THREE.Vector2( source.data[ idx32 ], 1.0 - source.data[ idx32 + 1 ] ) );
}
}
}
if ( cs.length === 0 ) {
// check the vertices inputs
input = this.vertices.input.COLOR;
if ( input ) {
source = sources[ input.source ];
numParams = source.accessor.params.length;
for ( var ndx = 0, len = vs.length; ndx < len; ndx ++ ) {
idx32 = vs[ ndx ] * numParams;
cs.push( new THREE.Color().setRGB( source.data[ idx32 ], source.data[ idx32 + 1 ], source.data[ idx32 + 2 ] ) );
}
}
}
var face = null, faces = [], uv, uvArr;
if ( vcount === 3 ) {
faces.push( new THREE.Face3( vs[0], vs[1], vs[2], ns, cs.length ? cs : new THREE.Color() ) );
} else if ( vcount === 4 ) {
faces.push( new THREE.Face3( vs[0], vs[1], vs[3], ns.length ? [ ns[0].clone(), ns[1].clone(), ns[3].clone() ] : [], cs.length ? [ cs[0], cs[1], cs[3] ] : new THREE.Color() ) );
faces.push( new THREE.Face3( vs[1], vs[2], vs[3], ns.length ? [ ns[1].clone(), ns[2].clone(), ns[3].clone() ] : [], cs.length ? [ cs[1], cs[2], cs[3] ] : new THREE.Color() ) );
} else if ( vcount > 4 && options.subdivideFaces ) {
var clr = cs.length ? cs : new THREE.Color(),
vec1, vec2, vec3, v1, v2, norm;
// subdivide into multiple Face3s
for ( k = 1; k < vcount - 1; ) {
faces.push( new THREE.Face3( vs[0], vs[k], vs[k + 1], ns.length ? [ ns[0].clone(), ns[k ++].clone(), ns[k].clone() ] : [], clr ) );
}
}
if ( faces.length ) {
for ( var ndx = 0, len = faces.length; ndx < len; ndx ++ ) {
face = faces[ndx];
face.daeMaterial = primitive.material;
geom.faces.push( face );
for ( k = 0; k < texture_sets.length; k ++ ) {
uv = ts[ texture_sets[k] ];
if ( vcount > 4 ) {
// Grab the right UVs for the vertices in this face
uvArr = [ uv[0], uv[ndx + 1], uv[ndx + 2] ];
} else if ( vcount === 4 ) {
if ( ndx === 0 ) {
uvArr = [ uv[0], uv[1], uv[3] ];
} else {
uvArr = [ uv[1].clone(), uv[2], uv[3].clone() ];
}
} else {
uvArr = [ uv[0], uv[1], uv[2] ];
}
if ( geom.faceVertexUvs[k] === undefined ) {
geom.faceVertexUvs[k] = [];
}
geom.faceVertexUvs[k].push( uvArr );
}
}
} else {
console.log( 'dropped face with vcount ' + vcount + ' for geometry with id: ' + geom.id );
}
i += maxOffset * vcount;
}
}
};
function Polygons () {
this.material = "";
this.count = 0;
this.inputs = [];
this.vcount = null;
this.p = [];
this.geometry = new THREE.Geometry();
}
Polygons.prototype.setVertices = function ( vertices ) {
for ( var i = 0; i < this.inputs.length; i ++ ) {
if ( this.inputs[ i ].source === vertices.id ) {
this.inputs[ i ].source = vertices.input[ 'POSITION' ].source;
}
}
};
Polygons.prototype.parse = function ( element ) {
this.material = element.getAttribute( 'material' );
this.count = _attr_as_int( element, 'count', 0 );
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
switch ( child.nodeName ) {
case 'input':
this.inputs.push( ( new Input() ).parse( element.childNodes[ i ] ) );
break;
case 'vcount':
this.vcount = _ints( child.textContent );
break;
case 'p':
this.p.push( _ints( child.textContent ) );
break;
case 'ph':
console.warn( 'polygon holes not yet supported!' );
break;
default:
break;
}
}
return this;
};
function Polylist () {
Polygons.call( this );
this.vcount = [];
}
Polylist.prototype = Object.create( Polygons.prototype );
Polylist.prototype.constructor = Polylist;
function LineStrips() {
Polygons.call( this );
this.vcount = 1;
}
LineStrips.prototype = Object.create( Polygons.prototype );
LineStrips.prototype.constructor = LineStrips;
function Triangles () {
Polygons.call( this );
this.vcount = 3;
}
Triangles.prototype = Object.create( Polygons.prototype );
Triangles.prototype.constructor = Triangles;
function Accessor() {
this.source = "";
this.count = 0;
this.stride = 0;
this.params = [];
}
Accessor.prototype.parse = function ( element ) {
this.params = [];
this.source = element.getAttribute( 'source' );
this.count = _attr_as_int( element, 'count', 0 );
this.stride = _attr_as_int( element, 'stride', 0 );
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
if ( child.nodeName === 'param' ) {
var param = {};
param[ 'name' ] = child.getAttribute( 'name' );
param[ 'type' ] = child.getAttribute( 'type' );
this.params.push( param );
}
}
return this;
};
function Vertices() {
this.input = {};
}
Vertices.prototype.parse = function ( element ) {
this.id = element.getAttribute('id');
for ( var i = 0; i < element.childNodes.length; i ++ ) {
if ( element.childNodes[i].nodeName === 'input' ) {
var input = ( new Input() ).parse( element.childNodes[ i ] );
this.input[ input.semantic ] = input;
}
}
return this;
};
function Input () {
this.semantic = "";
this.offset = 0;
this.source = "";
this.set = 0;
}
Input.prototype.parse = function ( element ) {
this.semantic = element.getAttribute('semantic');
this.source = element.getAttribute('source').replace(/^#/, '');
this.set = _attr_as_int(element, 'set', -1);
this.offset = _attr_as_int(element, 'offset', 0);
if ( this.semantic === 'TEXCOORD' && this.set < 0 ) {
this.set = 0;
}
return this;
};
function Source ( id ) {
this.id = id;
this.type = null;
}
Source.prototype.parse = function ( element ) {
this.id = element.getAttribute( 'id' );
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[i];
switch ( child.nodeName ) {
case 'bool_array':
this.data = _bools( child.textContent );
this.type = child.nodeName;
break;
case 'float_array':
this.data = _floats( child.textContent );
this.type = child.nodeName;
break;
case 'int_array':
this.data = _ints( child.textContent );
this.type = child.nodeName;
break;
case 'IDREF_array':
case 'Name_array':
this.data = _strings( child.textContent );
this.type = child.nodeName;
break;
case 'technique_common':
for ( var j = 0; j < child.childNodes.length; j ++ ) {
if ( child.childNodes[ j ].nodeName === 'accessor' ) {
this.accessor = ( new Accessor() ).parse( child.childNodes[ j ] );
break;
}
}
break;
default:
// console.log(child.nodeName);
break;
}
}
return this;
};
Source.prototype.read = function () {
var result = [];
//for (var i = 0; i < this.accessor.params.length; i++) {
var param = this.accessor.params[ 0 ];
//console.log(param.name + " " + param.type);
switch ( param.type ) {
case 'IDREF':
case 'Name': case 'name':
case 'float':
return this.data;
case 'float4x4':
for ( var j = 0; j < this.data.length; j += 16 ) {
var s = this.data.slice( j, j + 16 );
var m = getConvertedMat4( s );
result.push( m );
}
break;
default:
console.log( 'ColladaLoader: Source: Read dont know how to read ' + param.type + '.' );
break;
}
//}
return result;
};
function Material () {
this.id = "";
this.name = "";
this.instance_effect = null;
}
Material.prototype.parse = function ( element ) {
this.id = element.getAttribute( 'id' );
this.name = element.getAttribute( 'name' );
for ( var i = 0; i < element.childNodes.length; i ++ ) {
if ( element.childNodes[ i ].nodeName === 'instance_effect' ) {
this.instance_effect = ( new InstanceEffect() ).parse( element.childNodes[ i ] );
break;
}
}
return this;
};
function ColorOrTexture () {
this.color = new THREE.Color();
this.color.setRGB( Math.random(), Math.random(), Math.random() );
this.color.a = 1.0;
this.texture = null;
this.texcoord = null;
this.texOpts = null;
}
ColorOrTexture.prototype.isColor = function () {
return ( this.texture === null );
};
ColorOrTexture.prototype.isTexture = function () {
return ( this.texture != null );
};
ColorOrTexture.prototype.parse = function ( element ) {
if (element.nodeName === 'transparent') {
this.opaque = element.getAttribute('opaque');
}
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
if ( child.nodeType != 1 ) continue;
switch ( child.nodeName ) {
case 'color':
var rgba = _floats( child.textContent );
this.color = new THREE.Color();
this.color.setRGB( rgba[0], rgba[1], rgba[2] );
this.color.a = rgba[3];
break;
case 'texture':
this.texture = child.getAttribute('texture');
this.texcoord = child.getAttribute('texcoord');
// Defaults from:
// https://collada.org/mediawiki/index.php/Maya_texture_placement_MAYA_extension
this.texOpts = {
offsetU: 0,
offsetV: 0,
repeatU: 1,
repeatV: 1,
wrapU: 1,
wrapV: 1
};
this.parseTexture( child );
break;
default:
break;
}
}
return this;
};
ColorOrTexture.prototype.parseTexture = function ( element ) {
if ( ! element.childNodes ) return this;
// This should be supported by Maya, 3dsMax, and MotionBuilder
if ( element.childNodes[1] && element.childNodes[1].nodeName === 'extra' ) {
element = element.childNodes[1];
if ( element.childNodes[1] && element.childNodes[1].nodeName === 'technique' ) {
element = element.childNodes[1];
}
}
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
switch ( child.nodeName ) {
case 'offsetU':
case 'offsetV':
case 'repeatU':
case 'repeatV':
this.texOpts[ child.nodeName ] = parseFloat( child.textContent );
break;
case 'wrapU':
case 'wrapV':
// some dae have a value of true which becomes NaN via parseInt
if ( child.textContent.toUpperCase() === 'TRUE' ) {
this.texOpts[ child.nodeName ] = 1;
} else {
this.texOpts[ child.nodeName ] = parseInt( child.textContent );
}
break;
default:
this.texOpts[ child.nodeName ] = child.textContent;
break;
}
}
return this;
};
function Shader ( type, effect ) {
this.type = type;
this.effect = effect;
this.material = null;
}
Shader.prototype.parse = function ( element ) {
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
if ( child.nodeType != 1 ) continue;
switch ( child.nodeName ) {
case 'emission':
case 'diffuse':
case 'specular':
case 'transparent':
this[ child.nodeName ] = ( new ColorOrTexture() ).parse( child );
break;
case 'bump':
// If 'bumptype' is 'heightfield', create a 'bump' property
// Else if 'bumptype' is 'normalmap', create a 'normal' property
// (Default to 'bump')
var bumpType = child.getAttribute( 'bumptype' );
if ( bumpType ) {
if ( bumpType.toLowerCase() === "heightfield" ) {
this[ 'bump' ] = ( new ColorOrTexture() ).parse( child );
} else if ( bumpType.toLowerCase() === "normalmap" ) {
this[ 'normal' ] = ( new ColorOrTexture() ).parse( child );
} else {
console.error( "Shader.prototype.parse: Invalid value for attribute 'bumptype' (" + bumpType + ") - valid bumptypes are 'HEIGHTFIELD' and 'NORMALMAP' - defaulting to 'HEIGHTFIELD'" );
this[ 'bump' ] = ( new ColorOrTexture() ).parse( child );
}
} else {
console.warn( "Shader.prototype.parse: Attribute 'bumptype' missing from bump node - defaulting to 'HEIGHTFIELD'" );
this[ 'bump' ] = ( new ColorOrTexture() ).parse( child );
}
break;
case 'shininess':
case 'reflectivity':
case 'index_of_refraction':
case 'transparency':
var f = child.querySelectorAll('float');
if ( f.length > 0 )
this[ child.nodeName ] = parseFloat( f[ 0 ].textContent );
break;
default:
break;
}
}
this.create();
return this;
};
Shader.prototype.create = function() {
var props = {};
var transparent = false;
if (this['transparency'] !== undefined && this['transparent'] !== undefined) {
// convert transparent color RBG to average value
var transparentColor = this['transparent'];
var transparencyLevel = (this.transparent.color.r + this.transparent.color.g + this.transparent.color.b) / 3 * this.transparency;
if (transparencyLevel > 0) {
transparent = true;
props[ 'transparent' ] = true;
props[ 'opacity' ] = 1 - transparencyLevel;
}
}
var keys = {
'diffuse':'map',
'ambient':'lightMap',
'specular':'specularMap',
'emission':'emissionMap',
'bump':'bumpMap',
'normal':'normalMap'
};
for ( var prop in this ) {
switch ( prop ) {
case 'ambient':
case 'emission':
case 'diffuse':
case 'specular':
case 'bump':
case 'normal':
var cot = this[ prop ];
if ( cot instanceof ColorOrTexture ) {
if ( cot.isTexture() ) {
var samplerId = cot.texture;
var surfaceId = this.effect.sampler[samplerId];
if ( surfaceId !== undefined && surfaceId.source !== undefined ) {
var surface = this.effect.surface[surfaceId.source];
if ( surface !== undefined ) {
var image = images[ surface.init_from ];
if ( image ) {
var url = baseUrl + image.init_from;
var texture;
var loader = THREE.Loader.Handlers.get( url );
if ( loader !== null ) {
texture = loader.load( url );
} else {
texture = new THREE.Texture();
loadTextureImage( texture, url );
}
texture.wrapS = cot.texOpts.wrapU ? THREE.RepeatWrapping : THREE.ClampToEdgeWrapping;
texture.wrapT = cot.texOpts.wrapV ? THREE.RepeatWrapping : THREE.ClampToEdgeWrapping;
texture.offset.x = cot.texOpts.offsetU;
texture.offset.y = cot.texOpts.offsetV;
texture.repeat.x = cot.texOpts.repeatU;
texture.repeat.y = cot.texOpts.repeatV;
props[keys[prop]] = texture;
// Texture with baked lighting?
if (prop === 'emission') props['emissive'] = 0xffffff;
}
}
}
} else if ( prop === 'diffuse' || !transparent ) {
if ( prop === 'emission' ) {
props[ 'emissive' ] = cot.color.getHex();
} else {
props[ prop ] = cot.color.getHex();
}
}
}
break;
case 'shininess':
props[ prop ] = this[ prop ];
break;
case 'reflectivity':
props[ prop ] = this[ prop ];
if ( props[ prop ] > 0.0 ) props['envMap'] = options.defaultEnvMap;
props['combine'] = THREE.MixOperation; //mix regular shading with reflective component
break;
case 'index_of_refraction':
props[ 'refractionRatio' ] = this[ prop ]; //TODO: "index_of_refraction" becomes "refractionRatio" in shader, but I'm not sure if the two are actually comparable
if ( this[ prop ] !== 1.0 ) props['envMap'] = options.defaultEnvMap;
break;
case 'transparency':
// gets figured out up top
break;
default:
break;
}
}
props[ 'shading' ] = preferredShading;
props[ 'side' ] = this.effect.doubleSided ? THREE.DoubleSide : THREE.FrontSide;
if ( props.diffuse !== undefined ) {
props.color = props.diffuse;
delete props.diffuse;
}
switch ( this.type ) {
case 'constant':
if (props.emissive != undefined) props.color = props.emissive;
this.material = new THREE.MeshBasicMaterial( props );
break;
case 'phong':
case 'blinn':
this.material = new THREE.MeshPhongMaterial( props );
break;
case 'lambert':
default:
this.material = new THREE.MeshLambertMaterial( props );
break;
}
return this.material;
};
function Surface ( effect ) {
this.effect = effect;
this.init_from = null;
this.format = null;
}
Surface.prototype.parse = function ( element ) {
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
if ( child.nodeType != 1 ) continue;
switch ( child.nodeName ) {
case 'init_from':
this.init_from = child.textContent;
break;
case 'format':
this.format = child.textContent;
break;
default:
console.log( "unhandled Surface prop: " + child.nodeName );
break;
}
}
return this;
};
function Sampler2D ( effect ) {
this.effect = effect;
this.source = null;
this.wrap_s = null;
this.wrap_t = null;
this.minfilter = null;
this.magfilter = null;
this.mipfilter = null;
}
Sampler2D.prototype.parse = function ( element ) {
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
if ( child.nodeType != 1 ) continue;
switch ( child.nodeName ) {
case 'source':
this.source = child.textContent;
break;
case 'minfilter':
this.minfilter = child.textContent;
break;
case 'magfilter':
this.magfilter = child.textContent;
break;
case 'mipfilter':
this.mipfilter = child.textContent;
break;
case 'wrap_s':
this.wrap_s = child.textContent;
break;
case 'wrap_t':
this.wrap_t = child.textContent;
break;
default:
console.log( "unhandled Sampler2D prop: " + child.nodeName );
break;
}
}
return this;
};
function Effect () {
this.id = "";
this.name = "";
this.shader = null;
this.surface = {};
this.sampler = {};
}
Effect.prototype.create = function () {
if ( this.shader === null ) {
return null;
}
};
Effect.prototype.parse = function ( element ) {
this.id = element.getAttribute( 'id' );
this.name = element.getAttribute( 'name' );
extractDoubleSided( this, element );
this.shader = null;
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
if ( child.nodeType != 1 ) continue;
switch ( child.nodeName ) {
case 'profile_COMMON':
this.parseTechnique( this.parseProfileCOMMON( child ) );
break;
default:
break;
}
}
return this;
};
Effect.prototype.parseNewparam = function ( element ) {
var sid = element.getAttribute( 'sid' );
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
if ( child.nodeType != 1 ) continue;
switch ( child.nodeName ) {
case 'surface':
this.surface[sid] = ( new Surface( this ) ).parse( child );
break;
case 'sampler2D':
this.sampler[sid] = ( new Sampler2D( this ) ).parse( child );
break;
case 'extra':
break;
default:
console.log( child.nodeName );
break;
}
}
};
Effect.prototype.parseProfileCOMMON = function ( element ) {
var technique;
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
if ( child.nodeType != 1 ) continue;
switch ( child.nodeName ) {
case 'profile_COMMON':
this.parseProfileCOMMON( child );
break;
case 'technique':
technique = child;
break;
case 'newparam':
this.parseNewparam( child );
break;
case 'image':
var _image = ( new _Image() ).parse( child );
images[ _image.id ] = _image;
break;
case 'extra':
break;
default:
console.log( child.nodeName );
break;
}
}
return technique;
};
Effect.prototype.parseTechnique = function ( element ) {
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[i];
if ( child.nodeType != 1 ) continue;
switch ( child.nodeName ) {
case 'constant':
case 'lambert':
case 'blinn':
case 'phong':
this.shader = ( new Shader( child.nodeName, this ) ).parse( child );
break;
case 'extra':
this.parseExtra(child);
break;
default:
break;
}
}
};
Effect.prototype.parseExtra = function ( element ) {
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[i];
if ( child.nodeType != 1 ) continue;
switch ( child.nodeName ) {
case 'technique':
this.parseExtraTechnique( child );
break;
default:
break;
}
}
};
Effect.prototype.parseExtraTechnique = function ( element ) {
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[i];
if ( child.nodeType != 1 ) continue;
switch ( child.nodeName ) {
case 'bump':
this.shader.parse( element );
break;
default:
break;
}
}
};
function InstanceEffect () {
this.url = "";
}
InstanceEffect.prototype.parse = function ( element ) {
this.url = element.getAttribute( 'url' ).replace( /^#/, '' );
return this;
};
function Animation() {
this.id = "";
this.name = "";
this.source = {};
this.sampler = [];
this.channel = [];
}
Animation.prototype.parse = function ( element ) {
this.id = element.getAttribute( 'id' );
this.name = element.getAttribute( 'name' );
this.source = {};
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
if ( child.nodeType != 1 ) continue;
switch ( child.nodeName ) {
case 'animation':
var anim = ( new Animation() ).parse( child );
for ( var src in anim.source ) {
this.source[ src ] = anim.source[ src ];
}
for ( var j = 0; j < anim.channel.length; j ++ ) {
this.channel.push( anim.channel[ j ] );
this.sampler.push( anim.sampler[ j ] );
}
break;
case 'source':
var src = ( new Source() ).parse( child );
this.source[ src.id ] = src;
break;
case 'sampler':
this.sampler.push( ( new Sampler( this ) ).parse( child ) );
break;
case 'channel':
this.channel.push( ( new Channel( this ) ).parse( child ) );
break;
default:
break;
}
}
return this;
};
function Channel( animation ) {
this.animation = animation;
this.source = "";
this.target = "";
this.fullSid = null;
this.sid = null;
this.dotSyntax = null;
this.arrSyntax = null;
this.arrIndices = null;
this.member = null;
}
Channel.prototype.parse = function ( element ) {
this.source = element.getAttribute( 'source' ).replace( /^#/, '' );
this.target = element.getAttribute( 'target' );
var parts = this.target.split( '/' );
var id = parts.shift();
var sid = parts.shift();
var dotSyntax = ( sid.indexOf(".") >= 0 );
var arrSyntax = ( sid.indexOf("(") >= 0 );
if ( dotSyntax ) {
parts = sid.split(".");
this.sid = parts.shift();
this.member = parts.shift();
} else if ( arrSyntax ) {
var arrIndices = sid.split("(");
this.sid = arrIndices.shift();
for (var j = 0; j < arrIndices.length; j ++ ) {
arrIndices[j] = parseInt( arrIndices[j].replace(/\)/, '') );
}
this.arrIndices = arrIndices;
} else {
this.sid = sid;
}
this.fullSid = sid;
this.dotSyntax = dotSyntax;
this.arrSyntax = arrSyntax;
return this;
};
function Sampler ( animation ) {
this.id = "";
this.animation = animation;
this.inputs = [];
this.input = null;
this.output = null;
this.strideOut = null;
this.interpolation = null;
this.startTime = null;
this.endTime = null;
this.duration = 0;
}
Sampler.prototype.parse = function ( element ) {
this.id = element.getAttribute( 'id' );
this.inputs = [];
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
if ( child.nodeType != 1 ) continue;
switch ( child.nodeName ) {
case 'input':
this.inputs.push( (new Input()).parse( child ) );
break;
default:
break;
}
}
return this;
};
Sampler.prototype.create = function () {
for ( var i = 0; i < this.inputs.length; i ++ ) {
var input = this.inputs[ i ];
var source = this.animation.source[ input.source ];
switch ( input.semantic ) {
case 'INPUT':
this.input = source.read();
break;
case 'OUTPUT':
this.output = source.read();
this.strideOut = source.accessor.stride;
break;
case 'INTERPOLATION':
this.interpolation = source.read();
break;
case 'IN_TANGENT':
break;
case 'OUT_TANGENT':
break;
default:
console.log(input.semantic);
break;
}
}
this.startTime = 0;
this.endTime = 0;
this.duration = 0;
if ( this.input.length ) {
this.startTime = 100000000;
this.endTime = -100000000;
for ( var i = 0; i < this.input.length; i ++ ) {
this.startTime = Math.min( this.startTime, this.input[ i ] );
this.endTime = Math.max( this.endTime, this.input[ i ] );
}
this.duration = this.endTime - this.startTime;
}
};
Sampler.prototype.getData = function ( type, ndx, member ) {
var data;
if ( type === 'matrix' && this.strideOut === 16 ) {
data = this.output[ ndx ];
} else if ( this.strideOut > 1 ) {
data = [];
ndx *= this.strideOut;
for ( var i = 0; i < this.strideOut; ++ i ) {
data[ i ] = this.output[ ndx + i ];
}
if ( this.strideOut === 3 ) {
switch ( type ) {
case 'rotate':
case 'translate':
fixCoords( data, -1 );
break;
case 'scale':
fixCoords( data, 1 );
break;
}
} else if ( this.strideOut === 4 && type === 'matrix' ) {
fixCoords( data, -1 );
}
} else {
data = this.output[ ndx ];
if ( member && type === 'translate' ) {
data = getConvertedTranslation( member, data );
}
}
return data;
};
function Key ( time ) {
this.targets = [];
this.time = time;
}
Key.prototype.addTarget = function ( fullSid, transform, member, data ) {
this.targets.push( {
sid: fullSid,
member: member,
transform: transform,
data: data
} );
};
Key.prototype.apply = function ( opt_sid ) {
for ( var i = 0; i < this.targets.length; ++ i ) {
var target = this.targets[ i ];
if ( !opt_sid || target.sid === opt_sid ) {
target.transform.update( target.data, target.member );
}
}
};
Key.prototype.getTarget = function ( fullSid ) {
for ( var i = 0; i < this.targets.length; ++ i ) {
if ( this.targets[ i ].sid === fullSid ) {
return this.targets[ i ];
}
}
return null;
};
Key.prototype.hasTarget = function ( fullSid ) {
for ( var i = 0; i < this.targets.length; ++ i ) {
if ( this.targets[ i ].sid === fullSid ) {
return true;
}
}
return false;
};
// TODO: Currently only doing linear interpolation. Should support full COLLADA spec.
Key.prototype.interpolate = function ( nextKey, time ) {
for ( var i = 0, l = this.targets.length; i < l; i ++ ) {
var target = this.targets[ i ],
nextTarget = nextKey.getTarget( target.sid ),
data;
if ( target.transform.type !== 'matrix' && nextTarget ) {
var scale = ( time - this.time ) / ( nextKey.time - this.time ),
nextData = nextTarget.data,
prevData = target.data;
if ( scale < 0 ) scale = 0;
if ( scale > 1 ) scale = 1;
if ( prevData.length ) {
data = [];
for ( var j = 0; j < prevData.length; ++ j ) {
data[ j ] = prevData[ j ] + ( nextData[ j ] - prevData[ j ] ) * scale;
}
} else {
data = prevData + ( nextData - prevData ) * scale;
}
} else {
data = target.data;
}
target.transform.update( data, target.member );
}
};
// Camera
function Camera() {
this.id = "";
this.name = "";
this.technique = "";
}
Camera.prototype.parse = function ( element ) {
this.id = element.getAttribute( 'id' );
this.name = element.getAttribute( 'name' );
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
if ( child.nodeType != 1 ) continue;
switch ( child.nodeName ) {
case 'optics':
this.parseOptics( child );
break;
default:
break;
}
}
return this;
};
Camera.prototype.parseOptics = function ( element ) {
for ( var i = 0; i < element.childNodes.length; i ++ ) {
if ( element.childNodes[ i ].nodeName === 'technique_common' ) {
var technique = element.childNodes[ i ];
for ( var j = 0; j < technique.childNodes.length; j ++ ) {
this.technique = technique.childNodes[ j ].nodeName;
if ( this.technique === 'perspective' ) {
var perspective = technique.childNodes[ j ];
for ( var k = 0; k < perspective.childNodes.length; k ++ ) {
var param = perspective.childNodes[ k ];
switch ( param.nodeName ) {
case 'yfov':
this.yfov = param.textContent;
break;
case 'xfov':
this.xfov = param.textContent;
break;
case 'znear':
this.znear = param.textContent;
break;
case 'zfar':
this.zfar = param.textContent;
break;
case 'aspect_ratio':
this.aspect_ratio = param.textContent;
break;
}
}
} else if ( this.technique === 'orthographic' ) {
var orthographic = technique.childNodes[ j ];
for ( var k = 0; k < orthographic.childNodes.length; k ++ ) {
var param = orthographic.childNodes[ k ];
switch ( param.nodeName ) {
case 'xmag':
this.xmag = param.textContent;
break;
case 'ymag':
this.ymag = param.textContent;
break;
case 'znear':
this.znear = param.textContent;
break;
case 'zfar':
this.zfar = param.textContent;
break;
case 'aspect_ratio':
this.aspect_ratio = param.textContent;
break;
}
}
}
}
}
}
return this;
};
function InstanceCamera() {
this.url = "";
}
InstanceCamera.prototype.parse = function ( element ) {
this.url = element.getAttribute('url').replace(/^#/, '');
return this;
};
// Light
function Light() {
this.id = "";
this.name = "";
this.technique = "";
}
Light.prototype.parse = function ( element ) {
this.id = element.getAttribute( 'id' );
this.name = element.getAttribute( 'name' );
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
if ( child.nodeType != 1 ) continue;
switch ( child.nodeName ) {
case 'technique_common':
this.parseCommon( child );
break;
case 'technique':
this.parseTechnique( child );
break;
default:
break;
}
}
return this;
};
Light.prototype.parseCommon = function ( element ) {
for ( var i = 0; i < element.childNodes.length; i ++ ) {
switch ( element.childNodes[ i ].nodeName ) {
case 'directional':
case 'point':
case 'spot':
case 'ambient':
this.technique = element.childNodes[ i ].nodeName;
var light = element.childNodes[ i ];
for ( var j = 0; j < light.childNodes.length; j ++ ) {
var child = light.childNodes[j];
switch ( child.nodeName ) {
case 'color':
var rgba = _floats( child.textContent );
this.color = new THREE.Color(0);
this.color.setRGB( rgba[0], rgba[1], rgba[2] );
this.color.a = rgba[3];
break;
case 'falloff_angle':
this.falloff_angle = parseFloat( child.textContent );
break;
case 'quadratic_attenuation':
var f = parseFloat( child.textContent );
this.distance = f ? Math.sqrt( 1 / f ) : 0;
}
}
}
}
return this;
};
Light.prototype.parseTechnique = function ( element ) {
this.profile = element.getAttribute( 'profile' );
for ( var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
switch ( child.nodeName ) {
case 'intensity':
this.intensity = parseFloat(child.textContent);
break;
}
}
return this;
};
function InstanceLight() {
this.url = "";
}
InstanceLight.prototype.parse = function ( element ) {
this.url = element.getAttribute('url').replace(/^#/, '');
return this;
};
function KinematicsModel( ) {
this.id = '';
this.name = '';
this.joints = [];
this.links = [];
}
KinematicsModel.prototype.parse = function( element ) {
this.id = element.getAttribute('id');
this.name = element.getAttribute('name');
this.joints = [];
this.links = [];
for (var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
if ( child.nodeType != 1 ) continue;
switch ( child.nodeName ) {
case 'technique_common':
this.parseCommon(child);
break;
default:
break;
}
}
return this;
};
KinematicsModel.prototype.parseCommon = function( element ) {
for (var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
if ( child.nodeType != 1 ) continue;
switch ( element.childNodes[ i ].nodeName ) {
case 'joint':
this.joints.push( (new Joint()).parse(child) );
break;
case 'link':
this.links.push( (new Link()).parse(child) );
break;
default:
break;
}
}
return this;
};
function Joint( ) {
this.sid = '';
this.name = '';
this.axis = new THREE.Vector3();
this.limits = {
min: 0,
max: 0
};
this.type = '';
this.static = false;
this.zeroPosition = 0.0;
this.middlePosition = 0.0;
}
Joint.prototype.parse = function( element ) {
this.sid = element.getAttribute('sid');
this.name = element.getAttribute('name');
this.axis = new THREE.Vector3();
this.limits = {
min: 0,
max: 0
};
this.type = '';
this.static = false;
this.zeroPosition = 0.0;
this.middlePosition = 0.0;
var axisElement = element.querySelector('axis');
var _axis = _floats(axisElement.textContent);
this.axis = getConvertedVec3(_axis, 0);
var min = element.querySelector('limits min') ? parseFloat(element.querySelector('limits min').textContent) : -360;
var max = element.querySelector('limits max') ? parseFloat(element.querySelector('limits max').textContent) : 360;
this.limits = {
min: min,
max: max
};
var jointTypes = [ 'prismatic', 'revolute' ];
for (var i = 0; i < jointTypes.length; i ++ ) {
var type = jointTypes[ i ];
var jointElement = element.querySelector(type);
if ( jointElement ) {
this.type = type;
}
}
// if the min is equal to or somehow greater than the max, consider the joint static
if ( this.limits.min >= this.limits.max ) {
this.static = true;
}
this.middlePosition = (this.limits.min + this.limits.max) / 2.0;
return this;
};
function Link( ) {
this.sid = '';
this.name = '';
this.transforms = [];
this.attachments = [];
}
Link.prototype.parse = function( element ) {
this.sid = element.getAttribute('sid');
this.name = element.getAttribute('name');
this.transforms = [];
this.attachments = [];
for (var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
if ( child.nodeType != 1 ) continue;
switch ( child.nodeName ) {
case 'attachment_full':
this.attachments.push( (new Attachment()).parse(child) );
break;
case 'rotate':
case 'translate':
case 'matrix':
this.transforms.push( (new Transform()).parse(child) );
break;
default:
break;
}
}
return this;
};
function Attachment( ) {
this.joint = '';
this.transforms = [];
this.links = [];
}
Attachment.prototype.parse = function( element ) {
this.joint = element.getAttribute('joint').split('/').pop();
this.links = [];
for (var i = 0; i < element.childNodes.length; i ++ ) {
var child = element.childNodes[ i ];
if ( child.nodeType != 1 ) continue;
switch ( child.nodeName ) {
case 'link':
this.links.push( (new Link()).parse(child) );
break;
case 'rotate':
case 'translate':
case 'matrix':
this.transforms.push( (new Transform()).parse(child) );
break;
default:
break;
}
}
return this;
};
function _source( element ) {
var id = element.getAttribute( 'id' );
if ( sources[ id ] != undefined ) {
return sources[ id ];
}
sources[ id ] = ( new Source(id )).parse( element );
return sources[ id ];
}
function _nsResolver( nsPrefix ) {
if ( nsPrefix === "dae" ) {
return "http://www.collada.org/2005/11/COLLADASchema";
}
return null;
}
function _bools( str ) {
var raw = _strings( str );
var data = [];
for ( var i = 0, l = raw.length; i < l; i ++ ) {
data.push( (raw[i] === 'true' || raw[i] === '1') ? true : false );
}
return data;
}
function _floats( str ) {
var raw = _strings(str);
var data = [];
for ( var i = 0, l = raw.length; i < l; i ++ ) {
data.push( parseFloat( raw[ i ] ) );
}
return data;
}
function _ints( str ) {
var raw = _strings( str );
var data = [];
for ( var i = 0, l = raw.length; i < l; i ++ ) {
data.push( parseInt( raw[ i ], 10 ) );
}
return data;
}
function _strings( str ) {
return ( str.length > 0 ) ? _trimString( str ).split( /\s+/ ) : [];
}
function _trimString( str ) {
return str.replace( /^\s+/, "" ).replace( /\s+$/, "" );
}
function _attr_as_float( element, name, defaultValue ) {
if ( element.hasAttribute( name ) ) {
return parseFloat( element.getAttribute( name ) );
} else {
return defaultValue;
}
}
function _attr_as_int( element, name, defaultValue ) {
if ( element.hasAttribute( name ) ) {
return parseInt( element.getAttribute( name ), 10) ;
} else {
return defaultValue;
}
}
function _attr_as_string( element, name, defaultValue ) {
if ( element.hasAttribute( name ) ) {
return element.getAttribute( name );
} else {
return defaultValue;
}
}
function _format_float( f, num ) {
if ( f === undefined ) {
var s = '0.';
while ( s.length < num + 2 ) {
s += '0';
}
return s;
}
num = num || 2;
var parts = f.toString().split( '.' );
parts[ 1 ] = parts.length > 1 ? parts[ 1 ].substr( 0, num ) : "0";
while ( parts[ 1 ].length < num ) {
parts[ 1 ] += '0';
}
return parts.join( '.' );
}
function loadTextureImage ( texture, url ) {
var loader = new THREE.ImageLoader();
loader.load( url, function ( image ) {
texture.image = image;
texture.needsUpdate = true;
} );
}
function extractDoubleSided( obj, element ) {
obj.doubleSided = false;
var node = element.querySelectorAll('extra double_sided')[0];
if ( node ) {
if ( node && parseInt( node.textContent, 10 ) === 1 ) {
obj.doubleSided = true;
}
}
}
// Up axis conversion
function setUpConversion() {
if ( options.convertUpAxis !== true || colladaUp === options.upAxis ) {
upConversion = null;
} else {
switch ( colladaUp ) {
case 'X':
upConversion = options.upAxis === 'Y' ? 'XtoY' : 'XtoZ';
break;
case 'Y':
upConversion = options.upAxis === 'X' ? 'YtoX' : 'YtoZ';
break;
case 'Z':
upConversion = options.upAxis === 'X' ? 'ZtoX' : 'ZtoY';
break;
}
}
}
function fixCoords( data, sign ) {
if ( options.convertUpAxis !== true || colladaUp === options.upAxis ) {
return;
}
switch ( upConversion ) {
case 'XtoY':
var tmp = data[ 0 ];
data[ 0 ] = sign * data[ 1 ];
data[ 1 ] = tmp;
break;
case 'XtoZ':
var tmp = data[ 2 ];
data[ 2 ] = data[ 1 ];
data[ 1 ] = data[ 0 ];
data[ 0 ] = tmp;
break;
case 'YtoX':
var tmp = data[ 0 ];
data[ 0 ] = data[ 1 ];
data[ 1 ] = sign * tmp;
break;
case 'YtoZ':
var tmp = data[ 1 ];
data[ 1 ] = sign * data[ 2 ];
data[ 2 ] = tmp;
break;
case 'ZtoX':
var tmp = data[ 0 ];
data[ 0 ] = data[ 1 ];
data[ 1 ] = data[ 2 ];
data[ 2 ] = tmp;
break;
case 'ZtoY':
var tmp = data[ 1 ];
data[ 1 ] = data[ 2 ];
data[ 2 ] = sign * tmp;
break;
}
}
function getConvertedTranslation( axis, data ) {
if ( options.convertUpAxis !== true || colladaUp === options.upAxis ) {
return data;
}
switch ( axis ) {
case 'X':
data = upConversion === 'XtoY' ? data * -1 : data;
break;
case 'Y':
data = upConversion === 'YtoZ' || upConversion === 'YtoX' ? data * -1 : data;
break;
case 'Z':
data = upConversion === 'ZtoY' ? data * -1 : data ;
break;
default:
break;
}
return data;
}
function getConvertedVec3( data, offset ) {
var arr = [ data[ offset ], data[ offset + 1 ], data[ offset + 2 ] ];
fixCoords( arr, -1 );
return new THREE.Vector3( arr[ 0 ], arr[ 1 ], arr[ 2 ] );
}
function getConvertedMat4( data ) {
if ( options.convertUpAxis ) {
// First fix rotation and scale
// Columns first
var arr = [ data[ 0 ], data[ 4 ], data[ 8 ] ];
fixCoords( arr, -1 );
data[ 0 ] = arr[ 0 ];
data[ 4 ] = arr[ 1 ];
data[ 8 ] = arr[ 2 ];
arr = [ data[ 1 ], data[ 5 ], data[ 9 ] ];
fixCoords( arr, -1 );
data[ 1 ] = arr[ 0 ];
data[ 5 ] = arr[ 1 ];
data[ 9 ] = arr[ 2 ];
arr = [ data[ 2 ], data[ 6 ], data[ 10 ] ];
fixCoords( arr, -1 );
data[ 2 ] = arr[ 0 ];
data[ 6 ] = arr[ 1 ];
data[ 10 ] = arr[ 2 ];
// Rows second
arr = [ data[ 0 ], data[ 1 ], data[ 2 ] ];
fixCoords( arr, -1 );
data[ 0 ] = arr[ 0 ];
data[ 1 ] = arr[ 1 ];
data[ 2 ] = arr[ 2 ];
arr = [ data[ 4 ], data[ 5 ], data[ 6 ] ];
fixCoords( arr, -1 );
data[ 4 ] = arr[ 0 ];
data[ 5 ] = arr[ 1 ];
data[ 6 ] = arr[ 2 ];
arr = [ data[ 8 ], data[ 9 ], data[ 10 ] ];
fixCoords( arr, -1 );
data[ 8 ] = arr[ 0 ];
data[ 9 ] = arr[ 1 ];
data[ 10 ] = arr[ 2 ];
// Now fix translation
arr = [ data[ 3 ], data[ 7 ], data[ 11 ] ];
fixCoords( arr, -1 );
data[ 3 ] = arr[ 0 ];
data[ 7 ] = arr[ 1 ];
data[ 11 ] = arr[ 2 ];
}
return new THREE.Matrix4().set(
data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
data[8], data[9], data[10], data[11],
data[12], data[13], data[14], data[15]
);
}
function getConvertedIndex( index ) {
if ( index > -1 && index < 3 ) {
var members = [ 'X', 'Y', 'Z' ],
indices = { X: 0, Y: 1, Z: 2 };
index = getConvertedMember( members[ index ] );
index = indices[ index ];
}
return index;
}
function getConvertedMember( member ) {
if ( options.convertUpAxis ) {
switch ( member ) {
case 'X':
switch ( upConversion ) {
case 'XtoY':
case 'XtoZ':
case 'YtoX':
member = 'Y';
break;
case 'ZtoX':
member = 'Z';
break;
}
break;
case 'Y':
switch ( upConversion ) {
case 'XtoY':
case 'YtoX':
case 'ZtoX':
member = 'X';
break;
case 'XtoZ':
case 'YtoZ':
case 'ZtoY':
member = 'Z';
break;
}
break;
case 'Z':
switch ( upConversion ) {
case 'XtoZ':
member = 'X';
break;
case 'YtoZ':
case 'ZtoX':
case 'ZtoY':
member = 'Y';
break;
}
break;
}
}
return member;
}
return {
load: load,
parse: parse,
setPreferredShading: setPreferredShading,
applySkin: applySkin,
geometries : geometries,
options: options
};
};
module.exports = ColladaLoader;
/***/ }),
/* 214 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(11);
var _react2 = _interopRequireDefault(_react);
var _midiPlayerJs = __webpack_require__(215);
var _midiPlayerJs2 = _interopRequireDefault(_midiPlayerJs);
var _soundfontPlayer = __webpack_require__(221);
var _soundfontPlayer2 = _interopRequireDefault(_soundfontPlayer);
var _reactPlayerControls = __webpack_require__(236);
var _reactSimpleFlexGrid = __webpack_require__(201);
var _reactIconsKit = __webpack_require__(245);
var _reactIconsKit2 = _interopRequireDefault(_reactIconsKit);
var _play = __webpack_require__(256);
var _pause = __webpack_require__(257);
var _copy = __webpack_require__(258);
var _heart = __webpack_require__(259);
__webpack_require__(202);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var AudioContext = window.AudioContext || window.webkitAudioContext || false;
var MidiPlayerComponent = function (_Component) {
_inherits(MidiPlayerComponent, _Component);
function MidiPlayerComponent(props) {
_classCallCheck(this, MidiPlayerComponent);
var _this = _possibleConstructorReturn(this, (MidiPlayerComponent.__proto__ || Object.getPrototypeOf(MidiPlayerComponent)).call(this, props));
_this.state = {
submission_id: "something",
isLoading: true,
isPlayEnabled: false,
hasPlayedOnce: false,
isPauseEnabled: false,
isHeartEnabled: false,
isInstrument_loaded: false,
isMIDIFileLoaded: false,
isSeekable: true,
isMuted: false,
currentTime: 0,
totalTime: 0,
status_message: 'Loading Instruments 🎻 🎷 🎺 🎸 🥁 ...',
largeIconSize: 50
};
_this.load_data_uri = _this.load_data_uri.bind(_this);
_this.instrument_loaded = _this.instrument_loaded.bind(_this);
_this.player_fileLoaded = _this.player_fileLoaded.bind(_this);
_this.player_playing = _this.player_playing.bind(_this);
_this.player_midiEvent = _this.player_midiEvent.bind(_this);
_this.player_endOfFile = _this.player_endOfFile.bind(_this);
_this.playSong = _this.playSong.bind(_this);
_this.pauseSong = _this.pauseSong.bind(_this);
_this.unlockAudioContext = _this.unlockAudioContext.bind(_this);
_this.AudioContextUnlocked = false;
_this.audio_context = new AudioContext();
_this.instrument = false;
_soundfontPlayer2.default.instrument(_this.audio_context, 'acoustic_grand_piano').then(_this.instrument_loaded);
_this.Player = new _midiPlayerJs2.default.Player();
_this.Player.on('fileLoaded', _this.player_fileLoaded);
_this.Player.on('playing', _this.player_playing);
_this.Player.on('midiEvent', _this.player_midiEvent);
_this.Player.on('endOfFile', _this.player_endOfFile);
// this.Player.playLoop(false);
_this.note_states = {};
return _this;
}
_createClass(MidiPlayerComponent, [{
key: 'componentDidMount',
value: function componentDidMount() {
this.load_data_uri(this.props.dataUri);
}
}, {
key: 'componentWillMount',
value: function componentWillMount() {}
}, {
key: 'unlockAudioContext',
value: function unlockAudioContext() {
var iOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);
if (!iOS || this.AudioContextUnlocked) return;
// create empty buffer and play it
var buffer = this.audio_context.createBuffer(1, 1, 22050);
var source = this.audio_context.createBufferSource();
source.buffer = buffer;
source.connect(this.audio_context.destination);
if (source.start) {
source.start(0);
} else if (source.noteOn) {
source.noteOn(0);
}
// by checking the play state after some time, we know if we're really unlocked
setTimeout(function () {
if (source.playbackState === source.PLAYING_STATE || source.playbackState === source.FINISHED_STATE) {
this.AudioContextUnlocked = true;
}
}, 0);
}
}, {
key: 'player_fileLoaded',
value: function player_fileLoaded() {
//This is where the UI for Play/Pause etc will be enabled
var totalTime = this.Player.getSongTime();
// let currentTime = this.Player.getSongTime() - this.Player.getSongTimeRemaining();
this.setState({ isMIDIFileLoaded: true, totalTime: totalTime, currentTime: 0, isPlayEnabled: this.state.isInstrument_loaded ? true : false, isPauseEnabled: false, status_message: "" });
if (this.state.isInstrument_loaded && this.state.isMIDIFileLoaded) {
this.setState({ isLoading: false });
}
}
}, {
key: 'player_playing',
value: function player_playing(currentTick) {
// console.log("Play Remainnig : ", this.Player.getSongTimeRemaining());
var totalTime = this.Player.getSongTime();
var currentTime = this.Player.getSongTime() - this.Player.getSongTimeRemaining();
var isHeartEnabled = false;
if (this.state.currentTime !== 0 && this.state.totalTime !== 0 && this.state.currentTime * 1.0 / this.state.totalTime > 0.2) {
isHeartEnabled = true;
}
this.setState({
totalTime: totalTime,
hasPlayedOnce: true,
currentTime: currentTime,
isPlayEnabled: false,
isPauseEnabled: true,
isHeartEnabled: isHeartEnabled
});
if (this.Player.getSongTimeRemaining() <= 0) {
this.player_endOfFile();
}
}
}, {
key: 'player_midiEvent',
value: function player_midiEvent(event) {
if (event.name === "Note on") {
if (event.velocity <= 0) {
//Register a NOTE_OFF
this.props.onNoteOff(event.noteNumber);
this.note_states[event.noteNumber] = 'stopped';
} else {
this.instrument.play(event.noteNumber, this.audio_context.current_time, { gain: event.velocity / 100.0 });
this.props.onNoteOn(event.noteNumber);
this.note_states[event.noteNumber] = 'playing';
// Register a Note ON
}
} else if (event.name === "Note off") {
// console.log(event);
//Register a NoteOff
this.props.onNoteOff(event.noteNumber);
this.note_states[event.noteNumber] = 'stopped';
}
}
}, {
key: 'player_endOfFile',
value: function player_endOfFile() {
this.Player.skipToSeconds(0);
this.Player.stop();
this.setState({ isPlayEnabled: true, isPauseEnabled: false, currentTime: this.Player.getSongTime() });
this.props.resetKeyBoard();
}
}, {
key: 'instrument_loaded',
value: function instrument_loaded(_instrument) {
this.instrument = _instrument;
this.setState({ isInstrument_loaded: true, isPlayEnabled: this.state.isMIDIFileLoaded ? true : false });
if (this.state.isInstrument_loaded && this.state.isMIDIFileLoaded) {
this.setState({ isLoading: false });
}
}
}, {
key: 'load_data_uri',
value: function load_data_uri(dataUri) {
if (dataUri && dataUri !== this.dataUri) {
this.setState({ status_message: "Loading MIDI file.", isMIDIFileLoaded: false });
this.Player.loadDataUri(dataUri);
this.datUri = dataUri;
}
}
}, {
key: 'playSong',
value: function playSong() {
this.setState({ isPlayEnabled: false, isPauseEnabled: true });
this.unlockAudioContext();
this.Player.play();
}
}, {
key: 'pauseSong',
value: function pauseSong() {
this.Player.pause();
this.setState({ isPlayEnabled: true, isPauseEnabled: false });
this.props.resetKeyBoard();
}
}, {
key: 'onSeekStart',
value: function onSeekStart(time) {
this.pauseSong();
}
}, {
key: 'onSeekEnd',
value: function onSeekEnd(time) {
this.Player.skipToSeconds(time);
this.playSong();
}
}, {
key: 'renderPlayPause',
value: function renderPlayPause() {
var _this2 = this;
if (this.state.isPlayEnabled) {
var THIS = this;
return _react2.default.createElement(
'button',
{
className: 'crowdai_music_challenge_btns',
disabled: !this.state.isPlayEnabled,
onClick: function onClick() {
_this2.props.onPlay(_this2.props.playerName);
},
'data-rh': 'Play Song',
'data-rh-at': 'left'
},
_react2.default.createElement(_reactIconsKit2.default, { icon: _play.play, size: this.state.largeIconSize })
);
} else if (this.state.isPauseEnabled) {
return _react2.default.createElement(
'button',
{
className: 'crowdai_music_challenge_btns',
disabled: this.state.isPlayEnabled,
onClick: this.pauseSong,
'data-rh': 'Pause Song',
'data-rh-at': 'left'
},
_react2.default.createElement(_reactIconsKit2.default, { icon: _pause.pause, size: this.state.largeIconSize })
);
} else {
return _react2.default.createElement(
'button',
{
className: 'crowdai_music_challenge_btns',
disabled: !this.state.isPlayEnabled,
onClick: function onClick() {
_this2.props.onPlay(_this2.props.playerName);
},
'data-rh': 'Loading \uD83C\uDFB5',
'data-rh-at': 'left'
},
_react2.default.createElement(_reactIconsKit2.default, { icon: _play.play, size: this.state.largeIconSize })
);
}
}
}, {
key: 'renderProgressBar',
value: function renderProgressBar() {
var _this3 = this;
return _react2.default.createElement(_reactPlayerControls.ProgressBar, {
totalTime: this.state.totalTime,
currentTime: this.state.currentTime,
isSeekable: this.state.isSeekable,
onSeek: function onSeek(time) {
return _this3.setState(function () {
return { currentTime: time };
});
},
onSeekStart: this.onSeekStart.bind(this),
onSeekEnd: this.onSeekEnd.bind(this)
// onSeekStart={time => this.setState(() => ({ lastSeekStart: time }))}
// onSeekEnd={time => this.setState(() => ({ lastSeekEnd: time }))}
// onIntent={time => this.setState(() => ({ lastIntent: time }))}
});
}
}, {
key: 'renderTimeMarker',
value: function renderTimeMarker() {
return _react2.default.createElement(_reactPlayerControls.TimeMarker, {
totalTime: this.state.totalTime,
currentTime: Math.max(0, this.state.currentTime),
markerSeparator: " / "
});
}
}, {
key: 'renderHeart',
value: function renderHeart() {
var _this4 = this;
return _react2.default.createElement(
'button',
{
className: 'crowdai_music_challenge_btns share_button',
disabled: !this.state.isHeartEnabled,
'data-rh': this.state.isHeartEnabled ? "Vote for this song !" : "You can vote for this song only after listening to it ;)",
'data-rh-at': 'bottom',
onClick: function onClick() {
_this4.props.onHeartClicked(_this4.props.playerName);
}
},
_react2.default.createElement(_reactIconsKit2.default, { icon: _heart.heart, size: this.state.largeIconSize })
);
}
}, {
key: 'renderSubmissionID',
value: function renderSubmissionID() {
if (this.state.submission_id) {
return _react2.default.createElement(
'pre',
null,
_react2.default.createElement(
'strong',
null,
'#song',
this.props.playerName + 1
),
' : ',
this.state.submission_id.slice(0, 13)
);
} else {
return _react2.default.createElement(
'pre',
null,
"...."
);
}
}
}, {
key: 'renderTopRow',
value: function renderTopRow() {
if (!this.state.isLoading) {
return _react2.default.createElement(
'div',
null,
_react2.default.createElement(
_reactSimpleFlexGrid.Row,
{ gutter: '20', justify: 'center' },
this.renderSubmissionID()
),
_react2.default.createElement(
_reactSimpleFlexGrid.Row,
{ gutter: '20', justify: 'center' },
_react2.default.createElement(
_reactSimpleFlexGrid.Col,
{ className: '', xs: { span: 5 }, sm: { span: 4 }, md: { span: 3 }, lg: { span: 3 }, xl: { span: 3 } },
this.renderPlayPause()
),
_react2.default.createElement(
_reactSimpleFlexGrid.Col,
{ className: '', xs: { span: 5 }, sm: { span: 4 }, md: { span: 3 }, lg: { span: 3 }, xl: { span: 3 } },
this.renderHeart()
)
)
);
} else {
return _react2.default.createElement(
_reactSimpleFlexGrid.Row,
{ gutter: 10, align: 'middle', justify: 'center' },
_react2.default.createElement('div', { className: 'crowdai_interface_loader' })
);
}
}
}, {
key: 'render',
value: function render() {
var active_state = "controlsWrapper_notactive";
if (this.state.isPauseEnabled) {
active_state = " controlsWrapper_active";
}
return _react2.default.createElement(
'div',
{ className: "controlsWrapper " + active_state },
this.renderTopRow(),
_react2.default.createElement(
_reactSimpleFlexGrid.Row,
{ align: 'middle', justify: 'center' },
_react2.default.createElement(
_reactSimpleFlexGrid.Col,
{ xs: 7, sm: 7, md: 7, lg: 8, xl: 10 },
this.renderProgressBar()
),
_react2.default.createElement(
_reactSimpleFlexGrid.Col,
{ sm: 3, md: 3, lg: 2, xl: 1 },
this.renderTimeMarker()
),
_react2.default.createElement(
_reactSimpleFlexGrid.Col,
{ className: 'hidden-xs', xs: 1, sm: 2, md: 2, lg: 2, xl: 1 },
_react2.default.createElement(
'button',
{
className: 'crowdai_music_challenge_btns share_button',
disabled: true,
'data-rh': 'Unique link to this song',
'data-rh-at': 'bottom'
},
_react2.default.createElement(_reactIconsKit2.default, { icon: _copy.copy })
)
)
)
);
}
}]);
return MidiPlayerComponent;
}(_react.Component);
MidiPlayerComponent.defaultProps = {
playOnLoad: false
// dataUri: "data:audio/midi;base64,TVRoZAAAAAYAAQACAQBNVHJrAAAAGgD/WAQEAhgIAP9ZAv8AAP9YBAMCGAgB/y8ATVRyawAAAagAsFsyALAKSQCwWzIAsApJALAAAACwIAAAwAAAkDxGgS2QPAATkDxIOpA8AAaQPlMAkDVJAJA5SIFnkD4AGZA8SIFnkDwAGZBBVYFOkDUAAJA5ABmQQQAZkEBPAJAwUQCQOlGDTpBAADKQPEeBLZA8ABOQPEgOkDAAAJA6ACyQPAAGkD5VAJAwUACQOk+BZ5A+ABmQPEWBZ5A8ABmQQ1qBTpAwAACQOgAZkEMAGZBBSwCQNUkAkDlJg06QQQAykDxFgS2QPAATkDxKDpA1AACQOQAskDwABpBIYwCQNU0AkDlPgWeQSAAZkEVKgWeQRQAZkEFCgU6QNQAAkDkAGZBBABmQQEkAkDVRAJA6VIFnkEAAGZA+RYFH/1EDOThwIJA+AAD/UQMJJ8AZkEZZgS2QRgAB/1EDOThwEpBGTg6QNQAAkDoAAP9RAwknwCyQRgAGkEVMAJA1SwCQOUuBZ5BFABmQQUGBTpA1AACQOQAZkEEAGZBDTQCQME4AkDpPgWeQQwAAkDAAAJA6ABmQQUkAkDVMAJA5TIVOkEEAAJA1AACQOQAB/y8A"
};
exports.default = MidiPlayerComponent;
/***/ }),
/* 215 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* WEBPACK VAR INJECTION */(function(Buffer) {
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Constants = {
VERSION: '1.1.4',
NOTES: []
};
(function () {
var allNotes = [['C'], ['C#', 'Db'], ['D'], ['D#', 'Eb'], ['E'], ['F'], ['F#', 'Gb'], ['G'], ['G#', 'Ab'], ['A'], ['A#', 'Bb'], ['B']];
var counter = 0;
var _loop = function _loop(i) {
allNotes.forEach(function (noteGroup) {
noteGroup.forEach(function (note) {
return Constants.NOTES[counter] = note + i;
});
counter++;
});
};
for (var i = -1; i <= 9; i++) {
_loop(i);
}
})();
exports.Constants = Constants;
var Player = function () {
function Player(eventHandler, buffer) {
_classCallCheck(this, Player);
this.sampleRate = 5;
this.startTime = 0;
this.buffer = buffer || null;
this.division;
this.format;
this.setIntervalId = false;
this.tracks = [];
this.tempo = 120;
this.startTick = 0;
this.tick = 0;
this.lastTick = null;
this.inLoop = false;
this.totalTicks = 0;
this.events = [];
this.totalEvents = 0;
this.eventListeners = {};
if (typeof eventHandler === 'function') this.on('midiEvent', eventHandler);
}
_createClass(Player, [{
key: 'loadFile',
value: function loadFile(path) {
var fs = __webpack_require__(220);
this.buffer = fs.readFileSync(path);
return this.fileLoaded();
}
}, {
key: 'loadArrayBuffer',
value: function loadArrayBuffer(arrayBuffer) {
this.buffer = new Uint8Array(arrayBuffer);
return this.fileLoaded();
}
}, {
key: 'loadDataUri',
value: function loadDataUri(dataUri) {
var byteString = Utils.atob(dataUri.split(',')[1]);
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
this.buffer = ia;
return this.fileLoaded();
}
}, {
key: 'getFilesize',
value: function getFilesize() {
return this.buffer ? this.buffer.length : 0;
}
}, {
key: 'fileLoaded',
value: function fileLoaded() {
if (!this.validate()) throw 'Invalid MIDI file; should start with MThd';
return this.getDivision().getFormat().getTracks().dryRun();
}
}, {
key: 'validate',
value: function validate() {
return Utils.bytesToLetters(this.buffer.slice(0, 4)) === 'MThd';
}
}, {
key: 'getFormat',
value: function getFormat() {
this.format = Utils.bytesToNumber(this.buffer.slice(8, 10));
return this;
}
}, {
key: 'getTracks',
value: function getTracks() {
this.tracks = [];
this.buffer.forEach(function (byte, index) {
if (Utils.bytesToLetters(this.buffer.slice(index, index + 4)) == 'MTrk') {
var trackLength = Utils.bytesToNumber(this.buffer.slice(index + 4, index + 8));
this.tracks.push(new Track(this.tracks.length, this.buffer.slice(index + 8, index + 8 + trackLength)));
}
}, this);
return this;
}
}, {
key: 'enableTrack',
value: function enableTrack(trackNumber) {
this.tracks[trackNumber - 1].enable();
return this;
}
}, {
key: 'disableTrack',
value: function disableTrack(trackNumber) {
this.tracks[trackNumber - 1].disable();
return this;
}
}, {
key: 'getDivision',
value: function getDivision() {
this.division = Utils.bytesToNumber(this.buffer.slice(12, 14));
return this;
}
}, {
key: 'playLoop',
value: function playLoop(dryRun) {
if (!this.inLoop) {
this.inLoop = true;
this.tick = this.getCurrentTick();
this.tracks.forEach(function (track) {
if (!dryRun && this.endOfFile()) {
this.triggerPlayerEvent('endOfFile');
this.stop();
} else {
var _event = track.handleEvent(this.tick, dryRun);
if (dryRun && _event && _event.hasOwnProperty('name') && _event.name === 'Set Tempo') {
this.tempo = _event.data;
}
if (_event && !dryRun) this.emitEvent(_event);
}
}, this);
if (!dryRun) this.triggerPlayerEvent('playing', { tick: this.tick });
this.inLoop = false;
}
}
}, {
key: 'setStartTime',
value: function setStartTime(startTime) {
this.startTime = startTime;
}
}, {
key: 'play',
value: function play() {
if (this.isPlaying()) throw 'Already playing...';
if (!this.startTime) this.startTime = new Date().getTime();
this.setIntervalId = setInterval(this.playLoop.bind(this), this.sampleRate);
return this;
}
}, {
key: 'pause',
value: function pause() {
clearInterval(this.setIntervalId);
this.setIntervalId = false;
this.startTick = this.tick;
this.startTime = 0;
return this;
}
}, {
key: 'stop',
value: function stop() {
clearInterval(this.setIntervalId);
this.setIntervalId = false;
this.startTick = 0;
this.startTime = 0;
this.resetTracks();
return this;
}
}, {
key: 'skipToTick',
value: function skipToTick(tick) {
this.stop();
this.startTick = tick;
this.tracks.forEach(function (track) {
track.setEventIndexByTick(tick);
});
return this;
}
}, {
key: 'skipToPercent',
value: function skipToPercent(percent) {
if (percent < 0 || percent > 100) throw "Percent must be number between 1 and 100.";
this.skipToTick(Math.round(percent / 100 * this.totalTicks));
return this;
}
}, {
key: 'skipToSeconds',
value: function skipToSeconds(seconds) {
var songTime = this.getSongTime();
if (seconds < 0 || seconds > songTime) throw seconds + " seconds not within song time of " + songTime;
this.skipToPercent(seconds / songTime * 100);
return this;
}
}, {
key: 'isPlaying',
value: function isPlaying() {
return this.setIntervalId > 0 || _typeof(this.setIntervalId) === 'object';
}
}, {
key: 'dryRun',
value: function dryRun() {
this.resetTracks();
while (!this.endOfFile()) {
this.playLoop(true);
}this.events = this.getEvents();
this.totalEvents = this.getTotalEvents();
this.totalTicks = this.getTotalTicks();
this.startTick = 0;
this.startTime = 0;
this.resetTracks();
this.triggerPlayerEvent('fileLoaded', this);
return this;
}
}, {
key: 'resetTracks',
value: function resetTracks() {
this.tracks.forEach(function (track) {
return track.reset();
});
return this;
}
}, {
key: 'getEvents',
value: function getEvents() {
return this.tracks.map(function (track) {
return track.events;
});
}
}, {
key: 'getTotalTicks',
value: function getTotalTicks() {
return Math.max.apply(null, this.tracks.map(function (track) {
return track.delta;
}));
}
}, {
key: 'getTotalEvents',
value: function getTotalEvents() {
return this.tracks.reduce(function (a, b) {
return { events: { length: a.events.length + b.events.length } };
}, { events: { length: 0 } }).events.length;
}
}, {
key: 'getSongTime',
value: function getSongTime() {
return this.totalTicks / this.division / this.tempo * 60;
}
}, {
key: 'getSongTimeRemaining',
value: function getSongTimeRemaining() {
return Math.round((this.totalTicks - this.tick) / this.division / this.tempo * 60);
}
}, {
key: 'getSongPercentRemaining',
value: function getSongPercentRemaining() {
return Math.round(this.getSongTimeRemaining() / this.getSongTime() * 100);
}
}, {
key: 'bytesProcessed',
value: function bytesProcessed() {
return 14 + this.tracks.length * 8 + this.tracks.reduce(function (a, b) {
return { pointer: a.pointer + b.pointer };
}, { pointer: 0 }).pointer;
}
}, {
key: 'eventsPlayed',
value: function eventsPlayed() {
return this.tracks.reduce(function (a, b) {
return { eventIndex: a.eventIndex + b.eventIndex };
}, { eventIndex: 0 }).eventIndex;
}
}, {
key: 'endOfFile',
value: function endOfFile() {
if (this.isPlaying()) {
return this.eventsPlayed() == this.totalEvents;
}
return this.bytesProcessed() == this.buffer.length;
}
}, {
key: 'getCurrentTick',
value: function getCurrentTick() {
return Math.round((new Date().getTime() - this.startTime) / 1000 * (this.division * (this.tempo / 60))) + this.startTick;
}
}, {
key: 'emitEvent',
value: function emitEvent(event) {
this.triggerPlayerEvent('midiEvent', event);
return this;
}
}, {
key: 'on',
value: function on(playerEvent, fn) {
if (!this.eventListeners.hasOwnProperty(playerEvent)) this.eventListeners[playerEvent] = [];
this.eventListeners[playerEvent].push(fn);
return this;
}
}, {
key: 'triggerPlayerEvent',
value: function triggerPlayerEvent(playerEvent, data) {
if (this.eventListeners.hasOwnProperty(playerEvent)) this.eventListeners[playerEvent].forEach(function (fn) {
return fn(data || {});
});
return this;
}
}]);
return Player;
}();
exports.Player = Player;
var Track = function () {
function Track(index, data) {
_classCallCheck(this, Track);
this.enabled = true;
this.eventIndex = 0;
this.pointer = 0;
this.lastTick = 0;
this.lastStatus = null;
this.index = index;
this.data = data;
this.delta = 0;
this.runningDelta = 0;
this.events = [];
}
_createClass(Track, [{
key: 'reset',
value: function reset() {
this.enabled = true;
this.eventIndex = 0;
this.pointer = 0;
this.lastTick = 0;
this.lastStatus = null;
this.delta = 0;
this.runningDelta = 0;
return this;
}
}, {
key: 'enable',
value: function enable() {
this.enabled = true;
return this;
}
}, {
key: 'disable',
value: function disable() {
this.enabled = false;
return this;
}
}, {
key: 'setEventIndexByTick',
value: function setEventIndexByTick(tick) {
tick = tick || 0;
for (var i in this.events) {
if (this.events[i].tick >= tick) {
this.eventIndex = i;
return this;
}
}
}
}, {
key: 'getCurrentByte',
value: function getCurrentByte() {
return this.data[this.pointer];
}
}, {
key: 'getDeltaByteCount',
value: function getDeltaByteCount() {
var currentByte = this.getCurrentByte();
var byteCount = 1;
while (currentByte >= 128) {
currentByte = this.data[this.pointer + byteCount];
byteCount++;
}
return byteCount;
}
}, {
key: 'getDelta',
value: function getDelta() {
return Utils.readVarInt(this.data.slice(this.pointer, this.pointer + this.getDeltaByteCount()));
}
}, {
key: 'handleEvent',
value: function handleEvent(currentTick, dryRun) {
dryRun = dryRun || false;
if (dryRun) {
var elapsedTicks = currentTick - this.lastTick;
var delta = this.getDelta();
var eventReady = elapsedTicks >= delta;
if (this.pointer < this.data.length && (dryRun || eventReady)) {
var _event2 = this.parseEvent();
if (this.enabled) return _event2;
}
} else {
if (this.events[this.eventIndex] && this.events[this.eventIndex].tick <= currentTick) {
this.eventIndex++;
if (this.enabled) return this.events[this.eventIndex - 1];
}
}
return null;
}
}, {
key: 'getStringData',
value: function getStringData(eventStartIndex) {
var currentByte = this.pointer;
var byteCount = 1;
var length = Utils.readVarInt(this.data.slice(eventStartIndex + 2, eventStartIndex + 2 + byteCount));
var stringLength = length;
return Utils.bytesToLetters(this.data.slice(eventStartIndex + byteCount + 2, eventStartIndex + byteCount + length + 2));
}
}, {
key: 'parseEvent',
value: function parseEvent() {
var eventStartIndex = this.pointer + this.getDeltaByteCount();
var eventJson = {};
var deltaByteCount = this.getDeltaByteCount();
eventJson.track = this.index + 1;
eventJson.delta = this.getDelta();
this.lastTick = this.lastTick + eventJson.delta;
this.runningDelta += eventJson.delta;
eventJson.tick = this.runningDelta;
eventJson.byteIndex = this.pointer;
if (this.data[eventStartIndex] == 0xff) {
switch (this.data[eventStartIndex + 1]) {
case 0x00:
eventJson.name = 'Sequence Number';
break;
case 0x01:
eventJson.name = 'Text Event';
eventJson.string = this.getStringData(eventStartIndex);
break;
case 0x02:
eventJson.name = 'Copyright Notice';
break;
case 0x03:
eventJson.name = 'Sequence/Track Name';
eventJson.string = this.getStringData(eventStartIndex);
break;
case 0x04:
eventJson.name = 'Instrument Name';
eventJson.string = this.getStringData(eventStartIndex);
break;
case 0x05:
eventJson.name = 'Lyric';
eventJson.string = this.getStringData(eventStartIndex);
break;
case 0x06:
eventJson.name = 'Marker';
break;
case 0x07:
eventJson.name = 'Cue Point';
eventJson.string = this.getStringData(eventStartIndex);
break;
case 0x09:
eventJson.name = 'Device Name';
eventJson.string = this.getStringData(eventStartIndex);
break;
case 0x20:
eventJson.name = 'MIDI Channel Prefix';
break;
case 0x21:
eventJson.name = 'MIDI Port';
eventJson.data = Utils.bytesToNumber([this.data[eventStartIndex + 3]]);
break;
case 0x2F:
eventJson.name = 'End of Track';
break;
case 0x51:
eventJson.name = 'Set Tempo';
eventJson.data = Math.round(60000000 / Utils.bytesToNumber(this.data.slice(eventStartIndex + 3, eventStartIndex + 6)));
this.tempo = eventJson.data;
break;
case 0x54:
eventJson.name = 'SMTPE Offset';
break;
case 0x58:
eventJson.name = 'Time Signature';
break;
case 0x59:
eventJson.name = 'Key Signature';
break;
case 0x7F:
eventJson.name = 'Sequencer-Specific Meta-event';
break;
default:
eventJson.name = 'Unknown: ' + this.data[eventStartIndex + 1].toString(16);
break;
}
var length = this.data[this.pointer + deltaByteCount + 2];
this.pointer += deltaByteCount + 3 + length;
} else if (this.data[eventStartIndex] == 0xf0) {
eventJson.name = 'Sysex';
var length = this.data[this.pointer + deltaByteCount + 1];
this.pointer += deltaByteCount + 2 + length;
} else {
if (this.data[eventStartIndex] < 0x80) {
eventJson.running = true;
eventJson.noteNumber = this.data[eventStartIndex];
eventJson.noteName = Constants.NOTES[this.data[eventStartIndex]];
eventJson.velocity = this.data[eventStartIndex + 1];
if (this.lastStatus <= 0x8f) {
eventJson.name = 'Note off';
eventJson.channel = this.lastStatus - 0x80 + 1;
} else if (this.lastStatus <= 0x9f) {
eventJson.name = 'Note on';
eventJson.channel = this.lastStatus - 0x90 + 1;
}
this.pointer += deltaByteCount + 2;
} else {
this.lastStatus = this.data[eventStartIndex];
if (this.data[eventStartIndex] <= 0x8f) {
eventJson.name = 'Note off';
eventJson.channel = this.lastStatus - 0x80 + 1;
eventJson.noteNumber = this.data[eventStartIndex + 1];
eventJson.noteName = Constants.NOTES[this.data[eventStartIndex + 1]];
eventJson.velocity = Math.round(this.data[eventStartIndex + 2] / 127 * 100);
this.pointer += deltaByteCount + 3;
} else if (this.data[eventStartIndex] <= 0x9f) {
eventJson.name = 'Note on';
eventJson.channel = this.lastStatus - 0x90 + 1;
eventJson.noteNumber = this.data[eventStartIndex + 1];
eventJson.noteName = Constants.NOTES[this.data[eventStartIndex + 1]];
eventJson.velocity = Math.round(this.data[eventStartIndex + 2] / 127 * 100);
this.pointer += deltaByteCount + 3;
} else if (this.data[eventStartIndex] <= 0xaf) {
eventJson.name = 'Polyphonic Key Pressure';
eventJson.channel = this.lastStatus - 0xa0 + 1;
eventJson.note = Constants.NOTES[this.data[eventStartIndex + 1]];
eventJson.pressure = event[2];
this.pointer += deltaByteCount + 3;
} else if (this.data[eventStartIndex] <= 0xbf) {
eventJson.name = 'Controller Change';
eventJson.channel = this.lastStatus - 0xb0 + 1;
eventJson.number = this.data[eventStartIndex + 1];
eventJson.value = this.data[eventStartIndex + 2];
this.pointer += deltaByteCount + 3;
} else if (this.data[eventStartIndex] <= 0xcf) {
eventJson.name = 'Program Change';
eventJson.channel = this.lastStatus - 0xc0 + 1;
this.pointer += deltaByteCount + 2;
} else if (this.data[eventStartIndex] <= 0xdf) {
eventJson.name = 'Channel Key Pressure';
eventJson.channel = this.lastStatus - 0xd0 + 1;
this.pointer += deltaByteCount + 2;
} else if (this.data[eventStartIndex] <= 0xef) {
eventJson.name = 'Pitch Bend';
eventJson.channel = this.lastStatus - 0xe0 + 1;
this.pointer += deltaByteCount + 3;
} else {
eventJson.name = 'Unknown. Pointer: ' + this.pointer.toString() + ' ' + eventStartIndex.toString() + ' ' + this.data.length;
}
}
}
this.delta += eventJson.delta;
this.events.push(eventJson);
return eventJson;
}
}, {
key: 'endOfTrack',
value: function endOfTrack() {
if (this.data[this.pointer + 1] == 0xff && this.data[this.pointer + 2] == 0x2f && this.data[this.pointer + 3] == 0x00) {
return true;
}
return false;
}
}]);
return Track;
}();
var Utils = function () {
function Utils() {
_classCallCheck(this, Utils);
}
_createClass(Utils, null, [{
key: 'byteToHex',
value: function byteToHex(byte) {
return ('0' + byte.toString(16)).slice(-2);
}
}, {
key: 'bytesToHex',
value: function bytesToHex(byteArray) {
var hex = [];
byteArray.forEach(function (byte) {
return hex.push(Utils.byteToHex(byte));
});
return hex.join('');
}
}, {
key: 'hexToNumber',
value: function hexToNumber(hexString) {
return parseInt(hexString, 16);
}
}, {
key: 'bytesToNumber',
value: function bytesToNumber(byteArray) {
return Utils.hexToNumber(Utils.bytesToHex(byteArray));
}
}, {
key: 'bytesToLetters',
value: function bytesToLetters(byteArray) {
var letters = [];
byteArray.forEach(function (byte) {
return letters.push(String.fromCharCode(byte));
});
return letters.join('');
}
}, {
key: 'decToBinary',
value: function decToBinary(dec) {
return (dec >>> 0).toString(2);
}
}, {
key: 'readVarInt',
value: function readVarInt(byteArray) {
var result = 0;
byteArray.forEach(function (number) {
var b = number;
if (b & 0x80) {
result += b & 0x7f;
result <<= 7;
} else {
result += b;
}
});
return result;
}
}, {
key: 'atob',
value: function (_atob) {
function atob(_x) {
return _atob.apply(this, arguments);
}
atob.toString = function () {
return _atob.toString();
};
return atob;
}(function (string) {
if (typeof atob === 'function') return atob(string);
return new Buffer(string, 'base64').toString('binary');
})
}]);
return Utils;
}();
exports.Utils = Utils;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LmpzIl0sIm5hbWVzIjpbIkNvbnN0YW50cyIsIlZFUlNJT04iLCJOT1RFUyIsImFsbE5vdGVzIiwiY291bnRlciIsImkiLCJmb3JFYWNoIiwibm90ZUdyb3VwIiwibm90ZSIsImV4cG9ydHMiLCJQbGF5ZXIiLCJldmVudEhhbmRsZXIiLCJidWZmZXIiLCJzYW1wbGVSYXRlIiwic3RhcnRUaW1lIiwiZGl2aXNpb24iLCJmb3JtYXQiLCJzZXRJbnRlcnZhbElkIiwidHJhY2tzIiwidGVtcG8iLCJzdGFydFRpY2siLCJ0aWNrIiwibGFzdFRpY2siLCJpbkxvb3AiLCJ0b3RhbFRpY2tzIiwiZXZlbnRzIiwidG90YWxFdmVudHMiLCJldmVudExpc3RlbmVycyIsIm9uIiwicGF0aCIsImZzIiwicmVxdWlyZSIsInJlYWRGaWxlU3luYyIsImZpbGVMb2FkZWQiLCJhcnJheUJ1ZmZlciIsIlVpbnQ4QXJyYXkiLCJkYXRhVXJpIiwiYnl0ZVN0cmluZyIsIlV0aWxzIiwiYXRvYiIsInNwbGl0IiwiaWEiLCJsZW5ndGgiLCJjaGFyQ29kZUF0IiwidmFsaWRhdGUiLCJnZXREaXZpc2lvbiIsImdldEZvcm1hdCIsImdldFRyYWNrcyIsImRyeVJ1biIsImJ5dGVzVG9MZXR0ZXJzIiwic2xpY2UiLCJieXRlc1RvTnVtYmVyIiwiYnl0ZSIsImluZGV4IiwidHJhY2tMZW5ndGgiLCJwdXNoIiwiVHJhY2siLCJ0cmFja051bWJlciIsImVuYWJsZSIsImRpc2FibGUiLCJnZXRDdXJyZW50VGljayIsInRyYWNrIiwiZW5kT2ZGaWxlIiwidHJpZ2dlclBsYXllckV2ZW50Iiwic3RvcCIsImV2ZW50IiwiaGFuZGxlRXZlbnQiLCJoYXNPd25Qcm9wZXJ0eSIsIm5hbWUiLCJkYXRhIiwiZW1pdEV2ZW50IiwiaXNQbGF5aW5nIiwiRGF0ZSIsImdldFRpbWUiLCJzZXRJbnRlcnZhbCIsInBsYXlMb29wIiwiYmluZCIsImNsZWFySW50ZXJ2YWwiLCJyZXNldFRyYWNrcyIsInNldEV2ZW50SW5kZXhCeVRpY2siLCJwZXJjZW50Iiwic2tpcFRvVGljayIsIk1hdGgiLCJyb3VuZCIsInNlY29uZHMiLCJzb25nVGltZSIsImdldFNvbmdUaW1lIiwic2tpcFRvUGVyY2VudCIsImdldEV2ZW50cyIsImdldFRvdGFsRXZlbnRzIiwiZ2V0VG90YWxUaWNrcyIsInJlc2V0IiwibWFwIiwibWF4IiwiYXBwbHkiLCJkZWx0YSIsInJlZHVjZSIsImEiLCJiIiwiZ2V0U29uZ1RpbWVSZW1haW5pbmciLCJwb2ludGVyIiwiZXZlbnRJbmRleCIsImV2ZW50c1BsYXllZCIsImJ5dGVzUHJvY2Vzc2VkIiwicGxheWVyRXZlbnQiLCJmbiIsImVuYWJsZWQiLCJsYXN0U3RhdHVzIiwicnVubmluZ0RlbHRhIiwiY3VycmVudEJ5dGUiLCJnZXRDdXJyZW50Qnl0ZSIsImJ5dGVDb3VudCIsInJlYWRWYXJJbnQiLCJnZXREZWx0YUJ5dGVDb3VudCIsImN1cnJlbnRUaWNrIiwiZWxhcHNlZFRpY2tzIiwiZ2V0RGVsdGEiLCJldmVudFJlYWR5IiwicGFyc2VFdmVudCIsImV2ZW50U3RhcnRJbmRleCIsInN0cmluZ0xlbmd0aCIsImV2ZW50SnNvbiIsImRlbHRhQnl0ZUNvdW50IiwiYnl0ZUluZGV4Iiwic3RyaW5nIiwiZ2V0U3RyaW5nRGF0YSIsInRvU3RyaW5nIiwicnVubmluZyIsIm5vdGVOdW1iZXIiLCJub3RlTmFtZSIsInZlbG9jaXR5IiwiY2hhbm5lbCIsInByZXNzdXJlIiwibnVtYmVyIiwidmFsdWUiLCJieXRlQXJyYXkiLCJoZXgiLCJieXRlVG9IZXgiLCJqb2luIiwiaGV4U3RyaW5nIiwicGFyc2VJbnQiLCJoZXhUb051bWJlciIsImJ5dGVzVG9IZXgiLCJsZXR0ZXJzIiwiU3RyaW5nIiwiZnJvbUNoYXJDb2RlIiwiZGVjIiwicmVzdWx0IiwiQnVmZmVyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUdBLElBQUlBLFlBQVk7QUFDZkMsVUFBUyxPQURNO0FBRWZDLFFBQU87QUFGUSxDQUFoQjs7QUFLQSxDQUFDLFlBQVc7QUFFWCxLQUFJQyxXQUFXLENBQUMsQ0FBQyxHQUFELENBQUQsRUFBUSxDQUFDLElBQUQsRUFBTSxJQUFOLENBQVIsRUFBcUIsQ0FBQyxHQUFELENBQXJCLEVBQTRCLENBQUMsSUFBRCxFQUFNLElBQU4sQ0FBNUIsRUFBeUMsQ0FBQyxHQUFELENBQXpDLEVBQStDLENBQUMsR0FBRCxDQUEvQyxFQUFzRCxDQUFDLElBQUQsRUFBTSxJQUFOLENBQXRELEVBQW1FLENBQUMsR0FBRCxDQUFuRSxFQUEwRSxDQUFDLElBQUQsRUFBTSxJQUFOLENBQTFFLEVBQXVGLENBQUMsR0FBRCxDQUF2RixFQUE4RixDQUFDLElBQUQsRUFBTSxJQUFOLENBQTlGLEVBQTJHLENBQUMsR0FBRCxDQUEzRyxDQUFmO0FBQ0EsS0FBSUMsVUFBVSxDQUFkOztBQUhXLDRCQU1GQyxDQU5FO0FBT1ZGLFdBQVNHLE9BQVQsQ0FBaUIscUJBQWE7QUFDN0JDLGFBQVVELE9BQVYsQ0FBa0I7QUFBQSxXQUFRTixVQUFVRSxLQUFWLENBQWdCRSxPQUFoQixJQUEyQkksT0FBT0gsQ0FBMUM7QUFBQSxJQUFsQjtBQUNBRDtBQUNBLEdBSEQ7QUFQVTs7QUFNWCxNQUFLLElBQUlDLElBQUksQ0FBQyxDQUFkLEVBQWlCQSxLQUFLLENBQXRCLEVBQXlCQSxHQUF6QixFQUE4QjtBQUFBLFFBQXJCQSxDQUFxQjtBQUs3QjtBQUNELENBWkQ7O0FBY0FJLFFBQVFULFNBQVIsR0FBb0JBLFNBQXBCO0lBS01VLE07QUFDTCxpQkFBWUMsWUFBWixFQUEwQkMsTUFBMUIsRUFBa0M7QUFBQTs7QUFDakMsT0FBS0MsVUFBTCxHQUFrQixDQUFsQjtBQUNBLE9BQUtDLFNBQUwsR0FBaUIsQ0FBakI7QUFDQSxPQUFLRixNQUFMLEdBQWNBLFVBQVUsSUFBeEI7QUFDQSxPQUFLRyxRQUFMO0FBQ0EsT0FBS0MsTUFBTDtBQUNBLE9BQUtDLGFBQUwsR0FBcUIsS0FBckI7QUFDQSxPQUFLQyxNQUFMLEdBQWMsRUFBZDtBQUNBLE9BQUtDLEtBQUwsR0FBYSxHQUFiO0FBQ0EsT0FBS0MsU0FBTCxHQUFpQixDQUFqQjtBQUNBLE9BQUtDLElBQUwsR0FBWSxDQUFaO0FBQ0EsT0FBS0MsUUFBTCxHQUFnQixJQUFoQjtBQUNBLE9BQUtDLE1BQUwsR0FBYyxLQUFkO0FBQ0EsT0FBS0MsVUFBTCxHQUFrQixDQUFsQjtBQUNBLE9BQUtDLE1BQUwsR0FBYyxFQUFkO0FBQ0EsT0FBS0MsV0FBTCxHQUFtQixDQUFuQjtBQUNBLE9BQUtDLGNBQUwsR0FBc0IsRUFBdEI7O0FBRUEsTUFBSSxPQUFPaEIsWUFBUCxLQUF5QixVQUE3QixFQUF5QyxLQUFLaUIsRUFBTCxDQUFRLFdBQVIsRUFBcUJqQixZQUFyQjtBQUN6Qzs7OzsyQkFPUWtCLEksRUFBTTtBQUNkLE9BQUlDLEtBQUtDLFFBQVEsSUFBUixDQUFUO0FBQ0EsUUFBS25CLE1BQUwsR0FBY2tCLEdBQUdFLFlBQUgsQ0FBZ0JILElBQWhCLENBQWQ7QUFDQSxVQUFPLEtBQUtJLFVBQUwsRUFBUDtBQUNBOzs7a0NBT2VDLFcsRUFBYTtBQUM1QixRQUFLdEIsTUFBTCxHQUFjLElBQUl1QixVQUFKLENBQWVELFdBQWYsQ0FBZDtBQUNBLFVBQU8sS0FBS0QsVUFBTCxFQUFQO0FBQ0E7Ozs4QkFPV0csTyxFQUFTO0FBR3BCLE9BQUlDLGFBQWFDLE1BQU1DLElBQU4sQ0FBV0gsUUFBUUksS0FBUixDQUFjLEdBQWQsRUFBbUIsQ0FBbkIsQ0FBWCxDQUFqQjs7QUFHQSxPQUFJQyxLQUFLLElBQUlOLFVBQUosQ0FBZUUsV0FBV0ssTUFBMUIsQ0FBVDtBQUNBLFFBQUssSUFBSXJDLElBQUksQ0FBYixFQUFnQkEsSUFBSWdDLFdBQVdLLE1BQS9CLEVBQXVDckMsR0FBdkMsRUFBNEM7QUFDM0NvQyxPQUFHcEMsQ0FBSCxJQUFRZ0MsV0FBV00sVUFBWCxDQUFzQnRDLENBQXRCLENBQVI7QUFDQTs7QUFFRCxRQUFLTyxNQUFMLEdBQWM2QixFQUFkO0FBQ0EsVUFBTyxLQUFLUixVQUFMLEVBQVA7QUFDQTs7O2dDQU1hO0FBQ2IsVUFBTyxLQUFLckIsTUFBTCxHQUFjLEtBQUtBLE1BQUwsQ0FBWThCLE1BQTFCLEdBQW1DLENBQTFDO0FBQ0E7OzsrQkFPWTtBQUNaLE9BQUksQ0FBQyxLQUFLRSxRQUFMLEVBQUwsRUFBc0IsTUFBTSwyQ0FBTjtBQUN0QixVQUFPLEtBQUtDLFdBQUwsR0FBbUJDLFNBQW5CLEdBQStCQyxTQUEvQixHQUEyQ0MsTUFBM0MsRUFBUDtBQUNBOzs7NkJBTVU7QUFDVixVQUFPVixNQUFNVyxjQUFOLENBQXFCLEtBQUtyQyxNQUFMLENBQVlzQyxLQUFaLENBQWtCLENBQWxCLEVBQXFCLENBQXJCLENBQXJCLE1BQWtELE1BQXpEO0FBQ0E7Ozs4QkFNVzs7QUFXWCxRQUFLbEMsTUFBTCxHQUFjc0IsTUFBTWEsYUFBTixDQUFvQixLQUFLdkMsTUFBTCxDQUFZc0MsS0FBWixDQUFrQixDQUFsQixFQUFxQixFQUFyQixDQUFwQixDQUFkO0FBQ0EsVUFBTyxJQUFQO0FBQ0E7Ozs4QkFNVztBQUNYLFFBQUtoQyxNQUFMLEdBQWMsRUFBZDtBQUNBLFFBQUtOLE1BQUwsQ0FBWU4sT0FBWixDQUFvQixVQUFTOEMsSUFBVCxFQUFlQyxLQUFmLEVBQXNCO0FBQ3pDLFFBQUlmLE1BQU1XLGNBQU4sQ0FBcUIsS0FBS3JDLE1BQUwsQ0FBWXNDLEtBQVosQ0FBa0JHLEtBQWxCLEVBQXlCQSxRQUFRLENBQWpDLENBQXJCLEtBQTZELE1BQWpFLEVBQXlFO0FBQ3hFLFNBQUlDLGNBQWNoQixNQUFNYSxhQUFOLENBQW9CLEtBQUt2QyxNQUFMLENBQVlzQyxLQUFaLENBQWtCRyxRQUFRLENBQTFCLEVBQTZCQSxRQUFRLENBQXJDLENBQXBCLENBQWxCO0FBQ0EsVUFBS25DLE1BQUwsQ0FBWXFDLElBQVosQ0FBaUIsSUFBSUMsS0FBSixDQUFVLEtBQUt0QyxNQUFMLENBQVl3QixNQUF0QixFQUE4QixLQUFLOUIsTUFBTCxDQUFZc0MsS0FBWixDQUFrQkcsUUFBUSxDQUExQixFQUE2QkEsUUFBUSxDQUFSLEdBQVlDLFdBQXpDLENBQTlCLENBQWpCO0FBQ0E7QUFDRCxJQUxELEVBS0csSUFMSDs7QUFPQSxVQUFPLElBQVA7QUFDQTs7OzhCQU9XRyxXLEVBQWE7QUFDeEIsUUFBS3ZDLE1BQUwsQ0FBWXVDLGNBQWMsQ0FBMUIsRUFBNkJDLE1BQTdCO0FBQ0EsVUFBTyxJQUFQO0FBQ0E7OzsrQkFPWUQsVyxFQUFhO0FBQ3pCLFFBQUt2QyxNQUFMLENBQVl1QyxjQUFjLENBQTFCLEVBQTZCRSxPQUE3QjtBQUNBLFVBQU8sSUFBUDtBQUNBOzs7Z0NBTWE7QUFDYixRQUFLNUMsUUFBTCxHQUFnQnVCLE1BQU1hLGFBQU4sQ0FBb0IsS0FBS3ZDLE1BQUwsQ0FBWXNDLEtBQVosQ0FBa0IsRUFBbEIsRUFBc0IsRUFBdEIsQ0FBcEIsQ0FBaEI7QUFDQSxVQUFPLElBQVA7QUFDQTs7OzJCQU9RRixNLEVBQVE7QUFDaEIsT0FBSSxDQUFDLEtBQUt6QixNQUFWLEVBQWtCO0FBQ2pCLFNBQUtBLE1BQUwsR0FBYyxJQUFkO0FBQ0EsU0FBS0YsSUFBTCxHQUFZLEtBQUt1QyxjQUFMLEVBQVo7O0FBRUEsU0FBSzFDLE1BQUwsQ0FBWVosT0FBWixDQUFvQixVQUFTdUQsS0FBVCxFQUFnQjtBQUVuQyxTQUFJLENBQUNiLE1BQUQsSUFBVyxLQUFLYyxTQUFMLEVBQWYsRUFBaUM7QUFFaEMsV0FBS0Msa0JBQUwsQ0FBd0IsV0FBeEI7QUFDQSxXQUFLQyxJQUFMO0FBRUEsTUFMRCxNQUtPO0FBQ04sVUFBSUMsU0FBUUosTUFBTUssV0FBTixDQUFrQixLQUFLN0MsSUFBdkIsRUFBNkIyQixNQUE3QixDQUFaOztBQUVBLFVBQUlBLFVBQVVpQixNQUFWLElBQW1CQSxPQUFNRSxjQUFOLENBQXFCLE1BQXJCLENBQW5CLElBQW1ERixPQUFNRyxJQUFOLEtBQWUsV0FBdEUsRUFBbUY7QUFFbEYsWUFBS2pELEtBQUwsR0FBYThDLE9BQU1JLElBQW5CO0FBQ0E7O0FBRUQsVUFBSUosVUFBUyxDQUFDakIsTUFBZCxFQUFzQixLQUFLc0IsU0FBTCxDQUFlTCxNQUFmO0FBQ3RCO0FBRUQsS0FsQkQsRUFrQkcsSUFsQkg7O0FBb0JBLFFBQUksQ0FBQ2pCLE1BQUwsRUFBYSxLQUFLZSxrQkFBTCxDQUF3QixTQUF4QixFQUFtQyxFQUFDMUMsTUFBTSxLQUFLQSxJQUFaLEVBQW5DO0FBQ2IsU0FBS0UsTUFBTCxHQUFjLEtBQWQ7QUFDQTtBQUNEOzs7K0JBTVlULFMsRUFBVztBQUN2QixRQUFLQSxTQUFMLEdBQWlCQSxTQUFqQjtBQUNBOzs7eUJBTU07QUFDTixPQUFJLEtBQUt5RCxTQUFMLEVBQUosRUFBc0IsTUFBTSxvQkFBTjs7QUFHdEIsT0FBSSxDQUFDLEtBQUt6RCxTQUFWLEVBQXFCLEtBQUtBLFNBQUwsR0FBa0IsSUFBSTBELElBQUosRUFBRCxDQUFhQyxPQUFiLEVBQWpCOztBQUlyQixRQUFLeEQsYUFBTCxHQUFxQnlELFlBQVksS0FBS0MsUUFBTCxDQUFjQyxJQUFkLENBQW1CLElBQW5CLENBQVosRUFBc0MsS0FBSy9ELFVBQTNDLENBQXJCOztBQUVBLFVBQU8sSUFBUDtBQUNBOzs7MEJBTU87QUFDUGdFLGlCQUFjLEtBQUs1RCxhQUFuQjtBQUNBLFFBQUtBLGFBQUwsR0FBcUIsS0FBckI7QUFDQSxRQUFLRyxTQUFMLEdBQWlCLEtBQUtDLElBQXRCO0FBQ0EsUUFBS1AsU0FBTCxHQUFpQixDQUFqQjtBQUNBLFVBQU8sSUFBUDtBQUNBOzs7eUJBTU07QUFDTitELGlCQUFjLEtBQUs1RCxhQUFuQjtBQUNBLFFBQUtBLGFBQUwsR0FBcUIsS0FBckI7QUFDQSxRQUFLRyxTQUFMLEdBQWlCLENBQWpCO0FBQ0EsUUFBS04sU0FBTCxHQUFpQixDQUFqQjtBQUNBLFFBQUtnRSxXQUFMO0FBQ0EsVUFBTyxJQUFQO0FBQ0E7Ozs2QkFPVXpELEksRUFBTTtBQUNoQixRQUFLMkMsSUFBTDtBQUNBLFFBQUs1QyxTQUFMLEdBQWlCQyxJQUFqQjs7QUFHQSxRQUFLSCxNQUFMLENBQVlaLE9BQVosQ0FBb0IsVUFBU3VELEtBQVQsRUFBZ0I7QUFDbkNBLFVBQU1rQixtQkFBTixDQUEwQjFELElBQTFCO0FBQ0EsSUFGRDtBQUdBLFVBQU8sSUFBUDtBQUNBOzs7Z0NBT2EyRCxPLEVBQVM7QUFDdEIsT0FBSUEsVUFBVSxDQUFWLElBQWVBLFVBQVUsR0FBN0IsRUFBa0MsTUFBTSwyQ0FBTjtBQUNsQyxRQUFLQyxVQUFMLENBQWdCQyxLQUFLQyxLQUFMLENBQVdILFVBQVUsR0FBVixHQUFnQixLQUFLeEQsVUFBaEMsQ0FBaEI7QUFDQSxVQUFPLElBQVA7QUFDQTs7O2dDQU9hNEQsTyxFQUFTO0FBQ3RCLE9BQUlDLFdBQVcsS0FBS0MsV0FBTCxFQUFmO0FBQ0EsT0FBSUYsVUFBVSxDQUFWLElBQWVBLFVBQVVDLFFBQTdCLEVBQXVDLE1BQU1ELFVBQVUsbUNBQVYsR0FBZ0RDLFFBQXREO0FBQ3ZDLFFBQUtFLGFBQUwsQ0FBbUJILFVBQVVDLFFBQVYsR0FBcUIsR0FBeEM7QUFDQSxVQUFPLElBQVA7QUFDQTs7OzhCQU1XO0FBQ1gsVUFBTyxLQUFLcEUsYUFBTCxHQUFxQixDQUFyQixJQUEwQixRQUFPLEtBQUtBLGFBQVosTUFBOEIsUUFBL0Q7QUFDQTs7OzJCQU1RO0FBRVIsUUFBSzZELFdBQUw7QUFDQSxVQUFPLENBQUMsS0FBS2hCLFNBQUwsRUFBUjtBQUEwQixTQUFLYSxRQUFMLENBQWMsSUFBZDtBQUExQixJQUNBLEtBQUtsRCxNQUFMLEdBQWMsS0FBSytELFNBQUwsRUFBZDtBQUNBLFFBQUs5RCxXQUFMLEdBQW1CLEtBQUsrRCxjQUFMLEVBQW5CO0FBQ0EsUUFBS2pFLFVBQUwsR0FBa0IsS0FBS2tFLGFBQUwsRUFBbEI7QUFDQSxRQUFLdEUsU0FBTCxHQUFpQixDQUFqQjtBQUNBLFFBQUtOLFNBQUwsR0FBaUIsQ0FBakI7O0FBR0EsUUFBS2dFLFdBQUw7O0FBSUEsUUFBS2Ysa0JBQUwsQ0FBd0IsWUFBeEIsRUFBc0MsSUFBdEM7QUFDQSxVQUFPLElBQVA7QUFDQTs7O2dDQU1hO0FBQ2IsUUFBSzdDLE1BQUwsQ0FBWVosT0FBWixDQUFvQjtBQUFBLFdBQVN1RCxNQUFNOEIsS0FBTixFQUFUO0FBQUEsSUFBcEI7QUFDQSxVQUFPLElBQVA7QUFDQTs7OzhCQU1XO0FBQ1gsVUFBTyxLQUFLekUsTUFBTCxDQUFZMEUsR0FBWixDQUFnQjtBQUFBLFdBQVMvQixNQUFNcEMsTUFBZjtBQUFBLElBQWhCLENBQVA7QUFDQTs7O2tDQU1lO0FBQ2YsVUFBT3lELEtBQUtXLEdBQUwsQ0FBU0MsS0FBVCxDQUFlLElBQWYsRUFBcUIsS0FBSzVFLE1BQUwsQ0FBWTBFLEdBQVosQ0FBZ0I7QUFBQSxXQUFTL0IsTUFBTWtDLEtBQWY7QUFBQSxJQUFoQixDQUFyQixDQUFQO0FBQ0E7OzttQ0FNZ0I7QUFDaEIsVUFBTyxLQUFLN0UsTUFBTCxDQUFZOEUsTUFBWixDQUFtQixVQUFDQyxDQUFELEVBQUlDLENBQUosRUFBVTtBQUFDLFdBQU8sRUFBQ3pFLFFBQVEsRUFBQ2lCLFFBQVF1RCxFQUFFeEUsTUFBRixDQUFTaUIsTUFBVCxHQUFrQndELEVBQUV6RSxNQUFGLENBQVNpQixNQUFwQyxFQUFULEVBQVA7QUFBNkQsSUFBM0YsRUFBNkYsRUFBQ2pCLFFBQVEsRUFBQ2lCLFFBQVEsQ0FBVCxFQUFULEVBQTdGLEVBQW9IakIsTUFBcEgsQ0FBMkhpQixNQUFsSTtBQUNBOzs7Z0NBTWE7QUFDYixVQUFPLEtBQUtsQixVQUFMLEdBQWtCLEtBQUtULFFBQXZCLEdBQWtDLEtBQUtJLEtBQXZDLEdBQStDLEVBQXREO0FBQ0E7Ozt5Q0FNc0I7QUFDdEIsVUFBTytELEtBQUtDLEtBQUwsQ0FBVyxDQUFDLEtBQUszRCxVQUFMLEdBQWtCLEtBQUtILElBQXhCLElBQWdDLEtBQUtOLFFBQXJDLEdBQWdELEtBQUtJLEtBQXJELEdBQTZELEVBQXhFLENBQVA7QUFDQTs7OzRDQU15QjtBQUN6QixVQUFPK0QsS0FBS0MsS0FBTCxDQUFXLEtBQUtnQixvQkFBTCxLQUE4QixLQUFLYixXQUFMLEVBQTlCLEdBQW1ELEdBQTlELENBQVA7QUFDQTs7O21DQU1nQjtBQUVoQixVQUFPLEtBQUssS0FBS3BFLE1BQUwsQ0FBWXdCLE1BQVosR0FBcUIsQ0FBMUIsR0FBOEIsS0FBS3hCLE1BQUwsQ0FBWThFLE1BQVosQ0FBbUIsVUFBQ0MsQ0FBRCxFQUFJQyxDQUFKLEVBQVU7QUFBQyxXQUFPLEVBQUNFLFNBQVNILEVBQUVHLE9BQUYsR0FBWUYsRUFBRUUsT0FBeEIsRUFBUDtBQUF3QyxJQUF0RSxFQUF3RSxFQUFDQSxTQUFTLENBQVYsRUFBeEUsRUFBc0ZBLE9BQTNIO0FBQ0E7OztpQ0FNYztBQUNkLFVBQU8sS0FBS2xGLE1BQUwsQ0FBWThFLE1BQVosQ0FBbUIsVUFBQ0MsQ0FBRCxFQUFJQyxDQUFKLEVBQVU7QUFBQyxXQUFPLEVBQUNHLFlBQVlKLEVBQUVJLFVBQUYsR0FBZUgsRUFBRUcsVUFBOUIsRUFBUDtBQUFpRCxJQUEvRSxFQUFpRixFQUFDQSxZQUFZLENBQWIsRUFBakYsRUFBa0dBLFVBQXpHO0FBQ0E7Ozs4QkFTVztBQUNYLE9BQUksS0FBSzlCLFNBQUwsRUFBSixFQUFzQjtBQUNyQixXQUFPLEtBQUsrQixZQUFMLE1BQXVCLEtBQUs1RSxXQUFuQztBQUNBOztBQUVELFVBQU8sS0FBSzZFLGNBQUwsTUFBeUIsS0FBSzNGLE1BQUwsQ0FBWThCLE1BQTVDO0FBQ0E7OzttQ0FNZ0I7QUFDaEIsVUFBT3dDLEtBQUtDLEtBQUwsQ0FBVyxDQUFFLElBQUlYLElBQUosRUFBRCxDQUFhQyxPQUFiLEtBQXlCLEtBQUszRCxTQUEvQixJQUE0QyxJQUE1QyxJQUFvRCxLQUFLQyxRQUFMLElBQWlCLEtBQUtJLEtBQUwsR0FBYSxFQUE5QixDQUFwRCxDQUFYLElBQXFHLEtBQUtDLFNBQWpIO0FBQ0E7Ozs0QkFPUzZDLEssRUFBTztBQUNoQixRQUFLRixrQkFBTCxDQUF3QixXQUF4QixFQUFxQ0UsS0FBckM7QUFDQSxVQUFPLElBQVA7QUFDQTs7O3FCQVFFdUMsVyxFQUFhQyxFLEVBQUk7QUFDbkIsT0FBSSxDQUFDLEtBQUs5RSxjQUFMLENBQW9Cd0MsY0FBcEIsQ0FBbUNxQyxXQUFuQyxDQUFMLEVBQXNELEtBQUs3RSxjQUFMLENBQW9CNkUsV0FBcEIsSUFBbUMsRUFBbkM7QUFDdEQsUUFBSzdFLGNBQUwsQ0FBb0I2RSxXQUFwQixFQUFpQ2pELElBQWpDLENBQXNDa0QsRUFBdEM7QUFDQSxVQUFPLElBQVA7QUFDQTs7O3FDQVFrQkQsVyxFQUFhbkMsSSxFQUFNO0FBQ3JDLE9BQUksS0FBSzFDLGNBQUwsQ0FBb0J3QyxjQUFwQixDQUFtQ3FDLFdBQW5DLENBQUosRUFBcUQsS0FBSzdFLGNBQUwsQ0FBb0I2RSxXQUFwQixFQUFpQ2xHLE9BQWpDLENBQXlDO0FBQUEsV0FBTW1HLEdBQUdwQyxRQUFRLEVBQVgsQ0FBTjtBQUFBLElBQXpDO0FBQ3JELFVBQU8sSUFBUDtBQUNBOzs7Ozs7QUFJRjVELFFBQVFDLE1BQVIsR0FBaUJBLE1BQWpCOztJQUlNOEMsSztBQUNMLGdCQUFZSCxLQUFaLEVBQW1CZ0IsSUFBbkIsRUFBeUI7QUFBQTs7QUFDeEIsT0FBS3FDLE9BQUwsR0FBZSxJQUFmO0FBQ0EsT0FBS0wsVUFBTCxHQUFrQixDQUFsQjtBQUNBLE9BQUtELE9BQUwsR0FBZSxDQUFmO0FBQ0EsT0FBSzlFLFFBQUwsR0FBZ0IsQ0FBaEI7QUFDQSxPQUFLcUYsVUFBTCxHQUFrQixJQUFsQjtBQUNBLE9BQUt0RCxLQUFMLEdBQWFBLEtBQWI7QUFDQSxPQUFLZ0IsSUFBTCxHQUFZQSxJQUFaO0FBQ0EsT0FBSzBCLEtBQUwsR0FBYSxDQUFiO0FBQ0EsT0FBS2EsWUFBTCxHQUFvQixDQUFwQjtBQUNBLE9BQUtuRixNQUFMLEdBQWMsRUFBZDtBQUNBOzs7OzBCQU1PO0FBQ1AsUUFBS2lGLE9BQUwsR0FBZSxJQUFmO0FBQ0EsUUFBS0wsVUFBTCxHQUFrQixDQUFsQjtBQUNBLFFBQUtELE9BQUwsR0FBZSxDQUFmO0FBQ0EsUUFBSzlFLFFBQUwsR0FBZ0IsQ0FBaEI7QUFDQSxRQUFLcUYsVUFBTCxHQUFrQixJQUFsQjtBQUNBLFFBQUtaLEtBQUwsR0FBYSxDQUFiO0FBQ0EsUUFBS2EsWUFBTCxHQUFvQixDQUFwQjtBQUNBLFVBQU8sSUFBUDtBQUNBOzs7MkJBTVE7QUFDUixRQUFLRixPQUFMLEdBQWUsSUFBZjtBQUNBLFVBQU8sSUFBUDtBQUNBOzs7NEJBTVM7QUFDVCxRQUFLQSxPQUFMLEdBQWUsS0FBZjtBQUNBLFVBQU8sSUFBUDtBQUNBOzs7c0NBT21CckYsSSxFQUFNO0FBQ3pCQSxVQUFPQSxRQUFRLENBQWY7O0FBRUEsUUFBSyxJQUFJaEIsQ0FBVCxJQUFjLEtBQUtvQixNQUFuQixFQUEyQjtBQUMxQixRQUFJLEtBQUtBLE1BQUwsQ0FBWXBCLENBQVosRUFBZWdCLElBQWYsSUFBdUJBLElBQTNCLEVBQWlDO0FBQ2hDLFVBQUtnRixVQUFMLEdBQWtCaEcsQ0FBbEI7QUFDQSxZQUFPLElBQVA7QUFDQTtBQUNEO0FBQ0Q7OzttQ0FNZ0I7QUFDaEIsVUFBTyxLQUFLZ0UsSUFBTCxDQUFVLEtBQUsrQixPQUFmLENBQVA7QUFDQTs7O3NDQU1tQjtBQU1oQixPQUFJUyxjQUFjLEtBQUtDLGNBQUwsRUFBbEI7QUFDQSxPQUFJQyxZQUFZLENBQWhCOztBQUVILFVBQU9GLGVBQWUsR0FBdEIsRUFBMkI7QUFDMUJBLGtCQUFjLEtBQUt4QyxJQUFMLENBQVUsS0FBSytCLE9BQUwsR0FBZVcsU0FBekIsQ0FBZDtBQUNBQTtBQUNBOztBQUVELFVBQU9BLFNBQVA7QUFDQTs7OzZCQU1VO0FBQ1YsVUFBT3pFLE1BQU0wRSxVQUFOLENBQWlCLEtBQUszQyxJQUFMLENBQVVuQixLQUFWLENBQWdCLEtBQUtrRCxPQUFyQixFQUE4QixLQUFLQSxPQUFMLEdBQWUsS0FBS2EsaUJBQUwsRUFBN0MsQ0FBakIsQ0FBUDtBQUNBOzs7OEJBT1dDLFcsRUFBYWxFLE0sRUFBUTtBQUNoQ0EsWUFBU0EsVUFBVSxLQUFuQjs7QUFFQSxPQUFJQSxNQUFKLEVBQVk7QUFDWCxRQUFJbUUsZUFBZUQsY0FBYyxLQUFLNUYsUUFBdEM7QUFDQSxRQUFJeUUsUUFBUSxLQUFLcUIsUUFBTCxFQUFaO0FBQ0EsUUFBSUMsYUFBYUYsZ0JBQWdCcEIsS0FBakM7O0FBRUEsUUFBSSxLQUFLSyxPQUFMLEdBQWUsS0FBSy9CLElBQUwsQ0FBVTNCLE1BQXpCLEtBQW9DTSxVQUFVcUUsVUFBOUMsQ0FBSixFQUErRDtBQUM5RCxTQUFJcEQsVUFBUSxLQUFLcUQsVUFBTCxFQUFaO0FBQ0EsU0FBSSxLQUFLWixPQUFULEVBQWtCLE9BQU96QyxPQUFQO0FBRWxCO0FBRUQsSUFYRCxNQVdPO0FBRU4sUUFBSSxLQUFLeEMsTUFBTCxDQUFZLEtBQUs0RSxVQUFqQixLQUFnQyxLQUFLNUUsTUFBTCxDQUFZLEtBQUs0RSxVQUFqQixFQUE2QmhGLElBQTdCLElBQXFDNkYsV0FBekUsRUFBc0Y7QUFDckYsVUFBS2IsVUFBTDtBQUNBLFNBQUksS0FBS0ssT0FBVCxFQUFrQixPQUFPLEtBQUtqRixNQUFMLENBQVksS0FBSzRFLFVBQUwsR0FBa0IsQ0FBOUIsQ0FBUDtBQUNsQjtBQUNEOztBQUVELFVBQU8sSUFBUDtBQUNBOzs7Z0NBT2FrQixlLEVBQWlCO0FBQzlCLE9BQUlWLGNBQWMsS0FBS1QsT0FBdkI7QUFDQSxPQUFJVyxZQUFZLENBQWhCO0FBQ0EsT0FBSXJFLFNBQVNKLE1BQU0wRSxVQUFOLENBQWlCLEtBQUszQyxJQUFMLENBQVVuQixLQUFWLENBQWdCcUUsa0JBQWtCLENBQWxDLEVBQXFDQSxrQkFBa0IsQ0FBbEIsR0FBc0JSLFNBQTNELENBQWpCLENBQWI7QUFDQSxPQUFJUyxlQUFlOUUsTUFBbkI7O0FBRUEsVUFBT0osTUFBTVcsY0FBTixDQUFxQixLQUFLb0IsSUFBTCxDQUFVbkIsS0FBVixDQUFnQnFFLGtCQUFrQlIsU0FBbEIsR0FBOEIsQ0FBOUMsRUFBaURRLGtCQUFrQlIsU0FBbEIsR0FBOEJyRSxNQUE5QixHQUF1QyxDQUF4RixDQUFyQixDQUFQO0FBQ0E7OzsrQkFNWTtBQUNaLE9BQUk2RSxrQkFBa0IsS0FBS25CLE9BQUwsR0FBZSxLQUFLYSxpQkFBTCxFQUFyQztBQUNBLE9BQUlRLFlBQVksRUFBaEI7QUFDQSxPQUFJQyxpQkFBaUIsS0FBS1QsaUJBQUwsRUFBckI7QUFDQVEsYUFBVTVELEtBQVYsR0FBa0IsS0FBS1IsS0FBTCxHQUFhLENBQS9CO0FBQ0FvRSxhQUFVMUIsS0FBVixHQUFrQixLQUFLcUIsUUFBTCxFQUFsQjtBQUNBLFFBQUs5RixRQUFMLEdBQWdCLEtBQUtBLFFBQUwsR0FBZ0JtRyxVQUFVMUIsS0FBMUM7QUFDQSxRQUFLYSxZQUFMLElBQXFCYSxVQUFVMUIsS0FBL0I7QUFDQTBCLGFBQVVwRyxJQUFWLEdBQWlCLEtBQUt1RixZQUF0QjtBQUNBYSxhQUFVRSxTQUFWLEdBQXNCLEtBQUt2QixPQUEzQjs7QUFHQSxPQUFJLEtBQUsvQixJQUFMLENBQVVrRCxlQUFWLEtBQThCLElBQWxDLEVBQXdDOztBQU92QyxZQUFPLEtBQUtsRCxJQUFMLENBQVVrRCxrQkFBa0IsQ0FBNUIsQ0FBUDtBQUNDLFVBQUssSUFBTDtBQUNDRSxnQkFBVXJELElBQVYsR0FBaUIsaUJBQWpCO0FBQ0E7QUFDRCxVQUFLLElBQUw7QUFDQ3FELGdCQUFVckQsSUFBVixHQUFpQixZQUFqQjtBQUNBcUQsZ0JBQVVHLE1BQVYsR0FBbUIsS0FBS0MsYUFBTCxDQUFtQk4sZUFBbkIsQ0FBbkI7QUFDQTtBQUNELFVBQUssSUFBTDtBQUNDRSxnQkFBVXJELElBQVYsR0FBaUIsa0JBQWpCO0FBQ0E7QUFDRCxVQUFLLElBQUw7QUFDQ3FELGdCQUFVckQsSUFBVixHQUFpQixxQkFBakI7QUFDQXFELGdCQUFVRyxNQUFWLEdBQW1CLEtBQUtDLGFBQUwsQ0FBbUJOLGVBQW5CLENBQW5CO0FBQ0E7QUFDRCxVQUFLLElBQUw7QUFDQ0UsZ0JBQVVyRCxJQUFWLEdBQWlCLGlCQUFqQjtBQUNBcUQsZ0JBQVVHLE1BQVYsR0FBbUIsS0FBS0MsYUFBTCxDQUFtQk4sZUFBbkIsQ0FBbkI7QUFDQTtBQUNELFVBQUssSUFBTDtBQUNDRSxnQkFBVXJELElBQVYsR0FBaUIsT0FBakI7QUFDQXFELGdCQUFVRyxNQUFWLEdBQW1CLEtBQUtDLGFBQUwsQ0FBbUJOLGVBQW5CLENBQW5CO0FBQ0E7QUFDRCxVQUFLLElBQUw7QUFDQ0UsZ0JBQVVyRCxJQUFWLEdBQWlCLFFBQWpCO0FBQ0E7QUFDRCxVQUFLLElBQUw7QUFDQ3FELGdCQUFVckQsSUFBVixHQUFpQixXQUFqQjtBQUNBcUQsZ0JBQVVHLE1BQVYsR0FBbUIsS0FBS0MsYUFBTCxDQUFtQk4sZUFBbkIsQ0FBbkI7QUFDQTtBQUNELFVBQUssSUFBTDtBQUNDRSxnQkFBVXJELElBQVYsR0FBaUIsYUFBakI7QUFDQXFELGdCQUFVRyxNQUFWLEdBQW1CLEtBQUtDLGFBQUwsQ0FBbUJOLGVBQW5CLENBQW5CO0FBQ0E7QUFDRCxVQUFLLElBQUw7QUFDQ0UsZ0JBQVVyRCxJQUFWLEdBQWlCLHFCQUFqQjtBQUNBO0FBQ0QsVUFBSyxJQUFMO0FBQ0NxRCxnQkFBVXJELElBQVYsR0FBaUIsV0FBakI7QUFDQXFELGdCQUFVcEQsSUFBVixHQUFpQi9CLE1BQU1hLGFBQU4sQ0FBb0IsQ0FBQyxLQUFLa0IsSUFBTCxDQUFVa0Qsa0JBQWtCLENBQTVCLENBQUQsQ0FBcEIsQ0FBakI7QUFDQTtBQUNELFVBQUssSUFBTDtBQUNDRSxnQkFBVXJELElBQVYsR0FBaUIsY0FBakI7QUFDQTtBQUNELFVBQUssSUFBTDtBQUNDcUQsZ0JBQVVyRCxJQUFWLEdBQWlCLFdBQWpCO0FBQ0FxRCxnQkFBVXBELElBQVYsR0FBaUJhLEtBQUtDLEtBQUwsQ0FBVyxXQUFXN0MsTUFBTWEsYUFBTixDQUFvQixLQUFLa0IsSUFBTCxDQUFVbkIsS0FBVixDQUFnQnFFLGtCQUFrQixDQUFsQyxFQUFxQ0Esa0JBQWtCLENBQXZELENBQXBCLENBQXRCLENBQWpCO0FBQ0EsV0FBS3BHLEtBQUwsR0FBYXNHLFVBQVVwRCxJQUF2QjtBQUNBO0FBQ0QsVUFBSyxJQUFMO0FBQ0NvRCxnQkFBVXJELElBQVYsR0FBaUIsY0FBakI7QUFDQTtBQUNELFVBQUssSUFBTDtBQUNDcUQsZ0JBQVVyRCxJQUFWLEdBQWlCLGdCQUFqQjtBQUNBO0FBQ0QsVUFBSyxJQUFMO0FBQ0NxRCxnQkFBVXJELElBQVYsR0FBaUIsZUFBakI7QUFDQTtBQUNELFVBQUssSUFBTDtBQUNDcUQsZ0JBQVVyRCxJQUFWLEdBQWlCLCtCQUFqQjtBQUNBO0FBQ0Q7QUFDQ3FELGdCQUFVckQsSUFBVixHQUFpQixjQUFjLEtBQUtDLElBQUwsQ0FBVWtELGtCQUFrQixDQUE1QixFQUErQk8sUUFBL0IsQ0FBd0MsRUFBeEMsQ0FBL0I7QUFDQTtBQS9ERjs7QUFrRUEsUUFBSXBGLFNBQVMsS0FBSzJCLElBQUwsQ0FBVSxLQUFLK0IsT0FBTCxHQUFlc0IsY0FBZixHQUFnQyxDQUExQyxDQUFiOzs7QUFHQSxTQUFLdEIsT0FBTCxJQUFnQnNCLGlCQUFpQixDQUFqQixHQUFxQmhGLE1BQXJDO0FBRUEsSUE5RUQsTUE4RU8sSUFBRyxLQUFLMkIsSUFBTCxDQUFVa0QsZUFBVixLQUE4QixJQUFqQyxFQUF1QztBQUU3Q0UsY0FBVXJELElBQVYsR0FBaUIsT0FBakI7QUFDQSxRQUFJMUIsU0FBUyxLQUFLMkIsSUFBTCxDQUFVLEtBQUsrQixPQUFMLEdBQWVzQixjQUFmLEdBQWdDLENBQTFDLENBQWI7QUFDQSxTQUFLdEIsT0FBTCxJQUFnQnNCLGlCQUFpQixDQUFqQixHQUFxQmhGLE1BQXJDO0FBRUEsSUFOTSxNQU1BO0FBRU4sUUFBSSxLQUFLMkIsSUFBTCxDQUFVa0QsZUFBVixJQUE2QixJQUFqQyxFQUF1QztBQUV0Q0UsZUFBVU0sT0FBVixHQUFvQixJQUFwQjtBQUNBTixlQUFVTyxVQUFWLEdBQXVCLEtBQUszRCxJQUFMLENBQVVrRCxlQUFWLENBQXZCO0FBQ0FFLGVBQVVRLFFBQVYsR0FBcUJqSSxVQUFVRSxLQUFWLENBQWdCLEtBQUttRSxJQUFMLENBQVVrRCxlQUFWLENBQWhCLENBQXJCO0FBQ0FFLGVBQVVTLFFBQVYsR0FBcUIsS0FBSzdELElBQUwsQ0FBVWtELGtCQUFrQixDQUE1QixDQUFyQjs7QUFFQSxTQUFJLEtBQUtaLFVBQUwsSUFBbUIsSUFBdkIsRUFBNkI7QUFDNUJjLGdCQUFVckQsSUFBVixHQUFpQixVQUFqQjtBQUNBcUQsZ0JBQVVVLE9BQVYsR0FBb0IsS0FBS3hCLFVBQUwsR0FBa0IsSUFBbEIsR0FBeUIsQ0FBN0M7QUFFQSxNQUpELE1BSU8sSUFBSSxLQUFLQSxVQUFMLElBQW1CLElBQXZCLEVBQTZCO0FBQ25DYyxnQkFBVXJELElBQVYsR0FBaUIsU0FBakI7QUFDQXFELGdCQUFVVSxPQUFWLEdBQW9CLEtBQUt4QixVQUFMLEdBQWtCLElBQWxCLEdBQXlCLENBQTdDO0FBQ0E7O0FBRUQsVUFBS1AsT0FBTCxJQUFnQnNCLGlCQUFpQixDQUFqQztBQUVBLEtBbEJELE1Ba0JPO0FBQ04sVUFBS2YsVUFBTCxHQUFrQixLQUFLdEMsSUFBTCxDQUFVa0QsZUFBVixDQUFsQjs7QUFFQSxTQUFJLEtBQUtsRCxJQUFMLENBQVVrRCxlQUFWLEtBQThCLElBQWxDLEVBQXdDO0FBRXZDRSxnQkFBVXJELElBQVYsR0FBaUIsVUFBakI7QUFDQXFELGdCQUFVVSxPQUFWLEdBQW9CLEtBQUt4QixVQUFMLEdBQWtCLElBQWxCLEdBQXlCLENBQTdDO0FBQ0FjLGdCQUFVTyxVQUFWLEdBQXVCLEtBQUszRCxJQUFMLENBQVVrRCxrQkFBa0IsQ0FBNUIsQ0FBdkI7QUFDQUUsZ0JBQVVRLFFBQVYsR0FBcUJqSSxVQUFVRSxLQUFWLENBQWdCLEtBQUttRSxJQUFMLENBQVVrRCxrQkFBa0IsQ0FBNUIsQ0FBaEIsQ0FBckI7QUFDQUUsZ0JBQVVTLFFBQVYsR0FBcUJoRCxLQUFLQyxLQUFMLENBQVcsS0FBS2QsSUFBTCxDQUFVa0Qsa0JBQWtCLENBQTVCLElBQWlDLEdBQWpDLEdBQXVDLEdBQWxELENBQXJCO0FBQ0EsV0FBS25CLE9BQUwsSUFBZ0JzQixpQkFBaUIsQ0FBakM7QUFFQSxNQVRELE1BU08sSUFBSSxLQUFLckQsSUFBTCxDQUFVa0QsZUFBVixLQUE4QixJQUFsQyxFQUF3QztBQUU5Q0UsZ0JBQVVyRCxJQUFWLEdBQWlCLFNBQWpCO0FBQ0FxRCxnQkFBVVUsT0FBVixHQUFvQixLQUFLeEIsVUFBTCxHQUFrQixJQUFsQixHQUF5QixDQUE3QztBQUNBYyxnQkFBVU8sVUFBVixHQUF1QixLQUFLM0QsSUFBTCxDQUFVa0Qsa0JBQWtCLENBQTVCLENBQXZCO0FBQ0FFLGdCQUFVUSxRQUFWLEdBQXFCakksVUFBVUUsS0FBVixDQUFnQixLQUFLbUUsSUFBTCxDQUFVa0Qsa0JBQWtCLENBQTVCLENBQWhCLENBQXJCO0FBQ0FFLGdCQUFVUyxRQUFWLEdBQXFCaEQsS0FBS0MsS0FBTCxDQUFXLEtBQUtkLElBQUwsQ0FBVWtELGtCQUFrQixDQUE1QixJQUFpQyxHQUFqQyxHQUF1QyxHQUFsRCxDQUFyQjtBQUNBLFdBQUtuQixPQUFMLElBQWdCc0IsaUJBQWlCLENBQWpDO0FBRUEsTUFUTSxNQVNBLElBQUksS0FBS3JELElBQUwsQ0FBVWtELGVBQVYsS0FBOEIsSUFBbEMsRUFBd0M7QUFFOUNFLGdCQUFVckQsSUFBVixHQUFpQix5QkFBakI7QUFDQXFELGdCQUFVVSxPQUFWLEdBQW9CLEtBQUt4QixVQUFMLEdBQWtCLElBQWxCLEdBQXlCLENBQTdDO0FBQ0FjLGdCQUFVakgsSUFBVixHQUFpQlIsVUFBVUUsS0FBVixDQUFnQixLQUFLbUUsSUFBTCxDQUFVa0Qsa0JBQWtCLENBQTVCLENBQWhCLENBQWpCO0FBQ0FFLGdCQUFVVyxRQUFWLEdBQXFCbkUsTUFBTSxDQUFOLENBQXJCO0FBQ0EsV0FBS21DLE9BQUwsSUFBZ0JzQixpQkFBaUIsQ0FBakM7QUFFQSxNQVJNLE1BUUEsSUFBSSxLQUFLckQsSUFBTCxDQUFVa0QsZUFBVixLQUE4QixJQUFsQyxFQUF3QztBQUU5Q0UsZ0JBQVVyRCxJQUFWLEdBQWlCLG1CQUFqQjtBQUNBcUQsZ0JBQVVVLE9BQVYsR0FBb0IsS0FBS3hCLFVBQUwsR0FBa0IsSUFBbEIsR0FBeUIsQ0FBN0M7QUFDQWMsZ0JBQVVZLE1BQVYsR0FBbUIsS0FBS2hFLElBQUwsQ0FBVWtELGtCQUFrQixDQUE1QixDQUFuQjtBQUNBRSxnQkFBVWEsS0FBVixHQUFrQixLQUFLakUsSUFBTCxDQUFVa0Qsa0JBQWtCLENBQTVCLENBQWxCO0FBQ0EsV0FBS25CLE9BQUwsSUFBZ0JzQixpQkFBaUIsQ0FBakM7QUFFQSxNQVJNLE1BUUEsSUFBSSxLQUFLckQsSUFBTCxDQUFVa0QsZUFBVixLQUE4QixJQUFsQyxFQUF3QztBQUU5Q0UsZ0JBQVVyRCxJQUFWLEdBQWlCLGdCQUFqQjtBQUNBcUQsZ0JBQVVVLE9BQVYsR0FBb0IsS0FBS3hCLFVBQUwsR0FBa0IsSUFBbEIsR0FBeUIsQ0FBN0M7QUFDQSxXQUFLUCxPQUFMLElBQWdCc0IsaUJBQWlCLENBQWpDO0FBRUEsTUFOTSxNQU1BLElBQUksS0FBS3JELElBQUwsQ0FBVWtELGVBQVYsS0FBOEIsSUFBbEMsRUFBd0M7QUFFOUNFLGdCQUFVckQsSUFBVixHQUFpQixzQkFBakI7QUFDQXFELGdCQUFVVSxPQUFWLEdBQW9CLEtBQUt4QixVQUFMLEdBQWtCLElBQWxCLEdBQXlCLENBQTdDO0FBQ0EsV0FBS1AsT0FBTCxJQUFnQnNCLGlCQUFpQixDQUFqQztBQUVBLE1BTk0sTUFNQSxJQUFJLEtBQUtyRCxJQUFMLENBQVVrRCxlQUFWLEtBQThCLElBQWxDLEVBQXdDO0FBRTlDRSxnQkFBVXJELElBQVYsR0FBaUIsWUFBakI7QUFDQXFELGdCQUFVVSxPQUFWLEdBQW9CLEtBQUt4QixVQUFMLEdBQWtCLElBQWxCLEdBQXlCLENBQTdDO0FBQ0EsV0FBS1AsT0FBTCxJQUFnQnNCLGlCQUFpQixDQUFqQztBQUVBLE1BTk0sTUFNQTtBQUNORCxnQkFBVXJELElBQVYsR0FBaUIsd0JBQXdCLEtBQUtnQyxPQUFMLENBQWEwQixRQUFiLEVBQXhCLEdBQWtELEdBQWxELEdBQXlEUCxnQkFBZ0JPLFFBQWhCLEVBQXpELEdBQXNGLEdBQXRGLEdBQTRGLEtBQUt6RCxJQUFMLENBQVUzQixNQUF2SDtBQUNBO0FBQ0Q7QUFDRDs7QUFFRCxRQUFLcUQsS0FBTCxJQUFjMEIsVUFBVTFCLEtBQXhCO0FBQ0EsUUFBS3RFLE1BQUwsQ0FBWThCLElBQVosQ0FBaUJrRSxTQUFqQjs7QUFFQSxVQUFPQSxTQUFQO0FBQ0E7OzsrQkFNWTtBQUNaLE9BQUksS0FBS3BELElBQUwsQ0FBVSxLQUFLK0IsT0FBTCxHQUFlLENBQXpCLEtBQStCLElBQS9CLElBQXVDLEtBQUsvQixJQUFMLENBQVUsS0FBSytCLE9BQUwsR0FBZSxDQUF6QixLQUErQixJQUF0RSxJQUE4RSxLQUFLL0IsSUFBTCxDQUFVLEtBQUsrQixPQUFMLEdBQWUsQ0FBekIsS0FBK0IsSUFBakgsRUFBdUg7QUFDdEgsV0FBTyxJQUFQO0FBQ0E7O0FBRUQsVUFBTyxLQUFQO0FBQ0E7Ozs7OztJQUtJOUQsSzs7Ozs7Ozs0QkFPWWMsSSxFQUFNO0FBRXRCLFVBQU8sQ0FBQyxNQUFNQSxLQUFLMEUsUUFBTCxDQUFjLEVBQWQsQ0FBUCxFQUEwQjVFLEtBQTFCLENBQWdDLENBQUMsQ0FBakMsQ0FBUDtBQUNBOzs7NkJBT2lCcUYsUyxFQUFXO0FBQzVCLE9BQUlDLE1BQU0sRUFBVjtBQUNBRCxhQUFVakksT0FBVixDQUFrQjtBQUFBLFdBQVFrSSxJQUFJakYsSUFBSixDQUFTakIsTUFBTW1HLFNBQU4sQ0FBZ0JyRixJQUFoQixDQUFULENBQVI7QUFBQSxJQUFsQjtBQUNBLFVBQU9vRixJQUFJRSxJQUFKLENBQVMsRUFBVCxDQUFQO0FBQ0E7Ozs4QkFPa0JDLFMsRUFBVztBQUM3QixVQUFPQyxTQUFTRCxTQUFULEVBQW9CLEVBQXBCLENBQVA7QUFDQTs7O2dDQU9vQkosUyxFQUFXO0FBQy9CLFVBQU9qRyxNQUFNdUcsV0FBTixDQUFrQnZHLE1BQU13RyxVQUFOLENBQWlCUCxTQUFqQixDQUFsQixDQUFQO0FBQ0E7OztpQ0FPcUJBLFMsRUFBVztBQUNoQyxPQUFJUSxVQUFVLEVBQWQ7QUFDQVIsYUFBVWpJLE9BQVYsQ0FBa0I7QUFBQSxXQUFReUksUUFBUXhGLElBQVIsQ0FBYXlGLE9BQU9DLFlBQVAsQ0FBb0I3RixJQUFwQixDQUFiLENBQVI7QUFBQSxJQUFsQjtBQUNBLFVBQU8yRixRQUFRTCxJQUFSLENBQWEsRUFBYixDQUFQO0FBQ0E7Ozs4QkFPa0JRLEcsRUFBSztBQUNwQixVQUFPLENBQUNBLFFBQVEsQ0FBVCxFQUFZcEIsUUFBWixDQUFxQixDQUFyQixDQUFQO0FBQ0g7Ozs2QkFPaUJTLFMsRUFBVztBQUM1QixPQUFJWSxTQUFTLENBQWI7QUFDQVosYUFBVWpJLE9BQVYsQ0FBa0Isa0JBQVU7QUFDM0IsUUFBSTRGLElBQUltQyxNQUFSO0FBQ0EsUUFBSW5DLElBQUksSUFBUixFQUFjO0FBQ2JpRCxlQUFXakQsSUFBSSxJQUFmO0FBQ0FpRCxnQkFBVyxDQUFYO0FBQ0EsS0FIRCxNQUdPO0FBRU5BLGVBQVVqRCxDQUFWO0FBQ0E7QUFDRCxJQVREOztBQVdBLFVBQU9pRCxNQUFQO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Y0FPV3ZCLE0sRUFBUTtBQUNuQixPQUFJLE9BQU9yRixJQUFQLEtBQWdCLFVBQXBCLEVBQWdDLE9BQU9BLEtBQUtxRixNQUFMLENBQVA7QUFDaEMsVUFBTyxJQUFJd0IsTUFBSixDQUFXeEIsTUFBWCxFQUFtQixRQUFuQixFQUE2QkUsUUFBN0IsQ0FBc0MsUUFBdEMsQ0FBUDtBQUNBLEc7Ozs7OztBQUdGckgsUUFBUTZCLEtBQVIsR0FBZ0JBLEtBQWhCIiwiZmlsZSI6ImluZGV4LmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb25zdGFudHMgdXNlZCBpbiBwbGF5ZXIuXG4gKi9cbnZhciBDb25zdGFudHMgPSB7XG5cdFZFUlNJT046ICcxLjEuNCcsXG5cdE5PVEVTOiBbXVxufTtcblxuKGZ1bmN0aW9uKCkge1xuXHQvLyBCdWlsZHMgbm90ZXMgb2JqZWN0IGZvciByZWZlcmVuY2UgYWdhaW5zdCBiaW5hcnkgdmFsdWVzLlxuXHR2YXIgYWxsTm90ZXMgPSBbWydDJ10sIFsnQyMnLCdEYiddLCBbJ0QnXSwgWydEIycsJ0ViJ10sIFsnRSddLFsnRiddLCBbJ0YjJywnR2InXSwgWydHJ10sIFsnRyMnLCdBYiddLCBbJ0EnXSwgWydBIycsJ0JiJ10sIFsnQiddXTtcblx0dmFyIGNvdW50ZXIgPSAwO1xuXG5cdC8vIEFsbCBhdmFpbGFibGUgb2N0YXZlcy5cblx0Zm9yIChsZXQgaSA9IC0xOyBpIDw9IDk7IGkrKykge1xuXHRcdGFsbE5vdGVzLmZvckVhY2gobm90ZUdyb3VwID0+IHtcblx0XHRcdG5vdGVHcm91cC5mb3JFYWNoKG5vdGUgPT4gQ29uc3RhbnRzLk5PVEVTW2NvdW50ZXJdID0gbm90ZSArIGkpO1xuXHRcdFx0Y291bnRlciArKztcblx0XHR9KTtcblx0fVxufSkoKTtcblxuZXhwb3J0cy5Db25zdGFudHMgPSBDb25zdGFudHM7LyoqXG4gKiBNYWluIHBsYXllciBjbGFzcy4gIENvbnRhaW5zIG1ldGhvZHMgdG8gbG9hZCBmaWxlcywgc3RhcnQsIHN0b3AuXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSAtIENhbGxiYWNrIHRvIGZpcmUgZm9yIGVhY2ggTUlESSBldmVudC4gIENhbiBhbHNvIGJlIGFkZGVkIHdpdGggb24oJ21pZGlFdmVudCcsIGZuKVxuICogQHBhcmFtIHthcnJheX0gLSBBcnJheSBidWZmZXIgb2YgTUlESSBmaWxlIChvcHRpb25hbCkuXG4gKi9cbmNsYXNzIFBsYXllciB7XG5cdGNvbnN0cnVjdG9yKGV2ZW50SGFuZGxlciwgYnVmZmVyKSB7XG5cdFx0dGhpcy5zYW1wbGVSYXRlID0gNTsgLy8gbWlsbGlzZWNvbmRzXG5cdFx0dGhpcy5zdGFydFRpbWUgPSAwO1xuXHRcdHRoaXMuYnVmZmVyID0gYnVmZmVyIHx8IG51bGw7XG5cdFx0dGhpcy5kaXZpc2lvbjtcblx0XHR0aGlzLmZvcm1hdDtcblx0XHR0aGlzLnNldEludGVydmFsSWQgPSBmYWxzZTtcblx0XHR0aGlzLnRyYWNrcyA9IFtdO1xuXHRcdHRoaXMudGVtcG8gPSAxMjA7XG5cdFx0dGhpcy5zdGFydFRpY2sgPSAwO1xuXHRcdHRoaXMudGljayA9IDA7XG5cdFx0dGhpcy5sYXN0VGljayA9IG51bGw7XG5cdFx0dGhpcy5pbkxvb3AgPSBmYWxzZTtcblx0XHR0aGlzLnRvdGFsVGlja3MgPSAwO1xuXHRcdHRoaXMuZXZlbnRzID0gW107XG5cdFx0dGhpcy50b3RhbEV2ZW50cyA9IDA7XG5cdFx0dGhpcy5ldmVudExpc3RlbmVycyA9IHt9O1xuXG5cdFx0aWYgKHR5cGVvZihldmVudEhhbmRsZXIpID09PSAnZnVuY3Rpb24nKSB0aGlzLm9uKCdtaWRpRXZlbnQnLCBldmVudEhhbmRsZXIpO1xuXHR9XG5cblx0LyoqXG5cdCAqIExvYWQgYSBmaWxlIGludG8gdGhlIHBsYXllciAoTm9kZS5qcyBvbmx5KS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHBhdGggLSBQYXRoIG9mIGZpbGUuXG5cdCAqIEByZXR1cm4ge1BsYXllcn1cblx0ICovXG5cdGxvYWRGaWxlKHBhdGgpIHtcblx0XHR2YXIgZnMgPSByZXF1aXJlKCdmcycpO1xuXHRcdHRoaXMuYnVmZmVyID0gZnMucmVhZEZpbGVTeW5jKHBhdGgpO1xuXHRcdHJldHVybiB0aGlzLmZpbGVMb2FkZWQoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBMb2FkIGFuIGFycmF5IGJ1ZmZlciBpbnRvIHRoZSBwbGF5ZXIuXG5cdCAqIEBwYXJhbSB7YXJyYXl9IGFycmF5QnVmZmVyIC0gQXJyYXkgYnVmZmVyIG9mIGZpbGUgdG8gYmUgbG9hZGVkLlxuXHQgKiBAcmV0dXJuIHtQbGF5ZXJ9XG5cdCAqL1xuXHRsb2FkQXJyYXlCdWZmZXIoYXJyYXlCdWZmZXIpIHtcblx0XHR0aGlzLmJ1ZmZlciA9IG5ldyBVaW50OEFycmF5KGFycmF5QnVmZmVyKTtcblx0XHRyZXR1cm4gdGhpcy5maWxlTG9hZGVkKCk7XG5cdH1cblxuXHQvKipcblx0ICogTG9hZCBhIGRhdGEgVVJJIGludG8gdGhlIHBsYXllci5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGRhdGFVcmkgLSBEYXRhIFVSSSB0byBiZSBsb2FkZWQuXG5cdCAqIEByZXR1cm4ge1BsYXllcn1cblx0ICovXG5cdGxvYWREYXRhVXJpKGRhdGFVcmkpIHtcblx0XHQvLyBjb252ZXJ0IGJhc2U2NCB0byByYXcgYmluYXJ5IGRhdGEgaGVsZCBpbiBhIHN0cmluZy5cblx0XHQvLyBkb2Vzbid0IGhhbmRsZSBVUkxFbmNvZGVkIERhdGFVUklzIC0gc2VlIFNPIGFuc3dlciAjNjg1MDI3NiBmb3IgY29kZSB0aGF0IGRvZXMgdGhpc1xuXHRcdHZhciBieXRlU3RyaW5nID0gVXRpbHMuYXRvYihkYXRhVXJpLnNwbGl0KCcsJylbMV0pO1xuXG5cdFx0Ly8gd3JpdGUgdGhlIGJ5dGVzIG9mIHRoZSBzdHJpbmcgdG8gYW4gQXJyYXlCdWZmZXJcblx0XHR2YXIgaWEgPSBuZXcgVWludDhBcnJheShieXRlU3RyaW5nLmxlbmd0aCk7XG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBieXRlU3RyaW5nLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRpYVtpXSA9IGJ5dGVTdHJpbmcuY2hhckNvZGVBdChpKTtcblx0XHR9XG5cblx0XHR0aGlzLmJ1ZmZlciA9IGlhO1xuXHRcdHJldHVybiB0aGlzLmZpbGVMb2FkZWQoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXQgZmlsZXNpemUgb2YgbG9hZGVkIGZpbGUgaW4gbnVtYmVyIG9mIGJ5dGVzLlxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9IC0gVGhlIGZpbGVzaXplLlxuXHQgKi9cblx0Z2V0RmlsZXNpemUoKSB7XG5cdFx0cmV0dXJuIHRoaXMuYnVmZmVyID8gdGhpcy5idWZmZXIubGVuZ3RoIDogMDtcblx0fVxuXG5cdC8qKlxuXHQgKiBQYXJzZXMgZmlsZSBmb3IgbmVjZXNzYXJ5IGluZm9ybWF0aW9uIGFuZCBkb2VzIGEgZHJ5IHJ1biB0byBjYWxjdWxhdGUgdG90YWwgbGVuZ3RoLlxuXHQgKiBQb3B1bGF0ZXMgdGhpcy5ldmVudHMgJiB0aGlzLnRvdGFsVGlja3MuXG5cdCAqIEByZXR1cm4ge1BsYXllcn1cblx0ICovXG5cdGZpbGVMb2FkZWQoKSB7XG5cdFx0aWYgKCF0aGlzLnZhbGlkYXRlKCkpIHRocm93ICdJbnZhbGlkIE1JREkgZmlsZTsgc2hvdWxkIHN0YXJ0IHdpdGggTVRoZCc7XG5cdFx0cmV0dXJuIHRoaXMuZ2V0RGl2aXNpb24oKS5nZXRGb3JtYXQoKS5nZXRUcmFja3MoKS5kcnlSdW4oKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBWYWxpZGF0ZXMgZmlsZSB1c2luZyBzaW1wbGUgbWVhbnMgLSBmaXJzdCBmb3VyIGJ5dGVzIHNob3VsZCA9PSBNVGhkLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKi9cblx0dmFsaWRhdGUoKSB7XG5cdFx0cmV0dXJuIFV0aWxzLmJ5dGVzVG9MZXR0ZXJzKHRoaXMuYnVmZmVyLnNsaWNlKDAsIDQpKSA9PT0gJ01UaGQnO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgTUlESSBmaWxlIGZvcm1hdCBmb3IgbG9hZGVkIGZpbGUuXG5cdCAqIEByZXR1cm4ge1BsYXllcn1cblx0ICovXG5cdGdldEZvcm1hdCgpIHtcblx0XHQvKlxuXHRcdE1JREkgZmlsZXMgY29tZSBpbiAzIHZhcmlhdGlvbnM6XG5cdFx0Rm9ybWF0IDAgd2hpY2ggY29udGFpbiBhIHNpbmdsZSB0cmFja1xuXHRcdEZvcm1hdCAxIHdoaWNoIGNvbnRhaW4gb25lIG9yIG1vcmUgc2ltdWx0YW5lb3VzIHRyYWNrc1xuXHRcdChpZSBhbGwgdHJhY2tzIGFyZSB0byBiZSBwbGF5ZWQgc2ltdWx0YW5lb3VzbHkpLlxuXHRcdEZvcm1hdCAyIHdoaWNoIGNvbnRhaW4gb25lIG9yIG1vcmUgaW5kZXBlbmRhbnQgdHJhY2tzXG5cdFx0KGllIGVhY2ggdHJhY2sgaXMgdG8gYmUgcGxheWVkIGluZGVwZW5kYW50bHkgb2YgdGhlIG90aGVycykuXG5cdFx0cmV0dXJuIFV0aWxzLmJ5dGVzVG9OdW1iZXIodGhpcy5idWZmZXIuc2xpY2UoOCwgMTApKTtcblx0XHQqL1xuXG5cdFx0dGhpcy5mb3JtYXQgPSBVdGlscy5ieXRlc1RvTnVtYmVyKHRoaXMuYnVmZmVyLnNsaWNlKDgsIDEwKSk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogUGFyc2VzIG91dCB0cmFja3MsIHBsYWNlcyB0aGVtIGluIHRoaXMudHJhY2tzIGFuZCBpbml0aWFsaXplcyB0aGlzLnBvaW50ZXJzXG5cdCAqIEByZXR1cm4ge1BsYXllcn1cblx0ICovXG5cdGdldFRyYWNrcygpIHtcblx0XHR0aGlzLnRyYWNrcyA9IFtdO1xuXHRcdHRoaXMuYnVmZmVyLmZvckVhY2goZnVuY3Rpb24oYnl0ZSwgaW5kZXgpIHtcblx0XHRcdGlmIChVdGlscy5ieXRlc1RvTGV0dGVycyh0aGlzLmJ1ZmZlci5zbGljZShpbmRleCwgaW5kZXggKyA0KSkgPT0gJ01UcmsnKSB7XG5cdFx0XHRcdGxldCB0cmFja0xlbmd0aCA9IFV0aWxzLmJ5dGVzVG9OdW1iZXIodGhpcy5idWZmZXIuc2xpY2UoaW5kZXggKyA0LCBpbmRleCArIDgpKTtcblx0XHRcdFx0dGhpcy50cmFja3MucHVzaChuZXcgVHJhY2sodGhpcy50cmFja3MubGVuZ3RoLCB0aGlzLmJ1ZmZlci5zbGljZShpbmRleCArIDgsIGluZGV4ICsgOCArIHRyYWNrTGVuZ3RoKSkpO1xuXHRcdFx0fVxuXHRcdH0sIHRoaXMpO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogRW5hYmxlcyBhIHRyYWNrIGZvciBwbGF5aW5nLlxuXHQgKiBAcGFyYW0ge251bWJlcn0gdHJhY2tOdW1iZXIgLSBUcmFjayBudW1iZXJcblx0ICogQHJldHVybiB7UGxheWVyfVxuXHQgKi9cblx0ZW5hYmxlVHJhY2sodHJhY2tOdW1iZXIpIHtcblx0XHR0aGlzLnRyYWNrc1t0cmFja051bWJlciAtIDFdLmVuYWJsZSgpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIERpc2FibGVzIGEgdHJhY2sgZm9yIHBsYXlpbmcuXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSAtIFRyYWNrIG51bWJlclxuXHQgKiBAcmV0dXJuIHtQbGF5ZXJ9XG5cdCAqL1xuXHRkaXNhYmxlVHJhY2sodHJhY2tOdW1iZXIpIHtcblx0XHR0aGlzLnRyYWNrc1t0cmFja051bWJlciAtIDFdLmRpc2FibGUoKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHF1YXJ0ZXIgbm90ZSBkaXZpc2lvbiBvZiBsb2FkZWQgTUlESSBmaWxlLlxuXHQgKiBAcmV0dXJuIHtQbGF5ZXJ9XG5cdCAqL1xuXHRnZXREaXZpc2lvbigpIHtcblx0XHR0aGlzLmRpdmlzaW9uID0gVXRpbHMuYnl0ZXNUb051bWJlcih0aGlzLmJ1ZmZlci5zbGljZSgxMiwgMTQpKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgbWFpbiBwbGF5IGxvb3AuXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gLSBJbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdGhpcyBpcyBiZWluZyBjYWxsZWQgc2ltcGx5IGZvciBwYXJzaW5nIHB1cnBvc2VzLiAgRGlzcmVnYXJkcyB0aW1pbmcgaWYgc28uXG5cdCAqIEByZXR1cm4ge3VuZGVmaW5lZH1cblx0ICovXG5cdHBsYXlMb29wKGRyeVJ1bikge1xuXHRcdGlmICghdGhpcy5pbkxvb3ApIHtcblx0XHRcdHRoaXMuaW5Mb29wID0gdHJ1ZTtcblx0XHRcdHRoaXMudGljayA9IHRoaXMuZ2V0Q3VycmVudFRpY2soKTtcblxuXHRcdFx0dGhpcy50cmFja3MuZm9yRWFjaChmdW5jdGlvbih0cmFjaykge1xuXHRcdFx0XHQvLyBIYW5kbGUgbmV4dCBldmVudFxuXHRcdFx0XHRpZiAoIWRyeVJ1biAmJiB0aGlzLmVuZE9mRmlsZSgpKSB7XG5cdFx0XHRcdFx0Ly9jb25zb2xlLmxvZygnZW5kIG9mIGZpbGUnKVxuXHRcdFx0XHRcdHRoaXMudHJpZ2dlclBsYXllckV2ZW50KCdlbmRPZkZpbGUnKTtcblx0XHRcdFx0XHR0aGlzLnN0b3AoKTtcblxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGxldCBldmVudCA9IHRyYWNrLmhhbmRsZUV2ZW50KHRoaXMudGljaywgZHJ5UnVuKTtcblxuXHRcdFx0XHRcdGlmIChkcnlSdW4gJiYgZXZlbnQgJiYgZXZlbnQuaGFzT3duUHJvcGVydHkoJ25hbWUnKSAmJiBldmVudC5uYW1lID09PSAnU2V0IFRlbXBvJykge1xuXHRcdFx0XHRcdFx0Ly8gR3JhYiB0ZW1wbyBpZiBhdmFpbGFibGUuXG5cdFx0XHRcdFx0XHR0aGlzLnRlbXBvID0gZXZlbnQuZGF0YTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRpZiAoZXZlbnQgJiYgIWRyeVJ1bikgdGhpcy5lbWl0RXZlbnQoZXZlbnQpO1xuXHRcdFx0XHR9XG5cblx0XHRcdH0sIHRoaXMpO1xuXG5cdFx0XHRpZiAoIWRyeVJ1bikgdGhpcy50cmlnZ2VyUGxheWVyRXZlbnQoJ3BsYXlpbmcnLCB7dGljazogdGhpcy50aWNrfSk7XG5cdFx0XHR0aGlzLmluTG9vcCA9IGZhbHNlO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBTZXR0ZXIgZm9yIHN0YXJ0VGltZS5cblx0ICogQHBhcmFtIHtudW1iZXJ9IC0gVVRDIHRpbWVzdGFtcFxuXHQgKi9cblx0c2V0U3RhcnRUaW1lKHN0YXJ0VGltZSkge1xuXHRcdHRoaXMuc3RhcnRUaW1lID0gc3RhcnRUaW1lO1xuXHR9XG5cblx0LyoqXG5cdCAqIFN0YXJ0IHBsYXlpbmcgbG9hZGVkIE1JREkgZmlsZSBpZiBub3QgYWxyZWFkeSBwbGF5aW5nLlxuXHQgKiBAcmV0dXJuIHtQbGF5ZXJ9XG5cdCAqL1xuXHRwbGF5KCkge1xuXHRcdGlmICh0aGlzLmlzUGxheWluZygpKSB0aHJvdyAnQWxyZWFkeSBwbGF5aW5nLi4uJztcblxuXHRcdC8vIEluaXRpYWxpemVcblx0XHRpZiAoIXRoaXMuc3RhcnRUaW1lKSB0aGlzLnN0YXJ0VGltZSA9IChuZXcgRGF0ZSgpKS5nZXRUaW1lKCk7XG5cblx0XHQvLyBTdGFydCBwbGF5IGxvb3Bcblx0XHQvL3dpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUodGhpcy5wbGF5TG9vcC5iaW5kKHRoaXMpKTtcblx0XHR0aGlzLnNldEludGVydmFsSWQgPSBzZXRJbnRlcnZhbCh0aGlzLnBsYXlMb29wLmJpbmQodGhpcyksIHRoaXMuc2FtcGxlUmF0ZSk7XG5cblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBQYXVzZXMgcGxheWJhY2sgaWYgcGxheWluZy5cblx0ICogQHJldHVybiB7UGxheWVyfVxuXHQgKi9cblx0cGF1c2UoKSB7XG5cdFx0Y2xlYXJJbnRlcnZhbCh0aGlzLnNldEludGVydmFsSWQpO1xuXHRcdHRoaXMuc2V0SW50ZXJ2YWxJZCA9IGZhbHNlO1xuXHRcdHRoaXMuc3RhcnRUaWNrID0gdGhpcy50aWNrO1xuXHRcdHRoaXMuc3RhcnRUaW1lID0gMDtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBTdG9wcyBwbGF5YmFjayBpZiBwbGF5aW5nLlxuXHQgKiBAcmV0dXJuIHtQbGF5ZXJ9XG5cdCAqL1xuXHRzdG9wKCkge1xuXHRcdGNsZWFySW50ZXJ2YWwodGhpcy5zZXRJbnRlcnZhbElkKTtcblx0XHR0aGlzLnNldEludGVydmFsSWQgPSBmYWxzZTtcblx0XHR0aGlzLnN0YXJ0VGljayA9IDA7XG5cdFx0dGhpcy5zdGFydFRpbWUgPSAwO1xuXHRcdHRoaXMucmVzZXRUcmFja3MoKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBTa2lwcyBwbGF5ZXIgcG9pbnRlciB0byBzcGVjaWZpZWQgdGljay5cblx0ICogQHBhcmFtIHtudW1iZXJ9IC0gVGljayB0byBza2lwIHRvLlxuXHQgKiBAcmV0dXJuIHtQbGF5ZXJ9XG5cdCAqL1xuXHRza2lwVG9UaWNrKHRpY2spIHtcblx0XHR0aGlzLnN0b3AoKTtcblx0XHR0aGlzLnN0YXJ0VGljayA9IHRpY2s7XG5cblx0XHQvLyBOZWVkIHRvIHNldCB0cmFjayBldmVudCBpbmRleGVzIHRvIHRoZSBuZWFyZXN0IHBvc3NpYmxlIGV2ZW50IHRvIHRoZSBzcGVjaWZpZWQgdGljay5cblx0XHR0aGlzLnRyYWNrcy5mb3JFYWNoKGZ1bmN0aW9uKHRyYWNrKSB7XG5cdFx0XHR0cmFjay5zZXRFdmVudEluZGV4QnlUaWNrKHRpY2spO1xuXHRcdH0pO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNraXBzIHBsYXllciBwb2ludGVyIHRvIHNwZWNpZmllZCBwZXJjZW50YWdlLlxuXHQgKiBAcGFyYW0ge251bWJlcn0gLSBQZXJjZW50IHZhbHVlIGluIGludGVnZXIgZm9ybWF0LlxuXHQgKiBAcmV0dXJuIHtQbGF5ZXJ9XG5cdCAqL1xuXHRza2lwVG9QZXJjZW50KHBlcmNlbnQpIHtcblx0XHRpZiAocGVyY2VudCA8IDAgfHwgcGVyY2VudCA+IDEwMCkgdGhyb3cgXCJQZXJjZW50IG11c3QgYmUgbnVtYmVyIGJldHdlZW4gMSBhbmQgMTAwLlwiO1xuXHRcdHRoaXMuc2tpcFRvVGljayhNYXRoLnJvdW5kKHBlcmNlbnQgLyAxMDAgKiB0aGlzLnRvdGFsVGlja3MpKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBTa2lwcyBwbGF5ZXIgcG9pbnRlciB0byBzcGVjaWZpZWQgc2Vjb25kcy5cblx0ICogQHBhcmFtIHtudW1iZXJ9IC0gU2Vjb25kcyB0byBza2lwIHRvLlxuXHQgKiBAcmV0dXJuIHtQbGF5ZXJ9XG5cdCAqL1xuXHRza2lwVG9TZWNvbmRzKHNlY29uZHMpIHtcblx0XHR2YXIgc29uZ1RpbWUgPSB0aGlzLmdldFNvbmdUaW1lKCk7XG5cdFx0aWYgKHNlY29uZHMgPCAwIHx8IHNlY29uZHMgPiBzb25nVGltZSkgdGhyb3cgc2Vjb25kcyArIFwiIHNlY29uZHMgbm90IHdpdGhpbiBzb25nIHRpbWUgb2YgXCIgKyBzb25nVGltZTtcblx0XHR0aGlzLnNraXBUb1BlcmNlbnQoc2Vjb25kcyAvIHNvbmdUaW1lICogMTAwKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBDaGVja3MgaWYgcGxheWVyIGlzIHBsYXlpbmdcblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdGlzUGxheWluZygpIHtcblx0XHRyZXR1cm4gdGhpcy5zZXRJbnRlcnZhbElkID4gMCB8fCB0eXBlb2YgdGhpcy5zZXRJbnRlcnZhbElkID09PSAnb2JqZWN0Jztcblx0fVxuXG5cdC8qKlxuXHQgKiBQbGF5cyB0aGUgbG9hZGVkIE1JREkgZmlsZSB3aXRob3V0IHJlZ2FyZCBmb3IgdGltaW5nIGFuZCBzYXZlcyBldmVudHMgaW4gdGhpcy5ldmVudHMuICBFc3NlbnRpYWxseSB1c2VkIGFzIGEgcGFyc2VyLlxuXHQgKiBAcmV0dXJuIHtQbGF5ZXJ9XG5cdCAqL1xuXHRkcnlSdW4oKSB7XG5cdFx0Ly8gUmVzZXQgdHJhY2tzIGZpcnN0XG5cdFx0dGhpcy5yZXNldFRyYWNrcygpO1xuXHRcdHdoaWxlICghdGhpcy5lbmRPZkZpbGUoKSkgdGhpcy5wbGF5TG9vcCh0cnVlKTtcblx0XHR0aGlzLmV2ZW50cyA9IHRoaXMuZ2V0RXZlbnRzKCk7XG5cdFx0dGhpcy50b3RhbEV2ZW50cyA9IHRoaXMuZ2V0VG90YWxFdmVudHMoKTtcblx0XHR0aGlzLnRvdGFsVGlja3MgPSB0aGlzLmdldFRvdGFsVGlja3MoKTtcblx0XHR0aGlzLnN0YXJ0VGljayA9IDA7XG5cdFx0dGhpcy5zdGFydFRpbWUgPSAwO1xuXG5cdFx0Ly8gTGVhdmUgdHJhY2tzIGluIHByaXN0aW5lIGNvbmRpc2hcblx0XHR0aGlzLnJlc2V0VHJhY2tzKCk7XG5cblx0XHQvL2NvbnNvbGUubG9nKCdTb25nIHRpbWU6ICcgKyB0aGlzLmdldFNvbmdUaW1lKCkgKyAnIHNlY29uZHMgLyAnICsgdGhpcy50b3RhbFRpY2tzICsgJyB0aWNrcy4nKTtcblxuXHRcdHRoaXMudHJpZ2dlclBsYXllckV2ZW50KCdmaWxlTG9hZGVkJywgdGhpcyk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogUmVzZXRzIHBsYXkgcG9pbnRlcnMgZm9yIGFsbCB0cmFja3MuXG5cdCAqIEByZXR1cm4ge1BsYXllcn1cblx0ICovXG5cdHJlc2V0VHJhY2tzKCkge1xuXHRcdHRoaXMudHJhY2tzLmZvckVhY2godHJhY2sgPT4gdHJhY2sucmVzZXQoKSk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyBhbiBhcnJheSBvZiBldmVudHMgZ3JvdXBlZCBieSB0cmFjay5cblx0ICogQHJldHVybiB7YXJyYXl9XG5cdCAqL1xuXHRnZXRFdmVudHMoKSB7XG5cdFx0cmV0dXJuIHRoaXMudHJhY2tzLm1hcCh0cmFjayA9PiB0cmFjay5ldmVudHMpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdG90YWwgbnVtYmVyIG9mIHRpY2tzIGluIHRoZSBsb2FkZWQgTUlESSBmaWxlLlxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9XG5cdCAqL1xuXHRnZXRUb3RhbFRpY2tzKCkge1xuXHRcdHJldHVybiBNYXRoLm1heC5hcHBseShudWxsLCB0aGlzLnRyYWNrcy5tYXAodHJhY2sgPT4gdHJhY2suZGVsdGEpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRvdGFsIG51bWJlciBvZiBldmVudHMgaW4gdGhlIGxvYWRlZCBNSURJIGZpbGUuXG5cdCAqIEByZXR1cm4ge251bWJlcn1cblx0ICovXG5cdGdldFRvdGFsRXZlbnRzKCkge1xuXHRcdHJldHVybiB0aGlzLnRyYWNrcy5yZWR1Y2UoKGEsIGIpID0+IHtyZXR1cm4ge2V2ZW50czoge2xlbmd0aDogYS5ldmVudHMubGVuZ3RoICsgYi5ldmVudHMubGVuZ3RofX19LCB7ZXZlbnRzOiB7bGVuZ3RoOiAwfX0pLmV2ZW50cy5sZW5ndGg7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyBzb25nIGR1cmF0aW9uIGluIHNlY29uZHMuXG5cdCAqIEByZXR1cm4ge251bWJlcn1cblx0ICovXG5cdGdldFNvbmdUaW1lKCkge1xuXHRcdHJldHVybiB0aGlzLnRvdGFsVGlja3MgLyB0aGlzLmRpdmlzaW9uIC8gdGhpcy50ZW1wbyAqIDYwO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgcmVtYWluaW5nIG51bWJlciBvZiBzZWNvbmRzIGluIHBsYXliYWNrLlxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9XG5cdCAqL1xuXHRnZXRTb25nVGltZVJlbWFpbmluZygpIHtcblx0XHRyZXR1cm4gTWF0aC5yb3VuZCgodGhpcy50b3RhbFRpY2tzIC0gdGhpcy50aWNrKSAvIHRoaXMuZGl2aXNpb24gLyB0aGlzLnRlbXBvICogNjApO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgcmVtYWluaW5nIHBlcmNlbnQgb2YgcGxheWJhY2suXG5cdCAqIEByZXR1cm4ge251bWJlcn1cblx0ICovXG5cdGdldFNvbmdQZXJjZW50UmVtYWluaW5nKCkge1xuXHRcdHJldHVybiBNYXRoLnJvdW5kKHRoaXMuZ2V0U29uZ1RpbWVSZW1haW5pbmcoKSAvIHRoaXMuZ2V0U29uZ1RpbWUoKSAqIDEwMCk7XG5cdH1cblxuXHQvKipcblx0ICogTnVtYmVyIG9mIGJ5dGVzIHByb2Nlc3NlZCBpbiB0aGUgbG9hZGVkIE1JREkgZmlsZS5cblx0ICogQHJldHVybiB7bnVtYmVyfVxuXHQgKi9cblx0Ynl0ZXNQcm9jZXNzZWQoKSB7XG5cdFx0Ly8gQ3VycmVudGx5IGFzc3VtZSBoZWFkZXIgY2h1bmsgaXMgc3RyaWN0bHkgMTQgYnl0ZXNcblx0XHRyZXR1cm4gMTQgKyB0aGlzLnRyYWNrcy5sZW5ndGggKiA4ICsgdGhpcy50cmFja3MucmVkdWNlKChhLCBiKSA9PiB7cmV0dXJuIHtwb2ludGVyOiBhLnBvaW50ZXIgKyBiLnBvaW50ZXJ9fSwge3BvaW50ZXI6IDB9KS5wb2ludGVyO1xuXHR9XG5cblx0LyoqXG5cdCAqIE51bWJlciBvZiBldmVudHMgcGxheWVkIHVwIHRvIHRoaXMgcG9pbnQuXG5cdCAqIEByZXR1cm4ge251bWJlcn1cblx0ICovXG5cdGV2ZW50c1BsYXllZCgpIHtcblx0XHRyZXR1cm4gdGhpcy50cmFja3MucmVkdWNlKChhLCBiKSA9PiB7cmV0dXJuIHtldmVudEluZGV4OiBhLmV2ZW50SW5kZXggKyBiLmV2ZW50SW5kZXh9fSwge2V2ZW50SW5kZXg6IDB9KS5ldmVudEluZGV4O1xuXHR9XG5cblx0LyoqXG5cdCAqIERldGVybWluZXMgaWYgdGhlIHBsYXllciBwb2ludGVyIGhhcyByZWFjaGVkIHRoZSBlbmQgb2YgdGhlIGxvYWRlZCBNSURJIGZpbGUuXG5cdCAqIFVzZWQgaW4gdHdvIHdheXM6XG5cdCAqIDEuIElmIHBsYXlpbmcgcmVzdWx0IGlzIGJhc2VkIG9uIGxvYWRlZCBKU09OIGV2ZW50cy5cblx0ICogMi4gSWYgcGFyc2luZyAoZHJ5UnVuKSBpdCdzIGJhc2VkIG9uIHRoZSBhY3R1YWwgYnVmZmVyIGxlbmd0aCB2cyBieXRlcyBwcm9jZXNzZWQuXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqL1xuXHRlbmRPZkZpbGUoKSB7XG5cdFx0aWYgKHRoaXMuaXNQbGF5aW5nKCkpIHtcblx0XHRcdHJldHVybiB0aGlzLmV2ZW50c1BsYXllZCgpID09IHRoaXMudG90YWxFdmVudHM7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMuYnl0ZXNQcm9jZXNzZWQoKSA9PSB0aGlzLmJ1ZmZlci5sZW5ndGg7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgY3VycmVudCB0aWNrIG51bWJlciBpbiBwbGF5YmFjay5cblx0ICogQHJldHVybiB7bnVtYmVyfVxuXHQgKi9cblx0Z2V0Q3VycmVudFRpY2soKSB7XG5cdFx0cmV0dXJuIE1hdGgucm91bmQoKChuZXcgRGF0ZSgpKS5nZXRUaW1lKCkgLSB0aGlzLnN0YXJ0VGltZSkgLyAxMDAwICogKHRoaXMuZGl2aXNpb24gKiAodGhpcy50ZW1wbyAvIDYwKSkpICsgdGhpcy5zdGFydFRpY2s7XG5cdH1cblxuXHQvKipcblx0ICogU2VuZHMgTUlESSBldmVudCBvdXQgdG8gbGlzdGVuZXIuXG5cdCAqIEBwYXJhbSB7b2JqZWN0fVxuXHQgKiBAcmV0dXJuIHtQbGF5ZXJ9XG5cdCAqL1xuXHRlbWl0RXZlbnQoZXZlbnQpIHtcblx0XHR0aGlzLnRyaWdnZXJQbGF5ZXJFdmVudCgnbWlkaUV2ZW50JywgZXZlbnQpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFN1YnNjcmliZXMgZXZlbnRzIHRvIGxpc3RlbmVycyBcblx0ICogQHBhcmFtIHtzdHJpbmd9IC0gTmFtZSBvZiBldmVudCB0byBzdWJzY3JpYmUgdG8uXG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb259IC0gQ2FsbGJhY2sgdG8gZmlyZSB3aGVuIGV2ZW50IGlzIGJyb2FkY2FzdC5cblx0ICogQHJldHVybiB7UGxheWVyfVxuXHQgKi9cblx0b24ocGxheWVyRXZlbnQsIGZuKSB7XG5cdFx0aWYgKCF0aGlzLmV2ZW50TGlzdGVuZXJzLmhhc093blByb3BlcnR5KHBsYXllckV2ZW50KSkgdGhpcy5ldmVudExpc3RlbmVyc1twbGF5ZXJFdmVudF0gPSBbXTtcblx0XHR0aGlzLmV2ZW50TGlzdGVuZXJzW3BsYXllckV2ZW50XS5wdXNoKGZuKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBCcm9hZGNhc3RzIGV2ZW50IHRvIHRyaWdnZXIgc3Vic2NyaWJlZCBjYWxsYmFja3MuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSAtIE5hbWUgb2YgZXZlbnQuXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSAtIERhdGEgdG8gYmUgcGFzc2VkIHRvIHN1YnNjcmliZXIgY2FsbGJhY2suXG5cdCAqIEByZXR1cm4ge1BsYXllcn1cblx0ICovXG5cdHRyaWdnZXJQbGF5ZXJFdmVudChwbGF5ZXJFdmVudCwgZGF0YSkge1xuXHRcdGlmICh0aGlzLmV2ZW50TGlzdGVuZXJzLmhhc093blByb3BlcnR5KHBsYXllckV2ZW50KSkgdGhpcy5ldmVudExpc3RlbmVyc1twbGF5ZXJFdmVudF0uZm9yRWFjaChmbiA9PiBmbihkYXRhIHx8IHt9KSk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxufVxuXG5leHBvcnRzLlBsYXllciA9IFBsYXllcjtcbi8qKlxuICogQ2xhc3MgcmVwcmVzZW50aW5nIGEgdHJhY2suICBDb250YWlucyBtZXRob2RzIGZvciBwYXJzaW5nIGV2ZW50cyBhbmQga2VlcGluZyB0cmFjayBvZiBwb2ludGVyLlxuICovXG5jbGFzcyBUcmFja1x0e1xuXHRjb25zdHJ1Y3RvcihpbmRleCwgZGF0YSkge1xuXHRcdHRoaXMuZW5hYmxlZCA9IHRydWU7XG5cdFx0dGhpcy5ldmVudEluZGV4ID0gMDtcblx0XHR0aGlzLnBvaW50ZXIgPSAwO1xuXHRcdHRoaXMubGFzdFRpY2sgPSAwO1xuXHRcdHRoaXMubGFzdFN0YXR1cyA9IG51bGw7XG5cdFx0dGhpcy5pbmRleCA9IGluZGV4O1xuXHRcdHRoaXMuZGF0YSA9IGRhdGE7XG5cdFx0dGhpcy5kZWx0YSA9IDA7XG5cdFx0dGhpcy5ydW5uaW5nRGVsdGEgPSAwO1xuXHRcdHRoaXMuZXZlbnRzID0gW107XG5cdH1cblxuXHQvKipcblx0ICogUmVzZXRzIGFsbCBzdGF0ZWZ1bCB0cmFjayBpbmZvcm1haW9uIHVzZWQgZHVyaW5nIHBsYXliYWNrLlxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdHJlc2V0KCkge1xuXHRcdHRoaXMuZW5hYmxlZCA9IHRydWU7XG5cdFx0dGhpcy5ldmVudEluZGV4ID0gMDtcblx0XHR0aGlzLnBvaW50ZXIgPSAwO1xuXHRcdHRoaXMubGFzdFRpY2sgPSAwO1xuXHRcdHRoaXMubGFzdFN0YXR1cyA9IG51bGw7XG5cdFx0dGhpcy5kZWx0YSA9IDA7XG5cdFx0dGhpcy5ydW5uaW5nRGVsdGEgPSAwO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhpcyB0cmFjayB0byBiZSBlbmFibGVkIGR1cmluZyBwbGF5YmFjay5cblx0ICogQHJldHVybiB7VHJhY2t9XG5cdCAqL1xuXHRlbmFibGUoKSB7XG5cdFx0dGhpcy5lbmFibGVkID0gdHJ1ZTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoaXMgdHJhY2sgdG8gYmUgZGlzYWJsZWQgZHVyaW5nIHBsYXliYWNrLlxuXHQgKiBAcmV0dXJuIHtUcmFja31cblx0ICovXG5cdGRpc2FibGUoKSB7XG5cdFx0dGhpcy5lbmFibGVkID0gZmFsc2U7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgdHJhY2sgZXZlbnQgaW5kZXggdG8gdGhlIG5lYXJlc3QgZXZlbnQgdG8gdGhlIGdpdmVuIHRpY2suXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSB0aWNrXG5cdCAqIEByZXR1cm4ge1RyYWNrfVxuXHQgKi9cblx0c2V0RXZlbnRJbmRleEJ5VGljayh0aWNrKSB7XG5cdFx0dGljayA9IHRpY2sgfHwgMDtcblxuXHRcdGZvciAodmFyIGkgaW4gdGhpcy5ldmVudHMpIHtcblx0XHRcdGlmICh0aGlzLmV2ZW50c1tpXS50aWNrID49IHRpY2spIHtcblx0XHRcdFx0dGhpcy5ldmVudEluZGV4ID0gaTtcblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgYnl0ZSBsb2NhdGVkIGF0IHBvaW50ZXIgcG9zaXRpb24uXG5cdCAqIEByZXR1cm4ge251bWJlcn1cblx0ICovXG5cdGdldEN1cnJlbnRCeXRlKCkge1xuXHRcdHJldHVybiB0aGlzLmRhdGFbdGhpcy5wb2ludGVyXTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIGNvdW50IG9mIGRlbHRhIGJ5dGVzIGFuZCBjdXJyZW50IHBvaW50ZXIgcG9zaXRpb24uXG5cdCAqIEByZXR1cm4ge251bWJlcn1cblx0ICovXG5cdGdldERlbHRhQnl0ZUNvdW50KCkge1xuXHRcdC8vIEdldCBieXRlIGNvdW50IG9mIGRlbHRhIFZMVlxuXHRcdC8vIGh0dHA6Ly93d3cuY2Nhcmgub3JnL2NvdXJzZXMvMjUzL2hhbmRvdXQvdmx2L1xuXHRcdC8vIElmIGJ5dGUgaXMgZ3JlYXRlciBvciBlcXVhbCB0byA4MGggKDEyOCBkZWNpbWFsKSB0aGVuIHRoZSBuZXh0IGJ5dGVcblx0ICAgIC8vIGlzIGFsc28gcGFydCBvZiB0aGUgVkxWLFxuXHQgICBcdC8vIGVsc2UgYnl0ZSBpcyB0aGUgbGFzdCBieXRlIGluIGEgVkxWLlxuXHQgICBcdHZhciBjdXJyZW50Qnl0ZSA9IHRoaXMuZ2V0Q3VycmVudEJ5dGUoKTtcblx0ICAgXHR2YXIgYnl0ZUNvdW50ID0gMTtcblxuXHRcdHdoaWxlIChjdXJyZW50Qnl0ZSA+PSAxMjgpIHtcblx0XHRcdGN1cnJlbnRCeXRlID0gdGhpcy5kYXRhW3RoaXMucG9pbnRlciArIGJ5dGVDb3VudF07XG5cdFx0XHRieXRlQ291bnQrKztcblx0XHR9XG5cblx0XHRyZXR1cm4gYnl0ZUNvdW50O1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldCBkZWx0YSB2YWx1ZSBhdCBjdXJyZW50IHBvaW50ZXIgcG9zaXRpb24uXG5cdCAqIEByZXR1cm4ge251bWJlcn1cblx0ICovXG5cdGdldERlbHRhKCkge1xuXHRcdHJldHVybiBVdGlscy5yZWFkVmFySW50KHRoaXMuZGF0YS5zbGljZSh0aGlzLnBvaW50ZXIsIHRoaXMucG9pbnRlciArIHRoaXMuZ2V0RGVsdGFCeXRlQ291bnQoKSkpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEhhbmRsZXMgZXZlbnQgd2l0aGluIGEgZ2l2ZW4gdHJhY2sgc3RhcnRpbmcgYXQgc3BlY2lmaWVkIGluZGV4XG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBjdXJyZW50VGlja1xuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IGRyeVJ1biAtIElmIHRydWUgZXZlbnRzIHdpbGwgYmUgcGFyc2VkIGFuZCByZXR1cm5lZCByZWdhcmRsZXNzIG9mIHRpbWUuXG5cdCAqL1xuXHRoYW5kbGVFdmVudChjdXJyZW50VGljaywgZHJ5UnVuKSB7XG5cdFx0ZHJ5UnVuID0gZHJ5UnVuIHx8IGZhbHNlO1xuXG5cdFx0aWYgKGRyeVJ1bikge1xuXHRcdFx0dmFyIGVsYXBzZWRUaWNrcyA9IGN1cnJlbnRUaWNrIC0gdGhpcy5sYXN0VGljaztcblx0XHRcdHZhciBkZWx0YSA9IHRoaXMuZ2V0RGVsdGEoKTtcblx0XHRcdHZhciBldmVudFJlYWR5ID0gZWxhcHNlZFRpY2tzID49IGRlbHRhO1xuXG5cdFx0XHRpZiAodGhpcy5wb2ludGVyIDwgdGhpcy5kYXRhLmxlbmd0aCAmJiAoZHJ5UnVuIHx8IGV2ZW50UmVhZHkpKSB7XG5cdFx0XHRcdGxldCBldmVudCA9IHRoaXMucGFyc2VFdmVudCgpO1xuXHRcdFx0XHRpZiAodGhpcy5lbmFibGVkKSByZXR1cm4gZXZlbnQ7XG5cdFx0XHRcdC8vIFJlY3Vyc2l2ZWx5IGNhbGwgdGhpcyBmdW5jdGlvbiBmb3IgZWFjaCBldmVudCBhaGVhZCB0aGF0IGhhcyAwIGRlbHRhIHRpbWU/XG5cdFx0XHR9XG5cblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gTGV0J3MgYWN0dWFsbHkgcGxheSB0aGUgTUlESSBmcm9tIHRoZSBnZW5lcmF0ZWQgSlNPTiBldmVudHMgY3JlYXRlZCBieSB0aGUgZHJ5IHJ1bi5cblx0XHRcdGlmICh0aGlzLmV2ZW50c1t0aGlzLmV2ZW50SW5kZXhdICYmIHRoaXMuZXZlbnRzW3RoaXMuZXZlbnRJbmRleF0udGljayA8PSBjdXJyZW50VGljaykge1xuXHRcdFx0XHR0aGlzLmV2ZW50SW5kZXgrKztcblx0XHRcdFx0aWYgKHRoaXMuZW5hYmxlZCkgcmV0dXJuIHRoaXMuZXZlbnRzW3RoaXMuZXZlbnRJbmRleCAtIDFdO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldCBzdHJpbmcgZGF0YSBmcm9tIGV2ZW50LlxuXHQgKiBAcGFyYW0ge251bWJlcn0gZXZlbnRTdGFydEluZGV4XG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICovXG5cdGdldFN0cmluZ0RhdGEoZXZlbnRTdGFydEluZGV4KSB7XG5cdFx0dmFyIGN1cnJlbnRCeXRlID0gdGhpcy5wb2ludGVyO1xuXHRcdHZhciBieXRlQ291bnQgPSAxO1xuXHRcdHZhciBsZW5ndGggPSBVdGlscy5yZWFkVmFySW50KHRoaXMuZGF0YS5zbGljZShldmVudFN0YXJ0SW5kZXggKyAyLCBldmVudFN0YXJ0SW5kZXggKyAyICsgYnl0ZUNvdW50KSk7XG5cdFx0dmFyIHN0cmluZ0xlbmd0aCA9IGxlbmd0aDtcblxuXHRcdHJldHVybiBVdGlscy5ieXRlc1RvTGV0dGVycyh0aGlzLmRhdGEuc2xpY2UoZXZlbnRTdGFydEluZGV4ICsgYnl0ZUNvdW50ICsgMiwgZXZlbnRTdGFydEluZGV4ICsgYnl0ZUNvdW50ICsgbGVuZ3RoICsgMikpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFBhcnNlcyBldmVudCBpbnRvIEpTT04gYW5kIGFkdmFuY2VzIHBvaW50ZXIgZm9yIHRoZSB0cmFja1xuXHQgKiBAcmV0dXJuIHtvYmplY3R9XG5cdCAqL1xuXHRwYXJzZUV2ZW50KCkge1xuXHRcdHZhciBldmVudFN0YXJ0SW5kZXggPSB0aGlzLnBvaW50ZXIgKyB0aGlzLmdldERlbHRhQnl0ZUNvdW50KCk7XG5cdFx0dmFyIGV2ZW50SnNvbiA9IHt9O1xuXHRcdHZhciBkZWx0YUJ5dGVDb3VudCA9IHRoaXMuZ2V0RGVsdGFCeXRlQ291bnQoKTtcblx0XHRldmVudEpzb24udHJhY2sgPSB0aGlzLmluZGV4ICsgMTtcblx0XHRldmVudEpzb24uZGVsdGEgPSB0aGlzLmdldERlbHRhKCk7XG5cdFx0dGhpcy5sYXN0VGljayA9IHRoaXMubGFzdFRpY2sgKyBldmVudEpzb24uZGVsdGE7XG5cdFx0dGhpcy5ydW5uaW5nRGVsdGEgKz0gZXZlbnRKc29uLmRlbHRhO1xuXHRcdGV2ZW50SnNvbi50aWNrID0gdGhpcy5ydW5uaW5nRGVsdGE7XG5cdFx0ZXZlbnRKc29uLmJ5dGVJbmRleCA9IHRoaXMucG9pbnRlcjtcblxuXHRcdC8vZXZlbnRKc29uLnJhdyA9IGV2ZW50O1xuXHRcdGlmICh0aGlzLmRhdGFbZXZlbnRTdGFydEluZGV4XSA9PSAweGZmKSB7XG5cdFx0XHQvLyBNZXRhIEV2ZW50XG5cblx0XHRcdC8vIElmIHRoaXMgaXMgYSBtZXRhIGV2ZW50IHdlIHNob3VsZCBlbWl0IHRoZSBkYXRhIGFuZCBpbW1lZGlhdGVseSBtb3ZlIHRvIHRoZSBuZXh0IGV2ZW50XG5cdFx0XHQvLyBvdGhlcndpc2UgaWYgd2UgbGV0IGl0IHJ1biB0aHJvdWdoIHRoZSBuZXh0IGN5Y2xlIGEgc2xpZ2h0IGRlbGF5IHdpbGwgYWNjdW11bGF0ZSBpZiBtdWx0aXBsZSB0cmFja3Ncblx0XHRcdC8vIGFyZSBiZWluZyBwbGF5ZWQgc2ltdWx0YW5lb3VzbHlcblxuXHRcdFx0c3dpdGNoKHRoaXMuZGF0YVtldmVudFN0YXJ0SW5kZXggKyAxXSkge1xuXHRcdFx0XHRjYXNlIDB4MDA6IC8vIFNlcXVlbmNlIE51bWJlclxuXHRcdFx0XHRcdGV2ZW50SnNvbi5uYW1lID0gJ1NlcXVlbmNlIE51bWJlcic7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgMHgwMTogLy8gVGV4dCBFdmVudFxuXHRcdFx0XHRcdGV2ZW50SnNvbi5uYW1lID0gJ1RleHQgRXZlbnQnO1xuXHRcdFx0XHRcdGV2ZW50SnNvbi5zdHJpbmcgPSB0aGlzLmdldFN0cmluZ0RhdGEoZXZlbnRTdGFydEluZGV4KTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAweDAyOiAvLyBDb3B5cmlnaHQgTm90aWNlXG5cdFx0XHRcdFx0ZXZlbnRKc29uLm5hbWUgPSAnQ29weXJpZ2h0IE5vdGljZSc7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgMHgwMzogLy8gU2VxdWVuY2UvVHJhY2sgTmFtZVxuXHRcdFx0XHRcdGV2ZW50SnNvbi5uYW1lID0gJ1NlcXVlbmNlL1RyYWNrIE5hbWUnO1xuXHRcdFx0XHRcdGV2ZW50SnNvbi5zdHJpbmcgPSB0aGlzLmdldFN0cmluZ0RhdGEoZXZlbnRTdGFydEluZGV4KTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAweDA0OiAvLyBJbnN0cnVtZW50IE5hbWVcblx0XHRcdFx0XHRldmVudEpzb24ubmFtZSA9ICdJbnN0cnVtZW50IE5hbWUnO1xuXHRcdFx0XHRcdGV2ZW50SnNvbi5zdHJpbmcgPSB0aGlzLmdldFN0cmluZ0RhdGEoZXZlbnRTdGFydEluZGV4KTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAweDA1OiAvLyBMeXJpY1xuXHRcdFx0XHRcdGV2ZW50SnNvbi5uYW1lID0gJ0x5cmljJztcblx0XHRcdFx0XHRldmVudEpzb24uc3RyaW5nID0gdGhpcy5nZXRTdHJpbmdEYXRhKGV2ZW50U3RhcnRJbmRleCk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgMHgwNjogLy8gTWFya2VyXG5cdFx0XHRcdFx0ZXZlbnRKc29uLm5hbWUgPSAnTWFya2VyJztcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAweDA3OiAvLyBDdWUgUG9pbnRcblx0XHRcdFx0XHRldmVudEpzb24ubmFtZSA9ICdDdWUgUG9pbnQnO1xuXHRcdFx0XHRcdGV2ZW50SnNvbi5zdHJpbmcgPSB0aGlzLmdldFN0cmluZ0RhdGEoZXZlbnRTdGFydEluZGV4KTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAweDA5OiAvLyBEZXZpY2UgTmFtZVxuXHRcdFx0XHRcdGV2ZW50SnNvbi5uYW1lID0gJ0RldmljZSBOYW1lJztcblx0XHRcdFx0XHRldmVudEpzb24uc3RyaW5nID0gdGhpcy5nZXRTdHJpbmdEYXRhKGV2ZW50U3RhcnRJbmRleCk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgMHgyMDogLy8gTUlESSBDaGFubmVsIFByZWZpeFxuXHRcdFx0XHRcdGV2ZW50SnNvbi5uYW1lID0gJ01JREkgQ2hhbm5lbCBQcmVmaXgnO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIDB4MjE6IC8vIE1JREkgUG9ydFxuXHRcdFx0XHRcdGV2ZW50SnNvbi5uYW1lID0gJ01JREkgUG9ydCc7XG5cdFx0XHRcdFx0ZXZlbnRKc29uLmRhdGEgPSBVdGlscy5ieXRlc1RvTnVtYmVyKFt0aGlzLmRhdGFbZXZlbnRTdGFydEluZGV4ICsgM11dKTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAweDJGOiAvLyBFbmQgb2YgVHJhY2tcblx0XHRcdFx0XHRldmVudEpzb24ubmFtZSA9ICdFbmQgb2YgVHJhY2snO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIDB4NTE6IC8vIFNldCBUZW1wb1xuXHRcdFx0XHRcdGV2ZW50SnNvbi5uYW1lID0gJ1NldCBUZW1wbyc7XG5cdFx0XHRcdFx0ZXZlbnRKc29uLmRhdGEgPSBNYXRoLnJvdW5kKDYwMDAwMDAwIC8gVXRpbHMuYnl0ZXNUb051bWJlcih0aGlzLmRhdGEuc2xpY2UoZXZlbnRTdGFydEluZGV4ICsgMywgZXZlbnRTdGFydEluZGV4ICsgNikpKTtcblx0XHRcdFx0XHR0aGlzLnRlbXBvID0gZXZlbnRKc29uLmRhdGE7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgMHg1NDogLy8gU01UUEUgT2Zmc2V0XG5cdFx0XHRcdFx0ZXZlbnRKc29uLm5hbWUgPSAnU01UUEUgT2Zmc2V0Jztcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAweDU4OiAvLyBUaW1lIFNpZ25hdHVyZVxuXHRcdFx0XHRcdGV2ZW50SnNvbi5uYW1lID0gJ1RpbWUgU2lnbmF0dXJlJztcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAweDU5OiAvLyBLZXkgU2lnbmF0dXJlXG5cdFx0XHRcdFx0ZXZlbnRKc29uLm5hbWUgPSAnS2V5IFNpZ25hdHVyZSc7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgMHg3RjogLy8gU2VxdWVuY2VyLVNwZWNpZmljIE1ldGEtZXZlbnRcblx0XHRcdFx0XHRldmVudEpzb24ubmFtZSA9ICdTZXF1ZW5jZXItU3BlY2lmaWMgTWV0YS1ldmVudCc7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0ZXZlbnRKc29uLm5hbWUgPSAnVW5rbm93bjogJyArIHRoaXMuZGF0YVtldmVudFN0YXJ0SW5kZXggKyAxXS50b1N0cmluZygxNik7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cblx0XHRcdHZhciBsZW5ndGggPSB0aGlzLmRhdGFbdGhpcy5wb2ludGVyICsgZGVsdGFCeXRlQ291bnQgKyAyXTtcblx0XHRcdC8vIFNvbWUgbWV0YSBldmVudHMgd2lsbCBoYXZlIHZsdiB0aGF0IG5lZWRzIHRvIGJlIGhhbmRsZWRcblxuXHRcdFx0dGhpcy5wb2ludGVyICs9IGRlbHRhQnl0ZUNvdW50ICsgMyArIGxlbmd0aDtcblxuXHRcdH0gZWxzZSBpZih0aGlzLmRhdGFbZXZlbnRTdGFydEluZGV4XSA9PSAweGYwKSB7XG5cdFx0XHQvLyBTeXNleFxuXHRcdFx0ZXZlbnRKc29uLm5hbWUgPSAnU3lzZXgnO1xuXHRcdFx0dmFyIGxlbmd0aCA9IHRoaXMuZGF0YVt0aGlzLnBvaW50ZXIgKyBkZWx0YUJ5dGVDb3VudCArIDFdO1xuXHRcdFx0dGhpcy5wb2ludGVyICs9IGRlbHRhQnl0ZUNvdW50ICsgMiArIGxlbmd0aDtcblxuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBWb2ljZSBldmVudFxuXHRcdFx0aWYgKHRoaXMuZGF0YVtldmVudFN0YXJ0SW5kZXhdIDwgMHg4MCkge1xuXHRcdFx0XHQvLyBSdW5uaW5nIHN0YXR1c1xuXHRcdFx0XHRldmVudEpzb24ucnVubmluZyA9IHRydWU7XG5cdFx0XHRcdGV2ZW50SnNvbi5ub3RlTnVtYmVyID0gdGhpcy5kYXRhW2V2ZW50U3RhcnRJbmRleF07XG5cdFx0XHRcdGV2ZW50SnNvbi5ub3RlTmFtZSA9IENvbnN0YW50cy5OT1RFU1t0aGlzLmRhdGFbZXZlbnRTdGFydEluZGV4XV07XG5cdFx0XHRcdGV2ZW50SnNvbi52ZWxvY2l0eSA9IHRoaXMuZGF0YVtldmVudFN0YXJ0SW5kZXggKyAxXTtcblxuXHRcdFx0XHRpZiAodGhpcy5sYXN0U3RhdHVzIDw9IDB4OGYpIHtcblx0XHRcdFx0XHRldmVudEpzb24ubmFtZSA9ICdOb3RlIG9mZic7XG5cdFx0XHRcdFx0ZXZlbnRKc29uLmNoYW5uZWwgPSB0aGlzLmxhc3RTdGF0dXMgLSAweDgwICsgMTtcblxuXHRcdFx0XHR9IGVsc2UgaWYgKHRoaXMubGFzdFN0YXR1cyA8PSAweDlmKSB7XG5cdFx0XHRcdFx0ZXZlbnRKc29uLm5hbWUgPSAnTm90ZSBvbic7XG5cdFx0XHRcdFx0ZXZlbnRKc29uLmNoYW5uZWwgPSB0aGlzLmxhc3RTdGF0dXMgLSAweDkwICsgMTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHRoaXMucG9pbnRlciArPSBkZWx0YUJ5dGVDb3VudCArIDI7XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRoaXMubGFzdFN0YXR1cyA9IHRoaXMuZGF0YVtldmVudFN0YXJ0SW5kZXhdO1xuXG5cdFx0XHRcdGlmICh0aGlzLmRhdGFbZXZlbnRTdGFydEluZGV4XSA8PSAweDhmKSB7XG5cdFx0XHRcdFx0Ly8gTm90ZSBvZmZcblx0XHRcdFx0XHRldmVudEpzb24ubmFtZSA9ICdOb3RlIG9mZic7XG5cdFx0XHRcdFx0ZXZlbnRKc29uLmNoYW5uZWwgPSB0aGlzLmxhc3RTdGF0dXMgLSAweDgwICsgMTtcblx0XHRcdFx0XHRldmVudEpzb24ubm90ZU51bWJlciA9IHRoaXMuZGF0YVtldmVudFN0YXJ0SW5kZXggKyAxXTtcblx0XHRcdFx0XHRldmVudEpzb24ubm90ZU5hbWUgPSBDb25zdGFudHMuTk9URVNbdGhpcy5kYXRhW2V2ZW50U3RhcnRJbmRleCArIDFdXTtcblx0XHRcdFx0XHRldmVudEpzb24udmVsb2NpdHkgPSBNYXRoLnJvdW5kKHRoaXMuZGF0YVtldmVudFN0YXJ0SW5kZXggKyAyXSAvIDEyNyAqIDEwMCk7XG5cdFx0XHRcdFx0dGhpcy5wb2ludGVyICs9IGRlbHRhQnl0ZUNvdW50ICsgMztcblxuXHRcdFx0XHR9IGVsc2UgaWYgKHRoaXMuZGF0YVtldmVudFN0YXJ0SW5kZXhdIDw9IDB4OWYpIHtcblx0XHRcdFx0XHQvLyBOb3RlIG9uXG5cdFx0XHRcdFx0ZXZlbnRKc29uLm5hbWUgPSAnTm90ZSBvbic7XG5cdFx0XHRcdFx0ZXZlbnRKc29uLmNoYW5uZWwgPSB0aGlzLmxhc3RTdGF0dXMgLSAweDkwICsgMTtcblx0XHRcdFx0XHRldmVudEpzb24ubm90ZU51bWJlciA9IHRoaXMuZGF0YVtldmVudFN0YXJ0SW5kZXggKyAxXTtcblx0XHRcdFx0XHRldmVudEpzb24ubm90ZU5hbWUgPSBDb25zdGFudHMuTk9URVNbdGhpcy5kYXRhW2V2ZW50U3RhcnRJbmRleCArIDFdXTtcblx0XHRcdFx0XHRldmVudEpzb24udmVsb2NpdHkgPSBNYXRoLnJvdW5kKHRoaXMuZGF0YVtldmVudFN0YXJ0SW5kZXggKyAyXSAvIDEyNyAqIDEwMCk7XG5cdFx0XHRcdFx0dGhpcy5wb2ludGVyICs9IGRlbHRhQnl0ZUNvdW50ICsgMztcblxuXHRcdFx0XHR9IGVsc2UgaWYgKHRoaXMuZGF0YVtldmVudFN0YXJ0SW5kZXhdIDw9IDB4YWYpIHtcblx0XHRcdFx0XHQvLyBQb2x5cGhvbmljIEtleSBQcmVzc3VyZVxuXHRcdFx0XHRcdGV2ZW50SnNvbi5uYW1lID0gJ1BvbHlwaG9uaWMgS2V5IFByZXNzdXJlJztcblx0XHRcdFx0XHRldmVudEpzb24uY2hhbm5lbCA9IHRoaXMubGFzdFN0YXR1cyAtIDB4YTAgKyAxO1xuXHRcdFx0XHRcdGV2ZW50SnNvbi5ub3RlID0gQ29uc3RhbnRzLk5PVEVTW3RoaXMuZGF0YVtldmVudFN0YXJ0SW5kZXggKyAxXV07XG5cdFx0XHRcdFx0ZXZlbnRKc29uLnByZXNzdXJlID0gZXZlbnRbMl07XG5cdFx0XHRcdFx0dGhpcy5wb2ludGVyICs9IGRlbHRhQnl0ZUNvdW50ICsgMztcblxuXHRcdFx0XHR9IGVsc2UgaWYgKHRoaXMuZGF0YVtldmVudFN0YXJ0SW5kZXhdIDw9IDB4YmYpIHtcblx0XHRcdFx0XHQvLyBDb250cm9sbGVyIENoYW5nZVxuXHRcdFx0XHRcdGV2ZW50SnNvbi5uYW1lID0gJ0NvbnRyb2xsZXIgQ2hhbmdlJztcblx0XHRcdFx0XHRldmVudEpzb24uY2hhbm5lbCA9IHRoaXMubGFzdFN0YXR1cyAtIDB4YjAgKyAxO1xuXHRcdFx0XHRcdGV2ZW50SnNvbi5udW1iZXIgPSB0aGlzLmRhdGFbZXZlbnRTdGFydEluZGV4ICsgMV07XG5cdFx0XHRcdFx0ZXZlbnRKc29uLnZhbHVlID0gdGhpcy5kYXRhW2V2ZW50U3RhcnRJbmRleCArIDJdO1xuXHRcdFx0XHRcdHRoaXMucG9pbnRlciArPSBkZWx0YUJ5dGVDb3VudCArIDM7XG5cblx0XHRcdFx0fSBlbHNlIGlmICh0aGlzLmRhdGFbZXZlbnRTdGFydEluZGV4XSA8PSAweGNmKSB7XG5cdFx0XHRcdFx0Ly8gUHJvZ3JhbSBDaGFuZ2Vcblx0XHRcdFx0XHRldmVudEpzb24ubmFtZSA9ICdQcm9ncmFtIENoYW5nZSc7XG5cdFx0XHRcdFx0ZXZlbnRKc29uLmNoYW5uZWwgPSB0aGlzLmxhc3RTdGF0dXMgLSAweGMwICsgMTtcblx0XHRcdFx0XHR0aGlzLnBvaW50ZXIgKz0gZGVsdGFCeXRlQ291bnQgKyAyO1xuXG5cdFx0XHRcdH0gZWxzZSBpZiAodGhpcy5kYXRhW2V2ZW50U3RhcnRJbmRleF0gPD0gMHhkZikge1xuXHRcdFx0XHRcdC8vIENoYW5uZWwgS2V5IFByZXNzdXJlXG5cdFx0XHRcdFx0ZXZlbnRKc29uLm5hbWUgPSAnQ2hhbm5lbCBLZXkgUHJlc3N1cmUnO1xuXHRcdFx0XHRcdGV2ZW50SnNvbi5jaGFubmVsID0gdGhpcy5sYXN0U3RhdHVzIC0gMHhkMCArIDE7XG5cdFx0XHRcdFx0dGhpcy5wb2ludGVyICs9IGRlbHRhQnl0ZUNvdW50ICsgMjtcblxuXHRcdFx0XHR9IGVsc2UgaWYgKHRoaXMuZGF0YVtldmVudFN0YXJ0SW5kZXhdIDw9IDB4ZWYpIHtcblx0XHRcdFx0XHQvLyBQaXRjaCBCZW5kXG5cdFx0XHRcdFx0ZXZlbnRKc29uLm5hbWUgPSAnUGl0Y2ggQmVuZCc7XG5cdFx0XHRcdFx0ZXZlbnRKc29uLmNoYW5uZWwgPSB0aGlzLmxhc3RTdGF0dXMgLSAweGUwICsgMTtcblx0XHRcdFx0XHR0aGlzLnBvaW50ZXIgKz0gZGVsdGFCeXRlQ291bnQgKyAzO1xuXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0ZXZlbnRKc29uLm5hbWUgPSAnVW5rbm93bi4gIFBvaW50ZXI6ICcgKyB0aGlzLnBvaW50ZXIudG9TdHJpbmcoKSArICcgJyAgKyBldmVudFN0YXJ0SW5kZXgudG9TdHJpbmcoKSArICcgJyArIHRoaXMuZGF0YS5sZW5ndGg7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHR0aGlzLmRlbHRhICs9IGV2ZW50SnNvbi5kZWx0YTtcblx0XHR0aGlzLmV2ZW50cy5wdXNoKGV2ZW50SnNvbik7XG5cblx0XHRyZXR1cm4gZXZlbnRKc29uO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdHJ1ZSBpZiBwb2ludGVyIGhhcyByZWFjaGVkIHRoZSBlbmQgb2YgdGhlIHRyYWNrLlxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59XG5cdCAqL1xuXHRlbmRPZlRyYWNrKCkge1xuXHRcdGlmICh0aGlzLmRhdGFbdGhpcy5wb2ludGVyICsgMV0gPT0gMHhmZiAmJiB0aGlzLmRhdGFbdGhpcy5wb2ludGVyICsgMl0gPT0gMHgyZiAmJiB0aGlzLmRhdGFbdGhpcy5wb2ludGVyICsgM10gPT0gMHgwMCkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG59XG4vKipcbiAqIENvbnRhaW5zIG1pc2Mgc3RhdGljIHV0aWxpdHkgbWV0aG9kcy5cbiAqL1xuY2xhc3MgVXRpbHMge1xuXG5cdC8qKlxuXHQgKiBDb252ZXJ0cyBhIHNpbmdsZSBieXRlIHRvIGEgaGV4IHN0cmluZy5cblx0ICogQHBhcmFtIHtudW1iZXJ9IGJ5dGVcblx0ICogQHJldHVybiB7c3RyaW5nfVxuXHQgKi9cblx0c3RhdGljIGJ5dGVUb0hleChieXRlKSB7XG5cdFx0Ly8gRW5zdXJlIGhleCBzdHJpbmcgYWx3YXlzIGhhcyB0d28gY2hhcnNcblx0XHRyZXR1cm4gKCcwJyArIGJ5dGUudG9TdHJpbmcoMTYpKS5zbGljZSgtMik7XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydHMgYW4gYXJyYXkgb2YgYnl0ZXMgdG8gYSBoZXggc3RyaW5nLlxuXHQgKiBAcGFyYW0ge2FycmF5fSBieXRlQXJyYXlcblx0ICogQHJldHVybiB7c3RyaW5nfVxuXHQgKi9cblx0c3RhdGljIGJ5dGVzVG9IZXgoYnl0ZUFycmF5KSB7XG5cdFx0dmFyIGhleCA9IFtdO1xuXHRcdGJ5dGVBcnJheS5mb3JFYWNoKGJ5dGUgPT4gaGV4LnB1c2goVXRpbHMuYnl0ZVRvSGV4KGJ5dGUpKSk7XG5cdFx0cmV0dXJuIGhleC5qb2luKCcnKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0cyBhIGhleCBzdHJpbmcgdG8gYSBudW1iZXIuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBoZXhTdHJpbmdcblx0ICogQHJldHVybiB7bnVtYmVyfVxuXHQgKi9cblx0c3RhdGljIGhleFRvTnVtYmVyKGhleFN0cmluZykge1xuXHRcdHJldHVybiBwYXJzZUludChoZXhTdHJpbmcsIDE2KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0cyBhbiBhcnJheSBvZiBieXRlcyB0byBhIG51bWJlci5cblx0ICogQHBhcmFtIHthcnJheX0gYnl0ZUFycmF5XG5cdCAqIEByZXR1cm4ge251bWJlcn1cblx0ICovXG5cdHN0YXRpYyBieXRlc1RvTnVtYmVyKGJ5dGVBcnJheSkge1xuXHRcdHJldHVybiBVdGlscy5oZXhUb051bWJlcihVdGlscy5ieXRlc1RvSGV4KGJ5dGVBcnJheSkpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENvbnZlcnRzIGFuIGFycmF5IG9mIGJ5dGVzIHRvIGxldHRlcnMuXG5cdCAqIEBwYXJhbSB7YXJyYXl9IGJ5dGVBcnJheVxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRzdGF0aWMgYnl0ZXNUb0xldHRlcnMoYnl0ZUFycmF5KSB7XG5cdFx0dmFyIGxldHRlcnMgPSBbXTtcblx0XHRieXRlQXJyYXkuZm9yRWFjaChieXRlID0+IGxldHRlcnMucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGUpKSk7XG5cdFx0cmV0dXJuIGxldHRlcnMuam9pbignJyk7XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydHMgYSBkZWNpbWFsIHRvIGl0J3MgYmluYXJ5IHJlcHJlc2VudGF0aW9uLlxuXHQgKiBAcGFyYW0ge251bWJlcn0gZGVjXG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICovXG5cdHN0YXRpYyBkZWNUb0JpbmFyeShkZWMpIHtcbiAgICBcdHJldHVybiAoZGVjID4+PiAwKS50b1N0cmluZygyKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZWFkcyBhIHZhcmlhYmxlIGxlbmd0aCB2YWx1ZS5cblx0ICogQHBhcmFtIHthcnJheX0gYnl0ZUFycmF5XG5cdCAqIEByZXR1cm4ge251bWJlcn1cblx0ICovXG5cdHN0YXRpYyByZWFkVmFySW50KGJ5dGVBcnJheSkge1xuXHRcdHZhciByZXN1bHQgPSAwO1xuXHRcdGJ5dGVBcnJheS5mb3JFYWNoKG51bWJlciA9PiB7XG5cdFx0XHR2YXIgYiA9IG51bWJlcjtcblx0XHRcdGlmIChiICYgMHg4MCkge1xuXHRcdFx0XHRyZXN1bHQgKz0gKGIgJiAweDdmKTtcblx0XHRcdFx0cmVzdWx0IDw8PSA3O1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0LyogYiBpcyB0aGUgbGFzdCBieXRlICovXG5cdFx0XHRcdHJlc3VsdCArPSBiO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fVxuXG5cdC8qKlxuXHQgKiBEZWNvZGVzIGJhc2UtNjQgZW5jb2RlZCBzdHJpbmcgXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmdcblx0ICogQHJldHVybiB7c3RyaW5nfVxuXHQgKi9cblx0c3RhdGljIGF0b2Ioc3RyaW5nKSB7XG5cdFx0aWYgKHR5cGVvZiBhdG9iID09PSAnZnVuY3Rpb24nKSByZXR1cm4gYXRvYihzdHJpbmcpO1xuXHRcdHJldHVybiBuZXcgQnVmZmVyKHN0cmluZywgJ2Jhc2U2NCcpLnRvU3RyaW5nKCdiaW5hcnknKTtcblx0fVxufVxuXG5leHBvcnRzLlV0aWxzID0gVXRpbHM7Il19
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(216).Buffer))
/***/ }),
/* 216 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* WEBPACK VAR INJECTION */(function(global) {/*!
* The buffer module from node.js, for the browser.
*
* @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
* @license MIT
*/
/* eslint-disable no-proto */
var base64 = __webpack_require__(217)
var ieee754 = __webpack_require__(218)
var isArray = __webpack_require__(219)
exports.Buffer = Buffer
exports.SlowBuffer = SlowBuffer
exports.INSPECT_MAX_BYTES = 50
/**
* If `Buffer.TYPED_ARRAY_SUPPORT`:
* === true Use Uint8Array implementation (fastest)
* === false Use Object implementation (most compatible, even IE6)
*
* Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
* Opera 11.6+, iOS 4.2+.
*
* Due to various browser bugs, sometimes the Object implementation will be used even
* when the browser supports typed arrays.
*
* Note:
*
* - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
* See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
*
* - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
*
* - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
* incorrect length in some situations.
* We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
* get the Object implementation, which is slower but behaves correctly.
*/
Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined
? global.TYPED_ARRAY_SUPPORT
: typedArraySupport()
/*
* Export kMaxLength after typed array support is determined.
*/
exports.kMaxLength = kMaxLength()
function typedArraySupport () {
try {
var arr = new Uint8Array(1)
arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}
return arr.foo() === 42 && // typed array instances can be augmented
typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
} catch (e) {
return false
}
}
function kMaxLength () {
return Buffer.TYPED_ARRAY_SUPPORT
? 0x7fffffff
: 0x3fffffff
}
function createBuffer (that, length) {
if (kMaxLength() < length) {
throw new RangeError('Invalid typed array length')
}
if (Buffer.TYPED_ARRAY_SUPPORT) {
// Return an augmented `Uint8Array` instance, for best performance
that = new Uint8Array(length)
that.__proto__ = Buffer.prototype
} else {
// Fallback: Return an object instance of the Buffer class
if (that === null) {
that = new Buffer(length)
}
that.length = length
}
return that
}
/**
* The Buffer constructor returns instances of `Uint8Array` that have their
* prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
* `Uint8Array`, so the returned instances will have all the node `Buffer` methods
* and the `Uint8Array` methods. Square bracket notation works as expected -- it
* returns a single octet.
*
* The `Uint8Array` prototype remains unmodified.
*/
function Buffer (arg, encodingOrOffset, length) {
if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {
return new Buffer(arg, encodingOrOffset, length)
}
// Common case.
if (typeof arg === 'number') {
if (typeof encodingOrOffset === 'string') {
throw new Error(
'If encoding is specified then the first argument must be a string'
)
}
return allocUnsafe(this, arg)
}
return from(this, arg, encodingOrOffset, length)
}
Buffer.poolSize = 8192 // not used by this implementation
// TODO: Legacy, not needed anymore. Remove in next major version.
Buffer._augment = function (arr) {
arr.__proto__ = Buffer.prototype
return arr
}
function from (that, value, encodingOrOffset, length) {
if (typeof value === 'number') {
throw new TypeError('"value" argument must not be a number')
}
if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {
return fromArrayBuffer(that, value, encodingOrOffset, length)
}
if (typeof value === 'string') {
return fromString(that, value, encodingOrOffset)
}
return fromObject(that, value)
}
/**
* Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
* if value is a number.
* Buffer.from(str[, encoding])
* Buffer.from(array)
* Buffer.from(buffer)
* Buffer.from(arrayBuffer[, byteOffset[, length]])
**/
Buffer.from = function (value, encodingOrOffset, length) {
return from(null, value, encodingOrOffset, length)
}
if (Buffer.TYPED_ARRAY_SUPPORT) {
Buffer.prototype.__proto__ = Uint8Array.prototype
Buffer.__proto__ = Uint8Array
if (typeof Symbol !== 'undefined' && Symbol.species &&
Buffer[Symbol.species] === Buffer) {
// Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
Object.defineProperty(Buffer, Symbol.species, {
value: null,
configurable: true
})
}
}
function assertSize (size) {
if (typeof size !== 'number') {
throw new TypeError('"size" argument must be a number')
} else if (size < 0) {
throw new RangeError('"size" argument must not be negative')
}
}
function alloc (that, size, fill, encoding) {
assertSize(size)
if (size <= 0) {
return createBuffer(that, size)
}
if (fill !== undefined) {
// Only pay attention to encoding if it's a string. This
// prevents accidentally sending in a number that would
// be interpretted as a start offset.
return typeof encoding === 'string'
? createBuffer(that, size).fill(fill, encoding)
: createBuffer(that, size).fill(fill)
}
return createBuffer(that, size)
}
/**
* Creates a new filled Buffer instance.
* alloc(size[, fill[, encoding]])
**/
Buffer.alloc = function (size, fill, encoding) {
return alloc(null, size, fill, encoding)
}
function allocUnsafe (that, size) {
assertSize(size)
that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)
if (!Buffer.TYPED_ARRAY_SUPPORT) {
for (var i = 0; i < size; ++i) {
that[i] = 0
}
}
return that
}
/**
* Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
* */
Buffer.allocUnsafe = function (size) {
return allocUnsafe(null, size)
}
/**
* Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
*/
Buffer.allocUnsafeSlow = function (size) {
return allocUnsafe(null, size)
}
function fromString (that, string, encoding) {
if (typeof encoding !== 'string' || encoding === '') {
encoding = 'utf8'
}
if (!Buffer.isEncoding(encoding)) {
throw new TypeError('"encoding" must be a valid string encoding')
}
var length = byteLength(string, encoding) | 0
that = createBuffer(that, length)
var actual = that.write(string, encoding)
if (actual !== length) {
// Writing a hex string, for example, that contains invalid characters will
// cause everything after the first invalid character to be ignored. (e.g.
// 'abxxcd' will be treated as 'ab')
that = that.slice(0, actual)
}
return that
}
function fromArrayLike (that, array) {
var length = array.length < 0 ? 0 : checked(array.length) | 0
that = createBuffer(that, length)
for (var i = 0; i < length; i += 1) {
that[i] = array[i] & 255
}
return that
}
function fromArrayBuffer (that, array, byteOffset, length) {
array.byteLength // this throws if `array` is not a valid ArrayBuffer
if (byteOffset < 0 || array.byteLength < byteOffset) {
throw new RangeError('\'offset\' is out of bounds')
}
if (array.byteLength < byteOffset + (length || 0)) {
throw new RangeError('\'length\' is out of bounds')
}
if (byteOffset === undefined && length === undefined) {
array = new Uint8Array(array)
} else if (length === undefined) {
array = new Uint8Array(array, byteOffset)
} else {
array = new Uint8Array(array, byteOffset, length)
}
if (Buffer.TYPED_ARRAY_SUPPORT) {
// Return an augmented `Uint8Array` instance, for best performance
that = array
that.__proto__ = Buffer.prototype
} else {
// Fallback: Return an object instance of the Buffer class
that = fromArrayLike(that, array)
}
return that
}
function fromObject (that, obj) {
if (Buffer.isBuffer(obj)) {
var len = checked(obj.length) | 0
that = createBuffer(that, len)
if (that.length === 0) {
return that
}
obj.copy(that, 0, 0, len)
return that
}
if (obj) {
if ((typeof ArrayBuffer !== 'undefined' &&
obj.buffer instanceof ArrayBuffer) || 'length' in obj) {
if (typeof obj.length !== 'number' || isnan(obj.length)) {
return createBuffer(that, 0)
}
return fromArrayLike(that, obj)
}
if (obj.type === 'Buffer' && isArray(obj.data)) {
return fromArrayLike(that, obj.data)
}
}
throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')
}
function checked (length) {
// Note: cannot use `length < kMaxLength()` here because that fails when
// length is NaN (which is otherwise coerced to zero.)
if (length >= kMaxLength()) {
throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
'size: 0x' + kMaxLength().toString(16) + ' bytes')
}
return length | 0
}
function SlowBuffer (length) {
if (+length != length) { // eslint-disable-line eqeqeq
length = 0
}
return Buffer.alloc(+length)
}
Buffer.isBuffer = function isBuffer (b) {
return !!(b != null && b._isBuffer)
}
Buffer.compare = function compare (a, b) {
if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
throw new TypeError('Arguments must be Buffers')
}
if (a === b) return 0
var x = a.length
var y = b.length
for (var i = 0, len = Math.min(x, y); i < len; ++i) {
if (a[i] !== b[i]) {
x = a[i]
y = b[i]
break
}
}
if (x < y) return -1
if (y < x) return 1
return 0
}
Buffer.isEncoding = function isEncoding (encoding) {
switch (String(encoding).toLowerCase()) {
case 'hex':
case 'utf8':
case 'utf-8':
case 'ascii':
case 'latin1':
case 'binary':
case 'base64':
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return true
default:
return false
}
}
Buffer.concat = function concat (list, length) {
if (!isArray(list)) {
throw new TypeError('"list" argument must be an Array of Buffers')
}
if (list.length === 0) {
return Buffer.alloc(0)
}
var i
if (length === undefined) {
length = 0
for (i = 0; i < list.length; ++i) {
length += list[i].length
}
}
var buffer = Buffer.allocUnsafe(length)
var pos = 0
for (i = 0; i < list.length; ++i) {
var buf = list[i]
if (!Buffer.isBuffer(buf)) {
throw new TypeError('"list" argument must be an Array of Buffers')
}
buf.copy(buffer, pos)
pos += buf.length
}
return buffer
}
function byteLength (string, encoding) {
if (Buffer.isBuffer(string)) {
return string.length
}
if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&
(ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {
return string.byteLength
}
if (typeof string !== 'string') {
string = '' + string
}
var len = string.length
if (len === 0) return 0
// Use a for loop to avoid recursion
var loweredCase = false
for (;;) {
switch (encoding) {
case 'ascii':
case 'latin1':
case 'binary':
return len
case 'utf8':
case 'utf-8':
case undefined:
return utf8ToBytes(string).length
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return len * 2
case 'hex':
return len >>> 1
case 'base64':
return base64ToBytes(string).length
default:
if (loweredCase) return utf8ToBytes(string).length // assume utf8
encoding = ('' + encoding).toLowerCase()
loweredCase = true
}
}
}
Buffer.byteLength = byteLength
function slowToString (encoding, start, end) {
var loweredCase = false
// No need to verify that "this.length <= MAX_UINT32" since it's a read-only
// property of a typed array.
// This behaves neither like String nor Uint8Array in that we set start/end
// to their upper/lower bounds if the value passed is out of range.
// undefined is handled specially as per ECMA-262 6th Edition,
// Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
if (start === undefined || start < 0) {
start = 0
}
// Return early if start > this.length. Done here to prevent potential uint32
// coercion fail below.
if (start > this.length) {
return ''
}
if (end === undefined || end > this.length) {
end = this.length
}
if (end <= 0) {
return ''
}
// Force coersion to uint32. This will also coerce falsey/NaN values to 0.
end >>>= 0
start >>>= 0
if (end <= start) {
return ''
}
if (!encoding) encoding = 'utf8'
while (true) {
switch (encoding) {
case 'hex':
return hexSlice(this, start, end)
case 'utf8':
case 'utf-8':
return utf8Slice(this, start, end)
case 'ascii':
return asciiSlice(this, start, end)
case 'latin1':
case 'binary':
return latin1Slice(this, start, end)
case 'base64':
return base64Slice(this, start, end)
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return utf16leSlice(this, start, end)
default:
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
encoding = (encoding + '').toLowerCase()
loweredCase = true
}
}
}
// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect
// Buffer instances.
Buffer.prototype._isBuffer = true
function swap (b, n, m) {
var i = b[n]
b[n] = b[m]
b[m] = i
}
Buffer.prototype.swap16 = function swap16 () {
var len = this.length
if (len % 2 !== 0) {
throw new RangeError('Buffer size must be a multiple of 16-bits')
}
for (var i = 0; i < len; i += 2) {
swap(this, i, i + 1)
}
return this
}
Buffer.prototype.swap32 = function swap32 () {
var len = this.length
if (len % 4 !== 0) {
throw new RangeError('Buffer size must be a multiple of 32-bits')
}
for (var i = 0; i < len; i += 4) {
swap(this, i, i + 3)
swap(this, i + 1, i + 2)
}
return this
}
Buffer.prototype.swap64 = function swap64 () {
var len = this.length
if (len % 8 !== 0) {
throw new RangeError('Buffer size must be a multiple of 64-bits')
}
for (var i = 0; i < len; i += 8) {
swap(this, i, i + 7)
swap(this, i + 1, i + 6)
swap(this, i + 2, i + 5)
swap(this, i + 3, i + 4)
}
return this
}
Buffer.prototype.toString = function toString () {
var length = this.length | 0
if (length === 0) return ''
if (arguments.length === 0) return utf8Slice(this, 0, length)
return slowToString.apply(this, arguments)
}
Buffer.prototype.equals = function equals (b) {
if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
if (this === b) return true
return Buffer.compare(this, b) === 0
}
Buffer.prototype.inspect = function inspect () {
var str = ''
var max = exports.INSPECT_MAX_BYTES
if (this.length > 0) {
str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
if (this.length > max) str += ' ... '
}
return '<Buffer ' + str + '>'
}
Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {
if (!Buffer.isBuffer(target)) {
throw new TypeError('Argument must be a Buffer')
}
if (start === undefined) {
start = 0
}
if (end === undefined) {
end = target ? target.length : 0
}
if (thisStart === undefined) {
thisStart = 0
}
if (thisEnd === undefined) {
thisEnd = this.length
}
if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
throw new RangeError('out of range index')
}
if (thisStart >= thisEnd && start >= end) {
return 0
}
if (thisStart >= thisEnd) {
return -1
}
if (start >= end) {
return 1
}
start >>>= 0
end >>>= 0
thisStart >>>= 0
thisEnd >>>= 0
if (this === target) return 0
var x = thisEnd - thisStart
var y = end - start
var len = Math.min(x, y)
var thisCopy = this.slice(thisStart, thisEnd)
var targetCopy = target.slice(start, end)
for (var i = 0; i < len; ++i) {
if (thisCopy[i] !== targetCopy[i]) {
x = thisCopy[i]
y = targetCopy[i]
break
}
}
if (x < y) return -1
if (y < x) return 1
return 0
}
// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
// OR the last index of `val` in `buffer` at offset <= `byteOffset`.
//
// Arguments:
// - buffer - a Buffer to search
// - val - a string, Buffer, or number
// - byteOffset - an index into `buffer`; will be clamped to an int32
// - encoding - an optional encoding, relevant is val is a string
// - dir - true for indexOf, false for lastIndexOf
function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
// Empty buffer means no match
if (buffer.length === 0) return -1
// Normalize byteOffset
if (typeof byteOffset === 'string') {
encoding = byteOffset
byteOffset = 0
} else if (byteOffset > 0x7fffffff) {
byteOffset = 0x7fffffff
} else if (byteOffset < -0x80000000) {
byteOffset = -0x80000000
}
byteOffset = +byteOffset // Coerce to Number.
if (isNaN(byteOffset)) {
// byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
byteOffset = dir ? 0 : (buffer.length - 1)
}
// Normalize byteOffset: negative offsets start from the end of the buffer
if (byteOffset < 0) byteOffset = buffer.length + byteOffset
if (byteOffset >= buffer.length) {
if (dir) return -1
else byteOffset = buffer.length - 1
} else if (byteOffset < 0) {
if (dir) byteOffset = 0
else return -1
}
// Normalize val
if (typeof val === 'string') {
val = Buffer.from(val, encoding)
}
// Finally, search either indexOf (if dir is true) or lastIndexOf
if (Buffer.isBuffer(val)) {
// Special case: looking for empty string/buffer always fails
if (val.length === 0) {
return -1
}
return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
} else if (typeof val === 'number') {
val = val & 0xFF // Search for a byte value [0-255]
if (Buffer.TYPED_ARRAY_SUPPORT &&
typeof Uint8Array.prototype.indexOf === 'function') {
if (dir) {
return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)
} else {
return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)
}
}
return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)
}
throw new TypeError('val must be string, number or Buffer')
}
function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
var indexSize = 1
var arrLength = arr.length
var valLength = val.length
if (encoding !== undefined) {
encoding = String(encoding).toLowerCase()
if (encoding === 'ucs2' || encoding === 'ucs-2' ||
encoding === 'utf16le' || encoding === 'utf-16le') {
if (arr.length < 2 || val.length < 2) {
return -1
}
indexSize = 2
arrLength /= 2
valLength /= 2
byteOffset /= 2
}
}
function read (buf, i) {
if (indexSize === 1) {
return buf[i]
} else {
return buf.readUInt16BE(i * indexSize)
}
}
var i
if (dir) {
var foundIndex = -1
for (i = byteOffset; i < arrLength; i++) {
if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
if (foundIndex === -1) foundIndex = i
if (i - foundIndex + 1 === valLength) return foundIndex * indexSize
} else {
if (foundIndex !== -1) i -= i - foundIndex
foundIndex = -1
}
}
} else {
if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength
for (i = byteOffset; i >= 0; i--) {
var found = true
for (var j = 0; j < valLength; j++) {
if (read(arr, i + j) !== read(val, j)) {
found = false
break
}
}
if (found) return i
}
}
return -1
}
Buffer.prototype.includes = function includes (val, byteOffset, encoding) {
return this.indexOf(val, byteOffset, encoding) !== -1
}
Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {
return bidirectionalIndexOf(this, val, byteOffset, encoding, true)
}
Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {
return bidirectionalIndexOf(this, val, byteOffset, encoding, false)
}
function hexWrite (buf, string, offset, length) {
offset = Number(offset) || 0
var remaining = buf.length - offset
if (!length) {
length = remaining
} else {
length = Number(length)
if (length > remaining) {
length = remaining
}
}
// must be an even number of digits
var strLen = string.length
if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')
if (length > strLen / 2) {
length = strLen / 2
}
for (var i = 0; i < length; ++i) {
var parsed = parseInt(string.substr(i * 2, 2), 16)
if (isNaN(parsed)) return i
buf[offset + i] = parsed
}
return i
}
function utf8Write (buf, string, offset, length) {
return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
}
function asciiWrite (buf, string, offset, length) {
return blitBuffer(asciiToBytes(string), buf, offset, length)
}
function latin1Write (buf, string, offset, length) {
return asciiWrite(buf, string, offset, length)
}
function base64Write (buf, string, offset, length) {
return blitBuffer(base64ToBytes(string), buf, offset, length)
}
function ucs2Write (buf, string, offset, length) {
return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
}
Buffer.prototype.write = function write (string, offset, length, encoding) {
// Buffer#write(string)
if (offset === undefined) {
encoding = 'utf8'
length = this.length
offset = 0
// Buffer#write(string, encoding)
} else if (length === undefined && typeof offset === 'string') {
encoding = offset
length = this.length
offset = 0
// Buffer#write(string, offset[, length][, encoding])
} else if (isFinite(offset)) {
offset = offset | 0
if (isFinite(length)) {
length = length | 0
if (encoding === undefined) encoding = 'utf8'
} else {
encoding = length
length = undefined
}
// legacy write(string, encoding, offset, length) - remove in v0.13
} else {
throw new Error(
'Buffer.write(string, encoding, offset[, length]) is no longer supported'
)
}
var remaining = this.length - offset
if (length === undefined || length > remaining) length = remaining
if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
throw new RangeError('Attempt to write outside buffer bounds')
}
if (!encoding) encoding = 'utf8'
var loweredCase = false
for (;;) {
switch (encoding) {
case 'hex':
return hexWrite(this, string, offset, length)
case 'utf8':
case 'utf-8':
return utf8Write(this, string, offset, length)
case 'ascii':
return asciiWrite(this, string, offset, length)
case 'latin1':
case 'binary':
return latin1Write(this, string, offset, length)
case 'base64':
// Warning: maxLength not taken into account in base64Write
return base64Write(this, string, offset, length)
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return ucs2Write(this, string, offset, length)
default:
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
encoding = ('' + encoding).toLowerCase()
loweredCase = true
}
}
}
Buffer.prototype.toJSON = function toJSON () {
return {
type: 'Buffer',
data: Array.prototype.slice.call(this._arr || this, 0)
}
}
function base64Slice (buf, start, end) {
if (start === 0 && end === buf.length) {
return base64.fromByteArray(buf)
} else {
return base64.fromByteArray(buf.slice(start, end))
}
}
function utf8Slice (buf, start, end) {
end = Math.min(buf.length, end)
var res = []
var i = start
while (i < end) {
var firstByte = buf[i]
var codePoint = null
var bytesPerSequence = (firstByte > 0xEF) ? 4
: (firstByte > 0xDF) ? 3
: (firstByte > 0xBF) ? 2
: 1
if (i + bytesPerSequence <= end) {
var secondByte, thirdByte, fourthByte, tempCodePoint
switch (bytesPerSequence) {
case 1:
if (firstByte < 0x80) {
codePoint = firstByte
}
break
case 2:
secondByte = buf[i + 1]
if ((secondByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
if (tempCodePoint > 0x7F) {
codePoint = tempCodePoint
}
}
break
case 3:
secondByte = buf[i + 1]
thirdByte = buf[i + 2]
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
codePoint = tempCodePoint
}
}
break
case 4:
secondByte = buf[i + 1]
thirdByte = buf[i + 2]
fourthByte = buf[i + 3]
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
codePoint = tempCodePoint
}
}
}
}
if (codePoint === null) {
// we did not generate a valid codePoint so insert a
// replacement char (U+FFFD) and advance only 1 byte
codePoint = 0xFFFD
bytesPerSequence = 1
} else if (codePoint > 0xFFFF) {
// encode to utf16 (surrogate pair dance)
codePoint -= 0x10000
res.push(codePoint >>> 10 & 0x3FF | 0xD800)
codePoint = 0xDC00 | codePoint & 0x3FF
}
res.push(codePoint)
i += bytesPerSequence
}
return decodeCodePointsArray(res)
}
// Based on http://stackoverflow.com/a/22747272/680742, the browser with
// the lowest limit is Chrome, with 0x10000 args.
// We go 1 magnitude less, for safety
var MAX_ARGUMENTS_LENGTH = 0x1000
function decodeCodePointsArray (codePoints) {
var len = codePoints.length
if (len <= MAX_ARGUMENTS_LENGTH) {
return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
}
// Decode in chunks to avoid "call stack size exceeded".
var res = ''
var i = 0
while (i < len) {
res += String.fromCharCode.apply(
String,
codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
)
}
return res
}
function asciiSlice (buf, start, end) {
var ret = ''
end = Math.min(buf.length, end)
for (var i = start; i < end; ++i) {
ret += String.fromCharCode(buf[i] & 0x7F)
}
return ret
}
function latin1Slice (buf, start, end) {
var ret = ''
end = Math.min(buf.length, end)
for (var i = start; i < end; ++i) {
ret += String.fromCharCode(buf[i])
}
return ret
}
function hexSlice (buf, start, end) {
var len = buf.length
if (!start || start < 0) start = 0
if (!end || end < 0 || end > len) end = len
var out = ''
for (var i = start; i < end; ++i) {
out += toHex(buf[i])
}
return out
}
function utf16leSlice (buf, start, end) {
var bytes = buf.slice(start, end)
var res = ''
for (var i = 0; i < bytes.length; i += 2) {
res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
}
return res
}
Buffer.prototype.slice = function slice (start, end) {
var len = this.length
start = ~~start
end = end === undefined ? len : ~~end
if (start < 0) {
start += len
if (start < 0) start = 0
} else if (start > len) {
start = len
}
if (end < 0) {
end += len
if (end < 0) end = 0
} else if (end > len) {
end = len
}
if (end < start) end = start
var newBuf
if (Buffer.TYPED_ARRAY_SUPPORT) {
newBuf = this.subarray(start, end)
newBuf.__proto__ = Buffer.prototype
} else {
var sliceLen = end - start
newBuf = new Buffer(sliceLen, undefined)
for (var i = 0; i < sliceLen; ++i) {
newBuf[i] = this[i + start]
}
}
return newBuf
}
/*
* Need to make sure that buffer isn't trying to write out of bounds.
*/
function checkOffset (offset, ext, length) {
if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
}
Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) checkOffset(offset, byteLength, this.length)
var val = this[offset]
var mul = 1
var i = 0
while (++i < byteLength && (mul *= 0x100)) {
val += this[offset + i] * mul
}
return val
}
Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) {
checkOffset(offset, byteLength, this.length)
}
var val = this[offset + --byteLength]
var mul = 1
while (byteLength > 0 && (mul *= 0x100)) {
val += this[offset + --byteLength] * mul
}
return val
}
Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
if (!noAssert) checkOffset(offset, 1, this.length)
return this[offset]
}
Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 2, this.length)
return this[offset] | (this[offset + 1] << 8)
}
Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 2, this.length)
return (this[offset] << 8) | this[offset + 1]
}
Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return ((this[offset]) |
(this[offset + 1] << 8) |
(this[offset + 2] << 16)) +
(this[offset + 3] * 0x1000000)
}
Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return (this[offset] * 0x1000000) +
((this[offset + 1] << 16) |
(this[offset + 2] << 8) |
this[offset + 3])
}
Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) checkOffset(offset, byteLength, this.length)
var val = this[offset]
var mul = 1
var i = 0
while (++i < byteLength && (mul *= 0x100)) {
val += this[offset + i] * mul
}
mul *= 0x80
if (val >= mul) val -= Math.pow(2, 8 * byteLength)
return val
}
Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) checkOffset(offset, byteLength, this.length)
var i = byteLength
var mul = 1
var val = this[offset + --i]
while (i > 0 && (mul *= 0x100)) {
val += this[offset + --i] * mul
}
mul *= 0x80
if (val >= mul) val -= Math.pow(2, 8 * byteLength)
return val
}
Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
if (!noAssert) checkOffset(offset, 1, this.length)
if (!(this[offset] & 0x80)) return (this[offset])
return ((0xff - this[offset] + 1) * -1)
}
Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 2, this.length)
var val = this[offset] | (this[offset + 1] << 8)
return (val & 0x8000) ? val | 0xFFFF0000 : val
}
Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 2, this.length)
var val = this[offset + 1] | (this[offset] << 8)
return (val & 0x8000) ? val | 0xFFFF0000 : val
}
Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return (this[offset]) |
(this[offset + 1] << 8) |
(this[offset + 2] << 16) |
(this[offset + 3] << 24)
}
Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return (this[offset] << 24) |
(this[offset + 1] << 16) |
(this[offset + 2] << 8) |
(this[offset + 3])
}
Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return ieee754.read(this, offset, true, 23, 4)
}
Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return ieee754.read(this, offset, false, 23, 4)
}
Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 8, this.length)
return ieee754.read(this, offset, true, 52, 8)
}
Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 8, this.length)
return ieee754.read(this, offset, false, 52, 8)
}
function checkInt (buf, value, offset, ext, max, min) {
if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance')
if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')
if (offset + ext > buf.length) throw new RangeError('Index out of range')
}
Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) {
var maxBytes = Math.pow(2, 8 * byteLength) - 1
checkInt(this, value, offset, byteLength, maxBytes, 0)
}
var mul = 1
var i = 0
this[offset] = value & 0xFF
while (++i < byteLength && (mul *= 0x100)) {
this[offset + i] = (value / mul) & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) {
var maxBytes = Math.pow(2, 8 * byteLength) - 1
checkInt(this, value, offset, byteLength, maxBytes, 0)
}
var i = byteLength - 1
var mul = 1
this[offset + i] = value & 0xFF
while (--i >= 0 && (mul *= 0x100)) {
this[offset + i] = (value / mul) & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
this[offset] = (value & 0xff)
return offset + 1
}
function objectWriteUInt16 (buf, value, offset, littleEndian) {
if (value < 0) value = 0xffff + value + 1
for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {
buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
(littleEndian ? i : 1 - i) * 8
}
}
Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value & 0xff)
this[offset + 1] = (value >>> 8)
} else {
objectWriteUInt16(this, value, offset, true)
}
return offset + 2
}
Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value >>> 8)
this[offset + 1] = (value & 0xff)
} else {
objectWriteUInt16(this, value, offset, false)
}
return offset + 2
}
function objectWriteUInt32 (buf, value, offset, littleEndian) {
if (value < 0) value = 0xffffffff + value + 1
for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {
buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
}
}
Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset + 3] = (value >>> 24)
this[offset + 2] = (value >>> 16)
this[offset + 1] = (value >>> 8)
this[offset] = (value & 0xff)
} else {
objectWriteUInt32(this, value, offset, true)
}
return offset + 4
}
Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value >>> 24)
this[offset + 1] = (value >>> 16)
this[offset + 2] = (value >>> 8)
this[offset + 3] = (value & 0xff)
} else {
objectWriteUInt32(this, value, offset, false)
}
return offset + 4
}
Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) {
var limit = Math.pow(2, 8 * byteLength - 1)
checkInt(this, value, offset, byteLength, limit - 1, -limit)
}
var i = 0
var mul = 1
var sub = 0
this[offset] = value & 0xFF
while (++i < byteLength && (mul *= 0x100)) {
if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
sub = 1
}
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) {
var limit = Math.pow(2, 8 * byteLength - 1)
checkInt(this, value, offset, byteLength, limit - 1, -limit)
}
var i = byteLength - 1
var mul = 1
var sub = 0
this[offset + i] = value & 0xFF
while (--i >= 0 && (mul *= 0x100)) {
if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
sub = 1
}
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
if (value < 0) value = 0xff + value + 1
this[offset] = (value & 0xff)
return offset + 1
}
Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value & 0xff)
this[offset + 1] = (value >>> 8)
} else {
objectWriteUInt16(this, value, offset, true)
}
return offset + 2
}
Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value >>> 8)
this[offset + 1] = (value & 0xff)
} else {
objectWriteUInt16(this, value, offset, false)
}
return offset + 2
}
Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value & 0xff)
this[offset + 1] = (value >>> 8)
this[offset + 2] = (value >>> 16)
this[offset + 3] = (value >>> 24)
} else {
objectWriteUInt32(this, value, offset, true)
}
return offset + 4
}
Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
if (value < 0) value = 0xffffffff + value + 1
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value >>> 24)
this[offset + 1] = (value >>> 16)
this[offset + 2] = (value >>> 8)
this[offset + 3] = (value & 0xff)
} else {
objectWriteUInt32(this, value, offset, false)
}
return offset + 4
}
function checkIEEE754 (buf, value, offset, ext, max, min) {
if (offset + ext > buf.length) throw new RangeError('Index out of range')
if (offset < 0) throw new RangeError('Index out of range')
}
function writeFloat (buf, value, offset, littleEndian, noAssert) {
if (!noAssert) {
checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
}
ieee754.write(buf, value, offset, littleEndian, 23, 4)
return offset + 4
}
Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
return writeFloat(this, value, offset, true, noAssert)
}
Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
return writeFloat(this, value, offset, false, noAssert)
}
function writeDouble (buf, value, offset, littleEndian, noAssert) {
if (!noAssert) {
checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
}
ieee754.write(buf, value, offset, littleEndian, 52, 8)
return offset + 8
}
Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
return writeDouble(this, value, offset, true, noAssert)
}
Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
return writeDouble(this, value, offset, false, noAssert)
}
// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
Buffer.prototype.copy = function copy (target, targetStart, start, end) {
if (!start) start = 0
if (!end && end !== 0) end = this.length
if (targetStart >= target.length) targetStart = target.length
if (!targetStart) targetStart = 0
if (end > 0 && end < start) end = start
// Copy 0 bytes; we're done
if (end === start) return 0
if (target.length === 0 || this.length === 0) return 0
// Fatal error conditions
if (targetStart < 0) {
throw new RangeError('targetStart out of bounds')
}
if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
if (end < 0) throw new RangeError('sourceEnd out of bounds')
// Are we oob?
if (end > this.length) end = this.length
if (target.length - targetStart < end - start) {
end = target.length - targetStart + start
}
var len = end - start
var i
if (this === target && start < targetStart && targetStart < end) {
// descending copy from end
for (i = len - 1; i >= 0; --i) {
target[i + targetStart] = this[i + start]
}
} else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
// ascending copy from start
for (i = 0; i < len; ++i) {
target[i + targetStart] = this[i + start]
}
} else {
Uint8Array.prototype.set.call(
target,
this.subarray(start, start + len),
targetStart
)
}
return len
}
// Usage:
// buffer.fill(number[, offset[, end]])
// buffer.fill(buffer[, offset[, end]])
// buffer.fill(string[, offset[, end]][, encoding])
Buffer.prototype.fill = function fill (val, start, end, encoding) {
// Handle string cases:
if (typeof val === 'string') {
if (typeof start === 'string') {
encoding = start
start = 0
end = this.length
} else if (typeof end === 'string') {
encoding = end
end = this.length
}
if (val.length === 1) {
var code = val.charCodeAt(0)
if (code < 256) {
val = code
}
}
if (encoding !== undefined && typeof encoding !== 'string') {
throw new TypeError('encoding must be a string')
}
if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
throw new TypeError('Unknown encoding: ' + encoding)
}
} else if (typeof val === 'number') {
val = val & 255
}
// Invalid ranges are not set to a default, so can range check early.
if (start < 0 || this.length < start || this.length < end) {
throw new RangeError('Out of range index')
}
if (end <= start) {
return this
}
start = start >>> 0
end = end === undefined ? this.length : end >>> 0
if (!val) val = 0
var i
if (typeof val === 'number') {
for (i = start; i < end; ++i) {
this[i] = val
}
} else {
var bytes = Buffer.isBuffer(val)
? val
: utf8ToBytes(new Buffer(val, encoding).toString())
var len = bytes.length
for (i = 0; i < end - start; ++i) {
this[i + start] = bytes[i % len]
}
}
return this
}
// HELPER FUNCTIONS
// ================
var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g
function base64clean (str) {
// Node strips out invalid characters like \n and \t from the string, base64-js does not
str = stringtrim(str).replace(INVALID_BASE64_RE, '')
// Node converts strings with length < 2 to ''
if (str.length < 2) return ''
// Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
while (str.length % 4 !== 0) {
str = str + '='
}
return str
}
function stringtrim (str) {
if (str.trim) return str.trim()
return str.replace(/^\s+|\s+$/g, '')
}
function toHex (n) {
if (n < 16) return '0' + n.toString(16)
return n.toString(16)
}
function utf8ToBytes (string, units) {
units = units || Infinity
var codePoint
var length = string.length
var leadSurrogate = null
var bytes = []
for (var i = 0; i < length; ++i) {
codePoint = string.charCodeAt(i)
// is surrogate component
if (codePoint > 0xD7FF && codePoint < 0xE000) {
// last char was a lead
if (!leadSurrogate) {
// no lead yet
if (codePoint > 0xDBFF) {
// unexpected trail
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
continue
} else if (i + 1 === length) {
// unpaired lead
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
continue
}
// valid lead
leadSurrogate = codePoint
continue
}
// 2 leads in a row
if (codePoint < 0xDC00) {
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
leadSurrogate = codePoint
continue
}
// valid surrogate pair
codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
} else if (leadSurrogate) {
// valid bmp char, but last char was a lead
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
}
leadSurrogate = null
// encode utf8
if (codePoint < 0x80) {
if ((units -= 1) < 0) break
bytes.push(codePoint)
} else if (codePoint < 0x800) {
if ((units -= 2) < 0) break
bytes.push(
codePoint >> 0x6 | 0xC0,
codePoint & 0x3F | 0x80
)
} else if (codePoint < 0x10000) {
if ((units -= 3) < 0) break
bytes.push(
codePoint >> 0xC | 0xE0,
codePoint >> 0x6 & 0x3F | 0x80,
codePoint & 0x3F | 0x80
)
} else if (codePoint < 0x110000) {
if ((units -= 4) < 0) break
bytes.push(
codePoint >> 0x12 | 0xF0,
codePoint >> 0xC & 0x3F | 0x80,
codePoint >> 0x6 & 0x3F | 0x80,
codePoint & 0x3F | 0x80
)
} else {
throw new Error('Invalid code point')
}
}
return bytes
}
function asciiToBytes (str) {
var byteArray = []
for (var i = 0; i < str.length; ++i) {
// Node's code seems to be doing this and not & 0x7F..
byteArray.push(str.charCodeAt(i) & 0xFF)
}
return byteArray
}
function utf16leToBytes (str, units) {
var c, hi, lo
var byteArray = []
for (var i = 0; i < str.length; ++i) {
if ((units -= 2) < 0) break
c = str.charCodeAt(i)
hi = c >> 8
lo = c % 256
byteArray.push(lo)
byteArray.push(hi)
}
return byteArray
}
function base64ToBytes (str) {
return base64.toByteArray(base64clean(str))
}
function blitBuffer (src, dst, offset, length) {
for (var i = 0; i < length; ++i) {
if ((i + offset >= dst.length) || (i >= src.length)) break
dst[i + offset] = src[i]
}
return i
}
function isnan (val) {
return val !== val // eslint-disable-line no-self-compare
}
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(190)))
/***/ }),
/* 217 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
exports.byteLength = byteLength
exports.toByteArray = toByteArray
exports.fromByteArray = fromByteArray
var lookup = []
var revLookup = []
var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
for (var i = 0, len = code.length; i < len; ++i) {
lookup[i] = code[i]
revLookup[code.charCodeAt(i)] = i
}
revLookup['-'.charCodeAt(0)] = 62
revLookup['_'.charCodeAt(0)] = 63
function placeHoldersCount (b64) {
var len = b64.length
if (len % 4 > 0) {
throw new Error('Invalid string. Length must be a multiple of 4')
}
// the number of equal signs (place holders)
// if there are two placeholders, than the two characters before it
// represent one byte
// if there is only one, then the three characters before it represent 2 bytes
// this is just a cheap hack to not do indexOf twice
return b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0
}
function byteLength (b64) {
// base64 is 4/3 + up to two characters of the original data
return (b64.length * 3 / 4) - placeHoldersCount(b64)
}
function toByteArray (b64) {
var i, l, tmp, placeHolders, arr
var len = b64.length
placeHolders = placeHoldersCount(b64)
arr = new Arr((len * 3 / 4) - placeHolders)
// if there are placeholders, only get up to the last complete 4 chars
l = placeHolders > 0 ? len - 4 : len
var L = 0
for (i = 0; i < l; i += 4) {
tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]
arr[L++] = (tmp >> 16) & 0xFF
arr[L++] = (tmp >> 8) & 0xFF
arr[L++] = tmp & 0xFF
}
if (placeHolders === 2) {
tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4)
arr[L++] = tmp & 0xFF
} else if (placeHolders === 1) {
tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2)
arr[L++] = (tmp >> 8) & 0xFF
arr[L++] = tmp & 0xFF
}
return arr
}
function tripletToBase64 (num) {
return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]
}
function encodeChunk (uint8, start, end) {
var tmp
var output = []
for (var i = start; i < end; i += 3) {
tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
output.push(tripletToBase64(tmp))
}
return output.join('')
}
function fromByteArray (uint8) {
var tmp
var len = uint8.length
var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
var output = ''
var parts = []
var maxChunkLength = 16383 // must be multiple of 3
// go through the array every three bytes, we'll deal with trailing stuff later
for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))
}
// pad the end with zeros, but make sure to not forget the extra bytes
if (extraBytes === 1) {
tmp = uint8[len - 1]
output += lookup[tmp >> 2]
output += lookup[(tmp << 4) & 0x3F]
output += '=='
} else if (extraBytes === 2) {
tmp = (uint8[len - 2] << 8) + (uint8[len - 1])
output += lookup[tmp >> 10]
output += lookup[(tmp >> 4) & 0x3F]
output += lookup[(tmp << 2) & 0x3F]
output += '='
}
parts.push(output)
return parts.join('')
}
/***/ }),
/* 218 */
/***/ (function(module, exports) {
exports.read = function (buffer, offset, isLE, mLen, nBytes) {
var e, m
var eLen = nBytes * 8 - mLen - 1
var eMax = (1 << eLen) - 1
var eBias = eMax >> 1
var nBits = -7
var i = isLE ? (nBytes - 1) : 0
var d = isLE ? -1 : 1
var s = buffer[offset + i]
i += d
e = s & ((1 << (-nBits)) - 1)
s >>= (-nBits)
nBits += eLen
for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
m = e & ((1 << (-nBits)) - 1)
e >>= (-nBits)
nBits += mLen
for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
if (e === 0) {
e = 1 - eBias
} else if (e === eMax) {
return m ? NaN : ((s ? -1 : 1) * Infinity)
} else {
m = m + Math.pow(2, mLen)
e = e - eBias
}
return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
}
exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
var e, m, c
var eLen = nBytes * 8 - mLen - 1
var eMax = (1 << eLen) - 1
var eBias = eMax >> 1
var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
var i = isLE ? 0 : (nBytes - 1)
var d = isLE ? 1 : -1
var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
value = Math.abs(value)
if (isNaN(value) || value === Infinity) {
m = isNaN(value) ? 1 : 0
e = eMax
} else {
e = Math.floor(Math.log(value) / Math.LN2)
if (value * (c = Math.pow(2, -e)) < 1) {
e--
c *= 2
}
if (e + eBias >= 1) {
value += rt / c
} else {
value += rt * Math.pow(2, 1 - eBias)
}
if (value * c >= 2) {
e++
c /= 2
}
if (e + eBias >= eMax) {
m = 0
e = eMax
} else if (e + eBias >= 1) {
m = (value * c - 1) * Math.pow(2, mLen)
e = e + eBias
} else {
m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
e = 0
}
}
for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
e = (e << mLen) | m
eLen += mLen
for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
buffer[offset + i - d] |= s * 128
}
/***/ }),
/* 219 */
/***/ (function(module, exports) {
var toString = {}.toString;
module.exports = Array.isArray || function (arr) {
return toString.call(arr) == '[object Array]';
};
/***/ }),
/* 220 */
/***/ (function(module, exports) {
/***/ }),
/* 221 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var load = __webpack_require__(222)
var player = __webpack_require__(225)
/**
* Load a soundfont instrument. It returns a promise that resolves to a
* instrument object.
*
* The instrument object returned by the promise has the following properties:
*
* - name: the instrument name
* - play: A function to play notes from the buffer with the signature
* `play(note, time, duration, options)`
*
*
* The valid options are:
*
* - `format`: the soundfont format. 'mp3' by default. Can be 'ogg'
* - `soundfont`: the soundfont name. 'MusyngKite' by default. Can be 'FluidR3_GM'
* - `nameToUrl` <Function>: a function to convert from instrument names to URL
* - `destination`: by default Soundfont uses the `audioContext.destination` but you can override it.
* - `gain`: the gain of the player (1 by default)
* - `notes`: an array of the notes to decode. It can be an array of strings
* with note names or an array of numbers with midi note numbers. This is a
* performance option: since decoding mp3 is a cpu intensive process, you can limit
* limit the number of notes you want and reduce the time to load the instrument.
*
* @param {AudioContext} ac - the audio context
* @param {String} name - the instrument name. For example: 'acoustic_grand_piano'
* @param {Object} options - (Optional) the same options as Soundfont.loadBuffers
* @return {Promise}
*
* @example
* var Soundfont = require('sounfont-player')
* Soundfont.instrument('marimba').then(function (marimba) {
* marimba.play('C4')
* })
*/
function instrument (ac, name, options) {
if (arguments.length === 1) return function (n, o) { return instrument(ac, n, o) }
var opts = options || {}
var isUrl = opts.isSoundfontURL || isSoundfontURL
var toUrl = opts.nameToUrl || nameToUrl
var url = isUrl(name) ? name : toUrl(name, opts.soundfont, opts.format)
return load(ac, url, { only: opts.only || opts.notes }).then(function (buffers) {
var p = player(ac, buffers, opts).connect(ac.destination)
p.url = url
p.name = name
return p
})
}
function isSoundfontURL (name) {
return /\.js(\?.*)?$/i.test(name)
}
/**
* Given an instrument name returns a URL to to the Benjamin Gleitzman's
* package of [pre-rendered sound fonts](https://github.com/gleitz/midi-js-soundfonts)
*
* @param {String} name - instrument name
* @param {String} soundfont - (Optional) the soundfont name. One of 'FluidR3_GM'
* or 'MusyngKite' ('MusyngKite' by default)
* @param {String} format - (Optional) Can be 'mp3' or 'ogg' (mp3 by default)
* @returns {String} the Soundfont file url
* @example
* var Soundfont = require('soundfont-player')
* Soundfont.nameToUrl('marimba', 'mp3')
*/
function nameToUrl (name, sf, format) {
format = format === 'ogg' ? format : 'mp3'
sf = sf === 'FluidR3_GM' ? sf : 'MusyngKite'
return 'https://gleitz.github.io/midi-js-soundfonts/' + sf + '/' + name + '-' + format + '.js'
}
// In the 1.0.0 release it will be:
// var Soundfont = {}
var Soundfont = __webpack_require__(234)
Soundfont.instrument = instrument
Soundfont.nameToUrl = nameToUrl
if (typeof module === 'object' && module.exports) module.exports = Soundfont
if (typeof window !== 'undefined') window.Soundfont = Soundfont
/***/ }),
/* 222 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var base64 = __webpack_require__(223)
var fetch = __webpack_require__(224)
// Given a regex, return a function that test if against a string
function fromRegex (r) {
return function (o) { return typeof o === 'string' && r.test(o) }
}
// Try to apply a prefix to a name
function prefix (pre, name) {
return typeof pre === 'string' ? pre + name
: typeof pre === 'function' ? pre(name)
: name
}
/**
* Load one or more audio files
*
*
* Possible option keys:
*
* - __from__ {Function|String}: a function or string to convert from file names to urls.
* If is a string it will be prefixed to the name:
* `load(ac, 'snare.mp3', { from: 'http://audio.net/samples/' })`
* If it's a function it receives the file name and should return the url as string.
* - __only__ {Array} - when loading objects, if provided, only the given keys
* will be included in the decoded object:
* `load(ac, 'piano.json', { only: ['C2', 'D2'] })`
*
* @param {AudioContext} ac - the audio context
* @param {Object} source - the object to be loaded
* @param {Object} options - (Optional) the load options for that object
* @param {Object} defaultValue - (Optional) the default value to return as
* in a promise if not valid loader found
*/
function load (ac, source, options, defVal) {
var loader =
// Basic audio loading
isArrayBuffer(source) ? loadArrayBuffer
: isAudioFileName(source) ? loadAudioFile
: isPromise(source) ? loadPromise
// Compound objects
: isArray(source) ? loadArrayData
: isObject(source) ? loadObjectData
: isJsonFileName(source) ? loadJsonFile
// Base64 encoded audio
: isBase64Audio(source) ? loadBase64Audio
: isJsFileName(source) ? loadMidiJSFile
: null
var opts = options || {}
return loader ? loader(ac, source, opts)
: defVal ? Promise.resolve(defVal)
: Promise.reject('Source not valid (' + source + ')')
}
load.fetch = fetch
// BASIC AUDIO LOADING
// ===================
// Load (decode) an array buffer
function isArrayBuffer (o) { return o instanceof ArrayBuffer }
function loadArrayBuffer (ac, array, options) {
return new Promise(function (done, reject) {
ac.decodeAudioData(array,
function (buffer) { done(buffer) },
function () { reject("Can't decode audio data (" + array.slice(0, 30) + '...)') }
)
})
}
// Load an audio filename
var isAudioFileName = fromRegex(/\.(mp3|wav|ogg)(\?.*)?$/i)
function loadAudioFile (ac, name, options) {
var url = prefix(options.from, name)
return load(ac, load.fetch(url, 'arraybuffer'), options)
}
// Load the result of a promise
function isPromise (o) { return o && typeof o.then === 'function' }
function loadPromise (ac, promise, options) {
return promise.then(function (value) {
return load(ac, value, options)
})
}
// COMPOUND OBJECTS
// ================
// Try to load all the items of an array
var isArray = Array.isArray
function loadArrayData (ac, array, options) {
return Promise.all(array.map(function (data) {
return load(ac, data, options, data)
}))
}
// Try to load all the values of a key/value object
function isObject (o) { return o && typeof o === 'object' }
function loadObjectData (ac, obj, options) {
var dest = {}
var promises = Object.keys(obj).map(function (key) {
if (options.only && options.only.indexOf(key) === -1) return null
var value = obj[key]
return load(ac, value, options, value).then(function (audio) {
dest[key] = audio
})
})
return Promise.all(promises).then(function () { return dest })
}
// Load the content of a JSON file
var isJsonFileName = fromRegex(/\.json(\?.*)?$/i)
function loadJsonFile (ac, name, options) {
var url = prefix(options.from, name)
return load(ac, load.fetch(url, 'text').then(JSON.parse), options)
}
// BASE64 ENCODED FORMATS
// ======================
// Load strings with Base64 encoded audio
var isBase64Audio = fromRegex(/^data:audio/)
function loadBase64Audio (ac, source, options) {
var i = source.indexOf(',')
return load(ac, base64.decode(source.slice(i + 1)).buffer, options)
}
// Load .js files with MidiJS soundfont prerendered audio
var isJsFileName = fromRegex(/\.js(\?.*)?$/i)
function loadMidiJSFile (ac, name, options) {
var url = prefix(options.from, name)
return load(ac, load.fetch(url, 'text').then(midiJsToJson), options)
}
// convert a MIDI.js javascript soundfont file to json
function midiJsToJson (data) {
var begin = data.indexOf('MIDI.Soundfont.')
if (begin < 0) throw Error('Invalid MIDI.js Soundfont format')
begin = data.indexOf('=', begin) + 2
var end = data.lastIndexOf(',')
return JSON.parse(data.slice(begin, end) + '}')
}
if (typeof module === 'object' && module.exports) module.exports = load
if (typeof window !== 'undefined') window.loadAudio = load
/***/ }),
/* 223 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
// DECODE UTILITIES
function b64ToUint6 (nChr) {
return nChr > 64 && nChr < 91 ? nChr - 65
: nChr > 96 && nChr < 123 ? nChr - 71
: nChr > 47 && nChr < 58 ? nChr + 4
: nChr === 43 ? 62
: nChr === 47 ? 63
: 0
}
// Decode Base64 to Uint8Array
// ---------------------------
function decode (sBase64, nBlocksSize) {
var sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, '')
var nInLen = sB64Enc.length
var nOutLen = nBlocksSize
? Math.ceil((nInLen * 3 + 1 >> 2) / nBlocksSize) * nBlocksSize
: nInLen * 3 + 1 >> 2
var taBytes = new Uint8Array(nOutLen)
for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) {
nMod4 = nInIdx & 3
nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 18 - 6 * nMod4
if (nMod4 === 3 || nInLen - nInIdx === 1) {
for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) {
taBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255
}
nUint24 = 0
}
}
return taBytes
}
module.exports = { decode: decode }
/***/ }),
/* 224 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* global XMLHttpRequest */
/**
* Given a url and a return type, returns a promise to the content of the url
* Basically it wraps a XMLHttpRequest into a Promise
*
* @param {String} url
* @param {String} type - can be 'text' or 'arraybuffer'
* @return {Promise}
*/
module.exports = function (url, type) {
return new Promise(function (done, reject) {
var req = new XMLHttpRequest()
if (type) req.responseType = type
req.open('GET', url)
req.onload = function () {
req.status === 200 ? done(req.response) : reject(Error(req.statusText))
}
req.onerror = function () { reject(Error('Network Error')) }
req.send()
})
}
/***/ }),
/* 225 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var player = __webpack_require__(226)
var events = __webpack_require__(228)
var notes = __webpack_require__(229)
var scheduler = __webpack_require__(231)
var midi = __webpack_require__(232)
function SamplePlayer (ac, source, options) {
return midi(scheduler(notes(events(player(ac, source, options)))))
}
if (typeof module === 'object' && module.exports) module.exports = SamplePlayer
if (typeof window !== 'undefined') window.SamplePlayer = SamplePlayer
/***/ }),
/* 226 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* global AudioBuffer */
var ADSR = __webpack_require__(227)
var EMPTY = {}
var DEFAULTS = {
gain: 1,
attack: 0.01,
decay: 0.1,
sustain: 0.9,
release: 0.3,
loop: false,
cents: 0,
loopStart: 0,
loopEnd: 0
}
/**
* Create a sample player.
*
* @param {AudioContext} ac - the audio context
* @param {ArrayBuffer|Object<String,ArrayBuffer>} source
* @param {Onject} options - (Optional) an options object
* @return {player} the player
* @example
* var SamplePlayer = require('sample-player')
* var ac = new AudioContext()
* var snare = SamplePlayer(ac, <AudioBuffer>)
* snare.play()
*/
function SamplePlayer (ac, source, options) {
var connected = false
var nextId = 0
var tracked = {}
var out = ac.createGain()
out.gain.value = 1
var opts = Object.assign({}, DEFAULTS, options)
/**
* @namespace
*/
var player = { context: ac, out: out, opts: opts }
if (source instanceof AudioBuffer) player.buffer = source
else player.buffers = source
/**
* Start a sample buffer.
*
* The returned object has a function `stop(when)` to stop the sound.
*
* @param {String} name - the name of the buffer. If the source of the
* SamplePlayer is one sample buffer, this parameter is not required
* @param {Float} when - (Optional) when to start (current time if by default)
* @param {Object} options - additional sample playing options
* @return {AudioNode} an audio node with a `stop` function
* @example
* var sample = player(ac, <AudioBuffer>).connect(ac.destination)
* sample.start()
* sample.start(5, { gain: 0.7 }) // name not required since is only one AudioBuffer
* @example
* var drums = player(ac, { snare: <AudioBuffer>, kick: <AudioBuffer>, ... }).connect(ac.destination)
* drums.start('snare')
* drums.start('snare', 0, { gain: 0.3 })
*/
player.start = function (name, when, options) {
// if only one buffer, reorder arguments
if (player.buffer && name !== null) return player.start(null, name, when)
var buffer = name ? player.buffers[name] : player.buffer
if (!buffer) {
console.warn('Buffer ' + name + ' not found.')
return
} else if (!connected) {
console.warn('SamplePlayer not connected to any node.')
return
}
var opts = options || EMPTY
when = Math.max(ac.currentTime, when || 0)
player.emit('start', when, name, opts)
var node = createNode(name, buffer, opts)
node.id = track(name, node)
node.env.start(when)
node.source.start(when)
player.emit('started', when, node.id, node)
if (opts.duration) node.stop(when + opts.duration)
return node
}
// NOTE: start will be override so we can't copy the function reference
// this is obviously not a good design, so this code will be gone soon.
/**
* An alias for `player.start`
* @see player.start
* @since 0.3.0
*/
player.play = function (name, when, options) {
return player.start(name, when, options)
}
/**
* Stop some or all samples
*
* @param {Float} when - (Optional) an absolute time in seconds (or currentTime
* if not specified)
* @param {Array} nodes - (Optional) an array of nodes or nodes ids to stop
* @return {Array} an array of ids of the stoped samples
*
* @example
* var longSound = player(ac, <AudioBuffer>).connect(ac.destination)
* longSound.start(ac.currentTime)
* longSound.start(ac.currentTime + 1)
* longSound.start(ac.currentTime + 2)
* longSound.stop(ac.currentTime + 3) // stop the three sounds
*/
player.stop = function (when, ids) {
var node
ids = ids || Object.keys(tracked)
return ids.map(function (id) {
node = tracked[id]
if (!node) return null
node.stop(when)
return node.id
})
}
/**
* Connect the player to a destination node
*
* @param {AudioNode} destination - the destination node
* @return {AudioPlayer} the player
* @chainable
* @example
* var sample = player(ac, <AudioBuffer>).connect(ac.destination)
*/
player.connect = function (dest) {
connected = true
out.connect(dest)
return player
}
player.emit = function (event, when, obj, opts) {
if (player.onevent) player.onevent(event, when, obj, opts)
var fn = player['on' + event]
if (fn) fn(when, obj, opts)
}
return player
// =============== PRIVATE FUNCTIONS ============== //
function track (name, node) {
node.id = nextId++
tracked[node.id] = node
node.source.onended = function () {
var now = ac.currentTime
node.source.disconnect()
node.env.disconnect()
node.disconnect()
player.emit('ended', now, node.id, node)
}
return node.id
}
function createNode (name, buffer, options) {
var node = ac.createGain()
node.gain.value = 0 // the envelope will control the gain
node.connect(out)
node.env = envelope(ac, options, opts)
node.env.connect(node.gain)
node.source = ac.createBufferSource()
node.source.buffer = buffer
node.source.connect(node)
node.source.loop = options.loop || opts.loop
node.source.playbackRate.value = centsToRate(options.cents || opts.cents)
node.source.loopStart = options.loopStart || opts.loopStart
node.source.loopEnd = options.loopEnd || opts.loopEnd
node.stop = function (when) {
var time = when || ac.currentTime
player.emit('stop', time, name)
var stopAt = node.env.stop(time)
node.source.stop(stopAt)
}
return node
}
}
function isNum (x) { return typeof x === 'number' }
var PARAMS = ['attack', 'decay', 'sustain', 'release']
function envelope (ac, options, opts) {
var env = ADSR(ac)
var adsr = options.adsr || opts.adsr
PARAMS.forEach(function (name, i) {
if (adsr) env[name] = adsr[i]
else env[name] = options[name] || opts[name]
})
env.value.value = isNum(options.gain) ? options.gain
: isNum(opts.gain) ? opts.gain : 1
return env
}
/*
* Get playback rate for a given pitch change (in cents)
* Basic [math](http://www.birdsoft.demon.co.uk/music/samplert.htm):
* f2 = f1 * 2^( C / 1200 )
*/
function centsToRate (cents) { return cents ? Math.pow(2, cents / 1200) : 1 }
module.exports = SamplePlayer
/***/ }),
/* 227 */
/***/ (function(module, exports) {
module.exports = ADSR
function ADSR(audioContext){
var node = audioContext.createGain()
var voltage = node._voltage = getVoltage(audioContext)
var value = scale(voltage)
var startValue = scale(voltage)
var endValue = scale(voltage)
node._startAmount = scale(startValue)
node._endAmount = scale(endValue)
node._multiplier = scale(value)
node._multiplier.connect(node)
node._startAmount.connect(node)
node._endAmount.connect(node)
node.value = value.gain
node.startValue = startValue.gain
node.endValue = endValue.gain
node.startValue.value = 0
node.endValue.value = 0
Object.defineProperties(node, props)
return node
}
var props = {
attack: { value: 0, writable: true },
decay: { value: 0, writable: true },
sustain: { value: 1, writable: true },
release: {value: 0, writable: true },
getReleaseDuration: {
value: function(){
return this.release
}
},
start: {
value: function(at){
var target = this._multiplier.gain
var startAmount = this._startAmount.gain
var endAmount = this._endAmount.gain
this._voltage.start(at)
this._decayFrom = this._decayFrom = at+this.attack
this._startedAt = at
var sustain = this.sustain
target.cancelScheduledValues(at)
startAmount.cancelScheduledValues(at)
endAmount.cancelScheduledValues(at)
endAmount.setValueAtTime(0, at)
if (this.attack){
target.setValueAtTime(0, at)
target.linearRampToValueAtTime(1, at + this.attack)
startAmount.setValueAtTime(1, at)
startAmount.linearRampToValueAtTime(0, at + this.attack)
} else {
target.setValueAtTime(1, at)
startAmount.setValueAtTime(0, at)
}
if (this.decay){
target.setTargetAtTime(sustain, this._decayFrom, getTimeConstant(this.decay))
}
}
},
stop: {
value: function(at, isTarget){
if (isTarget){
at = at - this.release
}
var endTime = at + this.release
if (this.release){
var target = this._multiplier.gain
var startAmount = this._startAmount.gain
var endAmount = this._endAmount.gain
target.cancelScheduledValues(at)
startAmount.cancelScheduledValues(at)
endAmount.cancelScheduledValues(at)
var expFalloff = getTimeConstant(this.release)
// truncate attack (required as linearRamp is removed by cancelScheduledValues)
if (this.attack && at < this._decayFrom){
var valueAtTime = getValue(0, 1, this._startedAt, this._decayFrom, at)
target.linearRampToValueAtTime(valueAtTime, at)
startAmount.linearRampToValueAtTime(1-valueAtTime, at)
startAmount.setTargetAtTime(0, at, expFalloff)
}
endAmount.setTargetAtTime(1, at, expFalloff)
target.setTargetAtTime(0, at, expFalloff)
}
this._voltage.stop(endTime)
return endTime
}
},
onended: {
get: function(){
return this._voltage.onended
},
set: function(value){
this._voltage.onended = value
}
}
}
var flat = new Float32Array([1,1])
function getVoltage(context){
var voltage = context.createBufferSource()
var buffer = context.createBuffer(1, 2, context.sampleRate)
buffer.getChannelData(0).set(flat)
voltage.buffer = buffer
voltage.loop = true
return voltage
}
function scale(node){
var gain = node.context.createGain()
node.connect(gain)
return gain
}
function getTimeConstant(time){
return Math.log(time+1)/Math.log(100)
}
function getValue(start, end, fromTime, toTime, at){
var difference = end - start
var time = toTime - fromTime
var truncateTime = at - fromTime
var phase = truncateTime / time
var value = start + phase * difference
if (value <= start) {
value = start
}
if (value >= end) {
value = end
}
return value
}
/***/ }),
/* 228 */
/***/ (function(module, exports) {
module.exports = function (player) {
/**
* Adds a listener of an event
* @chainable
* @param {String} event - the event name
* @param {Function} callback - the event handler
* @return {SamplePlayer} the player
* @example
* player.on('start', function(time, note) {
* console.log(time, note)
* })
*/
player.on = function (event, cb) {
if (arguments.length === 1 && typeof event === 'function') return player.on('event', event)
var prop = 'on' + event
var old = player[prop]
player[prop] = old ? chain(old, cb) : cb
return player
}
return player
}
function chain (fn1, fn2) {
return function (a, b, c, d) { fn1(a, b, c, d); fn2(a, b, c, d) }
}
/***/ }),
/* 229 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var note = __webpack_require__(230)
var isMidi = function (n) { return n !== null && n !== [] && n >= 0 && n < 129 }
var toMidi = function (n) { return isMidi(n) ? +n : note.midi(n) }
// Adds note name to midi conversion
module.exports = function (player) {
if (player.buffers) {
var map = player.opts.map
var toKey = typeof map === 'function' ? map : toMidi
var mapper = function (name) {
return name ? toKey(name) || name : null
}
player.buffers = mapBuffers(player.buffers, mapper)
var start = player.start
player.start = function (name, when, options) {
var key = mapper(name)
var dec = key % 1
if (dec) {
key = Math.floor(key)
options = Object.assign(options || {}, { cents: Math.floor(dec * 100) })
}
return start(key, when, options)
}
}
return player
}
function mapBuffers (buffers, toKey) {
return Object.keys(buffers).reduce(function (mapped, name) {
mapped[toKey(name)] = buffers[name]
return mapped
}, {})
}
/***/ }),
/* 230 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var REGEX = /^([a-gA-G])(#{1,}|b{1,}|x{1,}|)(-?\d*)\s*(.*)\s*$/
/**
* A regex for matching note strings in scientific notation.
*
* @name regex
* @function
* @return {RegExp} the regexp used to parse the note name
*
* The note string should have the form `letter[accidentals][octave][element]`
* where:
*
* - letter: (Required) is a letter from A to G either upper or lower case
* - accidentals: (Optional) can be one or more `b` (flats), `#` (sharps) or `x` (double sharps).
* They can NOT be mixed.
* - octave: (Optional) a positive or negative integer
* - element: (Optional) additionally anything after the duration is considered to
* be the element name (for example: 'C2 dorian')
*
* The executed regex contains (by array index):
*
* - 0: the complete string
* - 1: the note letter
* - 2: the optional accidentals
* - 3: the optional octave
* - 4: the rest of the string (trimmed)
*
* @example
* var parser = require('note-parser')
* parser.regex.exec('c#4')
* // => ['c#4', 'c', '#', '4', '']
* parser.regex.exec('c#4 major')
* // => ['c#4major', 'c', '#', '4', 'major']
* parser.regex().exec('CMaj7')
* // => ['CMaj7', 'C', '', '', 'Maj7']
*/
function regex () { return REGEX }
var SEMITONES = [0, 2, 4, 5, 7, 9, 11]
/**
* Parse a note name in scientific notation an return it's components,
* and some numeric properties including midi number and frequency.
*
* @name parse
* @function
* @param {String} note - the note string to be parsed
* @param {Boolean} isTonic - true if the note is the tonic of something.
* If true, en extra tonicOf property is returned. It's false by default.
* @param {Float} tunning - The frequency of A4 note to calculate frequencies.
* By default it 440.
* @return {Object} the parsed note name or null if not a valid note
*
* The parsed note name object will ALWAYS contains:
* - letter: the uppercase letter of the note
* - acc: the accidentals of the note (only sharps or flats)
* - pc: the pitch class (letter + acc)
* - step: s a numeric representation of the letter. It's an integer from 0 to 6
* where 0 = C, 1 = D ... 6 = B
* - alt: a numeric representation of the accidentals. 0 means no alteration,
* positive numbers are for sharps and negative for flats
* - chroma: a numeric representation of the pitch class. It's like midi for
* pitch classes. 0 = C, 1 = C#, 2 = D ... It can have negative values: -1 = Cb.
* Can detect pitch class enhramonics.
*
* If the note has octave, the parser object will contain:
* - oct: the octave number (as integer)
* - midi: the midi number
* - freq: the frequency (using tuning parameter as base)
*
* If the parameter `isTonic` is set to true, the parsed object will contain:
* - tonicOf: the rest of the string that follows note name (left and right trimmed)
*
* @example
* var parse = require('note-parser').parse
* parse('Cb4')
* // => { letter: 'C', acc: 'b', pc: 'Cb', step: 0, alt: -1, chroma: -1,
* oct: 4, midi: 59, freq: 246.94165062806206 }
* // if no octave, no midi, no freq
* parse('fx')
* // => { letter: 'F', acc: '##', pc: 'F##', step: 3, alt: 2, chroma: 7 })
*/
function parse (str, isTonic, tuning) {
if (typeof str !== 'string') return null
var m = REGEX.exec(str)
if (!m || !isTonic && m[4]) return null
var p = { letter: m[1].toUpperCase(), acc: m[2].replace(/x/g, '##') }
p.pc = p.letter + p.acc
p.step = (p.letter.charCodeAt(0) + 3) % 7
p.alt = p.acc[0] === 'b' ? -p.acc.length : p.acc.length
p.chroma = SEMITONES[p.step] + p.alt
if (m[3]) {
p.oct = +m[3]
p.midi = p.chroma + 12 * (p.oct + 1)
p.freq = midiToFreq(p.midi, tuning)
}
if (isTonic) p.tonicOf = m[4]
return p
}
/**
* Given a midi number, return its frequency
* @param {Integer} midi - midi note number
* @param {Float} tuning - (Optional) the A4 tuning (440Hz by default)
* @return {Float} frequency in hertzs
*/
function midiToFreq (midi, tuning) {
return Math.pow(2, (midi - 69) / 12) * (tuning || 440)
}
var parser = { parse: parse, regex: regex, midiToFreq: midiToFreq }
var FNS = ['letter', 'acc', 'pc', 'step', 'alt', 'chroma', 'oct', 'midi', 'freq']
FNS.forEach(function (name) {
parser[name] = function (src) {
var p = parse(src)
return p && (typeof p[name] !== 'undefined') ? p[name] : null
}
})
module.exports = parser
// extra API docs
/**
* Get midi of a note
*
* @name midi
* @function
* @param {String} note - the note name
* @return {Integer} the midi number of the note or null if not a valid note
* or the note does NOT contains octave
* @example
* var parser = require('note-parser')
* parser.midi('A4') // => 69
* parser.midi('A') // => null
*/
/**
* Get freq of a note in hertzs (in a well tempered 440Hz A4)
*
* @name freq
* @function
* @param {String} note - the note name
* @return {Float} the freq of the number if hertzs or null if not valid note
* or the note does NOT contains octave
* @example
* var parser = require('note-parser')
* parser.freq('A4') // => 440
* parser.freq('A') // => null
*/
/***/ }),
/* 231 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var isArr = Array.isArray
var isObj = function (o) { return o && typeof o === 'object' }
var OPTS = {}
module.exports = function (player) {
/**
* Schedule a list of events to be played at specific time.
*
* It supports three formats of events for the events list:
*
* - An array with [time, note]
* - An array with [time, object]
* - An object with { time: ?, [name|note|midi|key]: ? }
*
* @param {Float} time - an absolute time to start (or AudioContext's
* currentTime if provided number is 0)
* @param {Array} events - the events list.
* @return {Array} an array of ids
*
* @example
* // Event format: [time, note]
* var piano = player(ac, ...).connect(ac.destination)
* piano.schedule(0, [ [0, 'C2'], [0.5, 'C3'], [1, 'C4'] ])
*
* @example
* // Event format: an object { time: ?, name: ? }
* var drums = player(ac, ...).connect(ac.destination)
* drums.schedule(0, [
* { name: 'kick', time: 0 },
* { name: 'snare', time: 0.5 },
* { name: 'kick', time: 1 },
* { name: 'snare', time: 1.5 }
* ])
*/
player.schedule = function (time, events) {
var now = player.context.currentTime
var when = time < now ? now : time
player.emit('schedule', when, events)
var t, o, note, opts
return events.map(function (event) {
if (!event) return null
else if (isArr(event)) {
t = event[0]; o = event[1]
} else {
t = event.time; o = event
}
if (isObj(o)) {
note = o.name || o.key || o.note || o.midi || null
opts = o
} else {
note = o
opts = OPTS
}
return player.start(note, when + (t || 0), opts)
})
}
return player
}
/***/ }),
/* 232 */
/***/ (function(module, exports, __webpack_require__) {
var midimessage = __webpack_require__(233)
module.exports = function (player) {
/**
* Connect a player to a midi input
*
* The options accepts:
*
* - channel: the channel to listen to. Listen to all channels by default.
*
* @param {MIDIInput} input
* @param {Object} options - (Optional)
* @return {SamplePlayer} the player
* @example
* var piano = player(...)
* window.navigator.requestMIDIAccess().then(function (midiAccess) {
* midiAccess.inputs.forEach(function (midiInput) {
* piano.listenToMidi(midiInput)
* })
* })
*/
player.listenToMidi = function (input, options) {
var started = {}
var opts = options || {}
var gain = opts.gain || function (vel) { return vel / 127 }
input.onmidimessage = function (msg) {
var mm = msg.messageType ? msg : midimessage(msg)
if (mm.messageType === 'noteon' && mm.velocity === 0) {
mm.messageType = 'noteoff'
}
if (opts.channel && mm.channel !== opts.channel) return
switch (mm.messageType) {
case 'noteon':
started[mm.key] = player.play(mm.key, 0, { gain: gain(mm.velocity) })
break
case 'noteoff':
if (started[mm.key]) {
started[mm.key].stop()
delete started[mm.key]
}
break
}
}
return player
}
return player
}
/***/ }),
/* 233 */
/***/ (function(module, exports, __webpack_require__) {
var require;var require;(function(e){if(true){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.midimessage=e()}})(function(){var e,t,s;return function o(e,t,s){function a(n,i){if(!t[n]){if(!e[n]){var l=typeof require=="function"&&require;if(!i&&l)return require(n,!0);if(r)return r(n,!0);var h=new Error("Cannot find module '"+n+"'");throw h.code="MODULE_NOT_FOUND",h}var c=t[n]={exports:{}};e[n][0].call(c.exports,function(t){var s=e[n][1][t];return a(s?s:t)},c,c.exports,o,e,t,s)}return t[n].exports}var r=typeof require=="function"&&require;for(var n=0;n<s.length;n++)a(s[n]);return a}({1:[function(e,t,s){"use strict";Object.defineProperty(s,"__esModule",{value:true});s["default"]=function(e){function t(e){this._event=e;this._data=e.data;this.receivedTime=e.receivedTime;if(this._data&&this._data.length<2){console.warn("Illegal MIDI message of length",this._data.length);return}this._messageCode=e.data[0]&240;this.channel=e.data[0]&15;switch(this._messageCode){case 128:this.messageType="noteoff";this.key=e.data[1]&127;this.velocity=e.data[2]&127;break;case 144:this.messageType="noteon";this.key=e.data[1]&127;this.velocity=e.data[2]&127;break;case 160:this.messageType="keypressure";this.key=e.data[1]&127;this.pressure=e.data[2]&127;break;case 176:this.messageType="controlchange";this.controllerNumber=e.data[1]&127;this.controllerValue=e.data[2]&127;if(this.controllerNumber===120&&this.controllerValue===0){this.channelModeMessage="allsoundoff"}else if(this.controllerNumber===121){this.channelModeMessage="resetallcontrollers"}else if(this.controllerNumber===122){if(this.controllerValue===0){this.channelModeMessage="localcontroloff"}else{this.channelModeMessage="localcontrolon"}}else if(this.controllerNumber===123&&this.controllerValue===0){this.channelModeMessage="allnotesoff"}else if(this.controllerNumber===124&&this.controllerValue===0){this.channelModeMessage="omnimodeoff"}else if(this.controllerNumber===125&&this.controllerValue===0){this.channelModeMessage="omnimodeon"}else if(this.controllerNumber===126){this.channelModeMessage="monomodeon"}else if(this.controllerNumber===127){this.channelModeMessage="polymodeon"}break;case 192:this.messageType="programchange";this.program=e.data[1];break;case 208:this.messageType="channelpressure";this.pressure=e.data[1]&127;break;case 224:this.messageType="pitchbendchange";var t=e.data[2]&127;var s=e.data[1]&127;this.pitchBend=(t<<8)+s;break}}return new t(e)};t.exports=s["default"]},{}]},{},[1])(1)});
//# sourceMappingURL=dist/index.js.map
/***/ }),
/* 234 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var parser = __webpack_require__(235)
/**
* Create a Soundfont object
*
* @param {AudioContext} context - the [audio context](https://developer.mozilla.org/en/docs/Web/API/AudioContext)
* @param {Function} nameToUrl - (Optional) a function that maps the sound font name to the url
* @return {Soundfont} a soundfont object
*/
function Soundfont (ctx, nameToUrl) {
console.warn('new Soundfont() is deprected')
console.log('Please use Soundfont.instrument() instead of new Soundfont().instrument()')
if (!(this instanceof Soundfont)) return new Soundfont(ctx)
this.nameToUrl = nameToUrl || Soundfont.nameToUrl
this.ctx = ctx
this.instruments = {}
this.promises = []
}
Soundfont.prototype.onready = function (callback) {
console.warn('deprecated API')
console.log('Please use Promise.all(Soundfont.instrument(), Soundfont.instrument()).then() instead of new Soundfont().onready()')
Promise.all(this.promises).then(callback)
}
Soundfont.prototype.instrument = function (name, options) {
console.warn('new Soundfont().instrument() is deprecated.')
console.log('Please use Soundfont.instrument() instead.')
var ctx = this.ctx
name = name || 'default'
if (name in this.instruments) return this.instruments[name]
var inst = {name: name, play: oscillatorPlayer(ctx, options)}
this.instruments[name] = inst
if (name !== 'default') {
var promise = Soundfont.instrument(ctx, name, options).then(function (instrument) {
inst.play = instrument.play
return inst
})
this.promises.push(promise)
inst.onready = function (cb) {
console.warn('onready is deprecated. Use Soundfont.instrument().then()')
promise.then(cb)
}
} else {
inst.onready = function (cb) {
console.warn('onready is deprecated. Use Soundfont.instrument().then()')
cb()
}
}
return inst
}
/*
* Load the buffers of a given instrument name. It returns a promise that resolves
* to a hash with midi note numbers as keys, and audio buffers as values.
*
* @param {AudioContext} ac - the audio context
* @param {String} name - the instrument name (it accepts an url if starts with "http")
* @param {Object} options - (Optional) options object
* @return {Promise} a promise that resolves to a Hash of { midiNoteNum: <AudioBuffer> }
*
* The options object accepts the following keys:
*
* - nameToUrl {Function}: a function to convert from instrument names to urls.
* By default it uses Benjamin Gleitzman's package of
* [pre-rendered sound fonts](https://github.com/gleitz/midi-js-soundfonts)
* - notes {Array}: the list of note names to be decoded (all by default)
*
* @example
* var Soundfont = require('soundfont-player')
* Soundfont.loadBuffers(ctx, 'acoustic_grand_piano').then(function(buffers) {
* buffers[60] // => An <AudioBuffer> corresponding to note C4
* })
*/
function loadBuffers (ac, name, options) {
console.warn('Soundfont.loadBuffers is deprecate.')
console.log('Use Soundfont.instrument(..) and get buffers properties from the result.')
return Soundfont.instrument(ac, name, options).then(function (inst) {
return inst.buffers
})
}
Soundfont.loadBuffers = loadBuffers
/**
* Returns a function that plays an oscillator
*
* @param {AudioContext} ac - the audio context
* @param {Hash} defaultOptions - (Optional) a hash of options:
* - vcoType: the oscillator type (default: 'sine')
* - gain: the output gain value (default: 0.4)
* - destination: the player destination (default: ac.destination)
*/
function oscillatorPlayer (ctx, defaultOptions) {
defaultOptions = defaultOptions || {}
return function (note, time, duration, options) {
console.warn('The oscillator player is deprecated.')
console.log('Starting with version 0.9.0 you will have to wait until the soundfont is loaded to play sounds.')
var midi = note > 0 && note < 129 ? +note : parser.midi(note)
var freq = midi ? parser.midiToFreq(midi, 440) : null
if (!freq) return
duration = duration || 0.2
options = options || {}
var destination = options.destination || defaultOptions.destination || ctx.destination
var vcoType = options.vcoType || defaultOptions.vcoType || 'sine'
var gain = options.gain || defaultOptions.gain || 0.4
var vco = ctx.createOscillator()
vco.type = vcoType
vco.frequency.value = freq
/* VCA */
var vca = ctx.createGain()
vca.gain.value = gain
/* Connections */
vco.connect(vca)
vca.connect(destination)
vco.start(time)
if (duration > 0) vco.stop(time + duration)
return vco
}
}
/**
* Given a note name, return the note midi number
*
* @name noteToMidi
* @function
* @param {String} noteName
* @return {Integer} the note midi number or null if not a valid note name
*/
Soundfont.noteToMidi = parser.midi
module.exports = Soundfont
/***/ }),
/* 235 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony export (immutable) */ __webpack_exports__["regex"] = regex;
/* harmony export (immutable) */ __webpack_exports__["parse"] = parse;
/* harmony export (immutable) */ __webpack_exports__["build"] = build;
/* harmony export (immutable) */ __webpack_exports__["midi"] = midi;
/* harmony export (immutable) */ __webpack_exports__["freq"] = freq;
/* harmony export (immutable) */ __webpack_exports__["letter"] = letter;
/* harmony export (immutable) */ __webpack_exports__["acc"] = acc;
/* harmony export (immutable) */ __webpack_exports__["pc"] = pc;
/* harmony export (immutable) */ __webpack_exports__["step"] = step;
/* harmony export (immutable) */ __webpack_exports__["alt"] = alt;
/* harmony export (immutable) */ __webpack_exports__["chroma"] = chroma;
/* harmony export (immutable) */ __webpack_exports__["oct"] = oct;
// util
function fillStr (s, num) { return Array(num + 1).join(s) }
function isNum (x) { return typeof x === 'number' }
function isStr (x) { return typeof x === 'string' }
function isDef (x) { return typeof x !== 'undefined' }
function midiToFreq (midi, tuning) {
return Math.pow(2, (midi - 69) / 12) * (tuning || 440)
}
var REGEX = /^([a-gA-G])(#{1,}|b{1,}|x{1,}|)(-?\d*)\s*(.*)\s*$/
/**
* A regex for matching note strings in scientific notation.
*
* @name regex
* @function
* @return {RegExp} the regexp used to parse the note name
*
* The note string should have the form `letter[accidentals][octave][element]`
* where:
*
* - letter: (Required) is a letter from A to G either upper or lower case
* - accidentals: (Optional) can be one or more `b` (flats), `#` (sharps) or `x` (double sharps).
* They can NOT be mixed.
* - octave: (Optional) a positive or negative integer
* - element: (Optional) additionally anything after the duration is considered to
* be the element name (for example: 'C2 dorian')
*
* The executed regex contains (by array index):
*
* - 0: the complete string
* - 1: the note letter
* - 2: the optional accidentals
* - 3: the optional octave
* - 4: the rest of the string (trimmed)
*
* @example
* var parser = require('note-parser')
* parser.regex.exec('c#4')
* // => ['c#4', 'c', '#', '4', '']
* parser.regex.exec('c#4 major')
* // => ['c#4major', 'c', '#', '4', 'major']
* parser.regex().exec('CMaj7')
* // => ['CMaj7', 'C', '', '', 'Maj7']
*/
function regex () { return REGEX }
var SEMITONES = [0, 2, 4, 5, 7, 9, 11]
/**
* Parse a note name in scientific notation an return it's components,
* and some numeric properties including midi number and frequency.
*
* @name parse
* @function
* @param {String} note - the note string to be parsed
* @param {Boolean} isTonic - true the strings it's supposed to contain a note number
* and some category (for example an scale: 'C# major'). It's false by default,
* but when true, en extra tonicOf property is returned with the category ('major')
* @param {Float} tunning - The frequency of A4 note to calculate frequencies.
* By default it 440.
* @return {Object} the parsed note name or null if not a valid note
*
* The parsed note name object will ALWAYS contains:
* - letter: the uppercase letter of the note
* - acc: the accidentals of the note (only sharps or flats)
* - pc: the pitch class (letter + acc)
* - step: s a numeric representation of the letter. It's an integer from 0 to 6
* where 0 = C, 1 = D ... 6 = B
* - alt: a numeric representation of the accidentals. 0 means no alteration,
* positive numbers are for sharps and negative for flats
* - chroma: a numeric representation of the pitch class. It's like midi for
* pitch classes. 0 = C, 1 = C#, 2 = D ... 11 = B. Can be used to find enharmonics
* since, for example, chroma of 'Cb' and 'B' are both 11
*
* If the note has octave, the parser object will contain:
* - oct: the octave number (as integer)
* - midi: the midi number
* - freq: the frequency (using tuning parameter as base)
*
* If the parameter `isTonic` is set to true, the parsed object will contain:
* - tonicOf: the rest of the string that follows note name (left and right trimmed)
*
* @example
* var parse = require('note-parser').parse
* parse('Cb4')
* // => { letter: 'C', acc: 'b', pc: 'Cb', step: 0, alt: -1, chroma: -1,
* oct: 4, midi: 59, freq: 246.94165062806206 }
* // if no octave, no midi, no freq
* parse('fx')
* // => { letter: 'F', acc: '##', pc: 'F##', step: 3, alt: 2, chroma: 7 })
*/
function parse (str, isTonic, tuning) {
if (typeof str !== 'string') return null
var m = REGEX.exec(str)
if (!m || (!isTonic && m[4])) return null
var p = { letter: m[1].toUpperCase(), acc: m[2].replace(/x/g, '##') }
p.pc = p.letter + p.acc
p.step = (p.letter.charCodeAt(0) + 3) % 7
p.alt = p.acc[0] === 'b' ? -p.acc.length : p.acc.length
var pos = SEMITONES[p.step] + p.alt
p.chroma = pos < 0 ? 12 + pos : pos % 12
if (m[3]) { // has octave
p.oct = +m[3]
p.midi = pos + 12 * (p.oct + 1)
p.freq = midiToFreq(p.midi, tuning)
}
if (isTonic) p.tonicOf = m[4]
return p
}
var LETTERS = 'CDEFGAB'
function accStr (n) { return !isNum(n) ? '' : n < 0 ? fillStr('b', -n) : fillStr('#', n) }
function octStr (n) { return !isNum(n) ? '' : '' + n }
/**
* Create a string from a parsed object or `step, alteration, octave` parameters
* @param {Object} obj - the parsed data object
* @return {String} a note string or null if not valid parameters
* @since 1.2
* @example
* parser.build(parser.parse('cb2')) // => 'Cb2'
*
* @example
* // it accepts (step, alteration, octave) parameters:
* parser.build(3) // => 'F'
* parser.build(3, -1) // => 'Fb'
* parser.build(3, -1, 4) // => 'Fb4'
*/
function build (s, a, o) {
if (s === null || typeof s === 'undefined') return null
if (s.step) return build(s.step, s.alt, s.oct)
if (s < 0 || s > 6) return null
return LETTERS.charAt(s) + accStr(a) + octStr(o)
}
/**
* Get midi of a note
*
* @name midi
* @function
* @param {String|Integer} note - the note name or midi number
* @return {Integer} the midi number of the note or null if not a valid note
* or the note does NOT contains octave
* @example
* var parser = require('note-parser')
* parser.midi('A4') // => 69
* parser.midi('A') // => null
* @example
* // midi numbers are bypassed (even as strings)
* parser.midi(60) // => 60
* parser.midi('60') // => 60
*/
function midi (note) {
if ((isNum(note) || isStr(note)) && note >= 0 && note < 128) return +note
var p = parse(note)
return p && isDef(p.midi) ? p.midi : null
}
/**
* Get freq of a note in hertzs (in a well tempered 440Hz A4)
*
* @name freq
* @function
* @param {String} note - the note name or note midi number
* @param {String} tuning - (Optional) the A4 frequency (440 by default)
* @return {Float} the freq of the number if hertzs or null if not valid note
* @example
* var parser = require('note-parser')
* parser.freq('A4') // => 440
* parser.freq('A') // => null
* @example
* // can change tuning (440 by default)
* parser.freq('A4', 444) // => 444
* parser.freq('A3', 444) // => 222
* @example
* // it accepts midi numbers (as numbers and as strings)
* parser.freq(69) // => 440
* parser.freq('69', 442) // => 442
*/
function freq (note, tuning) {
var m = midi(note)
return m === null ? null : midiToFreq(m, tuning)
}
function letter (src) { return (parse(src) || {}).letter }
function acc (src) { return (parse(src) || {}).acc }
function pc (src) { return (parse(src) || {}).pc }
function step (src) { return (parse(src) || {}).step }
function alt (src) { return (parse(src) || {}).alt }
function chroma (src) { return (parse(src) || {}).chroma }
function oct (src) { return (parse(src) || {}).oct }
/***/ }),
/* 236 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.VolumeSlider = exports.MuteToggleButton = exports.SoundOffButton = exports.SoundOnButton = exports.TimeMarkerType = exports.TimeMarker = exports.FormattedTime = exports.ProgressBar = exports.PrevButton = exports.NextButton = exports.PauseButton = exports.PlayButton = exports.PlaybackControls = exports.Button = undefined;
var _icons = __webpack_require__(86);
Object.keys(_icons).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
return _icons[key];
}
});
});
var _Button = __webpack_require__(87);
var _Button2 = _interopRequireDefault(_Button);
var _PlaybackControls = __webpack_require__(237);
var _PlaybackControls2 = _interopRequireDefault(_PlaybackControls);
var _PlayButton = __webpack_require__(193);
var _PlayButton2 = _interopRequireDefault(_PlayButton);
var _PauseButton = __webpack_require__(194);
var _PauseButton2 = _interopRequireDefault(_PauseButton);
var _NextButton = __webpack_require__(196);
var _NextButton2 = _interopRequireDefault(_NextButton);
var _PrevButton = __webpack_require__(195);
var _PrevButton2 = _interopRequireDefault(_PrevButton);
var _ProgressBar = __webpack_require__(240);
var _ProgressBar2 = _interopRequireDefault(_ProgressBar);
var _FormattedTime = __webpack_require__(198);
var _FormattedTime2 = _interopRequireDefault(_FormattedTime);
var _TimeMarker = __webpack_require__(241);
var _TimeMarker2 = _interopRequireDefault(_TimeMarker);
var _SoundOnButton = __webpack_require__(199);
var _SoundOnButton2 = _interopRequireDefault(_SoundOnButton);
var _SoundOffButton = __webpack_require__(200);
var _SoundOffButton2 = _interopRequireDefault(_SoundOffButton);
var _MuteToggleButton = __webpack_require__(243);
var _MuteToggleButton2 = _interopRequireDefault(_MuteToggleButton);
var _VolumeSlider = __webpack_require__(244);
var _VolumeSlider2 = _interopRequireDefault(_VolumeSlider);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
exports.Button = _Button2.default;
exports.PlaybackControls = _PlaybackControls2.default;
exports.PlayButton = _PlayButton2.default;
exports.PauseButton = _PauseButton2.default;
exports.NextButton = _NextButton2.default;
exports.PrevButton = _PrevButton2.default;
exports.ProgressBar = _ProgressBar2.default;
exports.FormattedTime = _FormattedTime2.default;
exports.TimeMarker = _TimeMarker2.default;
exports.TimeMarkerType = _TimeMarker.TimeMarkerType;
exports.SoundOnButton = _SoundOnButton2.default;
exports.SoundOffButton = _SoundOffButton2.default;
exports.MuteToggleButton = _MuteToggleButton2.default;
exports.VolumeSlider = _VolumeSlider2.default;
/***/ }),
/* 237 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _desc, _value, _class;
var _react = __webpack_require__(11);
var _react2 = _interopRequireDefault(_react);
var _propTypes = __webpack_require__(25);
var _propTypes2 = _interopRequireDefault(_propTypes);
var _autobindDecorator = __webpack_require__(89);
var _autobindDecorator2 = _interopRequireDefault(_autobindDecorator);
var _classnames = __webpack_require__(84);
var _classnames2 = _interopRequireDefault(_classnames);
var _composers = __webpack_require__(88);
var _PlayButton = __webpack_require__(193);
var _PlayButton2 = _interopRequireDefault(_PlayButton);
var _PauseButton = __webpack_require__(194);
var _PauseButton2 = _interopRequireDefault(_PauseButton);
var _PrevButton = __webpack_require__(195);
var _PrevButton2 = _interopRequireDefault(_PrevButton);
var _NextButton = __webpack_require__(196);
var _NextButton2 = _interopRequireDefault(_NextButton);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
var desc = {};
Object['ke' + 'ys'](descriptor).forEach(function (key) {
desc[key] = descriptor[key];
});
desc.enumerable = !!desc.enumerable;
desc.configurable = !!desc.configurable;
if ('value' in desc || desc.initializer) {
desc.writable = true;
}
desc = decorators.slice().reverse().reduce(function (desc, decorator) {
return decorator(target, property, desc) || desc;
}, desc);
if (context && desc.initializer !== void 0) {
desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
desc.initializer = undefined;
}
if (desc.initializer === void 0) {
Object['define' + 'Property'](target, property, desc);
desc = null;
}
return desc;
}
var bool = _propTypes2.default.bool,
func = _propTypes2.default.func,
object = _propTypes2.default.object;
var noop = function noop() {};
/**
* Play and pause controls
*/
var PlaybackControls = (_class = function (_Component) {
_inherits(PlaybackControls, _Component);
function PlaybackControls() {
_classCallCheck(this, PlaybackControls);
return _possibleConstructorReturn(this, (PlaybackControls.__proto__ || Object.getPrototypeOf(PlaybackControls)).apply(this, arguments));
}
_createClass(PlaybackControls, [{
key: 'handlePlay',
value: function handlePlay() {
if (this.props.isPlayable) {
this.props.onPlaybackChange(true);
}
}
}, {
key: 'handlePause',
value: function handlePause() {
this.props.onPlaybackChange(false);
}
}, {
key: 'render',
value: function render() {
var _props = this.props,
isPlayable = _props.isPlayable,
isPlaying = _props.isPlaying,
showPrevious = _props.showPrevious,
hasPrevious = _props.hasPrevious,
onPrevious = _props.onPrevious,
showNext = _props.showNext,
hasNext = _props.hasNext,
onNext = _props.onNext,
className = _props.className,
extraClasses = _props.extraClasses,
childClasses = _props.childClasses,
style = _props.style,
childrenStyles = _props.childrenStyles;
return _react2.default.createElement(
'div',
{
className: (0, _classnames2.default)(className, { isPlayable: isPlayable, isPlaying: isPlaying }, extraClasses),
style: style
},
showPrevious && _react2.default.createElement(_PrevButton2.default, {
isEnabled: hasPrevious,
onClick: onPrevious,
className: childClasses.PrevButton,
style: childrenStyles.PrevButton
}),
isPlaying && isPlayable ? _react2.default.createElement(_PauseButton2.default, {
onClick: this.handlePause,
className: childClasses.PauseButton,
style: childrenStyles.PauseButton
}) : _react2.default.createElement(_PlayButton2.default, {
isEnabled: isPlayable,
onClick: this.handlePlay,
className: childClasses.PlayButton,
style: childrenStyles.PlayButton
}),
showNext && _react2.default.createElement(_NextButton2.default, {
isEnabled: hasNext,
onClick: onNext,
className: childClasses.NextButton,
style: childrenStyles.NextButton
})
);
}
}]);
return PlaybackControls;
}(_react.Component), (_applyDecoratedDescriptor(_class.prototype, 'handlePlay', [_autobindDecorator2.default], Object.getOwnPropertyDescriptor(_class.prototype, 'handlePlay'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'handlePause', [_autobindDecorator2.default], Object.getOwnPropertyDescriptor(_class.prototype, 'handlePause'), _class.prototype)), _class);
PlaybackControls.propTypes = {
onPlaybackChange: func.isRequired,
isPlayable: bool,
isPlaying: bool,
showPrevious: bool,
hasPrevious: bool,
onPrevious: func,
showNext: bool,
hasNext: bool,
onNext: func,
style: object
};
PlaybackControls.defaultProps = {
isPlayable: false,
isPlaying: false,
showPrevious: true,
hasPrevious: false,
onPrevious: noop,
showNext: true,
hasNext: false,
onNext: noop,
style: {}
};
exports.default = (0, _composers.compose)((0, _composers.withChildrenStyles)(), (0, _composers.withCustomizableClasses)('PlaybackControls'), (0, _composers.withChildClasses)())(PlaybackControls);
/***/ }),
/* 238 */
/***/ (function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global) {/**
* lodash (Custom Build) <https://lodash.com/>
* Build: `lodash modularize exports="npm" -o ./`
* Copyright jQuery Foundation and other contributors <https://jquery.org/>
* Released under MIT license <https://lodash.com/license>
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
*/
/** Used as the `TypeError` message for "Functions" methods. */
var FUNC_ERROR_TEXT = 'Expected a function';
/** Used as the internal argument placeholder. */
var PLACEHOLDER = '__lodash_placeholder__';
/** Used to compose bitmasks for function metadata. */
var BIND_FLAG = 1,
BIND_KEY_FLAG = 2,
CURRY_BOUND_FLAG = 4,
CURRY_FLAG = 8,
CURRY_RIGHT_FLAG = 16,
PARTIAL_FLAG = 32,
PARTIAL_RIGHT_FLAG = 64,
ARY_FLAG = 128,
REARG_FLAG = 256,
FLIP_FLAG = 512;
/** Used as references for various `Number` constants. */
var INFINITY = 1 / 0,
MAX_SAFE_INTEGER = 9007199254740991,
MAX_INTEGER = 1.7976931348623157e+308,
NAN = 0 / 0;
/** Used to associate wrap methods with their bit flags. */
var wrapFlags = [
['ary', ARY_FLAG],
['bind', BIND_FLAG],
['bindKey', BIND_KEY_FLAG],
['curry', CURRY_FLAG],
['curryRight', CURRY_RIGHT_FLAG],
['flip', FLIP_FLAG],
['partial', PARTIAL_FLAG],
['partialRight', PARTIAL_RIGHT_FLAG],
['rearg', REARG_FLAG]
];
/** `Object#toString` result references. */
var funcTag = '[object Function]',
genTag = '[object GeneratorFunction]',
symbolTag = '[object Symbol]';
/**
* Used to match `RegExp`
* [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
*/
var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
/** Used to match leading and trailing whitespace. */
var reTrim = /^\s+|\s+$/g;
/** Used to match wrap detail comments. */
var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,
reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/,
reSplitDetails = /,? & /;
/** Used to detect bad signed hexadecimal string values. */
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
/** Used to detect binary string values. */
var reIsBinary = /^0b[01]+$/i;
/** Used to detect host constructors (Safari). */
var reIsHostCtor = /^\[object .+?Constructor\]$/;
/** Used to detect octal string values. */
var reIsOctal = /^0o[0-7]+$/i;
/** Used to detect unsigned integer values. */
var reIsUint = /^(?:0|[1-9]\d*)$/;
/** Built-in method references without a dependency on `root`. */
var freeParseInt = parseInt;
/** Detect free variable `global` from Node.js. */
var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
/** Detect free variable `self`. */
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
/** Used as a reference to the global object. */
var root = freeGlobal || freeSelf || Function('return this')();
/**
* A faster alternative to `Function#apply`, this function invokes `func`
* with the `this` binding of `thisArg` and the arguments of `args`.
*
* @private
* @param {Function} func The function to invoke.
* @param {*} thisArg The `this` binding of `func`.
* @param {Array} args The arguments to invoke `func` with.
* @returns {*} Returns the result of `func`.
*/
function apply(func, thisArg, args) {
switch (args.length) {
case 0: return func.call(thisArg);
case 1: return func.call(thisArg, args[0]);
case 2: return func.call(thisArg, args[0], args[1]);
case 3: return func.call(thisArg, args[0], args[1], args[2]);
}
return func.apply(thisArg, args);
}
/**
* A specialized version of `_.forEach` for arrays without support for
* iteratee shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array} Returns `array`.
*/
function arrayEach(array, iteratee) {
var index = -1,
length = array ? array.length : 0;
while (++index < length) {
if (iteratee(array[index], index, array) === false) {
break;
}
}
return array;
}
/**
* A specialized version of `_.includes` for arrays without support for
* specifying an index to search from.
*
* @private
* @param {Array} [array] The array to inspect.
* @param {*} target The value to search for.
* @returns {boolean} Returns `true` if `target` is found, else `false`.
*/
function arrayIncludes(array, value) {
var length = array ? array.length : 0;
return !!length && baseIndexOf(array, value, 0) > -1;
}
/**
* The base implementation of `_.findIndex` and `_.findLastIndex` without
* support for iteratee shorthands.
*
* @private
* @param {Array} array The array to inspect.
* @param {Function} predicate The function invoked per iteration.
* @param {number} fromIndex The index to search from.
* @param {boolean} [fromRight] Specify iterating from right to left.
* @returns {number} Returns the index of the matched value, else `-1`.
*/
function baseFindIndex(array, predicate, fromIndex, fromRight) {
var length = array.length,
index = fromIndex + (fromRight ? 1 : -1);
while ((fromRight ? index-- : ++index < length)) {
if (predicate(array[index], index, array)) {
return index;
}
}
return -1;
}
/**
* The base implementation of `_.indexOf` without `fromIndex` bounds checks.
*
* @private
* @param {Array} array The array to inspect.
* @param {*} value The value to search for.
* @param {number} fromIndex The index to search from.
* @returns {number} Returns the index of the matched value, else `-1`.
*/
function baseIndexOf(array, value, fromIndex) {
if (value !== value) {
return baseFindIndex(array, baseIsNaN, fromIndex);
}
var index = fromIndex - 1,
length = array.length;
while (++index < length) {
if (array[index] === value) {
return index;
}
}
return -1;
}
/**
* The base implementation of `_.isNaN` without support for number objects.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
*/
function baseIsNaN(value) {
return value !== value;
}
/**
* Gets the number of `placeholder` occurrences in `array`.
*
* @private
* @param {Array} array The array to inspect.
* @param {*} placeholder The placeholder to search for.
* @returns {number} Returns the placeholder count.
*/
function countHolders(array, placeholder) {
var length = array.length,
result = 0;
while (length--) {
if (array[length] === placeholder) {
result++;
}
}
return result;
}
/**
* Gets the value at `key` of `object`.
*
* @private
* @param {Object} [object] The object to query.
* @param {string} key The key of the property to get.
* @returns {*} Returns the property value.
*/
function getValue(object, key) {
return object == null ? undefined : object[key];
}
/**
* Checks if `value` is a host object in IE < 9.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a host object, else `false`.
*/
function isHostObject(value) {
// Many host objects are `Object` objects that can coerce to strings
// despite having improperly defined `toString` methods.
var result = false;
if (value != null && typeof value.toString != 'function') {
try {
result = !!(value + '');
} catch (e) {}
}
return result;
}
/**
* Replaces all `placeholder` elements in `array` with an internal placeholder
* and returns an array of their indexes.
*
* @private
* @param {Array} array The array to modify.
* @param {*} placeholder The placeholder to replace.
* @returns {Array} Returns the new array of placeholder indexes.
*/
function replaceHolders(array, placeholder) {
var index = -1,
length = array.length,
resIndex = 0,
result = [];
while (++index < length) {
var value = array[index];
if (value === placeholder || value === PLACEHOLDER) {
array[index] = PLACEHOLDER;
result[resIndex++] = index;
}
}
return result;
}
/** Used for built-in method references. */
var funcProto = Function.prototype,
objectProto = Object.prototype;
/** Used to detect overreaching core-js shims. */
var coreJsData = root['__core-js_shared__'];
/** Used to detect methods masquerading as native. */
var maskSrcKey = (function() {
var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
return uid ? ('Symbol(src)_1.' + uid) : '';
}());
/** Used to resolve the decompiled source of functions. */
var funcToString = funcProto.toString;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var objectToString = objectProto.toString;
/** Used to detect if a method is native. */
var reIsNative = RegExp('^' +
funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
.replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
);
/** Built-in value references. */
var objectCreate = Object.create;
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max,
nativeMin = Math.min;
/* Used to set `toString` methods. */
var defineProperty = (function() {
var func = getNative(Object, 'defineProperty'),
name = getNative.name;
return (name && name.length > 2) ? func : undefined;
}());
/**
* The base implementation of `_.create` without support for assigning
* properties to the created object.
*
* @private
* @param {Object} prototype The object to inherit from.
* @returns {Object} Returns the new object.
*/
function baseCreate(proto) {
return isObject(proto) ? objectCreate(proto) : {};
}
/**
* The base implementation of `_.isNative` without bad shim checks.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a native function,
* else `false`.
*/
function baseIsNative(value) {
if (!isObject(value) || isMasked(value)) {
return false;
}
var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;
return pattern.test(toSource(value));
}
/**
* Creates an array that is the composition of partially applied arguments,
* placeholders, and provided arguments into a single array of arguments.
*
* @private
* @param {Array} args The provided arguments.
* @param {Array} partials The arguments to prepend to those provided.
* @param {Array} holders The `partials` placeholder indexes.
* @params {boolean} [isCurried] Specify composing for a curried function.
* @returns {Array} Returns the new array of composed arguments.
*/
function composeArgs(args, partials, holders, isCurried) {
var argsIndex = -1,
argsLength = args.length,
holdersLength = holders.length,
leftIndex = -1,
leftLength = partials.length,
rangeLength = nativeMax(argsLength - holdersLength, 0),
result = Array(leftLength + rangeLength),
isUncurried = !isCurried;
while (++leftIndex < leftLength) {
result[leftIndex] = partials[leftIndex];
}
while (++argsIndex < holdersLength) {
if (isUncurried || argsIndex < argsLength) {
result[holders[argsIndex]] = args[argsIndex];
}
}
while (rangeLength--) {
result[leftIndex++] = args[argsIndex++];
}
return result;
}
/**
* This function is like `composeArgs` except that the arguments composition
* is tailored for `_.partialRight`.
*
* @private
* @param {Array} args The provided arguments.
* @param {Array} partials The arguments to append to those provided.
* @param {Array} holders The `partials` placeholder indexes.
* @params {boolean} [isCurried] Specify composing for a curried function.
* @returns {Array} Returns the new array of composed arguments.
*/
function composeArgsRight(args, partials, holders, isCurried) {
var argsIndex = -1,
argsLength = args.length,
holdersIndex = -1,
holdersLength = holders.length,
rightIndex = -1,
rightLength = partials.length,
rangeLength = nativeMax(argsLength - holdersLength, 0),
result = Array(rangeLength + rightLength),
isUncurried = !isCurried;
while (++argsIndex < rangeLength) {
result[argsIndex] = args[argsIndex];
}
var offset = argsIndex;
while (++rightIndex < rightLength) {
result[offset + rightIndex] = partials[rightIndex];
}
while (++holdersIndex < holdersLength) {
if (isUncurried || argsIndex < argsLength) {
result[offset + holders[holdersIndex]] = args[argsIndex++];
}
}
return result;
}
/**
* Copies the values of `source` to `array`.
*
* @private
* @param {Array} source The array to copy values from.
* @param {Array} [array=[]] The array to copy values to.
* @returns {Array} Returns `array`.
*/
function copyArray(source, array) {
var index = -1,
length = source.length;
array || (array = Array(length));
while (++index < length) {
array[index] = source[index];
}
return array;
}
/**
* Creates a function that wraps `func` to invoke it with the optional `this`
* binding of `thisArg`.
*
* @private
* @param {Function} func The function to wrap.
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
* @param {*} [thisArg] The `this` binding of `func`.
* @returns {Function} Returns the new wrapped function.
*/
function createBind(func, bitmask, thisArg) {
var isBind = bitmask & BIND_FLAG,
Ctor = createCtor(func);
function wrapper() {
var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
return fn.apply(isBind ? thisArg : this, arguments);
}
return wrapper;
}
/**
* Creates a function that produces an instance of `Ctor` regardless of
* whether it was invoked as part of a `new` expression or by `call` or `apply`.
*
* @private
* @param {Function} Ctor The constructor to wrap.
* @returns {Function} Returns the new wrapped function.
*/
function createCtor(Ctor) {
return function() {
// Use a `switch` statement to work with class constructors. See
// http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
// for more details.
var args = arguments;
switch (args.length) {
case 0: return new Ctor;
case 1: return new Ctor(args[0]);
case 2: return new Ctor(args[0], args[1]);
case 3: return new Ctor(args[0], args[1], args[2]);
case 4: return new Ctor(args[0], args[1], args[2], args[3]);
case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
}
var thisBinding = baseCreate(Ctor.prototype),
result = Ctor.apply(thisBinding, args);
// Mimic the constructor's `return` behavior.
// See https://es5.github.io/#x13.2.2 for more details.
return isObject(result) ? result : thisBinding;
};
}
/**
* Creates a function that wraps `func` to enable currying.
*
* @private
* @param {Function} func The function to wrap.
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
* @param {number} arity The arity of `func`.
* @returns {Function} Returns the new wrapped function.
*/
function createCurry(func, bitmask, arity) {
var Ctor = createCtor(func);
function wrapper() {
var length = arguments.length,
args = Array(length),
index = length,
placeholder = getHolder(wrapper);
while (index--) {
args[index] = arguments[index];
}
var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
? []
: replaceHolders(args, placeholder);
length -= holders.length;
if (length < arity) {
return createRecurry(
func, bitmask, createHybrid, wrapper.placeholder, undefined,
args, holders, undefined, undefined, arity - length);
}
var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
return apply(fn, this, args);
}
return wrapper;
}
/**
* Creates a function that wraps `func` to invoke it with optional `this`
* binding of `thisArg`, partial application, and currying.
*
* @private
* @param {Function|string} func The function or method name to wrap.
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
* @param {*} [thisArg] The `this` binding of `func`.
* @param {Array} [partials] The arguments to prepend to those provided to
* the new function.
* @param {Array} [holders] The `partials` placeholder indexes.
* @param {Array} [partialsRight] The arguments to append to those provided
* to the new function.
* @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
* @param {Array} [argPos] The argument positions of the new function.
* @param {number} [ary] The arity cap of `func`.
* @param {number} [arity] The arity of `func`.
* @returns {Function} Returns the new wrapped function.
*/
function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
var isAry = bitmask & ARY_FLAG,
isBind = bitmask & BIND_FLAG,
isBindKey = bitmask & BIND_KEY_FLAG,
isCurried = bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG),
isFlip = bitmask & FLIP_FLAG,
Ctor = isBindKey ? undefined : createCtor(func);
function wrapper() {
var length = arguments.length,
args = Array(length),
index = length;
while (index--) {
args[index] = arguments[index];
}
if (isCurried) {
var placeholder = getHolder(wrapper),
holdersCount = countHolders(args, placeholder);
}
if (partials) {
args = composeArgs(args, partials, holders, isCurried);
}
if (partialsRight) {
args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
}
length -= holdersCount;
if (isCurried && length < arity) {
var newHolders = replaceHolders(args, placeholder);
return createRecurry(
func, bitmask, createHybrid, wrapper.placeholder, thisArg,
args, newHolders, argPos, ary, arity - length
);
}
var thisBinding = isBind ? thisArg : this,
fn = isBindKey ? thisBinding[func] : func;
length = args.length;
if (argPos) {
args = reorder(args, argPos);
} else if (isFlip && length > 1) {
args.reverse();
}
if (isAry && ary < length) {
args.length = ary;
}
if (this && this !== root && this instanceof wrapper) {
fn = Ctor || createCtor(fn);
}
return fn.apply(thisBinding, args);
}
return wrapper;
}
/**
* Creates a function that wraps `func` to invoke it with the `this` binding
* of `thisArg` and `partials` prepended to the arguments it receives.
*
* @private
* @param {Function} func The function to wrap.
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
* @param {*} thisArg The `this` binding of `func`.
* @param {Array} partials The arguments to prepend to those provided to
* the new function.
* @returns {Function} Returns the new wrapped function.
*/
function createPartial(func, bitmask, thisArg, partials) {
var isBind = bitmask & BIND_FLAG,
Ctor = createCtor(func);
function wrapper() {
var argsIndex = -1,
argsLength = arguments.length,
leftIndex = -1,
leftLength = partials.length,
args = Array(leftLength + argsLength),
fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
while (++leftIndex < leftLength) {
args[leftIndex] = partials[leftIndex];
}
while (argsLength--) {
args[leftIndex++] = arguments[++argsIndex];
}
return apply(fn, isBind ? thisArg : this, args);
}
return wrapper;
}
/**
* Creates a function that wraps `func` to continue currying.
*
* @private
* @param {Function} func The function to wrap.
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
* @param {Function} wrapFunc The function to create the `func` wrapper.
* @param {*} placeholder The placeholder value.
* @param {*} [thisArg] The `this` binding of `func`.
* @param {Array} [partials] The arguments to prepend to those provided to
* the new function.
* @param {Array} [holders] The `partials` placeholder indexes.
* @param {Array} [argPos] The argument positions of the new function.
* @param {number} [ary] The arity cap of `func`.
* @param {number} [arity] The arity of `func`.
* @returns {Function} Returns the new wrapped function.
*/
function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
var isCurry = bitmask & CURRY_FLAG,
newHolders = isCurry ? holders : undefined,
newHoldersRight = isCurry ? undefined : holders,
newPartials = isCurry ? partials : undefined,
newPartialsRight = isCurry ? undefined : partials;
bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);
if (!(bitmask & CURRY_BOUND_FLAG)) {
bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
}
var result = wrapFunc(func, bitmask, thisArg, newPartials, newHolders, newPartialsRight, newHoldersRight, argPos, ary, arity);
result.placeholder = placeholder;
return setWrapToString(result, func, bitmask);
}
/**
* Creates a function that either curries or invokes `func` with optional
* `this` binding and partially applied arguments.
*
* @private
* @param {Function|string} func The function or method name to wrap.
* @param {number} bitmask The bitmask flags.
* The bitmask may be composed of the following flags:
* 1 - `_.bind`
* 2 - `_.bindKey`
* 4 - `_.curry` or `_.curryRight` of a bound function
* 8 - `_.curry`
* 16 - `_.curryRight`
* 32 - `_.partial`
* 64 - `_.partialRight`
* 128 - `_.rearg`
* 256 - `_.ary`
* 512 - `_.flip`
* @param {*} [thisArg] The `this` binding of `func`.
* @param {Array} [partials] The arguments to be partially applied.
* @param {Array} [holders] The `partials` placeholder indexes.
* @param {Array} [argPos] The argument positions of the new function.
* @param {number} [ary] The arity cap of `func`.
* @param {number} [arity] The arity of `func`.
* @returns {Function} Returns the new wrapped function.
*/
function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
var isBindKey = bitmask & BIND_KEY_FLAG;
if (!isBindKey && typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
var length = partials ? partials.length : 0;
if (!length) {
bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
partials = holders = undefined;
}
ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
arity = arity === undefined ? arity : toInteger(arity);
length -= holders ? holders.length : 0;
if (bitmask & PARTIAL_RIGHT_FLAG) {
var partialsRight = partials,
holdersRight = holders;
partials = holders = undefined;
}
var newData = [
func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
argPos, ary, arity
];
func = newData[0];
bitmask = newData[1];
thisArg = newData[2];
partials = newData[3];
holders = newData[4];
arity = newData[9] = newData[9] == null
? (isBindKey ? 0 : func.length)
: nativeMax(newData[9] - length, 0);
if (!arity && bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG)) {
bitmask &= ~(CURRY_FLAG | CURRY_RIGHT_FLAG);
}
if (!bitmask || bitmask == BIND_FLAG) {
var result = createBind(func, bitmask, thisArg);
} else if (bitmask == CURRY_FLAG || bitmask == CURRY_RIGHT_FLAG) {
result = createCurry(func, bitmask, arity);
} else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !holders.length) {
result = createPartial(func, bitmask, thisArg, partials);
} else {
result = createHybrid.apply(undefined, newData);
}
return setWrapToString(result, func, bitmask);
}
/**
* Gets the argument placeholder value for `func`.
*
* @private
* @param {Function} func The function to inspect.
* @returns {*} Returns the placeholder value.
*/
function getHolder(func) {
var object = func;
return object.placeholder;
}
/**
* Gets the native function at `key` of `object`.
*
* @private
* @param {Object} object The object to query.
* @param {string} key The key of the method to get.
* @returns {*} Returns the function if it's native, else `undefined`.
*/
function getNative(object, key) {
var value = getValue(object, key);
return baseIsNative(value) ? value : undefined;
}
/**
* Extracts wrapper details from the `source` body comment.
*
* @private
* @param {string} source The source to inspect.
* @returns {Array} Returns the wrapper details.
*/
function getWrapDetails(source) {
var match = source.match(reWrapDetails);
return match ? match[1].split(reSplitDetails) : [];
}
/**
* Inserts wrapper `details` in a comment at the top of the `source` body.
*
* @private
* @param {string} source The source to modify.
* @returns {Array} details The details to insert.
* @returns {string} Returns the modified source.
*/
function insertWrapDetails(source, details) {
var length = details.length,
lastIndex = length - 1;
details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
details = details.join(length > 2 ? ', ' : ' ');
return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
}
/**
* Checks if `value` is a valid array-like index.
*
* @private
* @param {*} value The value to check.
* @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
* @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
*/
function isIndex(value, length) {
length = length == null ? MAX_SAFE_INTEGER : length;
return !!length &&
(typeof value == 'number' || reIsUint.test(value)) &&
(value > -1 && value % 1 == 0 && value < length);
}
/**
* Checks if `func` has its source masked.
*
* @private
* @param {Function} func The function to check.
* @returns {boolean} Returns `true` if `func` is masked, else `false`.
*/
function isMasked(func) {
return !!maskSrcKey && (maskSrcKey in func);
}
/**
* Reorder `array` according to the specified indexes where the element at
* the first index is assigned as the first element, the element at
* the second index is assigned as the second element, and so on.
*
* @private
* @param {Array} array The array to reorder.
* @param {Array} indexes The arranged array indexes.
* @returns {Array} Returns `array`.
*/
function reorder(array, indexes) {
var arrLength = array.length,
length = nativeMin(indexes.length, arrLength),
oldArray = copyArray(array);
while (length--) {
var index = indexes[length];
array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
}
return array;
}
/**
* Sets the `toString` method of `wrapper` to mimic the source of `reference`
* with wrapper details in a comment at the top of the source body.
*
* @private
* @param {Function} wrapper The function to modify.
* @param {Function} reference The reference function.
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
* @returns {Function} Returns `wrapper`.
*/
var setWrapToString = !defineProperty ? identity : function(wrapper, reference, bitmask) {
var source = (reference + '');
return defineProperty(wrapper, 'toString', {
'configurable': true,
'enumerable': false,
'value': constant(insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)))
});
};
/**
* Converts `func` to its source code.
*
* @private
* @param {Function} func The function to process.
* @returns {string} Returns the source code.
*/
function toSource(func) {
if (func != null) {
try {
return funcToString.call(func);
} catch (e) {}
try {
return (func + '');
} catch (e) {}
}
return '';
}
/**
* Updates wrapper `details` based on `bitmask` flags.
*
* @private
* @returns {Array} details The details to modify.
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
* @returns {Array} Returns `details`.
*/
function updateWrapDetails(details, bitmask) {
arrayEach(wrapFlags, function(pair) {
var value = '_.' + pair[0];
if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
details.push(value);
}
});
return details.sort();
}
/**
* Creates a function that accepts arguments of `func` and either invokes
* `func` returning its result, if at least `arity` number of arguments have
* been provided, or returns a function that accepts the remaining `func`
* arguments, and so on. The arity of `func` may be specified if `func.length`
* is not sufficient.
*
* The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
* may be used as a placeholder for provided arguments.
*
* **Note:** This method doesn't set the "length" property of curried functions.
*
* @static
* @memberOf _
* @since 2.0.0
* @category Function
* @param {Function} func The function to curry.
* @param {number} [arity=func.length] The arity of `func`.
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
* @returns {Function} Returns the new curried function.
* @example
*
* var abc = function(a, b, c) {
* return [a, b, c];
* };
*
* var curried = _.curry(abc);
*
* curried(1)(2)(3);
* // => [1, 2, 3]
*
* curried(1, 2)(3);
* // => [1, 2, 3]
*
* curried(1, 2, 3);
* // => [1, 2, 3]
*
* // Curried with placeholders.
* curried(1)(_, 3)(2);
* // => [1, 2, 3]
*/
function curry(func, arity, guard) {
arity = guard ? undefined : arity;
var result = createWrap(func, CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
result.placeholder = curry.placeholder;
return result;
}
/**
* Checks if `value` is classified as a `Function` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a function, else `false`.
* @example
*
* _.isFunction(_);
* // => true
*
* _.isFunction(/abc/);
* // => false
*/
function isFunction(value) {
// The use of `Object#toString` avoids issues with the `typeof` operator
// in Safari 8-9 which returns 'object' for typed array and other constructors.
var tag = isObject(value) ? objectToString.call(value) : '';
return tag == funcTag || tag == genTag;
}
/**
* Checks if `value` is the
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
* @example
*
* _.isObject({});
* // => true
*
* _.isObject([1, 2, 3]);
* // => true
*
* _.isObject(_.noop);
* // => true
*
* _.isObject(null);
* // => false
*/
function isObject(value) {
var type = typeof value;
return !!value && (type == 'object' || type == 'function');
}
/**
* Checks if `value` is object-like. A value is object-like if it's not `null`
* and has a `typeof` result of "object".
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
* @example
*
* _.isObjectLike({});
* // => true
*
* _.isObjectLike([1, 2, 3]);
* // => true
*
* _.isObjectLike(_.noop);
* // => false
*
* _.isObjectLike(null);
* // => false
*/
function isObjectLike(value) {
return !!value && typeof value == 'object';
}
/**
* Checks if `value` is classified as a `Symbol` primitive or object.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
* @example
*
* _.isSymbol(Symbol.iterator);
* // => true
*
* _.isSymbol('abc');
* // => false
*/
function isSymbol(value) {
return typeof value == 'symbol' ||
(isObjectLike(value) && objectToString.call(value) == symbolTag);
}
/**
* Converts `value` to a finite number.
*
* @static
* @memberOf _
* @since 4.12.0
* @category Lang
* @param {*} value The value to convert.
* @returns {number} Returns the converted number.
* @example
*
* _.toFinite(3.2);
* // => 3.2
*
* _.toFinite(Number.MIN_VALUE);
* // => 5e-324
*
* _.toFinite(Infinity);
* // => 1.7976931348623157e+308
*
* _.toFinite('3.2');
* // => 3.2
*/
function toFinite(value) {
if (!value) {
return value === 0 ? value : 0;
}
value = toNumber(value);
if (value === INFINITY || value === -INFINITY) {
var sign = (value < 0 ? -1 : 1);
return sign * MAX_INTEGER;
}
return value === value ? value : 0;
}
/**
* Converts `value` to an integer.
*
* **Note:** This method is loosely based on
* [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to convert.
* @returns {number} Returns the converted integer.
* @example
*
* _.toInteger(3.2);
* // => 3
*
* _.toInteger(Number.MIN_VALUE);
* // => 0
*
* _.toInteger(Infinity);
* // => 1.7976931348623157e+308
*
* _.toInteger('3.2');
* // => 3
*/
function toInteger(value) {
var result = toFinite(value),
remainder = result % 1;
return result === result ? (remainder ? result - remainder : result) : 0;
}
/**
* Converts `value` to a number.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to process.
* @returns {number} Returns the number.
* @example
*
* _.toNumber(3.2);
* // => 3.2
*
* _.toNumber(Number.MIN_VALUE);
* // => 5e-324
*
* _.toNumber(Infinity);
* // => Infinity
*
* _.toNumber('3.2');
* // => 3.2
*/
function toNumber(value) {
if (typeof value == 'number') {
return value;
}
if (isSymbol(value)) {
return NAN;
}
if (isObject(value)) {
var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
value = isObject(other) ? (other + '') : other;
}
if (typeof value != 'string') {
return value === 0 ? value : +value;
}
value = value.replace(reTrim, '');
var isBinary = reIsBinary.test(value);
return (isBinary || reIsOctal.test(value))
? freeParseInt(value.slice(2), isBinary ? 2 : 8)
: (reIsBadHex.test(value) ? NAN : +value);
}
/**
* Creates a function that returns `value`.
*
* @static
* @memberOf _
* @since 2.4.0
* @category Util
* @param {*} value The value to return from the new function.
* @returns {Function} Returns the new constant function.
* @example
*
* var objects = _.times(2, _.constant({ 'a': 1 }));
*
* console.log(objects);
* // => [{ 'a': 1 }, { 'a': 1 }]
*
* console.log(objects[0] === objects[1]);
* // => true
*/
function constant(value) {
return function() {
return value;
};
}
/**
* This method returns the first argument it receives.
*
* @static
* @since 0.1.0
* @memberOf _
* @category Util
* @param {*} value Any value.
* @returns {*} Returns `value`.
* @example
*
* var object = { 'a': 1 };
*
* console.log(_.identity(object) === object);
* // => true
*/
function identity(value) {
return value;
}
// Assign default placeholders.
curry.placeholder = {};
module.exports = curry;
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(190)))
/***/ }),
/* 239 */
/***/ (function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global) {/**
* lodash (Custom Build) <https://lodash.com/>
* Build: `lodash modularize exports="npm" -o ./`
* Copyright jQuery Foundation and other contributors <https://jquery.org/>
* Released under MIT license <https://lodash.com/license>
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
*/
/** Used as the `TypeError` message for "Functions" methods. */
var FUNC_ERROR_TEXT = 'Expected a function';
/** Used as references for various `Number` constants. */
var MAX_SAFE_INTEGER = 9007199254740991;
/** `Object#toString` result references. */
var argsTag = '[object Arguments]',
funcTag = '[object Function]',
genTag = '[object GeneratorFunction]';
/** Detect free variable `global` from Node.js. */
var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
/** Detect free variable `self`. */
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
/** Used as a reference to the global object. */
var root = freeGlobal || freeSelf || Function('return this')();
/**
* A faster alternative to `Function#apply`, this function invokes `func`
* with the `this` binding of `thisArg` and the arguments of `args`.
*
* @private
* @param {Function} func The function to invoke.
* @param {*} thisArg The `this` binding of `func`.
* @param {Array} args The arguments to invoke `func` with.
* @returns {*} Returns the result of `func`.
*/
function apply(func, thisArg, args) {
switch (args.length) {
case 0: return func.call(thisArg);
case 1: return func.call(thisArg, args[0]);
case 2: return func.call(thisArg, args[0], args[1]);
case 3: return func.call(thisArg, args[0], args[1], args[2]);
}
return func.apply(thisArg, args);
}
/**
* Appends the elements of `values` to `array`.
*
* @private
* @param {Array} array The array to modify.
* @param {Array} values The values to append.
* @returns {Array} Returns `array`.
*/
function arrayPush(array, values) {
var index = -1,
length = values.length,
offset = array.length;
while (++index < length) {
array[offset + index] = values[index];
}
return array;
}
/** Used for built-in method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var objectToString = objectProto.toString;
/** Built-in value references. */
var Symbol = root.Symbol,
propertyIsEnumerable = objectProto.propertyIsEnumerable,
spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined;
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max;
/**
* The base implementation of `_.flatten` with support for restricting flattening.
*
* @private
* @param {Array} array The array to flatten.
* @param {number} depth The maximum recursion depth.
* @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
* @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
* @param {Array} [result=[]] The initial result value.
* @returns {Array} Returns the new flattened array.
*/
function baseFlatten(array, depth, predicate, isStrict, result) {
var index = -1,
length = array.length;
predicate || (predicate = isFlattenable);
result || (result = []);
while (++index < length) {
var value = array[index];
if (depth > 0 && predicate(value)) {
if (depth > 1) {
// Recursively flatten arrays (susceptible to call stack limits).
baseFlatten(value, depth - 1, predicate, isStrict, result);
} else {
arrayPush(result, value);
}
} else if (!isStrict) {
result[result.length] = value;
}
}
return result;
}
/**
* The base implementation of `_.rest` which doesn't validate or coerce arguments.
*
* @private
* @param {Function} func The function to apply a rest parameter to.
* @param {number} [start=func.length-1] The start position of the rest parameter.
* @returns {Function} Returns the new function.
*/
function baseRest(func, start) {
start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
return function() {
var args = arguments,
index = -1,
length = nativeMax(args.length - start, 0),
array = Array(length);
while (++index < length) {
array[index] = args[start + index];
}
index = -1;
var otherArgs = Array(start + 1);
while (++index < start) {
otherArgs[index] = args[index];
}
otherArgs[start] = array;
return apply(func, this, otherArgs);
};
}
/**
* Creates a `_.flow` or `_.flowRight` function.
*
* @private
* @param {boolean} [fromRight] Specify iterating from right to left.
* @returns {Function} Returns the new flow function.
*/
function createFlow(fromRight) {
return baseRest(function(funcs) {
funcs = baseFlatten(funcs, 1);
var length = funcs.length,
index = length;
if (fromRight) {
funcs.reverse();
}
while (index--) {
if (typeof funcs[index] != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
}
return function() {
var index = 0,
result = length ? funcs[index].apply(this, arguments) : arguments[0];
while (++index < length) {
result = funcs[index].call(this, result);
}
return result;
};
});
}
/**
* Checks if `value` is a flattenable `arguments` object or array.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
*/
function isFlattenable(value) {
return isArray(value) || isArguments(value) ||
!!(spreadableSymbol && value && value[spreadableSymbol]);
}
/**
* Checks if `value` is likely an `arguments` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an `arguments` object,
* else `false`.
* @example
*
* _.isArguments(function() { return arguments; }());
* // => true
*
* _.isArguments([1, 2, 3]);
* // => false
*/
function isArguments(value) {
// Safari 8.1 makes `arguments.callee` enumerable in strict mode.
return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
(!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
}
/**
* Checks if `value` is classified as an `Array` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an array, else `false`.
* @example
*
* _.isArray([1, 2, 3]);
* // => true
*
* _.isArray(document.body.children);
* // => false
*
* _.isArray('abc');
* // => false
*
* _.isArray(_.noop);
* // => false
*/
var isArray = Array.isArray;
/**
* Checks if `value` is array-like. A value is considered array-like if it's
* not a function and has a `value.length` that's an integer greater than or
* equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is array-like, else `false`.
* @example
*
* _.isArrayLike([1, 2, 3]);
* // => true
*
* _.isArrayLike(document.body.children);
* // => true
*
* _.isArrayLike('abc');
* // => true
*
* _.isArrayLike(_.noop);
* // => false
*/
function isArrayLike(value) {
return value != null && isLength(value.length) && !isFunction(value);
}
/**
* This method is like `_.isArrayLike` except that it also checks if `value`
* is an object.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an array-like object,
* else `false`.
* @example
*
* _.isArrayLikeObject([1, 2, 3]);
* // => true
*
* _.isArrayLikeObject(document.body.children);
* // => true
*
* _.isArrayLikeObject('abc');
* // => false
*
* _.isArrayLikeObject(_.noop);
* // => false
*/
function isArrayLikeObject(value) {
return isObjectLike(value) && isArrayLike(value);
}
/**
* Checks if `value` is classified as a `Function` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a function, else `false`.
* @example
*
* _.isFunction(_);
* // => true
*
* _.isFunction(/abc/);
* // => false
*/
function isFunction(value) {
// The use of `Object#toString` avoids issues with the `typeof` operator
// in Safari 8-9 which returns 'object' for typed array and other constructors.
var tag = isObject(value) ? objectToString.call(value) : '';
return tag == funcTag || tag == genTag;
}
/**
* Checks if `value` is a valid array-like length.
*
* **Note:** This method is loosely based on
* [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
* @example
*
* _.isLength(3);
* // => true
*
* _.isLength(Number.MIN_VALUE);
* // => false
*
* _.isLength(Infinity);
* // => false
*
* _.isLength('3');
* // => false
*/
function isLength(value) {
return typeof value == 'number' &&
value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
}
/**
* Checks if `value` is the
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
* @example
*
* _.isObject({});
* // => true
*
* _.isObject([1, 2, 3]);
* // => true
*
* _.isObject(_.noop);
* // => true
*
* _.isObject(null);
* // => false
*/
function isObject(value) {
var type = typeof value;
return !!value && (type == 'object' || type == 'function');
}
/**
* Checks if `value` is object-like. A value is object-like if it's not `null`
* and has a `typeof` result of "object".
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
* @example
*
* _.isObjectLike({});
* // => true
*
* _.isObjectLike([1, 2, 3]);
* // => true
*
* _.isObjectLike(_.noop);
* // => false
*
* _.isObjectLike(null);
* // => false
*/
function isObjectLike(value) {
return !!value && typeof value == 'object';
}
/**
* This method is like `_.flow` except that it creates a function that
* invokes the given functions from right to left.
*
* @static
* @since 3.0.0
* @memberOf _
* @category Util
* @param {...(Function|Function[])} [funcs] The functions to invoke.
* @returns {Function} Returns the new composite function.
* @see _.flow
* @example
*
* function square(n) {
* return n * n;
* }
*
* var addSquare = _.flowRight([square, _.add]);
* addSquare(1, 2);
* // => 9
*/
var flowRight = createFlow(true);
module.exports = flowRight;
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(190)))
/***/ }),
/* 240 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _desc, _value, _class;
var _react = __webpack_require__(11);
var _react2 = _interopRequireDefault(_react);
var _propTypes = __webpack_require__(25);
var _propTypes2 = _interopRequireDefault(_propTypes);
var _autobindDecorator = __webpack_require__(89);
var _autobindDecorator2 = _interopRequireDefault(_autobindDecorator);
var _classnames = __webpack_require__(84);
var _classnames2 = _interopRequireDefault(_classnames);
var _composers = __webpack_require__(88);
var _RangeControlOverlay = __webpack_require__(197);
var _RangeControlOverlay2 = _interopRequireDefault(_RangeControlOverlay);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
var desc = {};
Object['ke' + 'ys'](descriptor).forEach(function (key) {
desc[key] = descriptor[key];
});
desc.enumerable = !!desc.enumerable;
desc.configurable = !!desc.configurable;
if ('value' in desc || desc.initializer) {
desc.writable = true;
}
desc = decorators.slice().reverse().reduce(function (desc, decorator) {
return decorator(target, property, desc) || desc;
}, desc);
if (context && desc.initializer !== void 0) {
desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
desc.initializer = undefined;
}
if (desc.initializer === void 0) {
Object['define' + 'Property'](target, property, desc);
desc = null;
}
return desc;
}
var number = _propTypes2.default.number,
bool = _propTypes2.default.bool,
func = _propTypes2.default.func,
object = _propTypes2.default.object;
/**
* Seekable progress bar
*
* TODO: Make use of the range input element?
*/
var ProgressBar = (_class = function (_Component) {
_inherits(ProgressBar, _Component);
function ProgressBar(props) {
_classCallCheck(this, ProgressBar);
var _this = _possibleConstructorReturn(this, (ProgressBar.__proto__ || Object.getPrototypeOf(ProgressBar)).call(this, props));
_this.progressBarEl = null;
_this.state = {
currentIntent: 0
};
return _this;
}
_createClass(ProgressBar, [{
key: 'storeRef',
value: function storeRef(rootEl) {
this.progressBarEl = rootEl;
}
}, {
key: 'handleSeek',
value: function handleSeek(relativeTime) {
var _props = this.props,
isSeekable = _props.isSeekable,
onSeek = _props.onSeek,
totalTime = _props.totalTime;
if (isSeekable) {
onSeek(relativeTime * totalTime);
}
}
}, {
key: 'handleSeekStart',
value: function handleSeekStart(relativeTime) {
var _props2 = this.props,
isSeekable = _props2.isSeekable,
onSeekStart = _props2.onSeekStart,
totalTime = _props2.totalTime;
if (isSeekable) {
onSeekStart(relativeTime * totalTime);
}
}
}, {
key: 'handleSeekEnd',
value: function handleSeekEnd(relativeTime) {
var _props3 = this.props,
isSeekable = _props3.isSeekable,
onSeekEnd = _props3.onSeekEnd,
totalTime = _props3.totalTime;
if (isSeekable) {
onSeekEnd(relativeTime * totalTime);
}
}
}, {
key: 'handleIntent',
value: function handleIntent(relativeTime) {
var _props4 = this.props,
isSeekable = _props4.isSeekable,
onIntent = _props4.onIntent,
totalTime = _props4.totalTime;
var intent = isSeekable ? relativeTime : 0;
this.setState(_extends({}, this.state, {
currentIntent: intent
}));
if (isSeekable) {
onIntent(relativeTime * totalTime);
}
}
}, {
key: 'render',
value: function render() {
var _this2 = this;
var _props5 = this.props,
totalTime = _props5.totalTime,
currentTime = _props5.currentTime,
isSeekable = _props5.isSeekable,
className = _props5.className,
extraClasses = _props5.extraClasses,
childClasses = _props5.childClasses,
style = _props5.style,
childrenStyles = _props5.childrenStyles;
var currentIntent = this.state.currentIntent;
var progressPercent = Math.min(100, 100 * currentTime / totalTime);
var styleLeft = progressPercent + '%';
var isRewindIntent = currentIntent !== 0 && currentIntent < currentTime / totalTime;
return _react2.default.createElement(
'div',
{
className: (0, _classnames2.default)(className, extraClasses, {
isSeekable: isSeekable,
isRewindIntent: isRewindIntent
}),
style: style,
ref: this.storeRef
},
_react2.default.createElement('div', {
className: childClasses.elapsed || 'ProgressBar-elapsed',
style: _extends({ width: styleLeft }, childrenStyles.elapsed || {})
}),
_react2.default.createElement('div', {
className: childClasses.intent || 'ProgressBar-intent',
style: _extends({ width: currentIntent * 100 + '%' }, childrenStyles.intent || {})
}),
_react2.default.createElement('div', {
className: childClasses.handle || 'ProgressBar-handle',
style: _extends({ left: styleLeft }, childrenStyles.handle || {})
}),
isSeekable && _react2.default.createElement(_RangeControlOverlay2.default, {
className: childClasses.seek || 'ProgressBar-seek',
style: childrenStyles.RangeControlOverlay,
bounds: function bounds() {
return _this2.progressBarEl.getBoundingClientRect();
},
onValue: this.handleSeek,
onChangeStart: this.handleSeekStart,
onChangeEnd: this.handleSeekEnd,
onIntent: this.handleIntent
})
);
}
}]);
return ProgressBar;
}(_react.Component), (_applyDecoratedDescriptor(_class.prototype, 'storeRef', [_autobindDecorator2.default], Object.getOwnPropertyDescriptor(_class.prototype, 'storeRef'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'handleSeek', [_autobindDecorator2.default], Object.getOwnPropertyDescriptor(_class.prototype, 'handleSeek'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'handleSeekStart', [_autobindDecorator2.default], Object.getOwnPropertyDescriptor(_class.prototype, 'handleSeekStart'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'handleSeekEnd', [_autobindDecorator2.default], Object.getOwnPropertyDescriptor(_class.prototype, 'handleSeekEnd'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'handleIntent', [_autobindDecorator2.default], Object.getOwnPropertyDescriptor(_class.prototype, 'handleIntent'), _class.prototype)), _class);
ProgressBar.propTypes = {
totalTime: number,
currentTime: number,
isSeekable: bool,
onSeek: func,
onSeekStart: func,
onSeekEnd: func,
onIntent: func,
style: object
};
ProgressBar.defaultProps = {
totalTime: Infinity,
currentTime: 0,
isSeekable: false,
onSeek: function onSeek() {},
onSeekStart: function onSeekStart() {},
onSeekEnd: function onSeekEnd() {},
onIntent: function onIntent() {},
style: {}
};
exports.default = (0, _composers.compose)((0, _composers.withChildrenStyles)(), (0, _composers.withCustomizableClasses)('ProgressBar'), (0, _composers.withChildClasses)())(ProgressBar);
/***/ }),
/* 241 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.TimeMarkerType = undefined;
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(11);
var _react2 = _interopRequireDefault(_react);
var _propTypes = __webpack_require__(25);
var _propTypes2 = _interopRequireDefault(_propTypes);
var _classnames = __webpack_require__(84);
var _classnames2 = _interopRequireDefault(_classnames);
var _collections = __webpack_require__(242);
var _composers = __webpack_require__(88);
var _FormattedTime = __webpack_require__(198);
var _FormattedTime2 = _interopRequireDefault(_FormattedTime);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var number = _propTypes2.default.number,
oneOf = _propTypes2.default.oneOf,
string = _propTypes2.default.string,
object = _propTypes2.default.object;
/**
* Time marker types
*/
var TimeMarkerType = exports.TimeMarkerType = {
ELAPSED: 'ELAPSED',
LEFT: 'LEFT',
LEFT_NEGATIVE: 'LEFT_NEGATIVE',
DURATION: 'DURATION'
/**
* Composite component showing current and total time
*/
};
var TimeMarker = function (_Component) {
_inherits(TimeMarker, _Component);
function TimeMarker() {
_classCallCheck(this, TimeMarker);
return _possibleConstructorReturn(this, (TimeMarker.__proto__ || Object.getPrototypeOf(TimeMarker)).apply(this, arguments));
}
_createClass(TimeMarker, [{
key: 'getSecondsForTimeWithMarkerType',
value: function getSecondsForTimeWithMarkerType(markerType) {
var _props = this.props,
currentTime = _props.currentTime,
totalTime = _props.totalTime;
if (markerType === TimeMarkerType.DURATION) {
return totalTime;
} else if (markerType === TimeMarkerType.ELAPSED) {
return currentTime;
} else if (markerType === TimeMarkerType.LEFT) {
return totalTime - currentTime;
} else if (markerType === TimeMarkerType.LEFT_NEGATIVE) {
return currentTime - totalTime;
}
return 0;
}
}, {
key: 'render',
value: function render() {
var _props2 = this.props,
firstMarkerType = _props2.firstMarkerType,
secondMarkerType = _props2.secondMarkerType,
markerSeparator = _props2.markerSeparator,
className = _props2.className,
extraClasses = _props2.extraClasses,
childClasses = _props2.childClasses,
style = _props2.style,
childrenStyles = _props2.childrenStyles;
var seconds1 = this.getSecondsForTimeWithMarkerType(firstMarkerType);
var seconds2 = this.getSecondsForTimeWithMarkerType(secondMarkerType);
return _react2.default.createElement(
'div',
{
className: (0, _classnames2.default)(className, extraClasses),
style: style
},
_react2.default.createElement(_FormattedTime2.default, {
numSeconds: seconds1,
extraClasses: (0, _classnames2.default)('TimeMarker-firstMarker', childClasses.firstMarker),
style: childrenStyles.firstMarker
}),
markerSeparator && _react2.default.createElement(
'span',
{
className: (0, _classnames2.default)('TimeMarker-separator', childClasses.separator),
style: childrenStyles.separator
},
markerSeparator
),
_react2.default.createElement(_FormattedTime2.default, {
numSeconds: seconds2,
extraClasses: (0, _classnames2.default)('TimeMarker-secondMarker', childClasses.secondMarker),
style: childrenStyles.secondMarker
})
);
}
}]);
return TimeMarker;
}(_react.Component);
TimeMarker.propTypes = {
totalTime: number,
currentTime: number,
firstMarkerType: oneOf((0, _collections.values)(TimeMarkerType)),
secondMarkerType: oneOf((0, _collections.values)(TimeMarkerType)),
markerSeparator: string,
style: object
};
TimeMarker.defaultProps = {
totalTime: Infinity,
currentTime: 0,
firstMarkerType: TimeMarkerType.ELAPSED,
secondMarkerType: TimeMarkerType.DURATION,
markerSeparator: null,
style: {}
};
exports.default = (0, _composers.compose)((0, _composers.withChildrenStyles)(), (0, _composers.withCustomizableClasses)('TimeMarker'), (0, _composers.withChildClasses)())(TimeMarker);
/***/ }),
/* 242 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
/**
* Returns an array containing the values of an object literal
*/
var values = exports.values = function values(obj) {
return Object.keys(obj).map(function (k) {
return obj[k];
});
};
/***/ }),
/* 243 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _desc, _value, _class;
var _react = __webpack_require__(11);
var _react2 = _interopRequireDefault(_react);
var _propTypes = __webpack_require__(25);
var _propTypes2 = _interopRequireDefault(_propTypes);
var _classnames = __webpack_require__(84);
var _classnames2 = _interopRequireDefault(_classnames);
var _autobindDecorator = __webpack_require__(89);
var _autobindDecorator2 = _interopRequireDefault(_autobindDecorator);
var _composers = __webpack_require__(88);
var _SoundOnButton = __webpack_require__(199);
var _SoundOnButton2 = _interopRequireDefault(_SoundOnButton);
var _SoundOffButton = __webpack_require__(200);
var _SoundOffButton2 = _interopRequireDefault(_SoundOffButton);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
var desc = {};
Object['ke' + 'ys'](descriptor).forEach(function (key) {
desc[key] = descriptor[key];
});
desc.enumerable = !!desc.enumerable;
desc.configurable = !!desc.configurable;
if ('value' in desc || desc.initializer) {
desc.writable = true;
}
desc = decorators.slice().reverse().reduce(function (desc, decorator) {
return decorator(target, property, desc) || desc;
}, desc);
if (context && desc.initializer !== void 0) {
desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
desc.initializer = undefined;
}
if (desc.initializer === void 0) {
Object['define' + 'Property'](target, property, desc);
desc = null;
}
return desc;
}
/**
* Mute toggle button
*/
var MuteToggleButton = (_class = function (_Component) {
_inherits(MuteToggleButton, _Component);
function MuteToggleButton() {
_classCallCheck(this, MuteToggleButton);
return _possibleConstructorReturn(this, (MuteToggleButton.__proto__ || Object.getPrototypeOf(MuteToggleButton)).apply(this, arguments));
}
_createClass(MuteToggleButton, [{
key: 'handleMuteChange',
value: function handleMuteChange(isMuted) {
if (this.props.isEnabled) {
this.props.onMuteChange(isMuted);
}
}
}, {
key: 'render',
value: function render() {
var _this2 = this;
var _props = this.props,
isMuted = _props.isMuted,
isEnabled = _props.isEnabled,
className = _props.className,
extraClasses = _props.extraClasses,
childClasses = _props.childClasses,
style = _props.style,
childrenStyles = _props.childrenStyles;
return _react2.default.createElement(
'div',
{
className: (0, _classnames2.default)(className, extraClasses, { isMuted: isMuted, isEnabled: isEnabled }),
style: style
},
isMuted ? _react2.default.createElement(_SoundOffButton2.default, {
className: childClasses.SoundOffButton,
style: childrenStyles.SoundOffButton,
isEnabled: isEnabled,
onClick: function onClick() {
return _this2.handleMuteChange(false);
}
}) : _react2.default.createElement(_SoundOnButton2.default, {
className: childClasses.SoundOnButton,
style: childrenStyles.SoundOnButton,
isEnabled: isEnabled,
onClick: function onClick() {
return _this2.handleMuteChange(true);
}
})
);
}
}]);
return MuteToggleButton;
}(_react.Component), (_applyDecoratedDescriptor(_class.prototype, 'handleMuteChange', [_autobindDecorator2.default], Object.getOwnPropertyDescriptor(_class.prototype, 'handleMuteChange'), _class.prototype)), _class);
MuteToggleButton.propTypes = {
onMuteChange: _propTypes2.default.func.isRequired,
isMuted: _propTypes2.default.bool,
isEnabled: _propTypes2.default.bool,
className: _propTypes2.default.string,
extraClasses: _propTypes2.default.string,
style: _propTypes2.default.object
};
MuteToggleButton.defaultProps = {
isMuted: false,
isEnabled: true,
className: 'MuteToggleButton',
extraClasses: '',
style: {}
};
exports.default = (0, _composers.withChildClasses)((0, _composers.withChildrenStyles)(MuteToggleButton));
/***/ }),
/* 244 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _desc, _value, _class;
var _react = __webpack_require__(11);
var _react2 = _interopRequireDefault(_react);
var _propTypes = __webpack_require__(25);
var _propTypes2 = _interopRequireDefault(_propTypes);
var _autobindDecorator = __webpack_require__(89);
var _autobindDecorator2 = _interopRequireDefault(_autobindDecorator);
var _classnames = __webpack_require__(84);
var _classnames2 = _interopRequireDefault(_classnames);
var _composers = __webpack_require__(88);
var _RangeControlOverlay = __webpack_require__(197);
var _RangeControlOverlay2 = _interopRequireDefault(_RangeControlOverlay);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
var desc = {};
Object['ke' + 'ys'](descriptor).forEach(function (key) {
desc[key] = descriptor[key];
});
desc.enumerable = !!desc.enumerable;
desc.configurable = !!desc.configurable;
if ('value' in desc || desc.initializer) {
desc.writable = true;
}
desc = decorators.slice().reverse().reduce(function (desc, decorator) {
return decorator(target, property, desc) || desc;
}, desc);
if (context && desc.initializer !== void 0) {
desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
desc.initializer = undefined;
}
if (desc.initializer === void 0) {
Object['define' + 'Property'](target, property, desc);
desc = null;
}
return desc;
}
var number = _propTypes2.default.number,
bool = _propTypes2.default.bool,
func = _propTypes2.default.func,
string = _propTypes2.default.string,
object = _propTypes2.default.object;
/**
* Volume slider component
*/
var VolumeSlider = (_class = function (_Component) {
_inherits(VolumeSlider, _Component);
function VolumeSlider(props) {
_classCallCheck(this, VolumeSlider);
var _this = _possibleConstructorReturn(this, (VolumeSlider.__proto__ || Object.getPrototypeOf(VolumeSlider)).call(this, props));
_this.sliderEl = null;
_this.state = {
currentIntent: 0
};
return _this;
}
_createClass(VolumeSlider, [{
key: 'storeRef',
value: function storeRef(rootEl) {
this.sliderEl = rootEl;
}
}, {
key: 'getBounds',
value: function getBounds() {
return this.sliderEl.getBoundingClientRect();
}
}, {
key: 'handleVolumeChange',
value: function handleVolumeChange(volume) {
var _props = this.props,
isEnabled = _props.isEnabled,
onVolumeChange = _props.onVolumeChange;
if (isEnabled) {
onVolumeChange(volume);
}
}
}, {
key: 'handleIntent',
value: function handleIntent(volume) {
var intent = this.props.isEnabled ? volume : 0;
this.setState({
currentIntent: intent
});
}
}, {
key: 'render',
value: function render() {
var _props2 = this.props,
volume = _props2.volume,
isEnabled = _props2.isEnabled,
className = _props2.className,
extraClasses = _props2.extraClasses,
childClasses = _props2.childClasses,
style = _props2.style,
childrenStyles = _props2.childrenStyles;
var currentIntent = this.state.currentIntent;
var volumePercentage = Math.min(100, Math.max(0, volume * 100));
var styleBottom = volumePercentage + '%';
var appliedIntent = isEnabled && currentIntent !== 0 ? currentIntent : 0;
var isDecreaseIntent = appliedIntent && currentIntent < volume;
return _react2.default.createElement(
'div',
{
className: (0, _classnames2.default)(className, extraClasses, {
isEnabled: isEnabled,
isDecreaseIntent: isDecreaseIntent
}),
style: style,
ref: this.storeRef
},
_react2.default.createElement('div', {
className: childClasses.value || 'VolumeSlider-value',
style: _extends({ height: styleBottom }, childrenStyles.value || {})
}),
_react2.default.createElement('div', {
className: childClasses.intent || 'VolumeSlider-intent',
style: _extends({ height: appliedIntent * 100 + '%' }, childrenStyles.intent || {})
}),
_react2.default.createElement('div', {
className: childClasses.handle || 'VolumeSlider-handle',
style: _extends({ bottom: styleBottom }, childrenStyles.handle || {})
}),
isEnabled && _react2.default.createElement(_RangeControlOverlay2.default, {
extraClasses: childClasses.seek || 'VolumeSlider-seek',
style: childrenStyles.RangeControlOverlay,
bounds: this.getBounds,
direction: _RangeControlOverlay.ControlDirection.VERTICAL,
onValue: this.handleVolumeChange,
onIntent: this.handleIntent
})
);
}
}]);
return VolumeSlider;
}(_react.Component), (_applyDecoratedDescriptor(_class.prototype, 'storeRef', [_autobindDecorator2.default], Object.getOwnPropertyDescriptor(_class.prototype, 'storeRef'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'getBounds', [_autobindDecorator2.default], Object.getOwnPropertyDescriptor(_class.prototype, 'getBounds'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'handleVolumeChange', [_autobindDecorator2.default], Object.getOwnPropertyDescriptor(_class.prototype, 'handleVolumeChange'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'handleIntent', [_autobindDecorator2.default], Object.getOwnPropertyDescriptor(_class.prototype, 'handleIntent'), _class.prototype)), _class);
VolumeSlider.propTypes = {
volume: number,
isEnabled: bool,
onVolumeChange: func,
extraClasses: string,
style: object
};
VolumeSlider.defaultProps = {
volume: 0,
isEnabled: false,
onVolumeChange: function onVolumeChange() {},
extraClasses: '',
style: {}
};
exports.default = (0, _composers.compose)((0, _composers.withChildrenStyles)(), (0, _composers.withCustomizableClasses)('VolumeSlider'), (0, _composers.withChildClasses)())(VolumeSlider);
/***/ }),
/* 245 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.horizontalCenter = exports.Icon = exports.withBaseIcon = undefined;
var _Icon = __webpack_require__(246);
var _horizontalCenter = __webpack_require__(255);
exports.withBaseIcon = _Icon.withBaseIcon;
exports.Icon = _Icon.Icon;
exports.horizontalCenter = _horizontalCenter.horizontalCenter;
exports.default = _Icon.Icon;
/***/ }),
/* 246 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.withBaseIcon = exports.Icon = undefined;
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _react = __webpack_require__(11);
var _react2 = _interopRequireDefault(_react);
var _propTypes = __webpack_require__(25);
var _propTypes2 = _interopRequireDefault(_propTypes);
var _SvgIcon = __webpack_require__(247);
var _SvgIcon2 = _interopRequireDefault(_SvgIcon);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
var Icon = function Icon(props) {
var style = props.style,
className = props.className,
icon = props.icon,
others = _objectWithoutProperties(props, ['style', 'className', 'icon']); //eslint-disable-line
return _react2.default.createElement(
'div',
_extends({}, others, { style: _extends({}, style, { display: 'inline-flex', justifyContent: 'center', alignItems: 'center' }), className: className }),
_react2.default.createElement(_SvgIcon2.default, { size: props.size, icon: props.icon })
);
};
exports.Icon = Icon;
var withBaseIcon = exports.withBaseIcon = function withBaseIcon(defaultProps) {
return function (props) {
var propsToUse = _extends({}, defaultProps);
return _react2.default.createElement(Icon, _extends({}, propsToUse, props));
};
};
Icon.defaultProps = {
size: 16,
fill: 'currentColor'
};
Icon.propTypes = {
icon: _propTypes2.default.object.isRequired,
size: _propTypes2.default.number,
style: _propTypes2.default.object,
className: _propTypes2.default.string
};
exports.default = Icon;
/***/ }),
/* 247 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.SvgIcon = undefined;
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _react = __webpack_require__(11);
var _react2 = _interopRequireDefault(_react);
var _propTypes = __webpack_require__(25);
var _propTypes2 = _interopRequireDefault(_propTypes);
var _camelCase = __webpack_require__(248);
var _camelCase2 = _interopRequireDefault(_camelCase);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var walkChildren = function walkChildren(children) {
return children.map(function (child, idx) {
var name = child.name,
attribsMap = child.attribs,
_child$children = child.children,
gchildren = _child$children === undefined ? null : _child$children;
//fill, stroke
var attribs = Object.keys(attribsMap).filter(function (key) {
return key !== 'fill' && key !== 'stroke' && attribsMap[key] !== 'none';
}).reduce(function (partial, key) {
partial[(0, _camelCase2.default)(key)] = attribsMap[key];
return partial;
}, {});
//special case, it has fill and stroke at the same time
var merge = {};
if (attribsMap.fill === 'none' && attribsMap.stroke) {
merge = { fill: 'none', stroke: 'currentColor' };
}
return (0, _react.createElement)(name, _extends({ key: idx }, attribs, merge), gchildren === null ? gchildren : walkChildren(gchildren));
});
};
var SvgIcon = exports.SvgIcon = function SvgIcon(props) {
var size = props.size;
var _props$icon = props.icon,
children = _props$icon.children,
viewBox = _props$icon.viewBox;
return _react2.default.createElement(
'svg',
{ fill: 'currentColor', style: { display: 'inline-block', verticalAlign: 'middle' }, height: size, width: size, viewBox: viewBox },
walkChildren(children)
);
};
SvgIcon.defaultProps = {
size: '16'
};
SvgIcon.propTypes = {
icon: _propTypes2.default.object.isRequired,
size: _propTypes2.default.number
};
exports.default = SvgIcon;
/***/ }),
/* 248 */
/***/ (function(module, exports, __webpack_require__) {
var upperCase = __webpack_require__(249)
var noCase = __webpack_require__(250)
/**
* Camel case a string.
*
* @param {string} value
* @param {string} [locale]
* @return {string}
*/
module.exports = function (value, locale, mergeNumbers) {
var result = noCase(value, locale)
// Replace periods between numeric entities with an underscore.
if (!mergeNumbers) {
result = result.replace(/ (?=\d)/g, '_')
}
// Replace spaces between words with an upper cased character.
return result.replace(/ (.)/g, function (m, $1) {
return upperCase($1, locale)
})
}
/***/ }),
/* 249 */
/***/ (function(module, exports) {
/**
* Special language-specific overrides.
*
* Source: ftp://ftp.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt
*
* @type {Object}
*/
var LANGUAGES = {
tr: {
regexp: /[\u0069]/g,
map: {
'\u0069': '\u0130'
}
},
az: {
regexp: /[\u0069]/g,
map: {
'\u0069': '\u0130'
}
},
lt: {
regexp: /[\u0069\u006A\u012F]\u0307|\u0069\u0307[\u0300\u0301\u0303]/g,
map: {
'\u0069\u0307': '\u0049',
'\u006A\u0307': '\u004A',
'\u012F\u0307': '\u012E',
'\u0069\u0307\u0300': '\u00CC',
'\u0069\u0307\u0301': '\u00CD',
'\u0069\u0307\u0303': '\u0128'
}
}
}
/**
* Upper case a string.
*
* @param {String} str
* @return {String}
*/
module.exports = function (str, locale) {
var lang = LANGUAGES[locale]
str = str == null ? '' : String(str)
if (lang) {
str = str.replace(lang.regexp, function (m) { return lang.map[m] })
}
return str.toUpperCase()
}
/***/ }),
/* 250 */
/***/ (function(module, exports, __webpack_require__) {
var lowerCase = __webpack_require__(251)
var NON_WORD_REGEXP = __webpack_require__(252)
var CAMEL_CASE_REGEXP = __webpack_require__(253)
var CAMEL_CASE_UPPER_REGEXP = __webpack_require__(254)
/**
* Sentence case a string.
*
* @param {string} str
* @param {string} locale
* @param {string} replacement
* @return {string}
*/
module.exports = function (str, locale, replacement) {
if (str == null) {
return ''
}
replacement = typeof replacement !== 'string' ? ' ' : replacement
function replace (match, index, value) {
if (index === 0 || index === (value.length - match.length)) {
return ''
}
return replacement
}
str = String(str)
// Support camel case ("camelCase" -> "camel Case").
.replace(CAMEL_CASE_REGEXP, '$1 $2')
// Support odd camel case ("CAMELCase" -> "CAMEL Case").
.replace(CAMEL_CASE_UPPER_REGEXP, '$1 $2')
// Remove all non-word characters and replace with a single space.
.replace(NON_WORD_REGEXP, replace)
// Lower case the entire string.
return lowerCase(str, locale)
}
/***/ }),
/* 251 */
/***/ (function(module, exports) {
/**
* Special language-specific overrides.
*
* Source: ftp://ftp.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt
*
* @type {Object}
*/
var LANGUAGES = {
tr: {
regexp: /\u0130|\u0049|\u0049\u0307/g,
map: {
'\u0130': '\u0069',
'\u0049': '\u0131',
'\u0049\u0307': '\u0069'
}
},
az: {
regexp: /[\u0130]/g,
map: {
'\u0130': '\u0069',
'\u0049': '\u0131',
'\u0049\u0307': '\u0069'
}
},
lt: {
regexp: /[\u0049\u004A\u012E\u00CC\u00CD\u0128]/g,
map: {
'\u0049': '\u0069\u0307',
'\u004A': '\u006A\u0307',
'\u012E': '\u012F\u0307',
'\u00CC': '\u0069\u0307\u0300',
'\u00CD': '\u0069\u0307\u0301',
'\u0128': '\u0069\u0307\u0303'
}
}
}
/**
* Lowercase a string.
*
* @param {String} str
* @return {String}
*/
module.exports = function (str, locale) {
var lang = LANGUAGES[locale]
str = str == null ? '' : String(str)
if (lang) {
str = str.replace(lang.regexp, function (m) { return lang.map[m] })
}
return str.toLowerCase()
}
/***/ }),
/* 252 */
/***/ (function(module, exports) {
module.exports = /[^A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B4\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC0-9\xB2\xB3\xB9\xBC-\xBE\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u09F4-\u09F9\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0B72-\u0B77\u0BE6-\u0BF2\u0C66-\u0C6F\u0C78-\u0C7E\u0CE6-\u0CEF\u0D66-\u0D75\u0DE6-\u0DEF\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F33\u1040-\u1049\u1090-\u1099\u1369-\u137C\u16EE-\u16F0\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1946-\u194F\u19D0-\u19DA\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\u2070\u2074-\u2079\u2080-\u2089\u2150-\u2182\u2185-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2CFD\u3007\u3021-\u3029\u3038-\u303A\u3192-\u3195\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\uA620-\uA629\uA6E6-\uA6EF\uA830-\uA835\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uA9F0-\uA9F9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19]+/g
/***/ }),
/* 253 */
/***/ (function(module, exports) {
module.exports = /([a-z\xB5\xDF-\xF6\xF8-\xFF\u0101\u0103\u0105\u0107\u0109\u010B\u010D\u010F\u0111\u0113\u0115\u0117\u0119\u011B\u011D\u011F\u0121\u0123\u0125\u0127\u0129\u012B\u012D\u012F\u0131\u0133\u0135\u0137\u0138\u013A\u013C\u013E\u0140\u0142\u0144\u0146\u0148\u0149\u014B\u014D\u014F\u0151\u0153\u0155\u0157\u0159\u015B\u015D\u015F\u0161\u0163\u0165\u0167\u0169\u016B\u016D\u016F\u0171\u0173\u0175\u0177\u017A\u017C\u017E-\u0180\u0183\u0185\u0188\u018C\u018D\u0192\u0195\u0199-\u019B\u019E\u01A1\u01A3\u01A5\u01A8\u01AA\u01AB\u01AD\u01B0\u01B4\u01B6\u01B9\u01BA\u01BD-\u01BF\u01C6\u01C9\u01CC\u01CE\u01D0\u01D2\u01D4\u01D6\u01D8\u01DA\u01DC\u01DD\u01DF\u01E1\u01E3\u01E5\u01E7\u01E9\u01EB\u01ED\u01EF\u01F0\u01F3\u01F5\u01F9\u01FB\u01FD\u01FF\u0201\u0203\u0205\u0207\u0209\u020B\u020D\u020F\u0211\u0213\u0215\u0217\u0219\u021B\u021D\u021F\u0221\u0223\u0225\u0227\u0229\u022B\u022D\u022F\u0231\u0233-\u0239\u023C\u023F\u0240\u0242\u0247\u0249\u024B\u024D\u024F-\u0293\u0295-\u02AF\u0371\u0373\u0377\u037B-\u037D\u0390\u03AC-\u03CE\u03D0\u03D1\u03D5-\u03D7\u03D9\u03DB\u03DD\u03DF\u03E1\u03E3\u03E5\u03E7\u03E9\u03EB\u03ED\u03EF-\u03F3\u03F5\u03F8\u03FB\u03FC\u0430-\u045F\u0461\u0463\u0465\u0467\u0469\u046B\u046D\u046F\u0471\u0473\u0475\u0477\u0479\u047B\u047D\u047F\u0481\u048B\u048D\u048F\u0491\u0493\u0495\u0497\u0499\u049B\u049D\u049F\u04A1\u04A3\u04A5\u04A7\u04A9\u04AB\u04AD\u04AF\u04B1\u04B3\u04B5\u04B7\u04B9\u04BB\u04BD\u04BF\u04C2\u04C4\u04C6\u04C8\u04CA\u04CC\u04CE\u04CF\u04D1\u04D3\u04D5\u04D7\u04D9\u04DB\u04DD\u04DF\u04E1\u04E3\u04E5\u04E7\u04E9\u04EB\u04ED\u04EF\u04F1\u04F3\u04F5\u04F7\u04F9\u04FB\u04FD\u04FF\u0501\u0503\u0505\u0507\u0509\u050B\u050D\u050F\u0511\u0513\u0515\u0517\u0519\u051B\u051D\u051F\u0521\u0523\u0525\u0527\u0529\u052B\u052D\u052F\u0561-\u0587\u13F8-\u13FD\u1D00-\u1D2B\u1D6B-\u1D77\u1D79-\u1D9A\u1E01\u1E03\u1E05\u1E07\u1E09\u1E0B\u1E0D\u1E0F\u1E11\u1E13\u1E15\u1E17\u1E19\u1E1B\u1E1D\u1E1F\u1E21\u1E23\u1E25\u1E27\u1E29\u1E2B\u1E2D\u1E2F\u1E31\u1E33\u1E35\u1E37\u1E39\u1E3B\u1E3D\u1E3F\u1E41\u1E43\u1E45\u1E47\u1E49\u1E4B\u1E4D\u1E4F\u1E51\u1E53\u1E55\u1E57\u1E59\u1E5B\u1E5D\u1E5F\u1E61\u1E63\u1E65\u1E67\u1E69\u1E6B\u1E6D\u1E6F\u1E71\u1E73\u1E75\u1E77\u1E79\u1E7B\u1E7D\u1E7F\u1E81\u1E83\u1E85\u1E87\u1E89\u1E8B\u1E8D\u1E8F\u1E91\u1E93\u1E95-\u1E9D\u1E9F\u1EA1\u1EA3\u1EA5\u1EA7\u1EA9\u1EAB\u1EAD\u1EAF\u1EB1\u1EB3\u1EB5\u1EB7\u1EB9\u1EBB\u1EBD\u1EBF\u1EC1\u1EC3\u1EC5\u1EC7\u1EC9\u1ECB\u1ECD\u1ECF\u1ED1\u1ED3\u1ED5\u1ED7\u1ED9\u1EDB\u1EDD\u1EDF\u1EE1\u1EE3\u1EE5\u1EE7\u1EE9\u1EEB\u1EED\u1EEF\u1EF1\u1EF3\u1EF5\u1EF7\u1EF9\u1EFB\u1EFD\u1EFF-\u1F07\u1F10-\u1F15\u1F20-\u1F27\u1F30-\u1F37\u1F40-\u1F45\u1F50-\u1F57\u1F60-\u1F67\u1F70-\u1F7D\u1F80-\u1F87\u1F90-\u1F97\u1FA0-\u1FA7\u1FB0-\u1FB4\u1FB6\u1FB7\u1FBE\u1FC2-\u1FC4\u1FC6\u1FC7\u1FD0-\u1FD3\u1FD6\u1FD7\u1FE0-\u1FE7\u1FF2-\u1FF4\u1FF6\u1FF7\u210A\u210E\u210F\u2113\u212F\u2134\u2139\u213C\u213D\u2146-\u2149\u214E\u2184\u2C30-\u2C5E\u2C61\u2C65\u2C66\u2C68\u2C6A\u2C6C\u2C71\u2C73\u2C74\u2C76-\u2C7B\u2C81\u2C83\u2C85\u2C87\u2C89\u2C8B\u2C8D\u2C8F\u2C91\u2C93\u2C95\u2C97\u2C99\u2C9B\u2C9D\u2C9F\u2CA1\u2CA3\u2CA5\u2CA7\u2CA9\u2CAB\u2CAD\u2CAF\u2CB1\u2CB3\u2CB5\u2CB7\u2CB9\u2CBB\u2CBD\u2CBF\u2CC1\u2CC3\u2CC5\u2CC7\u2CC9\u2CCB\u2CCD\u2CCF\u2CD1\u2CD3\u2CD5\u2CD7\u2CD9\u2CDB\u2CDD\u2CDF\u2CE1\u2CE3\u2CE4\u2CEC\u2CEE\u2CF3\u2D00-\u2D25\u2D27\u2D2D\uA641\uA643\uA645\uA647\uA649\uA64B\uA64D\uA64F\uA651\uA653\uA655\uA657\uA659\uA65B\uA65D\uA65F\uA661\uA663\uA665\uA667\uA669\uA66B\uA66D\uA681\uA683\uA685\uA687\uA689\uA68B\uA68D\uA68F\uA691\uA693\uA695\uA697\uA699\uA69B\uA723\uA725\uA727\uA729\uA72B\uA72D\uA72F-\uA731\uA733\uA735\uA737\uA739\uA73B\uA73D\uA73F\uA741\uA743\uA745\uA747\uA749\uA74B\uA74D\uA74F\uA751\uA753\uA755\uA757\uA759\uA75B\uA75D\uA75F\uA761\uA763\uA765\uA767\uA769\uA76B\uA76D\uA76F\uA771-\uA778\uA77A\uA77C\uA77F\uA781\uA783\uA785\uA787\uA78C\uA78E\uA791\uA793-\uA795\uA797\uA799\uA79B\uA79D\uA79F\uA7A1\uA7A3\uA7A5\uA7A7\uA7A9\uA7B5\uA7B7\uA7FA\uAB30-\uAB5A\uAB60-\uAB65\uAB70-\uABBF\uFB00-\uFB06\uFB13-\uFB17\uFF41-\uFF5A0-9\xB2\xB3\xB9\xBC-\xBE\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u09F4-\u09F9\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0B72-\u0B77\u0BE6-\u0BF2\u0C66-\u0C6F\u0C78-\u0C7E\u0CE6-\u0CEF\u0D66-\u0D75\u0DE6-\u0DEF\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F33\u1040-\u1049\u1090-\u1099\u1369-\u137C\u16EE-\u16F0\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1946-\u194F\u19D0-\u19DA\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\u2070\u2074-\u2079\u2080-\u2089\u2150-\u2182\u2185-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2CFD\u3007\u3021-\u3029\u3038-\u303A\u3192-\u3195\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\uA620-\uA629\uA6E6-\uA6EF\uA830-\uA835\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uA9F0-\uA9F9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19])([A-Z\xC0-\xD6\xD8-\xDE\u0100\u0102\u0104\u0106\u0108\u010A\u010C\u010E\u0110\u0112\u0114\u0116\u0118\u011A\u011C\u011E\u0120\u0122\u0124\u0126\u0128\u012A\u012C\u012E\u0130\u0132\u0134\u0136\u0139\u013B\u013D\u013F\u0141\u0143\u0145\u0147\u014A\u014C\u014E\u0150\u0152\u0154\u0156\u0158\u015A\u015C\u015E\u0160\u0162\u0164\u0166\u0168\u016A\u016C\u016E\u0170\u0172\u0174\u0176\u0178\u0179\u017B\u017D\u0181\u0182\u0184\u0186\u0187\u0189-\u018B\u018E-\u0191\u0193\u0194\u0196-\u0198\u019C\u019D\u019F\u01A0\u01A2\u01A4\u01A6\u01A7\u01A9\u01AC\u01AE\u01AF\u01B1-\u01B3\u01B5\u01B7\u01B8\u01BC\u01C4\u01C7\u01CA\u01CD\u01CF\u01D1\u01D3\u01D5\u01D7\u01D9\u01DB\u01DE\u01E0\u01E2\u01E4\u01E6\u01E8\u01EA\u01EC\u01EE\u01F1\u01F4\u01F6-\u01F8\u01FA\u01FC\u01FE\u0200\u0202\u0204\u0206\u0208\u020A\u020C\u020E\u0210\u0212\u0214\u0216\u0218\u021A\u021C\u021E\u0220\u0222\u0224\u0226\u0228\u022A\u022C\u022E\u0230\u0232\u023A\u023B\u023D\u023E\u0241\u0243-\u0246\u0248\u024A\u024C\u024E\u0370\u0372\u0376\u037F\u0386\u0388-\u038A\u038C\u038E\u038F\u0391-\u03A1\u03A3-\u03AB\u03CF\u03D2-\u03D4\u03D8\u03DA\u03DC\u03DE\u03E0\u03E2\u03E4\u03E6\u03E8\u03EA\u03EC\u03EE\u03F4\u03F7\u03F9\u03FA\u03FD-\u042F\u0460\u0462\u0464\u0466\u0468\u046A\u046C\u046E\u0470\u0472\u0474\u0476\u0478\u047A\u047C\u047E\u0480\u048A\u048C\u048E\u0490\u0492\u0494\u0496\u0498\u049A\u049C\u049E\u04A0\u04A2\u04A4\u04A6\u04A8\u04AA\u04AC\u04AE\u04B0\u04B2\u04B4\u04B6\u04B8\u04BA\u04BC\u04BE\u04C0\u04C1\u04C3\u04C5\u04C7\u04C9\u04CB\u04CD\u04D0\u04D2\u04D4\u04D6\u04D8\u04DA\u04DC\u04DE\u04E0\u04E2\u04E4\u04E6\u04E8\u04EA\u04EC\u04EE\u04F0\u04F2\u04F4\u04F6\u04F8\u04FA\u04FC\u04FE\u0500\u0502\u0504\u0506\u0508\u050A\u050C\u050E\u0510\u0512\u0514\u0516\u0518\u051A\u051C\u051E\u0520\u0522\u0524\u0526\u0528\u052A\u052C\u052E\u0531-\u0556\u10A0-\u10C5\u10C7\u10CD\u13A0-\u13F5\u1E00\u1E02\u1E04\u1E06\u1E08\u1E0A\u1E0C\u1E0E\u1E10\u1E12\u1E14\u1E16\u1E18\u1E1A\u1E1C\u1E1E\u1E20\u1E22\u1E24\u1E26\u1E28\u1E2A\u1E2C\u1E2E\u1E30\u1E32\u1E34\u1E36\u1E38\u1E3A\u1E3C\u1E3E\u1E40\u1E42\u1E44\u1E46\u1E48\u1E4A\u1E4C\u1E4E\u1E50\u1E52\u1E54\u1E56\u1E58\u1E5A\u1E5C\u1E5E\u1E60\u1E62\u1E64\u1E66\u1E68\u1E6A\u1E6C\u1E6E\u1E70\u1E72\u1E74\u1E76\u1E78\u1E7A\u1E7C\u1E7E\u1E80\u1E82\u1E84\u1E86\u1E88\u1E8A\u1E8C\u1E8E\u1E90\u1E92\u1E94\u1E9E\u1EA0\u1EA2\u1EA4\u1EA6\u1EA8\u1EAA\u1EAC\u1EAE\u1EB0\u1EB2\u1EB4\u1EB6\u1EB8\u1EBA\u1EBC\u1EBE\u1EC0\u1EC2\u1EC4\u1EC6\u1EC8\u1ECA\u1ECC\u1ECE\u1ED0\u1ED2\u1ED4\u1ED6\u1ED8\u1EDA\u1EDC\u1EDE\u1EE0\u1EE2\u1EE4\u1EE6\u1EE8\u1EEA\u1EEC\u1EEE\u1EF0\u1EF2\u1EF4\u1EF6\u1EF8\u1EFA\u1EFC\u1EFE\u1F08-\u1F0F\u1F18-\u1F1D\u1F28-\u1F2F\u1F38-\u1F3F\u1F48-\u1F4D\u1F59\u1F5B\u1F5D\u1F5F\u1F68-\u1F6F\u1FB8-\u1FBB\u1FC8-\u1FCB\u1FD8-\u1FDB\u1FE8-\u1FEC\u1FF8-\u1FFB\u2102\u2107\u210B-\u210D\u2110-\u2112\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u2130-\u2133\u213E\u213F\u2145\u2183\u2C00-\u2C2E\u2C60\u2C62-\u2C64\u2C67\u2C69\u2C6B\u2C6D-\u2C70\u2C72\u2C75\u2C7E-\u2C80\u2C82\u2C84\u2C86\u2C88\u2C8A\u2C8C\u2C8E\u2C90\u2C92\u2C94\u2C96\u2C98\u2C9A\u2C9C\u2C9E\u2CA0\u2CA2\u2CA4\u2CA6\u2CA8\u2CAA\u2CAC\u2CAE\u2CB0\u2CB2\u2CB4\u2CB6\u2CB8\u2CBA\u2CBC\u2CBE\u2CC0\u2CC2\u2CC4\u2CC6\u2CC8\u2CCA\u2CCC\u2CCE\u2CD0\u2CD2\u2CD4\u2CD6\u2CD8\u2CDA\u2CDC\u2CDE\u2CE0\u2CE2\u2CEB\u2CED\u2CF2\uA640\uA642\uA644\uA646\uA648\uA64A\uA64C\uA64E\uA650\uA652\uA654\uA656\uA658\uA65A\uA65C\uA65E\uA660\uA662\uA664\uA666\uA668\uA66A\uA66C\uA680\uA682\uA684\uA686\uA688\uA68A\uA68C\uA68E\uA690\uA692\uA694\uA696\uA698\uA69A\uA722\uA724\uA726\uA728\uA72A\uA72C\uA72E\uA732\uA734\uA736\uA738\uA73A\uA73C\uA73E\uA740\uA742\uA744\uA746\uA748\uA74A\uA74C\uA74E\uA750\uA752\uA754\uA756\uA758\uA75A\uA75C\uA75E\uA760\uA762\uA764\uA766\uA768\uA76A\uA76C\uA76E\uA779\uA77B\uA77D\uA77E\uA780\uA782\uA784\uA786\uA78B\uA78D\uA790\uA792\uA796\uA798\uA79A\uA79C\uA79E\uA7A0\uA7A2\uA7A4\uA7A6\uA7A8\uA7AA-\uA7AD\uA7B0-\uA7B4\uA7B6\uFF21-\uFF3A])/g
/***/ }),
/* 254 */
/***/ (function(module, exports) {
module.exports = /([A-Z\xC0-\xD6\xD8-\xDE\u0100\u0102\u0104\u0106\u0108\u010A\u010C\u010E\u0110\u0112\u0114\u0116\u0118\u011A\u011C\u011E\u0120\u0122\u0124\u0126\u0128\u012A\u012C\u012E\u0130\u0132\u0134\u0136\u0139\u013B\u013D\u013F\u0141\u0143\u0145\u0147\u014A\u014C\u014E\u0150\u0152\u0154\u0156\u0158\u015A\u015C\u015E\u0160\u0162\u0164\u0166\u0168\u016A\u016C\u016E\u0170\u0172\u0174\u0176\u0178\u0179\u017B\u017D\u0181\u0182\u0184\u0186\u0187\u0189-\u018B\u018E-\u0191\u0193\u0194\u0196-\u0198\u019C\u019D\u019F\u01A0\u01A2\u01A4\u01A6\u01A7\u01A9\u01AC\u01AE\u01AF\u01B1-\u01B3\u01B5\u01B7\u01B8\u01BC\u01C4\u01C7\u01CA\u01CD\u01CF\u01D1\u01D3\u01D5\u01D7\u01D9\u01DB\u01DE\u01E0\u01E2\u01E4\u01E6\u01E8\u01EA\u01EC\u01EE\u01F1\u01F4\u01F6-\u01F8\u01FA\u01FC\u01FE\u0200\u0202\u0204\u0206\u0208\u020A\u020C\u020E\u0210\u0212\u0214\u0216\u0218\u021A\u021C\u021E\u0220\u0222\u0224\u0226\u0228\u022A\u022C\u022E\u0230\u0232\u023A\u023B\u023D\u023E\u0241\u0243-\u0246\u0248\u024A\u024C\u024E\u0370\u0372\u0376\u037F\u0386\u0388-\u038A\u038C\u038E\u038F\u0391-\u03A1\u03A3-\u03AB\u03CF\u03D2-\u03D4\u03D8\u03DA\u03DC\u03DE\u03E0\u03E2\u03E4\u03E6\u03E8\u03EA\u03EC\u03EE\u03F4\u03F7\u03F9\u03FA\u03FD-\u042F\u0460\u0462\u0464\u0466\u0468\u046A\u046C\u046E\u0470\u0472\u0474\u0476\u0478\u047A\u047C\u047E\u0480\u048A\u048C\u048E\u0490\u0492\u0494\u0496\u0498\u049A\u049C\u049E\u04A0\u04A2\u04A4\u04A6\u04A8\u04AA\u04AC\u04AE\u04B0\u04B2\u04B4\u04B6\u04B8\u04BA\u04BC\u04BE\u04C0\u04C1\u04C3\u04C5\u04C7\u04C9\u04CB\u04CD\u04D0\u04D2\u04D4\u04D6\u04D8\u04DA\u04DC\u04DE\u04E0\u04E2\u04E4\u04E6\u04E8\u04EA\u04EC\u04EE\u04F0\u04F2\u04F4\u04F6\u04F8\u04FA\u04FC\u04FE\u0500\u0502\u0504\u0506\u0508\u050A\u050C\u050E\u0510\u0512\u0514\u0516\u0518\u051A\u051C\u051E\u0520\u0522\u0524\u0526\u0528\u052A\u052C\u052E\u0531-\u0556\u10A0-\u10C5\u10C7\u10CD\u13A0-\u13F5\u1E00\u1E02\u1E04\u1E06\u1E08\u1E0A\u1E0C\u1E0E\u1E10\u1E12\u1E14\u1E16\u1E18\u1E1A\u1E1C\u1E1E\u1E20\u1E22\u1E24\u1E26\u1E28\u1E2A\u1E2C\u1E2E\u1E30\u1E32\u1E34\u1E36\u1E38\u1E3A\u1E3C\u1E3E\u1E40\u1E42\u1E44\u1E46\u1E48\u1E4A\u1E4C\u1E4E\u1E50\u1E52\u1E54\u1E56\u1E58\u1E5A\u1E5C\u1E5E\u1E60\u1E62\u1E64\u1E66\u1E68\u1E6A\u1E6C\u1E6E\u1E70\u1E72\u1E74\u1E76\u1E78\u1E7A\u1E7C\u1E7E\u1E80\u1E82\u1E84\u1E86\u1E88\u1E8A\u1E8C\u1E8E\u1E90\u1E92\u1E94\u1E9E\u1EA0\u1EA2\u1EA4\u1EA6\u1EA8\u1EAA\u1EAC\u1EAE\u1EB0\u1EB2\u1EB4\u1EB6\u1EB8\u1EBA\u1EBC\u1EBE\u1EC0\u1EC2\u1EC4\u1EC6\u1EC8\u1ECA\u1ECC\u1ECE\u1ED0\u1ED2\u1ED4\u1ED6\u1ED8\u1EDA\u1EDC\u1EDE\u1EE0\u1EE2\u1EE4\u1EE6\u1EE8\u1EEA\u1EEC\u1EEE\u1EF0\u1EF2\u1EF4\u1EF6\u1EF8\u1EFA\u1EFC\u1EFE\u1F08-\u1F0F\u1F18-\u1F1D\u1F28-\u1F2F\u1F38-\u1F3F\u1F48-\u1F4D\u1F59\u1F5B\u1F5D\u1F5F\u1F68-\u1F6F\u1FB8-\u1FBB\u1FC8-\u1FCB\u1FD8-\u1FDB\u1FE8-\u1FEC\u1FF8-\u1FFB\u2102\u2107\u210B-\u210D\u2110-\u2112\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u2130-\u2133\u213E\u213F\u2145\u2183\u2C00-\u2C2E\u2C60\u2C62-\u2C64\u2C67\u2C69\u2C6B\u2C6D-\u2C70\u2C72\u2C75\u2C7E-\u2C80\u2C82\u2C84\u2C86\u2C88\u2C8A\u2C8C\u2C8E\u2C90\u2C92\u2C94\u2C96\u2C98\u2C9A\u2C9C\u2C9E\u2CA0\u2CA2\u2CA4\u2CA6\u2CA8\u2CAA\u2CAC\u2CAE\u2CB0\u2CB2\u2CB4\u2CB6\u2CB8\u2CBA\u2CBC\u2CBE\u2CC0\u2CC2\u2CC4\u2CC6\u2CC8\u2CCA\u2CCC\u2CCE\u2CD0\u2CD2\u2CD4\u2CD6\u2CD8\u2CDA\u2CDC\u2CDE\u2CE0\u2CE2\u2CEB\u2CED\u2CF2\uA640\uA642\uA644\uA646\uA648\uA64A\uA64C\uA64E\uA650\uA652\uA654\uA656\uA658\uA65A\uA65C\uA65E\uA660\uA662\uA664\uA666\uA668\uA66A\uA66C\uA680\uA682\uA684\uA686\uA688\uA68A\uA68C\uA68E\uA690\uA692\uA694\uA696\uA698\uA69A\uA722\uA724\uA726\uA728\uA72A\uA72C\uA72E\uA732\uA734\uA736\uA738\uA73A\uA73C\uA73E\uA740\uA742\uA744\uA746\uA748\uA74A\uA74C\uA74E\uA750\uA752\uA754\uA756\uA758\uA75A\uA75C\uA75E\uA760\uA762\uA764\uA766\uA768\uA76A\uA76C\uA76E\uA779\uA77B\uA77D\uA77E\uA780\uA782\uA784\uA786\uA78B\uA78D\uA790\uA792\uA796\uA798\uA79A\uA79C\uA79E\uA7A0\uA7A2\uA7A4\uA7A6\uA7A8\uA7AA-\uA7AD\uA7B0-\uA7B4\uA7B6\uFF21-\uFF3A])([A-Z\xC0-\xD6\xD8-\xDE\u0100\u0102\u0104\u0106\u0108\u010A\u010C\u010E\u0110\u0112\u0114\u0116\u0118\u011A\u011C\u011E\u0120\u0122\u0124\u0126\u0128\u012A\u012C\u012E\u0130\u0132\u0134\u0136\u0139\u013B\u013D\u013F\u0141\u0143\u0145\u0147\u014A\u014C\u014E\u0150\u0152\u0154\u0156\u0158\u015A\u015C\u015E\u0160\u0162\u0164\u0166\u0168\u016A\u016C\u016E\u0170\u0172\u0174\u0176\u0178\u0179\u017B\u017D\u0181\u0182\u0184\u0186\u0187\u0189-\u018B\u018E-\u0191\u0193\u0194\u0196-\u0198\u019C\u019D\u019F\u01A0\u01A2\u01A4\u01A6\u01A7\u01A9\u01AC\u01AE\u01AF\u01B1-\u01B3\u01B5\u01B7\u01B8\u01BC\u01C4\u01C7\u01CA\u01CD\u01CF\u01D1\u01D3\u01D5\u01D7\u01D9\u01DB\u01DE\u01E0\u01E2\u01E4\u01E6\u01E8\u01EA\u01EC\u01EE\u01F1\u01F4\u01F6-\u01F8\u01FA\u01FC\u01FE\u0200\u0202\u0204\u0206\u0208\u020A\u020C\u020E\u0210\u0212\u0214\u0216\u0218\u021A\u021C\u021E\u0220\u0222\u0224\u0226\u0228\u022A\u022C\u022E\u0230\u0232\u023A\u023B\u023D\u023E\u0241\u0243-\u0246\u0248\u024A\u024C\u024E\u0370\u0372\u0376\u037F\u0386\u0388-\u038A\u038C\u038E\u038F\u0391-\u03A1\u03A3-\u03AB\u03CF\u03D2-\u03D4\u03D8\u03DA\u03DC\u03DE\u03E0\u03E2\u03E4\u03E6\u03E8\u03EA\u03EC\u03EE\u03F4\u03F7\u03F9\u03FA\u03FD-\u042F\u0460\u0462\u0464\u0466\u0468\u046A\u046C\u046E\u0470\u0472\u0474\u0476\u0478\u047A\u047C\u047E\u0480\u048A\u048C\u048E\u0490\u0492\u0494\u0496\u0498\u049A\u049C\u049E\u04A0\u04A2\u04A4\u04A6\u04A8\u04AA\u04AC\u04AE\u04B0\u04B2\u04B4\u04B6\u04B8\u04BA\u04BC\u04BE\u04C0\u04C1\u04C3\u04C5\u04C7\u04C9\u04CB\u04CD\u04D0\u04D2\u04D4\u04D6\u04D8\u04DA\u04DC\u04DE\u04E0\u04E2\u04E4\u04E6\u04E8\u04EA\u04EC\u04EE\u04F0\u04F2\u04F4\u04F6\u04F8\u04FA\u04FC\u04FE\u0500\u0502\u0504\u0506\u0508\u050A\u050C\u050E\u0510\u0512\u0514\u0516\u0518\u051A\u051C\u051E\u0520\u0522\u0524\u0526\u0528\u052A\u052C\u052E\u0531-\u0556\u10A0-\u10C5\u10C7\u10CD\u13A0-\u13F5\u1E00\u1E02\u1E04\u1E06\u1E08\u1E0A\u1E0C\u1E0E\u1E10\u1E12\u1E14\u1E16\u1E18\u1E1A\u1E1C\u1E1E\u1E20\u1E22\u1E24\u1E26\u1E28\u1E2A\u1E2C\u1E2E\u1E30\u1E32\u1E34\u1E36\u1E38\u1E3A\u1E3C\u1E3E\u1E40\u1E42\u1E44\u1E46\u1E48\u1E4A\u1E4C\u1E4E\u1E50\u1E52\u1E54\u1E56\u1E58\u1E5A\u1E5C\u1E5E\u1E60\u1E62\u1E64\u1E66\u1E68\u1E6A\u1E6C\u1E6E\u1E70\u1E72\u1E74\u1E76\u1E78\u1E7A\u1E7C\u1E7E\u1E80\u1E82\u1E84\u1E86\u1E88\u1E8A\u1E8C\u1E8E\u1E90\u1E92\u1E94\u1E9E\u1EA0\u1EA2\u1EA4\u1EA6\u1EA8\u1EAA\u1EAC\u1EAE\u1EB0\u1EB2\u1EB4\u1EB6\u1EB8\u1EBA\u1EBC\u1EBE\u1EC0\u1EC2\u1EC4\u1EC6\u1EC8\u1ECA\u1ECC\u1ECE\u1ED0\u1ED2\u1ED4\u1ED6\u1ED8\u1EDA\u1EDC\u1EDE\u1EE0\u1EE2\u1EE4\u1EE6\u1EE8\u1EEA\u1EEC\u1EEE\u1EF0\u1EF2\u1EF4\u1EF6\u1EF8\u1EFA\u1EFC\u1EFE\u1F08-\u1F0F\u1F18-\u1F1D\u1F28-\u1F2F\u1F38-\u1F3F\u1F48-\u1F4D\u1F59\u1F5B\u1F5D\u1F5F\u1F68-\u1F6F\u1FB8-\u1FBB\u1FC8-\u1FCB\u1FD8-\u1FDB\u1FE8-\u1FEC\u1FF8-\u1FFB\u2102\u2107\u210B-\u210D\u2110-\u2112\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u2130-\u2133\u213E\u213F\u2145\u2183\u2C00-\u2C2E\u2C60\u2C62-\u2C64\u2C67\u2C69\u2C6B\u2C6D-\u2C70\u2C72\u2C75\u2C7E-\u2C80\u2C82\u2C84\u2C86\u2C88\u2C8A\u2C8C\u2C8E\u2C90\u2C92\u2C94\u2C96\u2C98\u2C9A\u2C9C\u2C9E\u2CA0\u2CA2\u2CA4\u2CA6\u2CA8\u2CAA\u2CAC\u2CAE\u2CB0\u2CB2\u2CB4\u2CB6\u2CB8\u2CBA\u2CBC\u2CBE\u2CC0\u2CC2\u2CC4\u2CC6\u2CC8\u2CCA\u2CCC\u2CCE\u2CD0\u2CD2\u2CD4\u2CD6\u2CD8\u2CDA\u2CDC\u2CDE\u2CE0\u2CE2\u2CEB\u2CED\u2CF2\uA640\uA642\uA644\uA646\uA648\uA64A\uA64C\uA64E\uA650\uA652\uA654\uA656\uA658\uA65A\uA65C\uA65E\uA660\uA662\uA664\uA666\uA668\uA66A\uA66C\uA680\uA682\uA684\uA686\uA688\uA68A\uA68C\uA68E\uA690\uA692\uA694\uA696\uA698\uA69A\uA722\uA724\uA726\uA728\uA72A\uA72C\uA72E\uA732\uA734\uA736\uA738\uA73A\uA73C\uA73E\uA740\uA742\uA744\uA746\uA748\uA74A\uA74C\uA74E\uA750\uA752\uA754\uA756\uA758\uA75A\uA75C\uA75E\uA760\uA762\uA764\uA766\uA768\uA76A\uA76C\uA76E\uA779\uA77B\uA77D\uA77E\uA780\uA782\uA784\uA786\uA78B\uA78D\uA790\uA792\uA796\uA798\uA79A\uA79C\uA79E\uA7A0\uA7A2\uA7A4\uA7A6\uA7A8\uA7AA-\uA7AD\uA7B0-\uA7B4\uA7B6\uFF21-\uFF3A][a-z\xB5\xDF-\xF6\xF8-\xFF\u0101\u0103\u0105\u0107\u0109\u010B\u010D\u010F\u0111\u0113\u0115\u0117\u0119\u011B\u011D\u011F\u0121\u0123\u0125\u0127\u0129\u012B\u012D\u012F\u0131\u0133\u0135\u0137\u0138\u013A\u013C\u013E\u0140\u0142\u0144\u0146\u0148\u0149\u014B\u014D\u014F\u0151\u0153\u0155\u0157\u0159\u015B\u015D\u015F\u0161\u0163\u0165\u0167\u0169\u016B\u016D\u016F\u0171\u0173\u0175\u0177\u017A\u017C\u017E-\u0180\u0183\u0185\u0188\u018C\u018D\u0192\u0195\u0199-\u019B\u019E\u01A1\u01A3\u01A5\u01A8\u01AA\u01AB\u01AD\u01B0\u01B4\u01B6\u01B9\u01BA\u01BD-\u01BF\u01C6\u01C9\u01CC\u01CE\u01D0\u01D2\u01D4\u01D6\u01D8\u01DA\u01DC\u01DD\u01DF\u01E1\u01E3\u01E5\u01E7\u01E9\u01EB\u01ED\u01EF\u01F0\u01F3\u01F5\u01F9\u01FB\u01FD\u01FF\u0201\u0203\u0205\u0207\u0209\u020B\u020D\u020F\u0211\u0213\u0215\u0217\u0219\u021B\u021D\u021F\u0221\u0223\u0225\u0227\u0229\u022B\u022D\u022F\u0231\u0233-\u0239\u023C\u023F\u0240\u0242\u0247\u0249\u024B\u024D\u024F-\u0293\u0295-\u02AF\u0371\u0373\u0377\u037B-\u037D\u0390\u03AC-\u03CE\u03D0\u03D1\u03D5-\u03D7\u03D9\u03DB\u03DD\u03DF\u03E1\u03E3\u03E5\u03E7\u03E9\u03EB\u03ED\u03EF-\u03F3\u03F5\u03F8\u03FB\u03FC\u0430-\u045F\u0461\u0463\u0465\u0467\u0469\u046B\u046D\u046F\u0471\u0473\u0475\u0477\u0479\u047B\u047D\u047F\u0481\u048B\u048D\u048F\u0491\u0493\u0495\u0497\u0499\u049B\u049D\u049F\u04A1\u04A3\u04A5\u04A7\u04A9\u04AB\u04AD\u04AF\u04B1\u04B3\u04B5\u04B7\u04B9\u04BB\u04BD\u04BF\u04C2\u04C4\u04C6\u04C8\u04CA\u04CC\u04CE\u04CF\u04D1\u04D3\u04D5\u04D7\u04D9\u04DB\u04DD\u04DF\u04E1\u04E3\u04E5\u04E7\u04E9\u04EB\u04ED\u04EF\u04F1\u04F3\u04F5\u04F7\u04F9\u04FB\u04FD\u04FF\u0501\u0503\u0505\u0507\u0509\u050B\u050D\u050F\u0511\u0513\u0515\u0517\u0519\u051B\u051D\u051F\u0521\u0523\u0525\u0527\u0529\u052B\u052D\u052F\u0561-\u0587\u13F8-\u13FD\u1D00-\u1D2B\u1D6B-\u1D77\u1D79-\u1D9A\u1E01\u1E03\u1E05\u1E07\u1E09\u1E0B\u1E0D\u1E0F\u1E11\u1E13\u1E15\u1E17\u1E19\u1E1B\u1E1D\u1E1F\u1E21\u1E23\u1E25\u1E27\u1E29\u1E2B\u1E2D\u1E2F\u1E31\u1E33\u1E35\u1E37\u1E39\u1E3B\u1E3D\u1E3F\u1E41\u1E43\u1E45\u1E47\u1E49\u1E4B\u1E4D\u1E4F\u1E51\u1E53\u1E55\u1E57\u1E59\u1E5B\u1E5D\u1E5F\u1E61\u1E63\u1E65\u1E67\u1E69\u1E6B\u1E6D\u1E6F\u1E71\u1E73\u1E75\u1E77\u1E79\u1E7B\u1E7D\u1E7F\u1E81\u1E83\u1E85\u1E87\u1E89\u1E8B\u1E8D\u1E8F\u1E91\u1E93\u1E95-\u1E9D\u1E9F\u1EA1\u1EA3\u1EA5\u1EA7\u1EA9\u1EAB\u1EAD\u1EAF\u1EB1\u1EB3\u1EB5\u1EB7\u1EB9\u1EBB\u1EBD\u1EBF\u1EC1\u1EC3\u1EC5\u1EC7\u1EC9\u1ECB\u1ECD\u1ECF\u1ED1\u1ED3\u1ED5\u1ED7\u1ED9\u1EDB\u1EDD\u1EDF\u1EE1\u1EE3\u1EE5\u1EE7\u1EE9\u1EEB\u1EED\u1EEF\u1EF1\u1EF3\u1EF5\u1EF7\u1EF9\u1EFB\u1EFD\u1EFF-\u1F07\u1F10-\u1F15\u1F20-\u1F27\u1F30-\u1F37\u1F40-\u1F45\u1F50-\u1F57\u1F60-\u1F67\u1F70-\u1F7D\u1F80-\u1F87\u1F90-\u1F97\u1FA0-\u1FA7\u1FB0-\u1FB4\u1FB6\u1FB7\u1FBE\u1FC2-\u1FC4\u1FC6\u1FC7\u1FD0-\u1FD3\u1FD6\u1FD7\u1FE0-\u1FE7\u1FF2-\u1FF4\u1FF6\u1FF7\u210A\u210E\u210F\u2113\u212F\u2134\u2139\u213C\u213D\u2146-\u2149\u214E\u2184\u2C30-\u2C5E\u2C61\u2C65\u2C66\u2C68\u2C6A\u2C6C\u2C71\u2C73\u2C74\u2C76-\u2C7B\u2C81\u2C83\u2C85\u2C87\u2C89\u2C8B\u2C8D\u2C8F\u2C91\u2C93\u2C95\u2C97\u2C99\u2C9B\u2C9D\u2C9F\u2CA1\u2CA3\u2CA5\u2CA7\u2CA9\u2CAB\u2CAD\u2CAF\u2CB1\u2CB3\u2CB5\u2CB7\u2CB9\u2CBB\u2CBD\u2CBF\u2CC1\u2CC3\u2CC5\u2CC7\u2CC9\u2CCB\u2CCD\u2CCF\u2CD1\u2CD3\u2CD5\u2CD7\u2CD9\u2CDB\u2CDD\u2CDF\u2CE1\u2CE3\u2CE4\u2CEC\u2CEE\u2CF3\u2D00-\u2D25\u2D27\u2D2D\uA641\uA643\uA645\uA647\uA649\uA64B\uA64D\uA64F\uA651\uA653\uA655\uA657\uA659\uA65B\uA65D\uA65F\uA661\uA663\uA665\uA667\uA669\uA66B\uA66D\uA681\uA683\uA685\uA687\uA689\uA68B\uA68D\uA68F\uA691\uA693\uA695\uA697\uA699\uA69B\uA723\uA725\uA727\uA729\uA72B\uA72D\uA72F-\uA731\uA733\uA735\uA737\uA739\uA73B\uA73D\uA73F\uA741\uA743\uA745\uA747\uA749\uA74B\uA74D\uA74F\uA751\uA753\uA755\uA757\uA759\uA75B\uA75D\uA75F\uA761\uA763\uA765\uA767\uA769\uA76B\uA76D\uA76F\uA771-\uA778\uA77A\uA77C\uA77F\uA781\uA783\uA785\uA787\uA78C\uA78E\uA791\uA793-\uA795\uA797\uA799\uA79B\uA79D\uA79F\uA7A1\uA7A3\uA7A5\uA7A7\uA7A9\uA7B5\uA7B7\uA7FA\uAB30-\uAB5A\uAB60-\uAB65\uAB70-\uABBF\uFB00-\uFB06\uFB13-\uFB17\uFF41-\uFF5A])/g
/***/ }),
/* 255 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.horizontalCenter = undefined;
var _react = __webpack_require__(11);
var _react2 = _interopRequireDefault(_react);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var horizontalCenter = exports.horizontalCenter = function horizontalCenter(Component) {
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
_ref$rAlign = _ref.rAlign,
rAlign = _ref$rAlign === undefined ? false : _ref$rAlign,
_ref$space = _ref.space,
space = _ref$space === undefined ? 4 : _ref$space;
return function (props) {
return _react2.default.createElement(
Component,
props,
_react2.default.createElement(
'div',
{ style: { display: 'inline-flex', justifyContent: 'center', 'alignItems': 'center' } },
_react.Children.toArray(props.children).map(function (child, idx) {
var spacerField = rAlign ? 'paddingLeft' : 'paddingRight';
return _react2.default.createElement(
'div',
{ key: idx, style: _defineProperty({ display: 'inline-block' }, spacerField, space) },
child
);
})
)
);
};
};
exports.default = horizontalCenter;
/***/ }),
/* 256 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var play = exports.play = { "viewBox": "0 0 1408 1792", "children": [{ "name": "path", "attribs": { "d": "M1384 927l-1328 738q-23 13-39.5 3t-16.5-36v-1472q0-26 16.5-36t39.5 3l1328 738q23 13 23 31t-23 31z" } }] };
/***/ }),
/* 257 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var pause = exports.pause = { "viewBox": "0 0 1536 1792", "children": [{ "name": "path", "attribs": { "d": "M1536 192v1408q0 26-19 45t-45 19h-512q-26 0-45-19t-19-45v-1408q0-26 19-45t45-19h512q26 0 45 19t19 45zM640 192v1408q0 26-19 45t-45 19h-512q-26 0-45-19t-19-45v-1408q0-26 19-45t45-19h512q26 0 45 19t19 45z" } }] };
/***/ }),
/* 258 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var copy = exports.copy = { "viewBox": "0 0 1792 1792", "children": [{ "name": "path", "attribs": { "d": "M1696 384q40 0 68 28t28 68v1216q0 40-28 68t-68 28h-960q-40 0-68-28t-28-68v-288h-544q-40 0-68-28t-28-68v-672q0-40 20-88t48-76l408-408q28-28 76-48t88-20h416q40 0 68 28t28 68v328q68-40 128-40h416zM1152 597l-299 299h299v-299zM512 213l-299 299h299v-299zM708 860l316-316v-416h-384v416q0 40-28 68t-68 28h-416v640h512v-256q0-40 20-88t48-76zM1664 1664v-1152h-384v416q0 40-28 68t-68 28h-416v640h896z" } }] };
/***/ }),
/* 259 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var heart = exports.heart = { "viewBox": "0 0 1792 1792", "children": [{ "name": "path", "attribs": { "d": "M896 1664q-26 0-44-18l-624-602q-10-8-27.5-26t-55.5-65.5-68-97.5-53.5-121-23.5-138q0-220 127-344t351-124q62 0 126.5 21.5t120 58 95.5 68.5 76 68q36-36 76-68t95.5-68.5 120-58 126.5-21.5q224 0 351 124t127 344q0 221-229 450l-623 600q-18 18-44 18z" } }] };
/***/ }),
/* 260 */
/***/ (function(module, exports) {
// removed by extract-text-webpack-plugin
/***/ }),
/* 261 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
exports.__esModule = true;
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
exports.default = function (_ref) {
var _class, _temp2;
var Component = _ref.Component,
createElement = _ref.createElement;
return _temp2 = _class = function (_Component) {
_inherits(ReactHint, _Component);
function ReactHint() {
var _temp, _this, _ret;
_classCallCheck(this, ReactHint);
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return _ret = (_temp = (_this = _possibleConstructorReturn(this, _Component.call.apply(_Component, [this].concat(args))), _this), _this.state = { target: null }, _this._containerStyle = { position: 'relative' }, _this.toggleEvents = function (_ref2, flag) {
var events = _ref2.events,
_ref2$events = _ref2.events,
click = _ref2$events.click,
focus = _ref2$events.focus,
hover = _ref2$events.hover;
var action = flag ? 'addEventListener' : 'removeEventListener';
var hasEvents = events === true;(click || hasEvents) && document[action]('click', _this.toggleHint);(focus || hasEvents) && document[action]('focusin', _this.toggleHint);(hover || hasEvents) && document[action]('mouseover', _this.toggleHint);(click || hover || hasEvents) && document[action]('touchend', _this.toggleHint);
}, _this.toggleHint = function () {
var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
_ref3$target = _ref3.target,
target = _ref3$target === undefined ? null : _ref3$target;
clearTimeout(_this._timeout);
_this._timeout = setTimeout(function () {
return _this.setState(function () {
return {
target: _this.getHint(target)
};
});
}, _this.props.delay);
}, _this.getHint = function (el) {
var _this$props = _this.props,
attribute = _this$props.attribute,
persist = _this$props.persist;
var target = _this.state.target;
while (el) {
if (el === document) break;
if (persist && el === _this._hint) return target;
if (el.hasAttribute(attribute)) return el;
el = el.parentNode;
}return null;
}, _this.shallowEqual = function (a, b) {
var keys = Object.keys(a);
return keys.length === Object.keys(b).length && keys.reduce(function (result, key) {
return result && (typeof a[key] === 'function' && typeof b[key] === 'function' || a[key] === b[key]);
}, true);
}, _this.getHintData = function (_ref4, _ref5) {
var target = _ref4.target;
var attribute = _ref5.attribute,
position = _ref5.position;
var content = target.getAttribute(attribute) || '';
var at = target.getAttribute(attribute + '-at') || position;
var _this$_container$getB = _this._container.getBoundingClientRect(),
containerTop = _this$_container$getB.top,
containerLeft = _this$_container$getB.left;
var _this$_hint$getBoundi = _this._hint.getBoundingClientRect(),
hintWidth = _this$_hint$getBoundi.width,
hintHeight = _this$_hint$getBoundi.height;
var _target$getBoundingCl = target.getBoundingClientRect(),
targetTop = _target$getBoundingCl.top,
targetLeft = _target$getBoundingCl.left,
targetWidth = _target$getBoundingCl.width,
targetHeight = _target$getBoundingCl.height;
var top = void 0,
left = void 0;
switch (at) {
case 'left':
top = targetHeight - hintHeight >> 1;
left = -hintWidth;
break;
case 'right':
top = targetHeight - hintHeight >> 1;
left = targetWidth;
break;
case 'bottom':
top = targetHeight;
left = targetWidth - hintWidth >> 1;
break;
case 'top':
default:
top = -hintHeight;
left = targetWidth - hintWidth >> 1;
}
return {
content: content, at: at,
top: top + targetTop - containerTop,
left: left + targetLeft - containerLeft
};
}, _temp), _possibleConstructorReturn(_this, _ret);
}
ReactHint.prototype.componentDidMount = function componentDidMount() {
this.toggleEvents(this.props, true);
};
ReactHint.prototype.componentWillUnmount = function componentWillUnmount() {
this.toggleEvents(this.props, false);
clearTimeout(this._timeout);
};
ReactHint.prototype.shouldComponentUpdate = function shouldComponentUpdate(props, state) {
return !this.shallowEqual(state, this.state) || !this.shallowEqual(props, this.props);
};
ReactHint.prototype.componentDidUpdate = function componentDidUpdate() {
if (this.state.target) this.setState(this.getHintData);
};
ReactHint.prototype.render = function render() {
var _this2 = this;
var _props = this.props,
className = _props.className,
onRenderContent = _props.onRenderContent;
var _state = this.state,
target = _state.target,
content = _state.content,
at = _state.at,
top = _state.top,
left = _state.left;
return createElement(
'div',
{ ref: function ref(_ref7) {
return _this2._container = _ref7;
},
style: this._containerStyle },
target && createElement(
'div',
{ className: className + ' ' + className + '--' + at,
ref: function ref(_ref6) {
return _this2._hint = _ref6;
},
style: { top: top, left: left } },
onRenderContent ? onRenderContent(target, content) : createElement(
'div',
{ className: className + '__content' },
content
)
)
);
};
return ReactHint;
}(Component), _class.defaultProps = {
attribute: 'data-rh',
className: 'react-hint',
delay: 0,
events: false,
onRenderContent: null,
persist: false,
position: 'top'
}, _temp2;
};
module.exports = exports['default'];
/***/ }),
/* 262 */
/***/ (function(module, exports) {
// removed by extract-text-webpack-plugin
/***/ }),
/* 263 */
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(264);
/***/ }),
/* 264 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var utils = __webpack_require__(34);
var bind = __webpack_require__(203);
var Axios = __webpack_require__(266);
var defaults = __webpack_require__(191);
/**
* Create an instance of Axios
*
* @param {Object} defaultConfig The default config for the instance
* @return {Axios} A new instance of Axios
*/
function createInstance(defaultConfig) {
var context = new Axios(defaultConfig);
var instance = bind(Axios.prototype.request, context);
// Copy axios.prototype to instance
utils.extend(instance, Axios.prototype, context);
// Copy context to instance
utils.extend(instance, context);
return instance;
}
// Create the default instance to be exported
var axios = createInstance(defaults);
// Expose Axios class to allow class inheritance
axios.Axios = Axios;
// Factory for creating new instances
axios.create = function create(instanceConfig) {
return createInstance(utils.merge(defaults, instanceConfig));
};
// Expose Cancel & CancelToken
axios.Cancel = __webpack_require__(207);
axios.CancelToken = __webpack_require__(280);
axios.isCancel = __webpack_require__(206);
// Expose all/spread
axios.all = function all(promises) {
return Promise.all(promises);
};
axios.spread = __webpack_require__(281);
module.exports = axios;
// Allow use of default import syntax in TypeScript
module.exports.default = axios;
/***/ }),
/* 265 */
/***/ (function(module, exports) {
/*!
* Determine if an object is a Buffer
*
* @author Feross Aboukhadijeh <https://feross.org>
* @license MIT
*/
// The _isBuffer check is for Safari 5-7 support, because it's missing
// Object.prototype.constructor. Remove this eventually
module.exports = function (obj) {
return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)
}
function isBuffer (obj) {
return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)
}
// For Node v0.10 support. Remove this eventually.
function isSlowBuffer (obj) {
return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))
}
/***/ }),
/* 266 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var defaults = __webpack_require__(191);
var utils = __webpack_require__(34);
var InterceptorManager = __webpack_require__(275);
var dispatchRequest = __webpack_require__(276);
/**
* Create a new instance of Axios
*
* @param {Object} instanceConfig The default config for the instance
*/
function Axios(instanceConfig) {
this.defaults = instanceConfig;
this.interceptors = {
request: new InterceptorManager(),
response: new InterceptorManager()
};
}
/**
* Dispatch a request
*
* @param {Object} config The config specific for this request (merged with this.defaults)
*/
Axios.prototype.request = function request(config) {
/*eslint no-param-reassign:0*/
// Allow for axios('example/url'[, config]) a la fetch API
if (typeof config === 'string') {
config = utils.merge({
url: arguments[0]
}, arguments[1]);
}
config = utils.merge(defaults, this.defaults, { method: 'get' }, config);
config.method = config.method.toLowerCase();
// Hook up interceptors middleware
var chain = [dispatchRequest, undefined];
var promise = Promise.resolve(config);
this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
chain.unshift(interceptor.fulfilled, interceptor.rejected);
});
this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {
chain.push(interceptor.fulfilled, interceptor.rejected);
});
while (chain.length) {
promise = promise.then(chain.shift(), chain.shift());
}
return promise;
};
// Provide aliases for supported request methods
utils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {
/*eslint func-names:0*/
Axios.prototype[method] = function(url, config) {
return this.request(utils.merge(config || {}, {
method: method,
url: url
}));
};
});
utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
/*eslint func-names:0*/
Axios.prototype[method] = function(url, data, config) {
return this.request(utils.merge(config || {}, {
method: method,
url: url,
data: data
}));
};
});
module.exports = Axios;
/***/ }),
/* 267 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var utils = __webpack_require__(34);
module.exports = function normalizeHeaderName(headers, normalizedName) {
utils.forEach(headers, function processHeader(value, name) {
if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) {
headers[normalizedName] = value;
delete headers[name];
}
});
};
/***/ }),
/* 268 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var createError = __webpack_require__(205);
/**
* Resolve or reject a Promise based on response status.
*
* @param {Function} resolve A function that resolves the promise.
* @param {Function} reject A function that rejects the promise.
* @param {object} response The response.
*/
module.exports = function settle(resolve, reject, response) {
var validateStatus = response.config.validateStatus;
// Note: status is not exposed by XDomainRequest
if (!response.status || !validateStatus || validateStatus(response.status)) {
resolve(response);
} else {
reject(createError(
'Request failed with status code ' + response.status,
response.config,
null,
response.request,
response
));
}
};
/***/ }),
/* 269 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Update an Error with the specified config, error code, and response.
*
* @param {Error} error The error to update.
* @param {Object} config The config.
* @param {string} [code] The error code (for example, 'ECONNABORTED').
* @param {Object} [request] The request.
* @param {Object} [response] The response.
* @returns {Error} The error.
*/
module.exports = function enhanceError(error, config, code, request, response) {
error.config = config;
if (code) {
error.code = code;
}
error.request = request;
error.response = response;
return error;
};
/***/ }),
/* 270 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var utils = __webpack_require__(34);
function encode(val) {
return encodeURIComponent(val).
replace(/%40/gi, '@').
replace(/%3A/gi, ':').
replace(/%24/g, '$').
replace(/%2C/gi, ',').
replace(/%20/g, '+').
replace(/%5B/gi, '[').
replace(/%5D/gi, ']');
}
/**
* Build a URL by appending params to the end
*
* @param {string} url The base of the url (e.g., http://www.google.com)
* @param {object} [params] The params to be appended
* @returns {string} The formatted url
*/
module.exports = function buildURL(url, params, paramsSerializer) {
/*eslint no-param-reassign:0*/
if (!params) {
return url;
}
var serializedParams;
if (paramsSerializer) {
serializedParams = paramsSerializer(params);
} else if (utils.isURLSearchParams(params)) {
serializedParams = params.toString();
} else {
var parts = [];
utils.forEach(params, function serialize(val, key) {
if (val === null || typeof val === 'undefined') {
return;
}
if (utils.isArray(val)) {
key = key + '[]';
}
if (!utils.isArray(val)) {
val = [val];
}
utils.forEach(val, function parseValue(v) {
if (utils.isDate(v)) {
v = v.toISOString();
} else if (utils.isObject(v)) {
v = JSON.stringify(v);
}
parts.push(encode(key) + '=' + encode(v));
});
});
serializedParams = parts.join('&');
}
if (serializedParams) {
url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;
}
return url;
};
/***/ }),
/* 271 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var utils = __webpack_require__(34);
// Headers whose duplicates are ignored by node
// c.f. https://nodejs.org/api/http.html#http_message_headers
var ignoreDuplicateOf = [
'age', 'authorization', 'content-length', 'content-type', 'etag',
'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',
'last-modified', 'location', 'max-forwards', 'proxy-authorization',
'referer', 'retry-after', 'user-agent'
];
/**
* Parse headers into an object
*
* ```
* Date: Wed, 27 Aug 2014 08:58:49 GMT
* Content-Type: application/json
* Connection: keep-alive
* Transfer-Encoding: chunked
* ```
*
* @param {String} headers Headers needing to be parsed
* @returns {Object} Headers parsed into an object
*/
module.exports = function parseHeaders(headers) {
var parsed = {};
var key;
var val;
var i;
if (!headers) { return parsed; }
utils.forEach(headers.split('\n'), function parser(line) {
i = line.indexOf(':');
key = utils.trim(line.substr(0, i)).toLowerCase();
val = utils.trim(line.substr(i + 1));
if (key) {
if (parsed[key] && ignoreDuplicateOf.indexOf(key) >= 0) {
return;
}
if (key === 'set-cookie') {
parsed[key] = (parsed[key] ? parsed[key] : []).concat([val]);
} else {
parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
}
}
});
return parsed;
};
/***/ }),
/* 272 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var utils = __webpack_require__(34);
module.exports = (
utils.isStandardBrowserEnv() ?
// Standard browser envs have full support of the APIs needed to test
// whether the request URL is of the same origin as current location.
(function standardBrowserEnv() {
var msie = /(msie|trident)/i.test(navigator.userAgent);
var urlParsingNode = document.createElement('a');
var originURL;
/**
* Parse a URL to discover it's components
*
* @param {String} url The URL to be parsed
* @returns {Object}
*/
function resolveURL(url) {
var href = url;
if (msie) {
// IE needs attribute set twice to normalize properties
urlParsingNode.setAttribute('href', href);
href = urlParsingNode.href;
}
urlParsingNode.setAttribute('href', href);
// urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
return {
href: urlParsingNode.href,
protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',
host: urlParsingNode.host,
search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '',
hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
hostname: urlParsingNode.hostname,
port: urlParsingNode.port,
pathname: (urlParsingNode.pathname.charAt(0) === '/') ?
urlParsingNode.pathname :
'/' + urlParsingNode.pathname
};
}
originURL = resolveURL(window.location.href);
/**
* Determine if a URL shares the same origin as the current location
*
* @param {String} requestURL The URL to test
* @returns {boolean} True if URL shares the same origin, otherwise false
*/
return function isURLSameOrigin(requestURL) {
var parsed = (utils.isString(requestURL)) ? resolveURL(requestURL) : requestURL;
return (parsed.protocol === originURL.protocol &&
parsed.host === originURL.host);
};
})() :
// Non standard browser envs (web workers, react-native) lack needed support.
(function nonStandardBrowserEnv() {
return function isURLSameOrigin() {
return true;
};
})()
);
/***/ }),
/* 273 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
// btoa polyfill for IE<10 courtesy https://github.com/davidchambers/Base64.js
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
function E() {
this.message = 'String contains an invalid character';
}
E.prototype = new Error;
E.prototype.code = 5;
E.prototype.name = 'InvalidCharacterError';
function btoa(input) {
var str = String(input);
var output = '';
for (
// initialize result and counter
var block, charCode, idx = 0, map = chars;
// if the next str index does not exist:
// change the mapping table to "="
// check if d has no fractional digits
str.charAt(idx | 0) || (map = '=', idx % 1);
// "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8
output += map.charAt(63 & block >> 8 - idx % 1 * 8)
) {
charCode = str.charCodeAt(idx += 3 / 4);
if (charCode > 0xFF) {
throw new E();
}
block = block << 8 | charCode;
}
return output;
}
module.exports = btoa;
/***/ }),
/* 274 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var utils = __webpack_require__(34);
module.exports = (
utils.isStandardBrowserEnv() ?
// Standard browser envs support document.cookie
(function standardBrowserEnv() {
return {
write: function write(name, value, expires, path, domain, secure) {
var cookie = [];
cookie.push(name + '=' + encodeURIComponent(value));
if (utils.isNumber(expires)) {
cookie.push('expires=' + new Date(expires).toGMTString());
}
if (utils.isString(path)) {
cookie.push('path=' + path);
}
if (utils.isString(domain)) {
cookie.push('domain=' + domain);
}
if (secure === true) {
cookie.push('secure');
}
document.cookie = cookie.join('; ');
},
read: function read(name) {
var match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)'));
return (match ? decodeURIComponent(match[3]) : null);
},
remove: function remove(name) {
this.write(name, '', Date.now() - 86400000);
}
};
})() :
// Non standard browser env (web workers, react-native) lack needed support.
(function nonStandardBrowserEnv() {
return {
write: function write() {},
read: function read() { return null; },
remove: function remove() {}
};
})()
);
/***/ }),
/* 275 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var utils = __webpack_require__(34);
function InterceptorManager() {
this.handlers = [];
}
/**
* Add a new interceptor to the stack
*
* @param {Function} fulfilled The function to handle `then` for a `Promise`
* @param {Function} rejected The function to handle `reject` for a `Promise`
*
* @return {Number} An ID used to remove interceptor later
*/
InterceptorManager.prototype.use = function use(fulfilled, rejected) {
this.handlers.push({
fulfilled: fulfilled,
rejected: rejected
});
return this.handlers.length - 1;
};
/**
* Remove an interceptor from the stack
*
* @param {Number} id The ID that was returned by `use`
*/
InterceptorManager.prototype.eject = function eject(id) {
if (this.handlers[id]) {
this.handlers[id] = null;
}
};
/**
* Iterate over all the registered interceptors
*
* This method is particularly useful for skipping over any
* interceptors that may have become `null` calling `eject`.
*
* @param {Function} fn The function to call for each interceptor
*/
InterceptorManager.prototype.forEach = function forEach(fn) {
utils.forEach(this.handlers, function forEachHandler(h) {
if (h !== null) {
fn(h);
}
});
};
module.exports = InterceptorManager;
/***/ }),
/* 276 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var utils = __webpack_require__(34);
var transformData = __webpack_require__(277);
var isCancel = __webpack_require__(206);
var defaults = __webpack_require__(191);
var isAbsoluteURL = __webpack_require__(278);
var combineURLs = __webpack_require__(279);
/**
* Throws a `Cancel` if cancellation has been requested.
*/
function throwIfCancellationRequested(config) {
if (config.cancelToken) {
config.cancelToken.throwIfRequested();
}
}
/**
* Dispatch a request to the server using the configured adapter.
*
* @param {object} config The config that is to be used for the request
* @returns {Promise} The Promise to be fulfilled
*/
module.exports = function dispatchRequest(config) {
throwIfCancellationRequested(config);
// Support baseURL config
if (config.baseURL && !isAbsoluteURL(config.url)) {
config.url = combineURLs(config.baseURL, config.url);
}
// Ensure headers exist
config.headers = config.headers || {};
// Transform request data
config.data = transformData(
config.data,
config.headers,
config.transformRequest
);
// Flatten headers
config.headers = utils.merge(
config.headers.common || {},
config.headers[config.method] || {},
config.headers || {}
);
utils.forEach(
['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],
function cleanHeaderConfig(method) {
delete config.headers[method];
}
);
var adapter = config.adapter || defaults.adapter;
return adapter(config).then(function onAdapterResolution(response) {
throwIfCancellationRequested(config);
// Transform response data
response.data = transformData(
response.data,
response.headers,
config.transformResponse
);
return response;
}, function onAdapterRejection(reason) {
if (!isCancel(reason)) {
throwIfCancellationRequested(config);
// Transform response data
if (reason && reason.response) {
reason.response.data = transformData(
reason.response.data,
reason.response.headers,
config.transformResponse
);
}
}
return Promise.reject(reason);
});
};
/***/ }),
/* 277 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var utils = __webpack_require__(34);
/**
* Transform the data for a request or a response
*
* @param {Object|String} data The data to be transformed
* @param {Array} headers The headers for the request or response
* @param {Array|Function} fns A single function or Array of functions
* @returns {*} The resulting transformed data
*/
module.exports = function transformData(data, headers, fns) {
/*eslint no-param-reassign:0*/
utils.forEach(fns, function transform(fn) {
data = fn(data, headers);
});
return data;
};
/***/ }),
/* 278 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Determines whether the specified URL is absolute
*
* @param {string} url The URL to test
* @returns {boolean} True if the specified URL is absolute, otherwise false
*/
module.exports = function isAbsoluteURL(url) {
// A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL).
// RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
// by any combination of letters, digits, plus, period, or hyphen.
return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url);
};
/***/ }),
/* 279 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Creates a new URL by combining the specified URLs
*
* @param {string} baseURL The base URL
* @param {string} relativeURL The relative URL
* @returns {string} The combined URL
*/
module.exports = function combineURLs(baseURL, relativeURL) {
return relativeURL
? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '')
: baseURL;
};
/***/ }),
/* 280 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var Cancel = __webpack_require__(207);
/**
* A `CancelToken` is an object that can be used to request cancellation of an operation.
*
* @class
* @param {Function} executor The executor function.
*/
function CancelToken(executor) {
if (typeof executor !== 'function') {
throw new TypeError('executor must be a function.');
}
var resolvePromise;
this.promise = new Promise(function promiseExecutor(resolve) {
resolvePromise = resolve;
});
var token = this;
executor(function cancel(message) {
if (token.reason) {
// Cancellation has already been requested
return;
}
token.reason = new Cancel(message);
resolvePromise(token.reason);
});
}
/**
* Throws a `Cancel` if cancellation has been requested.
*/
CancelToken.prototype.throwIfRequested = function throwIfRequested() {
if (this.reason) {
throw this.reason;
}
};
/**
* Returns an object that contains a new `CancelToken` and a function that, when called,
* cancels the `CancelToken`.
*/
CancelToken.source = function source() {
var cancel;
var token = new CancelToken(function executor(c) {
cancel = c;
});
return {
token: token,
cancel: cancel
};
};
module.exports = CancelToken;
/***/ }),
/* 281 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Syntactic sugar for invoking a function and expanding an array for arguments.
*
* Common use case would be to use `Function.prototype.apply`.
*
* ```js
* function f(x, y, z) {}
* var args = [1, 2, 3];
* f.apply(null, args);
* ```
*
* With `spread` this example can be re-written.
*
* ```js
* spread(function(x, y, z) {})([1, 2, 3]);
* ```
*
* @param {Function} callback
* @returns {Function}
*/
module.exports = function spread(callback) {
return function wrap(arr) {
return callback.apply(null, arr);
};
};
/***/ }),
/* 282 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _skylight = __webpack_require__(283);
Object.defineProperty(exports, 'default', {
enumerable: true,
get: function get() {
return _interopRequireDefault(_skylight).default;
}
});
var _skylightstateless = __webpack_require__(208);
Object.defineProperty(exports, 'SkyLightStateless', {
enumerable: true,
get: function get() {
return _interopRequireDefault(_skylightstateless).default;
}
});
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/***/ }),
/* 283 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(11);
var _react2 = _interopRequireDefault(_react);
var _propTypes = __webpack_require__(25);
var _propTypes2 = _interopRequireDefault(_propTypes);
var _skylightstateless = __webpack_require__(208);
var _skylightstateless2 = _interopRequireDefault(_skylightstateless);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var isOpening = function isOpening(s1, s2) {
return !s1.isVisible && s2.isVisible;
};
var isClosing = function isClosing(s1, s2) {
return s1.isVisible && !s2.isVisible;
};
var SkyLight = function (_React$Component) {
_inherits(SkyLight, _React$Component);
function SkyLight(props) {
_classCallCheck(this, SkyLight);
var _this = _possibleConstructorReturn(this, (SkyLight.__proto__ || Object.getPrototypeOf(SkyLight)).call(this, props));
_this.state = { isVisible: false };
return _this;
}
_createClass(SkyLight, [{
key: 'componentWillUpdate',
value: function componentWillUpdate(nextProps, nextState) {
if (isOpening(this.state, nextState) && this.props.beforeOpen) {
this.props.beforeOpen();
}
if (isClosing(this.state, nextState) && this.props.beforeClose) {
this.props.beforeClose();
}
}
}, {
key: 'componentDidUpdate',
value: function componentDidUpdate(prevProps, prevState) {
if (isOpening(prevState, this.state) && this.props.afterOpen) {
this.props.afterOpen();
}
if (isClosing(prevState, this.state) && this.props.afterClose) {
this.props.afterClose();
}
}
}, {
key: 'show',
value: function show() {
this.setState({ isVisible: true });
}
}, {
key: 'hide',
value: function hide() {
this.setState({ isVisible: false });
}
}, {
key: '_onOverlayClicked',
value: function _onOverlayClicked() {
if (this.props.hideOnOverlayClicked) {
this.hide();
}
if (this.props.onOverlayClicked) {
this.props.onOverlayClicked();
}
}
}, {
key: 'render',
value: function render() {
var _this2 = this;
return _react2.default.createElement(_skylightstateless2.default, _extends({}, this.props, {
isVisible: this.state.isVisible,
onOverlayClicked: function onOverlayClicked() {
return _this2._onOverlayClicked();
},
onCloseClicked: function onCloseClicked() {
return _this2.hide();
}
}));
}
}]);
return SkyLight;
}(_react2.default.Component);
exports.default = SkyLight;
SkyLight.displayName = 'SkyLight';
SkyLight.propTypes = _extends({}, _skylightstateless2.default.sharedPropTypes, {
afterClose: _propTypes2.default.func,
afterOpen: _propTypes2.default.func,
beforeClose: _propTypes2.default.func,
beforeOpen: _propTypes2.default.func,
hideOnOverlayClicked: _propTypes2.default.bool
});
SkyLight.defaultProps = _extends({}, _skylightstateless2.default.defaultProps, {
hideOnOverlayClicked: false
});
/***/ }),
/* 284 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var styles = {
overlayStyles: {
position: 'fixed',
top: '0px',
left: '0px',
width: '100%',
height: '100%',
zIndex: '99',
backgroundColor: 'rgba(0,0,0,0.3)',
transitionProperty: 'all',
transitionTimingFunction: 'ease',
display: 'none'
},
dialogStyles: {
width: '50%',
height: '400px',
position: 'fixed',
top: '50%',
left: '50%',
marginTop: '-200px',
marginLeft: '-25%',
backgroundColor: '#fff',
borderRadius: '2px',
zIndex: '100',
padding: '15px',
boxShadow: '0px 0px 4px rgba(0,0,0,.14),0px 4px 8px rgba(0,0,0,.28)'
},
animationBase: {
transform: 'scale(0)',
transitionProperty: 'transform',
transitionTimingFunction: 'ease'
},
animationOpen: {
transform: 'scale(1)',
transitionProperty: 'transform',
transitionTimingFunction: 'ease'
},
title: {
marginTop: '0px'
},
closeButtonStyle: {
cursor: 'pointer',
position: 'absolute',
fontSize: '1.8em',
right: '10px',
top: '0px'
}
};
exports.default = styles;
/***/ }),
/* 285 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (target) {
if (target === null) {
throw new TypeError('Cannot convert undefined or null to object');
}
var newTarget = target;
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
for (var index = 0; index < args.length; index++) {
var source = args[index];
if (source !== null) {
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
newTarget[key] = source[key];
}
}
}
}
return newTarget;
};
/***/ })
/******/ ]);