datatable.directory codebase
https://datatable.directory/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
47387 lines
1.3 MiB
47387 lines
1.3 MiB
/******/ (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 = "/"; |
|
/******/ |
|
/******/ // Load entry module and return exports |
|
/******/ return __webpack_require__(__webpack_require__.s = 11); |
|
/******/ }) |
|
/************************************************************************/ |
|
/******/ ([ |
|
/* 0 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
"use strict"; |
|
|
|
|
|
var bind = __webpack_require__(5); |
|
var isBuffer = __webpack_require__(19); |
|
|
|
/*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 |
|
}; |
|
|
|
|
|
/***/ }), |
|
/* 1 */ |
|
/***/ (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; |
|
|
|
|
|
/***/ }), |
|
/* 2 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
"use strict"; |
|
/* WEBPACK VAR INJECTION */(function(process) { |
|
|
|
var utils = __webpack_require__(0); |
|
var normalizeHeaderName = __webpack_require__(21); |
|
|
|
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__(7); |
|
} else if (typeof process !== 'undefined') { |
|
// For node use HTTP adapter |
|
adapter = __webpack_require__(7); |
|
} |
|
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; |
|
}], |
|
|
|
/** |
|
* A timeout in milliseconds to abort a request. If set to 0 (default) a |
|
* timeout is not created. |
|
*/ |
|
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__(6))) |
|
|
|
/***/ }), |
|
/* 3 */ |
|
/***/ (function(module, __webpack_exports__, __webpack_require__) { |
|
|
|
"use strict"; |
|
Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); |
|
/* WEBPACK VAR INJECTION */(function(global) {/**! |
|
* @fileOverview Kickass library to create and place poppers near their reference elements. |
|
* @version 1.14.3 |
|
* @license |
|
* Copyright (c) 2016 Federico Zivolo and contributors |
|
* |
|
* 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. |
|
*/ |
|
var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined'; |
|
|
|
var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox']; |
|
var timeoutDuration = 0; |
|
for (var i = 0; i < longerTimeoutBrowsers.length; i += 1) { |
|
if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) { |
|
timeoutDuration = 1; |
|
break; |
|
} |
|
} |
|
|
|
function microtaskDebounce(fn) { |
|
var called = false; |
|
return function () { |
|
if (called) { |
|
return; |
|
} |
|
called = true; |
|
window.Promise.resolve().then(function () { |
|
called = false; |
|
fn(); |
|
}); |
|
}; |
|
} |
|
|
|
function taskDebounce(fn) { |
|
var scheduled = false; |
|
return function () { |
|
if (!scheduled) { |
|
scheduled = true; |
|
setTimeout(function () { |
|
scheduled = false; |
|
fn(); |
|
}, timeoutDuration); |
|
} |
|
}; |
|
} |
|
|
|
var supportsMicroTasks = isBrowser && window.Promise; |
|
|
|
/** |
|
* Create a debounced version of a method, that's asynchronously deferred |
|
* but called in the minimum time possible. |
|
* |
|
* @method |
|
* @memberof Popper.Utils |
|
* @argument {Function} fn |
|
* @returns {Function} |
|
*/ |
|
var debounce = supportsMicroTasks ? microtaskDebounce : taskDebounce; |
|
|
|
/** |
|
* Check if the given variable is a function |
|
* @method |
|
* @memberof Popper.Utils |
|
* @argument {Any} functionToCheck - variable to check |
|
* @returns {Boolean} answer to: is a function? |
|
*/ |
|
function isFunction(functionToCheck) { |
|
var getType = {}; |
|
return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]'; |
|
} |
|
|
|
/** |
|
* Get CSS computed property of the given element |
|
* @method |
|
* @memberof Popper.Utils |
|
* @argument {Eement} element |
|
* @argument {String} property |
|
*/ |
|
function getStyleComputedProperty(element, property) { |
|
if (element.nodeType !== 1) { |
|
return []; |
|
} |
|
// NOTE: 1 DOM access here |
|
var css = getComputedStyle(element, null); |
|
return property ? css[property] : css; |
|
} |
|
|
|
/** |
|
* Returns the parentNode or the host of the element |
|
* @method |
|
* @memberof Popper.Utils |
|
* @argument {Element} element |
|
* @returns {Element} parent |
|
*/ |
|
function getParentNode(element) { |
|
if (element.nodeName === 'HTML') { |
|
return element; |
|
} |
|
return element.parentNode || element.host; |
|
} |
|
|
|
/** |
|
* Returns the scrolling parent of the given element |
|
* @method |
|
* @memberof Popper.Utils |
|
* @argument {Element} element |
|
* @returns {Element} scroll parent |
|
*/ |
|
function getScrollParent(element) { |
|
// Return body, `getScroll` will take care to get the correct `scrollTop` from it |
|
if (!element) { |
|
return document.body; |
|
} |
|
|
|
switch (element.nodeName) { |
|
case 'HTML': |
|
case 'BODY': |
|
return element.ownerDocument.body; |
|
case '#document': |
|
return element.body; |
|
} |
|
|
|
// Firefox want us to check `-x` and `-y` variations as well |
|
|
|
var _getStyleComputedProp = getStyleComputedProperty(element), |
|
overflow = _getStyleComputedProp.overflow, |
|
overflowX = _getStyleComputedProp.overflowX, |
|
overflowY = _getStyleComputedProp.overflowY; |
|
|
|
if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) { |
|
return element; |
|
} |
|
|
|
return getScrollParent(getParentNode(element)); |
|
} |
|
|
|
var isIE11 = isBrowser && !!(window.MSInputMethodContext && document.documentMode); |
|
var isIE10 = isBrowser && /MSIE 10/.test(navigator.userAgent); |
|
|
|
/** |
|
* Determines if the browser is Internet Explorer |
|
* @method |
|
* @memberof Popper.Utils |
|
* @param {Number} version to check |
|
* @returns {Boolean} isIE |
|
*/ |
|
function isIE(version) { |
|
if (version === 11) { |
|
return isIE11; |
|
} |
|
if (version === 10) { |
|
return isIE10; |
|
} |
|
return isIE11 || isIE10; |
|
} |
|
|
|
/** |
|
* Returns the offset parent of the given element |
|
* @method |
|
* @memberof Popper.Utils |
|
* @argument {Element} element |
|
* @returns {Element} offset parent |
|
*/ |
|
function getOffsetParent(element) { |
|
if (!element) { |
|
return document.documentElement; |
|
} |
|
|
|
var noOffsetParent = isIE(10) ? document.body : null; |
|
|
|
// NOTE: 1 DOM access here |
|
var offsetParent = element.offsetParent; |
|
// Skip hidden elements which don't have an offsetParent |
|
while (offsetParent === noOffsetParent && element.nextElementSibling) { |
|
offsetParent = (element = element.nextElementSibling).offsetParent; |
|
} |
|
|
|
var nodeName = offsetParent && offsetParent.nodeName; |
|
|
|
if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') { |
|
return element ? element.ownerDocument.documentElement : document.documentElement; |
|
} |
|
|
|
// .offsetParent will return the closest TD or TABLE in case |
|
// no offsetParent is present, I hate this job... |
|
if (['TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 'position') === 'static') { |
|
return getOffsetParent(offsetParent); |
|
} |
|
|
|
return offsetParent; |
|
} |
|
|
|
function isOffsetContainer(element) { |
|
var nodeName = element.nodeName; |
|
|
|
if (nodeName === 'BODY') { |
|
return false; |
|
} |
|
return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element; |
|
} |
|
|
|
/** |
|
* Finds the root node (document, shadowDOM root) of the given element |
|
* @method |
|
* @memberof Popper.Utils |
|
* @argument {Element} node |
|
* @returns {Element} root node |
|
*/ |
|
function getRoot(node) { |
|
if (node.parentNode !== null) { |
|
return getRoot(node.parentNode); |
|
} |
|
|
|
return node; |
|
} |
|
|
|
/** |
|
* Finds the offset parent common to the two provided nodes |
|
* @method |
|
* @memberof Popper.Utils |
|
* @argument {Element} element1 |
|
* @argument {Element} element2 |
|
* @returns {Element} common offset parent |
|
*/ |
|
function findCommonOffsetParent(element1, element2) { |
|
// This check is needed to avoid errors in case one of the elements isn't defined for any reason |
|
if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) { |
|
return document.documentElement; |
|
} |
|
|
|
// Here we make sure to give as "start" the element that comes first in the DOM |
|
var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING; |
|
var start = order ? element1 : element2; |
|
var end = order ? element2 : element1; |
|
|
|
// Get common ancestor container |
|
var range = document.createRange(); |
|
range.setStart(start, 0); |
|
range.setEnd(end, 0); |
|
var commonAncestorContainer = range.commonAncestorContainer; |
|
|
|
// Both nodes are inside #document |
|
|
|
if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) { |
|
if (isOffsetContainer(commonAncestorContainer)) { |
|
return commonAncestorContainer; |
|
} |
|
|
|
return getOffsetParent(commonAncestorContainer); |
|
} |
|
|
|
// one of the nodes is inside shadowDOM, find which one |
|
var element1root = getRoot(element1); |
|
if (element1root.host) { |
|
return findCommonOffsetParent(element1root.host, element2); |
|
} else { |
|
return findCommonOffsetParent(element1, getRoot(element2).host); |
|
} |
|
} |
|
|
|
/** |
|
* Gets the scroll value of the given element in the given side (top and left) |
|
* @method |
|
* @memberof Popper.Utils |
|
* @argument {Element} element |
|
* @argument {String} side `top` or `left` |
|
* @returns {number} amount of scrolled pixels |
|
*/ |
|
function getScroll(element) { |
|
var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top'; |
|
|
|
var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft'; |
|
var nodeName = element.nodeName; |
|
|
|
if (nodeName === 'BODY' || nodeName === 'HTML') { |
|
var html = element.ownerDocument.documentElement; |
|
var scrollingElement = element.ownerDocument.scrollingElement || html; |
|
return scrollingElement[upperSide]; |
|
} |
|
|
|
return element[upperSide]; |
|
} |
|
|
|
/* |
|
* Sum or subtract the element scroll values (left and top) from a given rect object |
|
* @method |
|
* @memberof Popper.Utils |
|
* @param {Object} rect - Rect object you want to change |
|
* @param {HTMLElement} element - The element from the function reads the scroll values |
|
* @param {Boolean} subtract - set to true if you want to subtract the scroll values |
|
* @return {Object} rect - The modifier rect object |
|
*/ |
|
function includeScroll(rect, element) { |
|
var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; |
|
|
|
var scrollTop = getScroll(element, 'top'); |
|
var scrollLeft = getScroll(element, 'left'); |
|
var modifier = subtract ? -1 : 1; |
|
rect.top += scrollTop * modifier; |
|
rect.bottom += scrollTop * modifier; |
|
rect.left += scrollLeft * modifier; |
|
rect.right += scrollLeft * modifier; |
|
return rect; |
|
} |
|
|
|
/* |
|
* Helper to detect borders of a given element |
|
* @method |
|
* @memberof Popper.Utils |
|
* @param {CSSStyleDeclaration} styles |
|
* Result of `getStyleComputedProperty` on the given element |
|
* @param {String} axis - `x` or `y` |
|
* @return {number} borders - The borders size of the given axis |
|
*/ |
|
|
|
function getBordersSize(styles, axis) { |
|
var sideA = axis === 'x' ? 'Left' : 'Top'; |
|
var sideB = sideA === 'Left' ? 'Right' : 'Bottom'; |
|
|
|
return parseFloat(styles['border' + sideA + 'Width'], 10) + parseFloat(styles['border' + sideB + 'Width'], 10); |
|
} |
|
|
|
function getSize(axis, body, html, computedStyle) { |
|
return Math.max(body['offset' + axis], body['scroll' + axis], html['client' + axis], html['offset' + axis], html['scroll' + axis], isIE(10) ? html['offset' + axis] + computedStyle['margin' + (axis === 'Height' ? 'Top' : 'Left')] + computedStyle['margin' + (axis === 'Height' ? 'Bottom' : 'Right')] : 0); |
|
} |
|
|
|
function getWindowSizes() { |
|
var body = document.body; |
|
var html = document.documentElement; |
|
var computedStyle = isIE(10) && getComputedStyle(html); |
|
|
|
return { |
|
height: getSize('Height', body, html, computedStyle), |
|
width: getSize('Width', body, html, computedStyle) |
|
}; |
|
} |
|
|
|
var classCallCheck = function (instance, Constructor) { |
|
if (!(instance instanceof Constructor)) { |
|
throw new TypeError("Cannot call a class as a function"); |
|
} |
|
}; |
|
|
|
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 defineProperty = function (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 _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; |
|
}; |
|
|
|
/** |
|
* Given element offsets, generate an output similar to getBoundingClientRect |
|
* @method |
|
* @memberof Popper.Utils |
|
* @argument {Object} offsets |
|
* @returns {Object} ClientRect like output |
|
*/ |
|
function getClientRect(offsets) { |
|
return _extends({}, offsets, { |
|
right: offsets.left + offsets.width, |
|
bottom: offsets.top + offsets.height |
|
}); |
|
} |
|
|
|
/** |
|
* Get bounding client rect of given element |
|
* @method |
|
* @memberof Popper.Utils |
|
* @param {HTMLElement} element |
|
* @return {Object} client rect |
|
*/ |
|
function getBoundingClientRect(element) { |
|
var rect = {}; |
|
|
|
// IE10 10 FIX: Please, don't ask, the element isn't |
|
// considered in DOM in some circumstances... |
|
// This isn't reproducible in IE10 compatibility mode of IE11 |
|
try { |
|
if (isIE(10)) { |
|
rect = element.getBoundingClientRect(); |
|
var scrollTop = getScroll(element, 'top'); |
|
var scrollLeft = getScroll(element, 'left'); |
|
rect.top += scrollTop; |
|
rect.left += scrollLeft; |
|
rect.bottom += scrollTop; |
|
rect.right += scrollLeft; |
|
} else { |
|
rect = element.getBoundingClientRect(); |
|
} |
|
} catch (e) {} |
|
|
|
var result = { |
|
left: rect.left, |
|
top: rect.top, |
|
width: rect.right - rect.left, |
|
height: rect.bottom - rect.top |
|
}; |
|
|
|
// subtract scrollbar size from sizes |
|
var sizes = element.nodeName === 'HTML' ? getWindowSizes() : {}; |
|
var width = sizes.width || element.clientWidth || result.right - result.left; |
|
var height = sizes.height || element.clientHeight || result.bottom - result.top; |
|
|
|
var horizScrollbar = element.offsetWidth - width; |
|
var vertScrollbar = element.offsetHeight - height; |
|
|
|
// if an hypothetical scrollbar is detected, we must be sure it's not a `border` |
|
// we make this check conditional for performance reasons |
|
if (horizScrollbar || vertScrollbar) { |
|
var styles = getStyleComputedProperty(element); |
|
horizScrollbar -= getBordersSize(styles, 'x'); |
|
vertScrollbar -= getBordersSize(styles, 'y'); |
|
|
|
result.width -= horizScrollbar; |
|
result.height -= vertScrollbar; |
|
} |
|
|
|
return getClientRect(result); |
|
} |
|
|
|
function getOffsetRectRelativeToArbitraryNode(children, parent) { |
|
var fixedPosition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; |
|
|
|
var isIE10 = isIE(10); |
|
var isHTML = parent.nodeName === 'HTML'; |
|
var childrenRect = getBoundingClientRect(children); |
|
var parentRect = getBoundingClientRect(parent); |
|
var scrollParent = getScrollParent(children); |
|
|
|
var styles = getStyleComputedProperty(parent); |
|
var borderTopWidth = parseFloat(styles.borderTopWidth, 10); |
|
var borderLeftWidth = parseFloat(styles.borderLeftWidth, 10); |
|
|
|
// In cases where the parent is fixed, we must ignore negative scroll in offset calc |
|
if (fixedPosition && parent.nodeName === 'HTML') { |
|
parentRect.top = Math.max(parentRect.top, 0); |
|
parentRect.left = Math.max(parentRect.left, 0); |
|
} |
|
var offsets = getClientRect({ |
|
top: childrenRect.top - parentRect.top - borderTopWidth, |
|
left: childrenRect.left - parentRect.left - borderLeftWidth, |
|
width: childrenRect.width, |
|
height: childrenRect.height |
|
}); |
|
offsets.marginTop = 0; |
|
offsets.marginLeft = 0; |
|
|
|
// Subtract margins of documentElement in case it's being used as parent |
|
// we do this only on HTML because it's the only element that behaves |
|
// differently when margins are applied to it. The margins are included in |
|
// the box of the documentElement, in the other cases not. |
|
if (!isIE10 && isHTML) { |
|
var marginTop = parseFloat(styles.marginTop, 10); |
|
var marginLeft = parseFloat(styles.marginLeft, 10); |
|
|
|
offsets.top -= borderTopWidth - marginTop; |
|
offsets.bottom -= borderTopWidth - marginTop; |
|
offsets.left -= borderLeftWidth - marginLeft; |
|
offsets.right -= borderLeftWidth - marginLeft; |
|
|
|
// Attach marginTop and marginLeft because in some circumstances we may need them |
|
offsets.marginTop = marginTop; |
|
offsets.marginLeft = marginLeft; |
|
} |
|
|
|
if (isIE10 && !fixedPosition ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') { |
|
offsets = includeScroll(offsets, parent); |
|
} |
|
|
|
return offsets; |
|
} |
|
|
|
function getViewportOffsetRectRelativeToArtbitraryNode(element) { |
|
var excludeScroll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; |
|
|
|
var html = element.ownerDocument.documentElement; |
|
var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html); |
|
var width = Math.max(html.clientWidth, window.innerWidth || 0); |
|
var height = Math.max(html.clientHeight, window.innerHeight || 0); |
|
|
|
var scrollTop = !excludeScroll ? getScroll(html) : 0; |
|
var scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0; |
|
|
|
var offset = { |
|
top: scrollTop - relativeOffset.top + relativeOffset.marginTop, |
|
left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft, |
|
width: width, |
|
height: height |
|
}; |
|
|
|
return getClientRect(offset); |
|
} |
|
|
|
/** |
|
* Check if the given element is fixed or is inside a fixed parent |
|
* @method |
|
* @memberof Popper.Utils |
|
* @argument {Element} element |
|
* @argument {Element} customContainer |
|
* @returns {Boolean} answer to "isFixed?" |
|
*/ |
|
function isFixed(element) { |
|
var nodeName = element.nodeName; |
|
if (nodeName === 'BODY' || nodeName === 'HTML') { |
|
return false; |
|
} |
|
if (getStyleComputedProperty(element, 'position') === 'fixed') { |
|
return true; |
|
} |
|
return isFixed(getParentNode(element)); |
|
} |
|
|
|
/** |
|
* Finds the first parent of an element that has a transformed property defined |
|
* @method |
|
* @memberof Popper.Utils |
|
* @argument {Element} element |
|
* @returns {Element} first transformed parent or documentElement |
|
*/ |
|
|
|
function getFixedPositionOffsetParent(element) { |
|
// This check is needed to avoid errors in case one of the elements isn't defined for any reason |
|
if (!element || !element.parentElement || isIE()) { |
|
return document.documentElement; |
|
} |
|
var el = element.parentElement; |
|
while (el && getStyleComputedProperty(el, 'transform') === 'none') { |
|
el = el.parentElement; |
|
} |
|
return el || document.documentElement; |
|
} |
|
|
|
/** |
|
* Computed the boundaries limits and return them |
|
* @method |
|
* @memberof Popper.Utils |
|
* @param {HTMLElement} popper |
|
* @param {HTMLElement} reference |
|
* @param {number} padding |
|
* @param {HTMLElement} boundariesElement - Element used to define the boundaries |
|
* @param {Boolean} fixedPosition - Is in fixed position mode |
|
* @returns {Object} Coordinates of the boundaries |
|
*/ |
|
function getBoundaries(popper, reference, padding, boundariesElement) { |
|
var fixedPosition = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; |
|
|
|
// NOTE: 1 DOM access here |
|
|
|
var boundaries = { top: 0, left: 0 }; |
|
var offsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, reference); |
|
|
|
// Handle viewport case |
|
if (boundariesElement === 'viewport') { |
|
boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition); |
|
} else { |
|
// Handle other cases based on DOM element used as boundaries |
|
var boundariesNode = void 0; |
|
if (boundariesElement === 'scrollParent') { |
|
boundariesNode = getScrollParent(getParentNode(reference)); |
|
if (boundariesNode.nodeName === 'BODY') { |
|
boundariesNode = popper.ownerDocument.documentElement; |
|
} |
|
} else if (boundariesElement === 'window') { |
|
boundariesNode = popper.ownerDocument.documentElement; |
|
} else { |
|
boundariesNode = boundariesElement; |
|
} |
|
|
|
var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent, fixedPosition); |
|
|
|
// In case of HTML, we need a different computation |
|
if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) { |
|
var _getWindowSizes = getWindowSizes(), |
|
height = _getWindowSizes.height, |
|
width = _getWindowSizes.width; |
|
|
|
boundaries.top += offsets.top - offsets.marginTop; |
|
boundaries.bottom = height + offsets.top; |
|
boundaries.left += offsets.left - offsets.marginLeft; |
|
boundaries.right = width + offsets.left; |
|
} else { |
|
// for all the other DOM elements, this one is good |
|
boundaries = offsets; |
|
} |
|
} |
|
|
|
// Add paddings |
|
boundaries.left += padding; |
|
boundaries.top += padding; |
|
boundaries.right -= padding; |
|
boundaries.bottom -= padding; |
|
|
|
return boundaries; |
|
} |
|
|
|
function getArea(_ref) { |
|
var width = _ref.width, |
|
height = _ref.height; |
|
|
|
return width * height; |
|
} |
|
|
|
/** |
|
* Utility used to transform the `auto` placement to the placement with more |
|
* available space. |
|
* @method |
|
* @memberof Popper.Utils |
|
* @argument {Object} data - The data object generated by update method |
|
* @argument {Object} options - Modifiers configuration and options |
|
* @returns {Object} The data object, properly modified |
|
*/ |
|
function computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) { |
|
var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0; |
|
|
|
if (placement.indexOf('auto') === -1) { |
|
return placement; |
|
} |
|
|
|
var boundaries = getBoundaries(popper, reference, padding, boundariesElement); |
|
|
|
var rects = { |
|
top: { |
|
width: boundaries.width, |
|
height: refRect.top - boundaries.top |
|
}, |
|
right: { |
|
width: boundaries.right - refRect.right, |
|
height: boundaries.height |
|
}, |
|
bottom: { |
|
width: boundaries.width, |
|
height: boundaries.bottom - refRect.bottom |
|
}, |
|
left: { |
|
width: refRect.left - boundaries.left, |
|
height: boundaries.height |
|
} |
|
}; |
|
|
|
var sortedAreas = Object.keys(rects).map(function (key) { |
|
return _extends({ |
|
key: key |
|
}, rects[key], { |
|
area: getArea(rects[key]) |
|
}); |
|
}).sort(function (a, b) { |
|
return b.area - a.area; |
|
}); |
|
|
|
var filteredAreas = sortedAreas.filter(function (_ref2) { |
|
var width = _ref2.width, |
|
height = _ref2.height; |
|
return width >= popper.clientWidth && height >= popper.clientHeight; |
|
}); |
|
|
|
var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key; |
|
|
|
var variation = placement.split('-')[1]; |
|
|
|
return computedPlacement + (variation ? '-' + variation : ''); |
|
} |
|
|
|
/** |
|
* Get offsets to the reference element |
|
* @method |
|
* @memberof Popper.Utils |
|
* @param {Object} state |
|
* @param {Element} popper - the popper element |
|
* @param {Element} reference - the reference element (the popper will be relative to this) |
|
* @param {Element} fixedPosition - is in fixed position mode |
|
* @returns {Object} An object containing the offsets which will be applied to the popper |
|
*/ |
|
function getReferenceOffsets(state, popper, reference) { |
|
var fixedPosition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; |
|
|
|
var commonOffsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, reference); |
|
return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent, fixedPosition); |
|
} |
|
|
|
/** |
|
* Get the outer sizes of the given element (offset size + margins) |
|
* @method |
|
* @memberof Popper.Utils |
|
* @argument {Element} element |
|
* @returns {Object} object containing width and height properties |
|
*/ |
|
function getOuterSizes(element) { |
|
var styles = getComputedStyle(element); |
|
var x = parseFloat(styles.marginTop) + parseFloat(styles.marginBottom); |
|
var y = parseFloat(styles.marginLeft) + parseFloat(styles.marginRight); |
|
var result = { |
|
width: element.offsetWidth + y, |
|
height: element.offsetHeight + x |
|
}; |
|
return result; |
|
} |
|
|
|
/** |
|
* Get the opposite placement of the given one |
|
* @method |
|
* @memberof Popper.Utils |
|
* @argument {String} placement |
|
* @returns {String} flipped placement |
|
*/ |
|
function getOppositePlacement(placement) { |
|
var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' }; |
|
return placement.replace(/left|right|bottom|top/g, function (matched) { |
|
return hash[matched]; |
|
}); |
|
} |
|
|
|
/** |
|
* Get offsets to the popper |
|
* @method |
|
* @memberof Popper.Utils |
|
* @param {Object} position - CSS position the Popper will get applied |
|
* @param {HTMLElement} popper - the popper element |
|
* @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this) |
|
* @param {String} placement - one of the valid placement options |
|
* @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper |
|
*/ |
|
function getPopperOffsets(popper, referenceOffsets, placement) { |
|
placement = placement.split('-')[0]; |
|
|
|
// Get popper node sizes |
|
var popperRect = getOuterSizes(popper); |
|
|
|
// Add position, width and height to our offsets object |
|
var popperOffsets = { |
|
width: popperRect.width, |
|
height: popperRect.height |
|
}; |
|
|
|
// depending by the popper placement we have to compute its offsets slightly differently |
|
var isHoriz = ['right', 'left'].indexOf(placement) !== -1; |
|
var mainSide = isHoriz ? 'top' : 'left'; |
|
var secondarySide = isHoriz ? 'left' : 'top'; |
|
var measurement = isHoriz ? 'height' : 'width'; |
|
var secondaryMeasurement = !isHoriz ? 'height' : 'width'; |
|
|
|
popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2; |
|
if (placement === secondarySide) { |
|
popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement]; |
|
} else { |
|
popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)]; |
|
} |
|
|
|
return popperOffsets; |
|
} |
|
|
|
/** |
|
* Mimics the `find` method of Array |
|
* @method |
|
* @memberof Popper.Utils |
|
* @argument {Array} arr |
|
* @argument prop |
|
* @argument value |
|
* @returns index or -1 |
|
*/ |
|
function find(arr, check) { |
|
// use native find if supported |
|
if (Array.prototype.find) { |
|
return arr.find(check); |
|
} |
|
|
|
// use `filter` to obtain the same behavior of `find` |
|
return arr.filter(check)[0]; |
|
} |
|
|
|
/** |
|
* Return the index of the matching object |
|
* @method |
|
* @memberof Popper.Utils |
|
* @argument {Array} arr |
|
* @argument prop |
|
* @argument value |
|
* @returns index or -1 |
|
*/ |
|
function findIndex(arr, prop, value) { |
|
// use native findIndex if supported |
|
if (Array.prototype.findIndex) { |
|
return arr.findIndex(function (cur) { |
|
return cur[prop] === value; |
|
}); |
|
} |
|
|
|
// use `find` + `indexOf` if `findIndex` isn't supported |
|
var match = find(arr, function (obj) { |
|
return obj[prop] === value; |
|
}); |
|
return arr.indexOf(match); |
|
} |
|
|
|
/** |
|
* Loop trough the list of modifiers and run them in order, |
|
* each of them will then edit the data object. |
|
* @method |
|
* @memberof Popper.Utils |
|
* @param {dataObject} data |
|
* @param {Array} modifiers |
|
* @param {String} ends - Optional modifier name used as stopper |
|
* @returns {dataObject} |
|
*/ |
|
function runModifiers(modifiers, data, ends) { |
|
var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends)); |
|
|
|
modifiersToRun.forEach(function (modifier) { |
|
if (modifier['function']) { |
|
// eslint-disable-line dot-notation |
|
console.warn('`modifier.function` is deprecated, use `modifier.fn`!'); |
|
} |
|
var fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation |
|
if (modifier.enabled && isFunction(fn)) { |
|
// Add properties to offsets to make them a complete clientRect object |
|
// we do this before each modifier to make sure the previous one doesn't |
|
// mess with these values |
|
data.offsets.popper = getClientRect(data.offsets.popper); |
|
data.offsets.reference = getClientRect(data.offsets.reference); |
|
|
|
data = fn(data, modifier); |
|
} |
|
}); |
|
|
|
return data; |
|
} |
|
|
|
/** |
|
* Updates the position of the popper, computing the new offsets and applying |
|
* the new style.<br /> |
|
* Prefer `scheduleUpdate` over `update` because of performance reasons. |
|
* @method |
|
* @memberof Popper |
|
*/ |
|
function update() { |
|
// if popper is destroyed, don't perform any further update |
|
if (this.state.isDestroyed) { |
|
return; |
|
} |
|
|
|
var data = { |
|
instance: this, |
|
styles: {}, |
|
arrowStyles: {}, |
|
attributes: {}, |
|
flipped: false, |
|
offsets: {} |
|
}; |
|
|
|
// compute reference element offsets |
|
data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference, this.options.positionFixed); |
|
|
|
// compute auto placement, store placement inside the data object, |
|
// modifiers will be able to edit `placement` if needed |
|
// and refer to originalPlacement to know the original value |
|
data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding); |
|
|
|
// store the computed placement inside `originalPlacement` |
|
data.originalPlacement = data.placement; |
|
|
|
data.positionFixed = this.options.positionFixed; |
|
|
|
// compute the popper offsets |
|
data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement); |
|
|
|
data.offsets.popper.position = this.options.positionFixed ? 'fixed' : 'absolute'; |
|
|
|
// run the modifiers |
|
data = runModifiers(this.modifiers, data); |
|
|
|
// the first `update` will call `onCreate` callback |
|
// the other ones will call `onUpdate` callback |
|
if (!this.state.isCreated) { |
|
this.state.isCreated = true; |
|
this.options.onCreate(data); |
|
} else { |
|
this.options.onUpdate(data); |
|
} |
|
} |
|
|
|
/** |
|
* Helper used to know if the given modifier is enabled. |
|
* @method |
|
* @memberof Popper.Utils |
|
* @returns {Boolean} |
|
*/ |
|
function isModifierEnabled(modifiers, modifierName) { |
|
return modifiers.some(function (_ref) { |
|
var name = _ref.name, |
|
enabled = _ref.enabled; |
|
return enabled && name === modifierName; |
|
}); |
|
} |
|
|
|
/** |
|
* Get the prefixed supported property name |
|
* @method |
|
* @memberof Popper.Utils |
|
* @argument {String} property (camelCase) |
|
* @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix) |
|
*/ |
|
function getSupportedPropertyName(property) { |
|
var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O']; |
|
var upperProp = property.charAt(0).toUpperCase() + property.slice(1); |
|
|
|
for (var i = 0; i < prefixes.length; i++) { |
|
var prefix = prefixes[i]; |
|
var toCheck = prefix ? '' + prefix + upperProp : property; |
|
if (typeof document.body.style[toCheck] !== 'undefined') { |
|
return toCheck; |
|
} |
|
} |
|
return null; |
|
} |
|
|
|
/** |
|
* Destroy the popper |
|
* @method |
|
* @memberof Popper |
|
*/ |
|
function destroy() { |
|
this.state.isDestroyed = true; |
|
|
|
// touch DOM only if `applyStyle` modifier is enabled |
|
if (isModifierEnabled(this.modifiers, 'applyStyle')) { |
|
this.popper.removeAttribute('x-placement'); |
|
this.popper.style.position = ''; |
|
this.popper.style.top = ''; |
|
this.popper.style.left = ''; |
|
this.popper.style.right = ''; |
|
this.popper.style.bottom = ''; |
|
this.popper.style.willChange = ''; |
|
this.popper.style[getSupportedPropertyName('transform')] = ''; |
|
} |
|
|
|
this.disableEventListeners(); |
|
|
|
// remove the popper if user explicity asked for the deletion on destroy |
|
// do not use `remove` because IE11 doesn't support it |
|
if (this.options.removeOnDestroy) { |
|
this.popper.parentNode.removeChild(this.popper); |
|
} |
|
return this; |
|
} |
|
|
|
/** |
|
* Get the window associated with the element |
|
* @argument {Element} element |
|
* @returns {Window} |
|
*/ |
|
function getWindow(element) { |
|
var ownerDocument = element.ownerDocument; |
|
return ownerDocument ? ownerDocument.defaultView : window; |
|
} |
|
|
|
function attachToScrollParents(scrollParent, event, callback, scrollParents) { |
|
var isBody = scrollParent.nodeName === 'BODY'; |
|
var target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent; |
|
target.addEventListener(event, callback, { passive: true }); |
|
|
|
if (!isBody) { |
|
attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents); |
|
} |
|
scrollParents.push(target); |
|
} |
|
|
|
/** |
|
* Setup needed event listeners used to update the popper position |
|
* @method |
|
* @memberof Popper.Utils |
|
* @private |
|
*/ |
|
function setupEventListeners(reference, options, state, updateBound) { |
|
// Resize event listener on window |
|
state.updateBound = updateBound; |
|
getWindow(reference).addEventListener('resize', state.updateBound, { passive: true }); |
|
|
|
// Scroll event listener on scroll parents |
|
var scrollElement = getScrollParent(reference); |
|
attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents); |
|
state.scrollElement = scrollElement; |
|
state.eventsEnabled = true; |
|
|
|
return state; |
|
} |
|
|
|
/** |
|
* It will add resize/scroll events and start recalculating |
|
* position of the popper element when they are triggered. |
|
* @method |
|
* @memberof Popper |
|
*/ |
|
function enableEventListeners() { |
|
if (!this.state.eventsEnabled) { |
|
this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate); |
|
} |
|
} |
|
|
|
/** |
|
* Remove event listeners used to update the popper position |
|
* @method |
|
* @memberof Popper.Utils |
|
* @private |
|
*/ |
|
function removeEventListeners(reference, state) { |
|
// Remove resize event listener on window |
|
getWindow(reference).removeEventListener('resize', state.updateBound); |
|
|
|
// Remove scroll event listener on scroll parents |
|
state.scrollParents.forEach(function (target) { |
|
target.removeEventListener('scroll', state.updateBound); |
|
}); |
|
|
|
// Reset state |
|
state.updateBound = null; |
|
state.scrollParents = []; |
|
state.scrollElement = null; |
|
state.eventsEnabled = false; |
|
return state; |
|
} |
|
|
|
/** |
|
* It will remove resize/scroll events and won't recalculate popper position |
|
* when they are triggered. It also won't trigger onUpdate callback anymore, |
|
* unless you call `update` method manually. |
|
* @method |
|
* @memberof Popper |
|
*/ |
|
function disableEventListeners() { |
|
if (this.state.eventsEnabled) { |
|
cancelAnimationFrame(this.scheduleUpdate); |
|
this.state = removeEventListeners(this.reference, this.state); |
|
} |
|
} |
|
|
|
/** |
|
* Tells if a given input is a number |
|
* @method |
|
* @memberof Popper.Utils |
|
* @param {*} input to check |
|
* @return {Boolean} |
|
*/ |
|
function isNumeric(n) { |
|
return n !== '' && !isNaN(parseFloat(n)) && isFinite(n); |
|
} |
|
|
|
/** |
|
* Set the style to the given popper |
|
* @method |
|
* @memberof Popper.Utils |
|
* @argument {Element} element - Element to apply the style to |
|
* @argument {Object} styles |
|
* Object with a list of properties and values which will be applied to the element |
|
*/ |
|
function setStyles(element, styles) { |
|
Object.keys(styles).forEach(function (prop) { |
|
var unit = ''; |
|
// add unit if the value is numeric and is one of the following |
|
if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) { |
|
unit = 'px'; |
|
} |
|
element.style[prop] = styles[prop] + unit; |
|
}); |
|
} |
|
|
|
/** |
|
* Set the attributes to the given popper |
|
* @method |
|
* @memberof Popper.Utils |
|
* @argument {Element} element - Element to apply the attributes to |
|
* @argument {Object} styles |
|
* Object with a list of properties and values which will be applied to the element |
|
*/ |
|
function setAttributes(element, attributes) { |
|
Object.keys(attributes).forEach(function (prop) { |
|
var value = attributes[prop]; |
|
if (value !== false) { |
|
element.setAttribute(prop, attributes[prop]); |
|
} else { |
|
element.removeAttribute(prop); |
|
} |
|
}); |
|
} |
|
|
|
/** |
|
* @function |
|
* @memberof Modifiers |
|
* @argument {Object} data - The data object generated by `update` method |
|
* @argument {Object} data.styles - List of style properties - values to apply to popper element |
|
* @argument {Object} data.attributes - List of attribute properties - values to apply to popper element |
|
* @argument {Object} options - Modifiers configuration and options |
|
* @returns {Object} The same data object |
|
*/ |
|
function applyStyle(data) { |
|
// any property present in `data.styles` will be applied to the popper, |
|
// in this way we can make the 3rd party modifiers add custom styles to it |
|
// Be aware, modifiers could override the properties defined in the previous |
|
// lines of this modifier! |
|
setStyles(data.instance.popper, data.styles); |
|
|
|
// any property present in `data.attributes` will be applied to the popper, |
|
// they will be set as HTML attributes of the element |
|
setAttributes(data.instance.popper, data.attributes); |
|
|
|
// if arrowElement is defined and arrowStyles has some properties |
|
if (data.arrowElement && Object.keys(data.arrowStyles).length) { |
|
setStyles(data.arrowElement, data.arrowStyles); |
|
} |
|
|
|
return data; |
|
} |
|
|
|
/** |
|
* Set the x-placement attribute before everything else because it could be used |
|
* to add margins to the popper margins needs to be calculated to get the |
|
* correct popper offsets. |
|
* @method |
|
* @memberof Popper.modifiers |
|
* @param {HTMLElement} reference - The reference element used to position the popper |
|
* @param {HTMLElement} popper - The HTML element used as popper |
|
* @param {Object} options - Popper.js options |
|
*/ |
|
function applyStyleOnLoad(reference, popper, options, modifierOptions, state) { |
|
// compute reference element offsets |
|
var referenceOffsets = getReferenceOffsets(state, popper, reference, options.positionFixed); |
|
|
|
// compute auto placement, store placement inside the data object, |
|
// modifiers will be able to edit `placement` if needed |
|
// and refer to originalPlacement to know the original value |
|
var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, options.modifiers.flip.boundariesElement, options.modifiers.flip.padding); |
|
|
|
popper.setAttribute('x-placement', placement); |
|
|
|
// Apply `position` to popper before anything else because |
|
// without the position applied we can't guarantee correct computations |
|
setStyles(popper, { position: options.positionFixed ? 'fixed' : 'absolute' }); |
|
|
|
return options; |
|
} |
|
|
|
/** |
|
* @function |
|
* @memberof Modifiers |
|
* @argument {Object} data - The data object generated by `update` method |
|
* @argument {Object} options - Modifiers configuration and options |
|
* @returns {Object} The data object, properly modified |
|
*/ |
|
function computeStyle(data, options) { |
|
var x = options.x, |
|
y = options.y; |
|
var popper = data.offsets.popper; |
|
|
|
// Remove this legacy support in Popper.js v2 |
|
|
|
var legacyGpuAccelerationOption = find(data.instance.modifiers, function (modifier) { |
|
return modifier.name === 'applyStyle'; |
|
}).gpuAcceleration; |
|
if (legacyGpuAccelerationOption !== undefined) { |
|
console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!'); |
|
} |
|
var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration; |
|
|
|
var offsetParent = getOffsetParent(data.instance.popper); |
|
var offsetParentRect = getBoundingClientRect(offsetParent); |
|
|
|
// Styles |
|
var styles = { |
|
position: popper.position |
|
}; |
|
|
|
// Avoid blurry text by using full pixel integers. |
|
// For pixel-perfect positioning, top/bottom prefers rounded |
|
// values, while left/right prefers floored values. |
|
var offsets = { |
|
left: Math.floor(popper.left), |
|
top: Math.round(popper.top), |
|
bottom: Math.round(popper.bottom), |
|
right: Math.floor(popper.right) |
|
}; |
|
|
|
var sideA = x === 'bottom' ? 'top' : 'bottom'; |
|
var sideB = y === 'right' ? 'left' : 'right'; |
|
|
|
// if gpuAcceleration is set to `true` and transform is supported, |
|
// we use `translate3d` to apply the position to the popper we |
|
// automatically use the supported prefixed version if needed |
|
var prefixedProperty = getSupportedPropertyName('transform'); |
|
|
|
// now, let's make a step back and look at this code closely (wtf?) |
|
// If the content of the popper grows once it's been positioned, it |
|
// may happen that the popper gets misplaced because of the new content |
|
// overflowing its reference element |
|
// To avoid this problem, we provide two options (x and y), which allow |
|
// the consumer to define the offset origin. |
|
// If we position a popper on top of a reference element, we can set |
|
// `x` to `top` to make the popper grow towards its top instead of |
|
// its bottom. |
|
var left = void 0, |
|
top = void 0; |
|
if (sideA === 'bottom') { |
|
top = -offsetParentRect.height + offsets.bottom; |
|
} else { |
|
top = offsets.top; |
|
} |
|
if (sideB === 'right') { |
|
left = -offsetParentRect.width + offsets.right; |
|
} else { |
|
left = offsets.left; |
|
} |
|
if (gpuAcceleration && prefixedProperty) { |
|
styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)'; |
|
styles[sideA] = 0; |
|
styles[sideB] = 0; |
|
styles.willChange = 'transform'; |
|
} else { |
|
// othwerise, we use the standard `top`, `left`, `bottom` and `right` properties |
|
var invertTop = sideA === 'bottom' ? -1 : 1; |
|
var invertLeft = sideB === 'right' ? -1 : 1; |
|
styles[sideA] = top * invertTop; |
|
styles[sideB] = left * invertLeft; |
|
styles.willChange = sideA + ', ' + sideB; |
|
} |
|
|
|
// Attributes |
|
var attributes = { |
|
'x-placement': data.placement |
|
}; |
|
|
|
// Update `data` attributes, styles and arrowStyles |
|
data.attributes = _extends({}, attributes, data.attributes); |
|
data.styles = _extends({}, styles, data.styles); |
|
data.arrowStyles = _extends({}, data.offsets.arrow, data.arrowStyles); |
|
|
|
return data; |
|
} |
|
|
|
/** |
|
* Helper used to know if the given modifier depends from another one.<br /> |
|
* It checks if the needed modifier is listed and enabled. |
|
* @method |
|
* @memberof Popper.Utils |
|
* @param {Array} modifiers - list of modifiers |
|
* @param {String} requestingName - name of requesting modifier |
|
* @param {String} requestedName - name of requested modifier |
|
* @returns {Boolean} |
|
*/ |
|
function isModifierRequired(modifiers, requestingName, requestedName) { |
|
var requesting = find(modifiers, function (_ref) { |
|
var name = _ref.name; |
|
return name === requestingName; |
|
}); |
|
|
|
var isRequired = !!requesting && modifiers.some(function (modifier) { |
|
return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order; |
|
}); |
|
|
|
if (!isRequired) { |
|
var _requesting = '`' + requestingName + '`'; |
|
var requested = '`' + requestedName + '`'; |
|
console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!'); |
|
} |
|
return isRequired; |
|
} |
|
|
|
/** |
|
* @function |
|
* @memberof Modifiers |
|
* @argument {Object} data - The data object generated by update method |
|
* @argument {Object} options - Modifiers configuration and options |
|
* @returns {Object} The data object, properly modified |
|
*/ |
|
function arrow(data, options) { |
|
var _data$offsets$arrow; |
|
|
|
// arrow depends on keepTogether in order to work |
|
if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) { |
|
return data; |
|
} |
|
|
|
var arrowElement = options.element; |
|
|
|
// if arrowElement is a string, suppose it's a CSS selector |
|
if (typeof arrowElement === 'string') { |
|
arrowElement = data.instance.popper.querySelector(arrowElement); |
|
|
|
// if arrowElement is not found, don't run the modifier |
|
if (!arrowElement) { |
|
return data; |
|
} |
|
} else { |
|
// if the arrowElement isn't a query selector we must check that the |
|
// provided DOM node is child of its popper node |
|
if (!data.instance.popper.contains(arrowElement)) { |
|
console.warn('WARNING: `arrow.element` must be child of its popper element!'); |
|
return data; |
|
} |
|
} |
|
|
|
var placement = data.placement.split('-')[0]; |
|
var _data$offsets = data.offsets, |
|
popper = _data$offsets.popper, |
|
reference = _data$offsets.reference; |
|
|
|
var isVertical = ['left', 'right'].indexOf(placement) !== -1; |
|
|
|
var len = isVertical ? 'height' : 'width'; |
|
var sideCapitalized = isVertical ? 'Top' : 'Left'; |
|
var side = sideCapitalized.toLowerCase(); |
|
var altSide = isVertical ? 'left' : 'top'; |
|
var opSide = isVertical ? 'bottom' : 'right'; |
|
var arrowElementSize = getOuterSizes(arrowElement)[len]; |
|
|
|
// |
|
// extends keepTogether behavior making sure the popper and its |
|
// reference have enough pixels in conjuction |
|
// |
|
|
|
// top/left side |
|
if (reference[opSide] - arrowElementSize < popper[side]) { |
|
data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize); |
|
} |
|
// bottom/right side |
|
if (reference[side] + arrowElementSize > popper[opSide]) { |
|
data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide]; |
|
} |
|
data.offsets.popper = getClientRect(data.offsets.popper); |
|
|
|
// compute center of the popper |
|
var center = reference[side] + reference[len] / 2 - arrowElementSize / 2; |
|
|
|
// Compute the sideValue using the updated popper offsets |
|
// take popper margin in account because we don't have this info available |
|
var css = getStyleComputedProperty(data.instance.popper); |
|
var popperMarginSide = parseFloat(css['margin' + sideCapitalized], 10); |
|
var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width'], 10); |
|
var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide; |
|
|
|
// prevent arrowElement from being placed not contiguously to its popper |
|
sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0); |
|
|
|
data.arrowElement = arrowElement; |
|
data.offsets.arrow = (_data$offsets$arrow = {}, defineProperty(_data$offsets$arrow, side, Math.round(sideValue)), defineProperty(_data$offsets$arrow, altSide, ''), _data$offsets$arrow); |
|
|
|
return data; |
|
} |
|
|
|
/** |
|
* Get the opposite placement variation of the given one |
|
* @method |
|
* @memberof Popper.Utils |
|
* @argument {String} placement variation |
|
* @returns {String} flipped placement variation |
|
*/ |
|
function getOppositeVariation(variation) { |
|
if (variation === 'end') { |
|
return 'start'; |
|
} else if (variation === 'start') { |
|
return 'end'; |
|
} |
|
return variation; |
|
} |
|
|
|
/** |
|
* List of accepted placements to use as values of the `placement` option.<br /> |
|
* Valid placements are: |
|
* - `auto` |
|
* - `top` |
|
* - `right` |
|
* - `bottom` |
|
* - `left` |
|
* |
|
* Each placement can have a variation from this list: |
|
* - `-start` |
|
* - `-end` |
|
* |
|
* Variations are interpreted easily if you think of them as the left to right |
|
* written languages. Horizontally (`top` and `bottom`), `start` is left and `end` |
|
* is right.<br /> |
|
* Vertically (`left` and `right`), `start` is top and `end` is bottom. |
|
* |
|
* Some valid examples are: |
|
* - `top-end` (on top of reference, right aligned) |
|
* - `right-start` (on right of reference, top aligned) |
|
* - `bottom` (on bottom, centered) |
|
* - `auto-right` (on the side with more space available, alignment depends by placement) |
|
* |
|
* @static |
|
* @type {Array} |
|
* @enum {String} |
|
* @readonly |
|
* @method placements |
|
* @memberof Popper |
|
*/ |
|
var placements = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start']; |
|
|
|
// Get rid of `auto` `auto-start` and `auto-end` |
|
var validPlacements = placements.slice(3); |
|
|
|
/** |
|
* Given an initial placement, returns all the subsequent placements |
|
* clockwise (or counter-clockwise). |
|
* |
|
* @method |
|
* @memberof Popper.Utils |
|
* @argument {String} placement - A valid placement (it accepts variations) |
|
* @argument {Boolean} counter - Set to true to walk the placements counterclockwise |
|
* @returns {Array} placements including their variations |
|
*/ |
|
function clockwise(placement) { |
|
var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; |
|
|
|
var index = validPlacements.indexOf(placement); |
|
var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index)); |
|
return counter ? arr.reverse() : arr; |
|
} |
|
|
|
var BEHAVIORS = { |
|
FLIP: 'flip', |
|
CLOCKWISE: 'clockwise', |
|
COUNTERCLOCKWISE: 'counterclockwise' |
|
}; |
|
|
|
/** |
|
* @function |
|
* @memberof Modifiers |
|
* @argument {Object} data - The data object generated by update method |
|
* @argument {Object} options - Modifiers configuration and options |
|
* @returns {Object} The data object, properly modified |
|
*/ |
|
function flip(data, options) { |
|
// if `inner` modifier is enabled, we can't use the `flip` modifier |
|
if (isModifierEnabled(data.instance.modifiers, 'inner')) { |
|
return data; |
|
} |
|
|
|
if (data.flipped && data.placement === data.originalPlacement) { |
|
// seems like flip is trying to loop, probably there's not enough space on any of the flippable sides |
|
return data; |
|
} |
|
|
|
var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement, data.positionFixed); |
|
|
|
var placement = data.placement.split('-')[0]; |
|
var placementOpposite = getOppositePlacement(placement); |
|
var variation = data.placement.split('-')[1] || ''; |
|
|
|
var flipOrder = []; |
|
|
|
switch (options.behavior) { |
|
case BEHAVIORS.FLIP: |
|
flipOrder = [placement, placementOpposite]; |
|
break; |
|
case BEHAVIORS.CLOCKWISE: |
|
flipOrder = clockwise(placement); |
|
break; |
|
case BEHAVIORS.COUNTERCLOCKWISE: |
|
flipOrder = clockwise(placement, true); |
|
break; |
|
default: |
|
flipOrder = options.behavior; |
|
} |
|
|
|
flipOrder.forEach(function (step, index) { |
|
if (placement !== step || flipOrder.length === index + 1) { |
|
return data; |
|
} |
|
|
|
placement = data.placement.split('-')[0]; |
|
placementOpposite = getOppositePlacement(placement); |
|
|
|
var popperOffsets = data.offsets.popper; |
|
var refOffsets = data.offsets.reference; |
|
|
|
// using floor because the reference offsets may contain decimals we are not going to consider here |
|
var floor = Math.floor; |
|
var overlapsRef = placement === 'left' && floor(popperOffsets.right) > floor(refOffsets.left) || placement === 'right' && floor(popperOffsets.left) < floor(refOffsets.right) || placement === 'top' && floor(popperOffsets.bottom) > floor(refOffsets.top) || placement === 'bottom' && floor(popperOffsets.top) < floor(refOffsets.bottom); |
|
|
|
var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left); |
|
var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right); |
|
var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top); |
|
var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom); |
|
|
|
var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom; |
|
|
|
// flip the variation if required |
|
var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; |
|
var flippedVariation = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom); |
|
|
|
if (overlapsRef || overflowsBoundaries || flippedVariation) { |
|
// this boolean to detect any flip loop |
|
data.flipped = true; |
|
|
|
if (overlapsRef || overflowsBoundaries) { |
|
placement = flipOrder[index + 1]; |
|
} |
|
|
|
if (flippedVariation) { |
|
variation = getOppositeVariation(variation); |
|
} |
|
|
|
data.placement = placement + (variation ? '-' + variation : ''); |
|
|
|
// this object contains `position`, we want to preserve it along with |
|
// any additional property we may add in the future |
|
data.offsets.popper = _extends({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement)); |
|
|
|
data = runModifiers(data.instance.modifiers, data, 'flip'); |
|
} |
|
}); |
|
return data; |
|
} |
|
|
|
/** |
|
* @function |
|
* @memberof Modifiers |
|
* @argument {Object} data - The data object generated by update method |
|
* @argument {Object} options - Modifiers configuration and options |
|
* @returns {Object} The data object, properly modified |
|
*/ |
|
function keepTogether(data) { |
|
var _data$offsets = data.offsets, |
|
popper = _data$offsets.popper, |
|
reference = _data$offsets.reference; |
|
|
|
var placement = data.placement.split('-')[0]; |
|
var floor = Math.floor; |
|
var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; |
|
var side = isVertical ? 'right' : 'bottom'; |
|
var opSide = isVertical ? 'left' : 'top'; |
|
var measurement = isVertical ? 'width' : 'height'; |
|
|
|
if (popper[side] < floor(reference[opSide])) { |
|
data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement]; |
|
} |
|
if (popper[opSide] > floor(reference[side])) { |
|
data.offsets.popper[opSide] = floor(reference[side]); |
|
} |
|
|
|
return data; |
|
} |
|
|
|
/** |
|
* Converts a string containing value + unit into a px value number |
|
* @function |
|
* @memberof {modifiers~offset} |
|
* @private |
|
* @argument {String} str - Value + unit string |
|
* @argument {String} measurement - `height` or `width` |
|
* @argument {Object} popperOffsets |
|
* @argument {Object} referenceOffsets |
|
* @returns {Number|String} |
|
* Value in pixels, or original string if no values were extracted |
|
*/ |
|
function toValue(str, measurement, popperOffsets, referenceOffsets) { |
|
// separate value from unit |
|
var split = str.match(/((?:\-|\+)?\d*\.?\d*)(.*)/); |
|
var value = +split[1]; |
|
var unit = split[2]; |
|
|
|
// If it's not a number it's an operator, I guess |
|
if (!value) { |
|
return str; |
|
} |
|
|
|
if (unit.indexOf('%') === 0) { |
|
var element = void 0; |
|
switch (unit) { |
|
case '%p': |
|
element = popperOffsets; |
|
break; |
|
case '%': |
|
case '%r': |
|
default: |
|
element = referenceOffsets; |
|
} |
|
|
|
var rect = getClientRect(element); |
|
return rect[measurement] / 100 * value; |
|
} else if (unit === 'vh' || unit === 'vw') { |
|
// if is a vh or vw, we calculate the size based on the viewport |
|
var size = void 0; |
|
if (unit === 'vh') { |
|
size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); |
|
} else { |
|
size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); |
|
} |
|
return size / 100 * value; |
|
} else { |
|
// if is an explicit pixel unit, we get rid of the unit and keep the value |
|
// if is an implicit unit, it's px, and we return just the value |
|
return value; |
|
} |
|
} |
|
|
|
/** |
|
* Parse an `offset` string to extrapolate `x` and `y` numeric offsets. |
|
* @function |
|
* @memberof {modifiers~offset} |
|
* @private |
|
* @argument {String} offset |
|
* @argument {Object} popperOffsets |
|
* @argument {Object} referenceOffsets |
|
* @argument {String} basePlacement |
|
* @returns {Array} a two cells array with x and y offsets in numbers |
|
*/ |
|
function parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) { |
|
var offsets = [0, 0]; |
|
|
|
// Use height if placement is left or right and index is 0 otherwise use width |
|
// in this way the first offset will use an axis and the second one |
|
// will use the other one |
|
var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1; |
|
|
|
// Split the offset string to obtain a list of values and operands |
|
// The regex addresses values with the plus or minus sign in front (+10, -20, etc) |
|
var fragments = offset.split(/(\+|\-)/).map(function (frag) { |
|
return frag.trim(); |
|
}); |
|
|
|
// Detect if the offset string contains a pair of values or a single one |
|
// they could be separated by comma or space |
|
var divider = fragments.indexOf(find(fragments, function (frag) { |
|
return frag.search(/,|\s/) !== -1; |
|
})); |
|
|
|
if (fragments[divider] && fragments[divider].indexOf(',') === -1) { |
|
console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.'); |
|
} |
|
|
|
// If divider is found, we divide the list of values and operands to divide |
|
// them by ofset X and Y. |
|
var splitRegex = /\s*,\s*|\s+/; |
|
var ops = divider !== -1 ? [fragments.slice(0, divider).concat([fragments[divider].split(splitRegex)[0]]), [fragments[divider].split(splitRegex)[1]].concat(fragments.slice(divider + 1))] : [fragments]; |
|
|
|
// Convert the values with units to absolute pixels to allow our computations |
|
ops = ops.map(function (op, index) { |
|
// Most of the units rely on the orientation of the popper |
|
var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width'; |
|
var mergeWithPrevious = false; |
|
return op |
|
// This aggregates any `+` or `-` sign that aren't considered operators |
|
// e.g.: 10 + +5 => [10, +, +5] |
|
.reduce(function (a, b) { |
|
if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) { |
|
a[a.length - 1] = b; |
|
mergeWithPrevious = true; |
|
return a; |
|
} else if (mergeWithPrevious) { |
|
a[a.length - 1] += b; |
|
mergeWithPrevious = false; |
|
return a; |
|
} else { |
|
return a.concat(b); |
|
} |
|
}, []) |
|
// Here we convert the string values into number values (in px) |
|
.map(function (str) { |
|
return toValue(str, measurement, popperOffsets, referenceOffsets); |
|
}); |
|
}); |
|
|
|
// Loop trough the offsets arrays and execute the operations |
|
ops.forEach(function (op, index) { |
|
op.forEach(function (frag, index2) { |
|
if (isNumeric(frag)) { |
|
offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1); |
|
} |
|
}); |
|
}); |
|
return offsets; |
|
} |
|
|
|
/** |
|
* @function |
|
* @memberof Modifiers |
|
* @argument {Object} data - The data object generated by update method |
|
* @argument {Object} options - Modifiers configuration and options |
|
* @argument {Number|String} options.offset=0 |
|
* The offset value as described in the modifier description |
|
* @returns {Object} The data object, properly modified |
|
*/ |
|
function offset(data, _ref) { |
|
var offset = _ref.offset; |
|
var placement = data.placement, |
|
_data$offsets = data.offsets, |
|
popper = _data$offsets.popper, |
|
reference = _data$offsets.reference; |
|
|
|
var basePlacement = placement.split('-')[0]; |
|
|
|
var offsets = void 0; |
|
if (isNumeric(+offset)) { |
|
offsets = [+offset, 0]; |
|
} else { |
|
offsets = parseOffset(offset, popper, reference, basePlacement); |
|
} |
|
|
|
if (basePlacement === 'left') { |
|
popper.top += offsets[0]; |
|
popper.left -= offsets[1]; |
|
} else if (basePlacement === 'right') { |
|
popper.top += offsets[0]; |
|
popper.left += offsets[1]; |
|
} else if (basePlacement === 'top') { |
|
popper.left += offsets[0]; |
|
popper.top -= offsets[1]; |
|
} else if (basePlacement === 'bottom') { |
|
popper.left += offsets[0]; |
|
popper.top += offsets[1]; |
|
} |
|
|
|
data.popper = popper; |
|
return data; |
|
} |
|
|
|
/** |
|
* @function |
|
* @memberof Modifiers |
|
* @argument {Object} data - The data object generated by `update` method |
|
* @argument {Object} options - Modifiers configuration and options |
|
* @returns {Object} The data object, properly modified |
|
*/ |
|
function preventOverflow(data, options) { |
|
var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper); |
|
|
|
// If offsetParent is the reference element, we really want to |
|
// go one step up and use the next offsetParent as reference to |
|
// avoid to make this modifier completely useless and look like broken |
|
if (data.instance.reference === boundariesElement) { |
|
boundariesElement = getOffsetParent(boundariesElement); |
|
} |
|
|
|
// NOTE: DOM access here |
|
// resets the popper's position so that the document size can be calculated excluding |
|
// the size of the popper element itself |
|
var transformProp = getSupportedPropertyName('transform'); |
|
var popperStyles = data.instance.popper.style; // assignment to help minification |
|
var top = popperStyles.top, |
|
left = popperStyles.left, |
|
transform = popperStyles[transformProp]; |
|
|
|
popperStyles.top = ''; |
|
popperStyles.left = ''; |
|
popperStyles[transformProp] = ''; |
|
|
|
var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement, data.positionFixed); |
|
|
|
// NOTE: DOM access here |
|
// restores the original style properties after the offsets have been computed |
|
popperStyles.top = top; |
|
popperStyles.left = left; |
|
popperStyles[transformProp] = transform; |
|
|
|
options.boundaries = boundaries; |
|
|
|
var order = options.priority; |
|
var popper = data.offsets.popper; |
|
|
|
var check = { |
|
primary: function primary(placement) { |
|
var value = popper[placement]; |
|
if (popper[placement] < boundaries[placement] && !options.escapeWithReference) { |
|
value = Math.max(popper[placement], boundaries[placement]); |
|
} |
|
return defineProperty({}, placement, value); |
|
}, |
|
secondary: function secondary(placement) { |
|
var mainSide = placement === 'right' ? 'left' : 'top'; |
|
var value = popper[mainSide]; |
|
if (popper[placement] > boundaries[placement] && !options.escapeWithReference) { |
|
value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height)); |
|
} |
|
return defineProperty({}, mainSide, value); |
|
} |
|
}; |
|
|
|
order.forEach(function (placement) { |
|
var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary'; |
|
popper = _extends({}, popper, check[side](placement)); |
|
}); |
|
|
|
data.offsets.popper = popper; |
|
|
|
return data; |
|
} |
|
|
|
/** |
|
* @function |
|
* @memberof Modifiers |
|
* @argument {Object} data - The data object generated by `update` method |
|
* @argument {Object} options - Modifiers configuration and options |
|
* @returns {Object} The data object, properly modified |
|
*/ |
|
function shift(data) { |
|
var placement = data.placement; |
|
var basePlacement = placement.split('-')[0]; |
|
var shiftvariation = placement.split('-')[1]; |
|
|
|
// if shift shiftvariation is specified, run the modifier |
|
if (shiftvariation) { |
|
var _data$offsets = data.offsets, |
|
reference = _data$offsets.reference, |
|
popper = _data$offsets.popper; |
|
|
|
var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1; |
|
var side = isVertical ? 'left' : 'top'; |
|
var measurement = isVertical ? 'width' : 'height'; |
|
|
|
var shiftOffsets = { |
|
start: defineProperty({}, side, reference[side]), |
|
end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement]) |
|
}; |
|
|
|
data.offsets.popper = _extends({}, popper, shiftOffsets[shiftvariation]); |
|
} |
|
|
|
return data; |
|
} |
|
|
|
/** |
|
* @function |
|
* @memberof Modifiers |
|
* @argument {Object} data - The data object generated by update method |
|
* @argument {Object} options - Modifiers configuration and options |
|
* @returns {Object} The data object, properly modified |
|
*/ |
|
function hide(data) { |
|
if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) { |
|
return data; |
|
} |
|
|
|
var refRect = data.offsets.reference; |
|
var bound = find(data.instance.modifiers, function (modifier) { |
|
return modifier.name === 'preventOverflow'; |
|
}).boundaries; |
|
|
|
if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) { |
|
// Avoid unnecessary DOM access if visibility hasn't changed |
|
if (data.hide === true) { |
|
return data; |
|
} |
|
|
|
data.hide = true; |
|
data.attributes['x-out-of-boundaries'] = ''; |
|
} else { |
|
// Avoid unnecessary DOM access if visibility hasn't changed |
|
if (data.hide === false) { |
|
return data; |
|
} |
|
|
|
data.hide = false; |
|
data.attributes['x-out-of-boundaries'] = false; |
|
} |
|
|
|
return data; |
|
} |
|
|
|
/** |
|
* @function |
|
* @memberof Modifiers |
|
* @argument {Object} data - The data object generated by `update` method |
|
* @argument {Object} options - Modifiers configuration and options |
|
* @returns {Object} The data object, properly modified |
|
*/ |
|
function inner(data) { |
|
var placement = data.placement; |
|
var basePlacement = placement.split('-')[0]; |
|
var _data$offsets = data.offsets, |
|
popper = _data$offsets.popper, |
|
reference = _data$offsets.reference; |
|
|
|
var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1; |
|
|
|
var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1; |
|
|
|
popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0); |
|
|
|
data.placement = getOppositePlacement(placement); |
|
data.offsets.popper = getClientRect(popper); |
|
|
|
return data; |
|
} |
|
|
|
/** |
|
* Modifier function, each modifier can have a function of this type assigned |
|
* to its `fn` property.<br /> |
|
* These functions will be called on each update, this means that you must |
|
* make sure they are performant enough to avoid performance bottlenecks. |
|
* |
|
* @function ModifierFn |
|
* @argument {dataObject} data - The data object generated by `update` method |
|
* @argument {Object} options - Modifiers configuration and options |
|
* @returns {dataObject} The data object, properly modified |
|
*/ |
|
|
|
/** |
|
* Modifiers are plugins used to alter the behavior of your poppers.<br /> |
|
* Popper.js uses a set of 9 modifiers to provide all the basic functionalities |
|
* needed by the library. |
|
* |
|
* Usually you don't want to override the `order`, `fn` and `onLoad` props. |
|
* All the other properties are configurations that could be tweaked. |
|
* @namespace modifiers |
|
*/ |
|
var modifiers = { |
|
/** |
|
* Modifier used to shift the popper on the start or end of its reference |
|
* element.<br /> |
|
* It will read the variation of the `placement` property.<br /> |
|
* It can be one either `-end` or `-start`. |
|
* @memberof modifiers |
|
* @inner |
|
*/ |
|
shift: { |
|
/** @prop {number} order=100 - Index used to define the order of execution */ |
|
order: 100, |
|
/** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ |
|
enabled: true, |
|
/** @prop {ModifierFn} */ |
|
fn: shift |
|
}, |
|
|
|
/** |
|
* The `offset` modifier can shift your popper on both its axis. |
|
* |
|
* It accepts the following units: |
|
* - `px` or unitless, interpreted as pixels |
|
* - `%` or `%r`, percentage relative to the length of the reference element |
|
* - `%p`, percentage relative to the length of the popper element |
|
* - `vw`, CSS viewport width unit |
|
* - `vh`, CSS viewport height unit |
|
* |
|
* For length is intended the main axis relative to the placement of the popper.<br /> |
|
* This means that if the placement is `top` or `bottom`, the length will be the |
|
* `width`. In case of `left` or `right`, it will be the height. |
|
* |
|
* You can provide a single value (as `Number` or `String`), or a pair of values |
|
* as `String` divided by a comma or one (or more) white spaces.<br /> |
|
* The latter is a deprecated method because it leads to confusion and will be |
|
* removed in v2.<br /> |
|
* Additionally, it accepts additions and subtractions between different units. |
|
* Note that multiplications and divisions aren't supported. |
|
* |
|
* Valid examples are: |
|
* ``` |
|
* 10 |
|
* '10%' |
|
* '10, 10' |
|
* '10%, 10' |
|
* '10 + 10%' |
|
* '10 - 5vh + 3%' |
|
* '-10px + 5vh, 5px - 6%' |
|
* ``` |
|
* > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap |
|
* > with their reference element, unfortunately, you will have to disable the `flip` modifier. |
|
* > More on this [reading this issue](https://github.com/FezVrasta/popper.js/issues/373) |
|
* |
|
* @memberof modifiers |
|
* @inner |
|
*/ |
|
offset: { |
|
/** @prop {number} order=200 - Index used to define the order of execution */ |
|
order: 200, |
|
/** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ |
|
enabled: true, |
|
/** @prop {ModifierFn} */ |
|
fn: offset, |
|
/** @prop {Number|String} offset=0 |
|
* The offset value as described in the modifier description |
|
*/ |
|
offset: 0 |
|
}, |
|
|
|
/** |
|
* Modifier used to prevent the popper from being positioned outside the boundary. |
|
* |
|
* An scenario exists where the reference itself is not within the boundaries.<br /> |
|
* We can say it has "escaped the boundaries" — or just "escaped".<br /> |
|
* In this case we need to decide whether the popper should either: |
|
* |
|
* - detach from the reference and remain "trapped" in the boundaries, or |
|
* - if it should ignore the boundary and "escape with its reference" |
|
* |
|
* When `escapeWithReference` is set to`true` and reference is completely |
|
* outside its boundaries, the popper will overflow (or completely leave) |
|
* the boundaries in order to remain attached to the edge of the reference. |
|
* |
|
* @memberof modifiers |
|
* @inner |
|
*/ |
|
preventOverflow: { |
|
/** @prop {number} order=300 - Index used to define the order of execution */ |
|
order: 300, |
|
/** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ |
|
enabled: true, |
|
/** @prop {ModifierFn} */ |
|
fn: preventOverflow, |
|
/** |
|
* @prop {Array} [priority=['left','right','top','bottom']] |
|
* Popper will try to prevent overflow following these priorities by default, |
|
* then, it could overflow on the left and on top of the `boundariesElement` |
|
*/ |
|
priority: ['left', 'right', 'top', 'bottom'], |
|
/** |
|
* @prop {number} padding=5 |
|
* Amount of pixel used to define a minimum distance between the boundaries |
|
* and the popper this makes sure the popper has always a little padding |
|
* between the edges of its container |
|
*/ |
|
padding: 5, |
|
/** |
|
* @prop {String|HTMLElement} boundariesElement='scrollParent' |
|
* Boundaries used by the modifier, can be `scrollParent`, `window`, |
|
* `viewport` or any DOM element. |
|
*/ |
|
boundariesElement: 'scrollParent' |
|
}, |
|
|
|
/** |
|
* Modifier used to make sure the reference and its popper stay near eachothers |
|
* without leaving any gap between the two. Expecially useful when the arrow is |
|
* enabled and you want to assure it to point to its reference element. |
|
* It cares only about the first axis, you can still have poppers with margin |
|
* between the popper and its reference element. |
|
* @memberof modifiers |
|
* @inner |
|
*/ |
|
keepTogether: { |
|
/** @prop {number} order=400 - Index used to define the order of execution */ |
|
order: 400, |
|
/** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ |
|
enabled: true, |
|
/** @prop {ModifierFn} */ |
|
fn: keepTogether |
|
}, |
|
|
|
/** |
|
* This modifier is used to move the `arrowElement` of the popper to make |
|
* sure it is positioned between the reference element and its popper element. |
|
* It will read the outer size of the `arrowElement` node to detect how many |
|
* pixels of conjuction are needed. |
|
* |
|
* It has no effect if no `arrowElement` is provided. |
|
* @memberof modifiers |
|
* @inner |
|
*/ |
|
arrow: { |
|
/** @prop {number} order=500 - Index used to define the order of execution */ |
|
order: 500, |
|
/** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ |
|
enabled: true, |
|
/** @prop {ModifierFn} */ |
|
fn: arrow, |
|
/** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */ |
|
element: '[x-arrow]' |
|
}, |
|
|
|
/** |
|
* Modifier used to flip the popper's placement when it starts to overlap its |
|
* reference element. |
|
* |
|
* Requires the `preventOverflow` modifier before it in order to work. |
|
* |
|
* **NOTE:** this modifier will interrupt the current update cycle and will |
|
* restart it if it detects the need to flip the placement. |
|
* @memberof modifiers |
|
* @inner |
|
*/ |
|
flip: { |
|
/** @prop {number} order=600 - Index used to define the order of execution */ |
|
order: 600, |
|
/** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ |
|
enabled: true, |
|
/** @prop {ModifierFn} */ |
|
fn: flip, |
|
/** |
|
* @prop {String|Array} behavior='flip' |
|
* The behavior used to change the popper's placement. It can be one of |
|
* `flip`, `clockwise`, `counterclockwise` or an array with a list of valid |
|
* placements (with optional variations). |
|
*/ |
|
behavior: 'flip', |
|
/** |
|
* @prop {number} padding=5 |
|
* The popper will flip if it hits the edges of the `boundariesElement` |
|
*/ |
|
padding: 5, |
|
/** |
|
* @prop {String|HTMLElement} boundariesElement='viewport' |
|
* The element which will define the boundaries of the popper position, |
|
* the popper will never be placed outside of the defined boundaries |
|
* (except if keepTogether is enabled) |
|
*/ |
|
boundariesElement: 'viewport' |
|
}, |
|
|
|
/** |
|
* Modifier used to make the popper flow toward the inner of the reference element. |
|
* By default, when this modifier is disabled, the popper will be placed outside |
|
* the reference element. |
|
* @memberof modifiers |
|
* @inner |
|
*/ |
|
inner: { |
|
/** @prop {number} order=700 - Index used to define the order of execution */ |
|
order: 700, |
|
/** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */ |
|
enabled: false, |
|
/** @prop {ModifierFn} */ |
|
fn: inner |
|
}, |
|
|
|
/** |
|
* Modifier used to hide the popper when its reference element is outside of the |
|
* popper boundaries. It will set a `x-out-of-boundaries` attribute which can |
|
* be used to hide with a CSS selector the popper when its reference is |
|
* out of boundaries. |
|
* |
|
* Requires the `preventOverflow` modifier before it in order to work. |
|
* @memberof modifiers |
|
* @inner |
|
*/ |
|
hide: { |
|
/** @prop {number} order=800 - Index used to define the order of execution */ |
|
order: 800, |
|
/** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ |
|
enabled: true, |
|
/** @prop {ModifierFn} */ |
|
fn: hide |
|
}, |
|
|
|
/** |
|
* Computes the style that will be applied to the popper element to gets |
|
* properly positioned. |
|
* |
|
* Note that this modifier will not touch the DOM, it just prepares the styles |
|
* so that `applyStyle` modifier can apply it. This separation is useful |
|
* in case you need to replace `applyStyle` with a custom implementation. |
|
* |
|
* This modifier has `850` as `order` value to maintain backward compatibility |
|
* with previous versions of Popper.js. Expect the modifiers ordering method |
|
* to change in future major versions of the library. |
|
* |
|
* @memberof modifiers |
|
* @inner |
|
*/ |
|
computeStyle: { |
|
/** @prop {number} order=850 - Index used to define the order of execution */ |
|
order: 850, |
|
/** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ |
|
enabled: true, |
|
/** @prop {ModifierFn} */ |
|
fn: computeStyle, |
|
/** |
|
* @prop {Boolean} gpuAcceleration=true |
|
* If true, it uses the CSS 3d transformation to position the popper. |
|
* Otherwise, it will use the `top` and `left` properties. |
|
*/ |
|
gpuAcceleration: true, |
|
/** |
|
* @prop {string} [x='bottom'] |
|
* Where to anchor the X axis (`bottom` or `top`). AKA X offset origin. |
|
* Change this if your popper should grow in a direction different from `bottom` |
|
*/ |
|
x: 'bottom', |
|
/** |
|
* @prop {string} [x='left'] |
|
* Where to anchor the Y axis (`left` or `right`). AKA Y offset origin. |
|
* Change this if your popper should grow in a direction different from `right` |
|
*/ |
|
y: 'right' |
|
}, |
|
|
|
/** |
|
* Applies the computed styles to the popper element. |
|
* |
|
* All the DOM manipulations are limited to this modifier. This is useful in case |
|
* you want to integrate Popper.js inside a framework or view library and you |
|
* want to delegate all the DOM manipulations to it. |
|
* |
|
* Note that if you disable this modifier, you must make sure the popper element |
|
* has its position set to `absolute` before Popper.js can do its work! |
|
* |
|
* Just disable this modifier and define you own to achieve the desired effect. |
|
* |
|
* @memberof modifiers |
|
* @inner |
|
*/ |
|
applyStyle: { |
|
/** @prop {number} order=900 - Index used to define the order of execution */ |
|
order: 900, |
|
/** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ |
|
enabled: true, |
|
/** @prop {ModifierFn} */ |
|
fn: applyStyle, |
|
/** @prop {Function} */ |
|
onLoad: applyStyleOnLoad, |
|
/** |
|
* @deprecated since version 1.10.0, the property moved to `computeStyle` modifier |
|
* @prop {Boolean} gpuAcceleration=true |
|
* If true, it uses the CSS 3d transformation to position the popper. |
|
* Otherwise, it will use the `top` and `left` properties. |
|
*/ |
|
gpuAcceleration: undefined |
|
} |
|
}; |
|
|
|
/** |
|
* The `dataObject` is an object containing all the informations used by Popper.js |
|
* this object get passed to modifiers and to the `onCreate` and `onUpdate` callbacks. |
|
* @name dataObject |
|
* @property {Object} data.instance The Popper.js instance |
|
* @property {String} data.placement Placement applied to popper |
|
* @property {String} data.originalPlacement Placement originally defined on init |
|
* @property {Boolean} data.flipped True if popper has been flipped by flip modifier |
|
* @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper. |
|
* @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier |
|
* @property {Object} data.styles Any CSS property defined here will be applied to the popper, it expects the JavaScript nomenclature (eg. `marginBottom`) |
|
* @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow, it expects the JavaScript nomenclature (eg. `marginBottom`) |
|
* @property {Object} data.boundaries Offsets of the popper boundaries |
|
* @property {Object} data.offsets The measurements of popper, reference and arrow elements. |
|
* @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values |
|
* @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values |
|
* @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0 |
|
*/ |
|
|
|
/** |
|
* Default options provided to Popper.js constructor.<br /> |
|
* These can be overriden using the `options` argument of Popper.js.<br /> |
|
* To override an option, simply pass as 3rd argument an object with the same |
|
* structure of this object, example: |
|
* ``` |
|
* new Popper(ref, pop, { |
|
* modifiers: { |
|
* preventOverflow: { enabled: false } |
|
* } |
|
* }) |
|
* ``` |
|
* @type {Object} |
|
* @static |
|
* @memberof Popper |
|
*/ |
|
var Defaults = { |
|
/** |
|
* Popper's placement |
|
* @prop {Popper.placements} placement='bottom' |
|
*/ |
|
placement: 'bottom', |
|
|
|
/** |
|
* Set this to true if you want popper to position it self in 'fixed' mode |
|
* @prop {Boolean} positionFixed=false |
|
*/ |
|
positionFixed: false, |
|
|
|
/** |
|
* Whether events (resize, scroll) are initially enabled |
|
* @prop {Boolean} eventsEnabled=true |
|
*/ |
|
eventsEnabled: true, |
|
|
|
/** |
|
* Set to true if you want to automatically remove the popper when |
|
* you call the `destroy` method. |
|
* @prop {Boolean} removeOnDestroy=false |
|
*/ |
|
removeOnDestroy: false, |
|
|
|
/** |
|
* Callback called when the popper is created.<br /> |
|
* By default, is set to no-op.<br /> |
|
* Access Popper.js instance with `data.instance`. |
|
* @prop {onCreate} |
|
*/ |
|
onCreate: function onCreate() {}, |
|
|
|
/** |
|
* Callback called when the popper is updated, this callback is not called |
|
* on the initialization/creation of the popper, but only on subsequent |
|
* updates.<br /> |
|
* By default, is set to no-op.<br /> |
|
* Access Popper.js instance with `data.instance`. |
|
* @prop {onUpdate} |
|
*/ |
|
onUpdate: function onUpdate() {}, |
|
|
|
/** |
|
* List of modifiers used to modify the offsets before they are applied to the popper. |
|
* They provide most of the functionalities of Popper.js |
|
* @prop {modifiers} |
|
*/ |
|
modifiers: modifiers |
|
}; |
|
|
|
/** |
|
* @callback onCreate |
|
* @param {dataObject} data |
|
*/ |
|
|
|
/** |
|
* @callback onUpdate |
|
* @param {dataObject} data |
|
*/ |
|
|
|
// Utils |
|
// Methods |
|
var Popper = function () { |
|
/** |
|
* Create a new Popper.js instance |
|
* @class Popper |
|
* @param {HTMLElement|referenceObject} reference - The reference element used to position the popper |
|
* @param {HTMLElement} popper - The HTML element used as popper. |
|
* @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults) |
|
* @return {Object} instance - The generated Popper.js instance |
|
*/ |
|
function Popper(reference, popper) { |
|
var _this = this; |
|
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; |
|
classCallCheck(this, Popper); |
|
|
|
this.scheduleUpdate = function () { |
|
return requestAnimationFrame(_this.update); |
|
}; |
|
|
|
// make update() debounced, so that it only runs at most once-per-tick |
|
this.update = debounce(this.update.bind(this)); |
|
|
|
// with {} we create a new object with the options inside it |
|
this.options = _extends({}, Popper.Defaults, options); |
|
|
|
// init state |
|
this.state = { |
|
isDestroyed: false, |
|
isCreated: false, |
|
scrollParents: [] |
|
}; |
|
|
|
// get reference and popper elements (allow jQuery wrappers) |
|
this.reference = reference && reference.jquery ? reference[0] : reference; |
|
this.popper = popper && popper.jquery ? popper[0] : popper; |
|
|
|
// Deep merge modifiers options |
|
this.options.modifiers = {}; |
|
Object.keys(_extends({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) { |
|
_this.options.modifiers[name] = _extends({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {}); |
|
}); |
|
|
|
// Refactoring modifiers' list (Object => Array) |
|
this.modifiers = Object.keys(this.options.modifiers).map(function (name) { |
|
return _extends({ |
|
name: name |
|
}, _this.options.modifiers[name]); |
|
}) |
|
// sort the modifiers by order |
|
.sort(function (a, b) { |
|
return a.order - b.order; |
|
}); |
|
|
|
// modifiers have the ability to execute arbitrary code when Popper.js get inited |
|
// such code is executed in the same order of its modifier |
|
// they could add new properties to their options configuration |
|
// BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`! |
|
this.modifiers.forEach(function (modifierOptions) { |
|
if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) { |
|
modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state); |
|
} |
|
}); |
|
|
|
// fire the first update to position the popper in the right place |
|
this.update(); |
|
|
|
var eventsEnabled = this.options.eventsEnabled; |
|
if (eventsEnabled) { |
|
// setup event listeners, they will take care of update the position in specific situations |
|
this.enableEventListeners(); |
|
} |
|
|
|
this.state.eventsEnabled = eventsEnabled; |
|
} |
|
|
|
// We can't use class properties because they don't get listed in the |
|
// class prototype and break stuff like Sinon stubs |
|
|
|
|
|
createClass(Popper, [{ |
|
key: 'update', |
|
value: function update$$1() { |
|
return update.call(this); |
|
} |
|
}, { |
|
key: 'destroy', |
|
value: function destroy$$1() { |
|
return destroy.call(this); |
|
} |
|
}, { |
|
key: 'enableEventListeners', |
|
value: function enableEventListeners$$1() { |
|
return enableEventListeners.call(this); |
|
} |
|
}, { |
|
key: 'disableEventListeners', |
|
value: function disableEventListeners$$1() { |
|
return disableEventListeners.call(this); |
|
} |
|
|
|
/** |
|
* Schedule an update, it will run on the next UI update available |
|
* @method scheduleUpdate |
|
* @memberof Popper |
|
*/ |
|
|
|
|
|
/** |
|
* Collection of utilities useful when writing custom modifiers. |
|
* Starting from version 1.7, this method is available only if you |
|
* include `popper-utils.js` before `popper.js`. |
|
* |
|
* **DEPRECATION**: This way to access PopperUtils is deprecated |
|
* and will be removed in v2! Use the PopperUtils module directly instead. |
|
* Due to the high instability of the methods contained in Utils, we can't |
|
* guarantee them to follow semver. Use them at your own risk! |
|
* @static |
|
* @private |
|
* @type {Object} |
|
* @deprecated since version 1.8 |
|
* @member Utils |
|
* @memberof Popper |
|
*/ |
|
|
|
}]); |
|
return Popper; |
|
}(); |
|
|
|
/** |
|
* The `referenceObject` is an object that provides an interface compatible with Popper.js |
|
* and lets you use it as replacement of a real DOM node.<br /> |
|
* You can use this method to position a popper relatively to a set of coordinates |
|
* in case you don't have a DOM node to use as reference. |
|
* |
|
* ``` |
|
* new Popper(referenceObject, popperNode); |
|
* ``` |
|
* |
|
* NB: This feature isn't supported in Internet Explorer 10 |
|
* @name referenceObject |
|
* @property {Function} data.getBoundingClientRect |
|
* A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method. |
|
* @property {number} data.clientWidth |
|
* An ES6 getter that will return the width of the virtual reference element. |
|
* @property {number} data.clientHeight |
|
* An ES6 getter that will return the height of the virtual reference element. |
|
*/ |
|
|
|
|
|
Popper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils; |
|
Popper.placements = placements; |
|
Popper.Defaults = Defaults; |
|
|
|
/* harmony default export */ __webpack_exports__["default"] = (Popper); |
|
//# sourceMappingURL=popper.js.map |
|
|
|
/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(1))) |
|
|
|
/***/ }), |
|
/* 4 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! |
|
* jQuery JavaScript Library v3.3.1 |
|
* https://jquery.com/ |
|
* |
|
* Includes Sizzle.js |
|
* https://sizzlejs.com/ |
|
* |
|
* Copyright JS Foundation and other contributors |
|
* Released under the MIT license |
|
* https://jquery.org/license |
|
* |
|
* Date: 2018-01-20T17:24Z |
|
*/ |
|
( function( global, factory ) { |
|
|
|
"use strict"; |
|
|
|
if ( typeof module === "object" && typeof module.exports === "object" ) { |
|
|
|
// For CommonJS and CommonJS-like environments where a proper `window` |
|
// is present, execute the factory and get jQuery. |
|
// For environments that do not have a `window` with a `document` |
|
// (such as Node.js), expose a factory as module.exports. |
|
// This accentuates the need for the creation of a real `window`. |
|
// e.g. var jQuery = require("jquery")(window); |
|
// See ticket #14549 for more info. |
|
module.exports = global.document ? |
|
factory( global, true ) : |
|
function( w ) { |
|
if ( !w.document ) { |
|
throw new Error( "jQuery requires a window with a document" ); |
|
} |
|
return factory( w ); |
|
}; |
|
} else { |
|
factory( global ); |
|
} |
|
|
|
// Pass this if window is not defined yet |
|
} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { |
|
|
|
// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 |
|
// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode |
|
// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common |
|
// enough that all such attempts are guarded in a try block. |
|
"use strict"; |
|
|
|
var arr = []; |
|
|
|
var document = window.document; |
|
|
|
var getProto = Object.getPrototypeOf; |
|
|
|
var slice = arr.slice; |
|
|
|
var concat = arr.concat; |
|
|
|
var push = arr.push; |
|
|
|
var indexOf = arr.indexOf; |
|
|
|
var class2type = {}; |
|
|
|
var toString = class2type.toString; |
|
|
|
var hasOwn = class2type.hasOwnProperty; |
|
|
|
var fnToString = hasOwn.toString; |
|
|
|
var ObjectFunctionString = fnToString.call( Object ); |
|
|
|
var support = {}; |
|
|
|
var isFunction = function isFunction( obj ) { |
|
|
|
// Support: Chrome <=57, Firefox <=52 |
|
// In some browsers, typeof returns "function" for HTML <object> elements |
|
// (i.e., `typeof document.createElement( "object" ) === "function"`). |
|
// We don't want to classify *any* DOM node as a function. |
|
return typeof obj === "function" && typeof obj.nodeType !== "number"; |
|
}; |
|
|
|
|
|
var isWindow = function isWindow( obj ) { |
|
return obj != null && obj === obj.window; |
|
}; |
|
|
|
|
|
|
|
|
|
var preservedScriptAttributes = { |
|
type: true, |
|
src: true, |
|
noModule: true |
|
}; |
|
|
|
function DOMEval( code, doc, node ) { |
|
doc = doc || document; |
|
|
|
var i, |
|
script = doc.createElement( "script" ); |
|
|
|
script.text = code; |
|
if ( node ) { |
|
for ( i in preservedScriptAttributes ) { |
|
if ( node[ i ] ) { |
|
script[ i ] = node[ i ]; |
|
} |
|
} |
|
} |
|
doc.head.appendChild( script ).parentNode.removeChild( script ); |
|
} |
|
|
|
|
|
function toType( obj ) { |
|
if ( obj == null ) { |
|
return obj + ""; |
|
} |
|
|
|
// Support: Android <=2.3 only (functionish RegExp) |
|
return typeof obj === "object" || typeof obj === "function" ? |
|
class2type[ toString.call( obj ) ] || "object" : |
|
typeof obj; |
|
} |
|
/* global Symbol */ |
|
// Defining this global in .eslintrc.json would create a danger of using the global |
|
// unguarded in another place, it seems safer to define global only for this module |
|
|
|
|
|
|
|
var |
|
version = "3.3.1", |
|
|
|
// Define a local copy of jQuery |
|
jQuery = function( selector, context ) { |
|
|
|
// The jQuery object is actually just the init constructor 'enhanced' |
|
// Need init if jQuery is called (just allow error to be thrown if not included) |
|
return new jQuery.fn.init( selector, context ); |
|
}, |
|
|
|
// Support: Android <=4.0 only |
|
// Make sure we trim BOM and NBSP |
|
rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; |
|
|
|
jQuery.fn = jQuery.prototype = { |
|
|
|
// The current version of jQuery being used |
|
jquery: version, |
|
|
|
constructor: jQuery, |
|
|
|
// The default length of a jQuery object is 0 |
|
length: 0, |
|
|
|
toArray: function() { |
|
return slice.call( this ); |
|
}, |
|
|
|
// Get the Nth element in the matched element set OR |
|
// Get the whole matched element set as a clean array |
|
get: function( num ) { |
|
|
|
// Return all the elements in a clean array |
|
if ( num == null ) { |
|
return slice.call( this ); |
|
} |
|
|
|
// Return just the one element from the set |
|
return num < 0 ? this[ num + this.length ] : this[ num ]; |
|
}, |
|
|
|
// Take an array of elements and push it onto the stack |
|
// (returning the new matched element set) |
|
pushStack: function( elems ) { |
|
|
|
// Build a new jQuery matched element set |
|
var ret = jQuery.merge( this.constructor(), elems ); |
|
|
|
// Add the old object onto the stack (as a reference) |
|
ret.prevObject = this; |
|
|
|
// Return the newly-formed element set |
|
return ret; |
|
}, |
|
|
|
// Execute a callback for every element in the matched set. |
|
each: function( callback ) { |
|
return jQuery.each( this, callback ); |
|
}, |
|
|
|
map: function( callback ) { |
|
return this.pushStack( jQuery.map( this, function( elem, i ) { |
|
return callback.call( elem, i, elem ); |
|
} ) ); |
|
}, |
|
|
|
slice: function() { |
|
return this.pushStack( slice.apply( this, arguments ) ); |
|
}, |
|
|
|
first: function() { |
|
return this.eq( 0 ); |
|
}, |
|
|
|
last: function() { |
|
return this.eq( -1 ); |
|
}, |
|
|
|
eq: function( i ) { |
|
var len = this.length, |
|
j = +i + ( i < 0 ? len : 0 ); |
|
return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); |
|
}, |
|
|
|
end: function() { |
|
return this.prevObject || this.constructor(); |
|
}, |
|
|
|
// For internal use only. |
|
// Behaves like an Array's method, not like a jQuery method. |
|
push: push, |
|
sort: arr.sort, |
|
splice: arr.splice |
|
}; |
|
|
|
jQuery.extend = jQuery.fn.extend = function() { |
|
var options, name, src, copy, copyIsArray, clone, |
|
target = arguments[ 0 ] || {}, |
|
i = 1, |
|
length = arguments.length, |
|
deep = false; |
|
|
|
// Handle a deep copy situation |
|
if ( typeof target === "boolean" ) { |
|
deep = target; |
|
|
|
// Skip the boolean and the target |
|
target = arguments[ i ] || {}; |
|
i++; |
|
} |
|
|
|
// Handle case when target is a string or something (possible in deep copy) |
|
if ( typeof target !== "object" && !isFunction( target ) ) { |
|
target = {}; |
|
} |
|
|
|
// Extend jQuery itself if only one argument is passed |
|
if ( i === length ) { |
|
target = this; |
|
i--; |
|
} |
|
|
|
for ( ; i < length; i++ ) { |
|
|
|
// Only deal with non-null/undefined values |
|
if ( ( options = arguments[ i ] ) != null ) { |
|
|
|
// Extend the base object |
|
for ( name in options ) { |
|
src = target[ name ]; |
|
copy = options[ name ]; |
|
|
|
// Prevent never-ending loop |
|
if ( target === copy ) { |
|
continue; |
|
} |
|
|
|
// Recurse if we're merging plain objects or arrays |
|
if ( deep && copy && ( jQuery.isPlainObject( copy ) || |
|
( copyIsArray = Array.isArray( copy ) ) ) ) { |
|
|
|
if ( copyIsArray ) { |
|
copyIsArray = false; |
|
clone = src && Array.isArray( src ) ? src : []; |
|
|
|
} else { |
|
clone = src && jQuery.isPlainObject( src ) ? src : {}; |
|
} |
|
|
|
// Never move original objects, clone them |
|
target[ name ] = jQuery.extend( deep, clone, copy ); |
|
|
|
// Don't bring in undefined values |
|
} else if ( copy !== undefined ) { |
|
target[ name ] = copy; |
|
} |
|
} |
|
} |
|
} |
|
|
|
// Return the modified object |
|
return target; |
|
}; |
|
|
|
jQuery.extend( { |
|
|
|
// Unique for each copy of jQuery on the page |
|
expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), |
|
|
|
// Assume jQuery is ready without the ready module |
|
isReady: true, |
|
|
|
error: function( msg ) { |
|
throw new Error( msg ); |
|
}, |
|
|
|
noop: function() {}, |
|
|
|
isPlainObject: function( obj ) { |
|
var proto, Ctor; |
|
|
|
// Detect obvious negatives |
|
// Use toString instead of jQuery.type to catch host objects |
|
if ( !obj || toString.call( obj ) !== "[object Object]" ) { |
|
return false; |
|
} |
|
|
|
proto = getProto( obj ); |
|
|
|
// Objects with no prototype (e.g., `Object.create( null )`) are plain |
|
if ( !proto ) { |
|
return true; |
|
} |
|
|
|
// Objects with prototype are plain iff they were constructed by a global Object function |
|
Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; |
|
return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; |
|
}, |
|
|
|
isEmptyObject: function( obj ) { |
|
|
|
/* eslint-disable no-unused-vars */ |
|
// See https://github.com/eslint/eslint/issues/6125 |
|
var name; |
|
|
|
for ( name in obj ) { |
|
return false; |
|
} |
|
return true; |
|
}, |
|
|
|
// Evaluates a script in a global context |
|
globalEval: function( code ) { |
|
DOMEval( code ); |
|
}, |
|
|
|
each: function( obj, callback ) { |
|
var length, i = 0; |
|
|
|
if ( isArrayLike( obj ) ) { |
|
length = obj.length; |
|
for ( ; i < length; i++ ) { |
|
if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { |
|
break; |
|
} |
|
} |
|
} else { |
|
for ( i in obj ) { |
|
if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { |
|
break; |
|
} |
|
} |
|
} |
|
|
|
return obj; |
|
}, |
|
|
|
// Support: Android <=4.0 only |
|
trim: function( text ) { |
|
return text == null ? |
|
"" : |
|
( text + "" ).replace( rtrim, "" ); |
|
}, |
|
|
|
// results is for internal usage only |
|
makeArray: function( arr, results ) { |
|
var ret = results || []; |
|
|
|
if ( arr != null ) { |
|
if ( isArrayLike( Object( arr ) ) ) { |
|
jQuery.merge( ret, |
|
typeof arr === "string" ? |
|
[ arr ] : arr |
|
); |
|
} else { |
|
push.call( ret, arr ); |
|
} |
|
} |
|
|
|
return ret; |
|
}, |
|
|
|
inArray: function( elem, arr, i ) { |
|
return arr == null ? -1 : indexOf.call( arr, elem, i ); |
|
}, |
|
|
|
// Support: Android <=4.0 only, PhantomJS 1 only |
|
// push.apply(_, arraylike) throws on ancient WebKit |
|
merge: function( first, second ) { |
|
var len = +second.length, |
|
j = 0, |
|
i = first.length; |
|
|
|
for ( ; j < len; j++ ) { |
|
first[ i++ ] = second[ j ]; |
|
} |
|
|
|
first.length = i; |
|
|
|
return first; |
|
}, |
|
|
|
grep: function( elems, callback, invert ) { |
|
var callbackInverse, |
|
matches = [], |
|
i = 0, |
|
length = elems.length, |
|
callbackExpect = !invert; |
|
|
|
// Go through the array, only saving the items |
|
// that pass the validator function |
|
for ( ; i < length; i++ ) { |
|
callbackInverse = !callback( elems[ i ], i ); |
|
if ( callbackInverse !== callbackExpect ) { |
|
matches.push( elems[ i ] ); |
|
} |
|
} |
|
|
|
return matches; |
|
}, |
|
|
|
// arg is for internal usage only |
|
map: function( elems, callback, arg ) { |
|
var length, value, |
|
i = 0, |
|
ret = []; |
|
|
|
// Go through the array, translating each of the items to their new values |
|
if ( isArrayLike( elems ) ) { |
|
length = elems.length; |
|
for ( ; i < length; i++ ) { |
|
value = callback( elems[ i ], i, arg ); |
|
|
|
if ( value != null ) { |
|
ret.push( value ); |
|
} |
|
} |
|
|
|
// Go through every key on the object, |
|
} else { |
|
for ( i in elems ) { |
|
value = callback( elems[ i ], i, arg ); |
|
|
|
if ( value != null ) { |
|
ret.push( value ); |
|
} |
|
} |
|
} |
|
|
|
// Flatten any nested arrays |
|
return concat.apply( [], ret ); |
|
}, |
|
|
|
// A global GUID counter for objects |
|
guid: 1, |
|
|
|
// jQuery.support is not used in Core but other projects attach their |
|
// properties to it so it needs to exist. |
|
support: support |
|
} ); |
|
|
|
if ( typeof Symbol === "function" ) { |
|
jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; |
|
} |
|
|
|
// Populate the class2type map |
|
jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), |
|
function( i, name ) { |
|
class2type[ "[object " + name + "]" ] = name.toLowerCase(); |
|
} ); |
|
|
|
function isArrayLike( obj ) { |
|
|
|
// Support: real iOS 8.2 only (not reproducible in simulator) |
|
// `in` check used to prevent JIT error (gh-2145) |
|
// hasOwn isn't used here due to false negatives |
|
// regarding Nodelist length in IE |
|
var length = !!obj && "length" in obj && obj.length, |
|
type = toType( obj ); |
|
|
|
if ( isFunction( obj ) || isWindow( obj ) ) { |
|
return false; |
|
} |
|
|
|
return type === "array" || length === 0 || |
|
typeof length === "number" && length > 0 && ( length - 1 ) in obj; |
|
} |
|
var Sizzle = |
|
/*! |
|
* Sizzle CSS Selector Engine v2.3.3 |
|
* https://sizzlejs.com/ |
|
* |
|
* Copyright jQuery Foundation and other contributors |
|
* Released under the MIT license |
|
* http://jquery.org/license |
|
* |
|
* Date: 2016-08-08 |
|
*/ |
|
(function( window ) { |
|
|
|
var i, |
|
support, |
|
Expr, |
|
getText, |
|
isXML, |
|
tokenize, |
|
compile, |
|
select, |
|
outermostContext, |
|
sortInput, |
|
hasDuplicate, |
|
|
|
// Local document vars |
|
setDocument, |
|
document, |
|
docElem, |
|
documentIsHTML, |
|
rbuggyQSA, |
|
rbuggyMatches, |
|
matches, |
|
contains, |
|
|
|
// Instance-specific data |
|
expando = "sizzle" + 1 * new Date(), |
|
preferredDoc = window.document, |
|
dirruns = 0, |
|
done = 0, |
|
classCache = createCache(), |
|
tokenCache = createCache(), |
|
compilerCache = createCache(), |
|
sortOrder = function( a, b ) { |
|
if ( a === b ) { |
|
hasDuplicate = true; |
|
} |
|
return 0; |
|
}, |
|
|
|
// Instance methods |
|
hasOwn = ({}).hasOwnProperty, |
|
arr = [], |
|
pop = arr.pop, |
|
push_native = arr.push, |
|
push = arr.push, |
|
slice = arr.slice, |
|
// Use a stripped-down indexOf as it's faster than native |
|
// https://jsperf.com/thor-indexof-vs-for/5 |
|
indexOf = function( list, elem ) { |
|
var i = 0, |
|
len = list.length; |
|
for ( ; i < len; i++ ) { |
|
if ( list[i] === elem ) { |
|
return i; |
|
} |
|
} |
|
return -1; |
|
}, |
|
|
|
booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", |
|
|
|
// Regular expressions |
|
|
|
// http://www.w3.org/TR/css3-selectors/#whitespace |
|
whitespace = "[\\x20\\t\\r\\n\\f]", |
|
|
|
// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier |
|
identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", |
|
|
|
// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors |
|
attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + |
|
// Operator (capture 2) |
|
"*([*^$|!~]?=)" + whitespace + |
|
// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" |
|
"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + |
|
"*\\]", |
|
|
|
pseudos = ":(" + identifier + ")(?:\\((" + |
|
// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: |
|
// 1. quoted (capture 3; capture 4 or capture 5) |
|
"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + |
|
// 2. simple (capture 6) |
|
"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + |
|
// 3. anything else (capture 2) |
|
".*" + |
|
")\\)|)", |
|
|
|
// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter |
|
rwhitespace = new RegExp( whitespace + "+", "g" ), |
|
rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), |
|
|
|
rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), |
|
rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), |
|
|
|
rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), |
|
|
|
rpseudo = new RegExp( pseudos ), |
|
ridentifier = new RegExp( "^" + identifier + "$" ), |
|
|
|
matchExpr = { |
|
"ID": new RegExp( "^#(" + identifier + ")" ), |
|
"CLASS": new RegExp( "^\\.(" + identifier + ")" ), |
|
"TAG": new RegExp( "^(" + identifier + "|[*])" ), |
|
"ATTR": new RegExp( "^" + attributes ), |
|
"PSEUDO": new RegExp( "^" + pseudos ), |
|
"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + |
|
"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + |
|
"*(\\d+)|))" + whitespace + "*\\)|)", "i" ), |
|
"bool": new RegExp( "^(?:" + booleans + ")$", "i" ), |
|
// For use in libraries implementing .is() |
|
// We use this for POS matching in `select` |
|
"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + |
|
whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) |
|
}, |
|
|
|
rinputs = /^(?:input|select|textarea|button)$/i, |
|
rheader = /^h\d$/i, |
|
|
|
rnative = /^[^{]+\{\s*\[native \w/, |
|
|
|
// Easily-parseable/retrievable ID or TAG or CLASS selectors |
|
rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, |
|
|
|
rsibling = /[+~]/, |
|
|
|
// CSS escapes |
|
// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters |
|
runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), |
|
funescape = function( _, escaped, escapedWhitespace ) { |
|
var high = "0x" + escaped - 0x10000; |
|
// NaN means non-codepoint |
|
// Support: Firefox<24 |
|
// Workaround erroneous numeric interpretation of +"0x" |
|
return high !== high || escapedWhitespace ? |
|
escaped : |
|
high < 0 ? |
|
// BMP codepoint |
|
String.fromCharCode( high + 0x10000 ) : |
|
// Supplemental Plane codepoint (surrogate pair) |
|
String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); |
|
}, |
|
|
|
// CSS string/identifier serialization |
|
// https://drafts.csswg.org/cssom/#common-serializing-idioms |
|
rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, |
|
fcssescape = function( ch, asCodePoint ) { |
|
if ( asCodePoint ) { |
|
|
|
// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER |
|
if ( ch === "\0" ) { |
|
return "\uFFFD"; |
|
} |
|
|
|
// Control characters and (dependent upon position) numbers get escaped as code points |
|
return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; |
|
} |
|
|
|
// Other potentially-special ASCII characters get backslash-escaped |
|
return "\\" + ch; |
|
}, |
|
|
|
// Used for iframes |
|
// See setDocument() |
|
// Removing the function wrapper causes a "Permission Denied" |
|
// error in IE |
|
unloadHandler = function() { |
|
setDocument(); |
|
}, |
|
|
|
disabledAncestor = addCombinator( |
|
function( elem ) { |
|
return elem.disabled === true && ("form" in elem || "label" in elem); |
|
}, |
|
{ dir: "parentNode", next: "legend" } |
|
); |
|
|
|
// Optimize for push.apply( _, NodeList ) |
|
try { |
|
push.apply( |
|
(arr = slice.call( preferredDoc.childNodes )), |
|
preferredDoc.childNodes |
|
); |
|
// Support: Android<4.0 |
|
// Detect silently failing push.apply |
|
arr[ preferredDoc.childNodes.length ].nodeType; |
|
} catch ( e ) { |
|
push = { apply: arr.length ? |
|
|
|
// Leverage slice if possible |
|
function( target, els ) { |
|
push_native.apply( target, slice.call(els) ); |
|
} : |
|
|
|
// Support: IE<9 |
|
// Otherwise append directly |
|
function( target, els ) { |
|
var j = target.length, |
|
i = 0; |
|
// Can't trust NodeList.length |
|
while ( (target[j++] = els[i++]) ) {} |
|
target.length = j - 1; |
|
} |
|
}; |
|
} |
|
|
|
function Sizzle( selector, context, results, seed ) { |
|
var m, i, elem, nid, match, groups, newSelector, |
|
newContext = context && context.ownerDocument, |
|
|
|
// nodeType defaults to 9, since context defaults to document |
|
nodeType = context ? context.nodeType : 9; |
|
|
|
results = results || []; |
|
|
|
// Return early from calls with invalid selector or context |
|
if ( typeof selector !== "string" || !selector || |
|
nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { |
|
|
|
return results; |
|
} |
|
|
|
// Try to shortcut find operations (as opposed to filters) in HTML documents |
|
if ( !seed ) { |
|
|
|
if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { |
|
setDocument( context ); |
|
} |
|
context = context || document; |
|
|
|
if ( documentIsHTML ) { |
|
|
|
// If the selector is sufficiently simple, try using a "get*By*" DOM method |
|
// (excepting DocumentFragment context, where the methods don't exist) |
|
if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { |
|
|
|
// ID selector |
|
if ( (m = match[1]) ) { |
|
|
|
// Document context |
|
if ( nodeType === 9 ) { |
|
if ( (elem = context.getElementById( m )) ) { |
|
|
|
// Support: IE, Opera, Webkit |
|
// TODO: identify versions |
|
// getElementById can match elements by name instead of ID |
|
if ( elem.id === m ) { |
|
results.push( elem ); |
|
return results; |
|
} |
|
} else { |
|
return results; |
|
} |
|
|
|
// Element context |
|
} else { |
|
|
|
// Support: IE, Opera, Webkit |
|
// TODO: identify versions |
|
// getElementById can match elements by name instead of ID |
|
if ( newContext && (elem = newContext.getElementById( m )) && |
|
contains( context, elem ) && |
|
elem.id === m ) { |
|
|
|
results.push( elem ); |
|
return results; |
|
} |
|
} |
|
|
|
// Type selector |
|
} else if ( match[2] ) { |
|
push.apply( results, context.getElementsByTagName( selector ) ); |
|
return results; |
|
|
|
// Class selector |
|
} else if ( (m = match[3]) && support.getElementsByClassName && |
|
context.getElementsByClassName ) { |
|
|
|
push.apply( results, context.getElementsByClassName( m ) ); |
|
return results; |
|
} |
|
} |
|
|
|
// Take advantage of querySelectorAll |
|
if ( support.qsa && |
|
!compilerCache[ selector + " " ] && |
|
(!rbuggyQSA || !rbuggyQSA.test( selector )) ) { |
|
|
|
if ( nodeType !== 1 ) { |
|
newContext = context; |
|
newSelector = selector; |
|
|
|
// qSA looks outside Element context, which is not what we want |
|
// Thanks to Andrew Dupont for this workaround technique |
|
// Support: IE <=8 |
|
// Exclude object elements |
|
} else if ( context.nodeName.toLowerCase() !== "object" ) { |
|
|
|
// Capture the context ID, setting it first if necessary |
|
if ( (nid = context.getAttribute( "id" )) ) { |
|
nid = nid.replace( rcssescape, fcssescape ); |
|
} else { |
|
context.setAttribute( "id", (nid = expando) ); |
|
} |
|
|
|
// Prefix every selector in the list |
|
groups = tokenize( selector ); |
|
i = groups.length; |
|
while ( i-- ) { |
|
groups[i] = "#" + nid + " " + toSelector( groups[i] ); |
|
} |
|
newSelector = groups.join( "," ); |
|
|
|
// Expand context for sibling selectors |
|
newContext = rsibling.test( selector ) && testContext( context.parentNode ) || |
|
context; |
|
} |
|
|
|
if ( newSelector ) { |
|
try { |
|
push.apply( results, |
|
newContext.querySelectorAll( newSelector ) |
|
); |
|
return results; |
|
} catch ( qsaError ) { |
|
} finally { |
|
if ( nid === expando ) { |
|
context.removeAttribute( "id" ); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
// All others |
|
return select( selector.replace( rtrim, "$1" ), context, results, seed ); |
|
} |
|
|
|
/** |
|
* Create key-value caches of limited size |
|
* @returns {function(string, object)} Returns the Object data after storing it on itself with |
|
* property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) |
|
* deleting the oldest entry |
|
*/ |
|
function createCache() { |
|
var keys = []; |
|
|
|
function cache( key, value ) { |
|
// Use (key + " ") to avoid collision with native prototype properties (see Issue #157) |
|
if ( keys.push( key + " " ) > Expr.cacheLength ) { |
|
// Only keep the most recent entries |
|
delete cache[ keys.shift() ]; |
|
} |
|
return (cache[ key + " " ] = value); |
|
} |
|
return cache; |
|
} |
|
|
|
/** |
|
* Mark a function for special use by Sizzle |
|
* @param {Function} fn The function to mark |
|
*/ |
|
function markFunction( fn ) { |
|
fn[ expando ] = true; |
|
return fn; |
|
} |
|
|
|
/** |
|
* Support testing using an element |
|
* @param {Function} fn Passed the created element and returns a boolean result |
|
*/ |
|
function assert( fn ) { |
|
var el = document.createElement("fieldset"); |
|
|
|
try { |
|
return !!fn( el ); |
|
} catch (e) { |
|
return false; |
|
} finally { |
|
// Remove from its parent by default |
|
if ( el.parentNode ) { |
|
el.parentNode.removeChild( el ); |
|
} |
|
// release memory in IE |
|
el = null; |
|
} |
|
} |
|
|
|
/** |
|
* Adds the same handler for all of the specified attrs |
|
* @param {String} attrs Pipe-separated list of attributes |
|
* @param {Function} handler The method that will be applied |
|
*/ |
|
function addHandle( attrs, handler ) { |
|
var arr = attrs.split("|"), |
|
i = arr.length; |
|
|
|
while ( i-- ) { |
|
Expr.attrHandle[ arr[i] ] = handler; |
|
} |
|
} |
|
|
|
/** |
|
* Checks document order of two siblings |
|
* @param {Element} a |
|
* @param {Element} b |
|
* @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b |
|
*/ |
|
function siblingCheck( a, b ) { |
|
var cur = b && a, |
|
diff = cur && a.nodeType === 1 && b.nodeType === 1 && |
|
a.sourceIndex - b.sourceIndex; |
|
|
|
// Use IE sourceIndex if available on both nodes |
|
if ( diff ) { |
|
return diff; |
|
} |
|
|
|
// Check if b follows a |
|
if ( cur ) { |
|
while ( (cur = cur.nextSibling) ) { |
|
if ( cur === b ) { |
|
return -1; |
|
} |
|
} |
|
} |
|
|
|
return a ? 1 : -1; |
|
} |
|
|
|
/** |
|
* Returns a function to use in pseudos for input types |
|
* @param {String} type |
|
*/ |
|
function createInputPseudo( type ) { |
|
return function( elem ) { |
|
var name = elem.nodeName.toLowerCase(); |
|
return name === "input" && elem.type === type; |
|
}; |
|
} |
|
|
|
/** |
|
* Returns a function to use in pseudos for buttons |
|
* @param {String} type |
|
*/ |
|
function createButtonPseudo( type ) { |
|
return function( elem ) { |
|
var name = elem.nodeName.toLowerCase(); |
|
return (name === "input" || name === "button") && elem.type === type; |
|
}; |
|
} |
|
|
|
/** |
|
* Returns a function to use in pseudos for :enabled/:disabled |
|
* @param {Boolean} disabled true for :disabled; false for :enabled |
|
*/ |
|
function createDisabledPseudo( disabled ) { |
|
|
|
// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable |
|
return function( elem ) { |
|
|
|
// Only certain elements can match :enabled or :disabled |
|
// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled |
|
// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled |
|
if ( "form" in elem ) { |
|
|
|
// Check for inherited disabledness on relevant non-disabled elements: |
|
// * listed form-associated elements in a disabled fieldset |
|
// https://html.spec.whatwg.org/multipage/forms.html#category-listed |
|
// https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled |
|
// * option elements in a disabled optgroup |
|
// https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled |
|
// All such elements have a "form" property. |
|
if ( elem.parentNode && elem.disabled === false ) { |
|
|
|
// Option elements defer to a parent optgroup if present |
|
if ( "label" in elem ) { |
|
if ( "label" in elem.parentNode ) { |
|
return elem.parentNode.disabled === disabled; |
|
} else { |
|
return elem.disabled === disabled; |
|
} |
|
} |
|
|
|
// Support: IE 6 - 11 |
|
// Use the isDisabled shortcut property to check for disabled fieldset ancestors |
|
return elem.isDisabled === disabled || |
|
|
|
// Where there is no isDisabled, check manually |
|
/* jshint -W018 */ |
|
elem.isDisabled !== !disabled && |
|
disabledAncestor( elem ) === disabled; |
|
} |
|
|
|
return elem.disabled === disabled; |
|
|
|
// Try to winnow out elements that can't be disabled before trusting the disabled property. |
|
// Some victims get caught in our net (label, legend, menu, track), but it shouldn't |
|
// even exist on them, let alone have a boolean value. |
|
} else if ( "label" in elem ) { |
|
return elem.disabled === disabled; |
|
} |
|
|
|
// Remaining elements are neither :enabled nor :disabled |
|
return false; |
|
}; |
|
} |
|
|
|
/** |
|
* Returns a function to use in pseudos for positionals |
|
* @param {Function} fn |
|
*/ |
|
function createPositionalPseudo( fn ) { |
|
return markFunction(function( argument ) { |
|
argument = +argument; |
|
return markFunction(function( seed, matches ) { |
|
var j, |
|
matchIndexes = fn( [], seed.length, argument ), |
|
i = matchIndexes.length; |
|
|
|
// Match elements found at the specified indexes |
|
while ( i-- ) { |
|
if ( seed[ (j = matchIndexes[i]) ] ) { |
|
seed[j] = !(matches[j] = seed[j]); |
|
} |
|
} |
|
}); |
|
}); |
|
} |
|
|
|
/** |
|
* Checks a node for validity as a Sizzle context |
|
* @param {Element|Object=} context |
|
* @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value |
|
*/ |
|
function testContext( context ) { |
|
return context && typeof context.getElementsByTagName !== "undefined" && context; |
|
} |
|
|
|
// Expose support vars for convenience |
|
support = Sizzle.support = {}; |
|
|
|
/** |
|
* Detects XML nodes |
|
* @param {Element|Object} elem An element or a document |
|
* @returns {Boolean} True iff elem is a non-HTML XML node |
|
*/ |
|
isXML = Sizzle.isXML = function( elem ) { |
|
// documentElement is verified for cases where it doesn't yet exist |
|
// (such as loading iframes in IE - #4833) |
|
var documentElement = elem && (elem.ownerDocument || elem).documentElement; |
|
return documentElement ? documentElement.nodeName !== "HTML" : false; |
|
}; |
|
|
|
/** |
|
* Sets document-related variables once based on the current document |
|
* @param {Element|Object} [doc] An element or document object to use to set the document |
|
* @returns {Object} Returns the current document |
|
*/ |
|
setDocument = Sizzle.setDocument = function( node ) { |
|
var hasCompare, subWindow, |
|
doc = node ? node.ownerDocument || node : preferredDoc; |
|
|
|
// Return early if doc is invalid or already selected |
|
if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { |
|
return document; |
|
} |
|
|
|
// Update global variables |
|
document = doc; |
|
docElem = document.documentElement; |
|
documentIsHTML = !isXML( document ); |
|
|
|
// Support: IE 9-11, Edge |
|
// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) |
|
if ( preferredDoc !== document && |
|
(subWindow = document.defaultView) && subWindow.top !== subWindow ) { |
|
|
|
// Support: IE 11, Edge |
|
if ( subWindow.addEventListener ) { |
|
subWindow.addEventListener( "unload", unloadHandler, false ); |
|
|
|
// Support: IE 9 - 10 only |
|
} else if ( subWindow.attachEvent ) { |
|
subWindow.attachEvent( "onunload", unloadHandler ); |
|
} |
|
} |
|
|
|
/* Attributes |
|
---------------------------------------------------------------------- */ |
|
|
|
// Support: IE<8 |
|
// Verify that getAttribute really returns attributes and not properties |
|
// (excepting IE8 booleans) |
|
support.attributes = assert(function( el ) { |
|
el.className = "i"; |
|
return !el.getAttribute("className"); |
|
}); |
|
|
|
/* getElement(s)By* |
|
---------------------------------------------------------------------- */ |
|
|
|
// Check if getElementsByTagName("*") returns only elements |
|
support.getElementsByTagName = assert(function( el ) { |
|
el.appendChild( document.createComment("") ); |
|
return !el.getElementsByTagName("*").length; |
|
}); |
|
|
|
// Support: IE<9 |
|
support.getElementsByClassName = rnative.test( document.getElementsByClassName ); |
|
|
|
// Support: IE<10 |
|
// Check if getElementById returns elements by name |
|
// The broken getElementById methods don't pick up programmatically-set names, |
|
// so use a roundabout getElementsByName test |
|
support.getById = assert(function( el ) { |
|
docElem.appendChild( el ).id = expando; |
|
return !document.getElementsByName || !document.getElementsByName( expando ).length; |
|
}); |
|
|
|
// ID filter and find |
|
if ( support.getById ) { |
|
Expr.filter["ID"] = function( id ) { |
|
var attrId = id.replace( runescape, funescape ); |
|
return function( elem ) { |
|
return elem.getAttribute("id") === attrId; |
|
}; |
|
}; |
|
Expr.find["ID"] = function( id, context ) { |
|
if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { |
|
var elem = context.getElementById( id ); |
|
return elem ? [ elem ] : []; |
|
} |
|
}; |
|
} else { |
|
Expr.filter["ID"] = function( id ) { |
|
var attrId = id.replace( runescape, funescape ); |
|
return function( elem ) { |
|
var node = typeof elem.getAttributeNode !== "undefined" && |
|
elem.getAttributeNode("id"); |
|
return node && node.value === attrId; |
|
}; |
|
}; |
|
|
|
// Support: IE 6 - 7 only |
|
// getElementById is not reliable as a find shortcut |
|
Expr.find["ID"] = function( id, context ) { |
|
if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { |
|
var node, i, elems, |
|
elem = context.getElementById( id ); |
|
|
|
if ( elem ) { |
|
|
|
// Verify the id attribute |
|
node = elem.getAttributeNode("id"); |
|
if ( node && node.value === id ) { |
|
return [ elem ]; |
|
} |
|
|
|
// Fall back on getElementsByName |
|
elems = context.getElementsByName( id ); |
|
i = 0; |
|
while ( (elem = elems[i++]) ) { |
|
node = elem.getAttributeNode("id"); |
|
if ( node && node.value === id ) { |
|
return [ elem ]; |
|
} |
|
} |
|
} |
|
|
|
return []; |
|
} |
|
}; |
|
} |
|
|
|
// Tag |
|
Expr.find["TAG"] = support.getElementsByTagName ? |
|
function( tag, context ) { |
|
if ( typeof context.getElementsByTagName !== "undefined" ) { |
|
return context.getElementsByTagName( tag ); |
|
|
|
// DocumentFragment nodes don't have gEBTN |
|
} else if ( support.qsa ) { |
|
return context.querySelectorAll( tag ); |
|
} |
|
} : |
|
|
|
function( tag, context ) { |
|
var elem, |
|
tmp = [], |
|
i = 0, |
|
// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too |
|
results = context.getElementsByTagName( tag ); |
|
|
|
// Filter out possible comments |
|
if ( tag === "*" ) { |
|
while ( (elem = results[i++]) ) { |
|
if ( elem.nodeType === 1 ) { |
|
tmp.push( elem ); |
|
} |
|
} |
|
|
|
return tmp; |
|
} |
|
return results; |
|
}; |
|
|
|
// Class |
|
Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { |
|
if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { |
|
return context.getElementsByClassName( className ); |
|
} |
|
}; |
|
|
|
/* QSA/matchesSelector |
|
---------------------------------------------------------------------- */ |
|
|
|
// QSA and matchesSelector support |
|
|
|
// matchesSelector(:active) reports false when true (IE9/Opera 11.5) |
|
rbuggyMatches = []; |
|
|
|
// qSa(:focus) reports false when true (Chrome 21) |
|
// We allow this because of a bug in IE8/9 that throws an error |
|
// whenever `document.activeElement` is accessed on an iframe |
|
// So, we allow :focus to pass through QSA all the time to avoid the IE error |
|
// See https://bugs.jquery.com/ticket/13378 |
|
rbuggyQSA = []; |
|
|
|
if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { |
|
// Build QSA regex |
|
// Regex strategy adopted from Diego Perini |
|
assert(function( el ) { |
|
// Select is set to empty string on purpose |
|
// This is to test IE's treatment of not explicitly |
|
// setting a boolean content attribute, |
|
// since its presence should be enough |
|
// https://bugs.jquery.com/ticket/12359 |
|
docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" + |
|
"<select id='" + expando + "-\r\\' msallowcapture=''>" + |
|
"<option selected=''></option></select>"; |
|
|
|
// Support: IE8, Opera 11-12.16 |
|
// Nothing should be selected when empty strings follow ^= or $= or *= |
|
// The test attribute must be unknown in Opera but "safe" for WinRT |
|
// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section |
|
if ( el.querySelectorAll("[msallowcapture^='']").length ) { |
|
rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); |
|
} |
|
|
|
// Support: IE8 |
|
// Boolean attributes and "value" are not treated correctly |
|
if ( !el.querySelectorAll("[selected]").length ) { |
|
rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); |
|
} |
|
|
|
// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ |
|
if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { |
|
rbuggyQSA.push("~="); |
|
} |
|
|
|
// Webkit/Opera - :checked should return selected option elements |
|
// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked |
|
// IE8 throws error here and will not see later tests |
|
if ( !el.querySelectorAll(":checked").length ) { |
|
rbuggyQSA.push(":checked"); |
|
} |
|
|
|
// Support: Safari 8+, iOS 8+ |
|
// https://bugs.webkit.org/show_bug.cgi?id=136851 |
|
// In-page `selector#id sibling-combinator selector` fails |
|
if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { |
|
rbuggyQSA.push(".#.+[+~]"); |
|
} |
|
}); |
|
|
|
assert(function( el ) { |
|
el.innerHTML = "<a href='' disabled='disabled'></a>" + |
|
"<select disabled='disabled'><option/></select>"; |
|
|
|
// Support: Windows 8 Native Apps |
|
// The type and name attributes are restricted during .innerHTML assignment |
|
var input = document.createElement("input"); |
|
input.setAttribute( "type", "hidden" ); |
|
el.appendChild( input ).setAttribute( "name", "D" ); |
|
|
|
// Support: IE8 |
|
// Enforce case-sensitivity of name attribute |
|
if ( el.querySelectorAll("[name=d]").length ) { |
|
rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); |
|
} |
|
|
|
// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) |
|
// IE8 throws error here and will not see later tests |
|
if ( el.querySelectorAll(":enabled").length !== 2 ) { |
|
rbuggyQSA.push( ":enabled", ":disabled" ); |
|
} |
|
|
|
// Support: IE9-11+ |
|
// IE's :disabled selector does not pick up the children of disabled fieldsets |
|
docElem.appendChild( el ).disabled = true; |
|
if ( el.querySelectorAll(":disabled").length !== 2 ) { |
|
rbuggyQSA.push( ":enabled", ":disabled" ); |
|
} |
|
|
|
// Opera 10-11 does not throw on post-comma invalid pseudos |
|
el.querySelectorAll("*,:x"); |
|
rbuggyQSA.push(",.*:"); |
|
}); |
|
} |
|
|
|
if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || |
|
docElem.webkitMatchesSelector || |
|
docElem.mozMatchesSelector || |
|
docElem.oMatchesSelector || |
|
docElem.msMatchesSelector) )) ) { |
|
|
|
assert(function( el ) { |
|
// Check to see if it's possible to do matchesSelector |
|
// on a disconnected node (IE 9) |
|
support.disconnectedMatch = matches.call( el, "*" ); |
|
|
|
// This should fail with an exception |
|
// Gecko does not error, returns false instead |
|
matches.call( el, "[s!='']:x" ); |
|
rbuggyMatches.push( "!=", pseudos ); |
|
}); |
|
} |
|
|
|
rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); |
|
rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); |
|
|
|
/* Contains |
|
---------------------------------------------------------------------- */ |
|
hasCompare = rnative.test( docElem.compareDocumentPosition ); |
|
|
|
// Element contains another |
|
// Purposefully self-exclusive |
|
// As in, an element does not contain itself |
|
contains = hasCompare || rnative.test( docElem.contains ) ? |
|
function( a, b ) { |
|
var adown = a.nodeType === 9 ? a.documentElement : a, |
|
bup = b && b.parentNode; |
|
return a === bup || !!( bup && bup.nodeType === 1 && ( |
|
adown.contains ? |
|
adown.contains( bup ) : |
|
a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 |
|
)); |
|
} : |
|
function( a, b ) { |
|
if ( b ) { |
|
while ( (b = b.parentNode) ) { |
|
if ( b === a ) { |
|
return true; |
|
} |
|
} |
|
} |
|
return false; |
|
}; |
|
|
|
/* Sorting |
|
---------------------------------------------------------------------- */ |
|
|
|
// Document order sorting |
|
sortOrder = hasCompare ? |
|
function( a, b ) { |
|
|
|
// Flag for duplicate removal |
|
if ( a === b ) { |
|
hasDuplicate = true; |
|
return 0; |
|
} |
|
|
|
// Sort on method existence if only one input has compareDocumentPosition |
|
var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; |
|
if ( compare ) { |
|
return compare; |
|
} |
|
|
|
// Calculate position if both inputs belong to the same document |
|
compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? |
|
a.compareDocumentPosition( b ) : |
|
|
|
// Otherwise we know they are disconnected |
|
1; |
|
|
|
// Disconnected nodes |
|
if ( compare & 1 || |
|
(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { |
|
|
|
// Choose the first element that is related to our preferred document |
|
if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { |
|
return -1; |
|
} |
|
if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { |
|
return 1; |
|
} |
|
|
|
// Maintain original order |
|
return sortInput ? |
|
( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : |
|
0; |
|
} |
|
|
|
return compare & 4 ? -1 : 1; |
|
} : |
|
function( a, b ) { |
|
// Exit early if the nodes are identical |
|
if ( a === b ) { |
|
hasDuplicate = true; |
|
return 0; |
|
} |
|
|
|
var cur, |
|
i = 0, |
|
aup = a.parentNode, |
|
bup = b.parentNode, |
|
ap = [ a ], |
|
bp = [ b ]; |
|
|
|
// Parentless nodes are either documents or disconnected |
|
if ( !aup || !bup ) { |
|
return a === document ? -1 : |
|
b === document ? 1 : |
|
aup ? -1 : |
|
bup ? 1 : |
|
sortInput ? |
|
( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : |
|
0; |
|
|
|
// If the nodes are siblings, we can do a quick check |
|
} else if ( aup === bup ) { |
|
return siblingCheck( a, b ); |
|
} |
|
|
|
// Otherwise we need full lists of their ancestors for comparison |
|
cur = a; |
|
while ( (cur = cur.parentNode) ) { |
|
ap.unshift( cur ); |
|
} |
|
cur = b; |
|
while ( (cur = cur.parentNode) ) { |
|
bp.unshift( cur ); |
|
} |
|
|
|
// Walk down the tree looking for a discrepancy |
|
while ( ap[i] === bp[i] ) { |
|
i++; |
|
} |
|
|
|
return i ? |
|
// Do a sibling check if the nodes have a common ancestor |
|
siblingCheck( ap[i], bp[i] ) : |
|
|
|
// Otherwise nodes in our document sort first |
|
ap[i] === preferredDoc ? -1 : |
|
bp[i] === preferredDoc ? 1 : |
|
0; |
|
}; |
|
|
|
return document; |
|
}; |
|
|
|
Sizzle.matches = function( expr, elements ) { |
|
return Sizzle( expr, null, null, elements ); |
|
}; |
|
|
|
Sizzle.matchesSelector = function( elem, expr ) { |
|
// Set document vars if needed |
|
if ( ( elem.ownerDocument || elem ) !== document ) { |
|
setDocument( elem ); |
|
} |
|
|
|
// Make sure that attribute selectors are quoted |
|
expr = expr.replace( rattributeQuotes, "='$1']" ); |
|
|
|
if ( support.matchesSelector && documentIsHTML && |
|
!compilerCache[ expr + " " ] && |
|
( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && |
|
( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { |
|
|
|
try { |
|
var ret = matches.call( elem, expr ); |
|
|
|
// IE 9's matchesSelector returns false on disconnected nodes |
|
if ( ret || support.disconnectedMatch || |
|
// As well, disconnected nodes are said to be in a document |
|
// fragment in IE 9 |
|
elem.document && elem.document.nodeType !== 11 ) { |
|
return ret; |
|
} |
|
} catch (e) {} |
|
} |
|
|
|
return Sizzle( expr, document, null, [ elem ] ).length > 0; |
|
}; |
|
|
|
Sizzle.contains = function( context, elem ) { |
|
// Set document vars if needed |
|
if ( ( context.ownerDocument || context ) !== document ) { |
|
setDocument( context ); |
|
} |
|
return contains( context, elem ); |
|
}; |
|
|
|
Sizzle.attr = function( elem, name ) { |
|
// Set document vars if needed |
|
if ( ( elem.ownerDocument || elem ) !== document ) { |
|
setDocument( elem ); |
|
} |
|
|
|
var fn = Expr.attrHandle[ name.toLowerCase() ], |
|
// Don't get fooled by Object.prototype properties (jQuery #13807) |
|
val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? |
|
fn( elem, name, !documentIsHTML ) : |
|
undefined; |
|
|
|
return val !== undefined ? |
|
val : |
|
support.attributes || !documentIsHTML ? |
|
elem.getAttribute( name ) : |
|
(val = elem.getAttributeNode(name)) && val.specified ? |
|
val.value : |
|
null; |
|
}; |
|
|
|
Sizzle.escape = function( sel ) { |
|
return (sel + "").replace( rcssescape, fcssescape ); |
|
}; |
|
|
|
Sizzle.error = function( msg ) { |
|
throw new Error( "Syntax error, unrecognized expression: " + msg ); |
|
}; |
|
|
|
/** |
|
* Document sorting and removing duplicates |
|
* @param {ArrayLike} results |
|
*/ |
|
Sizzle.uniqueSort = function( results ) { |
|
var elem, |
|
duplicates = [], |
|
j = 0, |
|
i = 0; |
|
|
|
// Unless we *know* we can detect duplicates, assume their presence |
|
hasDuplicate = !support.detectDuplicates; |
|
sortInput = !support.sortStable && results.slice( 0 ); |
|
results.sort( sortOrder ); |
|
|
|
if ( hasDuplicate ) { |
|
while ( (elem = results[i++]) ) { |
|
if ( elem === results[ i ] ) { |
|
j = duplicates.push( i ); |
|
} |
|
} |
|
while ( j-- ) { |
|
results.splice( duplicates[ j ], 1 ); |
|
} |
|
} |
|
|
|
// Clear input after sorting to release objects |
|
// See https://github.com/jquery/sizzle/pull/225 |
|
sortInput = null; |
|
|
|
return results; |
|
}; |
|
|
|
/** |
|
* Utility function for retrieving the text value of an array of DOM nodes |
|
* @param {Array|Element} elem |
|
*/ |
|
getText = Sizzle.getText = function( elem ) { |
|
var node, |
|
ret = "", |
|
i = 0, |
|
nodeType = elem.nodeType; |
|
|
|
if ( !nodeType ) { |
|
// If no nodeType, this is expected to be an array |
|
while ( (node = elem[i++]) ) { |
|
// Do not traverse comment nodes |
|
ret += getText( node ); |
|
} |
|
} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { |
|
// Use textContent for elements |
|
// innerText usage removed for consistency of new lines (jQuery #11153) |
|
if ( typeof elem.textContent === "string" ) { |
|
return elem.textContent; |
|
} else { |
|
// Traverse its children |
|
for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { |
|
ret += getText( elem ); |
|
} |
|
} |
|
} else if ( nodeType === 3 || nodeType === 4 ) { |
|
return elem.nodeValue; |
|
} |
|
// Do not include comment or processing instruction nodes |
|
|
|
return ret; |
|
}; |
|
|
|
Expr = Sizzle.selectors = { |
|
|
|
// Can be adjusted by the user |
|
cacheLength: 50, |
|
|
|
createPseudo: markFunction, |
|
|
|
match: matchExpr, |
|
|
|
attrHandle: {}, |
|
|
|
find: {}, |
|
|
|
relative: { |
|
">": { dir: "parentNode", first: true }, |
|
" ": { dir: "parentNode" }, |
|
"+": { dir: "previousSibling", first: true }, |
|
"~": { dir: "previousSibling" } |
|
}, |
|
|
|
preFilter: { |
|
"ATTR": function( match ) { |
|
match[1] = match[1].replace( runescape, funescape ); |
|
|
|
// Move the given value to match[3] whether quoted or unquoted |
|
match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); |
|
|
|
if ( match[2] === "~=" ) { |
|
match[3] = " " + match[3] + " "; |
|
} |
|
|
|
return match.slice( 0, 4 ); |
|
}, |
|
|
|
"CHILD": function( match ) { |
|
/* matches from matchExpr["CHILD"] |
|
1 type (only|nth|...) |
|
2 what (child|of-type) |
|
3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) |
|
4 xn-component of xn+y argument ([+-]?\d*n|) |
|
5 sign of xn-component |
|
6 x of xn-component |
|
7 sign of y-component |
|
8 y of y-component |
|
*/ |
|
match[1] = match[1].toLowerCase(); |
|
|
|
if ( match[1].slice( 0, 3 ) === "nth" ) { |
|
// nth-* requires argument |
|
if ( !match[3] ) { |
|
Sizzle.error( match[0] ); |
|
} |
|
|
|
// numeric x and y parameters for Expr.filter.CHILD |
|
// remember that false/true cast respectively to 0/1 |
|
match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); |
|
match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); |
|
|
|
// other types prohibit arguments |
|
} else if ( match[3] ) { |
|
Sizzle.error( match[0] ); |
|
} |
|
|
|
return match; |
|
}, |
|
|
|
"PSEUDO": function( match ) { |
|
var excess, |
|
unquoted = !match[6] && match[2]; |
|
|
|
if ( matchExpr["CHILD"].test( match[0] ) ) { |
|
return null; |
|
} |
|
|
|
// Accept quoted arguments as-is |
|
if ( match[3] ) { |
|
match[2] = match[4] || match[5] || ""; |
|
|
|
// Strip excess characters from unquoted arguments |
|
} else if ( unquoted && rpseudo.test( unquoted ) && |
|
// Get excess from tokenize (recursively) |
|
(excess = tokenize( unquoted, true )) && |
|
// advance to the next closing parenthesis |
|
(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { |
|
|
|
// excess is a negative index |
|
match[0] = match[0].slice( 0, excess ); |
|
match[2] = unquoted.slice( 0, excess ); |
|
} |
|
|
|
// Return only captures needed by the pseudo filter method (type and argument) |
|
return match.slice( 0, 3 ); |
|
} |
|
}, |
|
|
|
filter: { |
|
|
|
"TAG": function( nodeNameSelector ) { |
|
var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); |
|
return nodeNameSelector === "*" ? |
|
function() { return true; } : |
|
function( elem ) { |
|
return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; |
|
}; |
|
}, |
|
|
|
"CLASS": function( className ) { |
|
var pattern = classCache[ className + " " ]; |
|
|
|
return pattern || |
|
(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && |
|
classCache( className, function( elem ) { |
|
return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); |
|
}); |
|
}, |
|
|
|
"ATTR": function( name, operator, check ) { |
|
return function( elem ) { |
|
var result = Sizzle.attr( elem, name ); |
|
|
|
if ( result == null ) { |
|
return operator === "!="; |
|
} |
|
if ( !operator ) { |
|
return true; |
|
} |
|
|
|
result += ""; |
|
|
|
return operator === "=" ? result === check : |
|
operator === "!=" ? result !== check : |
|
operator === "^=" ? check && result.indexOf( check ) === 0 : |
|
operator === "*=" ? check && result.indexOf( check ) > -1 : |
|
operator === "$=" ? check && result.slice( -check.length ) === check : |
|
operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : |
|
operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : |
|
false; |
|
}; |
|
}, |
|
|
|
"CHILD": function( type, what, argument, first, last ) { |
|
var simple = type.slice( 0, 3 ) !== "nth", |
|
forward = type.slice( -4 ) !== "last", |
|
ofType = what === "of-type"; |
|
|
|
return first === 1 && last === 0 ? |
|
|
|
// Shortcut for :nth-*(n) |
|
function( elem ) { |
|
return !!elem.parentNode; |
|
} : |
|
|
|
function( elem, context, xml ) { |
|
var cache, uniqueCache, outerCache, node, nodeIndex, start, |
|
dir = simple !== forward ? "nextSibling" : "previousSibling", |
|
parent = elem.parentNode, |
|
name = ofType && elem.nodeName.toLowerCase(), |
|
useCache = !xml && !ofType, |
|
diff = false; |
|
|
|
if ( parent ) { |
|
|
|
// :(first|last|only)-(child|of-type) |
|
if ( simple ) { |
|
while ( dir ) { |
|
node = elem; |
|
while ( (node = node[ dir ]) ) { |
|
if ( ofType ? |
|
node.nodeName.toLowerCase() === name : |
|
node.nodeType === 1 ) { |
|
|
|
return false; |
|
} |
|
} |
|
// Reverse direction for :only-* (if we haven't yet done so) |
|
start = dir = type === "only" && !start && "nextSibling"; |
|
} |
|
return true; |
|
} |
|
|
|
start = [ forward ? parent.firstChild : parent.lastChild ]; |
|
|
|
// non-xml :nth-child(...) stores cache data on `parent` |
|
if ( forward && useCache ) { |
|
|
|
// Seek `elem` from a previously-cached index |
|
|
|
// ...in a gzip-friendly way |
|
node = parent; |
|
outerCache = node[ expando ] || (node[ expando ] = {}); |
|
|
|
// Support: IE <9 only |
|
// Defend against cloned attroperties (jQuery gh-1709) |
|
uniqueCache = outerCache[ node.uniqueID ] || |
|
(outerCache[ node.uniqueID ] = {}); |
|
|
|
cache = uniqueCache[ type ] || []; |
|
nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; |
|
diff = nodeIndex && cache[ 2 ]; |
|
node = nodeIndex && parent.childNodes[ nodeIndex ]; |
|
|
|
while ( (node = ++nodeIndex && node && node[ dir ] || |
|
|
|
// Fallback to seeking `elem` from the start |
|
(diff = nodeIndex = 0) || start.pop()) ) { |
|
|
|
// When found, cache indexes on `parent` and break |
|
if ( node.nodeType === 1 && ++diff && node === elem ) { |
|
uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; |
|
break; |
|
} |
|
} |
|
|
|
} else { |
|
// Use previously-cached element index if available |
|
if ( useCache ) { |
|
// ...in a gzip-friendly way |
|
node = elem; |
|
outerCache = node[ expando ] || (node[ expando ] = {}); |
|
|
|
// Support: IE <9 only |
|
// Defend against cloned attroperties (jQuery gh-1709) |
|
uniqueCache = outerCache[ node.uniqueID ] || |
|
(outerCache[ node.uniqueID ] = {}); |
|
|
|
cache = uniqueCache[ type ] || []; |
|
nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; |
|
diff = nodeIndex; |
|
} |
|
|
|
// xml :nth-child(...) |
|
// or :nth-last-child(...) or :nth(-last)?-of-type(...) |
|
if ( diff === false ) { |
|
// Use the same loop as above to seek `elem` from the start |
|
while ( (node = ++nodeIndex && node && node[ dir ] || |
|
(diff = nodeIndex = 0) || start.pop()) ) { |
|
|
|
if ( ( ofType ? |
|
node.nodeName.toLowerCase() === name : |
|
node.nodeType === 1 ) && |
|
++diff ) { |
|
|
|
// Cache the index of each encountered element |
|
if ( useCache ) { |
|
outerCache = node[ expando ] || (node[ expando ] = {}); |
|
|
|
// Support: IE <9 only |
|
// Defend against cloned attroperties (jQuery gh-1709) |
|
uniqueCache = outerCache[ node.uniqueID ] || |
|
(outerCache[ node.uniqueID ] = {}); |
|
|
|
uniqueCache[ type ] = [ dirruns, diff ]; |
|
} |
|
|
|
if ( node === elem ) { |
|
break; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
// Incorporate the offset, then check against cycle size |
|
diff -= last; |
|
return diff === first || ( diff % first === 0 && diff / first >= 0 ); |
|
} |
|
}; |
|
}, |
|
|
|
"PSEUDO": function( pseudo, argument ) { |
|
// pseudo-class names are case-insensitive |
|
// http://www.w3.org/TR/selectors/#pseudo-classes |
|
// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters |
|
// Remember that setFilters inherits from pseudos |
|
var args, |
|
fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || |
|
Sizzle.error( "unsupported pseudo: " + pseudo ); |
|
|
|
// The user may use createPseudo to indicate that |
|
// arguments are needed to create the filter function |
|
// just as Sizzle does |
|
if ( fn[ expando ] ) { |
|
return fn( argument ); |
|
} |
|
|
|
// But maintain support for old signatures |
|
if ( fn.length > 1 ) { |
|
args = [ pseudo, pseudo, "", argument ]; |
|
return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? |
|
markFunction(function( seed, matches ) { |
|
var idx, |
|
matched = fn( seed, argument ), |
|
i = matched.length; |
|
while ( i-- ) { |
|
idx = indexOf( seed, matched[i] ); |
|
seed[ idx ] = !( matches[ idx ] = matched[i] ); |
|
} |
|
}) : |
|
function( elem ) { |
|
return fn( elem, 0, args ); |
|
}; |
|
} |
|
|
|
return fn; |
|
} |
|
}, |
|
|
|
pseudos: { |
|
// Potentially complex pseudos |
|
"not": markFunction(function( selector ) { |
|
// Trim the selector passed to compile |
|
// to avoid treating leading and trailing |
|
// spaces as combinators |
|
var input = [], |
|
results = [], |
|
matcher = compile( selector.replace( rtrim, "$1" ) ); |
|
|
|
return matcher[ expando ] ? |
|
markFunction(function( seed, matches, context, xml ) { |
|
var elem, |
|
unmatched = matcher( seed, null, xml, [] ), |
|
i = seed.length; |
|
|
|
// Match elements unmatched by `matcher` |
|
while ( i-- ) { |
|
if ( (elem = unmatched[i]) ) { |
|
seed[i] = !(matches[i] = elem); |
|
} |
|
} |
|
}) : |
|
function( elem, context, xml ) { |
|
input[0] = elem; |
|
matcher( input, null, xml, results ); |
|
// Don't keep the element (issue #299) |
|
input[0] = null; |
|
return !results.pop(); |
|
}; |
|
}), |
|
|
|
"has": markFunction(function( selector ) { |
|
return function( elem ) { |
|
return Sizzle( selector, elem ).length > 0; |
|
}; |
|
}), |
|
|
|
"contains": markFunction(function( text ) { |
|
text = text.replace( runescape, funescape ); |
|
return function( elem ) { |
|
return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; |
|
}; |
|
}), |
|
|
|
// "Whether an element is represented by a :lang() selector |
|
// is based solely on the element's language value |
|
// being equal to the identifier C, |
|
// or beginning with the identifier C immediately followed by "-". |
|
// The matching of C against the element's language value is performed case-insensitively. |
|
// The identifier C does not have to be a valid language name." |
|
// http://www.w3.org/TR/selectors/#lang-pseudo |
|
"lang": markFunction( function( lang ) { |
|
// lang value must be a valid identifier |
|
if ( !ridentifier.test(lang || "") ) { |
|
Sizzle.error( "unsupported lang: " + lang ); |
|
} |
|
lang = lang.replace( runescape, funescape ).toLowerCase(); |
|
return function( elem ) { |
|
var elemLang; |
|
do { |
|
if ( (elemLang = documentIsHTML ? |
|
elem.lang : |
|
elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { |
|
|
|
elemLang = elemLang.toLowerCase(); |
|
return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; |
|
} |
|
} while ( (elem = elem.parentNode) && elem.nodeType === 1 ); |
|
return false; |
|
}; |
|
}), |
|
|
|
// Miscellaneous |
|
"target": function( elem ) { |
|
var hash = window.location && window.location.hash; |
|
return hash && hash.slice( 1 ) === elem.id; |
|
}, |
|
|
|
"root": function( elem ) { |
|
return elem === docElem; |
|
}, |
|
|
|
"focus": function( elem ) { |
|
return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); |
|
}, |
|
|
|
// Boolean properties |
|
"enabled": createDisabledPseudo( false ), |
|
"disabled": createDisabledPseudo( true ), |
|
|
|
"checked": function( elem ) { |
|
// In CSS3, :checked should return both checked and selected elements |
|
// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked |
|
var nodeName = elem.nodeName.toLowerCase(); |
|
return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); |
|
}, |
|
|
|
"selected": function( elem ) { |
|
// Accessing this property makes selected-by-default |
|
// options in Safari work properly |
|
if ( elem.parentNode ) { |
|
elem.parentNode.selectedIndex; |
|
} |
|
|
|
return elem.selected === true; |
|
}, |
|
|
|
// Contents |
|
"empty": function( elem ) { |
|
// http://www.w3.org/TR/selectors/#empty-pseudo |
|
// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), |
|
// but not by others (comment: 8; processing instruction: 7; etc.) |
|
// nodeType < 6 works because attributes (2) do not appear as children |
|
for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { |
|
if ( elem.nodeType < 6 ) { |
|
return false; |
|
} |
|
} |
|
return true; |
|
}, |
|
|
|
"parent": function( elem ) { |
|
return !Expr.pseudos["empty"]( elem ); |
|
}, |
|
|
|
// Element/input types |
|
"header": function( elem ) { |
|
return rheader.test( elem.nodeName ); |
|
}, |
|
|
|
"input": function( elem ) { |
|
return rinputs.test( elem.nodeName ); |
|
}, |
|
|
|
"button": function( elem ) { |
|
var name = elem.nodeName.toLowerCase(); |
|
return name === "input" && elem.type === "button" || name === "button"; |
|
}, |
|
|
|
"text": function( elem ) { |
|
var attr; |
|
return elem.nodeName.toLowerCase() === "input" && |
|
elem.type === "text" && |
|
|
|
// Support: IE<8 |
|
// New HTML5 attribute values (e.g., "search") appear with elem.type === "text" |
|
( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); |
|
}, |
|
|
|
// Position-in-collection |
|
"first": createPositionalPseudo(function() { |
|
return [ 0 ]; |
|
}), |
|
|
|
"last": createPositionalPseudo(function( matchIndexes, length ) { |
|
return [ length - 1 ]; |
|
}), |
|
|
|
"eq": createPositionalPseudo(function( matchIndexes, length, argument ) { |
|
return [ argument < 0 ? argument + length : argument ]; |
|
}), |
|
|
|
"even": createPositionalPseudo(function( matchIndexes, length ) { |
|
var i = 0; |
|
for ( ; i < length; i += 2 ) { |
|
matchIndexes.push( i ); |
|
} |
|
return matchIndexes; |
|
}), |
|
|
|
"odd": createPositionalPseudo(function( matchIndexes, length ) { |
|
var i = 1; |
|
for ( ; i < length; i += 2 ) { |
|
matchIndexes.push( i ); |
|
} |
|
return matchIndexes; |
|
}), |
|
|
|
"lt": createPositionalPseudo(function( matchIndexes, length, argument ) { |
|
var i = argument < 0 ? argument + length : argument; |
|
for ( ; --i >= 0; ) { |
|
matchIndexes.push( i ); |
|
} |
|
return matchIndexes; |
|
}), |
|
|
|
"gt": createPositionalPseudo(function( matchIndexes, length, argument ) { |
|
var i = argument < 0 ? argument + length : argument; |
|
for ( ; ++i < length; ) { |
|
matchIndexes.push( i ); |
|
} |
|
return matchIndexes; |
|
}) |
|
} |
|
}; |
|
|
|
Expr.pseudos["nth"] = Expr.pseudos["eq"]; |
|
|
|
// Add button/input type pseudos |
|
for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { |
|
Expr.pseudos[ i ] = createInputPseudo( i ); |
|
} |
|
for ( i in { submit: true, reset: true } ) { |
|
Expr.pseudos[ i ] = createButtonPseudo( i ); |
|
} |
|
|
|
// Easy API for creating new setFilters |
|
function setFilters() {} |
|
setFilters.prototype = Expr.filters = Expr.pseudos; |
|
Expr.setFilters = new setFilters(); |
|
|
|
tokenize = Sizzle.tokenize = function( selector, parseOnly ) { |
|
var matched, match, tokens, type, |
|
soFar, groups, preFilters, |
|
cached = tokenCache[ selector + " " ]; |
|
|
|
if ( cached ) { |
|
return parseOnly ? 0 : cached.slice( 0 ); |
|
} |
|
|
|
soFar = selector; |
|
groups = []; |
|
preFilters = Expr.preFilter; |
|
|
|
while ( soFar ) { |
|
|
|
// Comma and first run |
|
if ( !matched || (match = rcomma.exec( soFar )) ) { |
|
if ( match ) { |
|
// Don't consume trailing commas as valid |
|
soFar = soFar.slice( match[0].length ) || soFar; |
|
} |
|
groups.push( (tokens = []) ); |
|
} |
|
|
|
matched = false; |
|
|
|
// Combinators |
|
if ( (match = rcombinators.exec( soFar )) ) { |
|
matched = match.shift(); |
|
tokens.push({ |
|
value: matched, |
|
// Cast descendant combinators to space |
|
type: match[0].replace( rtrim, " " ) |
|
}); |
|
soFar = soFar.slice( matched.length ); |
|
} |
|
|
|
// Filters |
|
for ( type in Expr.filter ) { |
|
if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || |
|
(match = preFilters[ type ]( match ))) ) { |
|
matched = match.shift(); |
|
tokens.push({ |
|
value: matched, |
|
type: type, |
|
matches: match |
|
}); |
|
soFar = soFar.slice( matched.length ); |
|
} |
|
} |
|
|
|
if ( !matched ) { |
|
break; |
|
} |
|
} |
|
|
|
// Return the length of the invalid excess |
|
// if we're just parsing |
|
// Otherwise, throw an error or return tokens |
|
return parseOnly ? |
|
soFar.length : |
|
soFar ? |
|
Sizzle.error( selector ) : |
|
// Cache the tokens |
|
tokenCache( selector, groups ).slice( 0 ); |
|
}; |
|
|
|
function toSelector( tokens ) { |
|
var i = 0, |
|
len = tokens.length, |
|
selector = ""; |
|
for ( ; i < len; i++ ) { |
|
selector += tokens[i].value; |
|
} |
|
return selector; |
|
} |
|
|
|
function addCombinator( matcher, combinator, base ) { |
|
var dir = combinator.dir, |
|
skip = combinator.next, |
|
key = skip || dir, |
|
checkNonElements = base && key === "parentNode", |
|
doneName = done++; |
|
|
|
return combinator.first ? |
|
// Check against closest ancestor/preceding element |
|
function( elem, context, xml ) { |
|
while ( (elem = elem[ dir ]) ) { |
|
if ( elem.nodeType === 1 || checkNonElements ) { |
|
return matcher( elem, context, xml ); |
|
} |
|
} |
|
return false; |
|
} : |
|
|
|
// Check against all ancestor/preceding elements |
|
function( elem, context, xml ) { |
|
var oldCache, uniqueCache, outerCache, |
|
newCache = [ dirruns, doneName ]; |
|
|
|
// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching |
|
if ( xml ) { |
|
while ( (elem = elem[ dir ]) ) { |
|
if ( elem.nodeType === 1 || checkNonElements ) { |
|
if ( matcher( elem, context, xml ) ) { |
|
return true; |
|
} |
|
} |
|
} |
|
} else { |
|
while ( (elem = elem[ dir ]) ) { |
|
if ( elem.nodeType === 1 || checkNonElements ) { |
|
outerCache = elem[ expando ] || (elem[ expando ] = {}); |
|
|
|
// Support: IE <9 only |
|
// Defend against cloned attroperties (jQuery gh-1709) |
|
uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); |
|
|
|
if ( skip && skip === elem.nodeName.toLowerCase() ) { |
|
elem = elem[ dir ] || elem; |
|
} else if ( (oldCache = uniqueCache[ key ]) && |
|
oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { |
|
|
|
// Assign to newCache so results back-propagate to previous elements |
|
return (newCache[ 2 ] = oldCache[ 2 ]); |
|
} else { |
|
// Reuse newcache so results back-propagate to previous elements |
|
uniqueCache[ key ] = newCache; |
|
|
|
// A match means we're done; a fail means we have to keep checking |
|
if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { |
|
return true; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
return false; |
|
}; |
|
} |
|
|
|
function elementMatcher( matchers ) { |
|
return matchers.length > 1 ? |
|
function( elem, context, xml ) { |
|
var i = matchers.length; |
|
while ( i-- ) { |
|
if ( !matchers[i]( elem, context, xml ) ) { |
|
return false; |
|
} |
|
} |
|
return true; |
|
} : |
|
matchers[0]; |
|
} |
|
|
|
function multipleContexts( selector, contexts, results ) { |
|
var i = 0, |
|
len = contexts.length; |
|
for ( ; i < len; i++ ) { |
|
Sizzle( selector, contexts[i], results ); |
|
} |
|
return results; |
|
} |
|
|
|
function condense( unmatched, map, filter, context, xml ) { |
|
var elem, |
|
newUnmatched = [], |
|
i = 0, |
|
len = unmatched.length, |
|
mapped = map != null; |
|
|
|
for ( ; i < len; i++ ) { |
|
if ( (elem = unmatched[i]) ) { |
|
if ( !filter || filter( elem, context, xml ) ) { |
|
newUnmatched.push( elem ); |
|
if ( mapped ) { |
|
map.push( i ); |
|
} |
|
} |
|
} |
|
} |
|
|
|
return newUnmatched; |
|
} |
|
|
|
function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { |
|
if ( postFilter && !postFilter[ expando ] ) { |
|
postFilter = setMatcher( postFilter ); |
|
} |
|
if ( postFinder && !postFinder[ expando ] ) { |
|
postFinder = setMatcher( postFinder, postSelector ); |
|
} |
|
return markFunction(function( seed, results, context, xml ) { |
|
var temp, i, elem, |
|
preMap = [], |
|
postMap = [], |
|
preexisting = results.length, |
|
|
|
// Get initial elements from seed or context |
|
elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), |
|
|
|
// Prefilter to get matcher input, preserving a map for seed-results synchronization |
|
matcherIn = preFilter && ( seed || !selector ) ? |
|
condense( elems, preMap, preFilter, context, xml ) : |
|
elems, |
|
|
|
matcherOut = matcher ? |
|
// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, |
|
postFinder || ( seed ? preFilter : preexisting || postFilter ) ? |
|
|
|
// ...intermediate processing is necessary |
|
[] : |
|
|
|
// ...otherwise use results directly |
|
results : |
|
matcherIn; |
|
|
|
// Find primary matches |
|
if ( matcher ) { |
|
matcher( matcherIn, matcherOut, context, xml ); |
|
} |
|
|
|
// Apply postFilter |
|
if ( postFilter ) { |
|
temp = condense( matcherOut, postMap ); |
|
postFilter( temp, [], context, xml ); |
|
|
|
// Un-match failing elements by moving them back to matcherIn |
|
i = temp.length; |
|
while ( i-- ) { |
|
if ( (elem = temp[i]) ) { |
|
matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); |
|
} |
|
} |
|
} |
|
|
|
if ( seed ) { |
|
if ( postFinder || preFilter ) { |
|
if ( postFinder ) { |
|
// Get the final matcherOut by condensing this intermediate into postFinder contexts |
|
temp = []; |
|
i = matcherOut.length; |
|
while ( i-- ) { |
|
if ( (elem = matcherOut[i]) ) { |
|
// Restore matcherIn since elem is not yet a final match |
|
temp.push( (matcherIn[i] = elem) ); |
|
} |
|
} |
|
postFinder( null, (matcherOut = []), temp, xml ); |
|
} |
|
|
|
// Move matched elements from seed to results to keep them synchronized |
|
i = matcherOut.length; |
|
while ( i-- ) { |
|
if ( (elem = matcherOut[i]) && |
|
(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { |
|
|
|
seed[temp] = !(results[temp] = elem); |
|
} |
|
} |
|
} |
|
|
|
// Add elements to results, through postFinder if defined |
|
} else { |
|
matcherOut = condense( |
|
matcherOut === results ? |
|
matcherOut.splice( preexisting, matcherOut.length ) : |
|
matcherOut |
|
); |
|
if ( postFinder ) { |
|
postFinder( null, results, matcherOut, xml ); |
|
} else { |
|
push.apply( results, matcherOut ); |
|
} |
|
} |
|
}); |
|
} |
|
|
|
function matcherFromTokens( tokens ) { |
|
var checkContext, matcher, j, |
|
len = tokens.length, |
|
leadingRelative = Expr.relative[ tokens[0].type ], |
|
implicitRelative = leadingRelative || Expr.relative[" "], |
|
i = leadingRelative ? 1 : 0, |
|
|
|
// The foundational matcher ensures that elements are reachable from top-level context(s) |
|
matchContext = addCombinator( function( elem ) { |
|
return elem === checkContext; |
|
}, implicitRelative, true ), |
|
matchAnyContext = addCombinator( function( elem ) { |
|
return indexOf( checkContext, elem ) > -1; |
|
}, implicitRelative, true ), |
|
matchers = [ function( elem, context, xml ) { |
|
var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( |
|
(checkContext = context).nodeType ? |
|
matchContext( elem, context, xml ) : |
|
matchAnyContext( elem, context, xml ) ); |
|
// Avoid hanging onto element (issue #299) |
|
checkContext = null; |
|
return ret; |
|
} ]; |
|
|
|
for ( ; i < len; i++ ) { |
|
if ( (matcher = Expr.relative[ tokens[i].type ]) ) { |
|
matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; |
|
} else { |
|
matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); |
|
|
|
// Return special upon seeing a positional matcher |
|
if ( matcher[ expando ] ) { |
|
// Find the next relative operator (if any) for proper handling |
|
j = ++i; |
|
for ( ; j < len; j++ ) { |
|
if ( Expr.relative[ tokens[j].type ] ) { |
|
break; |
|
} |
|
} |
|
return setMatcher( |
|
i > 1 && elementMatcher( matchers ), |
|
i > 1 && toSelector( |
|
// If the preceding token was a descendant combinator, insert an implicit any-element `*` |
|
tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) |
|
).replace( rtrim, "$1" ), |
|
matcher, |
|
i < j && matcherFromTokens( tokens.slice( i, j ) ), |
|
j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), |
|
j < len && toSelector( tokens ) |
|
); |
|
} |
|
matchers.push( matcher ); |
|
} |
|
} |
|
|
|
return elementMatcher( matchers ); |
|
} |
|
|
|
function matcherFromGroupMatchers( elementMatchers, setMatchers ) { |
|
var bySet = setMatchers.length > 0, |
|
byElement = elementMatchers.length > 0, |
|
superMatcher = function( seed, context, xml, results, outermost ) { |
|
var elem, j, matcher, |
|
matchedCount = 0, |
|
i = "0", |
|
unmatched = seed && [], |
|
setMatched = [], |
|
contextBackup = outermostContext, |
|
// We must always have either seed elements or outermost context |
|
elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), |
|
// Use integer dirruns iff this is the outermost matcher |
|
dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), |
|
len = elems.length; |
|
|
|
if ( outermost ) { |
|
outermostContext = context === document || context || outermost; |
|
} |
|
|
|
// Add elements passing elementMatchers directly to results |
|
// Support: IE<9, Safari |
|
// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id |
|
for ( ; i !== len && (elem = elems[i]) != null; i++ ) { |
|
if ( byElement && elem ) { |
|
j = 0; |
|
if ( !context && elem.ownerDocument !== document ) { |
|
setDocument( elem ); |
|
xml = !documentIsHTML; |
|
} |
|
while ( (matcher = elementMatchers[j++]) ) { |
|
if ( matcher( elem, context || document, xml) ) { |
|
results.push( elem ); |
|
break; |
|
} |
|
} |
|
if ( outermost ) { |
|
dirruns = dirrunsUnique; |
|
} |
|
} |
|
|
|
// Track unmatched elements for set filters |
|
if ( bySet ) { |
|
// They will have gone through all possible matchers |
|
if ( (elem = !matcher && elem) ) { |
|
matchedCount--; |
|
} |
|
|
|
// Lengthen the array for every element, matched or not |
|
if ( seed ) { |
|
unmatched.push( elem ); |
|
} |
|
} |
|
} |
|
|
|
// `i` is now the count of elements visited above, and adding it to `matchedCount` |
|
// makes the latter nonnegative. |
|
matchedCount += i; |
|
|
|
// Apply set filters to unmatched elements |
|
// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` |
|
// equals `i`), unless we didn't visit _any_ elements in the above loop because we have |
|
// no element matchers and no seed. |
|
// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that |
|
// case, which will result in a "00" `matchedCount` that differs from `i` but is also |
|
// numerically zero. |
|
if ( bySet && i !== matchedCount ) { |
|
j = 0; |
|
while ( (matcher = setMatchers[j++]) ) { |
|
matcher( unmatched, setMatched, context, xml ); |
|
} |
|
|
|
if ( seed ) { |
|
// Reintegrate element matches to eliminate the need for sorting |
|
if ( matchedCount > 0 ) { |
|
while ( i-- ) { |
|
if ( !(unmatched[i] || setMatched[i]) ) { |
|
setMatched[i] = pop.call( results ); |
|
} |
|
} |
|
} |
|
|
|
// Discard index placeholder values to get only actual matches |
|
setMatched = condense( setMatched ); |
|
} |
|
|
|
// Add matches to results |
|
push.apply( results, setMatched ); |
|
|
|
// Seedless set matches succeeding multiple successful matchers stipulate sorting |
|
if ( outermost && !seed && setMatched.length > 0 && |
|
( matchedCount + setMatchers.length ) > 1 ) { |
|
|
|
Sizzle.uniqueSort( results ); |
|
} |
|
} |
|
|
|
// Override manipulation of globals by nested matchers |
|
if ( outermost ) { |
|
dirruns = dirrunsUnique; |
|
outermostContext = contextBackup; |
|
} |
|
|
|
return unmatched; |
|
}; |
|
|
|
return bySet ? |
|
markFunction( superMatcher ) : |
|
superMatcher; |
|
} |
|
|
|
compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { |
|
var i, |
|
setMatchers = [], |
|
elementMatchers = [], |
|
cached = compilerCache[ selector + " " ]; |
|
|
|
if ( !cached ) { |
|
// Generate a function of recursive functions that can be used to check each element |
|
if ( !match ) { |
|
match = tokenize( selector ); |
|
} |
|
i = match.length; |
|
while ( i-- ) { |
|
cached = matcherFromTokens( match[i] ); |
|
if ( cached[ expando ] ) { |
|
setMatchers.push( cached ); |
|
} else { |
|
elementMatchers.push( cached ); |
|
} |
|
} |
|
|
|
// Cache the compiled function |
|
cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); |
|
|
|
// Save selector and tokenization |
|
cached.selector = selector; |
|
} |
|
return cached; |
|
}; |
|
|
|
/** |
|
* A low-level selection function that works with Sizzle's compiled |
|
* selector functions |
|
* @param {String|Function} selector A selector or a pre-compiled |
|
* selector function built with Sizzle.compile |
|
* @param {Element} context |
|
* @param {Array} [results] |
|
* @param {Array} [seed] A set of elements to match against |
|
*/ |
|
select = Sizzle.select = function( selector, context, results, seed ) { |
|
var i, tokens, token, type, find, |
|
compiled = typeof selector === "function" && selector, |
|
match = !seed && tokenize( (selector = compiled.selector || selector) ); |
|
|
|
results = results || []; |
|
|
|
// Try to minimize operations if there is only one selector in the list and no seed |
|
// (the latter of which guarantees us context) |
|
if ( match.length === 1 ) { |
|
|
|
// Reduce context if the leading compound selector is an ID |
|
tokens = match[0] = match[0].slice( 0 ); |
|
if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && |
|
context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) { |
|
|
|
context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; |
|
if ( !context ) { |
|
return results; |
|
|
|
// Precompiled matchers will still verify ancestry, so step up a level |
|
} else if ( compiled ) { |
|
context = context.parentNode; |
|
} |
|
|
|
selector = selector.slice( tokens.shift().value.length ); |
|
} |
|
|
|
// Fetch a seed set for right-to-left matching |
|
i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; |
|
while ( i-- ) { |
|
token = tokens[i]; |
|
|
|
// Abort if we hit a combinator |
|
if ( Expr.relative[ (type = token.type) ] ) { |
|
break; |
|
} |
|
if ( (find = Expr.find[ type ]) ) { |
|
// Search, expanding context for leading sibling combinators |
|
if ( (seed = find( |
|
token.matches[0].replace( runescape, funescape ), |
|
rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context |
|
)) ) { |
|
|
|
// If seed is empty or no tokens remain, we can return early |
|
tokens.splice( i, 1 ); |
|
selector = seed.length && toSelector( tokens ); |
|
if ( !selector ) { |
|
push.apply( results, seed ); |
|
return results; |
|
} |
|
|
|
break; |
|
} |
|
} |
|
} |
|
} |
|
|
|
// Compile and execute a filtering function if one is not provided |
|
// Provide `match` to avoid retokenization if we modified the selector above |
|
( compiled || compile( selector, match ) )( |
|
seed, |
|
context, |
|
!documentIsHTML, |
|
results, |
|
!context || rsibling.test( selector ) && testContext( context.parentNode ) || context |
|
); |
|
return results; |
|
}; |
|
|
|
// One-time assignments |
|
|
|
// Sort stability |
|
support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; |
|
|
|
// Support: Chrome 14-35+ |
|
// Always assume duplicates if they aren't passed to the comparison function |
|
support.detectDuplicates = !!hasDuplicate; |
|
|
|
// Initialize against the default document |
|
setDocument(); |
|
|
|
// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) |
|
// Detached nodes confoundingly follow *each other* |
|
support.sortDetached = assert(function( el ) { |
|
// Should return 1, but returns 4 (following) |
|
return el.compareDocumentPosition( document.createElement("fieldset") ) & 1; |
|
}); |
|
|
|
// Support: IE<8 |
|
// Prevent attribute/property "interpolation" |
|
// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx |
|
if ( !assert(function( el ) { |
|
el.innerHTML = "<a href='#'></a>"; |
|
return el.firstChild.getAttribute("href") === "#" ; |
|
}) ) { |
|
addHandle( "type|href|height|width", function( elem, name, isXML ) { |
|
if ( !isXML ) { |
|
return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); |
|
} |
|
}); |
|
} |
|
|
|
// Support: IE<9 |
|
// Use defaultValue in place of getAttribute("value") |
|
if ( !support.attributes || !assert(function( el ) { |
|
el.innerHTML = "<input/>"; |
|
el.firstChild.setAttribute( "value", "" ); |
|
return el.firstChild.getAttribute( "value" ) === ""; |
|
}) ) { |
|
addHandle( "value", function( elem, name, isXML ) { |
|
if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { |
|
return elem.defaultValue; |
|
} |
|
}); |
|
} |
|
|
|
// Support: IE<9 |
|
// Use getAttributeNode to fetch booleans when getAttribute lies |
|
if ( !assert(function( el ) { |
|
return el.getAttribute("disabled") == null; |
|
}) ) { |
|
addHandle( booleans, function( elem, name, isXML ) { |
|
var val; |
|
if ( !isXML ) { |
|
return elem[ name ] === true ? name.toLowerCase() : |
|
(val = elem.getAttributeNode( name )) && val.specified ? |
|
val.value : |
|
null; |
|
} |
|
}); |
|
} |
|
|
|
return Sizzle; |
|
|
|
})( window ); |
|
|
|
|
|
|
|
jQuery.find = Sizzle; |
|
jQuery.expr = Sizzle.selectors; |
|
|
|
// Deprecated |
|
jQuery.expr[ ":" ] = jQuery.expr.pseudos; |
|
jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; |
|
jQuery.text = Sizzle.getText; |
|
jQuery.isXMLDoc = Sizzle.isXML; |
|
jQuery.contains = Sizzle.contains; |
|
jQuery.escapeSelector = Sizzle.escape; |
|
|
|
|
|
|
|
|
|
var dir = function( elem, dir, until ) { |
|
var matched = [], |
|
truncate = until !== undefined; |
|
|
|
while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { |
|
if ( elem.nodeType === 1 ) { |
|
if ( truncate && jQuery( elem ).is( until ) ) { |
|
break; |
|
} |
|
matched.push( elem ); |
|
} |
|
} |
|
return matched; |
|
}; |
|
|
|
|
|
var siblings = function( n, elem ) { |
|
var matched = []; |
|
|
|
for ( ; n; n = n.nextSibling ) { |
|
if ( n.nodeType === 1 && n !== elem ) { |
|
matched.push( n ); |
|
} |
|
} |
|
|
|
return matched; |
|
}; |
|
|
|
|
|
var rneedsContext = jQuery.expr.match.needsContext; |
|
|
|
|
|
|
|
function nodeName( elem, name ) { |
|
|
|
return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); |
|
|
|
}; |
|
var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); |
|
|
|
|
|
|
|
// Implement the identical functionality for filter and not |
|
function winnow( elements, qualifier, not ) { |
|
if ( isFunction( qualifier ) ) { |
|
return jQuery.grep( elements, function( elem, i ) { |
|
return !!qualifier.call( elem, i, elem ) !== not; |
|
} ); |
|
} |
|
|
|
// Single element |
|
if ( qualifier.nodeType ) { |
|
return jQuery.grep( elements, function( elem ) { |
|
return ( elem === qualifier ) !== not; |
|
} ); |
|
} |
|
|
|
// Arraylike of elements (jQuery, arguments, Array) |
|
if ( typeof qualifier !== "string" ) { |
|
return jQuery.grep( elements, function( elem ) { |
|
return ( indexOf.call( qualifier, elem ) > -1 ) !== not; |
|
} ); |
|
} |
|
|
|
// Filtered directly for both simple and complex selectors |
|
return jQuery.filter( qualifier, elements, not ); |
|
} |
|
|
|
jQuery.filter = function( expr, elems, not ) { |
|
var elem = elems[ 0 ]; |
|
|
|
if ( not ) { |
|
expr = ":not(" + expr + ")"; |
|
} |
|
|
|
if ( elems.length === 1 && elem.nodeType === 1 ) { |
|
return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; |
|
} |
|
|
|
return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { |
|
return elem.nodeType === 1; |
|
} ) ); |
|
}; |
|
|
|
jQuery.fn.extend( { |
|
find: function( selector ) { |
|
var i, ret, |
|
len = this.length, |
|
self = this; |
|
|
|
if ( typeof selector !== "string" ) { |
|
return this.pushStack( jQuery( selector ).filter( function() { |
|
for ( i = 0; i < len; i++ ) { |
|
if ( jQuery.contains( self[ i ], this ) ) { |
|
return true; |
|
} |
|
} |
|
} ) ); |
|
} |
|
|
|
ret = this.pushStack( [] ); |
|
|
|
for ( i = 0; i < len; i++ ) { |
|
jQuery.find( selector, self[ i ], ret ); |
|
} |
|
|
|
return len > 1 ? jQuery.uniqueSort( ret ) : ret; |
|
}, |
|
filter: function( selector ) { |
|
return this.pushStack( winnow( this, selector || [], false ) ); |
|
}, |
|
not: function( selector ) { |
|
return this.pushStack( winnow( this, selector || [], true ) ); |
|
}, |
|
is: function( selector ) { |
|
return !!winnow( |
|
this, |
|
|
|
// If this is a positional/relative selector, check membership in the returned set |
|
// so $("p:first").is("p:last") won't return true for a doc with two "p". |
|
typeof selector === "string" && rneedsContext.test( selector ) ? |
|
jQuery( selector ) : |
|
selector || [], |
|
false |
|
).length; |
|
} |
|
} ); |
|
|
|
|
|
// Initialize a jQuery object |
|
|
|
|
|
// A central reference to the root jQuery(document) |
|
var rootjQuery, |
|
|
|
// A simple way to check for HTML strings |
|
// Prioritize #id over <tag> to avoid XSS via location.hash (#9521) |
|
// Strict HTML recognition (#11290: must start with <) |
|
// Shortcut simple #id case for speed |
|
rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, |
|
|
|
init = jQuery.fn.init = function( selector, context, root ) { |
|
var match, elem; |
|
|
|
// HANDLE: $(""), $(null), $(undefined), $(false) |
|
if ( !selector ) { |
|
return this; |
|
} |
|
|
|
// Method init() accepts an alternate rootjQuery |
|
// so migrate can support jQuery.sub (gh-2101) |
|
root = root || rootjQuery; |
|
|
|
// Handle HTML strings |
|
if ( typeof selector === "string" ) { |
|
if ( selector[ 0 ] === "<" && |
|
selector[ selector.length - 1 ] === ">" && |
|
selector.length >= 3 ) { |
|
|
|
// Assume that strings that start and end with <> are HTML and skip the regex check |
|
match = [ null, selector, null ]; |
|
|
|
} else { |
|
match = rquickExpr.exec( selector ); |
|
} |
|
|
|
// Match html or make sure no context is specified for #id |
|
if ( match && ( match[ 1 ] || !context ) ) { |
|
|
|
// HANDLE: $(html) -> $(array) |
|
if ( match[ 1 ] ) { |
|
context = context instanceof jQuery ? context[ 0 ] : context; |
|
|
|
// Option to run scripts is true for back-compat |
|
// Intentionally let the error be thrown if parseHTML is not present |
|
jQuery.merge( this, jQuery.parseHTML( |
|
match[ 1 ], |
|
context && context.nodeType ? context.ownerDocument || context : document, |
|
true |
|
) ); |
|
|
|
// HANDLE: $(html, props) |
|
if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { |
|
for ( match in context ) { |
|
|
|
// Properties of context are called as methods if possible |
|
if ( isFunction( this[ match ] ) ) { |
|
this[ match ]( context[ match ] ); |
|
|
|
// ...and otherwise set as attributes |
|
} else { |
|
this.attr( match, context[ match ] ); |
|
} |
|
} |
|
} |
|
|
|
return this; |
|
|
|
// HANDLE: $(#id) |
|
} else { |
|
elem = document.getElementById( match[ 2 ] ); |
|
|
|
if ( elem ) { |
|
|
|
// Inject the element directly into the jQuery object |
|
this[ 0 ] = elem; |
|
this.length = 1; |
|
} |
|
return this; |
|
} |
|
|
|
// HANDLE: $(expr, $(...)) |
|
} else if ( !context || context.jquery ) { |
|
return ( context || root ).find( selector ); |
|
|
|
// HANDLE: $(expr, context) |
|
// (which is just equivalent to: $(context).find(expr) |
|
} else { |
|
return this.constructor( context ).find( selector ); |
|
} |
|
|
|
// HANDLE: $(DOMElement) |
|
} else if ( selector.nodeType ) { |
|
this[ 0 ] = selector; |
|
this.length = 1; |
|
return this; |
|
|
|
// HANDLE: $(function) |
|
// Shortcut for document ready |
|
} else if ( isFunction( selector ) ) { |
|
return root.ready !== undefined ? |
|
root.ready( selector ) : |
|
|
|
// Execute immediately if ready is not present |
|
selector( jQuery ); |
|
} |
|
|
|
return jQuery.makeArray( selector, this ); |
|
}; |
|
|
|
// Give the init function the jQuery prototype for later instantiation |
|
init.prototype = jQuery.fn; |
|
|
|
// Initialize central reference |
|
rootjQuery = jQuery( document ); |
|
|
|
|
|
var rparentsprev = /^(?:parents|prev(?:Until|All))/, |
|
|
|
// Methods guaranteed to produce a unique set when starting from a unique set |
|
guaranteedUnique = { |
|
children: true, |
|
contents: true, |
|
next: true, |
|
prev: true |
|
}; |
|
|
|
jQuery.fn.extend( { |
|
has: function( target ) { |
|
var targets = jQuery( target, this ), |
|
l = targets.length; |
|
|
|
return this.filter( function() { |
|
var i = 0; |
|
for ( ; i < l; i++ ) { |
|
if ( jQuery.contains( this, targets[ i ] ) ) { |
|
return true; |
|
} |
|
} |
|
} ); |
|
}, |
|
|
|
closest: function( selectors, context ) { |
|
var cur, |
|
i = 0, |
|
l = this.length, |
|
matched = [], |
|
targets = typeof selectors !== "string" && jQuery( selectors ); |
|
|
|
// Positional selectors never match, since there's no _selection_ context |
|
if ( !rneedsContext.test( selectors ) ) { |
|
for ( ; i < l; i++ ) { |
|
for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { |
|
|
|
// Always skip document fragments |
|
if ( cur.nodeType < 11 && ( targets ? |
|
targets.index( cur ) > -1 : |
|
|
|
// Don't pass non-elements to Sizzle |
|
cur.nodeType === 1 && |
|
jQuery.find.matchesSelector( cur, selectors ) ) ) { |
|
|
|
matched.push( cur ); |
|
break; |
|
} |
|
} |
|
} |
|
} |
|
|
|
return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); |
|
}, |
|
|
|
// Determine the position of an element within the set |
|
index: function( elem ) { |
|
|
|
// No argument, return index in parent |
|
if ( !elem ) { |
|
return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; |
|
} |
|
|
|
// Index in selector |
|
if ( typeof elem === "string" ) { |
|
return indexOf.call( jQuery( elem ), this[ 0 ] ); |
|
} |
|
|
|
// Locate the position of the desired element |
|
return indexOf.call( this, |
|
|
|
// If it receives a jQuery object, the first element is used |
|
elem.jquery ? elem[ 0 ] : elem |
|
); |
|
}, |
|
|
|
add: function( selector, context ) { |
|
return this.pushStack( |
|
jQuery.uniqueSort( |
|
jQuery.merge( this.get(), jQuery( selector, context ) ) |
|
) |
|
); |
|
}, |
|
|
|
addBack: function( selector ) { |
|
return this.add( selector == null ? |
|
this.prevObject : this.prevObject.filter( selector ) |
|
); |
|
} |
|
} ); |
|
|
|
function sibling( cur, dir ) { |
|
while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} |
|
return cur; |
|
} |
|
|
|
jQuery.each( { |
|
parent: function( elem ) { |
|
var parent = elem.parentNode; |
|
return parent && parent.nodeType !== 11 ? parent : null; |
|
}, |
|
parents: function( elem ) { |
|
return dir( elem, "parentNode" ); |
|
}, |
|
parentsUntil: function( elem, i, until ) { |
|
return dir( elem, "parentNode", until ); |
|
}, |
|
next: function( elem ) { |
|
return sibling( elem, "nextSibling" ); |
|
}, |
|
prev: function( elem ) { |
|
return sibling( elem, "previousSibling" ); |
|
}, |
|
nextAll: function( elem ) { |
|
return dir( elem, "nextSibling" ); |
|
}, |
|
prevAll: function( elem ) { |
|
return dir( elem, "previousSibling" ); |
|
}, |
|
nextUntil: function( elem, i, until ) { |
|
return dir( elem, "nextSibling", until ); |
|
}, |
|
prevUntil: function( elem, i, until ) { |
|
return dir( elem, "previousSibling", until ); |
|
}, |
|
siblings: function( elem ) { |
|
return siblings( ( elem.parentNode || {} ).firstChild, elem ); |
|
}, |
|
children: function( elem ) { |
|
return siblings( elem.firstChild ); |
|
}, |
|
contents: function( elem ) { |
|
if ( nodeName( elem, "iframe" ) ) { |
|
return elem.contentDocument; |
|
} |
|
|
|
// Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only |
|
// Treat the template element as a regular one in browsers that |
|
// don't support it. |
|
if ( nodeName( elem, "template" ) ) { |
|
elem = elem.content || elem; |
|
} |
|
|
|
return jQuery.merge( [], elem.childNodes ); |
|
} |
|
}, function( name, fn ) { |
|
jQuery.fn[ name ] = function( until, selector ) { |
|
var matched = jQuery.map( this, fn, until ); |
|
|
|
if ( name.slice( -5 ) !== "Until" ) { |
|
selector = until; |
|
} |
|
|
|
if ( selector && typeof selector === "string" ) { |
|
matched = jQuery.filter( selector, matched ); |
|
} |
|
|
|
if ( this.length > 1 ) { |
|
|
|
// Remove duplicates |
|
if ( !guaranteedUnique[ name ] ) { |
|
jQuery.uniqueSort( matched ); |
|
} |
|
|
|
// Reverse order for parents* and prev-derivatives |
|
if ( rparentsprev.test( name ) ) { |
|
matched.reverse(); |
|
} |
|
} |
|
|
|
return this.pushStack( matched ); |
|
}; |
|
} ); |
|
var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); |
|
|
|
|
|
|
|
// Convert String-formatted options into Object-formatted ones |
|
function createOptions( options ) { |
|
var object = {}; |
|
jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { |
|
object[ flag ] = true; |
|
} ); |
|
return object; |
|
} |
|
|
|
/* |
|
* Create a callback list using the following parameters: |
|
* |
|
* options: an optional list of space-separated options that will change how |
|
* the callback list behaves or a more traditional option object |
|
* |
|
* By default a callback list will act like an event callback list and can be |
|
* "fired" multiple times. |
|
* |
|
* Possible options: |
|
* |
|
* once: will ensure the callback list can only be fired once (like a Deferred) |
|
* |
|
* memory: will keep track of previous values and will call any callback added |
|
* after the list has been fired right away with the latest "memorized" |
|
* values (like a Deferred) |
|
* |
|
* unique: will ensure a callback can only be added once (no duplicate in the list) |
|
* |
|
* stopOnFalse: interrupt callings when a callback returns false |
|
* |
|
*/ |
|
jQuery.Callbacks = function( options ) { |
|
|
|
// Convert options from String-formatted to Object-formatted if needed |
|
// (we check in cache first) |
|
options = typeof options === "string" ? |
|
createOptions( options ) : |
|
jQuery.extend( {}, options ); |
|
|
|
var // Flag to know if list is currently firing |
|
firing, |
|
|
|
// Last fire value for non-forgettable lists |
|
memory, |
|
|
|
// Flag to know if list was already fired |
|
fired, |
|
|
|
// Flag to prevent firing |
|
locked, |
|
|
|
// Actual callback list |
|
list = [], |
|
|
|
// Queue of execution data for repeatable lists |
|
queue = [], |
|
|
|
// Index of currently firing callback (modified by add/remove as needed) |
|
firingIndex = -1, |
|
|
|
// Fire callbacks |
|
fire = function() { |
|
|
|
// Enforce single-firing |
|
locked = locked || options.once; |
|
|
|
// Execute callbacks for all pending executions, |
|
// respecting firingIndex overrides and runtime changes |
|
fired = firing = true; |
|
for ( ; queue.length; firingIndex = -1 ) { |
|
memory = queue.shift(); |
|
while ( ++firingIndex < list.length ) { |
|
|
|
// Run callback and check for early termination |
|
if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && |
|
options.stopOnFalse ) { |
|
|
|
// Jump to end and forget the data so .add doesn't re-fire |
|
firingIndex = list.length; |
|
memory = false; |
|
} |
|
} |
|
} |
|
|
|
// Forget the data if we're done with it |
|
if ( !options.memory ) { |
|
memory = false; |
|
} |
|
|
|
firing = false; |
|
|
|
// Clean up if we're done firing for good |
|
if ( locked ) { |
|
|
|
// Keep an empty list if we have data for future add calls |
|
if ( memory ) { |
|
list = []; |
|
|
|
// Otherwise, this object is spent |
|
} else { |
|
list = ""; |
|
} |
|
} |
|
}, |
|
|
|
// Actual Callbacks object |
|
self = { |
|
|
|
// Add a callback or a collection of callbacks to the list |
|
add: function() { |
|
if ( list ) { |
|
|
|
// If we have memory from a past run, we should fire after adding |
|
if ( memory && !firing ) { |
|
firingIndex = list.length - 1; |
|
queue.push( memory ); |
|
} |
|
|
|
( function add( args ) { |
|
jQuery.each( args, function( _, arg ) { |
|
if ( isFunction( arg ) ) { |
|
if ( !options.unique || !self.has( arg ) ) { |
|
list.push( arg ); |
|
} |
|
} else if ( arg && arg.length && toType( arg ) !== "string" ) { |
|
|
|
// Inspect recursively |
|
add( arg ); |
|
} |
|
} ); |
|
} )( arguments ); |
|
|
|
if ( memory && !firing ) { |
|
fire(); |
|
} |
|
} |
|
return this; |
|
}, |
|
|
|
// Remove a callback from the list |
|
remove: function() { |
|
jQuery.each( arguments, function( _, arg ) { |
|
var index; |
|
while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { |
|
list.splice( index, 1 ); |
|
|
|
// Handle firing indexes |
|
if ( index <= firingIndex ) { |
|
firingIndex--; |
|
} |
|
} |
|
} ); |
|
return this; |
|
}, |
|
|
|
// Check if a given callback is in the list. |
|
// If no argument is given, return whether or not list has callbacks attached. |
|
has: function( fn ) { |
|
return fn ? |
|
jQuery.inArray( fn, list ) > -1 : |
|
list.length > 0; |
|
}, |
|
|
|
// Remove all callbacks from the list |
|
empty: function() { |
|
if ( list ) { |
|
list = []; |
|
} |
|
return this; |
|
}, |
|
|
|
// Disable .fire and .add |
|
// Abort any current/pending executions |
|
// Clear all callbacks and values |
|
disable: function() { |
|
locked = queue = []; |
|
list = memory = ""; |
|
return this; |
|
}, |
|
disabled: function() { |
|
return !list; |
|
}, |
|
|
|
// Disable .fire |
|
// Also disable .add unless we have memory (since it would have no effect) |
|
// Abort any pending executions |
|
lock: function() { |
|
locked = queue = []; |
|
if ( !memory && !firing ) { |
|
list = memory = ""; |
|
} |
|
return this; |
|
}, |
|
locked: function() { |
|
return !!locked; |
|
}, |
|
|
|
// Call all callbacks with the given context and arguments |
|
fireWith: function( context, args ) { |
|
if ( !locked ) { |
|
args = args || []; |
|
args = [ context, args.slice ? args.slice() : args ]; |
|
queue.push( args ); |
|
if ( !firing ) { |
|
fire(); |
|
} |
|
} |
|
return this; |
|
}, |
|
|
|
// Call all the callbacks with the given arguments |
|
fire: function() { |
|
self.fireWith( this, arguments ); |
|
return this; |
|
}, |
|
|
|
// To know if the callbacks have already been called at least once |
|
fired: function() { |
|
return !!fired; |
|
} |
|
}; |
|
|
|
return self; |
|
}; |
|
|
|
|
|
function Identity( v ) { |
|
return v; |
|
} |
|
function Thrower( ex ) { |
|
throw ex; |
|
} |
|
|
|
function adoptValue( value, resolve, reject, noValue ) { |
|
var method; |
|
|
|
try { |
|
|
|
// Check for promise aspect first to privilege synchronous behavior |
|
if ( value && isFunction( ( method = value.promise ) ) ) { |
|
method.call( value ).done( resolve ).fail( reject ); |
|
|
|
// Other thenables |
|
} else if ( value && isFunction( ( method = value.then ) ) ) { |
|
method.call( value, resolve, reject ); |
|
|
|
// Other non-thenables |
|
} else { |
|
|
|
// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: |
|
// * false: [ value ].slice( 0 ) => resolve( value ) |
|
// * true: [ value ].slice( 1 ) => resolve() |
|
resolve.apply( undefined, [ value ].slice( noValue ) ); |
|
} |
|
|
|
// For Promises/A+, convert exceptions into rejections |
|
// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in |
|
// Deferred#then to conditionally suppress rejection. |
|
} catch ( value ) { |
|
|
|
// Support: Android 4.0 only |
|
// Strict mode functions invoked without .call/.apply get global-object context |
|
reject.apply( undefined, [ value ] ); |
|
} |
|
} |
|
|
|
jQuery.extend( { |
|
|
|
Deferred: function( func ) { |
|
var tuples = [ |
|
|
|
// action, add listener, callbacks, |
|
// ... .then handlers, argument index, [final state] |
|
[ "notify", "progress", jQuery.Callbacks( "memory" ), |
|
jQuery.Callbacks( "memory" ), 2 ], |
|
[ "resolve", "done", jQuery.Callbacks( "once memory" ), |
|
jQuery.Callbacks( "once memory" ), 0, "resolved" ], |
|
[ "reject", "fail", jQuery.Callbacks( "once memory" ), |
|
jQuery.Callbacks( "once memory" ), 1, "rejected" ] |
|
], |
|
state = "pending", |
|
promise = { |
|
state: function() { |
|
return state; |
|
}, |
|
always: function() { |
|
deferred.done( arguments ).fail( arguments ); |
|
return this; |
|
}, |
|
"catch": function( fn ) { |
|
return promise.then( null, fn ); |
|
}, |
|
|
|
// Keep pipe for back-compat |
|
pipe: function( /* fnDone, fnFail, fnProgress */ ) { |
|
var fns = arguments; |
|
|
|
return jQuery.Deferred( function( newDefer ) { |
|
jQuery.each( tuples, function( i, tuple ) { |
|
|
|
// Map tuples (progress, done, fail) to arguments (done, fail, progress) |
|
var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; |
|
|
|
// deferred.progress(function() { bind to newDefer or newDefer.notify }) |
|
// deferred.done(function() { bind to newDefer or newDefer.resolve }) |
|
// deferred.fail(function() { bind to newDefer or newDefer.reject }) |
|
deferred[ tuple[ 1 ] ]( function() { |
|
var returned = fn && fn.apply( this, arguments ); |
|
if ( returned && isFunction( returned.promise ) ) { |
|
returned.promise() |
|
.progress( newDefer.notify ) |
|
.done( newDefer.resolve ) |
|
.fail( newDefer.reject ); |
|
} else { |
|
newDefer[ tuple[ 0 ] + "With" ]( |
|
this, |
|
fn ? [ returned ] : arguments |
|
); |
|
} |
|
} ); |
|
} ); |
|
fns = null; |
|
} ).promise(); |
|
}, |
|
then: function( onFulfilled, onRejected, onProgress ) { |
|
var maxDepth = 0; |
|
function resolve( depth, deferred, handler, special ) { |
|
return function() { |
|
var that = this, |
|
args = arguments, |
|
mightThrow = function() { |
|
var returned, then; |
|
|
|
// Support: Promises/A+ section 2.3.3.3.3 |
|
// https://promisesaplus.com/#point-59 |
|
// Ignore double-resolution attempts |
|
if ( depth < maxDepth ) { |
|
return; |
|
} |
|
|
|
returned = handler.apply( that, args ); |
|
|
|
// Support: Promises/A+ section 2.3.1 |
|
// https://promisesaplus.com/#point-48 |
|
if ( returned === deferred.promise() ) { |
|
throw new TypeError( "Thenable self-resolution" ); |
|
} |
|
|
|
// Support: Promises/A+ sections 2.3.3.1, 3.5 |
|
// https://promisesaplus.com/#point-54 |
|
// https://promisesaplus.com/#point-75 |
|
// Retrieve `then` only once |
|
then = returned && |
|
|
|
// Support: Promises/A+ section 2.3.4 |
|
// https://promisesaplus.com/#point-64 |
|
// Only check objects and functions for thenability |
|
( typeof returned === "object" || |
|
typeof returned === "function" ) && |
|
returned.then; |
|
|
|
// Handle a returned thenable |
|
if ( isFunction( then ) ) { |
|
|
|
// Special processors (notify) just wait for resolution |
|
if ( special ) { |
|
then.call( |
|
returned, |
|
resolve( maxDepth, deferred, Identity, special ), |
|
resolve( maxDepth, deferred, Thrower, special ) |
|
); |
|
|
|
// Normal processors (resolve) also hook into progress |
|
} else { |
|
|
|
// ...and disregard older resolution values |
|
maxDepth++; |
|
|
|
then.call( |
|
returned, |
|
resolve( maxDepth, deferred, Identity, special ), |
|
resolve( maxDepth, deferred, Thrower, special ), |
|
resolve( maxDepth, deferred, Identity, |
|
deferred.notifyWith ) |
|
); |
|
} |
|
|
|
// Handle all other returned values |
|
} else { |
|
|
|
// Only substitute handlers pass on context |
|
// and multiple values (non-spec behavior) |
|
if ( handler !== Identity ) { |
|
that = undefined; |
|
args = [ returned ]; |
|
} |
|
|
|
// Process the value(s) |
|
// Default process is resolve |
|
( special || deferred.resolveWith )( that, args ); |
|
} |
|
}, |
|
|
|
// Only normal processors (resolve) catch and reject exceptions |
|
process = special ? |
|
mightThrow : |
|
function() { |
|
try { |
|
mightThrow(); |
|
} catch ( e ) { |
|
|
|
if ( jQuery.Deferred.exceptionHook ) { |
|
jQuery.Deferred.exceptionHook( e, |
|
process.stackTrace ); |
|
} |
|
|
|
// Support: Promises/A+ section 2.3.3.3.4.1 |
|
// https://promisesaplus.com/#point-61 |
|
// Ignore post-resolution exceptions |
|
if ( depth + 1 >= maxDepth ) { |
|
|
|
// Only substitute handlers pass on context |
|
// and multiple values (non-spec behavior) |
|
if ( handler !== Thrower ) { |
|
that = undefined; |
|
args = [ e ]; |
|
} |
|
|
|
deferred.rejectWith( that, args ); |
|
} |
|
} |
|
}; |
|
|
|
// Support: Promises/A+ section 2.3.3.3.1 |
|
// https://promisesaplus.com/#point-57 |
|
// Re-resolve promises immediately to dodge false rejection from |
|
// subsequent errors |
|
if ( depth ) { |
|
process(); |
|
} else { |
|
|
|
// Call an optional hook to record the stack, in case of exception |
|
// since it's otherwise lost when execution goes async |
|
if ( jQuery.Deferred.getStackHook ) { |
|
process.stackTrace = jQuery.Deferred.getStackHook(); |
|
} |
|
window.setTimeout( process ); |
|
} |
|
}; |
|
} |
|
|
|
return jQuery.Deferred( function( newDefer ) { |
|
|
|
// progress_handlers.add( ... ) |
|
tuples[ 0 ][ 3 ].add( |
|
resolve( |
|
0, |
|
newDefer, |
|
isFunction( onProgress ) ? |
|
onProgress : |
|
Identity, |
|
newDefer.notifyWith |
|
) |
|
); |
|
|
|
// fulfilled_handlers.add( ... ) |
|
tuples[ 1 ][ 3 ].add( |
|
resolve( |
|
0, |
|
newDefer, |
|
isFunction( onFulfilled ) ? |
|
onFulfilled : |
|
Identity |
|
) |
|
); |
|
|
|
// rejected_handlers.add( ... ) |
|
tuples[ 2 ][ 3 ].add( |
|
resolve( |
|
0, |
|
newDefer, |
|
isFunction( onRejected ) ? |
|
onRejected : |
|
Thrower |
|
) |
|
); |
|
} ).promise(); |
|
}, |
|
|
|
// Get a promise for this deferred |
|
// If obj is provided, the promise aspect is added to the object |
|
promise: function( obj ) { |
|
return obj != null ? jQuery.extend( obj, promise ) : promise; |
|
} |
|
}, |
|
deferred = {}; |
|
|
|
// Add list-specific methods |
|
jQuery.each( tuples, function( i, tuple ) { |
|
var list = tuple[ 2 ], |
|
stateString = tuple[ 5 ]; |
|
|
|
// promise.progress = list.add |
|
// promise.done = list.add |
|
// promise.fail = list.add |
|
promise[ tuple[ 1 ] ] = list.add; |
|
|
|
// Handle state |
|
if ( stateString ) { |
|
list.add( |
|
function() { |
|
|
|
// state = "resolved" (i.e., fulfilled) |
|
// state = "rejected" |
|
state = stateString; |
|
}, |
|
|
|
// rejected_callbacks.disable |
|
// fulfilled_callbacks.disable |
|
tuples[ 3 - i ][ 2 ].disable, |
|
|
|
// rejected_handlers.disable |
|
// fulfilled_handlers.disable |
|
tuples[ 3 - i ][ 3 ].disable, |
|
|
|
// progress_callbacks.lock |
|
tuples[ 0 ][ 2 ].lock, |
|
|
|
// progress_handlers.lock |
|
tuples[ 0 ][ 3 ].lock |
|
); |
|
} |
|
|
|
// progress_handlers.fire |
|
// fulfilled_handlers.fire |
|
// rejected_handlers.fire |
|
list.add( tuple[ 3 ].fire ); |
|
|
|
// deferred.notify = function() { deferred.notifyWith(...) } |
|
// deferred.resolve = function() { deferred.resolveWith(...) } |
|
// deferred.reject = function() { deferred.rejectWith(...) } |
|
deferred[ tuple[ 0 ] ] = function() { |
|
deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); |
|
return this; |
|
}; |
|
|
|
// deferred.notifyWith = list.fireWith |
|
// deferred.resolveWith = list.fireWith |
|
// deferred.rejectWith = list.fireWith |
|
deferred[ tuple[ 0 ] + "With" ] = list.fireWith; |
|
} ); |
|
|
|
// Make the deferred a promise |
|
promise.promise( deferred ); |
|
|
|
// Call given func if any |
|
if ( func ) { |
|
func.call( deferred, deferred ); |
|
} |
|
|
|
// All done! |
|
return deferred; |
|
}, |
|
|
|
// Deferred helper |
|
when: function( singleValue ) { |
|
var |
|
|
|
// count of uncompleted subordinates |
|
remaining = arguments.length, |
|
|
|
// count of unprocessed arguments |
|
i = remaining, |
|
|
|
// subordinate fulfillment data |
|
resolveContexts = Array( i ), |
|
resolveValues = slice.call( arguments ), |
|
|
|
// the master Deferred |
|
master = jQuery.Deferred(), |
|
|
|
// subordinate callback factory |
|
updateFunc = function( i ) { |
|
return function( value ) { |
|
resolveContexts[ i ] = this; |
|
resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; |
|
if ( !( --remaining ) ) { |
|
master.resolveWith( resolveContexts, resolveValues ); |
|
} |
|
}; |
|
}; |
|
|
|
// Single- and empty arguments are adopted like Promise.resolve |
|
if ( remaining <= 1 ) { |
|
adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, |
|
!remaining ); |
|
|
|
// Use .then() to unwrap secondary thenables (cf. gh-3000) |
|
if ( master.state() === "pending" || |
|
isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { |
|
|
|
return master.then(); |
|
} |
|
} |
|
|
|
// Multiple arguments are aggregated like Promise.all array elements |
|
while ( i-- ) { |
|
adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); |
|
} |
|
|
|
return master.promise(); |
|
} |
|
} ); |
|
|
|
|
|
// These usually indicate a programmer mistake during development, |
|
// warn about them ASAP rather than swallowing them by default. |
|
var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; |
|
|
|
jQuery.Deferred.exceptionHook = function( error, stack ) { |
|
|
|
// Support: IE 8 - 9 only |
|
// Console exists when dev tools are open, which can happen at any time |
|
if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { |
|
window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); |
|
} |
|
}; |
|
|
|
|
|
|
|
|
|
jQuery.readyException = function( error ) { |
|
window.setTimeout( function() { |
|
throw error; |
|
} ); |
|
}; |
|
|
|
|
|
|
|
|
|
// The deferred used on DOM ready |
|
var readyList = jQuery.Deferred(); |
|
|
|
jQuery.fn.ready = function( fn ) { |
|
|
|
readyList |
|
.then( fn ) |
|
|
|
// Wrap jQuery.readyException in a function so that the lookup |
|
// happens at the time of error handling instead of callback |
|
// registration. |
|
.catch( function( error ) { |
|
jQuery.readyException( error ); |
|
} ); |
|
|
|
return this; |
|
}; |
|
|
|
jQuery.extend( { |
|
|
|
// Is the DOM ready to be used? Set to true once it occurs. |
|
isReady: false, |
|
|
|
// A counter to track how many items to wait for before |
|
// the ready event fires. See #6781 |
|
readyWait: 1, |
|
|
|
// Handle when the DOM is ready |
|
ready: function( wait ) { |
|
|
|
// Abort if there are pending holds or we're already ready |
|
if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { |
|
return; |
|
} |
|
|
|
// Remember that the DOM is ready |
|
jQuery.isReady = true; |
|
|
|
// If a normal DOM Ready event fired, decrement, and wait if need be |
|
if ( wait !== true && --jQuery.readyWait > 0 ) { |
|
return; |
|
} |
|
|
|
// If there are functions bound, to execute |
|
readyList.resolveWith( document, [ jQuery ] ); |
|
} |
|
} ); |
|
|
|
jQuery.ready.then = readyList.then; |
|
|
|
// The ready event handler and self cleanup method |
|
function completed() { |
|
document.removeEventListener( "DOMContentLoaded", completed ); |
|
window.removeEventListener( "load", completed ); |
|
jQuery.ready(); |
|
} |
|
|
|
// Catch cases where $(document).ready() is called |
|
// after the browser event has already occurred. |
|
// Support: IE <=9 - 10 only |
|
// Older IE sometimes signals "interactive" too soon |
|
if ( document.readyState === "complete" || |
|
( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { |
|
|
|
// Handle it asynchronously to allow scripts the opportunity to delay ready |
|
window.setTimeout( jQuery.ready ); |
|
|
|
} else { |
|
|
|
// Use the handy event callback |
|
document.addEventListener( "DOMContentLoaded", completed ); |
|
|
|
// A fallback to window.onload, that will always work |
|
window.addEventListener( "load", completed ); |
|
} |
|
|
|
|
|
|
|
|
|
// Multifunctional method to get and set values of a collection |
|
// The value/s can optionally be executed if it's a function |
|
var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { |
|
var i = 0, |
|
len = elems.length, |
|
bulk = key == null; |
|
|
|
// Sets many values |
|
if ( toType( key ) === "object" ) { |
|
chainable = true; |
|
for ( i in key ) { |
|
access( elems, fn, i, key[ i ], true, emptyGet, raw ); |
|
} |
|
|
|
// Sets one value |
|
} else if ( value !== undefined ) { |
|
chainable = true; |
|
|
|
if ( !isFunction( value ) ) { |
|
raw = true; |
|
} |
|
|
|
if ( bulk ) { |
|
|
|
// Bulk operations run against the entire set |
|
if ( raw ) { |
|
fn.call( elems, value ); |
|
fn = null; |
|
|
|
// ...except when executing function values |
|
} else { |
|
bulk = fn; |
|
fn = function( elem, key, value ) { |
|
return bulk.call( jQuery( elem ), value ); |
|
}; |
|
} |
|
} |
|
|
|
if ( fn ) { |
|
for ( ; i < len; i++ ) { |
|
fn( |
|
elems[ i ], key, raw ? |
|
value : |
|
value.call( elems[ i ], i, fn( elems[ i ], key ) ) |
|
); |
|
} |
|
} |
|
} |
|
|
|
if ( chainable ) { |
|
return elems; |
|
} |
|
|
|
// Gets |
|
if ( bulk ) { |
|
return fn.call( elems ); |
|
} |
|
|
|
return len ? fn( elems[ 0 ], key ) : emptyGet; |
|
}; |
|
|
|
|
|
// Matches dashed string for camelizing |
|
var rmsPrefix = /^-ms-/, |
|
rdashAlpha = /-([a-z])/g; |
|
|
|
// Used by camelCase as callback to replace() |
|
function fcamelCase( all, letter ) { |
|
return letter.toUpperCase(); |
|
} |
|
|
|
// Convert dashed to camelCase; used by the css and data modules |
|
// Support: IE <=9 - 11, Edge 12 - 15 |
|
// Microsoft forgot to hump their vendor prefix (#9572) |
|
function camelCase( string ) { |
|
return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); |
|
} |
|
var acceptData = function( owner ) { |
|
|
|
// Accepts only: |
|
// - Node |
|
// - Node.ELEMENT_NODE |
|
// - Node.DOCUMENT_NODE |
|
// - Object |
|
// - Any |
|
return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); |
|
}; |
|
|
|
|
|
|
|
|
|
function Data() { |
|
this.expando = jQuery.expando + Data.uid++; |
|
} |
|
|
|
Data.uid = 1; |
|
|
|
Data.prototype = { |
|
|
|
cache: function( owner ) { |
|
|
|
// Check if the owner object already has a cache |
|
var value = owner[ this.expando ]; |
|
|
|
// If not, create one |
|
if ( !value ) { |
|
value = {}; |
|
|
|
// We can accept data for non-element nodes in modern browsers, |
|
// but we should not, see #8335. |
|
// Always return an empty object. |
|
if ( acceptData( owner ) ) { |
|
|
|
// If it is a node unlikely to be stringify-ed or looped over |
|
// use plain assignment |
|
if ( owner.nodeType ) { |
|
owner[ this.expando ] = value; |
|
|
|
// Otherwise secure it in a non-enumerable property |
|
// configurable must be true to allow the property to be |
|
// deleted when data is removed |
|
} else { |
|
Object.defineProperty( owner, this.expando, { |
|
value: value, |
|
configurable: true |
|
} ); |
|
} |
|
} |
|
} |
|
|
|
return value; |
|
}, |
|
set: function( owner, data, value ) { |
|
var prop, |
|
cache = this.cache( owner ); |
|
|
|
// Handle: [ owner, key, value ] args |
|
// Always use camelCase key (gh-2257) |
|
if ( typeof data === "string" ) { |
|
cache[ camelCase( data ) ] = value; |
|
|
|
// Handle: [ owner, { properties } ] args |
|
} else { |
|
|
|
// Copy the properties one-by-one to the cache object |
|
for ( prop in data ) { |
|
cache[ camelCase( prop ) ] = data[ prop ]; |
|
} |
|
} |
|
return cache; |
|
}, |
|
get: function( owner, key ) { |
|
return key === undefined ? |
|
this.cache( owner ) : |
|
|
|
// Always use camelCase key (gh-2257) |
|
owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; |
|
}, |
|
access: function( owner, key, value ) { |
|
|
|
// In cases where either: |
|
// |
|
// 1. No key was specified |
|
// 2. A string key was specified, but no value provided |
|
// |
|
// Take the "read" path and allow the get method to determine |
|
// which value to return, respectively either: |
|
// |
|
// 1. The entire cache object |
|
// 2. The data stored at the key |
|
// |
|
if ( key === undefined || |
|
( ( key && typeof key === "string" ) && value === undefined ) ) { |
|
|
|
return this.get( owner, key ); |
|
} |
|
|
|
// When the key is not a string, or both a key and value |
|
// are specified, set or extend (existing objects) with either: |
|
// |
|
// 1. An object of properties |
|
// 2. A key and value |
|
// |
|
this.set( owner, key, value ); |
|
|
|
// Since the "set" path can have two possible entry points |
|
// return the expected data based on which path was taken[*] |
|
return value !== undefined ? value : key; |
|
}, |
|
remove: function( owner, key ) { |
|
var i, |
|
cache = owner[ this.expando ]; |
|
|
|
if ( cache === undefined ) { |
|
return; |
|
} |
|
|
|
if ( key !== undefined ) { |
|
|
|
// Support array or space separated string of keys |
|
if ( Array.isArray( key ) ) { |
|
|
|
// If key is an array of keys... |
|
// We always set camelCase keys, so remove that. |
|
key = key.map( camelCase ); |
|
} else { |
|
key = camelCase( key ); |
|
|
|
// If a key with the spaces exists, use it. |
|
// Otherwise, create an array by matching non-whitespace |
|
key = key in cache ? |
|
[ key ] : |
|
( key.match( rnothtmlwhite ) || [] ); |
|
} |
|
|
|
i = key.length; |
|
|
|
while ( i-- ) { |
|
delete cache[ key[ i ] ]; |
|
} |
|
} |
|
|
|
// Remove the expando if there's no more data |
|
if ( key === undefined || jQuery.isEmptyObject( cache ) ) { |
|
|
|
// Support: Chrome <=35 - 45 |
|
// Webkit & Blink performance suffers when deleting properties |
|
// from DOM nodes, so set to undefined instead |
|
// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) |
|
if ( owner.nodeType ) { |
|
owner[ this.expando ] = undefined; |
|
} else { |
|
delete owner[ this.expando ]; |
|
} |
|
} |
|
}, |
|
hasData: function( owner ) { |
|
var cache = owner[ this.expando ]; |
|
return cache !== undefined && !jQuery.isEmptyObject( cache ); |
|
} |
|
}; |
|
var dataPriv = new Data(); |
|
|
|
var dataUser = new Data(); |
|
|
|
|
|
|
|
// Implementation Summary |
|
// |
|
// 1. Enforce API surface and semantic compatibility with 1.9.x branch |
|
// 2. Improve the module's maintainability by reducing the storage |
|
// paths to a single mechanism. |
|
// 3. Use the same single mechanism to support "private" and "user" data. |
|
// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) |
|
// 5. Avoid exposing implementation details on user objects (eg. expando properties) |
|
// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 |
|
|
|
var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, |
|
rmultiDash = /[A-Z]/g; |
|
|
|
function getData( data ) { |
|
if ( data === "true" ) { |
|
return true; |
|
} |
|
|
|
if ( data === "false" ) { |
|
return false; |
|
} |
|
|
|
if ( data === "null" ) { |
|
return null; |
|
} |
|
|
|
// Only convert to a number if it doesn't change the string |
|
if ( data === +data + "" ) { |
|
return +data; |
|
} |
|
|
|
if ( rbrace.test( data ) ) { |
|
return JSON.parse( data ); |
|
} |
|
|
|
return data; |
|
} |
|
|
|
function dataAttr( elem, key, data ) { |
|
var name; |
|
|
|
// If nothing was found internally, try to fetch any |
|
// data from the HTML5 data-* attribute |
|
if ( data === undefined && elem.nodeType === 1 ) { |
|
name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); |
|
data = elem.getAttribute( name ); |
|
|
|
if ( typeof data === "string" ) { |
|
try { |
|
data = getData( data ); |
|
} catch ( e ) {} |
|
|
|
// Make sure we set the data so it isn't changed later |
|
dataUser.set( elem, key, data ); |
|
} else { |
|
data = undefined; |
|
} |
|
} |
|
return data; |
|
} |
|
|
|
jQuery.extend( { |
|
hasData: function( elem ) { |
|
return dataUser.hasData( elem ) || dataPriv.hasData( elem ); |
|
}, |
|
|
|
data: function( elem, name, data ) { |
|
return dataUser.access( elem, name, data ); |
|
}, |
|
|
|
removeData: function( elem, name ) { |
|
dataUser.remove( elem, name ); |
|
}, |
|
|
|
// TODO: Now that all calls to _data and _removeData have been replaced |
|
// with direct calls to dataPriv methods, these can be deprecated. |
|
_data: function( elem, name, data ) { |
|
return dataPriv.access( elem, name, data ); |
|
}, |
|
|
|
_removeData: function( elem, name ) { |
|
dataPriv.remove( elem, name ); |
|
} |
|
} ); |
|
|
|
jQuery.fn.extend( { |
|
data: function( key, value ) { |
|
var i, name, data, |
|
elem = this[ 0 ], |
|
attrs = elem && elem.attributes; |
|
|
|
// Gets all values |
|
if ( key === undefined ) { |
|
if ( this.length ) { |
|
data = dataUser.get( elem ); |
|
|
|
if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { |
|
i = attrs.length; |
|
while ( i-- ) { |
|
|
|
// Support: IE 11 only |
|
// The attrs elements can be null (#14894) |
|
if ( attrs[ i ] ) { |
|
name = attrs[ i ].name; |
|
if ( name.indexOf( "data-" ) === 0 ) { |
|
name = camelCase( name.slice( 5 ) ); |
|
dataAttr( elem, name, data[ name ] ); |
|
} |
|
} |
|
} |
|
dataPriv.set( elem, "hasDataAttrs", true ); |
|
} |
|
} |
|
|
|
return data; |
|
} |
|
|
|
// Sets multiple values |
|
if ( typeof key === "object" ) { |
|
return this.each( function() { |
|
dataUser.set( this, key ); |
|
} ); |
|
} |
|
|
|
return access( this, function( value ) { |
|
var data; |
|
|
|
// The calling jQuery object (element matches) is not empty |
|
// (and therefore has an element appears at this[ 0 ]) and the |
|
// `value` parameter was not undefined. An empty jQuery object |
|
// will result in `undefined` for elem = this[ 0 ] which will |
|
// throw an exception if an attempt to read a data cache is made. |
|
if ( elem && value === undefined ) { |
|
|
|
// Attempt to get data from the cache |
|
// The key will always be camelCased in Data |
|
data = dataUser.get( elem, key ); |
|
if ( data !== undefined ) { |
|
return data; |
|
} |
|
|
|
// Attempt to "discover" the data in |
|
// HTML5 custom data-* attrs |
|
data = dataAttr( elem, key ); |
|
if ( data !== undefined ) { |
|
return data; |
|
} |
|
|
|
// We tried really hard, but the data doesn't exist. |
|
return; |
|
} |
|
|
|
// Set the data... |
|
this.each( function() { |
|
|
|
// We always store the camelCased key |
|
dataUser.set( this, key, value ); |
|
} ); |
|
}, null, value, arguments.length > 1, null, true ); |
|
}, |
|
|
|
removeData: function( key ) { |
|
return this.each( function() { |
|
dataUser.remove( this, key ); |
|
} ); |
|
} |
|
} ); |
|
|
|
|
|
jQuery.extend( { |
|
queue: function( elem, type, data ) { |
|
var queue; |
|
|
|
if ( elem ) { |
|
type = ( type || "fx" ) + "queue"; |
|
queue = dataPriv.get( elem, type ); |
|
|
|
// Speed up dequeue by getting out quickly if this is just a lookup |
|
if ( data ) { |
|
if ( !queue || Array.isArray( data ) ) { |
|
queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); |
|
} else { |
|
queue.push( data ); |
|
} |
|
} |
|
return queue || []; |
|
} |
|
}, |
|
|
|
dequeue: function( elem, type ) { |
|
type = type || "fx"; |
|
|
|
var queue = jQuery.queue( elem, type ), |
|
startLength = queue.length, |
|
fn = queue.shift(), |
|
hooks = jQuery._queueHooks( elem, type ), |
|
next = function() { |
|
jQuery.dequeue( elem, type ); |
|
}; |
|
|
|
// If the fx queue is dequeued, always remove the progress sentinel |
|
if ( fn === "inprogress" ) { |
|
fn = queue.shift(); |
|
startLength--; |
|
} |
|
|
|
if ( fn ) { |
|
|
|
// Add a progress sentinel to prevent the fx queue from being |
|
// automatically dequeued |
|
if ( type === "fx" ) { |
|
queue.unshift( "inprogress" ); |
|
} |
|
|
|
// Clear up the last queue stop function |
|
delete hooks.stop; |
|
fn.call( elem, next, hooks ); |
|
} |
|
|
|
if ( !startLength && hooks ) { |
|
hooks.empty.fire(); |
|
} |
|
}, |
|
|
|
// Not public - generate a queueHooks object, or return the current one |
|
_queueHooks: function( elem, type ) { |
|
var key = type + "queueHooks"; |
|
return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { |
|
empty: jQuery.Callbacks( "once memory" ).add( function() { |
|
dataPriv.remove( elem, [ type + "queue", key ] ); |
|
} ) |
|
} ); |
|
} |
|
} ); |
|
|
|
jQuery.fn.extend( { |
|
queue: function( type, data ) { |
|
var setter = 2; |
|
|
|
if ( typeof type !== "string" ) { |
|
data = type; |
|
type = "fx"; |
|
setter--; |
|
} |
|
|
|
if ( arguments.length < setter ) { |
|
return jQuery.queue( this[ 0 ], type ); |
|
} |
|
|
|
return data === undefined ? |
|
this : |
|
this.each( function() { |
|
var queue = jQuery.queue( this, type, data ); |
|
|
|
// Ensure a hooks for this queue |
|
jQuery._queueHooks( this, type ); |
|
|
|
if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { |
|
jQuery.dequeue( this, type ); |
|
} |
|
} ); |
|
}, |
|
dequeue: function( type ) { |
|
return this.each( function() { |
|
jQuery.dequeue( this, type ); |
|
} ); |
|
}, |
|
clearQueue: function( type ) { |
|
return this.queue( type || "fx", [] ); |
|
}, |
|
|
|
// Get a promise resolved when queues of a certain type |
|
// are emptied (fx is the type by default) |
|
promise: function( type, obj ) { |
|
var tmp, |
|
count = 1, |
|
defer = jQuery.Deferred(), |
|
elements = this, |
|
i = this.length, |
|
resolve = function() { |
|
if ( !( --count ) ) { |
|
defer.resolveWith( elements, [ elements ] ); |
|
} |
|
}; |
|
|
|
if ( typeof type !== "string" ) { |
|
obj = type; |
|
type = undefined; |
|
} |
|
type = type || "fx"; |
|
|
|
while ( i-- ) { |
|
tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); |
|
if ( tmp && tmp.empty ) { |
|
count++; |
|
tmp.empty.add( resolve ); |
|
} |
|
} |
|
resolve(); |
|
return defer.promise( obj ); |
|
} |
|
} ); |
|
var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; |
|
|
|
var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); |
|
|
|
|
|
var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; |
|
|
|
var isHiddenWithinTree = function( elem, el ) { |
|
|
|
// isHiddenWithinTree might be called from jQuery#filter function; |
|
// in that case, element will be second argument |
|
elem = el || elem; |
|
|
|
// Inline style trumps all |
|
return elem.style.display === "none" || |
|
elem.style.display === "" && |
|
|
|
// Otherwise, check computed style |
|
// Support: Firefox <=43 - 45 |
|
// Disconnected elements can have computed display: none, so first confirm that elem is |
|
// in the document. |
|
jQuery.contains( elem.ownerDocument, elem ) && |
|
|
|
jQuery.css( elem, "display" ) === "none"; |
|
}; |
|
|
|
var swap = function( elem, options, callback, args ) { |
|
var ret, name, |
|
old = {}; |
|
|
|
// Remember the old values, and insert the new ones |
|
for ( name in options ) { |
|
old[ name ] = elem.style[ name ]; |
|
elem.style[ name ] = options[ name ]; |
|
} |
|
|
|
ret = callback.apply( elem, args || [] ); |
|
|
|
// Revert the old values |
|
for ( name in options ) { |
|
elem.style[ name ] = old[ name ]; |
|
} |
|
|
|
return ret; |
|
}; |
|
|
|
|
|
|
|
|
|
function adjustCSS( elem, prop, valueParts, tween ) { |
|
var adjusted, scale, |
|
maxIterations = 20, |
|
currentValue = tween ? |
|
function() { |
|
return tween.cur(); |
|
} : |
|
function() { |
|
return jQuery.css( elem, prop, "" ); |
|
}, |
|
initial = currentValue(), |
|
unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), |
|
|
|
// Starting value computation is required for potential unit mismatches |
|
initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && |
|
rcssNum.exec( jQuery.css( elem, prop ) ); |
|
|
|
if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { |
|
|
|
// Support: Firefox <=54 |
|
// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) |
|
initial = initial / 2; |
|
|
|
// Trust units reported by jQuery.css |
|
unit = unit || initialInUnit[ 3 ]; |
|
|
|
// Iteratively approximate from a nonzero starting point |
|
initialInUnit = +initial || 1; |
|
|
|
while ( maxIterations-- ) { |
|
|
|
// Evaluate and update our best guess (doubling guesses that zero out). |
|
// Finish if the scale equals or crosses 1 (making the old*new product non-positive). |
|
jQuery.style( elem, prop, initialInUnit + unit ); |
|
if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { |
|
maxIterations = 0; |
|
} |
|
initialInUnit = initialInUnit / scale; |
|
|
|
} |
|
|
|
initialInUnit = initialInUnit * 2; |
|
jQuery.style( elem, prop, initialInUnit + unit ); |
|
|
|
// Make sure we update the tween properties later on |
|
valueParts = valueParts || []; |
|
} |
|
|
|
if ( valueParts ) { |
|
initialInUnit = +initialInUnit || +initial || 0; |
|
|
|
// Apply relative offset (+=/-=) if specified |
|
adjusted = valueParts[ 1 ] ? |
|
initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : |
|
+valueParts[ 2 ]; |
|
if ( tween ) { |
|
tween.unit = unit; |
|
tween.start = initialInUnit; |
|
tween.end = adjusted; |
|
} |
|
} |
|
return adjusted; |
|
} |
|
|
|
|
|
var defaultDisplayMap = {}; |
|
|
|
function getDefaultDisplay( elem ) { |
|
var temp, |
|
doc = elem.ownerDocument, |
|
nodeName = elem.nodeName, |
|
display = defaultDisplayMap[ nodeName ]; |
|
|
|
if ( display ) { |
|
return display; |
|
} |
|
|
|
temp = doc.body.appendChild( doc.createElement( nodeName ) ); |
|
display = jQuery.css( temp, "display" ); |
|
|
|
temp.parentNode.removeChild( temp ); |
|
|
|
if ( display === "none" ) { |
|
display = "block"; |
|
} |
|
defaultDisplayMap[ nodeName ] = display; |
|
|
|
return display; |
|
} |
|
|
|
function showHide( elements, show ) { |
|
var display, elem, |
|
values = [], |
|
index = 0, |
|
length = elements.length; |
|
|
|
// Determine new display value for elements that need to change |
|
for ( ; index < length; index++ ) { |
|
elem = elements[ index ]; |
|
if ( !elem.style ) { |
|
continue; |
|
} |
|
|
|
display = elem.style.display; |
|
if ( show ) { |
|
|
|
// Since we force visibility upon cascade-hidden elements, an immediate (and slow) |
|
// check is required in this first loop unless we have a nonempty display value (either |
|
// inline or about-to-be-restored) |
|
if ( display === "none" ) { |
|
values[ index ] = dataPriv.get( elem, "display" ) || null; |
|
if ( !values[ index ] ) { |
|
elem.style.display = ""; |
|
} |
|
} |
|
if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { |
|
values[ index ] = getDefaultDisplay( elem ); |
|
} |
|
} else { |
|
if ( display !== "none" ) { |
|
values[ index ] = "none"; |
|
|
|
// Remember what we're overwriting |
|
dataPriv.set( elem, "display", display ); |
|
} |
|
} |
|
} |
|
|
|
// Set the display of the elements in a second loop to avoid constant reflow |
|
for ( index = 0; index < length; index++ ) { |
|
if ( values[ index ] != null ) { |
|
elements[ index ].style.display = values[ index ]; |
|
} |
|
} |
|
|
|
return elements; |
|
} |
|
|
|
jQuery.fn.extend( { |
|
show: function() { |
|
return showHide( this, true ); |
|
}, |
|
hide: function() { |
|
return showHide( this ); |
|
}, |
|
toggle: function( state ) { |
|
if ( typeof state === "boolean" ) { |
|
return state ? this.show() : this.hide(); |
|
} |
|
|
|
return this.each( function() { |
|
if ( isHiddenWithinTree( this ) ) { |
|
jQuery( this ).show(); |
|
} else { |
|
jQuery( this ).hide(); |
|
} |
|
} ); |
|
} |
|
} ); |
|
var rcheckableType = ( /^(?:checkbox|radio)$/i ); |
|
|
|
var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i ); |
|
|
|
var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); |
|
|
|
|
|
|
|
// We have to close these tags to support XHTML (#13200) |
|
var wrapMap = { |
|
|
|
// Support: IE <=9 only |
|
option: [ 1, "<select multiple='multiple'>", "</select>" ], |
|
|
|
// XHTML parsers do not magically insert elements in the |
|
// same way that tag soup parsers do. So we cannot shorten |
|
// this by omitting <tbody> or other required elements. |
|
thead: [ 1, "<table>", "</table>" ], |
|
col: [ 2, "<table><colgroup>", "</colgroup></table>" ], |
|
tr: [ 2, "<table><tbody>", "</tbody></table>" ], |
|
td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], |
|
|
|
_default: [ 0, "", "" ] |
|
}; |
|
|
|
// Support: IE <=9 only |
|
wrapMap.optgroup = wrapMap.option; |
|
|
|
wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; |
|
wrapMap.th = wrapMap.td; |
|
|
|
|
|
function getAll( context, tag ) { |
|
|
|
// Support: IE <=9 - 11 only |
|
// Use typeof to avoid zero-argument method invocation on host objects (#15151) |
|
var ret; |
|
|
|
if ( typeof context.getElementsByTagName !== "undefined" ) { |
|
ret = context.getElementsByTagName( tag || "*" ); |
|
|
|
} else if ( typeof context.querySelectorAll !== "undefined" ) { |
|
ret = context.querySelectorAll( tag || "*" ); |
|
|
|
} else { |
|
ret = []; |
|
} |
|
|
|
if ( tag === undefined || tag && nodeName( context, tag ) ) { |
|
return jQuery.merge( [ context ], ret ); |
|
} |
|
|
|
return ret; |
|
} |
|
|
|
|
|
// Mark scripts as having already been evaluated |
|
function setGlobalEval( elems, refElements ) { |
|
var i = 0, |
|
l = elems.length; |
|
|
|
for ( ; i < l; i++ ) { |
|
dataPriv.set( |
|
elems[ i ], |
|
"globalEval", |
|
!refElements || dataPriv.get( refElements[ i ], "globalEval" ) |
|
); |
|
} |
|
} |
|
|
|
|
|
var rhtml = /<|&#?\w+;/; |
|
|
|
function buildFragment( elems, context, scripts, selection, ignored ) { |
|
var elem, tmp, tag, wrap, contains, j, |
|
fragment = context.createDocumentFragment(), |
|
nodes = [], |
|
i = 0, |
|
l = elems.length; |
|
|
|
for ( ; i < l; i++ ) { |
|
elem = elems[ i ]; |
|
|
|
if ( elem || elem === 0 ) { |
|
|
|
// Add nodes directly |
|
if ( toType( elem ) === "object" ) { |
|
|
|
// Support: Android <=4.0 only, PhantomJS 1 only |
|
// push.apply(_, arraylike) throws on ancient WebKit |
|
jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); |
|
|
|
// Convert non-html into a text node |
|
} else if ( !rhtml.test( elem ) ) { |
|
nodes.push( context.createTextNode( elem ) ); |
|
|
|
// Convert html into DOM nodes |
|
} else { |
|
tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); |
|
|
|
// Deserialize a standard representation |
|
tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); |
|
wrap = wrapMap[ tag ] || wrapMap._default; |
|
tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; |
|
|
|
// Descend through wrappers to the right content |
|
j = wrap[ 0 ]; |
|
while ( j-- ) { |
|
tmp = tmp.lastChild; |
|
} |
|
|
|
// Support: Android <=4.0 only, PhantomJS 1 only |
|
// push.apply(_, arraylike) throws on ancient WebKit |
|
jQuery.merge( nodes, tmp.childNodes ); |
|
|
|
// Remember the top-level container |
|
tmp = fragment.firstChild; |
|
|
|
// Ensure the created nodes are orphaned (#12392) |
|
tmp.textContent = ""; |
|
} |
|
} |
|
} |
|
|
|
// Remove wrapper from fragment |
|
fragment.textContent = ""; |
|
|
|
i = 0; |
|
while ( ( elem = nodes[ i++ ] ) ) { |
|
|
|
// Skip elements already in the context collection (trac-4087) |
|
if ( selection && jQuery.inArray( elem, selection ) > -1 ) { |
|
if ( ignored ) { |
|
ignored.push( elem ); |
|
} |
|
continue; |
|
} |
|
|
|
contains = jQuery.contains( elem.ownerDocument, elem ); |
|
|
|
// Append to fragment |
|
tmp = getAll( fragment.appendChild( elem ), "script" ); |
|
|
|
// Preserve script evaluation history |
|
if ( contains ) { |
|
setGlobalEval( tmp ); |
|
} |
|
|
|
// Capture executables |
|
if ( scripts ) { |
|
j = 0; |
|
while ( ( elem = tmp[ j++ ] ) ) { |
|
if ( rscriptType.test( elem.type || "" ) ) { |
|
scripts.push( elem ); |
|
} |
|
} |
|
} |
|
} |
|
|
|
return fragment; |
|
} |
|
|
|
|
|
( function() { |
|
var fragment = document.createDocumentFragment(), |
|
div = fragment.appendChild( document.createElement( "div" ) ), |
|
input = document.createElement( "input" ); |
|
|
|
// Support: Android 4.0 - 4.3 only |
|
// Check state lost if the name is set (#11217) |
|
// Support: Windows Web Apps (WWA) |
|
// `name` and `type` must use .setAttribute for WWA (#14901) |
|
input.setAttribute( "type", "radio" ); |
|
input.setAttribute( "checked", "checked" ); |
|
input.setAttribute( "name", "t" ); |
|
|
|
div.appendChild( input ); |
|
|
|
// Support: Android <=4.1 only |
|
// Older WebKit doesn't clone checked state correctly in fragments |
|
support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; |
|
|
|
// Support: IE <=11 only |
|
// Make sure textarea (and checkbox) defaultValue is properly cloned |
|
div.innerHTML = "<textarea>x</textarea>"; |
|
support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; |
|
} )(); |
|
var documentElement = document.documentElement; |
|
|
|
|
|
|
|
var |
|
rkeyEvent = /^key/, |
|
rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, |
|
rtypenamespace = /^([^.]*)(?:\.(.+)|)/; |
|
|
|
function returnTrue() { |
|
return true; |
|
} |
|
|
|
function returnFalse() { |
|
return false; |
|
} |
|
|
|
// Support: IE <=9 only |
|
// See #13393 for more info |
|
function safeActiveElement() { |
|
try { |
|
return document.activeElement; |
|
} catch ( err ) { } |
|
} |
|
|
|
function on( elem, types, selector, data, fn, one ) { |
|
var origFn, type; |
|
|
|
// Types can be a map of types/handlers |
|
if ( typeof types === "object" ) { |
|
|
|
// ( types-Object, selector, data ) |
|
if ( typeof selector !== "string" ) { |
|
|
|
// ( types-Object, data ) |
|
data = data || selector; |
|
selector = undefined; |
|
} |
|
for ( type in types ) { |
|
on( elem, type, selector, data, types[ type ], one ); |
|
} |
|
return elem; |
|
} |
|
|
|
if ( data == null && fn == null ) { |
|
|
|
// ( types, fn ) |
|
fn = selector; |
|
data = selector = undefined; |
|
} else if ( fn == null ) { |
|
if ( typeof selector === "string" ) { |
|
|
|
// ( types, selector, fn ) |
|
fn = data; |
|
data = undefined; |
|
} else { |
|
|
|
// ( types, data, fn ) |
|
fn = data; |
|
data = selector; |
|
selector = undefined; |
|
} |
|
} |
|
if ( fn === false ) { |
|
fn = returnFalse; |
|
} else if ( !fn ) { |
|
return elem; |
|
} |
|
|
|
if ( one === 1 ) { |
|
origFn = fn; |
|
fn = function( event ) { |
|
|
|
// Can use an empty set, since event contains the info |
|
jQuery().off( event ); |
|
return origFn.apply( this, arguments ); |
|
}; |
|
|
|
// Use same guid so caller can remove using origFn |
|
fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); |
|
} |
|
return elem.each( function() { |
|
jQuery.event.add( this, types, fn, data, selector ); |
|
} ); |
|
} |
|
|
|
/* |
|
* Helper functions for managing events -- not part of the public interface. |
|
* Props to Dean Edwards' addEvent library for many of the ideas. |
|
*/ |
|
jQuery.event = { |
|
|
|
global: {}, |
|
|
|
add: function( elem, types, handler, data, selector ) { |
|
|
|
var handleObjIn, eventHandle, tmp, |
|
events, t, handleObj, |
|
special, handlers, type, namespaces, origType, |
|
elemData = dataPriv.get( elem ); |
|
|
|
// Don't attach events to noData or text/comment nodes (but allow plain objects) |
|
if ( !elemData ) { |
|
return; |
|
} |
|
|
|
// Caller can pass in an object of custom data in lieu of the handler |
|
if ( handler.handler ) { |
|
handleObjIn = handler; |
|
handler = handleObjIn.handler; |
|
selector = handleObjIn.selector; |
|
} |
|
|
|
// Ensure that invalid selectors throw exceptions at attach time |
|
// Evaluate against documentElement in case elem is a non-element node (e.g., document) |
|
if ( selector ) { |
|
jQuery.find.matchesSelector( documentElement, selector ); |
|
} |
|
|
|
// Make sure that the handler has a unique ID, used to find/remove it later |
|
if ( !handler.guid ) { |
|
handler.guid = jQuery.guid++; |
|
} |
|
|
|
// Init the element's event structure and main handler, if this is the first |
|
if ( !( events = elemData.events ) ) { |
|
events = elemData.events = {}; |
|
} |
|
if ( !( eventHandle = elemData.handle ) ) { |
|
eventHandle = elemData.handle = function( e ) { |
|
|
|
// Discard the second event of a jQuery.event.trigger() and |
|
// when an event is called after a page has unloaded |
|
return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? |
|
jQuery.event.dispatch.apply( elem, arguments ) : undefined; |
|
}; |
|
} |
|
|
|
// Handle multiple events separated by a space |
|
types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; |
|
t = types.length; |
|
while ( t-- ) { |
|
tmp = rtypenamespace.exec( types[ t ] ) || []; |
|
type = origType = tmp[ 1 ]; |
|
namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); |
|
|
|
// There *must* be a type, no attaching namespace-only handlers |
|
if ( !type ) { |
|
continue; |
|
} |
|
|
|
// If event changes its type, use the special event handlers for the changed type |
|
special = jQuery.event.special[ type ] || {}; |
|
|
|
// If selector defined, determine special event api type, otherwise given type |
|
type = ( selector ? special.delegateType : special.bindType ) || type; |
|
|
|
// Update special based on newly reset type |
|
special = jQuery.event.special[ type ] || {}; |
|
|
|
// handleObj is passed to all event handlers |
|
handleObj = jQuery.extend( { |
|
type: type, |
|
origType: origType, |
|
data: data, |
|
handler: handler, |
|
guid: handler.guid, |
|
selector: selector, |
|
needsContext: selector && jQuery.expr.match.needsContext.test( selector ), |
|
namespace: namespaces.join( "." ) |
|
}, handleObjIn ); |
|
|
|
// Init the event handler queue if we're the first |
|
if ( !( handlers = events[ type ] ) ) { |
|
handlers = events[ type ] = []; |
|
handlers.delegateCount = 0; |
|
|
|
// Only use addEventListener if the special events handler returns false |
|
if ( !special.setup || |
|
special.setup.call( elem, data, namespaces, eventHandle ) === false ) { |
|
|
|
if ( elem.addEventListener ) { |
|
elem.addEventListener( type, eventHandle ); |
|
} |
|
} |
|
} |
|
|
|
if ( special.add ) { |
|
special.add.call( elem, handleObj ); |
|
|
|
if ( !handleObj.handler.guid ) { |
|
handleObj.handler.guid = handler.guid; |
|
} |
|
} |
|
|
|
// Add to the element's handler list, delegates in front |
|
if ( selector ) { |
|
handlers.splice( handlers.delegateCount++, 0, handleObj ); |
|
} else { |
|
handlers.push( handleObj ); |
|
} |
|
|
|
// Keep track of which events have ever been used, for event optimization |
|
jQuery.event.global[ type ] = true; |
|
} |
|
|
|
}, |
|
|
|
// Detach an event or set of events from an element |
|
remove: function( elem, types, handler, selector, mappedTypes ) { |
|
|
|
var j, origCount, tmp, |
|
events, t, handleObj, |
|
special, handlers, type, namespaces, origType, |
|
elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); |
|
|
|
if ( !elemData || !( events = elemData.events ) ) { |
|
return; |
|
} |
|
|
|
// Once for each type.namespace in types; type may be omitted |
|
types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; |
|
t = types.length; |
|
while ( t-- ) { |
|
tmp = rtypenamespace.exec( types[ t ] ) || []; |
|
type = origType = tmp[ 1 ]; |
|
namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); |
|
|
|
// Unbind all events (on this namespace, if provided) for the element |
|
if ( !type ) { |
|
for ( type in events ) { |
|
jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); |
|
} |
|
continue; |
|
} |
|
|
|
special = jQuery.event.special[ type ] || {}; |
|
type = ( selector ? special.delegateType : special.bindType ) || type; |
|
handlers = events[ type ] || []; |
|
tmp = tmp[ 2 ] && |
|
new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); |
|
|
|
// Remove matching events |
|
origCount = j = handlers.length; |
|
while ( j-- ) { |
|
handleObj = handlers[ j ]; |
|
|
|
if ( ( mappedTypes || origType === handleObj.origType ) && |
|
( !handler || handler.guid === handleObj.guid ) && |
|
( !tmp || tmp.test( handleObj.namespace ) ) && |
|
( !selector || selector === handleObj.selector || |
|
selector === "**" && handleObj.selector ) ) { |
|
handlers.splice( j, 1 ); |
|
|
|
if ( handleObj.selector ) { |
|
handlers.delegateCount--; |
|
} |
|
if ( special.remove ) { |
|
special.remove.call( elem, handleObj ); |
|
} |
|
} |
|
} |
|
|
|
// Remove generic event handler if we removed something and no more handlers exist |
|
// (avoids potential for endless recursion during removal of special event handlers) |
|
if ( origCount && !handlers.length ) { |
|
if ( !special.teardown || |
|
special.teardown.call( elem, namespaces, elemData.handle ) === false ) { |
|
|
|
jQuery.removeEvent( elem, type, elemData.handle ); |
|
} |
|
|
|
delete events[ type ]; |
|
} |
|
} |
|
|
|
// Remove data and the expando if it's no longer used |
|
if ( jQuery.isEmptyObject( events ) ) { |
|
dataPriv.remove( elem, "handle events" ); |
|
} |
|
}, |
|
|
|
dispatch: function( nativeEvent ) { |
|
|
|
// Make a writable jQuery.Event from the native event object |
|
var event = jQuery.event.fix( nativeEvent ); |
|
|
|
var i, j, ret, matched, handleObj, handlerQueue, |
|
args = new Array( arguments.length ), |
|
handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], |
|
special = jQuery.event.special[ event.type ] || {}; |
|
|
|
// Use the fix-ed jQuery.Event rather than the (read-only) native event |
|
args[ 0 ] = event; |
|
|
|
for ( i = 1; i < arguments.length; i++ ) { |
|
args[ i ] = arguments[ i ]; |
|
} |
|
|
|
event.delegateTarget = this; |
|
|
|
// Call the preDispatch hook for the mapped type, and let it bail if desired |
|
if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { |
|
return; |
|
} |
|
|
|
// Determine handlers |
|
handlerQueue = jQuery.event.handlers.call( this, event, handlers ); |
|
|
|
// Run delegates first; they may want to stop propagation beneath us |
|
i = 0; |
|
while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { |
|
event.currentTarget = matched.elem; |
|
|
|
j = 0; |
|
while ( ( handleObj = matched.handlers[ j++ ] ) && |
|
!event.isImmediatePropagationStopped() ) { |
|
|
|
// Triggered event must either 1) have no namespace, or 2) have namespace(s) |
|
// a subset or equal to those in the bound event (both can have no namespace). |
|
if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) { |
|
|
|
event.handleObj = handleObj; |
|
event.data = handleObj.data; |
|
|
|
ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || |
|
handleObj.handler ).apply( matched.elem, args ); |
|
|
|
if ( ret !== undefined ) { |
|
if ( ( event.result = ret ) === false ) { |
|
event.preventDefault(); |
|
event.stopPropagation(); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
// Call the postDispatch hook for the mapped type |
|
if ( special.postDispatch ) { |
|
special.postDispatch.call( this, event ); |
|
} |
|
|
|
return event.result; |
|
}, |
|
|
|
handlers: function( event, handlers ) { |
|
var i, handleObj, sel, matchedHandlers, matchedSelectors, |
|
handlerQueue = [], |
|
delegateCount = handlers.delegateCount, |
|
cur = event.target; |
|
|
|
// Find delegate handlers |
|
if ( delegateCount && |
|
|
|
// Support: IE <=9 |
|
// Black-hole SVG <use> instance trees (trac-13180) |
|
cur.nodeType && |
|
|
|
// Support: Firefox <=42 |
|
// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) |
|
// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click |
|
// Support: IE 11 only |
|
// ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) |
|
!( event.type === "click" && event.button >= 1 ) ) { |
|
|
|
for ( ; cur !== this; cur = cur.parentNode || this ) { |
|
|
|
// Don't check non-elements (#13208) |
|
// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) |
|
if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { |
|
matchedHandlers = []; |
|
matchedSelectors = {}; |
|
for ( i = 0; i < delegateCount; i++ ) { |
|
handleObj = handlers[ i ]; |
|
|
|
// Don't conflict with Object.prototype properties (#13203) |
|
sel = handleObj.selector + " "; |
|
|
|
if ( matchedSelectors[ sel ] === undefined ) { |
|
matchedSelectors[ sel ] = handleObj.needsContext ? |
|
jQuery( sel, this ).index( cur ) > -1 : |
|
jQuery.find( sel, this, null, [ cur ] ).length; |
|
} |
|
if ( matchedSelectors[ sel ] ) { |
|
matchedHandlers.push( handleObj ); |
|
} |
|
} |
|
if ( matchedHandlers.length ) { |
|
handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); |
|
} |
|
} |
|
} |
|
} |
|
|
|
// Add the remaining (directly-bound) handlers |
|
cur = this; |
|
if ( delegateCount < handlers.length ) { |
|
handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); |
|
} |
|
|
|
return handlerQueue; |
|
}, |
|
|
|
addProp: function( name, hook ) { |
|
Object.defineProperty( jQuery.Event.prototype, name, { |
|
enumerable: true, |
|
configurable: true, |
|
|
|
get: isFunction( hook ) ? |
|
function() { |
|
if ( this.originalEvent ) { |
|
return hook( this.originalEvent ); |
|
} |
|
} : |
|
function() { |
|
if ( this.originalEvent ) { |
|
return this.originalEvent[ name ]; |
|
} |
|
}, |
|
|
|
set: function( value ) { |
|
Object.defineProperty( this, name, { |
|
enumerable: true, |
|
configurable: true, |
|
writable: true, |
|
value: value |
|
} ); |
|
} |
|
} ); |
|
}, |
|
|
|
fix: function( originalEvent ) { |
|
return originalEvent[ jQuery.expando ] ? |
|
originalEvent : |
|
new jQuery.Event( originalEvent ); |
|
}, |
|
|
|
special: { |
|
load: { |
|
|
|
// Prevent triggered image.load events from bubbling to window.load |
|
noBubble: true |
|
}, |
|
focus: { |
|
|
|
// Fire native event if possible so blur/focus sequence is correct |
|
trigger: function() { |
|
if ( this !== safeActiveElement() && this.focus ) { |
|
this.focus(); |
|
return false; |
|
} |
|
}, |
|
delegateType: "focusin" |
|
}, |
|
blur: { |
|
trigger: function() { |
|
if ( this === safeActiveElement() && this.blur ) { |
|
this.blur(); |
|
return false; |
|
} |
|
}, |
|
delegateType: "focusout" |
|
}, |
|
click: { |
|
|
|
// For checkbox, fire native event so checked state will be right |
|
trigger: function() { |
|
if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) { |
|
this.click(); |
|
return false; |
|
} |
|
}, |
|
|
|
// For cross-browser consistency, don't fire native .click() on links |
|
_default: function( event ) { |
|
return nodeName( event.target, "a" ); |
|
} |
|
}, |
|
|
|
beforeunload: { |
|
postDispatch: function( event ) { |
|
|
|
// Support: Firefox 20+ |
|
// Firefox doesn't alert if the returnValue field is not set. |
|
if ( event.result !== undefined && event.originalEvent ) { |
|
event.originalEvent.returnValue = event.result; |
|
} |
|
} |
|
} |
|
} |
|
}; |
|
|
|
jQuery.removeEvent = function( elem, type, handle ) { |
|
|
|
// This "if" is needed for plain objects |
|
if ( elem.removeEventListener ) { |
|
elem.removeEventListener( type, handle ); |
|
} |
|
}; |
|
|
|
jQuery.Event = function( src, props ) { |
|
|
|
// Allow instantiation without the 'new' keyword |
|
if ( !( this instanceof jQuery.Event ) ) { |
|
return new jQuery.Event( src, props ); |
|
} |
|
|
|
// Event object |
|
if ( src && src.type ) { |
|
this.originalEvent = src; |
|
this.type = src.type; |
|
|
|
// Events bubbling up the document may have been marked as prevented |
|
// by a handler lower down the tree; reflect the correct value. |
|
this.isDefaultPrevented = src.defaultPrevented || |
|
src.defaultPrevented === undefined && |
|
|
|
// Support: Android <=2.3 only |
|
src.returnValue === false ? |
|
returnTrue : |
|
returnFalse; |
|
|
|
// Create target properties |
|
// Support: Safari <=6 - 7 only |
|
// Target should not be a text node (#504, #13143) |
|
this.target = ( src.target && src.target.nodeType === 3 ) ? |
|
src.target.parentNode : |
|
src.target; |
|
|
|
this.currentTarget = src.currentTarget; |
|
this.relatedTarget = src.relatedTarget; |
|
|
|
// Event type |
|
} else { |
|
this.type = src; |
|
} |
|
|
|
// Put explicitly provided properties onto the event object |
|
if ( props ) { |
|
jQuery.extend( this, props ); |
|
} |
|
|
|
// Create a timestamp if incoming event doesn't have one |
|
this.timeStamp = src && src.timeStamp || Date.now(); |
|
|
|
// Mark it as fixed |
|
this[ jQuery.expando ] = true; |
|
}; |
|
|
|
// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding |
|
// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html |
|
jQuery.Event.prototype = { |
|
constructor: jQuery.Event, |
|
isDefaultPrevented: returnFalse, |
|
isPropagationStopped: returnFalse, |
|
isImmediatePropagationStopped: returnFalse, |
|
isSimulated: false, |
|
|
|
preventDefault: function() { |
|
var e = this.originalEvent; |
|
|
|
this.isDefaultPrevented = returnTrue; |
|
|
|
if ( e && !this.isSimulated ) { |
|
e.preventDefault(); |
|
} |
|
}, |
|
stopPropagation: function() { |
|
var e = this.originalEvent; |
|
|
|
this.isPropagationStopped = returnTrue; |
|
|
|
if ( e && !this.isSimulated ) { |
|
e.stopPropagation(); |
|
} |
|
}, |
|
stopImmediatePropagation: function() { |
|
var e = this.originalEvent; |
|
|
|
this.isImmediatePropagationStopped = returnTrue; |
|
|
|
if ( e && !this.isSimulated ) { |
|
e.stopImmediatePropagation(); |
|
} |
|
|
|
this.stopPropagation(); |
|
} |
|
}; |
|
|
|
// Includes all common event props including KeyEvent and MouseEvent specific props |
|
jQuery.each( { |
|
altKey: true, |
|
bubbles: true, |
|
cancelable: true, |
|
changedTouches: true, |
|
ctrlKey: true, |
|
detail: true, |
|
eventPhase: true, |
|
metaKey: true, |
|
pageX: true, |
|
pageY: true, |
|
shiftKey: true, |
|
view: true, |
|
"char": true, |
|
charCode: true, |
|
key: true, |
|
keyCode: true, |
|
button: true, |
|
buttons: true, |
|
clientX: true, |
|
clientY: true, |
|
offsetX: true, |
|
offsetY: true, |
|
pointerId: true, |
|
pointerType: true, |
|
screenX: true, |
|
screenY: true, |
|
targetTouches: true, |
|
toElement: true, |
|
touches: true, |
|
|
|
which: function( event ) { |
|
var button = event.button; |
|
|
|
// Add which for key events |
|
if ( event.which == null && rkeyEvent.test( event.type ) ) { |
|
return event.charCode != null ? event.charCode : event.keyCode; |
|
} |
|
|
|
// Add which for click: 1 === left; 2 === middle; 3 === right |
|
if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { |
|
if ( button & 1 ) { |
|
return 1; |
|
} |
|
|
|
if ( button & 2 ) { |
|
return 3; |
|
} |
|
|
|
if ( button & 4 ) { |
|
return 2; |
|
} |
|
|
|
return 0; |
|
} |
|
|
|
return event.which; |
|
} |
|
}, jQuery.event.addProp ); |
|
|
|
// Create mouseenter/leave events using mouseover/out and event-time checks |
|
// so that event delegation works in jQuery. |
|
// Do the same for pointerenter/pointerleave and pointerover/pointerout |
|
// |
|
// Support: Safari 7 only |
|
// Safari sends mouseenter too often; see: |
|
// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 |
|
// for the description of the bug (it existed in older Chrome versions as well). |
|
jQuery.each( { |
|
mouseenter: "mouseover", |
|
mouseleave: "mouseout", |
|
pointerenter: "pointerover", |
|
pointerleave: "pointerout" |
|
}, function( orig, fix ) { |
|
jQuery.event.special[ orig ] = { |
|
delegateType: fix, |
|
bindType: fix, |
|
|
|
handle: function( event ) { |
|
var ret, |
|
target = this, |
|
related = event.relatedTarget, |
|
handleObj = event.handleObj; |
|
|
|
// For mouseenter/leave call the handler if related is outside the target. |
|
// NB: No relatedTarget if the mouse left/entered the browser window |
|
if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { |
|
event.type = handleObj.origType; |
|
ret = handleObj.handler.apply( this, arguments ); |
|
event.type = fix; |
|
} |
|
return ret; |
|
} |
|
}; |
|
} ); |
|
|
|
jQuery.fn.extend( { |
|
|
|
on: function( types, selector, data, fn ) { |
|
return on( this, types, selector, data, fn ); |
|
}, |
|
one: function( types, selector, data, fn ) { |
|
return on( this, types, selector, data, fn, 1 ); |
|
}, |
|
off: function( types, selector, fn ) { |
|
var handleObj, type; |
|
if ( types && types.preventDefault && types.handleObj ) { |
|
|
|
// ( event ) dispatched jQuery.Event |
|
handleObj = types.handleObj; |
|
jQuery( types.delegateTarget ).off( |
|
handleObj.namespace ? |
|
handleObj.origType + "." + handleObj.namespace : |
|
handleObj.origType, |
|
handleObj.selector, |
|
handleObj.handler |
|
); |
|
return this; |
|
} |
|
if ( typeof types === "object" ) { |
|
|
|
// ( types-object [, selector] ) |
|
for ( type in types ) { |
|
this.off( type, selector, types[ type ] ); |
|
} |
|
return this; |
|
} |
|
if ( selector === false || typeof selector === "function" ) { |
|
|
|
// ( types [, fn] ) |
|
fn = selector; |
|
selector = undefined; |
|
} |
|
if ( fn === false ) { |
|
fn = returnFalse; |
|
} |
|
return this.each( function() { |
|
jQuery.event.remove( this, types, fn, selector ); |
|
} ); |
|
} |
|
} ); |
|
|
|
|
|
var |
|
|
|
/* eslint-disable max-len */ |
|
|
|
// See https://github.com/eslint/eslint/issues/3229 |
|
rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, |
|
|
|
/* eslint-enable */ |
|
|
|
// Support: IE <=10 - 11, Edge 12 - 13 only |
|
// In IE/Edge using regex groups here causes severe slowdowns. |
|
// See https://connect.microsoft.com/IE/feedback/details/1736512/ |
|
rnoInnerhtml = /<script|<style|<link/i, |
|
|
|
// checked="checked" or checked |
|
rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, |
|
rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g; |
|
|
|
// Prefer a tbody over its parent table for containing new rows |
|
function manipulationTarget( elem, content ) { |
|
if ( nodeName( elem, "table" ) && |
|
nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { |
|
|
|
return jQuery( elem ).children( "tbody" )[ 0 ] || elem; |
|
} |
|
|
|
return elem; |
|
} |
|
|
|
// Replace/restore the type attribute of script elements for safe DOM manipulation |
|
function disableScript( elem ) { |
|
elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; |
|
return elem; |
|
} |
|
function restoreScript( elem ) { |
|
if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { |
|
elem.type = elem.type.slice( 5 ); |
|
} else { |
|
elem.removeAttribute( "type" ); |
|
} |
|
|
|
return elem; |
|
} |
|
|
|
function cloneCopyEvent( src, dest ) { |
|
var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; |
|
|
|
if ( dest.nodeType !== 1 ) { |
|
return; |
|
} |
|
|
|
// 1. Copy private data: events, handlers, etc. |
|
if ( dataPriv.hasData( src ) ) { |
|
pdataOld = dataPriv.access( src ); |
|
pdataCur = dataPriv.set( dest, pdataOld ); |
|
events = pdataOld.events; |
|
|
|
if ( events ) { |
|
delete pdataCur.handle; |
|
pdataCur.events = {}; |
|
|
|
for ( type in events ) { |
|
for ( i = 0, l = events[ type ].length; i < l; i++ ) { |
|
jQuery.event.add( dest, type, events[ type ][ i ] ); |
|
} |
|
} |
|
} |
|
} |
|
|
|
// 2. Copy user data |
|
if ( dataUser.hasData( src ) ) { |
|
udataOld = dataUser.access( src ); |
|
udataCur = jQuery.extend( {}, udataOld ); |
|
|
|
dataUser.set( dest, udataCur ); |
|
} |
|
} |
|
|
|
// Fix IE bugs, see support tests |
|
function fixInput( src, dest ) { |
|
var nodeName = dest.nodeName.toLowerCase(); |
|
|
|
// Fails to persist the checked state of a cloned checkbox or radio button. |
|
if ( nodeName === "input" && rcheckableType.test( src.type ) ) { |
|
dest.checked = src.checked; |
|
|
|
// Fails to return the selected option to the default selected state when cloning options |
|
} else if ( nodeName === "input" || nodeName === "textarea" ) { |
|
dest.defaultValue = src.defaultValue; |
|
} |
|
} |
|
|
|
function domManip( collection, args, callback, ignored ) { |
|
|
|
// Flatten any nested arrays |
|
args = concat.apply( [], args ); |
|
|
|
var fragment, first, scripts, hasScripts, node, doc, |
|
i = 0, |
|
l = collection.length, |
|
iNoClone = l - 1, |
|
value = args[ 0 ], |
|
valueIsFunction = isFunction( value ); |
|
|
|
// We can't cloneNode fragments that contain checked, in WebKit |
|
if ( valueIsFunction || |
|
( l > 1 && typeof value === "string" && |
|
!support.checkClone && rchecked.test( value ) ) ) { |
|
return collection.each( function( index ) { |
|
var self = collection.eq( index ); |
|
if ( valueIsFunction ) { |
|
args[ 0 ] = value.call( this, index, self.html() ); |
|
} |
|
domManip( self, args, callback, ignored ); |
|
} ); |
|
} |
|
|
|
if ( l ) { |
|
fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); |
|
first = fragment.firstChild; |
|
|
|
if ( fragment.childNodes.length === 1 ) { |
|
fragment = first; |
|
} |
|
|
|
// Require either new content or an interest in ignored elements to invoke the callback |
|
if ( first || ignored ) { |
|
scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); |
|
hasScripts = scripts.length; |
|
|
|
// Use the original fragment for the last item |
|
// instead of the first because it can end up |
|
// being emptied incorrectly in certain situations (#8070). |
|
for ( ; i < l; i++ ) { |
|
node = fragment; |
|
|
|
if ( i !== iNoClone ) { |
|
node = jQuery.clone( node, true, true ); |
|
|
|
// Keep references to cloned scripts for later restoration |
|
if ( hasScripts ) { |
|
|
|
// Support: Android <=4.0 only, PhantomJS 1 only |
|
// push.apply(_, arraylike) throws on ancient WebKit |
|
jQuery.merge( scripts, getAll( node, "script" ) ); |
|
} |
|
} |
|
|
|
callback.call( collection[ i ], node, i ); |
|
} |
|
|
|
if ( hasScripts ) { |
|
doc = scripts[ scripts.length - 1 ].ownerDocument; |
|
|
|
// Reenable scripts |
|
jQuery.map( scripts, restoreScript ); |
|
|
|
// Evaluate executable scripts on first document insertion |
|
for ( i = 0; i < hasScripts; i++ ) { |
|
node = scripts[ i ]; |
|
if ( rscriptType.test( node.type || "" ) && |
|
!dataPriv.access( node, "globalEval" ) && |
|
jQuery.contains( doc, node ) ) { |
|
|
|
if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { |
|
|
|
// Optional AJAX dependency, but won't run scripts if not present |
|
if ( jQuery._evalUrl ) { |
|
jQuery._evalUrl( node.src ); |
|
} |
|
} else { |
|
DOMEval( node.textContent.replace( rcleanScript, "" ), doc, node ); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
return collection; |
|
} |
|
|
|
function remove( elem, selector, keepData ) { |
|
var node, |
|
nodes = selector ? jQuery.filter( selector, elem ) : elem, |
|
i = 0; |
|
|
|
for ( ; ( node = nodes[ i ] ) != null; i++ ) { |
|
if ( !keepData && node.nodeType === 1 ) { |
|
jQuery.cleanData( getAll( node ) ); |
|
} |
|
|
|
if ( node.parentNode ) { |
|
if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { |
|
setGlobalEval( getAll( node, "script" ) ); |
|
} |
|
node.parentNode.removeChild( node ); |
|
} |
|
} |
|
|
|
return elem; |
|
} |
|
|
|
jQuery.extend( { |
|
htmlPrefilter: function( html ) { |
|
return html.replace( rxhtmlTag, "<$1></$2>" ); |
|
}, |
|
|
|
clone: function( elem, dataAndEvents, deepDataAndEvents ) { |
|
var i, l, srcElements, destElements, |
|
clone = elem.cloneNode( true ), |
|
inPage = jQuery.contains( elem.ownerDocument, elem ); |
|
|
|
// Fix IE cloning issues |
|
if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && |
|
!jQuery.isXMLDoc( elem ) ) { |
|
|
|
// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 |
|
destElements = getAll( clone ); |
|
srcElements = getAll( elem ); |
|
|
|
for ( i = 0, l = srcElements.length; i < l; i++ ) { |
|
fixInput( srcElements[ i ], destElements[ i ] ); |
|
} |
|
} |
|
|
|
// Copy the events from the original to the clone |
|
if ( dataAndEvents ) { |
|
if ( deepDataAndEvents ) { |
|
srcElements = srcElements || getAll( elem ); |
|
destElements = destElements || getAll( clone ); |
|
|
|
for ( i = 0, l = srcElements.length; i < l; i++ ) { |
|
cloneCopyEvent( srcElements[ i ], destElements[ i ] ); |
|
} |
|
} else { |
|
cloneCopyEvent( elem, clone ); |
|
} |
|
} |
|
|
|
// Preserve script evaluation history |
|
destElements = getAll( clone, "script" ); |
|
if ( destElements.length > 0 ) { |
|
setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); |
|
} |
|
|
|
// Return the cloned set |
|
return clone; |
|
}, |
|
|
|
cleanData: function( elems ) { |
|
var data, elem, type, |
|
special = jQuery.event.special, |
|
i = 0; |
|
|
|
for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { |
|
if ( acceptData( elem ) ) { |
|
if ( ( data = elem[ dataPriv.expando ] ) ) { |
|
if ( data.events ) { |
|
for ( type in data.events ) { |
|
if ( special[ type ] ) { |
|
jQuery.event.remove( elem, type ); |
|
|
|
// This is a shortcut to avoid jQuery.event.remove's overhead |
|
} else { |
|
jQuery.removeEvent( elem, type, data.handle ); |
|
} |
|
} |
|
} |
|
|
|
// Support: Chrome <=35 - 45+ |
|
// Assign undefined instead of using delete, see Data#remove |
|
elem[ dataPriv.expando ] = undefined; |
|
} |
|
if ( elem[ dataUser.expando ] ) { |
|
|
|
// Support: Chrome <=35 - 45+ |
|
// Assign undefined instead of using delete, see Data#remove |
|
elem[ dataUser.expando ] = undefined; |
|
} |
|
} |
|
} |
|
} |
|
} ); |
|
|
|
jQuery.fn.extend( { |
|
detach: function( selector ) { |
|
return remove( this, selector, true ); |
|
}, |
|
|
|
remove: function( selector ) { |
|
return remove( this, selector ); |
|
}, |
|
|
|
text: function( value ) { |
|
return access( this, function( value ) { |
|
return value === undefined ? |
|
jQuery.text( this ) : |
|
this.empty().each( function() { |
|
if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { |
|
this.textContent = value; |
|
} |
|
} ); |
|
}, null, value, arguments.length ); |
|
}, |
|
|
|
append: function() { |
|
return domManip( this, arguments, function( elem ) { |
|
if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { |
|
var target = manipulationTarget( this, elem ); |
|
target.appendChild( elem ); |
|
} |
|
} ); |
|
}, |
|
|
|
prepend: function() { |
|
return domManip( this, arguments, function( elem ) { |
|
if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { |
|
var target = manipulationTarget( this, elem ); |
|
target.insertBefore( elem, target.firstChild ); |
|
} |
|
} ); |
|
}, |
|
|
|
before: function() { |
|
return domManip( this, arguments, function( elem ) { |
|
if ( this.parentNode ) { |
|
this.parentNode.insertBefore( elem, this ); |
|
} |
|
} ); |
|
}, |
|
|
|
after: function() { |
|
return domManip( this, arguments, function( elem ) { |
|
if ( this.parentNode ) { |
|
this.parentNode.insertBefore( elem, this.nextSibling ); |
|
} |
|
} ); |
|
}, |
|
|
|
empty: function() { |
|
var elem, |
|
i = 0; |
|
|
|
for ( ; ( elem = this[ i ] ) != null; i++ ) { |
|
if ( elem.nodeType === 1 ) { |
|
|
|
// Prevent memory leaks |
|
jQuery.cleanData( getAll( elem, false ) ); |
|
|
|
// Remove any remaining nodes |
|
elem.textContent = ""; |
|
} |
|
} |
|
|
|
return this; |
|
}, |
|
|
|
clone: function( dataAndEvents, deepDataAndEvents ) { |
|
dataAndEvents = dataAndEvents == null ? false : dataAndEvents; |
|
deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; |
|
|
|
return this.map( function() { |
|
return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); |
|
} ); |
|
}, |
|
|
|
html: function( value ) { |
|
return access( this, function( value ) { |
|
var elem = this[ 0 ] || {}, |
|
i = 0, |
|
l = this.length; |
|
|
|
if ( value === undefined && elem.nodeType === 1 ) { |
|
return elem.innerHTML; |
|
} |
|
|
|
// See if we can take a shortcut and just use innerHTML |
|
if ( typeof value === "string" && !rnoInnerhtml.test( value ) && |
|
!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { |
|
|
|
value = jQuery.htmlPrefilter( value ); |
|
|
|
try { |
|
for ( ; i < l; i++ ) { |
|
elem = this[ i ] || {}; |
|
|
|
// Remove element nodes and prevent memory leaks |
|
if ( elem.nodeType === 1 ) { |
|
jQuery.cleanData( getAll( elem, false ) ); |
|
elem.innerHTML = value; |
|
} |
|
} |
|
|
|
elem = 0; |
|
|
|
// If using innerHTML throws an exception, use the fallback method |
|
} catch ( e ) {} |
|
} |
|
|
|
if ( elem ) { |
|
this.empty().append( value ); |
|
} |
|
}, null, value, arguments.length ); |
|
}, |
|
|
|
replaceWith: function() { |
|
var ignored = []; |
|
|
|
// Make the changes, replacing each non-ignored context element with the new content |
|
return domManip( this, arguments, function( elem ) { |
|
var parent = this.parentNode; |
|
|
|
if ( jQuery.inArray( this, ignored ) < 0 ) { |
|
jQuery.cleanData( getAll( this ) ); |
|
if ( parent ) { |
|
parent.replaceChild( elem, this ); |
|
} |
|
} |
|
|
|
// Force callback invocation |
|
}, ignored ); |
|
} |
|
} ); |
|
|
|
jQuery.each( { |
|
appendTo: "append", |
|
prependTo: "prepend", |
|
insertBefore: "before", |
|
insertAfter: "after", |
|
replaceAll: "replaceWith" |
|
}, function( name, original ) { |
|
jQuery.fn[ name ] = function( selector ) { |
|
var elems, |
|
ret = [], |
|
insert = jQuery( selector ), |
|
last = insert.length - 1, |
|
i = 0; |
|
|
|
for ( ; i <= last; i++ ) { |
|
elems = i === last ? this : this.clone( true ); |
|
jQuery( insert[ i ] )[ original ]( elems ); |
|
|
|
// Support: Android <=4.0 only, PhantomJS 1 only |
|
// .get() because push.apply(_, arraylike) throws on ancient WebKit |
|
push.apply( ret, elems.get() ); |
|
} |
|
|
|
return this.pushStack( ret ); |
|
}; |
|
} ); |
|
var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); |
|
|
|
var getStyles = function( elem ) { |
|
|
|
// Support: IE <=11 only, Firefox <=30 (#15098, #14150) |
|
// IE throws on elements created in popups |
|
// FF meanwhile throws on frame elements through "defaultView.getComputedStyle" |
|
var view = elem.ownerDocument.defaultView; |
|
|
|
if ( !view || !view.opener ) { |
|
view = window; |
|
} |
|
|
|
return view.getComputedStyle( elem ); |
|
}; |
|
|
|
var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); |
|
|
|
|
|
|
|
( function() { |
|
|
|
// Executing both pixelPosition & boxSizingReliable tests require only one layout |
|
// so they're executed at the same time to save the second computation. |
|
function computeStyleTests() { |
|
|
|
// This is a singleton, we need to execute it only once |
|
if ( !div ) { |
|
return; |
|
} |
|
|
|
container.style.cssText = "position:absolute;left:-11111px;width:60px;" + |
|
"margin-top:1px;padding:0;border:0"; |
|
div.style.cssText = |
|
"position:relative;display:block;box-sizing:border-box;overflow:scroll;" + |
|
"margin:auto;border:1px;padding:1px;" + |
|
"width:60%;top:1%"; |
|
documentElement.appendChild( container ).appendChild( div ); |
|
|
|
var divStyle = window.getComputedStyle( div ); |
|
pixelPositionVal = divStyle.top !== "1%"; |
|
|
|
// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 |
|
reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; |
|
|
|
// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 |
|
// Some styles come back with percentage values, even though they shouldn't |
|
div.style.right = "60%"; |
|
pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; |
|
|
|
// Support: IE 9 - 11 only |
|
// Detect misreporting of content dimensions for box-sizing:border-box elements |
|
boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; |
|
|
|
// Support: IE 9 only |
|
// Detect overflow:scroll screwiness (gh-3699) |
|
div.style.position = "absolute"; |
|
scrollboxSizeVal = div.offsetWidth === 36 || "absolute"; |
|
|
|
documentElement.removeChild( container ); |
|
|
|
// Nullify the div so it wouldn't be stored in the memory and |
|
// it will also be a sign that checks already performed |
|
div = null; |
|
} |
|
|
|
function roundPixelMeasures( measure ) { |
|
return Math.round( parseFloat( measure ) ); |
|
} |
|
|
|
var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, |
|
reliableMarginLeftVal, |
|
container = document.createElement( "div" ), |
|
div = document.createElement( "div" ); |
|
|
|
// Finish early in limited (non-browser) environments |
|
if ( !div.style ) { |
|
return; |
|
} |
|
|
|
// Support: IE <=9 - 11 only |
|
// Style of cloned element affects source element cloned (#8908) |
|
div.style.backgroundClip = "content-box"; |
|
div.cloneNode( true ).style.backgroundClip = ""; |
|
support.clearCloneStyle = div.style.backgroundClip === "content-box"; |
|
|
|
jQuery.extend( support, { |
|
boxSizingReliable: function() { |
|
computeStyleTests(); |
|
return boxSizingReliableVal; |
|
}, |
|
pixelBoxStyles: function() { |
|
computeStyleTests(); |
|
return pixelBoxStylesVal; |
|
}, |
|
pixelPosition: function() { |
|
computeStyleTests(); |
|
return pixelPositionVal; |
|
}, |
|
reliableMarginLeft: function() { |
|
computeStyleTests(); |
|
return reliableMarginLeftVal; |
|
}, |
|
scrollboxSize: function() { |
|
computeStyleTests(); |
|
return scrollboxSizeVal; |
|
} |
|
} ); |
|
} )(); |
|
|
|
|
|
function curCSS( elem, name, computed ) { |
|
var width, minWidth, maxWidth, ret, |
|
|
|
// Support: Firefox 51+ |
|
// Retrieving style before computed somehow |
|
// fixes an issue with getting wrong values |
|
// on detached elements |
|
style = elem.style; |
|
|
|
computed = computed || getStyles( elem ); |
|
|
|
// getPropertyValue is needed for: |
|
// .css('filter') (IE 9 only, #12537) |
|
// .css('--customProperty) (#3144) |
|
if ( computed ) { |
|
ret = computed.getPropertyValue( name ) || computed[ name ]; |
|
|
|
if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { |
|
ret = jQuery.style( elem, name ); |
|
} |
|
|
|
// A tribute to the "awesome hack by Dean Edwards" |
|
// Android Browser returns percentage for some values, |
|
// but width seems to be reliably pixels. |
|
// This is against the CSSOM draft spec: |
|
// https://drafts.csswg.org/cssom/#resolved-values |
|
if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { |
|
|
|
// Remember the original values |
|
width = style.width; |
|
minWidth = style.minWidth; |
|
maxWidth = style.maxWidth; |
|
|
|
// Put in the new values to get a computed value out |
|
style.minWidth = style.maxWidth = style.width = ret; |
|
ret = computed.width; |
|
|
|
// Revert the changed values |
|
style.width = width; |
|
style.minWidth = minWidth; |
|
style.maxWidth = maxWidth; |
|
} |
|
} |
|
|
|
return ret !== undefined ? |
|
|
|
// Support: IE <=9 - 11 only |
|
// IE returns zIndex value as an integer. |
|
ret + "" : |
|
ret; |
|
} |
|
|
|
|
|
function addGetHookIf( conditionFn, hookFn ) { |
|
|
|
// Define the hook, we'll check on the first run if it's really needed. |
|
return { |
|
get: function() { |
|
if ( conditionFn() ) { |
|
|
|
// Hook not needed (or it's not possible to use it due |
|
// to missing dependency), remove it. |
|
delete this.get; |
|
return; |
|
} |
|
|
|
// Hook needed; redefine it so that the support test is not executed again. |
|
return ( this.get = hookFn ).apply( this, arguments ); |
|
} |
|
}; |
|
} |
|
|
|
|
|
var |
|
|
|
// Swappable if display is none or starts with table |
|
// except "table", "table-cell", or "table-caption" |
|
// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display |
|
rdisplayswap = /^(none|table(?!-c[ea]).+)/, |
|
rcustomProp = /^--/, |
|
cssShow = { position: "absolute", visibility: "hidden", display: "block" }, |
|
cssNormalTransform = { |
|
letterSpacing: "0", |
|
fontWeight: "400" |
|
}, |
|
|
|
cssPrefixes = [ "Webkit", "Moz", "ms" ], |
|
emptyStyle = document.createElement( "div" ).style; |
|
|
|
// Return a css property mapped to a potentially vendor prefixed property |
|
function vendorPropName( name ) { |
|
|
|
// Shortcut for names that are not vendor prefixed |
|
if ( name in emptyStyle ) { |
|
return name; |
|
} |
|
|
|
// Check for vendor prefixed names |
|
var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), |
|
i = cssPrefixes.length; |
|
|
|
while ( i-- ) { |
|
name = cssPrefixes[ i ] + capName; |
|
if ( name in emptyStyle ) { |
|
return name; |
|
} |
|
} |
|
} |
|
|
|
// Return a property mapped along what jQuery.cssProps suggests or to |
|
// a vendor prefixed property. |
|
function finalPropName( name ) { |
|
var ret = jQuery.cssProps[ name ]; |
|
if ( !ret ) { |
|
ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name; |
|
} |
|
return ret; |
|
} |
|
|
|
function setPositiveNumber( elem, value, subtract ) { |
|
|
|
// Any relative (+/-) values have already been |
|
// normalized at this point |
|
var matches = rcssNum.exec( value ); |
|
return matches ? |
|
|
|
// Guard against undefined "subtract", e.g., when used as in cssHooks |
|
Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : |
|
value; |
|
} |
|
|
|
function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { |
|
var i = dimension === "width" ? 1 : 0, |
|
extra = 0, |
|
delta = 0; |
|
|
|
// Adjustment may not be necessary |
|
if ( box === ( isBorderBox ? "border" : "content" ) ) { |
|
return 0; |
|
} |
|
|
|
for ( ; i < 4; i += 2 ) { |
|
|
|
// Both box models exclude margin |
|
if ( box === "margin" ) { |
|
delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); |
|
} |
|
|
|
// If we get here with a content-box, we're seeking "padding" or "border" or "margin" |
|
if ( !isBorderBox ) { |
|
|
|
// Add padding |
|
delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); |
|
|
|
// For "border" or "margin", add border |
|
if ( box !== "padding" ) { |
|
delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); |
|
|
|
// But still keep track of it otherwise |
|
} else { |
|
extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); |
|
} |
|
|
|
// If we get here with a border-box (content + padding + border), we're seeking "content" or |
|
// "padding" or "margin" |
|
} else { |
|
|
|
// For "content", subtract padding |
|
if ( box === "content" ) { |
|
delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); |
|
} |
|
|
|
// For "content" or "padding", subtract border |
|
if ( box !== "margin" ) { |
|
delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); |
|
} |
|
} |
|
} |
|
|
|
// Account for positive content-box scroll gutter when requested by providing computedVal |
|
if ( !isBorderBox && computedVal >= 0 ) { |
|
|
|
// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border |
|
// Assuming integer scroll gutter, subtract the rest and round down |
|
delta += Math.max( 0, Math.ceil( |
|
elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - |
|
computedVal - |
|
delta - |
|
extra - |
|
0.5 |
|
) ); |
|
} |
|
|
|
return delta; |
|
} |
|
|
|
function getWidthOrHeight( elem, dimension, extra ) { |
|
|
|
// Start with computed style |
|
var styles = getStyles( elem ), |
|
val = curCSS( elem, dimension, styles ), |
|
isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box", |
|
valueIsBorderBox = isBorderBox; |
|
|
|
// Support: Firefox <=54 |
|
// Return a confounding non-pixel value or feign ignorance, as appropriate. |
|
if ( rnumnonpx.test( val ) ) { |
|
if ( !extra ) { |
|
return val; |
|
} |
|
val = "auto"; |
|
} |
|
|
|
// Check for style in case a browser which returns unreliable values |
|
// for getComputedStyle silently falls back to the reliable elem.style |
|
valueIsBorderBox = valueIsBorderBox && |
|
( support.boxSizingReliable() || val === elem.style[ dimension ] ); |
|
|
|
// Fall back to offsetWidth/offsetHeight when value is "auto" |
|
// This happens for inline elements with no explicit setting (gh-3571) |
|
// Support: Android <=4.1 - 4.3 only |
|
// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) |
|
if ( val === "auto" || |
|
!parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) { |
|
|
|
val = elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ]; |
|
|
|
// offsetWidth/offsetHeight provide border-box values |
|
valueIsBorderBox = true; |
|
} |
|
|
|
// Normalize "" and auto |
|
val = parseFloat( val ) || 0; |
|
|
|
// Adjust for the element's box model |
|
return ( val + |
|
boxModelAdjustment( |
|
elem, |
|
dimension, |
|
extra || ( isBorderBox ? "border" : "content" ), |
|
valueIsBorderBox, |
|
styles, |
|
|
|
// Provide the current computed size to request scroll gutter calculation (gh-3589) |
|
val |
|
) |
|
) + "px"; |
|
} |
|
|
|
jQuery.extend( { |
|
|
|
// Add in style property hooks for overriding the default |
|
// behavior of getting and setting a style property |
|
cssHooks: { |
|
opacity: { |
|
get: function( elem, computed ) { |
|
if ( computed ) { |
|
|
|
// We should always get a number back from opacity |
|
var ret = curCSS( elem, "opacity" ); |
|
return ret === "" ? "1" : ret; |
|
} |
|
} |
|
} |
|
}, |
|
|
|
// Don't automatically add "px" to these possibly-unitless properties |
|
cssNumber: { |
|
"animationIterationCount": true, |
|
"columnCount": true, |
|
"fillOpacity": true, |
|
"flexGrow": true, |
|
"flexShrink": true, |
|
"fontWeight": true, |
|
"lineHeight": true, |
|
"opacity": true, |
|
"order": true, |
|
"orphans": true, |
|
"widows": true, |
|
"zIndex": true, |
|
"zoom": true |
|
}, |
|
|
|
// Add in properties whose names you wish to fix before |
|
// setting or getting the value |
|
cssProps: {}, |
|
|
|
// Get and set the style property on a DOM Node |
|
style: function( elem, name, value, extra ) { |
|
|
|
// Don't set styles on text and comment nodes |
|
if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { |
|
return; |
|
} |
|
|
|
// Make sure that we're working with the right name |
|
var ret, type, hooks, |
|
origName = camelCase( name ), |
|
isCustomProp = rcustomProp.test( name ), |
|
style = elem.style; |
|
|
|
// Make sure that we're working with the right name. We don't |
|
// want to query the value if it is a CSS custom property |
|
// since they are user-defined. |
|
if ( !isCustomProp ) { |
|
name = finalPropName( origName ); |
|
} |
|
|
|
// Gets hook for the prefixed version, then unprefixed version |
|
hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; |
|
|
|
// Check if we're setting a value |
|
if ( value !== undefined ) { |
|
type = typeof value; |
|
|
|
// Convert "+=" or "-=" to relative numbers (#7345) |
|
if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { |
|
value = adjustCSS( elem, name, ret ); |
|
|
|
// Fixes bug #9237 |
|
type = "number"; |
|
} |
|
|
|
// Make sure that null and NaN values aren't set (#7116) |
|
if ( value == null || value !== value ) { |
|
return; |
|
} |
|
|
|
// If a number was passed in, add the unit (except for certain CSS properties) |
|
if ( type === "number" ) { |
|
value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); |
|
} |
|
|
|
// background-* props affect original clone's values |
|
if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { |
|
style[ name ] = "inherit"; |
|
} |
|
|
|
// If a hook was provided, use that value, otherwise just set the specified value |
|
if ( !hooks || !( "set" in hooks ) || |
|
( value = hooks.set( elem, value, extra ) ) !== undefined ) { |
|
|
|
if ( isCustomProp ) { |
|
style.setProperty( name, value ); |
|
} else { |
|
style[ name ] = value; |
|
} |
|
} |
|
|
|
} else { |
|
|
|
// If a hook was provided get the non-computed value from there |
|
if ( hooks && "get" in hooks && |
|
( ret = hooks.get( elem, false, extra ) ) !== undefined ) { |
|
|
|
return ret; |
|
} |
|
|
|
// Otherwise just get the value from the style object |
|
return style[ name ]; |
|
} |
|
}, |
|
|
|
css: function( elem, name, extra, styles ) { |
|
var val, num, hooks, |
|
origName = camelCase( name ), |
|
isCustomProp = rcustomProp.test( name ); |
|
|
|
// Make sure that we're working with the right name. We don't |
|
// want to modify the value if it is a CSS custom property |
|
// since they are user-defined. |
|
if ( !isCustomProp ) { |
|
name = finalPropName( origName ); |
|
} |
|
|
|
// Try prefixed name followed by the unprefixed name |
|
hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; |
|
|
|
// If a hook was provided get the computed value from there |
|
if ( hooks && "get" in hooks ) { |
|
val = hooks.get( elem, true, extra ); |
|
} |
|
|
|
// Otherwise, if a way to get the computed value exists, use that |
|
if ( val === undefined ) { |
|
val = curCSS( elem, name, styles ); |
|
} |
|
|
|
// Convert "normal" to computed value |
|
if ( val === "normal" && name in cssNormalTransform ) { |
|
val = cssNormalTransform[ name ]; |
|
} |
|
|
|
// Make numeric if forced or a qualifier was provided and val looks numeric |
|
if ( extra === "" || extra ) { |
|
num = parseFloat( val ); |
|
return extra === true || isFinite( num ) ? num || 0 : val; |
|
} |
|
|
|
return val; |
|
} |
|
} ); |
|
|
|
jQuery.each( [ "height", "width" ], function( i, dimension ) { |
|
jQuery.cssHooks[ dimension ] = { |
|
get: function( elem, computed, extra ) { |
|
if ( computed ) { |
|
|
|
// Certain elements can have dimension info if we invisibly show them |
|
// but it must have a current display style that would benefit |
|
return rdisplayswap.test( jQuery.css( elem, "display" ) ) && |
|
|
|
// Support: Safari 8+ |
|
// Table columns in Safari have non-zero offsetWidth & zero |
|
// getBoundingClientRect().width unless display is changed. |
|
// Support: IE <=11 only |
|
// Running getBoundingClientRect on a disconnected node |
|
// in IE throws an error. |
|
( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? |
|
swap( elem, cssShow, function() { |
|
return getWidthOrHeight( elem, dimension, extra ); |
|
} ) : |
|
getWidthOrHeight( elem, dimension, extra ); |
|
} |
|
}, |
|
|
|
set: function( elem, value, extra ) { |
|
var matches, |
|
styles = getStyles( elem ), |
|
isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box", |
|
subtract = extra && boxModelAdjustment( |
|
elem, |
|
dimension, |
|
extra, |
|
isBorderBox, |
|
styles |
|
); |
|
|
|
// Account for unreliable border-box dimensions by comparing offset* to computed and |
|
// faking a content-box to get border and padding (gh-3699) |
|
if ( isBorderBox && support.scrollboxSize() === styles.position ) { |
|
subtract -= Math.ceil( |
|
elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - |
|
parseFloat( styles[ dimension ] ) - |
|
boxModelAdjustment( elem, dimension, "border", false, styles ) - |
|
0.5 |
|
); |
|
} |
|
|
|
// Convert to pixels if value adjustment is needed |
|
if ( subtract && ( matches = rcssNum.exec( value ) ) && |
|
( matches[ 3 ] || "px" ) !== "px" ) { |
|
|
|
elem.style[ dimension ] = value; |
|
value = jQuery.css( elem, dimension ); |
|
} |
|
|
|
return setPositiveNumber( elem, value, subtract ); |
|
} |
|
}; |
|
} ); |
|
|
|
jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, |
|
function( elem, computed ) { |
|
if ( computed ) { |
|
return ( parseFloat( curCSS( elem, "marginLeft" ) ) || |
|
elem.getBoundingClientRect().left - |
|
swap( elem, { marginLeft: 0 }, function() { |
|
return elem.getBoundingClientRect().left; |
|
} ) |
|
) + "px"; |
|
} |
|
} |
|
); |
|
|
|
// These hooks are used by animate to expand properties |
|
jQuery.each( { |
|
margin: "", |
|
padding: "", |
|
border: "Width" |
|
}, function( prefix, suffix ) { |
|
jQuery.cssHooks[ prefix + suffix ] = { |
|
expand: function( value ) { |
|
var i = 0, |
|
expanded = {}, |
|
|
|
// Assumes a single number if not a string |
|
parts = typeof value === "string" ? value.split( " " ) : [ value ]; |
|
|
|
for ( ; i < 4; i++ ) { |
|
expanded[ prefix + cssExpand[ i ] + suffix ] = |
|
parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; |
|
} |
|
|
|
return expanded; |
|
} |
|
}; |
|
|
|
if ( prefix !== "margin" ) { |
|
jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; |
|
} |
|
} ); |
|
|
|
jQuery.fn.extend( { |
|
css: function( name, value ) { |
|
return access( this, function( elem, name, value ) { |
|
var styles, len, |
|
map = {}, |
|
i = 0; |
|
|
|
if ( Array.isArray( name ) ) { |
|
styles = getStyles( elem ); |
|
len = name.length; |
|
|
|
for ( ; i < len; i++ ) { |
|
map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); |
|
} |
|
|
|
return map; |
|
} |
|
|
|
return value !== undefined ? |
|
jQuery.style( elem, name, value ) : |
|
jQuery.css( elem, name ); |
|
}, name, value, arguments.length > 1 ); |
|
} |
|
} ); |
|
|
|
|
|
function Tween( elem, options, prop, end, easing ) { |
|
return new Tween.prototype.init( elem, options, prop, end, easing ); |
|
} |
|
jQuery.Tween = Tween; |
|
|
|
Tween.prototype = { |
|
constructor: Tween, |
|
init: function( elem, options, prop, end, easing, unit ) { |
|
this.elem = elem; |
|
this.prop = prop; |
|
this.easing = easing || jQuery.easing._default; |
|
this.options = options; |
|
this.start = this.now = this.cur(); |
|
this.end = end; |
|
this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); |
|
}, |
|
cur: function() { |
|
var hooks = Tween.propHooks[ this.prop ]; |
|
|
|
return hooks && hooks.get ? |
|
hooks.get( this ) : |
|
Tween.propHooks._default.get( this ); |
|
}, |
|
run: function( percent ) { |
|
var eased, |
|
hooks = Tween.propHooks[ this.prop ]; |
|
|
|
if ( this.options.duration ) { |
|
this.pos = eased = jQuery.easing[ this.easing ]( |
|
percent, this.options.duration * percent, 0, 1, this.options.duration |
|
); |
|
} else { |
|
this.pos = eased = percent; |
|
} |
|
this.now = ( this.end - this.start ) * eased + this.start; |
|
|
|
if ( this.options.step ) { |
|
this.options.step.call( this.elem, this.now, this ); |
|
} |
|
|
|
if ( hooks && hooks.set ) { |
|
hooks.set( this ); |
|
} else { |
|
Tween.propHooks._default.set( this ); |
|
} |
|
return this; |
|
} |
|
}; |
|
|
|
Tween.prototype.init.prototype = Tween.prototype; |
|
|
|
Tween.propHooks = { |
|
_default: { |
|
get: function( tween ) { |
|
var result; |
|
|
|
// Use a property on the element directly when it is not a DOM element, |
|
// or when there is no matching style property that exists. |
|
if ( tween.elem.nodeType !== 1 || |
|
tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { |
|
return tween.elem[ tween.prop ]; |
|
} |
|
|
|
// Passing an empty string as a 3rd parameter to .css will automatically |
|
// attempt a parseFloat and fallback to a string if the parse fails. |
|
// Simple values such as "10px" are parsed to Float; |
|
// complex values such as "rotate(1rad)" are returned as-is. |
|
result = jQuery.css( tween.elem, tween.prop, "" ); |
|
|
|
// Empty strings, null, undefined and "auto" are converted to 0. |
|
return !result || result === "auto" ? 0 : result; |
|
}, |
|
set: function( tween ) { |
|
|
|
// Use step hook for back compat. |
|
// Use cssHook if its there. |
|
// Use .style if available and use plain properties where available. |
|
if ( jQuery.fx.step[ tween.prop ] ) { |
|
jQuery.fx.step[ tween.prop ]( tween ); |
|
} else if ( tween.elem.nodeType === 1 && |
|
( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || |
|
jQuery.cssHooks[ tween.prop ] ) ) { |
|
jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); |
|
} else { |
|
tween.elem[ tween.prop ] = tween.now; |
|
} |
|
} |
|
} |
|
}; |
|
|
|
// Support: IE <=9 only |
|
// Panic based approach to setting things on disconnected nodes |
|
Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { |
|
set: function( tween ) { |
|
if ( tween.elem.nodeType && tween.elem.parentNode ) { |
|
tween.elem[ tween.prop ] = tween.now; |
|
} |
|
} |
|
}; |
|
|
|
jQuery.easing = { |
|
linear: function( p ) { |
|
return p; |
|
}, |
|
swing: function( p ) { |
|
return 0.5 - Math.cos( p * Math.PI ) / 2; |
|
}, |
|
_default: "swing" |
|
}; |
|
|
|
jQuery.fx = Tween.prototype.init; |
|
|
|
// Back compat <1.8 extension point |
|
jQuery.fx.step = {}; |
|
|
|
|
|
|
|
|
|
var |
|
fxNow, inProgress, |
|
rfxtypes = /^(?:toggle|show|hide)$/, |
|
rrun = /queueHooks$/; |
|
|
|
function schedule() { |
|
if ( inProgress ) { |
|
if ( document.hidden === false && window.requestAnimationFrame ) { |
|
window.requestAnimationFrame( schedule ); |
|
} else { |
|
window.setTimeout( schedule, jQuery.fx.interval ); |
|
} |
|
|
|
jQuery.fx.tick(); |
|
} |
|
} |
|
|
|
// Animations created synchronously will run synchronously |
|
function createFxNow() { |
|
window.setTimeout( function() { |
|
fxNow = undefined; |
|
} ); |
|
return ( fxNow = Date.now() ); |
|
} |
|
|
|
// Generate parameters to create a standard animation |
|
function genFx( type, includeWidth ) { |
|
var which, |
|
i = 0, |
|
attrs = { height: type }; |
|
|
|
// If we include width, step value is 1 to do all cssExpand values, |
|
// otherwise step value is 2 to skip over Left and Right |
|
includeWidth = includeWidth ? 1 : 0; |
|
for ( ; i < 4; i += 2 - includeWidth ) { |
|
which = cssExpand[ i ]; |
|
attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; |
|
} |
|
|
|
if ( includeWidth ) { |
|
attrs.opacity = attrs.width = type; |
|
} |
|
|
|
return attrs; |
|
} |
|
|
|
function createTween( value, prop, animation ) { |
|
var tween, |
|
collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), |
|
index = 0, |
|
length = collection.length; |
|
for ( ; index < length; index++ ) { |
|
if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { |
|
|
|
// We're done with this property |
|
return tween; |
|
} |
|
} |
|
} |
|
|
|
function defaultPrefilter( elem, props, opts ) { |
|
var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, |
|
isBox = "width" in props || "height" in props, |
|
anim = this, |
|
orig = {}, |
|
style = elem.style, |
|
hidden = elem.nodeType && isHiddenWithinTree( elem ), |
|
dataShow = dataPriv.get( elem, "fxshow" ); |
|
|
|
// Queue-skipping animations hijack the fx hooks |
|
if ( !opts.queue ) { |
|
hooks = jQuery._queueHooks( elem, "fx" ); |
|
if ( hooks.unqueued == null ) { |
|
hooks.unqueued = 0; |
|
oldfire = hooks.empty.fire; |
|
hooks.empty.fire = function() { |
|
if ( !hooks.unqueued ) { |
|
oldfire(); |
|
} |
|
}; |
|
} |
|
hooks.unqueued++; |
|
|
|
anim.always( function() { |
|
|
|
// Ensure the complete handler is called before this completes |
|
anim.always( function() { |
|
hooks.unqueued--; |
|
if ( !jQuery.queue( elem, "fx" ).length ) { |
|
hooks.empty.fire(); |
|
} |
|
} ); |
|
} ); |
|
} |
|
|
|
// Detect show/hide animations |
|
for ( prop in props ) { |
|
value = props[ prop ]; |
|
if ( rfxtypes.test( value ) ) { |
|
delete props[ prop ]; |
|
toggle = toggle || value === "toggle"; |
|
if ( value === ( hidden ? "hide" : "show" ) ) { |
|
|
|
// Pretend to be hidden if this is a "show" and |
|
// there is still data from a stopped show/hide |
|
if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { |
|
hidden = true; |
|
|
|
// Ignore all other no-op show/hide data |
|
} else { |
|
continue; |
|
} |
|
} |
|
orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); |
|
} |
|
} |
|
|
|
// Bail out if this is a no-op like .hide().hide() |
|
propTween = !jQuery.isEmptyObject( props ); |
|
if ( !propTween && jQuery.isEmptyObject( orig ) ) { |
|
return; |
|
} |
|
|
|
// Restrict "overflow" and "display" styles during box animations |
|
if ( isBox && elem.nodeType === 1 ) { |
|
|
|
// Support: IE <=9 - 11, Edge 12 - 15 |
|
// Record all 3 overflow attributes because IE does not infer the shorthand |
|
// from identically-valued overflowX and overflowY and Edge just mirrors |
|
// the overflowX value there. |
|
opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; |
|
|
|
// Identify a display type, preferring old show/hide data over the CSS cascade |
|
restoreDisplay = dataShow && dataShow.display; |
|
if ( restoreDisplay == null ) { |
|
restoreDisplay = dataPriv.get( elem, "display" ); |
|
} |
|
display = jQuery.css( elem, "display" ); |
|
if ( display === "none" ) { |
|
if ( restoreDisplay ) { |
|
display = restoreDisplay; |
|
} else { |
|
|
|
// Get nonempty value(s) by temporarily forcing visibility |
|
showHide( [ elem ], true ); |
|
restoreDisplay = elem.style.display || restoreDisplay; |
|
display = jQuery.css( elem, "display" ); |
|
showHide( [ elem ] ); |
|
} |
|
} |
|
|
|
// Animate inline elements as inline-block |
|
if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { |
|
if ( jQuery.css( elem, "float" ) === "none" ) { |
|
|
|
// Restore the original display value at the end of pure show/hide animations |
|
if ( !propTween ) { |
|
anim.done( function() { |
|
style.display = restoreDisplay; |
|
} ); |
|
if ( restoreDisplay == null ) { |
|
display = style.display; |
|
restoreDisplay = display === "none" ? "" : display; |
|
} |
|
} |
|
style.display = "inline-block"; |
|
} |
|
} |
|
} |
|
|
|
if ( opts.overflow ) { |
|
style.overflow = "hidden"; |
|
anim.always( function() { |
|
style.overflow = opts.overflow[ 0 ]; |
|
style.overflowX = opts.overflow[ 1 ]; |
|
style.overflowY = opts.overflow[ 2 ]; |
|
} ); |
|
} |
|
|
|
// Implement show/hide animations |
|
propTween = false; |
|
for ( prop in orig ) { |
|
|
|
// General show/hide setup for this element animation |
|
if ( !propTween ) { |
|
if ( dataShow ) { |
|
if ( "hidden" in dataShow ) { |
|
hidden = dataShow.hidden; |
|
} |
|
} else { |
|
dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); |
|
} |
|
|
|
// Store hidden/visible for toggle so `.stop().toggle()` "reverses" |
|
if ( toggle ) { |
|
dataShow.hidden = !hidden; |
|
} |
|
|
|
// Show elements before animating them |
|
if ( hidden ) { |
|
showHide( [ elem ], true ); |
|
} |
|
|
|
/* eslint-disable no-loop-func */ |
|
|
|
anim.done( function() { |
|
|
|
/* eslint-enable no-loop-func */ |
|
|
|
// The final step of a "hide" animation is actually hiding the element |
|
if ( !hidden ) { |
|
showHide( [ elem ] ); |
|
} |
|
dataPriv.remove( elem, "fxshow" ); |
|
for ( prop in orig ) { |
|
jQuery.style( elem, prop, orig[ prop ] ); |
|
} |
|
} ); |
|
} |
|
|
|
// Per-property setup |
|
propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); |
|
if ( !( prop in dataShow ) ) { |
|
dataShow[ prop ] = propTween.start; |
|
if ( hidden ) { |
|
propTween.end = propTween.start; |
|
propTween.start = 0; |
|
} |
|
} |
|
} |
|
} |
|
|
|
function propFilter( props, specialEasing ) { |
|
var index, name, easing, value, hooks; |
|
|
|
// camelCase, specialEasing and expand cssHook pass |
|
for ( index in props ) { |
|
name = camelCase( index ); |
|
easing = specialEasing[ name ]; |
|
value = props[ index ]; |
|
if ( Array.isArray( value ) ) { |
|
easing = value[ 1 ]; |
|
value = props[ index ] = value[ 0 ]; |
|
} |
|
|
|
if ( index !== name ) { |
|
props[ name ] = value; |
|
delete props[ index ]; |
|
} |
|
|
|
hooks = jQuery.cssHooks[ name ]; |
|
if ( hooks && "expand" in hooks ) { |
|
value = hooks.expand( value ); |
|
delete props[ name ]; |
|
|
|
// Not quite $.extend, this won't overwrite existing keys. |
|
// Reusing 'index' because we have the correct "name" |
|
for ( index in value ) { |
|
if ( !( index in props ) ) { |
|
props[ index ] = value[ index ]; |
|
specialEasing[ index ] = easing; |
|
} |
|
} |
|
} else { |
|
specialEasing[ name ] = easing; |
|
} |
|
} |
|
} |
|
|
|
function Animation( elem, properties, options ) { |
|
var result, |
|
stopped, |
|
index = 0, |
|
length = Animation.prefilters.length, |
|
deferred = jQuery.Deferred().always( function() { |
|
|
|
// Don't match elem in the :animated selector |
|
delete tick.elem; |
|
} ), |
|
tick = function() { |
|
if ( stopped ) { |
|
return false; |
|
} |
|
var currentTime = fxNow || createFxNow(), |
|
remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), |
|
|
|
// Support: Android 2.3 only |
|
// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) |
|
temp = remaining / animation.duration || 0, |
|
percent = 1 - temp, |
|
index = 0, |
|
length = animation.tweens.length; |
|
|
|
for ( ; index < length; index++ ) { |
|
animation.tweens[ index ].run( percent ); |
|
} |
|
|
|
deferred.notifyWith( elem, [ animation, percent, remaining ] ); |
|
|
|
// If there's more to do, yield |
|
if ( percent < 1 && length ) { |
|
return remaining; |
|
} |
|
|
|
// If this was an empty animation, synthesize a final progress notification |
|
if ( !length ) { |
|
deferred.notifyWith( elem, [ animation, 1, 0 ] ); |
|
} |
|
|
|
// Resolve the animation and report its conclusion |
|
deferred.resolveWith( elem, [ animation ] ); |
|
return false; |
|
}, |
|
animation = deferred.promise( { |
|
elem: elem, |
|
props: jQuery.extend( {}, properties ), |
|
opts: jQuery.extend( true, { |
|
specialEasing: {}, |
|
easing: jQuery.easing._default |
|
}, options ), |
|
originalProperties: properties, |
|
originalOptions: options, |
|
startTime: fxNow || createFxNow(), |
|
duration: options.duration, |
|
tweens: [], |
|
createTween: function( prop, end ) { |
|
var tween = jQuery.Tween( elem, animation.opts, prop, end, |
|
animation.opts.specialEasing[ prop ] || animation.opts.easing ); |
|
animation.tweens.push( tween ); |
|
return tween; |
|
}, |
|
stop: function( gotoEnd ) { |
|
var index = 0, |
|
|
|
// If we are going to the end, we want to run all the tweens |
|
// otherwise we skip this part |
|
length = gotoEnd ? animation.tweens.length : 0; |
|
if ( stopped ) { |
|
return this; |
|
} |
|
stopped = true; |
|
for ( ; index < length; index++ ) { |
|
animation.tweens[ index ].run( 1 ); |
|
} |
|
|
|
// Resolve when we played the last frame; otherwise, reject |
|
if ( gotoEnd ) { |
|
deferred.notifyWith( elem, [ animation, 1, 0 ] ); |
|
deferred.resolveWith( elem, [ animation, gotoEnd ] ); |
|
} else { |
|
deferred.rejectWith( elem, [ animation, gotoEnd ] ); |
|
} |
|
return this; |
|
} |
|
} ), |
|
props = animation.props; |
|
|
|
propFilter( props, animation.opts.specialEasing ); |
|
|
|
for ( ; index < length; index++ ) { |
|
result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); |
|
if ( result ) { |
|
if ( isFunction( result.stop ) ) { |
|
jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = |
|
result.stop.bind( result ); |
|
} |
|
return result; |
|
} |
|
} |
|
|
|
jQuery.map( props, createTween, animation ); |
|
|
|
if ( isFunction( animation.opts.start ) ) { |
|
animation.opts.start.call( elem, animation ); |
|
} |
|
|
|
// Attach callbacks from options |
|
animation |
|
.progress( animation.opts.progress ) |
|
.done( animation.opts.done, animation.opts.complete ) |
|
.fail( animation.opts.fail ) |
|
.always( animation.opts.always ); |
|
|
|
jQuery.fx.timer( |
|
jQuery.extend( tick, { |
|
elem: elem, |
|
anim: animation, |
|
queue: animation.opts.queue |
|
} ) |
|
); |
|
|
|
return animation; |
|
} |
|
|
|
jQuery.Animation = jQuery.extend( Animation, { |
|
|
|
tweeners: { |
|
"*": [ function( prop, value ) { |
|
var tween = this.createTween( prop, value ); |
|
adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); |
|
return tween; |
|
} ] |
|
}, |
|
|
|
tweener: function( props, callback ) { |
|
if ( isFunction( props ) ) { |
|
callback = props; |
|
props = [ "*" ]; |
|
} else { |
|
props = props.match( rnothtmlwhite ); |
|
} |
|
|
|
var prop, |
|
index = 0, |
|
length = props.length; |
|
|
|
for ( ; index < length; index++ ) { |
|
prop = props[ index ]; |
|
Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; |
|
Animation.tweeners[ prop ].unshift( callback ); |
|
} |
|
}, |
|
|
|
prefilters: [ defaultPrefilter ], |
|
|
|
prefilter: function( callback, prepend ) { |
|
if ( prepend ) { |
|
Animation.prefilters.unshift( callback ); |
|
} else { |
|
Animation.prefilters.push( callback ); |
|
} |
|
} |
|
} ); |
|
|
|
jQuery.speed = function( speed, easing, fn ) { |
|
var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { |
|
complete: fn || !fn && easing || |
|
isFunction( speed ) && speed, |
|
duration: speed, |
|
easing: fn && easing || easing && !isFunction( easing ) && easing |
|
}; |
|
|
|
// Go to the end state if fx are off |
|
if ( jQuery.fx.off ) { |
|
opt.duration = 0; |
|
|
|
} else { |
|
if ( typeof opt.duration !== "number" ) { |
|
if ( opt.duration in jQuery.fx.speeds ) { |
|
opt.duration = jQuery.fx.speeds[ opt.duration ]; |
|
|
|
} else { |
|
opt.duration = jQuery.fx.speeds._default; |
|
} |
|
} |
|
} |
|
|
|
// Normalize opt.queue - true/undefined/null -> "fx" |
|
if ( opt.queue == null || opt.queue === true ) { |
|
opt.queue = "fx"; |
|
} |
|
|
|
// Queueing |
|
opt.old = opt.complete; |
|
|
|
opt.complete = function() { |
|
if ( isFunction( opt.old ) ) { |
|
opt.old.call( this ); |
|
} |
|
|
|
if ( opt.queue ) { |
|
jQuery.dequeue( this, opt.queue ); |
|
} |
|
}; |
|
|
|
return opt; |
|
}; |
|
|
|
jQuery.fn.extend( { |
|
fadeTo: function( speed, to, easing, callback ) { |
|
|
|
// Show any hidden elements after setting opacity to 0 |
|
return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() |
|
|
|
// Animate to the value specified |
|
.end().animate( { opacity: to }, speed, easing, callback ); |
|
}, |
|
animate: function( prop, speed, easing, callback ) { |
|
var empty = jQuery.isEmptyObject( prop ), |
|
optall = jQuery.speed( speed, easing, callback ), |
|
doAnimation = function() { |
|
|
|
// Operate on a copy of prop so per-property easing won't be lost |
|
var anim = Animation( this, jQuery.extend( {}, prop ), optall ); |
|
|
|
// Empty animations, or finishing resolves immediately |
|
if ( empty || dataPriv.get( this, "finish" ) ) { |
|
anim.stop( true ); |
|
} |
|
}; |
|
doAnimation.finish = doAnimation; |
|
|
|
return empty || optall.queue === false ? |
|
this.each( doAnimation ) : |
|
this.queue( optall.queue, doAnimation ); |
|
}, |
|
stop: function( type, clearQueue, gotoEnd ) { |
|
var stopQueue = function( hooks ) { |
|
var stop = hooks.stop; |
|
delete hooks.stop; |
|
stop( gotoEnd ); |
|
}; |
|
|
|
if ( typeof type !== "string" ) { |
|
gotoEnd = clearQueue; |
|
clearQueue = type; |
|
type = undefined; |
|
} |
|
if ( clearQueue && type !== false ) { |
|
this.queue( type || "fx", [] ); |
|
} |
|
|
|
return this.each( function() { |
|
var dequeue = true, |
|
index = type != null && type + "queueHooks", |
|
timers = jQuery.timers, |
|
data = dataPriv.get( this ); |
|
|
|
if ( index ) { |
|
if ( data[ index ] && data[ index ].stop ) { |
|
stopQueue( data[ index ] ); |
|
} |
|
} else { |
|
for ( index in data ) { |
|
if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { |
|
stopQueue( data[ index ] ); |
|
} |
|
} |
|
} |
|
|
|
for ( index = timers.length; index--; ) { |
|
if ( timers[ index ].elem === this && |
|
( type == null || timers[ index ].queue === type ) ) { |
|
|
|
timers[ index ].anim.stop( gotoEnd ); |
|
dequeue = false; |
|
timers.splice( index, 1 ); |
|
} |
|
} |
|
|
|
// Start the next in the queue if the last step wasn't forced. |
|
// Timers currently will call their complete callbacks, which |
|
// will dequeue but only if they were gotoEnd. |
|
if ( dequeue || !gotoEnd ) { |
|
jQuery.dequeue( this, type ); |
|
} |
|
} ); |
|
}, |
|
finish: function( type ) { |
|
if ( type !== false ) { |
|
type = type || "fx"; |
|
} |
|
return this.each( function() { |
|
var index, |
|
data = dataPriv.get( this ), |
|
queue = data[ type + "queue" ], |
|
hooks = data[ type + "queueHooks" ], |
|
timers = jQuery.timers, |
|
length = queue ? queue.length : 0; |
|
|
|
// Enable finishing flag on private data |
|
data.finish = true; |
|
|
|
// Empty the queue first |
|
jQuery.queue( this, type, [] ); |
|
|
|
if ( hooks && hooks.stop ) { |
|
hooks.stop.call( this, true ); |
|
} |
|
|
|
// Look for any active animations, and finish them |
|
for ( index = timers.length; index--; ) { |
|
if ( timers[ index ].elem === this && timers[ index ].queue === type ) { |
|
timers[ index ].anim.stop( true ); |
|
timers.splice( index, 1 ); |
|
} |
|
} |
|
|
|
// Look for any animations in the old queue and finish them |
|
for ( index = 0; index < length; index++ ) { |
|
if ( queue[ index ] && queue[ index ].finish ) { |
|
queue[ index ].finish.call( this ); |
|
} |
|
} |
|
|
|
// Turn off finishing flag |
|
delete data.finish; |
|
} ); |
|
} |
|
} ); |
|
|
|
jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) { |
|
var cssFn = jQuery.fn[ name ]; |
|
jQuery.fn[ name ] = function( speed, easing, callback ) { |
|
return speed == null || typeof speed === "boolean" ? |
|
cssFn.apply( this, arguments ) : |
|
this.animate( genFx( name, true ), speed, easing, callback ); |
|
}; |
|
} ); |
|
|
|
// Generate shortcuts for custom animations |
|
jQuery.each( { |
|
slideDown: genFx( "show" ), |
|
slideUp: genFx( "hide" ), |
|
slideToggle: genFx( "toggle" ), |
|
fadeIn: { opacity: "show" }, |
|
fadeOut: { opacity: "hide" }, |
|
fadeToggle: { opacity: "toggle" } |
|
}, function( name, props ) { |
|
jQuery.fn[ name ] = function( speed, easing, callback ) { |
|
return this.animate( props, speed, easing, callback ); |
|
}; |
|
} ); |
|
|
|
jQuery.timers = []; |
|
jQuery.fx.tick = function() { |
|
var timer, |
|
i = 0, |
|
timers = jQuery.timers; |
|
|
|
fxNow = Date.now(); |
|
|
|
for ( ; i < timers.length; i++ ) { |
|
timer = timers[ i ]; |
|
|
|
// Run the timer and safely remove it when done (allowing for external removal) |
|
if ( !timer() && timers[ i ] === timer ) { |
|
timers.splice( i--, 1 ); |
|
} |
|
} |
|
|
|
if ( !timers.length ) { |
|
jQuery.fx.stop(); |
|
} |
|
fxNow = undefined; |
|
}; |
|
|
|
jQuery.fx.timer = function( timer ) { |
|
jQuery.timers.push( timer ); |
|
jQuery.fx.start(); |
|
}; |
|
|
|
jQuery.fx.interval = 13; |
|
jQuery.fx.start = function() { |
|
if ( inProgress ) { |
|
return; |
|
} |
|
|
|
inProgress = true; |
|
schedule(); |
|
}; |
|
|
|
jQuery.fx.stop = function() { |
|
inProgress = null; |
|
}; |
|
|
|
jQuery.fx.speeds = { |
|
slow: 600, |
|
fast: 200, |
|
|
|
// Default speed |
|
_default: 400 |
|
}; |
|
|
|
|
|
// Based off of the plugin by Clint Helfers, with permission. |
|
// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ |
|
jQuery.fn.delay = function( time, type ) { |
|
time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; |
|
type = type || "fx"; |
|
|
|
return this.queue( type, function( next, hooks ) { |
|
var timeout = window.setTimeout( next, time ); |
|
hooks.stop = function() { |
|
window.clearTimeout( timeout ); |
|
}; |
|
} ); |
|
}; |
|
|
|
|
|
( function() { |
|
var input = document.createElement( "input" ), |
|
select = document.createElement( "select" ), |
|
opt = select.appendChild( document.createElement( "option" ) ); |
|
|
|
input.type = "checkbox"; |
|
|
|
// Support: Android <=4.3 only |
|
// Default value for a checkbox should be "on" |
|
support.checkOn = input.value !== ""; |
|
|
|
// Support: IE <=11 only |
|
// Must access selectedIndex to make default options select |
|
support.optSelected = opt.selected; |
|
|
|
// Support: IE <=11 only |
|
// An input loses its value after becoming a radio |
|
input = document.createElement( "input" ); |
|
input.value = "t"; |
|
input.type = "radio"; |
|
support.radioValue = input.value === "t"; |
|
} )(); |
|
|
|
|
|
var boolHook, |
|
attrHandle = jQuery.expr.attrHandle; |
|
|
|
jQuery.fn.extend( { |
|
attr: function( name, value ) { |
|
return access( this, jQuery.attr, name, value, arguments.length > 1 ); |
|
}, |
|
|
|
removeAttr: function( name ) { |
|
return this.each( function() { |
|
jQuery.removeAttr( this, name ); |
|
} ); |
|
} |
|
} ); |
|
|
|
jQuery.extend( { |
|
attr: function( elem, name, value ) { |
|
var ret, hooks, |
|
nType = elem.nodeType; |
|
|
|
// Don't get/set attributes on text, comment and attribute nodes |
|
if ( nType === 3 || nType === 8 || nType === 2 ) { |
|
return; |
|
} |
|
|
|
// Fallback to prop when attributes are not supported |
|
if ( typeof elem.getAttribute === "undefined" ) { |
|
return jQuery.prop( elem, name, value ); |
|
} |
|
|
|
// Attribute hooks are determined by the lowercase version |
|
// Grab necessary hook if one is defined |
|
if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { |
|
hooks = jQuery.attrHooks[ name.toLowerCase() ] || |
|
( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); |
|
} |
|
|
|
if ( value !== undefined ) { |
|
if ( value === null ) { |
|
jQuery.removeAttr( elem, name ); |
|
return; |
|
} |
|
|
|
if ( hooks && "set" in hooks && |
|
( ret = hooks.set( elem, value, name ) ) !== undefined ) { |
|
return ret; |
|
} |
|
|
|
elem.setAttribute( name, value + "" ); |
|
return value; |
|
} |
|
|
|
if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { |
|
return ret; |
|
} |
|
|
|
ret = jQuery.find.attr( elem, name ); |
|
|
|
// Non-existent attributes return null, we normalize to undefined |
|
return ret == null ? undefined : ret; |
|
}, |
|
|
|
attrHooks: { |
|
type: { |
|
set: function( elem, value ) { |
|
if ( !support.radioValue && value === "radio" && |
|
nodeName( elem, "input" ) ) { |
|
var val = elem.value; |
|
elem.setAttribute( "type", value ); |
|
if ( val ) { |
|
elem.value = val; |
|
} |
|
return value; |
|
} |
|
} |
|
} |
|
}, |
|
|
|
removeAttr: function( elem, value ) { |
|
var name, |
|
i = 0, |
|
|
|
// Attribute names can contain non-HTML whitespace characters |
|
// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 |
|
attrNames = value && value.match( rnothtmlwhite ); |
|
|
|
if ( attrNames && elem.nodeType === 1 ) { |
|
while ( ( name = attrNames[ i++ ] ) ) { |
|
elem.removeAttribute( name ); |
|
} |
|
} |
|
} |
|
} ); |
|
|
|
// Hooks for boolean attributes |
|
boolHook = { |
|
set: function( elem, value, name ) { |
|
if ( value === false ) { |
|
|
|
// Remove boolean attributes when set to false |
|
jQuery.removeAttr( elem, name ); |
|
} else { |
|
elem.setAttribute( name, name ); |
|
} |
|
return name; |
|
} |
|
}; |
|
|
|
jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { |
|
var getter = attrHandle[ name ] || jQuery.find.attr; |
|
|
|
attrHandle[ name ] = function( elem, name, isXML ) { |
|
var ret, handle, |
|
lowercaseName = name.toLowerCase(); |
|
|
|
if ( !isXML ) { |
|
|
|
// Avoid an infinite loop by temporarily removing this function from the getter |
|
handle = attrHandle[ lowercaseName ]; |
|
attrHandle[ lowercaseName ] = ret; |
|
ret = getter( elem, name, isXML ) != null ? |
|
lowercaseName : |
|
null; |
|
attrHandle[ lowercaseName ] = handle; |
|
} |
|
return ret; |
|
}; |
|
} ); |
|
|
|
|
|
|
|
|
|
var rfocusable = /^(?:input|select|textarea|button)$/i, |
|
rclickable = /^(?:a|area)$/i; |
|
|
|
jQuery.fn.extend( { |
|
prop: function( name, value ) { |
|
return access( this, jQuery.prop, name, value, arguments.length > 1 ); |
|
}, |
|
|
|
removeProp: function( name ) { |
|
return this.each( function() { |
|
delete this[ jQuery.propFix[ name ] || name ]; |
|
} ); |
|
} |
|
} ); |
|
|
|
jQuery.extend( { |
|
prop: function( elem, name, value ) { |
|
var ret, hooks, |
|
nType = elem.nodeType; |
|
|
|
// Don't get/set properties on text, comment and attribute nodes |
|
if ( nType === 3 || nType === 8 || nType === 2 ) { |
|
return; |
|
} |
|
|
|
if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { |
|
|
|
// Fix name and attach hooks |
|
name = jQuery.propFix[ name ] || name; |
|
hooks = jQuery.propHooks[ name ]; |
|
} |
|
|
|
if ( value !== undefined ) { |
|
if ( hooks && "set" in hooks && |
|
( ret = hooks.set( elem, value, name ) ) !== undefined ) { |
|
return ret; |
|
} |
|
|
|
return ( elem[ name ] = value ); |
|
} |
|
|
|
if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { |
|
return ret; |
|
} |
|
|
|
return elem[ name ]; |
|
}, |
|
|
|
propHooks: { |
|
tabIndex: { |
|
get: function( elem ) { |
|
|
|
// Support: IE <=9 - 11 only |
|
// elem.tabIndex doesn't always return the |
|
// correct value when it hasn't been explicitly set |
|
// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ |
|
// Use proper attribute retrieval(#12072) |
|
var tabindex = jQuery.find.attr( elem, "tabindex" ); |
|
|
|
if ( tabindex ) { |
|
return parseInt( tabindex, 10 ); |
|
} |
|
|
|
if ( |
|
rfocusable.test( elem.nodeName ) || |
|
rclickable.test( elem.nodeName ) && |
|
elem.href |
|
) { |
|
return 0; |
|
} |
|
|
|
return -1; |
|
} |
|
} |
|
}, |
|
|
|
propFix: { |
|
"for": "htmlFor", |
|
"class": "className" |
|
} |
|
} ); |
|
|
|
// Support: IE <=11 only |
|
// Accessing the selectedIndex property |
|
// forces the browser to respect setting selected |
|
// on the option |
|
// The getter ensures a default option is selected |
|
// when in an optgroup |
|
// eslint rule "no-unused-expressions" is disabled for this code |
|
// since it considers such accessions noop |
|
if ( !support.optSelected ) { |
|
jQuery.propHooks.selected = { |
|
get: function( elem ) { |
|
|
|
/* eslint no-unused-expressions: "off" */ |
|
|
|
var parent = elem.parentNode; |
|
if ( parent && parent.parentNode ) { |
|
parent.parentNode.selectedIndex; |
|
} |
|
return null; |
|
}, |
|
set: function( elem ) { |
|
|
|
/* eslint no-unused-expressions: "off" */ |
|
|
|
var parent = elem.parentNode; |
|
if ( parent ) { |
|
parent.selectedIndex; |
|
|
|
if ( parent.parentNode ) { |
|
parent.parentNode.selectedIndex; |
|
} |
|
} |
|
} |
|
}; |
|
} |
|
|
|
jQuery.each( [ |
|
"tabIndex", |
|
"readOnly", |
|
"maxLength", |
|
"cellSpacing", |
|
"cellPadding", |
|
"rowSpan", |
|
"colSpan", |
|
"useMap", |
|
"frameBorder", |
|
"contentEditable" |
|
], function() { |
|
jQuery.propFix[ this.toLowerCase() ] = this; |
|
} ); |
|
|
|
|
|
|
|
|
|
// Strip and collapse whitespace according to HTML spec |
|
// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace |
|
function stripAndCollapse( value ) { |
|
var tokens = value.match( rnothtmlwhite ) || []; |
|
return tokens.join( " " ); |
|
} |
|
|
|
|
|
function getClass( elem ) { |
|
return elem.getAttribute && elem.getAttribute( "class" ) || ""; |
|
} |
|
|
|
function classesToArray( value ) { |
|
if ( Array.isArray( value ) ) { |
|
return value; |
|
} |
|
if ( typeof value === "string" ) { |
|
return value.match( rnothtmlwhite ) || []; |
|
} |
|
return []; |
|
} |
|
|
|
jQuery.fn.extend( { |
|
addClass: function( value ) { |
|
var classes, elem, cur, curValue, clazz, j, finalValue, |
|
i = 0; |
|
|
|
if ( isFunction( value ) ) { |
|
return this.each( function( j ) { |
|
jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); |
|
} ); |
|
} |
|
|
|
classes = classesToArray( value ); |
|
|
|
if ( classes.length ) { |
|
while ( ( elem = this[ i++ ] ) ) { |
|
curValue = getClass( elem ); |
|
cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); |
|
|
|
if ( cur ) { |
|
j = 0; |
|
while ( ( clazz = classes[ j++ ] ) ) { |
|
if ( cur.indexOf( " " + clazz + " " ) < 0 ) { |
|
cur += clazz + " "; |
|
} |
|
} |
|
|
|
// Only assign if different to avoid unneeded rendering. |
|
finalValue = stripAndCollapse( cur ); |
|
if ( curValue !== finalValue ) { |
|
elem.setAttribute( "class", finalValue ); |
|
} |
|
} |
|
} |
|
} |
|
|
|
return this; |
|
}, |
|
|
|
removeClass: function( value ) { |
|
var classes, elem, cur, curValue, clazz, j, finalValue, |
|
i = 0; |
|
|
|
if ( isFunction( value ) ) { |
|
return this.each( function( j ) { |
|
jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); |
|
} ); |
|
} |
|
|
|
if ( !arguments.length ) { |
|
return this.attr( "class", "" ); |
|
} |
|
|
|
classes = classesToArray( value ); |
|
|
|
if ( classes.length ) { |
|
while ( ( elem = this[ i++ ] ) ) { |
|
curValue = getClass( elem ); |
|
|
|
// This expression is here for better compressibility (see addClass) |
|
cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); |
|
|
|
if ( cur ) { |
|
j = 0; |
|
while ( ( clazz = classes[ j++ ] ) ) { |
|
|
|
// Remove *all* instances |
|
while ( cur.indexOf( " " + clazz + " " ) > -1 ) { |
|
cur = cur.replace( " " + clazz + " ", " " ); |
|
} |
|
} |
|
|
|
// Only assign if different to avoid unneeded rendering. |
|
finalValue = stripAndCollapse( cur ); |
|
if ( curValue !== finalValue ) { |
|
elem.setAttribute( "class", finalValue ); |
|
} |
|
} |
|
} |
|
} |
|
|
|
return this; |
|
}, |
|
|
|
toggleClass: function( value, stateVal ) { |
|
var type = typeof value, |
|
isValidValue = type === "string" || Array.isArray( value ); |
|
|
|
if ( typeof stateVal === "boolean" && isValidValue ) { |
|
return stateVal ? this.addClass( value ) : this.removeClass( value ); |
|
} |
|
|
|
if ( isFunction( value ) ) { |
|
return this.each( function( i ) { |
|
jQuery( this ).toggleClass( |
|
value.call( this, i, getClass( this ), stateVal ), |
|
stateVal |
|
); |
|
} ); |
|
} |
|
|
|
return this.each( function() { |
|
var className, i, self, classNames; |
|
|
|
if ( isValidValue ) { |
|
|
|
// Toggle individual class names |
|
i = 0; |
|
self = jQuery( this ); |
|
classNames = classesToArray( value ); |
|
|
|
while ( ( className = classNames[ i++ ] ) ) { |
|
|
|
// Check each className given, space separated list |
|
if ( self.hasClass( className ) ) { |
|
self.removeClass( className ); |
|
} else { |
|
self.addClass( className ); |
|
} |
|
} |
|
|
|
// Toggle whole class name |
|
} else if ( value === undefined || type === "boolean" ) { |
|
className = getClass( this ); |
|
if ( className ) { |
|
|
|
// Store className if set |
|
dataPriv.set( this, "__className__", className ); |
|
} |
|
|
|
// If the element has a class name or if we're passed `false`, |
|
// then remove the whole classname (if there was one, the above saved it). |
|
// Otherwise bring back whatever was previously saved (if anything), |
|
// falling back to the empty string if nothing was stored. |
|
if ( this.setAttribute ) { |
|
this.setAttribute( "class", |
|
className || value === false ? |
|
"" : |
|
dataPriv.get( this, "__className__" ) || "" |
|
); |
|
} |
|
} |
|
} ); |
|
}, |
|
|
|
hasClass: function( selector ) { |
|
var className, elem, |
|
i = 0; |
|
|
|
className = " " + selector + " "; |
|
while ( ( elem = this[ i++ ] ) ) { |
|
if ( elem.nodeType === 1 && |
|
( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { |
|
return true; |
|
} |
|
} |
|
|
|
return false; |
|
} |
|
} ); |
|
|
|
|
|
|
|
|
|
var rreturn = /\r/g; |
|
|
|
jQuery.fn.extend( { |
|
val: function( value ) { |
|
var hooks, ret, valueIsFunction, |
|
elem = this[ 0 ]; |
|
|
|
if ( !arguments.length ) { |
|
if ( elem ) { |
|
hooks = jQuery.valHooks[ elem.type ] || |
|
jQuery.valHooks[ elem.nodeName.toLowerCase() ]; |
|
|
|
if ( hooks && |
|
"get" in hooks && |
|
( ret = hooks.get( elem, "value" ) ) !== undefined |
|
) { |
|
return ret; |
|
} |
|
|
|
ret = elem.value; |
|
|
|
// Handle most common string cases |
|
if ( typeof ret === "string" ) { |
|
return ret.replace( rreturn, "" ); |
|
} |
|
|
|
// Handle cases where value is null/undef or number |
|
return ret == null ? "" : ret; |
|
} |
|
|
|
return; |
|
} |
|
|
|
valueIsFunction = isFunction( value ); |
|
|
|
return this.each( function( i ) { |
|
var val; |
|
|
|
if ( this.nodeType !== 1 ) { |
|
return; |
|
} |
|
|
|
if ( valueIsFunction ) { |
|
val = value.call( this, i, jQuery( this ).val() ); |
|
} else { |
|
val = value; |
|
} |
|
|
|
// Treat null/undefined as ""; convert numbers to string |
|
if ( val == null ) { |
|
val = ""; |
|
|
|
} else if ( typeof val === "number" ) { |
|
val += ""; |
|
|
|
} else if ( Array.isArray( val ) ) { |
|
val = jQuery.map( val, function( value ) { |
|
return value == null ? "" : value + ""; |
|
} ); |
|
} |
|
|
|
hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; |
|
|
|
// If set returns undefined, fall back to normal setting |
|
if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { |
|
this.value = val; |
|
} |
|
} ); |
|
} |
|
} ); |
|
|
|
jQuery.extend( { |
|
valHooks: { |
|
option: { |
|
get: function( elem ) { |
|
|
|
var val = jQuery.find.attr( elem, "value" ); |
|
return val != null ? |
|
val : |
|
|
|
// Support: IE <=10 - 11 only |
|
// option.text throws exceptions (#14686, #14858) |
|
// Strip and collapse whitespace |
|
// https://html.spec.whatwg.org/#strip-and-collapse-whitespace |
|
stripAndCollapse( jQuery.text( elem ) ); |
|
} |
|
}, |
|
select: { |
|
get: function( elem ) { |
|
var value, option, i, |
|
options = elem.options, |
|
index = elem.selectedIndex, |
|
one = elem.type === "select-one", |
|
values = one ? null : [], |
|
max = one ? index + 1 : options.length; |
|
|
|
if ( index < 0 ) { |
|
i = max; |
|
|
|
} else { |
|
i = one ? index : 0; |
|
} |
|
|
|
// Loop through all the selected options |
|
for ( ; i < max; i++ ) { |
|
option = options[ i ]; |
|
|
|
// Support: IE <=9 only |
|
// IE8-9 doesn't update selected after form reset (#2551) |
|
if ( ( option.selected || i === index ) && |
|
|
|
// Don't return options that are disabled or in a disabled optgroup |
|
!option.disabled && |
|
( !option.parentNode.disabled || |
|
!nodeName( option.parentNode, "optgroup" ) ) ) { |
|
|
|
// Get the specific value for the option |
|
value = jQuery( option ).val(); |
|
|
|
// We don't need an array for one selects |
|
if ( one ) { |
|
return value; |
|
} |
|
|
|
// Multi-Selects return an array |
|
values.push( value ); |
|
} |
|
} |
|
|
|
return values; |
|
}, |
|
|
|
set: function( elem, value ) { |
|
var optionSet, option, |
|
options = elem.options, |
|
values = jQuery.makeArray( value ), |
|
i = options.length; |
|
|
|
while ( i-- ) { |
|
option = options[ i ]; |
|
|
|
/* eslint-disable no-cond-assign */ |
|
|
|
if ( option.selected = |
|
jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 |
|
) { |
|
optionSet = true; |
|
} |
|
|
|
/* eslint-enable no-cond-assign */ |
|
} |
|
|
|
// Force browsers to behave consistently when non-matching value is set |
|
if ( !optionSet ) { |
|
elem.selectedIndex = -1; |
|
} |
|
return values; |
|
} |
|
} |
|
} |
|
} ); |
|
|
|
// Radios and checkboxes getter/setter |
|
jQuery.each( [ "radio", "checkbox" ], function() { |
|
jQuery.valHooks[ this ] = { |
|
set: function( elem, value ) { |
|
if ( Array.isArray( value ) ) { |
|
return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); |
|
} |
|
} |
|
}; |
|
if ( !support.checkOn ) { |
|
jQuery.valHooks[ this ].get = function( elem ) { |
|
return elem.getAttribute( "value" ) === null ? "on" : elem.value; |
|
}; |
|
} |
|
} ); |
|
|
|
|
|
|
|
|
|
// Return jQuery for attributes-only inclusion |
|
|
|
|
|
support.focusin = "onfocusin" in window; |
|
|
|
|
|
var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, |
|
stopPropagationCallback = function( e ) { |
|
e.stopPropagation(); |
|
}; |
|
|
|
jQuery.extend( jQuery.event, { |
|
|
|
trigger: function( event, data, elem, onlyHandlers ) { |
|
|
|
var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, |
|
eventPath = [ elem || document ], |
|
type = hasOwn.call( event, "type" ) ? event.type : event, |
|
namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; |
|
|
|
cur = lastElement = tmp = elem = elem || document; |
|
|
|
// Don't do events on text and comment nodes |
|
if ( elem.nodeType === 3 || elem.nodeType === 8 ) { |
|
return; |
|
} |
|
|
|
// focus/blur morphs to focusin/out; ensure we're not firing them right now |
|
if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { |
|
return; |
|
} |
|
|
|
if ( type.indexOf( "." ) > -1 ) { |
|
|
|
// Namespaced trigger; create a regexp to match event type in handle() |
|
namespaces = type.split( "." ); |
|
type = namespaces.shift(); |
|
namespaces.sort(); |
|
} |
|
ontype = type.indexOf( ":" ) < 0 && "on" + type; |
|
|
|
// Caller can pass in a jQuery.Event object, Object, or just an event type string |
|
event = event[ jQuery.expando ] ? |
|
event : |
|
new jQuery.Event( type, typeof event === "object" && event ); |
|
|
|
// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) |
|
event.isTrigger = onlyHandlers ? 2 : 3; |
|
event.namespace = namespaces.join( "." ); |
|
event.rnamespace = event.namespace ? |
|
new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : |
|
null; |
|
|
|
// Clean up the event in case it is being reused |
|
event.result = undefined; |
|
if ( !event.target ) { |
|
event.target = elem; |
|
} |
|
|
|
// Clone any incoming data and prepend the event, creating the handler arg list |
|
data = data == null ? |
|
[ event ] : |
|
jQuery.makeArray( data, [ event ] ); |
|
|
|
// Allow special events to draw outside the lines |
|
special = jQuery.event.special[ type ] || {}; |
|
if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { |
|
return; |
|
} |
|
|
|
// Determine event propagation path in advance, per W3C events spec (#9951) |
|
// Bubble up to document, then to window; watch for a global ownerDocument var (#9724) |
|
if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { |
|
|
|
bubbleType = special.delegateType || type; |
|
if ( !rfocusMorph.test( bubbleType + type ) ) { |
|
cur = cur.parentNode; |
|
} |
|
for ( ; cur; cur = cur.parentNode ) { |
|
eventPath.push( cur ); |
|
tmp = cur; |
|
} |
|
|
|
// Only add window if we got to document (e.g., not plain obj or detached DOM) |
|
if ( tmp === ( elem.ownerDocument || document ) ) { |
|
eventPath.push( tmp.defaultView || tmp.parentWindow || window ); |
|
} |
|
} |
|
|
|
// Fire handlers on the event path |
|
i = 0; |
|
while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { |
|
lastElement = cur; |
|
event.type = i > 1 ? |
|
bubbleType : |
|
special.bindType || type; |
|
|
|
// jQuery handler |
|
handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] && |
|
dataPriv.get( cur, "handle" ); |
|
if ( handle ) { |
|
handle.apply( cur, data ); |
|
} |
|
|
|
// Native handler |
|
handle = ontype && cur[ ontype ]; |
|
if ( handle && handle.apply && acceptData( cur ) ) { |
|
event.result = handle.apply( cur, data ); |
|
if ( event.result === false ) { |
|
event.preventDefault(); |
|
} |
|
} |
|
} |
|
event.type = type; |
|
|
|
// If nobody prevented the default action, do it now |
|
if ( !onlyHandlers && !event.isDefaultPrevented() ) { |
|
|
|
if ( ( !special._default || |
|
special._default.apply( eventPath.pop(), data ) === false ) && |
|
acceptData( elem ) ) { |
|
|
|
// Call a native DOM method on the target with the same name as the event. |
|
// Don't do default actions on window, that's where global variables be (#6170) |
|
if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { |
|
|
|
// Don't re-trigger an onFOO event when we call its FOO() method |
|
tmp = elem[ ontype ]; |
|
|
|
if ( tmp ) { |
|
elem[ ontype ] = null; |
|
} |
|
|
|
// Prevent re-triggering of the same event, since we already bubbled it above |
|
jQuery.event.triggered = type; |
|
|
|
if ( event.isPropagationStopped() ) { |
|
lastElement.addEventListener( type, stopPropagationCallback ); |
|
} |
|
|
|
elem[ type ](); |
|
|
|
if ( event.isPropagationStopped() ) { |
|
lastElement.removeEventListener( type, stopPropagationCallback ); |
|
} |
|
|
|
jQuery.event.triggered = undefined; |
|
|
|
if ( tmp ) { |
|
elem[ ontype ] = tmp; |
|
} |
|
} |
|
} |
|
} |
|
|
|
return event.result; |
|
}, |
|
|
|
// Piggyback on a donor event to simulate a different one |
|
// Used only for `focus(in | out)` events |
|
simulate: function( type, elem, event ) { |
|
var e = jQuery.extend( |
|
new jQuery.Event(), |
|
event, |
|
{ |
|
type: type, |
|
isSimulated: true |
|
} |
|
); |
|
|
|
jQuery.event.trigger( e, null, elem ); |
|
} |
|
|
|
} ); |
|
|
|
jQuery.fn.extend( { |
|
|
|
trigger: function( type, data ) { |
|
return this.each( function() { |
|
jQuery.event.trigger( type, data, this ); |
|
} ); |
|
}, |
|
triggerHandler: function( type, data ) { |
|
var elem = this[ 0 ]; |
|
if ( elem ) { |
|
return jQuery.event.trigger( type, data, elem, true ); |
|
} |
|
} |
|
} ); |
|
|
|
|
|
// Support: Firefox <=44 |
|
// Firefox doesn't have focus(in | out) events |
|
// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 |
|
// |
|
// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 |
|
// focus(in | out) events fire after focus & blur events, |
|
// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order |
|
// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 |
|
if ( !support.focusin ) { |
|
jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { |
|
|
|
// Attach a single capturing handler on the document while someone wants focusin/focusout |
|
var handler = function( event ) { |
|
jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); |
|
}; |
|
|
|
jQuery.event.special[ fix ] = { |
|
setup: function() { |
|
var doc = this.ownerDocument || this, |
|
attaches = dataPriv.access( doc, fix ); |
|
|
|
if ( !attaches ) { |
|
doc.addEventListener( orig, handler, true ); |
|
} |
|
dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); |
|
}, |
|
teardown: function() { |
|
var doc = this.ownerDocument || this, |
|
attaches = dataPriv.access( doc, fix ) - 1; |
|
|
|
if ( !attaches ) { |
|
doc.removeEventListener( orig, handler, true ); |
|
dataPriv.remove( doc, fix ); |
|
|
|
} else { |
|
dataPriv.access( doc, fix, attaches ); |
|
} |
|
} |
|
}; |
|
} ); |
|
} |
|
var location = window.location; |
|
|
|
var nonce = Date.now(); |
|
|
|
var rquery = ( /\?/ ); |
|
|
|
|
|
|
|
// Cross-browser xml parsing |
|
jQuery.parseXML = function( data ) { |
|
var xml; |
|
if ( !data || typeof data !== "string" ) { |
|
return null; |
|
} |
|
|
|
// Support: IE 9 - 11 only |
|
// IE throws on parseFromString with invalid input. |
|
try { |
|
xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); |
|
} catch ( e ) { |
|
xml = undefined; |
|
} |
|
|
|
if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { |
|
jQuery.error( "Invalid XML: " + data ); |
|
} |
|
return xml; |
|
}; |
|
|
|
|
|
var |
|
rbracket = /\[\]$/, |
|
rCRLF = /\r?\n/g, |
|
rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, |
|
rsubmittable = /^(?:input|select|textarea|keygen)/i; |
|
|
|
function buildParams( prefix, obj, traditional, add ) { |
|
var name; |
|
|
|
if ( Array.isArray( obj ) ) { |
|
|
|
// Serialize array item. |
|
jQuery.each( obj, function( i, v ) { |
|
if ( traditional || rbracket.test( prefix ) ) { |
|
|
|
// Treat each array item as a scalar. |
|
add( prefix, v ); |
|
|
|
} else { |
|
|
|
// Item is non-scalar (array or object), encode its numeric index. |
|
buildParams( |
|
prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", |
|
v, |
|
traditional, |
|
add |
|
); |
|
} |
|
} ); |
|
|
|
} else if ( !traditional && toType( obj ) === "object" ) { |
|
|
|
// Serialize object item. |
|
for ( name in obj ) { |
|
buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); |
|
} |
|
|
|
} else { |
|
|
|
// Serialize scalar item. |
|
add( prefix, obj ); |
|
} |
|
} |
|
|
|
// Serialize an array of form elements or a set of |
|
// key/values into a query string |
|
jQuery.param = function( a, traditional ) { |
|
var prefix, |
|
s = [], |
|
add = function( key, valueOrFunction ) { |
|
|
|
// If value is a function, invoke it and use its return value |
|
var value = isFunction( valueOrFunction ) ? |
|
valueOrFunction() : |
|
valueOrFunction; |
|
|
|
s[ s.length ] = encodeURIComponent( key ) + "=" + |
|
encodeURIComponent( value == null ? "" : value ); |
|
}; |
|
|
|
// If an array was passed in, assume that it is an array of form elements. |
|
if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { |
|
|
|
// Serialize the form elements |
|
jQuery.each( a, function() { |
|
add( this.name, this.value ); |
|
} ); |
|
|
|
} else { |
|
|
|
// If traditional, encode the "old" way (the way 1.3.2 or older |
|
// did it), otherwise encode params recursively. |
|
for ( prefix in a ) { |
|
buildParams( prefix, a[ prefix ], traditional, add ); |
|
} |
|
} |
|
|
|
// Return the resulting serialization |
|
return s.join( "&" ); |
|
}; |
|
|
|
jQuery.fn.extend( { |
|
serialize: function() { |
|
return jQuery.param( this.serializeArray() ); |
|
}, |
|
serializeArray: function() { |
|
return this.map( function() { |
|
|
|
// Can add propHook for "elements" to filter or add form elements |
|
var elements = jQuery.prop( this, "elements" ); |
|
return elements ? jQuery.makeArray( elements ) : this; |
|
} ) |
|
.filter( function() { |
|
var type = this.type; |
|
|
|
// Use .is( ":disabled" ) so that fieldset[disabled] works |
|
return this.name && !jQuery( this ).is( ":disabled" ) && |
|
rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && |
|
( this.checked || !rcheckableType.test( type ) ); |
|
} ) |
|
.map( function( i, elem ) { |
|
var val = jQuery( this ).val(); |
|
|
|
if ( val == null ) { |
|
return null; |
|
} |
|
|
|
if ( Array.isArray( val ) ) { |
|
return jQuery.map( val, function( val ) { |
|
return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; |
|
} ); |
|
} |
|
|
|
return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; |
|
} ).get(); |
|
} |
|
} ); |
|
|
|
|
|
var |
|
r20 = /%20/g, |
|
rhash = /#.*$/, |
|
rantiCache = /([?&])_=[^&]*/, |
|
rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, |
|
|
|
// #7653, #8125, #8152: local protocol detection |
|
rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, |
|
rnoContent = /^(?:GET|HEAD)$/, |
|
rprotocol = /^\/\//, |
|
|
|
/* Prefilters |
|
* 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) |
|
* 2) These are called: |
|
* - BEFORE asking for a transport |
|
* - AFTER param serialization (s.data is a string if s.processData is true) |
|
* 3) key is the dataType |
|
* 4) the catchall symbol "*" can be used |
|
* 5) execution will start with transport dataType and THEN continue down to "*" if needed |
|
*/ |
|
prefilters = {}, |
|
|
|
/* Transports bindings |
|
* 1) key is the dataType |
|
* 2) the catchall symbol "*" can be used |
|
* 3) selection will start with transport dataType and THEN go to "*" if needed |
|
*/ |
|
transports = {}, |
|
|
|
// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression |
|
allTypes = "*/".concat( "*" ), |
|
|
|
// Anchor tag for parsing the document origin |
|
originAnchor = document.createElement( "a" ); |
|
originAnchor.href = location.href; |
|
|
|
// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport |
|
function addToPrefiltersOrTransports( structure ) { |
|
|
|
// dataTypeExpression is optional and defaults to "*" |
|
return function( dataTypeExpression, func ) { |
|
|
|
if ( typeof dataTypeExpression !== "string" ) { |
|
func = dataTypeExpression; |
|
dataTypeExpression = "*"; |
|
} |
|
|
|
var dataType, |
|
i = 0, |
|
dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; |
|
|
|
if ( isFunction( func ) ) { |
|
|
|
// For each dataType in the dataTypeExpression |
|
while ( ( dataType = dataTypes[ i++ ] ) ) { |
|
|
|
// Prepend if requested |
|
if ( dataType[ 0 ] === "+" ) { |
|
dataType = dataType.slice( 1 ) || "*"; |
|
( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); |
|
|
|
// Otherwise append |
|
} else { |
|
( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); |
|
} |
|
} |
|
} |
|
}; |
|
} |
|
|
|
// Base inspection function for prefilters and transports |
|
function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { |
|
|
|
var inspected = {}, |
|
seekingTransport = ( structure === transports ); |
|
|
|
function inspect( dataType ) { |
|
var selected; |
|
inspected[ dataType ] = true; |
|
jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { |
|
var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); |
|
if ( typeof dataTypeOrTransport === "string" && |
|
!seekingTransport && !inspected[ dataTypeOrTransport ] ) { |
|
|
|
options.dataTypes.unshift( dataTypeOrTransport ); |
|
inspect( dataTypeOrTransport ); |
|
return false; |
|
} else if ( seekingTransport ) { |
|
return !( selected = dataTypeOrTransport ); |
|
} |
|
} ); |
|
return selected; |
|
} |
|
|
|
return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); |
|
} |
|
|
|
// A special extend for ajax options |
|
// that takes "flat" options (not to be deep extended) |
|
// Fixes #9887 |
|
function ajaxExtend( target, src ) { |
|
var key, deep, |
|
flatOptions = jQuery.ajaxSettings.flatOptions || {}; |
|
|
|
for ( key in src ) { |
|
if ( src[ key ] !== undefined ) { |
|
( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; |
|
} |
|
} |
|
if ( deep ) { |
|
jQuery.extend( true, target, deep ); |
|
} |
|
|
|
return target; |
|
} |
|
|
|
/* Handles responses to an ajax request: |
|
* - finds the right dataType (mediates between content-type and expected dataType) |
|
* - returns the corresponding response |
|
*/ |
|
function ajaxHandleResponses( s, jqXHR, responses ) { |
|
|
|
var ct, type, finalDataType, firstDataType, |
|
contents = s.contents, |
|
dataTypes = s.dataTypes; |
|
|
|
// Remove auto dataType and get content-type in the process |
|
while ( dataTypes[ 0 ] === "*" ) { |
|
dataTypes.shift(); |
|
if ( ct === undefined ) { |
|
ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); |
|
} |
|
} |
|
|
|
// Check if we're dealing with a known content-type |
|
if ( ct ) { |
|
for ( type in contents ) { |
|
if ( contents[ type ] && contents[ type ].test( ct ) ) { |
|
dataTypes.unshift( type ); |
|
break; |
|
} |
|
} |
|
} |
|
|
|
// Check to see if we have a response for the expected dataType |
|
if ( dataTypes[ 0 ] in responses ) { |
|
finalDataType = dataTypes[ 0 ]; |
|
} else { |
|
|
|
// Try convertible dataTypes |
|
for ( type in responses ) { |
|
if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { |
|
finalDataType = type; |
|
break; |
|
} |
|
if ( !firstDataType ) { |
|
firstDataType = type; |
|
} |
|
} |
|
|
|
// Or just use first one |
|
finalDataType = finalDataType || firstDataType; |
|
} |
|
|
|
// If we found a dataType |
|
// We add the dataType to the list if needed |
|
// and return the corresponding response |
|
if ( finalDataType ) { |
|
if ( finalDataType !== dataTypes[ 0 ] ) { |
|
dataTypes.unshift( finalDataType ); |
|
} |
|
return responses[ finalDataType ]; |
|
} |
|
} |
|
|
|
/* Chain conversions given the request and the original response |
|
* Also sets the responseXXX fields on the jqXHR instance |
|
*/ |
|
function ajaxConvert( s, response, jqXHR, isSuccess ) { |
|
var conv2, current, conv, tmp, prev, |
|
converters = {}, |
|
|
|
// Work with a copy of dataTypes in case we need to modify it for conversion |
|
dataTypes = s.dataTypes.slice(); |
|
|
|
// Create converters map with lowercased keys |
|
if ( dataTypes[ 1 ] ) { |
|
for ( conv in s.converters ) { |
|
converters[ conv.toLowerCase() ] = s.converters[ conv ]; |
|
} |
|
} |
|
|
|
current = dataTypes.shift(); |
|
|
|
// Convert to each sequential dataType |
|
while ( current ) { |
|
|
|
if ( s.responseFields[ current ] ) { |
|
jqXHR[ s.responseFields[ current ] ] = response; |
|
} |
|
|
|
// Apply the dataFilter if provided |
|
if ( !prev && isSuccess && s.dataFilter ) { |
|
response = s.dataFilter( response, s.dataType ); |
|
} |
|
|
|
prev = current; |
|
current = dataTypes.shift(); |
|
|
|
if ( current ) { |
|
|
|
// There's only work to do if current dataType is non-auto |
|
if ( current === "*" ) { |
|
|
|
current = prev; |
|
|
|
// Convert response if prev dataType is non-auto and differs from current |
|
} else if ( prev !== "*" && prev !== current ) { |
|
|
|
// Seek a direct converter |
|
conv = converters[ prev + " " + current ] || converters[ "* " + current ]; |
|
|
|
// If none found, seek a pair |
|
if ( !conv ) { |
|
for ( conv2 in converters ) { |
|
|
|
// If conv2 outputs current |
|
tmp = conv2.split( " " ); |
|
if ( tmp[ 1 ] === current ) { |
|
|
|
// If prev can be converted to accepted input |
|
conv = converters[ prev + " " + tmp[ 0 ] ] || |
|
converters[ "* " + tmp[ 0 ] ]; |
|
if ( conv ) { |
|
|
|
// Condense equivalence converters |
|
if ( conv === true ) { |
|
conv = converters[ conv2 ]; |
|
|
|
// Otherwise, insert the intermediate dataType |
|
} else if ( converters[ conv2 ] !== true ) { |
|
current = tmp[ 0 ]; |
|
dataTypes.unshift( tmp[ 1 ] ); |
|
} |
|
break; |
|
} |
|
} |
|
} |
|
} |
|
|
|
// Apply converter (if not an equivalence) |
|
if ( conv !== true ) { |
|
|
|
// Unless errors are allowed to bubble, catch and return them |
|
if ( conv && s.throws ) { |
|
response = conv( response ); |
|
} else { |
|
try { |
|
response = conv( response ); |
|
} catch ( e ) { |
|
return { |
|
state: "parsererror", |
|
error: conv ? e : "No conversion from " + prev + " to " + current |
|
}; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
return { state: "success", data: response }; |
|
} |
|
|
|
jQuery.extend( { |
|
|
|
// Counter for holding the number of active queries |
|
active: 0, |
|
|
|
// Last-Modified header cache for next request |
|
lastModified: {}, |
|
etag: {}, |
|
|
|
ajaxSettings: { |
|
url: location.href, |
|
type: "GET", |
|
isLocal: rlocalProtocol.test( location.protocol ), |
|
global: true, |
|
processData: true, |
|
async: true, |
|
contentType: "application/x-www-form-urlencoded; charset=UTF-8", |
|
|
|
/* |
|
timeout: 0, |
|
data: null, |
|
dataType: null, |
|
username: null, |
|
password: null, |
|
cache: null, |
|
throws: false, |
|
traditional: false, |
|
headers: {}, |
|
*/ |
|
|
|
accepts: { |
|
"*": allTypes, |
|
text: "text/plain", |
|
html: "text/html", |
|
xml: "application/xml, text/xml", |
|
json: "application/json, text/javascript" |
|
}, |
|
|
|
contents: { |
|
xml: /\bxml\b/, |
|
html: /\bhtml/, |
|
json: /\bjson\b/ |
|
}, |
|
|
|
responseFields: { |
|
xml: "responseXML", |
|
text: "responseText", |
|
json: "responseJSON" |
|
}, |
|
|
|
// Data converters |
|
// Keys separate source (or catchall "*") and destination types with a single space |
|
converters: { |
|
|
|
// Convert anything to text |
|
"* text": String, |
|
|
|
// Text to html (true = no transformation) |
|
"text html": true, |
|
|
|
// Evaluate text as a json expression |
|
"text json": JSON.parse, |
|
|
|
// Parse text as xml |
|
"text xml": jQuery.parseXML |
|
}, |
|
|
|
// For options that shouldn't be deep extended: |
|
// you can add your own custom options here if |
|
// and when you create one that shouldn't be |
|
// deep extended (see ajaxExtend) |
|
flatOptions: { |
|
url: true, |
|
context: true |
|
} |
|
}, |
|
|
|
// Creates a full fledged settings object into target |
|
// with both ajaxSettings and settings fields. |
|
// If target is omitted, writes into ajaxSettings. |
|
ajaxSetup: function( target, settings ) { |
|
return settings ? |
|
|
|
// Building a settings object |
|
ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : |
|
|
|
// Extending ajaxSettings |
|
ajaxExtend( jQuery.ajaxSettings, target ); |
|
}, |
|
|
|
ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), |
|
ajaxTransport: addToPrefiltersOrTransports( transports ), |
|
|
|
// Main method |
|
ajax: function( url, options ) { |
|
|
|
// If url is an object, simulate pre-1.5 signature |
|
if ( typeof url === "object" ) { |
|
options = url; |
|
url = undefined; |
|
} |
|
|
|
// Force options to be an object |
|
options = options || {}; |
|
|
|
var transport, |
|
|
|
// URL without anti-cache param |
|
cacheURL, |
|
|
|
// Response headers |
|
responseHeadersString, |
|
responseHeaders, |
|
|
|
// timeout handle |
|
timeoutTimer, |
|
|
|
// Url cleanup var |
|
urlAnchor, |
|
|
|
// Request state (becomes false upon send and true upon completion) |
|
completed, |
|
|
|
// To know if global events are to be dispatched |
|
fireGlobals, |
|
|
|
// Loop variable |
|
i, |
|
|
|
// uncached part of the url |
|
uncached, |
|
|
|
// Create the final options object |
|
s = jQuery.ajaxSetup( {}, options ), |
|
|
|
// Callbacks context |
|
callbackContext = s.context || s, |
|
|
|
// Context for global events is callbackContext if it is a DOM node or jQuery collection |
|
globalEventContext = s.context && |
|
( callbackContext.nodeType || callbackContext.jquery ) ? |
|
jQuery( callbackContext ) : |
|
jQuery.event, |
|
|
|
// Deferreds |
|
deferred = jQuery.Deferred(), |
|
completeDeferred = jQuery.Callbacks( "once memory" ), |
|
|
|
// Status-dependent callbacks |
|
statusCode = s.statusCode || {}, |
|
|
|
// Headers (they are sent all at once) |
|
requestHeaders = {}, |
|
requestHeadersNames = {}, |
|
|
|
// Default abort message |
|
strAbort = "canceled", |
|
|
|
// Fake xhr |
|
jqXHR = { |
|
readyState: 0, |
|
|
|
// Builds headers hashtable if needed |
|
getResponseHeader: function( key ) { |
|
var match; |
|
if ( completed ) { |
|
if ( !responseHeaders ) { |
|
responseHeaders = {}; |
|
while ( ( match = rheaders.exec( responseHeadersString ) ) ) { |
|
responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ]; |
|
} |
|
} |
|
match = responseHeaders[ key.toLowerCase() ]; |
|
} |
|
return match == null ? null : match; |
|
}, |
|
|
|
// Raw string |
|
getAllResponseHeaders: function() { |
|
return completed ? responseHeadersString : null; |
|
}, |
|
|
|
// Caches the header |
|
setRequestHeader: function( name, value ) { |
|
if ( completed == null ) { |
|
name = requestHeadersNames[ name.toLowerCase() ] = |
|
requestHeadersNames[ name.toLowerCase() ] || name; |
|
requestHeaders[ name ] = value; |
|
} |
|
return this; |
|
}, |
|
|
|
// Overrides response content-type header |
|
overrideMimeType: function( type ) { |
|
if ( completed == null ) { |
|
s.mimeType = type; |
|
} |
|
return this; |
|
}, |
|
|
|
// Status-dependent callbacks |
|
statusCode: function( map ) { |
|
var code; |
|
if ( map ) { |
|
if ( completed ) { |
|
|
|
// Execute the appropriate callbacks |
|
jqXHR.always( map[ jqXHR.status ] ); |
|
} else { |
|
|
|
// Lazy-add the new callbacks in a way that preserves old ones |
|
for ( code in map ) { |
|
statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; |
|
} |
|
} |
|
} |
|
return this; |
|
}, |
|
|
|
// Cancel the request |
|
abort: function( statusText ) { |
|
var finalText = statusText || strAbort; |
|
if ( transport ) { |
|
transport.abort( finalText ); |
|
} |
|
done( 0, finalText ); |
|
return this; |
|
} |
|
}; |
|
|
|
// Attach deferreds |
|
deferred.promise( jqXHR ); |
|
|
|
// Add protocol if not provided (prefilters might expect it) |
|
// Handle falsy url in the settings object (#10093: consistency with old signature) |
|
// We also use the url parameter if available |
|
s.url = ( ( url || s.url || location.href ) + "" ) |
|
.replace( rprotocol, location.protocol + "//" ); |
|
|
|
// Alias method option to type as per ticket #12004 |
|
s.type = options.method || options.type || s.method || s.type; |
|
|
|
// Extract dataTypes list |
|
s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; |
|
|
|
// A cross-domain request is in order when the origin doesn't match the current origin. |
|
if ( s.crossDomain == null ) { |
|
urlAnchor = document.createElement( "a" ); |
|
|
|
// Support: IE <=8 - 11, Edge 12 - 15 |
|
// IE throws exception on accessing the href property if url is malformed, |
|
// e.g. http://example.com:80x/ |
|
try { |
|
urlAnchor.href = s.url; |
|
|
|
// Support: IE <=8 - 11 only |
|
// Anchor's host property isn't correctly set when s.url is relative |
|
urlAnchor.href = urlAnchor.href; |
|
s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== |
|
urlAnchor.protocol + "//" + urlAnchor.host; |
|
} catch ( e ) { |
|
|
|
// If there is an error parsing the URL, assume it is crossDomain, |
|
// it can be rejected by the transport if it is invalid |
|
s.crossDomain = true; |
|
} |
|
} |
|
|
|
// Convert data if not already a string |
|
if ( s.data && s.processData && typeof s.data !== "string" ) { |
|
s.data = jQuery.param( s.data, s.traditional ); |
|
} |
|
|
|
// Apply prefilters |
|
inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); |
|
|
|
// If request was aborted inside a prefilter, stop there |
|
if ( completed ) { |
|
return jqXHR; |
|
} |
|
|
|
// We can fire global events as of now if asked to |
|
// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) |
|
fireGlobals = jQuery.event && s.global; |
|
|
|
// Watch for a new set of requests |
|
if ( fireGlobals && jQuery.active++ === 0 ) { |
|
jQuery.event.trigger( "ajaxStart" ); |
|
} |
|
|
|
// Uppercase the type |
|
s.type = s.type.toUpperCase(); |
|
|
|
// Determine if request has content |
|
s.hasContent = !rnoContent.test( s.type ); |
|
|
|
// Save the URL in case we're toying with the If-Modified-Since |
|
// and/or If-None-Match header later on |
|
// Remove hash to simplify url manipulation |
|
cacheURL = s.url.replace( rhash, "" ); |
|
|
|
// More options handling for requests with no content |
|
if ( !s.hasContent ) { |
|
|
|
// Remember the hash so we can put it back |
|
uncached = s.url.slice( cacheURL.length ); |
|
|
|
// If data is available and should be processed, append data to url |
|
if ( s.data && ( s.processData || typeof s.data === "string" ) ) { |
|
cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; |
|
|
|
// #9682: remove data so that it's not used in an eventual retry |
|
delete s.data; |
|
} |
|
|
|
// Add or update anti-cache param if needed |
|
if ( s.cache === false ) { |
|
cacheURL = cacheURL.replace( rantiCache, "$1" ); |
|
uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached; |
|
} |
|
|
|
// Put hash and anti-cache on the URL that will be requested (gh-1732) |
|
s.url = cacheURL + uncached; |
|
|
|
// Change '%20' to '+' if this is encoded form body content (gh-2658) |
|
} else if ( s.data && s.processData && |
|
( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { |
|
s.data = s.data.replace( r20, "+" ); |
|
} |
|
|
|
// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. |
|
if ( s.ifModified ) { |
|
if ( jQuery.lastModified[ cacheURL ] ) { |
|
jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); |
|
} |
|
if ( jQuery.etag[ cacheURL ] ) { |
|
jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); |
|
} |
|
} |
|
|
|
// Set the correct header, if data is being sent |
|
if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { |
|
jqXHR.setRequestHeader( "Content-Type", s.contentType ); |
|
} |
|
|
|
// Set the Accepts header for the server, depending on the dataType |
|
jqXHR.setRequestHeader( |
|
"Accept", |
|
s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? |
|
s.accepts[ s.dataTypes[ 0 ] ] + |
|
( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : |
|
s.accepts[ "*" ] |
|
); |
|
|
|
// Check for headers option |
|
for ( i in s.headers ) { |
|
jqXHR.setRequestHeader( i, s.headers[ i ] ); |
|
} |
|
|
|
// Allow custom headers/mimetypes and early abort |
|
if ( s.beforeSend && |
|
( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { |
|
|
|
// Abort if not done already and return |
|
return jqXHR.abort(); |
|
} |
|
|
|
// Aborting is no longer a cancellation |
|
strAbort = "abort"; |
|
|
|
// Install callbacks on deferreds |
|
completeDeferred.add( s.complete ); |
|
jqXHR.done( s.success ); |
|
jqXHR.fail( s.error ); |
|
|
|
// Get transport |
|
transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); |
|
|
|
// If no transport, we auto-abort |
|
if ( !transport ) { |
|
done( -1, "No Transport" ); |
|
} else { |
|
jqXHR.readyState = 1; |
|
|
|
// Send global event |
|
if ( fireGlobals ) { |
|
globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); |
|
} |
|
|
|
// If request was aborted inside ajaxSend, stop there |
|
if ( completed ) { |
|
return jqXHR; |
|
} |
|
|
|
// Timeout |
|
if ( s.async && s.timeout > 0 ) { |
|
timeoutTimer = window.setTimeout( function() { |
|
jqXHR.abort( "timeout" ); |
|
}, s.timeout ); |
|
} |
|
|
|
try { |
|
completed = false; |
|
transport.send( requestHeaders, done ); |
|
} catch ( e ) { |
|
|
|
// Rethrow post-completion exceptions |
|
if ( completed ) { |
|
throw e; |
|
} |
|
|
|
// Propagate others as results |
|
done( -1, e ); |
|
} |
|
} |
|
|
|
// Callback for when everything is done |
|
function done( status, nativeStatusText, responses, headers ) { |
|
var isSuccess, success, error, response, modified, |
|
statusText = nativeStatusText; |
|
|
|
// Ignore repeat invocations |
|
if ( completed ) { |
|
return; |
|
} |
|
|
|
completed = true; |
|
|
|
// Clear timeout if it exists |
|
if ( timeoutTimer ) { |
|
window.clearTimeout( timeoutTimer ); |
|
} |
|
|
|
// Dereference transport for early garbage collection |
|
// (no matter how long the jqXHR object will be used) |
|
transport = undefined; |
|
|
|
// Cache response headers |
|
responseHeadersString = headers || ""; |
|
|
|
// Set readyState |
|
jqXHR.readyState = status > 0 ? 4 : 0; |
|
|
|
// Determine if successful |
|
isSuccess = status >= 200 && status < 300 || status === 304; |
|
|
|
// Get response data |
|
if ( responses ) { |
|
response = ajaxHandleResponses( s, jqXHR, responses ); |
|
} |
|
|
|
// Convert no matter what (that way responseXXX fields are always set) |
|
response = ajaxConvert( s, response, jqXHR, isSuccess ); |
|
|
|
// If successful, handle type chaining |
|
if ( isSuccess ) { |
|
|
|
// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. |
|
if ( s.ifModified ) { |
|
modified = jqXHR.getResponseHeader( "Last-Modified" ); |
|
if ( modified ) { |
|
jQuery.lastModified[ cacheURL ] = modified; |
|
} |
|
modified = jqXHR.getResponseHeader( "etag" ); |
|
if ( modified ) { |
|
jQuery.etag[ cacheURL ] = modified; |
|
} |
|
} |
|
|
|
// if no content |
|
if ( status === 204 || s.type === "HEAD" ) { |
|
statusText = "nocontent"; |
|
|
|
// if not modified |
|
} else if ( status === 304 ) { |
|
statusText = "notmodified"; |
|
|
|
// If we have data, let's convert it |
|
} else { |
|
statusText = response.state; |
|
success = response.data; |
|
error = response.error; |
|
isSuccess = !error; |
|
} |
|
} else { |
|
|
|
// Extract error from statusText and normalize for non-aborts |
|
error = statusText; |
|
if ( status || !statusText ) { |
|
statusText = "error"; |
|
if ( status < 0 ) { |
|
status = 0; |
|
} |
|
} |
|
} |
|
|
|
// Set data for the fake xhr object |
|
jqXHR.status = status; |
|
jqXHR.statusText = ( nativeStatusText || statusText ) + ""; |
|
|
|
// Success/Error |
|
if ( isSuccess ) { |
|
deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); |
|
} else { |
|
deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); |
|
} |
|
|
|
// Status-dependent callbacks |
|
jqXHR.statusCode( statusCode ); |
|
statusCode = undefined; |
|
|
|
if ( fireGlobals ) { |
|
globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", |
|
[ jqXHR, s, isSuccess ? success : error ] ); |
|
} |
|
|
|
// Complete |
|
completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); |
|
|
|
if ( fireGlobals ) { |
|
globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); |
|
|
|
// Handle the global AJAX counter |
|
if ( !( --jQuery.active ) ) { |
|
jQuery.event.trigger( "ajaxStop" ); |
|
} |
|
} |
|
} |
|
|
|
return jqXHR; |
|
}, |
|
|
|
getJSON: function( url, data, callback ) { |
|
return jQuery.get( url, data, callback, "json" ); |
|
}, |
|
|
|
getScript: function( url, callback ) { |
|
return jQuery.get( url, undefined, callback, "script" ); |
|
} |
|
} ); |
|
|
|
jQuery.each( [ "get", "post" ], function( i, method ) { |
|
jQuery[ method ] = function( url, data, callback, type ) { |
|
|
|
// Shift arguments if data argument was omitted |
|
if ( isFunction( data ) ) { |
|
type = type || callback; |
|
callback = data; |
|
data = undefined; |
|
} |
|
|
|
// The url can be an options object (which then must have .url) |
|
return jQuery.ajax( jQuery.extend( { |
|
url: url, |
|
type: method, |
|
dataType: type, |
|
data: data, |
|
success: callback |
|
}, jQuery.isPlainObject( url ) && url ) ); |
|
}; |
|
} ); |
|
|
|
|
|
jQuery._evalUrl = function( url ) { |
|
return jQuery.ajax( { |
|
url: url, |
|
|
|
// Make this explicit, since user can override this through ajaxSetup (#11264) |
|
type: "GET", |
|
dataType: "script", |
|
cache: true, |
|
async: false, |
|
global: false, |
|
"throws": true |
|
} ); |
|
}; |
|
|
|
|
|
jQuery.fn.extend( { |
|
wrapAll: function( html ) { |
|
var wrap; |
|
|
|
if ( this[ 0 ] ) { |
|
if ( isFunction( html ) ) { |
|
html = html.call( this[ 0 ] ); |
|
} |
|
|
|
// The elements to wrap the target around |
|
wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); |
|
|
|
if ( this[ 0 ].parentNode ) { |
|
wrap.insertBefore( this[ 0 ] ); |
|
} |
|
|
|
wrap.map( function() { |
|
var elem = this; |
|
|
|
while ( elem.firstElementChild ) { |
|
elem = elem.firstElementChild; |
|
} |
|
|
|
return elem; |
|
} ).append( this ); |
|
} |
|
|
|
return this; |
|
}, |
|
|
|
wrapInner: function( html ) { |
|
if ( isFunction( html ) ) { |
|
return this.each( function( i ) { |
|
jQuery( this ).wrapInner( html.call( this, i ) ); |
|
} ); |
|
} |
|
|
|
return this.each( function() { |
|
var self = jQuery( this ), |
|
contents = self.contents(); |
|
|
|
if ( contents.length ) { |
|
contents.wrapAll( html ); |
|
|
|
} else { |
|
self.append( html ); |
|
} |
|
} ); |
|
}, |
|
|
|
wrap: function( html ) { |
|
var htmlIsFunction = isFunction( html ); |
|
|
|
return this.each( function( i ) { |
|
jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); |
|
} ); |
|
}, |
|
|
|
unwrap: function( selector ) { |
|
this.parent( selector ).not( "body" ).each( function() { |
|
jQuery( this ).replaceWith( this.childNodes ); |
|
} ); |
|
return this; |
|
} |
|
} ); |
|
|
|
|
|
jQuery.expr.pseudos.hidden = function( elem ) { |
|
return !jQuery.expr.pseudos.visible( elem ); |
|
}; |
|
jQuery.expr.pseudos.visible = function( elem ) { |
|
return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); |
|
}; |
|
|
|
|
|
|
|
|
|
jQuery.ajaxSettings.xhr = function() { |
|
try { |
|
return new window.XMLHttpRequest(); |
|
} catch ( e ) {} |
|
}; |
|
|
|
var xhrSuccessStatus = { |
|
|
|
// File protocol always yields status code 0, assume 200 |
|
0: 200, |
|
|
|
// Support: IE <=9 only |
|
// #1450: sometimes IE returns 1223 when it should be 204 |
|
1223: 204 |
|
}, |
|
xhrSupported = jQuery.ajaxSettings.xhr(); |
|
|
|
support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); |
|
support.ajax = xhrSupported = !!xhrSupported; |
|
|
|
jQuery.ajaxTransport( function( options ) { |
|
var callback, errorCallback; |
|
|
|
// Cross domain only allowed if supported through XMLHttpRequest |
|
if ( support.cors || xhrSupported && !options.crossDomain ) { |
|
return { |
|
send: function( headers, complete ) { |
|
var i, |
|
xhr = options.xhr(); |
|
|
|
xhr.open( |
|
options.type, |
|
options.url, |
|
options.async, |
|
options.username, |
|
options.password |
|
); |
|
|
|
// Apply custom fields if provided |
|
if ( options.xhrFields ) { |
|
for ( i in options.xhrFields ) { |
|
xhr[ i ] = options.xhrFields[ i ]; |
|
} |
|
} |
|
|
|
// Override mime type if needed |
|
if ( options.mimeType && xhr.overrideMimeType ) { |
|
xhr.overrideMimeType( options.mimeType ); |
|
} |
|
|
|
// X-Requested-With header |
|
// For cross-domain requests, seeing as conditions for a preflight are |
|
// akin to a jigsaw puzzle, we simply never set it to be sure. |
|
// (it can always be set on a per-request basis or even using ajaxSetup) |
|
// For same-domain requests, won't change header if already provided. |
|
if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { |
|
headers[ "X-Requested-With" ] = "XMLHttpRequest"; |
|
} |
|
|
|
// Set headers |
|
for ( i in headers ) { |
|
xhr.setRequestHeader( i, headers[ i ] ); |
|
} |
|
|
|
// Callback |
|
callback = function( type ) { |
|
return function() { |
|
if ( callback ) { |
|
callback = errorCallback = xhr.onload = |
|
xhr.onerror = xhr.onabort = xhr.ontimeout = |
|
xhr.onreadystatechange = null; |
|
|
|
if ( type === "abort" ) { |
|
xhr.abort(); |
|
} else if ( type === "error" ) { |
|
|
|
// Support: IE <=9 only |
|
// On a manual native abort, IE9 throws |
|
// errors on any property access that is not readyState |
|
if ( typeof xhr.status !== "number" ) { |
|
complete( 0, "error" ); |
|
} else { |
|
complete( |
|
|
|
// File: protocol always yields status 0; see #8605, #14207 |
|
xhr.status, |
|
xhr.statusText |
|
); |
|
} |
|
} else { |
|
complete( |
|
xhrSuccessStatus[ xhr.status ] || xhr.status, |
|
xhr.statusText, |
|
|
|
// Support: IE <=9 only |
|
// IE9 has no XHR2 but throws on binary (trac-11426) |
|
// For XHR2 non-text, let the caller handle it (gh-2498) |
|
( xhr.responseType || "text" ) !== "text" || |
|
typeof xhr.responseText !== "string" ? |
|
{ binary: xhr.response } : |
|
{ text: xhr.responseText }, |
|
xhr.getAllResponseHeaders() |
|
); |
|
} |
|
} |
|
}; |
|
}; |
|
|
|
// Listen to events |
|
xhr.onload = callback(); |
|
errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); |
|
|
|
// Support: IE 9 only |
|
// Use onreadystatechange to replace onabort |
|
// to handle uncaught aborts |
|
if ( xhr.onabort !== undefined ) { |
|
xhr.onabort = errorCallback; |
|
} else { |
|
xhr.onreadystatechange = function() { |
|
|
|
// Check readyState before timeout as it changes |
|
if ( xhr.readyState === 4 ) { |
|
|
|
// Allow onerror to be called first, |
|
// but that will not handle a native abort |
|
// Also, save errorCallback to a variable |
|
// as xhr.onerror cannot be accessed |
|
window.setTimeout( function() { |
|
if ( callback ) { |
|
errorCallback(); |
|
} |
|
} ); |
|
} |
|
}; |
|
} |
|
|
|
// Create the abort callback |
|
callback = callback( "abort" ); |
|
|
|
try { |
|
|
|
// Do send the request (this may raise an exception) |
|
xhr.send( options.hasContent && options.data || null ); |
|
} catch ( e ) { |
|
|
|
// #14683: Only rethrow if this hasn't been notified as an error yet |
|
if ( callback ) { |
|
throw e; |
|
} |
|
} |
|
}, |
|
|
|
abort: function() { |
|
if ( callback ) { |
|
callback(); |
|
} |
|
} |
|
}; |
|
} |
|
} ); |
|
|
|
|
|
|
|
|
|
// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) |
|
jQuery.ajaxPrefilter( function( s ) { |
|
if ( s.crossDomain ) { |
|
s.contents.script = false; |
|
} |
|
} ); |
|
|
|
// Install script dataType |
|
jQuery.ajaxSetup( { |
|
accepts: { |
|
script: "text/javascript, application/javascript, " + |
|
"application/ecmascript, application/x-ecmascript" |
|
}, |
|
contents: { |
|
script: /\b(?:java|ecma)script\b/ |
|
}, |
|
converters: { |
|
"text script": function( text ) { |
|
jQuery.globalEval( text ); |
|
return text; |
|
} |
|
} |
|
} ); |
|
|
|
// Handle cache's special case and crossDomain |
|
jQuery.ajaxPrefilter( "script", function( s ) { |
|
if ( s.cache === undefined ) { |
|
s.cache = false; |
|
} |
|
if ( s.crossDomain ) { |
|
s.type = "GET"; |
|
} |
|
} ); |
|
|
|
// Bind script tag hack transport |
|
jQuery.ajaxTransport( "script", function( s ) { |
|
|
|
// This transport only deals with cross domain requests |
|
if ( s.crossDomain ) { |
|
var script, callback; |
|
return { |
|
send: function( _, complete ) { |
|
script = jQuery( "<script>" ).prop( { |
|
charset: s.scriptCharset, |
|
src: s.url |
|
} ).on( |
|
"load error", |
|
callback = function( evt ) { |
|
script.remove(); |
|
callback = null; |
|
if ( evt ) { |
|
complete( evt.type === "error" ? 404 : 200, evt.type ); |
|
} |
|
} |
|
); |
|
|
|
// Use native DOM manipulation to avoid our domManip AJAX trickery |
|
document.head.appendChild( script[ 0 ] ); |
|
}, |
|
abort: function() { |
|
if ( callback ) { |
|
callback(); |
|
} |
|
} |
|
}; |
|
} |
|
} ); |
|
|
|
|
|
|
|
|
|
var oldCallbacks = [], |
|
rjsonp = /(=)\?(?=&|$)|\?\?/; |
|
|
|
// Default jsonp settings |
|
jQuery.ajaxSetup( { |
|
jsonp: "callback", |
|
jsonpCallback: function() { |
|
var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); |
|
this[ callback ] = true; |
|
return callback; |
|
} |
|
} ); |
|
|
|
// Detect, normalize options and install callbacks for jsonp requests |
|
jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { |
|
|
|
var callbackName, overwritten, responseContainer, |
|
jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? |
|
"url" : |
|
typeof s.data === "string" && |
|
( s.contentType || "" ) |
|
.indexOf( "application/x-www-form-urlencoded" ) === 0 && |
|
rjsonp.test( s.data ) && "data" |
|
); |
|
|
|
// Handle iff the expected data type is "jsonp" or we have a parameter to set |
|
if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { |
|
|
|
// Get callback name, remembering preexisting value associated with it |
|
callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ? |
|
s.jsonpCallback() : |
|
s.jsonpCallback; |
|
|
|
// Insert callback into url or form data |
|
if ( jsonProp ) { |
|
s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); |
|
} else if ( s.jsonp !== false ) { |
|
s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; |
|
} |
|
|
|
// Use data converter to retrieve json after script execution |
|
s.converters[ "script json" ] = function() { |
|
if ( !responseContainer ) { |
|
jQuery.error( callbackName + " was not called" ); |
|
} |
|
return responseContainer[ 0 ]; |
|
}; |
|
|
|
// Force json dataType |
|
s.dataTypes[ 0 ] = "json"; |
|
|
|
// Install callback |
|
overwritten = window[ callbackName ]; |
|
window[ callbackName ] = function() { |
|
responseContainer = arguments; |
|
}; |
|
|
|
// Clean-up function (fires after converters) |
|
jqXHR.always( function() { |
|
|
|
// If previous value didn't exist - remove it |
|
if ( overwritten === undefined ) { |
|
jQuery( window ).removeProp( callbackName ); |
|
|
|
// Otherwise restore preexisting value |
|
} else { |
|
window[ callbackName ] = overwritten; |
|
} |
|
|
|
// Save back as free |
|
if ( s[ callbackName ] ) { |
|
|
|
// Make sure that re-using the options doesn't screw things around |
|
s.jsonpCallback = originalSettings.jsonpCallback; |
|
|
|
// Save the callback name for future use |
|
oldCallbacks.push( callbackName ); |
|
} |
|
|
|
// Call if it was a function and we have a response |
|
if ( responseContainer && isFunction( overwritten ) ) { |
|
overwritten( responseContainer[ 0 ] ); |
|
} |
|
|
|
responseContainer = overwritten = undefined; |
|
} ); |
|
|
|
// Delegate to script |
|
return "script"; |
|
} |
|
} ); |
|
|
|
|
|
|
|
|
|
// Support: Safari 8 only |
|
// In Safari 8 documents created via document.implementation.createHTMLDocument |
|
// collapse sibling forms: the second one becomes a child of the first one. |
|
// Because of that, this security measure has to be disabled in Safari 8. |
|
// https://bugs.webkit.org/show_bug.cgi?id=137337 |
|
support.createHTMLDocument = ( function() { |
|
var body = document.implementation.createHTMLDocument( "" ).body; |
|
body.innerHTML = "<form></form><form></form>"; |
|
return body.childNodes.length === 2; |
|
} )(); |
|
|
|
|
|
// Argument "data" should be string of html |
|
// context (optional): If specified, the fragment will be created in this context, |
|
// defaults to document |
|
// keepScripts (optional): If true, will include scripts passed in the html string |
|
jQuery.parseHTML = function( data, context, keepScripts ) { |
|
if ( typeof data !== "string" ) { |
|
return []; |
|
} |
|
if ( typeof context === "boolean" ) { |
|
keepScripts = context; |
|
context = false; |
|
} |
|
|
|
var base, parsed, scripts; |
|
|
|
if ( !context ) { |
|
|
|
// Stop scripts or inline event handlers from being executed immediately |
|
// by using document.implementation |
|
if ( support.createHTMLDocument ) { |
|
context = document.implementation.createHTMLDocument( "" ); |
|
|
|
// Set the base href for the created document |
|
// so any parsed elements with URLs |
|
// are based on the document's URL (gh-2965) |
|
base = context.createElement( "base" ); |
|
base.href = document.location.href; |
|
context.head.appendChild( base ); |
|
} else { |
|
context = document; |
|
} |
|
} |
|
|
|
parsed = rsingleTag.exec( data ); |
|
scripts = !keepScripts && []; |
|
|
|
// Single tag |
|
if ( parsed ) { |
|
return [ context.createElement( parsed[ 1 ] ) ]; |
|
} |
|
|
|
parsed = buildFragment( [ data ], context, scripts ); |
|
|
|
if ( scripts && scripts.length ) { |
|
jQuery( scripts ).remove(); |
|
} |
|
|
|
return jQuery.merge( [], parsed.childNodes ); |
|
}; |
|
|
|
|
|
/** |
|
* Load a url into a page |
|
*/ |
|
jQuery.fn.load = function( url, params, callback ) { |
|
var selector, type, response, |
|
self = this, |
|
off = url.indexOf( " " ); |
|
|
|
if ( off > -1 ) { |
|
selector = stripAndCollapse( url.slice( off ) ); |
|
url = url.slice( 0, off ); |
|
} |
|
|
|
// If it's a function |
|
if ( isFunction( params ) ) { |
|
|
|
// We assume that it's the callback |
|
callback = params; |
|
params = undefined; |
|
|
|
// Otherwise, build a param string |
|
} else if ( params && typeof params === "object" ) { |
|
type = "POST"; |
|
} |
|
|
|
// If we have elements to modify, make the request |
|
if ( self.length > 0 ) { |
|
jQuery.ajax( { |
|
url: url, |
|
|
|
// If "type" variable is undefined, then "GET" method will be used. |
|
// Make value of this field explicit since |
|
// user can override it through ajaxSetup method |
|
type: type || "GET", |
|
dataType: "html", |
|
data: params |
|
} ).done( function( responseText ) { |
|
|
|
// Save response for use in complete callback |
|
response = arguments; |
|
|
|
self.html( selector ? |
|
|
|
// If a selector was specified, locate the right elements in a dummy div |
|
// Exclude scripts to avoid IE 'Permission Denied' errors |
|
jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) : |
|
|
|
// Otherwise use the full result |
|
responseText ); |
|
|
|
// If the request succeeds, this function gets "data", "status", "jqXHR" |
|
// but they are ignored because response was set above. |
|
// If it fails, this function gets "jqXHR", "status", "error" |
|
} ).always( callback && function( jqXHR, status ) { |
|
self.each( function() { |
|
callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] ); |
|
} ); |
|
} ); |
|
} |
|
|
|
return this; |
|
}; |
|
|
|
|
|
|
|
|
|
// Attach a bunch of functions for handling common AJAX events |
|
jQuery.each( [ |
|
"ajaxStart", |
|
"ajaxStop", |
|
"ajaxComplete", |
|
"ajaxError", |
|
"ajaxSuccess", |
|
"ajaxSend" |
|
], function( i, type ) { |
|
jQuery.fn[ type ] = function( fn ) { |
|
return this.on( type, fn ); |
|
}; |
|
} ); |
|
|
|
|
|
|
|
|
|
jQuery.expr.pseudos.animated = function( elem ) { |
|
return jQuery.grep( jQuery.timers, function( fn ) { |
|
return elem === fn.elem; |
|
} ).length; |
|
}; |
|
|
|
|
|
|
|
|
|
jQuery.offset = { |
|
setOffset: function( elem, options, i ) { |
|
var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, |
|
position = jQuery.css( elem, "position" ), |
|
curElem = jQuery( elem ), |
|
props = {}; |
|
|
|
// Set position first, in-case top/left are set even on static elem |
|
if ( position === "static" ) { |
|
elem.style.position = "relative"; |
|
} |
|
|
|
curOffset = curElem.offset(); |
|
curCSSTop = jQuery.css( elem, "top" ); |
|
curCSSLeft = jQuery.css( elem, "left" ); |
|
calculatePosition = ( position === "absolute" || position === "fixed" ) && |
|
( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1; |
|
|
|
// Need to be able to calculate position if either |
|
// top or left is auto and position is either absolute or fixed |
|
if ( calculatePosition ) { |
|
curPosition = curElem.position(); |
|
curTop = curPosition.top; |
|
curLeft = curPosition.left; |
|
|
|
} else { |
|
curTop = parseFloat( curCSSTop ) || 0; |
|
curLeft = parseFloat( curCSSLeft ) || 0; |
|
} |
|
|
|
if ( isFunction( options ) ) { |
|
|
|
// Use jQuery.extend here to allow modification of coordinates argument (gh-1848) |
|
options = options.call( elem, i, jQuery.extend( {}, curOffset ) ); |
|
} |
|
|
|
if ( options.top != null ) { |
|
props.top = ( options.top - curOffset.top ) + curTop; |
|
} |
|
if ( options.left != null ) { |
|
props.left = ( options.left - curOffset.left ) + curLeft; |
|
} |
|
|
|
if ( "using" in options ) { |
|
options.using.call( elem, props ); |
|
|
|
} else { |
|
curElem.css( props ); |
|
} |
|
} |
|
}; |
|
|
|
jQuery.fn.extend( { |
|
|
|
// offset() relates an element's border box to the document origin |
|
offset: function( options ) { |
|
|
|
// Preserve chaining for setter |
|
if ( arguments.length ) { |
|
return options === undefined ? |
|
this : |
|
this.each( function( i ) { |
|
jQuery.offset.setOffset( this, options, i ); |
|
} ); |
|
} |
|
|
|
var rect, win, |
|
elem = this[ 0 ]; |
|
|
|
if ( !elem ) { |
|
return; |
|
} |
|
|
|
// Return zeros for disconnected and hidden (display: none) elements (gh-2310) |
|
// Support: IE <=11 only |
|
// Running getBoundingClientRect on a |
|
// disconnected node in IE throws an error |
|
if ( !elem.getClientRects().length ) { |
|
return { top: 0, left: 0 }; |
|
} |
|
|
|
// Get document-relative position by adding viewport scroll to viewport-relative gBCR |
|
rect = elem.getBoundingClientRect(); |
|
win = elem.ownerDocument.defaultView; |
|
return { |
|
top: rect.top + win.pageYOffset, |
|
left: rect.left + win.pageXOffset |
|
}; |
|
}, |
|
|
|
// position() relates an element's margin box to its offset parent's padding box |
|
// This corresponds to the behavior of CSS absolute positioning |
|
position: function() { |
|
if ( !this[ 0 ] ) { |
|
return; |
|
} |
|
|
|
var offsetParent, offset, doc, |
|
elem = this[ 0 ], |
|
parentOffset = { top: 0, left: 0 }; |
|
|
|
// position:fixed elements are offset from the viewport, which itself always has zero offset |
|
if ( jQuery.css( elem, "position" ) === "fixed" ) { |
|
|
|
// Assume position:fixed implies availability of getBoundingClientRect |
|
offset = elem.getBoundingClientRect(); |
|
|
|
} else { |
|
offset = this.offset(); |
|
|
|
// Account for the *real* offset parent, which can be the document or its root element |
|
// when a statically positioned element is identified |
|
doc = elem.ownerDocument; |
|
offsetParent = elem.offsetParent || doc.documentElement; |
|
while ( offsetParent && |
|
( offsetParent === doc.body || offsetParent === doc.documentElement ) && |
|
jQuery.css( offsetParent, "position" ) === "static" ) { |
|
|
|
offsetParent = offsetParent.parentNode; |
|
} |
|
if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) { |
|
|
|
// Incorporate borders into its offset, since they are outside its content origin |
|
parentOffset = jQuery( offsetParent ).offset(); |
|
parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true ); |
|
parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true ); |
|
} |
|
} |
|
|
|
// Subtract parent offsets and element margins |
|
return { |
|
top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), |
|
left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true ) |
|
}; |
|
}, |
|
|
|
// This method will return documentElement in the following cases: |
|
// 1) For the element inside the iframe without offsetParent, this method will return |
|
// documentElement of the parent window |
|
// 2) For the hidden or detached element |
|
// 3) For body or html element, i.e. in case of the html node - it will return itself |
|
// |
|
// but those exceptions were never presented as a real life use-cases |
|
// and might be considered as more preferable results. |
|
// |
|
// This logic, however, is not guaranteed and can change at any point in the future |
|
offsetParent: function() { |
|
return this.map( function() { |
|
var offsetParent = this.offsetParent; |
|
|
|
while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) { |
|
offsetParent = offsetParent.offsetParent; |
|
} |
|
|
|
return offsetParent || documentElement; |
|
} ); |
|
} |
|
} ); |
|
|
|
// Create scrollLeft and scrollTop methods |
|
jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) { |
|
var top = "pageYOffset" === prop; |
|
|
|
jQuery.fn[ method ] = function( val ) { |
|
return access( this, function( elem, method, val ) { |
|
|
|
// Coalesce documents and windows |
|
var win; |
|
if ( isWindow( elem ) ) { |
|
win = elem; |
|
} else if ( elem.nodeType === 9 ) { |
|
win = elem.defaultView; |
|
} |
|
|
|
if ( val === undefined ) { |
|
return win ? win[ prop ] : elem[ method ]; |
|
} |
|
|
|
if ( win ) { |
|
win.scrollTo( |
|
!top ? val : win.pageXOffset, |
|
top ? val : win.pageYOffset |
|
); |
|
|
|
} else { |
|
elem[ method ] = val; |
|
} |
|
}, method, val, arguments.length ); |
|
}; |
|
} ); |
|
|
|
// Support: Safari <=7 - 9.1, Chrome <=37 - 49 |
|
// Add the top/left cssHooks using jQuery.fn.position |
|
// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 |
|
// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347 |
|
// getComputedStyle returns percent when specified for top/left/bottom/right; |
|
// rather than make the css module depend on the offset module, just check for it here |
|
jQuery.each( [ "top", "left" ], function( i, prop ) { |
|
jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, |
|
function( elem, computed ) { |
|
if ( computed ) { |
|
computed = curCSS( elem, prop ); |
|
|
|
// If curCSS returns percentage, fallback to offset |
|
return rnumnonpx.test( computed ) ? |
|
jQuery( elem ).position()[ prop ] + "px" : |
|
computed; |
|
} |
|
} |
|
); |
|
} ); |
|
|
|
|
|
// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods |
|
jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { |
|
jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, |
|
function( defaultExtra, funcName ) { |
|
|
|
// Margin is only for outerHeight, outerWidth |
|
jQuery.fn[ funcName ] = function( margin, value ) { |
|
var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), |
|
extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); |
|
|
|
return access( this, function( elem, type, value ) { |
|
var doc; |
|
|
|
if ( isWindow( elem ) ) { |
|
|
|
// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729) |
|
return funcName.indexOf( "outer" ) === 0 ? |
|
elem[ "inner" + name ] : |
|
elem.document.documentElement[ "client" + name ]; |
|
} |
|
|
|
// Get document width or height |
|
if ( elem.nodeType === 9 ) { |
|
doc = elem.documentElement; |
|
|
|
// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], |
|
// whichever is greatest |
|
return Math.max( |
|
elem.body[ "scroll" + name ], doc[ "scroll" + name ], |
|
elem.body[ "offset" + name ], doc[ "offset" + name ], |
|
doc[ "client" + name ] |
|
); |
|
} |
|
|
|
return value === undefined ? |
|
|
|
// Get width or height on the element, requesting but not forcing parseFloat |
|
jQuery.css( elem, type, extra ) : |
|
|
|
// Set width or height on the element |
|
jQuery.style( elem, type, value, extra ); |
|
}, type, chainable ? margin : undefined, chainable ); |
|
}; |
|
} ); |
|
} ); |
|
|
|
|
|
jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " + |
|
"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + |
|
"change select submit keydown keypress keyup contextmenu" ).split( " " ), |
|
function( i, name ) { |
|
|
|
// Handle event binding |
|
jQuery.fn[ name ] = function( data, fn ) { |
|
return arguments.length > 0 ? |
|
this.on( name, null, data, fn ) : |
|
this.trigger( name ); |
|
}; |
|
} ); |
|
|
|
jQuery.fn.extend( { |
|
hover: function( fnOver, fnOut ) { |
|
return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); |
|
} |
|
} ); |
|
|
|
|
|
|
|
|
|
jQuery.fn.extend( { |
|
|
|
bind: function( types, data, fn ) { |
|
return this.on( types, null, data, fn ); |
|
}, |
|
unbind: function( types, fn ) { |
|
return this.off( types, null, fn ); |
|
}, |
|
|
|
delegate: function( selector, types, data, fn ) { |
|
return this.on( types, selector, data, fn ); |
|
}, |
|
undelegate: function( selector, types, fn ) { |
|
|
|
// ( namespace ) or ( selector, types [, fn] ) |
|
return arguments.length === 1 ? |
|
this.off( selector, "**" ) : |
|
this.off( types, selector || "**", fn ); |
|
} |
|
} ); |
|
|
|
// Bind a function to a context, optionally partially applying any |
|
// arguments. |
|
// jQuery.proxy is deprecated to promote standards (specifically Function#bind) |
|
// However, it is not slated for removal any time soon |
|
jQuery.proxy = function( fn, context ) { |
|
var tmp, args, proxy; |
|
|
|
if ( typeof context === "string" ) { |
|
tmp = fn[ context ]; |
|
context = fn; |
|
fn = tmp; |
|
} |
|
|
|
// Quick check to determine if target is callable, in the spec |
|
// this throws a TypeError, but we will just return undefined. |
|
if ( !isFunction( fn ) ) { |
|
return undefined; |
|
} |
|
|
|
// Simulated bind |
|
args = slice.call( arguments, 2 ); |
|
proxy = function() { |
|
return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); |
|
}; |
|
|
|
// Set the guid of unique handler to the same of original handler, so it can be removed |
|
proxy.guid = fn.guid = fn.guid || jQuery.guid++; |
|
|
|
return proxy; |
|
}; |
|
|
|
jQuery.holdReady = function( hold ) { |
|
if ( hold ) { |
|
jQuery.readyWait++; |
|
} else { |
|
jQuery.ready( true ); |
|
} |
|
}; |
|
jQuery.isArray = Array.isArray; |
|
jQuery.parseJSON = JSON.parse; |
|
jQuery.nodeName = nodeName; |
|
jQuery.isFunction = isFunction; |
|
jQuery.isWindow = isWindow; |
|
jQuery.camelCase = camelCase; |
|
jQuery.type = toType; |
|
|
|
jQuery.now = Date.now; |
|
|
|
jQuery.isNumeric = function( obj ) { |
|
|
|
// As of jQuery 3.0, isNumeric is limited to |
|
// strings and numbers (primitives or objects) |
|
// that can be coerced to finite numbers (gh-2662) |
|
var type = jQuery.type( obj ); |
|
return ( type === "number" || type === "string" ) && |
|
|
|
// parseFloat NaNs numeric-cast false positives ("") |
|
// ...but misinterprets leading-number strings, particularly hex literals ("0x...") |
|
// subtraction forces infinities to NaN |
|
!isNaN( obj - parseFloat( obj ) ); |
|
}; |
|
|
|
|
|
|
|
|
|
// Register as a named AMD module, since jQuery can be concatenated with other |
|
// files that may use define, but not via a proper concatenation script that |
|
// understands anonymous AMD modules. A named AMD is safest and most robust |
|
// way to register. Lowercase jquery is used because AMD module names are |
|
// derived from file names, and jQuery is normally delivered in a lowercase |
|
// file name. Do this after creating the global so that if an AMD module wants |
|
// to call noConflict to hide this version of jQuery, it will work. |
|
|
|
// Note that for maximum portability, libraries that are not jQuery should |
|
// declare themselves as anonymous modules, and avoid setting a global if an |
|
// AMD loader is present. jQuery is a special case. For more information, see |
|
// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon |
|
|
|
if ( true ) { |
|
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function() { |
|
return jQuery; |
|
}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), |
|
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); |
|
} |
|
|
|
|
|
|
|
|
|
var |
|
|
|
// Map over jQuery in case of overwrite |
|
_jQuery = window.jQuery, |
|
|
|
// Map over the $ in case of overwrite |
|
_$ = window.$; |
|
|
|
jQuery.noConflict = function( deep ) { |
|
if ( window.$ === jQuery ) { |
|
window.$ = _$; |
|
} |
|
|
|
if ( deep && window.jQuery === jQuery ) { |
|
window.jQuery = _jQuery; |
|
} |
|
|
|
return jQuery; |
|
}; |
|
|
|
// Expose jQuery and $ identifiers, even in AMD |
|
// (#7102#comment:10, https://github.com/jquery/jquery/pull/557) |
|
// and CommonJS for browser emulators (#13566) |
|
if ( !noGlobal ) { |
|
window.jQuery = window.$ = jQuery; |
|
} |
|
|
|
|
|
|
|
|
|
return jQuery; |
|
} ); |
|
|
|
|
|
/***/ }), |
|
/* 5 */ |
|
/***/ (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); |
|
}; |
|
}; |
|
|
|
|
|
/***/ }), |
|
/* 6 */ |
|
/***/ (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; }; |
|
|
|
|
|
/***/ }), |
|
/* 7 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
"use strict"; |
|
|
|
|
|
var utils = __webpack_require__(0); |
|
var settle = __webpack_require__(22); |
|
var buildURL = __webpack_require__(24); |
|
var parseHeaders = __webpack_require__(25); |
|
var isURLSameOrigin = __webpack_require__(26); |
|
var createError = __webpack_require__(8); |
|
var btoa = (typeof window !== 'undefined' && window.btoa && window.btoa.bind(window)) || __webpack_require__(27); |
|
|
|
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 ("development" !== 'test' && |
|
typeof window !== 'undefined' && |
|
window.XDomainRequest && !('withCredentials' in request) && |
|
!isURLSameOrigin(config.url)) { |
|
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__(28); |
|
|
|
// 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); |
|
}); |
|
}; |
|
|
|
|
|
/***/ }), |
|
/* 8 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
"use strict"; |
|
|
|
|
|
var enhanceError = __webpack_require__(23); |
|
|
|
/** |
|
* 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); |
|
}; |
|
|
|
|
|
/***/ }), |
|
/* 9 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
"use strict"; |
|
|
|
|
|
module.exports = function isCancel(value) { |
|
return !!(value && value.__CANCEL__); |
|
}; |
|
|
|
|
|
/***/ }), |
|
/* 10 */ |
|
/***/ (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; |
|
|
|
|
|
/***/ }), |
|
/* 11 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
__webpack_require__(12); |
|
module.exports = __webpack_require__(43); |
|
|
|
|
|
/***/ }), |
|
/* 12 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
|
|
/** |
|
* First we will load all of this project's JavaScript dependencies which |
|
* includes Vue and other libraries. It is a great starting point when |
|
* building robust, powerful web applications using Vue and Laravel. |
|
*/ |
|
|
|
__webpack_require__(13); |
|
|
|
window.Vue = __webpack_require__(36); |
|
|
|
/** |
|
* Next, we will create a fresh Vue application instance and attach it to |
|
* the page. Then, you may begin adding components to this application |
|
* or customize the JavaScript scaffolding to fit your unique needs. |
|
*/ |
|
|
|
Vue.component('example-component', __webpack_require__(39)); |
|
|
|
var app = new Vue({ |
|
el: '#app' |
|
}); |
|
|
|
/***/ }), |
|
/* 13 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
|
|
window._ = __webpack_require__(14); |
|
window.Popper = __webpack_require__(3).default; |
|
|
|
/** |
|
* We'll load jQuery and the Bootstrap jQuery plugin which provides support |
|
* for JavaScript based Bootstrap features such as modals and tabs. This |
|
* code may be modified to fit the specific needs of your application. |
|
*/ |
|
|
|
try { |
|
window.$ = window.jQuery = __webpack_require__(4); |
|
|
|
__webpack_require__(16); |
|
} catch (e) {} |
|
|
|
/** |
|
* We'll load the axios HTTP library which allows us to easily issue requests |
|
* to our Laravel back-end. This library automatically handles sending the |
|
* CSRF token as a header based on the value of the "XSRF" token cookie. |
|
*/ |
|
|
|
window.axios = __webpack_require__(17); |
|
|
|
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; |
|
|
|
/** |
|
* Next we will register the CSRF Token as a common header with Axios so that |
|
* all outgoing HTTP requests automatically have it attached. This is just |
|
* a simple convenience so we don't have to attach every token manually. |
|
*/ |
|
|
|
var token = document.head.querySelector('meta[name="csrf-token"]'); |
|
|
|
if (token) { |
|
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content; |
|
} else { |
|
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token'); |
|
} |
|
|
|
/** |
|
* Echo exposes an expressive API for subscribing to channels and listening |
|
* for events that are broadcast by Laravel. Echo and event broadcasting |
|
* allows your team to easily build robust real-time web applications. |
|
*/ |
|
|
|
// import Echo from 'laravel-echo' |
|
|
|
// window.Pusher = require('pusher-js'); |
|
|
|
// window.Echo = new Echo({ |
|
// broadcaster: 'pusher', |
|
// key: process.env.MIX_PUSHER_APP_KEY, |
|
// cluster: process.env.MIX_PUSHER_APP_CLUSTER, |
|
// encrypted: true |
|
// }); |
|
|
|
/***/ }), |
|
/* 14 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
/* WEBPACK VAR INJECTION */(function(global, module) {var __WEBPACK_AMD_DEFINE_RESULT__;/** |
|
* @license |
|
* Lodash <https://lodash.com/> |
|
* Copyright JS Foundation and other contributors <https://js.foundation/> |
|
* 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 |
|
*/ |
|
;(function() { |
|
|
|
/** Used as a safe reference for `undefined` in pre-ES5 environments. */ |
|
var undefined; |
|
|
|
/** Used as the semantic version number. */ |
|
var VERSION = '4.17.10'; |
|
|
|
/** Used as the size to enable large array optimizations. */ |
|
var LARGE_ARRAY_SIZE = 200; |
|
|
|
/** Error message constants. */ |
|
var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.', |
|
FUNC_ERROR_TEXT = 'Expected a function'; |
|
|
|
/** Used to stand-in for `undefined` hash values. */ |
|
var HASH_UNDEFINED = '__lodash_hash_undefined__'; |
|
|
|
/** Used as the maximum memoize cache size. */ |
|
var MAX_MEMOIZE_SIZE = 500; |
|
|
|
/** Used as the internal argument placeholder. */ |
|
var PLACEHOLDER = '__lodash_placeholder__'; |
|
|
|
/** Used to compose bitmasks for cloning. */ |
|
var CLONE_DEEP_FLAG = 1, |
|
CLONE_FLAT_FLAG = 2, |
|
CLONE_SYMBOLS_FLAG = 4; |
|
|
|
/** Used to compose bitmasks for value comparisons. */ |
|
var COMPARE_PARTIAL_FLAG = 1, |
|
COMPARE_UNORDERED_FLAG = 2; |
|
|
|
/** Used to compose bitmasks for function metadata. */ |
|
var WRAP_BIND_FLAG = 1, |
|
WRAP_BIND_KEY_FLAG = 2, |
|
WRAP_CURRY_BOUND_FLAG = 4, |
|
WRAP_CURRY_FLAG = 8, |
|
WRAP_CURRY_RIGHT_FLAG = 16, |
|
WRAP_PARTIAL_FLAG = 32, |
|
WRAP_PARTIAL_RIGHT_FLAG = 64, |
|
WRAP_ARY_FLAG = 128, |
|
WRAP_REARG_FLAG = 256, |
|
WRAP_FLIP_FLAG = 512; |
|
|
|
/** Used as default options for `_.truncate`. */ |
|
var DEFAULT_TRUNC_LENGTH = 30, |
|
DEFAULT_TRUNC_OMISSION = '...'; |
|
|
|
/** Used to detect hot functions by number of calls within a span of milliseconds. */ |
|
var HOT_COUNT = 800, |
|
HOT_SPAN = 16; |
|
|
|
/** Used to indicate the type of lazy iteratees. */ |
|
var LAZY_FILTER_FLAG = 1, |
|
LAZY_MAP_FLAG = 2, |
|
LAZY_WHILE_FLAG = 3; |
|
|
|
/** Used as references for various `Number` constants. */ |
|
var INFINITY = 1 / 0, |
|
MAX_SAFE_INTEGER = 9007199254740991, |
|
MAX_INTEGER = 1.7976931348623157e+308, |
|
NAN = 0 / 0; |
|
|
|
/** Used as references for the maximum length and index of an array. */ |
|
var MAX_ARRAY_LENGTH = 4294967295, |
|
MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, |
|
HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; |
|
|
|
/** Used to associate wrap methods with their bit flags. */ |
|
var wrapFlags = [ |
|
['ary', WRAP_ARY_FLAG], |
|
['bind', WRAP_BIND_FLAG], |
|
['bindKey', WRAP_BIND_KEY_FLAG], |
|
['curry', WRAP_CURRY_FLAG], |
|
['curryRight', WRAP_CURRY_RIGHT_FLAG], |
|
['flip', WRAP_FLIP_FLAG], |
|
['partial', WRAP_PARTIAL_FLAG], |
|
['partialRight', WRAP_PARTIAL_RIGHT_FLAG], |
|
['rearg', WRAP_REARG_FLAG] |
|
]; |
|
|
|
/** `Object#toString` result references. */ |
|
var argsTag = '[object Arguments]', |
|
arrayTag = '[object Array]', |
|
asyncTag = '[object AsyncFunction]', |
|
boolTag = '[object Boolean]', |
|
dateTag = '[object Date]', |
|
domExcTag = '[object DOMException]', |
|
errorTag = '[object Error]', |
|
funcTag = '[object Function]', |
|
genTag = '[object GeneratorFunction]', |
|
mapTag = '[object Map]', |
|
numberTag = '[object Number]', |
|
nullTag = '[object Null]', |
|
objectTag = '[object Object]', |
|
promiseTag = '[object Promise]', |
|
proxyTag = '[object Proxy]', |
|
regexpTag = '[object RegExp]', |
|
setTag = '[object Set]', |
|
stringTag = '[object String]', |
|
symbolTag = '[object Symbol]', |
|
undefinedTag = '[object Undefined]', |
|
weakMapTag = '[object WeakMap]', |
|
weakSetTag = '[object WeakSet]'; |
|
|
|
var arrayBufferTag = '[object ArrayBuffer]', |
|
dataViewTag = '[object DataView]', |
|
float32Tag = '[object Float32Array]', |
|
float64Tag = '[object Float64Array]', |
|
int8Tag = '[object Int8Array]', |
|
int16Tag = '[object Int16Array]', |
|
int32Tag = '[object Int32Array]', |
|
uint8Tag = '[object Uint8Array]', |
|
uint8ClampedTag = '[object Uint8ClampedArray]', |
|
uint16Tag = '[object Uint16Array]', |
|
uint32Tag = '[object Uint32Array]'; |
|
|
|
/** Used to match empty string literals in compiled template source. */ |
|
var reEmptyStringLeading = /\b__p \+= '';/g, |
|
reEmptyStringMiddle = /\b(__p \+=) '' \+/g, |
|
reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; |
|
|
|
/** Used to match HTML entities and HTML characters. */ |
|
var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g, |
|
reUnescapedHtml = /[&<>"']/g, |
|
reHasEscapedHtml = RegExp(reEscapedHtml.source), |
|
reHasUnescapedHtml = RegExp(reUnescapedHtml.source); |
|
|
|
/** Used to match template delimiters. */ |
|
var reEscape = /<%-([\s\S]+?)%>/g, |
|
reEvaluate = /<%([\s\S]+?)%>/g, |
|
reInterpolate = /<%=([\s\S]+?)%>/g; |
|
|
|
/** Used to match property names within property paths. */ |
|
var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, |
|
reIsPlainProp = /^\w*$/, |
|
rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; |
|
|
|
/** |
|
* Used to match `RegExp` |
|
* [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). |
|
*/ |
|
var reRegExpChar = /[\\^$.*+?()[\]{}|]/g, |
|
reHasRegExpChar = RegExp(reRegExpChar.source); |
|
|
|
/** Used to match leading and trailing whitespace. */ |
|
var reTrim = /^\s+|\s+$/g, |
|
reTrimStart = /^\s+/, |
|
reTrimEnd = /\s+$/; |
|
|
|
/** Used to match wrap detail comments. */ |
|
var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/, |
|
reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/, |
|
reSplitDetails = /,? & /; |
|
|
|
/** Used to match words composed of alphanumeric characters. */ |
|
var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g; |
|
|
|
/** Used to match backslashes in property paths. */ |
|
var reEscapeChar = /\\(\\)?/g; |
|
|
|
/** |
|
* Used to match |
|
* [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components). |
|
*/ |
|
var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; |
|
|
|
/** Used to match `RegExp` flags from their coerced string values. */ |
|
var reFlags = /\w*$/; |
|
|
|
/** 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*)$/; |
|
|
|
/** Used to match Latin Unicode letters (excluding mathematical operators). */ |
|
var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g; |
|
|
|
/** Used to ensure capturing order of template delimiters. */ |
|
var reNoMatch = /($^)/; |
|
|
|
/** Used to match unescaped characters in compiled string literals. */ |
|
var reUnescapedString = /['\n\r\u2028\u2029\\]/g; |
|
|
|
/** Used to compose unicode character classes. */ |
|
var rsAstralRange = '\\ud800-\\udfff', |
|
rsComboMarksRange = '\\u0300-\\u036f', |
|
reComboHalfMarksRange = '\\ufe20-\\ufe2f', |
|
rsComboSymbolsRange = '\\u20d0-\\u20ff', |
|
rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, |
|
rsDingbatRange = '\\u2700-\\u27bf', |
|
rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff', |
|
rsMathOpRange = '\\xac\\xb1\\xd7\\xf7', |
|
rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf', |
|
rsPunctuationRange = '\\u2000-\\u206f', |
|
rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000', |
|
rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde', |
|
rsVarRange = '\\ufe0e\\ufe0f', |
|
rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange; |
|
|
|
/** Used to compose unicode capture groups. */ |
|
var rsApos = "['\u2019]", |
|
rsAstral = '[' + rsAstralRange + ']', |
|
rsBreak = '[' + rsBreakRange + ']', |
|
rsCombo = '[' + rsComboRange + ']', |
|
rsDigits = '\\d+', |
|
rsDingbat = '[' + rsDingbatRange + ']', |
|
rsLower = '[' + rsLowerRange + ']', |
|
rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']', |
|
rsFitz = '\\ud83c[\\udffb-\\udfff]', |
|
rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', |
|
rsNonAstral = '[^' + rsAstralRange + ']', |
|
rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', |
|
rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', |
|
rsUpper = '[' + rsUpperRange + ']', |
|
rsZWJ = '\\u200d'; |
|
|
|
/** Used to compose unicode regexes. */ |
|
var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')', |
|
rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')', |
|
rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?', |
|
rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?', |
|
reOptMod = rsModifier + '?', |
|
rsOptVar = '[' + rsVarRange + ']?', |
|
rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', |
|
rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])', |
|
rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])', |
|
rsSeq = rsOptVar + reOptMod + rsOptJoin, |
|
rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq, |
|
rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; |
|
|
|
/** Used to match apostrophes. */ |
|
var reApos = RegExp(rsApos, 'g'); |
|
|
|
/** |
|
* Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and |
|
* [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols). |
|
*/ |
|
var reComboMark = RegExp(rsCombo, 'g'); |
|
|
|
/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ |
|
var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); |
|
|
|
/** Used to match complex or compound words. */ |
|
var reUnicodeWord = RegExp([ |
|
rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')', |
|
rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')', |
|
rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower, |
|
rsUpper + '+' + rsOptContrUpper, |
|
rsOrdUpper, |
|
rsOrdLower, |
|
rsDigits, |
|
rsEmoji |
|
].join('|'), 'g'); |
|
|
|
/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ |
|
var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); |
|
|
|
/** Used to detect strings that need a more robust regexp to match words. */ |
|
var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/; |
|
|
|
/** Used to assign default `context` object properties. */ |
|
var contextProps = [ |
|
'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array', |
|
'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object', |
|
'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array', |
|
'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', |
|
'_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout' |
|
]; |
|
|
|
/** Used to make template sourceURLs easier to identify. */ |
|
var templateCounter = -1; |
|
|
|
/** Used to identify `toStringTag` values of typed arrays. */ |
|
var typedArrayTags = {}; |
|
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = |
|
typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = |
|
typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = |
|
typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = |
|
typedArrayTags[uint32Tag] = true; |
|
typedArrayTags[argsTag] = typedArrayTags[arrayTag] = |
|
typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = |
|
typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = |
|
typedArrayTags[errorTag] = typedArrayTags[funcTag] = |
|
typedArrayTags[mapTag] = typedArrayTags[numberTag] = |
|
typedArrayTags[objectTag] = typedArrayTags[regexpTag] = |
|
typedArrayTags[setTag] = typedArrayTags[stringTag] = |
|
typedArrayTags[weakMapTag] = false; |
|
|
|
/** Used to identify `toStringTag` values supported by `_.clone`. */ |
|
var cloneableTags = {}; |
|
cloneableTags[argsTag] = cloneableTags[arrayTag] = |
|
cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = |
|
cloneableTags[boolTag] = cloneableTags[dateTag] = |
|
cloneableTags[float32Tag] = cloneableTags[float64Tag] = |
|
cloneableTags[int8Tag] = cloneableTags[int16Tag] = |
|
cloneableTags[int32Tag] = cloneableTags[mapTag] = |
|
cloneableTags[numberTag] = cloneableTags[objectTag] = |
|
cloneableTags[regexpTag] = cloneableTags[setTag] = |
|
cloneableTags[stringTag] = cloneableTags[symbolTag] = |
|
cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = |
|
cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; |
|
cloneableTags[errorTag] = cloneableTags[funcTag] = |
|
cloneableTags[weakMapTag] = false; |
|
|
|
/** Used to map Latin Unicode letters to basic Latin letters. */ |
|
var deburredLetters = { |
|
// Latin-1 Supplement block. |
|
'\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', |
|
'\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', |
|
'\xc7': 'C', '\xe7': 'c', |
|
'\xd0': 'D', '\xf0': 'd', |
|
'\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', |
|
'\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', |
|
'\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', |
|
'\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', |
|
'\xd1': 'N', '\xf1': 'n', |
|
'\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', |
|
'\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', |
|
'\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', |
|
'\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', |
|
'\xdd': 'Y', '\xfd': 'y', '\xff': 'y', |
|
'\xc6': 'Ae', '\xe6': 'ae', |
|
'\xde': 'Th', '\xfe': 'th', |
|
'\xdf': 'ss', |
|
// Latin Extended-A block. |
|
'\u0100': 'A', '\u0102': 'A', '\u0104': 'A', |
|
'\u0101': 'a', '\u0103': 'a', '\u0105': 'a', |
|
'\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C', |
|
'\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c', |
|
'\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd', |
|
'\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E', |
|
'\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e', |
|
'\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G', |
|
'\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g', |
|
'\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h', |
|
'\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I', |
|
'\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i', |
|
'\u0134': 'J', '\u0135': 'j', |
|
'\u0136': 'K', '\u0137': 'k', '\u0138': 'k', |
|
'\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L', |
|
'\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l', |
|
'\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N', |
|
'\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n', |
|
'\u014c': 'O', '\u014e': 'O', '\u0150': 'O', |
|
'\u014d': 'o', '\u014f': 'o', '\u0151': 'o', |
|
'\u0154': 'R', '\u0156': 'R', '\u0158': 'R', |
|
'\u0155': 'r', '\u0157': 'r', '\u0159': 'r', |
|
'\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S', |
|
'\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's', |
|
'\u0162': 'T', '\u0164': 'T', '\u0166': 'T', |
|
'\u0163': 't', '\u0165': 't', '\u0167': 't', |
|
'\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U', |
|
'\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u', |
|
'\u0174': 'W', '\u0175': 'w', |
|
'\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y', |
|
'\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z', |
|
'\u017a': 'z', '\u017c': 'z', '\u017e': 'z', |
|
'\u0132': 'IJ', '\u0133': 'ij', |
|
'\u0152': 'Oe', '\u0153': 'oe', |
|
'\u0149': "'n", '\u017f': 's' |
|
}; |
|
|
|
/** Used to map characters to HTML entities. */ |
|
var htmlEscapes = { |
|
'&': '&', |
|
'<': '<', |
|
'>': '>', |
|
'"': '"', |
|
"'": ''' |
|
}; |
|
|
|
/** Used to map HTML entities to characters. */ |
|
var htmlUnescapes = { |
|
'&': '&', |
|
'<': '<', |
|
'>': '>', |
|
'"': '"', |
|
''': "'" |
|
}; |
|
|
|
/** Used to escape characters for inclusion in compiled string literals. */ |
|
var stringEscapes = { |
|
'\\': '\\', |
|
"'": "'", |
|
'\n': 'n', |
|
'\r': 'r', |
|
'\u2028': 'u2028', |
|
'\u2029': 'u2029' |
|
}; |
|
|
|
/** Built-in method references without a dependency on `root`. */ |
|
var freeParseFloat = parseFloat, |
|
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')(); |
|
|
|
/** Detect free variable `exports`. */ |
|
var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; |
|
|
|
/** Detect free variable `module`. */ |
|
var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; |
|
|
|
/** Detect the popular CommonJS extension `module.exports`. */ |
|
var moduleExports = freeModule && freeModule.exports === freeExports; |
|
|
|
/** Detect free variable `process` from Node.js. */ |
|
var freeProcess = moduleExports && freeGlobal.process; |
|
|
|
/** Used to access faster Node.js helpers. */ |
|
var nodeUtil = (function() { |
|
try { |
|
// Use `util.types` for Node.js 10+. |
|
var types = freeModule && freeModule.require && freeModule.require('util').types; |
|
|
|
if (types) { |
|
return types; |
|
} |
|
|
|
// Legacy `process.binding('util')` for Node.js < 10. |
|
return freeProcess && freeProcess.binding && freeProcess.binding('util'); |
|
} catch (e) {} |
|
}()); |
|
|
|
/* Node.js helper references. */ |
|
var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer, |
|
nodeIsDate = nodeUtil && nodeUtil.isDate, |
|
nodeIsMap = nodeUtil && nodeUtil.isMap, |
|
nodeIsRegExp = nodeUtil && nodeUtil.isRegExp, |
|
nodeIsSet = nodeUtil && nodeUtil.isSet, |
|
nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; |
|
|
|
/*--------------------------------------------------------------------------*/ |
|
|
|
/** |
|
* 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 `baseAggregator` for arrays. |
|
* |
|
* @private |
|
* @param {Array} [array] The array to iterate over. |
|
* @param {Function} setter The function to set `accumulator` values. |
|
* @param {Function} iteratee The iteratee to transform keys. |
|
* @param {Object} accumulator The initial aggregated object. |
|
* @returns {Function} Returns `accumulator`. |
|
*/ |
|
function arrayAggregator(array, setter, iteratee, accumulator) { |
|
var index = -1, |
|
length = array == null ? 0 : array.length; |
|
|
|
while (++index < length) { |
|
var value = array[index]; |
|
setter(accumulator, value, iteratee(value), array); |
|
} |
|
return accumulator; |
|
} |
|
|
|
/** |
|
* 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 == null ? 0 : array.length; |
|
|
|
while (++index < length) { |
|
if (iteratee(array[index], index, array) === false) { |
|
break; |
|
} |
|
} |
|
return array; |
|
} |
|
|
|
/** |
|
* A specialized version of `_.forEachRight` 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 arrayEachRight(array, iteratee) { |
|
var length = array == null ? 0 : array.length; |
|
|
|
while (length--) { |
|
if (iteratee(array[length], length, array) === false) { |
|
break; |
|
} |
|
} |
|
return array; |
|
} |
|
|
|
/** |
|
* A specialized version of `_.every` for arrays without support for |
|
* iteratee shorthands. |
|
* |
|
* @private |
|
* @param {Array} [array] The array to iterate over. |
|
* @param {Function} predicate The function invoked per iteration. |
|
* @returns {boolean} Returns `true` if all elements pass the predicate check, |
|
* else `false`. |
|
*/ |
|
function arrayEvery(array, predicate) { |
|
var index = -1, |
|
length = array == null ? 0 : array.length; |
|
|
|
while (++index < length) { |
|
if (!predicate(array[index], index, array)) { |
|
return false; |
|
} |
|
} |
|
return true; |
|
} |
|
|
|
/** |
|
* A specialized version of `_.filter` for arrays without support for |
|
* iteratee shorthands. |
|
* |
|
* @private |
|
* @param {Array} [array] The array to iterate over. |
|
* @param {Function} predicate The function invoked per iteration. |
|
* @returns {Array} Returns the new filtered array. |
|
*/ |
|
function arrayFilter(array, predicate) { |
|
var index = -1, |
|
length = array == null ? 0 : array.length, |
|
resIndex = 0, |
|
result = []; |
|
|
|
while (++index < length) { |
|
var value = array[index]; |
|
if (predicate(value, index, array)) { |
|
result[resIndex++] = value; |
|
} |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* 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 == null ? 0 : array.length; |
|
return !!length && baseIndexOf(array, value, 0) > -1; |
|
} |
|
|
|
/** |
|
* This function is like `arrayIncludes` except that it accepts a comparator. |
|
* |
|
* @private |
|
* @param {Array} [array] The array to inspect. |
|
* @param {*} target The value to search for. |
|
* @param {Function} comparator The comparator invoked per element. |
|
* @returns {boolean} Returns `true` if `target` is found, else `false`. |
|
*/ |
|
function arrayIncludesWith(array, value, comparator) { |
|
var index = -1, |
|
length = array == null ? 0 : array.length; |
|
|
|
while (++index < length) { |
|
if (comparator(value, array[index])) { |
|
return true; |
|
} |
|
} |
|
return false; |
|
} |
|
|
|
/** |
|
* A specialized version of `_.map` 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 the new mapped array. |
|
*/ |
|
function arrayMap(array, iteratee) { |
|
var index = -1, |
|
length = array == null ? 0 : array.length, |
|
result = Array(length); |
|
|
|
while (++index < length) { |
|
result[index] = iteratee(array[index], index, array); |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* 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; |
|
} |
|
|
|
/** |
|
* A specialized version of `_.reduce` for arrays without support for |
|
* iteratee shorthands. |
|
* |
|
* @private |
|
* @param {Array} [array] The array to iterate over. |
|
* @param {Function} iteratee The function invoked per iteration. |
|
* @param {*} [accumulator] The initial value. |
|
* @param {boolean} [initAccum] Specify using the first element of `array` as |
|
* the initial value. |
|
* @returns {*} Returns the accumulated value. |
|
*/ |
|
function arrayReduce(array, iteratee, accumulator, initAccum) { |
|
var index = -1, |
|
length = array == null ? 0 : array.length; |
|
|
|
if (initAccum && length) { |
|
accumulator = array[++index]; |
|
} |
|
while (++index < length) { |
|
accumulator = iteratee(accumulator, array[index], index, array); |
|
} |
|
return accumulator; |
|
} |
|
|
|
/** |
|
* A specialized version of `_.reduceRight` for arrays without support for |
|
* iteratee shorthands. |
|
* |
|
* @private |
|
* @param {Array} [array] The array to iterate over. |
|
* @param {Function} iteratee The function invoked per iteration. |
|
* @param {*} [accumulator] The initial value. |
|
* @param {boolean} [initAccum] Specify using the last element of `array` as |
|
* the initial value. |
|
* @returns {*} Returns the accumulated value. |
|
*/ |
|
function arrayReduceRight(array, iteratee, accumulator, initAccum) { |
|
var length = array == null ? 0 : array.length; |
|
if (initAccum && length) { |
|
accumulator = array[--length]; |
|
} |
|
while (length--) { |
|
accumulator = iteratee(accumulator, array[length], length, array); |
|
} |
|
return accumulator; |
|
} |
|
|
|
/** |
|
* A specialized version of `_.some` for arrays without support for iteratee |
|
* shorthands. |
|
* |
|
* @private |
|
* @param {Array} [array] The array to iterate over. |
|
* @param {Function} predicate The function invoked per iteration. |
|
* @returns {boolean} Returns `true` if any element passes the predicate check, |
|
* else `false`. |
|
*/ |
|
function arraySome(array, predicate) { |
|
var index = -1, |
|
length = array == null ? 0 : array.length; |
|
|
|
while (++index < length) { |
|
if (predicate(array[index], index, array)) { |
|
return true; |
|
} |
|
} |
|
return false; |
|
} |
|
|
|
/** |
|
* Gets the size of an ASCII `string`. |
|
* |
|
* @private |
|
* @param {string} string The string inspect. |
|
* @returns {number} Returns the string size. |
|
*/ |
|
var asciiSize = baseProperty('length'); |
|
|
|
/** |
|
* Converts an ASCII `string` to an array. |
|
* |
|
* @private |
|
* @param {string} string The string to convert. |
|
* @returns {Array} Returns the converted array. |
|
*/ |
|
function asciiToArray(string) { |
|
return string.split(''); |
|
} |
|
|
|
/** |
|
* Splits an ASCII `string` into an array of its words. |
|
* |
|
* @private |
|
* @param {string} The string to inspect. |
|
* @returns {Array} Returns the words of `string`. |
|
*/ |
|
function asciiWords(string) { |
|
return string.match(reAsciiWord) || []; |
|
} |
|
|
|
/** |
|
* The base implementation of methods like `_.findKey` and `_.findLastKey`, |
|
* without support for iteratee shorthands, which iterates over `collection` |
|
* using `eachFunc`. |
|
* |
|
* @private |
|
* @param {Array|Object} collection The collection to inspect. |
|
* @param {Function} predicate The function invoked per iteration. |
|
* @param {Function} eachFunc The function to iterate over `collection`. |
|
* @returns {*} Returns the found element or its key, else `undefined`. |
|
*/ |
|
function baseFindKey(collection, predicate, eachFunc) { |
|
var result; |
|
eachFunc(collection, function(value, key, collection) { |
|
if (predicate(value, key, collection)) { |
|
result = key; |
|
return false; |
|
} |
|
}); |
|
return result; |
|
} |
|
|
|
/** |
|
* 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) { |
|
return value === value |
|
? strictIndexOf(array, value, fromIndex) |
|
: baseFindIndex(array, baseIsNaN, fromIndex); |
|
} |
|
|
|
/** |
|
* This function is like `baseIndexOf` except that it accepts a comparator. |
|
* |
|
* @private |
|
* @param {Array} array The array to inspect. |
|
* @param {*} value The value to search for. |
|
* @param {number} fromIndex The index to search from. |
|
* @param {Function} comparator The comparator invoked per element. |
|
* @returns {number} Returns the index of the matched value, else `-1`. |
|
*/ |
|
function baseIndexOfWith(array, value, fromIndex, comparator) { |
|
var index = fromIndex - 1, |
|
length = array.length; |
|
|
|
while (++index < length) { |
|
if (comparator(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; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.mean` and `_.meanBy` without support for |
|
* iteratee shorthands. |
|
* |
|
* @private |
|
* @param {Array} array The array to iterate over. |
|
* @param {Function} iteratee The function invoked per iteration. |
|
* @returns {number} Returns the mean. |
|
*/ |
|
function baseMean(array, iteratee) { |
|
var length = array == null ? 0 : array.length; |
|
return length ? (baseSum(array, iteratee) / length) : NAN; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.property` without support for deep paths. |
|
* |
|
* @private |
|
* @param {string} key The key of the property to get. |
|
* @returns {Function} Returns the new accessor function. |
|
*/ |
|
function baseProperty(key) { |
|
return function(object) { |
|
return object == null ? undefined : object[key]; |
|
}; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.propertyOf` without support for deep paths. |
|
* |
|
* @private |
|
* @param {Object} object The object to query. |
|
* @returns {Function} Returns the new accessor function. |
|
*/ |
|
function basePropertyOf(object) { |
|
return function(key) { |
|
return object == null ? undefined : object[key]; |
|
}; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.reduce` and `_.reduceRight`, without support |
|
* for iteratee shorthands, which iterates over `collection` using `eachFunc`. |
|
* |
|
* @private |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {Function} iteratee The function invoked per iteration. |
|
* @param {*} accumulator The initial value. |
|
* @param {boolean} initAccum Specify using the first or last element of |
|
* `collection` as the initial value. |
|
* @param {Function} eachFunc The function to iterate over `collection`. |
|
* @returns {*} Returns the accumulated value. |
|
*/ |
|
function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { |
|
eachFunc(collection, function(value, index, collection) { |
|
accumulator = initAccum |
|
? (initAccum = false, value) |
|
: iteratee(accumulator, value, index, collection); |
|
}); |
|
return accumulator; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.sortBy` which uses `comparer` to define the |
|
* sort order of `array` and replaces criteria objects with their corresponding |
|
* values. |
|
* |
|
* @private |
|
* @param {Array} array The array to sort. |
|
* @param {Function} comparer The function to define sort order. |
|
* @returns {Array} Returns `array`. |
|
*/ |
|
function baseSortBy(array, comparer) { |
|
var length = array.length; |
|
|
|
array.sort(comparer); |
|
while (length--) { |
|
array[length] = array[length].value; |
|
} |
|
return array; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.sum` and `_.sumBy` without support for |
|
* iteratee shorthands. |
|
* |
|
* @private |
|
* @param {Array} array The array to iterate over. |
|
* @param {Function} iteratee The function invoked per iteration. |
|
* @returns {number} Returns the sum. |
|
*/ |
|
function baseSum(array, iteratee) { |
|
var result, |
|
index = -1, |
|
length = array.length; |
|
|
|
while (++index < length) { |
|
var current = iteratee(array[index]); |
|
if (current !== undefined) { |
|
result = result === undefined ? current : (result + current); |
|
} |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.times` without support for iteratee shorthands |
|
* or max array length checks. |
|
* |
|
* @private |
|
* @param {number} n The number of times to invoke `iteratee`. |
|
* @param {Function} iteratee The function invoked per iteration. |
|
* @returns {Array} Returns the array of results. |
|
*/ |
|
function baseTimes(n, iteratee) { |
|
var index = -1, |
|
result = Array(n); |
|
|
|
while (++index < n) { |
|
result[index] = iteratee(index); |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array |
|
* of key-value pairs for `object` corresponding to the property names of `props`. |
|
* |
|
* @private |
|
* @param {Object} object The object to query. |
|
* @param {Array} props The property names to get values for. |
|
* @returns {Object} Returns the key-value pairs. |
|
*/ |
|
function baseToPairs(object, props) { |
|
return arrayMap(props, function(key) { |
|
return [key, object[key]]; |
|
}); |
|
} |
|
|
|
/** |
|
* The base implementation of `_.unary` without support for storing metadata. |
|
* |
|
* @private |
|
* @param {Function} func The function to cap arguments for. |
|
* @returns {Function} Returns the new capped function. |
|
*/ |
|
function baseUnary(func) { |
|
return function(value) { |
|
return func(value); |
|
}; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.values` and `_.valuesIn` which creates an |
|
* array of `object` property values corresponding to the property names |
|
* of `props`. |
|
* |
|
* @private |
|
* @param {Object} object The object to query. |
|
* @param {Array} props The property names to get values for. |
|
* @returns {Object} Returns the array of property values. |
|
*/ |
|
function baseValues(object, props) { |
|
return arrayMap(props, function(key) { |
|
return object[key]; |
|
}); |
|
} |
|
|
|
/** |
|
* Checks if a `cache` value for `key` exists. |
|
* |
|
* @private |
|
* @param {Object} cache The cache to query. |
|
* @param {string} key The key of the entry to check. |
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. |
|
*/ |
|
function cacheHas(cache, key) { |
|
return cache.has(key); |
|
} |
|
|
|
/** |
|
* Used by `_.trim` and `_.trimStart` to get the index of the first string symbol |
|
* that is not found in the character symbols. |
|
* |
|
* @private |
|
* @param {Array} strSymbols The string symbols to inspect. |
|
* @param {Array} chrSymbols The character symbols to find. |
|
* @returns {number} Returns the index of the first unmatched string symbol. |
|
*/ |
|
function charsStartIndex(strSymbols, chrSymbols) { |
|
var index = -1, |
|
length = strSymbols.length; |
|
|
|
while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} |
|
return index; |
|
} |
|
|
|
/** |
|
* Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol |
|
* that is not found in the character symbols. |
|
* |
|
* @private |
|
* @param {Array} strSymbols The string symbols to inspect. |
|
* @param {Array} chrSymbols The character symbols to find. |
|
* @returns {number} Returns the index of the last unmatched string symbol. |
|
*/ |
|
function charsEndIndex(strSymbols, chrSymbols) { |
|
var index = strSymbols.length; |
|
|
|
while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} |
|
return index; |
|
} |
|
|
|
/** |
|
* 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; |
|
} |
|
|
|
/** |
|
* Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A |
|
* letters to basic Latin letters. |
|
* |
|
* @private |
|
* @param {string} letter The matched letter to deburr. |
|
* @returns {string} Returns the deburred letter. |
|
*/ |
|
var deburrLetter = basePropertyOf(deburredLetters); |
|
|
|
/** |
|
* Used by `_.escape` to convert characters to HTML entities. |
|
* |
|
* @private |
|
* @param {string} chr The matched character to escape. |
|
* @returns {string} Returns the escaped character. |
|
*/ |
|
var escapeHtmlChar = basePropertyOf(htmlEscapes); |
|
|
|
/** |
|
* Used by `_.template` to escape characters for inclusion in compiled string literals. |
|
* |
|
* @private |
|
* @param {string} chr The matched character to escape. |
|
* @returns {string} Returns the escaped character. |
|
*/ |
|
function escapeStringChar(chr) { |
|
return '\\' + stringEscapes[chr]; |
|
} |
|
|
|
/** |
|
* 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 `string` contains Unicode symbols. |
|
* |
|
* @private |
|
* @param {string} string The string to inspect. |
|
* @returns {boolean} Returns `true` if a symbol is found, else `false`. |
|
*/ |
|
function hasUnicode(string) { |
|
return reHasUnicode.test(string); |
|
} |
|
|
|
/** |
|
* Checks if `string` contains a word composed of Unicode symbols. |
|
* |
|
* @private |
|
* @param {string} string The string to inspect. |
|
* @returns {boolean} Returns `true` if a word is found, else `false`. |
|
*/ |
|
function hasUnicodeWord(string) { |
|
return reHasUnicodeWord.test(string); |
|
} |
|
|
|
/** |
|
* Converts `iterator` to an array. |
|
* |
|
* @private |
|
* @param {Object} iterator The iterator to convert. |
|
* @returns {Array} Returns the converted array. |
|
*/ |
|
function iteratorToArray(iterator) { |
|
var data, |
|
result = []; |
|
|
|
while (!(data = iterator.next()).done) { |
|
result.push(data.value); |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* Converts `map` to its key-value pairs. |
|
* |
|
* @private |
|
* @param {Object} map The map to convert. |
|
* @returns {Array} Returns the key-value pairs. |
|
*/ |
|
function mapToArray(map) { |
|
var index = -1, |
|
result = Array(map.size); |
|
|
|
map.forEach(function(value, key) { |
|
result[++index] = [key, value]; |
|
}); |
|
return result; |
|
} |
|
|
|
/** |
|
* Creates a unary function that invokes `func` with its argument transformed. |
|
* |
|
* @private |
|
* @param {Function} func The function to wrap. |
|
* @param {Function} transform The argument transform. |
|
* @returns {Function} Returns the new function. |
|
*/ |
|
function overArg(func, transform) { |
|
return function(arg) { |
|
return func(transform(arg)); |
|
}; |
|
} |
|
|
|
/** |
|
* 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; |
|
} |
|
|
|
/** |
|
* Gets the value at `key`, unless `key` is "__proto__". |
|
* |
|
* @private |
|
* @param {Object} object The object to query. |
|
* @param {string} key The key of the property to get. |
|
* @returns {*} Returns the property value. |
|
*/ |
|
function safeGet(object, key) { |
|
return key == '__proto__' |
|
? undefined |
|
: object[key]; |
|
} |
|
|
|
/** |
|
* Converts `set` to an array of its values. |
|
* |
|
* @private |
|
* @param {Object} set The set to convert. |
|
* @returns {Array} Returns the values. |
|
*/ |
|
function setToArray(set) { |
|
var index = -1, |
|
result = Array(set.size); |
|
|
|
set.forEach(function(value) { |
|
result[++index] = value; |
|
}); |
|
return result; |
|
} |
|
|
|
/** |
|
* Converts `set` to its value-value pairs. |
|
* |
|
* @private |
|
* @param {Object} set The set to convert. |
|
* @returns {Array} Returns the value-value pairs. |
|
*/ |
|
function setToPairs(set) { |
|
var index = -1, |
|
result = Array(set.size); |
|
|
|
set.forEach(function(value) { |
|
result[++index] = [value, value]; |
|
}); |
|
return result; |
|
} |
|
|
|
/** |
|
* A specialized version of `_.indexOf` which performs strict equality |
|
* comparisons of values, i.e. `===`. |
|
* |
|
* @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 strictIndexOf(array, value, fromIndex) { |
|
var index = fromIndex - 1, |
|
length = array.length; |
|
|
|
while (++index < length) { |
|
if (array[index] === value) { |
|
return index; |
|
} |
|
} |
|
return -1; |
|
} |
|
|
|
/** |
|
* A specialized version of `_.lastIndexOf` which performs strict equality |
|
* comparisons of values, i.e. `===`. |
|
* |
|
* @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 strictLastIndexOf(array, value, fromIndex) { |
|
var index = fromIndex + 1; |
|
while (index--) { |
|
if (array[index] === value) { |
|
return index; |
|
} |
|
} |
|
return index; |
|
} |
|
|
|
/** |
|
* Gets the number of symbols in `string`. |
|
* |
|
* @private |
|
* @param {string} string The string to inspect. |
|
* @returns {number} Returns the string size. |
|
*/ |
|
function stringSize(string) { |
|
return hasUnicode(string) |
|
? unicodeSize(string) |
|
: asciiSize(string); |
|
} |
|
|
|
/** |
|
* Converts `string` to an array. |
|
* |
|
* @private |
|
* @param {string} string The string to convert. |
|
* @returns {Array} Returns the converted array. |
|
*/ |
|
function stringToArray(string) { |
|
return hasUnicode(string) |
|
? unicodeToArray(string) |
|
: asciiToArray(string); |
|
} |
|
|
|
/** |
|
* Used by `_.unescape` to convert HTML entities to characters. |
|
* |
|
* @private |
|
* @param {string} chr The matched character to unescape. |
|
* @returns {string} Returns the unescaped character. |
|
*/ |
|
var unescapeHtmlChar = basePropertyOf(htmlUnescapes); |
|
|
|
/** |
|
* Gets the size of a Unicode `string`. |
|
* |
|
* @private |
|
* @param {string} string The string inspect. |
|
* @returns {number} Returns the string size. |
|
*/ |
|
function unicodeSize(string) { |
|
var result = reUnicode.lastIndex = 0; |
|
while (reUnicode.test(string)) { |
|
++result; |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* Converts a Unicode `string` to an array. |
|
* |
|
* @private |
|
* @param {string} string The string to convert. |
|
* @returns {Array} Returns the converted array. |
|
*/ |
|
function unicodeToArray(string) { |
|
return string.match(reUnicode) || []; |
|
} |
|
|
|
/** |
|
* Splits a Unicode `string` into an array of its words. |
|
* |
|
* @private |
|
* @param {string} The string to inspect. |
|
* @returns {Array} Returns the words of `string`. |
|
*/ |
|
function unicodeWords(string) { |
|
return string.match(reUnicodeWord) || []; |
|
} |
|
|
|
/*--------------------------------------------------------------------------*/ |
|
|
|
/** |
|
* Create a new pristine `lodash` function using the `context` object. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 1.1.0 |
|
* @category Util |
|
* @param {Object} [context=root] The context object. |
|
* @returns {Function} Returns a new `lodash` function. |
|
* @example |
|
* |
|
* _.mixin({ 'foo': _.constant('foo') }); |
|
* |
|
* var lodash = _.runInContext(); |
|
* lodash.mixin({ 'bar': lodash.constant('bar') }); |
|
* |
|
* _.isFunction(_.foo); |
|
* // => true |
|
* _.isFunction(_.bar); |
|
* // => false |
|
* |
|
* lodash.isFunction(lodash.foo); |
|
* // => false |
|
* lodash.isFunction(lodash.bar); |
|
* // => true |
|
* |
|
* // Create a suped-up `defer` in Node.js. |
|
* var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; |
|
*/ |
|
var runInContext = (function runInContext(context) { |
|
context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps)); |
|
|
|
/** Built-in constructor references. */ |
|
var Array = context.Array, |
|
Date = context.Date, |
|
Error = context.Error, |
|
Function = context.Function, |
|
Math = context.Math, |
|
Object = context.Object, |
|
RegExp = context.RegExp, |
|
String = context.String, |
|
TypeError = context.TypeError; |
|
|
|
/** Used for built-in method references. */ |
|
var arrayProto = Array.prototype, |
|
funcProto = Function.prototype, |
|
objectProto = Object.prototype; |
|
|
|
/** Used to detect overreaching core-js shims. */ |
|
var coreJsData = context['__core-js_shared__']; |
|
|
|
/** 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 generate unique IDs. */ |
|
var idCounter = 0; |
|
|
|
/** 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 |
|
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) |
|
* of values. |
|
*/ |
|
var nativeObjectToString = objectProto.toString; |
|
|
|
/** Used to infer the `Object` constructor. */ |
|
var objectCtorString = funcToString.call(Object); |
|
|
|
/** Used to restore the original `_` reference in `_.noConflict`. */ |
|
var oldDash = root._; |
|
|
|
/** 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 Buffer = moduleExports ? context.Buffer : undefined, |
|
Symbol = context.Symbol, |
|
Uint8Array = context.Uint8Array, |
|
allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined, |
|
getPrototype = overArg(Object.getPrototypeOf, Object), |
|
objectCreate = Object.create, |
|
propertyIsEnumerable = objectProto.propertyIsEnumerable, |
|
splice = arrayProto.splice, |
|
spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined, |
|
symIterator = Symbol ? Symbol.iterator : undefined, |
|
symToStringTag = Symbol ? Symbol.toStringTag : undefined; |
|
|
|
var defineProperty = (function() { |
|
try { |
|
var func = getNative(Object, 'defineProperty'); |
|
func({}, '', {}); |
|
return func; |
|
} catch (e) {} |
|
}()); |
|
|
|
/** Mocked built-ins. */ |
|
var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout, |
|
ctxNow = Date && Date.now !== root.Date.now && Date.now, |
|
ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout; |
|
|
|
/* Built-in method references for those with the same name as other `lodash` methods. */ |
|
var nativeCeil = Math.ceil, |
|
nativeFloor = Math.floor, |
|
nativeGetSymbols = Object.getOwnPropertySymbols, |
|
nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, |
|
nativeIsFinite = context.isFinite, |
|
nativeJoin = arrayProto.join, |
|
nativeKeys = overArg(Object.keys, Object), |
|
nativeMax = Math.max, |
|
nativeMin = Math.min, |
|
nativeNow = Date.now, |
|
nativeParseInt = context.parseInt, |
|
nativeRandom = Math.random, |
|
nativeReverse = arrayProto.reverse; |
|
|
|
/* Built-in method references that are verified to be native. */ |
|
var DataView = getNative(context, 'DataView'), |
|
Map = getNative(context, 'Map'), |
|
Promise = getNative(context, 'Promise'), |
|
Set = getNative(context, 'Set'), |
|
WeakMap = getNative(context, 'WeakMap'), |
|
nativeCreate = getNative(Object, 'create'); |
|
|
|
/** Used to store function metadata. */ |
|
var metaMap = WeakMap && new WeakMap; |
|
|
|
/** Used to lookup unminified function names. */ |
|
var realNames = {}; |
|
|
|
/** Used to detect maps, sets, and weakmaps. */ |
|
var dataViewCtorString = toSource(DataView), |
|
mapCtorString = toSource(Map), |
|
promiseCtorString = toSource(Promise), |
|
setCtorString = toSource(Set), |
|
weakMapCtorString = toSource(WeakMap); |
|
|
|
/** Used to convert symbols to primitives and strings. */ |
|
var symbolProto = Symbol ? Symbol.prototype : undefined, |
|
symbolValueOf = symbolProto ? symbolProto.valueOf : undefined, |
|
symbolToString = symbolProto ? symbolProto.toString : undefined; |
|
|
|
/*------------------------------------------------------------------------*/ |
|
|
|
/** |
|
* Creates a `lodash` object which wraps `value` to enable implicit method |
|
* chain sequences. Methods that operate on and return arrays, collections, |
|
* and functions can be chained together. Methods that retrieve a single value |
|
* or may return a primitive value will automatically end the chain sequence |
|
* and return the unwrapped value. Otherwise, the value must be unwrapped |
|
* with `_#value`. |
|
* |
|
* Explicit chain sequences, which must be unwrapped with `_#value`, may be |
|
* enabled using `_.chain`. |
|
* |
|
* The execution of chained methods is lazy, that is, it's deferred until |
|
* `_#value` is implicitly or explicitly called. |
|
* |
|
* Lazy evaluation allows several methods to support shortcut fusion. |
|
* Shortcut fusion is an optimization to merge iteratee calls; this avoids |
|
* the creation of intermediate arrays and can greatly reduce the number of |
|
* iteratee executions. Sections of a chain sequence qualify for shortcut |
|
* fusion if the section is applied to an array and iteratees accept only |
|
* one argument. The heuristic for whether a section qualifies for shortcut |
|
* fusion is subject to change. |
|
* |
|
* Chaining is supported in custom builds as long as the `_#value` method is |
|
* directly or indirectly included in the build. |
|
* |
|
* In addition to lodash methods, wrappers have `Array` and `String` methods. |
|
* |
|
* The wrapper `Array` methods are: |
|
* `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift` |
|
* |
|
* The wrapper `String` methods are: |
|
* `replace` and `split` |
|
* |
|
* The wrapper methods that support shortcut fusion are: |
|
* `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`, |
|
* `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`, |
|
* `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray` |
|
* |
|
* The chainable wrapper methods are: |
|
* `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, |
|
* `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, |
|
* `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, |
|
* `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, |
|
* `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`, |
|
* `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`, |
|
* `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`, |
|
* `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, |
|
* `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`, |
|
* `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, |
|
* `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, |
|
* `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, |
|
* `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, |
|
* `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`, |
|
* `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, |
|
* `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`, |
|
* `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`, |
|
* `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`, |
|
* `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, |
|
* `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`, |
|
* `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, |
|
* `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`, |
|
* `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, |
|
* `zipObject`, `zipObjectDeep`, and `zipWith` |
|
* |
|
* The wrapper methods that are **not** chainable by default are: |
|
* `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`, |
|
* `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`, |
|
* `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`, |
|
* `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`, |
|
* `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`, |
|
* `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`, |
|
* `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`, |
|
* `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, |
|
* `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`, |
|
* `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, |
|
* `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, |
|
* `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, |
|
* `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`, |
|
* `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`, |
|
* `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`, |
|
* `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`, |
|
* `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, |
|
* `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`, |
|
* `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, |
|
* `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`, |
|
* `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`, |
|
* `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`, |
|
* `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, |
|
* `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, |
|
* `upperFirst`, `value`, and `words` |
|
* |
|
* @name _ |
|
* @constructor |
|
* @category Seq |
|
* @param {*} value The value to wrap in a `lodash` instance. |
|
* @returns {Object} Returns the new `lodash` wrapper instance. |
|
* @example |
|
* |
|
* function square(n) { |
|
* return n * n; |
|
* } |
|
* |
|
* var wrapped = _([1, 2, 3]); |
|
* |
|
* // Returns an unwrapped value. |
|
* wrapped.reduce(_.add); |
|
* // => 6 |
|
* |
|
* // Returns a wrapped value. |
|
* var squares = wrapped.map(square); |
|
* |
|
* _.isArray(squares); |
|
* // => false |
|
* |
|
* _.isArray(squares.value()); |
|
* // => true |
|
*/ |
|
function lodash(value) { |
|
if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { |
|
if (value instanceof LodashWrapper) { |
|
return value; |
|
} |
|
if (hasOwnProperty.call(value, '__wrapped__')) { |
|
return wrapperClone(value); |
|
} |
|
} |
|
return new LodashWrapper(value); |
|
} |
|
|
|
/** |
|
* The base implementation of `_.create` without support for assigning |
|
* properties to the created object. |
|
* |
|
* @private |
|
* @param {Object} proto The object to inherit from. |
|
* @returns {Object} Returns the new object. |
|
*/ |
|
var baseCreate = (function() { |
|
function object() {} |
|
return function(proto) { |
|
if (!isObject(proto)) { |
|
return {}; |
|
} |
|
if (objectCreate) { |
|
return objectCreate(proto); |
|
} |
|
object.prototype = proto; |
|
var result = new object; |
|
object.prototype = undefined; |
|
return result; |
|
}; |
|
}()); |
|
|
|
/** |
|
* The function whose prototype chain sequence wrappers inherit from. |
|
* |
|
* @private |
|
*/ |
|
function baseLodash() { |
|
// No operation performed. |
|
} |
|
|
|
/** |
|
* The base constructor for creating `lodash` wrapper objects. |
|
* |
|
* @private |
|
* @param {*} value The value to wrap. |
|
* @param {boolean} [chainAll] Enable explicit method chain sequences. |
|
*/ |
|
function LodashWrapper(value, chainAll) { |
|
this.__wrapped__ = value; |
|
this.__actions__ = []; |
|
this.__chain__ = !!chainAll; |
|
this.__index__ = 0; |
|
this.__values__ = undefined; |
|
} |
|
|
|
/** |
|
* By default, the template delimiters used by lodash are like those in |
|
* embedded Ruby (ERB) as well as ES2015 template strings. Change the |
|
* following template settings to use alternative delimiters. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @type {Object} |
|
*/ |
|
lodash.templateSettings = { |
|
|
|
/** |
|
* Used to detect `data` property values to be HTML-escaped. |
|
* |
|
* @memberOf _.templateSettings |
|
* @type {RegExp} |
|
*/ |
|
'escape': reEscape, |
|
|
|
/** |
|
* Used to detect code to be evaluated. |
|
* |
|
* @memberOf _.templateSettings |
|
* @type {RegExp} |
|
*/ |
|
'evaluate': reEvaluate, |
|
|
|
/** |
|
* Used to detect `data` property values to inject. |
|
* |
|
* @memberOf _.templateSettings |
|
* @type {RegExp} |
|
*/ |
|
'interpolate': reInterpolate, |
|
|
|
/** |
|
* Used to reference the data object in the template text. |
|
* |
|
* @memberOf _.templateSettings |
|
* @type {string} |
|
*/ |
|
'variable': '', |
|
|
|
/** |
|
* Used to import variables into the compiled template. |
|
* |
|
* @memberOf _.templateSettings |
|
* @type {Object} |
|
*/ |
|
'imports': { |
|
|
|
/** |
|
* A reference to the `lodash` function. |
|
* |
|
* @memberOf _.templateSettings.imports |
|
* @type {Function} |
|
*/ |
|
'_': lodash |
|
} |
|
}; |
|
|
|
// Ensure wrappers are instances of `baseLodash`. |
|
lodash.prototype = baseLodash.prototype; |
|
lodash.prototype.constructor = lodash; |
|
|
|
LodashWrapper.prototype = baseCreate(baseLodash.prototype); |
|
LodashWrapper.prototype.constructor = LodashWrapper; |
|
|
|
/*------------------------------------------------------------------------*/ |
|
|
|
/** |
|
* Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. |
|
* |
|
* @private |
|
* @constructor |
|
* @param {*} value The value to wrap. |
|
*/ |
|
function LazyWrapper(value) { |
|
this.__wrapped__ = value; |
|
this.__actions__ = []; |
|
this.__dir__ = 1; |
|
this.__filtered__ = false; |
|
this.__iteratees__ = []; |
|
this.__takeCount__ = MAX_ARRAY_LENGTH; |
|
this.__views__ = []; |
|
} |
|
|
|
/** |
|
* Creates a clone of the lazy wrapper object. |
|
* |
|
* @private |
|
* @name clone |
|
* @memberOf LazyWrapper |
|
* @returns {Object} Returns the cloned `LazyWrapper` object. |
|
*/ |
|
function lazyClone() { |
|
var result = new LazyWrapper(this.__wrapped__); |
|
result.__actions__ = copyArray(this.__actions__); |
|
result.__dir__ = this.__dir__; |
|
result.__filtered__ = this.__filtered__; |
|
result.__iteratees__ = copyArray(this.__iteratees__); |
|
result.__takeCount__ = this.__takeCount__; |
|
result.__views__ = copyArray(this.__views__); |
|
return result; |
|
} |
|
|
|
/** |
|
* Reverses the direction of lazy iteration. |
|
* |
|
* @private |
|
* @name reverse |
|
* @memberOf LazyWrapper |
|
* @returns {Object} Returns the new reversed `LazyWrapper` object. |
|
*/ |
|
function lazyReverse() { |
|
if (this.__filtered__) { |
|
var result = new LazyWrapper(this); |
|
result.__dir__ = -1; |
|
result.__filtered__ = true; |
|
} else { |
|
result = this.clone(); |
|
result.__dir__ *= -1; |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* Extracts the unwrapped value from its lazy wrapper. |
|
* |
|
* @private |
|
* @name value |
|
* @memberOf LazyWrapper |
|
* @returns {*} Returns the unwrapped value. |
|
*/ |
|
function lazyValue() { |
|
var array = this.__wrapped__.value(), |
|
dir = this.__dir__, |
|
isArr = isArray(array), |
|
isRight = dir < 0, |
|
arrLength = isArr ? array.length : 0, |
|
view = getView(0, arrLength, this.__views__), |
|
start = view.start, |
|
end = view.end, |
|
length = end - start, |
|
index = isRight ? end : (start - 1), |
|
iteratees = this.__iteratees__, |
|
iterLength = iteratees.length, |
|
resIndex = 0, |
|
takeCount = nativeMin(length, this.__takeCount__); |
|
|
|
if (!isArr || (!isRight && arrLength == length && takeCount == length)) { |
|
return baseWrapperValue(array, this.__actions__); |
|
} |
|
var result = []; |
|
|
|
outer: |
|
while (length-- && resIndex < takeCount) { |
|
index += dir; |
|
|
|
var iterIndex = -1, |
|
value = array[index]; |
|
|
|
while (++iterIndex < iterLength) { |
|
var data = iteratees[iterIndex], |
|
iteratee = data.iteratee, |
|
type = data.type, |
|
computed = iteratee(value); |
|
|
|
if (type == LAZY_MAP_FLAG) { |
|
value = computed; |
|
} else if (!computed) { |
|
if (type == LAZY_FILTER_FLAG) { |
|
continue outer; |
|
} else { |
|
break outer; |
|
} |
|
} |
|
} |
|
result[resIndex++] = value; |
|
} |
|
return result; |
|
} |
|
|
|
// Ensure `LazyWrapper` is an instance of `baseLodash`. |
|
LazyWrapper.prototype = baseCreate(baseLodash.prototype); |
|
LazyWrapper.prototype.constructor = LazyWrapper; |
|
|
|
/*------------------------------------------------------------------------*/ |
|
|
|
/** |
|
* Creates a hash object. |
|
* |
|
* @private |
|
* @constructor |
|
* @param {Array} [entries] The key-value pairs to cache. |
|
*/ |
|
function Hash(entries) { |
|
var index = -1, |
|
length = entries == null ? 0 : entries.length; |
|
|
|
this.clear(); |
|
while (++index < length) { |
|
var entry = entries[index]; |
|
this.set(entry[0], entry[1]); |
|
} |
|
} |
|
|
|
/** |
|
* Removes all key-value entries from the hash. |
|
* |
|
* @private |
|
* @name clear |
|
* @memberOf Hash |
|
*/ |
|
function hashClear() { |
|
this.__data__ = nativeCreate ? nativeCreate(null) : {}; |
|
this.size = 0; |
|
} |
|
|
|
/** |
|
* Removes `key` and its value from the hash. |
|
* |
|
* @private |
|
* @name delete |
|
* @memberOf Hash |
|
* @param {Object} hash The hash to modify. |
|
* @param {string} key The key of the value to remove. |
|
* @returns {boolean} Returns `true` if the entry was removed, else `false`. |
|
*/ |
|
function hashDelete(key) { |
|
var result = this.has(key) && delete this.__data__[key]; |
|
this.size -= result ? 1 : 0; |
|
return result; |
|
} |
|
|
|
/** |
|
* Gets the hash value for `key`. |
|
* |
|
* @private |
|
* @name get |
|
* @memberOf Hash |
|
* @param {string} key The key of the value to get. |
|
* @returns {*} Returns the entry value. |
|
*/ |
|
function hashGet(key) { |
|
var data = this.__data__; |
|
if (nativeCreate) { |
|
var result = data[key]; |
|
return result === HASH_UNDEFINED ? undefined : result; |
|
} |
|
return hasOwnProperty.call(data, key) ? data[key] : undefined; |
|
} |
|
|
|
/** |
|
* Checks if a hash value for `key` exists. |
|
* |
|
* @private |
|
* @name has |
|
* @memberOf Hash |
|
* @param {string} key The key of the entry to check. |
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. |
|
*/ |
|
function hashHas(key) { |
|
var data = this.__data__; |
|
return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); |
|
} |
|
|
|
/** |
|
* Sets the hash `key` to `value`. |
|
* |
|
* @private |
|
* @name set |
|
* @memberOf Hash |
|
* @param {string} key The key of the value to set. |
|
* @param {*} value The value to set. |
|
* @returns {Object} Returns the hash instance. |
|
*/ |
|
function hashSet(key, value) { |
|
var data = this.__data__; |
|
this.size += this.has(key) ? 0 : 1; |
|
data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; |
|
return this; |
|
} |
|
|
|
// Add methods to `Hash`. |
|
Hash.prototype.clear = hashClear; |
|
Hash.prototype['delete'] = hashDelete; |
|
Hash.prototype.get = hashGet; |
|
Hash.prototype.has = hashHas; |
|
Hash.prototype.set = hashSet; |
|
|
|
/*------------------------------------------------------------------------*/ |
|
|
|
/** |
|
* Creates an list cache object. |
|
* |
|
* @private |
|
* @constructor |
|
* @param {Array} [entries] The key-value pairs to cache. |
|
*/ |
|
function ListCache(entries) { |
|
var index = -1, |
|
length = entries == null ? 0 : entries.length; |
|
|
|
this.clear(); |
|
while (++index < length) { |
|
var entry = entries[index]; |
|
this.set(entry[0], entry[1]); |
|
} |
|
} |
|
|
|
/** |
|
* Removes all key-value entries from the list cache. |
|
* |
|
* @private |
|
* @name clear |
|
* @memberOf ListCache |
|
*/ |
|
function listCacheClear() { |
|
this.__data__ = []; |
|
this.size = 0; |
|
} |
|
|
|
/** |
|
* Removes `key` and its value from the list cache. |
|
* |
|
* @private |
|
* @name delete |
|
* @memberOf ListCache |
|
* @param {string} key The key of the value to remove. |
|
* @returns {boolean} Returns `true` if the entry was removed, else `false`. |
|
*/ |
|
function listCacheDelete(key) { |
|
var data = this.__data__, |
|
index = assocIndexOf(data, key); |
|
|
|
if (index < 0) { |
|
return false; |
|
} |
|
var lastIndex = data.length - 1; |
|
if (index == lastIndex) { |
|
data.pop(); |
|
} else { |
|
splice.call(data, index, 1); |
|
} |
|
--this.size; |
|
return true; |
|
} |
|
|
|
/** |
|
* Gets the list cache value for `key`. |
|
* |
|
* @private |
|
* @name get |
|
* @memberOf ListCache |
|
* @param {string} key The key of the value to get. |
|
* @returns {*} Returns the entry value. |
|
*/ |
|
function listCacheGet(key) { |
|
var data = this.__data__, |
|
index = assocIndexOf(data, key); |
|
|
|
return index < 0 ? undefined : data[index][1]; |
|
} |
|
|
|
/** |
|
* Checks if a list cache value for `key` exists. |
|
* |
|
* @private |
|
* @name has |
|
* @memberOf ListCache |
|
* @param {string} key The key of the entry to check. |
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. |
|
*/ |
|
function listCacheHas(key) { |
|
return assocIndexOf(this.__data__, key) > -1; |
|
} |
|
|
|
/** |
|
* Sets the list cache `key` to `value`. |
|
* |
|
* @private |
|
* @name set |
|
* @memberOf ListCache |
|
* @param {string} key The key of the value to set. |
|
* @param {*} value The value to set. |
|
* @returns {Object} Returns the list cache instance. |
|
*/ |
|
function listCacheSet(key, value) { |
|
var data = this.__data__, |
|
index = assocIndexOf(data, key); |
|
|
|
if (index < 0) { |
|
++this.size; |
|
data.push([key, value]); |
|
} else { |
|
data[index][1] = value; |
|
} |
|
return this; |
|
} |
|
|
|
// Add methods to `ListCache`. |
|
ListCache.prototype.clear = listCacheClear; |
|
ListCache.prototype['delete'] = listCacheDelete; |
|
ListCache.prototype.get = listCacheGet; |
|
ListCache.prototype.has = listCacheHas; |
|
ListCache.prototype.set = listCacheSet; |
|
|
|
/*------------------------------------------------------------------------*/ |
|
|
|
/** |
|
* Creates a map cache object to store key-value pairs. |
|
* |
|
* @private |
|
* @constructor |
|
* @param {Array} [entries] The key-value pairs to cache. |
|
*/ |
|
function MapCache(entries) { |
|
var index = -1, |
|
length = entries == null ? 0 : entries.length; |
|
|
|
this.clear(); |
|
while (++index < length) { |
|
var entry = entries[index]; |
|
this.set(entry[0], entry[1]); |
|
} |
|
} |
|
|
|
/** |
|
* Removes all key-value entries from the map. |
|
* |
|
* @private |
|
* @name clear |
|
* @memberOf MapCache |
|
*/ |
|
function mapCacheClear() { |
|
this.size = 0; |
|
this.__data__ = { |
|
'hash': new Hash, |
|
'map': new (Map || ListCache), |
|
'string': new Hash |
|
}; |
|
} |
|
|
|
/** |
|
* Removes `key` and its value from the map. |
|
* |
|
* @private |
|
* @name delete |
|
* @memberOf MapCache |
|
* @param {string} key The key of the value to remove. |
|
* @returns {boolean} Returns `true` if the entry was removed, else `false`. |
|
*/ |
|
function mapCacheDelete(key) { |
|
var result = getMapData(this, key)['delete'](key); |
|
this.size -= result ? 1 : 0; |
|
return result; |
|
} |
|
|
|
/** |
|
* Gets the map value for `key`. |
|
* |
|
* @private |
|
* @name get |
|
* @memberOf MapCache |
|
* @param {string} key The key of the value to get. |
|
* @returns {*} Returns the entry value. |
|
*/ |
|
function mapCacheGet(key) { |
|
return getMapData(this, key).get(key); |
|
} |
|
|
|
/** |
|
* Checks if a map value for `key` exists. |
|
* |
|
* @private |
|
* @name has |
|
* @memberOf MapCache |
|
* @param {string} key The key of the entry to check. |
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. |
|
*/ |
|
function mapCacheHas(key) { |
|
return getMapData(this, key).has(key); |
|
} |
|
|
|
/** |
|
* Sets the map `key` to `value`. |
|
* |
|
* @private |
|
* @name set |
|
* @memberOf MapCache |
|
* @param {string} key The key of the value to set. |
|
* @param {*} value The value to set. |
|
* @returns {Object} Returns the map cache instance. |
|
*/ |
|
function mapCacheSet(key, value) { |
|
var data = getMapData(this, key), |
|
size = data.size; |
|
|
|
data.set(key, value); |
|
this.size += data.size == size ? 0 : 1; |
|
return this; |
|
} |
|
|
|
// Add methods to `MapCache`. |
|
MapCache.prototype.clear = mapCacheClear; |
|
MapCache.prototype['delete'] = mapCacheDelete; |
|
MapCache.prototype.get = mapCacheGet; |
|
MapCache.prototype.has = mapCacheHas; |
|
MapCache.prototype.set = mapCacheSet; |
|
|
|
/*------------------------------------------------------------------------*/ |
|
|
|
/** |
|
* |
|
* Creates an array cache object to store unique values. |
|
* |
|
* @private |
|
* @constructor |
|
* @param {Array} [values] The values to cache. |
|
*/ |
|
function SetCache(values) { |
|
var index = -1, |
|
length = values == null ? 0 : values.length; |
|
|
|
this.__data__ = new MapCache; |
|
while (++index < length) { |
|
this.add(values[index]); |
|
} |
|
} |
|
|
|
/** |
|
* Adds `value` to the array cache. |
|
* |
|
* @private |
|
* @name add |
|
* @memberOf SetCache |
|
* @alias push |
|
* @param {*} value The value to cache. |
|
* @returns {Object} Returns the cache instance. |
|
*/ |
|
function setCacheAdd(value) { |
|
this.__data__.set(value, HASH_UNDEFINED); |
|
return this; |
|
} |
|
|
|
/** |
|
* Checks if `value` is in the array cache. |
|
* |
|
* @private |
|
* @name has |
|
* @memberOf SetCache |
|
* @param {*} value The value to search for. |
|
* @returns {number} Returns `true` if `value` is found, else `false`. |
|
*/ |
|
function setCacheHas(value) { |
|
return this.__data__.has(value); |
|
} |
|
|
|
// Add methods to `SetCache`. |
|
SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; |
|
SetCache.prototype.has = setCacheHas; |
|
|
|
/*------------------------------------------------------------------------*/ |
|
|
|
/** |
|
* Creates a stack cache object to store key-value pairs. |
|
* |
|
* @private |
|
* @constructor |
|
* @param {Array} [entries] The key-value pairs to cache. |
|
*/ |
|
function Stack(entries) { |
|
var data = this.__data__ = new ListCache(entries); |
|
this.size = data.size; |
|
} |
|
|
|
/** |
|
* Removes all key-value entries from the stack. |
|
* |
|
* @private |
|
* @name clear |
|
* @memberOf Stack |
|
*/ |
|
function stackClear() { |
|
this.__data__ = new ListCache; |
|
this.size = 0; |
|
} |
|
|
|
/** |
|
* Removes `key` and its value from the stack. |
|
* |
|
* @private |
|
* @name delete |
|
* @memberOf Stack |
|
* @param {string} key The key of the value to remove. |
|
* @returns {boolean} Returns `true` if the entry was removed, else `false`. |
|
*/ |
|
function stackDelete(key) { |
|
var data = this.__data__, |
|
result = data['delete'](key); |
|
|
|
this.size = data.size; |
|
return result; |
|
} |
|
|
|
/** |
|
* Gets the stack value for `key`. |
|
* |
|
* @private |
|
* @name get |
|
* @memberOf Stack |
|
* @param {string} key The key of the value to get. |
|
* @returns {*} Returns the entry value. |
|
*/ |
|
function stackGet(key) { |
|
return this.__data__.get(key); |
|
} |
|
|
|
/** |
|
* Checks if a stack value for `key` exists. |
|
* |
|
* @private |
|
* @name has |
|
* @memberOf Stack |
|
* @param {string} key The key of the entry to check. |
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. |
|
*/ |
|
function stackHas(key) { |
|
return this.__data__.has(key); |
|
} |
|
|
|
/** |
|
* Sets the stack `key` to `value`. |
|
* |
|
* @private |
|
* @name set |
|
* @memberOf Stack |
|
* @param {string} key The key of the value to set. |
|
* @param {*} value The value to set. |
|
* @returns {Object} Returns the stack cache instance. |
|
*/ |
|
function stackSet(key, value) { |
|
var data = this.__data__; |
|
if (data instanceof ListCache) { |
|
var pairs = data.__data__; |
|
if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { |
|
pairs.push([key, value]); |
|
this.size = ++data.size; |
|
return this; |
|
} |
|
data = this.__data__ = new MapCache(pairs); |
|
} |
|
data.set(key, value); |
|
this.size = data.size; |
|
return this; |
|
} |
|
|
|
// Add methods to `Stack`. |
|
Stack.prototype.clear = stackClear; |
|
Stack.prototype['delete'] = stackDelete; |
|
Stack.prototype.get = stackGet; |
|
Stack.prototype.has = stackHas; |
|
Stack.prototype.set = stackSet; |
|
|
|
/*------------------------------------------------------------------------*/ |
|
|
|
/** |
|
* Creates an array of the enumerable property names of the array-like `value`. |
|
* |
|
* @private |
|
* @param {*} value The value to query. |
|
* @param {boolean} inherited Specify returning inherited property names. |
|
* @returns {Array} Returns the array of property names. |
|
*/ |
|
function arrayLikeKeys(value, inherited) { |
|
var isArr = isArray(value), |
|
isArg = !isArr && isArguments(value), |
|
isBuff = !isArr && !isArg && isBuffer(value), |
|
isType = !isArr && !isArg && !isBuff && isTypedArray(value), |
|
skipIndexes = isArr || isArg || isBuff || isType, |
|
result = skipIndexes ? baseTimes(value.length, String) : [], |
|
length = result.length; |
|
|
|
for (var key in value) { |
|
if ((inherited || hasOwnProperty.call(value, key)) && |
|
!(skipIndexes && ( |
|
// Safari 9 has enumerable `arguments.length` in strict mode. |
|
key == 'length' || |
|
// Node.js 0.10 has enumerable non-index properties on buffers. |
|
(isBuff && (key == 'offset' || key == 'parent')) || |
|
// PhantomJS 2 has enumerable non-index properties on typed arrays. |
|
(isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || |
|
// Skip index properties. |
|
isIndex(key, length) |
|
))) { |
|
result.push(key); |
|
} |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* A specialized version of `_.sample` for arrays. |
|
* |
|
* @private |
|
* @param {Array} array The array to sample. |
|
* @returns {*} Returns the random element. |
|
*/ |
|
function arraySample(array) { |
|
var length = array.length; |
|
return length ? array[baseRandom(0, length - 1)] : undefined; |
|
} |
|
|
|
/** |
|
* A specialized version of `_.sampleSize` for arrays. |
|
* |
|
* @private |
|
* @param {Array} array The array to sample. |
|
* @param {number} n The number of elements to sample. |
|
* @returns {Array} Returns the random elements. |
|
*/ |
|
function arraySampleSize(array, n) { |
|
return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length)); |
|
} |
|
|
|
/** |
|
* A specialized version of `_.shuffle` for arrays. |
|
* |
|
* @private |
|
* @param {Array} array The array to shuffle. |
|
* @returns {Array} Returns the new shuffled array. |
|
*/ |
|
function arrayShuffle(array) { |
|
return shuffleSelf(copyArray(array)); |
|
} |
|
|
|
/** |
|
* This function is like `assignValue` except that it doesn't assign |
|
* `undefined` values. |
|
* |
|
* @private |
|
* @param {Object} object The object to modify. |
|
* @param {string} key The key of the property to assign. |
|
* @param {*} value The value to assign. |
|
*/ |
|
function assignMergeValue(object, key, value) { |
|
if ((value !== undefined && !eq(object[key], value)) || |
|
(value === undefined && !(key in object))) { |
|
baseAssignValue(object, key, value); |
|
} |
|
} |
|
|
|
/** |
|
* Assigns `value` to `key` of `object` if the existing value is not equivalent |
|
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) |
|
* for equality comparisons. |
|
* |
|
* @private |
|
* @param {Object} object The object to modify. |
|
* @param {string} key The key of the property to assign. |
|
* @param {*} value The value to assign. |
|
*/ |
|
function assignValue(object, key, value) { |
|
var objValue = object[key]; |
|
if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || |
|
(value === undefined && !(key in object))) { |
|
baseAssignValue(object, key, value); |
|
} |
|
} |
|
|
|
/** |
|
* Gets the index at which the `key` is found in `array` of key-value pairs. |
|
* |
|
* @private |
|
* @param {Array} array The array to inspect. |
|
* @param {*} key The key to search for. |
|
* @returns {number} Returns the index of the matched value, else `-1`. |
|
*/ |
|
function assocIndexOf(array, key) { |
|
var length = array.length; |
|
while (length--) { |
|
if (eq(array[length][0], key)) { |
|
return length; |
|
} |
|
} |
|
return -1; |
|
} |
|
|
|
/** |
|
* Aggregates elements of `collection` on `accumulator` with keys transformed |
|
* by `iteratee` and values set by `setter`. |
|
* |
|
* @private |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {Function} setter The function to set `accumulator` values. |
|
* @param {Function} iteratee The iteratee to transform keys. |
|
* @param {Object} accumulator The initial aggregated object. |
|
* @returns {Function} Returns `accumulator`. |
|
*/ |
|
function baseAggregator(collection, setter, iteratee, accumulator) { |
|
baseEach(collection, function(value, key, collection) { |
|
setter(accumulator, value, iteratee(value), collection); |
|
}); |
|
return accumulator; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.assign` without support for multiple sources |
|
* or `customizer` functions. |
|
* |
|
* @private |
|
* @param {Object} object The destination object. |
|
* @param {Object} source The source object. |
|
* @returns {Object} Returns `object`. |
|
*/ |
|
function baseAssign(object, source) { |
|
return object && copyObject(source, keys(source), object); |
|
} |
|
|
|
/** |
|
* The base implementation of `_.assignIn` without support for multiple sources |
|
* or `customizer` functions. |
|
* |
|
* @private |
|
* @param {Object} object The destination object. |
|
* @param {Object} source The source object. |
|
* @returns {Object} Returns `object`. |
|
*/ |
|
function baseAssignIn(object, source) { |
|
return object && copyObject(source, keysIn(source), object); |
|
} |
|
|
|
/** |
|
* The base implementation of `assignValue` and `assignMergeValue` without |
|
* value checks. |
|
* |
|
* @private |
|
* @param {Object} object The object to modify. |
|
* @param {string} key The key of the property to assign. |
|
* @param {*} value The value to assign. |
|
*/ |
|
function baseAssignValue(object, key, value) { |
|
if (key == '__proto__' && defineProperty) { |
|
defineProperty(object, key, { |
|
'configurable': true, |
|
'enumerable': true, |
|
'value': value, |
|
'writable': true |
|
}); |
|
} else { |
|
object[key] = value; |
|
} |
|
} |
|
|
|
/** |
|
* The base implementation of `_.at` without support for individual paths. |
|
* |
|
* @private |
|
* @param {Object} object The object to iterate over. |
|
* @param {string[]} paths The property paths to pick. |
|
* @returns {Array} Returns the picked elements. |
|
*/ |
|
function baseAt(object, paths) { |
|
var index = -1, |
|
length = paths.length, |
|
result = Array(length), |
|
skip = object == null; |
|
|
|
while (++index < length) { |
|
result[index] = skip ? undefined : get(object, paths[index]); |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.clamp` which doesn't coerce arguments. |
|
* |
|
* @private |
|
* @param {number} number The number to clamp. |
|
* @param {number} [lower] The lower bound. |
|
* @param {number} upper The upper bound. |
|
* @returns {number} Returns the clamped number. |
|
*/ |
|
function baseClamp(number, lower, upper) { |
|
if (number === number) { |
|
if (upper !== undefined) { |
|
number = number <= upper ? number : upper; |
|
} |
|
if (lower !== undefined) { |
|
number = number >= lower ? number : lower; |
|
} |
|
} |
|
return number; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.clone` and `_.cloneDeep` which tracks |
|
* traversed objects. |
|
* |
|
* @private |
|
* @param {*} value The value to clone. |
|
* @param {boolean} bitmask The bitmask flags. |
|
* 1 - Deep clone |
|
* 2 - Flatten inherited properties |
|
* 4 - Clone symbols |
|
* @param {Function} [customizer] The function to customize cloning. |
|
* @param {string} [key] The key of `value`. |
|
* @param {Object} [object] The parent object of `value`. |
|
* @param {Object} [stack] Tracks traversed objects and their clone counterparts. |
|
* @returns {*} Returns the cloned value. |
|
*/ |
|
function baseClone(value, bitmask, customizer, key, object, stack) { |
|
var result, |
|
isDeep = bitmask & CLONE_DEEP_FLAG, |
|
isFlat = bitmask & CLONE_FLAT_FLAG, |
|
isFull = bitmask & CLONE_SYMBOLS_FLAG; |
|
|
|
if (customizer) { |
|
result = object ? customizer(value, key, object, stack) : customizer(value); |
|
} |
|
if (result !== undefined) { |
|
return result; |
|
} |
|
if (!isObject(value)) { |
|
return value; |
|
} |
|
var isArr = isArray(value); |
|
if (isArr) { |
|
result = initCloneArray(value); |
|
if (!isDeep) { |
|
return copyArray(value, result); |
|
} |
|
} else { |
|
var tag = getTag(value), |
|
isFunc = tag == funcTag || tag == genTag; |
|
|
|
if (isBuffer(value)) { |
|
return cloneBuffer(value, isDeep); |
|
} |
|
if (tag == objectTag || tag == argsTag || (isFunc && !object)) { |
|
result = (isFlat || isFunc) ? {} : initCloneObject(value); |
|
if (!isDeep) { |
|
return isFlat |
|
? copySymbolsIn(value, baseAssignIn(result, value)) |
|
: copySymbols(value, baseAssign(result, value)); |
|
} |
|
} else { |
|
if (!cloneableTags[tag]) { |
|
return object ? value : {}; |
|
} |
|
result = initCloneByTag(value, tag, isDeep); |
|
} |
|
} |
|
// Check for circular references and return its corresponding clone. |
|
stack || (stack = new Stack); |
|
var stacked = stack.get(value); |
|
if (stacked) { |
|
return stacked; |
|
} |
|
stack.set(value, result); |
|
|
|
if (isSet(value)) { |
|
value.forEach(function(subValue) { |
|
result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); |
|
}); |
|
|
|
return result; |
|
} |
|
|
|
if (isMap(value)) { |
|
value.forEach(function(subValue, key) { |
|
result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); |
|
}); |
|
|
|
return result; |
|
} |
|
|
|
var keysFunc = isFull |
|
? (isFlat ? getAllKeysIn : getAllKeys) |
|
: (isFlat ? keysIn : keys); |
|
|
|
var props = isArr ? undefined : keysFunc(value); |
|
arrayEach(props || value, function(subValue, key) { |
|
if (props) { |
|
key = subValue; |
|
subValue = value[key]; |
|
} |
|
// Recursively populate clone (susceptible to call stack limits). |
|
assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); |
|
}); |
|
return result; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.conforms` which doesn't clone `source`. |
|
* |
|
* @private |
|
* @param {Object} source The object of property predicates to conform to. |
|
* @returns {Function} Returns the new spec function. |
|
*/ |
|
function baseConforms(source) { |
|
var props = keys(source); |
|
return function(object) { |
|
return baseConformsTo(object, source, props); |
|
}; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.conformsTo` which accepts `props` to check. |
|
* |
|
* @private |
|
* @param {Object} object The object to inspect. |
|
* @param {Object} source The object of property predicates to conform to. |
|
* @returns {boolean} Returns `true` if `object` conforms, else `false`. |
|
*/ |
|
function baseConformsTo(object, source, props) { |
|
var length = props.length; |
|
if (object == null) { |
|
return !length; |
|
} |
|
object = Object(object); |
|
while (length--) { |
|
var key = props[length], |
|
predicate = source[key], |
|
value = object[key]; |
|
|
|
if ((value === undefined && !(key in object)) || !predicate(value)) { |
|
return false; |
|
} |
|
} |
|
return true; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.delay` and `_.defer` which accepts `args` |
|
* to provide to `func`. |
|
* |
|
* @private |
|
* @param {Function} func The function to delay. |
|
* @param {number} wait The number of milliseconds to delay invocation. |
|
* @param {Array} args The arguments to provide to `func`. |
|
* @returns {number|Object} Returns the timer id or timeout object. |
|
*/ |
|
function baseDelay(func, wait, args) { |
|
if (typeof func != 'function') { |
|
throw new TypeError(FUNC_ERROR_TEXT); |
|
} |
|
return setTimeout(function() { func.apply(undefined, args); }, wait); |
|
} |
|
|
|
/** |
|
* The base implementation of methods like `_.difference` without support |
|
* for excluding multiple arrays or iteratee shorthands. |
|
* |
|
* @private |
|
* @param {Array} array The array to inspect. |
|
* @param {Array} values The values to exclude. |
|
* @param {Function} [iteratee] The iteratee invoked per element. |
|
* @param {Function} [comparator] The comparator invoked per element. |
|
* @returns {Array} Returns the new array of filtered values. |
|
*/ |
|
function baseDifference(array, values, iteratee, comparator) { |
|
var index = -1, |
|
includes = arrayIncludes, |
|
isCommon = true, |
|
length = array.length, |
|
result = [], |
|
valuesLength = values.length; |
|
|
|
if (!length) { |
|
return result; |
|
} |
|
if (iteratee) { |
|
values = arrayMap(values, baseUnary(iteratee)); |
|
} |
|
if (comparator) { |
|
includes = arrayIncludesWith; |
|
isCommon = false; |
|
} |
|
else if (values.length >= LARGE_ARRAY_SIZE) { |
|
includes = cacheHas; |
|
isCommon = false; |
|
values = new SetCache(values); |
|
} |
|
outer: |
|
while (++index < length) { |
|
var value = array[index], |
|
computed = iteratee == null ? value : iteratee(value); |
|
|
|
value = (comparator || value !== 0) ? value : 0; |
|
if (isCommon && computed === computed) { |
|
var valuesIndex = valuesLength; |
|
while (valuesIndex--) { |
|
if (values[valuesIndex] === computed) { |
|
continue outer; |
|
} |
|
} |
|
result.push(value); |
|
} |
|
else if (!includes(values, computed, comparator)) { |
|
result.push(value); |
|
} |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.forEach` without support for iteratee shorthands. |
|
* |
|
* @private |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {Function} iteratee The function invoked per iteration. |
|
* @returns {Array|Object} Returns `collection`. |
|
*/ |
|
var baseEach = createBaseEach(baseForOwn); |
|
|
|
/** |
|
* The base implementation of `_.forEachRight` without support for iteratee shorthands. |
|
* |
|
* @private |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {Function} iteratee The function invoked per iteration. |
|
* @returns {Array|Object} Returns `collection`. |
|
*/ |
|
var baseEachRight = createBaseEach(baseForOwnRight, true); |
|
|
|
/** |
|
* The base implementation of `_.every` without support for iteratee shorthands. |
|
* |
|
* @private |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {Function} predicate The function invoked per iteration. |
|
* @returns {boolean} Returns `true` if all elements pass the predicate check, |
|
* else `false` |
|
*/ |
|
function baseEvery(collection, predicate) { |
|
var result = true; |
|
baseEach(collection, function(value, index, collection) { |
|
result = !!predicate(value, index, collection); |
|
return result; |
|
}); |
|
return result; |
|
} |
|
|
|
/** |
|
* The base implementation of methods like `_.max` and `_.min` which accepts a |
|
* `comparator` to determine the extremum value. |
|
* |
|
* @private |
|
* @param {Array} array The array to iterate over. |
|
* @param {Function} iteratee The iteratee invoked per iteration. |
|
* @param {Function} comparator The comparator used to compare values. |
|
* @returns {*} Returns the extremum value. |
|
*/ |
|
function baseExtremum(array, iteratee, comparator) { |
|
var index = -1, |
|
length = array.length; |
|
|
|
while (++index < length) { |
|
var value = array[index], |
|
current = iteratee(value); |
|
|
|
if (current != null && (computed === undefined |
|
? (current === current && !isSymbol(current)) |
|
: comparator(current, computed) |
|
)) { |
|
var computed = current, |
|
result = value; |
|
} |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.fill` without an iteratee call guard. |
|
* |
|
* @private |
|
* @param {Array} array The array to fill. |
|
* @param {*} value The value to fill `array` with. |
|
* @param {number} [start=0] The start position. |
|
* @param {number} [end=array.length] The end position. |
|
* @returns {Array} Returns `array`. |
|
*/ |
|
function baseFill(array, value, start, end) { |
|
var length = array.length; |
|
|
|
start = toInteger(start); |
|
if (start < 0) { |
|
start = -start > length ? 0 : (length + start); |
|
} |
|
end = (end === undefined || end > length) ? length : toInteger(end); |
|
if (end < 0) { |
|
end += length; |
|
} |
|
end = start > end ? 0 : toLength(end); |
|
while (start < end) { |
|
array[start++] = value; |
|
} |
|
return array; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.filter` without support for iteratee shorthands. |
|
* |
|
* @private |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {Function} predicate The function invoked per iteration. |
|
* @returns {Array} Returns the new filtered array. |
|
*/ |
|
function baseFilter(collection, predicate) { |
|
var result = []; |
|
baseEach(collection, function(value, index, collection) { |
|
if (predicate(value, index, collection)) { |
|
result.push(value); |
|
} |
|
}); |
|
return result; |
|
} |
|
|
|
/** |
|
* 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 `baseForOwn` which iterates over `object` |
|
* properties returned by `keysFunc` and invokes `iteratee` for each property. |
|
* Iteratee functions may exit iteration early by explicitly returning `false`. |
|
* |
|
* @private |
|
* @param {Object} object The object to iterate over. |
|
* @param {Function} iteratee The function invoked per iteration. |
|
* @param {Function} keysFunc The function to get the keys of `object`. |
|
* @returns {Object} Returns `object`. |
|
*/ |
|
var baseFor = createBaseFor(); |
|
|
|
/** |
|
* This function is like `baseFor` except that it iterates over properties |
|
* in the opposite order. |
|
* |
|
* @private |
|
* @param {Object} object The object to iterate over. |
|
* @param {Function} iteratee The function invoked per iteration. |
|
* @param {Function} keysFunc The function to get the keys of `object`. |
|
* @returns {Object} Returns `object`. |
|
*/ |
|
var baseForRight = createBaseFor(true); |
|
|
|
/** |
|
* The base implementation of `_.forOwn` without support for iteratee shorthands. |
|
* |
|
* @private |
|
* @param {Object} object The object to iterate over. |
|
* @param {Function} iteratee The function invoked per iteration. |
|
* @returns {Object} Returns `object`. |
|
*/ |
|
function baseForOwn(object, iteratee) { |
|
return object && baseFor(object, iteratee, keys); |
|
} |
|
|
|
/** |
|
* The base implementation of `_.forOwnRight` without support for iteratee shorthands. |
|
* |
|
* @private |
|
* @param {Object} object The object to iterate over. |
|
* @param {Function} iteratee The function invoked per iteration. |
|
* @returns {Object} Returns `object`. |
|
*/ |
|
function baseForOwnRight(object, iteratee) { |
|
return object && baseForRight(object, iteratee, keys); |
|
} |
|
|
|
/** |
|
* The base implementation of `_.functions` which creates an array of |
|
* `object` function property names filtered from `props`. |
|
* |
|
* @private |
|
* @param {Object} object The object to inspect. |
|
* @param {Array} props The property names to filter. |
|
* @returns {Array} Returns the function names. |
|
*/ |
|
function baseFunctions(object, props) { |
|
return arrayFilter(props, function(key) { |
|
return isFunction(object[key]); |
|
}); |
|
} |
|
|
|
/** |
|
* The base implementation of `_.get` without support for default values. |
|
* |
|
* @private |
|
* @param {Object} object The object to query. |
|
* @param {Array|string} path The path of the property to get. |
|
* @returns {*} Returns the resolved value. |
|
*/ |
|
function baseGet(object, path) { |
|
path = castPath(path, object); |
|
|
|
var index = 0, |
|
length = path.length; |
|
|
|
while (object != null && index < length) { |
|
object = object[toKey(path[index++])]; |
|
} |
|
return (index && index == length) ? object : undefined; |
|
} |
|
|
|
/** |
|
* The base implementation of `getAllKeys` and `getAllKeysIn` which uses |
|
* `keysFunc` and `symbolsFunc` to get the enumerable property names and |
|
* symbols of `object`. |
|
* |
|
* @private |
|
* @param {Object} object The object to query. |
|
* @param {Function} keysFunc The function to get the keys of `object`. |
|
* @param {Function} symbolsFunc The function to get the symbols of `object`. |
|
* @returns {Array} Returns the array of property names and symbols. |
|
*/ |
|
function baseGetAllKeys(object, keysFunc, symbolsFunc) { |
|
var result = keysFunc(object); |
|
return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); |
|
} |
|
|
|
/** |
|
* The base implementation of `getTag` without fallbacks for buggy environments. |
|
* |
|
* @private |
|
* @param {*} value The value to query. |
|
* @returns {string} Returns the `toStringTag`. |
|
*/ |
|
function baseGetTag(value) { |
|
if (value == null) { |
|
return value === undefined ? undefinedTag : nullTag; |
|
} |
|
return (symToStringTag && symToStringTag in Object(value)) |
|
? getRawTag(value) |
|
: objectToString(value); |
|
} |
|
|
|
/** |
|
* The base implementation of `_.gt` which doesn't coerce arguments. |
|
* |
|
* @private |
|
* @param {*} value The value to compare. |
|
* @param {*} other The other value to compare. |
|
* @returns {boolean} Returns `true` if `value` is greater than `other`, |
|
* else `false`. |
|
*/ |
|
function baseGt(value, other) { |
|
return value > other; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.has` without support for deep paths. |
|
* |
|
* @private |
|
* @param {Object} [object] The object to query. |
|
* @param {Array|string} key The key to check. |
|
* @returns {boolean} Returns `true` if `key` exists, else `false`. |
|
*/ |
|
function baseHas(object, key) { |
|
return object != null && hasOwnProperty.call(object, key); |
|
} |
|
|
|
/** |
|
* The base implementation of `_.hasIn` without support for deep paths. |
|
* |
|
* @private |
|
* @param {Object} [object] The object to query. |
|
* @param {Array|string} key The key to check. |
|
* @returns {boolean} Returns `true` if `key` exists, else `false`. |
|
*/ |
|
function baseHasIn(object, key) { |
|
return object != null && key in Object(object); |
|
} |
|
|
|
/** |
|
* The base implementation of `_.inRange` which doesn't coerce arguments. |
|
* |
|
* @private |
|
* @param {number} number The number to check. |
|
* @param {number} start The start of the range. |
|
* @param {number} end The end of the range. |
|
* @returns {boolean} Returns `true` if `number` is in the range, else `false`. |
|
*/ |
|
function baseInRange(number, start, end) { |
|
return number >= nativeMin(start, end) && number < nativeMax(start, end); |
|
} |
|
|
|
/** |
|
* The base implementation of methods like `_.intersection`, without support |
|
* for iteratee shorthands, that accepts an array of arrays to inspect. |
|
* |
|
* @private |
|
* @param {Array} arrays The arrays to inspect. |
|
* @param {Function} [iteratee] The iteratee invoked per element. |
|
* @param {Function} [comparator] The comparator invoked per element. |
|
* @returns {Array} Returns the new array of shared values. |
|
*/ |
|
function baseIntersection(arrays, iteratee, comparator) { |
|
var includes = comparator ? arrayIncludesWith : arrayIncludes, |
|
length = arrays[0].length, |
|
othLength = arrays.length, |
|
othIndex = othLength, |
|
caches = Array(othLength), |
|
maxLength = Infinity, |
|
result = []; |
|
|
|
while (othIndex--) { |
|
var array = arrays[othIndex]; |
|
if (othIndex && iteratee) { |
|
array = arrayMap(array, baseUnary(iteratee)); |
|
} |
|
maxLength = nativeMin(array.length, maxLength); |
|
caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120)) |
|
? new SetCache(othIndex && array) |
|
: undefined; |
|
} |
|
array = arrays[0]; |
|
|
|
var index = -1, |
|
seen = caches[0]; |
|
|
|
outer: |
|
while (++index < length && result.length < maxLength) { |
|
var value = array[index], |
|
computed = iteratee ? iteratee(value) : value; |
|
|
|
value = (comparator || value !== 0) ? value : 0; |
|
if (!(seen |
|
? cacheHas(seen, computed) |
|
: includes(result, computed, comparator) |
|
)) { |
|
othIndex = othLength; |
|
while (--othIndex) { |
|
var cache = caches[othIndex]; |
|
if (!(cache |
|
? cacheHas(cache, computed) |
|
: includes(arrays[othIndex], computed, comparator)) |
|
) { |
|
continue outer; |
|
} |
|
} |
|
if (seen) { |
|
seen.push(computed); |
|
} |
|
result.push(value); |
|
} |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.invert` and `_.invertBy` which inverts |
|
* `object` with values transformed by `iteratee` and set by `setter`. |
|
* |
|
* @private |
|
* @param {Object} object The object to iterate over. |
|
* @param {Function} setter The function to set `accumulator` values. |
|
* @param {Function} iteratee The iteratee to transform values. |
|
* @param {Object} accumulator The initial inverted object. |
|
* @returns {Function} Returns `accumulator`. |
|
*/ |
|
function baseInverter(object, setter, iteratee, accumulator) { |
|
baseForOwn(object, function(value, key, object) { |
|
setter(accumulator, iteratee(value), key, object); |
|
}); |
|
return accumulator; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.invoke` without support for individual |
|
* method arguments. |
|
* |
|
* @private |
|
* @param {Object} object The object to query. |
|
* @param {Array|string} path The path of the method to invoke. |
|
* @param {Array} args The arguments to invoke the method with. |
|
* @returns {*} Returns the result of the invoked method. |
|
*/ |
|
function baseInvoke(object, path, args) { |
|
path = castPath(path, object); |
|
object = parent(object, path); |
|
var func = object == null ? object : object[toKey(last(path))]; |
|
return func == null ? undefined : apply(func, object, args); |
|
} |
|
|
|
/** |
|
* The base implementation of `_.isArguments`. |
|
* |
|
* @private |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is an `arguments` object, |
|
*/ |
|
function baseIsArguments(value) { |
|
return isObjectLike(value) && baseGetTag(value) == argsTag; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.isArrayBuffer` without Node.js optimizations. |
|
* |
|
* @private |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is an array buffer, else `false`. |
|
*/ |
|
function baseIsArrayBuffer(value) { |
|
return isObjectLike(value) && baseGetTag(value) == arrayBufferTag; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.isDate` without Node.js optimizations. |
|
* |
|
* @private |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is a date object, else `false`. |
|
*/ |
|
function baseIsDate(value) { |
|
return isObjectLike(value) && baseGetTag(value) == dateTag; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.isEqual` which supports partial comparisons |
|
* and tracks traversed objects. |
|
* |
|
* @private |
|
* @param {*} value The value to compare. |
|
* @param {*} other The other value to compare. |
|
* @param {boolean} bitmask The bitmask flags. |
|
* 1 - Unordered comparison |
|
* 2 - Partial comparison |
|
* @param {Function} [customizer] The function to customize comparisons. |
|
* @param {Object} [stack] Tracks traversed `value` and `other` objects. |
|
* @returns {boolean} Returns `true` if the values are equivalent, else `false`. |
|
*/ |
|
function baseIsEqual(value, other, bitmask, customizer, stack) { |
|
if (value === other) { |
|
return true; |
|
} |
|
if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) { |
|
return value !== value && other !== other; |
|
} |
|
return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); |
|
} |
|
|
|
/** |
|
* A specialized version of `baseIsEqual` for arrays and objects which performs |
|
* deep comparisons and tracks traversed objects enabling objects with circular |
|
* references to be compared. |
|
* |
|
* @private |
|
* @param {Object} object The object to compare. |
|
* @param {Object} other The other object to compare. |
|
* @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. |
|
* @param {Function} customizer The function to customize comparisons. |
|
* @param {Function} equalFunc The function to determine equivalents of values. |
|
* @param {Object} [stack] Tracks traversed `object` and `other` objects. |
|
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`. |
|
*/ |
|
function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { |
|
var objIsArr = isArray(object), |
|
othIsArr = isArray(other), |
|
objTag = objIsArr ? arrayTag : getTag(object), |
|
othTag = othIsArr ? arrayTag : getTag(other); |
|
|
|
objTag = objTag == argsTag ? objectTag : objTag; |
|
othTag = othTag == argsTag ? objectTag : othTag; |
|
|
|
var objIsObj = objTag == objectTag, |
|
othIsObj = othTag == objectTag, |
|
isSameTag = objTag == othTag; |
|
|
|
if (isSameTag && isBuffer(object)) { |
|
if (!isBuffer(other)) { |
|
return false; |
|
} |
|
objIsArr = true; |
|
objIsObj = false; |
|
} |
|
if (isSameTag && !objIsObj) { |
|
stack || (stack = new Stack); |
|
return (objIsArr || isTypedArray(object)) |
|
? equalArrays(object, other, bitmask, customizer, equalFunc, stack) |
|
: equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); |
|
} |
|
if (!(bitmask & COMPARE_PARTIAL_FLAG)) { |
|
var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), |
|
othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); |
|
|
|
if (objIsWrapped || othIsWrapped) { |
|
var objUnwrapped = objIsWrapped ? object.value() : object, |
|
othUnwrapped = othIsWrapped ? other.value() : other; |
|
|
|
stack || (stack = new Stack); |
|
return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); |
|
} |
|
} |
|
if (!isSameTag) { |
|
return false; |
|
} |
|
stack || (stack = new Stack); |
|
return equalObjects(object, other, bitmask, customizer, equalFunc, stack); |
|
} |
|
|
|
/** |
|
* The base implementation of `_.isMap` without Node.js optimizations. |
|
* |
|
* @private |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is a map, else `false`. |
|
*/ |
|
function baseIsMap(value) { |
|
return isObjectLike(value) && getTag(value) == mapTag; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.isMatch` without support for iteratee shorthands. |
|
* |
|
* @private |
|
* @param {Object} object The object to inspect. |
|
* @param {Object} source The object of property values to match. |
|
* @param {Array} matchData The property names, values, and compare flags to match. |
|
* @param {Function} [customizer] The function to customize comparisons. |
|
* @returns {boolean} Returns `true` if `object` is a match, else `false`. |
|
*/ |
|
function baseIsMatch(object, source, matchData, customizer) { |
|
var index = matchData.length, |
|
length = index, |
|
noCustomizer = !customizer; |
|
|
|
if (object == null) { |
|
return !length; |
|
} |
|
object = Object(object); |
|
while (index--) { |
|
var data = matchData[index]; |
|
if ((noCustomizer && data[2]) |
|
? data[1] !== object[data[0]] |
|
: !(data[0] in object) |
|
) { |
|
return false; |
|
} |
|
} |
|
while (++index < length) { |
|
data = matchData[index]; |
|
var key = data[0], |
|
objValue = object[key], |
|
srcValue = data[1]; |
|
|
|
if (noCustomizer && data[2]) { |
|
if (objValue === undefined && !(key in object)) { |
|
return false; |
|
} |
|
} else { |
|
var stack = new Stack; |
|
if (customizer) { |
|
var result = customizer(objValue, srcValue, key, object, source, stack); |
|
} |
|
if (!(result === undefined |
|
? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack) |
|
: result |
|
)) { |
|
return false; |
|
} |
|
} |
|
} |
|
return true; |
|
} |
|
|
|
/** |
|
* 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) ? reIsNative : reIsHostCtor; |
|
return pattern.test(toSource(value)); |
|
} |
|
|
|
/** |
|
* The base implementation of `_.isRegExp` without Node.js optimizations. |
|
* |
|
* @private |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is a regexp, else `false`. |
|
*/ |
|
function baseIsRegExp(value) { |
|
return isObjectLike(value) && baseGetTag(value) == regexpTag; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.isSet` without Node.js optimizations. |
|
* |
|
* @private |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is a set, else `false`. |
|
*/ |
|
function baseIsSet(value) { |
|
return isObjectLike(value) && getTag(value) == setTag; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.isTypedArray` without Node.js optimizations. |
|
* |
|
* @private |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is a typed array, else `false`. |
|
*/ |
|
function baseIsTypedArray(value) { |
|
return isObjectLike(value) && |
|
isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.iteratee`. |
|
* |
|
* @private |
|
* @param {*} [value=_.identity] The value to convert to an iteratee. |
|
* @returns {Function} Returns the iteratee. |
|
*/ |
|
function baseIteratee(value) { |
|
// Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. |
|
// See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. |
|
if (typeof value == 'function') { |
|
return value; |
|
} |
|
if (value == null) { |
|
return identity; |
|
} |
|
if (typeof value == 'object') { |
|
return isArray(value) |
|
? baseMatchesProperty(value[0], value[1]) |
|
: baseMatches(value); |
|
} |
|
return property(value); |
|
} |
|
|
|
/** |
|
* The base implementation of `_.keys` which doesn't treat sparse arrays as dense. |
|
* |
|
* @private |
|
* @param {Object} object The object to query. |
|
* @returns {Array} Returns the array of property names. |
|
*/ |
|
function baseKeys(object) { |
|
if (!isPrototype(object)) { |
|
return nativeKeys(object); |
|
} |
|
var result = []; |
|
for (var key in Object(object)) { |
|
if (hasOwnProperty.call(object, key) && key != 'constructor') { |
|
result.push(key); |
|
} |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. |
|
* |
|
* @private |
|
* @param {Object} object The object to query. |
|
* @returns {Array} Returns the array of property names. |
|
*/ |
|
function baseKeysIn(object) { |
|
if (!isObject(object)) { |
|
return nativeKeysIn(object); |
|
} |
|
var isProto = isPrototype(object), |
|
result = []; |
|
|
|
for (var key in object) { |
|
if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { |
|
result.push(key); |
|
} |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.lt` which doesn't coerce arguments. |
|
* |
|
* @private |
|
* @param {*} value The value to compare. |
|
* @param {*} other The other value to compare. |
|
* @returns {boolean} Returns `true` if `value` is less than `other`, |
|
* else `false`. |
|
*/ |
|
function baseLt(value, other) { |
|
return value < other; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.map` without support for iteratee shorthands. |
|
* |
|
* @private |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {Function} iteratee The function invoked per iteration. |
|
* @returns {Array} Returns the new mapped array. |
|
*/ |
|
function baseMap(collection, iteratee) { |
|
var index = -1, |
|
result = isArrayLike(collection) ? Array(collection.length) : []; |
|
|
|
baseEach(collection, function(value, key, collection) { |
|
result[++index] = iteratee(value, key, collection); |
|
}); |
|
return result; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.matches` which doesn't clone `source`. |
|
* |
|
* @private |
|
* @param {Object} source The object of property values to match. |
|
* @returns {Function} Returns the new spec function. |
|
*/ |
|
function baseMatches(source) { |
|
var matchData = getMatchData(source); |
|
if (matchData.length == 1 && matchData[0][2]) { |
|
return matchesStrictComparable(matchData[0][0], matchData[0][1]); |
|
} |
|
return function(object) { |
|
return object === source || baseIsMatch(object, source, matchData); |
|
}; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. |
|
* |
|
* @private |
|
* @param {string} path The path of the property to get. |
|
* @param {*} srcValue The value to match. |
|
* @returns {Function} Returns the new spec function. |
|
*/ |
|
function baseMatchesProperty(path, srcValue) { |
|
if (isKey(path) && isStrictComparable(srcValue)) { |
|
return matchesStrictComparable(toKey(path), srcValue); |
|
} |
|
return function(object) { |
|
var objValue = get(object, path); |
|
return (objValue === undefined && objValue === srcValue) |
|
? hasIn(object, path) |
|
: baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG); |
|
}; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.merge` without support for multiple sources. |
|
* |
|
* @private |
|
* @param {Object} object The destination object. |
|
* @param {Object} source The source object. |
|
* @param {number} srcIndex The index of `source`. |
|
* @param {Function} [customizer] The function to customize merged values. |
|
* @param {Object} [stack] Tracks traversed source values and their merged |
|
* counterparts. |
|
*/ |
|
function baseMerge(object, source, srcIndex, customizer, stack) { |
|
if (object === source) { |
|
return; |
|
} |
|
baseFor(source, function(srcValue, key) { |
|
if (isObject(srcValue)) { |
|
stack || (stack = new Stack); |
|
baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); |
|
} |
|
else { |
|
var newValue = customizer |
|
? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack) |
|
: undefined; |
|
|
|
if (newValue === undefined) { |
|
newValue = srcValue; |
|
} |
|
assignMergeValue(object, key, newValue); |
|
} |
|
}, keysIn); |
|
} |
|
|
|
/** |
|
* A specialized version of `baseMerge` for arrays and objects which performs |
|
* deep merges and tracks traversed objects enabling objects with circular |
|
* references to be merged. |
|
* |
|
* @private |
|
* @param {Object} object The destination object. |
|
* @param {Object} source The source object. |
|
* @param {string} key The key of the value to merge. |
|
* @param {number} srcIndex The index of `source`. |
|
* @param {Function} mergeFunc The function to merge values. |
|
* @param {Function} [customizer] The function to customize assigned values. |
|
* @param {Object} [stack] Tracks traversed source values and their merged |
|
* counterparts. |
|
*/ |
|
function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { |
|
var objValue = safeGet(object, key), |
|
srcValue = safeGet(source, key), |
|
stacked = stack.get(srcValue); |
|
|
|
if (stacked) { |
|
assignMergeValue(object, key, stacked); |
|
return; |
|
} |
|
var newValue = customizer |
|
? customizer(objValue, srcValue, (key + ''), object, source, stack) |
|
: undefined; |
|
|
|
var isCommon = newValue === undefined; |
|
|
|
if (isCommon) { |
|
var isArr = isArray(srcValue), |
|
isBuff = !isArr && isBuffer(srcValue), |
|
isTyped = !isArr && !isBuff && isTypedArray(srcValue); |
|
|
|
newValue = srcValue; |
|
if (isArr || isBuff || isTyped) { |
|
if (isArray(objValue)) { |
|
newValue = objValue; |
|
} |
|
else if (isArrayLikeObject(objValue)) { |
|
newValue = copyArray(objValue); |
|
} |
|
else if (isBuff) { |
|
isCommon = false; |
|
newValue = cloneBuffer(srcValue, true); |
|
} |
|
else if (isTyped) { |
|
isCommon = false; |
|
newValue = cloneTypedArray(srcValue, true); |
|
} |
|
else { |
|
newValue = []; |
|
} |
|
} |
|
else if (isPlainObject(srcValue) || isArguments(srcValue)) { |
|
newValue = objValue; |
|
if (isArguments(objValue)) { |
|
newValue = toPlainObject(objValue); |
|
} |
|
else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) { |
|
newValue = initCloneObject(srcValue); |
|
} |
|
} |
|
else { |
|
isCommon = false; |
|
} |
|
} |
|
if (isCommon) { |
|
// Recursively merge objects and arrays (susceptible to call stack limits). |
|
stack.set(srcValue, newValue); |
|
mergeFunc(newValue, srcValue, srcIndex, customizer, stack); |
|
stack['delete'](srcValue); |
|
} |
|
assignMergeValue(object, key, newValue); |
|
} |
|
|
|
/** |
|
* The base implementation of `_.nth` which doesn't coerce arguments. |
|
* |
|
* @private |
|
* @param {Array} array The array to query. |
|
* @param {number} n The index of the element to return. |
|
* @returns {*} Returns the nth element of `array`. |
|
*/ |
|
function baseNth(array, n) { |
|
var length = array.length; |
|
if (!length) { |
|
return; |
|
} |
|
n += n < 0 ? length : 0; |
|
return isIndex(n, length) ? array[n] : undefined; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.orderBy` without param guards. |
|
* |
|
* @private |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. |
|
* @param {string[]} orders The sort orders of `iteratees`. |
|
* @returns {Array} Returns the new sorted array. |
|
*/ |
|
function baseOrderBy(collection, iteratees, orders) { |
|
var index = -1; |
|
iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee())); |
|
|
|
var result = baseMap(collection, function(value, key, collection) { |
|
var criteria = arrayMap(iteratees, function(iteratee) { |
|
return iteratee(value); |
|
}); |
|
return { 'criteria': criteria, 'index': ++index, 'value': value }; |
|
}); |
|
|
|
return baseSortBy(result, function(object, other) { |
|
return compareMultiple(object, other, orders); |
|
}); |
|
} |
|
|
|
/** |
|
* The base implementation of `_.pick` without support for individual |
|
* property identifiers. |
|
* |
|
* @private |
|
* @param {Object} object The source object. |
|
* @param {string[]} paths The property paths to pick. |
|
* @returns {Object} Returns the new object. |
|
*/ |
|
function basePick(object, paths) { |
|
return basePickBy(object, paths, function(value, path) { |
|
return hasIn(object, path); |
|
}); |
|
} |
|
|
|
/** |
|
* The base implementation of `_.pickBy` without support for iteratee shorthands. |
|
* |
|
* @private |
|
* @param {Object} object The source object. |
|
* @param {string[]} paths The property paths to pick. |
|
* @param {Function} predicate The function invoked per property. |
|
* @returns {Object} Returns the new object. |
|
*/ |
|
function basePickBy(object, paths, predicate) { |
|
var index = -1, |
|
length = paths.length, |
|
result = {}; |
|
|
|
while (++index < length) { |
|
var path = paths[index], |
|
value = baseGet(object, path); |
|
|
|
if (predicate(value, path)) { |
|
baseSet(result, castPath(path, object), value); |
|
} |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* A specialized version of `baseProperty` which supports deep paths. |
|
* |
|
* @private |
|
* @param {Array|string} path The path of the property to get. |
|
* @returns {Function} Returns the new accessor function. |
|
*/ |
|
function basePropertyDeep(path) { |
|
return function(object) { |
|
return baseGet(object, path); |
|
}; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.pullAllBy` without support for iteratee |
|
* shorthands. |
|
* |
|
* @private |
|
* @param {Array} array The array to modify. |
|
* @param {Array} values The values to remove. |
|
* @param {Function} [iteratee] The iteratee invoked per element. |
|
* @param {Function} [comparator] The comparator invoked per element. |
|
* @returns {Array} Returns `array`. |
|
*/ |
|
function basePullAll(array, values, iteratee, comparator) { |
|
var indexOf = comparator ? baseIndexOfWith : baseIndexOf, |
|
index = -1, |
|
length = values.length, |
|
seen = array; |
|
|
|
if (array === values) { |
|
values = copyArray(values); |
|
} |
|
if (iteratee) { |
|
seen = arrayMap(array, baseUnary(iteratee)); |
|
} |
|
while (++index < length) { |
|
var fromIndex = 0, |
|
value = values[index], |
|
computed = iteratee ? iteratee(value) : value; |
|
|
|
while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) { |
|
if (seen !== array) { |
|
splice.call(seen, fromIndex, 1); |
|
} |
|
splice.call(array, fromIndex, 1); |
|
} |
|
} |
|
return array; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.pullAt` without support for individual |
|
* indexes or capturing the removed elements. |
|
* |
|
* @private |
|
* @param {Array} array The array to modify. |
|
* @param {number[]} indexes The indexes of elements to remove. |
|
* @returns {Array} Returns `array`. |
|
*/ |
|
function basePullAt(array, indexes) { |
|
var length = array ? indexes.length : 0, |
|
lastIndex = length - 1; |
|
|
|
while (length--) { |
|
var index = indexes[length]; |
|
if (length == lastIndex || index !== previous) { |
|
var previous = index; |
|
if (isIndex(index)) { |
|
splice.call(array, index, 1); |
|
} else { |
|
baseUnset(array, index); |
|
} |
|
} |
|
} |
|
return array; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.random` without support for returning |
|
* floating-point numbers. |
|
* |
|
* @private |
|
* @param {number} lower The lower bound. |
|
* @param {number} upper The upper bound. |
|
* @returns {number} Returns the random number. |
|
*/ |
|
function baseRandom(lower, upper) { |
|
return lower + nativeFloor(nativeRandom() * (upper - lower + 1)); |
|
} |
|
|
|
/** |
|
* The base implementation of `_.range` and `_.rangeRight` which doesn't |
|
* coerce arguments. |
|
* |
|
* @private |
|
* @param {number} start The start of the range. |
|
* @param {number} end The end of the range. |
|
* @param {number} step The value to increment or decrement by. |
|
* @param {boolean} [fromRight] Specify iterating from right to left. |
|
* @returns {Array} Returns the range of numbers. |
|
*/ |
|
function baseRange(start, end, step, fromRight) { |
|
var index = -1, |
|
length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), |
|
result = Array(length); |
|
|
|
while (length--) { |
|
result[fromRight ? length : ++index] = start; |
|
start += step; |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.repeat` which doesn't coerce arguments. |
|
* |
|
* @private |
|
* @param {string} string The string to repeat. |
|
* @param {number} n The number of times to repeat the string. |
|
* @returns {string} Returns the repeated string. |
|
*/ |
|
function baseRepeat(string, n) { |
|
var result = ''; |
|
if (!string || n < 1 || n > MAX_SAFE_INTEGER) { |
|
return result; |
|
} |
|
// Leverage the exponentiation by squaring algorithm for a faster repeat. |
|
// See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details. |
|
do { |
|
if (n % 2) { |
|
result += string; |
|
} |
|
n = nativeFloor(n / 2); |
|
if (n) { |
|
string += string; |
|
} |
|
} while (n); |
|
|
|
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) { |
|
return setToString(overRest(func, start, identity), func + ''); |
|
} |
|
|
|
/** |
|
* The base implementation of `_.sample`. |
|
* |
|
* @private |
|
* @param {Array|Object} collection The collection to sample. |
|
* @returns {*} Returns the random element. |
|
*/ |
|
function baseSample(collection) { |
|
return arraySample(values(collection)); |
|
} |
|
|
|
/** |
|
* The base implementation of `_.sampleSize` without param guards. |
|
* |
|
* @private |
|
* @param {Array|Object} collection The collection to sample. |
|
* @param {number} n The number of elements to sample. |
|
* @returns {Array} Returns the random elements. |
|
*/ |
|
function baseSampleSize(collection, n) { |
|
var array = values(collection); |
|
return shuffleSelf(array, baseClamp(n, 0, array.length)); |
|
} |
|
|
|
/** |
|
* The base implementation of `_.set`. |
|
* |
|
* @private |
|
* @param {Object} object The object to modify. |
|
* @param {Array|string} path The path of the property to set. |
|
* @param {*} value The value to set. |
|
* @param {Function} [customizer] The function to customize path creation. |
|
* @returns {Object} Returns `object`. |
|
*/ |
|
function baseSet(object, path, value, customizer) { |
|
if (!isObject(object)) { |
|
return object; |
|
} |
|
path = castPath(path, object); |
|
|
|
var index = -1, |
|
length = path.length, |
|
lastIndex = length - 1, |
|
nested = object; |
|
|
|
while (nested != null && ++index < length) { |
|
var key = toKey(path[index]), |
|
newValue = value; |
|
|
|
if (index != lastIndex) { |
|
var objValue = nested[key]; |
|
newValue = customizer ? customizer(objValue, key, nested) : undefined; |
|
if (newValue === undefined) { |
|
newValue = isObject(objValue) |
|
? objValue |
|
: (isIndex(path[index + 1]) ? [] : {}); |
|
} |
|
} |
|
assignValue(nested, key, newValue); |
|
nested = nested[key]; |
|
} |
|
return object; |
|
} |
|
|
|
/** |
|
* The base implementation of `setData` without support for hot loop shorting. |
|
* |
|
* @private |
|
* @param {Function} func The function to associate metadata with. |
|
* @param {*} data The metadata. |
|
* @returns {Function} Returns `func`. |
|
*/ |
|
var baseSetData = !metaMap ? identity : function(func, data) { |
|
metaMap.set(func, data); |
|
return func; |
|
}; |
|
|
|
/** |
|
* The base implementation of `setToString` without support for hot loop shorting. |
|
* |
|
* @private |
|
* @param {Function} func The function to modify. |
|
* @param {Function} string The `toString` result. |
|
* @returns {Function} Returns `func`. |
|
*/ |
|
var baseSetToString = !defineProperty ? identity : function(func, string) { |
|
return defineProperty(func, 'toString', { |
|
'configurable': true, |
|
'enumerable': false, |
|
'value': constant(string), |
|
'writable': true |
|
}); |
|
}; |
|
|
|
/** |
|
* The base implementation of `_.shuffle`. |
|
* |
|
* @private |
|
* @param {Array|Object} collection The collection to shuffle. |
|
* @returns {Array} Returns the new shuffled array. |
|
*/ |
|
function baseShuffle(collection) { |
|
return shuffleSelf(values(collection)); |
|
} |
|
|
|
/** |
|
* The base implementation of `_.slice` without an iteratee call guard. |
|
* |
|
* @private |
|
* @param {Array} array The array to slice. |
|
* @param {number} [start=0] The start position. |
|
* @param {number} [end=array.length] The end position. |
|
* @returns {Array} Returns the slice of `array`. |
|
*/ |
|
function baseSlice(array, start, end) { |
|
var index = -1, |
|
length = array.length; |
|
|
|
if (start < 0) { |
|
start = -start > length ? 0 : (length + start); |
|
} |
|
end = end > length ? length : end; |
|
if (end < 0) { |
|
end += length; |
|
} |
|
length = start > end ? 0 : ((end - start) >>> 0); |
|
start >>>= 0; |
|
|
|
var result = Array(length); |
|
while (++index < length) { |
|
result[index] = array[index + start]; |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.some` without support for iteratee shorthands. |
|
* |
|
* @private |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {Function} predicate The function invoked per iteration. |
|
* @returns {boolean} Returns `true` if any element passes the predicate check, |
|
* else `false`. |
|
*/ |
|
function baseSome(collection, predicate) { |
|
var result; |
|
|
|
baseEach(collection, function(value, index, collection) { |
|
result = predicate(value, index, collection); |
|
return !result; |
|
}); |
|
return !!result; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which |
|
* performs a binary search of `array` to determine the index at which `value` |
|
* should be inserted into `array` in order to maintain its sort order. |
|
* |
|
* @private |
|
* @param {Array} array The sorted array to inspect. |
|
* @param {*} value The value to evaluate. |
|
* @param {boolean} [retHighest] Specify returning the highest qualified index. |
|
* @returns {number} Returns the index at which `value` should be inserted |
|
* into `array`. |
|
*/ |
|
function baseSortedIndex(array, value, retHighest) { |
|
var low = 0, |
|
high = array == null ? low : array.length; |
|
|
|
if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { |
|
while (low < high) { |
|
var mid = (low + high) >>> 1, |
|
computed = array[mid]; |
|
|
|
if (computed !== null && !isSymbol(computed) && |
|
(retHighest ? (computed <= value) : (computed < value))) { |
|
low = mid + 1; |
|
} else { |
|
high = mid; |
|
} |
|
} |
|
return high; |
|
} |
|
return baseSortedIndexBy(array, value, identity, retHighest); |
|
} |
|
|
|
/** |
|
* The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy` |
|
* which invokes `iteratee` for `value` and each element of `array` to compute |
|
* their sort ranking. The iteratee is invoked with one argument; (value). |
|
* |
|
* @private |
|
* @param {Array} array The sorted array to inspect. |
|
* @param {*} value The value to evaluate. |
|
* @param {Function} iteratee The iteratee invoked per element. |
|
* @param {boolean} [retHighest] Specify returning the highest qualified index. |
|
* @returns {number} Returns the index at which `value` should be inserted |
|
* into `array`. |
|
*/ |
|
function baseSortedIndexBy(array, value, iteratee, retHighest) { |
|
value = iteratee(value); |
|
|
|
var low = 0, |
|
high = array == null ? 0 : array.length, |
|
valIsNaN = value !== value, |
|
valIsNull = value === null, |
|
valIsSymbol = isSymbol(value), |
|
valIsUndefined = value === undefined; |
|
|
|
while (low < high) { |
|
var mid = nativeFloor((low + high) / 2), |
|
computed = iteratee(array[mid]), |
|
othIsDefined = computed !== undefined, |
|
othIsNull = computed === null, |
|
othIsReflexive = computed === computed, |
|
othIsSymbol = isSymbol(computed); |
|
|
|
if (valIsNaN) { |
|
var setLow = retHighest || othIsReflexive; |
|
} else if (valIsUndefined) { |
|
setLow = othIsReflexive && (retHighest || othIsDefined); |
|
} else if (valIsNull) { |
|
setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull); |
|
} else if (valIsSymbol) { |
|
setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol); |
|
} else if (othIsNull || othIsSymbol) { |
|
setLow = false; |
|
} else { |
|
setLow = retHighest ? (computed <= value) : (computed < value); |
|
} |
|
if (setLow) { |
|
low = mid + 1; |
|
} else { |
|
high = mid; |
|
} |
|
} |
|
return nativeMin(high, MAX_ARRAY_INDEX); |
|
} |
|
|
|
/** |
|
* The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without |
|
* support for iteratee shorthands. |
|
* |
|
* @private |
|
* @param {Array} array The array to inspect. |
|
* @param {Function} [iteratee] The iteratee invoked per element. |
|
* @returns {Array} Returns the new duplicate free array. |
|
*/ |
|
function baseSortedUniq(array, iteratee) { |
|
var index = -1, |
|
length = array.length, |
|
resIndex = 0, |
|
result = []; |
|
|
|
while (++index < length) { |
|
var value = array[index], |
|
computed = iteratee ? iteratee(value) : value; |
|
|
|
if (!index || !eq(computed, seen)) { |
|
var seen = computed; |
|
result[resIndex++] = value === 0 ? 0 : value; |
|
} |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.toNumber` which doesn't ensure correct |
|
* conversions of binary, hexadecimal, or octal string values. |
|
* |
|
* @private |
|
* @param {*} value The value to process. |
|
* @returns {number} Returns the number. |
|
*/ |
|
function baseToNumber(value) { |
|
if (typeof value == 'number') { |
|
return value; |
|
} |
|
if (isSymbol(value)) { |
|
return NAN; |
|
} |
|
return +value; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.toString` which doesn't convert nullish |
|
* values to empty strings. |
|
* |
|
* @private |
|
* @param {*} value The value to process. |
|
* @returns {string} Returns the string. |
|
*/ |
|
function baseToString(value) { |
|
// Exit early for strings to avoid a performance hit in some environments. |
|
if (typeof value == 'string') { |
|
return value; |
|
} |
|
if (isArray(value)) { |
|
// Recursively convert values (susceptible to call stack limits). |
|
return arrayMap(value, baseToString) + ''; |
|
} |
|
if (isSymbol(value)) { |
|
return symbolToString ? symbolToString.call(value) : ''; |
|
} |
|
var result = (value + ''); |
|
return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.uniqBy` without support for iteratee shorthands. |
|
* |
|
* @private |
|
* @param {Array} array The array to inspect. |
|
* @param {Function} [iteratee] The iteratee invoked per element. |
|
* @param {Function} [comparator] The comparator invoked per element. |
|
* @returns {Array} Returns the new duplicate free array. |
|
*/ |
|
function baseUniq(array, iteratee, comparator) { |
|
var index = -1, |
|
includes = arrayIncludes, |
|
length = array.length, |
|
isCommon = true, |
|
result = [], |
|
seen = result; |
|
|
|
if (comparator) { |
|
isCommon = false; |
|
includes = arrayIncludesWith; |
|
} |
|
else if (length >= LARGE_ARRAY_SIZE) { |
|
var set = iteratee ? null : createSet(array); |
|
if (set) { |
|
return setToArray(set); |
|
} |
|
isCommon = false; |
|
includes = cacheHas; |
|
seen = new SetCache; |
|
} |
|
else { |
|
seen = iteratee ? [] : result; |
|
} |
|
outer: |
|
while (++index < length) { |
|
var value = array[index], |
|
computed = iteratee ? iteratee(value) : value; |
|
|
|
value = (comparator || value !== 0) ? value : 0; |
|
if (isCommon && computed === computed) { |
|
var seenIndex = seen.length; |
|
while (seenIndex--) { |
|
if (seen[seenIndex] === computed) { |
|
continue outer; |
|
} |
|
} |
|
if (iteratee) { |
|
seen.push(computed); |
|
} |
|
result.push(value); |
|
} |
|
else if (!includes(seen, computed, comparator)) { |
|
if (seen !== result) { |
|
seen.push(computed); |
|
} |
|
result.push(value); |
|
} |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.unset`. |
|
* |
|
* @private |
|
* @param {Object} object The object to modify. |
|
* @param {Array|string} path The property path to unset. |
|
* @returns {boolean} Returns `true` if the property is deleted, else `false`. |
|
*/ |
|
function baseUnset(object, path) { |
|
path = castPath(path, object); |
|
object = parent(object, path); |
|
return object == null || delete object[toKey(last(path))]; |
|
} |
|
|
|
/** |
|
* The base implementation of `_.update`. |
|
* |
|
* @private |
|
* @param {Object} object The object to modify. |
|
* @param {Array|string} path The path of the property to update. |
|
* @param {Function} updater The function to produce the updated value. |
|
* @param {Function} [customizer] The function to customize path creation. |
|
* @returns {Object} Returns `object`. |
|
*/ |
|
function baseUpdate(object, path, updater, customizer) { |
|
return baseSet(object, path, updater(baseGet(object, path)), customizer); |
|
} |
|
|
|
/** |
|
* The base implementation of methods like `_.dropWhile` and `_.takeWhile` |
|
* without support for iteratee shorthands. |
|
* |
|
* @private |
|
* @param {Array} array The array to query. |
|
* @param {Function} predicate The function invoked per iteration. |
|
* @param {boolean} [isDrop] Specify dropping elements instead of taking them. |
|
* @param {boolean} [fromRight] Specify iterating from right to left. |
|
* @returns {Array} Returns the slice of `array`. |
|
*/ |
|
function baseWhile(array, predicate, isDrop, fromRight) { |
|
var length = array.length, |
|
index = fromRight ? length : -1; |
|
|
|
while ((fromRight ? index-- : ++index < length) && |
|
predicate(array[index], index, array)) {} |
|
|
|
return isDrop |
|
? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length)) |
|
: baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index)); |
|
} |
|
|
|
/** |
|
* The base implementation of `wrapperValue` which returns the result of |
|
* performing a sequence of actions on the unwrapped `value`, where each |
|
* successive action is supplied the return value of the previous. |
|
* |
|
* @private |
|
* @param {*} value The unwrapped value. |
|
* @param {Array} actions Actions to perform to resolve the unwrapped value. |
|
* @returns {*} Returns the resolved value. |
|
*/ |
|
function baseWrapperValue(value, actions) { |
|
var result = value; |
|
if (result instanceof LazyWrapper) { |
|
result = result.value(); |
|
} |
|
return arrayReduce(actions, function(result, action) { |
|
return action.func.apply(action.thisArg, arrayPush([result], action.args)); |
|
}, result); |
|
} |
|
|
|
/** |
|
* The base implementation of methods like `_.xor`, without support for |
|
* iteratee shorthands, that accepts an array of arrays to inspect. |
|
* |
|
* @private |
|
* @param {Array} arrays The arrays to inspect. |
|
* @param {Function} [iteratee] The iteratee invoked per element. |
|
* @param {Function} [comparator] The comparator invoked per element. |
|
* @returns {Array} Returns the new array of values. |
|
*/ |
|
function baseXor(arrays, iteratee, comparator) { |
|
var length = arrays.length; |
|
if (length < 2) { |
|
return length ? baseUniq(arrays[0]) : []; |
|
} |
|
var index = -1, |
|
result = Array(length); |
|
|
|
while (++index < length) { |
|
var array = arrays[index], |
|
othIndex = -1; |
|
|
|
while (++othIndex < length) { |
|
if (othIndex != index) { |
|
result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator); |
|
} |
|
} |
|
} |
|
return baseUniq(baseFlatten(result, 1), iteratee, comparator); |
|
} |
|
|
|
/** |
|
* This base implementation of `_.zipObject` which assigns values using `assignFunc`. |
|
* |
|
* @private |
|
* @param {Array} props The property identifiers. |
|
* @param {Array} values The property values. |
|
* @param {Function} assignFunc The function to assign values. |
|
* @returns {Object} Returns the new object. |
|
*/ |
|
function baseZipObject(props, values, assignFunc) { |
|
var index = -1, |
|
length = props.length, |
|
valsLength = values.length, |
|
result = {}; |
|
|
|
while (++index < length) { |
|
var value = index < valsLength ? values[index] : undefined; |
|
assignFunc(result, props[index], value); |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* Casts `value` to an empty array if it's not an array like object. |
|
* |
|
* @private |
|
* @param {*} value The value to inspect. |
|
* @returns {Array|Object} Returns the cast array-like object. |
|
*/ |
|
function castArrayLikeObject(value) { |
|
return isArrayLikeObject(value) ? value : []; |
|
} |
|
|
|
/** |
|
* Casts `value` to `identity` if it's not a function. |
|
* |
|
* @private |
|
* @param {*} value The value to inspect. |
|
* @returns {Function} Returns cast function. |
|
*/ |
|
function castFunction(value) { |
|
return typeof value == 'function' ? value : identity; |
|
} |
|
|
|
/** |
|
* Casts `value` to a path array if it's not one. |
|
* |
|
* @private |
|
* @param {*} value The value to inspect. |
|
* @param {Object} [object] The object to query keys on. |
|
* @returns {Array} Returns the cast property path array. |
|
*/ |
|
function castPath(value, object) { |
|
if (isArray(value)) { |
|
return value; |
|
} |
|
return isKey(value, object) ? [value] : stringToPath(toString(value)); |
|
} |
|
|
|
/** |
|
* A `baseRest` alias which can be replaced with `identity` by module |
|
* replacement plugins. |
|
* |
|
* @private |
|
* @type {Function} |
|
* @param {Function} func The function to apply a rest parameter to. |
|
* @returns {Function} Returns the new function. |
|
*/ |
|
var castRest = baseRest; |
|
|
|
/** |
|
* Casts `array` to a slice if it's needed. |
|
* |
|
* @private |
|
* @param {Array} array The array to inspect. |
|
* @param {number} start The start position. |
|
* @param {number} [end=array.length] The end position. |
|
* @returns {Array} Returns the cast slice. |
|
*/ |
|
function castSlice(array, start, end) { |
|
var length = array.length; |
|
end = end === undefined ? length : end; |
|
return (!start && end >= length) ? array : baseSlice(array, start, end); |
|
} |
|
|
|
/** |
|
* A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout). |
|
* |
|
* @private |
|
* @param {number|Object} id The timer id or timeout object of the timer to clear. |
|
*/ |
|
var clearTimeout = ctxClearTimeout || function(id) { |
|
return root.clearTimeout(id); |
|
}; |
|
|
|
/** |
|
* Creates a clone of `buffer`. |
|
* |
|
* @private |
|
* @param {Buffer} buffer The buffer to clone. |
|
* @param {boolean} [isDeep] Specify a deep clone. |
|
* @returns {Buffer} Returns the cloned buffer. |
|
*/ |
|
function cloneBuffer(buffer, isDeep) { |
|
if (isDeep) { |
|
return buffer.slice(); |
|
} |
|
var length = buffer.length, |
|
result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); |
|
|
|
buffer.copy(result); |
|
return result; |
|
} |
|
|
|
/** |
|
* Creates a clone of `arrayBuffer`. |
|
* |
|
* @private |
|
* @param {ArrayBuffer} arrayBuffer The array buffer to clone. |
|
* @returns {ArrayBuffer} Returns the cloned array buffer. |
|
*/ |
|
function cloneArrayBuffer(arrayBuffer) { |
|
var result = new arrayBuffer.constructor(arrayBuffer.byteLength); |
|
new Uint8Array(result).set(new Uint8Array(arrayBuffer)); |
|
return result; |
|
} |
|
|
|
/** |
|
* Creates a clone of `dataView`. |
|
* |
|
* @private |
|
* @param {Object} dataView The data view to clone. |
|
* @param {boolean} [isDeep] Specify a deep clone. |
|
* @returns {Object} Returns the cloned data view. |
|
*/ |
|
function cloneDataView(dataView, isDeep) { |
|
var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; |
|
return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); |
|
} |
|
|
|
/** |
|
* Creates a clone of `regexp`. |
|
* |
|
* @private |
|
* @param {Object} regexp The regexp to clone. |
|
* @returns {Object} Returns the cloned regexp. |
|
*/ |
|
function cloneRegExp(regexp) { |
|
var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); |
|
result.lastIndex = regexp.lastIndex; |
|
return result; |
|
} |
|
|
|
/** |
|
* Creates a clone of the `symbol` object. |
|
* |
|
* @private |
|
* @param {Object} symbol The symbol object to clone. |
|
* @returns {Object} Returns the cloned symbol object. |
|
*/ |
|
function cloneSymbol(symbol) { |
|
return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; |
|
} |
|
|
|
/** |
|
* Creates a clone of `typedArray`. |
|
* |
|
* @private |
|
* @param {Object} typedArray The typed array to clone. |
|
* @param {boolean} [isDeep] Specify a deep clone. |
|
* @returns {Object} Returns the cloned typed array. |
|
*/ |
|
function cloneTypedArray(typedArray, isDeep) { |
|
var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; |
|
return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); |
|
} |
|
|
|
/** |
|
* Compares values to sort them in ascending order. |
|
* |
|
* @private |
|
* @param {*} value The value to compare. |
|
* @param {*} other The other value to compare. |
|
* @returns {number} Returns the sort order indicator for `value`. |
|
*/ |
|
function compareAscending(value, other) { |
|
if (value !== other) { |
|
var valIsDefined = value !== undefined, |
|
valIsNull = value === null, |
|
valIsReflexive = value === value, |
|
valIsSymbol = isSymbol(value); |
|
|
|
var othIsDefined = other !== undefined, |
|
othIsNull = other === null, |
|
othIsReflexive = other === other, |
|
othIsSymbol = isSymbol(other); |
|
|
|
if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || |
|
(valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || |
|
(valIsNull && othIsDefined && othIsReflexive) || |
|
(!valIsDefined && othIsReflexive) || |
|
!valIsReflexive) { |
|
return 1; |
|
} |
|
if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || |
|
(othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || |
|
(othIsNull && valIsDefined && valIsReflexive) || |
|
(!othIsDefined && valIsReflexive) || |
|
!othIsReflexive) { |
|
return -1; |
|
} |
|
} |
|
return 0; |
|
} |
|
|
|
/** |
|
* Used by `_.orderBy` to compare multiple properties of a value to another |
|
* and stable sort them. |
|
* |
|
* If `orders` is unspecified, all values are sorted in ascending order. Otherwise, |
|
* specify an order of "desc" for descending or "asc" for ascending sort order |
|
* of corresponding values. |
|
* |
|
* @private |
|
* @param {Object} object The object to compare. |
|
* @param {Object} other The other object to compare. |
|
* @param {boolean[]|string[]} orders The order to sort by for each property. |
|
* @returns {number} Returns the sort order indicator for `object`. |
|
*/ |
|
function compareMultiple(object, other, orders) { |
|
var index = -1, |
|
objCriteria = object.criteria, |
|
othCriteria = other.criteria, |
|
length = objCriteria.length, |
|
ordersLength = orders.length; |
|
|
|
while (++index < length) { |
|
var result = compareAscending(objCriteria[index], othCriteria[index]); |
|
if (result) { |
|
if (index >= ordersLength) { |
|
return result; |
|
} |
|
var order = orders[index]; |
|
return result * (order == 'desc' ? -1 : 1); |
|
} |
|
} |
|
// Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications |
|
// that causes it, under certain circumstances, to provide the same value for |
|
// `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 |
|
// for more details. |
|
// |
|
// This also ensures a stable sort in V8 and other engines. |
|
// See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. |
|
return object.index - other.index; |
|
} |
|
|
|
/** |
|
* 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; |
|
} |
|
|
|
/** |
|
* Copies properties of `source` to `object`. |
|
* |
|
* @private |
|
* @param {Object} source The object to copy properties from. |
|
* @param {Array} props The property identifiers to copy. |
|
* @param {Object} [object={}] The object to copy properties to. |
|
* @param {Function} [customizer] The function to customize copied values. |
|
* @returns {Object} Returns `object`. |
|
*/ |
|
function copyObject(source, props, object, customizer) { |
|
var isNew = !object; |
|
object || (object = {}); |
|
|
|
var index = -1, |
|
length = props.length; |
|
|
|
while (++index < length) { |
|
var key = props[index]; |
|
|
|
var newValue = customizer |
|
? customizer(object[key], source[key], key, object, source) |
|
: undefined; |
|
|
|
if (newValue === undefined) { |
|
newValue = source[key]; |
|
} |
|
if (isNew) { |
|
baseAssignValue(object, key, newValue); |
|
} else { |
|
assignValue(object, key, newValue); |
|
} |
|
} |
|
return object; |
|
} |
|
|
|
/** |
|
* Copies own symbols of `source` to `object`. |
|
* |
|
* @private |
|
* @param {Object} source The object to copy symbols from. |
|
* @param {Object} [object={}] The object to copy symbols to. |
|
* @returns {Object} Returns `object`. |
|
*/ |
|
function copySymbols(source, object) { |
|
return copyObject(source, getSymbols(source), object); |
|
} |
|
|
|
/** |
|
* Copies own and inherited symbols of `source` to `object`. |
|
* |
|
* @private |
|
* @param {Object} source The object to copy symbols from. |
|
* @param {Object} [object={}] The object to copy symbols to. |
|
* @returns {Object} Returns `object`. |
|
*/ |
|
function copySymbolsIn(source, object) { |
|
return copyObject(source, getSymbolsIn(source), object); |
|
} |
|
|
|
/** |
|
* Creates a function like `_.groupBy`. |
|
* |
|
* @private |
|
* @param {Function} setter The function to set accumulator values. |
|
* @param {Function} [initializer] The accumulator object initializer. |
|
* @returns {Function} Returns the new aggregator function. |
|
*/ |
|
function createAggregator(setter, initializer) { |
|
return function(collection, iteratee) { |
|
var func = isArray(collection) ? arrayAggregator : baseAggregator, |
|
accumulator = initializer ? initializer() : {}; |
|
|
|
return func(collection, setter, getIteratee(iteratee, 2), accumulator); |
|
}; |
|
} |
|
|
|
/** |
|
* Creates a function like `_.assign`. |
|
* |
|
* @private |
|
* @param {Function} assigner The function to assign values. |
|
* @returns {Function} Returns the new assigner function. |
|
*/ |
|
function createAssigner(assigner) { |
|
return baseRest(function(object, sources) { |
|
var index = -1, |
|
length = sources.length, |
|
customizer = length > 1 ? sources[length - 1] : undefined, |
|
guard = length > 2 ? sources[2] : undefined; |
|
|
|
customizer = (assigner.length > 3 && typeof customizer == 'function') |
|
? (length--, customizer) |
|
: undefined; |
|
|
|
if (guard && isIterateeCall(sources[0], sources[1], guard)) { |
|
customizer = length < 3 ? undefined : customizer; |
|
length = 1; |
|
} |
|
object = Object(object); |
|
while (++index < length) { |
|
var source = sources[index]; |
|
if (source) { |
|
assigner(object, source, index, customizer); |
|
} |
|
} |
|
return object; |
|
}); |
|
} |
|
|
|
/** |
|
* Creates a `baseEach` or `baseEachRight` function. |
|
* |
|
* @private |
|
* @param {Function} eachFunc The function to iterate over a collection. |
|
* @param {boolean} [fromRight] Specify iterating from right to left. |
|
* @returns {Function} Returns the new base function. |
|
*/ |
|
function createBaseEach(eachFunc, fromRight) { |
|
return function(collection, iteratee) { |
|
if (collection == null) { |
|
return collection; |
|
} |
|
if (!isArrayLike(collection)) { |
|
return eachFunc(collection, iteratee); |
|
} |
|
var length = collection.length, |
|
index = fromRight ? length : -1, |
|
iterable = Object(collection); |
|
|
|
while ((fromRight ? index-- : ++index < length)) { |
|
if (iteratee(iterable[index], index, iterable) === false) { |
|
break; |
|
} |
|
} |
|
return collection; |
|
}; |
|
} |
|
|
|
/** |
|
* Creates a base function for methods like `_.forIn` and `_.forOwn`. |
|
* |
|
* @private |
|
* @param {boolean} [fromRight] Specify iterating from right to left. |
|
* @returns {Function} Returns the new base function. |
|
*/ |
|
function createBaseFor(fromRight) { |
|
return function(object, iteratee, keysFunc) { |
|
var index = -1, |
|
iterable = Object(object), |
|
props = keysFunc(object), |
|
length = props.length; |
|
|
|
while (length--) { |
|
var key = props[fromRight ? length : ++index]; |
|
if (iteratee(iterable[key], key, iterable) === false) { |
|
break; |
|
} |
|
} |
|
return object; |
|
}; |
|
} |
|
|
|
/** |
|
* 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 & WRAP_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 like `_.lowerFirst`. |
|
* |
|
* @private |
|
* @param {string} methodName The name of the `String` case method to use. |
|
* @returns {Function} Returns the new case function. |
|
*/ |
|
function createCaseFirst(methodName) { |
|
return function(string) { |
|
string = toString(string); |
|
|
|
var strSymbols = hasUnicode(string) |
|
? stringToArray(string) |
|
: undefined; |
|
|
|
var chr = strSymbols |
|
? strSymbols[0] |
|
: string.charAt(0); |
|
|
|
var trailing = strSymbols |
|
? castSlice(strSymbols, 1).join('') |
|
: string.slice(1); |
|
|
|
return chr[methodName]() + trailing; |
|
}; |
|
} |
|
|
|
/** |
|
* Creates a function like `_.camelCase`. |
|
* |
|
* @private |
|
* @param {Function} callback The function to combine each word. |
|
* @returns {Function} Returns the new compounder function. |
|
*/ |
|
function createCompounder(callback) { |
|
return function(string) { |
|
return arrayReduce(words(deburr(string).replace(reApos, '')), callback, ''); |
|
}; |
|
} |
|
|
|
/** |
|
* 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 `_.find` or `_.findLast` function. |
|
* |
|
* @private |
|
* @param {Function} findIndexFunc The function to find the collection index. |
|
* @returns {Function} Returns the new find function. |
|
*/ |
|
function createFind(findIndexFunc) { |
|
return function(collection, predicate, fromIndex) { |
|
var iterable = Object(collection); |
|
if (!isArrayLike(collection)) { |
|
var iteratee = getIteratee(predicate, 3); |
|
collection = keys(collection); |
|
predicate = function(key) { return iteratee(iterable[key], key, iterable); }; |
|
} |
|
var index = findIndexFunc(collection, predicate, fromIndex); |
|
return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; |
|
}; |
|
} |
|
|
|
/** |
|
* 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 flatRest(function(funcs) { |
|
var length = funcs.length, |
|
index = length, |
|
prereq = LodashWrapper.prototype.thru; |
|
|
|
if (fromRight) { |
|
funcs.reverse(); |
|
} |
|
while (index--) { |
|
var func = funcs[index]; |
|
if (typeof func != 'function') { |
|
throw new TypeError(FUNC_ERROR_TEXT); |
|
} |
|
if (prereq && !wrapper && getFuncName(func) == 'wrapper') { |
|
var wrapper = new LodashWrapper([], true); |
|
} |
|
} |
|
index = wrapper ? index : length; |
|
while (++index < length) { |
|
func = funcs[index]; |
|
|
|
var funcName = getFuncName(func), |
|
data = funcName == 'wrapper' ? getData(func) : undefined; |
|
|
|
if (data && isLaziable(data[0]) && |
|
data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) && |
|
!data[4].length && data[9] == 1 |
|
) { |
|
wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); |
|
} else { |
|
wrapper = (func.length == 1 && isLaziable(func)) |
|
? wrapper[funcName]() |
|
: wrapper.thru(func); |
|
} |
|
} |
|
return function() { |
|
var args = arguments, |
|
value = args[0]; |
|
|
|
if (wrapper && args.length == 1 && isArray(value)) { |
|
return wrapper.plant(value).value(); |
|
} |
|
var index = 0, |
|
result = length ? funcs[index].apply(this, args) : value; |
|
|
|
while (++index < length) { |
|
result = funcs[index].call(this, result); |
|
} |
|
return result; |
|
}; |
|
}); |
|
} |
|
|
|
/** |
|
* 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 & WRAP_ARY_FLAG, |
|
isBind = bitmask & WRAP_BIND_FLAG, |
|
isBindKey = bitmask & WRAP_BIND_KEY_FLAG, |
|
isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG), |
|
isFlip = bitmask & WRAP_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 like `_.invertBy`. |
|
* |
|
* @private |
|
* @param {Function} setter The function to set accumulator values. |
|
* @param {Function} toIteratee The function to resolve iteratees. |
|
* @returns {Function} Returns the new inverter function. |
|
*/ |
|
function createInverter(setter, toIteratee) { |
|
return function(object, iteratee) { |
|
return baseInverter(object, setter, toIteratee(iteratee), {}); |
|
}; |
|
} |
|
|
|
/** |
|
* Creates a function that performs a mathematical operation on two values. |
|
* |
|
* @private |
|
* @param {Function} operator The function to perform the operation. |
|
* @param {number} [defaultValue] The value used for `undefined` arguments. |
|
* @returns {Function} Returns the new mathematical operation function. |
|
*/ |
|
function createMathOperation(operator, defaultValue) { |
|
return function(value, other) { |
|
var result; |
|
if (value === undefined && other === undefined) { |
|
return defaultValue; |
|
} |
|
if (value !== undefined) { |
|
result = value; |
|
} |
|
if (other !== undefined) { |
|
if (result === undefined) { |
|
return other; |
|
} |
|
if (typeof value == 'string' || typeof other == 'string') { |
|
value = baseToString(value); |
|
other = baseToString(other); |
|
} else { |
|
value = baseToNumber(value); |
|
other = baseToNumber(other); |
|
} |
|
result = operator(value, other); |
|
} |
|
return result; |
|
}; |
|
} |
|
|
|
/** |
|
* Creates a function like `_.over`. |
|
* |
|
* @private |
|
* @param {Function} arrayFunc The function to iterate over iteratees. |
|
* @returns {Function} Returns the new over function. |
|
*/ |
|
function createOver(arrayFunc) { |
|
return flatRest(function(iteratees) { |
|
iteratees = arrayMap(iteratees, baseUnary(getIteratee())); |
|
return baseRest(function(args) { |
|
var thisArg = this; |
|
return arrayFunc(iteratees, function(iteratee) { |
|
return apply(iteratee, thisArg, args); |
|
}); |
|
}); |
|
}); |
|
} |
|
|
|
/** |
|
* Creates the padding for `string` based on `length`. The `chars` string |
|
* is truncated if the number of characters exceeds `length`. |
|
* |
|
* @private |
|
* @param {number} length The padding length. |
|
* @param {string} [chars=' '] The string used as padding. |
|
* @returns {string} Returns the padding for `string`. |
|
*/ |
|
function createPadding(length, chars) { |
|
chars = chars === undefined ? ' ' : baseToString(chars); |
|
|
|
var charsLength = chars.length; |
|
if (charsLength < 2) { |
|
return charsLength ? baseRepeat(chars, length) : chars; |
|
} |
|
var result = baseRepeat(chars, nativeCeil(length / stringSize(chars))); |
|
return hasUnicode(chars) |
|
? castSlice(stringToArray(result), 0, length).join('') |
|
: result.slice(0, length); |
|
} |
|
|
|
/** |
|
* 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 & WRAP_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 `_.range` or `_.rangeRight` function. |
|
* |
|
* @private |
|
* @param {boolean} [fromRight] Specify iterating from right to left. |
|
* @returns {Function} Returns the new range function. |
|
*/ |
|
function createRange(fromRight) { |
|
return function(start, end, step) { |
|
if (step && typeof step != 'number' && isIterateeCall(start, end, step)) { |
|
end = step = undefined; |
|
} |
|
// Ensure the sign of `-0` is preserved. |
|
start = toFinite(start); |
|
if (end === undefined) { |
|
end = start; |
|
start = 0; |
|
} else { |
|
end = toFinite(end); |
|
} |
|
step = step === undefined ? (start < end ? 1 : -1) : toFinite(step); |
|
return baseRange(start, end, step, fromRight); |
|
}; |
|
} |
|
|
|
/** |
|
* Creates a function that performs a relational operation on two values. |
|
* |
|
* @private |
|
* @param {Function} operator The function to perform the operation. |
|
* @returns {Function} Returns the new relational operation function. |
|
*/ |
|
function createRelationalOperation(operator) { |
|
return function(value, other) { |
|
if (!(typeof value == 'string' && typeof other == 'string')) { |
|
value = toNumber(value); |
|
other = toNumber(other); |
|
} |
|
return operator(value, other); |
|
}; |
|
} |
|
|
|
/** |
|
* 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 & WRAP_CURRY_FLAG, |
|
newHolders = isCurry ? holders : undefined, |
|
newHoldersRight = isCurry ? undefined : holders, |
|
newPartials = isCurry ? partials : undefined, |
|
newPartialsRight = isCurry ? undefined : partials; |
|
|
|
bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG); |
|
bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG); |
|
|
|
if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) { |
|
bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG); |
|
} |
|
var newData = [ |
|
func, bitmask, thisArg, newPartials, newHolders, newPartialsRight, |
|
newHoldersRight, argPos, ary, arity |
|
]; |
|
|
|
var result = wrapFunc.apply(undefined, newData); |
|
if (isLaziable(func)) { |
|
setData(result, newData); |
|
} |
|
result.placeholder = placeholder; |
|
return setWrapToString(result, func, bitmask); |
|
} |
|
|
|
/** |
|
* Creates a function like `_.round`. |
|
* |
|
* @private |
|
* @param {string} methodName The name of the `Math` method to use when rounding. |
|
* @returns {Function} Returns the new round function. |
|
*/ |
|
function createRound(methodName) { |
|
var func = Math[methodName]; |
|
return function(number, precision) { |
|
number = toNumber(number); |
|
precision = precision == null ? 0 : nativeMin(toInteger(precision), 292); |
|
if (precision) { |
|
// Shift with exponential notation to avoid floating-point issues. |
|
// See [MDN](https://mdn.io/round#Examples) for more details. |
|
var pair = (toString(number) + 'e').split('e'), |
|
value = func(pair[0] + 'e' + (+pair[1] + precision)); |
|
|
|
pair = (toString(value) + 'e').split('e'); |
|
return +(pair[0] + 'e' + (+pair[1] - precision)); |
|
} |
|
return func(number); |
|
}; |
|
} |
|
|
|
/** |
|
* Creates a set object of `values`. |
|
* |
|
* @private |
|
* @param {Array} values The values to add to the set. |
|
* @returns {Object} Returns the new set. |
|
*/ |
|
var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) { |
|
return new Set(values); |
|
}; |
|
|
|
/** |
|
* Creates a `_.toPairs` or `_.toPairsIn` function. |
|
* |
|
* @private |
|
* @param {Function} keysFunc The function to get the keys of a given object. |
|
* @returns {Function} Returns the new pairs function. |
|
*/ |
|
function createToPairs(keysFunc) { |
|
return function(object) { |
|
var tag = getTag(object); |
|
if (tag == mapTag) { |
|
return mapToArray(object); |
|
} |
|
if (tag == setTag) { |
|
return setToPairs(object); |
|
} |
|
return baseToPairs(object, keysFunc(object)); |
|
}; |
|
} |
|
|
|
/** |
|
* 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. |
|
* 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 & WRAP_BIND_KEY_FLAG; |
|
if (!isBindKey && typeof func != 'function') { |
|
throw new TypeError(FUNC_ERROR_TEXT); |
|
} |
|
var length = partials ? partials.length : 0; |
|
if (!length) { |
|
bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_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 & WRAP_PARTIAL_RIGHT_FLAG) { |
|
var partialsRight = partials, |
|
holdersRight = holders; |
|
|
|
partials = holders = undefined; |
|
} |
|
var data = isBindKey ? undefined : getData(func); |
|
|
|
var newData = [ |
|
func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, |
|
argPos, ary, arity |
|
]; |
|
|
|
if (data) { |
|
mergeData(newData, data); |
|
} |
|
func = newData[0]; |
|
bitmask = newData[1]; |
|
thisArg = newData[2]; |
|
partials = newData[3]; |
|
holders = newData[4]; |
|
arity = newData[9] = newData[9] === undefined |
|
? (isBindKey ? 0 : func.length) |
|
: nativeMax(newData[9] - length, 0); |
|
|
|
if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) { |
|
bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG); |
|
} |
|
if (!bitmask || bitmask == WRAP_BIND_FLAG) { |
|
var result = createBind(func, bitmask, thisArg); |
|
} else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) { |
|
result = createCurry(func, bitmask, arity); |
|
} else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) { |
|
result = createPartial(func, bitmask, thisArg, partials); |
|
} else { |
|
result = createHybrid.apply(undefined, newData); |
|
} |
|
var setter = data ? baseSetData : setData; |
|
return setWrapToString(setter(result, newData), func, bitmask); |
|
} |
|
|
|
/** |
|
* Used by `_.defaults` to customize its `_.assignIn` use to assign properties |
|
* of source objects to the destination object for all destination properties |
|
* that resolve to `undefined`. |
|
* |
|
* @private |
|
* @param {*} objValue The destination value. |
|
* @param {*} srcValue The source value. |
|
* @param {string} key The key of the property to assign. |
|
* @param {Object} object The parent object of `objValue`. |
|
* @returns {*} Returns the value to assign. |
|
*/ |
|
function customDefaultsAssignIn(objValue, srcValue, key, object) { |
|
if (objValue === undefined || |
|
(eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) { |
|
return srcValue; |
|
} |
|
return objValue; |
|
} |
|
|
|
/** |
|
* Used by `_.defaultsDeep` to customize its `_.merge` use to merge source |
|
* objects into destination objects that are passed thru. |
|
* |
|
* @private |
|
* @param {*} objValue The destination value. |
|
* @param {*} srcValue The source value. |
|
* @param {string} key The key of the property to merge. |
|
* @param {Object} object The parent object of `objValue`. |
|
* @param {Object} source The parent object of `srcValue`. |
|
* @param {Object} [stack] Tracks traversed source values and their merged |
|
* counterparts. |
|
* @returns {*} Returns the value to assign. |
|
*/ |
|
function customDefaultsMerge(objValue, srcValue, key, object, source, stack) { |
|
if (isObject(objValue) && isObject(srcValue)) { |
|
// Recursively merge objects and arrays (susceptible to call stack limits). |
|
stack.set(srcValue, objValue); |
|
baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack); |
|
stack['delete'](srcValue); |
|
} |
|
return objValue; |
|
} |
|
|
|
/** |
|
* Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain |
|
* objects. |
|
* |
|
* @private |
|
* @param {*} value The value to inspect. |
|
* @param {string} key The key of the property to inspect. |
|
* @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`. |
|
*/ |
|
function customOmitClone(value) { |
|
return isPlainObject(value) ? undefined : value; |
|
} |
|
|
|
/** |
|
* A specialized version of `baseIsEqualDeep` for arrays with support for |
|
* partial deep comparisons. |
|
* |
|
* @private |
|
* @param {Array} array The array to compare. |
|
* @param {Array} other The other array to compare. |
|
* @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. |
|
* @param {Function} customizer The function to customize comparisons. |
|
* @param {Function} equalFunc The function to determine equivalents of values. |
|
* @param {Object} stack Tracks traversed `array` and `other` objects. |
|
* @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. |
|
*/ |
|
function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { |
|
var isPartial = bitmask & COMPARE_PARTIAL_FLAG, |
|
arrLength = array.length, |
|
othLength = other.length; |
|
|
|
if (arrLength != othLength && !(isPartial && othLength > arrLength)) { |
|
return false; |
|
} |
|
// Assume cyclic values are equal. |
|
var stacked = stack.get(array); |
|
if (stacked && stack.get(other)) { |
|
return stacked == other; |
|
} |
|
var index = -1, |
|
result = true, |
|
seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined; |
|
|
|
stack.set(array, other); |
|
stack.set(other, array); |
|
|
|
// Ignore non-index properties. |
|
while (++index < arrLength) { |
|
var arrValue = array[index], |
|
othValue = other[index]; |
|
|
|
if (customizer) { |
|
var compared = isPartial |
|
? customizer(othValue, arrValue, index, other, array, stack) |
|
: customizer(arrValue, othValue, index, array, other, stack); |
|
} |
|
if (compared !== undefined) { |
|
if (compared) { |
|
continue; |
|
} |
|
result = false; |
|
break; |
|
} |
|
// Recursively compare arrays (susceptible to call stack limits). |
|
if (seen) { |
|
if (!arraySome(other, function(othValue, othIndex) { |
|
if (!cacheHas(seen, othIndex) && |
|
(arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { |
|
return seen.push(othIndex); |
|
} |
|
})) { |
|
result = false; |
|
break; |
|
} |
|
} else if (!( |
|
arrValue === othValue || |
|
equalFunc(arrValue, othValue, bitmask, customizer, stack) |
|
)) { |
|
result = false; |
|
break; |
|
} |
|
} |
|
stack['delete'](array); |
|
stack['delete'](other); |
|
return result; |
|
} |
|
|
|
/** |
|
* A specialized version of `baseIsEqualDeep` for comparing objects of |
|
* the same `toStringTag`. |
|
* |
|
* **Note:** This function only supports comparing values with tags of |
|
* `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. |
|
* |
|
* @private |
|
* @param {Object} object The object to compare. |
|
* @param {Object} other The other object to compare. |
|
* @param {string} tag The `toStringTag` of the objects to compare. |
|
* @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. |
|
* @param {Function} customizer The function to customize comparisons. |
|
* @param {Function} equalFunc The function to determine equivalents of values. |
|
* @param {Object} stack Tracks traversed `object` and `other` objects. |
|
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`. |
|
*/ |
|
function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { |
|
switch (tag) { |
|
case dataViewTag: |
|
if ((object.byteLength != other.byteLength) || |
|
(object.byteOffset != other.byteOffset)) { |
|
return false; |
|
} |
|
object = object.buffer; |
|
other = other.buffer; |
|
|
|
case arrayBufferTag: |
|
if ((object.byteLength != other.byteLength) || |
|
!equalFunc(new Uint8Array(object), new Uint8Array(other))) { |
|
return false; |
|
} |
|
return true; |
|
|
|
case boolTag: |
|
case dateTag: |
|
case numberTag: |
|
// Coerce booleans to `1` or `0` and dates to milliseconds. |
|
// Invalid dates are coerced to `NaN`. |
|
return eq(+object, +other); |
|
|
|
case errorTag: |
|
return object.name == other.name && object.message == other.message; |
|
|
|
case regexpTag: |
|
case stringTag: |
|
// Coerce regexes to strings and treat strings, primitives and objects, |
|
// as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring |
|
// for more details. |
|
return object == (other + ''); |
|
|
|
case mapTag: |
|
var convert = mapToArray; |
|
|
|
case setTag: |
|
var isPartial = bitmask & COMPARE_PARTIAL_FLAG; |
|
convert || (convert = setToArray); |
|
|
|
if (object.size != other.size && !isPartial) { |
|
return false; |
|
} |
|
// Assume cyclic values are equal. |
|
var stacked = stack.get(object); |
|
if (stacked) { |
|
return stacked == other; |
|
} |
|
bitmask |= COMPARE_UNORDERED_FLAG; |
|
|
|
// Recursively compare objects (susceptible to call stack limits). |
|
stack.set(object, other); |
|
var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); |
|
stack['delete'](object); |
|
return result; |
|
|
|
case symbolTag: |
|
if (symbolValueOf) { |
|
return symbolValueOf.call(object) == symbolValueOf.call(other); |
|
} |
|
} |
|
return false; |
|
} |
|
|
|
/** |
|
* A specialized version of `baseIsEqualDeep` for objects with support for |
|
* partial deep comparisons. |
|
* |
|
* @private |
|
* @param {Object} object The object to compare. |
|
* @param {Object} other The other object to compare. |
|
* @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. |
|
* @param {Function} customizer The function to customize comparisons. |
|
* @param {Function} equalFunc The function to determine equivalents of values. |
|
* @param {Object} stack Tracks traversed `object` and `other` objects. |
|
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`. |
|
*/ |
|
function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { |
|
var isPartial = bitmask & COMPARE_PARTIAL_FLAG, |
|
objProps = getAllKeys(object), |
|
objLength = objProps.length, |
|
othProps = getAllKeys(other), |
|
othLength = othProps.length; |
|
|
|
if (objLength != othLength && !isPartial) { |
|
return false; |
|
} |
|
var index = objLength; |
|
while (index--) { |
|
var key = objProps[index]; |
|
if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) { |
|
return false; |
|
} |
|
} |
|
// Assume cyclic values are equal. |
|
var stacked = stack.get(object); |
|
if (stacked && stack.get(other)) { |
|
return stacked == other; |
|
} |
|
var result = true; |
|
stack.set(object, other); |
|
stack.set(other, object); |
|
|
|
var skipCtor = isPartial; |
|
while (++index < objLength) { |
|
key = objProps[index]; |
|
var objValue = object[key], |
|
othValue = other[key]; |
|
|
|
if (customizer) { |
|
var compared = isPartial |
|
? customizer(othValue, objValue, key, other, object, stack) |
|
: customizer(objValue, othValue, key, object, other, stack); |
|
} |
|
// Recursively compare objects (susceptible to call stack limits). |
|
if (!(compared === undefined |
|
? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) |
|
: compared |
|
)) { |
|
result = false; |
|
break; |
|
} |
|
skipCtor || (skipCtor = key == 'constructor'); |
|
} |
|
if (result && !skipCtor) { |
|
var objCtor = object.constructor, |
|
othCtor = other.constructor; |
|
|
|
// Non `Object` object instances with different constructors are not equal. |
|
if (objCtor != othCtor && |
|
('constructor' in object && 'constructor' in other) && |
|
!(typeof objCtor == 'function' && objCtor instanceof objCtor && |
|
typeof othCtor == 'function' && othCtor instanceof othCtor)) { |
|
result = false; |
|
} |
|
} |
|
stack['delete'](object); |
|
stack['delete'](other); |
|
return result; |
|
} |
|
|
|
/** |
|
* A specialized version of `baseRest` which flattens the rest array. |
|
* |
|
* @private |
|
* @param {Function} func The function to apply a rest parameter to. |
|
* @returns {Function} Returns the new function. |
|
*/ |
|
function flatRest(func) { |
|
return setToString(overRest(func, undefined, flatten), func + ''); |
|
} |
|
|
|
/** |
|
* Creates an array of own enumerable property names and symbols of `object`. |
|
* |
|
* @private |
|
* @param {Object} object The object to query. |
|
* @returns {Array} Returns the array of property names and symbols. |
|
*/ |
|
function getAllKeys(object) { |
|
return baseGetAllKeys(object, keys, getSymbols); |
|
} |
|
|
|
/** |
|
* Creates an array of own and inherited enumerable property names and |
|
* symbols of `object`. |
|
* |
|
* @private |
|
* @param {Object} object The object to query. |
|
* @returns {Array} Returns the array of property names and symbols. |
|
*/ |
|
function getAllKeysIn(object) { |
|
return baseGetAllKeys(object, keysIn, getSymbolsIn); |
|
} |
|
|
|
/** |
|
* Gets metadata for `func`. |
|
* |
|
* @private |
|
* @param {Function} func The function to query. |
|
* @returns {*} Returns the metadata for `func`. |
|
*/ |
|
var getData = !metaMap ? noop : function(func) { |
|
return metaMap.get(func); |
|
}; |
|
|
|
/** |
|
* Gets the name of `func`. |
|
* |
|
* @private |
|
* @param {Function} func The function to query. |
|
* @returns {string} Returns the function name. |
|
*/ |
|
function getFuncName(func) { |
|
var result = (func.name + ''), |
|
array = realNames[result], |
|
length = hasOwnProperty.call(realNames, result) ? array.length : 0; |
|
|
|
while (length--) { |
|
var data = array[length], |
|
otherFunc = data.func; |
|
if (otherFunc == null || otherFunc == func) { |
|
return data.name; |
|
} |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* 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 = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func; |
|
return object.placeholder; |
|
} |
|
|
|
/** |
|
* Gets the appropriate "iteratee" function. If `_.iteratee` is customized, |
|
* this function returns the custom method, otherwise it returns `baseIteratee`. |
|
* If arguments are provided, the chosen function is invoked with them and |
|
* its result is returned. |
|
* |
|
* @private |
|
* @param {*} [value] The value to convert to an iteratee. |
|
* @param {number} [arity] The arity of the created iteratee. |
|
* @returns {Function} Returns the chosen function or its result. |
|
*/ |
|
function getIteratee() { |
|
var result = lodash.iteratee || iteratee; |
|
result = result === iteratee ? baseIteratee : result; |
|
return arguments.length ? result(arguments[0], arguments[1]) : result; |
|
} |
|
|
|
/** |
|
* Gets the data for `map`. |
|
* |
|
* @private |
|
* @param {Object} map The map to query. |
|
* @param {string} key The reference key. |
|
* @returns {*} Returns the map data. |
|
*/ |
|
function getMapData(map, key) { |
|
var data = map.__data__; |
|
return isKeyable(key) |
|
? data[typeof key == 'string' ? 'string' : 'hash'] |
|
: data.map; |
|
} |
|
|
|
/** |
|
* Gets the property names, values, and compare flags of `object`. |
|
* |
|
* @private |
|
* @param {Object} object The object to query. |
|
* @returns {Array} Returns the match data of `object`. |
|
*/ |
|
function getMatchData(object) { |
|
var result = keys(object), |
|
length = result.length; |
|
|
|
while (length--) { |
|
var key = result[length], |
|
value = object[key]; |
|
|
|
result[length] = [key, value, isStrictComparable(value)]; |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* 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; |
|
} |
|
|
|
/** |
|
* A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. |
|
* |
|
* @private |
|
* @param {*} value The value to query. |
|
* @returns {string} Returns the raw `toStringTag`. |
|
*/ |
|
function getRawTag(value) { |
|
var isOwn = hasOwnProperty.call(value, symToStringTag), |
|
tag = value[symToStringTag]; |
|
|
|
try { |
|
value[symToStringTag] = undefined; |
|
var unmasked = true; |
|
} catch (e) {} |
|
|
|
var result = nativeObjectToString.call(value); |
|
if (unmasked) { |
|
if (isOwn) { |
|
value[symToStringTag] = tag; |
|
} else { |
|
delete value[symToStringTag]; |
|
} |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* Creates an array of the own enumerable symbols of `object`. |
|
* |
|
* @private |
|
* @param {Object} object The object to query. |
|
* @returns {Array} Returns the array of symbols. |
|
*/ |
|
var getSymbols = !nativeGetSymbols ? stubArray : function(object) { |
|
if (object == null) { |
|
return []; |
|
} |
|
object = Object(object); |
|
return arrayFilter(nativeGetSymbols(object), function(symbol) { |
|
return propertyIsEnumerable.call(object, symbol); |
|
}); |
|
}; |
|
|
|
/** |
|
* Creates an array of the own and inherited enumerable symbols of `object`. |
|
* |
|
* @private |
|
* @param {Object} object The object to query. |
|
* @returns {Array} Returns the array of symbols. |
|
*/ |
|
var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) { |
|
var result = []; |
|
while (object) { |
|
arrayPush(result, getSymbols(object)); |
|
object = getPrototype(object); |
|
} |
|
return result; |
|
}; |
|
|
|
/** |
|
* Gets the `toStringTag` of `value`. |
|
* |
|
* @private |
|
* @param {*} value The value to query. |
|
* @returns {string} Returns the `toStringTag`. |
|
*/ |
|
var getTag = baseGetTag; |
|
|
|
// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. |
|
if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || |
|
(Map && getTag(new Map) != mapTag) || |
|
(Promise && getTag(Promise.resolve()) != promiseTag) || |
|
(Set && getTag(new Set) != setTag) || |
|
(WeakMap && getTag(new WeakMap) != weakMapTag)) { |
|
getTag = function(value) { |
|
var result = baseGetTag(value), |
|
Ctor = result == objectTag ? value.constructor : undefined, |
|
ctorString = Ctor ? toSource(Ctor) : ''; |
|
|
|
if (ctorString) { |
|
switch (ctorString) { |
|
case dataViewCtorString: return dataViewTag; |
|
case mapCtorString: return mapTag; |
|
case promiseCtorString: return promiseTag; |
|
case setCtorString: return setTag; |
|
case weakMapCtorString: return weakMapTag; |
|
} |
|
} |
|
return result; |
|
}; |
|
} |
|
|
|
/** |
|
* Gets the view, applying any `transforms` to the `start` and `end` positions. |
|
* |
|
* @private |
|
* @param {number} start The start of the view. |
|
* @param {number} end The end of the view. |
|
* @param {Array} transforms The transformations to apply to the view. |
|
* @returns {Object} Returns an object containing the `start` and `end` |
|
* positions of the view. |
|
*/ |
|
function getView(start, end, transforms) { |
|
var index = -1, |
|
length = transforms.length; |
|
|
|
while (++index < length) { |
|
var data = transforms[index], |
|
size = data.size; |
|
|
|
switch (data.type) { |
|
case 'drop': start += size; break; |
|
case 'dropRight': end -= size; break; |
|
case 'take': end = nativeMin(end, start + size); break; |
|
case 'takeRight': start = nativeMax(start, end - size); break; |
|
} |
|
} |
|
return { 'start': start, 'end': end }; |
|
} |
|
|
|
/** |
|
* 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) : []; |
|
} |
|
|
|
/** |
|
* Checks if `path` exists on `object`. |
|
* |
|
* @private |
|
* @param {Object} object The object to query. |
|
* @param {Array|string} path The path to check. |
|
* @param {Function} hasFunc The function to check properties. |
|
* @returns {boolean} Returns `true` if `path` exists, else `false`. |
|
*/ |
|
function hasPath(object, path, hasFunc) { |
|
path = castPath(path, object); |
|
|
|
var index = -1, |
|
length = path.length, |
|
result = false; |
|
|
|
while (++index < length) { |
|
var key = toKey(path[index]); |
|
if (!(result = object != null && hasFunc(object, key))) { |
|
break; |
|
} |
|
object = object[key]; |
|
} |
|
if (result || ++index != length) { |
|
return result; |
|
} |
|
length = object == null ? 0 : object.length; |
|
return !!length && isLength(length) && isIndex(key, length) && |
|
(isArray(object) || isArguments(object)); |
|
} |
|
|
|
/** |
|
* Initializes an array clone. |
|
* |
|
* @private |
|
* @param {Array} array The array to clone. |
|
* @returns {Array} Returns the initialized clone. |
|
*/ |
|
function initCloneArray(array) { |
|
var length = array.length, |
|
result = new array.constructor(length); |
|
|
|
// Add properties assigned by `RegExp#exec`. |
|
if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { |
|
result.index = array.index; |
|
result.input = array.input; |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* Initializes an object clone. |
|
* |
|
* @private |
|
* @param {Object} object The object to clone. |
|
* @returns {Object} Returns the initialized clone. |
|
*/ |
|
function initCloneObject(object) { |
|
return (typeof object.constructor == 'function' && !isPrototype(object)) |
|
? baseCreate(getPrototype(object)) |
|
: {}; |
|
} |
|
|
|
/** |
|
* Initializes an object clone based on its `toStringTag`. |
|
* |
|
* **Note:** This function only supports cloning values with tags of |
|
* `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. |
|
* |
|
* @private |
|
* @param {Object} object The object to clone. |
|
* @param {string} tag The `toStringTag` of the object to clone. |
|
* @param {boolean} [isDeep] Specify a deep clone. |
|
* @returns {Object} Returns the initialized clone. |
|
*/ |
|
function initCloneByTag(object, tag, isDeep) { |
|
var Ctor = object.constructor; |
|
switch (tag) { |
|
case arrayBufferTag: |
|
return cloneArrayBuffer(object); |
|
|
|
case boolTag: |
|
case dateTag: |
|
return new Ctor(+object); |
|
|
|
case dataViewTag: |
|
return cloneDataView(object, isDeep); |
|
|
|
case float32Tag: case float64Tag: |
|
case int8Tag: case int16Tag: case int32Tag: |
|
case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: |
|
return cloneTypedArray(object, isDeep); |
|
|
|
case mapTag: |
|
return new Ctor; |
|
|
|
case numberTag: |
|
case stringTag: |
|
return new Ctor(object); |
|
|
|
case regexpTag: |
|
return cloneRegExp(object); |
|
|
|
case setTag: |
|
return new Ctor; |
|
|
|
case symbolTag: |
|
return cloneSymbol(object); |
|
} |
|
} |
|
|
|
/** |
|
* 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; |
|
if (!length) { |
|
return source; |
|
} |
|
var 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 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 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) { |
|
var type = typeof value; |
|
length = length == null ? MAX_SAFE_INTEGER : length; |
|
|
|
return !!length && |
|
(type == 'number' || |
|
(type != 'symbol' && reIsUint.test(value))) && |
|
(value > -1 && value % 1 == 0 && value < length); |
|
} |
|
|
|
/** |
|
* Checks if the given arguments are from an iteratee call. |
|
* |
|
* @private |
|
* @param {*} value The potential iteratee value argument. |
|
* @param {*} index The potential iteratee index or key argument. |
|
* @param {*} object The potential iteratee object argument. |
|
* @returns {boolean} Returns `true` if the arguments are from an iteratee call, |
|
* else `false`. |
|
*/ |
|
function isIterateeCall(value, index, object) { |
|
if (!isObject(object)) { |
|
return false; |
|
} |
|
var type = typeof index; |
|
if (type == 'number' |
|
? (isArrayLike(object) && isIndex(index, object.length)) |
|
: (type == 'string' && index in object) |
|
) { |
|
return eq(object[index], value); |
|
} |
|
return false; |
|
} |
|
|
|
/** |
|
* Checks if `value` is a property name and not a property path. |
|
* |
|
* @private |
|
* @param {*} value The value to check. |
|
* @param {Object} [object] The object to query keys on. |
|
* @returns {boolean} Returns `true` if `value` is a property name, else `false`. |
|
*/ |
|
function isKey(value, object) { |
|
if (isArray(value)) { |
|
return false; |
|
} |
|
var type = typeof value; |
|
if (type == 'number' || type == 'symbol' || type == 'boolean' || |
|
value == null || isSymbol(value)) { |
|
return true; |
|
} |
|
return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || |
|
(object != null && value in Object(object)); |
|
} |
|
|
|
/** |
|
* Checks if `value` is suitable for use as unique object key. |
|
* |
|
* @private |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is suitable, else `false`. |
|
*/ |
|
function isKeyable(value) { |
|
var type = typeof value; |
|
return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') |
|
? (value !== '__proto__') |
|
: (value === null); |
|
} |
|
|
|
/** |
|
* Checks if `func` has a lazy counterpart. |
|
* |
|
* @private |
|
* @param {Function} func The function to check. |
|
* @returns {boolean} Returns `true` if `func` has a lazy counterpart, |
|
* else `false`. |
|
*/ |
|
function isLaziable(func) { |
|
var funcName = getFuncName(func), |
|
other = lodash[funcName]; |
|
|
|
if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) { |
|
return false; |
|
} |
|
if (func === other) { |
|
return true; |
|
} |
|
var data = getData(other); |
|
return !!data && func === data[0]; |
|
} |
|
|
|
/** |
|
* 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); |
|
} |
|
|
|
/** |
|
* Checks if `func` is capable of being masked. |
|
* |
|
* @private |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `func` is maskable, else `false`. |
|
*/ |
|
var isMaskable = coreJsData ? isFunction : stubFalse; |
|
|
|
/** |
|
* Checks if `value` is likely a prototype object. |
|
* |
|
* @private |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is a prototype, else `false`. |
|
*/ |
|
function isPrototype(value) { |
|
var Ctor = value && value.constructor, |
|
proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; |
|
|
|
return value === proto; |
|
} |
|
|
|
/** |
|
* Checks if `value` is suitable for strict equality comparisons, i.e. `===`. |
|
* |
|
* @private |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` if suitable for strict |
|
* equality comparisons, else `false`. |
|
*/ |
|
function isStrictComparable(value) { |
|
return value === value && !isObject(value); |
|
} |
|
|
|
/** |
|
* A specialized version of `matchesProperty` for source values suitable |
|
* for strict equality comparisons, i.e. `===`. |
|
* |
|
* @private |
|
* @param {string} key The key of the property to get. |
|
* @param {*} srcValue The value to match. |
|
* @returns {Function} Returns the new spec function. |
|
*/ |
|
function matchesStrictComparable(key, srcValue) { |
|
return function(object) { |
|
if (object == null) { |
|
return false; |
|
} |
|
return object[key] === srcValue && |
|
(srcValue !== undefined || (key in Object(object))); |
|
}; |
|
} |
|
|
|
/** |
|
* A specialized version of `_.memoize` which clears the memoized function's |
|
* cache when it exceeds `MAX_MEMOIZE_SIZE`. |
|
* |
|
* @private |
|
* @param {Function} func The function to have its output memoized. |
|
* @returns {Function} Returns the new memoized function. |
|
*/ |
|
function memoizeCapped(func) { |
|
var result = memoize(func, function(key) { |
|
if (cache.size === MAX_MEMOIZE_SIZE) { |
|
cache.clear(); |
|
} |
|
return key; |
|
}); |
|
|
|
var cache = result.cache; |
|
return result; |
|
} |
|
|
|
/** |
|
* Merges the function metadata of `source` into `data`. |
|
* |
|
* Merging metadata reduces the number of wrappers used to invoke a function. |
|
* This is possible because methods like `_.bind`, `_.curry`, and `_.partial` |
|
* may be applied regardless of execution order. Methods like `_.ary` and |
|
* `_.rearg` modify function arguments, making the order in which they are |
|
* executed important, preventing the merging of metadata. However, we make |
|
* an exception for a safe combined case where curried functions have `_.ary` |
|
* and or `_.rearg` applied. |
|
* |
|
* @private |
|
* @param {Array} data The destination metadata. |
|
* @param {Array} source The source metadata. |
|
* @returns {Array} Returns `data`. |
|
*/ |
|
function mergeData(data, source) { |
|
var bitmask = data[1], |
|
srcBitmask = source[1], |
|
newBitmask = bitmask | srcBitmask, |
|
isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG); |
|
|
|
var isCombo = |
|
((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) || |
|
((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) || |
|
((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG)); |
|
|
|
// Exit early if metadata can't be merged. |
|
if (!(isCommon || isCombo)) { |
|
return data; |
|
} |
|
// Use source `thisArg` if available. |
|
if (srcBitmask & WRAP_BIND_FLAG) { |
|
data[2] = source[2]; |
|
// Set when currying a bound function. |
|
newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG; |
|
} |
|
// Compose partial arguments. |
|
var value = source[3]; |
|
if (value) { |
|
var partials = data[3]; |
|
data[3] = partials ? composeArgs(partials, value, source[4]) : value; |
|
data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4]; |
|
} |
|
// Compose partial right arguments. |
|
value = source[5]; |
|
if (value) { |
|
partials = data[5]; |
|
data[5] = partials ? composeArgsRight(partials, value, source[6]) : value; |
|
data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6]; |
|
} |
|
// Use source `argPos` if available. |
|
value = source[7]; |
|
if (value) { |
|
data[7] = value; |
|
} |
|
// Use source `ary` if it's smaller. |
|
if (srcBitmask & WRAP_ARY_FLAG) { |
|
data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); |
|
} |
|
// Use source `arity` if one is not provided. |
|
if (data[9] == null) { |
|
data[9] = source[9]; |
|
} |
|
// Use source `func` and merge bitmasks. |
|
data[0] = source[0]; |
|
data[1] = newBitmask; |
|
|
|
return data; |
|
} |
|
|
|
/** |
|
* This function is like |
|
* [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) |
|
* except that it includes inherited enumerable properties. |
|
* |
|
* @private |
|
* @param {Object} object The object to query. |
|
* @returns {Array} Returns the array of property names. |
|
*/ |
|
function nativeKeysIn(object) { |
|
var result = []; |
|
if (object != null) { |
|
for (var key in Object(object)) { |
|
result.push(key); |
|
} |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* Converts `value` to a string using `Object.prototype.toString`. |
|
* |
|
* @private |
|
* @param {*} value The value to convert. |
|
* @returns {string} Returns the converted string. |
|
*/ |
|
function objectToString(value) { |
|
return nativeObjectToString.call(value); |
|
} |
|
|
|
/** |
|
* A specialized version of `baseRest` which transforms the rest array. |
|
* |
|
* @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. |
|
* @param {Function} transform The rest array transform. |
|
* @returns {Function} Returns the new function. |
|
*/ |
|
function overRest(func, start, transform) { |
|
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] = transform(array); |
|
return apply(func, this, otherArgs); |
|
}; |
|
} |
|
|
|
/** |
|
* Gets the parent value at `path` of `object`. |
|
* |
|
* @private |
|
* @param {Object} object The object to query. |
|
* @param {Array} path The path to get the parent value of. |
|
* @returns {*} Returns the parent value. |
|
*/ |
|
function parent(object, path) { |
|
return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1)); |
|
} |
|
|
|
/** |
|
* 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 metadata for `func`. |
|
* |
|
* **Note:** If this function becomes hot, i.e. is invoked a lot in a short |
|
* period of time, it will trip its breaker and transition to an identity |
|
* function to avoid garbage collection pauses in V8. See |
|
* [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070) |
|
* for more details. |
|
* |
|
* @private |
|
* @param {Function} func The function to associate metadata with. |
|
* @param {*} data The metadata. |
|
* @returns {Function} Returns `func`. |
|
*/ |
|
var setData = shortOut(baseSetData); |
|
|
|
/** |
|
* A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout). |
|
* |
|
* @private |
|
* @param {Function} func The function to delay. |
|
* @param {number} wait The number of milliseconds to delay invocation. |
|
* @returns {number|Object} Returns the timer id or timeout object. |
|
*/ |
|
var setTimeout = ctxSetTimeout || function(func, wait) { |
|
return root.setTimeout(func, wait); |
|
}; |
|
|
|
/** |
|
* Sets the `toString` method of `func` to return `string`. |
|
* |
|
* @private |
|
* @param {Function} func The function to modify. |
|
* @param {Function} string The `toString` result. |
|
* @returns {Function} Returns `func`. |
|
*/ |
|
var setToString = shortOut(baseSetToString); |
|
|
|
/** |
|
* 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`. |
|
*/ |
|
function setWrapToString(wrapper, reference, bitmask) { |
|
var source = (reference + ''); |
|
return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask))); |
|
} |
|
|
|
/** |
|
* Creates a function that'll short out and invoke `identity` instead |
|
* of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` |
|
* milliseconds. |
|
* |
|
* @private |
|
* @param {Function} func The function to restrict. |
|
* @returns {Function} Returns the new shortable function. |
|
*/ |
|
function shortOut(func) { |
|
var count = 0, |
|
lastCalled = 0; |
|
|
|
return function() { |
|
var stamp = nativeNow(), |
|
remaining = HOT_SPAN - (stamp - lastCalled); |
|
|
|
lastCalled = stamp; |
|
if (remaining > 0) { |
|
if (++count >= HOT_COUNT) { |
|
return arguments[0]; |
|
} |
|
} else { |
|
count = 0; |
|
} |
|
return func.apply(undefined, arguments); |
|
}; |
|
} |
|
|
|
/** |
|
* A specialized version of `_.shuffle` which mutates and sets the size of `array`. |
|
* |
|
* @private |
|
* @param {Array} array The array to shuffle. |
|
* @param {number} [size=array.length] The size of `array`. |
|
* @returns {Array} Returns `array`. |
|
*/ |
|
function shuffleSelf(array, size) { |
|
var index = -1, |
|
length = array.length, |
|
lastIndex = length - 1; |
|
|
|
size = size === undefined ? length : size; |
|
while (++index < size) { |
|
var rand = baseRandom(index, lastIndex), |
|
value = array[rand]; |
|
|
|
array[rand] = array[index]; |
|
array[index] = value; |
|
} |
|
array.length = size; |
|
return array; |
|
} |
|
|
|
/** |
|
* Converts `string` to a property path array. |
|
* |
|
* @private |
|
* @param {string} string The string to convert. |
|
* @returns {Array} Returns the property path array. |
|
*/ |
|
var stringToPath = memoizeCapped(function(string) { |
|
var result = []; |
|
if (string.charCodeAt(0) === 46 /* . */) { |
|
result.push(''); |
|
} |
|
string.replace(rePropName, function(match, number, quote, subString) { |
|
result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); |
|
}); |
|
return result; |
|
}); |
|
|
|
/** |
|
* Converts `value` to a string key if it's not a string or symbol. |
|
* |
|
* @private |
|
* @param {*} value The value to inspect. |
|
* @returns {string|symbol} Returns the key. |
|
*/ |
|
function toKey(value) { |
|
if (typeof value == 'string' || isSymbol(value)) { |
|
return value; |
|
} |
|
var result = (value + ''); |
|
return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; |
|
} |
|
|
|
/** |
|
* Converts `func` to its source code. |
|
* |
|
* @private |
|
* @param {Function} func The function to convert. |
|
* @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 clone of `wrapper`. |
|
* |
|
* @private |
|
* @param {Object} wrapper The wrapper to clone. |
|
* @returns {Object} Returns the cloned wrapper. |
|
*/ |
|
function wrapperClone(wrapper) { |
|
if (wrapper instanceof LazyWrapper) { |
|
return wrapper.clone(); |
|
} |
|
var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__); |
|
result.__actions__ = copyArray(wrapper.__actions__); |
|
result.__index__ = wrapper.__index__; |
|
result.__values__ = wrapper.__values__; |
|
return result; |
|
} |
|
|
|
/*------------------------------------------------------------------------*/ |
|
|
|
/** |
|
* Creates an array of elements split into groups the length of `size`. |
|
* If `array` can't be split evenly, the final chunk will be the remaining |
|
* elements. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Array |
|
* @param {Array} array The array to process. |
|
* @param {number} [size=1] The length of each chunk |
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. |
|
* @returns {Array} Returns the new array of chunks. |
|
* @example |
|
* |
|
* _.chunk(['a', 'b', 'c', 'd'], 2); |
|
* // => [['a', 'b'], ['c', 'd']] |
|
* |
|
* _.chunk(['a', 'b', 'c', 'd'], 3); |
|
* // => [['a', 'b', 'c'], ['d']] |
|
*/ |
|
function chunk(array, size, guard) { |
|
if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) { |
|
size = 1; |
|
} else { |
|
size = nativeMax(toInteger(size), 0); |
|
} |
|
var length = array == null ? 0 : array.length; |
|
if (!length || size < 1) { |
|
return []; |
|
} |
|
var index = 0, |
|
resIndex = 0, |
|
result = Array(nativeCeil(length / size)); |
|
|
|
while (index < length) { |
|
result[resIndex++] = baseSlice(array, index, (index += size)); |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* Creates an array with all falsey values removed. The values `false`, `null`, |
|
* `0`, `""`, `undefined`, and `NaN` are falsey. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Array |
|
* @param {Array} array The array to compact. |
|
* @returns {Array} Returns the new array of filtered values. |
|
* @example |
|
* |
|
* _.compact([0, 1, false, 2, '', 3]); |
|
* // => [1, 2, 3] |
|
*/ |
|
function compact(array) { |
|
var index = -1, |
|
length = array == null ? 0 : array.length, |
|
resIndex = 0, |
|
result = []; |
|
|
|
while (++index < length) { |
|
var value = array[index]; |
|
if (value) { |
|
result[resIndex++] = value; |
|
} |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* Creates a new array concatenating `array` with any additional arrays |
|
* and/or values. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Array |
|
* @param {Array} array The array to concatenate. |
|
* @param {...*} [values] The values to concatenate. |
|
* @returns {Array} Returns the new concatenated array. |
|
* @example |
|
* |
|
* var array = [1]; |
|
* var other = _.concat(array, 2, [3], [[4]]); |
|
* |
|
* console.log(other); |
|
* // => [1, 2, 3, [4]] |
|
* |
|
* console.log(array); |
|
* // => [1] |
|
*/ |
|
function concat() { |
|
var length = arguments.length; |
|
if (!length) { |
|
return []; |
|
} |
|
var args = Array(length - 1), |
|
array = arguments[0], |
|
index = length; |
|
|
|
while (index--) { |
|
args[index - 1] = arguments[index]; |
|
} |
|
return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1)); |
|
} |
|
|
|
/** |
|
* Creates an array of `array` values not included in the other given arrays |
|
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) |
|
* for equality comparisons. The order and references of result values are |
|
* determined by the first array. |
|
* |
|
* **Note:** Unlike `_.pullAll`, this method returns a new array. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Array |
|
* @param {Array} array The array to inspect. |
|
* @param {...Array} [values] The values to exclude. |
|
* @returns {Array} Returns the new array of filtered values. |
|
* @see _.without, _.xor |
|
* @example |
|
* |
|
* _.difference([2, 1], [2, 3]); |
|
* // => [1] |
|
*/ |
|
var difference = baseRest(function(array, values) { |
|
return isArrayLikeObject(array) |
|
? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true)) |
|
: []; |
|
}); |
|
|
|
/** |
|
* This method is like `_.difference` except that it accepts `iteratee` which |
|
* is invoked for each element of `array` and `values` to generate the criterion |
|
* by which they're compared. The order and references of result values are |
|
* determined by the first array. The iteratee is invoked with one argument: |
|
* (value). |
|
* |
|
* **Note:** Unlike `_.pullAllBy`, this method returns a new array. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Array |
|
* @param {Array} array The array to inspect. |
|
* @param {...Array} [values] The values to exclude. |
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element. |
|
* @returns {Array} Returns the new array of filtered values. |
|
* @example |
|
* |
|
* _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor); |
|
* // => [1.2] |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x'); |
|
* // => [{ 'x': 2 }] |
|
*/ |
|
var differenceBy = baseRest(function(array, values) { |
|
var iteratee = last(values); |
|
if (isArrayLikeObject(iteratee)) { |
|
iteratee = undefined; |
|
} |
|
return isArrayLikeObject(array) |
|
? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2)) |
|
: []; |
|
}); |
|
|
|
/** |
|
* This method is like `_.difference` except that it accepts `comparator` |
|
* which is invoked to compare elements of `array` to `values`. The order and |
|
* references of result values are determined by the first array. The comparator |
|
* is invoked with two arguments: (arrVal, othVal). |
|
* |
|
* **Note:** Unlike `_.pullAllWith`, this method returns a new array. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Array |
|
* @param {Array} array The array to inspect. |
|
* @param {...Array} [values] The values to exclude. |
|
* @param {Function} [comparator] The comparator invoked per element. |
|
* @returns {Array} Returns the new array of filtered values. |
|
* @example |
|
* |
|
* var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; |
|
* |
|
* _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual); |
|
* // => [{ 'x': 2, 'y': 1 }] |
|
*/ |
|
var differenceWith = baseRest(function(array, values) { |
|
var comparator = last(values); |
|
if (isArrayLikeObject(comparator)) { |
|
comparator = undefined; |
|
} |
|
return isArrayLikeObject(array) |
|
? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator) |
|
: []; |
|
}); |
|
|
|
/** |
|
* Creates a slice of `array` with `n` elements dropped from the beginning. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.5.0 |
|
* @category Array |
|
* @param {Array} array The array to query. |
|
* @param {number} [n=1] The number of elements to drop. |
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. |
|
* @returns {Array} Returns the slice of `array`. |
|
* @example |
|
* |
|
* _.drop([1, 2, 3]); |
|
* // => [2, 3] |
|
* |
|
* _.drop([1, 2, 3], 2); |
|
* // => [3] |
|
* |
|
* _.drop([1, 2, 3], 5); |
|
* // => [] |
|
* |
|
* _.drop([1, 2, 3], 0); |
|
* // => [1, 2, 3] |
|
*/ |
|
function drop(array, n, guard) { |
|
var length = array == null ? 0 : array.length; |
|
if (!length) { |
|
return []; |
|
} |
|
n = (guard || n === undefined) ? 1 : toInteger(n); |
|
return baseSlice(array, n < 0 ? 0 : n, length); |
|
} |
|
|
|
/** |
|
* Creates a slice of `array` with `n` elements dropped from the end. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Array |
|
* @param {Array} array The array to query. |
|
* @param {number} [n=1] The number of elements to drop. |
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. |
|
* @returns {Array} Returns the slice of `array`. |
|
* @example |
|
* |
|
* _.dropRight([1, 2, 3]); |
|
* // => [1, 2] |
|
* |
|
* _.dropRight([1, 2, 3], 2); |
|
* // => [1] |
|
* |
|
* _.dropRight([1, 2, 3], 5); |
|
* // => [] |
|
* |
|
* _.dropRight([1, 2, 3], 0); |
|
* // => [1, 2, 3] |
|
*/ |
|
function dropRight(array, n, guard) { |
|
var length = array == null ? 0 : array.length; |
|
if (!length) { |
|
return []; |
|
} |
|
n = (guard || n === undefined) ? 1 : toInteger(n); |
|
n = length - n; |
|
return baseSlice(array, 0, n < 0 ? 0 : n); |
|
} |
|
|
|
/** |
|
* Creates a slice of `array` excluding elements dropped from the end. |
|
* Elements are dropped until `predicate` returns falsey. The predicate is |
|
* invoked with three arguments: (value, index, array). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Array |
|
* @param {Array} array The array to query. |
|
* @param {Function} [predicate=_.identity] The function invoked per iteration. |
|
* @returns {Array} Returns the slice of `array`. |
|
* @example |
|
* |
|
* var users = [ |
|
* { 'user': 'barney', 'active': true }, |
|
* { 'user': 'fred', 'active': false }, |
|
* { 'user': 'pebbles', 'active': false } |
|
* ]; |
|
* |
|
* _.dropRightWhile(users, function(o) { return !o.active; }); |
|
* // => objects for ['barney'] |
|
* |
|
* // The `_.matches` iteratee shorthand. |
|
* _.dropRightWhile(users, { 'user': 'pebbles', 'active': false }); |
|
* // => objects for ['barney', 'fred'] |
|
* |
|
* // The `_.matchesProperty` iteratee shorthand. |
|
* _.dropRightWhile(users, ['active', false]); |
|
* // => objects for ['barney'] |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.dropRightWhile(users, 'active'); |
|
* // => objects for ['barney', 'fred', 'pebbles'] |
|
*/ |
|
function dropRightWhile(array, predicate) { |
|
return (array && array.length) |
|
? baseWhile(array, getIteratee(predicate, 3), true, true) |
|
: []; |
|
} |
|
|
|
/** |
|
* Creates a slice of `array` excluding elements dropped from the beginning. |
|
* Elements are dropped until `predicate` returns falsey. The predicate is |
|
* invoked with three arguments: (value, index, array). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Array |
|
* @param {Array} array The array to query. |
|
* @param {Function} [predicate=_.identity] The function invoked per iteration. |
|
* @returns {Array} Returns the slice of `array`. |
|
* @example |
|
* |
|
* var users = [ |
|
* { 'user': 'barney', 'active': false }, |
|
* { 'user': 'fred', 'active': false }, |
|
* { 'user': 'pebbles', 'active': true } |
|
* ]; |
|
* |
|
* _.dropWhile(users, function(o) { return !o.active; }); |
|
* // => objects for ['pebbles'] |
|
* |
|
* // The `_.matches` iteratee shorthand. |
|
* _.dropWhile(users, { 'user': 'barney', 'active': false }); |
|
* // => objects for ['fred', 'pebbles'] |
|
* |
|
* // The `_.matchesProperty` iteratee shorthand. |
|
* _.dropWhile(users, ['active', false]); |
|
* // => objects for ['pebbles'] |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.dropWhile(users, 'active'); |
|
* // => objects for ['barney', 'fred', 'pebbles'] |
|
*/ |
|
function dropWhile(array, predicate) { |
|
return (array && array.length) |
|
? baseWhile(array, getIteratee(predicate, 3), true) |
|
: []; |
|
} |
|
|
|
/** |
|
* Fills elements of `array` with `value` from `start` up to, but not |
|
* including, `end`. |
|
* |
|
* **Note:** This method mutates `array`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.2.0 |
|
* @category Array |
|
* @param {Array} array The array to fill. |
|
* @param {*} value The value to fill `array` with. |
|
* @param {number} [start=0] The start position. |
|
* @param {number} [end=array.length] The end position. |
|
* @returns {Array} Returns `array`. |
|
* @example |
|
* |
|
* var array = [1, 2, 3]; |
|
* |
|
* _.fill(array, 'a'); |
|
* console.log(array); |
|
* // => ['a', 'a', 'a'] |
|
* |
|
* _.fill(Array(3), 2); |
|
* // => [2, 2, 2] |
|
* |
|
* _.fill([4, 6, 8, 10], '*', 1, 3); |
|
* // => [4, '*', '*', 10] |
|
*/ |
|
function fill(array, value, start, end) { |
|
var length = array == null ? 0 : array.length; |
|
if (!length) { |
|
return []; |
|
} |
|
if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { |
|
start = 0; |
|
end = length; |
|
} |
|
return baseFill(array, value, start, end); |
|
} |
|
|
|
/** |
|
* This method is like `_.find` except that it returns the index of the first |
|
* element `predicate` returns truthy for instead of the element itself. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 1.1.0 |
|
* @category Array |
|
* @param {Array} array The array to inspect. |
|
* @param {Function} [predicate=_.identity] The function invoked per iteration. |
|
* @param {number} [fromIndex=0] The index to search from. |
|
* @returns {number} Returns the index of the found element, else `-1`. |
|
* @example |
|
* |
|
* var users = [ |
|
* { 'user': 'barney', 'active': false }, |
|
* { 'user': 'fred', 'active': false }, |
|
* { 'user': 'pebbles', 'active': true } |
|
* ]; |
|
* |
|
* _.findIndex(users, function(o) { return o.user == 'barney'; }); |
|
* // => 0 |
|
* |
|
* // The `_.matches` iteratee shorthand. |
|
* _.findIndex(users, { 'user': 'fred', 'active': false }); |
|
* // => 1 |
|
* |
|
* // The `_.matchesProperty` iteratee shorthand. |
|
* _.findIndex(users, ['active', false]); |
|
* // => 0 |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.findIndex(users, 'active'); |
|
* // => 2 |
|
*/ |
|
function findIndex(array, predicate, fromIndex) { |
|
var length = array == null ? 0 : array.length; |
|
if (!length) { |
|
return -1; |
|
} |
|
var index = fromIndex == null ? 0 : toInteger(fromIndex); |
|
if (index < 0) { |
|
index = nativeMax(length + index, 0); |
|
} |
|
return baseFindIndex(array, getIteratee(predicate, 3), index); |
|
} |
|
|
|
/** |
|
* This method is like `_.findIndex` except that it iterates over elements |
|
* of `collection` from right to left. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 2.0.0 |
|
* @category Array |
|
* @param {Array} array The array to inspect. |
|
* @param {Function} [predicate=_.identity] The function invoked per iteration. |
|
* @param {number} [fromIndex=array.length-1] The index to search from. |
|
* @returns {number} Returns the index of the found element, else `-1`. |
|
* @example |
|
* |
|
* var users = [ |
|
* { 'user': 'barney', 'active': true }, |
|
* { 'user': 'fred', 'active': false }, |
|
* { 'user': 'pebbles', 'active': false } |
|
* ]; |
|
* |
|
* _.findLastIndex(users, function(o) { return o.user == 'pebbles'; }); |
|
* // => 2 |
|
* |
|
* // The `_.matches` iteratee shorthand. |
|
* _.findLastIndex(users, { 'user': 'barney', 'active': true }); |
|
* // => 0 |
|
* |
|
* // The `_.matchesProperty` iteratee shorthand. |
|
* _.findLastIndex(users, ['active', false]); |
|
* // => 2 |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.findLastIndex(users, 'active'); |
|
* // => 0 |
|
*/ |
|
function findLastIndex(array, predicate, fromIndex) { |
|
var length = array == null ? 0 : array.length; |
|
if (!length) { |
|
return -1; |
|
} |
|
var index = length - 1; |
|
if (fromIndex !== undefined) { |
|
index = toInteger(fromIndex); |
|
index = fromIndex < 0 |
|
? nativeMax(length + index, 0) |
|
: nativeMin(index, length - 1); |
|
} |
|
return baseFindIndex(array, getIteratee(predicate, 3), index, true); |
|
} |
|
|
|
/** |
|
* Flattens `array` a single level deep. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Array |
|
* @param {Array} array The array to flatten. |
|
* @returns {Array} Returns the new flattened array. |
|
* @example |
|
* |
|
* _.flatten([1, [2, [3, [4]], 5]]); |
|
* // => [1, 2, [3, [4]], 5] |
|
*/ |
|
function flatten(array) { |
|
var length = array == null ? 0 : array.length; |
|
return length ? baseFlatten(array, 1) : []; |
|
} |
|
|
|
/** |
|
* Recursively flattens `array`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Array |
|
* @param {Array} array The array to flatten. |
|
* @returns {Array} Returns the new flattened array. |
|
* @example |
|
* |
|
* _.flattenDeep([1, [2, [3, [4]], 5]]); |
|
* // => [1, 2, 3, 4, 5] |
|
*/ |
|
function flattenDeep(array) { |
|
var length = array == null ? 0 : array.length; |
|
return length ? baseFlatten(array, INFINITY) : []; |
|
} |
|
|
|
/** |
|
* Recursively flatten `array` up to `depth` times. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.4.0 |
|
* @category Array |
|
* @param {Array} array The array to flatten. |
|
* @param {number} [depth=1] The maximum recursion depth. |
|
* @returns {Array} Returns the new flattened array. |
|
* @example |
|
* |
|
* var array = [1, [2, [3, [4]], 5]]; |
|
* |
|
* _.flattenDepth(array, 1); |
|
* // => [1, 2, [3, [4]], 5] |
|
* |
|
* _.flattenDepth(array, 2); |
|
* // => [1, 2, 3, [4], 5] |
|
*/ |
|
function flattenDepth(array, depth) { |
|
var length = array == null ? 0 : array.length; |
|
if (!length) { |
|
return []; |
|
} |
|
depth = depth === undefined ? 1 : toInteger(depth); |
|
return baseFlatten(array, depth); |
|
} |
|
|
|
/** |
|
* The inverse of `_.toPairs`; this method returns an object composed |
|
* from key-value `pairs`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Array |
|
* @param {Array} pairs The key-value pairs. |
|
* @returns {Object} Returns the new object. |
|
* @example |
|
* |
|
* _.fromPairs([['a', 1], ['b', 2]]); |
|
* // => { 'a': 1, 'b': 2 } |
|
*/ |
|
function fromPairs(pairs) { |
|
var index = -1, |
|
length = pairs == null ? 0 : pairs.length, |
|
result = {}; |
|
|
|
while (++index < length) { |
|
var pair = pairs[index]; |
|
result[pair[0]] = pair[1]; |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* Gets the first element of `array`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @alias first |
|
* @category Array |
|
* @param {Array} array The array to query. |
|
* @returns {*} Returns the first element of `array`. |
|
* @example |
|
* |
|
* _.head([1, 2, 3]); |
|
* // => 1 |
|
* |
|
* _.head([]); |
|
* // => undefined |
|
*/ |
|
function head(array) { |
|
return (array && array.length) ? array[0] : undefined; |
|
} |
|
|
|
/** |
|
* Gets the index at which the first occurrence of `value` is found in `array` |
|
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) |
|
* for equality comparisons. If `fromIndex` is negative, it's used as the |
|
* offset from the end of `array`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Array |
|
* @param {Array} array The array to inspect. |
|
* @param {*} value The value to search for. |
|
* @param {number} [fromIndex=0] The index to search from. |
|
* @returns {number} Returns the index of the matched value, else `-1`. |
|
* @example |
|
* |
|
* _.indexOf([1, 2, 1, 2], 2); |
|
* // => 1 |
|
* |
|
* // Search from the `fromIndex`. |
|
* _.indexOf([1, 2, 1, 2], 2, 2); |
|
* // => 3 |
|
*/ |
|
function indexOf(array, value, fromIndex) { |
|
var length = array == null ? 0 : array.length; |
|
if (!length) { |
|
return -1; |
|
} |
|
var index = fromIndex == null ? 0 : toInteger(fromIndex); |
|
if (index < 0) { |
|
index = nativeMax(length + index, 0); |
|
} |
|
return baseIndexOf(array, value, index); |
|
} |
|
|
|
/** |
|
* Gets all but the last element of `array`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Array |
|
* @param {Array} array The array to query. |
|
* @returns {Array} Returns the slice of `array`. |
|
* @example |
|
* |
|
* _.initial([1, 2, 3]); |
|
* // => [1, 2] |
|
*/ |
|
function initial(array) { |
|
var length = array == null ? 0 : array.length; |
|
return length ? baseSlice(array, 0, -1) : []; |
|
} |
|
|
|
/** |
|
* Creates an array of unique values that are included in all given arrays |
|
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) |
|
* for equality comparisons. The order and references of result values are |
|
* determined by the first array. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Array |
|
* @param {...Array} [arrays] The arrays to inspect. |
|
* @returns {Array} Returns the new array of intersecting values. |
|
* @example |
|
* |
|
* _.intersection([2, 1], [2, 3]); |
|
* // => [2] |
|
*/ |
|
var intersection = baseRest(function(arrays) { |
|
var mapped = arrayMap(arrays, castArrayLikeObject); |
|
return (mapped.length && mapped[0] === arrays[0]) |
|
? baseIntersection(mapped) |
|
: []; |
|
}); |
|
|
|
/** |
|
* This method is like `_.intersection` except that it accepts `iteratee` |
|
* which is invoked for each element of each `arrays` to generate the criterion |
|
* by which they're compared. The order and references of result values are |
|
* determined by the first array. The iteratee is invoked with one argument: |
|
* (value). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Array |
|
* @param {...Array} [arrays] The arrays to inspect. |
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element. |
|
* @returns {Array} Returns the new array of intersecting values. |
|
* @example |
|
* |
|
* _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor); |
|
* // => [2.1] |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); |
|
* // => [{ 'x': 1 }] |
|
*/ |
|
var intersectionBy = baseRest(function(arrays) { |
|
var iteratee = last(arrays), |
|
mapped = arrayMap(arrays, castArrayLikeObject); |
|
|
|
if (iteratee === last(mapped)) { |
|
iteratee = undefined; |
|
} else { |
|
mapped.pop(); |
|
} |
|
return (mapped.length && mapped[0] === arrays[0]) |
|
? baseIntersection(mapped, getIteratee(iteratee, 2)) |
|
: []; |
|
}); |
|
|
|
/** |
|
* This method is like `_.intersection` except that it accepts `comparator` |
|
* which is invoked to compare elements of `arrays`. The order and references |
|
* of result values are determined by the first array. The comparator is |
|
* invoked with two arguments: (arrVal, othVal). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Array |
|
* @param {...Array} [arrays] The arrays to inspect. |
|
* @param {Function} [comparator] The comparator invoked per element. |
|
* @returns {Array} Returns the new array of intersecting values. |
|
* @example |
|
* |
|
* var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; |
|
* var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; |
|
* |
|
* _.intersectionWith(objects, others, _.isEqual); |
|
* // => [{ 'x': 1, 'y': 2 }] |
|
*/ |
|
var intersectionWith = baseRest(function(arrays) { |
|
var comparator = last(arrays), |
|
mapped = arrayMap(arrays, castArrayLikeObject); |
|
|
|
comparator = typeof comparator == 'function' ? comparator : undefined; |
|
if (comparator) { |
|
mapped.pop(); |
|
} |
|
return (mapped.length && mapped[0] === arrays[0]) |
|
? baseIntersection(mapped, undefined, comparator) |
|
: []; |
|
}); |
|
|
|
/** |
|
* Converts all elements in `array` into a string separated by `separator`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Array |
|
* @param {Array} array The array to convert. |
|
* @param {string} [separator=','] The element separator. |
|
* @returns {string} Returns the joined string. |
|
* @example |
|
* |
|
* _.join(['a', 'b', 'c'], '~'); |
|
* // => 'a~b~c' |
|
*/ |
|
function join(array, separator) { |
|
return array == null ? '' : nativeJoin.call(array, separator); |
|
} |
|
|
|
/** |
|
* Gets the last element of `array`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Array |
|
* @param {Array} array The array to query. |
|
* @returns {*} Returns the last element of `array`. |
|
* @example |
|
* |
|
* _.last([1, 2, 3]); |
|
* // => 3 |
|
*/ |
|
function last(array) { |
|
var length = array == null ? 0 : array.length; |
|
return length ? array[length - 1] : undefined; |
|
} |
|
|
|
/** |
|
* This method is like `_.indexOf` except that it iterates over elements of |
|
* `array` from right to left. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Array |
|
* @param {Array} array The array to inspect. |
|
* @param {*} value The value to search for. |
|
* @param {number} [fromIndex=array.length-1] The index to search from. |
|
* @returns {number} Returns the index of the matched value, else `-1`. |
|
* @example |
|
* |
|
* _.lastIndexOf([1, 2, 1, 2], 2); |
|
* // => 3 |
|
* |
|
* // Search from the `fromIndex`. |
|
* _.lastIndexOf([1, 2, 1, 2], 2, 2); |
|
* // => 1 |
|
*/ |
|
function lastIndexOf(array, value, fromIndex) { |
|
var length = array == null ? 0 : array.length; |
|
if (!length) { |
|
return -1; |
|
} |
|
var index = length; |
|
if (fromIndex !== undefined) { |
|
index = toInteger(fromIndex); |
|
index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1); |
|
} |
|
return value === value |
|
? strictLastIndexOf(array, value, index) |
|
: baseFindIndex(array, baseIsNaN, index, true); |
|
} |
|
|
|
/** |
|
* Gets the element at index `n` of `array`. If `n` is negative, the nth |
|
* element from the end is returned. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.11.0 |
|
* @category Array |
|
* @param {Array} array The array to query. |
|
* @param {number} [n=0] The index of the element to return. |
|
* @returns {*} Returns the nth element of `array`. |
|
* @example |
|
* |
|
* var array = ['a', 'b', 'c', 'd']; |
|
* |
|
* _.nth(array, 1); |
|
* // => 'b' |
|
* |
|
* _.nth(array, -2); |
|
* // => 'c'; |
|
*/ |
|
function nth(array, n) { |
|
return (array && array.length) ? baseNth(array, toInteger(n)) : undefined; |
|
} |
|
|
|
/** |
|
* Removes all given values from `array` using |
|
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) |
|
* for equality comparisons. |
|
* |
|
* **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove` |
|
* to remove elements from an array by predicate. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 2.0.0 |
|
* @category Array |
|
* @param {Array} array The array to modify. |
|
* @param {...*} [values] The values to remove. |
|
* @returns {Array} Returns `array`. |
|
* @example |
|
* |
|
* var array = ['a', 'b', 'c', 'a', 'b', 'c']; |
|
* |
|
* _.pull(array, 'a', 'c'); |
|
* console.log(array); |
|
* // => ['b', 'b'] |
|
*/ |
|
var pull = baseRest(pullAll); |
|
|
|
/** |
|
* This method is like `_.pull` except that it accepts an array of values to remove. |
|
* |
|
* **Note:** Unlike `_.difference`, this method mutates `array`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Array |
|
* @param {Array} array The array to modify. |
|
* @param {Array} values The values to remove. |
|
* @returns {Array} Returns `array`. |
|
* @example |
|
* |
|
* var array = ['a', 'b', 'c', 'a', 'b', 'c']; |
|
* |
|
* _.pullAll(array, ['a', 'c']); |
|
* console.log(array); |
|
* // => ['b', 'b'] |
|
*/ |
|
function pullAll(array, values) { |
|
return (array && array.length && values && values.length) |
|
? basePullAll(array, values) |
|
: array; |
|
} |
|
|
|
/** |
|
* This method is like `_.pullAll` except that it accepts `iteratee` which is |
|
* invoked for each element of `array` and `values` to generate the criterion |
|
* by which they're compared. The iteratee is invoked with one argument: (value). |
|
* |
|
* **Note:** Unlike `_.differenceBy`, this method mutates `array`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Array |
|
* @param {Array} array The array to modify. |
|
* @param {Array} values The values to remove. |
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element. |
|
* @returns {Array} Returns `array`. |
|
* @example |
|
* |
|
* var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }]; |
|
* |
|
* _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x'); |
|
* console.log(array); |
|
* // => [{ 'x': 2 }] |
|
*/ |
|
function pullAllBy(array, values, iteratee) { |
|
return (array && array.length && values && values.length) |
|
? basePullAll(array, values, getIteratee(iteratee, 2)) |
|
: array; |
|
} |
|
|
|
/** |
|
* This method is like `_.pullAll` except that it accepts `comparator` which |
|
* is invoked to compare elements of `array` to `values`. The comparator is |
|
* invoked with two arguments: (arrVal, othVal). |
|
* |
|
* **Note:** Unlike `_.differenceWith`, this method mutates `array`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.6.0 |
|
* @category Array |
|
* @param {Array} array The array to modify. |
|
* @param {Array} values The values to remove. |
|
* @param {Function} [comparator] The comparator invoked per element. |
|
* @returns {Array} Returns `array`. |
|
* @example |
|
* |
|
* var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }]; |
|
* |
|
* _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual); |
|
* console.log(array); |
|
* // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }] |
|
*/ |
|
function pullAllWith(array, values, comparator) { |
|
return (array && array.length && values && values.length) |
|
? basePullAll(array, values, undefined, comparator) |
|
: array; |
|
} |
|
|
|
/** |
|
* Removes elements from `array` corresponding to `indexes` and returns an |
|
* array of removed elements. |
|
* |
|
* **Note:** Unlike `_.at`, this method mutates `array`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Array |
|
* @param {Array} array The array to modify. |
|
* @param {...(number|number[])} [indexes] The indexes of elements to remove. |
|
* @returns {Array} Returns the new array of removed elements. |
|
* @example |
|
* |
|
* var array = ['a', 'b', 'c', 'd']; |
|
* var pulled = _.pullAt(array, [1, 3]); |
|
* |
|
* console.log(array); |
|
* // => ['a', 'c'] |
|
* |
|
* console.log(pulled); |
|
* // => ['b', 'd'] |
|
*/ |
|
var pullAt = flatRest(function(array, indexes) { |
|
var length = array == null ? 0 : array.length, |
|
result = baseAt(array, indexes); |
|
|
|
basePullAt(array, arrayMap(indexes, function(index) { |
|
return isIndex(index, length) ? +index : index; |
|
}).sort(compareAscending)); |
|
|
|
return result; |
|
}); |
|
|
|
/** |
|
* Removes all elements from `array` that `predicate` returns truthy for |
|
* and returns an array of the removed elements. The predicate is invoked |
|
* with three arguments: (value, index, array). |
|
* |
|
* **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull` |
|
* to pull elements from an array by value. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 2.0.0 |
|
* @category Array |
|
* @param {Array} array The array to modify. |
|
* @param {Function} [predicate=_.identity] The function invoked per iteration. |
|
* @returns {Array} Returns the new array of removed elements. |
|
* @example |
|
* |
|
* var array = [1, 2, 3, 4]; |
|
* var evens = _.remove(array, function(n) { |
|
* return n % 2 == 0; |
|
* }); |
|
* |
|
* console.log(array); |
|
* // => [1, 3] |
|
* |
|
* console.log(evens); |
|
* // => [2, 4] |
|
*/ |
|
function remove(array, predicate) { |
|
var result = []; |
|
if (!(array && array.length)) { |
|
return result; |
|
} |
|
var index = -1, |
|
indexes = [], |
|
length = array.length; |
|
|
|
predicate = getIteratee(predicate, 3); |
|
while (++index < length) { |
|
var value = array[index]; |
|
if (predicate(value, index, array)) { |
|
result.push(value); |
|
indexes.push(index); |
|
} |
|
} |
|
basePullAt(array, indexes); |
|
return result; |
|
} |
|
|
|
/** |
|
* Reverses `array` so that the first element becomes the last, the second |
|
* element becomes the second to last, and so on. |
|
* |
|
* **Note:** This method mutates `array` and is based on |
|
* [`Array#reverse`](https://mdn.io/Array/reverse). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Array |
|
* @param {Array} array The array to modify. |
|
* @returns {Array} Returns `array`. |
|
* @example |
|
* |
|
* var array = [1, 2, 3]; |
|
* |
|
* _.reverse(array); |
|
* // => [3, 2, 1] |
|
* |
|
* console.log(array); |
|
* // => [3, 2, 1] |
|
*/ |
|
function reverse(array) { |
|
return array == null ? array : nativeReverse.call(array); |
|
} |
|
|
|
/** |
|
* Creates a slice of `array` from `start` up to, but not including, `end`. |
|
* |
|
* **Note:** This method is used instead of |
|
* [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are |
|
* returned. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Array |
|
* @param {Array} array The array to slice. |
|
* @param {number} [start=0] The start position. |
|
* @param {number} [end=array.length] The end position. |
|
* @returns {Array} Returns the slice of `array`. |
|
*/ |
|
function slice(array, start, end) { |
|
var length = array == null ? 0 : array.length; |
|
if (!length) { |
|
return []; |
|
} |
|
if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { |
|
start = 0; |
|
end = length; |
|
} |
|
else { |
|
start = start == null ? 0 : toInteger(start); |
|
end = end === undefined ? length : toInteger(end); |
|
} |
|
return baseSlice(array, start, end); |
|
} |
|
|
|
/** |
|
* Uses a binary search to determine the lowest index at which `value` |
|
* should be inserted into `array` in order to maintain its sort order. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Array |
|
* @param {Array} array The sorted array to inspect. |
|
* @param {*} value The value to evaluate. |
|
* @returns {number} Returns the index at which `value` should be inserted |
|
* into `array`. |
|
* @example |
|
* |
|
* _.sortedIndex([30, 50], 40); |
|
* // => 1 |
|
*/ |
|
function sortedIndex(array, value) { |
|
return baseSortedIndex(array, value); |
|
} |
|
|
|
/** |
|
* This method is like `_.sortedIndex` except that it accepts `iteratee` |
|
* which is invoked for `value` and each element of `array` to compute their |
|
* sort ranking. The iteratee is invoked with one argument: (value). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Array |
|
* @param {Array} array The sorted array to inspect. |
|
* @param {*} value The value to evaluate. |
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element. |
|
* @returns {number} Returns the index at which `value` should be inserted |
|
* into `array`. |
|
* @example |
|
* |
|
* var objects = [{ 'x': 4 }, { 'x': 5 }]; |
|
* |
|
* _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); |
|
* // => 0 |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.sortedIndexBy(objects, { 'x': 4 }, 'x'); |
|
* // => 0 |
|
*/ |
|
function sortedIndexBy(array, value, iteratee) { |
|
return baseSortedIndexBy(array, value, getIteratee(iteratee, 2)); |
|
} |
|
|
|
/** |
|
* This method is like `_.indexOf` except that it performs a binary |
|
* search on a sorted `array`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Array |
|
* @param {Array} array The array to inspect. |
|
* @param {*} value The value to search for. |
|
* @returns {number} Returns the index of the matched value, else `-1`. |
|
* @example |
|
* |
|
* _.sortedIndexOf([4, 5, 5, 5, 6], 5); |
|
* // => 1 |
|
*/ |
|
function sortedIndexOf(array, value) { |
|
var length = array == null ? 0 : array.length; |
|
if (length) { |
|
var index = baseSortedIndex(array, value); |
|
if (index < length && eq(array[index], value)) { |
|
return index; |
|
} |
|
} |
|
return -1; |
|
} |
|
|
|
/** |
|
* This method is like `_.sortedIndex` except that it returns the highest |
|
* index at which `value` should be inserted into `array` in order to |
|
* maintain its sort order. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Array |
|
* @param {Array} array The sorted array to inspect. |
|
* @param {*} value The value to evaluate. |
|
* @returns {number} Returns the index at which `value` should be inserted |
|
* into `array`. |
|
* @example |
|
* |
|
* _.sortedLastIndex([4, 5, 5, 5, 6], 5); |
|
* // => 4 |
|
*/ |
|
function sortedLastIndex(array, value) { |
|
return baseSortedIndex(array, value, true); |
|
} |
|
|
|
/** |
|
* This method is like `_.sortedLastIndex` except that it accepts `iteratee` |
|
* which is invoked for `value` and each element of `array` to compute their |
|
* sort ranking. The iteratee is invoked with one argument: (value). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Array |
|
* @param {Array} array The sorted array to inspect. |
|
* @param {*} value The value to evaluate. |
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element. |
|
* @returns {number} Returns the index at which `value` should be inserted |
|
* into `array`. |
|
* @example |
|
* |
|
* var objects = [{ 'x': 4 }, { 'x': 5 }]; |
|
* |
|
* _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); |
|
* // => 1 |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.sortedLastIndexBy(objects, { 'x': 4 }, 'x'); |
|
* // => 1 |
|
*/ |
|
function sortedLastIndexBy(array, value, iteratee) { |
|
return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true); |
|
} |
|
|
|
/** |
|
* This method is like `_.lastIndexOf` except that it performs a binary |
|
* search on a sorted `array`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Array |
|
* @param {Array} array The array to inspect. |
|
* @param {*} value The value to search for. |
|
* @returns {number} Returns the index of the matched value, else `-1`. |
|
* @example |
|
* |
|
* _.sortedLastIndexOf([4, 5, 5, 5, 6], 5); |
|
* // => 3 |
|
*/ |
|
function sortedLastIndexOf(array, value) { |
|
var length = array == null ? 0 : array.length; |
|
if (length) { |
|
var index = baseSortedIndex(array, value, true) - 1; |
|
if (eq(array[index], value)) { |
|
return index; |
|
} |
|
} |
|
return -1; |
|
} |
|
|
|
/** |
|
* This method is like `_.uniq` except that it's designed and optimized |
|
* for sorted arrays. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Array |
|
* @param {Array} array The array to inspect. |
|
* @returns {Array} Returns the new duplicate free array. |
|
* @example |
|
* |
|
* _.sortedUniq([1, 1, 2]); |
|
* // => [1, 2] |
|
*/ |
|
function sortedUniq(array) { |
|
return (array && array.length) |
|
? baseSortedUniq(array) |
|
: []; |
|
} |
|
|
|
/** |
|
* This method is like `_.uniqBy` except that it's designed and optimized |
|
* for sorted arrays. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Array |
|
* @param {Array} array The array to inspect. |
|
* @param {Function} [iteratee] The iteratee invoked per element. |
|
* @returns {Array} Returns the new duplicate free array. |
|
* @example |
|
* |
|
* _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor); |
|
* // => [1.1, 2.3] |
|
*/ |
|
function sortedUniqBy(array, iteratee) { |
|
return (array && array.length) |
|
? baseSortedUniq(array, getIteratee(iteratee, 2)) |
|
: []; |
|
} |
|
|
|
/** |
|
* Gets all but the first element of `array`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Array |
|
* @param {Array} array The array to query. |
|
* @returns {Array} Returns the slice of `array`. |
|
* @example |
|
* |
|
* _.tail([1, 2, 3]); |
|
* // => [2, 3] |
|
*/ |
|
function tail(array) { |
|
var length = array == null ? 0 : array.length; |
|
return length ? baseSlice(array, 1, length) : []; |
|
} |
|
|
|
/** |
|
* Creates a slice of `array` with `n` elements taken from the beginning. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Array |
|
* @param {Array} array The array to query. |
|
* @param {number} [n=1] The number of elements to take. |
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. |
|
* @returns {Array} Returns the slice of `array`. |
|
* @example |
|
* |
|
* _.take([1, 2, 3]); |
|
* // => [1] |
|
* |
|
* _.take([1, 2, 3], 2); |
|
* // => [1, 2] |
|
* |
|
* _.take([1, 2, 3], 5); |
|
* // => [1, 2, 3] |
|
* |
|
* _.take([1, 2, 3], 0); |
|
* // => [] |
|
*/ |
|
function take(array, n, guard) { |
|
if (!(array && array.length)) { |
|
return []; |
|
} |
|
n = (guard || n === undefined) ? 1 : toInteger(n); |
|
return baseSlice(array, 0, n < 0 ? 0 : n); |
|
} |
|
|
|
/** |
|
* Creates a slice of `array` with `n` elements taken from the end. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Array |
|
* @param {Array} array The array to query. |
|
* @param {number} [n=1] The number of elements to take. |
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. |
|
* @returns {Array} Returns the slice of `array`. |
|
* @example |
|
* |
|
* _.takeRight([1, 2, 3]); |
|
* // => [3] |
|
* |
|
* _.takeRight([1, 2, 3], 2); |
|
* // => [2, 3] |
|
* |
|
* _.takeRight([1, 2, 3], 5); |
|
* // => [1, 2, 3] |
|
* |
|
* _.takeRight([1, 2, 3], 0); |
|
* // => [] |
|
*/ |
|
function takeRight(array, n, guard) { |
|
var length = array == null ? 0 : array.length; |
|
if (!length) { |
|
return []; |
|
} |
|
n = (guard || n === undefined) ? 1 : toInteger(n); |
|
n = length - n; |
|
return baseSlice(array, n < 0 ? 0 : n, length); |
|
} |
|
|
|
/** |
|
* Creates a slice of `array` with elements taken from the end. Elements are |
|
* taken until `predicate` returns falsey. The predicate is invoked with |
|
* three arguments: (value, index, array). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Array |
|
* @param {Array} array The array to query. |
|
* @param {Function} [predicate=_.identity] The function invoked per iteration. |
|
* @returns {Array} Returns the slice of `array`. |
|
* @example |
|
* |
|
* var users = [ |
|
* { 'user': 'barney', 'active': true }, |
|
* { 'user': 'fred', 'active': false }, |
|
* { 'user': 'pebbles', 'active': false } |
|
* ]; |
|
* |
|
* _.takeRightWhile(users, function(o) { return !o.active; }); |
|
* // => objects for ['fred', 'pebbles'] |
|
* |
|
* // The `_.matches` iteratee shorthand. |
|
* _.takeRightWhile(users, { 'user': 'pebbles', 'active': false }); |
|
* // => objects for ['pebbles'] |
|
* |
|
* // The `_.matchesProperty` iteratee shorthand. |
|
* _.takeRightWhile(users, ['active', false]); |
|
* // => objects for ['fred', 'pebbles'] |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.takeRightWhile(users, 'active'); |
|
* // => [] |
|
*/ |
|
function takeRightWhile(array, predicate) { |
|
return (array && array.length) |
|
? baseWhile(array, getIteratee(predicate, 3), false, true) |
|
: []; |
|
} |
|
|
|
/** |
|
* Creates a slice of `array` with elements taken from the beginning. Elements |
|
* are taken until `predicate` returns falsey. The predicate is invoked with |
|
* three arguments: (value, index, array). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Array |
|
* @param {Array} array The array to query. |
|
* @param {Function} [predicate=_.identity] The function invoked per iteration. |
|
* @returns {Array} Returns the slice of `array`. |
|
* @example |
|
* |
|
* var users = [ |
|
* { 'user': 'barney', 'active': false }, |
|
* { 'user': 'fred', 'active': false }, |
|
* { 'user': 'pebbles', 'active': true } |
|
* ]; |
|
* |
|
* _.takeWhile(users, function(o) { return !o.active; }); |
|
* // => objects for ['barney', 'fred'] |
|
* |
|
* // The `_.matches` iteratee shorthand. |
|
* _.takeWhile(users, { 'user': 'barney', 'active': false }); |
|
* // => objects for ['barney'] |
|
* |
|
* // The `_.matchesProperty` iteratee shorthand. |
|
* _.takeWhile(users, ['active', false]); |
|
* // => objects for ['barney', 'fred'] |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.takeWhile(users, 'active'); |
|
* // => [] |
|
*/ |
|
function takeWhile(array, predicate) { |
|
return (array && array.length) |
|
? baseWhile(array, getIteratee(predicate, 3)) |
|
: []; |
|
} |
|
|
|
/** |
|
* Creates an array of unique values, in order, from all given arrays using |
|
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) |
|
* for equality comparisons. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Array |
|
* @param {...Array} [arrays] The arrays to inspect. |
|
* @returns {Array} Returns the new array of combined values. |
|
* @example |
|
* |
|
* _.union([2], [1, 2]); |
|
* // => [2, 1] |
|
*/ |
|
var union = baseRest(function(arrays) { |
|
return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true)); |
|
}); |
|
|
|
/** |
|
* This method is like `_.union` except that it accepts `iteratee` which is |
|
* invoked for each element of each `arrays` to generate the criterion by |
|
* which uniqueness is computed. Result values are chosen from the first |
|
* array in which the value occurs. The iteratee is invoked with one argument: |
|
* (value). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Array |
|
* @param {...Array} [arrays] The arrays to inspect. |
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element. |
|
* @returns {Array} Returns the new array of combined values. |
|
* @example |
|
* |
|
* _.unionBy([2.1], [1.2, 2.3], Math.floor); |
|
* // => [2.1, 1.2] |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); |
|
* // => [{ 'x': 1 }, { 'x': 2 }] |
|
*/ |
|
var unionBy = baseRest(function(arrays) { |
|
var iteratee = last(arrays); |
|
if (isArrayLikeObject(iteratee)) { |
|
iteratee = undefined; |
|
} |
|
return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2)); |
|
}); |
|
|
|
/** |
|
* This method is like `_.union` except that it accepts `comparator` which |
|
* is invoked to compare elements of `arrays`. Result values are chosen from |
|
* the first array in which the value occurs. The comparator is invoked |
|
* with two arguments: (arrVal, othVal). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Array |
|
* @param {...Array} [arrays] The arrays to inspect. |
|
* @param {Function} [comparator] The comparator invoked per element. |
|
* @returns {Array} Returns the new array of combined values. |
|
* @example |
|
* |
|
* var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; |
|
* var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; |
|
* |
|
* _.unionWith(objects, others, _.isEqual); |
|
* // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] |
|
*/ |
|
var unionWith = baseRest(function(arrays) { |
|
var comparator = last(arrays); |
|
comparator = typeof comparator == 'function' ? comparator : undefined; |
|
return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator); |
|
}); |
|
|
|
/** |
|
* Creates a duplicate-free version of an array, using |
|
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) |
|
* for equality comparisons, in which only the first occurrence of each element |
|
* is kept. The order of result values is determined by the order they occur |
|
* in the array. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Array |
|
* @param {Array} array The array to inspect. |
|
* @returns {Array} Returns the new duplicate free array. |
|
* @example |
|
* |
|
* _.uniq([2, 1, 2]); |
|
* // => [2, 1] |
|
*/ |
|
function uniq(array) { |
|
return (array && array.length) ? baseUniq(array) : []; |
|
} |
|
|
|
/** |
|
* This method is like `_.uniq` except that it accepts `iteratee` which is |
|
* invoked for each element in `array` to generate the criterion by which |
|
* uniqueness is computed. The order of result values is determined by the |
|
* order they occur in the array. The iteratee is invoked with one argument: |
|
* (value). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Array |
|
* @param {Array} array The array to inspect. |
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element. |
|
* @returns {Array} Returns the new duplicate free array. |
|
* @example |
|
* |
|
* _.uniqBy([2.1, 1.2, 2.3], Math.floor); |
|
* // => [2.1, 1.2] |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); |
|
* // => [{ 'x': 1 }, { 'x': 2 }] |
|
*/ |
|
function uniqBy(array, iteratee) { |
|
return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : []; |
|
} |
|
|
|
/** |
|
* This method is like `_.uniq` except that it accepts `comparator` which |
|
* is invoked to compare elements of `array`. The order of result values is |
|
* determined by the order they occur in the array.The comparator is invoked |
|
* with two arguments: (arrVal, othVal). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Array |
|
* @param {Array} array The array to inspect. |
|
* @param {Function} [comparator] The comparator invoked per element. |
|
* @returns {Array} Returns the new duplicate free array. |
|
* @example |
|
* |
|
* var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }]; |
|
* |
|
* _.uniqWith(objects, _.isEqual); |
|
* // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }] |
|
*/ |
|
function uniqWith(array, comparator) { |
|
comparator = typeof comparator == 'function' ? comparator : undefined; |
|
return (array && array.length) ? baseUniq(array, undefined, comparator) : []; |
|
} |
|
|
|
/** |
|
* This method is like `_.zip` except that it accepts an array of grouped |
|
* elements and creates an array regrouping the elements to their pre-zip |
|
* configuration. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 1.2.0 |
|
* @category Array |
|
* @param {Array} array The array of grouped elements to process. |
|
* @returns {Array} Returns the new array of regrouped elements. |
|
* @example |
|
* |
|
* var zipped = _.zip(['a', 'b'], [1, 2], [true, false]); |
|
* // => [['a', 1, true], ['b', 2, false]] |
|
* |
|
* _.unzip(zipped); |
|
* // => [['a', 'b'], [1, 2], [true, false]] |
|
*/ |
|
function unzip(array) { |
|
if (!(array && array.length)) { |
|
return []; |
|
} |
|
var length = 0; |
|
array = arrayFilter(array, function(group) { |
|
if (isArrayLikeObject(group)) { |
|
length = nativeMax(group.length, length); |
|
return true; |
|
} |
|
}); |
|
return baseTimes(length, function(index) { |
|
return arrayMap(array, baseProperty(index)); |
|
}); |
|
} |
|
|
|
/** |
|
* This method is like `_.unzip` except that it accepts `iteratee` to specify |
|
* how regrouped values should be combined. The iteratee is invoked with the |
|
* elements of each group: (...group). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.8.0 |
|
* @category Array |
|
* @param {Array} array The array of grouped elements to process. |
|
* @param {Function} [iteratee=_.identity] The function to combine |
|
* regrouped values. |
|
* @returns {Array} Returns the new array of regrouped elements. |
|
* @example |
|
* |
|
* var zipped = _.zip([1, 2], [10, 20], [100, 200]); |
|
* // => [[1, 10, 100], [2, 20, 200]] |
|
* |
|
* _.unzipWith(zipped, _.add); |
|
* // => [3, 30, 300] |
|
*/ |
|
function unzipWith(array, iteratee) { |
|
if (!(array && array.length)) { |
|
return []; |
|
} |
|
var result = unzip(array); |
|
if (iteratee == null) { |
|
return result; |
|
} |
|
return arrayMap(result, function(group) { |
|
return apply(iteratee, undefined, group); |
|
}); |
|
} |
|
|
|
/** |
|
* Creates an array excluding all given values using |
|
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) |
|
* for equality comparisons. |
|
* |
|
* **Note:** Unlike `_.pull`, this method returns a new array. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Array |
|
* @param {Array} array The array to inspect. |
|
* @param {...*} [values] The values to exclude. |
|
* @returns {Array} Returns the new array of filtered values. |
|
* @see _.difference, _.xor |
|
* @example |
|
* |
|
* _.without([2, 1, 2, 3], 1, 2); |
|
* // => [3] |
|
*/ |
|
var without = baseRest(function(array, values) { |
|
return isArrayLikeObject(array) |
|
? baseDifference(array, values) |
|
: []; |
|
}); |
|
|
|
/** |
|
* Creates an array of unique values that is the |
|
* [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) |
|
* of the given arrays. The order of result values is determined by the order |
|
* they occur in the arrays. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 2.4.0 |
|
* @category Array |
|
* @param {...Array} [arrays] The arrays to inspect. |
|
* @returns {Array} Returns the new array of filtered values. |
|
* @see _.difference, _.without |
|
* @example |
|
* |
|
* _.xor([2, 1], [2, 3]); |
|
* // => [1, 3] |
|
*/ |
|
var xor = baseRest(function(arrays) { |
|
return baseXor(arrayFilter(arrays, isArrayLikeObject)); |
|
}); |
|
|
|
/** |
|
* This method is like `_.xor` except that it accepts `iteratee` which is |
|
* invoked for each element of each `arrays` to generate the criterion by |
|
* which by which they're compared. The order of result values is determined |
|
* by the order they occur in the arrays. The iteratee is invoked with one |
|
* argument: (value). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Array |
|
* @param {...Array} [arrays] The arrays to inspect. |
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element. |
|
* @returns {Array} Returns the new array of filtered values. |
|
* @example |
|
* |
|
* _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor); |
|
* // => [1.2, 3.4] |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); |
|
* // => [{ 'x': 2 }] |
|
*/ |
|
var xorBy = baseRest(function(arrays) { |
|
var iteratee = last(arrays); |
|
if (isArrayLikeObject(iteratee)) { |
|
iteratee = undefined; |
|
} |
|
return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2)); |
|
}); |
|
|
|
/** |
|
* This method is like `_.xor` except that it accepts `comparator` which is |
|
* invoked to compare elements of `arrays`. The order of result values is |
|
* determined by the order they occur in the arrays. The comparator is invoked |
|
* with two arguments: (arrVal, othVal). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Array |
|
* @param {...Array} [arrays] The arrays to inspect. |
|
* @param {Function} [comparator] The comparator invoked per element. |
|
* @returns {Array} Returns the new array of filtered values. |
|
* @example |
|
* |
|
* var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; |
|
* var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; |
|
* |
|
* _.xorWith(objects, others, _.isEqual); |
|
* // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] |
|
*/ |
|
var xorWith = baseRest(function(arrays) { |
|
var comparator = last(arrays); |
|
comparator = typeof comparator == 'function' ? comparator : undefined; |
|
return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator); |
|
}); |
|
|
|
/** |
|
* Creates an array of grouped elements, the first of which contains the |
|
* first elements of the given arrays, the second of which contains the |
|
* second elements of the given arrays, and so on. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Array |
|
* @param {...Array} [arrays] The arrays to process. |
|
* @returns {Array} Returns the new array of grouped elements. |
|
* @example |
|
* |
|
* _.zip(['a', 'b'], [1, 2], [true, false]); |
|
* // => [['a', 1, true], ['b', 2, false]] |
|
*/ |
|
var zip = baseRest(unzip); |
|
|
|
/** |
|
* This method is like `_.fromPairs` except that it accepts two arrays, |
|
* one of property identifiers and one of corresponding values. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.4.0 |
|
* @category Array |
|
* @param {Array} [props=[]] The property identifiers. |
|
* @param {Array} [values=[]] The property values. |
|
* @returns {Object} Returns the new object. |
|
* @example |
|
* |
|
* _.zipObject(['a', 'b'], [1, 2]); |
|
* // => { 'a': 1, 'b': 2 } |
|
*/ |
|
function zipObject(props, values) { |
|
return baseZipObject(props || [], values || [], assignValue); |
|
} |
|
|
|
/** |
|
* This method is like `_.zipObject` except that it supports property paths. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.1.0 |
|
* @category Array |
|
* @param {Array} [props=[]] The property identifiers. |
|
* @param {Array} [values=[]] The property values. |
|
* @returns {Object} Returns the new object. |
|
* @example |
|
* |
|
* _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]); |
|
* // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } } |
|
*/ |
|
function zipObjectDeep(props, values) { |
|
return baseZipObject(props || [], values || [], baseSet); |
|
} |
|
|
|
/** |
|
* This method is like `_.zip` except that it accepts `iteratee` to specify |
|
* how grouped values should be combined. The iteratee is invoked with the |
|
* elements of each group: (...group). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.8.0 |
|
* @category Array |
|
* @param {...Array} [arrays] The arrays to process. |
|
* @param {Function} [iteratee=_.identity] The function to combine |
|
* grouped values. |
|
* @returns {Array} Returns the new array of grouped elements. |
|
* @example |
|
* |
|
* _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) { |
|
* return a + b + c; |
|
* }); |
|
* // => [111, 222] |
|
*/ |
|
var zipWith = baseRest(function(arrays) { |
|
var length = arrays.length, |
|
iteratee = length > 1 ? arrays[length - 1] : undefined; |
|
|
|
iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined; |
|
return unzipWith(arrays, iteratee); |
|
}); |
|
|
|
/*------------------------------------------------------------------------*/ |
|
|
|
/** |
|
* Creates a `lodash` wrapper instance that wraps `value` with explicit method |
|
* chain sequences enabled. The result of such sequences must be unwrapped |
|
* with `_#value`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 1.3.0 |
|
* @category Seq |
|
* @param {*} value The value to wrap. |
|
* @returns {Object} Returns the new `lodash` wrapper instance. |
|
* @example |
|
* |
|
* var users = [ |
|
* { 'user': 'barney', 'age': 36 }, |
|
* { 'user': 'fred', 'age': 40 }, |
|
* { 'user': 'pebbles', 'age': 1 } |
|
* ]; |
|
* |
|
* var youngest = _ |
|
* .chain(users) |
|
* .sortBy('age') |
|
* .map(function(o) { |
|
* return o.user + ' is ' + o.age; |
|
* }) |
|
* .head() |
|
* .value(); |
|
* // => 'pebbles is 1' |
|
*/ |
|
function chain(value) { |
|
var result = lodash(value); |
|
result.__chain__ = true; |
|
return result; |
|
} |
|
|
|
/** |
|
* This method invokes `interceptor` and returns `value`. The interceptor |
|
* is invoked with one argument; (value). The purpose of this method is to |
|
* "tap into" a method chain sequence in order to modify intermediate results. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Seq |
|
* @param {*} value The value to provide to `interceptor`. |
|
* @param {Function} interceptor The function to invoke. |
|
* @returns {*} Returns `value`. |
|
* @example |
|
* |
|
* _([1, 2, 3]) |
|
* .tap(function(array) { |
|
* // Mutate input array. |
|
* array.pop(); |
|
* }) |
|
* .reverse() |
|
* .value(); |
|
* // => [2, 1] |
|
*/ |
|
function tap(value, interceptor) { |
|
interceptor(value); |
|
return value; |
|
} |
|
|
|
/** |
|
* This method is like `_.tap` except that it returns the result of `interceptor`. |
|
* The purpose of this method is to "pass thru" values replacing intermediate |
|
* results in a method chain sequence. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Seq |
|
* @param {*} value The value to provide to `interceptor`. |
|
* @param {Function} interceptor The function to invoke. |
|
* @returns {*} Returns the result of `interceptor`. |
|
* @example |
|
* |
|
* _(' abc ') |
|
* .chain() |
|
* .trim() |
|
* .thru(function(value) { |
|
* return [value]; |
|
* }) |
|
* .value(); |
|
* // => ['abc'] |
|
*/ |
|
function thru(value, interceptor) { |
|
return interceptor(value); |
|
} |
|
|
|
/** |
|
* This method is the wrapper version of `_.at`. |
|
* |
|
* @name at |
|
* @memberOf _ |
|
* @since 1.0.0 |
|
* @category Seq |
|
* @param {...(string|string[])} [paths] The property paths to pick. |
|
* @returns {Object} Returns the new `lodash` wrapper instance. |
|
* @example |
|
* |
|
* var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; |
|
* |
|
* _(object).at(['a[0].b.c', 'a[1]']).value(); |
|
* // => [3, 4] |
|
*/ |
|
var wrapperAt = flatRest(function(paths) { |
|
var length = paths.length, |
|
start = length ? paths[0] : 0, |
|
value = this.__wrapped__, |
|
interceptor = function(object) { return baseAt(object, paths); }; |
|
|
|
if (length > 1 || this.__actions__.length || |
|
!(value instanceof LazyWrapper) || !isIndex(start)) { |
|
return this.thru(interceptor); |
|
} |
|
value = value.slice(start, +start + (length ? 1 : 0)); |
|
value.__actions__.push({ |
|
'func': thru, |
|
'args': [interceptor], |
|
'thisArg': undefined |
|
}); |
|
return new LodashWrapper(value, this.__chain__).thru(function(array) { |
|
if (length && !array.length) { |
|
array.push(undefined); |
|
} |
|
return array; |
|
}); |
|
}); |
|
|
|
/** |
|
* Creates a `lodash` wrapper instance with explicit method chain sequences enabled. |
|
* |
|
* @name chain |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Seq |
|
* @returns {Object} Returns the new `lodash` wrapper instance. |
|
* @example |
|
* |
|
* var users = [ |
|
* { 'user': 'barney', 'age': 36 }, |
|
* { 'user': 'fred', 'age': 40 } |
|
* ]; |
|
* |
|
* // A sequence without explicit chaining. |
|
* _(users).head(); |
|
* // => { 'user': 'barney', 'age': 36 } |
|
* |
|
* // A sequence with explicit chaining. |
|
* _(users) |
|
* .chain() |
|
* .head() |
|
* .pick('user') |
|
* .value(); |
|
* // => { 'user': 'barney' } |
|
*/ |
|
function wrapperChain() { |
|
return chain(this); |
|
} |
|
|
|
/** |
|
* Executes the chain sequence and returns the wrapped result. |
|
* |
|
* @name commit |
|
* @memberOf _ |
|
* @since 3.2.0 |
|
* @category Seq |
|
* @returns {Object} Returns the new `lodash` wrapper instance. |
|
* @example |
|
* |
|
* var array = [1, 2]; |
|
* var wrapped = _(array).push(3); |
|
* |
|
* console.log(array); |
|
* // => [1, 2] |
|
* |
|
* wrapped = wrapped.commit(); |
|
* console.log(array); |
|
* // => [1, 2, 3] |
|
* |
|
* wrapped.last(); |
|
* // => 3 |
|
* |
|
* console.log(array); |
|
* // => [1, 2, 3] |
|
*/ |
|
function wrapperCommit() { |
|
return new LodashWrapper(this.value(), this.__chain__); |
|
} |
|
|
|
/** |
|
* Gets the next value on a wrapped object following the |
|
* [iterator protocol](https://mdn.io/iteration_protocols#iterator). |
|
* |
|
* @name next |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Seq |
|
* @returns {Object} Returns the next iterator value. |
|
* @example |
|
* |
|
* var wrapped = _([1, 2]); |
|
* |
|
* wrapped.next(); |
|
* // => { 'done': false, 'value': 1 } |
|
* |
|
* wrapped.next(); |
|
* // => { 'done': false, 'value': 2 } |
|
* |
|
* wrapped.next(); |
|
* // => { 'done': true, 'value': undefined } |
|
*/ |
|
function wrapperNext() { |
|
if (this.__values__ === undefined) { |
|
this.__values__ = toArray(this.value()); |
|
} |
|
var done = this.__index__ >= this.__values__.length, |
|
value = done ? undefined : this.__values__[this.__index__++]; |
|
|
|
return { 'done': done, 'value': value }; |
|
} |
|
|
|
/** |
|
* Enables the wrapper to be iterable. |
|
* |
|
* @name Symbol.iterator |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Seq |
|
* @returns {Object} Returns the wrapper object. |
|
* @example |
|
* |
|
* var wrapped = _([1, 2]); |
|
* |
|
* wrapped[Symbol.iterator]() === wrapped; |
|
* // => true |
|
* |
|
* Array.from(wrapped); |
|
* // => [1, 2] |
|
*/ |
|
function wrapperToIterator() { |
|
return this; |
|
} |
|
|
|
/** |
|
* Creates a clone of the chain sequence planting `value` as the wrapped value. |
|
* |
|
* @name plant |
|
* @memberOf _ |
|
* @since 3.2.0 |
|
* @category Seq |
|
* @param {*} value The value to plant. |
|
* @returns {Object} Returns the new `lodash` wrapper instance. |
|
* @example |
|
* |
|
* function square(n) { |
|
* return n * n; |
|
* } |
|
* |
|
* var wrapped = _([1, 2]).map(square); |
|
* var other = wrapped.plant([3, 4]); |
|
* |
|
* other.value(); |
|
* // => [9, 16] |
|
* |
|
* wrapped.value(); |
|
* // => [1, 4] |
|
*/ |
|
function wrapperPlant(value) { |
|
var result, |
|
parent = this; |
|
|
|
while (parent instanceof baseLodash) { |
|
var clone = wrapperClone(parent); |
|
clone.__index__ = 0; |
|
clone.__values__ = undefined; |
|
if (result) { |
|
previous.__wrapped__ = clone; |
|
} else { |
|
result = clone; |
|
} |
|
var previous = clone; |
|
parent = parent.__wrapped__; |
|
} |
|
previous.__wrapped__ = value; |
|
return result; |
|
} |
|
|
|
/** |
|
* This method is the wrapper version of `_.reverse`. |
|
* |
|
* **Note:** This method mutates the wrapped array. |
|
* |
|
* @name reverse |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Seq |
|
* @returns {Object} Returns the new `lodash` wrapper instance. |
|
* @example |
|
* |
|
* var array = [1, 2, 3]; |
|
* |
|
* _(array).reverse().value() |
|
* // => [3, 2, 1] |
|
* |
|
* console.log(array); |
|
* // => [3, 2, 1] |
|
*/ |
|
function wrapperReverse() { |
|
var value = this.__wrapped__; |
|
if (value instanceof LazyWrapper) { |
|
var wrapped = value; |
|
if (this.__actions__.length) { |
|
wrapped = new LazyWrapper(this); |
|
} |
|
wrapped = wrapped.reverse(); |
|
wrapped.__actions__.push({ |
|
'func': thru, |
|
'args': [reverse], |
|
'thisArg': undefined |
|
}); |
|
return new LodashWrapper(wrapped, this.__chain__); |
|
} |
|
return this.thru(reverse); |
|
} |
|
|
|
/** |
|
* Executes the chain sequence to resolve the unwrapped value. |
|
* |
|
* @name value |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @alias toJSON, valueOf |
|
* @category Seq |
|
* @returns {*} Returns the resolved unwrapped value. |
|
* @example |
|
* |
|
* _([1, 2, 3]).value(); |
|
* // => [1, 2, 3] |
|
*/ |
|
function wrapperValue() { |
|
return baseWrapperValue(this.__wrapped__, this.__actions__); |
|
} |
|
|
|
/*------------------------------------------------------------------------*/ |
|
|
|
/** |
|
* Creates an object composed of keys generated from the results of running |
|
* each element of `collection` thru `iteratee`. The corresponding value of |
|
* each key is the number of times the key was returned by `iteratee`. The |
|
* iteratee is invoked with one argument: (value). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.5.0 |
|
* @category Collection |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {Function} [iteratee=_.identity] The iteratee to transform keys. |
|
* @returns {Object} Returns the composed aggregate object. |
|
* @example |
|
* |
|
* _.countBy([6.1, 4.2, 6.3], Math.floor); |
|
* // => { '4': 1, '6': 2 } |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.countBy(['one', 'two', 'three'], 'length'); |
|
* // => { '3': 2, '5': 1 } |
|
*/ |
|
var countBy = createAggregator(function(result, value, key) { |
|
if (hasOwnProperty.call(result, key)) { |
|
++result[key]; |
|
} else { |
|
baseAssignValue(result, key, 1); |
|
} |
|
}); |
|
|
|
/** |
|
* Checks if `predicate` returns truthy for **all** elements of `collection`. |
|
* Iteration is stopped once `predicate` returns falsey. The predicate is |
|
* invoked with three arguments: (value, index|key, collection). |
|
* |
|
* **Note:** This method returns `true` for |
|
* [empty collections](https://en.wikipedia.org/wiki/Empty_set) because |
|
* [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of |
|
* elements of empty collections. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Collection |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {Function} [predicate=_.identity] The function invoked per iteration. |
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. |
|
* @returns {boolean} Returns `true` if all elements pass the predicate check, |
|
* else `false`. |
|
* @example |
|
* |
|
* _.every([true, 1, null, 'yes'], Boolean); |
|
* // => false |
|
* |
|
* var users = [ |
|
* { 'user': 'barney', 'age': 36, 'active': false }, |
|
* { 'user': 'fred', 'age': 40, 'active': false } |
|
* ]; |
|
* |
|
* // The `_.matches` iteratee shorthand. |
|
* _.every(users, { 'user': 'barney', 'active': false }); |
|
* // => false |
|
* |
|
* // The `_.matchesProperty` iteratee shorthand. |
|
* _.every(users, ['active', false]); |
|
* // => true |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.every(users, 'active'); |
|
* // => false |
|
*/ |
|
function every(collection, predicate, guard) { |
|
var func = isArray(collection) ? arrayEvery : baseEvery; |
|
if (guard && isIterateeCall(collection, predicate, guard)) { |
|
predicate = undefined; |
|
} |
|
return func(collection, getIteratee(predicate, 3)); |
|
} |
|
|
|
/** |
|
* Iterates over elements of `collection`, returning an array of all elements |
|
* `predicate` returns truthy for. The predicate is invoked with three |
|
* arguments: (value, index|key, collection). |
|
* |
|
* **Note:** Unlike `_.remove`, this method returns a new array. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Collection |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {Function} [predicate=_.identity] The function invoked per iteration. |
|
* @returns {Array} Returns the new filtered array. |
|
* @see _.reject |
|
* @example |
|
* |
|
* var users = [ |
|
* { 'user': 'barney', 'age': 36, 'active': true }, |
|
* { 'user': 'fred', 'age': 40, 'active': false } |
|
* ]; |
|
* |
|
* _.filter(users, function(o) { return !o.active; }); |
|
* // => objects for ['fred'] |
|
* |
|
* // The `_.matches` iteratee shorthand. |
|
* _.filter(users, { 'age': 36, 'active': true }); |
|
* // => objects for ['barney'] |
|
* |
|
* // The `_.matchesProperty` iteratee shorthand. |
|
* _.filter(users, ['active', false]); |
|
* // => objects for ['fred'] |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.filter(users, 'active'); |
|
* // => objects for ['barney'] |
|
*/ |
|
function filter(collection, predicate) { |
|
var func = isArray(collection) ? arrayFilter : baseFilter; |
|
return func(collection, getIteratee(predicate, 3)); |
|
} |
|
|
|
/** |
|
* Iterates over elements of `collection`, returning the first element |
|
* `predicate` returns truthy for. The predicate is invoked with three |
|
* arguments: (value, index|key, collection). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Collection |
|
* @param {Array|Object} collection The collection to inspect. |
|
* @param {Function} [predicate=_.identity] The function invoked per iteration. |
|
* @param {number} [fromIndex=0] The index to search from. |
|
* @returns {*} Returns the matched element, else `undefined`. |
|
* @example |
|
* |
|
* var users = [ |
|
* { 'user': 'barney', 'age': 36, 'active': true }, |
|
* { 'user': 'fred', 'age': 40, 'active': false }, |
|
* { 'user': 'pebbles', 'age': 1, 'active': true } |
|
* ]; |
|
* |
|
* _.find(users, function(o) { return o.age < 40; }); |
|
* // => object for 'barney' |
|
* |
|
* // The `_.matches` iteratee shorthand. |
|
* _.find(users, { 'age': 1, 'active': true }); |
|
* // => object for 'pebbles' |
|
* |
|
* // The `_.matchesProperty` iteratee shorthand. |
|
* _.find(users, ['active', false]); |
|
* // => object for 'fred' |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.find(users, 'active'); |
|
* // => object for 'barney' |
|
*/ |
|
var find = createFind(findIndex); |
|
|
|
/** |
|
* This method is like `_.find` except that it iterates over elements of |
|
* `collection` from right to left. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 2.0.0 |
|
* @category Collection |
|
* @param {Array|Object} collection The collection to inspect. |
|
* @param {Function} [predicate=_.identity] The function invoked per iteration. |
|
* @param {number} [fromIndex=collection.length-1] The index to search from. |
|
* @returns {*} Returns the matched element, else `undefined`. |
|
* @example |
|
* |
|
* _.findLast([1, 2, 3, 4], function(n) { |
|
* return n % 2 == 1; |
|
* }); |
|
* // => 3 |
|
*/ |
|
var findLast = createFind(findLastIndex); |
|
|
|
/** |
|
* Creates a flattened array of values by running each element in `collection` |
|
* thru `iteratee` and flattening the mapped results. The iteratee is invoked |
|
* with three arguments: (value, index|key, collection). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Collection |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration. |
|
* @returns {Array} Returns the new flattened array. |
|
* @example |
|
* |
|
* function duplicate(n) { |
|
* return [n, n]; |
|
* } |
|
* |
|
* _.flatMap([1, 2], duplicate); |
|
* // => [1, 1, 2, 2] |
|
*/ |
|
function flatMap(collection, iteratee) { |
|
return baseFlatten(map(collection, iteratee), 1); |
|
} |
|
|
|
/** |
|
* This method is like `_.flatMap` except that it recursively flattens the |
|
* mapped results. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.7.0 |
|
* @category Collection |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration. |
|
* @returns {Array} Returns the new flattened array. |
|
* @example |
|
* |
|
* function duplicate(n) { |
|
* return [[[n, n]]]; |
|
* } |
|
* |
|
* _.flatMapDeep([1, 2], duplicate); |
|
* // => [1, 1, 2, 2] |
|
*/ |
|
function flatMapDeep(collection, iteratee) { |
|
return baseFlatten(map(collection, iteratee), INFINITY); |
|
} |
|
|
|
/** |
|
* This method is like `_.flatMap` except that it recursively flattens the |
|
* mapped results up to `depth` times. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.7.0 |
|
* @category Collection |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration. |
|
* @param {number} [depth=1] The maximum recursion depth. |
|
* @returns {Array} Returns the new flattened array. |
|
* @example |
|
* |
|
* function duplicate(n) { |
|
* return [[[n, n]]]; |
|
* } |
|
* |
|
* _.flatMapDepth([1, 2], duplicate, 2); |
|
* // => [[1, 1], [2, 2]] |
|
*/ |
|
function flatMapDepth(collection, iteratee, depth) { |
|
depth = depth === undefined ? 1 : toInteger(depth); |
|
return baseFlatten(map(collection, iteratee), depth); |
|
} |
|
|
|
/** |
|
* Iterates over elements of `collection` and invokes `iteratee` for each element. |
|
* The iteratee is invoked with three arguments: (value, index|key, collection). |
|
* Iteratee functions may exit iteration early by explicitly returning `false`. |
|
* |
|
* **Note:** As with other "Collections" methods, objects with a "length" |
|
* property are iterated like arrays. To avoid this behavior use `_.forIn` |
|
* or `_.forOwn` for object iteration. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @alias each |
|
* @category Collection |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration. |
|
* @returns {Array|Object} Returns `collection`. |
|
* @see _.forEachRight |
|
* @example |
|
* |
|
* _.forEach([1, 2], function(value) { |
|
* console.log(value); |
|
* }); |
|
* // => Logs `1` then `2`. |
|
* |
|
* _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { |
|
* console.log(key); |
|
* }); |
|
* // => Logs 'a' then 'b' (iteration order is not guaranteed). |
|
*/ |
|
function forEach(collection, iteratee) { |
|
var func = isArray(collection) ? arrayEach : baseEach; |
|
return func(collection, getIteratee(iteratee, 3)); |
|
} |
|
|
|
/** |
|
* This method is like `_.forEach` except that it iterates over elements of |
|
* `collection` from right to left. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 2.0.0 |
|
* @alias eachRight |
|
* @category Collection |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration. |
|
* @returns {Array|Object} Returns `collection`. |
|
* @see _.forEach |
|
* @example |
|
* |
|
* _.forEachRight([1, 2], function(value) { |
|
* console.log(value); |
|
* }); |
|
* // => Logs `2` then `1`. |
|
*/ |
|
function forEachRight(collection, iteratee) { |
|
var func = isArray(collection) ? arrayEachRight : baseEachRight; |
|
return func(collection, getIteratee(iteratee, 3)); |
|
} |
|
|
|
/** |
|
* Creates an object composed of keys generated from the results of running |
|
* each element of `collection` thru `iteratee`. The order of grouped values |
|
* is determined by the order they occur in `collection`. The corresponding |
|
* value of each key is an array of elements responsible for generating the |
|
* key. The iteratee is invoked with one argument: (value). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Collection |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {Function} [iteratee=_.identity] The iteratee to transform keys. |
|
* @returns {Object} Returns the composed aggregate object. |
|
* @example |
|
* |
|
* _.groupBy([6.1, 4.2, 6.3], Math.floor); |
|
* // => { '4': [4.2], '6': [6.1, 6.3] } |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.groupBy(['one', 'two', 'three'], 'length'); |
|
* // => { '3': ['one', 'two'], '5': ['three'] } |
|
*/ |
|
var groupBy = createAggregator(function(result, value, key) { |
|
if (hasOwnProperty.call(result, key)) { |
|
result[key].push(value); |
|
} else { |
|
baseAssignValue(result, key, [value]); |
|
} |
|
}); |
|
|
|
/** |
|
* Checks if `value` is in `collection`. If `collection` is a string, it's |
|
* checked for a substring of `value`, otherwise |
|
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) |
|
* is used for equality comparisons. If `fromIndex` is negative, it's used as |
|
* the offset from the end of `collection`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Collection |
|
* @param {Array|Object|string} collection The collection to inspect. |
|
* @param {*} value The value to search for. |
|
* @param {number} [fromIndex=0] The index to search from. |
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. |
|
* @returns {boolean} Returns `true` if `value` is found, else `false`. |
|
* @example |
|
* |
|
* _.includes([1, 2, 3], 1); |
|
* // => true |
|
* |
|
* _.includes([1, 2, 3], 1, 2); |
|
* // => false |
|
* |
|
* _.includes({ 'a': 1, 'b': 2 }, 1); |
|
* // => true |
|
* |
|
* _.includes('abcd', 'bc'); |
|
* // => true |
|
*/ |
|
function includes(collection, value, fromIndex, guard) { |
|
collection = isArrayLike(collection) ? collection : values(collection); |
|
fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0; |
|
|
|
var length = collection.length; |
|
if (fromIndex < 0) { |
|
fromIndex = nativeMax(length + fromIndex, 0); |
|
} |
|
return isString(collection) |
|
? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1) |
|
: (!!length && baseIndexOf(collection, value, fromIndex) > -1); |
|
} |
|
|
|
/** |
|
* Invokes the method at `path` of each element in `collection`, returning |
|
* an array of the results of each invoked method. Any additional arguments |
|
* are provided to each invoked method. If `path` is a function, it's invoked |
|
* for, and `this` bound to, each element in `collection`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Collection |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {Array|Function|string} path The path of the method to invoke or |
|
* the function invoked per iteration. |
|
* @param {...*} [args] The arguments to invoke each method with. |
|
* @returns {Array} Returns the array of results. |
|
* @example |
|
* |
|
* _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort'); |
|
* // => [[1, 5, 7], [1, 2, 3]] |
|
* |
|
* _.invokeMap([123, 456], String.prototype.split, ''); |
|
* // => [['1', '2', '3'], ['4', '5', '6']] |
|
*/ |
|
var invokeMap = baseRest(function(collection, path, args) { |
|
var index = -1, |
|
isFunc = typeof path == 'function', |
|
result = isArrayLike(collection) ? Array(collection.length) : []; |
|
|
|
baseEach(collection, function(value) { |
|
result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args); |
|
}); |
|
return result; |
|
}); |
|
|
|
/** |
|
* Creates an object composed of keys generated from the results of running |
|
* each element of `collection` thru `iteratee`. The corresponding value of |
|
* each key is the last element responsible for generating the key. The |
|
* iteratee is invoked with one argument: (value). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Collection |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {Function} [iteratee=_.identity] The iteratee to transform keys. |
|
* @returns {Object} Returns the composed aggregate object. |
|
* @example |
|
* |
|
* var array = [ |
|
* { 'dir': 'left', 'code': 97 }, |
|
* { 'dir': 'right', 'code': 100 } |
|
* ]; |
|
* |
|
* _.keyBy(array, function(o) { |
|
* return String.fromCharCode(o.code); |
|
* }); |
|
* // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } |
|
* |
|
* _.keyBy(array, 'dir'); |
|
* // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } |
|
*/ |
|
var keyBy = createAggregator(function(result, value, key) { |
|
baseAssignValue(result, key, value); |
|
}); |
|
|
|
/** |
|
* Creates an array of values by running each element in `collection` thru |
|
* `iteratee`. The iteratee is invoked with three arguments: |
|
* (value, index|key, collection). |
|
* |
|
* Many lodash methods are guarded to work as iteratees for methods like |
|
* `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. |
|
* |
|
* The guarded methods are: |
|
* `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, |
|
* `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, |
|
* `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, |
|
* `template`, `trim`, `trimEnd`, `trimStart`, and `words` |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Collection |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration. |
|
* @returns {Array} Returns the new mapped array. |
|
* @example |
|
* |
|
* function square(n) { |
|
* return n * n; |
|
* } |
|
* |
|
* _.map([4, 8], square); |
|
* // => [16, 64] |
|
* |
|
* _.map({ 'a': 4, 'b': 8 }, square); |
|
* // => [16, 64] (iteration order is not guaranteed) |
|
* |
|
* var users = [ |
|
* { 'user': 'barney' }, |
|
* { 'user': 'fred' } |
|
* ]; |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.map(users, 'user'); |
|
* // => ['barney', 'fred'] |
|
*/ |
|
function map(collection, iteratee) { |
|
var func = isArray(collection) ? arrayMap : baseMap; |
|
return func(collection, getIteratee(iteratee, 3)); |
|
} |
|
|
|
/** |
|
* This method is like `_.sortBy` except that it allows specifying the sort |
|
* orders of the iteratees to sort by. If `orders` is unspecified, all values |
|
* are sorted in ascending order. Otherwise, specify an order of "desc" for |
|
* descending or "asc" for ascending sort order of corresponding values. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Collection |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]] |
|
* The iteratees to sort by. |
|
* @param {string[]} [orders] The sort orders of `iteratees`. |
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. |
|
* @returns {Array} Returns the new sorted array. |
|
* @example |
|
* |
|
* var users = [ |
|
* { 'user': 'fred', 'age': 48 }, |
|
* { 'user': 'barney', 'age': 34 }, |
|
* { 'user': 'fred', 'age': 40 }, |
|
* { 'user': 'barney', 'age': 36 } |
|
* ]; |
|
* |
|
* // Sort by `user` in ascending order and by `age` in descending order. |
|
* _.orderBy(users, ['user', 'age'], ['asc', 'desc']); |
|
* // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] |
|
*/ |
|
function orderBy(collection, iteratees, orders, guard) { |
|
if (collection == null) { |
|
return []; |
|
} |
|
if (!isArray(iteratees)) { |
|
iteratees = iteratees == null ? [] : [iteratees]; |
|
} |
|
orders = guard ? undefined : orders; |
|
if (!isArray(orders)) { |
|
orders = orders == null ? [] : [orders]; |
|
} |
|
return baseOrderBy(collection, iteratees, orders); |
|
} |
|
|
|
/** |
|
* Creates an array of elements split into two groups, the first of which |
|
* contains elements `predicate` returns truthy for, the second of which |
|
* contains elements `predicate` returns falsey for. The predicate is |
|
* invoked with one argument: (value). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Collection |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {Function} [predicate=_.identity] The function invoked per iteration. |
|
* @returns {Array} Returns the array of grouped elements. |
|
* @example |
|
* |
|
* var users = [ |
|
* { 'user': 'barney', 'age': 36, 'active': false }, |
|
* { 'user': 'fred', 'age': 40, 'active': true }, |
|
* { 'user': 'pebbles', 'age': 1, 'active': false } |
|
* ]; |
|
* |
|
* _.partition(users, function(o) { return o.active; }); |
|
* // => objects for [['fred'], ['barney', 'pebbles']] |
|
* |
|
* // The `_.matches` iteratee shorthand. |
|
* _.partition(users, { 'age': 1, 'active': false }); |
|
* // => objects for [['pebbles'], ['barney', 'fred']] |
|
* |
|
* // The `_.matchesProperty` iteratee shorthand. |
|
* _.partition(users, ['active', false]); |
|
* // => objects for [['barney', 'pebbles'], ['fred']] |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.partition(users, 'active'); |
|
* // => objects for [['fred'], ['barney', 'pebbles']] |
|
*/ |
|
var partition = createAggregator(function(result, value, key) { |
|
result[key ? 0 : 1].push(value); |
|
}, function() { return [[], []]; }); |
|
|
|
/** |
|
* Reduces `collection` to a value which is the accumulated result of running |
|
* each element in `collection` thru `iteratee`, where each successive |
|
* invocation is supplied the return value of the previous. If `accumulator` |
|
* is not given, the first element of `collection` is used as the initial |
|
* value. The iteratee is invoked with four arguments: |
|
* (accumulator, value, index|key, collection). |
|
* |
|
* Many lodash methods are guarded to work as iteratees for methods like |
|
* `_.reduce`, `_.reduceRight`, and `_.transform`. |
|
* |
|
* The guarded methods are: |
|
* `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, |
|
* and `sortBy` |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Collection |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration. |
|
* @param {*} [accumulator] The initial value. |
|
* @returns {*} Returns the accumulated value. |
|
* @see _.reduceRight |
|
* @example |
|
* |
|
* _.reduce([1, 2], function(sum, n) { |
|
* return sum + n; |
|
* }, 0); |
|
* // => 3 |
|
* |
|
* _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { |
|
* (result[value] || (result[value] = [])).push(key); |
|
* return result; |
|
* }, {}); |
|
* // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) |
|
*/ |
|
function reduce(collection, iteratee, accumulator) { |
|
var func = isArray(collection) ? arrayReduce : baseReduce, |
|
initAccum = arguments.length < 3; |
|
|
|
return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach); |
|
} |
|
|
|
/** |
|
* This method is like `_.reduce` except that it iterates over elements of |
|
* `collection` from right to left. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Collection |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration. |
|
* @param {*} [accumulator] The initial value. |
|
* @returns {*} Returns the accumulated value. |
|
* @see _.reduce |
|
* @example |
|
* |
|
* var array = [[0, 1], [2, 3], [4, 5]]; |
|
* |
|
* _.reduceRight(array, function(flattened, other) { |
|
* return flattened.concat(other); |
|
* }, []); |
|
* // => [4, 5, 2, 3, 0, 1] |
|
*/ |
|
function reduceRight(collection, iteratee, accumulator) { |
|
var func = isArray(collection) ? arrayReduceRight : baseReduce, |
|
initAccum = arguments.length < 3; |
|
|
|
return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight); |
|
} |
|
|
|
/** |
|
* The opposite of `_.filter`; this method returns the elements of `collection` |
|
* that `predicate` does **not** return truthy for. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Collection |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {Function} [predicate=_.identity] The function invoked per iteration. |
|
* @returns {Array} Returns the new filtered array. |
|
* @see _.filter |
|
* @example |
|
* |
|
* var users = [ |
|
* { 'user': 'barney', 'age': 36, 'active': false }, |
|
* { 'user': 'fred', 'age': 40, 'active': true } |
|
* ]; |
|
* |
|
* _.reject(users, function(o) { return !o.active; }); |
|
* // => objects for ['fred'] |
|
* |
|
* // The `_.matches` iteratee shorthand. |
|
* _.reject(users, { 'age': 40, 'active': true }); |
|
* // => objects for ['barney'] |
|
* |
|
* // The `_.matchesProperty` iteratee shorthand. |
|
* _.reject(users, ['active', false]); |
|
* // => objects for ['fred'] |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.reject(users, 'active'); |
|
* // => objects for ['barney'] |
|
*/ |
|
function reject(collection, predicate) { |
|
var func = isArray(collection) ? arrayFilter : baseFilter; |
|
return func(collection, negate(getIteratee(predicate, 3))); |
|
} |
|
|
|
/** |
|
* Gets a random element from `collection`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 2.0.0 |
|
* @category Collection |
|
* @param {Array|Object} collection The collection to sample. |
|
* @returns {*} Returns the random element. |
|
* @example |
|
* |
|
* _.sample([1, 2, 3, 4]); |
|
* // => 2 |
|
*/ |
|
function sample(collection) { |
|
var func = isArray(collection) ? arraySample : baseSample; |
|
return func(collection); |
|
} |
|
|
|
/** |
|
* Gets `n` random elements at unique keys from `collection` up to the |
|
* size of `collection`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Collection |
|
* @param {Array|Object} collection The collection to sample. |
|
* @param {number} [n=1] The number of elements to sample. |
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. |
|
* @returns {Array} Returns the random elements. |
|
* @example |
|
* |
|
* _.sampleSize([1, 2, 3], 2); |
|
* // => [3, 1] |
|
* |
|
* _.sampleSize([1, 2, 3], 4); |
|
* // => [2, 3, 1] |
|
*/ |
|
function sampleSize(collection, n, guard) { |
|
if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) { |
|
n = 1; |
|
} else { |
|
n = toInteger(n); |
|
} |
|
var func = isArray(collection) ? arraySampleSize : baseSampleSize; |
|
return func(collection, n); |
|
} |
|
|
|
/** |
|
* Creates an array of shuffled values, using a version of the |
|
* [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Collection |
|
* @param {Array|Object} collection The collection to shuffle. |
|
* @returns {Array} Returns the new shuffled array. |
|
* @example |
|
* |
|
* _.shuffle([1, 2, 3, 4]); |
|
* // => [4, 1, 3, 2] |
|
*/ |
|
function shuffle(collection) { |
|
var func = isArray(collection) ? arrayShuffle : baseShuffle; |
|
return func(collection); |
|
} |
|
|
|
/** |
|
* Gets the size of `collection` by returning its length for array-like |
|
* values or the number of own enumerable string keyed properties for objects. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Collection |
|
* @param {Array|Object|string} collection The collection to inspect. |
|
* @returns {number} Returns the collection size. |
|
* @example |
|
* |
|
* _.size([1, 2, 3]); |
|
* // => 3 |
|
* |
|
* _.size({ 'a': 1, 'b': 2 }); |
|
* // => 2 |
|
* |
|
* _.size('pebbles'); |
|
* // => 7 |
|
*/ |
|
function size(collection) { |
|
if (collection == null) { |
|
return 0; |
|
} |
|
if (isArrayLike(collection)) { |
|
return isString(collection) ? stringSize(collection) : collection.length; |
|
} |
|
var tag = getTag(collection); |
|
if (tag == mapTag || tag == setTag) { |
|
return collection.size; |
|
} |
|
return baseKeys(collection).length; |
|
} |
|
|
|
/** |
|
* Checks if `predicate` returns truthy for **any** element of `collection`. |
|
* Iteration is stopped once `predicate` returns truthy. The predicate is |
|
* invoked with three arguments: (value, index|key, collection). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Collection |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {Function} [predicate=_.identity] The function invoked per iteration. |
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. |
|
* @returns {boolean} Returns `true` if any element passes the predicate check, |
|
* else `false`. |
|
* @example |
|
* |
|
* _.some([null, 0, 'yes', false], Boolean); |
|
* // => true |
|
* |
|
* var users = [ |
|
* { 'user': 'barney', 'active': true }, |
|
* { 'user': 'fred', 'active': false } |
|
* ]; |
|
* |
|
* // The `_.matches` iteratee shorthand. |
|
* _.some(users, { 'user': 'barney', 'active': false }); |
|
* // => false |
|
* |
|
* // The `_.matchesProperty` iteratee shorthand. |
|
* _.some(users, ['active', false]); |
|
* // => true |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.some(users, 'active'); |
|
* // => true |
|
*/ |
|
function some(collection, predicate, guard) { |
|
var func = isArray(collection) ? arraySome : baseSome; |
|
if (guard && isIterateeCall(collection, predicate, guard)) { |
|
predicate = undefined; |
|
} |
|
return func(collection, getIteratee(predicate, 3)); |
|
} |
|
|
|
/** |
|
* Creates an array of elements, sorted in ascending order by the results of |
|
* running each element in a collection thru each iteratee. This method |
|
* performs a stable sort, that is, it preserves the original sort order of |
|
* equal elements. The iteratees are invoked with one argument: (value). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Collection |
|
* @param {Array|Object} collection The collection to iterate over. |
|
* @param {...(Function|Function[])} [iteratees=[_.identity]] |
|
* The iteratees to sort by. |
|
* @returns {Array} Returns the new sorted array. |
|
* @example |
|
* |
|
* var users = [ |
|
* { 'user': 'fred', 'age': 48 }, |
|
* { 'user': 'barney', 'age': 36 }, |
|
* { 'user': 'fred', 'age': 40 }, |
|
* { 'user': 'barney', 'age': 34 } |
|
* ]; |
|
* |
|
* _.sortBy(users, [function(o) { return o.user; }]); |
|
* // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] |
|
* |
|
* _.sortBy(users, ['user', 'age']); |
|
* // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]] |
|
*/ |
|
var sortBy = baseRest(function(collection, iteratees) { |
|
if (collection == null) { |
|
return []; |
|
} |
|
var length = iteratees.length; |
|
if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) { |
|
iteratees = []; |
|
} else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) { |
|
iteratees = [iteratees[0]]; |
|
} |
|
return baseOrderBy(collection, baseFlatten(iteratees, 1), []); |
|
}); |
|
|
|
/*------------------------------------------------------------------------*/ |
|
|
|
/** |
|
* Gets the timestamp of the number of milliseconds that have elapsed since |
|
* the Unix epoch (1 January 1970 00:00:00 UTC). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 2.4.0 |
|
* @category Date |
|
* @returns {number} Returns the timestamp. |
|
* @example |
|
* |
|
* _.defer(function(stamp) { |
|
* console.log(_.now() - stamp); |
|
* }, _.now()); |
|
* // => Logs the number of milliseconds it took for the deferred invocation. |
|
*/ |
|
var now = ctxNow || function() { |
|
return root.Date.now(); |
|
}; |
|
|
|
/*------------------------------------------------------------------------*/ |
|
|
|
/** |
|
* The opposite of `_.before`; this method creates a function that invokes |
|
* `func` once it's called `n` or more times. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Function |
|
* @param {number} n The number of calls before `func` is invoked. |
|
* @param {Function} func The function to restrict. |
|
* @returns {Function} Returns the new restricted function. |
|
* @example |
|
* |
|
* var saves = ['profile', 'settings']; |
|
* |
|
* var done = _.after(saves.length, function() { |
|
* console.log('done saving!'); |
|
* }); |
|
* |
|
* _.forEach(saves, function(type) { |
|
* asyncSave({ 'type': type, 'complete': done }); |
|
* }); |
|
* // => Logs 'done saving!' after the two async saves have completed. |
|
*/ |
|
function after(n, func) { |
|
if (typeof func != 'function') { |
|
throw new TypeError(FUNC_ERROR_TEXT); |
|
} |
|
n = toInteger(n); |
|
return function() { |
|
if (--n < 1) { |
|
return func.apply(this, arguments); |
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* Creates a function that invokes `func`, with up to `n` arguments, |
|
* ignoring any additional arguments. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Function |
|
* @param {Function} func The function to cap arguments for. |
|
* @param {number} [n=func.length] The arity cap. |
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. |
|
* @returns {Function} Returns the new capped function. |
|
* @example |
|
* |
|
* _.map(['6', '8', '10'], _.ary(parseInt, 1)); |
|
* // => [6, 8, 10] |
|
*/ |
|
function ary(func, n, guard) { |
|
n = guard ? undefined : n; |
|
n = (func && n == null) ? func.length : n; |
|
return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n); |
|
} |
|
|
|
/** |
|
* Creates a function that invokes `func`, with the `this` binding and arguments |
|
* of the created function, while it's called less than `n` times. Subsequent |
|
* calls to the created function return the result of the last `func` invocation. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Function |
|
* @param {number} n The number of calls at which `func` is no longer invoked. |
|
* @param {Function} func The function to restrict. |
|
* @returns {Function} Returns the new restricted function. |
|
* @example |
|
* |
|
* jQuery(element).on('click', _.before(5, addContactToList)); |
|
* // => Allows adding up to 4 contacts to the list. |
|
*/ |
|
function before(n, func) { |
|
var result; |
|
if (typeof func != 'function') { |
|
throw new TypeError(FUNC_ERROR_TEXT); |
|
} |
|
n = toInteger(n); |
|
return function() { |
|
if (--n > 0) { |
|
result = func.apply(this, arguments); |
|
} |
|
if (n <= 1) { |
|
func = undefined; |
|
} |
|
return result; |
|
}; |
|
} |
|
|
|
/** |
|
* Creates a function that invokes `func` with the `this` binding of `thisArg` |
|
* and `partials` prepended to the arguments it receives. |
|
* |
|
* The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, |
|
* may be used as a placeholder for partially applied arguments. |
|
* |
|
* **Note:** Unlike native `Function#bind`, this method doesn't set the "length" |
|
* property of bound functions. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Function |
|
* @param {Function} func The function to bind. |
|
* @param {*} thisArg The `this` binding of `func`. |
|
* @param {...*} [partials] The arguments to be partially applied. |
|
* @returns {Function} Returns the new bound function. |
|
* @example |
|
* |
|
* function greet(greeting, punctuation) { |
|
* return greeting + ' ' + this.user + punctuation; |
|
* } |
|
* |
|
* var object = { 'user': 'fred' }; |
|
* |
|
* var bound = _.bind(greet, object, 'hi'); |
|
* bound('!'); |
|
* // => 'hi fred!' |
|
* |
|
* // Bound with placeholders. |
|
* var bound = _.bind(greet, object, _, '!'); |
|
* bound('hi'); |
|
* // => 'hi fred!' |
|
*/ |
|
var bind = baseRest(function(func, thisArg, partials) { |
|
var bitmask = WRAP_BIND_FLAG; |
|
if (partials.length) { |
|
var holders = replaceHolders(partials, getHolder(bind)); |
|
bitmask |= WRAP_PARTIAL_FLAG; |
|
} |
|
return createWrap(func, bitmask, thisArg, partials, holders); |
|
}); |
|
|
|
/** |
|
* Creates a function that invokes the method at `object[key]` with `partials` |
|
* prepended to the arguments it receives. |
|
* |
|
* This method differs from `_.bind` by allowing bound functions to reference |
|
* methods that may be redefined or don't yet exist. See |
|
* [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) |
|
* for more details. |
|
* |
|
* The `_.bindKey.placeholder` value, which defaults to `_` in monolithic |
|
* builds, may be used as a placeholder for partially applied arguments. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.10.0 |
|
* @category Function |
|
* @param {Object} object The object to invoke the method on. |
|
* @param {string} key The key of the method. |
|
* @param {...*} [partials] The arguments to be partially applied. |
|
* @returns {Function} Returns the new bound function. |
|
* @example |
|
* |
|
* var object = { |
|
* 'user': 'fred', |
|
* 'greet': function(greeting, punctuation) { |
|
* return greeting + ' ' + this.user + punctuation; |
|
* } |
|
* }; |
|
* |
|
* var bound = _.bindKey(object, 'greet', 'hi'); |
|
* bound('!'); |
|
* // => 'hi fred!' |
|
* |
|
* object.greet = function(greeting, punctuation) { |
|
* return greeting + 'ya ' + this.user + punctuation; |
|
* }; |
|
* |
|
* bound('!'); |
|
* // => 'hiya fred!' |
|
* |
|
* // Bound with placeholders. |
|
* var bound = _.bindKey(object, 'greet', _, '!'); |
|
* bound('hi'); |
|
* // => 'hiya fred!' |
|
*/ |
|
var bindKey = baseRest(function(object, key, partials) { |
|
var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG; |
|
if (partials.length) { |
|
var holders = replaceHolders(partials, getHolder(bindKey)); |
|
bitmask |= WRAP_PARTIAL_FLAG; |
|
} |
|
return createWrap(key, bitmask, object, partials, holders); |
|
}); |
|
|
|
/** |
|
* 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, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity); |
|
result.placeholder = curry.placeholder; |
|
return result; |
|
} |
|
|
|
/** |
|
* This method is like `_.curry` except that arguments are applied to `func` |
|
* in the manner of `_.partialRight` instead of `_.partial`. |
|
* |
|
* The `_.curryRight.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 3.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 = _.curryRight(abc); |
|
* |
|
* curried(3)(2)(1); |
|
* // => [1, 2, 3] |
|
* |
|
* curried(2, 3)(1); |
|
* // => [1, 2, 3] |
|
* |
|
* curried(1, 2, 3); |
|
* // => [1, 2, 3] |
|
* |
|
* // Curried with placeholders. |
|
* curried(3)(1, _)(2); |
|
* // => [1, 2, 3] |
|
*/ |
|
function curryRight(func, arity, guard) { |
|
arity = guard ? undefined : arity; |
|
var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity); |
|
result.placeholder = curryRight.placeholder; |
|
return result; |
|
} |
|
|
|
/** |
|
* Creates a debounced function that delays invoking `func` until after `wait` |
|
* milliseconds have elapsed since the last time the debounced function was |
|
* invoked. The debounced function comes with a `cancel` method to cancel |
|
* delayed `func` invocations and a `flush` method to immediately invoke them. |
|
* Provide `options` to indicate whether `func` should be invoked on the |
|
* leading and/or trailing edge of the `wait` timeout. The `func` is invoked |
|
* with the last arguments provided to the debounced function. Subsequent |
|
* calls to the debounced function return the result of the last `func` |
|
* invocation. |
|
* |
|
* **Note:** If `leading` and `trailing` options are `true`, `func` is |
|
* invoked on the trailing edge of the timeout only if the debounced function |
|
* is invoked more than once during the `wait` timeout. |
|
* |
|
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred |
|
* until to the next tick, similar to `setTimeout` with a timeout of `0`. |
|
* |
|
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) |
|
* for details over the differences between `_.debounce` and `_.throttle`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Function |
|
* @param {Function} func The function to debounce. |
|
* @param {number} [wait=0] The number of milliseconds to delay. |
|
* @param {Object} [options={}] The options object. |
|
* @param {boolean} [options.leading=false] |
|
* Specify invoking on the leading edge of the timeout. |
|
* @param {number} [options.maxWait] |
|
* The maximum time `func` is allowed to be delayed before it's invoked. |
|
* @param {boolean} [options.trailing=true] |
|
* Specify invoking on the trailing edge of the timeout. |
|
* @returns {Function} Returns the new debounced function. |
|
* @example |
|
* |
|
* // Avoid costly calculations while the window size is in flux. |
|
* jQuery(window).on('resize', _.debounce(calculateLayout, 150)); |
|
* |
|
* // Invoke `sendMail` when clicked, debouncing subsequent calls. |
|
* jQuery(element).on('click', _.debounce(sendMail, 300, { |
|
* 'leading': true, |
|
* 'trailing': false |
|
* })); |
|
* |
|
* // Ensure `batchLog` is invoked once after 1 second of debounced calls. |
|
* var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); |
|
* var source = new EventSource('/stream'); |
|
* jQuery(source).on('message', debounced); |
|
* |
|
* // Cancel the trailing debounced invocation. |
|
* jQuery(window).on('popstate', debounced.cancel); |
|
*/ |
|
function debounce(func, wait, options) { |
|
var lastArgs, |
|
lastThis, |
|
maxWait, |
|
result, |
|
timerId, |
|
lastCallTime, |
|
lastInvokeTime = 0, |
|
leading = false, |
|
maxing = false, |
|
trailing = true; |
|
|
|
if (typeof func != 'function') { |
|
throw new TypeError(FUNC_ERROR_TEXT); |
|
} |
|
wait = toNumber(wait) || 0; |
|
if (isObject(options)) { |
|
leading = !!options.leading; |
|
maxing = 'maxWait' in options; |
|
maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; |
|
trailing = 'trailing' in options ? !!options.trailing : trailing; |
|
} |
|
|
|
function invokeFunc(time) { |
|
var args = lastArgs, |
|
thisArg = lastThis; |
|
|
|
lastArgs = lastThis = undefined; |
|
lastInvokeTime = time; |
|
result = func.apply(thisArg, args); |
|
return result; |
|
} |
|
|
|
function leadingEdge(time) { |
|
// Reset any `maxWait` timer. |
|
lastInvokeTime = time; |
|
// Start the timer for the trailing edge. |
|
timerId = setTimeout(timerExpired, wait); |
|
// Invoke the leading edge. |
|
return leading ? invokeFunc(time) : result; |
|
} |
|
|
|
function remainingWait(time) { |
|
var timeSinceLastCall = time - lastCallTime, |
|
timeSinceLastInvoke = time - lastInvokeTime, |
|
timeWaiting = wait - timeSinceLastCall; |
|
|
|
return maxing |
|
? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) |
|
: timeWaiting; |
|
} |
|
|
|
function shouldInvoke(time) { |
|
var timeSinceLastCall = time - lastCallTime, |
|
timeSinceLastInvoke = time - lastInvokeTime; |
|
|
|
// Either this is the first call, activity has stopped and we're at the |
|
// trailing edge, the system time has gone backwards and we're treating |
|
// it as the trailing edge, or we've hit the `maxWait` limit. |
|
return (lastCallTime === undefined || (timeSinceLastCall >= wait) || |
|
(timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)); |
|
} |
|
|
|
function timerExpired() { |
|
var time = now(); |
|
if (shouldInvoke(time)) { |
|
return trailingEdge(time); |
|
} |
|
// Restart the timer. |
|
timerId = setTimeout(timerExpired, remainingWait(time)); |
|
} |
|
|
|
function trailingEdge(time) { |
|
timerId = undefined; |
|
|
|
// Only invoke if we have `lastArgs` which means `func` has been |
|
// debounced at least once. |
|
if (trailing && lastArgs) { |
|
return invokeFunc(time); |
|
} |
|
lastArgs = lastThis = undefined; |
|
return result; |
|
} |
|
|
|
function cancel() { |
|
if (timerId !== undefined) { |
|
clearTimeout(timerId); |
|
} |
|
lastInvokeTime = 0; |
|
lastArgs = lastCallTime = lastThis = timerId = undefined; |
|
} |
|
|
|
function flush() { |
|
return timerId === undefined ? result : trailingEdge(now()); |
|
} |
|
|
|
function debounced() { |
|
var time = now(), |
|
isInvoking = shouldInvoke(time); |
|
|
|
lastArgs = arguments; |
|
lastThis = this; |
|
lastCallTime = time; |
|
|
|
if (isInvoking) { |
|
if (timerId === undefined) { |
|
return leadingEdge(lastCallTime); |
|
} |
|
if (maxing) { |
|
// Handle invocations in a tight loop. |
|
timerId = setTimeout(timerExpired, wait); |
|
return invokeFunc(lastCallTime); |
|
} |
|
} |
|
if (timerId === undefined) { |
|
timerId = setTimeout(timerExpired, wait); |
|
} |
|
return result; |
|
} |
|
debounced.cancel = cancel; |
|
debounced.flush = flush; |
|
return debounced; |
|
} |
|
|
|
/** |
|
* Defers invoking the `func` until the current call stack has cleared. Any |
|
* additional arguments are provided to `func` when it's invoked. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Function |
|
* @param {Function} func The function to defer. |
|
* @param {...*} [args] The arguments to invoke `func` with. |
|
* @returns {number} Returns the timer id. |
|
* @example |
|
* |
|
* _.defer(function(text) { |
|
* console.log(text); |
|
* }, 'deferred'); |
|
* // => Logs 'deferred' after one millisecond. |
|
*/ |
|
var defer = baseRest(function(func, args) { |
|
return baseDelay(func, 1, args); |
|
}); |
|
|
|
/** |
|
* Invokes `func` after `wait` milliseconds. Any additional arguments are |
|
* provided to `func` when it's invoked. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Function |
|
* @param {Function} func The function to delay. |
|
* @param {number} wait The number of milliseconds to delay invocation. |
|
* @param {...*} [args] The arguments to invoke `func` with. |
|
* @returns {number} Returns the timer id. |
|
* @example |
|
* |
|
* _.delay(function(text) { |
|
* console.log(text); |
|
* }, 1000, 'later'); |
|
* // => Logs 'later' after one second. |
|
*/ |
|
var delay = baseRest(function(func, wait, args) { |
|
return baseDelay(func, toNumber(wait) || 0, args); |
|
}); |
|
|
|
/** |
|
* Creates a function that invokes `func` with arguments reversed. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Function |
|
* @param {Function} func The function to flip arguments for. |
|
* @returns {Function} Returns the new flipped function. |
|
* @example |
|
* |
|
* var flipped = _.flip(function() { |
|
* return _.toArray(arguments); |
|
* }); |
|
* |
|
* flipped('a', 'b', 'c', 'd'); |
|
* // => ['d', 'c', 'b', 'a'] |
|
*/ |
|
function flip(func) { |
|
return createWrap(func, WRAP_FLIP_FLAG); |
|
} |
|
|
|
/** |
|
* Creates a function that memoizes the result of `func`. If `resolver` is |
|
* provided, it determines the cache key for storing the result based on the |
|
* arguments provided to the memoized function. By default, the first argument |
|
* provided to the memoized function is used as the map cache key. The `func` |
|
* is invoked with the `this` binding of the memoized function. |
|
* |
|
* **Note:** The cache is exposed as the `cache` property on the memoized |
|
* function. Its creation may be customized by replacing the `_.memoize.Cache` |
|
* constructor with one whose instances implement the |
|
* [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) |
|
* method interface of `clear`, `delete`, `get`, `has`, and `set`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Function |
|
* @param {Function} func The function to have its output memoized. |
|
* @param {Function} [resolver] The function to resolve the cache key. |
|
* @returns {Function} Returns the new memoized function. |
|
* @example |
|
* |
|
* var object = { 'a': 1, 'b': 2 }; |
|
* var other = { 'c': 3, 'd': 4 }; |
|
* |
|
* var values = _.memoize(_.values); |
|
* values(object); |
|
* // => [1, 2] |
|
* |
|
* values(other); |
|
* // => [3, 4] |
|
* |
|
* object.a = 2; |
|
* values(object); |
|
* // => [1, 2] |
|
* |
|
* // Modify the result cache. |
|
* values.cache.set(object, ['a', 'b']); |
|
* values(object); |
|
* // => ['a', 'b'] |
|
* |
|
* // Replace `_.memoize.Cache`. |
|
* _.memoize.Cache = WeakMap; |
|
*/ |
|
function memoize(func, resolver) { |
|
if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { |
|
throw new TypeError(FUNC_ERROR_TEXT); |
|
} |
|
var memoized = function() { |
|
var args = arguments, |
|
key = resolver ? resolver.apply(this, args) : args[0], |
|
cache = memoized.cache; |
|
|
|
if (cache.has(key)) { |
|
return cache.get(key); |
|
} |
|
var result = func.apply(this, args); |
|
memoized.cache = cache.set(key, result) || cache; |
|
return result; |
|
}; |
|
memoized.cache = new (memoize.Cache || MapCache); |
|
return memoized; |
|
} |
|
|
|
// Expose `MapCache`. |
|
memoize.Cache = MapCache; |
|
|
|
/** |
|
* Creates a function that negates the result of the predicate `func`. The |
|
* `func` predicate is invoked with the `this` binding and arguments of the |
|
* created function. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Function |
|
* @param {Function} predicate The predicate to negate. |
|
* @returns {Function} Returns the new negated function. |
|
* @example |
|
* |
|
* function isEven(n) { |
|
* return n % 2 == 0; |
|
* } |
|
* |
|
* _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); |
|
* // => [1, 3, 5] |
|
*/ |
|
function negate(predicate) { |
|
if (typeof predicate != 'function') { |
|
throw new TypeError(FUNC_ERROR_TEXT); |
|
} |
|
return function() { |
|
var args = arguments; |
|
switch (args.length) { |
|
case 0: return !predicate.call(this); |
|
case 1: return !predicate.call(this, args[0]); |
|
case 2: return !predicate.call(this, args[0], args[1]); |
|
case 3: return !predicate.call(this, args[0], args[1], args[2]); |
|
} |
|
return !predicate.apply(this, args); |
|
}; |
|
} |
|
|
|
/** |
|
* Creates a function that is restricted to invoking `func` once. Repeat calls |
|
* to the function return the value of the first invocation. The `func` is |
|
* invoked with the `this` binding and arguments of the created function. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Function |
|
* @param {Function} func The function to restrict. |
|
* @returns {Function} Returns the new restricted function. |
|
* @example |
|
* |
|
* var initialize = _.once(createApplication); |
|
* initialize(); |
|
* initialize(); |
|
* // => `createApplication` is invoked once |
|
*/ |
|
function once(func) { |
|
return before(2, func); |
|
} |
|
|
|
/** |
|
* Creates a function that invokes `func` with its arguments transformed. |
|
* |
|
* @static |
|
* @since 4.0.0 |
|
* @memberOf _ |
|
* @category Function |
|
* @param {Function} func The function to wrap. |
|
* @param {...(Function|Function[])} [transforms=[_.identity]] |
|
* The argument transforms. |
|
* @returns {Function} Returns the new function. |
|
* @example |
|
* |
|
* function doubled(n) { |
|
* return n * 2; |
|
* } |
|
* |
|
* function square(n) { |
|
* return n * n; |
|
* } |
|
* |
|
* var func = _.overArgs(function(x, y) { |
|
* return [x, y]; |
|
* }, [square, doubled]); |
|
* |
|
* func(9, 3); |
|
* // => [81, 6] |
|
* |
|
* func(10, 5); |
|
* // => [100, 10] |
|
*/ |
|
var overArgs = castRest(function(func, transforms) { |
|
transforms = (transforms.length == 1 && isArray(transforms[0])) |
|
? arrayMap(transforms[0], baseUnary(getIteratee())) |
|
: arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee())); |
|
|
|
var funcsLength = transforms.length; |
|
return baseRest(function(args) { |
|
var index = -1, |
|
length = nativeMin(args.length, funcsLength); |
|
|
|
while (++index < length) { |
|
args[index] = transforms[index].call(this, args[index]); |
|
} |
|
return apply(func, this, args); |
|
}); |
|
}); |
|
|
|
/** |
|
* Creates a function that invokes `func` with `partials` prepended to the |
|
* arguments it receives. This method is like `_.bind` except it does **not** |
|
* alter the `this` binding. |
|
* |
|
* The `_.partial.placeholder` value, which defaults to `_` in monolithic |
|
* builds, may be used as a placeholder for partially applied arguments. |
|
* |
|
* **Note:** This method doesn't set the "length" property of partially |
|
* applied functions. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.2.0 |
|
* @category Function |
|
* @param {Function} func The function to partially apply arguments to. |
|
* @param {...*} [partials] The arguments to be partially applied. |
|
* @returns {Function} Returns the new partially applied function. |
|
* @example |
|
* |
|
* function greet(greeting, name) { |
|
* return greeting + ' ' + name; |
|
* } |
|
* |
|
* var sayHelloTo = _.partial(greet, 'hello'); |
|
* sayHelloTo('fred'); |
|
* // => 'hello fred' |
|
* |
|
* // Partially applied with placeholders. |
|
* var greetFred = _.partial(greet, _, 'fred'); |
|
* greetFred('hi'); |
|
* // => 'hi fred' |
|
*/ |
|
var partial = baseRest(function(func, partials) { |
|
var holders = replaceHolders(partials, getHolder(partial)); |
|
return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders); |
|
}); |
|
|
|
/** |
|
* This method is like `_.partial` except that partially applied arguments |
|
* are appended to the arguments it receives. |
|
* |
|
* The `_.partialRight.placeholder` value, which defaults to `_` in monolithic |
|
* builds, may be used as a placeholder for partially applied arguments. |
|
* |
|
* **Note:** This method doesn't set the "length" property of partially |
|
* applied functions. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 1.0.0 |
|
* @category Function |
|
* @param {Function} func The function to partially apply arguments to. |
|
* @param {...*} [partials] The arguments to be partially applied. |
|
* @returns {Function} Returns the new partially applied function. |
|
* @example |
|
* |
|
* function greet(greeting, name) { |
|
* return greeting + ' ' + name; |
|
* } |
|
* |
|
* var greetFred = _.partialRight(greet, 'fred'); |
|
* greetFred('hi'); |
|
* // => 'hi fred' |
|
* |
|
* // Partially applied with placeholders. |
|
* var sayHelloTo = _.partialRight(greet, 'hello', _); |
|
* sayHelloTo('fred'); |
|
* // => 'hello fred' |
|
*/ |
|
var partialRight = baseRest(function(func, partials) { |
|
var holders = replaceHolders(partials, getHolder(partialRight)); |
|
return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders); |
|
}); |
|
|
|
/** |
|
* Creates a function that invokes `func` with arguments arranged according |
|
* to the specified `indexes` where the argument value at the first index is |
|
* provided as the first argument, the argument value at the second index is |
|
* provided as the second argument, and so on. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Function |
|
* @param {Function} func The function to rearrange arguments for. |
|
* @param {...(number|number[])} indexes The arranged argument indexes. |
|
* @returns {Function} Returns the new function. |
|
* @example |
|
* |
|
* var rearged = _.rearg(function(a, b, c) { |
|
* return [a, b, c]; |
|
* }, [2, 0, 1]); |
|
* |
|
* rearged('b', 'c', 'a') |
|
* // => ['a', 'b', 'c'] |
|
*/ |
|
var rearg = flatRest(function(func, indexes) { |
|
return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes); |
|
}); |
|
|
|
/** |
|
* Creates a function that invokes `func` with the `this` binding of the |
|
* created function and arguments from `start` and beyond provided as |
|
* an array. |
|
* |
|
* **Note:** This method is based on the |
|
* [rest parameter](https://mdn.io/rest_parameters). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Function |
|
* @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. |
|
* @example |
|
* |
|
* var say = _.rest(function(what, names) { |
|
* return what + ' ' + _.initial(names).join(', ') + |
|
* (_.size(names) > 1 ? ', & ' : '') + _.last(names); |
|
* }); |
|
* |
|
* say('hello', 'fred', 'barney', 'pebbles'); |
|
* // => 'hello fred, barney, & pebbles' |
|
*/ |
|
function rest(func, start) { |
|
if (typeof func != 'function') { |
|
throw new TypeError(FUNC_ERROR_TEXT); |
|
} |
|
start = start === undefined ? start : toInteger(start); |
|
return baseRest(func, start); |
|
} |
|
|
|
/** |
|
* Creates a function that invokes `func` with the `this` binding of the |
|
* create function and an array of arguments much like |
|
* [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply). |
|
* |
|
* **Note:** This method is based on the |
|
* [spread operator](https://mdn.io/spread_operator). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.2.0 |
|
* @category Function |
|
* @param {Function} func The function to spread arguments over. |
|
* @param {number} [start=0] The start position of the spread. |
|
* @returns {Function} Returns the new function. |
|
* @example |
|
* |
|
* var say = _.spread(function(who, what) { |
|
* return who + ' says ' + what; |
|
* }); |
|
* |
|
* say(['fred', 'hello']); |
|
* // => 'fred says hello' |
|
* |
|
* var numbers = Promise.all([ |
|
* Promise.resolve(40), |
|
* Promise.resolve(36) |
|
* ]); |
|
* |
|
* numbers.then(_.spread(function(x, y) { |
|
* return x + y; |
|
* })); |
|
* // => a Promise of 76 |
|
*/ |
|
function spread(func, start) { |
|
if (typeof func != 'function') { |
|
throw new TypeError(FUNC_ERROR_TEXT); |
|
} |
|
start = start == null ? 0 : nativeMax(toInteger(start), 0); |
|
return baseRest(function(args) { |
|
var array = args[start], |
|
otherArgs = castSlice(args, 0, start); |
|
|
|
if (array) { |
|
arrayPush(otherArgs, array); |
|
} |
|
return apply(func, this, otherArgs); |
|
}); |
|
} |
|
|
|
/** |
|
* Creates a throttled function that only invokes `func` at most once per |
|
* every `wait` milliseconds. The throttled function comes with a `cancel` |
|
* method to cancel delayed `func` invocations and a `flush` method to |
|
* immediately invoke them. Provide `options` to indicate whether `func` |
|
* should be invoked on the leading and/or trailing edge of the `wait` |
|
* timeout. The `func` is invoked with the last arguments provided to the |
|
* throttled function. Subsequent calls to the throttled function return the |
|
* result of the last `func` invocation. |
|
* |
|
* **Note:** If `leading` and `trailing` options are `true`, `func` is |
|
* invoked on the trailing edge of the timeout only if the throttled function |
|
* is invoked more than once during the `wait` timeout. |
|
* |
|
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred |
|
* until to the next tick, similar to `setTimeout` with a timeout of `0`. |
|
* |
|
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) |
|
* for details over the differences between `_.throttle` and `_.debounce`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Function |
|
* @param {Function} func The function to throttle. |
|
* @param {number} [wait=0] The number of milliseconds to throttle invocations to. |
|
* @param {Object} [options={}] The options object. |
|
* @param {boolean} [options.leading=true] |
|
* Specify invoking on the leading edge of the timeout. |
|
* @param {boolean} [options.trailing=true] |
|
* Specify invoking on the trailing edge of the timeout. |
|
* @returns {Function} Returns the new throttled function. |
|
* @example |
|
* |
|
* // Avoid excessively updating the position while scrolling. |
|
* jQuery(window).on('scroll', _.throttle(updatePosition, 100)); |
|
* |
|
* // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes. |
|
* var throttled = _.throttle(renewToken, 300000, { 'trailing': false }); |
|
* jQuery(element).on('click', throttled); |
|
* |
|
* // Cancel the trailing throttled invocation. |
|
* jQuery(window).on('popstate', throttled.cancel); |
|
*/ |
|
function throttle(func, wait, options) { |
|
var leading = true, |
|
trailing = true; |
|
|
|
if (typeof func != 'function') { |
|
throw new TypeError(FUNC_ERROR_TEXT); |
|
} |
|
if (isObject(options)) { |
|
leading = 'leading' in options ? !!options.leading : leading; |
|
trailing = 'trailing' in options ? !!options.trailing : trailing; |
|
} |
|
return debounce(func, wait, { |
|
'leading': leading, |
|
'maxWait': wait, |
|
'trailing': trailing |
|
}); |
|
} |
|
|
|
/** |
|
* Creates a function that accepts up to one argument, ignoring any |
|
* additional arguments. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Function |
|
* @param {Function} func The function to cap arguments for. |
|
* @returns {Function} Returns the new capped function. |
|
* @example |
|
* |
|
* _.map(['6', '8', '10'], _.unary(parseInt)); |
|
* // => [6, 8, 10] |
|
*/ |
|
function unary(func) { |
|
return ary(func, 1); |
|
} |
|
|
|
/** |
|
* Creates a function that provides `value` to `wrapper` as its first |
|
* argument. Any additional arguments provided to the function are appended |
|
* to those provided to the `wrapper`. The wrapper is invoked with the `this` |
|
* binding of the created function. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Function |
|
* @param {*} value The value to wrap. |
|
* @param {Function} [wrapper=identity] The wrapper function. |
|
* @returns {Function} Returns the new function. |
|
* @example |
|
* |
|
* var p = _.wrap(_.escape, function(func, text) { |
|
* return '<p>' + func(text) + '</p>'; |
|
* }); |
|
* |
|
* p('fred, barney, & pebbles'); |
|
* // => '<p>fred, barney, & pebbles</p>' |
|
*/ |
|
function wrap(value, wrapper) { |
|
return partial(castFunction(wrapper), value); |
|
} |
|
|
|
/*------------------------------------------------------------------------*/ |
|
|
|
/** |
|
* Casts `value` as an array if it's not one. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.4.0 |
|
* @category Lang |
|
* @param {*} value The value to inspect. |
|
* @returns {Array} Returns the cast array. |
|
* @example |
|
* |
|
* _.castArray(1); |
|
* // => [1] |
|
* |
|
* _.castArray({ 'a': 1 }); |
|
* // => [{ 'a': 1 }] |
|
* |
|
* _.castArray('abc'); |
|
* // => ['abc'] |
|
* |
|
* _.castArray(null); |
|
* // => [null] |
|
* |
|
* _.castArray(undefined); |
|
* // => [undefined] |
|
* |
|
* _.castArray(); |
|
* // => [] |
|
* |
|
* var array = [1, 2, 3]; |
|
* console.log(_.castArray(array) === array); |
|
* // => true |
|
*/ |
|
function castArray() { |
|
if (!arguments.length) { |
|
return []; |
|
} |
|
var value = arguments[0]; |
|
return isArray(value) ? value : [value]; |
|
} |
|
|
|
/** |
|
* Creates a shallow clone of `value`. |
|
* |
|
* **Note:** This method is loosely based on the |
|
* [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) |
|
* and supports cloning arrays, array buffers, booleans, date objects, maps, |
|
* numbers, `Object` objects, regexes, sets, strings, symbols, and typed |
|
* arrays. The own enumerable properties of `arguments` objects are cloned |
|
* as plain objects. An empty object is returned for uncloneable values such |
|
* as error objects, functions, DOM nodes, and WeakMaps. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Lang |
|
* @param {*} value The value to clone. |
|
* @returns {*} Returns the cloned value. |
|
* @see _.cloneDeep |
|
* @example |
|
* |
|
* var objects = [{ 'a': 1 }, { 'b': 2 }]; |
|
* |
|
* var shallow = _.clone(objects); |
|
* console.log(shallow[0] === objects[0]); |
|
* // => true |
|
*/ |
|
function clone(value) { |
|
return baseClone(value, CLONE_SYMBOLS_FLAG); |
|
} |
|
|
|
/** |
|
* This method is like `_.clone` except that it accepts `customizer` which |
|
* is invoked to produce the cloned value. If `customizer` returns `undefined`, |
|
* cloning is handled by the method instead. The `customizer` is invoked with |
|
* up to four arguments; (value [, index|key, object, stack]). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Lang |
|
* @param {*} value The value to clone. |
|
* @param {Function} [customizer] The function to customize cloning. |
|
* @returns {*} Returns the cloned value. |
|
* @see _.cloneDeepWith |
|
* @example |
|
* |
|
* function customizer(value) { |
|
* if (_.isElement(value)) { |
|
* return value.cloneNode(false); |
|
* } |
|
* } |
|
* |
|
* var el = _.cloneWith(document.body, customizer); |
|
* |
|
* console.log(el === document.body); |
|
* // => false |
|
* console.log(el.nodeName); |
|
* // => 'BODY' |
|
* console.log(el.childNodes.length); |
|
* // => 0 |
|
*/ |
|
function cloneWith(value, customizer) { |
|
customizer = typeof customizer == 'function' ? customizer : undefined; |
|
return baseClone(value, CLONE_SYMBOLS_FLAG, customizer); |
|
} |
|
|
|
/** |
|
* This method is like `_.clone` except that it recursively clones `value`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 1.0.0 |
|
* @category Lang |
|
* @param {*} value The value to recursively clone. |
|
* @returns {*} Returns the deep cloned value. |
|
* @see _.clone |
|
* @example |
|
* |
|
* var objects = [{ 'a': 1 }, { 'b': 2 }]; |
|
* |
|
* var deep = _.cloneDeep(objects); |
|
* console.log(deep[0] === objects[0]); |
|
* // => false |
|
*/ |
|
function cloneDeep(value) { |
|
return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); |
|
} |
|
|
|
/** |
|
* This method is like `_.cloneWith` except that it recursively clones `value`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Lang |
|
* @param {*} value The value to recursively clone. |
|
* @param {Function} [customizer] The function to customize cloning. |
|
* @returns {*} Returns the deep cloned value. |
|
* @see _.cloneWith |
|
* @example |
|
* |
|
* function customizer(value) { |
|
* if (_.isElement(value)) { |
|
* return value.cloneNode(true); |
|
* } |
|
* } |
|
* |
|
* var el = _.cloneDeepWith(document.body, customizer); |
|
* |
|
* console.log(el === document.body); |
|
* // => false |
|
* console.log(el.nodeName); |
|
* // => 'BODY' |
|
* console.log(el.childNodes.length); |
|
* // => 20 |
|
*/ |
|
function cloneDeepWith(value, customizer) { |
|
customizer = typeof customizer == 'function' ? customizer : undefined; |
|
return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer); |
|
} |
|
|
|
/** |
|
* Checks if `object` conforms to `source` by invoking the predicate |
|
* properties of `source` with the corresponding property values of `object`. |
|
* |
|
* **Note:** This method is equivalent to `_.conforms` when `source` is |
|
* partially applied. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.14.0 |
|
* @category Lang |
|
* @param {Object} object The object to inspect. |
|
* @param {Object} source The object of property predicates to conform to. |
|
* @returns {boolean} Returns `true` if `object` conforms, else `false`. |
|
* @example |
|
* |
|
* var object = { 'a': 1, 'b': 2 }; |
|
* |
|
* _.conformsTo(object, { 'b': function(n) { return n > 1; } }); |
|
* // => true |
|
* |
|
* _.conformsTo(object, { 'b': function(n) { return n > 2; } }); |
|
* // => false |
|
*/ |
|
function conformsTo(object, source) { |
|
return source == null || baseConformsTo(object, source, keys(source)); |
|
} |
|
|
|
/** |
|
* Performs a |
|
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) |
|
* comparison between two values to determine if they are equivalent. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Lang |
|
* @param {*} value The value to compare. |
|
* @param {*} other The other value to compare. |
|
* @returns {boolean} Returns `true` if the values are equivalent, else `false`. |
|
* @example |
|
* |
|
* var object = { 'a': 1 }; |
|
* var other = { 'a': 1 }; |
|
* |
|
* _.eq(object, object); |
|
* // => true |
|
* |
|
* _.eq(object, other); |
|
* // => false |
|
* |
|
* _.eq('a', 'a'); |
|
* // => true |
|
* |
|
* _.eq('a', Object('a')); |
|
* // => false |
|
* |
|
* _.eq(NaN, NaN); |
|
* // => true |
|
*/ |
|
function eq(value, other) { |
|
return value === other || (value !== value && other !== other); |
|
} |
|
|
|
/** |
|
* Checks if `value` is greater than `other`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.9.0 |
|
* @category Lang |
|
* @param {*} value The value to compare. |
|
* @param {*} other The other value to compare. |
|
* @returns {boolean} Returns `true` if `value` is greater than `other`, |
|
* else `false`. |
|
* @see _.lt |
|
* @example |
|
* |
|
* _.gt(3, 1); |
|
* // => true |
|
* |
|
* _.gt(3, 3); |
|
* // => false |
|
* |
|
* _.gt(1, 3); |
|
* // => false |
|
*/ |
|
var gt = createRelationalOperation(baseGt); |
|
|
|
/** |
|
* Checks if `value` is greater than or equal to `other`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.9.0 |
|
* @category Lang |
|
* @param {*} value The value to compare. |
|
* @param {*} other The other value to compare. |
|
* @returns {boolean} Returns `true` if `value` is greater than or equal to |
|
* `other`, else `false`. |
|
* @see _.lte |
|
* @example |
|
* |
|
* _.gte(3, 1); |
|
* // => true |
|
* |
|
* _.gte(3, 3); |
|
* // => true |
|
* |
|
* _.gte(1, 3); |
|
* // => false |
|
*/ |
|
var gte = createRelationalOperation(function(value, other) { |
|
return value >= other; |
|
}); |
|
|
|
/** |
|
* 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 |
|
*/ |
|
var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { |
|
return isObjectLike(value) && hasOwnProperty.call(value, 'callee') && |
|
!propertyIsEnumerable.call(value, 'callee'); |
|
}; |
|
|
|
/** |
|
* 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 classified as an `ArrayBuffer` object. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.3.0 |
|
* @category Lang |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is an array buffer, else `false`. |
|
* @example |
|
* |
|
* _.isArrayBuffer(new ArrayBuffer(2)); |
|
* // => true |
|
* |
|
* _.isArrayBuffer(new Array(2)); |
|
* // => false |
|
*/ |
|
var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer; |
|
|
|
/** |
|
* 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 boolean primitive or object. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Lang |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is a boolean, else `false`. |
|
* @example |
|
* |
|
* _.isBoolean(false); |
|
* // => true |
|
* |
|
* _.isBoolean(null); |
|
* // => false |
|
*/ |
|
function isBoolean(value) { |
|
return value === true || value === false || |
|
(isObjectLike(value) && baseGetTag(value) == boolTag); |
|
} |
|
|
|
/** |
|
* Checks if `value` is a buffer. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.3.0 |
|
* @category Lang |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is a buffer, else `false`. |
|
* @example |
|
* |
|
* _.isBuffer(new Buffer(2)); |
|
* // => true |
|
* |
|
* _.isBuffer(new Uint8Array(2)); |
|
* // => false |
|
*/ |
|
var isBuffer = nativeIsBuffer || stubFalse; |
|
|
|
/** |
|
* Checks if `value` is classified as a `Date` object. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Lang |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is a date object, else `false`. |
|
* @example |
|
* |
|
* _.isDate(new Date); |
|
* // => true |
|
* |
|
* _.isDate('Mon April 23 2012'); |
|
* // => false |
|
*/ |
|
var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate; |
|
|
|
/** |
|
* Checks if `value` is likely a DOM element. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Lang |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. |
|
* @example |
|
* |
|
* _.isElement(document.body); |
|
* // => true |
|
* |
|
* _.isElement('<body>'); |
|
* // => false |
|
*/ |
|
function isElement(value) { |
|
return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value); |
|
} |
|
|
|
/** |
|
* Checks if `value` is an empty object, collection, map, or set. |
|
* |
|
* Objects are considered empty if they have no own enumerable string keyed |
|
* properties. |
|
* |
|
* Array-like values such as `arguments` objects, arrays, buffers, strings, or |
|
* jQuery-like collections are considered empty if they have a `length` of `0`. |
|
* Similarly, maps and sets are considered empty if they have a `size` of `0`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Lang |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is empty, else `false`. |
|
* @example |
|
* |
|
* _.isEmpty(null); |
|
* // => true |
|
* |
|
* _.isEmpty(true); |
|
* // => true |
|
* |
|
* _.isEmpty(1); |
|
* // => true |
|
* |
|
* _.isEmpty([1, 2, 3]); |
|
* // => false |
|
* |
|
* _.isEmpty({ 'a': 1 }); |
|
* // => false |
|
*/ |
|
function isEmpty(value) { |
|
if (value == null) { |
|
return true; |
|
} |
|
if (isArrayLike(value) && |
|
(isArray(value) || typeof value == 'string' || typeof value.splice == 'function' || |
|
isBuffer(value) || isTypedArray(value) || isArguments(value))) { |
|
return !value.length; |
|
} |
|
var tag = getTag(value); |
|
if (tag == mapTag || tag == setTag) { |
|
return !value.size; |
|
} |
|
if (isPrototype(value)) { |
|
return !baseKeys(value).length; |
|
} |
|
for (var key in value) { |
|
if (hasOwnProperty.call(value, key)) { |
|
return false; |
|
} |
|
} |
|
return true; |
|
} |
|
|
|
/** |
|
* Performs a deep comparison between two values to determine if they are |
|
* equivalent. |
|
* |
|
* **Note:** This method supports comparing arrays, array buffers, booleans, |
|
* date objects, error objects, maps, numbers, `Object` objects, regexes, |
|
* sets, strings, symbols, and typed arrays. `Object` objects are compared |
|
* by their own, not inherited, enumerable properties. Functions and DOM |
|
* nodes are compared by strict equality, i.e. `===`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Lang |
|
* @param {*} value The value to compare. |
|
* @param {*} other The other value to compare. |
|
* @returns {boolean} Returns `true` if the values are equivalent, else `false`. |
|
* @example |
|
* |
|
* var object = { 'a': 1 }; |
|
* var other = { 'a': 1 }; |
|
* |
|
* _.isEqual(object, other); |
|
* // => true |
|
* |
|
* object === other; |
|
* // => false |
|
*/ |
|
function isEqual(value, other) { |
|
return baseIsEqual(value, other); |
|
} |
|
|
|
/** |
|
* This method is like `_.isEqual` except that it accepts `customizer` which |
|
* is invoked to compare values. If `customizer` returns `undefined`, comparisons |
|
* are handled by the method instead. The `customizer` is invoked with up to |
|
* six arguments: (objValue, othValue [, index|key, object, other, stack]). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Lang |
|
* @param {*} value The value to compare. |
|
* @param {*} other The other value to compare. |
|
* @param {Function} [customizer] The function to customize comparisons. |
|
* @returns {boolean} Returns `true` if the values are equivalent, else `false`. |
|
* @example |
|
* |
|
* function isGreeting(value) { |
|
* return /^h(?:i|ello)$/.test(value); |
|
* } |
|
* |
|
* function customizer(objValue, othValue) { |
|
* if (isGreeting(objValue) && isGreeting(othValue)) { |
|
* return true; |
|
* } |
|
* } |
|
* |
|
* var array = ['hello', 'goodbye']; |
|
* var other = ['hi', 'goodbye']; |
|
* |
|
* _.isEqualWith(array, other, customizer); |
|
* // => true |
|
*/ |
|
function isEqualWith(value, other, customizer) { |
|
customizer = typeof customizer == 'function' ? customizer : undefined; |
|
var result = customizer ? customizer(value, other) : undefined; |
|
return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result; |
|
} |
|
|
|
/** |
|
* Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, |
|
* `SyntaxError`, `TypeError`, or `URIError` object. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Lang |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is an error object, else `false`. |
|
* @example |
|
* |
|
* _.isError(new Error); |
|
* // => true |
|
* |
|
* _.isError(Error); |
|
* // => false |
|
*/ |
|
function isError(value) { |
|
if (!isObjectLike(value)) { |
|
return false; |
|
} |
|
var tag = baseGetTag(value); |
|
return tag == errorTag || tag == domExcTag || |
|
(typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value)); |
|
} |
|
|
|
/** |
|
* Checks if `value` is a finite primitive number. |
|
* |
|
* **Note:** This method is based on |
|
* [`Number.isFinite`](https://mdn.io/Number/isFinite). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Lang |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is a finite number, else `false`. |
|
* @example |
|
* |
|
* _.isFinite(3); |
|
* // => true |
|
* |
|
* _.isFinite(Number.MIN_VALUE); |
|
* // => true |
|
* |
|
* _.isFinite(Infinity); |
|
* // => false |
|
* |
|
* _.isFinite('3'); |
|
* // => false |
|
*/ |
|
function isFinite(value) { |
|
return typeof value == 'number' && nativeIsFinite(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) { |
|
if (!isObject(value)) { |
|
return false; |
|
} |
|
// The use of `Object#toString` avoids issues with the `typeof` operator |
|
// in Safari 9 which returns 'object' for typed arrays and other constructors. |
|
var tag = baseGetTag(value); |
|
return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; |
|
} |
|
|
|
/** |
|
* Checks if `value` is an integer. |
|
* |
|
* **Note:** This method is based on |
|
* [`Number.isInteger`](https://mdn.io/Number/isInteger). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Lang |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is an integer, else `false`. |
|
* @example |
|
* |
|
* _.isInteger(3); |
|
* // => true |
|
* |
|
* _.isInteger(Number.MIN_VALUE); |
|
* // => false |
|
* |
|
* _.isInteger(Infinity); |
|
* // => false |
|
* |
|
* _.isInteger('3'); |
|
* // => false |
|
*/ |
|
function isInteger(value) { |
|
return typeof value == 'number' && value == toInteger(value); |
|
} |
|
|
|
/** |
|
* 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 != null && (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 != null && typeof value == 'object'; |
|
} |
|
|
|
/** |
|
* Checks if `value` is classified as a `Map` object. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.3.0 |
|
* @category Lang |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is a map, else `false`. |
|
* @example |
|
* |
|
* _.isMap(new Map); |
|
* // => true |
|
* |
|
* _.isMap(new WeakMap); |
|
* // => false |
|
*/ |
|
var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap; |
|
|
|
/** |
|
* Performs a partial deep comparison between `object` and `source` to |
|
* determine if `object` contains equivalent property values. |
|
* |
|
* **Note:** This method is equivalent to `_.matches` when `source` is |
|
* partially applied. |
|
* |
|
* Partial comparisons will match empty array and empty object `source` |
|
* values against any array or object value, respectively. See `_.isEqual` |
|
* for a list of supported value comparisons. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Lang |
|
* @param {Object} object The object to inspect. |
|
* @param {Object} source The object of property values to match. |
|
* @returns {boolean} Returns `true` if `object` is a match, else `false`. |
|
* @example |
|
* |
|
* var object = { 'a': 1, 'b': 2 }; |
|
* |
|
* _.isMatch(object, { 'b': 2 }); |
|
* // => true |
|
* |
|
* _.isMatch(object, { 'b': 1 }); |
|
* // => false |
|
*/ |
|
function isMatch(object, source) { |
|
return object === source || baseIsMatch(object, source, getMatchData(source)); |
|
} |
|
|
|
/** |
|
* This method is like `_.isMatch` except that it accepts `customizer` which |
|
* is invoked to compare values. If `customizer` returns `undefined`, comparisons |
|
* are handled by the method instead. The `customizer` is invoked with five |
|
* arguments: (objValue, srcValue, index|key, object, source). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Lang |
|
* @param {Object} object The object to inspect. |
|
* @param {Object} source The object of property values to match. |
|
* @param {Function} [customizer] The function to customize comparisons. |
|
* @returns {boolean} Returns `true` if `object` is a match, else `false`. |
|
* @example |
|
* |
|
* function isGreeting(value) { |
|
* return /^h(?:i|ello)$/.test(value); |
|
* } |
|
* |
|
* function customizer(objValue, srcValue) { |
|
* if (isGreeting(objValue) && isGreeting(srcValue)) { |
|
* return true; |
|
* } |
|
* } |
|
* |
|
* var object = { 'greeting': 'hello' }; |
|
* var source = { 'greeting': 'hi' }; |
|
* |
|
* _.isMatchWith(object, source, customizer); |
|
* // => true |
|
*/ |
|
function isMatchWith(object, source, customizer) { |
|
customizer = typeof customizer == 'function' ? customizer : undefined; |
|
return baseIsMatch(object, source, getMatchData(source), customizer); |
|
} |
|
|
|
/** |
|
* Checks if `value` is `NaN`. |
|
* |
|
* **Note:** This method is based on |
|
* [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as |
|
* global [`isNaN`](https://mdn.io/isNaN) which returns `true` for |
|
* `undefined` and other non-number values. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Lang |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. |
|
* @example |
|
* |
|
* _.isNaN(NaN); |
|
* // => true |
|
* |
|
* _.isNaN(new Number(NaN)); |
|
* // => true |
|
* |
|
* isNaN(undefined); |
|
* // => true |
|
* |
|
* _.isNaN(undefined); |
|
* // => false |
|
*/ |
|
function isNaN(value) { |
|
// An `NaN` primitive is the only value that is not equal to itself. |
|
// Perform the `toStringTag` check first to avoid errors with some |
|
// ActiveX objects in IE. |
|
return isNumber(value) && value != +value; |
|
} |
|
|
|
/** |
|
* Checks if `value` is a pristine native function. |
|
* |
|
* **Note:** This method can't reliably detect native functions in the presence |
|
* of the core-js package because core-js circumvents this kind of detection. |
|
* Despite multiple requests, the core-js maintainer has made it clear: any |
|
* attempt to fix the detection will be obstructed. As a result, we're left |
|
* with little choice but to throw an error. Unfortunately, this also affects |
|
* packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill), |
|
* which rely on core-js. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Lang |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is a native function, |
|
* else `false`. |
|
* @example |
|
* |
|
* _.isNative(Array.prototype.push); |
|
* // => true |
|
* |
|
* _.isNative(_); |
|
* // => false |
|
*/ |
|
function isNative(value) { |
|
if (isMaskable(value)) { |
|
throw new Error(CORE_ERROR_TEXT); |
|
} |
|
return baseIsNative(value); |
|
} |
|
|
|
/** |
|
* Checks if `value` is `null`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Lang |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is `null`, else `false`. |
|
* @example |
|
* |
|
* _.isNull(null); |
|
* // => true |
|
* |
|
* _.isNull(void 0); |
|
* // => false |
|
*/ |
|
function isNull(value) { |
|
return value === null; |
|
} |
|
|
|
/** |
|
* Checks if `value` is `null` or `undefined`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Lang |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is nullish, else `false`. |
|
* @example |
|
* |
|
* _.isNil(null); |
|
* // => true |
|
* |
|
* _.isNil(void 0); |
|
* // => true |
|
* |
|
* _.isNil(NaN); |
|
* // => false |
|
*/ |
|
function isNil(value) { |
|
return value == null; |
|
} |
|
|
|
/** |
|
* Checks if `value` is classified as a `Number` primitive or object. |
|
* |
|
* **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are |
|
* classified as numbers, use the `_.isFinite` method. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Lang |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is a number, else `false`. |
|
* @example |
|
* |
|
* _.isNumber(3); |
|
* // => true |
|
* |
|
* _.isNumber(Number.MIN_VALUE); |
|
* // => true |
|
* |
|
* _.isNumber(Infinity); |
|
* // => true |
|
* |
|
* _.isNumber('3'); |
|
* // => false |
|
*/ |
|
function isNumber(value) { |
|
return typeof value == 'number' || |
|
(isObjectLike(value) && baseGetTag(value) == numberTag); |
|
} |
|
|
|
/** |
|
* Checks if `value` is a plain object, that is, an object created by the |
|
* `Object` constructor or one with a `[[Prototype]]` of `null`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.8.0 |
|
* @category Lang |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is a plain object, else `false`. |
|
* @example |
|
* |
|
* function Foo() { |
|
* this.a = 1; |
|
* } |
|
* |
|
* _.isPlainObject(new Foo); |
|
* // => false |
|
* |
|
* _.isPlainObject([1, 2, 3]); |
|
* // => false |
|
* |
|
* _.isPlainObject({ 'x': 0, 'y': 0 }); |
|
* // => true |
|
* |
|
* _.isPlainObject(Object.create(null)); |
|
* // => true |
|
*/ |
|
function isPlainObject(value) { |
|
if (!isObjectLike(value) || baseGetTag(value) != objectTag) { |
|
return false; |
|
} |
|
var proto = getPrototype(value); |
|
if (proto === null) { |
|
return true; |
|
} |
|
var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; |
|
return typeof Ctor == 'function' && Ctor instanceof Ctor && |
|
funcToString.call(Ctor) == objectCtorString; |
|
} |
|
|
|
/** |
|
* Checks if `value` is classified as a `RegExp` object. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.1.0 |
|
* @category Lang |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is a regexp, else `false`. |
|
* @example |
|
* |
|
* _.isRegExp(/abc/); |
|
* // => true |
|
* |
|
* _.isRegExp('/abc/'); |
|
* // => false |
|
*/ |
|
var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp; |
|
|
|
/** |
|
* Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754 |
|
* double precision number which isn't the result of a rounded unsafe integer. |
|
* |
|
* **Note:** This method is based on |
|
* [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Lang |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is a safe integer, else `false`. |
|
* @example |
|
* |
|
* _.isSafeInteger(3); |
|
* // => true |
|
* |
|
* _.isSafeInteger(Number.MIN_VALUE); |
|
* // => false |
|
* |
|
* _.isSafeInteger(Infinity); |
|
* // => false |
|
* |
|
* _.isSafeInteger('3'); |
|
* // => false |
|
*/ |
|
function isSafeInteger(value) { |
|
return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER; |
|
} |
|
|
|
/** |
|
* Checks if `value` is classified as a `Set` object. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.3.0 |
|
* @category Lang |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is a set, else `false`. |
|
* @example |
|
* |
|
* _.isSet(new Set); |
|
* // => true |
|
* |
|
* _.isSet(new WeakSet); |
|
* // => false |
|
*/ |
|
var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet; |
|
|
|
/** |
|
* Checks if `value` is classified as a `String` primitive or object. |
|
* |
|
* @static |
|
* @since 0.1.0 |
|
* @memberOf _ |
|
* @category Lang |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is a string, else `false`. |
|
* @example |
|
* |
|
* _.isString('abc'); |
|
* // => true |
|
* |
|
* _.isString(1); |
|
* // => false |
|
*/ |
|
function isString(value) { |
|
return typeof value == 'string' || |
|
(!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag); |
|
} |
|
|
|
/** |
|
* 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) && baseGetTag(value) == symbolTag); |
|
} |
|
|
|
/** |
|
* Checks if `value` is classified as a typed array. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Lang |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is a typed array, else `false`. |
|
* @example |
|
* |
|
* _.isTypedArray(new Uint8Array); |
|
* // => true |
|
* |
|
* _.isTypedArray([]); |
|
* // => false |
|
*/ |
|
var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; |
|
|
|
/** |
|
* Checks if `value` is `undefined`. |
|
* |
|
* @static |
|
* @since 0.1.0 |
|
* @memberOf _ |
|
* @category Lang |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. |
|
* @example |
|
* |
|
* _.isUndefined(void 0); |
|
* // => true |
|
* |
|
* _.isUndefined(null); |
|
* // => false |
|
*/ |
|
function isUndefined(value) { |
|
return value === undefined; |
|
} |
|
|
|
/** |
|
* Checks if `value` is classified as a `WeakMap` object. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.3.0 |
|
* @category Lang |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is a weak map, else `false`. |
|
* @example |
|
* |
|
* _.isWeakMap(new WeakMap); |
|
* // => true |
|
* |
|
* _.isWeakMap(new Map); |
|
* // => false |
|
*/ |
|
function isWeakMap(value) { |
|
return isObjectLike(value) && getTag(value) == weakMapTag; |
|
} |
|
|
|
/** |
|
* Checks if `value` is classified as a `WeakSet` object. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.3.0 |
|
* @category Lang |
|
* @param {*} value The value to check. |
|
* @returns {boolean} Returns `true` if `value` is a weak set, else `false`. |
|
* @example |
|
* |
|
* _.isWeakSet(new WeakSet); |
|
* // => true |
|
* |
|
* _.isWeakSet(new Set); |
|
* // => false |
|
*/ |
|
function isWeakSet(value) { |
|
return isObjectLike(value) && baseGetTag(value) == weakSetTag; |
|
} |
|
|
|
/** |
|
* Checks if `value` is less than `other`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.9.0 |
|
* @category Lang |
|
* @param {*} value The value to compare. |
|
* @param {*} other The other value to compare. |
|
* @returns {boolean} Returns `true` if `value` is less than `other`, |
|
* else `false`. |
|
* @see _.gt |
|
* @example |
|
* |
|
* _.lt(1, 3); |
|
* // => true |
|
* |
|
* _.lt(3, 3); |
|
* // => false |
|
* |
|
* _.lt(3, 1); |
|
* // => false |
|
*/ |
|
var lt = createRelationalOperation(baseLt); |
|
|
|
/** |
|
* Checks if `value` is less than or equal to `other`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.9.0 |
|
* @category Lang |
|
* @param {*} value The value to compare. |
|
* @param {*} other The other value to compare. |
|
* @returns {boolean} Returns `true` if `value` is less than or equal to |
|
* `other`, else `false`. |
|
* @see _.gte |
|
* @example |
|
* |
|
* _.lte(1, 3); |
|
* // => true |
|
* |
|
* _.lte(3, 3); |
|
* // => true |
|
* |
|
* _.lte(3, 1); |
|
* // => false |
|
*/ |
|
var lte = createRelationalOperation(function(value, other) { |
|
return value <= other; |
|
}); |
|
|
|
/** |
|
* Converts `value` to an array. |
|
* |
|
* @static |
|
* @since 0.1.0 |
|
* @memberOf _ |
|
* @category Lang |
|
* @param {*} value The value to convert. |
|
* @returns {Array} Returns the converted array. |
|
* @example |
|
* |
|
* _.toArray({ 'a': 1, 'b': 2 }); |
|
* // => [1, 2] |
|
* |
|
* _.toArray('abc'); |
|
* // => ['a', 'b', 'c'] |
|
* |
|
* _.toArray(1); |
|
* // => [] |
|
* |
|
* _.toArray(null); |
|
* // => [] |
|
*/ |
|
function toArray(value) { |
|
if (!value) { |
|
return []; |
|
} |
|
if (isArrayLike(value)) { |
|
return isString(value) ? stringToArray(value) : copyArray(value); |
|
} |
|
if (symIterator && value[symIterator]) { |
|
return iteratorToArray(value[symIterator]()); |
|
} |
|
var tag = getTag(value), |
|
func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values); |
|
|
|
return func(value); |
|
} |
|
|
|
/** |
|
* 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 an integer suitable for use as the length of an |
|
* array-like object. |
|
* |
|
* **Note:** This method is 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 convert. |
|
* @returns {number} Returns the converted integer. |
|
* @example |
|
* |
|
* _.toLength(3.2); |
|
* // => 3 |
|
* |
|
* _.toLength(Number.MIN_VALUE); |
|
* // => 0 |
|
* |
|
* _.toLength(Infinity); |
|
* // => 4294967295 |
|
* |
|
* _.toLength('3.2'); |
|
* // => 3 |
|
*/ |
|
function toLength(value) { |
|
return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 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); |
|
} |
|
|
|
/** |
|
* Converts `value` to a plain object flattening inherited enumerable string |
|
* keyed properties of `value` to own properties of the plain object. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Lang |
|
* @param {*} value The value to convert. |
|
* @returns {Object} Returns the converted plain object. |
|
* @example |
|
* |
|
* function Foo() { |
|
* this.b = 2; |
|
* } |
|
* |
|
* Foo.prototype.c = 3; |
|
* |
|
* _.assign({ 'a': 1 }, new Foo); |
|
* // => { 'a': 1, 'b': 2 } |
|
* |
|
* _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); |
|
* // => { 'a': 1, 'b': 2, 'c': 3 } |
|
*/ |
|
function toPlainObject(value) { |
|
return copyObject(value, keysIn(value)); |
|
} |
|
|
|
/** |
|
* Converts `value` to a safe integer. A safe integer can be compared and |
|
* represented correctly. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Lang |
|
* @param {*} value The value to convert. |
|
* @returns {number} Returns the converted integer. |
|
* @example |
|
* |
|
* _.toSafeInteger(3.2); |
|
* // => 3 |
|
* |
|
* _.toSafeInteger(Number.MIN_VALUE); |
|
* // => 0 |
|
* |
|
* _.toSafeInteger(Infinity); |
|
* // => 9007199254740991 |
|
* |
|
* _.toSafeInteger('3.2'); |
|
* // => 3 |
|
*/ |
|
function toSafeInteger(value) { |
|
return value |
|
? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER) |
|
: (value === 0 ? value : 0); |
|
} |
|
|
|
/** |
|
* Converts `value` to a string. An empty string is returned for `null` |
|
* and `undefined` values. The sign of `-0` is preserved. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Lang |
|
* @param {*} value The value to convert. |
|
* @returns {string} Returns the converted string. |
|
* @example |
|
* |
|
* _.toString(null); |
|
* // => '' |
|
* |
|
* _.toString(-0); |
|
* // => '-0' |
|
* |
|
* _.toString([1, 2, 3]); |
|
* // => '1,2,3' |
|
*/ |
|
function toString(value) { |
|
return value == null ? '' : baseToString(value); |
|
} |
|
|
|
/*------------------------------------------------------------------------*/ |
|
|
|
/** |
|
* Assigns own enumerable string keyed properties of source objects to the |
|
* destination object. Source objects are applied from left to right. |
|
* Subsequent sources overwrite property assignments of previous sources. |
|
* |
|
* **Note:** This method mutates `object` and is loosely based on |
|
* [`Object.assign`](https://mdn.io/Object/assign). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.10.0 |
|
* @category Object |
|
* @param {Object} object The destination object. |
|
* @param {...Object} [sources] The source objects. |
|
* @returns {Object} Returns `object`. |
|
* @see _.assignIn |
|
* @example |
|
* |
|
* function Foo() { |
|
* this.a = 1; |
|
* } |
|
* |
|
* function Bar() { |
|
* this.c = 3; |
|
* } |
|
* |
|
* Foo.prototype.b = 2; |
|
* Bar.prototype.d = 4; |
|
* |
|
* _.assign({ 'a': 0 }, new Foo, new Bar); |
|
* // => { 'a': 1, 'c': 3 } |
|
*/ |
|
var assign = createAssigner(function(object, source) { |
|
if (isPrototype(source) || isArrayLike(source)) { |
|
copyObject(source, keys(source), object); |
|
return; |
|
} |
|
for (var key in source) { |
|
if (hasOwnProperty.call(source, key)) { |
|
assignValue(object, key, source[key]); |
|
} |
|
} |
|
}); |
|
|
|
/** |
|
* This method is like `_.assign` except that it iterates over own and |
|
* inherited source properties. |
|
* |
|
* **Note:** This method mutates `object`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @alias extend |
|
* @category Object |
|
* @param {Object} object The destination object. |
|
* @param {...Object} [sources] The source objects. |
|
* @returns {Object} Returns `object`. |
|
* @see _.assign |
|
* @example |
|
* |
|
* function Foo() { |
|
* this.a = 1; |
|
* } |
|
* |
|
* function Bar() { |
|
* this.c = 3; |
|
* } |
|
* |
|
* Foo.prototype.b = 2; |
|
* Bar.prototype.d = 4; |
|
* |
|
* _.assignIn({ 'a': 0 }, new Foo, new Bar); |
|
* // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 } |
|
*/ |
|
var assignIn = createAssigner(function(object, source) { |
|
copyObject(source, keysIn(source), object); |
|
}); |
|
|
|
/** |
|
* This method is like `_.assignIn` except that it accepts `customizer` |
|
* which is invoked to produce the assigned values. If `customizer` returns |
|
* `undefined`, assignment is handled by the method instead. The `customizer` |
|
* is invoked with five arguments: (objValue, srcValue, key, object, source). |
|
* |
|
* **Note:** This method mutates `object`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @alias extendWith |
|
* @category Object |
|
* @param {Object} object The destination object. |
|
* @param {...Object} sources The source objects. |
|
* @param {Function} [customizer] The function to customize assigned values. |
|
* @returns {Object} Returns `object`. |
|
* @see _.assignWith |
|
* @example |
|
* |
|
* function customizer(objValue, srcValue) { |
|
* return _.isUndefined(objValue) ? srcValue : objValue; |
|
* } |
|
* |
|
* var defaults = _.partialRight(_.assignInWith, customizer); |
|
* |
|
* defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); |
|
* // => { 'a': 1, 'b': 2 } |
|
*/ |
|
var assignInWith = createAssigner(function(object, source, srcIndex, customizer) { |
|
copyObject(source, keysIn(source), object, customizer); |
|
}); |
|
|
|
/** |
|
* This method is like `_.assign` except that it accepts `customizer` |
|
* which is invoked to produce the assigned values. If `customizer` returns |
|
* `undefined`, assignment is handled by the method instead. The `customizer` |
|
* is invoked with five arguments: (objValue, srcValue, key, object, source). |
|
* |
|
* **Note:** This method mutates `object`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Object |
|
* @param {Object} object The destination object. |
|
* @param {...Object} sources The source objects. |
|
* @param {Function} [customizer] The function to customize assigned values. |
|
* @returns {Object} Returns `object`. |
|
* @see _.assignInWith |
|
* @example |
|
* |
|
* function customizer(objValue, srcValue) { |
|
* return _.isUndefined(objValue) ? srcValue : objValue; |
|
* } |
|
* |
|
* var defaults = _.partialRight(_.assignWith, customizer); |
|
* |
|
* defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); |
|
* // => { 'a': 1, 'b': 2 } |
|
*/ |
|
var assignWith = createAssigner(function(object, source, srcIndex, customizer) { |
|
copyObject(source, keys(source), object, customizer); |
|
}); |
|
|
|
/** |
|
* Creates an array of values corresponding to `paths` of `object`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 1.0.0 |
|
* @category Object |
|
* @param {Object} object The object to iterate over. |
|
* @param {...(string|string[])} [paths] The property paths to pick. |
|
* @returns {Array} Returns the picked values. |
|
* @example |
|
* |
|
* var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; |
|
* |
|
* _.at(object, ['a[0].b.c', 'a[1]']); |
|
* // => [3, 4] |
|
*/ |
|
var at = flatRest(baseAt); |
|
|
|
/** |
|
* Creates an object that inherits from the `prototype` object. If a |
|
* `properties` object is given, its own enumerable string keyed properties |
|
* are assigned to the created object. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 2.3.0 |
|
* @category Object |
|
* @param {Object} prototype The object to inherit from. |
|
* @param {Object} [properties] The properties to assign to the object. |
|
* @returns {Object} Returns the new object. |
|
* @example |
|
* |
|
* function Shape() { |
|
* this.x = 0; |
|
* this.y = 0; |
|
* } |
|
* |
|
* function Circle() { |
|
* Shape.call(this); |
|
* } |
|
* |
|
* Circle.prototype = _.create(Shape.prototype, { |
|
* 'constructor': Circle |
|
* }); |
|
* |
|
* var circle = new Circle; |
|
* circle instanceof Circle; |
|
* // => true |
|
* |
|
* circle instanceof Shape; |
|
* // => true |
|
*/ |
|
function create(prototype, properties) { |
|
var result = baseCreate(prototype); |
|
return properties == null ? result : baseAssign(result, properties); |
|
} |
|
|
|
/** |
|
* Assigns own and inherited enumerable string keyed properties of source |
|
* objects to the destination object for all destination properties that |
|
* resolve to `undefined`. Source objects are applied from left to right. |
|
* Once a property is set, additional values of the same property are ignored. |
|
* |
|
* **Note:** This method mutates `object`. |
|
* |
|
* @static |
|
* @since 0.1.0 |
|
* @memberOf _ |
|
* @category Object |
|
* @param {Object} object The destination object. |
|
* @param {...Object} [sources] The source objects. |
|
* @returns {Object} Returns `object`. |
|
* @see _.defaultsDeep |
|
* @example |
|
* |
|
* _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); |
|
* // => { 'a': 1, 'b': 2 } |
|
*/ |
|
var defaults = baseRest(function(object, sources) { |
|
object = Object(object); |
|
|
|
var index = -1; |
|
var length = sources.length; |
|
var guard = length > 2 ? sources[2] : undefined; |
|
|
|
if (guard && isIterateeCall(sources[0], sources[1], guard)) { |
|
length = 1; |
|
} |
|
|
|
while (++index < length) { |
|
var source = sources[index]; |
|
var props = keysIn(source); |
|
var propsIndex = -1; |
|
var propsLength = props.length; |
|
|
|
while (++propsIndex < propsLength) { |
|
var key = props[propsIndex]; |
|
var value = object[key]; |
|
|
|
if (value === undefined || |
|
(eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { |
|
object[key] = source[key]; |
|
} |
|
} |
|
} |
|
|
|
return object; |
|
}); |
|
|
|
/** |
|
* This method is like `_.defaults` except that it recursively assigns |
|
* default properties. |
|
* |
|
* **Note:** This method mutates `object`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.10.0 |
|
* @category Object |
|
* @param {Object} object The destination object. |
|
* @param {...Object} [sources] The source objects. |
|
* @returns {Object} Returns `object`. |
|
* @see _.defaults |
|
* @example |
|
* |
|
* _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } }); |
|
* // => { 'a': { 'b': 2, 'c': 3 } } |
|
*/ |
|
var defaultsDeep = baseRest(function(args) { |
|
args.push(undefined, customDefaultsMerge); |
|
return apply(mergeWith, undefined, args); |
|
}); |
|
|
|
/** |
|
* This method is like `_.find` except that it returns the key of the first |
|
* element `predicate` returns truthy for instead of the element itself. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 1.1.0 |
|
* @category Object |
|
* @param {Object} object The object to inspect. |
|
* @param {Function} [predicate=_.identity] The function invoked per iteration. |
|
* @returns {string|undefined} Returns the key of the matched element, |
|
* else `undefined`. |
|
* @example |
|
* |
|
* var users = { |
|
* 'barney': { 'age': 36, 'active': true }, |
|
* 'fred': { 'age': 40, 'active': false }, |
|
* 'pebbles': { 'age': 1, 'active': true } |
|
* }; |
|
* |
|
* _.findKey(users, function(o) { return o.age < 40; }); |
|
* // => 'barney' (iteration order is not guaranteed) |
|
* |
|
* // The `_.matches` iteratee shorthand. |
|
* _.findKey(users, { 'age': 1, 'active': true }); |
|
* // => 'pebbles' |
|
* |
|
* // The `_.matchesProperty` iteratee shorthand. |
|
* _.findKey(users, ['active', false]); |
|
* // => 'fred' |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.findKey(users, 'active'); |
|
* // => 'barney' |
|
*/ |
|
function findKey(object, predicate) { |
|
return baseFindKey(object, getIteratee(predicate, 3), baseForOwn); |
|
} |
|
|
|
/** |
|
* This method is like `_.findKey` except that it iterates over elements of |
|
* a collection in the opposite order. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 2.0.0 |
|
* @category Object |
|
* @param {Object} object The object to inspect. |
|
* @param {Function} [predicate=_.identity] The function invoked per iteration. |
|
* @returns {string|undefined} Returns the key of the matched element, |
|
* else `undefined`. |
|
* @example |
|
* |
|
* var users = { |
|
* 'barney': { 'age': 36, 'active': true }, |
|
* 'fred': { 'age': 40, 'active': false }, |
|
* 'pebbles': { 'age': 1, 'active': true } |
|
* }; |
|
* |
|
* _.findLastKey(users, function(o) { return o.age < 40; }); |
|
* // => returns 'pebbles' assuming `_.findKey` returns 'barney' |
|
* |
|
* // The `_.matches` iteratee shorthand. |
|
* _.findLastKey(users, { 'age': 36, 'active': true }); |
|
* // => 'barney' |
|
* |
|
* // The `_.matchesProperty` iteratee shorthand. |
|
* _.findLastKey(users, ['active', false]); |
|
* // => 'fred' |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.findLastKey(users, 'active'); |
|
* // => 'pebbles' |
|
*/ |
|
function findLastKey(object, predicate) { |
|
return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight); |
|
} |
|
|
|
/** |
|
* Iterates over own and inherited enumerable string keyed properties of an |
|
* object and invokes `iteratee` for each property. The iteratee is invoked |
|
* with three arguments: (value, key, object). Iteratee functions may exit |
|
* iteration early by explicitly returning `false`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.3.0 |
|
* @category Object |
|
* @param {Object} object The object to iterate over. |
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration. |
|
* @returns {Object} Returns `object`. |
|
* @see _.forInRight |
|
* @example |
|
* |
|
* function Foo() { |
|
* this.a = 1; |
|
* this.b = 2; |
|
* } |
|
* |
|
* Foo.prototype.c = 3; |
|
* |
|
* _.forIn(new Foo, function(value, key) { |
|
* console.log(key); |
|
* }); |
|
* // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). |
|
*/ |
|
function forIn(object, iteratee) { |
|
return object == null |
|
? object |
|
: baseFor(object, getIteratee(iteratee, 3), keysIn); |
|
} |
|
|
|
/** |
|
* This method is like `_.forIn` except that it iterates over properties of |
|
* `object` in the opposite order. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 2.0.0 |
|
* @category Object |
|
* @param {Object} object The object to iterate over. |
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration. |
|
* @returns {Object} Returns `object`. |
|
* @see _.forIn |
|
* @example |
|
* |
|
* function Foo() { |
|
* this.a = 1; |
|
* this.b = 2; |
|
* } |
|
* |
|
* Foo.prototype.c = 3; |
|
* |
|
* _.forInRight(new Foo, function(value, key) { |
|
* console.log(key); |
|
* }); |
|
* // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'. |
|
*/ |
|
function forInRight(object, iteratee) { |
|
return object == null |
|
? object |
|
: baseForRight(object, getIteratee(iteratee, 3), keysIn); |
|
} |
|
|
|
/** |
|
* Iterates over own enumerable string keyed properties of an object and |
|
* invokes `iteratee` for each property. The iteratee is invoked with three |
|
* arguments: (value, key, object). Iteratee functions may exit iteration |
|
* early by explicitly returning `false`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.3.0 |
|
* @category Object |
|
* @param {Object} object The object to iterate over. |
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration. |
|
* @returns {Object} Returns `object`. |
|
* @see _.forOwnRight |
|
* @example |
|
* |
|
* function Foo() { |
|
* this.a = 1; |
|
* this.b = 2; |
|
* } |
|
* |
|
* Foo.prototype.c = 3; |
|
* |
|
* _.forOwn(new Foo, function(value, key) { |
|
* console.log(key); |
|
* }); |
|
* // => Logs 'a' then 'b' (iteration order is not guaranteed). |
|
*/ |
|
function forOwn(object, iteratee) { |
|
return object && baseForOwn(object, getIteratee(iteratee, 3)); |
|
} |
|
|
|
/** |
|
* This method is like `_.forOwn` except that it iterates over properties of |
|
* `object` in the opposite order. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 2.0.0 |
|
* @category Object |
|
* @param {Object} object The object to iterate over. |
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration. |
|
* @returns {Object} Returns `object`. |
|
* @see _.forOwn |
|
* @example |
|
* |
|
* function Foo() { |
|
* this.a = 1; |
|
* this.b = 2; |
|
* } |
|
* |
|
* Foo.prototype.c = 3; |
|
* |
|
* _.forOwnRight(new Foo, function(value, key) { |
|
* console.log(key); |
|
* }); |
|
* // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'. |
|
*/ |
|
function forOwnRight(object, iteratee) { |
|
return object && baseForOwnRight(object, getIteratee(iteratee, 3)); |
|
} |
|
|
|
/** |
|
* Creates an array of function property names from own enumerable properties |
|
* of `object`. |
|
* |
|
* @static |
|
* @since 0.1.0 |
|
* @memberOf _ |
|
* @category Object |
|
* @param {Object} object The object to inspect. |
|
* @returns {Array} Returns the function names. |
|
* @see _.functionsIn |
|
* @example |
|
* |
|
* function Foo() { |
|
* this.a = _.constant('a'); |
|
* this.b = _.constant('b'); |
|
* } |
|
* |
|
* Foo.prototype.c = _.constant('c'); |
|
* |
|
* _.functions(new Foo); |
|
* // => ['a', 'b'] |
|
*/ |
|
function functions(object) { |
|
return object == null ? [] : baseFunctions(object, keys(object)); |
|
} |
|
|
|
/** |
|
* Creates an array of function property names from own and inherited |
|
* enumerable properties of `object`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Object |
|
* @param {Object} object The object to inspect. |
|
* @returns {Array} Returns the function names. |
|
* @see _.functions |
|
* @example |
|
* |
|
* function Foo() { |
|
* this.a = _.constant('a'); |
|
* this.b = _.constant('b'); |
|
* } |
|
* |
|
* Foo.prototype.c = _.constant('c'); |
|
* |
|
* _.functionsIn(new Foo); |
|
* // => ['a', 'b', 'c'] |
|
*/ |
|
function functionsIn(object) { |
|
return object == null ? [] : baseFunctions(object, keysIn(object)); |
|
} |
|
|
|
/** |
|
* Gets the value at `path` of `object`. If the resolved value is |
|
* `undefined`, the `defaultValue` is returned in its place. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.7.0 |
|
* @category Object |
|
* @param {Object} object The object to query. |
|
* @param {Array|string} path The path of the property to get. |
|
* @param {*} [defaultValue] The value returned for `undefined` resolved values. |
|
* @returns {*} Returns the resolved value. |
|
* @example |
|
* |
|
* var object = { 'a': [{ 'b': { 'c': 3 } }] }; |
|
* |
|
* _.get(object, 'a[0].b.c'); |
|
* // => 3 |
|
* |
|
* _.get(object, ['a', '0', 'b', 'c']); |
|
* // => 3 |
|
* |
|
* _.get(object, 'a.b.c', 'default'); |
|
* // => 'default' |
|
*/ |
|
function get(object, path, defaultValue) { |
|
var result = object == null ? undefined : baseGet(object, path); |
|
return result === undefined ? defaultValue : result; |
|
} |
|
|
|
/** |
|
* Checks if `path` is a direct property of `object`. |
|
* |
|
* @static |
|
* @since 0.1.0 |
|
* @memberOf _ |
|
* @category Object |
|
* @param {Object} object The object to query. |
|
* @param {Array|string} path The path to check. |
|
* @returns {boolean} Returns `true` if `path` exists, else `false`. |
|
* @example |
|
* |
|
* var object = { 'a': { 'b': 2 } }; |
|
* var other = _.create({ 'a': _.create({ 'b': 2 }) }); |
|
* |
|
* _.has(object, 'a'); |
|
* // => true |
|
* |
|
* _.has(object, 'a.b'); |
|
* // => true |
|
* |
|
* _.has(object, ['a', 'b']); |
|
* // => true |
|
* |
|
* _.has(other, 'a'); |
|
* // => false |
|
*/ |
|
function has(object, path) { |
|
return object != null && hasPath(object, path, baseHas); |
|
} |
|
|
|
/** |
|
* Checks if `path` is a direct or inherited property of `object`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Object |
|
* @param {Object} object The object to query. |
|
* @param {Array|string} path The path to check. |
|
* @returns {boolean} Returns `true` if `path` exists, else `false`. |
|
* @example |
|
* |
|
* var object = _.create({ 'a': _.create({ 'b': 2 }) }); |
|
* |
|
* _.hasIn(object, 'a'); |
|
* // => true |
|
* |
|
* _.hasIn(object, 'a.b'); |
|
* // => true |
|
* |
|
* _.hasIn(object, ['a', 'b']); |
|
* // => true |
|
* |
|
* _.hasIn(object, 'b'); |
|
* // => false |
|
*/ |
|
function hasIn(object, path) { |
|
return object != null && hasPath(object, path, baseHasIn); |
|
} |
|
|
|
/** |
|
* Creates an object composed of the inverted keys and values of `object`. |
|
* If `object` contains duplicate values, subsequent values overwrite |
|
* property assignments of previous values. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.7.0 |
|
* @category Object |
|
* @param {Object} object The object to invert. |
|
* @returns {Object} Returns the new inverted object. |
|
* @example |
|
* |
|
* var object = { 'a': 1, 'b': 2, 'c': 1 }; |
|
* |
|
* _.invert(object); |
|
* // => { '1': 'c', '2': 'b' } |
|
*/ |
|
var invert = createInverter(function(result, value, key) { |
|
if (value != null && |
|
typeof value.toString != 'function') { |
|
value = nativeObjectToString.call(value); |
|
} |
|
|
|
result[value] = key; |
|
}, constant(identity)); |
|
|
|
/** |
|
* This method is like `_.invert` except that the inverted object is generated |
|
* from the results of running each element of `object` thru `iteratee`. The |
|
* corresponding inverted value of each inverted key is an array of keys |
|
* responsible for generating the inverted value. The iteratee is invoked |
|
* with one argument: (value). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.1.0 |
|
* @category Object |
|
* @param {Object} object The object to invert. |
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element. |
|
* @returns {Object} Returns the new inverted object. |
|
* @example |
|
* |
|
* var object = { 'a': 1, 'b': 2, 'c': 1 }; |
|
* |
|
* _.invertBy(object); |
|
* // => { '1': ['a', 'c'], '2': ['b'] } |
|
* |
|
* _.invertBy(object, function(value) { |
|
* return 'group' + value; |
|
* }); |
|
* // => { 'group1': ['a', 'c'], 'group2': ['b'] } |
|
*/ |
|
var invertBy = createInverter(function(result, value, key) { |
|
if (value != null && |
|
typeof value.toString != 'function') { |
|
value = nativeObjectToString.call(value); |
|
} |
|
|
|
if (hasOwnProperty.call(result, value)) { |
|
result[value].push(key); |
|
} else { |
|
result[value] = [key]; |
|
} |
|
}, getIteratee); |
|
|
|
/** |
|
* Invokes the method at `path` of `object`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Object |
|
* @param {Object} object The object to query. |
|
* @param {Array|string} path The path of the method to invoke. |
|
* @param {...*} [args] The arguments to invoke the method with. |
|
* @returns {*} Returns the result of the invoked method. |
|
* @example |
|
* |
|
* var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] }; |
|
* |
|
* _.invoke(object, 'a[0].b.c.slice', 1, 3); |
|
* // => [2, 3] |
|
*/ |
|
var invoke = baseRest(baseInvoke); |
|
|
|
/** |
|
* Creates an array of the own enumerable property names of `object`. |
|
* |
|
* **Note:** Non-object values are coerced to objects. See the |
|
* [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) |
|
* for more details. |
|
* |
|
* @static |
|
* @since 0.1.0 |
|
* @memberOf _ |
|
* @category Object |
|
* @param {Object} object The object to query. |
|
* @returns {Array} Returns the array of property names. |
|
* @example |
|
* |
|
* function Foo() { |
|
* this.a = 1; |
|
* this.b = 2; |
|
* } |
|
* |
|
* Foo.prototype.c = 3; |
|
* |
|
* _.keys(new Foo); |
|
* // => ['a', 'b'] (iteration order is not guaranteed) |
|
* |
|
* _.keys('hi'); |
|
* // => ['0', '1'] |
|
*/ |
|
function keys(object) { |
|
return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); |
|
} |
|
|
|
/** |
|
* Creates an array of the own and inherited enumerable property names of `object`. |
|
* |
|
* **Note:** Non-object values are coerced to objects. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Object |
|
* @param {Object} object The object to query. |
|
* @returns {Array} Returns the array of property names. |
|
* @example |
|
* |
|
* function Foo() { |
|
* this.a = 1; |
|
* this.b = 2; |
|
* } |
|
* |
|
* Foo.prototype.c = 3; |
|
* |
|
* _.keysIn(new Foo); |
|
* // => ['a', 'b', 'c'] (iteration order is not guaranteed) |
|
*/ |
|
function keysIn(object) { |
|
return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); |
|
} |
|
|
|
/** |
|
* The opposite of `_.mapValues`; this method creates an object with the |
|
* same values as `object` and keys generated by running each own enumerable |
|
* string keyed property of `object` thru `iteratee`. The iteratee is invoked |
|
* with three arguments: (value, key, object). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.8.0 |
|
* @category Object |
|
* @param {Object} object The object to iterate over. |
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration. |
|
* @returns {Object} Returns the new mapped object. |
|
* @see _.mapValues |
|
* @example |
|
* |
|
* _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { |
|
* return key + value; |
|
* }); |
|
* // => { 'a1': 1, 'b2': 2 } |
|
*/ |
|
function mapKeys(object, iteratee) { |
|
var result = {}; |
|
iteratee = getIteratee(iteratee, 3); |
|
|
|
baseForOwn(object, function(value, key, object) { |
|
baseAssignValue(result, iteratee(value, key, object), value); |
|
}); |
|
return result; |
|
} |
|
|
|
/** |
|
* Creates an object with the same keys as `object` and values generated |
|
* by running each own enumerable string keyed property of `object` thru |
|
* `iteratee`. The iteratee is invoked with three arguments: |
|
* (value, key, object). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 2.4.0 |
|
* @category Object |
|
* @param {Object} object The object to iterate over. |
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration. |
|
* @returns {Object} Returns the new mapped object. |
|
* @see _.mapKeys |
|
* @example |
|
* |
|
* var users = { |
|
* 'fred': { 'user': 'fred', 'age': 40 }, |
|
* 'pebbles': { 'user': 'pebbles', 'age': 1 } |
|
* }; |
|
* |
|
* _.mapValues(users, function(o) { return o.age; }); |
|
* // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.mapValues(users, 'age'); |
|
* // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) |
|
*/ |
|
function mapValues(object, iteratee) { |
|
var result = {}; |
|
iteratee = getIteratee(iteratee, 3); |
|
|
|
baseForOwn(object, function(value, key, object) { |
|
baseAssignValue(result, key, iteratee(value, key, object)); |
|
}); |
|
return result; |
|
} |
|
|
|
/** |
|
* This method is like `_.assign` except that it recursively merges own and |
|
* inherited enumerable string keyed properties of source objects into the |
|
* destination object. Source properties that resolve to `undefined` are |
|
* skipped if a destination value exists. Array and plain object properties |
|
* are merged recursively. Other objects and value types are overridden by |
|
* assignment. Source objects are applied from left to right. Subsequent |
|
* sources overwrite property assignments of previous sources. |
|
* |
|
* **Note:** This method mutates `object`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.5.0 |
|
* @category Object |
|
* @param {Object} object The destination object. |
|
* @param {...Object} [sources] The source objects. |
|
* @returns {Object} Returns `object`. |
|
* @example |
|
* |
|
* var object = { |
|
* 'a': [{ 'b': 2 }, { 'd': 4 }] |
|
* }; |
|
* |
|
* var other = { |
|
* 'a': [{ 'c': 3 }, { 'e': 5 }] |
|
* }; |
|
* |
|
* _.merge(object, other); |
|
* // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } |
|
*/ |
|
var merge = createAssigner(function(object, source, srcIndex) { |
|
baseMerge(object, source, srcIndex); |
|
}); |
|
|
|
/** |
|
* This method is like `_.merge` except that it accepts `customizer` which |
|
* is invoked to produce the merged values of the destination and source |
|
* properties. If `customizer` returns `undefined`, merging is handled by the |
|
* method instead. The `customizer` is invoked with six arguments: |
|
* (objValue, srcValue, key, object, source, stack). |
|
* |
|
* **Note:** This method mutates `object`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Object |
|
* @param {Object} object The destination object. |
|
* @param {...Object} sources The source objects. |
|
* @param {Function} customizer The function to customize assigned values. |
|
* @returns {Object} Returns `object`. |
|
* @example |
|
* |
|
* function customizer(objValue, srcValue) { |
|
* if (_.isArray(objValue)) { |
|
* return objValue.concat(srcValue); |
|
* } |
|
* } |
|
* |
|
* var object = { 'a': [1], 'b': [2] }; |
|
* var other = { 'a': [3], 'b': [4] }; |
|
* |
|
* _.mergeWith(object, other, customizer); |
|
* // => { 'a': [1, 3], 'b': [2, 4] } |
|
*/ |
|
var mergeWith = createAssigner(function(object, source, srcIndex, customizer) { |
|
baseMerge(object, source, srcIndex, customizer); |
|
}); |
|
|
|
/** |
|
* The opposite of `_.pick`; this method creates an object composed of the |
|
* own and inherited enumerable property paths of `object` that are not omitted. |
|
* |
|
* **Note:** This method is considerably slower than `_.pick`. |
|
* |
|
* @static |
|
* @since 0.1.0 |
|
* @memberOf _ |
|
* @category Object |
|
* @param {Object} object The source object. |
|
* @param {...(string|string[])} [paths] The property paths to omit. |
|
* @returns {Object} Returns the new object. |
|
* @example |
|
* |
|
* var object = { 'a': 1, 'b': '2', 'c': 3 }; |
|
* |
|
* _.omit(object, ['a', 'c']); |
|
* // => { 'b': '2' } |
|
*/ |
|
var omit = flatRest(function(object, paths) { |
|
var result = {}; |
|
if (object == null) { |
|
return result; |
|
} |
|
var isDeep = false; |
|
paths = arrayMap(paths, function(path) { |
|
path = castPath(path, object); |
|
isDeep || (isDeep = path.length > 1); |
|
return path; |
|
}); |
|
copyObject(object, getAllKeysIn(object), result); |
|
if (isDeep) { |
|
result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone); |
|
} |
|
var length = paths.length; |
|
while (length--) { |
|
baseUnset(result, paths[length]); |
|
} |
|
return result; |
|
}); |
|
|
|
/** |
|
* The opposite of `_.pickBy`; this method creates an object composed of |
|
* the own and inherited enumerable string keyed properties of `object` that |
|
* `predicate` doesn't return truthy for. The predicate is invoked with two |
|
* arguments: (value, key). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Object |
|
* @param {Object} object The source object. |
|
* @param {Function} [predicate=_.identity] The function invoked per property. |
|
* @returns {Object} Returns the new object. |
|
* @example |
|
* |
|
* var object = { 'a': 1, 'b': '2', 'c': 3 }; |
|
* |
|
* _.omitBy(object, _.isNumber); |
|
* // => { 'b': '2' } |
|
*/ |
|
function omitBy(object, predicate) { |
|
return pickBy(object, negate(getIteratee(predicate))); |
|
} |
|
|
|
/** |
|
* Creates an object composed of the picked `object` properties. |
|
* |
|
* @static |
|
* @since 0.1.0 |
|
* @memberOf _ |
|
* @category Object |
|
* @param {Object} object The source object. |
|
* @param {...(string|string[])} [paths] The property paths to pick. |
|
* @returns {Object} Returns the new object. |
|
* @example |
|
* |
|
* var object = { 'a': 1, 'b': '2', 'c': 3 }; |
|
* |
|
* _.pick(object, ['a', 'c']); |
|
* // => { 'a': 1, 'c': 3 } |
|
*/ |
|
var pick = flatRest(function(object, paths) { |
|
return object == null ? {} : basePick(object, paths); |
|
}); |
|
|
|
/** |
|
* Creates an object composed of the `object` properties `predicate` returns |
|
* truthy for. The predicate is invoked with two arguments: (value, key). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Object |
|
* @param {Object} object The source object. |
|
* @param {Function} [predicate=_.identity] The function invoked per property. |
|
* @returns {Object} Returns the new object. |
|
* @example |
|
* |
|
* var object = { 'a': 1, 'b': '2', 'c': 3 }; |
|
* |
|
* _.pickBy(object, _.isNumber); |
|
* // => { 'a': 1, 'c': 3 } |
|
*/ |
|
function pickBy(object, predicate) { |
|
if (object == null) { |
|
return {}; |
|
} |
|
var props = arrayMap(getAllKeysIn(object), function(prop) { |
|
return [prop]; |
|
}); |
|
predicate = getIteratee(predicate); |
|
return basePickBy(object, props, function(value, path) { |
|
return predicate(value, path[0]); |
|
}); |
|
} |
|
|
|
/** |
|
* This method is like `_.get` except that if the resolved value is a |
|
* function it's invoked with the `this` binding of its parent object and |
|
* its result is returned. |
|
* |
|
* @static |
|
* @since 0.1.0 |
|
* @memberOf _ |
|
* @category Object |
|
* @param {Object} object The object to query. |
|
* @param {Array|string} path The path of the property to resolve. |
|
* @param {*} [defaultValue] The value returned for `undefined` resolved values. |
|
* @returns {*} Returns the resolved value. |
|
* @example |
|
* |
|
* var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; |
|
* |
|
* _.result(object, 'a[0].b.c1'); |
|
* // => 3 |
|
* |
|
* _.result(object, 'a[0].b.c2'); |
|
* // => 4 |
|
* |
|
* _.result(object, 'a[0].b.c3', 'default'); |
|
* // => 'default' |
|
* |
|
* _.result(object, 'a[0].b.c3', _.constant('default')); |
|
* // => 'default' |
|
*/ |
|
function result(object, path, defaultValue) { |
|
path = castPath(path, object); |
|
|
|
var index = -1, |
|
length = path.length; |
|
|
|
// Ensure the loop is entered when path is empty. |
|
if (!length) { |
|
length = 1; |
|
object = undefined; |
|
} |
|
while (++index < length) { |
|
var value = object == null ? undefined : object[toKey(path[index])]; |
|
if (value === undefined) { |
|
index = length; |
|
value = defaultValue; |
|
} |
|
object = isFunction(value) ? value.call(object) : value; |
|
} |
|
return object; |
|
} |
|
|
|
/** |
|
* Sets the value at `path` of `object`. If a portion of `path` doesn't exist, |
|
* it's created. Arrays are created for missing index properties while objects |
|
* are created for all other missing properties. Use `_.setWith` to customize |
|
* `path` creation. |
|
* |
|
* **Note:** This method mutates `object`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.7.0 |
|
* @category Object |
|
* @param {Object} object The object to modify. |
|
* @param {Array|string} path The path of the property to set. |
|
* @param {*} value The value to set. |
|
* @returns {Object} Returns `object`. |
|
* @example |
|
* |
|
* var object = { 'a': [{ 'b': { 'c': 3 } }] }; |
|
* |
|
* _.set(object, 'a[0].b.c', 4); |
|
* console.log(object.a[0].b.c); |
|
* // => 4 |
|
* |
|
* _.set(object, ['x', '0', 'y', 'z'], 5); |
|
* console.log(object.x[0].y.z); |
|
* // => 5 |
|
*/ |
|
function set(object, path, value) { |
|
return object == null ? object : baseSet(object, path, value); |
|
} |
|
|
|
/** |
|
* This method is like `_.set` except that it accepts `customizer` which is |
|
* invoked to produce the objects of `path`. If `customizer` returns `undefined` |
|
* path creation is handled by the method instead. The `customizer` is invoked |
|
* with three arguments: (nsValue, key, nsObject). |
|
* |
|
* **Note:** This method mutates `object`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Object |
|
* @param {Object} object The object to modify. |
|
* @param {Array|string} path The path of the property to set. |
|
* @param {*} value The value to set. |
|
* @param {Function} [customizer] The function to customize assigned values. |
|
* @returns {Object} Returns `object`. |
|
* @example |
|
* |
|
* var object = {}; |
|
* |
|
* _.setWith(object, '[0][1]', 'a', Object); |
|
* // => { '0': { '1': 'a' } } |
|
*/ |
|
function setWith(object, path, value, customizer) { |
|
customizer = typeof customizer == 'function' ? customizer : undefined; |
|
return object == null ? object : baseSet(object, path, value, customizer); |
|
} |
|
|
|
/** |
|
* Creates an array of own enumerable string keyed-value pairs for `object` |
|
* which can be consumed by `_.fromPairs`. If `object` is a map or set, its |
|
* entries are returned. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @alias entries |
|
* @category Object |
|
* @param {Object} object The object to query. |
|
* @returns {Array} Returns the key-value pairs. |
|
* @example |
|
* |
|
* function Foo() { |
|
* this.a = 1; |
|
* this.b = 2; |
|
* } |
|
* |
|
* Foo.prototype.c = 3; |
|
* |
|
* _.toPairs(new Foo); |
|
* // => [['a', 1], ['b', 2]] (iteration order is not guaranteed) |
|
*/ |
|
var toPairs = createToPairs(keys); |
|
|
|
/** |
|
* Creates an array of own and inherited enumerable string keyed-value pairs |
|
* for `object` which can be consumed by `_.fromPairs`. If `object` is a map |
|
* or set, its entries are returned. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @alias entriesIn |
|
* @category Object |
|
* @param {Object} object The object to query. |
|
* @returns {Array} Returns the key-value pairs. |
|
* @example |
|
* |
|
* function Foo() { |
|
* this.a = 1; |
|
* this.b = 2; |
|
* } |
|
* |
|
* Foo.prototype.c = 3; |
|
* |
|
* _.toPairsIn(new Foo); |
|
* // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed) |
|
*/ |
|
var toPairsIn = createToPairs(keysIn); |
|
|
|
/** |
|
* An alternative to `_.reduce`; this method transforms `object` to a new |
|
* `accumulator` object which is the result of running each of its own |
|
* enumerable string keyed properties thru `iteratee`, with each invocation |
|
* potentially mutating the `accumulator` object. If `accumulator` is not |
|
* provided, a new object with the same `[[Prototype]]` will be used. The |
|
* iteratee is invoked with four arguments: (accumulator, value, key, object). |
|
* Iteratee functions may exit iteration early by explicitly returning `false`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 1.3.0 |
|
* @category Object |
|
* @param {Object} object The object to iterate over. |
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration. |
|
* @param {*} [accumulator] The custom accumulator value. |
|
* @returns {*} Returns the accumulated value. |
|
* @example |
|
* |
|
* _.transform([2, 3, 4], function(result, n) { |
|
* result.push(n *= n); |
|
* return n % 2 == 0; |
|
* }, []); |
|
* // => [4, 9] |
|
* |
|
* _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { |
|
* (result[value] || (result[value] = [])).push(key); |
|
* }, {}); |
|
* // => { '1': ['a', 'c'], '2': ['b'] } |
|
*/ |
|
function transform(object, iteratee, accumulator) { |
|
var isArr = isArray(object), |
|
isArrLike = isArr || isBuffer(object) || isTypedArray(object); |
|
|
|
iteratee = getIteratee(iteratee, 4); |
|
if (accumulator == null) { |
|
var Ctor = object && object.constructor; |
|
if (isArrLike) { |
|
accumulator = isArr ? new Ctor : []; |
|
} |
|
else if (isObject(object)) { |
|
accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {}; |
|
} |
|
else { |
|
accumulator = {}; |
|
} |
|
} |
|
(isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) { |
|
return iteratee(accumulator, value, index, object); |
|
}); |
|
return accumulator; |
|
} |
|
|
|
/** |
|
* Removes the property at `path` of `object`. |
|
* |
|
* **Note:** This method mutates `object`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Object |
|
* @param {Object} object The object to modify. |
|
* @param {Array|string} path The path of the property to unset. |
|
* @returns {boolean} Returns `true` if the property is deleted, else `false`. |
|
* @example |
|
* |
|
* var object = { 'a': [{ 'b': { 'c': 7 } }] }; |
|
* _.unset(object, 'a[0].b.c'); |
|
* // => true |
|
* |
|
* console.log(object); |
|
* // => { 'a': [{ 'b': {} }] }; |
|
* |
|
* _.unset(object, ['a', '0', 'b', 'c']); |
|
* // => true |
|
* |
|
* console.log(object); |
|
* // => { 'a': [{ 'b': {} }] }; |
|
*/ |
|
function unset(object, path) { |
|
return object == null ? true : baseUnset(object, path); |
|
} |
|
|
|
/** |
|
* This method is like `_.set` except that accepts `updater` to produce the |
|
* value to set. Use `_.updateWith` to customize `path` creation. The `updater` |
|
* is invoked with one argument: (value). |
|
* |
|
* **Note:** This method mutates `object`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.6.0 |
|
* @category Object |
|
* @param {Object} object The object to modify. |
|
* @param {Array|string} path The path of the property to set. |
|
* @param {Function} updater The function to produce the updated value. |
|
* @returns {Object} Returns `object`. |
|
* @example |
|
* |
|
* var object = { 'a': [{ 'b': { 'c': 3 } }] }; |
|
* |
|
* _.update(object, 'a[0].b.c', function(n) { return n * n; }); |
|
* console.log(object.a[0].b.c); |
|
* // => 9 |
|
* |
|
* _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; }); |
|
* console.log(object.x[0].y.z); |
|
* // => 0 |
|
*/ |
|
function update(object, path, updater) { |
|
return object == null ? object : baseUpdate(object, path, castFunction(updater)); |
|
} |
|
|
|
/** |
|
* This method is like `_.update` except that it accepts `customizer` which is |
|
* invoked to produce the objects of `path`. If `customizer` returns `undefined` |
|
* path creation is handled by the method instead. The `customizer` is invoked |
|
* with three arguments: (nsValue, key, nsObject). |
|
* |
|
* **Note:** This method mutates `object`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.6.0 |
|
* @category Object |
|
* @param {Object} object The object to modify. |
|
* @param {Array|string} path The path of the property to set. |
|
* @param {Function} updater The function to produce the updated value. |
|
* @param {Function} [customizer] The function to customize assigned values. |
|
* @returns {Object} Returns `object`. |
|
* @example |
|
* |
|
* var object = {}; |
|
* |
|
* _.updateWith(object, '[0][1]', _.constant('a'), Object); |
|
* // => { '0': { '1': 'a' } } |
|
*/ |
|
function updateWith(object, path, updater, customizer) { |
|
customizer = typeof customizer == 'function' ? customizer : undefined; |
|
return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer); |
|
} |
|
|
|
/** |
|
* Creates an array of the own enumerable string keyed property values of `object`. |
|
* |
|
* **Note:** Non-object values are coerced to objects. |
|
* |
|
* @static |
|
* @since 0.1.0 |
|
* @memberOf _ |
|
* @category Object |
|
* @param {Object} object The object to query. |
|
* @returns {Array} Returns the array of property values. |
|
* @example |
|
* |
|
* function Foo() { |
|
* this.a = 1; |
|
* this.b = 2; |
|
* } |
|
* |
|
* Foo.prototype.c = 3; |
|
* |
|
* _.values(new Foo); |
|
* // => [1, 2] (iteration order is not guaranteed) |
|
* |
|
* _.values('hi'); |
|
* // => ['h', 'i'] |
|
*/ |
|
function values(object) { |
|
return object == null ? [] : baseValues(object, keys(object)); |
|
} |
|
|
|
/** |
|
* Creates an array of the own and inherited enumerable string keyed property |
|
* values of `object`. |
|
* |
|
* **Note:** Non-object values are coerced to objects. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Object |
|
* @param {Object} object The object to query. |
|
* @returns {Array} Returns the array of property values. |
|
* @example |
|
* |
|
* function Foo() { |
|
* this.a = 1; |
|
* this.b = 2; |
|
* } |
|
* |
|
* Foo.prototype.c = 3; |
|
* |
|
* _.valuesIn(new Foo); |
|
* // => [1, 2, 3] (iteration order is not guaranteed) |
|
*/ |
|
function valuesIn(object) { |
|
return object == null ? [] : baseValues(object, keysIn(object)); |
|
} |
|
|
|
/*------------------------------------------------------------------------*/ |
|
|
|
/** |
|
* Clamps `number` within the inclusive `lower` and `upper` bounds. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Number |
|
* @param {number} number The number to clamp. |
|
* @param {number} [lower] The lower bound. |
|
* @param {number} upper The upper bound. |
|
* @returns {number} Returns the clamped number. |
|
* @example |
|
* |
|
* _.clamp(-10, -5, 5); |
|
* // => -5 |
|
* |
|
* _.clamp(10, -5, 5); |
|
* // => 5 |
|
*/ |
|
function clamp(number, lower, upper) { |
|
if (upper === undefined) { |
|
upper = lower; |
|
lower = undefined; |
|
} |
|
if (upper !== undefined) { |
|
upper = toNumber(upper); |
|
upper = upper === upper ? upper : 0; |
|
} |
|
if (lower !== undefined) { |
|
lower = toNumber(lower); |
|
lower = lower === lower ? lower : 0; |
|
} |
|
return baseClamp(toNumber(number), lower, upper); |
|
} |
|
|
|
/** |
|
* Checks if `n` is between `start` and up to, but not including, `end`. If |
|
* `end` is not specified, it's set to `start` with `start` then set to `0`. |
|
* If `start` is greater than `end` the params are swapped to support |
|
* negative ranges. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.3.0 |
|
* @category Number |
|
* @param {number} number The number to check. |
|
* @param {number} [start=0] The start of the range. |
|
* @param {number} end The end of the range. |
|
* @returns {boolean} Returns `true` if `number` is in the range, else `false`. |
|
* @see _.range, _.rangeRight |
|
* @example |
|
* |
|
* _.inRange(3, 2, 4); |
|
* // => true |
|
* |
|
* _.inRange(4, 8); |
|
* // => true |
|
* |
|
* _.inRange(4, 2); |
|
* // => false |
|
* |
|
* _.inRange(2, 2); |
|
* // => false |
|
* |
|
* _.inRange(1.2, 2); |
|
* // => true |
|
* |
|
* _.inRange(5.2, 4); |
|
* // => false |
|
* |
|
* _.inRange(-3, -2, -6); |
|
* // => true |
|
*/ |
|
function inRange(number, start, end) { |
|
start = toFinite(start); |
|
if (end === undefined) { |
|
end = start; |
|
start = 0; |
|
} else { |
|
end = toFinite(end); |
|
} |
|
number = toNumber(number); |
|
return baseInRange(number, start, end); |
|
} |
|
|
|
/** |
|
* Produces a random number between the inclusive `lower` and `upper` bounds. |
|
* If only one argument is provided a number between `0` and the given number |
|
* is returned. If `floating` is `true`, or either `lower` or `upper` are |
|
* floats, a floating-point number is returned instead of an integer. |
|
* |
|
* **Note:** JavaScript follows the IEEE-754 standard for resolving |
|
* floating-point values which can produce unexpected results. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.7.0 |
|
* @category Number |
|
* @param {number} [lower=0] The lower bound. |
|
* @param {number} [upper=1] The upper bound. |
|
* @param {boolean} [floating] Specify returning a floating-point number. |
|
* @returns {number} Returns the random number. |
|
* @example |
|
* |
|
* _.random(0, 5); |
|
* // => an integer between 0 and 5 |
|
* |
|
* _.random(5); |
|
* // => also an integer between 0 and 5 |
|
* |
|
* _.random(5, true); |
|
* // => a floating-point number between 0 and 5 |
|
* |
|
* _.random(1.2, 5.2); |
|
* // => a floating-point number between 1.2 and 5.2 |
|
*/ |
|
function random(lower, upper, floating) { |
|
if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) { |
|
upper = floating = undefined; |
|
} |
|
if (floating === undefined) { |
|
if (typeof upper == 'boolean') { |
|
floating = upper; |
|
upper = undefined; |
|
} |
|
else if (typeof lower == 'boolean') { |
|
floating = lower; |
|
lower = undefined; |
|
} |
|
} |
|
if (lower === undefined && upper === undefined) { |
|
lower = 0; |
|
upper = 1; |
|
} |
|
else { |
|
lower = toFinite(lower); |
|
if (upper === undefined) { |
|
upper = lower; |
|
lower = 0; |
|
} else { |
|
upper = toFinite(upper); |
|
} |
|
} |
|
if (lower > upper) { |
|
var temp = lower; |
|
lower = upper; |
|
upper = temp; |
|
} |
|
if (floating || lower % 1 || upper % 1) { |
|
var rand = nativeRandom(); |
|
return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper); |
|
} |
|
return baseRandom(lower, upper); |
|
} |
|
|
|
/*------------------------------------------------------------------------*/ |
|
|
|
/** |
|
* Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category String |
|
* @param {string} [string=''] The string to convert. |
|
* @returns {string} Returns the camel cased string. |
|
* @example |
|
* |
|
* _.camelCase('Foo Bar'); |
|
* // => 'fooBar' |
|
* |
|
* _.camelCase('--foo-bar--'); |
|
* // => 'fooBar' |
|
* |
|
* _.camelCase('__FOO_BAR__'); |
|
* // => 'fooBar' |
|
*/ |
|
var camelCase = createCompounder(function(result, word, index) { |
|
word = word.toLowerCase(); |
|
return result + (index ? capitalize(word) : word); |
|
}); |
|
|
|
/** |
|
* Converts the first character of `string` to upper case and the remaining |
|
* to lower case. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category String |
|
* @param {string} [string=''] The string to capitalize. |
|
* @returns {string} Returns the capitalized string. |
|
* @example |
|
* |
|
* _.capitalize('FRED'); |
|
* // => 'Fred' |
|
*/ |
|
function capitalize(string) { |
|
return upperFirst(toString(string).toLowerCase()); |
|
} |
|
|
|
/** |
|
* Deburrs `string` by converting |
|
* [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) |
|
* and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A) |
|
* letters to basic Latin letters and removing |
|
* [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category String |
|
* @param {string} [string=''] The string to deburr. |
|
* @returns {string} Returns the deburred string. |
|
* @example |
|
* |
|
* _.deburr('déjà vu'); |
|
* // => 'deja vu' |
|
*/ |
|
function deburr(string) { |
|
string = toString(string); |
|
return string && string.replace(reLatin, deburrLetter).replace(reComboMark, ''); |
|
} |
|
|
|
/** |
|
* Checks if `string` ends with the given target string. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category String |
|
* @param {string} [string=''] The string to inspect. |
|
* @param {string} [target] The string to search for. |
|
* @param {number} [position=string.length] The position to search up to. |
|
* @returns {boolean} Returns `true` if `string` ends with `target`, |
|
* else `false`. |
|
* @example |
|
* |
|
* _.endsWith('abc', 'c'); |
|
* // => true |
|
* |
|
* _.endsWith('abc', 'b'); |
|
* // => false |
|
* |
|
* _.endsWith('abc', 'b', 2); |
|
* // => true |
|
*/ |
|
function endsWith(string, target, position) { |
|
string = toString(string); |
|
target = baseToString(target); |
|
|
|
var length = string.length; |
|
position = position === undefined |
|
? length |
|
: baseClamp(toInteger(position), 0, length); |
|
|
|
var end = position; |
|
position -= target.length; |
|
return position >= 0 && string.slice(position, end) == target; |
|
} |
|
|
|
/** |
|
* Converts the characters "&", "<", ">", '"', and "'" in `string` to their |
|
* corresponding HTML entities. |
|
* |
|
* **Note:** No other characters are escaped. To escape additional |
|
* characters use a third-party library like [_he_](https://mths.be/he). |
|
* |
|
* Though the ">" character is escaped for symmetry, characters like |
|
* ">" and "/" don't need escaping in HTML and have no special meaning |
|
* unless they're part of a tag or unquoted attribute value. See |
|
* [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) |
|
* (under "semi-related fun fact") for more details. |
|
* |
|
* When working with HTML you should always |
|
* [quote attribute values](http://wonko.com/post/html-escaping) to reduce |
|
* XSS vectors. |
|
* |
|
* @static |
|
* @since 0.1.0 |
|
* @memberOf _ |
|
* @category String |
|
* @param {string} [string=''] The string to escape. |
|
* @returns {string} Returns the escaped string. |
|
* @example |
|
* |
|
* _.escape('fred, barney, & pebbles'); |
|
* // => 'fred, barney, & pebbles' |
|
*/ |
|
function escape(string) { |
|
string = toString(string); |
|
return (string && reHasUnescapedHtml.test(string)) |
|
? string.replace(reUnescapedHtml, escapeHtmlChar) |
|
: string; |
|
} |
|
|
|
/** |
|
* Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+", |
|
* "?", "(", ")", "[", "]", "{", "}", and "|" in `string`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category String |
|
* @param {string} [string=''] The string to escape. |
|
* @returns {string} Returns the escaped string. |
|
* @example |
|
* |
|
* _.escapeRegExp('[lodash](https://lodash.com/)'); |
|
* // => '\[lodash\]\(https://lodash\.com/\)' |
|
*/ |
|
function escapeRegExp(string) { |
|
string = toString(string); |
|
return (string && reHasRegExpChar.test(string)) |
|
? string.replace(reRegExpChar, '\\$&') |
|
: string; |
|
} |
|
|
|
/** |
|
* Converts `string` to |
|
* [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category String |
|
* @param {string} [string=''] The string to convert. |
|
* @returns {string} Returns the kebab cased string. |
|
* @example |
|
* |
|
* _.kebabCase('Foo Bar'); |
|
* // => 'foo-bar' |
|
* |
|
* _.kebabCase('fooBar'); |
|
* // => 'foo-bar' |
|
* |
|
* _.kebabCase('__FOO_BAR__'); |
|
* // => 'foo-bar' |
|
*/ |
|
var kebabCase = createCompounder(function(result, word, index) { |
|
return result + (index ? '-' : '') + word.toLowerCase(); |
|
}); |
|
|
|
/** |
|
* Converts `string`, as space separated words, to lower case. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category String |
|
* @param {string} [string=''] The string to convert. |
|
* @returns {string} Returns the lower cased string. |
|
* @example |
|
* |
|
* _.lowerCase('--Foo-Bar--'); |
|
* // => 'foo bar' |
|
* |
|
* _.lowerCase('fooBar'); |
|
* // => 'foo bar' |
|
* |
|
* _.lowerCase('__FOO_BAR__'); |
|
* // => 'foo bar' |
|
*/ |
|
var lowerCase = createCompounder(function(result, word, index) { |
|
return result + (index ? ' ' : '') + word.toLowerCase(); |
|
}); |
|
|
|
/** |
|
* Converts the first character of `string` to lower case. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category String |
|
* @param {string} [string=''] The string to convert. |
|
* @returns {string} Returns the converted string. |
|
* @example |
|
* |
|
* _.lowerFirst('Fred'); |
|
* // => 'fred' |
|
* |
|
* _.lowerFirst('FRED'); |
|
* // => 'fRED' |
|
*/ |
|
var lowerFirst = createCaseFirst('toLowerCase'); |
|
|
|
/** |
|
* Pads `string` on the left and right sides if it's shorter than `length`. |
|
* Padding characters are truncated if they can't be evenly divided by `length`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category String |
|
* @param {string} [string=''] The string to pad. |
|
* @param {number} [length=0] The padding length. |
|
* @param {string} [chars=' '] The string used as padding. |
|
* @returns {string} Returns the padded string. |
|
* @example |
|
* |
|
* _.pad('abc', 8); |
|
* // => ' abc ' |
|
* |
|
* _.pad('abc', 8, '_-'); |
|
* // => '_-abc_-_' |
|
* |
|
* _.pad('abc', 3); |
|
* // => 'abc' |
|
*/ |
|
function pad(string, length, chars) { |
|
string = toString(string); |
|
length = toInteger(length); |
|
|
|
var strLength = length ? stringSize(string) : 0; |
|
if (!length || strLength >= length) { |
|
return string; |
|
} |
|
var mid = (length - strLength) / 2; |
|
return ( |
|
createPadding(nativeFloor(mid), chars) + |
|
string + |
|
createPadding(nativeCeil(mid), chars) |
|
); |
|
} |
|
|
|
/** |
|
* Pads `string` on the right side if it's shorter than `length`. Padding |
|
* characters are truncated if they exceed `length`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category String |
|
* @param {string} [string=''] The string to pad. |
|
* @param {number} [length=0] The padding length. |
|
* @param {string} [chars=' '] The string used as padding. |
|
* @returns {string} Returns the padded string. |
|
* @example |
|
* |
|
* _.padEnd('abc', 6); |
|
* // => 'abc ' |
|
* |
|
* _.padEnd('abc', 6, '_-'); |
|
* // => 'abc_-_' |
|
* |
|
* _.padEnd('abc', 3); |
|
* // => 'abc' |
|
*/ |
|
function padEnd(string, length, chars) { |
|
string = toString(string); |
|
length = toInteger(length); |
|
|
|
var strLength = length ? stringSize(string) : 0; |
|
return (length && strLength < length) |
|
? (string + createPadding(length - strLength, chars)) |
|
: string; |
|
} |
|
|
|
/** |
|
* Pads `string` on the left side if it's shorter than `length`. Padding |
|
* characters are truncated if they exceed `length`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category String |
|
* @param {string} [string=''] The string to pad. |
|
* @param {number} [length=0] The padding length. |
|
* @param {string} [chars=' '] The string used as padding. |
|
* @returns {string} Returns the padded string. |
|
* @example |
|
* |
|
* _.padStart('abc', 6); |
|
* // => ' abc' |
|
* |
|
* _.padStart('abc', 6, '_-'); |
|
* // => '_-_abc' |
|
* |
|
* _.padStart('abc', 3); |
|
* // => 'abc' |
|
*/ |
|
function padStart(string, length, chars) { |
|
string = toString(string); |
|
length = toInteger(length); |
|
|
|
var strLength = length ? stringSize(string) : 0; |
|
return (length && strLength < length) |
|
? (createPadding(length - strLength, chars) + string) |
|
: string; |
|
} |
|
|
|
/** |
|
* Converts `string` to an integer of the specified radix. If `radix` is |
|
* `undefined` or `0`, a `radix` of `10` is used unless `value` is a |
|
* hexadecimal, in which case a `radix` of `16` is used. |
|
* |
|
* **Note:** This method aligns with the |
|
* [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 1.1.0 |
|
* @category String |
|
* @param {string} string The string to convert. |
|
* @param {number} [radix=10] The radix to interpret `value` by. |
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. |
|
* @returns {number} Returns the converted integer. |
|
* @example |
|
* |
|
* _.parseInt('08'); |
|
* // => 8 |
|
* |
|
* _.map(['6', '08', '10'], _.parseInt); |
|
* // => [6, 8, 10] |
|
*/ |
|
function parseInt(string, radix, guard) { |
|
if (guard || radix == null) { |
|
radix = 0; |
|
} else if (radix) { |
|
radix = +radix; |
|
} |
|
return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0); |
|
} |
|
|
|
/** |
|
* Repeats the given string `n` times. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category String |
|
* @param {string} [string=''] The string to repeat. |
|
* @param {number} [n=1] The number of times to repeat the string. |
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. |
|
* @returns {string} Returns the repeated string. |
|
* @example |
|
* |
|
* _.repeat('*', 3); |
|
* // => '***' |
|
* |
|
* _.repeat('abc', 2); |
|
* // => 'abcabc' |
|
* |
|
* _.repeat('abc', 0); |
|
* // => '' |
|
*/ |
|
function repeat(string, n, guard) { |
|
if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) { |
|
n = 1; |
|
} else { |
|
n = toInteger(n); |
|
} |
|
return baseRepeat(toString(string), n); |
|
} |
|
|
|
/** |
|
* Replaces matches for `pattern` in `string` with `replacement`. |
|
* |
|
* **Note:** This method is based on |
|
* [`String#replace`](https://mdn.io/String/replace). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category String |
|
* @param {string} [string=''] The string to modify. |
|
* @param {RegExp|string} pattern The pattern to replace. |
|
* @param {Function|string} replacement The match replacement. |
|
* @returns {string} Returns the modified string. |
|
* @example |
|
* |
|
* _.replace('Hi Fred', 'Fred', 'Barney'); |
|
* // => 'Hi Barney' |
|
*/ |
|
function replace() { |
|
var args = arguments, |
|
string = toString(args[0]); |
|
|
|
return args.length < 3 ? string : string.replace(args[1], args[2]); |
|
} |
|
|
|
/** |
|
* Converts `string` to |
|
* [snake case](https://en.wikipedia.org/wiki/Snake_case). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category String |
|
* @param {string} [string=''] The string to convert. |
|
* @returns {string} Returns the snake cased string. |
|
* @example |
|
* |
|
* _.snakeCase('Foo Bar'); |
|
* // => 'foo_bar' |
|
* |
|
* _.snakeCase('fooBar'); |
|
* // => 'foo_bar' |
|
* |
|
* _.snakeCase('--FOO-BAR--'); |
|
* // => 'foo_bar' |
|
*/ |
|
var snakeCase = createCompounder(function(result, word, index) { |
|
return result + (index ? '_' : '') + word.toLowerCase(); |
|
}); |
|
|
|
/** |
|
* Splits `string` by `separator`. |
|
* |
|
* **Note:** This method is based on |
|
* [`String#split`](https://mdn.io/String/split). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category String |
|
* @param {string} [string=''] The string to split. |
|
* @param {RegExp|string} separator The separator pattern to split by. |
|
* @param {number} [limit] The length to truncate results to. |
|
* @returns {Array} Returns the string segments. |
|
* @example |
|
* |
|
* _.split('a-b-c', '-', 2); |
|
* // => ['a', 'b'] |
|
*/ |
|
function split(string, separator, limit) { |
|
if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) { |
|
separator = limit = undefined; |
|
} |
|
limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0; |
|
if (!limit) { |
|
return []; |
|
} |
|
string = toString(string); |
|
if (string && ( |
|
typeof separator == 'string' || |
|
(separator != null && !isRegExp(separator)) |
|
)) { |
|
separator = baseToString(separator); |
|
if (!separator && hasUnicode(string)) { |
|
return castSlice(stringToArray(string), 0, limit); |
|
} |
|
} |
|
return string.split(separator, limit); |
|
} |
|
|
|
/** |
|
* Converts `string` to |
|
* [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.1.0 |
|
* @category String |
|
* @param {string} [string=''] The string to convert. |
|
* @returns {string} Returns the start cased string. |
|
* @example |
|
* |
|
* _.startCase('--foo-bar--'); |
|
* // => 'Foo Bar' |
|
* |
|
* _.startCase('fooBar'); |
|
* // => 'Foo Bar' |
|
* |
|
* _.startCase('__FOO_BAR__'); |
|
* // => 'FOO BAR' |
|
*/ |
|
var startCase = createCompounder(function(result, word, index) { |
|
return result + (index ? ' ' : '') + upperFirst(word); |
|
}); |
|
|
|
/** |
|
* Checks if `string` starts with the given target string. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category String |
|
* @param {string} [string=''] The string to inspect. |
|
* @param {string} [target] The string to search for. |
|
* @param {number} [position=0] The position to search from. |
|
* @returns {boolean} Returns `true` if `string` starts with `target`, |
|
* else `false`. |
|
* @example |
|
* |
|
* _.startsWith('abc', 'a'); |
|
* // => true |
|
* |
|
* _.startsWith('abc', 'b'); |
|
* // => false |
|
* |
|
* _.startsWith('abc', 'b', 1); |
|
* // => true |
|
*/ |
|
function startsWith(string, target, position) { |
|
string = toString(string); |
|
position = position == null |
|
? 0 |
|
: baseClamp(toInteger(position), 0, string.length); |
|
|
|
target = baseToString(target); |
|
return string.slice(position, position + target.length) == target; |
|
} |
|
|
|
/** |
|
* Creates a compiled template function that can interpolate data properties |
|
* in "interpolate" delimiters, HTML-escape interpolated data properties in |
|
* "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data |
|
* properties may be accessed as free variables in the template. If a setting |
|
* object is given, it takes precedence over `_.templateSettings` values. |
|
* |
|
* **Note:** In the development build `_.template` utilizes |
|
* [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) |
|
* for easier debugging. |
|
* |
|
* For more information on precompiling templates see |
|
* [lodash's custom builds documentation](https://lodash.com/custom-builds). |
|
* |
|
* For more information on Chrome extension sandboxes see |
|
* [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). |
|
* |
|
* @static |
|
* @since 0.1.0 |
|
* @memberOf _ |
|
* @category String |
|
* @param {string} [string=''] The template string. |
|
* @param {Object} [options={}] The options object. |
|
* @param {RegExp} [options.escape=_.templateSettings.escape] |
|
* The HTML "escape" delimiter. |
|
* @param {RegExp} [options.evaluate=_.templateSettings.evaluate] |
|
* The "evaluate" delimiter. |
|
* @param {Object} [options.imports=_.templateSettings.imports] |
|
* An object to import into the template as free variables. |
|
* @param {RegExp} [options.interpolate=_.templateSettings.interpolate] |
|
* The "interpolate" delimiter. |
|
* @param {string} [options.sourceURL='lodash.templateSources[n]'] |
|
* The sourceURL of the compiled template. |
|
* @param {string} [options.variable='obj'] |
|
* The data object variable name. |
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. |
|
* @returns {Function} Returns the compiled template function. |
|
* @example |
|
* |
|
* // Use the "interpolate" delimiter to create a compiled template. |
|
* var compiled = _.template('hello <%= user %>!'); |
|
* compiled({ 'user': 'fred' }); |
|
* // => 'hello fred!' |
|
* |
|
* // Use the HTML "escape" delimiter to escape data property values. |
|
* var compiled = _.template('<b><%- value %></b>'); |
|
* compiled({ 'value': '<script>' }); |
|
* // => '<b><script></b>' |
|
* |
|
* // Use the "evaluate" delimiter to execute JavaScript and generate HTML. |
|
* var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>'); |
|
* compiled({ 'users': ['fred', 'barney'] }); |
|
* // => '<li>fred</li><li>barney</li>' |
|
* |
|
* // Use the internal `print` function in "evaluate" delimiters. |
|
* var compiled = _.template('<% print("hello " + user); %>!'); |
|
* compiled({ 'user': 'barney' }); |
|
* // => 'hello barney!' |
|
* |
|
* // Use the ES template literal delimiter as an "interpolate" delimiter. |
|
* // Disable support by replacing the "interpolate" delimiter. |
|
* var compiled = _.template('hello ${ user }!'); |
|
* compiled({ 'user': 'pebbles' }); |
|
* // => 'hello pebbles!' |
|
* |
|
* // Use backslashes to treat delimiters as plain text. |
|
* var compiled = _.template('<%= "\\<%- value %\\>" %>'); |
|
* compiled({ 'value': 'ignored' }); |
|
* // => '<%- value %>' |
|
* |
|
* // Use the `imports` option to import `jQuery` as `jq`. |
|
* var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>'; |
|
* var compiled = _.template(text, { 'imports': { 'jq': jQuery } }); |
|
* compiled({ 'users': ['fred', 'barney'] }); |
|
* // => '<li>fred</li><li>barney</li>' |
|
* |
|
* // Use the `sourceURL` option to specify a custom sourceURL for the template. |
|
* var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' }); |
|
* compiled(data); |
|
* // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector. |
|
* |
|
* // Use the `variable` option to ensure a with-statement isn't used in the compiled template. |
|
* var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' }); |
|
* compiled.source; |
|
* // => function(data) { |
|
* // var __t, __p = ''; |
|
* // __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!'; |
|
* // return __p; |
|
* // } |
|
* |
|
* // Use custom template delimiters. |
|
* _.templateSettings.interpolate = /{{([\s\S]+?)}}/g; |
|
* var compiled = _.template('hello {{ user }}!'); |
|
* compiled({ 'user': 'mustache' }); |
|
* // => 'hello mustache!' |
|
* |
|
* // Use the `source` property to inline compiled templates for meaningful |
|
* // line numbers in error messages and stack traces. |
|
* fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\ |
|
* var JST = {\ |
|
* "main": ' + _.template(mainText).source + '\ |
|
* };\ |
|
* '); |
|
*/ |
|
function template(string, options, guard) { |
|
// Based on John Resig's `tmpl` implementation |
|
// (http://ejohn.org/blog/javascript-micro-templating/) |
|
// and Laura Doktorova's doT.js (https://github.com/olado/doT). |
|
var settings = lodash.templateSettings; |
|
|
|
if (guard && isIterateeCall(string, options, guard)) { |
|
options = undefined; |
|
} |
|
string = toString(string); |
|
options = assignInWith({}, options, settings, customDefaultsAssignIn); |
|
|
|
var imports = assignInWith({}, options.imports, settings.imports, customDefaultsAssignIn), |
|
importsKeys = keys(imports), |
|
importsValues = baseValues(imports, importsKeys); |
|
|
|
var isEscaping, |
|
isEvaluating, |
|
index = 0, |
|
interpolate = options.interpolate || reNoMatch, |
|
source = "__p += '"; |
|
|
|
// Compile the regexp to match each delimiter. |
|
var reDelimiters = RegExp( |
|
(options.escape || reNoMatch).source + '|' + |
|
interpolate.source + '|' + |
|
(interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' + |
|
(options.evaluate || reNoMatch).source + '|$' |
|
, 'g'); |
|
|
|
// Use a sourceURL for easier debugging. |
|
var sourceURL = '//# sourceURL=' + |
|
('sourceURL' in options |
|
? options.sourceURL |
|
: ('lodash.templateSources[' + (++templateCounter) + ']') |
|
) + '\n'; |
|
|
|
string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) { |
|
interpolateValue || (interpolateValue = esTemplateValue); |
|
|
|
// Escape characters that can't be included in string literals. |
|
source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar); |
|
|
|
// Replace delimiters with snippets. |
|
if (escapeValue) { |
|
isEscaping = true; |
|
source += "' +\n__e(" + escapeValue + ") +\n'"; |
|
} |
|
if (evaluateValue) { |
|
isEvaluating = true; |
|
source += "';\n" + evaluateValue + ";\n__p += '"; |
|
} |
|
if (interpolateValue) { |
|
source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'"; |
|
} |
|
index = offset + match.length; |
|
|
|
// The JS engine embedded in Adobe products needs `match` returned in |
|
// order to produce the correct `offset` value. |
|
return match; |
|
}); |
|
|
|
source += "';\n"; |
|
|
|
// If `variable` is not specified wrap a with-statement around the generated |
|
// code to add the data object to the top of the scope chain. |
|
var variable = options.variable; |
|
if (!variable) { |
|
source = 'with (obj) {\n' + source + '\n}\n'; |
|
} |
|
// Cleanup code by stripping empty strings. |
|
source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source) |
|
.replace(reEmptyStringMiddle, '$1') |
|
.replace(reEmptyStringTrailing, '$1;'); |
|
|
|
// Frame code as the function body. |
|
source = 'function(' + (variable || 'obj') + ') {\n' + |
|
(variable |
|
? '' |
|
: 'obj || (obj = {});\n' |
|
) + |
|
"var __t, __p = ''" + |
|
(isEscaping |
|
? ', __e = _.escape' |
|
: '' |
|
) + |
|
(isEvaluating |
|
? ', __j = Array.prototype.join;\n' + |
|
"function print() { __p += __j.call(arguments, '') }\n" |
|
: ';\n' |
|
) + |
|
source + |
|
'return __p\n}'; |
|
|
|
var result = attempt(function() { |
|
return Function(importsKeys, sourceURL + 'return ' + source) |
|
.apply(undefined, importsValues); |
|
}); |
|
|
|
// Provide the compiled function's source by its `toString` method or |
|
// the `source` property as a convenience for inlining compiled templates. |
|
result.source = source; |
|
if (isError(result)) { |
|
throw result; |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* Converts `string`, as a whole, to lower case just like |
|
* [String#toLowerCase](https://mdn.io/toLowerCase). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category String |
|
* @param {string} [string=''] The string to convert. |
|
* @returns {string} Returns the lower cased string. |
|
* @example |
|
* |
|
* _.toLower('--Foo-Bar--'); |
|
* // => '--foo-bar--' |
|
* |
|
* _.toLower('fooBar'); |
|
* // => 'foobar' |
|
* |
|
* _.toLower('__FOO_BAR__'); |
|
* // => '__foo_bar__' |
|
*/ |
|
function toLower(value) { |
|
return toString(value).toLowerCase(); |
|
} |
|
|
|
/** |
|
* Converts `string`, as a whole, to upper case just like |
|
* [String#toUpperCase](https://mdn.io/toUpperCase). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category String |
|
* @param {string} [string=''] The string to convert. |
|
* @returns {string} Returns the upper cased string. |
|
* @example |
|
* |
|
* _.toUpper('--foo-bar--'); |
|
* // => '--FOO-BAR--' |
|
* |
|
* _.toUpper('fooBar'); |
|
* // => 'FOOBAR' |
|
* |
|
* _.toUpper('__foo_bar__'); |
|
* // => '__FOO_BAR__' |
|
*/ |
|
function toUpper(value) { |
|
return toString(value).toUpperCase(); |
|
} |
|
|
|
/** |
|
* Removes leading and trailing whitespace or specified characters from `string`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category String |
|
* @param {string} [string=''] The string to trim. |
|
* @param {string} [chars=whitespace] The characters to trim. |
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. |
|
* @returns {string} Returns the trimmed string. |
|
* @example |
|
* |
|
* _.trim(' abc '); |
|
* // => 'abc' |
|
* |
|
* _.trim('-_-abc-_-', '_-'); |
|
* // => 'abc' |
|
* |
|
* _.map([' foo ', ' bar '], _.trim); |
|
* // => ['foo', 'bar'] |
|
*/ |
|
function trim(string, chars, guard) { |
|
string = toString(string); |
|
if (string && (guard || chars === undefined)) { |
|
return string.replace(reTrim, ''); |
|
} |
|
if (!string || !(chars = baseToString(chars))) { |
|
return string; |
|
} |
|
var strSymbols = stringToArray(string), |
|
chrSymbols = stringToArray(chars), |
|
start = charsStartIndex(strSymbols, chrSymbols), |
|
end = charsEndIndex(strSymbols, chrSymbols) + 1; |
|
|
|
return castSlice(strSymbols, start, end).join(''); |
|
} |
|
|
|
/** |
|
* Removes trailing whitespace or specified characters from `string`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category String |
|
* @param {string} [string=''] The string to trim. |
|
* @param {string} [chars=whitespace] The characters to trim. |
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. |
|
* @returns {string} Returns the trimmed string. |
|
* @example |
|
* |
|
* _.trimEnd(' abc '); |
|
* // => ' abc' |
|
* |
|
* _.trimEnd('-_-abc-_-', '_-'); |
|
* // => '-_-abc' |
|
*/ |
|
function trimEnd(string, chars, guard) { |
|
string = toString(string); |
|
if (string && (guard || chars === undefined)) { |
|
return string.replace(reTrimEnd, ''); |
|
} |
|
if (!string || !(chars = baseToString(chars))) { |
|
return string; |
|
} |
|
var strSymbols = stringToArray(string), |
|
end = charsEndIndex(strSymbols, stringToArray(chars)) + 1; |
|
|
|
return castSlice(strSymbols, 0, end).join(''); |
|
} |
|
|
|
/** |
|
* Removes leading whitespace or specified characters from `string`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category String |
|
* @param {string} [string=''] The string to trim. |
|
* @param {string} [chars=whitespace] The characters to trim. |
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. |
|
* @returns {string} Returns the trimmed string. |
|
* @example |
|
* |
|
* _.trimStart(' abc '); |
|
* // => 'abc ' |
|
* |
|
* _.trimStart('-_-abc-_-', '_-'); |
|
* // => 'abc-_-' |
|
*/ |
|
function trimStart(string, chars, guard) { |
|
string = toString(string); |
|
if (string && (guard || chars === undefined)) { |
|
return string.replace(reTrimStart, ''); |
|
} |
|
if (!string || !(chars = baseToString(chars))) { |
|
return string; |
|
} |
|
var strSymbols = stringToArray(string), |
|
start = charsStartIndex(strSymbols, stringToArray(chars)); |
|
|
|
return castSlice(strSymbols, start).join(''); |
|
} |
|
|
|
/** |
|
* Truncates `string` if it's longer than the given maximum string length. |
|
* The last characters of the truncated string are replaced with the omission |
|
* string which defaults to "...". |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category String |
|
* @param {string} [string=''] The string to truncate. |
|
* @param {Object} [options={}] The options object. |
|
* @param {number} [options.length=30] The maximum string length. |
|
* @param {string} [options.omission='...'] The string to indicate text is omitted. |
|
* @param {RegExp|string} [options.separator] The separator pattern to truncate to. |
|
* @returns {string} Returns the truncated string. |
|
* @example |
|
* |
|
* _.truncate('hi-diddly-ho there, neighborino'); |
|
* // => 'hi-diddly-ho there, neighbo...' |
|
* |
|
* _.truncate('hi-diddly-ho there, neighborino', { |
|
* 'length': 24, |
|
* 'separator': ' ' |
|
* }); |
|
* // => 'hi-diddly-ho there,...' |
|
* |
|
* _.truncate('hi-diddly-ho there, neighborino', { |
|
* 'length': 24, |
|
* 'separator': /,? +/ |
|
* }); |
|
* // => 'hi-diddly-ho there...' |
|
* |
|
* _.truncate('hi-diddly-ho there, neighborino', { |
|
* 'omission': ' [...]' |
|
* }); |
|
* // => 'hi-diddly-ho there, neig [...]' |
|
*/ |
|
function truncate(string, options) { |
|
var length = DEFAULT_TRUNC_LENGTH, |
|
omission = DEFAULT_TRUNC_OMISSION; |
|
|
|
if (isObject(options)) { |
|
var separator = 'separator' in options ? options.separator : separator; |
|
length = 'length' in options ? toInteger(options.length) : length; |
|
omission = 'omission' in options ? baseToString(options.omission) : omission; |
|
} |
|
string = toString(string); |
|
|
|
var strLength = string.length; |
|
if (hasUnicode(string)) { |
|
var strSymbols = stringToArray(string); |
|
strLength = strSymbols.length; |
|
} |
|
if (length >= strLength) { |
|
return string; |
|
} |
|
var end = length - stringSize(omission); |
|
if (end < 1) { |
|
return omission; |
|
} |
|
var result = strSymbols |
|
? castSlice(strSymbols, 0, end).join('') |
|
: string.slice(0, end); |
|
|
|
if (separator === undefined) { |
|
return result + omission; |
|
} |
|
if (strSymbols) { |
|
end += (result.length - end); |
|
} |
|
if (isRegExp(separator)) { |
|
if (string.slice(end).search(separator)) { |
|
var match, |
|
substring = result; |
|
|
|
if (!separator.global) { |
|
separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g'); |
|
} |
|
separator.lastIndex = 0; |
|
while ((match = separator.exec(substring))) { |
|
var newEnd = match.index; |
|
} |
|
result = result.slice(0, newEnd === undefined ? end : newEnd); |
|
} |
|
} else if (string.indexOf(baseToString(separator), end) != end) { |
|
var index = result.lastIndexOf(separator); |
|
if (index > -1) { |
|
result = result.slice(0, index); |
|
} |
|
} |
|
return result + omission; |
|
} |
|
|
|
/** |
|
* The inverse of `_.escape`; this method converts the HTML entities |
|
* `&`, `<`, `>`, `"`, and `'` in `string` to |
|
* their corresponding characters. |
|
* |
|
* **Note:** No other HTML entities are unescaped. To unescape additional |
|
* HTML entities use a third-party library like [_he_](https://mths.be/he). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 0.6.0 |
|
* @category String |
|
* @param {string} [string=''] The string to unescape. |
|
* @returns {string} Returns the unescaped string. |
|
* @example |
|
* |
|
* _.unescape('fred, barney, & pebbles'); |
|
* // => 'fred, barney, & pebbles' |
|
*/ |
|
function unescape(string) { |
|
string = toString(string); |
|
return (string && reHasEscapedHtml.test(string)) |
|
? string.replace(reEscapedHtml, unescapeHtmlChar) |
|
: string; |
|
} |
|
|
|
/** |
|
* Converts `string`, as space separated words, to upper case. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category String |
|
* @param {string} [string=''] The string to convert. |
|
* @returns {string} Returns the upper cased string. |
|
* @example |
|
* |
|
* _.upperCase('--foo-bar'); |
|
* // => 'FOO BAR' |
|
* |
|
* _.upperCase('fooBar'); |
|
* // => 'FOO BAR' |
|
* |
|
* _.upperCase('__foo_bar__'); |
|
* // => 'FOO BAR' |
|
*/ |
|
var upperCase = createCompounder(function(result, word, index) { |
|
return result + (index ? ' ' : '') + word.toUpperCase(); |
|
}); |
|
|
|
/** |
|
* Converts the first character of `string` to upper case. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category String |
|
* @param {string} [string=''] The string to convert. |
|
* @returns {string} Returns the converted string. |
|
* @example |
|
* |
|
* _.upperFirst('fred'); |
|
* // => 'Fred' |
|
* |
|
* _.upperFirst('FRED'); |
|
* // => 'FRED' |
|
*/ |
|
var upperFirst = createCaseFirst('toUpperCase'); |
|
|
|
/** |
|
* Splits `string` into an array of its words. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category String |
|
* @param {string} [string=''] The string to inspect. |
|
* @param {RegExp|string} [pattern] The pattern to match words. |
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. |
|
* @returns {Array} Returns the words of `string`. |
|
* @example |
|
* |
|
* _.words('fred, barney, & pebbles'); |
|
* // => ['fred', 'barney', 'pebbles'] |
|
* |
|
* _.words('fred, barney, & pebbles', /[^, ]+/g); |
|
* // => ['fred', 'barney', '&', 'pebbles'] |
|
*/ |
|
function words(string, pattern, guard) { |
|
string = toString(string); |
|
pattern = guard ? undefined : pattern; |
|
|
|
if (pattern === undefined) { |
|
return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string); |
|
} |
|
return string.match(pattern) || []; |
|
} |
|
|
|
/*------------------------------------------------------------------------*/ |
|
|
|
/** |
|
* Attempts to invoke `func`, returning either the result or the caught error |
|
* object. Any additional arguments are provided to `func` when it's invoked. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Util |
|
* @param {Function} func The function to attempt. |
|
* @param {...*} [args] The arguments to invoke `func` with. |
|
* @returns {*} Returns the `func` result or error object. |
|
* @example |
|
* |
|
* // Avoid throwing errors for invalid selectors. |
|
* var elements = _.attempt(function(selector) { |
|
* return document.querySelectorAll(selector); |
|
* }, '>_>'); |
|
* |
|
* if (_.isError(elements)) { |
|
* elements = []; |
|
* } |
|
*/ |
|
var attempt = baseRest(function(func, args) { |
|
try { |
|
return apply(func, undefined, args); |
|
} catch (e) { |
|
return isError(e) ? e : new Error(e); |
|
} |
|
}); |
|
|
|
/** |
|
* Binds methods of an object to the object itself, overwriting the existing |
|
* method. |
|
* |
|
* **Note:** This method doesn't set the "length" property of bound functions. |
|
* |
|
* @static |
|
* @since 0.1.0 |
|
* @memberOf _ |
|
* @category Util |
|
* @param {Object} object The object to bind and assign the bound methods to. |
|
* @param {...(string|string[])} methodNames The object method names to bind. |
|
* @returns {Object} Returns `object`. |
|
* @example |
|
* |
|
* var view = { |
|
* 'label': 'docs', |
|
* 'click': function() { |
|
* console.log('clicked ' + this.label); |
|
* } |
|
* }; |
|
* |
|
* _.bindAll(view, ['click']); |
|
* jQuery(element).on('click', view.click); |
|
* // => Logs 'clicked docs' when clicked. |
|
*/ |
|
var bindAll = flatRest(function(object, methodNames) { |
|
arrayEach(methodNames, function(key) { |
|
key = toKey(key); |
|
baseAssignValue(object, key, bind(object[key], object)); |
|
}); |
|
return object; |
|
}); |
|
|
|
/** |
|
* Creates a function that iterates over `pairs` and invokes the corresponding |
|
* function of the first predicate to return truthy. The predicate-function |
|
* pairs are invoked with the `this` binding and arguments of the created |
|
* function. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Util |
|
* @param {Array} pairs The predicate-function pairs. |
|
* @returns {Function} Returns the new composite function. |
|
* @example |
|
* |
|
* var func = _.cond([ |
|
* [_.matches({ 'a': 1 }), _.constant('matches A')], |
|
* [_.conforms({ 'b': _.isNumber }), _.constant('matches B')], |
|
* [_.stubTrue, _.constant('no match')] |
|
* ]); |
|
* |
|
* func({ 'a': 1, 'b': 2 }); |
|
* // => 'matches A' |
|
* |
|
* func({ 'a': 0, 'b': 1 }); |
|
* // => 'matches B' |
|
* |
|
* func({ 'a': '1', 'b': '2' }); |
|
* // => 'no match' |
|
*/ |
|
function cond(pairs) { |
|
var length = pairs == null ? 0 : pairs.length, |
|
toIteratee = getIteratee(); |
|
|
|
pairs = !length ? [] : arrayMap(pairs, function(pair) { |
|
if (typeof pair[1] != 'function') { |
|
throw new TypeError(FUNC_ERROR_TEXT); |
|
} |
|
return [toIteratee(pair[0]), pair[1]]; |
|
}); |
|
|
|
return baseRest(function(args) { |
|
var index = -1; |
|
while (++index < length) { |
|
var pair = pairs[index]; |
|
if (apply(pair[0], this, args)) { |
|
return apply(pair[1], this, args); |
|
} |
|
} |
|
}); |
|
} |
|
|
|
/** |
|
* Creates a function that invokes the predicate properties of `source` with |
|
* the corresponding property values of a given object, returning `true` if |
|
* all predicates return truthy, else `false`. |
|
* |
|
* **Note:** The created function is equivalent to `_.conformsTo` with |
|
* `source` partially applied. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Util |
|
* @param {Object} source The object of property predicates to conform to. |
|
* @returns {Function} Returns the new spec function. |
|
* @example |
|
* |
|
* var objects = [ |
|
* { 'a': 2, 'b': 1 }, |
|
* { 'a': 1, 'b': 2 } |
|
* ]; |
|
* |
|
* _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } })); |
|
* // => [{ 'a': 1, 'b': 2 }] |
|
*/ |
|
function conforms(source) { |
|
return baseConforms(baseClone(source, CLONE_DEEP_FLAG)); |
|
} |
|
|
|
/** |
|
* 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; |
|
}; |
|
} |
|
|
|
/** |
|
* Checks `value` to determine whether a default value should be returned in |
|
* its place. The `defaultValue` is returned if `value` is `NaN`, `null`, |
|
* or `undefined`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.14.0 |
|
* @category Util |
|
* @param {*} value The value to check. |
|
* @param {*} defaultValue The default value. |
|
* @returns {*} Returns the resolved value. |
|
* @example |
|
* |
|
* _.defaultTo(1, 10); |
|
* // => 1 |
|
* |
|
* _.defaultTo(undefined, 10); |
|
* // => 10 |
|
*/ |
|
function defaultTo(value, defaultValue) { |
|
return (value == null || value !== value) ? defaultValue : value; |
|
} |
|
|
|
/** |
|
* Creates a function that returns the result of invoking the given functions |
|
* with the `this` binding of the created function, where each successive |
|
* invocation is supplied the return value of the previous. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Util |
|
* @param {...(Function|Function[])} [funcs] The functions to invoke. |
|
* @returns {Function} Returns the new composite function. |
|
* @see _.flowRight |
|
* @example |
|
* |
|
* function square(n) { |
|
* return n * n; |
|
* } |
|
* |
|
* var addSquare = _.flow([_.add, square]); |
|
* addSquare(1, 2); |
|
* // => 9 |
|
*/ |
|
var flow = createFlow(); |
|
|
|
/** |
|
* 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); |
|
|
|
/** |
|
* 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; |
|
} |
|
|
|
/** |
|
* Creates a function that invokes `func` with the arguments of the created |
|
* function. If `func` is a property name, the created function returns the |
|
* property value for a given element. If `func` is an array or object, the |
|
* created function returns `true` for elements that contain the equivalent |
|
* source properties, otherwise it returns `false`. |
|
* |
|
* @static |
|
* @since 4.0.0 |
|
* @memberOf _ |
|
* @category Util |
|
* @param {*} [func=_.identity] The value to convert to a callback. |
|
* @returns {Function} Returns the callback. |
|
* @example |
|
* |
|
* var users = [ |
|
* { 'user': 'barney', 'age': 36, 'active': true }, |
|
* { 'user': 'fred', 'age': 40, 'active': false } |
|
* ]; |
|
* |
|
* // The `_.matches` iteratee shorthand. |
|
* _.filter(users, _.iteratee({ 'user': 'barney', 'active': true })); |
|
* // => [{ 'user': 'barney', 'age': 36, 'active': true }] |
|
* |
|
* // The `_.matchesProperty` iteratee shorthand. |
|
* _.filter(users, _.iteratee(['user', 'fred'])); |
|
* // => [{ 'user': 'fred', 'age': 40 }] |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.map(users, _.iteratee('user')); |
|
* // => ['barney', 'fred'] |
|
* |
|
* // Create custom iteratee shorthands. |
|
* _.iteratee = _.wrap(_.iteratee, function(iteratee, func) { |
|
* return !_.isRegExp(func) ? iteratee(func) : function(string) { |
|
* return func.test(string); |
|
* }; |
|
* }); |
|
* |
|
* _.filter(['abc', 'def'], /ef/); |
|
* // => ['def'] |
|
*/ |
|
function iteratee(func) { |
|
return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG)); |
|
} |
|
|
|
/** |
|
* Creates a function that performs a partial deep comparison between a given |
|
* object and `source`, returning `true` if the given object has equivalent |
|
* property values, else `false`. |
|
* |
|
* **Note:** The created function is equivalent to `_.isMatch` with `source` |
|
* partially applied. |
|
* |
|
* Partial comparisons will match empty array and empty object `source` |
|
* values against any array or object value, respectively. See `_.isEqual` |
|
* for a list of supported value comparisons. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Util |
|
* @param {Object} source The object of property values to match. |
|
* @returns {Function} Returns the new spec function. |
|
* @example |
|
* |
|
* var objects = [ |
|
* { 'a': 1, 'b': 2, 'c': 3 }, |
|
* { 'a': 4, 'b': 5, 'c': 6 } |
|
* ]; |
|
* |
|
* _.filter(objects, _.matches({ 'a': 4, 'c': 6 })); |
|
* // => [{ 'a': 4, 'b': 5, 'c': 6 }] |
|
*/ |
|
function matches(source) { |
|
return baseMatches(baseClone(source, CLONE_DEEP_FLAG)); |
|
} |
|
|
|
/** |
|
* Creates a function that performs a partial deep comparison between the |
|
* value at `path` of a given object to `srcValue`, returning `true` if the |
|
* object value is equivalent, else `false`. |
|
* |
|
* **Note:** Partial comparisons will match empty array and empty object |
|
* `srcValue` values against any array or object value, respectively. See |
|
* `_.isEqual` for a list of supported value comparisons. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.2.0 |
|
* @category Util |
|
* @param {Array|string} path The path of the property to get. |
|
* @param {*} srcValue The value to match. |
|
* @returns {Function} Returns the new spec function. |
|
* @example |
|
* |
|
* var objects = [ |
|
* { 'a': 1, 'b': 2, 'c': 3 }, |
|
* { 'a': 4, 'b': 5, 'c': 6 } |
|
* ]; |
|
* |
|
* _.find(objects, _.matchesProperty('a', 4)); |
|
* // => { 'a': 4, 'b': 5, 'c': 6 } |
|
*/ |
|
function matchesProperty(path, srcValue) { |
|
return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG)); |
|
} |
|
|
|
/** |
|
* Creates a function that invokes the method at `path` of a given object. |
|
* Any additional arguments are provided to the invoked method. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.7.0 |
|
* @category Util |
|
* @param {Array|string} path The path of the method to invoke. |
|
* @param {...*} [args] The arguments to invoke the method with. |
|
* @returns {Function} Returns the new invoker function. |
|
* @example |
|
* |
|
* var objects = [ |
|
* { 'a': { 'b': _.constant(2) } }, |
|
* { 'a': { 'b': _.constant(1) } } |
|
* ]; |
|
* |
|
* _.map(objects, _.method('a.b')); |
|
* // => [2, 1] |
|
* |
|
* _.map(objects, _.method(['a', 'b'])); |
|
* // => [2, 1] |
|
*/ |
|
var method = baseRest(function(path, args) { |
|
return function(object) { |
|
return baseInvoke(object, path, args); |
|
}; |
|
}); |
|
|
|
/** |
|
* The opposite of `_.method`; this method creates a function that invokes |
|
* the method at a given path of `object`. Any additional arguments are |
|
* provided to the invoked method. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.7.0 |
|
* @category Util |
|
* @param {Object} object The object to query. |
|
* @param {...*} [args] The arguments to invoke the method with. |
|
* @returns {Function} Returns the new invoker function. |
|
* @example |
|
* |
|
* var array = _.times(3, _.constant), |
|
* object = { 'a': array, 'b': array, 'c': array }; |
|
* |
|
* _.map(['a[2]', 'c[0]'], _.methodOf(object)); |
|
* // => [2, 0] |
|
* |
|
* _.map([['a', '2'], ['c', '0']], _.methodOf(object)); |
|
* // => [2, 0] |
|
*/ |
|
var methodOf = baseRest(function(object, args) { |
|
return function(path) { |
|
return baseInvoke(object, path, args); |
|
}; |
|
}); |
|
|
|
/** |
|
* Adds all own enumerable string keyed function properties of a source |
|
* object to the destination object. If `object` is a function, then methods |
|
* are added to its prototype as well. |
|
* |
|
* **Note:** Use `_.runInContext` to create a pristine `lodash` function to |
|
* avoid conflicts caused by modifying the original. |
|
* |
|
* @static |
|
* @since 0.1.0 |
|
* @memberOf _ |
|
* @category Util |
|
* @param {Function|Object} [object=lodash] The destination object. |
|
* @param {Object} source The object of functions to add. |
|
* @param {Object} [options={}] The options object. |
|
* @param {boolean} [options.chain=true] Specify whether mixins are chainable. |
|
* @returns {Function|Object} Returns `object`. |
|
* @example |
|
* |
|
* function vowels(string) { |
|
* return _.filter(string, function(v) { |
|
* return /[aeiou]/i.test(v); |
|
* }); |
|
* } |
|
* |
|
* _.mixin({ 'vowels': vowels }); |
|
* _.vowels('fred'); |
|
* // => ['e'] |
|
* |
|
* _('fred').vowels().value(); |
|
* // => ['e'] |
|
* |
|
* _.mixin({ 'vowels': vowels }, { 'chain': false }); |
|
* _('fred').vowels(); |
|
* // => ['e'] |
|
*/ |
|
function mixin(object, source, options) { |
|
var props = keys(source), |
|
methodNames = baseFunctions(source, props); |
|
|
|
if (options == null && |
|
!(isObject(source) && (methodNames.length || !props.length))) { |
|
options = source; |
|
source = object; |
|
object = this; |
|
methodNames = baseFunctions(source, keys(source)); |
|
} |
|
var chain = !(isObject(options) && 'chain' in options) || !!options.chain, |
|
isFunc = isFunction(object); |
|
|
|
arrayEach(methodNames, function(methodName) { |
|
var func = source[methodName]; |
|
object[methodName] = func; |
|
if (isFunc) { |
|
object.prototype[methodName] = function() { |
|
var chainAll = this.__chain__; |
|
if (chain || chainAll) { |
|
var result = object(this.__wrapped__), |
|
actions = result.__actions__ = copyArray(this.__actions__); |
|
|
|
actions.push({ 'func': func, 'args': arguments, 'thisArg': object }); |
|
result.__chain__ = chainAll; |
|
return result; |
|
} |
|
return func.apply(object, arrayPush([this.value()], arguments)); |
|
}; |
|
} |
|
}); |
|
|
|
return object; |
|
} |
|
|
|
/** |
|
* Reverts the `_` variable to its previous value and returns a reference to |
|
* the `lodash` function. |
|
* |
|
* @static |
|
* @since 0.1.0 |
|
* @memberOf _ |
|
* @category Util |
|
* @returns {Function} Returns the `lodash` function. |
|
* @example |
|
* |
|
* var lodash = _.noConflict(); |
|
*/ |
|
function noConflict() { |
|
if (root._ === this) { |
|
root._ = oldDash; |
|
} |
|
return this; |
|
} |
|
|
|
/** |
|
* This method returns `undefined`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 2.3.0 |
|
* @category Util |
|
* @example |
|
* |
|
* _.times(2, _.noop); |
|
* // => [undefined, undefined] |
|
*/ |
|
function noop() { |
|
// No operation performed. |
|
} |
|
|
|
/** |
|
* Creates a function that gets the argument at index `n`. If `n` is negative, |
|
* the nth argument from the end is returned. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Util |
|
* @param {number} [n=0] The index of the argument to return. |
|
* @returns {Function} Returns the new pass-thru function. |
|
* @example |
|
* |
|
* var func = _.nthArg(1); |
|
* func('a', 'b', 'c', 'd'); |
|
* // => 'b' |
|
* |
|
* var func = _.nthArg(-2); |
|
* func('a', 'b', 'c', 'd'); |
|
* // => 'c' |
|
*/ |
|
function nthArg(n) { |
|
n = toInteger(n); |
|
return baseRest(function(args) { |
|
return baseNth(args, n); |
|
}); |
|
} |
|
|
|
/** |
|
* Creates a function that invokes `iteratees` with the arguments it receives |
|
* and returns their results. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Util |
|
* @param {...(Function|Function[])} [iteratees=[_.identity]] |
|
* The iteratees to invoke. |
|
* @returns {Function} Returns the new function. |
|
* @example |
|
* |
|
* var func = _.over([Math.max, Math.min]); |
|
* |
|
* func(1, 2, 3, 4); |
|
* // => [4, 1] |
|
*/ |
|
var over = createOver(arrayMap); |
|
|
|
/** |
|
* Creates a function that checks if **all** of the `predicates` return |
|
* truthy when invoked with the arguments it receives. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Util |
|
* @param {...(Function|Function[])} [predicates=[_.identity]] |
|
* The predicates to check. |
|
* @returns {Function} Returns the new function. |
|
* @example |
|
* |
|
* var func = _.overEvery([Boolean, isFinite]); |
|
* |
|
* func('1'); |
|
* // => true |
|
* |
|
* func(null); |
|
* // => false |
|
* |
|
* func(NaN); |
|
* // => false |
|
*/ |
|
var overEvery = createOver(arrayEvery); |
|
|
|
/** |
|
* Creates a function that checks if **any** of the `predicates` return |
|
* truthy when invoked with the arguments it receives. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Util |
|
* @param {...(Function|Function[])} [predicates=[_.identity]] |
|
* The predicates to check. |
|
* @returns {Function} Returns the new function. |
|
* @example |
|
* |
|
* var func = _.overSome([Boolean, isFinite]); |
|
* |
|
* func('1'); |
|
* // => true |
|
* |
|
* func(null); |
|
* // => true |
|
* |
|
* func(NaN); |
|
* // => false |
|
*/ |
|
var overSome = createOver(arraySome); |
|
|
|
/** |
|
* Creates a function that returns the value at `path` of a given object. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 2.4.0 |
|
* @category Util |
|
* @param {Array|string} path The path of the property to get. |
|
* @returns {Function} Returns the new accessor function. |
|
* @example |
|
* |
|
* var objects = [ |
|
* { 'a': { 'b': 2 } }, |
|
* { 'a': { 'b': 1 } } |
|
* ]; |
|
* |
|
* _.map(objects, _.property('a.b')); |
|
* // => [2, 1] |
|
* |
|
* _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); |
|
* // => [1, 2] |
|
*/ |
|
function property(path) { |
|
return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path); |
|
} |
|
|
|
/** |
|
* The opposite of `_.property`; this method creates a function that returns |
|
* the value at a given path of `object`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.0.0 |
|
* @category Util |
|
* @param {Object} object The object to query. |
|
* @returns {Function} Returns the new accessor function. |
|
* @example |
|
* |
|
* var array = [0, 1, 2], |
|
* object = { 'a': array, 'b': array, 'c': array }; |
|
* |
|
* _.map(['a[2]', 'c[0]'], _.propertyOf(object)); |
|
* // => [2, 0] |
|
* |
|
* _.map([['a', '2'], ['c', '0']], _.propertyOf(object)); |
|
* // => [2, 0] |
|
*/ |
|
function propertyOf(object) { |
|
return function(path) { |
|
return object == null ? undefined : baseGet(object, path); |
|
}; |
|
} |
|
|
|
/** |
|
* Creates an array of numbers (positive and/or negative) progressing from |
|
* `start` up to, but not including, `end`. A step of `-1` is used if a negative |
|
* `start` is specified without an `end` or `step`. If `end` is not specified, |
|
* it's set to `start` with `start` then set to `0`. |
|
* |
|
* **Note:** JavaScript follows the IEEE-754 standard for resolving |
|
* floating-point values which can produce unexpected results. |
|
* |
|
* @static |
|
* @since 0.1.0 |
|
* @memberOf _ |
|
* @category Util |
|
* @param {number} [start=0] The start of the range. |
|
* @param {number} end The end of the range. |
|
* @param {number} [step=1] The value to increment or decrement by. |
|
* @returns {Array} Returns the range of numbers. |
|
* @see _.inRange, _.rangeRight |
|
* @example |
|
* |
|
* _.range(4); |
|
* // => [0, 1, 2, 3] |
|
* |
|
* _.range(-4); |
|
* // => [0, -1, -2, -3] |
|
* |
|
* _.range(1, 5); |
|
* // => [1, 2, 3, 4] |
|
* |
|
* _.range(0, 20, 5); |
|
* // => [0, 5, 10, 15] |
|
* |
|
* _.range(0, -4, -1); |
|
* // => [0, -1, -2, -3] |
|
* |
|
* _.range(1, 4, 0); |
|
* // => [1, 1, 1] |
|
* |
|
* _.range(0); |
|
* // => [] |
|
*/ |
|
var range = createRange(); |
|
|
|
/** |
|
* This method is like `_.range` except that it populates values in |
|
* descending order. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Util |
|
* @param {number} [start=0] The start of the range. |
|
* @param {number} end The end of the range. |
|
* @param {number} [step=1] The value to increment or decrement by. |
|
* @returns {Array} Returns the range of numbers. |
|
* @see _.inRange, _.range |
|
* @example |
|
* |
|
* _.rangeRight(4); |
|
* // => [3, 2, 1, 0] |
|
* |
|
* _.rangeRight(-4); |
|
* // => [-3, -2, -1, 0] |
|
* |
|
* _.rangeRight(1, 5); |
|
* // => [4, 3, 2, 1] |
|
* |
|
* _.rangeRight(0, 20, 5); |
|
* // => [15, 10, 5, 0] |
|
* |
|
* _.rangeRight(0, -4, -1); |
|
* // => [-3, -2, -1, 0] |
|
* |
|
* _.rangeRight(1, 4, 0); |
|
* // => [1, 1, 1] |
|
* |
|
* _.rangeRight(0); |
|
* // => [] |
|
*/ |
|
var rangeRight = createRange(true); |
|
|
|
/** |
|
* This method returns a new empty array. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.13.0 |
|
* @category Util |
|
* @returns {Array} Returns the new empty array. |
|
* @example |
|
* |
|
* var arrays = _.times(2, _.stubArray); |
|
* |
|
* console.log(arrays); |
|
* // => [[], []] |
|
* |
|
* console.log(arrays[0] === arrays[1]); |
|
* // => false |
|
*/ |
|
function stubArray() { |
|
return []; |
|
} |
|
|
|
/** |
|
* This method returns `false`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.13.0 |
|
* @category Util |
|
* @returns {boolean} Returns `false`. |
|
* @example |
|
* |
|
* _.times(2, _.stubFalse); |
|
* // => [false, false] |
|
*/ |
|
function stubFalse() { |
|
return false; |
|
} |
|
|
|
/** |
|
* This method returns a new empty object. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.13.0 |
|
* @category Util |
|
* @returns {Object} Returns the new empty object. |
|
* @example |
|
* |
|
* var objects = _.times(2, _.stubObject); |
|
* |
|
* console.log(objects); |
|
* // => [{}, {}] |
|
* |
|
* console.log(objects[0] === objects[1]); |
|
* // => false |
|
*/ |
|
function stubObject() { |
|
return {}; |
|
} |
|
|
|
/** |
|
* This method returns an empty string. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.13.0 |
|
* @category Util |
|
* @returns {string} Returns the empty string. |
|
* @example |
|
* |
|
* _.times(2, _.stubString); |
|
* // => ['', ''] |
|
*/ |
|
function stubString() { |
|
return ''; |
|
} |
|
|
|
/** |
|
* This method returns `true`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.13.0 |
|
* @category Util |
|
* @returns {boolean} Returns `true`. |
|
* @example |
|
* |
|
* _.times(2, _.stubTrue); |
|
* // => [true, true] |
|
*/ |
|
function stubTrue() { |
|
return true; |
|
} |
|
|
|
/** |
|
* Invokes the iteratee `n` times, returning an array of the results of |
|
* each invocation. The iteratee is invoked with one argument; (index). |
|
* |
|
* @static |
|
* @since 0.1.0 |
|
* @memberOf _ |
|
* @category Util |
|
* @param {number} n The number of times to invoke `iteratee`. |
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration. |
|
* @returns {Array} Returns the array of results. |
|
* @example |
|
* |
|
* _.times(3, String); |
|
* // => ['0', '1', '2'] |
|
* |
|
* _.times(4, _.constant(0)); |
|
* // => [0, 0, 0, 0] |
|
*/ |
|
function times(n, iteratee) { |
|
n = toInteger(n); |
|
if (n < 1 || n > MAX_SAFE_INTEGER) { |
|
return []; |
|
} |
|
var index = MAX_ARRAY_LENGTH, |
|
length = nativeMin(n, MAX_ARRAY_LENGTH); |
|
|
|
iteratee = getIteratee(iteratee); |
|
n -= MAX_ARRAY_LENGTH; |
|
|
|
var result = baseTimes(length, iteratee); |
|
while (++index < n) { |
|
iteratee(index); |
|
} |
|
return result; |
|
} |
|
|
|
/** |
|
* Converts `value` to a property path array. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Util |
|
* @param {*} value The value to convert. |
|
* @returns {Array} Returns the new property path array. |
|
* @example |
|
* |
|
* _.toPath('a.b.c'); |
|
* // => ['a', 'b', 'c'] |
|
* |
|
* _.toPath('a[0].b.c'); |
|
* // => ['a', '0', 'b', 'c'] |
|
*/ |
|
function toPath(value) { |
|
if (isArray(value)) { |
|
return arrayMap(value, toKey); |
|
} |
|
return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value))); |
|
} |
|
|
|
/** |
|
* Generates a unique ID. If `prefix` is given, the ID is appended to it. |
|
* |
|
* @static |
|
* @since 0.1.0 |
|
* @memberOf _ |
|
* @category Util |
|
* @param {string} [prefix=''] The value to prefix the ID with. |
|
* @returns {string} Returns the unique ID. |
|
* @example |
|
* |
|
* _.uniqueId('contact_'); |
|
* // => 'contact_104' |
|
* |
|
* _.uniqueId(); |
|
* // => '105' |
|
*/ |
|
function uniqueId(prefix) { |
|
var id = ++idCounter; |
|
return toString(prefix) + id; |
|
} |
|
|
|
/*------------------------------------------------------------------------*/ |
|
|
|
/** |
|
* Adds two numbers. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.4.0 |
|
* @category Math |
|
* @param {number} augend The first number in an addition. |
|
* @param {number} addend The second number in an addition. |
|
* @returns {number} Returns the total. |
|
* @example |
|
* |
|
* _.add(6, 4); |
|
* // => 10 |
|
*/ |
|
var add = createMathOperation(function(augend, addend) { |
|
return augend + addend; |
|
}, 0); |
|
|
|
/** |
|
* Computes `number` rounded up to `precision`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.10.0 |
|
* @category Math |
|
* @param {number} number The number to round up. |
|
* @param {number} [precision=0] The precision to round up to. |
|
* @returns {number} Returns the rounded up number. |
|
* @example |
|
* |
|
* _.ceil(4.006); |
|
* // => 5 |
|
* |
|
* _.ceil(6.004, 2); |
|
* // => 6.01 |
|
* |
|
* _.ceil(6040, -2); |
|
* // => 6100 |
|
*/ |
|
var ceil = createRound('ceil'); |
|
|
|
/** |
|
* Divide two numbers. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.7.0 |
|
* @category Math |
|
* @param {number} dividend The first number in a division. |
|
* @param {number} divisor The second number in a division. |
|
* @returns {number} Returns the quotient. |
|
* @example |
|
* |
|
* _.divide(6, 4); |
|
* // => 1.5 |
|
*/ |
|
var divide = createMathOperation(function(dividend, divisor) { |
|
return dividend / divisor; |
|
}, 1); |
|
|
|
/** |
|
* Computes `number` rounded down to `precision`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.10.0 |
|
* @category Math |
|
* @param {number} number The number to round down. |
|
* @param {number} [precision=0] The precision to round down to. |
|
* @returns {number} Returns the rounded down number. |
|
* @example |
|
* |
|
* _.floor(4.006); |
|
* // => 4 |
|
* |
|
* _.floor(0.046, 2); |
|
* // => 0.04 |
|
* |
|
* _.floor(4060, -2); |
|
* // => 4000 |
|
*/ |
|
var floor = createRound('floor'); |
|
|
|
/** |
|
* Computes the maximum value of `array`. If `array` is empty or falsey, |
|
* `undefined` is returned. |
|
* |
|
* @static |
|
* @since 0.1.0 |
|
* @memberOf _ |
|
* @category Math |
|
* @param {Array} array The array to iterate over. |
|
* @returns {*} Returns the maximum value. |
|
* @example |
|
* |
|
* _.max([4, 2, 8, 6]); |
|
* // => 8 |
|
* |
|
* _.max([]); |
|
* // => undefined |
|
*/ |
|
function max(array) { |
|
return (array && array.length) |
|
? baseExtremum(array, identity, baseGt) |
|
: undefined; |
|
} |
|
|
|
/** |
|
* This method is like `_.max` except that it accepts `iteratee` which is |
|
* invoked for each element in `array` to generate the criterion by which |
|
* the value is ranked. The iteratee is invoked with one argument: (value). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Math |
|
* @param {Array} array The array to iterate over. |
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element. |
|
* @returns {*} Returns the maximum value. |
|
* @example |
|
* |
|
* var objects = [{ 'n': 1 }, { 'n': 2 }]; |
|
* |
|
* _.maxBy(objects, function(o) { return o.n; }); |
|
* // => { 'n': 2 } |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.maxBy(objects, 'n'); |
|
* // => { 'n': 2 } |
|
*/ |
|
function maxBy(array, iteratee) { |
|
return (array && array.length) |
|
? baseExtremum(array, getIteratee(iteratee, 2), baseGt) |
|
: undefined; |
|
} |
|
|
|
/** |
|
* Computes the mean of the values in `array`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Math |
|
* @param {Array} array The array to iterate over. |
|
* @returns {number} Returns the mean. |
|
* @example |
|
* |
|
* _.mean([4, 2, 8, 6]); |
|
* // => 5 |
|
*/ |
|
function mean(array) { |
|
return baseMean(array, identity); |
|
} |
|
|
|
/** |
|
* This method is like `_.mean` except that it accepts `iteratee` which is |
|
* invoked for each element in `array` to generate the value to be averaged. |
|
* The iteratee is invoked with one argument: (value). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.7.0 |
|
* @category Math |
|
* @param {Array} array The array to iterate over. |
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element. |
|
* @returns {number} Returns the mean. |
|
* @example |
|
* |
|
* var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }]; |
|
* |
|
* _.meanBy(objects, function(o) { return o.n; }); |
|
* // => 5 |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.meanBy(objects, 'n'); |
|
* // => 5 |
|
*/ |
|
function meanBy(array, iteratee) { |
|
return baseMean(array, getIteratee(iteratee, 2)); |
|
} |
|
|
|
/** |
|
* Computes the minimum value of `array`. If `array` is empty or falsey, |
|
* `undefined` is returned. |
|
* |
|
* @static |
|
* @since 0.1.0 |
|
* @memberOf _ |
|
* @category Math |
|
* @param {Array} array The array to iterate over. |
|
* @returns {*} Returns the minimum value. |
|
* @example |
|
* |
|
* _.min([4, 2, 8, 6]); |
|
* // => 2 |
|
* |
|
* _.min([]); |
|
* // => undefined |
|
*/ |
|
function min(array) { |
|
return (array && array.length) |
|
? baseExtremum(array, identity, baseLt) |
|
: undefined; |
|
} |
|
|
|
/** |
|
* This method is like `_.min` except that it accepts `iteratee` which is |
|
* invoked for each element in `array` to generate the criterion by which |
|
* the value is ranked. The iteratee is invoked with one argument: (value). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Math |
|
* @param {Array} array The array to iterate over. |
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element. |
|
* @returns {*} Returns the minimum value. |
|
* @example |
|
* |
|
* var objects = [{ 'n': 1 }, { 'n': 2 }]; |
|
* |
|
* _.minBy(objects, function(o) { return o.n; }); |
|
* // => { 'n': 1 } |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.minBy(objects, 'n'); |
|
* // => { 'n': 1 } |
|
*/ |
|
function minBy(array, iteratee) { |
|
return (array && array.length) |
|
? baseExtremum(array, getIteratee(iteratee, 2), baseLt) |
|
: undefined; |
|
} |
|
|
|
/** |
|
* Multiply two numbers. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.7.0 |
|
* @category Math |
|
* @param {number} multiplier The first number in a multiplication. |
|
* @param {number} multiplicand The second number in a multiplication. |
|
* @returns {number} Returns the product. |
|
* @example |
|
* |
|
* _.multiply(6, 4); |
|
* // => 24 |
|
*/ |
|
var multiply = createMathOperation(function(multiplier, multiplicand) { |
|
return multiplier * multiplicand; |
|
}, 1); |
|
|
|
/** |
|
* Computes `number` rounded to `precision`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.10.0 |
|
* @category Math |
|
* @param {number} number The number to round. |
|
* @param {number} [precision=0] The precision to round to. |
|
* @returns {number} Returns the rounded number. |
|
* @example |
|
* |
|
* _.round(4.006); |
|
* // => 4 |
|
* |
|
* _.round(4.006, 2); |
|
* // => 4.01 |
|
* |
|
* _.round(4060, -2); |
|
* // => 4100 |
|
*/ |
|
var round = createRound('round'); |
|
|
|
/** |
|
* Subtract two numbers. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Math |
|
* @param {number} minuend The first number in a subtraction. |
|
* @param {number} subtrahend The second number in a subtraction. |
|
* @returns {number} Returns the difference. |
|
* @example |
|
* |
|
* _.subtract(6, 4); |
|
* // => 2 |
|
*/ |
|
var subtract = createMathOperation(function(minuend, subtrahend) { |
|
return minuend - subtrahend; |
|
}, 0); |
|
|
|
/** |
|
* Computes the sum of the values in `array`. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 3.4.0 |
|
* @category Math |
|
* @param {Array} array The array to iterate over. |
|
* @returns {number} Returns the sum. |
|
* @example |
|
* |
|
* _.sum([4, 2, 8, 6]); |
|
* // => 20 |
|
*/ |
|
function sum(array) { |
|
return (array && array.length) |
|
? baseSum(array, identity) |
|
: 0; |
|
} |
|
|
|
/** |
|
* This method is like `_.sum` except that it accepts `iteratee` which is |
|
* invoked for each element in `array` to generate the value to be summed. |
|
* The iteratee is invoked with one argument: (value). |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @since 4.0.0 |
|
* @category Math |
|
* @param {Array} array The array to iterate over. |
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element. |
|
* @returns {number} Returns the sum. |
|
* @example |
|
* |
|
* var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }]; |
|
* |
|
* _.sumBy(objects, function(o) { return o.n; }); |
|
* // => 20 |
|
* |
|
* // The `_.property` iteratee shorthand. |
|
* _.sumBy(objects, 'n'); |
|
* // => 20 |
|
*/ |
|
function sumBy(array, iteratee) { |
|
return (array && array.length) |
|
? baseSum(array, getIteratee(iteratee, 2)) |
|
: 0; |
|
} |
|
|
|
/*------------------------------------------------------------------------*/ |
|
|
|
// Add methods that return wrapped values in chain sequences. |
|
lodash.after = after; |
|
lodash.ary = ary; |
|
lodash.assign = assign; |
|
lodash.assignIn = assignIn; |
|
lodash.assignInWith = assignInWith; |
|
lodash.assignWith = assignWith; |
|
lodash.at = at; |
|
lodash.before = before; |
|
lodash.bind = bind; |
|
lodash.bindAll = bindAll; |
|
lodash.bindKey = bindKey; |
|
lodash.castArray = castArray; |
|
lodash.chain = chain; |
|
lodash.chunk = chunk; |
|
lodash.compact = compact; |
|
lodash.concat = concat; |
|
lodash.cond = cond; |
|
lodash.conforms = conforms; |
|
lodash.constant = constant; |
|
lodash.countBy = countBy; |
|
lodash.create = create; |
|
lodash.curry = curry; |
|
lodash.curryRight = curryRight; |
|
lodash.debounce = debounce; |
|
lodash.defaults = defaults; |
|
lodash.defaultsDeep = defaultsDeep; |
|
lodash.defer = defer; |
|
lodash.delay = delay; |
|
lodash.difference = difference; |
|
lodash.differenceBy = differenceBy; |
|
lodash.differenceWith = differenceWith; |
|
lodash.drop = drop; |
|
lodash.dropRight = dropRight; |
|
lodash.dropRightWhile = dropRightWhile; |
|
lodash.dropWhile = dropWhile; |
|
lodash.fill = fill; |
|
lodash.filter = filter; |
|
lodash.flatMap = flatMap; |
|
lodash.flatMapDeep = flatMapDeep; |
|
lodash.flatMapDepth = flatMapDepth; |
|
lodash.flatten = flatten; |
|
lodash.flattenDeep = flattenDeep; |
|
lodash.flattenDepth = flattenDepth; |
|
lodash.flip = flip; |
|
lodash.flow = flow; |
|
lodash.flowRight = flowRight; |
|
lodash.fromPairs = fromPairs; |
|
lodash.functions = functions; |
|
lodash.functionsIn = functionsIn; |
|
lodash.groupBy = groupBy; |
|
lodash.initial = initial; |
|
lodash.intersection = intersection; |
|
lodash.intersectionBy = intersectionBy; |
|
lodash.intersectionWith = intersectionWith; |
|
lodash.invert = invert; |
|
lodash.invertBy = invertBy; |
|
lodash.invokeMap = invokeMap; |
|
lodash.iteratee = iteratee; |
|
lodash.keyBy = keyBy; |
|
lodash.keys = keys; |
|
lodash.keysIn = keysIn; |
|
lodash.map = map; |
|
lodash.mapKeys = mapKeys; |
|
lodash.mapValues = mapValues; |
|
lodash.matches = matches; |
|
lodash.matchesProperty = matchesProperty; |
|
lodash.memoize = memoize; |
|
lodash.merge = merge; |
|
lodash.mergeWith = mergeWith; |
|
lodash.method = method; |
|
lodash.methodOf = methodOf; |
|
lodash.mixin = mixin; |
|
lodash.negate = negate; |
|
lodash.nthArg = nthArg; |
|
lodash.omit = omit; |
|
lodash.omitBy = omitBy; |
|
lodash.once = once; |
|
lodash.orderBy = orderBy; |
|
lodash.over = over; |
|
lodash.overArgs = overArgs; |
|
lodash.overEvery = overEvery; |
|
lodash.overSome = overSome; |
|
lodash.partial = partial; |
|
lodash.partialRight = partialRight; |
|
lodash.partition = partition; |
|
lodash.pick = pick; |
|
lodash.pickBy = pickBy; |
|
lodash.property = property; |
|
lodash.propertyOf = propertyOf; |
|
lodash.pull = pull; |
|
lodash.pullAll = pullAll; |
|
lodash.pullAllBy = pullAllBy; |
|
lodash.pullAllWith = pullAllWith; |
|
lodash.pullAt = pullAt; |
|
lodash.range = range; |
|
lodash.rangeRight = rangeRight; |
|
lodash.rearg = rearg; |
|
lodash.reject = reject; |
|
lodash.remove = remove; |
|
lodash.rest = rest; |
|
lodash.reverse = reverse; |
|
lodash.sampleSize = sampleSize; |
|
lodash.set = set; |
|
lodash.setWith = setWith; |
|
lodash.shuffle = shuffle; |
|
lodash.slice = slice; |
|
lodash.sortBy = sortBy; |
|
lodash.sortedUniq = sortedUniq; |
|
lodash.sortedUniqBy = sortedUniqBy; |
|
lodash.split = split; |
|
lodash.spread = spread; |
|
lodash.tail = tail; |
|
lodash.take = take; |
|
lodash.takeRight = takeRight; |
|
lodash.takeRightWhile = takeRightWhile; |
|
lodash.takeWhile = takeWhile; |
|
lodash.tap = tap; |
|
lodash.throttle = throttle; |
|
lodash.thru = thru; |
|
lodash.toArray = toArray; |
|
lodash.toPairs = toPairs; |
|
lodash.toPairsIn = toPairsIn; |
|
lodash.toPath = toPath; |
|
lodash.toPlainObject = toPlainObject; |
|
lodash.transform = transform; |
|
lodash.unary = unary; |
|
lodash.union = union; |
|
lodash.unionBy = unionBy; |
|
lodash.unionWith = unionWith; |
|
lodash.uniq = uniq; |
|
lodash.uniqBy = uniqBy; |
|
lodash.uniqWith = uniqWith; |
|
lodash.unset = unset; |
|
lodash.unzip = unzip; |
|
lodash.unzipWith = unzipWith; |
|
lodash.update = update; |
|
lodash.updateWith = updateWith; |
|
lodash.values = values; |
|
lodash.valuesIn = valuesIn; |
|
lodash.without = without; |
|
lodash.words = words; |
|
lodash.wrap = wrap; |
|
lodash.xor = xor; |
|
lodash.xorBy = xorBy; |
|
lodash.xorWith = xorWith; |
|
lodash.zip = zip; |
|
lodash.zipObject = zipObject; |
|
lodash.zipObjectDeep = zipObjectDeep; |
|
lodash.zipWith = zipWith; |
|
|
|
// Add aliases. |
|
lodash.entries = toPairs; |
|
lodash.entriesIn = toPairsIn; |
|
lodash.extend = assignIn; |
|
lodash.extendWith = assignInWith; |
|
|
|
// Add methods to `lodash.prototype`. |
|
mixin(lodash, lodash); |
|
|
|
/*------------------------------------------------------------------------*/ |
|
|
|
// Add methods that return unwrapped values in chain sequences. |
|
lodash.add = add; |
|
lodash.attempt = attempt; |
|
lodash.camelCase = camelCase; |
|
lodash.capitalize = capitalize; |
|
lodash.ceil = ceil; |
|
lodash.clamp = clamp; |
|
lodash.clone = clone; |
|
lodash.cloneDeep = cloneDeep; |
|
lodash.cloneDeepWith = cloneDeepWith; |
|
lodash.cloneWith = cloneWith; |
|
lodash.conformsTo = conformsTo; |
|
lodash.deburr = deburr; |
|
lodash.defaultTo = defaultTo; |
|
lodash.divide = divide; |
|
lodash.endsWith = endsWith; |
|
lodash.eq = eq; |
|
lodash.escape = escape; |
|
lodash.escapeRegExp = escapeRegExp; |
|
lodash.every = every; |
|
lodash.find = find; |
|
lodash.findIndex = findIndex; |
|
lodash.findKey = findKey; |
|
lodash.findLast = findLast; |
|
lodash.findLastIndex = findLastIndex; |
|
lodash.findLastKey = findLastKey; |
|
lodash.floor = floor; |
|
lodash.forEach = forEach; |
|
lodash.forEachRight = forEachRight; |
|
lodash.forIn = forIn; |
|
lodash.forInRight = forInRight; |
|
lodash.forOwn = forOwn; |
|
lodash.forOwnRight = forOwnRight; |
|
lodash.get = get; |
|
lodash.gt = gt; |
|
lodash.gte = gte; |
|
lodash.has = has; |
|
lodash.hasIn = hasIn; |
|
lodash.head = head; |
|
lodash.identity = identity; |
|
lodash.includes = includes; |
|
lodash.indexOf = indexOf; |
|
lodash.inRange = inRange; |
|
lodash.invoke = invoke; |
|
lodash.isArguments = isArguments; |
|
lodash.isArray = isArray; |
|
lodash.isArrayBuffer = isArrayBuffer; |
|
lodash.isArrayLike = isArrayLike; |
|
lodash.isArrayLikeObject = isArrayLikeObject; |
|
lodash.isBoolean = isBoolean; |
|
lodash.isBuffer = isBuffer; |
|
lodash.isDate = isDate; |
|
lodash.isElement = isElement; |
|
lodash.isEmpty = isEmpty; |
|
lodash.isEqual = isEqual; |
|
lodash.isEqualWith = isEqualWith; |
|
lodash.isError = isError; |
|
lodash.isFinite = isFinite; |
|
lodash.isFunction = isFunction; |
|
lodash.isInteger = isInteger; |
|
lodash.isLength = isLength; |
|
lodash.isMap = isMap; |
|
lodash.isMatch = isMatch; |
|
lodash.isMatchWith = isMatchWith; |
|
lodash.isNaN = isNaN; |
|
lodash.isNative = isNative; |
|
lodash.isNil = isNil; |
|
lodash.isNull = isNull; |
|
lodash.isNumber = isNumber; |
|
lodash.isObject = isObject; |
|
lodash.isObjectLike = isObjectLike; |
|
lodash.isPlainObject = isPlainObject; |
|
lodash.isRegExp = isRegExp; |
|
lodash.isSafeInteger = isSafeInteger; |
|
lodash.isSet = isSet; |
|
lodash.isString = isString; |
|
lodash.isSymbol = isSymbol; |
|
lodash.isTypedArray = isTypedArray; |
|
lodash.isUndefined = isUndefined; |
|
lodash.isWeakMap = isWeakMap; |
|
lodash.isWeakSet = isWeakSet; |
|
lodash.join = join; |
|
lodash.kebabCase = kebabCase; |
|
lodash.last = last; |
|
lodash.lastIndexOf = lastIndexOf; |
|
lodash.lowerCase = lowerCase; |
|
lodash.lowerFirst = lowerFirst; |
|
lodash.lt = lt; |
|
lodash.lte = lte; |
|
lodash.max = max; |
|
lodash.maxBy = maxBy; |
|
lodash.mean = mean; |
|
lodash.meanBy = meanBy; |
|
lodash.min = min; |
|
lodash.minBy = minBy; |
|
lodash.stubArray = stubArray; |
|
lodash.stubFalse = stubFalse; |
|
lodash.stubObject = stubObject; |
|
lodash.stubString = stubString; |
|
lodash.stubTrue = stubTrue; |
|
lodash.multiply = multiply; |
|
lodash.nth = nth; |
|
lodash.noConflict = noConflict; |
|
lodash.noop = noop; |
|
lodash.now = now; |
|
lodash.pad = pad; |
|
lodash.padEnd = padEnd; |
|
lodash.padStart = padStart; |
|
lodash.parseInt = parseInt; |
|
lodash.random = random; |
|
lodash.reduce = reduce; |
|
lodash.reduceRight = reduceRight; |
|
lodash.repeat = repeat; |
|
lodash.replace = replace; |
|
lodash.result = result; |
|
lodash.round = round; |
|
lodash.runInContext = runInContext; |
|
lodash.sample = sample; |
|
lodash.size = size; |
|
lodash.snakeCase = snakeCase; |
|
lodash.some = some; |
|
lodash.sortedIndex = sortedIndex; |
|
lodash.sortedIndexBy = sortedIndexBy; |
|
lodash.sortedIndexOf = sortedIndexOf; |
|
lodash.sortedLastIndex = sortedLastIndex; |
|
lodash.sortedLastIndexBy = sortedLastIndexBy; |
|
lodash.sortedLastIndexOf = sortedLastIndexOf; |
|
lodash.startCase = startCase; |
|
lodash.startsWith = startsWith; |
|
lodash.subtract = subtract; |
|
lodash.sum = sum; |
|
lodash.sumBy = sumBy; |
|
lodash.template = template; |
|
lodash.times = times; |
|
lodash.toFinite = toFinite; |
|
lodash.toInteger = toInteger; |
|
lodash.toLength = toLength; |
|
lodash.toLower = toLower; |
|
lodash.toNumber = toNumber; |
|
lodash.toSafeInteger = toSafeInteger; |
|
lodash.toString = toString; |
|
lodash.toUpper = toUpper; |
|
lodash.trim = trim; |
|
lodash.trimEnd = trimEnd; |
|
lodash.trimStart = trimStart; |
|
lodash.truncate = truncate; |
|
lodash.unescape = unescape; |
|
lodash.uniqueId = uniqueId; |
|
lodash.upperCase = upperCase; |
|
lodash.upperFirst = upperFirst; |
|
|
|
// Add aliases. |
|
lodash.each = forEach; |
|
lodash.eachRight = forEachRight; |
|
lodash.first = head; |
|
|
|
mixin(lodash, (function() { |
|
var source = {}; |
|
baseForOwn(lodash, function(func, methodName) { |
|
if (!hasOwnProperty.call(lodash.prototype, methodName)) { |
|
source[methodName] = func; |
|
} |
|
}); |
|
return source; |
|
}()), { 'chain': false }); |
|
|
|
/*------------------------------------------------------------------------*/ |
|
|
|
/** |
|
* The semantic version number. |
|
* |
|
* @static |
|
* @memberOf _ |
|
* @type {string} |
|
*/ |
|
lodash.VERSION = VERSION; |
|
|
|
// Assign default placeholders. |
|
arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) { |
|
lodash[methodName].placeholder = lodash; |
|
}); |
|
|
|
// Add `LazyWrapper` methods for `_.drop` and `_.take` variants. |
|
arrayEach(['drop', 'take'], function(methodName, index) { |
|
LazyWrapper.prototype[methodName] = function(n) { |
|
n = n === undefined ? 1 : nativeMax(toInteger(n), 0); |
|
|
|
var result = (this.__filtered__ && !index) |
|
? new LazyWrapper(this) |
|
: this.clone(); |
|
|
|
if (result.__filtered__) { |
|
result.__takeCount__ = nativeMin(n, result.__takeCount__); |
|
} else { |
|
result.__views__.push({ |
|
'size': nativeMin(n, MAX_ARRAY_LENGTH), |
|
'type': methodName + (result.__dir__ < 0 ? 'Right' : '') |
|
}); |
|
} |
|
return result; |
|
}; |
|
|
|
LazyWrapper.prototype[methodName + 'Right'] = function(n) { |
|
return this.reverse()[methodName](n).reverse(); |
|
}; |
|
}); |
|
|
|
// Add `LazyWrapper` methods that accept an `iteratee` value. |
|
arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) { |
|
var type = index + 1, |
|
isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG; |
|
|
|
LazyWrapper.prototype[methodName] = function(iteratee) { |
|
var result = this.clone(); |
|
result.__iteratees__.push({ |
|
'iteratee': getIteratee(iteratee, 3), |
|
'type': type |
|
}); |
|
result.__filtered__ = result.__filtered__ || isFilter; |
|
return result; |
|
}; |
|
}); |
|
|
|
// Add `LazyWrapper` methods for `_.head` and `_.last`. |
|
arrayEach(['head', 'last'], function(methodName, index) { |
|
var takeName = 'take' + (index ? 'Right' : ''); |
|
|
|
LazyWrapper.prototype[methodName] = function() { |
|
return this[takeName](1).value()[0]; |
|
}; |
|
}); |
|
|
|
// Add `LazyWrapper` methods for `_.initial` and `_.tail`. |
|
arrayEach(['initial', 'tail'], function(methodName, index) { |
|
var dropName = 'drop' + (index ? '' : 'Right'); |
|
|
|
LazyWrapper.prototype[methodName] = function() { |
|
return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1); |
|
}; |
|
}); |
|
|
|
LazyWrapper.prototype.compact = function() { |
|
return this.filter(identity); |
|
}; |
|
|
|
LazyWrapper.prototype.find = function(predicate) { |
|
return this.filter(predicate).head(); |
|
}; |
|
|
|
LazyWrapper.prototype.findLast = function(predicate) { |
|
return this.reverse().find(predicate); |
|
}; |
|
|
|
LazyWrapper.prototype.invokeMap = baseRest(function(path, args) { |
|
if (typeof path == 'function') { |
|
return new LazyWrapper(this); |
|
} |
|
return this.map(function(value) { |
|
return baseInvoke(value, path, args); |
|
}); |
|
}); |
|
|
|
LazyWrapper.prototype.reject = function(predicate) { |
|
return this.filter(negate(getIteratee(predicate))); |
|
}; |
|
|
|
LazyWrapper.prototype.slice = function(start, end) { |
|
start = toInteger(start); |
|
|
|
var result = this; |
|
if (result.__filtered__ && (start > 0 || end < 0)) { |
|
return new LazyWrapper(result); |
|
} |
|
if (start < 0) { |
|
result = result.takeRight(-start); |
|
} else if (start) { |
|
result = result.drop(start); |
|
} |
|
if (end !== undefined) { |
|
end = toInteger(end); |
|
result = end < 0 ? result.dropRight(-end) : result.take(end - start); |
|
} |
|
return result; |
|
}; |
|
|
|
LazyWrapper.prototype.takeRightWhile = function(predicate) { |
|
return this.reverse().takeWhile(predicate).reverse(); |
|
}; |
|
|
|
LazyWrapper.prototype.toArray = function() { |
|
return this.take(MAX_ARRAY_LENGTH); |
|
}; |
|
|
|
// Add `LazyWrapper` methods to `lodash.prototype`. |
|
baseForOwn(LazyWrapper.prototype, function(func, methodName) { |
|
var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName), |
|
isTaker = /^(?:head|last)$/.test(methodName), |
|
lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName], |
|
retUnwrapped = isTaker || /^find/.test(methodName); |
|
|
|
if (!lodashFunc) { |
|
return; |
|
} |
|
lodash.prototype[methodName] = function() { |
|
var value = this.__wrapped__, |
|
args = isTaker ? [1] : arguments, |
|
isLazy = value instanceof LazyWrapper, |
|
iteratee = args[0], |
|
useLazy = isLazy || isArray(value); |
|
|
|
var interceptor = function(value) { |
|
var result = lodashFunc.apply(lodash, arrayPush([value], args)); |
|
return (isTaker && chainAll) ? result[0] : result; |
|
}; |
|
|
|
if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) { |
|
// Avoid lazy use if the iteratee has a "length" value other than `1`. |
|
isLazy = useLazy = false; |
|
} |
|
var chainAll = this.__chain__, |
|
isHybrid = !!this.__actions__.length, |
|
isUnwrapped = retUnwrapped && !chainAll, |
|
onlyLazy = isLazy && !isHybrid; |
|
|
|
if (!retUnwrapped && useLazy) { |
|
value = onlyLazy ? value : new LazyWrapper(this); |
|
var result = func.apply(value, args); |
|
result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined }); |
|
return new LodashWrapper(result, chainAll); |
|
} |
|
if (isUnwrapped && onlyLazy) { |
|
return func.apply(this, args); |
|
} |
|
result = this.thru(interceptor); |
|
return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result; |
|
}; |
|
}); |
|
|
|
// Add `Array` methods to `lodash.prototype`. |
|
arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) { |
|
var func = arrayProto[methodName], |
|
chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru', |
|
retUnwrapped = /^(?:pop|shift)$/.test(methodName); |
|
|
|
lodash.prototype[methodName] = function() { |
|
var args = arguments; |
|
if (retUnwrapped && !this.__chain__) { |
|
var value = this.value(); |
|
return func.apply(isArray(value) ? value : [], args); |
|
} |
|
return this[chainName](function(value) { |
|
return func.apply(isArray(value) ? value : [], args); |
|
}); |
|
}; |
|
}); |
|
|
|
// Map minified method names to their real names. |
|
baseForOwn(LazyWrapper.prototype, function(func, methodName) { |
|
var lodashFunc = lodash[methodName]; |
|
if (lodashFunc) { |
|
var key = (lodashFunc.name + ''), |
|
names = realNames[key] || (realNames[key] = []); |
|
|
|
names.push({ 'name': methodName, 'func': lodashFunc }); |
|
} |
|
}); |
|
|
|
realNames[createHybrid(undefined, WRAP_BIND_KEY_FLAG).name] = [{ |
|
'name': 'wrapper', |
|
'func': undefined |
|
}]; |
|
|
|
// Add methods to `LazyWrapper`. |
|
LazyWrapper.prototype.clone = lazyClone; |
|
LazyWrapper.prototype.reverse = lazyReverse; |
|
LazyWrapper.prototype.value = lazyValue; |
|
|
|
// Add chain sequence methods to the `lodash` wrapper. |
|
lodash.prototype.at = wrapperAt; |
|
lodash.prototype.chain = wrapperChain; |
|
lodash.prototype.commit = wrapperCommit; |
|
lodash.prototype.next = wrapperNext; |
|
lodash.prototype.plant = wrapperPlant; |
|
lodash.prototype.reverse = wrapperReverse; |
|
lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue; |
|
|
|
// Add lazy aliases. |
|
lodash.prototype.first = lodash.prototype.head; |
|
|
|
if (symIterator) { |
|
lodash.prototype[symIterator] = wrapperToIterator; |
|
} |
|
return lodash; |
|
}); |
|
|
|
/*--------------------------------------------------------------------------*/ |
|
|
|
// Export lodash. |
|
var _ = runInContext(); |
|
|
|
// Some AMD build optimizers, like r.js, check for condition patterns like: |
|
if (true) { |
|
// Expose Lodash on the global object to prevent errors when Lodash is |
|
// loaded by a script tag in the presence of an AMD loader. |
|
// See http://requirejs.org/docs/errors.html#mismatch for more details. |
|
// Use `_.noConflict` to remove Lodash from the global object. |
|
root._ = _; |
|
|
|
// Define as an anonymous module so, through path mapping, it can be |
|
// referenced as the "underscore" module. |
|
!(__WEBPACK_AMD_DEFINE_RESULT__ = (function() { |
|
return _; |
|
}).call(exports, __webpack_require__, exports, module), |
|
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); |
|
} |
|
// Check for `exports` after `define` in case a build optimizer adds it. |
|
else if (freeModule) { |
|
// Export for Node.js. |
|
(freeModule.exports = _)._ = _; |
|
// Export for CommonJS support. |
|
freeExports._ = _; |
|
} |
|
else { |
|
// Export to the global object. |
|
root._ = _; |
|
} |
|
}.call(this)); |
|
|
|
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1), __webpack_require__(15)(module))) |
|
|
|
/***/ }), |
|
/* 15 */ |
|
/***/ (function(module, exports) { |
|
|
|
module.exports = function(module) { |
|
if(!module.webpackPolyfill) { |
|
module.deprecate = function() {}; |
|
module.paths = []; |
|
// module.parent = undefined by default |
|
if(!module.children) module.children = []; |
|
Object.defineProperty(module, "loaded", { |
|
enumerable: true, |
|
get: function() { |
|
return module.l; |
|
} |
|
}); |
|
Object.defineProperty(module, "id", { |
|
enumerable: true, |
|
get: function() { |
|
return module.i; |
|
} |
|
}); |
|
module.webpackPolyfill = 1; |
|
} |
|
return module; |
|
}; |
|
|
|
|
|
/***/ }), |
|
/* 16 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
/*! |
|
* Bootstrap v4.1.1 (https://getbootstrap.com/) |
|
* Copyright 2011-2018 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) |
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
|
*/ |
|
(function (global, factory) { |
|
true ? factory(exports, __webpack_require__(4), __webpack_require__(3)) : |
|
typeof define === 'function' && define.amd ? define(['exports', 'jquery', 'popper.js'], factory) : |
|
(factory((global.bootstrap = {}),global.jQuery,global.Popper)); |
|
}(this, (function (exports,$,Popper) { 'use strict'; |
|
|
|
$ = $ && $.hasOwnProperty('default') ? $['default'] : $; |
|
Popper = Popper && Popper.hasOwnProperty('default') ? Popper['default'] : Popper; |
|
|
|
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); |
|
} |
|
} |
|
|
|
function _createClass(Constructor, protoProps, staticProps) { |
|
if (protoProps) _defineProperties(Constructor.prototype, protoProps); |
|
if (staticProps) _defineProperties(Constructor, staticProps); |
|
return Constructor; |
|
} |
|
|
|
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; |
|
} |
|
|
|
function _objectSpread(target) { |
|
for (var i = 1; i < arguments.length; i++) { |
|
var source = arguments[i] != null ? arguments[i] : {}; |
|
var ownKeys = Object.keys(source); |
|
|
|
if (typeof Object.getOwnPropertySymbols === 'function') { |
|
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { |
|
return Object.getOwnPropertyDescriptor(source, sym).enumerable; |
|
})); |
|
} |
|
|
|
ownKeys.forEach(function (key) { |
|
_defineProperty(target, key, source[key]); |
|
}); |
|
} |
|
|
|
return target; |
|
} |
|
|
|
function _inheritsLoose(subClass, superClass) { |
|
subClass.prototype = Object.create(superClass.prototype); |
|
subClass.prototype.constructor = subClass; |
|
subClass.__proto__ = superClass; |
|
} |
|
|
|
/** |
|
* -------------------------------------------------------------------------- |
|
* Bootstrap (v4.1.1): util.js |
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
|
* -------------------------------------------------------------------------- |
|
*/ |
|
|
|
var Util = function ($$$1) { |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Private TransitionEnd Helpers |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
var TRANSITION_END = 'transitionend'; |
|
var MAX_UID = 1000000; |
|
var MILLISECONDS_MULTIPLIER = 1000; // Shoutout AngusCroll (https://goo.gl/pxwQGp) |
|
|
|
function toType(obj) { |
|
return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase(); |
|
} |
|
|
|
function getSpecialTransitionEndEvent() { |
|
return { |
|
bindType: TRANSITION_END, |
|
delegateType: TRANSITION_END, |
|
handle: function handle(event) { |
|
if ($$$1(event.target).is(this)) { |
|
return event.handleObj.handler.apply(this, arguments); // eslint-disable-line prefer-rest-params |
|
} |
|
|
|
return undefined; // eslint-disable-line no-undefined |
|
} |
|
}; |
|
} |
|
|
|
function transitionEndEmulator(duration) { |
|
var _this = this; |
|
|
|
var called = false; |
|
$$$1(this).one(Util.TRANSITION_END, function () { |
|
called = true; |
|
}); |
|
setTimeout(function () { |
|
if (!called) { |
|
Util.triggerTransitionEnd(_this); |
|
} |
|
}, duration); |
|
return this; |
|
} |
|
|
|
function setTransitionEndSupport() { |
|
$$$1.fn.emulateTransitionEnd = transitionEndEmulator; |
|
$$$1.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent(); |
|
} |
|
/** |
|
* -------------------------------------------------------------------------- |
|
* Public Util Api |
|
* -------------------------------------------------------------------------- |
|
*/ |
|
|
|
|
|
var Util = { |
|
TRANSITION_END: 'bsTransitionEnd', |
|
getUID: function getUID(prefix) { |
|
do { |
|
// eslint-disable-next-line no-bitwise |
|
prefix += ~~(Math.random() * MAX_UID); // "~~" acts like a faster Math.floor() here |
|
} while (document.getElementById(prefix)); |
|
|
|
return prefix; |
|
}, |
|
getSelectorFromElement: function getSelectorFromElement(element) { |
|
var selector = element.getAttribute('data-target'); |
|
|
|
if (!selector || selector === '#') { |
|
selector = element.getAttribute('href') || ''; |
|
} |
|
|
|
try { |
|
var $selector = $$$1(document).find(selector); |
|
return $selector.length > 0 ? selector : null; |
|
} catch (err) { |
|
return null; |
|
} |
|
}, |
|
getTransitionDurationFromElement: function getTransitionDurationFromElement(element) { |
|
if (!element) { |
|
return 0; |
|
} // Get transition-duration of the element |
|
|
|
|
|
var transitionDuration = $$$1(element).css('transition-duration'); |
|
var floatTransitionDuration = parseFloat(transitionDuration); // Return 0 if element or transition duration is not found |
|
|
|
if (!floatTransitionDuration) { |
|
return 0; |
|
} // If multiple durations are defined, take the first |
|
|
|
|
|
transitionDuration = transitionDuration.split(',')[0]; |
|
return parseFloat(transitionDuration) * MILLISECONDS_MULTIPLIER; |
|
}, |
|
reflow: function reflow(element) { |
|
return element.offsetHeight; |
|
}, |
|
triggerTransitionEnd: function triggerTransitionEnd(element) { |
|
$$$1(element).trigger(TRANSITION_END); |
|
}, |
|
// TODO: Remove in v5 |
|
supportsTransitionEnd: function supportsTransitionEnd() { |
|
return Boolean(TRANSITION_END); |
|
}, |
|
isElement: function isElement(obj) { |
|
return (obj[0] || obj).nodeType; |
|
}, |
|
typeCheckConfig: function typeCheckConfig(componentName, config, configTypes) { |
|
for (var property in configTypes) { |
|
if (Object.prototype.hasOwnProperty.call(configTypes, property)) { |
|
var expectedTypes = configTypes[property]; |
|
var value = config[property]; |
|
var valueType = value && Util.isElement(value) ? 'element' : toType(value); |
|
|
|
if (!new RegExp(expectedTypes).test(valueType)) { |
|
throw new Error(componentName.toUpperCase() + ": " + ("Option \"" + property + "\" provided type \"" + valueType + "\" ") + ("but expected type \"" + expectedTypes + "\".")); |
|
} |
|
} |
|
} |
|
} |
|
}; |
|
setTransitionEndSupport(); |
|
return Util; |
|
}($); |
|
|
|
/** |
|
* -------------------------------------------------------------------------- |
|
* Bootstrap (v4.1.1): alert.js |
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
|
* -------------------------------------------------------------------------- |
|
*/ |
|
|
|
var Alert = function ($$$1) { |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Constants |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
var NAME = 'alert'; |
|
var VERSION = '4.1.1'; |
|
var DATA_KEY = 'bs.alert'; |
|
var EVENT_KEY = "." + DATA_KEY; |
|
var DATA_API_KEY = '.data-api'; |
|
var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; |
|
var Selector = { |
|
DISMISS: '[data-dismiss="alert"]' |
|
}; |
|
var Event = { |
|
CLOSE: "close" + EVENT_KEY, |
|
CLOSED: "closed" + EVENT_KEY, |
|
CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY |
|
}; |
|
var ClassName = { |
|
ALERT: 'alert', |
|
FADE: 'fade', |
|
SHOW: 'show' |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Class Definition |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
}; |
|
|
|
var Alert = |
|
/*#__PURE__*/ |
|
function () { |
|
function Alert(element) { |
|
this._element = element; |
|
} // Getters |
|
|
|
|
|
var _proto = Alert.prototype; |
|
|
|
// Public |
|
_proto.close = function close(element) { |
|
var rootElement = this._element; |
|
|
|
if (element) { |
|
rootElement = this._getRootElement(element); |
|
} |
|
|
|
var customEvent = this._triggerCloseEvent(rootElement); |
|
|
|
if (customEvent.isDefaultPrevented()) { |
|
return; |
|
} |
|
|
|
this._removeElement(rootElement); |
|
}; |
|
|
|
_proto.dispose = function dispose() { |
|
$$$1.removeData(this._element, DATA_KEY); |
|
this._element = null; |
|
}; // Private |
|
|
|
|
|
_proto._getRootElement = function _getRootElement(element) { |
|
var selector = Util.getSelectorFromElement(element); |
|
var parent = false; |
|
|
|
if (selector) { |
|
parent = $$$1(selector)[0]; |
|
} |
|
|
|
if (!parent) { |
|
parent = $$$1(element).closest("." + ClassName.ALERT)[0]; |
|
} |
|
|
|
return parent; |
|
}; |
|
|
|
_proto._triggerCloseEvent = function _triggerCloseEvent(element) { |
|
var closeEvent = $$$1.Event(Event.CLOSE); |
|
$$$1(element).trigger(closeEvent); |
|
return closeEvent; |
|
}; |
|
|
|
_proto._removeElement = function _removeElement(element) { |
|
var _this = this; |
|
|
|
$$$1(element).removeClass(ClassName.SHOW); |
|
|
|
if (!$$$1(element).hasClass(ClassName.FADE)) { |
|
this._destroyElement(element); |
|
|
|
return; |
|
} |
|
|
|
var transitionDuration = Util.getTransitionDurationFromElement(element); |
|
$$$1(element).one(Util.TRANSITION_END, function (event) { |
|
return _this._destroyElement(element, event); |
|
}).emulateTransitionEnd(transitionDuration); |
|
}; |
|
|
|
_proto._destroyElement = function _destroyElement(element) { |
|
$$$1(element).detach().trigger(Event.CLOSED).remove(); |
|
}; // Static |
|
|
|
|
|
Alert._jQueryInterface = function _jQueryInterface(config) { |
|
return this.each(function () { |
|
var $element = $$$1(this); |
|
var data = $element.data(DATA_KEY); |
|
|
|
if (!data) { |
|
data = new Alert(this); |
|
$element.data(DATA_KEY, data); |
|
} |
|
|
|
if (config === 'close') { |
|
data[config](this); |
|
} |
|
}); |
|
}; |
|
|
|
Alert._handleDismiss = function _handleDismiss(alertInstance) { |
|
return function (event) { |
|
if (event) { |
|
event.preventDefault(); |
|
} |
|
|
|
alertInstance.close(this); |
|
}; |
|
}; |
|
|
|
_createClass(Alert, null, [{ |
|
key: "VERSION", |
|
get: function get() { |
|
return VERSION; |
|
} |
|
}]); |
|
|
|
return Alert; |
|
}(); |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Data Api implementation |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
|
|
$$$1(document).on(Event.CLICK_DATA_API, Selector.DISMISS, Alert._handleDismiss(new Alert())); |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* jQuery |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
$$$1.fn[NAME] = Alert._jQueryInterface; |
|
$$$1.fn[NAME].Constructor = Alert; |
|
|
|
$$$1.fn[NAME].noConflict = function () { |
|
$$$1.fn[NAME] = JQUERY_NO_CONFLICT; |
|
return Alert._jQueryInterface; |
|
}; |
|
|
|
return Alert; |
|
}($); |
|
|
|
/** |
|
* -------------------------------------------------------------------------- |
|
* Bootstrap (v4.1.1): button.js |
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
|
* -------------------------------------------------------------------------- |
|
*/ |
|
|
|
var Button = function ($$$1) { |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Constants |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
var NAME = 'button'; |
|
var VERSION = '4.1.1'; |
|
var DATA_KEY = 'bs.button'; |
|
var EVENT_KEY = "." + DATA_KEY; |
|
var DATA_API_KEY = '.data-api'; |
|
var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; |
|
var ClassName = { |
|
ACTIVE: 'active', |
|
BUTTON: 'btn', |
|
FOCUS: 'focus' |
|
}; |
|
var Selector = { |
|
DATA_TOGGLE_CARROT: '[data-toggle^="button"]', |
|
DATA_TOGGLE: '[data-toggle="buttons"]', |
|
INPUT: 'input', |
|
ACTIVE: '.active', |
|
BUTTON: '.btn' |
|
}; |
|
var Event = { |
|
CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY, |
|
FOCUS_BLUR_DATA_API: "focus" + EVENT_KEY + DATA_API_KEY + " " + ("blur" + EVENT_KEY + DATA_API_KEY) |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Class Definition |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
}; |
|
|
|
var Button = |
|
/*#__PURE__*/ |
|
function () { |
|
function Button(element) { |
|
this._element = element; |
|
} // Getters |
|
|
|
|
|
var _proto = Button.prototype; |
|
|
|
// Public |
|
_proto.toggle = function toggle() { |
|
var triggerChangeEvent = true; |
|
var addAriaPressed = true; |
|
var rootElement = $$$1(this._element).closest(Selector.DATA_TOGGLE)[0]; |
|
|
|
if (rootElement) { |
|
var input = $$$1(this._element).find(Selector.INPUT)[0]; |
|
|
|
if (input) { |
|
if (input.type === 'radio') { |
|
if (input.checked && $$$1(this._element).hasClass(ClassName.ACTIVE)) { |
|
triggerChangeEvent = false; |
|
} else { |
|
var activeElement = $$$1(rootElement).find(Selector.ACTIVE)[0]; |
|
|
|
if (activeElement) { |
|
$$$1(activeElement).removeClass(ClassName.ACTIVE); |
|
} |
|
} |
|
} |
|
|
|
if (triggerChangeEvent) { |
|
if (input.hasAttribute('disabled') || rootElement.hasAttribute('disabled') || input.classList.contains('disabled') || rootElement.classList.contains('disabled')) { |
|
return; |
|
} |
|
|
|
input.checked = !$$$1(this._element).hasClass(ClassName.ACTIVE); |
|
$$$1(input).trigger('change'); |
|
} |
|
|
|
input.focus(); |
|
addAriaPressed = false; |
|
} |
|
} |
|
|
|
if (addAriaPressed) { |
|
this._element.setAttribute('aria-pressed', !$$$1(this._element).hasClass(ClassName.ACTIVE)); |
|
} |
|
|
|
if (triggerChangeEvent) { |
|
$$$1(this._element).toggleClass(ClassName.ACTIVE); |
|
} |
|
}; |
|
|
|
_proto.dispose = function dispose() { |
|
$$$1.removeData(this._element, DATA_KEY); |
|
this._element = null; |
|
}; // Static |
|
|
|
|
|
Button._jQueryInterface = function _jQueryInterface(config) { |
|
return this.each(function () { |
|
var data = $$$1(this).data(DATA_KEY); |
|
|
|
if (!data) { |
|
data = new Button(this); |
|
$$$1(this).data(DATA_KEY, data); |
|
} |
|
|
|
if (config === 'toggle') { |
|
data[config](); |
|
} |
|
}); |
|
}; |
|
|
|
_createClass(Button, null, [{ |
|
key: "VERSION", |
|
get: function get() { |
|
return VERSION; |
|
} |
|
}]); |
|
|
|
return Button; |
|
}(); |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Data Api implementation |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
|
|
$$$1(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE_CARROT, function (event) { |
|
event.preventDefault(); |
|
var button = event.target; |
|
|
|
if (!$$$1(button).hasClass(ClassName.BUTTON)) { |
|
button = $$$1(button).closest(Selector.BUTTON); |
|
} |
|
|
|
Button._jQueryInterface.call($$$1(button), 'toggle'); |
|
}).on(Event.FOCUS_BLUR_DATA_API, Selector.DATA_TOGGLE_CARROT, function (event) { |
|
var button = $$$1(event.target).closest(Selector.BUTTON)[0]; |
|
$$$1(button).toggleClass(ClassName.FOCUS, /^focus(in)?$/.test(event.type)); |
|
}); |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* jQuery |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
$$$1.fn[NAME] = Button._jQueryInterface; |
|
$$$1.fn[NAME].Constructor = Button; |
|
|
|
$$$1.fn[NAME].noConflict = function () { |
|
$$$1.fn[NAME] = JQUERY_NO_CONFLICT; |
|
return Button._jQueryInterface; |
|
}; |
|
|
|
return Button; |
|
}($); |
|
|
|
/** |
|
* -------------------------------------------------------------------------- |
|
* Bootstrap (v4.1.1): carousel.js |
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
|
* -------------------------------------------------------------------------- |
|
*/ |
|
|
|
var Carousel = function ($$$1) { |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Constants |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
var NAME = 'carousel'; |
|
var VERSION = '4.1.1'; |
|
var DATA_KEY = 'bs.carousel'; |
|
var EVENT_KEY = "." + DATA_KEY; |
|
var DATA_API_KEY = '.data-api'; |
|
var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; |
|
var ARROW_LEFT_KEYCODE = 37; // KeyboardEvent.which value for left arrow key |
|
|
|
var ARROW_RIGHT_KEYCODE = 39; // KeyboardEvent.which value for right arrow key |
|
|
|
var TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch |
|
|
|
var Default = { |
|
interval: 5000, |
|
keyboard: true, |
|
slide: false, |
|
pause: 'hover', |
|
wrap: true |
|
}; |
|
var DefaultType = { |
|
interval: '(number|boolean)', |
|
keyboard: 'boolean', |
|
slide: '(boolean|string)', |
|
pause: '(string|boolean)', |
|
wrap: 'boolean' |
|
}; |
|
var Direction = { |
|
NEXT: 'next', |
|
PREV: 'prev', |
|
LEFT: 'left', |
|
RIGHT: 'right' |
|
}; |
|
var Event = { |
|
SLIDE: "slide" + EVENT_KEY, |
|
SLID: "slid" + EVENT_KEY, |
|
KEYDOWN: "keydown" + EVENT_KEY, |
|
MOUSEENTER: "mouseenter" + EVENT_KEY, |
|
MOUSELEAVE: "mouseleave" + EVENT_KEY, |
|
TOUCHEND: "touchend" + EVENT_KEY, |
|
LOAD_DATA_API: "load" + EVENT_KEY + DATA_API_KEY, |
|
CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY |
|
}; |
|
var ClassName = { |
|
CAROUSEL: 'carousel', |
|
ACTIVE: 'active', |
|
SLIDE: 'slide', |
|
RIGHT: 'carousel-item-right', |
|
LEFT: 'carousel-item-left', |
|
NEXT: 'carousel-item-next', |
|
PREV: 'carousel-item-prev', |
|
ITEM: 'carousel-item' |
|
}; |
|
var Selector = { |
|
ACTIVE: '.active', |
|
ACTIVE_ITEM: '.active.carousel-item', |
|
ITEM: '.carousel-item', |
|
NEXT_PREV: '.carousel-item-next, .carousel-item-prev', |
|
INDICATORS: '.carousel-indicators', |
|
DATA_SLIDE: '[data-slide], [data-slide-to]', |
|
DATA_RIDE: '[data-ride="carousel"]' |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Class Definition |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
}; |
|
|
|
var Carousel = |
|
/*#__PURE__*/ |
|
function () { |
|
function Carousel(element, config) { |
|
this._items = null; |
|
this._interval = null; |
|
this._activeElement = null; |
|
this._isPaused = false; |
|
this._isSliding = false; |
|
this.touchTimeout = null; |
|
this._config = this._getConfig(config); |
|
this._element = $$$1(element)[0]; |
|
this._indicatorsElement = $$$1(this._element).find(Selector.INDICATORS)[0]; |
|
|
|
this._addEventListeners(); |
|
} // Getters |
|
|
|
|
|
var _proto = Carousel.prototype; |
|
|
|
// Public |
|
_proto.next = function next() { |
|
if (!this._isSliding) { |
|
this._slide(Direction.NEXT); |
|
} |
|
}; |
|
|
|
_proto.nextWhenVisible = function nextWhenVisible() { |
|
// Don't call next when the page isn't visible |
|
// or the carousel or its parent isn't visible |
|
if (!document.hidden && $$$1(this._element).is(':visible') && $$$1(this._element).css('visibility') !== 'hidden') { |
|
this.next(); |
|
} |
|
}; |
|
|
|
_proto.prev = function prev() { |
|
if (!this._isSliding) { |
|
this._slide(Direction.PREV); |
|
} |
|
}; |
|
|
|
_proto.pause = function pause(event) { |
|
if (!event) { |
|
this._isPaused = true; |
|
} |
|
|
|
if ($$$1(this._element).find(Selector.NEXT_PREV)[0]) { |
|
Util.triggerTransitionEnd(this._element); |
|
this.cycle(true); |
|
} |
|
|
|
clearInterval(this._interval); |
|
this._interval = null; |
|
}; |
|
|
|
_proto.cycle = function cycle(event) { |
|
if (!event) { |
|
this._isPaused = false; |
|
} |
|
|
|
if (this._interval) { |
|
clearInterval(this._interval); |
|
this._interval = null; |
|
} |
|
|
|
if (this._config.interval && !this._isPaused) { |
|
this._interval = setInterval((document.visibilityState ? this.nextWhenVisible : this.next).bind(this), this._config.interval); |
|
} |
|
}; |
|
|
|
_proto.to = function to(index) { |
|
var _this = this; |
|
|
|
this._activeElement = $$$1(this._element).find(Selector.ACTIVE_ITEM)[0]; |
|
|
|
var activeIndex = this._getItemIndex(this._activeElement); |
|
|
|
if (index > this._items.length - 1 || index < 0) { |
|
return; |
|
} |
|
|
|
if (this._isSliding) { |
|
$$$1(this._element).one(Event.SLID, function () { |
|
return _this.to(index); |
|
}); |
|
return; |
|
} |
|
|
|
if (activeIndex === index) { |
|
this.pause(); |
|
this.cycle(); |
|
return; |
|
} |
|
|
|
var direction = index > activeIndex ? Direction.NEXT : Direction.PREV; |
|
|
|
this._slide(direction, this._items[index]); |
|
}; |
|
|
|
_proto.dispose = function dispose() { |
|
$$$1(this._element).off(EVENT_KEY); |
|
$$$1.removeData(this._element, DATA_KEY); |
|
this._items = null; |
|
this._config = null; |
|
this._element = null; |
|
this._interval = null; |
|
this._isPaused = null; |
|
this._isSliding = null; |
|
this._activeElement = null; |
|
this._indicatorsElement = null; |
|
}; // Private |
|
|
|
|
|
_proto._getConfig = function _getConfig(config) { |
|
config = _objectSpread({}, Default, config); |
|
Util.typeCheckConfig(NAME, config, DefaultType); |
|
return config; |
|
}; |
|
|
|
_proto._addEventListeners = function _addEventListeners() { |
|
var _this2 = this; |
|
|
|
if (this._config.keyboard) { |
|
$$$1(this._element).on(Event.KEYDOWN, function (event) { |
|
return _this2._keydown(event); |
|
}); |
|
} |
|
|
|
if (this._config.pause === 'hover') { |
|
$$$1(this._element).on(Event.MOUSEENTER, function (event) { |
|
return _this2.pause(event); |
|
}).on(Event.MOUSELEAVE, function (event) { |
|
return _this2.cycle(event); |
|
}); |
|
|
|
if ('ontouchstart' in document.documentElement) { |
|
// If it's a touch-enabled device, mouseenter/leave are fired as |
|
// part of the mouse compatibility events on first tap - the carousel |
|
// would stop cycling until user tapped out of it; |
|
// here, we listen for touchend, explicitly pause the carousel |
|
// (as if it's the second time we tap on it, mouseenter compat event |
|
// is NOT fired) and after a timeout (to allow for mouse compatibility |
|
// events to fire) we explicitly restart cycling |
|
$$$1(this._element).on(Event.TOUCHEND, function () { |
|
_this2.pause(); |
|
|
|
if (_this2.touchTimeout) { |
|
clearTimeout(_this2.touchTimeout); |
|
} |
|
|
|
_this2.touchTimeout = setTimeout(function (event) { |
|
return _this2.cycle(event); |
|
}, TOUCHEVENT_COMPAT_WAIT + _this2._config.interval); |
|
}); |
|
} |
|
} |
|
}; |
|
|
|
_proto._keydown = function _keydown(event) { |
|
if (/input|textarea/i.test(event.target.tagName)) { |
|
return; |
|
} |
|
|
|
switch (event.which) { |
|
case ARROW_LEFT_KEYCODE: |
|
event.preventDefault(); |
|
this.prev(); |
|
break; |
|
|
|
case ARROW_RIGHT_KEYCODE: |
|
event.preventDefault(); |
|
this.next(); |
|
break; |
|
|
|
default: |
|
} |
|
}; |
|
|
|
_proto._getItemIndex = function _getItemIndex(element) { |
|
this._items = $$$1.makeArray($$$1(element).parent().find(Selector.ITEM)); |
|
return this._items.indexOf(element); |
|
}; |
|
|
|
_proto._getItemByDirection = function _getItemByDirection(direction, activeElement) { |
|
var isNextDirection = direction === Direction.NEXT; |
|
var isPrevDirection = direction === Direction.PREV; |
|
|
|
var activeIndex = this._getItemIndex(activeElement); |
|
|
|
var lastItemIndex = this._items.length - 1; |
|
var isGoingToWrap = isPrevDirection && activeIndex === 0 || isNextDirection && activeIndex === lastItemIndex; |
|
|
|
if (isGoingToWrap && !this._config.wrap) { |
|
return activeElement; |
|
} |
|
|
|
var delta = direction === Direction.PREV ? -1 : 1; |
|
var itemIndex = (activeIndex + delta) % this._items.length; |
|
return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex]; |
|
}; |
|
|
|
_proto._triggerSlideEvent = function _triggerSlideEvent(relatedTarget, eventDirectionName) { |
|
var targetIndex = this._getItemIndex(relatedTarget); |
|
|
|
var fromIndex = this._getItemIndex($$$1(this._element).find(Selector.ACTIVE_ITEM)[0]); |
|
|
|
var slideEvent = $$$1.Event(Event.SLIDE, { |
|
relatedTarget: relatedTarget, |
|
direction: eventDirectionName, |
|
from: fromIndex, |
|
to: targetIndex |
|
}); |
|
$$$1(this._element).trigger(slideEvent); |
|
return slideEvent; |
|
}; |
|
|
|
_proto._setActiveIndicatorElement = function _setActiveIndicatorElement(element) { |
|
if (this._indicatorsElement) { |
|
$$$1(this._indicatorsElement).find(Selector.ACTIVE).removeClass(ClassName.ACTIVE); |
|
|
|
var nextIndicator = this._indicatorsElement.children[this._getItemIndex(element)]; |
|
|
|
if (nextIndicator) { |
|
$$$1(nextIndicator).addClass(ClassName.ACTIVE); |
|
} |
|
} |
|
}; |
|
|
|
_proto._slide = function _slide(direction, element) { |
|
var _this3 = this; |
|
|
|
var activeElement = $$$1(this._element).find(Selector.ACTIVE_ITEM)[0]; |
|
|
|
var activeElementIndex = this._getItemIndex(activeElement); |
|
|
|
var nextElement = element || activeElement && this._getItemByDirection(direction, activeElement); |
|
|
|
var nextElementIndex = this._getItemIndex(nextElement); |
|
|
|
var isCycling = Boolean(this._interval); |
|
var directionalClassName; |
|
var orderClassName; |
|
var eventDirectionName; |
|
|
|
if (direction === Direction.NEXT) { |
|
directionalClassName = ClassName.LEFT; |
|
orderClassName = ClassName.NEXT; |
|
eventDirectionName = Direction.LEFT; |
|
} else { |
|
directionalClassName = ClassName.RIGHT; |
|
orderClassName = ClassName.PREV; |
|
eventDirectionName = Direction.RIGHT; |
|
} |
|
|
|
if (nextElement && $$$1(nextElement).hasClass(ClassName.ACTIVE)) { |
|
this._isSliding = false; |
|
return; |
|
} |
|
|
|
var slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName); |
|
|
|
if (slideEvent.isDefaultPrevented()) { |
|
return; |
|
} |
|
|
|
if (!activeElement || !nextElement) { |
|
// Some weirdness is happening, so we bail |
|
return; |
|
} |
|
|
|
this._isSliding = true; |
|
|
|
if (isCycling) { |
|
this.pause(); |
|
} |
|
|
|
this._setActiveIndicatorElement(nextElement); |
|
|
|
var slidEvent = $$$1.Event(Event.SLID, { |
|
relatedTarget: nextElement, |
|
direction: eventDirectionName, |
|
from: activeElementIndex, |
|
to: nextElementIndex |
|
}); |
|
|
|
if ($$$1(this._element).hasClass(ClassName.SLIDE)) { |
|
$$$1(nextElement).addClass(orderClassName); |
|
Util.reflow(nextElement); |
|
$$$1(activeElement).addClass(directionalClassName); |
|
$$$1(nextElement).addClass(directionalClassName); |
|
var transitionDuration = Util.getTransitionDurationFromElement(activeElement); |
|
$$$1(activeElement).one(Util.TRANSITION_END, function () { |
|
$$$1(nextElement).removeClass(directionalClassName + " " + orderClassName).addClass(ClassName.ACTIVE); |
|
$$$1(activeElement).removeClass(ClassName.ACTIVE + " " + orderClassName + " " + directionalClassName); |
|
_this3._isSliding = false; |
|
setTimeout(function () { |
|
return $$$1(_this3._element).trigger(slidEvent); |
|
}, 0); |
|
}).emulateTransitionEnd(transitionDuration); |
|
} else { |
|
$$$1(activeElement).removeClass(ClassName.ACTIVE); |
|
$$$1(nextElement).addClass(ClassName.ACTIVE); |
|
this._isSliding = false; |
|
$$$1(this._element).trigger(slidEvent); |
|
} |
|
|
|
if (isCycling) { |
|
this.cycle(); |
|
} |
|
}; // Static |
|
|
|
|
|
Carousel._jQueryInterface = function _jQueryInterface(config) { |
|
return this.each(function () { |
|
var data = $$$1(this).data(DATA_KEY); |
|
|
|
var _config = _objectSpread({}, Default, $$$1(this).data()); |
|
|
|
if (typeof config === 'object') { |
|
_config = _objectSpread({}, _config, config); |
|
} |
|
|
|
var action = typeof config === 'string' ? config : _config.slide; |
|
|
|
if (!data) { |
|
data = new Carousel(this, _config); |
|
$$$1(this).data(DATA_KEY, data); |
|
} |
|
|
|
if (typeof config === 'number') { |
|
data.to(config); |
|
} else if (typeof action === 'string') { |
|
if (typeof data[action] === 'undefined') { |
|
throw new TypeError("No method named \"" + action + "\""); |
|
} |
|
|
|
data[action](); |
|
} else if (_config.interval) { |
|
data.pause(); |
|
data.cycle(); |
|
} |
|
}); |
|
}; |
|
|
|
Carousel._dataApiClickHandler = function _dataApiClickHandler(event) { |
|
var selector = Util.getSelectorFromElement(this); |
|
|
|
if (!selector) { |
|
return; |
|
} |
|
|
|
var target = $$$1(selector)[0]; |
|
|
|
if (!target || !$$$1(target).hasClass(ClassName.CAROUSEL)) { |
|
return; |
|
} |
|
|
|
var config = _objectSpread({}, $$$1(target).data(), $$$1(this).data()); |
|
|
|
var slideIndex = this.getAttribute('data-slide-to'); |
|
|
|
if (slideIndex) { |
|
config.interval = false; |
|
} |
|
|
|
Carousel._jQueryInterface.call($$$1(target), config); |
|
|
|
if (slideIndex) { |
|
$$$1(target).data(DATA_KEY).to(slideIndex); |
|
} |
|
|
|
event.preventDefault(); |
|
}; |
|
|
|
_createClass(Carousel, null, [{ |
|
key: "VERSION", |
|
get: function get() { |
|
return VERSION; |
|
} |
|
}, { |
|
key: "Default", |
|
get: function get() { |
|
return Default; |
|
} |
|
}]); |
|
|
|
return Carousel; |
|
}(); |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Data Api implementation |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
|
|
$$$1(document).on(Event.CLICK_DATA_API, Selector.DATA_SLIDE, Carousel._dataApiClickHandler); |
|
$$$1(window).on(Event.LOAD_DATA_API, function () { |
|
$$$1(Selector.DATA_RIDE).each(function () { |
|
var $carousel = $$$1(this); |
|
|
|
Carousel._jQueryInterface.call($carousel, $carousel.data()); |
|
}); |
|
}); |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* jQuery |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
$$$1.fn[NAME] = Carousel._jQueryInterface; |
|
$$$1.fn[NAME].Constructor = Carousel; |
|
|
|
$$$1.fn[NAME].noConflict = function () { |
|
$$$1.fn[NAME] = JQUERY_NO_CONFLICT; |
|
return Carousel._jQueryInterface; |
|
}; |
|
|
|
return Carousel; |
|
}($); |
|
|
|
/** |
|
* -------------------------------------------------------------------------- |
|
* Bootstrap (v4.1.1): collapse.js |
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
|
* -------------------------------------------------------------------------- |
|
*/ |
|
|
|
var Collapse = function ($$$1) { |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Constants |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
var NAME = 'collapse'; |
|
var VERSION = '4.1.1'; |
|
var DATA_KEY = 'bs.collapse'; |
|
var EVENT_KEY = "." + DATA_KEY; |
|
var DATA_API_KEY = '.data-api'; |
|
var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; |
|
var Default = { |
|
toggle: true, |
|
parent: '' |
|
}; |
|
var DefaultType = { |
|
toggle: 'boolean', |
|
parent: '(string|element)' |
|
}; |
|
var Event = { |
|
SHOW: "show" + EVENT_KEY, |
|
SHOWN: "shown" + EVENT_KEY, |
|
HIDE: "hide" + EVENT_KEY, |
|
HIDDEN: "hidden" + EVENT_KEY, |
|
CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY |
|
}; |
|
var ClassName = { |
|
SHOW: 'show', |
|
COLLAPSE: 'collapse', |
|
COLLAPSING: 'collapsing', |
|
COLLAPSED: 'collapsed' |
|
}; |
|
var Dimension = { |
|
WIDTH: 'width', |
|
HEIGHT: 'height' |
|
}; |
|
var Selector = { |
|
ACTIVES: '.show, .collapsing', |
|
DATA_TOGGLE: '[data-toggle="collapse"]' |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Class Definition |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
}; |
|
|
|
var Collapse = |
|
/*#__PURE__*/ |
|
function () { |
|
function Collapse(element, config) { |
|
this._isTransitioning = false; |
|
this._element = element; |
|
this._config = this._getConfig(config); |
|
this._triggerArray = $$$1.makeArray($$$1("[data-toggle=\"collapse\"][href=\"#" + element.id + "\"]," + ("[data-toggle=\"collapse\"][data-target=\"#" + element.id + "\"]"))); |
|
var tabToggles = $$$1(Selector.DATA_TOGGLE); |
|
|
|
for (var i = 0; i < tabToggles.length; i++) { |
|
var elem = tabToggles[i]; |
|
var selector = Util.getSelectorFromElement(elem); |
|
|
|
if (selector !== null && $$$1(selector).filter(element).length > 0) { |
|
this._selector = selector; |
|
|
|
this._triggerArray.push(elem); |
|
} |
|
} |
|
|
|
this._parent = this._config.parent ? this._getParent() : null; |
|
|
|
if (!this._config.parent) { |
|
this._addAriaAndCollapsedClass(this._element, this._triggerArray); |
|
} |
|
|
|
if (this._config.toggle) { |
|
this.toggle(); |
|
} |
|
} // Getters |
|
|
|
|
|
var _proto = Collapse.prototype; |
|
|
|
// Public |
|
_proto.toggle = function toggle() { |
|
if ($$$1(this._element).hasClass(ClassName.SHOW)) { |
|
this.hide(); |
|
} else { |
|
this.show(); |
|
} |
|
}; |
|
|
|
_proto.show = function show() { |
|
var _this = this; |
|
|
|
if (this._isTransitioning || $$$1(this._element).hasClass(ClassName.SHOW)) { |
|
return; |
|
} |
|
|
|
var actives; |
|
var activesData; |
|
|
|
if (this._parent) { |
|
actives = $$$1.makeArray($$$1(this._parent).find(Selector.ACTIVES).filter("[data-parent=\"" + this._config.parent + "\"]")); |
|
|
|
if (actives.length === 0) { |
|
actives = null; |
|
} |
|
} |
|
|
|
if (actives) { |
|
activesData = $$$1(actives).not(this._selector).data(DATA_KEY); |
|
|
|
if (activesData && activesData._isTransitioning) { |
|
return; |
|
} |
|
} |
|
|
|
var startEvent = $$$1.Event(Event.SHOW); |
|
$$$1(this._element).trigger(startEvent); |
|
|
|
if (startEvent.isDefaultPrevented()) { |
|
return; |
|
} |
|
|
|
if (actives) { |
|
Collapse._jQueryInterface.call($$$1(actives).not(this._selector), 'hide'); |
|
|
|
if (!activesData) { |
|
$$$1(actives).data(DATA_KEY, null); |
|
} |
|
} |
|
|
|
var dimension = this._getDimension(); |
|
|
|
$$$1(this._element).removeClass(ClassName.COLLAPSE).addClass(ClassName.COLLAPSING); |
|
this._element.style[dimension] = 0; |
|
|
|
if (this._triggerArray.length > 0) { |
|
$$$1(this._triggerArray).removeClass(ClassName.COLLAPSED).attr('aria-expanded', true); |
|
} |
|
|
|
this.setTransitioning(true); |
|
|
|
var complete = function complete() { |
|
$$$1(_this._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).addClass(ClassName.SHOW); |
|
_this._element.style[dimension] = ''; |
|
|
|
_this.setTransitioning(false); |
|
|
|
$$$1(_this._element).trigger(Event.SHOWN); |
|
}; |
|
|
|
var capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1); |
|
var scrollSize = "scroll" + capitalizedDimension; |
|
var transitionDuration = Util.getTransitionDurationFromElement(this._element); |
|
$$$1(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); |
|
this._element.style[dimension] = this._element[scrollSize] + "px"; |
|
}; |
|
|
|
_proto.hide = function hide() { |
|
var _this2 = this; |
|
|
|
if (this._isTransitioning || !$$$1(this._element).hasClass(ClassName.SHOW)) { |
|
return; |
|
} |
|
|
|
var startEvent = $$$1.Event(Event.HIDE); |
|
$$$1(this._element).trigger(startEvent); |
|
|
|
if (startEvent.isDefaultPrevented()) { |
|
return; |
|
} |
|
|
|
var dimension = this._getDimension(); |
|
|
|
this._element.style[dimension] = this._element.getBoundingClientRect()[dimension] + "px"; |
|
Util.reflow(this._element); |
|
$$$1(this._element).addClass(ClassName.COLLAPSING).removeClass(ClassName.COLLAPSE).removeClass(ClassName.SHOW); |
|
|
|
if (this._triggerArray.length > 0) { |
|
for (var i = 0; i < this._triggerArray.length; i++) { |
|
var trigger = this._triggerArray[i]; |
|
var selector = Util.getSelectorFromElement(trigger); |
|
|
|
if (selector !== null) { |
|
var $elem = $$$1(selector); |
|
|
|
if (!$elem.hasClass(ClassName.SHOW)) { |
|
$$$1(trigger).addClass(ClassName.COLLAPSED).attr('aria-expanded', false); |
|
} |
|
} |
|
} |
|
} |
|
|
|
this.setTransitioning(true); |
|
|
|
var complete = function complete() { |
|
_this2.setTransitioning(false); |
|
|
|
$$$1(_this2._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).trigger(Event.HIDDEN); |
|
}; |
|
|
|
this._element.style[dimension] = ''; |
|
var transitionDuration = Util.getTransitionDurationFromElement(this._element); |
|
$$$1(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); |
|
}; |
|
|
|
_proto.setTransitioning = function setTransitioning(isTransitioning) { |
|
this._isTransitioning = isTransitioning; |
|
}; |
|
|
|
_proto.dispose = function dispose() { |
|
$$$1.removeData(this._element, DATA_KEY); |
|
this._config = null; |
|
this._parent = null; |
|
this._element = null; |
|
this._triggerArray = null; |
|
this._isTransitioning = null; |
|
}; // Private |
|
|
|
|
|
_proto._getConfig = function _getConfig(config) { |
|
config = _objectSpread({}, Default, config); |
|
config.toggle = Boolean(config.toggle); // Coerce string values |
|
|
|
Util.typeCheckConfig(NAME, config, DefaultType); |
|
return config; |
|
}; |
|
|
|
_proto._getDimension = function _getDimension() { |
|
var hasWidth = $$$1(this._element).hasClass(Dimension.WIDTH); |
|
return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT; |
|
}; |
|
|
|
_proto._getParent = function _getParent() { |
|
var _this3 = this; |
|
|
|
var parent = null; |
|
|
|
if (Util.isElement(this._config.parent)) { |
|
parent = this._config.parent; // It's a jQuery object |
|
|
|
if (typeof this._config.parent.jquery !== 'undefined') { |
|
parent = this._config.parent[0]; |
|
} |
|
} else { |
|
parent = $$$1(this._config.parent)[0]; |
|
} |
|
|
|
var selector = "[data-toggle=\"collapse\"][data-parent=\"" + this._config.parent + "\"]"; |
|
$$$1(parent).find(selector).each(function (i, element) { |
|
_this3._addAriaAndCollapsedClass(Collapse._getTargetFromElement(element), [element]); |
|
}); |
|
return parent; |
|
}; |
|
|
|
_proto._addAriaAndCollapsedClass = function _addAriaAndCollapsedClass(element, triggerArray) { |
|
if (element) { |
|
var isOpen = $$$1(element).hasClass(ClassName.SHOW); |
|
|
|
if (triggerArray.length > 0) { |
|
$$$1(triggerArray).toggleClass(ClassName.COLLAPSED, !isOpen).attr('aria-expanded', isOpen); |
|
} |
|
} |
|
}; // Static |
|
|
|
|
|
Collapse._getTargetFromElement = function _getTargetFromElement(element) { |
|
var selector = Util.getSelectorFromElement(element); |
|
return selector ? $$$1(selector)[0] : null; |
|
}; |
|
|
|
Collapse._jQueryInterface = function _jQueryInterface(config) { |
|
return this.each(function () { |
|
var $this = $$$1(this); |
|
var data = $this.data(DATA_KEY); |
|
|
|
var _config = _objectSpread({}, Default, $this.data(), typeof config === 'object' && config ? config : {}); |
|
|
|
if (!data && _config.toggle && /show|hide/.test(config)) { |
|
_config.toggle = false; |
|
} |
|
|
|
if (!data) { |
|
data = new Collapse(this, _config); |
|
$this.data(DATA_KEY, data); |
|
} |
|
|
|
if (typeof config === 'string') { |
|
if (typeof data[config] === 'undefined') { |
|
throw new TypeError("No method named \"" + config + "\""); |
|
} |
|
|
|
data[config](); |
|
} |
|
}); |
|
}; |
|
|
|
_createClass(Collapse, null, [{ |
|
key: "VERSION", |
|
get: function get() { |
|
return VERSION; |
|
} |
|
}, { |
|
key: "Default", |
|
get: function get() { |
|
return Default; |
|
} |
|
}]); |
|
|
|
return Collapse; |
|
}(); |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Data Api implementation |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
|
|
$$$1(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { |
|
// preventDefault only for <a> elements (which change the URL) not inside the collapsible element |
|
if (event.currentTarget.tagName === 'A') { |
|
event.preventDefault(); |
|
} |
|
|
|
var $trigger = $$$1(this); |
|
var selector = Util.getSelectorFromElement(this); |
|
$$$1(selector).each(function () { |
|
var $target = $$$1(this); |
|
var data = $target.data(DATA_KEY); |
|
var config = data ? 'toggle' : $trigger.data(); |
|
|
|
Collapse._jQueryInterface.call($target, config); |
|
}); |
|
}); |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* jQuery |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
$$$1.fn[NAME] = Collapse._jQueryInterface; |
|
$$$1.fn[NAME].Constructor = Collapse; |
|
|
|
$$$1.fn[NAME].noConflict = function () { |
|
$$$1.fn[NAME] = JQUERY_NO_CONFLICT; |
|
return Collapse._jQueryInterface; |
|
}; |
|
|
|
return Collapse; |
|
}($); |
|
|
|
/** |
|
* -------------------------------------------------------------------------- |
|
* Bootstrap (v4.1.1): dropdown.js |
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
|
* -------------------------------------------------------------------------- |
|
*/ |
|
|
|
var Dropdown = function ($$$1) { |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Constants |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
var NAME = 'dropdown'; |
|
var VERSION = '4.1.1'; |
|
var DATA_KEY = 'bs.dropdown'; |
|
var EVENT_KEY = "." + DATA_KEY; |
|
var DATA_API_KEY = '.data-api'; |
|
var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; |
|
var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key |
|
|
|
var SPACE_KEYCODE = 32; // KeyboardEvent.which value for space key |
|
|
|
var TAB_KEYCODE = 9; // KeyboardEvent.which value for tab key |
|
|
|
var ARROW_UP_KEYCODE = 38; // KeyboardEvent.which value for up arrow key |
|
|
|
var ARROW_DOWN_KEYCODE = 40; // KeyboardEvent.which value for down arrow key |
|
|
|
var RIGHT_MOUSE_BUTTON_WHICH = 3; // MouseEvent.which value for the right button (assuming a right-handed mouse) |
|
|
|
var REGEXP_KEYDOWN = new RegExp(ARROW_UP_KEYCODE + "|" + ARROW_DOWN_KEYCODE + "|" + ESCAPE_KEYCODE); |
|
var Event = { |
|
HIDE: "hide" + EVENT_KEY, |
|
HIDDEN: "hidden" + EVENT_KEY, |
|
SHOW: "show" + EVENT_KEY, |
|
SHOWN: "shown" + EVENT_KEY, |
|
CLICK: "click" + EVENT_KEY, |
|
CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY, |
|
KEYDOWN_DATA_API: "keydown" + EVENT_KEY + DATA_API_KEY, |
|
KEYUP_DATA_API: "keyup" + EVENT_KEY + DATA_API_KEY |
|
}; |
|
var ClassName = { |
|
DISABLED: 'disabled', |
|
SHOW: 'show', |
|
DROPUP: 'dropup', |
|
DROPRIGHT: 'dropright', |
|
DROPLEFT: 'dropleft', |
|
MENURIGHT: 'dropdown-menu-right', |
|
MENULEFT: 'dropdown-menu-left', |
|
POSITION_STATIC: 'position-static' |
|
}; |
|
var Selector = { |
|
DATA_TOGGLE: '[data-toggle="dropdown"]', |
|
FORM_CHILD: '.dropdown form', |
|
MENU: '.dropdown-menu', |
|
NAVBAR_NAV: '.navbar-nav', |
|
VISIBLE_ITEMS: '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)' |
|
}; |
|
var AttachmentMap = { |
|
TOP: 'top-start', |
|
TOPEND: 'top-end', |
|
BOTTOM: 'bottom-start', |
|
BOTTOMEND: 'bottom-end', |
|
RIGHT: 'right-start', |
|
RIGHTEND: 'right-end', |
|
LEFT: 'left-start', |
|
LEFTEND: 'left-end' |
|
}; |
|
var Default = { |
|
offset: 0, |
|
flip: true, |
|
boundary: 'scrollParent', |
|
reference: 'toggle', |
|
display: 'dynamic' |
|
}; |
|
var DefaultType = { |
|
offset: '(number|string|function)', |
|
flip: 'boolean', |
|
boundary: '(string|element)', |
|
reference: '(string|element)', |
|
display: 'string' |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Class Definition |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
}; |
|
|
|
var Dropdown = |
|
/*#__PURE__*/ |
|
function () { |
|
function Dropdown(element, config) { |
|
this._element = element; |
|
this._popper = null; |
|
this._config = this._getConfig(config); |
|
this._menu = this._getMenuElement(); |
|
this._inNavbar = this._detectNavbar(); |
|
|
|
this._addEventListeners(); |
|
} // Getters |
|
|
|
|
|
var _proto = Dropdown.prototype; |
|
|
|
// Public |
|
_proto.toggle = function toggle() { |
|
if (this._element.disabled || $$$1(this._element).hasClass(ClassName.DISABLED)) { |
|
return; |
|
} |
|
|
|
var parent = Dropdown._getParentFromElement(this._element); |
|
|
|
var isActive = $$$1(this._menu).hasClass(ClassName.SHOW); |
|
|
|
Dropdown._clearMenus(); |
|
|
|
if (isActive) { |
|
return; |
|
} |
|
|
|
var relatedTarget = { |
|
relatedTarget: this._element |
|
}; |
|
var showEvent = $$$1.Event(Event.SHOW, relatedTarget); |
|
$$$1(parent).trigger(showEvent); |
|
|
|
if (showEvent.isDefaultPrevented()) { |
|
return; |
|
} // Disable totally Popper.js for Dropdown in Navbar |
|
|
|
|
|
if (!this._inNavbar) { |
|
/** |
|
* Check for Popper dependency |
|
* Popper - https://popper.js.org |
|
*/ |
|
if (typeof Popper === 'undefined') { |
|
throw new TypeError('Bootstrap dropdown require Popper.js (https://popper.js.org)'); |
|
} |
|
|
|
var referenceElement = this._element; |
|
|
|
if (this._config.reference === 'parent') { |
|
referenceElement = parent; |
|
} else if (Util.isElement(this._config.reference)) { |
|
referenceElement = this._config.reference; // Check if it's jQuery element |
|
|
|
if (typeof this._config.reference.jquery !== 'undefined') { |
|
referenceElement = this._config.reference[0]; |
|
} |
|
} // If boundary is not `scrollParent`, then set position to `static` |
|
// to allow the menu to "escape" the scroll parent's boundaries |
|
// https://github.com/twbs/bootstrap/issues/24251 |
|
|
|
|
|
if (this._config.boundary !== 'scrollParent') { |
|
$$$1(parent).addClass(ClassName.POSITION_STATIC); |
|
} |
|
|
|
this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig()); |
|
} // If this is a touch-enabled device we add extra |
|
// empty mouseover listeners to the body's immediate children; |
|
// only needed because of broken event delegation on iOS |
|
// https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html |
|
|
|
|
|
if ('ontouchstart' in document.documentElement && $$$1(parent).closest(Selector.NAVBAR_NAV).length === 0) { |
|
$$$1(document.body).children().on('mouseover', null, $$$1.noop); |
|
} |
|
|
|
this._element.focus(); |
|
|
|
this._element.setAttribute('aria-expanded', true); |
|
|
|
$$$1(this._menu).toggleClass(ClassName.SHOW); |
|
$$$1(parent).toggleClass(ClassName.SHOW).trigger($$$1.Event(Event.SHOWN, relatedTarget)); |
|
}; |
|
|
|
_proto.dispose = function dispose() { |
|
$$$1.removeData(this._element, DATA_KEY); |
|
$$$1(this._element).off(EVENT_KEY); |
|
this._element = null; |
|
this._menu = null; |
|
|
|
if (this._popper !== null) { |
|
this._popper.destroy(); |
|
|
|
this._popper = null; |
|
} |
|
}; |
|
|
|
_proto.update = function update() { |
|
this._inNavbar = this._detectNavbar(); |
|
|
|
if (this._popper !== null) { |
|
this._popper.scheduleUpdate(); |
|
} |
|
}; // Private |
|
|
|
|
|
_proto._addEventListeners = function _addEventListeners() { |
|
var _this = this; |
|
|
|
$$$1(this._element).on(Event.CLICK, function (event) { |
|
event.preventDefault(); |
|
event.stopPropagation(); |
|
|
|
_this.toggle(); |
|
}); |
|
}; |
|
|
|
_proto._getConfig = function _getConfig(config) { |
|
config = _objectSpread({}, this.constructor.Default, $$$1(this._element).data(), config); |
|
Util.typeCheckConfig(NAME, config, this.constructor.DefaultType); |
|
return config; |
|
}; |
|
|
|
_proto._getMenuElement = function _getMenuElement() { |
|
if (!this._menu) { |
|
var parent = Dropdown._getParentFromElement(this._element); |
|
|
|
this._menu = $$$1(parent).find(Selector.MENU)[0]; |
|
} |
|
|
|
return this._menu; |
|
}; |
|
|
|
_proto._getPlacement = function _getPlacement() { |
|
var $parentDropdown = $$$1(this._element).parent(); |
|
var placement = AttachmentMap.BOTTOM; // Handle dropup |
|
|
|
if ($parentDropdown.hasClass(ClassName.DROPUP)) { |
|
placement = AttachmentMap.TOP; |
|
|
|
if ($$$1(this._menu).hasClass(ClassName.MENURIGHT)) { |
|
placement = AttachmentMap.TOPEND; |
|
} |
|
} else if ($parentDropdown.hasClass(ClassName.DROPRIGHT)) { |
|
placement = AttachmentMap.RIGHT; |
|
} else if ($parentDropdown.hasClass(ClassName.DROPLEFT)) { |
|
placement = AttachmentMap.LEFT; |
|
} else if ($$$1(this._menu).hasClass(ClassName.MENURIGHT)) { |
|
placement = AttachmentMap.BOTTOMEND; |
|
} |
|
|
|
return placement; |
|
}; |
|
|
|
_proto._detectNavbar = function _detectNavbar() { |
|
return $$$1(this._element).closest('.navbar').length > 0; |
|
}; |
|
|
|
_proto._getPopperConfig = function _getPopperConfig() { |
|
var _this2 = this; |
|
|
|
var offsetConf = {}; |
|
|
|
if (typeof this._config.offset === 'function') { |
|
offsetConf.fn = function (data) { |
|
data.offsets = _objectSpread({}, data.offsets, _this2._config.offset(data.offsets) || {}); |
|
return data; |
|
}; |
|
} else { |
|
offsetConf.offset = this._config.offset; |
|
} |
|
|
|
var popperConfig = { |
|
placement: this._getPlacement(), |
|
modifiers: { |
|
offset: offsetConf, |
|
flip: { |
|
enabled: this._config.flip |
|
}, |
|
preventOverflow: { |
|
boundariesElement: this._config.boundary |
|
} |
|
} // Disable Popper.js if we have a static display |
|
|
|
}; |
|
|
|
if (this._config.display === 'static') { |
|
popperConfig.modifiers.applyStyle = { |
|
enabled: false |
|
}; |
|
} |
|
|
|
return popperConfig; |
|
}; // Static |
|
|
|
|
|
Dropdown._jQueryInterface = function _jQueryInterface(config) { |
|
return this.each(function () { |
|
var data = $$$1(this).data(DATA_KEY); |
|
|
|
var _config = typeof config === 'object' ? config : null; |
|
|
|
if (!data) { |
|
data = new Dropdown(this, _config); |
|
$$$1(this).data(DATA_KEY, data); |
|
} |
|
|
|
if (typeof config === 'string') { |
|
if (typeof data[config] === 'undefined') { |
|
throw new TypeError("No method named \"" + config + "\""); |
|
} |
|
|
|
data[config](); |
|
} |
|
}); |
|
}; |
|
|
|
Dropdown._clearMenus = function _clearMenus(event) { |
|
if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH || event.type === 'keyup' && event.which !== TAB_KEYCODE)) { |
|
return; |
|
} |
|
|
|
var toggles = $$$1.makeArray($$$1(Selector.DATA_TOGGLE)); |
|
|
|
for (var i = 0; i < toggles.length; i++) { |
|
var parent = Dropdown._getParentFromElement(toggles[i]); |
|
|
|
var context = $$$1(toggles[i]).data(DATA_KEY); |
|
var relatedTarget = { |
|
relatedTarget: toggles[i] |
|
}; |
|
|
|
if (!context) { |
|
continue; |
|
} |
|
|
|
var dropdownMenu = context._menu; |
|
|
|
if (!$$$1(parent).hasClass(ClassName.SHOW)) { |
|
continue; |
|
} |
|
|
|
if (event && (event.type === 'click' && /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) && $$$1.contains(parent, event.target)) { |
|
continue; |
|
} |
|
|
|
var hideEvent = $$$1.Event(Event.HIDE, relatedTarget); |
|
$$$1(parent).trigger(hideEvent); |
|
|
|
if (hideEvent.isDefaultPrevented()) { |
|
continue; |
|
} // If this is a touch-enabled device we remove the extra |
|
// empty mouseover listeners we added for iOS support |
|
|
|
|
|
if ('ontouchstart' in document.documentElement) { |
|
$$$1(document.body).children().off('mouseover', null, $$$1.noop); |
|
} |
|
|
|
toggles[i].setAttribute('aria-expanded', 'false'); |
|
$$$1(dropdownMenu).removeClass(ClassName.SHOW); |
|
$$$1(parent).removeClass(ClassName.SHOW).trigger($$$1.Event(Event.HIDDEN, relatedTarget)); |
|
} |
|
}; |
|
|
|
Dropdown._getParentFromElement = function _getParentFromElement(element) { |
|
var parent; |
|
var selector = Util.getSelectorFromElement(element); |
|
|
|
if (selector) { |
|
parent = $$$1(selector)[0]; |
|
} |
|
|
|
return parent || element.parentNode; |
|
}; // eslint-disable-next-line complexity |
|
|
|
|
|
Dropdown._dataApiKeydownHandler = function _dataApiKeydownHandler(event) { |
|
// If not input/textarea: |
|
// - And not a key in REGEXP_KEYDOWN => not a dropdown command |
|
// If input/textarea: |
|
// - If space key => not a dropdown command |
|
// - If key is other than escape |
|
// - If key is not up or down => not a dropdown command |
|
// - If trigger inside the menu => not a dropdown command |
|
if (/input|textarea/i.test(event.target.tagName) ? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE && (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE || $$$1(event.target).closest(Selector.MENU).length) : !REGEXP_KEYDOWN.test(event.which)) { |
|
return; |
|
} |
|
|
|
event.preventDefault(); |
|
event.stopPropagation(); |
|
|
|
if (this.disabled || $$$1(this).hasClass(ClassName.DISABLED)) { |
|
return; |
|
} |
|
|
|
var parent = Dropdown._getParentFromElement(this); |
|
|
|
var isActive = $$$1(parent).hasClass(ClassName.SHOW); |
|
|
|
if (!isActive && (event.which !== ESCAPE_KEYCODE || event.which !== SPACE_KEYCODE) || isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) { |
|
if (event.which === ESCAPE_KEYCODE) { |
|
var toggle = $$$1(parent).find(Selector.DATA_TOGGLE)[0]; |
|
$$$1(toggle).trigger('focus'); |
|
} |
|
|
|
$$$1(this).trigger('click'); |
|
return; |
|
} |
|
|
|
var items = $$$1(parent).find(Selector.VISIBLE_ITEMS).get(); |
|
|
|
if (items.length === 0) { |
|
return; |
|
} |
|
|
|
var index = items.indexOf(event.target); |
|
|
|
if (event.which === ARROW_UP_KEYCODE && index > 0) { |
|
// Up |
|
index--; |
|
} |
|
|
|
if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { |
|
// Down |
|
index++; |
|
} |
|
|
|
if (index < 0) { |
|
index = 0; |
|
} |
|
|
|
items[index].focus(); |
|
}; |
|
|
|
_createClass(Dropdown, null, [{ |
|
key: "VERSION", |
|
get: function get() { |
|
return VERSION; |
|
} |
|
}, { |
|
key: "Default", |
|
get: function get() { |
|
return Default; |
|
} |
|
}, { |
|
key: "DefaultType", |
|
get: function get() { |
|
return DefaultType; |
|
} |
|
}]); |
|
|
|
return Dropdown; |
|
}(); |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Data Api implementation |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
|
|
$$$1(document).on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN_DATA_API, Selector.MENU, Dropdown._dataApiKeydownHandler).on(Event.CLICK_DATA_API + " " + Event.KEYUP_DATA_API, Dropdown._clearMenus).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { |
|
event.preventDefault(); |
|
event.stopPropagation(); |
|
|
|
Dropdown._jQueryInterface.call($$$1(this), 'toggle'); |
|
}).on(Event.CLICK_DATA_API, Selector.FORM_CHILD, function (e) { |
|
e.stopPropagation(); |
|
}); |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* jQuery |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
$$$1.fn[NAME] = Dropdown._jQueryInterface; |
|
$$$1.fn[NAME].Constructor = Dropdown; |
|
|
|
$$$1.fn[NAME].noConflict = function () { |
|
$$$1.fn[NAME] = JQUERY_NO_CONFLICT; |
|
return Dropdown._jQueryInterface; |
|
}; |
|
|
|
return Dropdown; |
|
}($, Popper); |
|
|
|
/** |
|
* -------------------------------------------------------------------------- |
|
* Bootstrap (v4.1.1): modal.js |
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
|
* -------------------------------------------------------------------------- |
|
*/ |
|
|
|
var Modal = function ($$$1) { |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Constants |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
var NAME = 'modal'; |
|
var VERSION = '4.1.1'; |
|
var DATA_KEY = 'bs.modal'; |
|
var EVENT_KEY = "." + DATA_KEY; |
|
var DATA_API_KEY = '.data-api'; |
|
var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; |
|
var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key |
|
|
|
var Default = { |
|
backdrop: true, |
|
keyboard: true, |
|
focus: true, |
|
show: true |
|
}; |
|
var DefaultType = { |
|
backdrop: '(boolean|string)', |
|
keyboard: 'boolean', |
|
focus: 'boolean', |
|
show: 'boolean' |
|
}; |
|
var Event = { |
|
HIDE: "hide" + EVENT_KEY, |
|
HIDDEN: "hidden" + EVENT_KEY, |
|
SHOW: "show" + EVENT_KEY, |
|
SHOWN: "shown" + EVENT_KEY, |
|
FOCUSIN: "focusin" + EVENT_KEY, |
|
RESIZE: "resize" + EVENT_KEY, |
|
CLICK_DISMISS: "click.dismiss" + EVENT_KEY, |
|
KEYDOWN_DISMISS: "keydown.dismiss" + EVENT_KEY, |
|
MOUSEUP_DISMISS: "mouseup.dismiss" + EVENT_KEY, |
|
MOUSEDOWN_DISMISS: "mousedown.dismiss" + EVENT_KEY, |
|
CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY |
|
}; |
|
var ClassName = { |
|
SCROLLBAR_MEASURER: 'modal-scrollbar-measure', |
|
BACKDROP: 'modal-backdrop', |
|
OPEN: 'modal-open', |
|
FADE: 'fade', |
|
SHOW: 'show' |
|
}; |
|
var Selector = { |
|
DIALOG: '.modal-dialog', |
|
DATA_TOGGLE: '[data-toggle="modal"]', |
|
DATA_DISMISS: '[data-dismiss="modal"]', |
|
FIXED_CONTENT: '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top', |
|
STICKY_CONTENT: '.sticky-top', |
|
NAVBAR_TOGGLER: '.navbar-toggler' |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Class Definition |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
}; |
|
|
|
var Modal = |
|
/*#__PURE__*/ |
|
function () { |
|
function Modal(element, config) { |
|
this._config = this._getConfig(config); |
|
this._element = element; |
|
this._dialog = $$$1(element).find(Selector.DIALOG)[0]; |
|
this._backdrop = null; |
|
this._isShown = false; |
|
this._isBodyOverflowing = false; |
|
this._ignoreBackdropClick = false; |
|
this._scrollbarWidth = 0; |
|
} // Getters |
|
|
|
|
|
var _proto = Modal.prototype; |
|
|
|
// Public |
|
_proto.toggle = function toggle(relatedTarget) { |
|
return this._isShown ? this.hide() : this.show(relatedTarget); |
|
}; |
|
|
|
_proto.show = function show(relatedTarget) { |
|
var _this = this; |
|
|
|
if (this._isTransitioning || this._isShown) { |
|
return; |
|
} |
|
|
|
if ($$$1(this._element).hasClass(ClassName.FADE)) { |
|
this._isTransitioning = true; |
|
} |
|
|
|
var showEvent = $$$1.Event(Event.SHOW, { |
|
relatedTarget: relatedTarget |
|
}); |
|
$$$1(this._element).trigger(showEvent); |
|
|
|
if (this._isShown || showEvent.isDefaultPrevented()) { |
|
return; |
|
} |
|
|
|
this._isShown = true; |
|
|
|
this._checkScrollbar(); |
|
|
|
this._setScrollbar(); |
|
|
|
this._adjustDialog(); |
|
|
|
$$$1(document.body).addClass(ClassName.OPEN); |
|
|
|
this._setEscapeEvent(); |
|
|
|
this._setResizeEvent(); |
|
|
|
$$$1(this._element).on(Event.CLICK_DISMISS, Selector.DATA_DISMISS, function (event) { |
|
return _this.hide(event); |
|
}); |
|
$$$1(this._dialog).on(Event.MOUSEDOWN_DISMISS, function () { |
|
$$$1(_this._element).one(Event.MOUSEUP_DISMISS, function (event) { |
|
if ($$$1(event.target).is(_this._element)) { |
|
_this._ignoreBackdropClick = true; |
|
} |
|
}); |
|
}); |
|
|
|
this._showBackdrop(function () { |
|
return _this._showElement(relatedTarget); |
|
}); |
|
}; |
|
|
|
_proto.hide = function hide(event) { |
|
var _this2 = this; |
|
|
|
if (event) { |
|
event.preventDefault(); |
|
} |
|
|
|
if (this._isTransitioning || !this._isShown) { |
|
return; |
|
} |
|
|
|
var hideEvent = $$$1.Event(Event.HIDE); |
|
$$$1(this._element).trigger(hideEvent); |
|
|
|
if (!this._isShown || hideEvent.isDefaultPrevented()) { |
|
return; |
|
} |
|
|
|
this._isShown = false; |
|
var transition = $$$1(this._element).hasClass(ClassName.FADE); |
|
|
|
if (transition) { |
|
this._isTransitioning = true; |
|
} |
|
|
|
this._setEscapeEvent(); |
|
|
|
this._setResizeEvent(); |
|
|
|
$$$1(document).off(Event.FOCUSIN); |
|
$$$1(this._element).removeClass(ClassName.SHOW); |
|
$$$1(this._element).off(Event.CLICK_DISMISS); |
|
$$$1(this._dialog).off(Event.MOUSEDOWN_DISMISS); |
|
|
|
if (transition) { |
|
var transitionDuration = Util.getTransitionDurationFromElement(this._element); |
|
$$$1(this._element).one(Util.TRANSITION_END, function (event) { |
|
return _this2._hideModal(event); |
|
}).emulateTransitionEnd(transitionDuration); |
|
} else { |
|
this._hideModal(); |
|
} |
|
}; |
|
|
|
_proto.dispose = function dispose() { |
|
$$$1.removeData(this._element, DATA_KEY); |
|
$$$1(window, document, this._element, this._backdrop).off(EVENT_KEY); |
|
this._config = null; |
|
this._element = null; |
|
this._dialog = null; |
|
this._backdrop = null; |
|
this._isShown = null; |
|
this._isBodyOverflowing = null; |
|
this._ignoreBackdropClick = null; |
|
this._scrollbarWidth = null; |
|
}; |
|
|
|
_proto.handleUpdate = function handleUpdate() { |
|
this._adjustDialog(); |
|
}; // Private |
|
|
|
|
|
_proto._getConfig = function _getConfig(config) { |
|
config = _objectSpread({}, Default, config); |
|
Util.typeCheckConfig(NAME, config, DefaultType); |
|
return config; |
|
}; |
|
|
|
_proto._showElement = function _showElement(relatedTarget) { |
|
var _this3 = this; |
|
|
|
var transition = $$$1(this._element).hasClass(ClassName.FADE); |
|
|
|
if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) { |
|
// Don't move modal's DOM position |
|
document.body.appendChild(this._element); |
|
} |
|
|
|
this._element.style.display = 'block'; |
|
|
|
this._element.removeAttribute('aria-hidden'); |
|
|
|
this._element.scrollTop = 0; |
|
|
|
if (transition) { |
|
Util.reflow(this._element); |
|
} |
|
|
|
$$$1(this._element).addClass(ClassName.SHOW); |
|
|
|
if (this._config.focus) { |
|
this._enforceFocus(); |
|
} |
|
|
|
var shownEvent = $$$1.Event(Event.SHOWN, { |
|
relatedTarget: relatedTarget |
|
}); |
|
|
|
var transitionComplete = function transitionComplete() { |
|
if (_this3._config.focus) { |
|
_this3._element.focus(); |
|
} |
|
|
|
_this3._isTransitioning = false; |
|
$$$1(_this3._element).trigger(shownEvent); |
|
}; |
|
|
|
if (transition) { |
|
var transitionDuration = Util.getTransitionDurationFromElement(this._element); |
|
$$$1(this._dialog).one(Util.TRANSITION_END, transitionComplete).emulateTransitionEnd(transitionDuration); |
|
} else { |
|
transitionComplete(); |
|
} |
|
}; |
|
|
|
_proto._enforceFocus = function _enforceFocus() { |
|
var _this4 = this; |
|
|
|
$$$1(document).off(Event.FOCUSIN) // Guard against infinite focus loop |
|
.on(Event.FOCUSIN, function (event) { |
|
if (document !== event.target && _this4._element !== event.target && $$$1(_this4._element).has(event.target).length === 0) { |
|
_this4._element.focus(); |
|
} |
|
}); |
|
}; |
|
|
|
_proto._setEscapeEvent = function _setEscapeEvent() { |
|
var _this5 = this; |
|
|
|
if (this._isShown && this._config.keyboard) { |
|
$$$1(this._element).on(Event.KEYDOWN_DISMISS, function (event) { |
|
if (event.which === ESCAPE_KEYCODE) { |
|
event.preventDefault(); |
|
|
|
_this5.hide(); |
|
} |
|
}); |
|
} else if (!this._isShown) { |
|
$$$1(this._element).off(Event.KEYDOWN_DISMISS); |
|
} |
|
}; |
|
|
|
_proto._setResizeEvent = function _setResizeEvent() { |
|
var _this6 = this; |
|
|
|
if (this._isShown) { |
|
$$$1(window).on(Event.RESIZE, function (event) { |
|
return _this6.handleUpdate(event); |
|
}); |
|
} else { |
|
$$$1(window).off(Event.RESIZE); |
|
} |
|
}; |
|
|
|
_proto._hideModal = function _hideModal() { |
|
var _this7 = this; |
|
|
|
this._element.style.display = 'none'; |
|
|
|
this._element.setAttribute('aria-hidden', true); |
|
|
|
this._isTransitioning = false; |
|
|
|
this._showBackdrop(function () { |
|
$$$1(document.body).removeClass(ClassName.OPEN); |
|
|
|
_this7._resetAdjustments(); |
|
|
|
_this7._resetScrollbar(); |
|
|
|
$$$1(_this7._element).trigger(Event.HIDDEN); |
|
}); |
|
}; |
|
|
|
_proto._removeBackdrop = function _removeBackdrop() { |
|
if (this._backdrop) { |
|
$$$1(this._backdrop).remove(); |
|
this._backdrop = null; |
|
} |
|
}; |
|
|
|
_proto._showBackdrop = function _showBackdrop(callback) { |
|
var _this8 = this; |
|
|
|
var animate = $$$1(this._element).hasClass(ClassName.FADE) ? ClassName.FADE : ''; |
|
|
|
if (this._isShown && this._config.backdrop) { |
|
this._backdrop = document.createElement('div'); |
|
this._backdrop.className = ClassName.BACKDROP; |
|
|
|
if (animate) { |
|
$$$1(this._backdrop).addClass(animate); |
|
} |
|
|
|
$$$1(this._backdrop).appendTo(document.body); |
|
$$$1(this._element).on(Event.CLICK_DISMISS, function (event) { |
|
if (_this8._ignoreBackdropClick) { |
|
_this8._ignoreBackdropClick = false; |
|
return; |
|
} |
|
|
|
if (event.target !== event.currentTarget) { |
|
return; |
|
} |
|
|
|
if (_this8._config.backdrop === 'static') { |
|
_this8._element.focus(); |
|
} else { |
|
_this8.hide(); |
|
} |
|
}); |
|
|
|
if (animate) { |
|
Util.reflow(this._backdrop); |
|
} |
|
|
|
$$$1(this._backdrop).addClass(ClassName.SHOW); |
|
|
|
if (!callback) { |
|
return; |
|
} |
|
|
|
if (!animate) { |
|
callback(); |
|
return; |
|
} |
|
|
|
var backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop); |
|
$$$1(this._backdrop).one(Util.TRANSITION_END, callback).emulateTransitionEnd(backdropTransitionDuration); |
|
} else if (!this._isShown && this._backdrop) { |
|
$$$1(this._backdrop).removeClass(ClassName.SHOW); |
|
|
|
var callbackRemove = function callbackRemove() { |
|
_this8._removeBackdrop(); |
|
|
|
if (callback) { |
|
callback(); |
|
} |
|
}; |
|
|
|
if ($$$1(this._element).hasClass(ClassName.FADE)) { |
|
var _backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop); |
|
|
|
$$$1(this._backdrop).one(Util.TRANSITION_END, callbackRemove).emulateTransitionEnd(_backdropTransitionDuration); |
|
} else { |
|
callbackRemove(); |
|
} |
|
} else if (callback) { |
|
callback(); |
|
} |
|
}; // ---------------------------------------------------------------------- |
|
// the following methods are used to handle overflowing modals |
|
// todo (fat): these should probably be refactored out of modal.js |
|
// ---------------------------------------------------------------------- |
|
|
|
|
|
_proto._adjustDialog = function _adjustDialog() { |
|
var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; |
|
|
|
if (!this._isBodyOverflowing && isModalOverflowing) { |
|
this._element.style.paddingLeft = this._scrollbarWidth + "px"; |
|
} |
|
|
|
if (this._isBodyOverflowing && !isModalOverflowing) { |
|
this._element.style.paddingRight = this._scrollbarWidth + "px"; |
|
} |
|
}; |
|
|
|
_proto._resetAdjustments = function _resetAdjustments() { |
|
this._element.style.paddingLeft = ''; |
|
this._element.style.paddingRight = ''; |
|
}; |
|
|
|
_proto._checkScrollbar = function _checkScrollbar() { |
|
var rect = document.body.getBoundingClientRect(); |
|
this._isBodyOverflowing = rect.left + rect.right < window.innerWidth; |
|
this._scrollbarWidth = this._getScrollbarWidth(); |
|
}; |
|
|
|
_proto._setScrollbar = function _setScrollbar() { |
|
var _this9 = this; |
|
|
|
if (this._isBodyOverflowing) { |
|
// Note: DOMNode.style.paddingRight returns the actual value or '' if not set |
|
// while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set |
|
// Adjust fixed content padding |
|
$$$1(Selector.FIXED_CONTENT).each(function (index, element) { |
|
var actualPadding = $$$1(element)[0].style.paddingRight; |
|
var calculatedPadding = $$$1(element).css('padding-right'); |
|
$$$1(element).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + _this9._scrollbarWidth + "px"); |
|
}); // Adjust sticky content margin |
|
|
|
$$$1(Selector.STICKY_CONTENT).each(function (index, element) { |
|
var actualMargin = $$$1(element)[0].style.marginRight; |
|
var calculatedMargin = $$$1(element).css('margin-right'); |
|
$$$1(element).data('margin-right', actualMargin).css('margin-right', parseFloat(calculatedMargin) - _this9._scrollbarWidth + "px"); |
|
}); // Adjust navbar-toggler margin |
|
|
|
$$$1(Selector.NAVBAR_TOGGLER).each(function (index, element) { |
|
var actualMargin = $$$1(element)[0].style.marginRight; |
|
var calculatedMargin = $$$1(element).css('margin-right'); |
|
$$$1(element).data('margin-right', actualMargin).css('margin-right', parseFloat(calculatedMargin) + _this9._scrollbarWidth + "px"); |
|
}); // Adjust body padding |
|
|
|
var actualPadding = document.body.style.paddingRight; |
|
var calculatedPadding = $$$1(document.body).css('padding-right'); |
|
$$$1(document.body).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + this._scrollbarWidth + "px"); |
|
} |
|
}; |
|
|
|
_proto._resetScrollbar = function _resetScrollbar() { |
|
// Restore fixed content padding |
|
$$$1(Selector.FIXED_CONTENT).each(function (index, element) { |
|
var padding = $$$1(element).data('padding-right'); |
|
|
|
if (typeof padding !== 'undefined') { |
|
$$$1(element).css('padding-right', padding).removeData('padding-right'); |
|
} |
|
}); // Restore sticky content and navbar-toggler margin |
|
|
|
$$$1(Selector.STICKY_CONTENT + ", " + Selector.NAVBAR_TOGGLER).each(function (index, element) { |
|
var margin = $$$1(element).data('margin-right'); |
|
|
|
if (typeof margin !== 'undefined') { |
|
$$$1(element).css('margin-right', margin).removeData('margin-right'); |
|
} |
|
}); // Restore body padding |
|
|
|
var padding = $$$1(document.body).data('padding-right'); |
|
|
|
if (typeof padding !== 'undefined') { |
|
$$$1(document.body).css('padding-right', padding).removeData('padding-right'); |
|
} |
|
}; |
|
|
|
_proto._getScrollbarWidth = function _getScrollbarWidth() { |
|
// thx d.walsh |
|
var scrollDiv = document.createElement('div'); |
|
scrollDiv.className = ClassName.SCROLLBAR_MEASURER; |
|
document.body.appendChild(scrollDiv); |
|
var scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth; |
|
document.body.removeChild(scrollDiv); |
|
return scrollbarWidth; |
|
}; // Static |
|
|
|
|
|
Modal._jQueryInterface = function _jQueryInterface(config, relatedTarget) { |
|
return this.each(function () { |
|
var data = $$$1(this).data(DATA_KEY); |
|
|
|
var _config = _objectSpread({}, Default, $$$1(this).data(), typeof config === 'object' && config ? config : {}); |
|
|
|
if (!data) { |
|
data = new Modal(this, _config); |
|
$$$1(this).data(DATA_KEY, data); |
|
} |
|
|
|
if (typeof config === 'string') { |
|
if (typeof data[config] === 'undefined') { |
|
throw new TypeError("No method named \"" + config + "\""); |
|
} |
|
|
|
data[config](relatedTarget); |
|
} else if (_config.show) { |
|
data.show(relatedTarget); |
|
} |
|
}); |
|
}; |
|
|
|
_createClass(Modal, null, [{ |
|
key: "VERSION", |
|
get: function get() { |
|
return VERSION; |
|
} |
|
}, { |
|
key: "Default", |
|
get: function get() { |
|
return Default; |
|
} |
|
}]); |
|
|
|
return Modal; |
|
}(); |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Data Api implementation |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
|
|
$$$1(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { |
|
var _this10 = this; |
|
|
|
var target; |
|
var selector = Util.getSelectorFromElement(this); |
|
|
|
if (selector) { |
|
target = $$$1(selector)[0]; |
|
} |
|
|
|
var config = $$$1(target).data(DATA_KEY) ? 'toggle' : _objectSpread({}, $$$1(target).data(), $$$1(this).data()); |
|
|
|
if (this.tagName === 'A' || this.tagName === 'AREA') { |
|
event.preventDefault(); |
|
} |
|
|
|
var $target = $$$1(target).one(Event.SHOW, function (showEvent) { |
|
if (showEvent.isDefaultPrevented()) { |
|
// Only register focus restorer if modal will actually get shown |
|
return; |
|
} |
|
|
|
$target.one(Event.HIDDEN, function () { |
|
if ($$$1(_this10).is(':visible')) { |
|
_this10.focus(); |
|
} |
|
}); |
|
}); |
|
|
|
Modal._jQueryInterface.call($$$1(target), config, this); |
|
}); |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* jQuery |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
$$$1.fn[NAME] = Modal._jQueryInterface; |
|
$$$1.fn[NAME].Constructor = Modal; |
|
|
|
$$$1.fn[NAME].noConflict = function () { |
|
$$$1.fn[NAME] = JQUERY_NO_CONFLICT; |
|
return Modal._jQueryInterface; |
|
}; |
|
|
|
return Modal; |
|
}($); |
|
|
|
/** |
|
* -------------------------------------------------------------------------- |
|
* Bootstrap (v4.1.1): tooltip.js |
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
|
* -------------------------------------------------------------------------- |
|
*/ |
|
|
|
var Tooltip = function ($$$1) { |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Constants |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
var NAME = 'tooltip'; |
|
var VERSION = '4.1.1'; |
|
var DATA_KEY = 'bs.tooltip'; |
|
var EVENT_KEY = "." + DATA_KEY; |
|
var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; |
|
var CLASS_PREFIX = 'bs-tooltip'; |
|
var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g'); |
|
var DefaultType = { |
|
animation: 'boolean', |
|
template: 'string', |
|
title: '(string|element|function)', |
|
trigger: 'string', |
|
delay: '(number|object)', |
|
html: 'boolean', |
|
selector: '(string|boolean)', |
|
placement: '(string|function)', |
|
offset: '(number|string)', |
|
container: '(string|element|boolean)', |
|
fallbackPlacement: '(string|array)', |
|
boundary: '(string|element)' |
|
}; |
|
var AttachmentMap = { |
|
AUTO: 'auto', |
|
TOP: 'top', |
|
RIGHT: 'right', |
|
BOTTOM: 'bottom', |
|
LEFT: 'left' |
|
}; |
|
var Default = { |
|
animation: true, |
|
template: '<div class="tooltip" role="tooltip">' + '<div class="arrow"></div>' + '<div class="tooltip-inner"></div></div>', |
|
trigger: 'hover focus', |
|
title: '', |
|
delay: 0, |
|
html: false, |
|
selector: false, |
|
placement: 'top', |
|
offset: 0, |
|
container: false, |
|
fallbackPlacement: 'flip', |
|
boundary: 'scrollParent' |
|
}; |
|
var HoverState = { |
|
SHOW: 'show', |
|
OUT: 'out' |
|
}; |
|
var Event = { |
|
HIDE: "hide" + EVENT_KEY, |
|
HIDDEN: "hidden" + EVENT_KEY, |
|
SHOW: "show" + EVENT_KEY, |
|
SHOWN: "shown" + EVENT_KEY, |
|
INSERTED: "inserted" + EVENT_KEY, |
|
CLICK: "click" + EVENT_KEY, |
|
FOCUSIN: "focusin" + EVENT_KEY, |
|
FOCUSOUT: "focusout" + EVENT_KEY, |
|
MOUSEENTER: "mouseenter" + EVENT_KEY, |
|
MOUSELEAVE: "mouseleave" + EVENT_KEY |
|
}; |
|
var ClassName = { |
|
FADE: 'fade', |
|
SHOW: 'show' |
|
}; |
|
var Selector = { |
|
TOOLTIP: '.tooltip', |
|
TOOLTIP_INNER: '.tooltip-inner', |
|
ARROW: '.arrow' |
|
}; |
|
var Trigger = { |
|
HOVER: 'hover', |
|
FOCUS: 'focus', |
|
CLICK: 'click', |
|
MANUAL: 'manual' |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Class Definition |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
}; |
|
|
|
var Tooltip = |
|
/*#__PURE__*/ |
|
function () { |
|
function Tooltip(element, config) { |
|
/** |
|
* Check for Popper dependency |
|
* Popper - https://popper.js.org |
|
*/ |
|
if (typeof Popper === 'undefined') { |
|
throw new TypeError('Bootstrap tooltips require Popper.js (https://popper.js.org)'); |
|
} // private |
|
|
|
|
|
this._isEnabled = true; |
|
this._timeout = 0; |
|
this._hoverState = ''; |
|
this._activeTrigger = {}; |
|
this._popper = null; // Protected |
|
|
|
this.element = element; |
|
this.config = this._getConfig(config); |
|
this.tip = null; |
|
|
|
this._setListeners(); |
|
} // Getters |
|
|
|
|
|
var _proto = Tooltip.prototype; |
|
|
|
// Public |
|
_proto.enable = function enable() { |
|
this._isEnabled = true; |
|
}; |
|
|
|
_proto.disable = function disable() { |
|
this._isEnabled = false; |
|
}; |
|
|
|
_proto.toggleEnabled = function toggleEnabled() { |
|
this._isEnabled = !this._isEnabled; |
|
}; |
|
|
|
_proto.toggle = function toggle(event) { |
|
if (!this._isEnabled) { |
|
return; |
|
} |
|
|
|
if (event) { |
|
var dataKey = this.constructor.DATA_KEY; |
|
var context = $$$1(event.currentTarget).data(dataKey); |
|
|
|
if (!context) { |
|
context = new this.constructor(event.currentTarget, this._getDelegateConfig()); |
|
$$$1(event.currentTarget).data(dataKey, context); |
|
} |
|
|
|
context._activeTrigger.click = !context._activeTrigger.click; |
|
|
|
if (context._isWithActiveTrigger()) { |
|
context._enter(null, context); |
|
} else { |
|
context._leave(null, context); |
|
} |
|
} else { |
|
if ($$$1(this.getTipElement()).hasClass(ClassName.SHOW)) { |
|
this._leave(null, this); |
|
|
|
return; |
|
} |
|
|
|
this._enter(null, this); |
|
} |
|
}; |
|
|
|
_proto.dispose = function dispose() { |
|
clearTimeout(this._timeout); |
|
$$$1.removeData(this.element, this.constructor.DATA_KEY); |
|
$$$1(this.element).off(this.constructor.EVENT_KEY); |
|
$$$1(this.element).closest('.modal').off('hide.bs.modal'); |
|
|
|
if (this.tip) { |
|
$$$1(this.tip).remove(); |
|
} |
|
|
|
this._isEnabled = null; |
|
this._timeout = null; |
|
this._hoverState = null; |
|
this._activeTrigger = null; |
|
|
|
if (this._popper !== null) { |
|
this._popper.destroy(); |
|
} |
|
|
|
this._popper = null; |
|
this.element = null; |
|
this.config = null; |
|
this.tip = null; |
|
}; |
|
|
|
_proto.show = function show() { |
|
var _this = this; |
|
|
|
if ($$$1(this.element).css('display') === 'none') { |
|
throw new Error('Please use show on visible elements'); |
|
} |
|
|
|
var showEvent = $$$1.Event(this.constructor.Event.SHOW); |
|
|
|
if (this.isWithContent() && this._isEnabled) { |
|
$$$1(this.element).trigger(showEvent); |
|
var isInTheDom = $$$1.contains(this.element.ownerDocument.documentElement, this.element); |
|
|
|
if (showEvent.isDefaultPrevented() || !isInTheDom) { |
|
return; |
|
} |
|
|
|
var tip = this.getTipElement(); |
|
var tipId = Util.getUID(this.constructor.NAME); |
|
tip.setAttribute('id', tipId); |
|
this.element.setAttribute('aria-describedby', tipId); |
|
this.setContent(); |
|
|
|
if (this.config.animation) { |
|
$$$1(tip).addClass(ClassName.FADE); |
|
} |
|
|
|
var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement; |
|
|
|
var attachment = this._getAttachment(placement); |
|
|
|
this.addAttachmentClass(attachment); |
|
var container = this.config.container === false ? document.body : $$$1(this.config.container); |
|
$$$1(tip).data(this.constructor.DATA_KEY, this); |
|
|
|
if (!$$$1.contains(this.element.ownerDocument.documentElement, this.tip)) { |
|
$$$1(tip).appendTo(container); |
|
} |
|
|
|
$$$1(this.element).trigger(this.constructor.Event.INSERTED); |
|
this._popper = new Popper(this.element, tip, { |
|
placement: attachment, |
|
modifiers: { |
|
offset: { |
|
offset: this.config.offset |
|
}, |
|
flip: { |
|
behavior: this.config.fallbackPlacement |
|
}, |
|
arrow: { |
|
element: Selector.ARROW |
|
}, |
|
preventOverflow: { |
|
boundariesElement: this.config.boundary |
|
} |
|
}, |
|
onCreate: function onCreate(data) { |
|
if (data.originalPlacement !== data.placement) { |
|
_this._handlePopperPlacementChange(data); |
|
} |
|
}, |
|
onUpdate: function onUpdate(data) { |
|
_this._handlePopperPlacementChange(data); |
|
} |
|
}); |
|
$$$1(tip).addClass(ClassName.SHOW); // If this is a touch-enabled device we add extra |
|
// empty mouseover listeners to the body's immediate children; |
|
// only needed because of broken event delegation on iOS |
|
// https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html |
|
|
|
if ('ontouchstart' in document.documentElement) { |
|
$$$1(document.body).children().on('mouseover', null, $$$1.noop); |
|
} |
|
|
|
var complete = function complete() { |
|
if (_this.config.animation) { |
|
_this._fixTransition(); |
|
} |
|
|
|
var prevHoverState = _this._hoverState; |
|
_this._hoverState = null; |
|
$$$1(_this.element).trigger(_this.constructor.Event.SHOWN); |
|
|
|
if (prevHoverState === HoverState.OUT) { |
|
_this._leave(null, _this); |
|
} |
|
}; |
|
|
|
if ($$$1(this.tip).hasClass(ClassName.FADE)) { |
|
var transitionDuration = Util.getTransitionDurationFromElement(this.tip); |
|
$$$1(this.tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); |
|
} else { |
|
complete(); |
|
} |
|
} |
|
}; |
|
|
|
_proto.hide = function hide(callback) { |
|
var _this2 = this; |
|
|
|
var tip = this.getTipElement(); |
|
var hideEvent = $$$1.Event(this.constructor.Event.HIDE); |
|
|
|
var complete = function complete() { |
|
if (_this2._hoverState !== HoverState.SHOW && tip.parentNode) { |
|
tip.parentNode.removeChild(tip); |
|
} |
|
|
|
_this2._cleanTipClass(); |
|
|
|
_this2.element.removeAttribute('aria-describedby'); |
|
|
|
$$$1(_this2.element).trigger(_this2.constructor.Event.HIDDEN); |
|
|
|
if (_this2._popper !== null) { |
|
_this2._popper.destroy(); |
|
} |
|
|
|
if (callback) { |
|
callback(); |
|
} |
|
}; |
|
|
|
$$$1(this.element).trigger(hideEvent); |
|
|
|
if (hideEvent.isDefaultPrevented()) { |
|
return; |
|
} |
|
|
|
$$$1(tip).removeClass(ClassName.SHOW); // If this is a touch-enabled device we remove the extra |
|
// empty mouseover listeners we added for iOS support |
|
|
|
if ('ontouchstart' in document.documentElement) { |
|
$$$1(document.body).children().off('mouseover', null, $$$1.noop); |
|
} |
|
|
|
this._activeTrigger[Trigger.CLICK] = false; |
|
this._activeTrigger[Trigger.FOCUS] = false; |
|
this._activeTrigger[Trigger.HOVER] = false; |
|
|
|
if ($$$1(this.tip).hasClass(ClassName.FADE)) { |
|
var transitionDuration = Util.getTransitionDurationFromElement(tip); |
|
$$$1(tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); |
|
} else { |
|
complete(); |
|
} |
|
|
|
this._hoverState = ''; |
|
}; |
|
|
|
_proto.update = function update() { |
|
if (this._popper !== null) { |
|
this._popper.scheduleUpdate(); |
|
} |
|
}; // Protected |
|
|
|
|
|
_proto.isWithContent = function isWithContent() { |
|
return Boolean(this.getTitle()); |
|
}; |
|
|
|
_proto.addAttachmentClass = function addAttachmentClass(attachment) { |
|
$$$1(this.getTipElement()).addClass(CLASS_PREFIX + "-" + attachment); |
|
}; |
|
|
|
_proto.getTipElement = function getTipElement() { |
|
this.tip = this.tip || $$$1(this.config.template)[0]; |
|
return this.tip; |
|
}; |
|
|
|
_proto.setContent = function setContent() { |
|
var $tip = $$$1(this.getTipElement()); |
|
this.setElementContent($tip.find(Selector.TOOLTIP_INNER), this.getTitle()); |
|
$tip.removeClass(ClassName.FADE + " " + ClassName.SHOW); |
|
}; |
|
|
|
_proto.setElementContent = function setElementContent($element, content) { |
|
var html = this.config.html; |
|
|
|
if (typeof content === 'object' && (content.nodeType || content.jquery)) { |
|
// Content is a DOM node or a jQuery |
|
if (html) { |
|
if (!$$$1(content).parent().is($element)) { |
|
$element.empty().append(content); |
|
} |
|
} else { |
|
$element.text($$$1(content).text()); |
|
} |
|
} else { |
|
$element[html ? 'html' : 'text'](content); |
|
} |
|
}; |
|
|
|
_proto.getTitle = function getTitle() { |
|
var title = this.element.getAttribute('data-original-title'); |
|
|
|
if (!title) { |
|
title = typeof this.config.title === 'function' ? this.config.title.call(this.element) : this.config.title; |
|
} |
|
|
|
return title; |
|
}; // Private |
|
|
|
|
|
_proto._getAttachment = function _getAttachment(placement) { |
|
return AttachmentMap[placement.toUpperCase()]; |
|
}; |
|
|
|
_proto._setListeners = function _setListeners() { |
|
var _this3 = this; |
|
|
|
var triggers = this.config.trigger.split(' '); |
|
triggers.forEach(function (trigger) { |
|
if (trigger === 'click') { |
|
$$$1(_this3.element).on(_this3.constructor.Event.CLICK, _this3.config.selector, function (event) { |
|
return _this3.toggle(event); |
|
}); |
|
} else if (trigger !== Trigger.MANUAL) { |
|
var eventIn = trigger === Trigger.HOVER ? _this3.constructor.Event.MOUSEENTER : _this3.constructor.Event.FOCUSIN; |
|
var eventOut = trigger === Trigger.HOVER ? _this3.constructor.Event.MOUSELEAVE : _this3.constructor.Event.FOCUSOUT; |
|
$$$1(_this3.element).on(eventIn, _this3.config.selector, function (event) { |
|
return _this3._enter(event); |
|
}).on(eventOut, _this3.config.selector, function (event) { |
|
return _this3._leave(event); |
|
}); |
|
} |
|
|
|
$$$1(_this3.element).closest('.modal').on('hide.bs.modal', function () { |
|
return _this3.hide(); |
|
}); |
|
}); |
|
|
|
if (this.config.selector) { |
|
this.config = _objectSpread({}, this.config, { |
|
trigger: 'manual', |
|
selector: '' |
|
}); |
|
} else { |
|
this._fixTitle(); |
|
} |
|
}; |
|
|
|
_proto._fixTitle = function _fixTitle() { |
|
var titleType = typeof this.element.getAttribute('data-original-title'); |
|
|
|
if (this.element.getAttribute('title') || titleType !== 'string') { |
|
this.element.setAttribute('data-original-title', this.element.getAttribute('title') || ''); |
|
this.element.setAttribute('title', ''); |
|
} |
|
}; |
|
|
|
_proto._enter = function _enter(event, context) { |
|
var dataKey = this.constructor.DATA_KEY; |
|
context = context || $$$1(event.currentTarget).data(dataKey); |
|
|
|
if (!context) { |
|
context = new this.constructor(event.currentTarget, this._getDelegateConfig()); |
|
$$$1(event.currentTarget).data(dataKey, context); |
|
} |
|
|
|
if (event) { |
|
context._activeTrigger[event.type === 'focusin' ? Trigger.FOCUS : Trigger.HOVER] = true; |
|
} |
|
|
|
if ($$$1(context.getTipElement()).hasClass(ClassName.SHOW) || context._hoverState === HoverState.SHOW) { |
|
context._hoverState = HoverState.SHOW; |
|
return; |
|
} |
|
|
|
clearTimeout(context._timeout); |
|
context._hoverState = HoverState.SHOW; |
|
|
|
if (!context.config.delay || !context.config.delay.show) { |
|
context.show(); |
|
return; |
|
} |
|
|
|
context._timeout = setTimeout(function () { |
|
if (context._hoverState === HoverState.SHOW) { |
|
context.show(); |
|
} |
|
}, context.config.delay.show); |
|
}; |
|
|
|
_proto._leave = function _leave(event, context) { |
|
var dataKey = this.constructor.DATA_KEY; |
|
context = context || $$$1(event.currentTarget).data(dataKey); |
|
|
|
if (!context) { |
|
context = new this.constructor(event.currentTarget, this._getDelegateConfig()); |
|
$$$1(event.currentTarget).data(dataKey, context); |
|
} |
|
|
|
if (event) { |
|
context._activeTrigger[event.type === 'focusout' ? Trigger.FOCUS : Trigger.HOVER] = false; |
|
} |
|
|
|
if (context._isWithActiveTrigger()) { |
|
return; |
|
} |
|
|
|
clearTimeout(context._timeout); |
|
context._hoverState = HoverState.OUT; |
|
|
|
if (!context.config.delay || !context.config.delay.hide) { |
|
context.hide(); |
|
return; |
|
} |
|
|
|
context._timeout = setTimeout(function () { |
|
if (context._hoverState === HoverState.OUT) { |
|
context.hide(); |
|
} |
|
}, context.config.delay.hide); |
|
}; |
|
|
|
_proto._isWithActiveTrigger = function _isWithActiveTrigger() { |
|
for (var trigger in this._activeTrigger) { |
|
if (this._activeTrigger[trigger]) { |
|
return true; |
|
} |
|
} |
|
|
|
return false; |
|
}; |
|
|
|
_proto._getConfig = function _getConfig(config) { |
|
config = _objectSpread({}, this.constructor.Default, $$$1(this.element).data(), typeof config === 'object' && config ? config : {}); |
|
|
|
if (typeof config.delay === 'number') { |
|
config.delay = { |
|
show: config.delay, |
|
hide: config.delay |
|
}; |
|
} |
|
|
|
if (typeof config.title === 'number') { |
|
config.title = config.title.toString(); |
|
} |
|
|
|
if (typeof config.content === 'number') { |
|
config.content = config.content.toString(); |
|
} |
|
|
|
Util.typeCheckConfig(NAME, config, this.constructor.DefaultType); |
|
return config; |
|
}; |
|
|
|
_proto._getDelegateConfig = function _getDelegateConfig() { |
|
var config = {}; |
|
|
|
if (this.config) { |
|
for (var key in this.config) { |
|
if (this.constructor.Default[key] !== this.config[key]) { |
|
config[key] = this.config[key]; |
|
} |
|
} |
|
} |
|
|
|
return config; |
|
}; |
|
|
|
_proto._cleanTipClass = function _cleanTipClass() { |
|
var $tip = $$$1(this.getTipElement()); |
|
var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX); |
|
|
|
if (tabClass !== null && tabClass.length > 0) { |
|
$tip.removeClass(tabClass.join('')); |
|
} |
|
}; |
|
|
|
_proto._handlePopperPlacementChange = function _handlePopperPlacementChange(data) { |
|
this._cleanTipClass(); |
|
|
|
this.addAttachmentClass(this._getAttachment(data.placement)); |
|
}; |
|
|
|
_proto._fixTransition = function _fixTransition() { |
|
var tip = this.getTipElement(); |
|
var initConfigAnimation = this.config.animation; |
|
|
|
if (tip.getAttribute('x-placement') !== null) { |
|
return; |
|
} |
|
|
|
$$$1(tip).removeClass(ClassName.FADE); |
|
this.config.animation = false; |
|
this.hide(); |
|
this.show(); |
|
this.config.animation = initConfigAnimation; |
|
}; // Static |
|
|
|
|
|
Tooltip._jQueryInterface = function _jQueryInterface(config) { |
|
return this.each(function () { |
|
var data = $$$1(this).data(DATA_KEY); |
|
|
|
var _config = typeof config === 'object' && config; |
|
|
|
if (!data && /dispose|hide/.test(config)) { |
|
return; |
|
} |
|
|
|
if (!data) { |
|
data = new Tooltip(this, _config); |
|
$$$1(this).data(DATA_KEY, data); |
|
} |
|
|
|
if (typeof config === 'string') { |
|
if (typeof data[config] === 'undefined') { |
|
throw new TypeError("No method named \"" + config + "\""); |
|
} |
|
|
|
data[config](); |
|
} |
|
}); |
|
}; |
|
|
|
_createClass(Tooltip, null, [{ |
|
key: "VERSION", |
|
get: function get() { |
|
return VERSION; |
|
} |
|
}, { |
|
key: "Default", |
|
get: function get() { |
|
return Default; |
|
} |
|
}, { |
|
key: "NAME", |
|
get: function get() { |
|
return NAME; |
|
} |
|
}, { |
|
key: "DATA_KEY", |
|
get: function get() { |
|
return DATA_KEY; |
|
} |
|
}, { |
|
key: "Event", |
|
get: function get() { |
|
return Event; |
|
} |
|
}, { |
|
key: "EVENT_KEY", |
|
get: function get() { |
|
return EVENT_KEY; |
|
} |
|
}, { |
|
key: "DefaultType", |
|
get: function get() { |
|
return DefaultType; |
|
} |
|
}]); |
|
|
|
return Tooltip; |
|
}(); |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* jQuery |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
|
|
$$$1.fn[NAME] = Tooltip._jQueryInterface; |
|
$$$1.fn[NAME].Constructor = Tooltip; |
|
|
|
$$$1.fn[NAME].noConflict = function () { |
|
$$$1.fn[NAME] = JQUERY_NO_CONFLICT; |
|
return Tooltip._jQueryInterface; |
|
}; |
|
|
|
return Tooltip; |
|
}($, Popper); |
|
|
|
/** |
|
* -------------------------------------------------------------------------- |
|
* Bootstrap (v4.1.1): popover.js |
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
|
* -------------------------------------------------------------------------- |
|
*/ |
|
|
|
var Popover = function ($$$1) { |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Constants |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
var NAME = 'popover'; |
|
var VERSION = '4.1.1'; |
|
var DATA_KEY = 'bs.popover'; |
|
var EVENT_KEY = "." + DATA_KEY; |
|
var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; |
|
var CLASS_PREFIX = 'bs-popover'; |
|
var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g'); |
|
|
|
var Default = _objectSpread({}, Tooltip.Default, { |
|
placement: 'right', |
|
trigger: 'click', |
|
content: '', |
|
template: '<div class="popover" role="tooltip">' + '<div class="arrow"></div>' + '<h3 class="popover-header"></h3>' + '<div class="popover-body"></div></div>' |
|
}); |
|
|
|
var DefaultType = _objectSpread({}, Tooltip.DefaultType, { |
|
content: '(string|element|function)' |
|
}); |
|
|
|
var ClassName = { |
|
FADE: 'fade', |
|
SHOW: 'show' |
|
}; |
|
var Selector = { |
|
TITLE: '.popover-header', |
|
CONTENT: '.popover-body' |
|
}; |
|
var Event = { |
|
HIDE: "hide" + EVENT_KEY, |
|
HIDDEN: "hidden" + EVENT_KEY, |
|
SHOW: "show" + EVENT_KEY, |
|
SHOWN: "shown" + EVENT_KEY, |
|
INSERTED: "inserted" + EVENT_KEY, |
|
CLICK: "click" + EVENT_KEY, |
|
FOCUSIN: "focusin" + EVENT_KEY, |
|
FOCUSOUT: "focusout" + EVENT_KEY, |
|
MOUSEENTER: "mouseenter" + EVENT_KEY, |
|
MOUSELEAVE: "mouseleave" + EVENT_KEY |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Class Definition |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
}; |
|
|
|
var Popover = |
|
/*#__PURE__*/ |
|
function (_Tooltip) { |
|
_inheritsLoose(Popover, _Tooltip); |
|
|
|
function Popover() { |
|
return _Tooltip.apply(this, arguments) || this; |
|
} |
|
|
|
var _proto = Popover.prototype; |
|
|
|
// Overrides |
|
_proto.isWithContent = function isWithContent() { |
|
return this.getTitle() || this._getContent(); |
|
}; |
|
|
|
_proto.addAttachmentClass = function addAttachmentClass(attachment) { |
|
$$$1(this.getTipElement()).addClass(CLASS_PREFIX + "-" + attachment); |
|
}; |
|
|
|
_proto.getTipElement = function getTipElement() { |
|
this.tip = this.tip || $$$1(this.config.template)[0]; |
|
return this.tip; |
|
}; |
|
|
|
_proto.setContent = function setContent() { |
|
var $tip = $$$1(this.getTipElement()); // We use append for html objects to maintain js events |
|
|
|
this.setElementContent($tip.find(Selector.TITLE), this.getTitle()); |
|
|
|
var content = this._getContent(); |
|
|
|
if (typeof content === 'function') { |
|
content = content.call(this.element); |
|
} |
|
|
|
this.setElementContent($tip.find(Selector.CONTENT), content); |
|
$tip.removeClass(ClassName.FADE + " " + ClassName.SHOW); |
|
}; // Private |
|
|
|
|
|
_proto._getContent = function _getContent() { |
|
return this.element.getAttribute('data-content') || this.config.content; |
|
}; |
|
|
|
_proto._cleanTipClass = function _cleanTipClass() { |
|
var $tip = $$$1(this.getTipElement()); |
|
var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX); |
|
|
|
if (tabClass !== null && tabClass.length > 0) { |
|
$tip.removeClass(tabClass.join('')); |
|
} |
|
}; // Static |
|
|
|
|
|
Popover._jQueryInterface = function _jQueryInterface(config) { |
|
return this.each(function () { |
|
var data = $$$1(this).data(DATA_KEY); |
|
|
|
var _config = typeof config === 'object' ? config : null; |
|
|
|
if (!data && /destroy|hide/.test(config)) { |
|
return; |
|
} |
|
|
|
if (!data) { |
|
data = new Popover(this, _config); |
|
$$$1(this).data(DATA_KEY, data); |
|
} |
|
|
|
if (typeof config === 'string') { |
|
if (typeof data[config] === 'undefined') { |
|
throw new TypeError("No method named \"" + config + "\""); |
|
} |
|
|
|
data[config](); |
|
} |
|
}); |
|
}; |
|
|
|
_createClass(Popover, null, [{ |
|
key: "VERSION", |
|
// Getters |
|
get: function get() { |
|
return VERSION; |
|
} |
|
}, { |
|
key: "Default", |
|
get: function get() { |
|
return Default; |
|
} |
|
}, { |
|
key: "NAME", |
|
get: function get() { |
|
return NAME; |
|
} |
|
}, { |
|
key: "DATA_KEY", |
|
get: function get() { |
|
return DATA_KEY; |
|
} |
|
}, { |
|
key: "Event", |
|
get: function get() { |
|
return Event; |
|
} |
|
}, { |
|
key: "EVENT_KEY", |
|
get: function get() { |
|
return EVENT_KEY; |
|
} |
|
}, { |
|
key: "DefaultType", |
|
get: function get() { |
|
return DefaultType; |
|
} |
|
}]); |
|
|
|
return Popover; |
|
}(Tooltip); |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* jQuery |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
|
|
$$$1.fn[NAME] = Popover._jQueryInterface; |
|
$$$1.fn[NAME].Constructor = Popover; |
|
|
|
$$$1.fn[NAME].noConflict = function () { |
|
$$$1.fn[NAME] = JQUERY_NO_CONFLICT; |
|
return Popover._jQueryInterface; |
|
}; |
|
|
|
return Popover; |
|
}($); |
|
|
|
/** |
|
* -------------------------------------------------------------------------- |
|
* Bootstrap (v4.1.1): scrollspy.js |
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
|
* -------------------------------------------------------------------------- |
|
*/ |
|
|
|
var ScrollSpy = function ($$$1) { |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Constants |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
var NAME = 'scrollspy'; |
|
var VERSION = '4.1.1'; |
|
var DATA_KEY = 'bs.scrollspy'; |
|
var EVENT_KEY = "." + DATA_KEY; |
|
var DATA_API_KEY = '.data-api'; |
|
var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; |
|
var Default = { |
|
offset: 10, |
|
method: 'auto', |
|
target: '' |
|
}; |
|
var DefaultType = { |
|
offset: 'number', |
|
method: 'string', |
|
target: '(string|element)' |
|
}; |
|
var Event = { |
|
ACTIVATE: "activate" + EVENT_KEY, |
|
SCROLL: "scroll" + EVENT_KEY, |
|
LOAD_DATA_API: "load" + EVENT_KEY + DATA_API_KEY |
|
}; |
|
var ClassName = { |
|
DROPDOWN_ITEM: 'dropdown-item', |
|
DROPDOWN_MENU: 'dropdown-menu', |
|
ACTIVE: 'active' |
|
}; |
|
var Selector = { |
|
DATA_SPY: '[data-spy="scroll"]', |
|
ACTIVE: '.active', |
|
NAV_LIST_GROUP: '.nav, .list-group', |
|
NAV_LINKS: '.nav-link', |
|
NAV_ITEMS: '.nav-item', |
|
LIST_ITEMS: '.list-group-item', |
|
DROPDOWN: '.dropdown', |
|
DROPDOWN_ITEMS: '.dropdown-item', |
|
DROPDOWN_TOGGLE: '.dropdown-toggle' |
|
}; |
|
var OffsetMethod = { |
|
OFFSET: 'offset', |
|
POSITION: 'position' |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Class Definition |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
}; |
|
|
|
var ScrollSpy = |
|
/*#__PURE__*/ |
|
function () { |
|
function ScrollSpy(element, config) { |
|
var _this = this; |
|
|
|
this._element = element; |
|
this._scrollElement = element.tagName === 'BODY' ? window : element; |
|
this._config = this._getConfig(config); |
|
this._selector = this._config.target + " " + Selector.NAV_LINKS + "," + (this._config.target + " " + Selector.LIST_ITEMS + ",") + (this._config.target + " " + Selector.DROPDOWN_ITEMS); |
|
this._offsets = []; |
|
this._targets = []; |
|
this._activeTarget = null; |
|
this._scrollHeight = 0; |
|
$$$1(this._scrollElement).on(Event.SCROLL, function (event) { |
|
return _this._process(event); |
|
}); |
|
this.refresh(); |
|
|
|
this._process(); |
|
} // Getters |
|
|
|
|
|
var _proto = ScrollSpy.prototype; |
|
|
|
// Public |
|
_proto.refresh = function refresh() { |
|
var _this2 = this; |
|
|
|
var autoMethod = this._scrollElement === this._scrollElement.window ? OffsetMethod.OFFSET : OffsetMethod.POSITION; |
|
var offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method; |
|
var offsetBase = offsetMethod === OffsetMethod.POSITION ? this._getScrollTop() : 0; |
|
this._offsets = []; |
|
this._targets = []; |
|
this._scrollHeight = this._getScrollHeight(); |
|
var targets = $$$1.makeArray($$$1(this._selector)); |
|
targets.map(function (element) { |
|
var target; |
|
var targetSelector = Util.getSelectorFromElement(element); |
|
|
|
if (targetSelector) { |
|
target = $$$1(targetSelector)[0]; |
|
} |
|
|
|
if (target) { |
|
var targetBCR = target.getBoundingClientRect(); |
|
|
|
if (targetBCR.width || targetBCR.height) { |
|
// TODO (fat): remove sketch reliance on jQuery position/offset |
|
return [$$$1(target)[offsetMethod]().top + offsetBase, targetSelector]; |
|
} |
|
} |
|
|
|
return null; |
|
}).filter(function (item) { |
|
return item; |
|
}).sort(function (a, b) { |
|
return a[0] - b[0]; |
|
}).forEach(function (item) { |
|
_this2._offsets.push(item[0]); |
|
|
|
_this2._targets.push(item[1]); |
|
}); |
|
}; |
|
|
|
_proto.dispose = function dispose() { |
|
$$$1.removeData(this._element, DATA_KEY); |
|
$$$1(this._scrollElement).off(EVENT_KEY); |
|
this._element = null; |
|
this._scrollElement = null; |
|
this._config = null; |
|
this._selector = null; |
|
this._offsets = null; |
|
this._targets = null; |
|
this._activeTarget = null; |
|
this._scrollHeight = null; |
|
}; // Private |
|
|
|
|
|
_proto._getConfig = function _getConfig(config) { |
|
config = _objectSpread({}, Default, typeof config === 'object' && config ? config : {}); |
|
|
|
if (typeof config.target !== 'string') { |
|
var id = $$$1(config.target).attr('id'); |
|
|
|
if (!id) { |
|
id = Util.getUID(NAME); |
|
$$$1(config.target).attr('id', id); |
|
} |
|
|
|
config.target = "#" + id; |
|
} |
|
|
|
Util.typeCheckConfig(NAME, config, DefaultType); |
|
return config; |
|
}; |
|
|
|
_proto._getScrollTop = function _getScrollTop() { |
|
return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop; |
|
}; |
|
|
|
_proto._getScrollHeight = function _getScrollHeight() { |
|
return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight); |
|
}; |
|
|
|
_proto._getOffsetHeight = function _getOffsetHeight() { |
|
return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height; |
|
}; |
|
|
|
_proto._process = function _process() { |
|
var scrollTop = this._getScrollTop() + this._config.offset; |
|
|
|
var scrollHeight = this._getScrollHeight(); |
|
|
|
var maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight(); |
|
|
|
if (this._scrollHeight !== scrollHeight) { |
|
this.refresh(); |
|
} |
|
|
|
if (scrollTop >= maxScroll) { |
|
var target = this._targets[this._targets.length - 1]; |
|
|
|
if (this._activeTarget !== target) { |
|
this._activate(target); |
|
} |
|
|
|
return; |
|
} |
|
|
|
if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) { |
|
this._activeTarget = null; |
|
|
|
this._clear(); |
|
|
|
return; |
|
} |
|
|
|
for (var i = this._offsets.length; i--;) { |
|
var isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1]); |
|
|
|
if (isActiveTarget) { |
|
this._activate(this._targets[i]); |
|
} |
|
} |
|
}; |
|
|
|
_proto._activate = function _activate(target) { |
|
this._activeTarget = target; |
|
|
|
this._clear(); |
|
|
|
var queries = this._selector.split(','); // eslint-disable-next-line arrow-body-style |
|
|
|
|
|
queries = queries.map(function (selector) { |
|
return selector + "[data-target=\"" + target + "\"]," + (selector + "[href=\"" + target + "\"]"); |
|
}); |
|
var $link = $$$1(queries.join(',')); |
|
|
|
if ($link.hasClass(ClassName.DROPDOWN_ITEM)) { |
|
$link.closest(Selector.DROPDOWN).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE); |
|
$link.addClass(ClassName.ACTIVE); |
|
} else { |
|
// Set triggered link as active |
|
$link.addClass(ClassName.ACTIVE); // Set triggered links parents as active |
|
// With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor |
|
|
|
$link.parents(Selector.NAV_LIST_GROUP).prev(Selector.NAV_LINKS + ", " + Selector.LIST_ITEMS).addClass(ClassName.ACTIVE); // Handle special case when .nav-link is inside .nav-item |
|
|
|
$link.parents(Selector.NAV_LIST_GROUP).prev(Selector.NAV_ITEMS).children(Selector.NAV_LINKS).addClass(ClassName.ACTIVE); |
|
} |
|
|
|
$$$1(this._scrollElement).trigger(Event.ACTIVATE, { |
|
relatedTarget: target |
|
}); |
|
}; |
|
|
|
_proto._clear = function _clear() { |
|
$$$1(this._selector).filter(Selector.ACTIVE).removeClass(ClassName.ACTIVE); |
|
}; // Static |
|
|
|
|
|
ScrollSpy._jQueryInterface = function _jQueryInterface(config) { |
|
return this.each(function () { |
|
var data = $$$1(this).data(DATA_KEY); |
|
|
|
var _config = typeof config === 'object' && config; |
|
|
|
if (!data) { |
|
data = new ScrollSpy(this, _config); |
|
$$$1(this).data(DATA_KEY, data); |
|
} |
|
|
|
if (typeof config === 'string') { |
|
if (typeof data[config] === 'undefined') { |
|
throw new TypeError("No method named \"" + config + "\""); |
|
} |
|
|
|
data[config](); |
|
} |
|
}); |
|
}; |
|
|
|
_createClass(ScrollSpy, null, [{ |
|
key: "VERSION", |
|
get: function get() { |
|
return VERSION; |
|
} |
|
}, { |
|
key: "Default", |
|
get: function get() { |
|
return Default; |
|
} |
|
}]); |
|
|
|
return ScrollSpy; |
|
}(); |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Data Api implementation |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
|
|
$$$1(window).on(Event.LOAD_DATA_API, function () { |
|
var scrollSpys = $$$1.makeArray($$$1(Selector.DATA_SPY)); |
|
|
|
for (var i = scrollSpys.length; i--;) { |
|
var $spy = $$$1(scrollSpys[i]); |
|
|
|
ScrollSpy._jQueryInterface.call($spy, $spy.data()); |
|
} |
|
}); |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* jQuery |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
$$$1.fn[NAME] = ScrollSpy._jQueryInterface; |
|
$$$1.fn[NAME].Constructor = ScrollSpy; |
|
|
|
$$$1.fn[NAME].noConflict = function () { |
|
$$$1.fn[NAME] = JQUERY_NO_CONFLICT; |
|
return ScrollSpy._jQueryInterface; |
|
}; |
|
|
|
return ScrollSpy; |
|
}($); |
|
|
|
/** |
|
* -------------------------------------------------------------------------- |
|
* Bootstrap (v4.1.1): tab.js |
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
|
* -------------------------------------------------------------------------- |
|
*/ |
|
|
|
var Tab = function ($$$1) { |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Constants |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
var NAME = 'tab'; |
|
var VERSION = '4.1.1'; |
|
var DATA_KEY = 'bs.tab'; |
|
var EVENT_KEY = "." + DATA_KEY; |
|
var DATA_API_KEY = '.data-api'; |
|
var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; |
|
var Event = { |
|
HIDE: "hide" + EVENT_KEY, |
|
HIDDEN: "hidden" + EVENT_KEY, |
|
SHOW: "show" + EVENT_KEY, |
|
SHOWN: "shown" + EVENT_KEY, |
|
CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY |
|
}; |
|
var ClassName = { |
|
DROPDOWN_MENU: 'dropdown-menu', |
|
ACTIVE: 'active', |
|
DISABLED: 'disabled', |
|
FADE: 'fade', |
|
SHOW: 'show' |
|
}; |
|
var Selector = { |
|
DROPDOWN: '.dropdown', |
|
NAV_LIST_GROUP: '.nav, .list-group', |
|
ACTIVE: '.active', |
|
ACTIVE_UL: '> li > .active', |
|
DATA_TOGGLE: '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]', |
|
DROPDOWN_TOGGLE: '.dropdown-toggle', |
|
DROPDOWN_ACTIVE_CHILD: '> .dropdown-menu .active' |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Class Definition |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
}; |
|
|
|
var Tab = |
|
/*#__PURE__*/ |
|
function () { |
|
function Tab(element) { |
|
this._element = element; |
|
} // Getters |
|
|
|
|
|
var _proto = Tab.prototype; |
|
|
|
// Public |
|
_proto.show = function show() { |
|
var _this = this; |
|
|
|
if (this._element.parentNode && this._element.parentNode.nodeType === Node.ELEMENT_NODE && $$$1(this._element).hasClass(ClassName.ACTIVE) || $$$1(this._element).hasClass(ClassName.DISABLED)) { |
|
return; |
|
} |
|
|
|
var target; |
|
var previous; |
|
var listElement = $$$1(this._element).closest(Selector.NAV_LIST_GROUP)[0]; |
|
var selector = Util.getSelectorFromElement(this._element); |
|
|
|
if (listElement) { |
|
var itemSelector = listElement.nodeName === 'UL' ? Selector.ACTIVE_UL : Selector.ACTIVE; |
|
previous = $$$1.makeArray($$$1(listElement).find(itemSelector)); |
|
previous = previous[previous.length - 1]; |
|
} |
|
|
|
var hideEvent = $$$1.Event(Event.HIDE, { |
|
relatedTarget: this._element |
|
}); |
|
var showEvent = $$$1.Event(Event.SHOW, { |
|
relatedTarget: previous |
|
}); |
|
|
|
if (previous) { |
|
$$$1(previous).trigger(hideEvent); |
|
} |
|
|
|
$$$1(this._element).trigger(showEvent); |
|
|
|
if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) { |
|
return; |
|
} |
|
|
|
if (selector) { |
|
target = $$$1(selector)[0]; |
|
} |
|
|
|
this._activate(this._element, listElement); |
|
|
|
var complete = function complete() { |
|
var hiddenEvent = $$$1.Event(Event.HIDDEN, { |
|
relatedTarget: _this._element |
|
}); |
|
var shownEvent = $$$1.Event(Event.SHOWN, { |
|
relatedTarget: previous |
|
}); |
|
$$$1(previous).trigger(hiddenEvent); |
|
$$$1(_this._element).trigger(shownEvent); |
|
}; |
|
|
|
if (target) { |
|
this._activate(target, target.parentNode, complete); |
|
} else { |
|
complete(); |
|
} |
|
}; |
|
|
|
_proto.dispose = function dispose() { |
|
$$$1.removeData(this._element, DATA_KEY); |
|
this._element = null; |
|
}; // Private |
|
|
|
|
|
_proto._activate = function _activate(element, container, callback) { |
|
var _this2 = this; |
|
|
|
var activeElements; |
|
|
|
if (container.nodeName === 'UL') { |
|
activeElements = $$$1(container).find(Selector.ACTIVE_UL); |
|
} else { |
|
activeElements = $$$1(container).children(Selector.ACTIVE); |
|
} |
|
|
|
var active = activeElements[0]; |
|
var isTransitioning = callback && active && $$$1(active).hasClass(ClassName.FADE); |
|
|
|
var complete = function complete() { |
|
return _this2._transitionComplete(element, active, callback); |
|
}; |
|
|
|
if (active && isTransitioning) { |
|
var transitionDuration = Util.getTransitionDurationFromElement(active); |
|
$$$1(active).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); |
|
} else { |
|
complete(); |
|
} |
|
}; |
|
|
|
_proto._transitionComplete = function _transitionComplete(element, active, callback) { |
|
if (active) { |
|
$$$1(active).removeClass(ClassName.SHOW + " " + ClassName.ACTIVE); |
|
var dropdownChild = $$$1(active.parentNode).find(Selector.DROPDOWN_ACTIVE_CHILD)[0]; |
|
|
|
if (dropdownChild) { |
|
$$$1(dropdownChild).removeClass(ClassName.ACTIVE); |
|
} |
|
|
|
if (active.getAttribute('role') === 'tab') { |
|
active.setAttribute('aria-selected', false); |
|
} |
|
} |
|
|
|
$$$1(element).addClass(ClassName.ACTIVE); |
|
|
|
if (element.getAttribute('role') === 'tab') { |
|
element.setAttribute('aria-selected', true); |
|
} |
|
|
|
Util.reflow(element); |
|
$$$1(element).addClass(ClassName.SHOW); |
|
|
|
if (element.parentNode && $$$1(element.parentNode).hasClass(ClassName.DROPDOWN_MENU)) { |
|
var dropdownElement = $$$1(element).closest(Selector.DROPDOWN)[0]; |
|
|
|
if (dropdownElement) { |
|
$$$1(dropdownElement).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE); |
|
} |
|
|
|
element.setAttribute('aria-expanded', true); |
|
} |
|
|
|
if (callback) { |
|
callback(); |
|
} |
|
}; // Static |
|
|
|
|
|
Tab._jQueryInterface = function _jQueryInterface(config) { |
|
return this.each(function () { |
|
var $this = $$$1(this); |
|
var data = $this.data(DATA_KEY); |
|
|
|
if (!data) { |
|
data = new Tab(this); |
|
$this.data(DATA_KEY, data); |
|
} |
|
|
|
if (typeof config === 'string') { |
|
if (typeof data[config] === 'undefined') { |
|
throw new TypeError("No method named \"" + config + "\""); |
|
} |
|
|
|
data[config](); |
|
} |
|
}); |
|
}; |
|
|
|
_createClass(Tab, null, [{ |
|
key: "VERSION", |
|
get: function get() { |
|
return VERSION; |
|
} |
|
}]); |
|
|
|
return Tab; |
|
}(); |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* Data Api implementation |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
|
|
$$$1(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { |
|
event.preventDefault(); |
|
|
|
Tab._jQueryInterface.call($$$1(this), 'show'); |
|
}); |
|
/** |
|
* ------------------------------------------------------------------------ |
|
* jQuery |
|
* ------------------------------------------------------------------------ |
|
*/ |
|
|
|
$$$1.fn[NAME] = Tab._jQueryInterface; |
|
$$$1.fn[NAME].Constructor = Tab; |
|
|
|
$$$1.fn[NAME].noConflict = function () { |
|
$$$1.fn[NAME] = JQUERY_NO_CONFLICT; |
|
return Tab._jQueryInterface; |
|
}; |
|
|
|
return Tab; |
|
}($); |
|
|
|
/** |
|
* -------------------------------------------------------------------------- |
|
* Bootstrap (v4.1.1): index.js |
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
|
* -------------------------------------------------------------------------- |
|
*/ |
|
|
|
(function ($$$1) { |
|
if (typeof $$$1 === 'undefined') { |
|
throw new TypeError('Bootstrap\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\'s JavaScript.'); |
|
} |
|
|
|
var version = $$$1.fn.jquery.split(' ')[0].split('.'); |
|
var minMajor = 1; |
|
var ltMajor = 2; |
|
var minMinor = 9; |
|
var minPatch = 1; |
|
var maxMajor = 4; |
|
|
|
if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) { |
|
throw new Error('Bootstrap\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0'); |
|
} |
|
})($); |
|
|
|
exports.Util = Util; |
|
exports.Alert = Alert; |
|
exports.Button = Button; |
|
exports.Carousel = Carousel; |
|
exports.Collapse = Collapse; |
|
exports.Dropdown = Dropdown; |
|
exports.Modal = Modal; |
|
exports.Popover = Popover; |
|
exports.Scrollspy = ScrollSpy; |
|
exports.Tab = Tab; |
|
exports.Tooltip = Tooltip; |
|
|
|
Object.defineProperty(exports, '__esModule', { value: true }); |
|
|
|
}))); |
|
//# sourceMappingURL=bootstrap.js.map |
|
|
|
|
|
/***/ }), |
|
/* 17 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
module.exports = __webpack_require__(18); |
|
|
|
/***/ }), |
|
/* 18 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
"use strict"; |
|
|
|
|
|
var utils = __webpack_require__(0); |
|
var bind = __webpack_require__(5); |
|
var Axios = __webpack_require__(20); |
|
var defaults = __webpack_require__(2); |
|
|
|
/** |
|
* 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__(10); |
|
axios.CancelToken = __webpack_require__(34); |
|
axios.isCancel = __webpack_require__(9); |
|
|
|
// Expose all/spread |
|
axios.all = function all(promises) { |
|
return Promise.all(promises); |
|
}; |
|
axios.spread = __webpack_require__(35); |
|
|
|
module.exports = axios; |
|
|
|
// Allow use of default import syntax in TypeScript |
|
module.exports.default = axios; |
|
|
|
|
|
/***/ }), |
|
/* 19 */ |
|
/***/ (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)) |
|
} |
|
|
|
|
|
/***/ }), |
|
/* 20 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
"use strict"; |
|
|
|
|
|
var defaults = __webpack_require__(2); |
|
var utils = __webpack_require__(0); |
|
var InterceptorManager = __webpack_require__(29); |
|
var dispatchRequest = __webpack_require__(30); |
|
|
|
/** |
|
* 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, {method: 'get'}, this.defaults, 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; |
|
|
|
|
|
/***/ }), |
|
/* 21 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
"use strict"; |
|
|
|
|
|
var utils = __webpack_require__(0); |
|
|
|
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]; |
|
} |
|
}); |
|
}; |
|
|
|
|
|
/***/ }), |
|
/* 22 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
"use strict"; |
|
|
|
|
|
var createError = __webpack_require__(8); |
|
|
|
/** |
|
* 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 |
|
)); |
|
} |
|
}; |
|
|
|
|
|
/***/ }), |
|
/* 23 */ |
|
/***/ (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; |
|
}; |
|
|
|
|
|
/***/ }), |
|
/* 24 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
"use strict"; |
|
|
|
|
|
var utils = __webpack_require__(0); |
|
|
|
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 + '[]'; |
|
} else { |
|
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; |
|
}; |
|
|
|
|
|
/***/ }), |
|
/* 25 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
"use strict"; |
|
|
|
|
|
var utils = __webpack_require__(0); |
|
|
|
// 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; |
|
}; |
|
|
|
|
|
/***/ }), |
|
/* 26 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
"use strict"; |
|
|
|
|
|
var utils = __webpack_require__(0); |
|
|
|
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; |
|
}; |
|
})() |
|
); |
|
|
|
|
|
/***/ }), |
|
/* 27 */ |
|
/***/ (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; |
|
|
|
|
|
/***/ }), |
|
/* 28 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
"use strict"; |
|
|
|
|
|
var utils = __webpack_require__(0); |
|
|
|
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() {} |
|
}; |
|
})() |
|
); |
|
|
|
|
|
/***/ }), |
|
/* 29 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
"use strict"; |
|
|
|
|
|
var utils = __webpack_require__(0); |
|
|
|
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; |
|
|
|
|
|
/***/ }), |
|
/* 30 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
"use strict"; |
|
|
|
|
|
var utils = __webpack_require__(0); |
|
var transformData = __webpack_require__(31); |
|
var isCancel = __webpack_require__(9); |
|
var defaults = __webpack_require__(2); |
|
var isAbsoluteURL = __webpack_require__(32); |
|
var combineURLs = __webpack_require__(33); |
|
|
|
/** |
|
* 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); |
|
}); |
|
}; |
|
|
|
|
|
/***/ }), |
|
/* 31 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
"use strict"; |
|
|
|
|
|
var utils = __webpack_require__(0); |
|
|
|
/** |
|
* 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; |
|
}; |
|
|
|
|
|
/***/ }), |
|
/* 32 */ |
|
/***/ (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); |
|
}; |
|
|
|
|
|
/***/ }), |
|
/* 33 */ |
|
/***/ (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; |
|
}; |
|
|
|
|
|
/***/ }), |
|
/* 34 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
"use strict"; |
|
|
|
|
|
var Cancel = __webpack_require__(10); |
|
|
|
/** |
|
* 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; |
|
|
|
|
|
/***/ }), |
|
/* 35 */ |
|
/***/ (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); |
|
}; |
|
}; |
|
|
|
|
|
/***/ }), |
|
/* 36 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
"use strict"; |
|
/* WEBPACK VAR INJECTION */(function(global, setImmediate) {/*! |
|
* Vue.js v2.5.16 |
|
* (c) 2014-2018 Evan You |
|
* Released under the MIT License. |
|
*/ |
|
|
|
|
|
/* */ |
|
|
|
var emptyObject = Object.freeze({}); |
|
|
|
// these helpers produces better vm code in JS engines due to their |
|
// explicitness and function inlining |
|
function isUndef (v) { |
|
return v === undefined || v === null |
|
} |
|
|
|
function isDef (v) { |
|
return v !== undefined && v !== null |
|
} |
|
|
|
function isTrue (v) { |
|
return v === true |
|
} |
|
|
|
function isFalse (v) { |
|
return v === false |
|
} |
|
|
|
/** |
|
* Check if value is primitive |
|
*/ |
|
function isPrimitive (value) { |
|
return ( |
|
typeof value === 'string' || |
|
typeof value === 'number' || |
|
// $flow-disable-line |
|
typeof value === 'symbol' || |
|
typeof value === 'boolean' |
|
) |
|
} |
|
|
|
/** |
|
* Quick object check - this is primarily used to tell |
|
* Objects from primitive values when we know the value |
|
* is a JSON-compliant type. |
|
*/ |
|
function isObject (obj) { |
|
return obj !== null && typeof obj === 'object' |
|
} |
|
|
|
/** |
|
* Get the raw type string of a value e.g. [object Object] |
|
*/ |
|
var _toString = Object.prototype.toString; |
|
|
|
function toRawType (value) { |
|
return _toString.call(value).slice(8, -1) |
|
} |
|
|
|
/** |
|
* Strict object type check. Only returns true |
|
* for plain JavaScript objects. |
|
*/ |
|
function isPlainObject (obj) { |
|
return _toString.call(obj) === '[object Object]' |
|
} |
|
|
|
function isRegExp (v) { |
|
return _toString.call(v) === '[object RegExp]' |
|
} |
|
|
|
/** |
|
* Check if val is a valid array index. |
|
*/ |
|
function isValidArrayIndex (val) { |
|
var n = parseFloat(String(val)); |
|
return n >= 0 && Math.floor(n) === n && isFinite(val) |
|
} |
|
|
|
/** |
|
* Convert a value to a string that is actually rendered. |
|
*/ |
|
function toString (val) { |
|
return val == null |
|
? '' |
|
: typeof val === 'object' |
|
? JSON.stringify(val, null, 2) |
|
: String(val) |
|
} |
|
|
|
/** |
|
* Convert a input value to a number for persistence. |
|
* If the conversion fails, return original string. |
|
*/ |
|
function toNumber (val) { |
|
var n = parseFloat(val); |
|
return isNaN(n) ? val : n |
|
} |
|
|
|
/** |
|
* Make a map and return a function for checking if a key |
|
* is in that map. |
|
*/ |
|
function makeMap ( |
|
str, |
|
expectsLowerCase |
|
) { |
|
var map = Object.create(null); |
|
var list = str.split(','); |
|
for (var i = 0; i < list.length; i++) { |
|
map[list[i]] = true; |
|
} |
|
return expectsLowerCase |
|
? function (val) { return map[val.toLowerCase()]; } |
|
: function (val) { return map[val]; } |
|
} |
|
|
|
/** |
|
* Check if a tag is a built-in tag. |
|
*/ |
|
var isBuiltInTag = makeMap('slot,component', true); |
|
|
|
/** |
|
* Check if a attribute is a reserved attribute. |
|
*/ |
|
var isReservedAttribute = makeMap('key,ref,slot,slot-scope,is'); |
|
|
|
/** |
|
* Remove an item from an array |
|
*/ |
|
function remove (arr, item) { |
|
if (arr.length) { |
|
var index = arr.indexOf(item); |
|
if (index > -1) { |
|
return arr.splice(index, 1) |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* Check whether the object has the property. |
|
*/ |
|
var hasOwnProperty = Object.prototype.hasOwnProperty; |
|
function hasOwn (obj, key) { |
|
return hasOwnProperty.call(obj, key) |
|
} |
|
|
|
/** |
|
* Create a cached version of a pure function. |
|
*/ |
|
function cached (fn) { |
|
var cache = Object.create(null); |
|
return (function cachedFn (str) { |
|
var hit = cache[str]; |
|
return hit || (cache[str] = fn(str)) |
|
}) |
|
} |
|
|
|
/** |
|
* Camelize a hyphen-delimited string. |
|
*/ |
|
var camelizeRE = /-(\w)/g; |
|
var camelize = cached(function (str) { |
|
return str.replace(camelizeRE, function (_, c) { return c ? c.toUpperCase() : ''; }) |
|
}); |
|
|
|
/** |
|
* Capitalize a string. |
|
*/ |
|
var capitalize = cached(function (str) { |
|
return str.charAt(0).toUpperCase() + str.slice(1) |
|
}); |
|
|
|
/** |
|
* Hyphenate a camelCase string. |
|
*/ |
|
var hyphenateRE = /\B([A-Z])/g; |
|
var hyphenate = cached(function (str) { |
|
return str.replace(hyphenateRE, '-$1').toLowerCase() |
|
}); |
|
|
|
/** |
|
* Simple bind polyfill for environments that do not support it... e.g. |
|
* PhantomJS 1.x. Technically we don't need this anymore since native bind is |
|
* now more performant in most browsers, but removing it would be breaking for |
|
* code that was able to run in PhantomJS 1.x, so this must be kept for |
|
* backwards compatibility. |
|
*/ |
|
|
|
/* istanbul ignore next */ |
|
function polyfillBind (fn, ctx) { |
|
function boundFn (a) { |
|
var l = arguments.length; |
|
return l |
|
? l > 1 |
|
? fn.apply(ctx, arguments) |
|
: fn.call(ctx, a) |
|
: fn.call(ctx) |
|
} |
|
|
|
boundFn._length = fn.length; |
|
return boundFn |
|
} |
|
|
|
function nativeBind (fn, ctx) { |
|
return fn.bind(ctx) |
|
} |
|
|
|
var bind = Function.prototype.bind |
|
? nativeBind |
|
: polyfillBind; |
|
|
|
/** |
|
* Convert an Array-like object to a real Array. |
|
*/ |
|
function toArray (list, start) { |
|
start = start || 0; |
|
var i = list.length - start; |
|
var ret = new Array(i); |
|
while (i--) { |
|
ret[i] = list[i + start]; |
|
} |
|
return ret |
|
} |
|
|
|
/** |
|
* Mix properties into target object. |
|
*/ |
|
function extend (to, _from) { |
|
for (var key in _from) { |
|
to[key] = _from[key]; |
|
} |
|
return to |
|
} |
|
|
|
/** |
|
* Merge an Array of Objects into a single Object. |
|
*/ |
|
function toObject (arr) { |
|
var res = {}; |
|
for (var i = 0; i < arr.length; i++) { |
|
if (arr[i]) { |
|
extend(res, arr[i]); |
|
} |
|
} |
|
return res |
|
} |
|
|
|
/** |
|
* Perform no operation. |
|
* Stubbing args to make Flow happy without leaving useless transpiled code |
|
* with ...rest (https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity/) |
|
*/ |
|
function noop (a, b, c) {} |
|
|
|
/** |
|
* Always return false. |
|
*/ |
|
var no = function (a, b, c) { return false; }; |
|
|
|
/** |
|
* Return same value |
|
*/ |
|
var identity = function (_) { return _; }; |
|
|
|
/** |
|
* Generate a static keys string from compiler modules. |
|
*/ |
|
function genStaticKeys (modules) { |
|
return modules.reduce(function (keys, m) { |
|
return keys.concat(m.staticKeys || []) |
|
}, []).join(',') |
|
} |
|
|
|
/** |
|
* Check if two values are loosely equal - that is, |
|
* if they are plain objects, do they have the same shape? |
|
*/ |
|
function looseEqual (a, b) { |
|
if (a === b) { return true } |
|
var isObjectA = isObject(a); |
|
var isObjectB = isObject(b); |
|
if (isObjectA && isObjectB) { |
|
try { |
|
var isArrayA = Array.isArray(a); |
|
var isArrayB = Array.isArray(b); |
|
if (isArrayA && isArrayB) { |
|
return a.length === b.length && a.every(function (e, i) { |
|
return looseEqual(e, b[i]) |
|
}) |
|
} else if (!isArrayA && !isArrayB) { |
|
var keysA = Object.keys(a); |
|
var keysB = Object.keys(b); |
|
return keysA.length === keysB.length && keysA.every(function (key) { |
|
return looseEqual(a[key], b[key]) |
|
}) |
|
} else { |
|
/* istanbul ignore next */ |
|
return false |
|
} |
|
} catch (e) { |
|
/* istanbul ignore next */ |
|
return false |
|
} |
|
} else if (!isObjectA && !isObjectB) { |
|
return String(a) === String(b) |
|
} else { |
|
return false |
|
} |
|
} |
|
|
|
function looseIndexOf (arr, val) { |
|
for (var i = 0; i < arr.length; i++) { |
|
if (looseEqual(arr[i], val)) { return i } |
|
} |
|
return -1 |
|
} |
|
|
|
/** |
|
* Ensure a function is called only once. |
|
*/ |
|
function once (fn) { |
|
var called = false; |
|
return function () { |
|
if (!called) { |
|
called = true; |
|
fn.apply(this, arguments); |
|
} |
|
} |
|
} |
|
|
|
var SSR_ATTR = 'data-server-rendered'; |
|
|
|
var ASSET_TYPES = [ |
|
'component', |
|
'directive', |
|
'filter' |
|
]; |
|
|
|
var LIFECYCLE_HOOKS = [ |
|
'beforeCreate', |
|
'created', |
|
'beforeMount', |
|
'mounted', |
|
'beforeUpdate', |
|
'updated', |
|
'beforeDestroy', |
|
'destroyed', |
|
'activated', |
|
'deactivated', |
|
'errorCaptured' |
|
]; |
|
|
|
/* */ |
|
|
|
var config = ({ |
|
/** |
|
* Option merge strategies (used in core/util/options) |
|
*/ |
|
// $flow-disable-line |
|
optionMergeStrategies: Object.create(null), |
|
|
|
/** |
|
* Whether to suppress warnings. |
|
*/ |
|
silent: false, |
|
|
|
/** |
|
* Show production mode tip message on boot? |
|
*/ |
|
productionTip: "development" !== 'production', |
|
|
|
/** |
|
* Whether to enable devtools |
|
*/ |
|
devtools: "development" !== 'production', |
|
|
|
/** |
|
* Whether to record perf |
|
*/ |
|
performance: false, |
|
|
|
/** |
|
* Error handler for watcher errors |
|
*/ |
|
errorHandler: null, |
|
|
|
/** |
|
* Warn handler for watcher warns |
|
*/ |
|
warnHandler: null, |
|
|
|
/** |
|
* Ignore certain custom elements |
|
*/ |
|
ignoredElements: [], |
|
|
|
/** |
|
* Custom user key aliases for v-on |
|
*/ |
|
// $flow-disable-line |
|
keyCodes: Object.create(null), |
|
|
|
/** |
|
* Check if a tag is reserved so that it cannot be registered as a |
|
* component. This is platform-dependent and may be overwritten. |
|
*/ |
|
isReservedTag: no, |
|
|
|
/** |
|
* Check if an attribute is reserved so that it cannot be used as a component |
|
* prop. This is platform-dependent and may be overwritten. |
|
*/ |
|
isReservedAttr: no, |
|
|
|
/** |
|
* Check if a tag is an unknown element. |
|
* Platform-dependent. |
|
*/ |
|
isUnknownElement: no, |
|
|
|
/** |
|
* Get the namespace of an element |
|
*/ |
|
getTagNamespace: noop, |
|
|
|
/** |
|
* Parse the real tag name for the specific platform. |
|
*/ |
|
parsePlatformTagName: identity, |
|
|
|
/** |
|
* Check if an attribute must be bound using property, e.g. value |
|
* Platform-dependent. |
|
*/ |
|
mustUseProp: no, |
|
|
|
/** |
|
* Exposed for legacy reasons |
|
*/ |
|
_lifecycleHooks: LIFECYCLE_HOOKS |
|
}) |
|
|
|
/* */ |
|
|
|
/** |
|
* Check if a string starts with $ or _ |
|
*/ |
|
function isReserved (str) { |
|
var c = (str + '').charCodeAt(0); |
|
return c === 0x24 || c === 0x5F |
|
} |
|
|
|
/** |
|
* Define a property. |
|
*/ |
|
function def (obj, key, val, enumerable) { |
|
Object.defineProperty(obj, key, { |
|
value: val, |
|
enumerable: !!enumerable, |
|
writable: true, |
|
configurable: true |
|
}); |
|
} |
|
|
|
/** |
|
* Parse simple path. |
|
*/ |
|
var bailRE = /[^\w.$]/; |
|
function parsePath (path) { |
|
if (bailRE.test(path)) { |
|
return |
|
} |
|
var segments = path.split('.'); |
|
return function (obj) { |
|
for (var i = 0; i < segments.length; i++) { |
|
if (!obj) { return } |
|
obj = obj[segments[i]]; |
|
} |
|
return obj |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
// can we use __proto__? |
|
var hasProto = '__proto__' in {}; |
|
|
|
// Browser environment sniffing |
|
var inBrowser = typeof window !== 'undefined'; |
|
var inWeex = typeof WXEnvironment !== 'undefined' && !!WXEnvironment.platform; |
|
var weexPlatform = inWeex && WXEnvironment.platform.toLowerCase(); |
|
var UA = inBrowser && window.navigator.userAgent.toLowerCase(); |
|
var isIE = UA && /msie|trident/.test(UA); |
|
var isIE9 = UA && UA.indexOf('msie 9.0') > 0; |
|
var isEdge = UA && UA.indexOf('edge/') > 0; |
|
var isAndroid = (UA && UA.indexOf('android') > 0) || (weexPlatform === 'android'); |
|
var isIOS = (UA && /iphone|ipad|ipod|ios/.test(UA)) || (weexPlatform === 'ios'); |
|
var isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge; |
|
|
|
// Firefox has a "watch" function on Object.prototype... |
|
var nativeWatch = ({}).watch; |
|
|
|
var supportsPassive = false; |
|
if (inBrowser) { |
|
try { |
|
var opts = {}; |
|
Object.defineProperty(opts, 'passive', ({ |
|
get: function get () { |
|
/* istanbul ignore next */ |
|
supportsPassive = true; |
|
} |
|
})); // https://github.com/facebook/flow/issues/285 |
|
window.addEventListener('test-passive', null, opts); |
|
} catch (e) {} |
|
} |
|
|
|
// this needs to be lazy-evaled because vue may be required before |
|
// vue-server-renderer can set VUE_ENV |
|
var _isServer; |
|
var isServerRendering = function () { |
|
if (_isServer === undefined) { |
|
/* istanbul ignore if */ |
|
if (!inBrowser && !inWeex && typeof global !== 'undefined') { |
|
// detect presence of vue-server-renderer and avoid |
|
// Webpack shimming the process |
|
_isServer = global['process'].env.VUE_ENV === 'server'; |
|
} else { |
|
_isServer = false; |
|
} |
|
} |
|
return _isServer |
|
}; |
|
|
|
// detect devtools |
|
var devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__; |
|
|
|
/* istanbul ignore next */ |
|
function isNative (Ctor) { |
|
return typeof Ctor === 'function' && /native code/.test(Ctor.toString()) |
|
} |
|
|
|
var hasSymbol = |
|
typeof Symbol !== 'undefined' && isNative(Symbol) && |
|
typeof Reflect !== 'undefined' && isNative(Reflect.ownKeys); |
|
|
|
var _Set; |
|
/* istanbul ignore if */ // $flow-disable-line |
|
if (typeof Set !== 'undefined' && isNative(Set)) { |
|
// use native Set when available. |
|
_Set = Set; |
|
} else { |
|
// a non-standard Set polyfill that only works with primitive keys. |
|
_Set = (function () { |
|
function Set () { |
|
this.set = Object.create(null); |
|
} |
|
Set.prototype.has = function has (key) { |
|
return this.set[key] === true |
|
}; |
|
Set.prototype.add = function add (key) { |
|
this.set[key] = true; |
|
}; |
|
Set.prototype.clear = function clear () { |
|
this.set = Object.create(null); |
|
}; |
|
|
|
return Set; |
|
}()); |
|
} |
|
|
|
/* */ |
|
|
|
var warn = noop; |
|
var tip = noop; |
|
var generateComponentTrace = (noop); // work around flow check |
|
var formatComponentName = (noop); |
|
|
|
if (true) { |
|
var hasConsole = typeof console !== 'undefined'; |
|
var classifyRE = /(?:^|[-_])(\w)/g; |
|
var classify = function (str) { return str |
|
.replace(classifyRE, function (c) { return c.toUpperCase(); }) |
|
.replace(/[-_]/g, ''); }; |
|
|
|
warn = function (msg, vm) { |
|
var trace = vm ? generateComponentTrace(vm) : ''; |
|
|
|
if (config.warnHandler) { |
|
config.warnHandler.call(null, msg, vm, trace); |
|
} else if (hasConsole && (!config.silent)) { |
|
console.error(("[Vue warn]: " + msg + trace)); |
|
} |
|
}; |
|
|
|
tip = function (msg, vm) { |
|
if (hasConsole && (!config.silent)) { |
|
console.warn("[Vue tip]: " + msg + ( |
|
vm ? generateComponentTrace(vm) : '' |
|
)); |
|
} |
|
}; |
|
|
|
formatComponentName = function (vm, includeFile) { |
|
if (vm.$root === vm) { |
|
return '<Root>' |
|
} |
|
var options = typeof vm === 'function' && vm.cid != null |
|
? vm.options |
|
: vm._isVue |
|
? vm.$options || vm.constructor.options |
|
: vm || {}; |
|
var name = options.name || options._componentTag; |
|
var file = options.__file; |
|
if (!name && file) { |
|
var match = file.match(/([^/\\]+)\.vue$/); |
|
name = match && match[1]; |
|
} |
|
|
|
return ( |
|
(name ? ("<" + (classify(name)) + ">") : "<Anonymous>") + |
|
(file && includeFile !== false ? (" at " + file) : '') |
|
) |
|
}; |
|
|
|
var repeat = function (str, n) { |
|
var res = ''; |
|
while (n) { |
|
if (n % 2 === 1) { res += str; } |
|
if (n > 1) { str += str; } |
|
n >>= 1; |
|
} |
|
return res |
|
}; |
|
|
|
generateComponentTrace = function (vm) { |
|
if (vm._isVue && vm.$parent) { |
|
var tree = []; |
|
var currentRecursiveSequence = 0; |
|
while (vm) { |
|
if (tree.length > 0) { |
|
var last = tree[tree.length - 1]; |
|
if (last.constructor === vm.constructor) { |
|
currentRecursiveSequence++; |
|
vm = vm.$parent; |
|
continue |
|
} else if (currentRecursiveSequence > 0) { |
|
tree[tree.length - 1] = [last, currentRecursiveSequence]; |
|
currentRecursiveSequence = 0; |
|
} |
|
} |
|
tree.push(vm); |
|
vm = vm.$parent; |
|
} |
|
return '\n\nfound in\n\n' + tree |
|
.map(function (vm, i) { return ("" + (i === 0 ? '---> ' : repeat(' ', 5 + i * 2)) + (Array.isArray(vm) |
|
? ((formatComponentName(vm[0])) + "... (" + (vm[1]) + " recursive calls)") |
|
: formatComponentName(vm))); }) |
|
.join('\n') |
|
} else { |
|
return ("\n\n(found in " + (formatComponentName(vm)) + ")") |
|
} |
|
}; |
|
} |
|
|
|
/* */ |
|
|
|
|
|
var uid = 0; |
|
|
|
/** |
|
* A dep is an observable that can have multiple |
|
* directives subscribing to it. |
|
*/ |
|
var Dep = function Dep () { |
|
this.id = uid++; |
|
this.subs = []; |
|
}; |
|
|
|
Dep.prototype.addSub = function addSub (sub) { |
|
this.subs.push(sub); |
|
}; |
|
|
|
Dep.prototype.removeSub = function removeSub (sub) { |
|
remove(this.subs, sub); |
|
}; |
|
|
|
Dep.prototype.depend = function depend () { |
|
if (Dep.target) { |
|
Dep.target.addDep(this); |
|
} |
|
}; |
|
|
|
Dep.prototype.notify = function notify () { |
|
// stabilize the subscriber list first |
|
var subs = this.subs.slice(); |
|
for (var i = 0, l = subs.length; i < l; i++) { |
|
subs[i].update(); |
|
} |
|
}; |
|
|
|
// the current target watcher being evaluated. |
|
// this is globally unique because there could be only one |
|
// watcher being evaluated at any time. |
|
Dep.target = null; |
|
var targetStack = []; |
|
|
|
function pushTarget (_target) { |
|
if (Dep.target) { targetStack.push(Dep.target); } |
|
Dep.target = _target; |
|
} |
|
|
|
function popTarget () { |
|
Dep.target = targetStack.pop(); |
|
} |
|
|
|
/* */ |
|
|
|
var VNode = function VNode ( |
|
tag, |
|
data, |
|
children, |
|
text, |
|
elm, |
|
context, |
|
componentOptions, |
|
asyncFactory |
|
) { |
|
this.tag = tag; |
|
this.data = data; |
|
this.children = children; |
|
this.text = text; |
|
this.elm = elm; |
|
this.ns = undefined; |
|
this.context = context; |
|
this.fnContext = undefined; |
|
this.fnOptions = undefined; |
|
this.fnScopeId = undefined; |
|
this.key = data && data.key; |
|
this.componentOptions = componentOptions; |
|
this.componentInstance = undefined; |
|
this.parent = undefined; |
|
this.raw = false; |
|
this.isStatic = false; |
|
this.isRootInsert = true; |
|
this.isComment = false; |
|
this.isCloned = false; |
|
this.isOnce = false; |
|
this.asyncFactory = asyncFactory; |
|
this.asyncMeta = undefined; |
|
this.isAsyncPlaceholder = false; |
|
}; |
|
|
|
var prototypeAccessors = { child: { configurable: true } }; |
|
|
|
// DEPRECATED: alias for componentInstance for backwards compat. |
|
/* istanbul ignore next */ |
|
prototypeAccessors.child.get = function () { |
|
return this.componentInstance |
|
}; |
|
|
|
Object.defineProperties( VNode.prototype, prototypeAccessors ); |
|
|
|
var createEmptyVNode = function (text) { |
|
if ( text === void 0 ) text = ''; |
|
|
|
var node = new VNode(); |
|
node.text = text; |
|
node.isComment = true; |
|
return node |
|
}; |
|
|
|
function createTextVNode (val) { |
|
return new VNode(undefined, undefined, undefined, String(val)) |
|
} |
|
|
|
// optimized shallow clone |
|
// used for static nodes and slot nodes because they may be reused across |
|
// multiple renders, cloning them avoids errors when DOM manipulations rely |
|
// on their elm reference. |
|
function cloneVNode (vnode) { |
|
var cloned = new VNode( |
|
vnode.tag, |
|
vnode.data, |
|
vnode.children, |
|
vnode.text, |
|
vnode.elm, |
|
vnode.context, |
|
vnode.componentOptions, |
|
vnode.asyncFactory |
|
); |
|
cloned.ns = vnode.ns; |
|
cloned.isStatic = vnode.isStatic; |
|
cloned.key = vnode.key; |
|
cloned.isComment = vnode.isComment; |
|
cloned.fnContext = vnode.fnContext; |
|
cloned.fnOptions = vnode.fnOptions; |
|
cloned.fnScopeId = vnode.fnScopeId; |
|
cloned.isCloned = true; |
|
return cloned |
|
} |
|
|
|
/* |
|
* not type checking this file because flow doesn't play well with |
|
* dynamically accessing methods on Array prototype |
|
*/ |
|
|
|
var arrayProto = Array.prototype; |
|
var arrayMethods = Object.create(arrayProto); |
|
|
|
var methodsToPatch = [ |
|
'push', |
|
'pop', |
|
'shift', |
|
'unshift', |
|
'splice', |
|
'sort', |
|
'reverse' |
|
]; |
|
|
|
/** |
|
* Intercept mutating methods and emit events |
|
*/ |
|
methodsToPatch.forEach(function (method) { |
|
// cache original method |
|
var original = arrayProto[method]; |
|
def(arrayMethods, method, function mutator () { |
|
var args = [], len = arguments.length; |
|
while ( len-- ) args[ len ] = arguments[ len ]; |
|
|
|
var result = original.apply(this, args); |
|
var ob = this.__ob__; |
|
var inserted; |
|
switch (method) { |
|
case 'push': |
|
case 'unshift': |
|
inserted = args; |
|
break |
|
case 'splice': |
|
inserted = args.slice(2); |
|
break |
|
} |
|
if (inserted) { ob.observeArray(inserted); } |
|
// notify change |
|
ob.dep.notify(); |
|
return result |
|
}); |
|
}); |
|
|
|
/* */ |
|
|
|
var arrayKeys = Object.getOwnPropertyNames(arrayMethods); |
|
|
|
/** |
|
* In some cases we may want to disable observation inside a component's |
|
* update computation. |
|
*/ |
|
var shouldObserve = true; |
|
|
|
function toggleObserving (value) { |
|
shouldObserve = value; |
|
} |
|
|
|
/** |
|
* Observer class that is attached to each observed |
|
* object. Once attached, the observer converts the target |
|
* object's property keys into getter/setters that |
|
* collect dependencies and dispatch updates. |
|
*/ |
|
var Observer = function Observer (value) { |
|
this.value = value; |
|
this.dep = new Dep(); |
|
this.vmCount = 0; |
|
def(value, '__ob__', this); |
|
if (Array.isArray(value)) { |
|
var augment = hasProto |
|
? protoAugment |
|
: copyAugment; |
|
augment(value, arrayMethods, arrayKeys); |
|
this.observeArray(value); |
|
} else { |
|
this.walk(value); |
|
} |
|
}; |
|
|
|
/** |
|
* Walk through each property and convert them into |
|
* getter/setters. This method should only be called when |
|
* value type is Object. |
|
*/ |
|
Observer.prototype.walk = function walk (obj) { |
|
var keys = Object.keys(obj); |
|
for (var i = 0; i < keys.length; i++) { |
|
defineReactive(obj, keys[i]); |
|
} |
|
}; |
|
|
|
/** |
|
* Observe a list of Array items. |
|
*/ |
|
Observer.prototype.observeArray = function observeArray (items) { |
|
for (var i = 0, l = items.length; i < l; i++) { |
|
observe(items[i]); |
|
} |
|
}; |
|
|
|
// helpers |
|
|
|
/** |
|
* Augment an target Object or Array by intercepting |
|
* the prototype chain using __proto__ |
|
*/ |
|
function protoAugment (target, src, keys) { |
|
/* eslint-disable no-proto */ |
|
target.__proto__ = src; |
|
/* eslint-enable no-proto */ |
|
} |
|
|
|
/** |
|
* Augment an target Object or Array by defining |
|
* hidden properties. |
|
*/ |
|
/* istanbul ignore next */ |
|
function copyAugment (target, src, keys) { |
|
for (var i = 0, l = keys.length; i < l; i++) { |
|
var key = keys[i]; |
|
def(target, key, src[key]); |
|
} |
|
} |
|
|
|
/** |
|
* Attempt to create an observer instance for a value, |
|
* returns the new observer if successfully observed, |
|
* or the existing observer if the value already has one. |
|
*/ |
|
function observe (value, asRootData) { |
|
if (!isObject(value) || value instanceof VNode) { |
|
return |
|
} |
|
var ob; |
|
if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) { |
|
ob = value.__ob__; |
|
} else if ( |
|
shouldObserve && |
|
!isServerRendering() && |
|
(Array.isArray(value) || isPlainObject(value)) && |
|
Object.isExtensible(value) && |
|
!value._isVue |
|
) { |
|
ob = new Observer(value); |
|
} |
|
if (asRootData && ob) { |
|
ob.vmCount++; |
|
} |
|
return ob |
|
} |
|
|
|
/** |
|
* Define a reactive property on an Object. |
|
*/ |
|
function defineReactive ( |
|
obj, |
|
key, |
|
val, |
|
customSetter, |
|
shallow |
|
) { |
|
var dep = new Dep(); |
|
|
|
var property = Object.getOwnPropertyDescriptor(obj, key); |
|
if (property && property.configurable === false) { |
|
return |
|
} |
|
|
|
// cater for pre-defined getter/setters |
|
var getter = property && property.get; |
|
if (!getter && arguments.length === 2) { |
|
val = obj[key]; |
|
} |
|
var setter = property && property.set; |
|
|
|
var childOb = !shallow && observe(val); |
|
Object.defineProperty(obj, key, { |
|
enumerable: true, |
|
configurable: true, |
|
get: function reactiveGetter () { |
|
var value = getter ? getter.call(obj) : val; |
|
if (Dep.target) { |
|
dep.depend(); |
|
if (childOb) { |
|
childOb.dep.depend(); |
|
if (Array.isArray(value)) { |
|
dependArray(value); |
|
} |
|
} |
|
} |
|
return value |
|
}, |
|
set: function reactiveSetter (newVal) { |
|
var value = getter ? getter.call(obj) : val; |
|
/* eslint-disable no-self-compare */ |
|
if (newVal === value || (newVal !== newVal && value !== value)) { |
|
return |
|
} |
|
/* eslint-enable no-self-compare */ |
|
if ("development" !== 'production' && customSetter) { |
|
customSetter(); |
|
} |
|
if (setter) { |
|
setter.call(obj, newVal); |
|
} else { |
|
val = newVal; |
|
} |
|
childOb = !shallow && observe(newVal); |
|
dep.notify(); |
|
} |
|
}); |
|
} |
|
|
|
/** |
|
* Set a property on an object. Adds the new property and |
|
* triggers change notification if the property doesn't |
|
* already exist. |
|
*/ |
|
function set (target, key, val) { |
|
if ("development" !== 'production' && |
|
(isUndef(target) || isPrimitive(target)) |
|
) { |
|
warn(("Cannot set reactive property on undefined, null, or primitive value: " + ((target)))); |
|
} |
|
if (Array.isArray(target) && isValidArrayIndex(key)) { |
|
target.length = Math.max(target.length, key); |
|
target.splice(key, 1, val); |
|
return val |
|
} |
|
if (key in target && !(key in Object.prototype)) { |
|
target[key] = val; |
|
return val |
|
} |
|
var ob = (target).__ob__; |
|
if (target._isVue || (ob && ob.vmCount)) { |
|
"development" !== 'production' && warn( |
|
'Avoid adding reactive properties to a Vue instance or its root $data ' + |
|
'at runtime - declare it upfront in the data option.' |
|
); |
|
return val |
|
} |
|
if (!ob) { |
|
target[key] = val; |
|
return val |
|
} |
|
defineReactive(ob.value, key, val); |
|
ob.dep.notify(); |
|
return val |
|
} |
|
|
|
/** |
|
* Delete a property and trigger change if necessary. |
|
*/ |
|
function del (target, key) { |
|
if ("development" !== 'production' && |
|
(isUndef(target) || isPrimitive(target)) |
|
) { |
|
warn(("Cannot delete reactive property on undefined, null, or primitive value: " + ((target)))); |
|
} |
|
if (Array.isArray(target) && isValidArrayIndex(key)) { |
|
target.splice(key, 1); |
|
return |
|
} |
|
var ob = (target).__ob__; |
|
if (target._isVue || (ob && ob.vmCount)) { |
|
"development" !== 'production' && warn( |
|
'Avoid deleting properties on a Vue instance or its root $data ' + |
|
'- just set it to null.' |
|
); |
|
return |
|
} |
|
if (!hasOwn(target, key)) { |
|
return |
|
} |
|
delete target[key]; |
|
if (!ob) { |
|
return |
|
} |
|
ob.dep.notify(); |
|
} |
|
|
|
/** |
|
* Collect dependencies on array elements when the array is touched, since |
|
* we cannot intercept array element access like property getters. |
|
*/ |
|
function dependArray (value) { |
|
for (var e = (void 0), i = 0, l = value.length; i < l; i++) { |
|
e = value[i]; |
|
e && e.__ob__ && e.__ob__.dep.depend(); |
|
if (Array.isArray(e)) { |
|
dependArray(e); |
|
} |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
/** |
|
* Option overwriting strategies are functions that handle |
|
* how to merge a parent option value and a child option |
|
* value into the final value. |
|
*/ |
|
var strats = config.optionMergeStrategies; |
|
|
|
/** |
|
* Options with restrictions |
|
*/ |
|
if (true) { |
|
strats.el = strats.propsData = function (parent, child, vm, key) { |
|
if (!vm) { |
|
warn( |
|
"option \"" + key + "\" can only be used during instance " + |
|
'creation with the `new` keyword.' |
|
); |
|
} |
|
return defaultStrat(parent, child) |
|
}; |
|
} |
|
|
|
/** |
|
* Helper that recursively merges two data objects together. |
|
*/ |
|
function mergeData (to, from) { |
|
if (!from) { return to } |
|
var key, toVal, fromVal; |
|
var keys = Object.keys(from); |
|
for (var i = 0; i < keys.length; i++) { |
|
key = keys[i]; |
|
toVal = to[key]; |
|
fromVal = from[key]; |
|
if (!hasOwn(to, key)) { |
|
set(to, key, fromVal); |
|
} else if (isPlainObject(toVal) && isPlainObject(fromVal)) { |
|
mergeData(toVal, fromVal); |
|
} |
|
} |
|
return to |
|
} |
|
|
|
/** |
|
* Data |
|
*/ |
|
function mergeDataOrFn ( |
|
parentVal, |
|
childVal, |
|
vm |
|
) { |
|
if (!vm) { |
|
// in a Vue.extend merge, both should be functions |
|
if (!childVal) { |
|
return parentVal |
|
} |
|
if (!parentVal) { |
|
return childVal |
|
} |
|
// when parentVal & childVal are both present, |
|
// we need to return a function that returns the |
|
// merged result of both functions... no need to |
|
// check if parentVal is a function here because |
|
// it has to be a function to pass previous merges. |
|
return function mergedDataFn () { |
|
return mergeData( |
|
typeof childVal === 'function' ? childVal.call(this, this) : childVal, |
|
typeof parentVal === 'function' ? parentVal.call(this, this) : parentVal |
|
) |
|
} |
|
} else { |
|
return function mergedInstanceDataFn () { |
|
// instance merge |
|
var instanceData = typeof childVal === 'function' |
|
? childVal.call(vm, vm) |
|
: childVal; |
|
var defaultData = typeof parentVal === 'function' |
|
? parentVal.call(vm, vm) |
|
: parentVal; |
|
if (instanceData) { |
|
return mergeData(instanceData, defaultData) |
|
} else { |
|
return defaultData |
|
} |
|
} |
|
} |
|
} |
|
|
|
strats.data = function ( |
|
parentVal, |
|
childVal, |
|
vm |
|
) { |
|
if (!vm) { |
|
if (childVal && typeof childVal !== 'function') { |
|
"development" !== 'production' && warn( |
|
'The "data" option should be a function ' + |
|
'that returns a per-instance value in component ' + |
|
'definitions.', |
|
vm |
|
); |
|
|
|
return parentVal |
|
} |
|
return mergeDataOrFn(parentVal, childVal) |
|
} |
|
|
|
return mergeDataOrFn(parentVal, childVal, vm) |
|
}; |
|
|
|
/** |
|
* Hooks and props are merged as arrays. |
|
*/ |
|
function mergeHook ( |
|
parentVal, |
|
childVal |
|
) { |
|
return childVal |
|
? parentVal |
|
? parentVal.concat(childVal) |
|
: Array.isArray(childVal) |
|
? childVal |
|
: [childVal] |
|
: parentVal |
|
} |
|
|
|
LIFECYCLE_HOOKS.forEach(function (hook) { |
|
strats[hook] = mergeHook; |
|
}); |
|
|
|
/** |
|
* Assets |
|
* |
|
* When a vm is present (instance creation), we need to do |
|
* a three-way merge between constructor options, instance |
|
* options and parent options. |
|
*/ |
|
function mergeAssets ( |
|
parentVal, |
|
childVal, |
|
vm, |
|
key |
|
) { |
|
var res = Object.create(parentVal || null); |
|
if (childVal) { |
|
"development" !== 'production' && assertObjectType(key, childVal, vm); |
|
return extend(res, childVal) |
|
} else { |
|
return res |
|
} |
|
} |
|
|
|
ASSET_TYPES.forEach(function (type) { |
|
strats[type + 's'] = mergeAssets; |
|
}); |
|
|
|
/** |
|
* Watchers. |
|
* |
|
* Watchers hashes should not overwrite one |
|
* another, so we merge them as arrays. |
|
*/ |
|
strats.watch = function ( |
|
parentVal, |
|
childVal, |
|
vm, |
|
key |
|
) { |
|
// work around Firefox's Object.prototype.watch... |
|
if (parentVal === nativeWatch) { parentVal = undefined; } |
|
if (childVal === nativeWatch) { childVal = undefined; } |
|
/* istanbul ignore if */ |
|
if (!childVal) { return Object.create(parentVal || null) } |
|
if (true) { |
|
assertObjectType(key, childVal, vm); |
|
} |
|
if (!parentVal) { return childVal } |
|
var ret = {}; |
|
extend(ret, parentVal); |
|
for (var key$1 in childVal) { |
|
var parent = ret[key$1]; |
|
var child = childVal[key$1]; |
|
if (parent && !Array.isArray(parent)) { |
|
parent = [parent]; |
|
} |
|
ret[key$1] = parent |
|
? parent.concat(child) |
|
: Array.isArray(child) ? child : [child]; |
|
} |
|
return ret |
|
}; |
|
|
|
/** |
|
* Other object hashes. |
|
*/ |
|
strats.props = |
|
strats.methods = |
|
strats.inject = |
|
strats.computed = function ( |
|
parentVal, |
|
childVal, |
|
vm, |
|
key |
|
) { |
|
if (childVal && "development" !== 'production') { |
|
assertObjectType(key, childVal, vm); |
|
} |
|
if (!parentVal) { return childVal } |
|
var ret = Object.create(null); |
|
extend(ret, parentVal); |
|
if (childVal) { extend(ret, childVal); } |
|
return ret |
|
}; |
|
strats.provide = mergeDataOrFn; |
|
|
|
/** |
|
* Default strategy. |
|
*/ |
|
var defaultStrat = function (parentVal, childVal) { |
|
return childVal === undefined |
|
? parentVal |
|
: childVal |
|
}; |
|
|
|
/** |
|
* Validate component names |
|
*/ |
|
function checkComponents (options) { |
|
for (var key in options.components) { |
|
validateComponentName(key); |
|
} |
|
} |
|
|
|
function validateComponentName (name) { |
|
if (!/^[a-zA-Z][\w-]*$/.test(name)) { |
|
warn( |
|
'Invalid component name: "' + name + '". Component names ' + |
|
'can only contain alphanumeric characters and the hyphen, ' + |
|
'and must start with a letter.' |
|
); |
|
} |
|
if (isBuiltInTag(name) || config.isReservedTag(name)) { |
|
warn( |
|
'Do not use built-in or reserved HTML elements as component ' + |
|
'id: ' + name |
|
); |
|
} |
|
} |
|
|
|
/** |
|
* Ensure all props option syntax are normalized into the |
|
* Object-based format. |
|
*/ |
|
function normalizeProps (options, vm) { |
|
var props = options.props; |
|
if (!props) { return } |
|
var res = {}; |
|
var i, val, name; |
|
if (Array.isArray(props)) { |
|
i = props.length; |
|
while (i--) { |
|
val = props[i]; |
|
if (typeof val === 'string') { |
|
name = camelize(val); |
|
res[name] = { type: null }; |
|
} else if (true) { |
|
warn('props must be strings when using array syntax.'); |
|
} |
|
} |
|
} else if (isPlainObject(props)) { |
|
for (var key in props) { |
|
val = props[key]; |
|
name = camelize(key); |
|
res[name] = isPlainObject(val) |
|
? val |
|
: { type: val }; |
|
} |
|
} else if (true) { |
|
warn( |
|
"Invalid value for option \"props\": expected an Array or an Object, " + |
|
"but got " + (toRawType(props)) + ".", |
|
vm |
|
); |
|
} |
|
options.props = res; |
|
} |
|
|
|
/** |
|
* Normalize all injections into Object-based format |
|
*/ |
|
function normalizeInject (options, vm) { |
|
var inject = options.inject; |
|
if (!inject) { return } |
|
var normalized = options.inject = {}; |
|
if (Array.isArray(inject)) { |
|
for (var i = 0; i < inject.length; i++) { |
|
normalized[inject[i]] = { from: inject[i] }; |
|
} |
|
} else if (isPlainObject(inject)) { |
|
for (var key in inject) { |
|
var val = inject[key]; |
|
normalized[key] = isPlainObject(val) |
|
? extend({ from: key }, val) |
|
: { from: val }; |
|
} |
|
} else if (true) { |
|
warn( |
|
"Invalid value for option \"inject\": expected an Array or an Object, " + |
|
"but got " + (toRawType(inject)) + ".", |
|
vm |
|
); |
|
} |
|
} |
|
|
|
/** |
|
* Normalize raw function directives into object format. |
|
*/ |
|
function normalizeDirectives (options) { |
|
var dirs = options.directives; |
|
if (dirs) { |
|
for (var key in dirs) { |
|
var def = dirs[key]; |
|
if (typeof def === 'function') { |
|
dirs[key] = { bind: def, update: def }; |
|
} |
|
} |
|
} |
|
} |
|
|
|
function assertObjectType (name, value, vm) { |
|
if (!isPlainObject(value)) { |
|
warn( |
|
"Invalid value for option \"" + name + "\": expected an Object, " + |
|
"but got " + (toRawType(value)) + ".", |
|
vm |
|
); |
|
} |
|
} |
|
|
|
/** |
|
* Merge two option objects into a new one. |
|
* Core utility used in both instantiation and inheritance. |
|
*/ |
|
function mergeOptions ( |
|
parent, |
|
child, |
|
vm |
|
) { |
|
if (true) { |
|
checkComponents(child); |
|
} |
|
|
|
if (typeof child === 'function') { |
|
child = child.options; |
|
} |
|
|
|
normalizeProps(child, vm); |
|
normalizeInject(child, vm); |
|
normalizeDirectives(child); |
|
var extendsFrom = child.extends; |
|
if (extendsFrom) { |
|
parent = mergeOptions(parent, extendsFrom, vm); |
|
} |
|
if (child.mixins) { |
|
for (var i = 0, l = child.mixins.length; i < l; i++) { |
|
parent = mergeOptions(parent, child.mixins[i], vm); |
|
} |
|
} |
|
var options = {}; |
|
var key; |
|
for (key in parent) { |
|
mergeField(key); |
|
} |
|
for (key in child) { |
|
if (!hasOwn(parent, key)) { |
|
mergeField(key); |
|
} |
|
} |
|
function mergeField (key) { |
|
var strat = strats[key] || defaultStrat; |
|
options[key] = strat(parent[key], child[key], vm, key); |
|
} |
|
return options |
|
} |
|
|
|
/** |
|
* Resolve an asset. |
|
* This function is used because child instances need access |
|
* to assets defined in its ancestor chain. |
|
*/ |
|
function resolveAsset ( |
|
options, |
|
type, |
|
id, |
|
warnMissing |
|
) { |
|
/* istanbul ignore if */ |
|
if (typeof id !== 'string') { |
|
return |
|
} |
|
var assets = options[type]; |
|
// check local registration variations first |
|
if (hasOwn(assets, id)) { return assets[id] } |
|
var camelizedId = camelize(id); |
|
if (hasOwn(assets, camelizedId)) { return assets[camelizedId] } |
|
var PascalCaseId = capitalize(camelizedId); |
|
if (hasOwn(assets, PascalCaseId)) { return assets[PascalCaseId] } |
|
// fallback to prototype chain |
|
var res = assets[id] || assets[camelizedId] || assets[PascalCaseId]; |
|
if ("development" !== 'production' && warnMissing && !res) { |
|
warn( |
|
'Failed to resolve ' + type.slice(0, -1) + ': ' + id, |
|
options |
|
); |
|
} |
|
return res |
|
} |
|
|
|
/* */ |
|
|
|
function validateProp ( |
|
key, |
|
propOptions, |
|
propsData, |
|
vm |
|
) { |
|
var prop = propOptions[key]; |
|
var absent = !hasOwn(propsData, key); |
|
var value = propsData[key]; |
|
// boolean casting |
|
var booleanIndex = getTypeIndex(Boolean, prop.type); |
|
if (booleanIndex > -1) { |
|
if (absent && !hasOwn(prop, 'default')) { |
|
value = false; |
|
} else if (value === '' || value === hyphenate(key)) { |
|
// only cast empty string / same name to boolean if |
|
// boolean has higher priority |
|
var stringIndex = getTypeIndex(String, prop.type); |
|
if (stringIndex < 0 || booleanIndex < stringIndex) { |
|
value = true; |
|
} |
|
} |
|
} |
|
// check default value |
|
if (value === undefined) { |
|
value = getPropDefaultValue(vm, prop, key); |
|
// since the default value is a fresh copy, |
|
// make sure to observe it. |
|
var prevShouldObserve = shouldObserve; |
|
toggleObserving(true); |
|
observe(value); |
|
toggleObserving(prevShouldObserve); |
|
} |
|
if ( |
|
true |
|
) { |
|
assertProp(prop, key, value, vm, absent); |
|
} |
|
return value |
|
} |
|
|
|
/** |
|
* Get the default value of a prop. |
|
*/ |
|
function getPropDefaultValue (vm, prop, key) { |
|
// no default, return undefined |
|
if (!hasOwn(prop, 'default')) { |
|
return undefined |
|
} |
|
var def = prop.default; |
|
// warn against non-factory defaults for Object & Array |
|
if ("development" !== 'production' && isObject(def)) { |
|
warn( |
|
'Invalid default value for prop "' + key + '": ' + |
|
'Props with type Object/Array must use a factory function ' + |
|
'to return the default value.', |
|
vm |
|
); |
|
} |
|
// the raw prop value was also undefined from previous render, |
|
// return previous default value to avoid unnecessary watcher trigger |
|
if (vm && vm.$options.propsData && |
|
vm.$options.propsData[key] === undefined && |
|
vm._props[key] !== undefined |
|
) { |
|
return vm._props[key] |
|
} |
|
// call factory function for non-Function types |
|
// a value is Function if its prototype is function even across different execution context |
|
return typeof def === 'function' && getType(prop.type) !== 'Function' |
|
? def.call(vm) |
|
: def |
|
} |
|
|
|
/** |
|
* Assert whether a prop is valid. |
|
*/ |
|
function assertProp ( |
|
prop, |
|
name, |
|
value, |
|
vm, |
|
absent |
|
) { |
|
if (prop.required && absent) { |
|
warn( |
|
'Missing required prop: "' + name + '"', |
|
vm |
|
); |
|
return |
|
} |
|
if (value == null && !prop.required) { |
|
return |
|
} |
|
var type = prop.type; |
|
var valid = !type || type === true; |
|
var expectedTypes = []; |
|
if (type) { |
|
if (!Array.isArray(type)) { |
|
type = [type]; |
|
} |
|
for (var i = 0; i < type.length && !valid; i++) { |
|
var assertedType = assertType(value, type[i]); |
|
expectedTypes.push(assertedType.expectedType || ''); |
|
valid = assertedType.valid; |
|
} |
|
} |
|
if (!valid) { |
|
warn( |
|
"Invalid prop: type check failed for prop \"" + name + "\"." + |
|
" Expected " + (expectedTypes.map(capitalize).join(', ')) + |
|
", got " + (toRawType(value)) + ".", |
|
vm |
|
); |
|
return |
|
} |
|
var validator = prop.validator; |
|
if (validator) { |
|
if (!validator(value)) { |
|
warn( |
|
'Invalid prop: custom validator check failed for prop "' + name + '".', |
|
vm |
|
); |
|
} |
|
} |
|
} |
|
|
|
var simpleCheckRE = /^(String|Number|Boolean|Function|Symbol)$/; |
|
|
|
function assertType (value, type) { |
|
var valid; |
|
var expectedType = getType(type); |
|
if (simpleCheckRE.test(expectedType)) { |
|
var t = typeof value; |
|
valid = t === expectedType.toLowerCase(); |
|
// for primitive wrapper objects |
|
if (!valid && t === 'object') { |
|
valid = value instanceof type; |
|
} |
|
} else if (expectedType === 'Object') { |
|
valid = isPlainObject(value); |
|
} else if (expectedType === 'Array') { |
|
valid = Array.isArray(value); |
|
} else { |
|
valid = value instanceof type; |
|
} |
|
return { |
|
valid: valid, |
|
expectedType: expectedType |
|
} |
|
} |
|
|
|
/** |
|
* Use function string name to check built-in types, |
|
* because a simple equality check will fail when running |
|
* across different vms / iframes. |
|
*/ |
|
function getType (fn) { |
|
var match = fn && fn.toString().match(/^\s*function (\w+)/); |
|
return match ? match[1] : '' |
|
} |
|
|
|
function isSameType (a, b) { |
|
return getType(a) === getType(b) |
|
} |
|
|
|
function getTypeIndex (type, expectedTypes) { |
|
if (!Array.isArray(expectedTypes)) { |
|
return isSameType(expectedTypes, type) ? 0 : -1 |
|
} |
|
for (var i = 0, len = expectedTypes.length; i < len; i++) { |
|
if (isSameType(expectedTypes[i], type)) { |
|
return i |
|
} |
|
} |
|
return -1 |
|
} |
|
|
|
/* */ |
|
|
|
function handleError (err, vm, info) { |
|
if (vm) { |
|
var cur = vm; |
|
while ((cur = cur.$parent)) { |
|
var hooks = cur.$options.errorCaptured; |
|
if (hooks) { |
|
for (var i = 0; i < hooks.length; i++) { |
|
try { |
|
var capture = hooks[i].call(cur, err, vm, info) === false; |
|
if (capture) { return } |
|
} catch (e) { |
|
globalHandleError(e, cur, 'errorCaptured hook'); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
globalHandleError(err, vm, info); |
|
} |
|
|
|
function globalHandleError (err, vm, info) { |
|
if (config.errorHandler) { |
|
try { |
|
return config.errorHandler.call(null, err, vm, info) |
|
} catch (e) { |
|
logError(e, null, 'config.errorHandler'); |
|
} |
|
} |
|
logError(err, vm, info); |
|
} |
|
|
|
function logError (err, vm, info) { |
|
if (true) { |
|
warn(("Error in " + info + ": \"" + (err.toString()) + "\""), vm); |
|
} |
|
/* istanbul ignore else */ |
|
if ((inBrowser || inWeex) && typeof console !== 'undefined') { |
|
console.error(err); |
|
} else { |
|
throw err |
|
} |
|
} |
|
|
|
/* */ |
|
/* globals MessageChannel */ |
|
|
|
var callbacks = []; |
|
var pending = false; |
|
|
|
function flushCallbacks () { |
|
pending = false; |
|
var copies = callbacks.slice(0); |
|
callbacks.length = 0; |
|
for (var i = 0; i < copies.length; i++) { |
|
copies[i](); |
|
} |
|
} |
|
|
|
// Here we have async deferring wrappers using both microtasks and (macro) tasks. |
|
// In < 2.4 we used microtasks everywhere, but there are some scenarios where |
|
// microtasks have too high a priority and fire in between supposedly |
|
// sequential events (e.g. #4521, #6690) or even between bubbling of the same |
|
// event (#6566). However, using (macro) tasks everywhere also has subtle problems |
|
// when state is changed right before repaint (e.g. #6813, out-in transitions). |
|
// Here we use microtask by default, but expose a way to force (macro) task when |
|
// needed (e.g. in event handlers attached by v-on). |
|
var microTimerFunc; |
|
var macroTimerFunc; |
|
var useMacroTask = false; |
|
|
|
// Determine (macro) task defer implementation. |
|
// Technically setImmediate should be the ideal choice, but it's only available |
|
// in IE. The only polyfill that consistently queues the callback after all DOM |
|
// events triggered in the same loop is by using MessageChannel. |
|
/* istanbul ignore if */ |
|
if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) { |
|
macroTimerFunc = function () { |
|
setImmediate(flushCallbacks); |
|
}; |
|
} else if (typeof MessageChannel !== 'undefined' && ( |
|
isNative(MessageChannel) || |
|
// PhantomJS |
|
MessageChannel.toString() === '[object MessageChannelConstructor]' |
|
)) { |
|
var channel = new MessageChannel(); |
|
var port = channel.port2; |
|
channel.port1.onmessage = flushCallbacks; |
|
macroTimerFunc = function () { |
|
port.postMessage(1); |
|
}; |
|
} else { |
|
/* istanbul ignore next */ |
|
macroTimerFunc = function () { |
|
setTimeout(flushCallbacks, 0); |
|
}; |
|
} |
|
|
|
// Determine microtask defer implementation. |
|
/* istanbul ignore next, $flow-disable-line */ |
|
if (typeof Promise !== 'undefined' && isNative(Promise)) { |
|
var p = Promise.resolve(); |
|
microTimerFunc = function () { |
|
p.then(flushCallbacks); |
|
// in problematic UIWebViews, Promise.then doesn't completely break, but |
|
// it can get stuck in a weird state where callbacks are pushed into the |
|
// microtask queue but the queue isn't being flushed, until the browser |
|
// needs to do some other work, e.g. handle a timer. Therefore we can |
|
// "force" the microtask queue to be flushed by adding an empty timer. |
|
if (isIOS) { setTimeout(noop); } |
|
}; |
|
} else { |
|
// fallback to macro |
|
microTimerFunc = macroTimerFunc; |
|
} |
|
|
|
/** |
|
* Wrap a function so that if any code inside triggers state change, |
|
* the changes are queued using a (macro) task instead of a microtask. |
|
*/ |
|
function withMacroTask (fn) { |
|
return fn._withTask || (fn._withTask = function () { |
|
useMacroTask = true; |
|
var res = fn.apply(null, arguments); |
|
useMacroTask = false; |
|
return res |
|
}) |
|
} |
|
|
|
function nextTick (cb, ctx) { |
|
var _resolve; |
|
callbacks.push(function () { |
|
if (cb) { |
|
try { |
|
cb.call(ctx); |
|
} catch (e) { |
|
handleError(e, ctx, 'nextTick'); |
|
} |
|
} else if (_resolve) { |
|
_resolve(ctx); |
|
} |
|
}); |
|
if (!pending) { |
|
pending = true; |
|
if (useMacroTask) { |
|
macroTimerFunc(); |
|
} else { |
|
microTimerFunc(); |
|
} |
|
} |
|
// $flow-disable-line |
|
if (!cb && typeof Promise !== 'undefined') { |
|
return new Promise(function (resolve) { |
|
_resolve = resolve; |
|
}) |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
var mark; |
|
var measure; |
|
|
|
if (true) { |
|
var perf = inBrowser && window.performance; |
|
/* istanbul ignore if */ |
|
if ( |
|
perf && |
|
perf.mark && |
|
perf.measure && |
|
perf.clearMarks && |
|
perf.clearMeasures |
|
) { |
|
mark = function (tag) { return perf.mark(tag); }; |
|
measure = function (name, startTag, endTag) { |
|
perf.measure(name, startTag, endTag); |
|
perf.clearMarks(startTag); |
|
perf.clearMarks(endTag); |
|
perf.clearMeasures(name); |
|
}; |
|
} |
|
} |
|
|
|
/* not type checking this file because flow doesn't play well with Proxy */ |
|
|
|
var initProxy; |
|
|
|
if (true) { |
|
var allowedGlobals = makeMap( |
|
'Infinity,undefined,NaN,isFinite,isNaN,' + |
|
'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' + |
|
'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' + |
|
'require' // for Webpack/Browserify |
|
); |
|
|
|
var warnNonPresent = function (target, key) { |
|
warn( |
|
"Property or method \"" + key + "\" is not defined on the instance but " + |
|
'referenced during render. Make sure that this property is reactive, ' + |
|
'either in the data option, or for class-based components, by ' + |
|
'initializing the property. ' + |
|
'See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.', |
|
target |
|
); |
|
}; |
|
|
|
var hasProxy = |
|
typeof Proxy !== 'undefined' && isNative(Proxy); |
|
|
|
if (hasProxy) { |
|
var isBuiltInModifier = makeMap('stop,prevent,self,ctrl,shift,alt,meta,exact'); |
|
config.keyCodes = new Proxy(config.keyCodes, { |
|
set: function set (target, key, value) { |
|
if (isBuiltInModifier(key)) { |
|
warn(("Avoid overwriting built-in modifier in config.keyCodes: ." + key)); |
|
return false |
|
} else { |
|
target[key] = value; |
|
return true |
|
} |
|
} |
|
}); |
|
} |
|
|
|
var hasHandler = { |
|
has: function has (target, key) { |
|
var has = key in target; |
|
var isAllowed = allowedGlobals(key) || key.charAt(0) === '_'; |
|
if (!has && !isAllowed) { |
|
warnNonPresent(target, key); |
|
} |
|
return has || !isAllowed |
|
} |
|
}; |
|
|
|
var getHandler = { |
|
get: function get (target, key) { |
|
if (typeof key === 'string' && !(key in target)) { |
|
warnNonPresent(target, key); |
|
} |
|
return target[key] |
|
} |
|
}; |
|
|
|
initProxy = function initProxy (vm) { |
|
if (hasProxy) { |
|
// determine which proxy handler to use |
|
var options = vm.$options; |
|
var handlers = options.render && options.render._withStripped |
|
? getHandler |
|
: hasHandler; |
|
vm._renderProxy = new Proxy(vm, handlers); |
|
} else { |
|
vm._renderProxy = vm; |
|
} |
|
}; |
|
} |
|
|
|
/* */ |
|
|
|
var seenObjects = new _Set(); |
|
|
|
/** |
|
* Recursively traverse an object to evoke all converted |
|
* getters, so that every nested property inside the object |
|
* is collected as a "deep" dependency. |
|
*/ |
|
function traverse (val) { |
|
_traverse(val, seenObjects); |
|
seenObjects.clear(); |
|
} |
|
|
|
function _traverse (val, seen) { |
|
var i, keys; |
|
var isA = Array.isArray(val); |
|
if ((!isA && !isObject(val)) || Object.isFrozen(val) || val instanceof VNode) { |
|
return |
|
} |
|
if (val.__ob__) { |
|
var depId = val.__ob__.dep.id; |
|
if (seen.has(depId)) { |
|
return |
|
} |
|
seen.add(depId); |
|
} |
|
if (isA) { |
|
i = val.length; |
|
while (i--) { _traverse(val[i], seen); } |
|
} else { |
|
keys = Object.keys(val); |
|
i = keys.length; |
|
while (i--) { _traverse(val[keys[i]], seen); } |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
var normalizeEvent = cached(function (name) { |
|
var passive = name.charAt(0) === '&'; |
|
name = passive ? name.slice(1) : name; |
|
var once$$1 = name.charAt(0) === '~'; // Prefixed last, checked first |
|
name = once$$1 ? name.slice(1) : name; |
|
var capture = name.charAt(0) === '!'; |
|
name = capture ? name.slice(1) : name; |
|
return { |
|
name: name, |
|
once: once$$1, |
|
capture: capture, |
|
passive: passive |
|
} |
|
}); |
|
|
|
function createFnInvoker (fns) { |
|
function invoker () { |
|
var arguments$1 = arguments; |
|
|
|
var fns = invoker.fns; |
|
if (Array.isArray(fns)) { |
|
var cloned = fns.slice(); |
|
for (var i = 0; i < cloned.length; i++) { |
|
cloned[i].apply(null, arguments$1); |
|
} |
|
} else { |
|
// return handler return value for single handlers |
|
return fns.apply(null, arguments) |
|
} |
|
} |
|
invoker.fns = fns; |
|
return invoker |
|
} |
|
|
|
function updateListeners ( |
|
on, |
|
oldOn, |
|
add, |
|
remove$$1, |
|
vm |
|
) { |
|
var name, def, cur, old, event; |
|
for (name in on) { |
|
def = cur = on[name]; |
|
old = oldOn[name]; |
|
event = normalizeEvent(name); |
|
/* istanbul ignore if */ |
|
if (isUndef(cur)) { |
|
"development" !== 'production' && warn( |
|
"Invalid handler for event \"" + (event.name) + "\": got " + String(cur), |
|
vm |
|
); |
|
} else if (isUndef(old)) { |
|
if (isUndef(cur.fns)) { |
|
cur = on[name] = createFnInvoker(cur); |
|
} |
|
add(event.name, cur, event.once, event.capture, event.passive, event.params); |
|
} else if (cur !== old) { |
|
old.fns = cur; |
|
on[name] = old; |
|
} |
|
} |
|
for (name in oldOn) { |
|
if (isUndef(on[name])) { |
|
event = normalizeEvent(name); |
|
remove$$1(event.name, oldOn[name], event.capture); |
|
} |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
function mergeVNodeHook (def, hookKey, hook) { |
|
if (def instanceof VNode) { |
|
def = def.data.hook || (def.data.hook = {}); |
|
} |
|
var invoker; |
|
var oldHook = def[hookKey]; |
|
|
|
function wrappedHook () { |
|
hook.apply(this, arguments); |
|
// important: remove merged hook to ensure it's called only once |
|
// and prevent memory leak |
|
remove(invoker.fns, wrappedHook); |
|
} |
|
|
|
if (isUndef(oldHook)) { |
|
// no existing hook |
|
invoker = createFnInvoker([wrappedHook]); |
|
} else { |
|
/* istanbul ignore if */ |
|
if (isDef(oldHook.fns) && isTrue(oldHook.merged)) { |
|
// already a merged invoker |
|
invoker = oldHook; |
|
invoker.fns.push(wrappedHook); |
|
} else { |
|
// existing plain hook |
|
invoker = createFnInvoker([oldHook, wrappedHook]); |
|
} |
|
} |
|
|
|
invoker.merged = true; |
|
def[hookKey] = invoker; |
|
} |
|
|
|
/* */ |
|
|
|
function extractPropsFromVNodeData ( |
|
data, |
|
Ctor, |
|
tag |
|
) { |
|
// we are only extracting raw values here. |
|
// validation and default values are handled in the child |
|
// component itself. |
|
var propOptions = Ctor.options.props; |
|
if (isUndef(propOptions)) { |
|
return |
|
} |
|
var res = {}; |
|
var attrs = data.attrs; |
|
var props = data.props; |
|
if (isDef(attrs) || isDef(props)) { |
|
for (var key in propOptions) { |
|
var altKey = hyphenate(key); |
|
if (true) { |
|
var keyInLowerCase = key.toLowerCase(); |
|
if ( |
|
key !== keyInLowerCase && |
|
attrs && hasOwn(attrs, keyInLowerCase) |
|
) { |
|
tip( |
|
"Prop \"" + keyInLowerCase + "\" is passed to component " + |
|
(formatComponentName(tag || Ctor)) + ", but the declared prop name is" + |
|
" \"" + key + "\". " + |
|
"Note that HTML attributes are case-insensitive and camelCased " + |
|
"props need to use their kebab-case equivalents when using in-DOM " + |
|
"templates. You should probably use \"" + altKey + "\" instead of \"" + key + "\"." |
|
); |
|
} |
|
} |
|
checkProp(res, props, key, altKey, true) || |
|
checkProp(res, attrs, key, altKey, false); |
|
} |
|
} |
|
return res |
|
} |
|
|
|
function checkProp ( |
|
res, |
|
hash, |
|
key, |
|
altKey, |
|
preserve |
|
) { |
|
if (isDef(hash)) { |
|
if (hasOwn(hash, key)) { |
|
res[key] = hash[key]; |
|
if (!preserve) { |
|
delete hash[key]; |
|
} |
|
return true |
|
} else if (hasOwn(hash, altKey)) { |
|
res[key] = hash[altKey]; |
|
if (!preserve) { |
|
delete hash[altKey]; |
|
} |
|
return true |
|
} |
|
} |
|
return false |
|
} |
|
|
|
/* */ |
|
|
|
// The template compiler attempts to minimize the need for normalization by |
|
// statically analyzing the template at compile time. |
|
// |
|
// For plain HTML markup, normalization can be completely skipped because the |
|
// generated render function is guaranteed to return Array<VNode>. There are |
|
// two cases where extra normalization is needed: |
|
|
|
// 1. When the children contains components - because a functional component |
|
// may return an Array instead of a single root. In this case, just a simple |
|
// normalization is needed - if any child is an Array, we flatten the whole |
|
// thing with Array.prototype.concat. It is guaranteed to be only 1-level deep |
|
// because functional components already normalize their own children. |
|
function simpleNormalizeChildren (children) { |
|
for (var i = 0; i < children.length; i++) { |
|
if (Array.isArray(children[i])) { |
|
return Array.prototype.concat.apply([], children) |
|
} |
|
} |
|
return children |
|
} |
|
|
|
// 2. When the children contains constructs that always generated nested Arrays, |
|
// e.g. <template>, <slot>, v-for, or when the children is provided by user |
|
// with hand-written render functions / JSX. In such cases a full normalization |
|
// is needed to cater to all possible types of children values. |
|
function normalizeChildren (children) { |
|
return isPrimitive(children) |
|
? [createTextVNode(children)] |
|
: Array.isArray(children) |
|
? normalizeArrayChildren(children) |
|
: undefined |
|
} |
|
|
|
function isTextNode (node) { |
|
return isDef(node) && isDef(node.text) && isFalse(node.isComment) |
|
} |
|
|
|
function normalizeArrayChildren (children, nestedIndex) { |
|
var res = []; |
|
var i, c, lastIndex, last; |
|
for (i = 0; i < children.length; i++) { |
|
c = children[i]; |
|
if (isUndef(c) || typeof c === 'boolean') { continue } |
|
lastIndex = res.length - 1; |
|
last = res[lastIndex]; |
|
// nested |
|
if (Array.isArray(c)) { |
|
if (c.length > 0) { |
|
c = normalizeArrayChildren(c, ((nestedIndex || '') + "_" + i)); |
|
// merge adjacent text nodes |
|
if (isTextNode(c[0]) && isTextNode(last)) { |
|
res[lastIndex] = createTextVNode(last.text + (c[0]).text); |
|
c.shift(); |
|
} |
|
res.push.apply(res, c); |
|
} |
|
} else if (isPrimitive(c)) { |
|
if (isTextNode(last)) { |
|
// merge adjacent text nodes |
|
// this is necessary for SSR hydration because text nodes are |
|
// essentially merged when rendered to HTML strings |
|
res[lastIndex] = createTextVNode(last.text + c); |
|
} else if (c !== '') { |
|
// convert primitive to vnode |
|
res.push(createTextVNode(c)); |
|
} |
|
} else { |
|
if (isTextNode(c) && isTextNode(last)) { |
|
// merge adjacent text nodes |
|
res[lastIndex] = createTextVNode(last.text + c.text); |
|
} else { |
|
// default key for nested array children (likely generated by v-for) |
|
if (isTrue(children._isVList) && |
|
isDef(c.tag) && |
|
isUndef(c.key) && |
|
isDef(nestedIndex)) { |
|
c.key = "__vlist" + nestedIndex + "_" + i + "__"; |
|
} |
|
res.push(c); |
|
} |
|
} |
|
} |
|
return res |
|
} |
|
|
|
/* */ |
|
|
|
function ensureCtor (comp, base) { |
|
if ( |
|
comp.__esModule || |
|
(hasSymbol && comp[Symbol.toStringTag] === 'Module') |
|
) { |
|
comp = comp.default; |
|
} |
|
return isObject(comp) |
|
? base.extend(comp) |
|
: comp |
|
} |
|
|
|
function createAsyncPlaceholder ( |
|
factory, |
|
data, |
|
context, |
|
children, |
|
tag |
|
) { |
|
var node = createEmptyVNode(); |
|
node.asyncFactory = factory; |
|
node.asyncMeta = { data: data, context: context, children: children, tag: tag }; |
|
return node |
|
} |
|
|
|
function resolveAsyncComponent ( |
|
factory, |
|
baseCtor, |
|
context |
|
) { |
|
if (isTrue(factory.error) && isDef(factory.errorComp)) { |
|
return factory.errorComp |
|
} |
|
|
|
if (isDef(factory.resolved)) { |
|
return factory.resolved |
|
} |
|
|
|
if (isTrue(factory.loading) && isDef(factory.loadingComp)) { |
|
return factory.loadingComp |
|
} |
|
|
|
if (isDef(factory.contexts)) { |
|
// already pending |
|
factory.contexts.push(context); |
|
} else { |
|
var contexts = factory.contexts = [context]; |
|
var sync = true; |
|
|
|
var forceRender = function () { |
|
for (var i = 0, l = contexts.length; i < l; i++) { |
|
contexts[i].$forceUpdate(); |
|
} |
|
}; |
|
|
|
var resolve = once(function (res) { |
|
// cache resolved |
|
factory.resolved = ensureCtor(res, baseCtor); |
|
// invoke callbacks only if this is not a synchronous resolve |
|
// (async resolves are shimmed as synchronous during SSR) |
|
if (!sync) { |
|
forceRender(); |
|
} |
|
}); |
|
|
|
var reject = once(function (reason) { |
|
"development" !== 'production' && warn( |
|
"Failed to resolve async component: " + (String(factory)) + |
|
(reason ? ("\nReason: " + reason) : '') |
|
); |
|
if (isDef(factory.errorComp)) { |
|
factory.error = true; |
|
forceRender(); |
|
} |
|
}); |
|
|
|
var res = factory(resolve, reject); |
|
|
|
if (isObject(res)) { |
|
if (typeof res.then === 'function') { |
|
// () => Promise |
|
if (isUndef(factory.resolved)) { |
|
res.then(resolve, reject); |
|
} |
|
} else if (isDef(res.component) && typeof res.component.then === 'function') { |
|
res.component.then(resolve, reject); |
|
|
|
if (isDef(res.error)) { |
|
factory.errorComp = ensureCtor(res.error, baseCtor); |
|
} |
|
|
|
if (isDef(res.loading)) { |
|
factory.loadingComp = ensureCtor(res.loading, baseCtor); |
|
if (res.delay === 0) { |
|
factory.loading = true; |
|
} else { |
|
setTimeout(function () { |
|
if (isUndef(factory.resolved) && isUndef(factory.error)) { |
|
factory.loading = true; |
|
forceRender(); |
|
} |
|
}, res.delay || 200); |
|
} |
|
} |
|
|
|
if (isDef(res.timeout)) { |
|
setTimeout(function () { |
|
if (isUndef(factory.resolved)) { |
|
reject( |
|
true |
|
? ("timeout (" + (res.timeout) + "ms)") |
|
: null |
|
); |
|
} |
|
}, res.timeout); |
|
} |
|
} |
|
} |
|
|
|
sync = false; |
|
// return in case resolved synchronously |
|
return factory.loading |
|
? factory.loadingComp |
|
: factory.resolved |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
function isAsyncPlaceholder (node) { |
|
return node.isComment && node.asyncFactory |
|
} |
|
|
|
/* */ |
|
|
|
function getFirstComponentChild (children) { |
|
if (Array.isArray(children)) { |
|
for (var i = 0; i < children.length; i++) { |
|
var c = children[i]; |
|
if (isDef(c) && (isDef(c.componentOptions) || isAsyncPlaceholder(c))) { |
|
return c |
|
} |
|
} |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
/* */ |
|
|
|
function initEvents (vm) { |
|
vm._events = Object.create(null); |
|
vm._hasHookEvent = false; |
|
// init parent attached events |
|
var listeners = vm.$options._parentListeners; |
|
if (listeners) { |
|
updateComponentListeners(vm, listeners); |
|
} |
|
} |
|
|
|
var target; |
|
|
|
function add (event, fn, once) { |
|
if (once) { |
|
target.$once(event, fn); |
|
} else { |
|
target.$on(event, fn); |
|
} |
|
} |
|
|
|
function remove$1 (event, fn) { |
|
target.$off(event, fn); |
|
} |
|
|
|
function updateComponentListeners ( |
|
vm, |
|
listeners, |
|
oldListeners |
|
) { |
|
target = vm; |
|
updateListeners(listeners, oldListeners || {}, add, remove$1, vm); |
|
target = undefined; |
|
} |
|
|
|
function eventsMixin (Vue) { |
|
var hookRE = /^hook:/; |
|
Vue.prototype.$on = function (event, fn) { |
|
var this$1 = this; |
|
|
|
var vm = this; |
|
if (Array.isArray(event)) { |
|
for (var i = 0, l = event.length; i < l; i++) { |
|
this$1.$on(event[i], fn); |
|
} |
|
} else { |
|
(vm._events[event] || (vm._events[event] = [])).push(fn); |
|
// optimize hook:event cost by using a boolean flag marked at registration |
|
// instead of a hash lookup |
|
if (hookRE.test(event)) { |
|
vm._hasHookEvent = true; |
|
} |
|
} |
|
return vm |
|
}; |
|
|
|
Vue.prototype.$once = function (event, fn) { |
|
var vm = this; |
|
function on () { |
|
vm.$off(event, on); |
|
fn.apply(vm, arguments); |
|
} |
|
on.fn = fn; |
|
vm.$on(event, on); |
|
return vm |
|
}; |
|
|
|
Vue.prototype.$off = function (event, fn) { |
|
var this$1 = this; |
|
|
|
var vm = this; |
|
// all |
|
if (!arguments.length) { |
|
vm._events = Object.create(null); |
|
return vm |
|
} |
|
// array of events |
|
if (Array.isArray(event)) { |
|
for (var i = 0, l = event.length; i < l; i++) { |
|
this$1.$off(event[i], fn); |
|
} |
|
return vm |
|
} |
|
// specific event |
|
var cbs = vm._events[event]; |
|
if (!cbs) { |
|
return vm |
|
} |
|
if (!fn) { |
|
vm._events[event] = null; |
|
return vm |
|
} |
|
if (fn) { |
|
// specific handler |
|
var cb; |
|
var i$1 = cbs.length; |
|
while (i$1--) { |
|
cb = cbs[i$1]; |
|
if (cb === fn || cb.fn === fn) { |
|
cbs.splice(i$1, 1); |
|
break |
|
} |
|
} |
|
} |
|
return vm |
|
}; |
|
|
|
Vue.prototype.$emit = function (event) { |
|
var vm = this; |
|
if (true) { |
|
var lowerCaseEvent = event.toLowerCase(); |
|
if (lowerCaseEvent !== event && vm._events[lowerCaseEvent]) { |
|
tip( |
|
"Event \"" + lowerCaseEvent + "\" is emitted in component " + |
|
(formatComponentName(vm)) + " but the handler is registered for \"" + event + "\". " + |
|
"Note that HTML attributes are case-insensitive and you cannot use " + |
|
"v-on to listen to camelCase events when using in-DOM templates. " + |
|
"You should probably use \"" + (hyphenate(event)) + "\" instead of \"" + event + "\"." |
|
); |
|
} |
|
} |
|
var cbs = vm._events[event]; |
|
if (cbs) { |
|
cbs = cbs.length > 1 ? toArray(cbs) : cbs; |
|
var args = toArray(arguments, 1); |
|
for (var i = 0, l = cbs.length; i < l; i++) { |
|
try { |
|
cbs[i].apply(vm, args); |
|
} catch (e) { |
|
handleError(e, vm, ("event handler for \"" + event + "\"")); |
|
} |
|
} |
|
} |
|
return vm |
|
}; |
|
} |
|
|
|
/* */ |
|
|
|
|
|
|
|
/** |
|
* Runtime helper for resolving raw children VNodes into a slot object. |
|
*/ |
|
function resolveSlots ( |
|
children, |
|
context |
|
) { |
|
var slots = {}; |
|
if (!children) { |
|
return slots |
|
} |
|
for (var i = 0, l = children.length; i < l; i++) { |
|
var child = children[i]; |
|
var data = child.data; |
|
// remove slot attribute if the node is resolved as a Vue slot node |
|
if (data && data.attrs && data.attrs.slot) { |
|
delete data.attrs.slot; |
|
} |
|
// named slots should only be respected if the vnode was rendered in the |
|
// same context. |
|
if ((child.context === context || child.fnContext === context) && |
|
data && data.slot != null |
|
) { |
|
var name = data.slot; |
|
var slot = (slots[name] || (slots[name] = [])); |
|
if (child.tag === 'template') { |
|
slot.push.apply(slot, child.children || []); |
|
} else { |
|
slot.push(child); |
|
} |
|
} else { |
|
(slots.default || (slots.default = [])).push(child); |
|
} |
|
} |
|
// ignore slots that contains only whitespace |
|
for (var name$1 in slots) { |
|
if (slots[name$1].every(isWhitespace)) { |
|
delete slots[name$1]; |
|
} |
|
} |
|
return slots |
|
} |
|
|
|
function isWhitespace (node) { |
|
return (node.isComment && !node.asyncFactory) || node.text === ' ' |
|
} |
|
|
|
function resolveScopedSlots ( |
|
fns, // see flow/vnode |
|
res |
|
) { |
|
res = res || {}; |
|
for (var i = 0; i < fns.length; i++) { |
|
if (Array.isArray(fns[i])) { |
|
resolveScopedSlots(fns[i], res); |
|
} else { |
|
res[fns[i].key] = fns[i].fn; |
|
} |
|
} |
|
return res |
|
} |
|
|
|
/* */ |
|
|
|
var activeInstance = null; |
|
var isUpdatingChildComponent = false; |
|
|
|
function initLifecycle (vm) { |
|
var options = vm.$options; |
|
|
|
// locate first non-abstract parent |
|
var parent = options.parent; |
|
if (parent && !options.abstract) { |
|
while (parent.$options.abstract && parent.$parent) { |
|
parent = parent.$parent; |
|
} |
|
parent.$children.push(vm); |
|
} |
|
|
|
vm.$parent = parent; |
|
vm.$root = parent ? parent.$root : vm; |
|
|
|
vm.$children = []; |
|
vm.$refs = {}; |
|
|
|
vm._watcher = null; |
|
vm._inactive = null; |
|
vm._directInactive = false; |
|
vm._isMounted = false; |
|
vm._isDestroyed = false; |
|
vm._isBeingDestroyed = false; |
|
} |
|
|
|
function lifecycleMixin (Vue) { |
|
Vue.prototype._update = function (vnode, hydrating) { |
|
var vm = this; |
|
if (vm._isMounted) { |
|
callHook(vm, 'beforeUpdate'); |
|
} |
|
var prevEl = vm.$el; |
|
var prevVnode = vm._vnode; |
|
var prevActiveInstance = activeInstance; |
|
activeInstance = vm; |
|
vm._vnode = vnode; |
|
// Vue.prototype.__patch__ is injected in entry points |
|
// based on the rendering backend used. |
|
if (!prevVnode) { |
|
// initial render |
|
vm.$el = vm.__patch__( |
|
vm.$el, vnode, hydrating, false /* removeOnly */, |
|
vm.$options._parentElm, |
|
vm.$options._refElm |
|
); |
|
// no need for the ref nodes after initial patch |
|
// this prevents keeping a detached DOM tree in memory (#5851) |
|
vm.$options._parentElm = vm.$options._refElm = null; |
|
} else { |
|
// updates |
|
vm.$el = vm.__patch__(prevVnode, vnode); |
|
} |
|
activeInstance = prevActiveInstance; |
|
// update __vue__ reference |
|
if (prevEl) { |
|
prevEl.__vue__ = null; |
|
} |
|
if (vm.$el) { |
|
vm.$el.__vue__ = vm; |
|
} |
|
// if parent is an HOC, update its $el as well |
|
if (vm.$vnode && vm.$parent && vm.$vnode === vm.$parent._vnode) { |
|
vm.$parent.$el = vm.$el; |
|
} |
|
// updated hook is called by the scheduler to ensure that children are |
|
// updated in a parent's updated hook. |
|
}; |
|
|
|
Vue.prototype.$forceUpdate = function () { |
|
var vm = this; |
|
if (vm._watcher) { |
|
vm._watcher.update(); |
|
} |
|
}; |
|
|
|
Vue.prototype.$destroy = function () { |
|
var vm = this; |
|
if (vm._isBeingDestroyed) { |
|
return |
|
} |
|
callHook(vm, 'beforeDestroy'); |
|
vm._isBeingDestroyed = true; |
|
// remove self from parent |
|
var parent = vm.$parent; |
|
if (parent && !parent._isBeingDestroyed && !vm.$options.abstract) { |
|
remove(parent.$children, vm); |
|
} |
|
// teardown watchers |
|
if (vm._watcher) { |
|
vm._watcher.teardown(); |
|
} |
|
var i = vm._watchers.length; |
|
while (i--) { |
|
vm._watchers[i].teardown(); |
|
} |
|
// remove reference from data ob |
|
// frozen object may not have observer. |
|
if (vm._data.__ob__) { |
|
vm._data.__ob__.vmCount--; |
|
} |
|
// call the last hook... |
|
vm._isDestroyed = true; |
|
// invoke destroy hooks on current rendered tree |
|
vm.__patch__(vm._vnode, null); |
|
// fire destroyed hook |
|
callHook(vm, 'destroyed'); |
|
// turn off all instance listeners. |
|
vm.$off(); |
|
// remove __vue__ reference |
|
if (vm.$el) { |
|
vm.$el.__vue__ = null; |
|
} |
|
// release circular reference (#6759) |
|
if (vm.$vnode) { |
|
vm.$vnode.parent = null; |
|
} |
|
}; |
|
} |
|
|
|
function mountComponent ( |
|
vm, |
|
el, |
|
hydrating |
|
) { |
|
vm.$el = el; |
|
if (!vm.$options.render) { |
|
vm.$options.render = createEmptyVNode; |
|
if (true) { |
|
/* istanbul ignore if */ |
|
if ((vm.$options.template && vm.$options.template.charAt(0) !== '#') || |
|
vm.$options.el || el) { |
|
warn( |
|
'You are using the runtime-only build of Vue where the template ' + |
|
'compiler is not available. Either pre-compile the templates into ' + |
|
'render functions, or use the compiler-included build.', |
|
vm |
|
); |
|
} else { |
|
warn( |
|
'Failed to mount component: template or render function not defined.', |
|
vm |
|
); |
|
} |
|
} |
|
} |
|
callHook(vm, 'beforeMount'); |
|
|
|
var updateComponent; |
|
/* istanbul ignore if */ |
|
if ("development" !== 'production' && config.performance && mark) { |
|
updateComponent = function () { |
|
var name = vm._name; |
|
var id = vm._uid; |
|
var startTag = "vue-perf-start:" + id; |
|
var endTag = "vue-perf-end:" + id; |
|
|
|
mark(startTag); |
|
var vnode = vm._render(); |
|
mark(endTag); |
|
measure(("vue " + name + " render"), startTag, endTag); |
|
|
|
mark(startTag); |
|
vm._update(vnode, hydrating); |
|
mark(endTag); |
|
measure(("vue " + name + " patch"), startTag, endTag); |
|
}; |
|
} else { |
|
updateComponent = function () { |
|
vm._update(vm._render(), hydrating); |
|
}; |
|
} |
|
|
|
// we set this to vm._watcher inside the watcher's constructor |
|
// since the watcher's initial patch may call $forceUpdate (e.g. inside child |
|
// component's mounted hook), which relies on vm._watcher being already defined |
|
new Watcher(vm, updateComponent, noop, null, true /* isRenderWatcher */); |
|
hydrating = false; |
|
|
|
// manually mounted instance, call mounted on self |
|
// mounted is called for render-created child components in its inserted hook |
|
if (vm.$vnode == null) { |
|
vm._isMounted = true; |
|
callHook(vm, 'mounted'); |
|
} |
|
return vm |
|
} |
|
|
|
function updateChildComponent ( |
|
vm, |
|
propsData, |
|
listeners, |
|
parentVnode, |
|
renderChildren |
|
) { |
|
if (true) { |
|
isUpdatingChildComponent = true; |
|
} |
|
|
|
// determine whether component has slot children |
|
// we need to do this before overwriting $options._renderChildren |
|
var hasChildren = !!( |
|
renderChildren || // has new static slots |
|
vm.$options._renderChildren || // has old static slots |
|
parentVnode.data.scopedSlots || // has new scoped slots |
|
vm.$scopedSlots !== emptyObject // has old scoped slots |
|
); |
|
|
|
vm.$options._parentVnode = parentVnode; |
|
vm.$vnode = parentVnode; // update vm's placeholder node without re-render |
|
|
|
if (vm._vnode) { // update child tree's parent |
|
vm._vnode.parent = parentVnode; |
|
} |
|
vm.$options._renderChildren = renderChildren; |
|
|
|
// update $attrs and $listeners hash |
|
// these are also reactive so they may trigger child update if the child |
|
// used them during render |
|
vm.$attrs = parentVnode.data.attrs || emptyObject; |
|
vm.$listeners = listeners || emptyObject; |
|
|
|
// update props |
|
if (propsData && vm.$options.props) { |
|
toggleObserving(false); |
|
var props = vm._props; |
|
var propKeys = vm.$options._propKeys || []; |
|
for (var i = 0; i < propKeys.length; i++) { |
|
var key = propKeys[i]; |
|
var propOptions = vm.$options.props; // wtf flow? |
|
props[key] = validateProp(key, propOptions, propsData, vm); |
|
} |
|
toggleObserving(true); |
|
// keep a copy of raw propsData |
|
vm.$options.propsData = propsData; |
|
} |
|
|
|
// update listeners |
|
listeners = listeners || emptyObject; |
|
var oldListeners = vm.$options._parentListeners; |
|
vm.$options._parentListeners = listeners; |
|
updateComponentListeners(vm, listeners, oldListeners); |
|
|
|
// resolve slots + force update if has children |
|
if (hasChildren) { |
|
vm.$slots = resolveSlots(renderChildren, parentVnode.context); |
|
vm.$forceUpdate(); |
|
} |
|
|
|
if (true) { |
|
isUpdatingChildComponent = false; |
|
} |
|
} |
|
|
|
function isInInactiveTree (vm) { |
|
while (vm && (vm = vm.$parent)) { |
|
if (vm._inactive) { return true } |
|
} |
|
return false |
|
} |
|
|
|
function activateChildComponent (vm, direct) { |
|
if (direct) { |
|
vm._directInactive = false; |
|
if (isInInactiveTree(vm)) { |
|
return |
|
} |
|
} else if (vm._directInactive) { |
|
return |
|
} |
|
if (vm._inactive || vm._inactive === null) { |
|
vm._inactive = false; |
|
for (var i = 0; i < vm.$children.length; i++) { |
|
activateChildComponent(vm.$children[i]); |
|
} |
|
callHook(vm, 'activated'); |
|
} |
|
} |
|
|
|
function deactivateChildComponent (vm, direct) { |
|
if (direct) { |
|
vm._directInactive = true; |
|
if (isInInactiveTree(vm)) { |
|
return |
|
} |
|
} |
|
if (!vm._inactive) { |
|
vm._inactive = true; |
|
for (var i = 0; i < vm.$children.length; i++) { |
|
deactivateChildComponent(vm.$children[i]); |
|
} |
|
callHook(vm, 'deactivated'); |
|
} |
|
} |
|
|
|
function callHook (vm, hook) { |
|
// #7573 disable dep collection when invoking lifecycle hooks |
|
pushTarget(); |
|
var handlers = vm.$options[hook]; |
|
if (handlers) { |
|
for (var i = 0, j = handlers.length; i < j; i++) { |
|
try { |
|
handlers[i].call(vm); |
|
} catch (e) { |
|
handleError(e, vm, (hook + " hook")); |
|
} |
|
} |
|
} |
|
if (vm._hasHookEvent) { |
|
vm.$emit('hook:' + hook); |
|
} |
|
popTarget(); |
|
} |
|
|
|
/* */ |
|
|
|
|
|
var MAX_UPDATE_COUNT = 100; |
|
|
|
var queue = []; |
|
var activatedChildren = []; |
|
var has = {}; |
|
var circular = {}; |
|
var waiting = false; |
|
var flushing = false; |
|
var index = 0; |
|
|
|
/** |
|
* Reset the scheduler's state. |
|
*/ |
|
function resetSchedulerState () { |
|
index = queue.length = activatedChildren.length = 0; |
|
has = {}; |
|
if (true) { |
|
circular = {}; |
|
} |
|
waiting = flushing = false; |
|
} |
|
|
|
/** |
|
* Flush both queues and run the watchers. |
|
*/ |
|
function flushSchedulerQueue () { |
|
flushing = true; |
|
var watcher, id; |
|
|
|
// Sort queue before flush. |
|
// This ensures that: |
|
// 1. Components are updated from parent to child. (because parent is always |
|
// created before the child) |
|
// 2. A component's user watchers are run before its render watcher (because |
|
// user watchers are created before the render watcher) |
|
// 3. If a component is destroyed during a parent component's watcher run, |
|
// its watchers can be skipped. |
|
queue.sort(function (a, b) { return a.id - b.id; }); |
|
|
|
// do not cache length because more watchers might be pushed |
|
// as we run existing watchers |
|
for (index = 0; index < queue.length; index++) { |
|
watcher = queue[index]; |
|
id = watcher.id; |
|
has[id] = null; |
|
watcher.run(); |
|
// in dev build, check and stop circular updates. |
|
if ("development" !== 'production' && has[id] != null) { |
|
circular[id] = (circular[id] || 0) + 1; |
|
if (circular[id] > MAX_UPDATE_COUNT) { |
|
warn( |
|
'You may have an infinite update loop ' + ( |
|
watcher.user |
|
? ("in watcher with expression \"" + (watcher.expression) + "\"") |
|
: "in a component render function." |
|
), |
|
watcher.vm |
|
); |
|
break |
|
} |
|
} |
|
} |
|
|
|
// keep copies of post queues before resetting state |
|
var activatedQueue = activatedChildren.slice(); |
|
var updatedQueue = queue.slice(); |
|
|
|
resetSchedulerState(); |
|
|
|
// call component updated and activated hooks |
|
callActivatedHooks(activatedQueue); |
|
callUpdatedHooks(updatedQueue); |
|
|
|
// devtool hook |
|
/* istanbul ignore if */ |
|
if (devtools && config.devtools) { |
|
devtools.emit('flush'); |
|
} |
|
} |
|
|
|
function callUpdatedHooks (queue) { |
|
var i = queue.length; |
|
while (i--) { |
|
var watcher = queue[i]; |
|
var vm = watcher.vm; |
|
if (vm._watcher === watcher && vm._isMounted) { |
|
callHook(vm, 'updated'); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* Queue a kept-alive component that was activated during patch. |
|
* The queue will be processed after the entire tree has been patched. |
|
*/ |
|
function queueActivatedComponent (vm) { |
|
// setting _inactive to false here so that a render function can |
|
// rely on checking whether it's in an inactive tree (e.g. router-view) |
|
vm._inactive = false; |
|
activatedChildren.push(vm); |
|
} |
|
|
|
function callActivatedHooks (queue) { |
|
for (var i = 0; i < queue.length; i++) { |
|
queue[i]._inactive = true; |
|
activateChildComponent(queue[i], true /* true */); |
|
} |
|
} |
|
|
|
/** |
|
* Push a watcher into the watcher queue. |
|
* Jobs with duplicate IDs will be skipped unless it's |
|
* pushed when the queue is being flushed. |
|
*/ |
|
function queueWatcher (watcher) { |
|
var id = watcher.id; |
|
if (has[id] == null) { |
|
has[id] = true; |
|
if (!flushing) { |
|
queue.push(watcher); |
|
} else { |
|
// if already flushing, splice the watcher based on its id |
|
// if already past its id, it will be run next immediately. |
|
var i = queue.length - 1; |
|
while (i > index && queue[i].id > watcher.id) { |
|
i--; |
|
} |
|
queue.splice(i + 1, 0, watcher); |
|
} |
|
// queue the flush |
|
if (!waiting) { |
|
waiting = true; |
|
nextTick(flushSchedulerQueue); |
|
} |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
var uid$1 = 0; |
|
|
|
/** |
|
* A watcher parses an expression, collects dependencies, |
|
* and fires callback when the expression value changes. |
|
* This is used for both the $watch() api and directives. |
|
*/ |
|
var Watcher = function Watcher ( |
|
vm, |
|
expOrFn, |
|
cb, |
|
options, |
|
isRenderWatcher |
|
) { |
|
this.vm = vm; |
|
if (isRenderWatcher) { |
|
vm._watcher = this; |
|
} |
|
vm._watchers.push(this); |
|
// options |
|
if (options) { |
|
this.deep = !!options.deep; |
|
this.user = !!options.user; |
|
this.lazy = !!options.lazy; |
|
this.sync = !!options.sync; |
|
} else { |
|
this.deep = this.user = this.lazy = this.sync = false; |
|
} |
|
this.cb = cb; |
|
this.id = ++uid$1; // uid for batching |
|
this.active = true; |
|
this.dirty = this.lazy; // for lazy watchers |
|
this.deps = []; |
|
this.newDeps = []; |
|
this.depIds = new _Set(); |
|
this.newDepIds = new _Set(); |
|
this.expression = true |
|
? expOrFn.toString() |
|
: ''; |
|
// parse expression for getter |
|
if (typeof expOrFn === 'function') { |
|
this.getter = expOrFn; |
|
} else { |
|
this.getter = parsePath(expOrFn); |
|
if (!this.getter) { |
|
this.getter = function () {}; |
|
"development" !== 'production' && warn( |
|
"Failed watching path: \"" + expOrFn + "\" " + |
|
'Watcher only accepts simple dot-delimited paths. ' + |
|
'For full control, use a function instead.', |
|
vm |
|
); |
|
} |
|
} |
|
this.value = this.lazy |
|
? undefined |
|
: this.get(); |
|
}; |
|
|
|
/** |
|
* Evaluate the getter, and re-collect dependencies. |
|
*/ |
|
Watcher.prototype.get = function get () { |
|
pushTarget(this); |
|
var value; |
|
var vm = this.vm; |
|
try { |
|
value = this.getter.call(vm, vm); |
|
} catch (e) { |
|
if (this.user) { |
|
handleError(e, vm, ("getter for watcher \"" + (this.expression) + "\"")); |
|
} else { |
|
throw e |
|
} |
|
} finally { |
|
// "touch" every property so they are all tracked as |
|
// dependencies for deep watching |
|
if (this.deep) { |
|
traverse(value); |
|
} |
|
popTarget(); |
|
this.cleanupDeps(); |
|
} |
|
return value |
|
}; |
|
|
|
/** |
|
* Add a dependency to this directive. |
|
*/ |
|
Watcher.prototype.addDep = function addDep (dep) { |
|
var id = dep.id; |
|
if (!this.newDepIds.has(id)) { |
|
this.newDepIds.add(id); |
|
this.newDeps.push(dep); |
|
if (!this.depIds.has(id)) { |
|
dep.addSub(this); |
|
} |
|
} |
|
}; |
|
|
|
/** |
|
* Clean up for dependency collection. |
|
*/ |
|
Watcher.prototype.cleanupDeps = function cleanupDeps () { |
|
var this$1 = this; |
|
|
|
var i = this.deps.length; |
|
while (i--) { |
|
var dep = this$1.deps[i]; |
|
if (!this$1.newDepIds.has(dep.id)) { |
|
dep.removeSub(this$1); |
|
} |
|
} |
|
var tmp = this.depIds; |
|
this.depIds = this.newDepIds; |
|
this.newDepIds = tmp; |
|
this.newDepIds.clear(); |
|
tmp = this.deps; |
|
this.deps = this.newDeps; |
|
this.newDeps = tmp; |
|
this.newDeps.length = 0; |
|
}; |
|
|
|
/** |
|
* Subscriber interface. |
|
* Will be called when a dependency changes. |
|
*/ |
|
Watcher.prototype.update = function update () { |
|
/* istanbul ignore else */ |
|
if (this.lazy) { |
|
this.dirty = true; |
|
} else if (this.sync) { |
|
this.run(); |
|
} else { |
|
queueWatcher(this); |
|
} |
|
}; |
|
|
|
/** |
|
* Scheduler job interface. |
|
* Will be called by the scheduler. |
|
*/ |
|
Watcher.prototype.run = function run () { |
|
if (this.active) { |
|
var value = this.get(); |
|
if ( |
|
value !== this.value || |
|
// Deep watchers and watchers on Object/Arrays should fire even |
|
// when the value is the same, because the value may |
|
// have mutated. |
|
isObject(value) || |
|
this.deep |
|
) { |
|
// set new value |
|
var oldValue = this.value; |
|
this.value = value; |
|
if (this.user) { |
|
try { |
|
this.cb.call(this.vm, value, oldValue); |
|
} catch (e) { |
|
handleError(e, this.vm, ("callback for watcher \"" + (this.expression) + "\"")); |
|
} |
|
} else { |
|
this.cb.call(this.vm, value, oldValue); |
|
} |
|
} |
|
} |
|
}; |
|
|
|
/** |
|
* Evaluate the value of the watcher. |
|
* This only gets called for lazy watchers. |
|
*/ |
|
Watcher.prototype.evaluate = function evaluate () { |
|
this.value = this.get(); |
|
this.dirty = false; |
|
}; |
|
|
|
/** |
|
* Depend on all deps collected by this watcher. |
|
*/ |
|
Watcher.prototype.depend = function depend () { |
|
var this$1 = this; |
|
|
|
var i = this.deps.length; |
|
while (i--) { |
|
this$1.deps[i].depend(); |
|
} |
|
}; |
|
|
|
/** |
|
* Remove self from all dependencies' subscriber list. |
|
*/ |
|
Watcher.prototype.teardown = function teardown () { |
|
var this$1 = this; |
|
|
|
if (this.active) { |
|
// remove self from vm's watcher list |
|
// this is a somewhat expensive operation so we skip it |
|
// if the vm is being destroyed. |
|
if (!this.vm._isBeingDestroyed) { |
|
remove(this.vm._watchers, this); |
|
} |
|
var i = this.deps.length; |
|
while (i--) { |
|
this$1.deps[i].removeSub(this$1); |
|
} |
|
this.active = false; |
|
} |
|
}; |
|
|
|
/* */ |
|
|
|
var sharedPropertyDefinition = { |
|
enumerable: true, |
|
configurable: true, |
|
get: noop, |
|
set: noop |
|
}; |
|
|
|
function proxy (target, sourceKey, key) { |
|
sharedPropertyDefinition.get = function proxyGetter () { |
|
return this[sourceKey][key] |
|
}; |
|
sharedPropertyDefinition.set = function proxySetter (val) { |
|
this[sourceKey][key] = val; |
|
}; |
|
Object.defineProperty(target, key, sharedPropertyDefinition); |
|
} |
|
|
|
function initState (vm) { |
|
vm._watchers = []; |
|
var opts = vm.$options; |
|
if (opts.props) { initProps(vm, opts.props); } |
|
if (opts.methods) { initMethods(vm, opts.methods); } |
|
if (opts.data) { |
|
initData(vm); |
|
} else { |
|
observe(vm._data = {}, true /* asRootData */); |
|
} |
|
if (opts.computed) { initComputed(vm, opts.computed); } |
|
if (opts.watch && opts.watch !== nativeWatch) { |
|
initWatch(vm, opts.watch); |
|
} |
|
} |
|
|
|
function initProps (vm, propsOptions) { |
|
var propsData = vm.$options.propsData || {}; |
|
var props = vm._props = {}; |
|
// cache prop keys so that future props updates can iterate using Array |
|
// instead of dynamic object key enumeration. |
|
var keys = vm.$options._propKeys = []; |
|
var isRoot = !vm.$parent; |
|
// root instance props should be converted |
|
if (!isRoot) { |
|
toggleObserving(false); |
|
} |
|
var loop = function ( key ) { |
|
keys.push(key); |
|
var value = validateProp(key, propsOptions, propsData, vm); |
|
/* istanbul ignore else */ |
|
if (true) { |
|
var hyphenatedKey = hyphenate(key); |
|
if (isReservedAttribute(hyphenatedKey) || |
|
config.isReservedAttr(hyphenatedKey)) { |
|
warn( |
|
("\"" + hyphenatedKey + "\" is a reserved attribute and cannot be used as component prop."), |
|
vm |
|
); |
|
} |
|
defineReactive(props, key, value, function () { |
|
if (vm.$parent && !isUpdatingChildComponent) { |
|
warn( |
|
"Avoid mutating a prop directly since the value will be " + |
|
"overwritten whenever the parent component re-renders. " + |
|
"Instead, use a data or computed property based on the prop's " + |
|
"value. Prop being mutated: \"" + key + "\"", |
|
vm |
|
); |
|
} |
|
}); |
|
} else { |
|
defineReactive(props, key, value); |
|
} |
|
// static props are already proxied on the component's prototype |
|
// during Vue.extend(). We only need to proxy props defined at |
|
// instantiation here. |
|
if (!(key in vm)) { |
|
proxy(vm, "_props", key); |
|
} |
|
}; |
|
|
|
for (var key in propsOptions) loop( key ); |
|
toggleObserving(true); |
|
} |
|
|
|
function initData (vm) { |
|
var data = vm.$options.data; |
|
data = vm._data = typeof data === 'function' |
|
? getData(data, vm) |
|
: data || {}; |
|
if (!isPlainObject(data)) { |
|
data = {}; |
|
"development" !== 'production' && warn( |
|
'data functions should return an object:\n' + |
|
'https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function', |
|
vm |
|
); |
|
} |
|
// proxy data on instance |
|
var keys = Object.keys(data); |
|
var props = vm.$options.props; |
|
var methods = vm.$options.methods; |
|
var i = keys.length; |
|
while (i--) { |
|
var key = keys[i]; |
|
if (true) { |
|
if (methods && hasOwn(methods, key)) { |
|
warn( |
|
("Method \"" + key + "\" has already been defined as a data property."), |
|
vm |
|
); |
|
} |
|
} |
|
if (props && hasOwn(props, key)) { |
|
"development" !== 'production' && warn( |
|
"The data property \"" + key + "\" is already declared as a prop. " + |
|
"Use prop default value instead.", |
|
vm |
|
); |
|
} else if (!isReserved(key)) { |
|
proxy(vm, "_data", key); |
|
} |
|
} |
|
// observe data |
|
observe(data, true /* asRootData */); |
|
} |
|
|
|
function getData (data, vm) { |
|
// #7573 disable dep collection when invoking data getters |
|
pushTarget(); |
|
try { |
|
return data.call(vm, vm) |
|
} catch (e) { |
|
handleError(e, vm, "data()"); |
|
return {} |
|
} finally { |
|
popTarget(); |
|
} |
|
} |
|
|
|
var computedWatcherOptions = { lazy: true }; |
|
|
|
function initComputed (vm, computed) { |
|
// $flow-disable-line |
|
var watchers = vm._computedWatchers = Object.create(null); |
|
// computed properties are just getters during SSR |
|
var isSSR = isServerRendering(); |
|
|
|
for (var key in computed) { |
|
var userDef = computed[key]; |
|
var getter = typeof userDef === 'function' ? userDef : userDef.get; |
|
if ("development" !== 'production' && getter == null) { |
|
warn( |
|
("Getter is missing for computed property \"" + key + "\"."), |
|
vm |
|
); |
|
} |
|
|
|
if (!isSSR) { |
|
// create internal watcher for the computed property. |
|
watchers[key] = new Watcher( |
|
vm, |
|
getter || noop, |
|
noop, |
|
computedWatcherOptions |
|
); |
|
} |
|
|
|
// component-defined computed properties are already defined on the |
|
// component prototype. We only need to define computed properties defined |
|
// at instantiation here. |
|
if (!(key in vm)) { |
|
defineComputed(vm, key, userDef); |
|
} else if (true) { |
|
if (key in vm.$data) { |
|
warn(("The computed property \"" + key + "\" is already defined in data."), vm); |
|
} else if (vm.$options.props && key in vm.$options.props) { |
|
warn(("The computed property \"" + key + "\" is already defined as a prop."), vm); |
|
} |
|
} |
|
} |
|
} |
|
|
|
function defineComputed ( |
|
target, |
|
key, |
|
userDef |
|
) { |
|
var shouldCache = !isServerRendering(); |
|
if (typeof userDef === 'function') { |
|
sharedPropertyDefinition.get = shouldCache |
|
? createComputedGetter(key) |
|
: userDef; |
|
sharedPropertyDefinition.set = noop; |
|
} else { |
|
sharedPropertyDefinition.get = userDef.get |
|
? shouldCache && userDef.cache !== false |
|
? createComputedGetter(key) |
|
: userDef.get |
|
: noop; |
|
sharedPropertyDefinition.set = userDef.set |
|
? userDef.set |
|
: noop; |
|
} |
|
if ("development" !== 'production' && |
|
sharedPropertyDefinition.set === noop) { |
|
sharedPropertyDefinition.set = function () { |
|
warn( |
|
("Computed property \"" + key + "\" was assigned to but it has no setter."), |
|
this |
|
); |
|
}; |
|
} |
|
Object.defineProperty(target, key, sharedPropertyDefinition); |
|
} |
|
|
|
function createComputedGetter (key) { |
|
return function computedGetter () { |
|
var watcher = this._computedWatchers && this._computedWatchers[key]; |
|
if (watcher) { |
|
if (watcher.dirty) { |
|
watcher.evaluate(); |
|
} |
|
if (Dep.target) { |
|
watcher.depend(); |
|
} |
|
return watcher.value |
|
} |
|
} |
|
} |
|
|
|
function initMethods (vm, methods) { |
|
var props = vm.$options.props; |
|
for (var key in methods) { |
|
if (true) { |
|
if (methods[key] == null) { |
|
warn( |
|
"Method \"" + key + "\" has an undefined value in the component definition. " + |
|
"Did you reference the function correctly?", |
|
vm |
|
); |
|
} |
|
if (props && hasOwn(props, key)) { |
|
warn( |
|
("Method \"" + key + "\" has already been defined as a prop."), |
|
vm |
|
); |
|
} |
|
if ((key in vm) && isReserved(key)) { |
|
warn( |
|
"Method \"" + key + "\" conflicts with an existing Vue instance method. " + |
|
"Avoid defining component methods that start with _ or $." |
|
); |
|
} |
|
} |
|
vm[key] = methods[key] == null ? noop : bind(methods[key], vm); |
|
} |
|
} |
|
|
|
function initWatch (vm, watch) { |
|
for (var key in watch) { |
|
var handler = watch[key]; |
|
if (Array.isArray(handler)) { |
|
for (var i = 0; i < handler.length; i++) { |
|
createWatcher(vm, key, handler[i]); |
|
} |
|
} else { |
|
createWatcher(vm, key, handler); |
|
} |
|
} |
|
} |
|
|
|
function createWatcher ( |
|
vm, |
|
expOrFn, |
|
handler, |
|
options |
|
) { |
|
if (isPlainObject(handler)) { |
|
options = handler; |
|
handler = handler.handler; |
|
} |
|
if (typeof handler === 'string') { |
|
handler = vm[handler]; |
|
} |
|
return vm.$watch(expOrFn, handler, options) |
|
} |
|
|
|
function stateMixin (Vue) { |
|
// flow somehow has problems with directly declared definition object |
|
// when using Object.defineProperty, so we have to procedurally build up |
|
// the object here. |
|
var dataDef = {}; |
|
dataDef.get = function () { return this._data }; |
|
var propsDef = {}; |
|
propsDef.get = function () { return this._props }; |
|
if (true) { |
|
dataDef.set = function (newData) { |
|
warn( |
|
'Avoid replacing instance root $data. ' + |
|
'Use nested data properties instead.', |
|
this |
|
); |
|
}; |
|
propsDef.set = function () { |
|
warn("$props is readonly.", this); |
|
}; |
|
} |
|
Object.defineProperty(Vue.prototype, '$data', dataDef); |
|
Object.defineProperty(Vue.prototype, '$props', propsDef); |
|
|
|
Vue.prototype.$set = set; |
|
Vue.prototype.$delete = del; |
|
|
|
Vue.prototype.$watch = function ( |
|
expOrFn, |
|
cb, |
|
options |
|
) { |
|
var vm = this; |
|
if (isPlainObject(cb)) { |
|
return createWatcher(vm, expOrFn, cb, options) |
|
} |
|
options = options || {}; |
|
options.user = true; |
|
var watcher = new Watcher(vm, expOrFn, cb, options); |
|
if (options.immediate) { |
|
cb.call(vm, watcher.value); |
|
} |
|
return function unwatchFn () { |
|
watcher.teardown(); |
|
} |
|
}; |
|
} |
|
|
|
/* */ |
|
|
|
function initProvide (vm) { |
|
var provide = vm.$options.provide; |
|
if (provide) { |
|
vm._provided = typeof provide === 'function' |
|
? provide.call(vm) |
|
: provide; |
|
} |
|
} |
|
|
|
function initInjections (vm) { |
|
var result = resolveInject(vm.$options.inject, vm); |
|
if (result) { |
|
toggleObserving(false); |
|
Object.keys(result).forEach(function (key) { |
|
/* istanbul ignore else */ |
|
if (true) { |
|
defineReactive(vm, key, result[key], function () { |
|
warn( |
|
"Avoid mutating an injected value directly since the changes will be " + |
|
"overwritten whenever the provided component re-renders. " + |
|
"injection being mutated: \"" + key + "\"", |
|
vm |
|
); |
|
}); |
|
} else { |
|
defineReactive(vm, key, result[key]); |
|
} |
|
}); |
|
toggleObserving(true); |
|
} |
|
} |
|
|
|
function resolveInject (inject, vm) { |
|
if (inject) { |
|
// inject is :any because flow is not smart enough to figure out cached |
|
var result = Object.create(null); |
|
var keys = hasSymbol |
|
? Reflect.ownKeys(inject).filter(function (key) { |
|
/* istanbul ignore next */ |
|
return Object.getOwnPropertyDescriptor(inject, key).enumerable |
|
}) |
|
: Object.keys(inject); |
|
|
|
for (var i = 0; i < keys.length; i++) { |
|
var key = keys[i]; |
|
var provideKey = inject[key].from; |
|
var source = vm; |
|
while (source) { |
|
if (source._provided && hasOwn(source._provided, provideKey)) { |
|
result[key] = source._provided[provideKey]; |
|
break |
|
} |
|
source = source.$parent; |
|
} |
|
if (!source) { |
|
if ('default' in inject[key]) { |
|
var provideDefault = inject[key].default; |
|
result[key] = typeof provideDefault === 'function' |
|
? provideDefault.call(vm) |
|
: provideDefault; |
|
} else if (true) { |
|
warn(("Injection \"" + key + "\" not found"), vm); |
|
} |
|
} |
|
} |
|
return result |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
/** |
|
* Runtime helper for rendering v-for lists. |
|
*/ |
|
function renderList ( |
|
val, |
|
render |
|
) { |
|
var ret, i, l, keys, key; |
|
if (Array.isArray(val) || typeof val === 'string') { |
|
ret = new Array(val.length); |
|
for (i = 0, l = val.length; i < l; i++) { |
|
ret[i] = render(val[i], i); |
|
} |
|
} else if (typeof val === 'number') { |
|
ret = new Array(val); |
|
for (i = 0; i < val; i++) { |
|
ret[i] = render(i + 1, i); |
|
} |
|
} else if (isObject(val)) { |
|
keys = Object.keys(val); |
|
ret = new Array(keys.length); |
|
for (i = 0, l = keys.length; i < l; i++) { |
|
key = keys[i]; |
|
ret[i] = render(val[key], key, i); |
|
} |
|
} |
|
if (isDef(ret)) { |
|
(ret)._isVList = true; |
|
} |
|
return ret |
|
} |
|
|
|
/* */ |
|
|
|
/** |
|
* Runtime helper for rendering <slot> |
|
*/ |
|
function renderSlot ( |
|
name, |
|
fallback, |
|
props, |
|
bindObject |
|
) { |
|
var scopedSlotFn = this.$scopedSlots[name]; |
|
var nodes; |
|
if (scopedSlotFn) { // scoped slot |
|
props = props || {}; |
|
if (bindObject) { |
|
if ("development" !== 'production' && !isObject(bindObject)) { |
|
warn( |
|
'slot v-bind without argument expects an Object', |
|
this |
|
); |
|
} |
|
props = extend(extend({}, bindObject), props); |
|
} |
|
nodes = scopedSlotFn(props) || fallback; |
|
} else { |
|
var slotNodes = this.$slots[name]; |
|
// warn duplicate slot usage |
|
if (slotNodes) { |
|
if ("development" !== 'production' && slotNodes._rendered) { |
|
warn( |
|
"Duplicate presence of slot \"" + name + "\" found in the same render tree " + |
|
"- this will likely cause render errors.", |
|
this |
|
); |
|
} |
|
slotNodes._rendered = true; |
|
} |
|
nodes = slotNodes || fallback; |
|
} |
|
|
|
var target = props && props.slot; |
|
if (target) { |
|
return this.$createElement('template', { slot: target }, nodes) |
|
} else { |
|
return nodes |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
/** |
|
* Runtime helper for resolving filters |
|
*/ |
|
function resolveFilter (id) { |
|
return resolveAsset(this.$options, 'filters', id, true) || identity |
|
} |
|
|
|
/* */ |
|
|
|
function isKeyNotMatch (expect, actual) { |
|
if (Array.isArray(expect)) { |
|
return expect.indexOf(actual) === -1 |
|
} else { |
|
return expect !== actual |
|
} |
|
} |
|
|
|
/** |
|
* Runtime helper for checking keyCodes from config. |
|
* exposed as Vue.prototype._k |
|
* passing in eventKeyName as last argument separately for backwards compat |
|
*/ |
|
function checkKeyCodes ( |
|
eventKeyCode, |
|
key, |
|
builtInKeyCode, |
|
eventKeyName, |
|
builtInKeyName |
|
) { |
|
var mappedKeyCode = config.keyCodes[key] || builtInKeyCode; |
|
if (builtInKeyName && eventKeyName && !config.keyCodes[key]) { |
|
return isKeyNotMatch(builtInKeyName, eventKeyName) |
|
} else if (mappedKeyCode) { |
|
return isKeyNotMatch(mappedKeyCode, eventKeyCode) |
|
} else if (eventKeyName) { |
|
return hyphenate(eventKeyName) !== key |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
/** |
|
* Runtime helper for merging v-bind="object" into a VNode's data. |
|
*/ |
|
function bindObjectProps ( |
|
data, |
|
tag, |
|
value, |
|
asProp, |
|
isSync |
|
) { |
|
if (value) { |
|
if (!isObject(value)) { |
|
"development" !== 'production' && warn( |
|
'v-bind without argument expects an Object or Array value', |
|
this |
|
); |
|
} else { |
|
if (Array.isArray(value)) { |
|
value = toObject(value); |
|
} |
|
var hash; |
|
var loop = function ( key ) { |
|
if ( |
|
key === 'class' || |
|
key === 'style' || |
|
isReservedAttribute(key) |
|
) { |
|
hash = data; |
|
} else { |
|
var type = data.attrs && data.attrs.type; |
|
hash = asProp || config.mustUseProp(tag, type, key) |
|
? data.domProps || (data.domProps = {}) |
|
: data.attrs || (data.attrs = {}); |
|
} |
|
if (!(key in hash)) { |
|
hash[key] = value[key]; |
|
|
|
if (isSync) { |
|
var on = data.on || (data.on = {}); |
|
on[("update:" + key)] = function ($event) { |
|
value[key] = $event; |
|
}; |
|
} |
|
} |
|
}; |
|
|
|
for (var key in value) loop( key ); |
|
} |
|
} |
|
return data |
|
} |
|
|
|
/* */ |
|
|
|
/** |
|
* Runtime helper for rendering static trees. |
|
*/ |
|
function renderStatic ( |
|
index, |
|
isInFor |
|
) { |
|
var cached = this._staticTrees || (this._staticTrees = []); |
|
var tree = cached[index]; |
|
// if has already-rendered static tree and not inside v-for, |
|
// we can reuse the same tree. |
|
if (tree && !isInFor) { |
|
return tree |
|
} |
|
// otherwise, render a fresh tree. |
|
tree = cached[index] = this.$options.staticRenderFns[index].call( |
|
this._renderProxy, |
|
null, |
|
this // for render fns generated for functional component templates |
|
); |
|
markStatic(tree, ("__static__" + index), false); |
|
return tree |
|
} |
|
|
|
/** |
|
* Runtime helper for v-once. |
|
* Effectively it means marking the node as static with a unique key. |
|
*/ |
|
function markOnce ( |
|
tree, |
|
index, |
|
key |
|
) { |
|
markStatic(tree, ("__once__" + index + (key ? ("_" + key) : "")), true); |
|
return tree |
|
} |
|
|
|
function markStatic ( |
|
tree, |
|
key, |
|
isOnce |
|
) { |
|
if (Array.isArray(tree)) { |
|
for (var i = 0; i < tree.length; i++) { |
|
if (tree[i] && typeof tree[i] !== 'string') { |
|
markStaticNode(tree[i], (key + "_" + i), isOnce); |
|
} |
|
} |
|
} else { |
|
markStaticNode(tree, key, isOnce); |
|
} |
|
} |
|
|
|
function markStaticNode (node, key, isOnce) { |
|
node.isStatic = true; |
|
node.key = key; |
|
node.isOnce = isOnce; |
|
} |
|
|
|
/* */ |
|
|
|
function bindObjectListeners (data, value) { |
|
if (value) { |
|
if (!isPlainObject(value)) { |
|
"development" !== 'production' && warn( |
|
'v-on without argument expects an Object value', |
|
this |
|
); |
|
} else { |
|
var on = data.on = data.on ? extend({}, data.on) : {}; |
|
for (var key in value) { |
|
var existing = on[key]; |
|
var ours = value[key]; |
|
on[key] = existing ? [].concat(existing, ours) : ours; |
|
} |
|
} |
|
} |
|
return data |
|
} |
|
|
|
/* */ |
|
|
|
function installRenderHelpers (target) { |
|
target._o = markOnce; |
|
target._n = toNumber; |
|
target._s = toString; |
|
target._l = renderList; |
|
target._t = renderSlot; |
|
target._q = looseEqual; |
|
target._i = looseIndexOf; |
|
target._m = renderStatic; |
|
target._f = resolveFilter; |
|
target._k = checkKeyCodes; |
|
target._b = bindObjectProps; |
|
target._v = createTextVNode; |
|
target._e = createEmptyVNode; |
|
target._u = resolveScopedSlots; |
|
target._g = bindObjectListeners; |
|
} |
|
|
|
/* */ |
|
|
|
function FunctionalRenderContext ( |
|
data, |
|
props, |
|
children, |
|
parent, |
|
Ctor |
|
) { |
|
var options = Ctor.options; |
|
// ensure the createElement function in functional components |
|
// gets a unique context - this is necessary for correct named slot check |
|
var contextVm; |
|
if (hasOwn(parent, '_uid')) { |
|
contextVm = Object.create(parent); |
|
// $flow-disable-line |
|
contextVm._original = parent; |
|
} else { |
|
// the context vm passed in is a functional context as well. |
|
// in this case we want to make sure we are able to get a hold to the |
|
// real context instance. |
|
contextVm = parent; |
|
// $flow-disable-line |
|
parent = parent._original; |
|
} |
|
var isCompiled = isTrue(options._compiled); |
|
var needNormalization = !isCompiled; |
|
|
|
this.data = data; |
|
this.props = props; |
|
this.children = children; |
|
this.parent = parent; |
|
this.listeners = data.on || emptyObject; |
|
this.injections = resolveInject(options.inject, parent); |
|
this.slots = function () { return resolveSlots(children, parent); }; |
|
|
|
// support for compiled functional template |
|
if (isCompiled) { |
|
// exposing $options for renderStatic() |
|
this.$options = options; |
|
// pre-resolve slots for renderSlot() |
|
this.$slots = this.slots(); |
|
this.$scopedSlots = data.scopedSlots || emptyObject; |
|
} |
|
|
|
if (options._scopeId) { |
|
this._c = function (a, b, c, d) { |
|
var vnode = createElement(contextVm, a, b, c, d, needNormalization); |
|
if (vnode && !Array.isArray(vnode)) { |
|
vnode.fnScopeId = options._scopeId; |
|
vnode.fnContext = parent; |
|
} |
|
return vnode |
|
}; |
|
} else { |
|
this._c = function (a, b, c, d) { return createElement(contextVm, a, b, c, d, needNormalization); }; |
|
} |
|
} |
|
|
|
installRenderHelpers(FunctionalRenderContext.prototype); |
|
|
|
function createFunctionalComponent ( |
|
Ctor, |
|
propsData, |
|
data, |
|
contextVm, |
|
children |
|
) { |
|
var options = Ctor.options; |
|
var props = {}; |
|
var propOptions = options.props; |
|
if (isDef(propOptions)) { |
|
for (var key in propOptions) { |
|
props[key] = validateProp(key, propOptions, propsData || emptyObject); |
|
} |
|
} else { |
|
if (isDef(data.attrs)) { mergeProps(props, data.attrs); } |
|
if (isDef(data.props)) { mergeProps(props, data.props); } |
|
} |
|
|
|
var renderContext = new FunctionalRenderContext( |
|
data, |
|
props, |
|
children, |
|
contextVm, |
|
Ctor |
|
); |
|
|
|
var vnode = options.render.call(null, renderContext._c, renderContext); |
|
|
|
if (vnode instanceof VNode) { |
|
return cloneAndMarkFunctionalResult(vnode, data, renderContext.parent, options) |
|
} else if (Array.isArray(vnode)) { |
|
var vnodes = normalizeChildren(vnode) || []; |
|
var res = new Array(vnodes.length); |
|
for (var i = 0; i < vnodes.length; i++) { |
|
res[i] = cloneAndMarkFunctionalResult(vnodes[i], data, renderContext.parent, options); |
|
} |
|
return res |
|
} |
|
} |
|
|
|
function cloneAndMarkFunctionalResult (vnode, data, contextVm, options) { |
|
// #7817 clone node before setting fnContext, otherwise if the node is reused |
|
// (e.g. it was from a cached normal slot) the fnContext causes named slots |
|
// that should not be matched to match. |
|
var clone = cloneVNode(vnode); |
|
clone.fnContext = contextVm; |
|
clone.fnOptions = options; |
|
if (data.slot) { |
|
(clone.data || (clone.data = {})).slot = data.slot; |
|
} |
|
return clone |
|
} |
|
|
|
function mergeProps (to, from) { |
|
for (var key in from) { |
|
to[camelize(key)] = from[key]; |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
|
|
|
|
|
|
// Register the component hook to weex native render engine. |
|
// The hook will be triggered by native, not javascript. |
|
|
|
|
|
// Updates the state of the component to weex native render engine. |
|
|
|
/* */ |
|
|
|
// https://github.com/Hanks10100/weex-native-directive/tree/master/component |
|
|
|
// listening on native callback |
|
|
|
/* */ |
|
|
|
/* */ |
|
|
|
// inline hooks to be invoked on component VNodes during patch |
|
var componentVNodeHooks = { |
|
init: function init ( |
|
vnode, |
|
hydrating, |
|
parentElm, |
|
refElm |
|
) { |
|
if ( |
|
vnode.componentInstance && |
|
!vnode.componentInstance._isDestroyed && |
|
vnode.data.keepAlive |
|
) { |
|
// kept-alive components, treat as a patch |
|
var mountedNode = vnode; // work around flow |
|
componentVNodeHooks.prepatch(mountedNode, mountedNode); |
|
} else { |
|
var child = vnode.componentInstance = createComponentInstanceForVnode( |
|
vnode, |
|
activeInstance, |
|
parentElm, |
|
refElm |
|
); |
|
child.$mount(hydrating ? vnode.elm : undefined, hydrating); |
|
} |
|
}, |
|
|
|
prepatch: function prepatch (oldVnode, vnode) { |
|
var options = vnode.componentOptions; |
|
var child = vnode.componentInstance = oldVnode.componentInstance; |
|
updateChildComponent( |
|
child, |
|
options.propsData, // updated props |
|
options.listeners, // updated listeners |
|
vnode, // new parent vnode |
|
options.children // new children |
|
); |
|
}, |
|
|
|
insert: function insert (vnode) { |
|
var context = vnode.context; |
|
var componentInstance = vnode.componentInstance; |
|
if (!componentInstance._isMounted) { |
|
componentInstance._isMounted = true; |
|
callHook(componentInstance, 'mounted'); |
|
} |
|
if (vnode.data.keepAlive) { |
|
if (context._isMounted) { |
|
// vue-router#1212 |
|
// During updates, a kept-alive component's child components may |
|
// change, so directly walking the tree here may call activated hooks |
|
// on incorrect children. Instead we push them into a queue which will |
|
// be processed after the whole patch process ended. |
|
queueActivatedComponent(componentInstance); |
|
} else { |
|
activateChildComponent(componentInstance, true /* direct */); |
|
} |
|
} |
|
}, |
|
|
|
destroy: function destroy (vnode) { |
|
var componentInstance = vnode.componentInstance; |
|
if (!componentInstance._isDestroyed) { |
|
if (!vnode.data.keepAlive) { |
|
componentInstance.$destroy(); |
|
} else { |
|
deactivateChildComponent(componentInstance, true /* direct */); |
|
} |
|
} |
|
} |
|
}; |
|
|
|
var hooksToMerge = Object.keys(componentVNodeHooks); |
|
|
|
function createComponent ( |
|
Ctor, |
|
data, |
|
context, |
|
children, |
|
tag |
|
) { |
|
if (isUndef(Ctor)) { |
|
return |
|
} |
|
|
|
var baseCtor = context.$options._base; |
|
|
|
// plain options object: turn it into a constructor |
|
if (isObject(Ctor)) { |
|
Ctor = baseCtor.extend(Ctor); |
|
} |
|
|
|
// if at this stage it's not a constructor or an async component factory, |
|
// reject. |
|
if (typeof Ctor !== 'function') { |
|
if (true) { |
|
warn(("Invalid Component definition: " + (String(Ctor))), context); |
|
} |
|
return |
|
} |
|
|
|
// async component |
|
var asyncFactory; |
|
if (isUndef(Ctor.cid)) { |
|
asyncFactory = Ctor; |
|
Ctor = resolveAsyncComponent(asyncFactory, baseCtor, context); |
|
if (Ctor === undefined) { |
|
// return a placeholder node for async component, which is rendered |
|
// as a comment node but preserves all the raw information for the node. |
|
// the information will be used for async server-rendering and hydration. |
|
return createAsyncPlaceholder( |
|
asyncFactory, |
|
data, |
|
context, |
|
children, |
|
tag |
|
) |
|
} |
|
} |
|
|
|
data = data || {}; |
|
|
|
// resolve constructor options in case global mixins are applied after |
|
// component constructor creation |
|
resolveConstructorOptions(Ctor); |
|
|
|
// transform component v-model data into props & events |
|
if (isDef(data.model)) { |
|
transformModel(Ctor.options, data); |
|
} |
|
|
|
// extract props |
|
var propsData = extractPropsFromVNodeData(data, Ctor, tag); |
|
|
|
// functional component |
|
if (isTrue(Ctor.options.functional)) { |
|
return createFunctionalComponent(Ctor, propsData, data, context, children) |
|
} |
|
|
|
// extract listeners, since these needs to be treated as |
|
// child component listeners instead of DOM listeners |
|
var listeners = data.on; |
|
// replace with listeners with .native modifier |
|
// so it gets processed during parent component patch. |
|
data.on = data.nativeOn; |
|
|
|
if (isTrue(Ctor.options.abstract)) { |
|
// abstract components do not keep anything |
|
// other than props & listeners & slot |
|
|
|
// work around flow |
|
var slot = data.slot; |
|
data = {}; |
|
if (slot) { |
|
data.slot = slot; |
|
} |
|
} |
|
|
|
// install component management hooks onto the placeholder node |
|
installComponentHooks(data); |
|
|
|
// return a placeholder vnode |
|
var name = Ctor.options.name || tag; |
|
var vnode = new VNode( |
|
("vue-component-" + (Ctor.cid) + (name ? ("-" + name) : '')), |
|
data, undefined, undefined, undefined, context, |
|
{ Ctor: Ctor, propsData: propsData, listeners: listeners, tag: tag, children: children }, |
|
asyncFactory |
|
); |
|
|
|
// Weex specific: invoke recycle-list optimized @render function for |
|
// extracting cell-slot template. |
|
// https://github.com/Hanks10100/weex-native-directive/tree/master/component |
|
/* istanbul ignore if */ |
|
return vnode |
|
} |
|
|
|
function createComponentInstanceForVnode ( |
|
vnode, // we know it's MountedComponentVNode but flow doesn't |
|
parent, // activeInstance in lifecycle state |
|
parentElm, |
|
refElm |
|
) { |
|
var options = { |
|
_isComponent: true, |
|
parent: parent, |
|
_parentVnode: vnode, |
|
_parentElm: parentElm || null, |
|
_refElm: refElm || null |
|
}; |
|
// check inline-template render functions |
|
var inlineTemplate = vnode.data.inlineTemplate; |
|
if (isDef(inlineTemplate)) { |
|
options.render = inlineTemplate.render; |
|
options.staticRenderFns = inlineTemplate.staticRenderFns; |
|
} |
|
return new vnode.componentOptions.Ctor(options) |
|
} |
|
|
|
function installComponentHooks (data) { |
|
var hooks = data.hook || (data.hook = {}); |
|
for (var i = 0; i < hooksToMerge.length; i++) { |
|
var key = hooksToMerge[i]; |
|
hooks[key] = componentVNodeHooks[key]; |
|
} |
|
} |
|
|
|
// transform component v-model info (value and callback) into |
|
// prop and event handler respectively. |
|
function transformModel (options, data) { |
|
var prop = (options.model && options.model.prop) || 'value'; |
|
var event = (options.model && options.model.event) || 'input';(data.props || (data.props = {}))[prop] = data.model.value; |
|
var on = data.on || (data.on = {}); |
|
if (isDef(on[event])) { |
|
on[event] = [data.model.callback].concat(on[event]); |
|
} else { |
|
on[event] = data.model.callback; |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
var SIMPLE_NORMALIZE = 1; |
|
var ALWAYS_NORMALIZE = 2; |
|
|
|
// wrapper function for providing a more flexible interface |
|
// without getting yelled at by flow |
|
function createElement ( |
|
context, |
|
tag, |
|
data, |
|
children, |
|
normalizationType, |
|
alwaysNormalize |
|
) { |
|
if (Array.isArray(data) || isPrimitive(data)) { |
|
normalizationType = children; |
|
children = data; |
|
data = undefined; |
|
} |
|
if (isTrue(alwaysNormalize)) { |
|
normalizationType = ALWAYS_NORMALIZE; |
|
} |
|
return _createElement(context, tag, data, children, normalizationType) |
|
} |
|
|
|
function _createElement ( |
|
context, |
|
tag, |
|
data, |
|
children, |
|
normalizationType |
|
) { |
|
if (isDef(data) && isDef((data).__ob__)) { |
|
"development" !== 'production' && warn( |
|
"Avoid using observed data object as vnode data: " + (JSON.stringify(data)) + "\n" + |
|
'Always create fresh vnode data objects in each render!', |
|
context |
|
); |
|
return createEmptyVNode() |
|
} |
|
// object syntax in v-bind |
|
if (isDef(data) && isDef(data.is)) { |
|
tag = data.is; |
|
} |
|
if (!tag) { |
|
// in case of component :is set to falsy value |
|
return createEmptyVNode() |
|
} |
|
// warn against non-primitive key |
|
if ("development" !== 'production' && |
|
isDef(data) && isDef(data.key) && !isPrimitive(data.key) |
|
) { |
|
{ |
|
warn( |
|
'Avoid using non-primitive value as key, ' + |
|
'use string/number value instead.', |
|
context |
|
); |
|
} |
|
} |
|
// support single function children as default scoped slot |
|
if (Array.isArray(children) && |
|
typeof children[0] === 'function' |
|
) { |
|
data = data || {}; |
|
data.scopedSlots = { default: children[0] }; |
|
children.length = 0; |
|
} |
|
if (normalizationType === ALWAYS_NORMALIZE) { |
|
children = normalizeChildren(children); |
|
} else if (normalizationType === SIMPLE_NORMALIZE) { |
|
children = simpleNormalizeChildren(children); |
|
} |
|
var vnode, ns; |
|
if (typeof tag === 'string') { |
|
var Ctor; |
|
ns = (context.$vnode && context.$vnode.ns) || config.getTagNamespace(tag); |
|
if (config.isReservedTag(tag)) { |
|
// platform built-in elements |
|
vnode = new VNode( |
|
config.parsePlatformTagName(tag), data, children, |
|
undefined, undefined, context |
|
); |
|
} else if (isDef(Ctor = resolveAsset(context.$options, 'components', tag))) { |
|
// component |
|
vnode = createComponent(Ctor, data, context, children, tag); |
|
} else { |
|
// unknown or unlisted namespaced elements |
|
// check at runtime because it may get assigned a namespace when its |
|
// parent normalizes children |
|
vnode = new VNode( |
|
tag, data, children, |
|
undefined, undefined, context |
|
); |
|
} |
|
} else { |
|
// direct component options / constructor |
|
vnode = createComponent(tag, data, context, children); |
|
} |
|
if (Array.isArray(vnode)) { |
|
return vnode |
|
} else if (isDef(vnode)) { |
|
if (isDef(ns)) { applyNS(vnode, ns); } |
|
if (isDef(data)) { registerDeepBindings(data); } |
|
return vnode |
|
} else { |
|
return createEmptyVNode() |
|
} |
|
} |
|
|
|
function applyNS (vnode, ns, force) { |
|
vnode.ns = ns; |
|
if (vnode.tag === 'foreignObject') { |
|
// use default namespace inside foreignObject |
|
ns = undefined; |
|
force = true; |
|
} |
|
if (isDef(vnode.children)) { |
|
for (var i = 0, l = vnode.children.length; i < l; i++) { |
|
var child = vnode.children[i]; |
|
if (isDef(child.tag) && ( |
|
isUndef(child.ns) || (isTrue(force) && child.tag !== 'svg'))) { |
|
applyNS(child, ns, force); |
|
} |
|
} |
|
} |
|
} |
|
|
|
// ref #5318 |
|
// necessary to ensure parent re-render when deep bindings like :style and |
|
// :class are used on slot nodes |
|
function registerDeepBindings (data) { |
|
if (isObject(data.style)) { |
|
traverse(data.style); |
|
} |
|
if (isObject(data.class)) { |
|
traverse(data.class); |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
function initRender (vm) { |
|
vm._vnode = null; // the root of the child tree |
|
vm._staticTrees = null; // v-once cached trees |
|
var options = vm.$options; |
|
var parentVnode = vm.$vnode = options._parentVnode; // the placeholder node in parent tree |
|
var renderContext = parentVnode && parentVnode.context; |
|
vm.$slots = resolveSlots(options._renderChildren, renderContext); |
|
vm.$scopedSlots = emptyObject; |
|
// bind the createElement fn to this instance |
|
// so that we get proper render context inside it. |
|
// args order: tag, data, children, normalizationType, alwaysNormalize |
|
// internal version is used by render functions compiled from templates |
|
vm._c = function (a, b, c, d) { return createElement(vm, a, b, c, d, false); }; |
|
// normalization is always applied for the public version, used in |
|
// user-written render functions. |
|
vm.$createElement = function (a, b, c, d) { return createElement(vm, a, b, c, d, true); }; |
|
|
|
// $attrs & $listeners are exposed for easier HOC creation. |
|
// they need to be reactive so that HOCs using them are always updated |
|
var parentData = parentVnode && parentVnode.data; |
|
|
|
/* istanbul ignore else */ |
|
if (true) { |
|
defineReactive(vm, '$attrs', parentData && parentData.attrs || emptyObject, function () { |
|
!isUpdatingChildComponent && warn("$attrs is readonly.", vm); |
|
}, true); |
|
defineReactive(vm, '$listeners', options._parentListeners || emptyObject, function () { |
|
!isUpdatingChildComponent && warn("$listeners is readonly.", vm); |
|
}, true); |
|
} else { |
|
defineReactive(vm, '$attrs', parentData && parentData.attrs || emptyObject, null, true); |
|
defineReactive(vm, '$listeners', options._parentListeners || emptyObject, null, true); |
|
} |
|
} |
|
|
|
function renderMixin (Vue) { |
|
// install runtime convenience helpers |
|
installRenderHelpers(Vue.prototype); |
|
|
|
Vue.prototype.$nextTick = function (fn) { |
|
return nextTick(fn, this) |
|
}; |
|
|
|
Vue.prototype._render = function () { |
|
var vm = this; |
|
var ref = vm.$options; |
|
var render = ref.render; |
|
var _parentVnode = ref._parentVnode; |
|
|
|
// reset _rendered flag on slots for duplicate slot check |
|
if (true) { |
|
for (var key in vm.$slots) { |
|
// $flow-disable-line |
|
vm.$slots[key]._rendered = false; |
|
} |
|
} |
|
|
|
if (_parentVnode) { |
|
vm.$scopedSlots = _parentVnode.data.scopedSlots || emptyObject; |
|
} |
|
|
|
// set parent vnode. this allows render functions to have access |
|
// to the data on the placeholder node. |
|
vm.$vnode = _parentVnode; |
|
// render self |
|
var vnode; |
|
try { |
|
vnode = render.call(vm._renderProxy, vm.$createElement); |
|
} catch (e) { |
|
handleError(e, vm, "render"); |
|
// return error render result, |
|
// or previous vnode to prevent render error causing blank component |
|
/* istanbul ignore else */ |
|
if (true) { |
|
if (vm.$options.renderError) { |
|
try { |
|
vnode = vm.$options.renderError.call(vm._renderProxy, vm.$createElement, e); |
|
} catch (e) { |
|
handleError(e, vm, "renderError"); |
|
vnode = vm._vnode; |
|
} |
|
} else { |
|
vnode = vm._vnode; |
|
} |
|
} else { |
|
vnode = vm._vnode; |
|
} |
|
} |
|
// return empty vnode in case the render function errored out |
|
if (!(vnode instanceof VNode)) { |
|
if ("development" !== 'production' && Array.isArray(vnode)) { |
|
warn( |
|
'Multiple root nodes returned from render function. Render function ' + |
|
'should return a single root node.', |
|
vm |
|
); |
|
} |
|
vnode = createEmptyVNode(); |
|
} |
|
// set parent |
|
vnode.parent = _parentVnode; |
|
return vnode |
|
}; |
|
} |
|
|
|
/* */ |
|
|
|
var uid$3 = 0; |
|
|
|
function initMixin (Vue) { |
|
Vue.prototype._init = function (options) { |
|
var vm = this; |
|
// a uid |
|
vm._uid = uid$3++; |
|
|
|
var startTag, endTag; |
|
/* istanbul ignore if */ |
|
if ("development" !== 'production' && config.performance && mark) { |
|
startTag = "vue-perf-start:" + (vm._uid); |
|
endTag = "vue-perf-end:" + (vm._uid); |
|
mark(startTag); |
|
} |
|
|
|
// a flag to avoid this being observed |
|
vm._isVue = true; |
|
// merge options |
|
if (options && options._isComponent) { |
|
// optimize internal component instantiation |
|
// since dynamic options merging is pretty slow, and none of the |
|
// internal component options needs special treatment. |
|
initInternalComponent(vm, options); |
|
} else { |
|
vm.$options = mergeOptions( |
|
resolveConstructorOptions(vm.constructor), |
|
options || {}, |
|
vm |
|
); |
|
} |
|
/* istanbul ignore else */ |
|
if (true) { |
|
initProxy(vm); |
|
} else { |
|
vm._renderProxy = vm; |
|
} |
|
// expose real self |
|
vm._self = vm; |
|
initLifecycle(vm); |
|
initEvents(vm); |
|
initRender(vm); |
|
callHook(vm, 'beforeCreate'); |
|
initInjections(vm); // resolve injections before data/props |
|
initState(vm); |
|
initProvide(vm); // resolve provide after data/props |
|
callHook(vm, 'created'); |
|
|
|
/* istanbul ignore if */ |
|
if ("development" !== 'production' && config.performance && mark) { |
|
vm._name = formatComponentName(vm, false); |
|
mark(endTag); |
|
measure(("vue " + (vm._name) + " init"), startTag, endTag); |
|
} |
|
|
|
if (vm.$options.el) { |
|
vm.$mount(vm.$options.el); |
|
} |
|
}; |
|
} |
|
|
|
function initInternalComponent (vm, options) { |
|
var opts = vm.$options = Object.create(vm.constructor.options); |
|
// doing this because it's faster than dynamic enumeration. |
|
var parentVnode = options._parentVnode; |
|
opts.parent = options.parent; |
|
opts._parentVnode = parentVnode; |
|
opts._parentElm = options._parentElm; |
|
opts._refElm = options._refElm; |
|
|
|
var vnodeComponentOptions = parentVnode.componentOptions; |
|
opts.propsData = vnodeComponentOptions.propsData; |
|
opts._parentListeners = vnodeComponentOptions.listeners; |
|
opts._renderChildren = vnodeComponentOptions.children; |
|
opts._componentTag = vnodeComponentOptions.tag; |
|
|
|
if (options.render) { |
|
opts.render = options.render; |
|
opts.staticRenderFns = options.staticRenderFns; |
|
} |
|
} |
|
|
|
function resolveConstructorOptions (Ctor) { |
|
var options = Ctor.options; |
|
if (Ctor.super) { |
|
var superOptions = resolveConstructorOptions(Ctor.super); |
|
var cachedSuperOptions = Ctor.superOptions; |
|
if (superOptions !== cachedSuperOptions) { |
|
// super option changed, |
|
// need to resolve new options. |
|
Ctor.superOptions = superOptions; |
|
// check if there are any late-modified/attached options (#4976) |
|
var modifiedOptions = resolveModifiedOptions(Ctor); |
|
// update base extend options |
|
if (modifiedOptions) { |
|
extend(Ctor.extendOptions, modifiedOptions); |
|
} |
|
options = Ctor.options = mergeOptions(superOptions, Ctor.extendOptions); |
|
if (options.name) { |
|
options.components[options.name] = Ctor; |
|
} |
|
} |
|
} |
|
return options |
|
} |
|
|
|
function resolveModifiedOptions (Ctor) { |
|
var modified; |
|
var latest = Ctor.options; |
|
var extended = Ctor.extendOptions; |
|
var sealed = Ctor.sealedOptions; |
|
for (var key in latest) { |
|
if (latest[key] !== sealed[key]) { |
|
if (!modified) { modified = {}; } |
|
modified[key] = dedupe(latest[key], extended[key], sealed[key]); |
|
} |
|
} |
|
return modified |
|
} |
|
|
|
function dedupe (latest, extended, sealed) { |
|
// compare latest and sealed to ensure lifecycle hooks won't be duplicated |
|
// between merges |
|
if (Array.isArray(latest)) { |
|
var res = []; |
|
sealed = Array.isArray(sealed) ? sealed : [sealed]; |
|
extended = Array.isArray(extended) ? extended : [extended]; |
|
for (var i = 0; i < latest.length; i++) { |
|
// push original options and not sealed options to exclude duplicated options |
|
if (extended.indexOf(latest[i]) >= 0 || sealed.indexOf(latest[i]) < 0) { |
|
res.push(latest[i]); |
|
} |
|
} |
|
return res |
|
} else { |
|
return latest |
|
} |
|
} |
|
|
|
function Vue (options) { |
|
if ("development" !== 'production' && |
|
!(this instanceof Vue) |
|
) { |
|
warn('Vue is a constructor and should be called with the `new` keyword'); |
|
} |
|
this._init(options); |
|
} |
|
|
|
initMixin(Vue); |
|
stateMixin(Vue); |
|
eventsMixin(Vue); |
|
lifecycleMixin(Vue); |
|
renderMixin(Vue); |
|
|
|
/* */ |
|
|
|
function initUse (Vue) { |
|
Vue.use = function (plugin) { |
|
var installedPlugins = (this._installedPlugins || (this._installedPlugins = [])); |
|
if (installedPlugins.indexOf(plugin) > -1) { |
|
return this |
|
} |
|
|
|
// additional parameters |
|
var args = toArray(arguments, 1); |
|
args.unshift(this); |
|
if (typeof plugin.install === 'function') { |
|
plugin.install.apply(plugin, args); |
|
} else if (typeof plugin === 'function') { |
|
plugin.apply(null, args); |
|
} |
|
installedPlugins.push(plugin); |
|
return this |
|
}; |
|
} |
|
|
|
/* */ |
|
|
|
function initMixin$1 (Vue) { |
|
Vue.mixin = function (mixin) { |
|
this.options = mergeOptions(this.options, mixin); |
|
return this |
|
}; |
|
} |
|
|
|
/* */ |
|
|
|
function initExtend (Vue) { |
|
/** |
|
* Each instance constructor, including Vue, has a unique |
|
* cid. This enables us to create wrapped "child |
|
* constructors" for prototypal inheritance and cache them. |
|
*/ |
|
Vue.cid = 0; |
|
var cid = 1; |
|
|
|
/** |
|
* Class inheritance |
|
*/ |
|
Vue.extend = function (extendOptions) { |
|
extendOptions = extendOptions || {}; |
|
var Super = this; |
|
var SuperId = Super.cid; |
|
var cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {}); |
|
if (cachedCtors[SuperId]) { |
|
return cachedCtors[SuperId] |
|
} |
|
|
|
var name = extendOptions.name || Super.options.name; |
|
if ("development" !== 'production' && name) { |
|
validateComponentName(name); |
|
} |
|
|
|
var Sub = function VueComponent (options) { |
|
this._init(options); |
|
}; |
|
Sub.prototype = Object.create(Super.prototype); |
|
Sub.prototype.constructor = Sub; |
|
Sub.cid = cid++; |
|
Sub.options = mergeOptions( |
|
Super.options, |
|
extendOptions |
|
); |
|
Sub['super'] = Super; |
|
|
|
// For props and computed properties, we define the proxy getters on |
|
// the Vue instances at extension time, on the extended prototype. This |
|
// avoids Object.defineProperty calls for each instance created. |
|
if (Sub.options.props) { |
|
initProps$1(Sub); |
|
} |
|
if (Sub.options.computed) { |
|
initComputed$1(Sub); |
|
} |
|
|
|
// allow further extension/mixin/plugin usage |
|
Sub.extend = Super.extend; |
|
Sub.mixin = Super.mixin; |
|
Sub.use = Super.use; |
|
|
|
// create asset registers, so extended classes |
|
// can have their private assets too. |
|
ASSET_TYPES.forEach(function (type) { |
|
Sub[type] = Super[type]; |
|
}); |
|
// enable recursive self-lookup |
|
if (name) { |
|
Sub.options.components[name] = Sub; |
|
} |
|
|
|
// keep a reference to the super options at extension time. |
|
// later at instantiation we can check if Super's options have |
|
// been updated. |
|
Sub.superOptions = Super.options; |
|
Sub.extendOptions = extendOptions; |
|
Sub.sealedOptions = extend({}, Sub.options); |
|
|
|
// cache constructor |
|
cachedCtors[SuperId] = Sub; |
|
return Sub |
|
}; |
|
} |
|
|
|
function initProps$1 (Comp) { |
|
var props = Comp.options.props; |
|
for (var key in props) { |
|
proxy(Comp.prototype, "_props", key); |
|
} |
|
} |
|
|
|
function initComputed$1 (Comp) { |
|
var computed = Comp.options.computed; |
|
for (var key in computed) { |
|
defineComputed(Comp.prototype, key, computed[key]); |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
function initAssetRegisters (Vue) { |
|
/** |
|
* Create asset registration methods. |
|
*/ |
|
ASSET_TYPES.forEach(function (type) { |
|
Vue[type] = function ( |
|
id, |
|
definition |
|
) { |
|
if (!definition) { |
|
return this.options[type + 's'][id] |
|
} else { |
|
/* istanbul ignore if */ |
|
if ("development" !== 'production' && type === 'component') { |
|
validateComponentName(id); |
|
} |
|
if (type === 'component' && isPlainObject(definition)) { |
|
definition.name = definition.name || id; |
|
definition = this.options._base.extend(definition); |
|
} |
|
if (type === 'directive' && typeof definition === 'function') { |
|
definition = { bind: definition, update: definition }; |
|
} |
|
this.options[type + 's'][id] = definition; |
|
return definition |
|
} |
|
}; |
|
}); |
|
} |
|
|
|
/* */ |
|
|
|
function getComponentName (opts) { |
|
return opts && (opts.Ctor.options.name || opts.tag) |
|
} |
|
|
|
function matches (pattern, name) { |
|
if (Array.isArray(pattern)) { |
|
return pattern.indexOf(name) > -1 |
|
} else if (typeof pattern === 'string') { |
|
return pattern.split(',').indexOf(name) > -1 |
|
} else if (isRegExp(pattern)) { |
|
return pattern.test(name) |
|
} |
|
/* istanbul ignore next */ |
|
return false |
|
} |
|
|
|
function pruneCache (keepAliveInstance, filter) { |
|
var cache = keepAliveInstance.cache; |
|
var keys = keepAliveInstance.keys; |
|
var _vnode = keepAliveInstance._vnode; |
|
for (var key in cache) { |
|
var cachedNode = cache[key]; |
|
if (cachedNode) { |
|
var name = getComponentName(cachedNode.componentOptions); |
|
if (name && !filter(name)) { |
|
pruneCacheEntry(cache, key, keys, _vnode); |
|
} |
|
} |
|
} |
|
} |
|
|
|
function pruneCacheEntry ( |
|
cache, |
|
key, |
|
keys, |
|
current |
|
) { |
|
var cached$$1 = cache[key]; |
|
if (cached$$1 && (!current || cached$$1.tag !== current.tag)) { |
|
cached$$1.componentInstance.$destroy(); |
|
} |
|
cache[key] = null; |
|
remove(keys, key); |
|
} |
|
|
|
var patternTypes = [String, RegExp, Array]; |
|
|
|
var KeepAlive = { |
|
name: 'keep-alive', |
|
abstract: true, |
|
|
|
props: { |
|
include: patternTypes, |
|
exclude: patternTypes, |
|
max: [String, Number] |
|
}, |
|
|
|
created: function created () { |
|
this.cache = Object.create(null); |
|
this.keys = []; |
|
}, |
|
|
|
destroyed: function destroyed () { |
|
var this$1 = this; |
|
|
|
for (var key in this$1.cache) { |
|
pruneCacheEntry(this$1.cache, key, this$1.keys); |
|
} |
|
}, |
|
|
|
mounted: function mounted () { |
|
var this$1 = this; |
|
|
|
this.$watch('include', function (val) { |
|
pruneCache(this$1, function (name) { return matches(val, name); }); |
|
}); |
|
this.$watch('exclude', function (val) { |
|
pruneCache(this$1, function (name) { return !matches(val, name); }); |
|
}); |
|
}, |
|
|
|
render: function render () { |
|
var slot = this.$slots.default; |
|
var vnode = getFirstComponentChild(slot); |
|
var componentOptions = vnode && vnode.componentOptions; |
|
if (componentOptions) { |
|
// check pattern |
|
var name = getComponentName(componentOptions); |
|
var ref = this; |
|
var include = ref.include; |
|
var exclude = ref.exclude; |
|
if ( |
|
// not included |
|
(include && (!name || !matches(include, name))) || |
|
// excluded |
|
(exclude && name && matches(exclude, name)) |
|
) { |
|
return vnode |
|
} |
|
|
|
var ref$1 = this; |
|
var cache = ref$1.cache; |
|
var keys = ref$1.keys; |
|
var key = vnode.key == null |
|
// same constructor may get registered as different local components |
|
// so cid alone is not enough (#3269) |
|
? componentOptions.Ctor.cid + (componentOptions.tag ? ("::" + (componentOptions.tag)) : '') |
|
: vnode.key; |
|
if (cache[key]) { |
|
vnode.componentInstance = cache[key].componentInstance; |
|
// make current key freshest |
|
remove(keys, key); |
|
keys.push(key); |
|
} else { |
|
cache[key] = vnode; |
|
keys.push(key); |
|
// prune oldest entry |
|
if (this.max && keys.length > parseInt(this.max)) { |
|
pruneCacheEntry(cache, keys[0], keys, this._vnode); |
|
} |
|
} |
|
|
|
vnode.data.keepAlive = true; |
|
} |
|
return vnode || (slot && slot[0]) |
|
} |
|
} |
|
|
|
var builtInComponents = { |
|
KeepAlive: KeepAlive |
|
} |
|
|
|
/* */ |
|
|
|
function initGlobalAPI (Vue) { |
|
// config |
|
var configDef = {}; |
|
configDef.get = function () { return config; }; |
|
if (true) { |
|
configDef.set = function () { |
|
warn( |
|
'Do not replace the Vue.config object, set individual fields instead.' |
|
); |
|
}; |
|
} |
|
Object.defineProperty(Vue, 'config', configDef); |
|
|
|
// exposed util methods. |
|
// NOTE: these are not considered part of the public API - avoid relying on |
|
// them unless you are aware of the risk. |
|
Vue.util = { |
|
warn: warn, |
|
extend: extend, |
|
mergeOptions: mergeOptions, |
|
defineReactive: defineReactive |
|
}; |
|
|
|
Vue.set = set; |
|
Vue.delete = del; |
|
Vue.nextTick = nextTick; |
|
|
|
Vue.options = Object.create(null); |
|
ASSET_TYPES.forEach(function (type) { |
|
Vue.options[type + 's'] = Object.create(null); |
|
}); |
|
|
|
// this is used to identify the "base" constructor to extend all plain-object |
|
// components with in Weex's multi-instance scenarios. |
|
Vue.options._base = Vue; |
|
|
|
extend(Vue.options.components, builtInComponents); |
|
|
|
initUse(Vue); |
|
initMixin$1(Vue); |
|
initExtend(Vue); |
|
initAssetRegisters(Vue); |
|
} |
|
|
|
initGlobalAPI(Vue); |
|
|
|
Object.defineProperty(Vue.prototype, '$isServer', { |
|
get: isServerRendering |
|
}); |
|
|
|
Object.defineProperty(Vue.prototype, '$ssrContext', { |
|
get: function get () { |
|
/* istanbul ignore next */ |
|
return this.$vnode && this.$vnode.ssrContext |
|
} |
|
}); |
|
|
|
// expose FunctionalRenderContext for ssr runtime helper installation |
|
Object.defineProperty(Vue, 'FunctionalRenderContext', { |
|
value: FunctionalRenderContext |
|
}); |
|
|
|
Vue.version = '2.5.16'; |
|
|
|
/* */ |
|
|
|
// these are reserved for web because they are directly compiled away |
|
// during template compilation |
|
var isReservedAttr = makeMap('style,class'); |
|
|
|
// attributes that should be using props for binding |
|
var acceptValue = makeMap('input,textarea,option,select,progress'); |
|
var mustUseProp = function (tag, type, attr) { |
|
return ( |
|
(attr === 'value' && acceptValue(tag)) && type !== 'button' || |
|
(attr === 'selected' && tag === 'option') || |
|
(attr === 'checked' && tag === 'input') || |
|
(attr === 'muted' && tag === 'video') |
|
) |
|
}; |
|
|
|
var isEnumeratedAttr = makeMap('contenteditable,draggable,spellcheck'); |
|
|
|
var isBooleanAttr = makeMap( |
|
'allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,' + |
|
'default,defaultchecked,defaultmuted,defaultselected,defer,disabled,' + |
|
'enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,' + |
|
'muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,' + |
|
'required,reversed,scoped,seamless,selected,sortable,translate,' + |
|
'truespeed,typemustmatch,visible' |
|
); |
|
|
|
var xlinkNS = 'http://www.w3.org/1999/xlink'; |
|
|
|
var isXlink = function (name) { |
|
return name.charAt(5) === ':' && name.slice(0, 5) === 'xlink' |
|
}; |
|
|
|
var getXlinkProp = function (name) { |
|
return isXlink(name) ? name.slice(6, name.length) : '' |
|
}; |
|
|
|
var isFalsyAttrValue = function (val) { |
|
return val == null || val === false |
|
}; |
|
|
|
/* */ |
|
|
|
function genClassForVnode (vnode) { |
|
var data = vnode.data; |
|
var parentNode = vnode; |
|
var childNode = vnode; |
|
while (isDef(childNode.componentInstance)) { |
|
childNode = childNode.componentInstance._vnode; |
|
if (childNode && childNode.data) { |
|
data = mergeClassData(childNode.data, data); |
|
} |
|
} |
|
while (isDef(parentNode = parentNode.parent)) { |
|
if (parentNode && parentNode.data) { |
|
data = mergeClassData(data, parentNode.data); |
|
} |
|
} |
|
return renderClass(data.staticClass, data.class) |
|
} |
|
|
|
function mergeClassData (child, parent) { |
|
return { |
|
staticClass: concat(child.staticClass, parent.staticClass), |
|
class: isDef(child.class) |
|
? [child.class, parent.class] |
|
: parent.class |
|
} |
|
} |
|
|
|
function renderClass ( |
|
staticClass, |
|
dynamicClass |
|
) { |
|
if (isDef(staticClass) || isDef(dynamicClass)) { |
|
return concat(staticClass, stringifyClass(dynamicClass)) |
|
} |
|
/* istanbul ignore next */ |
|
return '' |
|
} |
|
|
|
function concat (a, b) { |
|
return a ? b ? (a + ' ' + b) : a : (b || '') |
|
} |
|
|
|
function stringifyClass (value) { |
|
if (Array.isArray(value)) { |
|
return stringifyArray(value) |
|
} |
|
if (isObject(value)) { |
|
return stringifyObject(value) |
|
} |
|
if (typeof value === 'string') { |
|
return value |
|
} |
|
/* istanbul ignore next */ |
|
return '' |
|
} |
|
|
|
function stringifyArray (value) { |
|
var res = ''; |
|
var stringified; |
|
for (var i = 0, l = value.length; i < l; i++) { |
|
if (isDef(stringified = stringifyClass(value[i])) && stringified !== '') { |
|
if (res) { res += ' '; } |
|
res += stringified; |
|
} |
|
} |
|
return res |
|
} |
|
|
|
function stringifyObject (value) { |
|
var res = ''; |
|
for (var key in value) { |
|
if (value[key]) { |
|
if (res) { res += ' '; } |
|
res += key; |
|
} |
|
} |
|
return res |
|
} |
|
|
|
/* */ |
|
|
|
var namespaceMap = { |
|
svg: 'http://www.w3.org/2000/svg', |
|
math: 'http://www.w3.org/1998/Math/MathML' |
|
}; |
|
|
|
var isHTMLTag = makeMap( |
|
'html,body,base,head,link,meta,style,title,' + |
|
'address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,' + |
|
'div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,' + |
|
'a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,' + |
|
's,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,' + |
|
'embed,object,param,source,canvas,script,noscript,del,ins,' + |
|
'caption,col,colgroup,table,thead,tbody,td,th,tr,' + |
|
'button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,' + |
|
'output,progress,select,textarea,' + |
|
'details,dialog,menu,menuitem,summary,' + |
|
'content,element,shadow,template,blockquote,iframe,tfoot' |
|
); |
|
|
|
// this map is intentionally selective, only covering SVG elements that may |
|
// contain child elements. |
|
var isSVG = makeMap( |
|
'svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face,' + |
|
'foreignObject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,' + |
|
'polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view', |
|
true |
|
); |
|
|
|
var isPreTag = function (tag) { return tag === 'pre'; }; |
|
|
|
var isReservedTag = function (tag) { |
|
return isHTMLTag(tag) || isSVG(tag) |
|
}; |
|
|
|
function getTagNamespace (tag) { |
|
if (isSVG(tag)) { |
|
return 'svg' |
|
} |
|
// basic support for MathML |
|
// note it doesn't support other MathML elements being component roots |
|
if (tag === 'math') { |
|
return 'math' |
|
} |
|
} |
|
|
|
var unknownElementCache = Object.create(null); |
|
function isUnknownElement (tag) { |
|
/* istanbul ignore if */ |
|
if (!inBrowser) { |
|
return true |
|
} |
|
if (isReservedTag(tag)) { |
|
return false |
|
} |
|
tag = tag.toLowerCase(); |
|
/* istanbul ignore if */ |
|
if (unknownElementCache[tag] != null) { |
|
return unknownElementCache[tag] |
|
} |
|
var el = document.createElement(tag); |
|
if (tag.indexOf('-') > -1) { |
|
// http://stackoverflow.com/a/28210364/1070244 |
|
return (unknownElementCache[tag] = ( |
|
el.constructor === window.HTMLUnknownElement || |
|
el.constructor === window.HTMLElement |
|
)) |
|
} else { |
|
return (unknownElementCache[tag] = /HTMLUnknownElement/.test(el.toString())) |
|
} |
|
} |
|
|
|
var isTextInputType = makeMap('text,number,password,search,email,tel,url'); |
|
|
|
/* */ |
|
|
|
/** |
|
* Query an element selector if it's not an element already. |
|
*/ |
|
function query (el) { |
|
if (typeof el === 'string') { |
|
var selected = document.querySelector(el); |
|
if (!selected) { |
|
"development" !== 'production' && warn( |
|
'Cannot find element: ' + el |
|
); |
|
return document.createElement('div') |
|
} |
|
return selected |
|
} else { |
|
return el |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
function createElement$1 (tagName, vnode) { |
|
var elm = document.createElement(tagName); |
|
if (tagName !== 'select') { |
|
return elm |
|
} |
|
// false or null will remove the attribute but undefined will not |
|
if (vnode.data && vnode.data.attrs && vnode.data.attrs.multiple !== undefined) { |
|
elm.setAttribute('multiple', 'multiple'); |
|
} |
|
return elm |
|
} |
|
|
|
function createElementNS (namespace, tagName) { |
|
return document.createElementNS(namespaceMap[namespace], tagName) |
|
} |
|
|
|
function createTextNode (text) { |
|
return document.createTextNode(text) |
|
} |
|
|
|
function createComment (text) { |
|
return document.createComment(text) |
|
} |
|
|
|
function insertBefore (parentNode, newNode, referenceNode) { |
|
parentNode.insertBefore(newNode, referenceNode); |
|
} |
|
|
|
function removeChild (node, child) { |
|
node.removeChild(child); |
|
} |
|
|
|
function appendChild (node, child) { |
|
node.appendChild(child); |
|
} |
|
|
|
function parentNode (node) { |
|
return node.parentNode |
|
} |
|
|
|
function nextSibling (node) { |
|
return node.nextSibling |
|
} |
|
|
|
function tagName (node) { |
|
return node.tagName |
|
} |
|
|
|
function setTextContent (node, text) { |
|
node.textContent = text; |
|
} |
|
|
|
function setStyleScope (node, scopeId) { |
|
node.setAttribute(scopeId, ''); |
|
} |
|
|
|
|
|
var nodeOps = Object.freeze({ |
|
createElement: createElement$1, |
|
createElementNS: createElementNS, |
|
createTextNode: createTextNode, |
|
createComment: createComment, |
|
insertBefore: insertBefore, |
|
removeChild: removeChild, |
|
appendChild: appendChild, |
|
parentNode: parentNode, |
|
nextSibling: nextSibling, |
|
tagName: tagName, |
|
setTextContent: setTextContent, |
|
setStyleScope: setStyleScope |
|
}); |
|
|
|
/* */ |
|
|
|
var ref = { |
|
create: function create (_, vnode) { |
|
registerRef(vnode); |
|
}, |
|
update: function update (oldVnode, vnode) { |
|
if (oldVnode.data.ref !== vnode.data.ref) { |
|
registerRef(oldVnode, true); |
|
registerRef(vnode); |
|
} |
|
}, |
|
destroy: function destroy (vnode) { |
|
registerRef(vnode, true); |
|
} |
|
} |
|
|
|
function registerRef (vnode, isRemoval) { |
|
var key = vnode.data.ref; |
|
if (!isDef(key)) { return } |
|
|
|
var vm = vnode.context; |
|
var ref = vnode.componentInstance || vnode.elm; |
|
var refs = vm.$refs; |
|
if (isRemoval) { |
|
if (Array.isArray(refs[key])) { |
|
remove(refs[key], ref); |
|
} else if (refs[key] === ref) { |
|
refs[key] = undefined; |
|
} |
|
} else { |
|
if (vnode.data.refInFor) { |
|
if (!Array.isArray(refs[key])) { |
|
refs[key] = [ref]; |
|
} else if (refs[key].indexOf(ref) < 0) { |
|
// $flow-disable-line |
|
refs[key].push(ref); |
|
} |
|
} else { |
|
refs[key] = ref; |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* Virtual DOM patching algorithm based on Snabbdom by |
|
* Simon Friis Vindum (@paldepind) |
|
* Licensed under the MIT License |
|
* https://github.com/paldepind/snabbdom/blob/master/LICENSE |
|
* |
|
* modified by Evan You (@yyx990803) |
|
* |
|
* Not type-checking this because this file is perf-critical and the cost |
|
* of making flow understand it is not worth it. |
|
*/ |
|
|
|
var emptyNode = new VNode('', {}, []); |
|
|
|
var hooks = ['create', 'activate', 'update', 'remove', 'destroy']; |
|
|
|
function sameVnode (a, b) { |
|
return ( |
|
a.key === b.key && ( |
|
( |
|
a.tag === b.tag && |
|
a.isComment === b.isComment && |
|
isDef(a.data) === isDef(b.data) && |
|
sameInputType(a, b) |
|
) || ( |
|
isTrue(a.isAsyncPlaceholder) && |
|
a.asyncFactory === b.asyncFactory && |
|
isUndef(b.asyncFactory.error) |
|
) |
|
) |
|
) |
|
} |
|
|
|
function sameInputType (a, b) { |
|
if (a.tag !== 'input') { return true } |
|
var i; |
|
var typeA = isDef(i = a.data) && isDef(i = i.attrs) && i.type; |
|
var typeB = isDef(i = b.data) && isDef(i = i.attrs) && i.type; |
|
return typeA === typeB || isTextInputType(typeA) && isTextInputType(typeB) |
|
} |
|
|
|
function createKeyToOldIdx (children, beginIdx, endIdx) { |
|
var i, key; |
|
var map = {}; |
|
for (i = beginIdx; i <= endIdx; ++i) { |
|
key = children[i].key; |
|
if (isDef(key)) { map[key] = i; } |
|
} |
|
return map |
|
} |
|
|
|
function createPatchFunction (backend) { |
|
var i, j; |
|
var cbs = {}; |
|
|
|
var modules = backend.modules; |
|
var nodeOps = backend.nodeOps; |
|
|
|
for (i = 0; i < hooks.length; ++i) { |
|
cbs[hooks[i]] = []; |
|
for (j = 0; j < modules.length; ++j) { |
|
if (isDef(modules[j][hooks[i]])) { |
|
cbs[hooks[i]].push(modules[j][hooks[i]]); |
|
} |
|
} |
|
} |
|
|
|
function emptyNodeAt (elm) { |
|
return new VNode(nodeOps.tagName(elm).toLowerCase(), {}, [], undefined, elm) |
|
} |
|
|
|
function createRmCb (childElm, listeners) { |
|
function remove () { |
|
if (--remove.listeners === 0) { |
|
removeNode(childElm); |
|
} |
|
} |
|
remove.listeners = listeners; |
|
return remove |
|
} |
|
|
|
function removeNode (el) { |
|
var parent = nodeOps.parentNode(el); |
|
// element may have already been removed due to v-html / v-text |
|
if (isDef(parent)) { |
|
nodeOps.removeChild(parent, el); |
|
} |
|
} |
|
|
|
function isUnknownElement$$1 (vnode, inVPre) { |
|
return ( |
|
!inVPre && |
|
!vnode.ns && |
|
!( |
|
config.ignoredElements.length && |
|
config.ignoredElements.some(function (ignore) { |
|
return isRegExp(ignore) |
|
? ignore.test(vnode.tag) |
|
: ignore === vnode.tag |
|
}) |
|
) && |
|
config.isUnknownElement(vnode.tag) |
|
) |
|
} |
|
|
|
var creatingElmInVPre = 0; |
|
|
|
function createElm ( |
|
vnode, |
|
insertedVnodeQueue, |
|
parentElm, |
|
refElm, |
|
nested, |
|
ownerArray, |
|
index |
|
) { |
|
if (isDef(vnode.elm) && isDef(ownerArray)) { |
|
// This vnode was used in a previous render! |
|
// now it's used as a new node, overwriting its elm would cause |
|
// potential patch errors down the road when it's used as an insertion |
|
// reference node. Instead, we clone the node on-demand before creating |
|
// associated DOM element for it. |
|
vnode = ownerArray[index] = cloneVNode(vnode); |
|
} |
|
|
|
vnode.isRootInsert = !nested; // for transition enter check |
|
if (createComponent(vnode, insertedVnodeQueue, parentElm, refElm)) { |
|
return |
|
} |
|
|
|
var data = vnode.data; |
|
var children = vnode.children; |
|
var tag = vnode.tag; |
|
if (isDef(tag)) { |
|
if (true) { |
|
if (data && data.pre) { |
|
creatingElmInVPre++; |
|
} |
|
if (isUnknownElement$$1(vnode, creatingElmInVPre)) { |
|
warn( |
|
'Unknown custom element: <' + tag + '> - did you ' + |
|
'register the component correctly? For recursive components, ' + |
|
'make sure to provide the "name" option.', |
|
vnode.context |
|
); |
|
} |
|
} |
|
|
|
vnode.elm = vnode.ns |
|
? nodeOps.createElementNS(vnode.ns, tag) |
|
: nodeOps.createElement(tag, vnode); |
|
setScope(vnode); |
|
|
|
/* istanbul ignore if */ |
|
{ |
|
createChildren(vnode, children, insertedVnodeQueue); |
|
if (isDef(data)) { |
|
invokeCreateHooks(vnode, insertedVnodeQueue); |
|
} |
|
insert(parentElm, vnode.elm, refElm); |
|
} |
|
|
|
if ("development" !== 'production' && data && data.pre) { |
|
creatingElmInVPre--; |
|
} |
|
} else if (isTrue(vnode.isComment)) { |
|
vnode.elm = nodeOps.createComment(vnode.text); |
|
insert(parentElm, vnode.elm, refElm); |
|
} else { |
|
vnode.elm = nodeOps.createTextNode(vnode.text); |
|
insert(parentElm, vnode.elm, refElm); |
|
} |
|
} |
|
|
|
function createComponent (vnode, insertedVnodeQueue, parentElm, refElm) { |
|
var i = vnode.data; |
|
if (isDef(i)) { |
|
var isReactivated = isDef(vnode.componentInstance) && i.keepAlive; |
|
if (isDef(i = i.hook) && isDef(i = i.init)) { |
|
i(vnode, false /* hydrating */, parentElm, refElm); |
|
} |
|
// after calling the init hook, if the vnode is a child component |
|
// it should've created a child instance and mounted it. the child |
|
// component also has set the placeholder vnode's elm. |
|
// in that case we can just return the element and be done. |
|
if (isDef(vnode.componentInstance)) { |
|
initComponent(vnode, insertedVnodeQueue); |
|
if (isTrue(isReactivated)) { |
|
reactivateComponent(vnode, insertedVnodeQueue, parentElm, refElm); |
|
} |
|
return true |
|
} |
|
} |
|
} |
|
|
|
function initComponent (vnode, insertedVnodeQueue) { |
|
if (isDef(vnode.data.pendingInsert)) { |
|
insertedVnodeQueue.push.apply(insertedVnodeQueue, vnode.data.pendingInsert); |
|
vnode.data.pendingInsert = null; |
|
} |
|
vnode.elm = vnode.componentInstance.$el; |
|
if (isPatchable(vnode)) { |
|
invokeCreateHooks(vnode, insertedVnodeQueue); |
|
setScope(vnode); |
|
} else { |
|
// empty component root. |
|
// skip all element-related modules except for ref (#3455) |
|
registerRef(vnode); |
|
// make sure to invoke the insert hook |
|
insertedVnodeQueue.push(vnode); |
|
} |
|
} |
|
|
|
function reactivateComponent (vnode, insertedVnodeQueue, parentElm, refElm) { |
|
var i; |
|
// hack for #4339: a reactivated component with inner transition |
|
// does not trigger because the inner node's created hooks are not called |
|
// again. It's not ideal to involve module-specific logic in here but |
|
// there doesn't seem to be a better way to do it. |
|
var innerNode = vnode; |
|
while (innerNode.componentInstance) { |
|
innerNode = innerNode.componentInstance._vnode; |
|
if (isDef(i = innerNode.data) && isDef(i = i.transition)) { |
|
for (i = 0; i < cbs.activate.length; ++i) { |
|
cbs.activate[i](emptyNode, innerNode); |
|
} |
|
insertedVnodeQueue.push(innerNode); |
|
break |
|
} |
|
} |
|
// unlike a newly created component, |
|
// a reactivated keep-alive component doesn't insert itself |
|
insert(parentElm, vnode.elm, refElm); |
|
} |
|
|
|
function insert (parent, elm, ref$$1) { |
|
if (isDef(parent)) { |
|
if (isDef(ref$$1)) { |
|
if (ref$$1.parentNode === parent) { |
|
nodeOps.insertBefore(parent, elm, ref$$1); |
|
} |
|
} else { |
|
nodeOps.appendChild(parent, elm); |
|
} |
|
} |
|
} |
|
|
|
function createChildren (vnode, children, insertedVnodeQueue) { |
|
if (Array.isArray(children)) { |
|
if (true) { |
|
checkDuplicateKeys(children); |
|
} |
|
for (var i = 0; i < children.length; ++i) { |
|
createElm(children[i], insertedVnodeQueue, vnode.elm, null, true, children, i); |
|
} |
|
} else if (isPrimitive(vnode.text)) { |
|
nodeOps.appendChild(vnode.elm, nodeOps.createTextNode(String(vnode.text))); |
|
} |
|
} |
|
|
|
function isPatchable (vnode) { |
|
while (vnode.componentInstance) { |
|
vnode = vnode.componentInstance._vnode; |
|
} |
|
return isDef(vnode.tag) |
|
} |
|
|
|
function invokeCreateHooks (vnode, insertedVnodeQueue) { |
|
for (var i$1 = 0; i$1 < cbs.create.length; ++i$1) { |
|
cbs.create[i$1](emptyNode, vnode); |
|
} |
|
i = vnode.data.hook; // Reuse variable |
|
if (isDef(i)) { |
|
if (isDef(i.create)) { i.create(emptyNode, vnode); } |
|
if (isDef(i.insert)) { insertedVnodeQueue.push(vnode); } |
|
} |
|
} |
|
|
|
// set scope id attribute for scoped CSS. |
|
// this is implemented as a special case to avoid the overhead |
|
// of going through the normal attribute patching process. |
|
function setScope (vnode) { |
|
var i; |
|
if (isDef(i = vnode.fnScopeId)) { |
|
nodeOps.setStyleScope(vnode.elm, i); |
|
} else { |
|
var ancestor = vnode; |
|
while (ancestor) { |
|
if (isDef(i = ancestor.context) && isDef(i = i.$options._scopeId)) { |
|
nodeOps.setStyleScope(vnode.elm, i); |
|
} |
|
ancestor = ancestor.parent; |
|
} |
|
} |
|
// for slot content they should also get the scopeId from the host instance. |
|
if (isDef(i = activeInstance) && |
|
i !== vnode.context && |
|
i !== vnode.fnContext && |
|
isDef(i = i.$options._scopeId) |
|
) { |
|
nodeOps.setStyleScope(vnode.elm, i); |
|
} |
|
} |
|
|
|
function addVnodes (parentElm, refElm, vnodes, startIdx, endIdx, insertedVnodeQueue) { |
|
for (; startIdx <= endIdx; ++startIdx) { |
|
createElm(vnodes[startIdx], insertedVnodeQueue, parentElm, refElm, false, vnodes, startIdx); |
|
} |
|
} |
|
|
|
function invokeDestroyHook (vnode) { |
|
var i, j; |
|
var data = vnode.data; |
|
if (isDef(data)) { |
|
if (isDef(i = data.hook) && isDef(i = i.destroy)) { i(vnode); } |
|
for (i = 0; i < cbs.destroy.length; ++i) { cbs.destroy[i](vnode); } |
|
} |
|
if (isDef(i = vnode.children)) { |
|
for (j = 0; j < vnode.children.length; ++j) { |
|
invokeDestroyHook(vnode.children[j]); |
|
} |
|
} |
|
} |
|
|
|
function removeVnodes (parentElm, vnodes, startIdx, endIdx) { |
|
for (; startIdx <= endIdx; ++startIdx) { |
|
var ch = vnodes[startIdx]; |
|
if (isDef(ch)) { |
|
if (isDef(ch.tag)) { |
|
removeAndInvokeRemoveHook(ch); |
|
invokeDestroyHook(ch); |
|
} else { // Text node |
|
removeNode(ch.elm); |
|
} |
|
} |
|
} |
|
} |
|
|
|
function removeAndInvokeRemoveHook (vnode, rm) { |
|
if (isDef(rm) || isDef(vnode.data)) { |
|
var i; |
|
var listeners = cbs.remove.length + 1; |
|
if (isDef(rm)) { |
|
// we have a recursively passed down rm callback |
|
// increase the listeners count |
|
rm.listeners += listeners; |
|
} else { |
|
// directly removing |
|
rm = createRmCb(vnode.elm, listeners); |
|
} |
|
// recursively invoke hooks on child component root node |
|
if (isDef(i = vnode.componentInstance) && isDef(i = i._vnode) && isDef(i.data)) { |
|
removeAndInvokeRemoveHook(i, rm); |
|
} |
|
for (i = 0; i < cbs.remove.length; ++i) { |
|
cbs.remove[i](vnode, rm); |
|
} |
|
if (isDef(i = vnode.data.hook) && isDef(i = i.remove)) { |
|
i(vnode, rm); |
|
} else { |
|
rm(); |
|
} |
|
} else { |
|
removeNode(vnode.elm); |
|
} |
|
} |
|
|
|
function updateChildren (parentElm, oldCh, newCh, insertedVnodeQueue, removeOnly) { |
|
var oldStartIdx = 0; |
|
var newStartIdx = 0; |
|
var oldEndIdx = oldCh.length - 1; |
|
var oldStartVnode = oldCh[0]; |
|
var oldEndVnode = oldCh[oldEndIdx]; |
|
var newEndIdx = newCh.length - 1; |
|
var newStartVnode = newCh[0]; |
|
var newEndVnode = newCh[newEndIdx]; |
|
var oldKeyToIdx, idxInOld, vnodeToMove, refElm; |
|
|
|
// removeOnly is a special flag used only by <transition-group> |
|
// to ensure removed elements stay in correct relative positions |
|
// during leaving transitions |
|
var canMove = !removeOnly; |
|
|
|
if (true) { |
|
checkDuplicateKeys(newCh); |
|
} |
|
|
|
while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) { |
|
if (isUndef(oldStartVnode)) { |
|
oldStartVnode = oldCh[++oldStartIdx]; // Vnode has been moved left |
|
} else if (isUndef(oldEndVnode)) { |
|
oldEndVnode = oldCh[--oldEndIdx]; |
|
} else if (sameVnode(oldStartVnode, newStartVnode)) { |
|
patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue); |
|
oldStartVnode = oldCh[++oldStartIdx]; |
|
newStartVnode = newCh[++newStartIdx]; |
|
} else if (sameVnode(oldEndVnode, newEndVnode)) { |
|
patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue); |
|
oldEndVnode = oldCh[--oldEndIdx]; |
|
newEndVnode = newCh[--newEndIdx]; |
|
} else if (sameVnode(oldStartVnode, newEndVnode)) { // Vnode moved right |
|
patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue); |
|
canMove && nodeOps.insertBefore(parentElm, oldStartVnode.elm, nodeOps.nextSibling(oldEndVnode.elm)); |
|
oldStartVnode = oldCh[++oldStartIdx]; |
|
newEndVnode = newCh[--newEndIdx]; |
|
} else if (sameVnode(oldEndVnode, newStartVnode)) { // Vnode moved left |
|
patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue); |
|
canMove && nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm); |
|
oldEndVnode = oldCh[--oldEndIdx]; |
|
newStartVnode = newCh[++newStartIdx]; |
|
} else { |
|
if (isUndef(oldKeyToIdx)) { oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx); } |
|
idxInOld = isDef(newStartVnode.key) |
|
? oldKeyToIdx[newStartVnode.key] |
|
: findIdxInOld(newStartVnode, oldCh, oldStartIdx, oldEndIdx); |
|
if (isUndef(idxInOld)) { // New element |
|
createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx); |
|
} else { |
|
vnodeToMove = oldCh[idxInOld]; |
|
if (sameVnode(vnodeToMove, newStartVnode)) { |
|
patchVnode(vnodeToMove, newStartVnode, insertedVnodeQueue); |
|
oldCh[idxInOld] = undefined; |
|
canMove && nodeOps.insertBefore(parentElm, vnodeToMove.elm, oldStartVnode.elm); |
|
} else { |
|
// same key but different element. treat as new element |
|
createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx); |
|
} |
|
} |
|
newStartVnode = newCh[++newStartIdx]; |
|
} |
|
} |
|
if (oldStartIdx > oldEndIdx) { |
|
refElm = isUndef(newCh[newEndIdx + 1]) ? null : newCh[newEndIdx + 1].elm; |
|
addVnodes(parentElm, refElm, newCh, newStartIdx, newEndIdx, insertedVnodeQueue); |
|
} else if (newStartIdx > newEndIdx) { |
|
removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx); |
|
} |
|
} |
|
|
|
function checkDuplicateKeys (children) { |
|
var seenKeys = {}; |
|
for (var i = 0; i < children.length; i++) { |
|
var vnode = children[i]; |
|
var key = vnode.key; |
|
if (isDef(key)) { |
|
if (seenKeys[key]) { |
|
warn( |
|
("Duplicate keys detected: '" + key + "'. This may cause an update error."), |
|
vnode.context |
|
); |
|
} else { |
|
seenKeys[key] = true; |
|
} |
|
} |
|
} |
|
} |
|
|
|
function findIdxInOld (node, oldCh, start, end) { |
|
for (var i = start; i < end; i++) { |
|
var c = oldCh[i]; |
|
if (isDef(c) && sameVnode(node, c)) { return i } |
|
} |
|
} |
|
|
|
function patchVnode (oldVnode, vnode, insertedVnodeQueue, removeOnly) { |
|
if (oldVnode === vnode) { |
|
return |
|
} |
|
|
|
var elm = vnode.elm = oldVnode.elm; |
|
|
|
if (isTrue(oldVnode.isAsyncPlaceholder)) { |
|
if (isDef(vnode.asyncFactory.resolved)) { |
|
hydrate(oldVnode.elm, vnode, insertedVnodeQueue); |
|
} else { |
|
vnode.isAsyncPlaceholder = true; |
|
} |
|
return |
|
} |
|
|
|
// reuse element for static trees. |
|
// note we only do this if the vnode is cloned - |
|
// if the new node is not cloned it means the render functions have been |
|
// reset by the hot-reload-api and we need to do a proper re-render. |
|
if (isTrue(vnode.isStatic) && |
|
isTrue(oldVnode.isStatic) && |
|
vnode.key === oldVnode.key && |
|
(isTrue(vnode.isCloned) || isTrue(vnode.isOnce)) |
|
) { |
|
vnode.componentInstance = oldVnode.componentInstance; |
|
return |
|
} |
|
|
|
var i; |
|
var data = vnode.data; |
|
if (isDef(data) && isDef(i = data.hook) && isDef(i = i.prepatch)) { |
|
i(oldVnode, vnode); |
|
} |
|
|
|
var oldCh = oldVnode.children; |
|
var ch = vnode.children; |
|
if (isDef(data) && isPatchable(vnode)) { |
|
for (i = 0; i < cbs.update.length; ++i) { cbs.update[i](oldVnode, vnode); } |
|
if (isDef(i = data.hook) && isDef(i = i.update)) { i(oldVnode, vnode); } |
|
} |
|
if (isUndef(vnode.text)) { |
|
if (isDef(oldCh) && isDef(ch)) { |
|
if (oldCh !== ch) { updateChildren(elm, oldCh, ch, insertedVnodeQueue, removeOnly); } |
|
} else if (isDef(ch)) { |
|
if (isDef(oldVnode.text)) { nodeOps.setTextContent(elm, ''); } |
|
addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue); |
|
} else if (isDef(oldCh)) { |
|
removeVnodes(elm, oldCh, 0, oldCh.length - 1); |
|
} else if (isDef(oldVnode.text)) { |
|
nodeOps.setTextContent(elm, ''); |
|
} |
|
} else if (oldVnode.text !== vnode.text) { |
|
nodeOps.setTextContent(elm, vnode.text); |
|
} |
|
if (isDef(data)) { |
|
if (isDef(i = data.hook) && isDef(i = i.postpatch)) { i(oldVnode, vnode); } |
|
} |
|
} |
|
|
|
function invokeInsertHook (vnode, queue, initial) { |
|
// delay insert hooks for component root nodes, invoke them after the |
|
// element is really inserted |
|
if (isTrue(initial) && isDef(vnode.parent)) { |
|
vnode.parent.data.pendingInsert = queue; |
|
} else { |
|
for (var i = 0; i < queue.length; ++i) { |
|
queue[i].data.hook.insert(queue[i]); |
|
} |
|
} |
|
} |
|
|
|
var hydrationBailed = false; |
|
// list of modules that can skip create hook during hydration because they |
|
// are already rendered on the client or has no need for initialization |
|
// Note: style is excluded because it relies on initial clone for future |
|
// deep updates (#7063). |
|
var isRenderedModule = makeMap('attrs,class,staticClass,staticStyle,key'); |
|
|
|
// Note: this is a browser-only function so we can assume elms are DOM nodes. |
|
function hydrate (elm, vnode, insertedVnodeQueue, inVPre) { |
|
var i; |
|
var tag = vnode.tag; |
|
var data = vnode.data; |
|
var children = vnode.children; |
|
inVPre = inVPre || (data && data.pre); |
|
vnode.elm = elm; |
|
|
|
if (isTrue(vnode.isComment) && isDef(vnode.asyncFactory)) { |
|
vnode.isAsyncPlaceholder = true; |
|
return true |
|
} |
|
// assert node match |
|
if (true) { |
|
if (!assertNodeMatch(elm, vnode, inVPre)) { |
|
return false |
|
} |
|
} |
|
if (isDef(data)) { |
|
if (isDef(i = data.hook) && isDef(i = i.init)) { i(vnode, true /* hydrating */); } |
|
if (isDef(i = vnode.componentInstance)) { |
|
// child component. it should have hydrated its own tree. |
|
initComponent(vnode, insertedVnodeQueue); |
|
return true |
|
} |
|
} |
|
if (isDef(tag)) { |
|
if (isDef(children)) { |
|
// empty element, allow client to pick up and populate children |
|
if (!elm.hasChildNodes()) { |
|
createChildren(vnode, children, insertedVnodeQueue); |
|
} else { |
|
// v-html and domProps: innerHTML |
|
if (isDef(i = data) && isDef(i = i.domProps) && isDef(i = i.innerHTML)) { |
|
if (i !== elm.innerHTML) { |
|
/* istanbul ignore if */ |
|
if ("development" !== 'production' && |
|
typeof console !== 'undefined' && |
|
!hydrationBailed |
|
) { |
|
hydrationBailed = true; |
|
console.warn('Parent: ', elm); |
|
console.warn('server innerHTML: ', i); |
|
console.warn('client innerHTML: ', elm.innerHTML); |
|
} |
|
return false |
|
} |
|
} else { |
|
// iterate and compare children lists |
|
var childrenMatch = true; |
|
var childNode = elm.firstChild; |
|
for (var i$1 = 0; i$1 < children.length; i$1++) { |
|
if (!childNode || !hydrate(childNode, children[i$1], insertedVnodeQueue, inVPre)) { |
|
childrenMatch = false; |
|
break |
|
} |
|
childNode = childNode.nextSibling; |
|
} |
|
// if childNode is not null, it means the actual childNodes list is |
|
// longer than the virtual children list. |
|
if (!childrenMatch || childNode) { |
|
/* istanbul ignore if */ |
|
if ("development" !== 'production' && |
|
typeof console !== 'undefined' && |
|
!hydrationBailed |
|
) { |
|
hydrationBailed = true; |
|
console.warn('Parent: ', elm); |
|
console.warn('Mismatching childNodes vs. VNodes: ', elm.childNodes, children); |
|
} |
|
return false |
|
} |
|
} |
|
} |
|
} |
|
if (isDef(data)) { |
|
var fullInvoke = false; |
|
for (var key in data) { |
|
if (!isRenderedModule(key)) { |
|
fullInvoke = true; |
|
invokeCreateHooks(vnode, insertedVnodeQueue); |
|
break |
|
} |
|
} |
|
if (!fullInvoke && data['class']) { |
|
// ensure collecting deps for deep class bindings for future updates |
|
traverse(data['class']); |
|
} |
|
} |
|
} else if (elm.data !== vnode.text) { |
|
elm.data = vnode.text; |
|
} |
|
return true |
|
} |
|
|
|
function assertNodeMatch (node, vnode, inVPre) { |
|
if (isDef(vnode.tag)) { |
|
return vnode.tag.indexOf('vue-component') === 0 || ( |
|
!isUnknownElement$$1(vnode, inVPre) && |
|
vnode.tag.toLowerCase() === (node.tagName && node.tagName.toLowerCase()) |
|
) |
|
} else { |
|
return node.nodeType === (vnode.isComment ? 8 : 3) |
|
} |
|
} |
|
|
|
return function patch (oldVnode, vnode, hydrating, removeOnly, parentElm, refElm) { |
|
if (isUndef(vnode)) { |
|
if (isDef(oldVnode)) { invokeDestroyHook(oldVnode); } |
|
return |
|
} |
|
|
|
var isInitialPatch = false; |
|
var insertedVnodeQueue = []; |
|
|
|
if (isUndef(oldVnode)) { |
|
// empty mount (likely as component), create new root element |
|
isInitialPatch = true; |
|
createElm(vnode, insertedVnodeQueue, parentElm, refElm); |
|
} else { |
|
var isRealElement = isDef(oldVnode.nodeType); |
|
if (!isRealElement && sameVnode(oldVnode, vnode)) { |
|
// patch existing root node |
|
patchVnode(oldVnode, vnode, insertedVnodeQueue, removeOnly); |
|
} else { |
|
if (isRealElement) { |
|
// mounting to a real element |
|
// check if this is server-rendered content and if we can perform |
|
// a successful hydration. |
|
if (oldVnode.nodeType === 1 && oldVnode.hasAttribute(SSR_ATTR)) { |
|
oldVnode.removeAttribute(SSR_ATTR); |
|
hydrating = true; |
|
} |
|
if (isTrue(hydrating)) { |
|
if (hydrate(oldVnode, vnode, insertedVnodeQueue)) { |
|
invokeInsertHook(vnode, insertedVnodeQueue, true); |
|
return oldVnode |
|
} else if (true) { |
|
warn( |
|
'The client-side rendered virtual DOM tree is not matching ' + |
|
'server-rendered content. This is likely caused by incorrect ' + |
|
'HTML markup, for example nesting block-level elements inside ' + |
|
'<p>, or missing <tbody>. Bailing hydration and performing ' + |
|
'full client-side render.' |
|
); |
|
} |
|
} |
|
// either not server-rendered, or hydration failed. |
|
// create an empty node and replace it |
|
oldVnode = emptyNodeAt(oldVnode); |
|
} |
|
|
|
// replacing existing element |
|
var oldElm = oldVnode.elm; |
|
var parentElm$1 = nodeOps.parentNode(oldElm); |
|
|
|
// create new node |
|
createElm( |
|
vnode, |
|
insertedVnodeQueue, |
|
// extremely rare edge case: do not insert if old element is in a |
|
// leaving transition. Only happens when combining transition + |
|
// keep-alive + HOCs. (#4590) |
|
oldElm._leaveCb ? null : parentElm$1, |
|
nodeOps.nextSibling(oldElm) |
|
); |
|
|
|
// update parent placeholder node element, recursively |
|
if (isDef(vnode.parent)) { |
|
var ancestor = vnode.parent; |
|
var patchable = isPatchable(vnode); |
|
while (ancestor) { |
|
for (var i = 0; i < cbs.destroy.length; ++i) { |
|
cbs.destroy[i](ancestor); |
|
} |
|
ancestor.elm = vnode.elm; |
|
if (patchable) { |
|
for (var i$1 = 0; i$1 < cbs.create.length; ++i$1) { |
|
cbs.create[i$1](emptyNode, ancestor); |
|
} |
|
// #6513 |
|
// invoke insert hooks that may have been merged by create hooks. |
|
// e.g. for directives that uses the "inserted" hook. |
|
var insert = ancestor.data.hook.insert; |
|
if (insert.merged) { |
|
// start at index 1 to avoid re-invoking component mounted hook |
|
for (var i$2 = 1; i$2 < insert.fns.length; i$2++) { |
|
insert.fns[i$2](); |
|
} |
|
} |
|
} else { |
|
registerRef(ancestor); |
|
} |
|
ancestor = ancestor.parent; |
|
} |
|
} |
|
|
|
// destroy old node |
|
if (isDef(parentElm$1)) { |
|
removeVnodes(parentElm$1, [oldVnode], 0, 0); |
|
} else if (isDef(oldVnode.tag)) { |
|
invokeDestroyHook(oldVnode); |
|
} |
|
} |
|
} |
|
|
|
invokeInsertHook(vnode, insertedVnodeQueue, isInitialPatch); |
|
return vnode.elm |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
var directives = { |
|
create: updateDirectives, |
|
update: updateDirectives, |
|
destroy: function unbindDirectives (vnode) { |
|
updateDirectives(vnode, emptyNode); |
|
} |
|
} |
|
|
|
function updateDirectives (oldVnode, vnode) { |
|
if (oldVnode.data.directives || vnode.data.directives) { |
|
_update(oldVnode, vnode); |
|
} |
|
} |
|
|
|
function _update (oldVnode, vnode) { |
|
var isCreate = oldVnode === emptyNode; |
|
var isDestroy = vnode === emptyNode; |
|
var oldDirs = normalizeDirectives$1(oldVnode.data.directives, oldVnode.context); |
|
var newDirs = normalizeDirectives$1(vnode.data.directives, vnode.context); |
|
|
|
var dirsWithInsert = []; |
|
var dirsWithPostpatch = []; |
|
|
|
var key, oldDir, dir; |
|
for (key in newDirs) { |
|
oldDir = oldDirs[key]; |
|
dir = newDirs[key]; |
|
if (!oldDir) { |
|
// new directive, bind |
|
callHook$1(dir, 'bind', vnode, oldVnode); |
|
if (dir.def && dir.def.inserted) { |
|
dirsWithInsert.push(dir); |
|
} |
|
} else { |
|
// existing directive, update |
|
dir.oldValue = oldDir.value; |
|
callHook$1(dir, 'update', vnode, oldVnode); |
|
if (dir.def && dir.def.componentUpdated) { |
|
dirsWithPostpatch.push(dir); |
|
} |
|
} |
|
} |
|
|
|
if (dirsWithInsert.length) { |
|
var callInsert = function () { |
|
for (var i = 0; i < dirsWithInsert.length; i++) { |
|
callHook$1(dirsWithInsert[i], 'inserted', vnode, oldVnode); |
|
} |
|
}; |
|
if (isCreate) { |
|
mergeVNodeHook(vnode, 'insert', callInsert); |
|
} else { |
|
callInsert(); |
|
} |
|
} |
|
|
|
if (dirsWithPostpatch.length) { |
|
mergeVNodeHook(vnode, 'postpatch', function () { |
|
for (var i = 0; i < dirsWithPostpatch.length; i++) { |
|
callHook$1(dirsWithPostpatch[i], 'componentUpdated', vnode, oldVnode); |
|
} |
|
}); |
|
} |
|
|
|
if (!isCreate) { |
|
for (key in oldDirs) { |
|
if (!newDirs[key]) { |
|
// no longer present, unbind |
|
callHook$1(oldDirs[key], 'unbind', oldVnode, oldVnode, isDestroy); |
|
} |
|
} |
|
} |
|
} |
|
|
|
var emptyModifiers = Object.create(null); |
|
|
|
function normalizeDirectives$1 ( |
|
dirs, |
|
vm |
|
) { |
|
var res = Object.create(null); |
|
if (!dirs) { |
|
// $flow-disable-line |
|
return res |
|
} |
|
var i, dir; |
|
for (i = 0; i < dirs.length; i++) { |
|
dir = dirs[i]; |
|
if (!dir.modifiers) { |
|
// $flow-disable-line |
|
dir.modifiers = emptyModifiers; |
|
} |
|
res[getRawDirName(dir)] = dir; |
|
dir.def = resolveAsset(vm.$options, 'directives', dir.name, true); |
|
} |
|
// $flow-disable-line |
|
return res |
|
} |
|
|
|
function getRawDirName (dir) { |
|
return dir.rawName || ((dir.name) + "." + (Object.keys(dir.modifiers || {}).join('.'))) |
|
} |
|
|
|
function callHook$1 (dir, hook, vnode, oldVnode, isDestroy) { |
|
var fn = dir.def && dir.def[hook]; |
|
if (fn) { |
|
try { |
|
fn(vnode.elm, dir, vnode, oldVnode, isDestroy); |
|
} catch (e) { |
|
handleError(e, vnode.context, ("directive " + (dir.name) + " " + hook + " hook")); |
|
} |
|
} |
|
} |
|
|
|
var baseModules = [ |
|
ref, |
|
directives |
|
] |
|
|
|
/* */ |
|
|
|
function updateAttrs (oldVnode, vnode) { |
|
var opts = vnode.componentOptions; |
|
if (isDef(opts) && opts.Ctor.options.inheritAttrs === false) { |
|
return |
|
} |
|
if (isUndef(oldVnode.data.attrs) && isUndef(vnode.data.attrs)) { |
|
return |
|
} |
|
var key, cur, old; |
|
var elm = vnode.elm; |
|
var oldAttrs = oldVnode.data.attrs || {}; |
|
var attrs = vnode.data.attrs || {}; |
|
// clone observed objects, as the user probably wants to mutate it |
|
if (isDef(attrs.__ob__)) { |
|
attrs = vnode.data.attrs = extend({}, attrs); |
|
} |
|
|
|
for (key in attrs) { |
|
cur = attrs[key]; |
|
old = oldAttrs[key]; |
|
if (old !== cur) { |
|
setAttr(elm, key, cur); |
|
} |
|
} |
|
// #4391: in IE9, setting type can reset value for input[type=radio] |
|
// #6666: IE/Edge forces progress value down to 1 before setting a max |
|
/* istanbul ignore if */ |
|
if ((isIE || isEdge) && attrs.value !== oldAttrs.value) { |
|
setAttr(elm, 'value', attrs.value); |
|
} |
|
for (key in oldAttrs) { |
|
if (isUndef(attrs[key])) { |
|
if (isXlink(key)) { |
|
elm.removeAttributeNS(xlinkNS, getXlinkProp(key)); |
|
} else if (!isEnumeratedAttr(key)) { |
|
elm.removeAttribute(key); |
|
} |
|
} |
|
} |
|
} |
|
|
|
function setAttr (el, key, value) { |
|
if (el.tagName.indexOf('-') > -1) { |
|
baseSetAttr(el, key, value); |
|
} else if (isBooleanAttr(key)) { |
|
// set attribute for blank value |
|
// e.g. <option disabled>Select one</option> |
|
if (isFalsyAttrValue(value)) { |
|
el.removeAttribute(key); |
|
} else { |
|
// technically allowfullscreen is a boolean attribute for <iframe>, |
|
// but Flash expects a value of "true" when used on <embed> tag |
|
value = key === 'allowfullscreen' && el.tagName === 'EMBED' |
|
? 'true' |
|
: key; |
|
el.setAttribute(key, value); |
|
} |
|
} else if (isEnumeratedAttr(key)) { |
|
el.setAttribute(key, isFalsyAttrValue(value) || value === 'false' ? 'false' : 'true'); |
|
} else if (isXlink(key)) { |
|
if (isFalsyAttrValue(value)) { |
|
el.removeAttributeNS(xlinkNS, getXlinkProp(key)); |
|
} else { |
|
el.setAttributeNS(xlinkNS, key, value); |
|
} |
|
} else { |
|
baseSetAttr(el, key, value); |
|
} |
|
} |
|
|
|
function baseSetAttr (el, key, value) { |
|
if (isFalsyAttrValue(value)) { |
|
el.removeAttribute(key); |
|
} else { |
|
// #7138: IE10 & 11 fires input event when setting placeholder on |
|
// <textarea>... block the first input event and remove the blocker |
|
// immediately. |
|
/* istanbul ignore if */ |
|
if ( |
|
isIE && !isIE9 && |
|
el.tagName === 'TEXTAREA' && |
|
key === 'placeholder' && !el.__ieph |
|
) { |
|
var blocker = function (e) { |
|
e.stopImmediatePropagation(); |
|
el.removeEventListener('input', blocker); |
|
}; |
|
el.addEventListener('input', blocker); |
|
// $flow-disable-line |
|
el.__ieph = true; /* IE placeholder patched */ |
|
} |
|
el.setAttribute(key, value); |
|
} |
|
} |
|
|
|
var attrs = { |
|
create: updateAttrs, |
|
update: updateAttrs |
|
} |
|
|
|
/* */ |
|
|
|
function updateClass (oldVnode, vnode) { |
|
var el = vnode.elm; |
|
var data = vnode.data; |
|
var oldData = oldVnode.data; |
|
if ( |
|
isUndef(data.staticClass) && |
|
isUndef(data.class) && ( |
|
isUndef(oldData) || ( |
|
isUndef(oldData.staticClass) && |
|
isUndef(oldData.class) |
|
) |
|
) |
|
) { |
|
return |
|
} |
|
|
|
var cls = genClassForVnode(vnode); |
|
|
|
// handle transition classes |
|
var transitionClass = el._transitionClasses; |
|
if (isDef(transitionClass)) { |
|
cls = concat(cls, stringifyClass(transitionClass)); |
|
} |
|
|
|
// set the class |
|
if (cls !== el._prevClass) { |
|
el.setAttribute('class', cls); |
|
el._prevClass = cls; |
|
} |
|
} |
|
|
|
var klass = { |
|
create: updateClass, |
|
update: updateClass |
|
} |
|
|
|
/* */ |
|
|
|
var validDivisionCharRE = /[\w).+\-_$\]]/; |
|
|
|
function parseFilters (exp) { |
|
var inSingle = false; |
|
var inDouble = false; |
|
var inTemplateString = false; |
|
var inRegex = false; |
|
var curly = 0; |
|
var square = 0; |
|
var paren = 0; |
|
var lastFilterIndex = 0; |
|
var c, prev, i, expression, filters; |
|
|
|
for (i = 0; i < exp.length; i++) { |
|
prev = c; |
|
c = exp.charCodeAt(i); |
|
if (inSingle) { |
|
if (c === 0x27 && prev !== 0x5C) { inSingle = false; } |
|
} else if (inDouble) { |
|
if (c === 0x22 && prev !== 0x5C) { inDouble = false; } |
|
} else if (inTemplateString) { |
|
if (c === 0x60 && prev !== 0x5C) { inTemplateString = false; } |
|
} else if (inRegex) { |
|
if (c === 0x2f && prev !== 0x5C) { inRegex = false; } |
|
} else if ( |
|
c === 0x7C && // pipe |
|
exp.charCodeAt(i + 1) !== 0x7C && |
|
exp.charCodeAt(i - 1) !== 0x7C && |
|
!curly && !square && !paren |
|
) { |
|
if (expression === undefined) { |
|
// first filter, end of expression |
|
lastFilterIndex = i + 1; |
|
expression = exp.slice(0, i).trim(); |
|
} else { |
|
pushFilter(); |
|
} |
|
} else { |
|
switch (c) { |
|
case 0x22: inDouble = true; break // " |
|
case 0x27: inSingle = true; break // ' |
|
case 0x60: inTemplateString = true; break // ` |
|
case 0x28: paren++; break // ( |
|
case 0x29: paren--; break // ) |
|
case 0x5B: square++; break // [ |
|
case 0x5D: square--; break // ] |
|
case 0x7B: curly++; break // { |
|
case 0x7D: curly--; break // } |
|
} |
|
if (c === 0x2f) { // / |
|
var j = i - 1; |
|
var p = (void 0); |
|
// find first non-whitespace prev char |
|
for (; j >= 0; j--) { |
|
p = exp.charAt(j); |
|
if (p !== ' ') { break } |
|
} |
|
if (!p || !validDivisionCharRE.test(p)) { |
|
inRegex = true; |
|
} |
|
} |
|
} |
|
} |
|
|
|
if (expression === undefined) { |
|
expression = exp.slice(0, i).trim(); |
|
} else if (lastFilterIndex !== 0) { |
|
pushFilter(); |
|
} |
|
|
|
function pushFilter () { |
|
(filters || (filters = [])).push(exp.slice(lastFilterIndex, i).trim()); |
|
lastFilterIndex = i + 1; |
|
} |
|
|
|
if (filters) { |
|
for (i = 0; i < filters.length; i++) { |
|
expression = wrapFilter(expression, filters[i]); |
|
} |
|
} |
|
|
|
return expression |
|
} |
|
|
|
function wrapFilter (exp, filter) { |
|
var i = filter.indexOf('('); |
|
if (i < 0) { |
|
// _f: resolveFilter |
|
return ("_f(\"" + filter + "\")(" + exp + ")") |
|
} else { |
|
var name = filter.slice(0, i); |
|
var args = filter.slice(i + 1); |
|
return ("_f(\"" + name + "\")(" + exp + (args !== ')' ? ',' + args : args)) |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
function baseWarn (msg) { |
|
console.error(("[Vue compiler]: " + msg)); |
|
} |
|
|
|
function pluckModuleFunction ( |
|
modules, |
|
key |
|
) { |
|
return modules |
|
? modules.map(function (m) { return m[key]; }).filter(function (_) { return _; }) |
|
: [] |
|
} |
|
|
|
function addProp (el, name, value) { |
|
(el.props || (el.props = [])).push({ name: name, value: value }); |
|
el.plain = false; |
|
} |
|
|
|
function addAttr (el, name, value) { |
|
(el.attrs || (el.attrs = [])).push({ name: name, value: value }); |
|
el.plain = false; |
|
} |
|
|
|
// add a raw attr (use this in preTransforms) |
|
function addRawAttr (el, name, value) { |
|
el.attrsMap[name] = value; |
|
el.attrsList.push({ name: name, value: value }); |
|
} |
|
|
|
function addDirective ( |
|
el, |
|
name, |
|
rawName, |
|
value, |
|
arg, |
|
modifiers |
|
) { |
|
(el.directives || (el.directives = [])).push({ name: name, rawName: rawName, value: value, arg: arg, modifiers: modifiers }); |
|
el.plain = false; |
|
} |
|
|
|
function addHandler ( |
|
el, |
|
name, |
|
value, |
|
modifiers, |
|
important, |
|
warn |
|
) { |
|
modifiers = modifiers || emptyObject; |
|
// warn prevent and passive modifier |
|
/* istanbul ignore if */ |
|
if ( |
|
"development" !== 'production' && warn && |
|
modifiers.prevent && modifiers.passive |
|
) { |
|
warn( |
|
'passive and prevent can\'t be used together. ' + |
|
'Passive handler can\'t prevent default event.' |
|
); |
|
} |
|
|
|
// check capture modifier |
|
if (modifiers.capture) { |
|
delete modifiers.capture; |
|
name = '!' + name; // mark the event as captured |
|
} |
|
if (modifiers.once) { |
|
delete modifiers.once; |
|
name = '~' + name; // mark the event as once |
|
} |
|
/* istanbul ignore if */ |
|
if (modifiers.passive) { |
|
delete modifiers.passive; |
|
name = '&' + name; // mark the event as passive |
|
} |
|
|
|
// normalize click.right and click.middle since they don't actually fire |
|
// this is technically browser-specific, but at least for now browsers are |
|
// the only target envs that have right/middle clicks. |
|
if (name === 'click') { |
|
if (modifiers.right) { |
|
name = 'contextmenu'; |
|
delete modifiers.right; |
|
} else if (modifiers.middle) { |
|
name = 'mouseup'; |
|
} |
|
} |
|
|
|
var events; |
|
if (modifiers.native) { |
|
delete modifiers.native; |
|
events = el.nativeEvents || (el.nativeEvents = {}); |
|
} else { |
|
events = el.events || (el.events = {}); |
|
} |
|
|
|
var newHandler = { |
|
value: value.trim() |
|
}; |
|
if (modifiers !== emptyObject) { |
|
newHandler.modifiers = modifiers; |
|
} |
|
|
|
var handlers = events[name]; |
|
/* istanbul ignore if */ |
|
if (Array.isArray(handlers)) { |
|
important ? handlers.unshift(newHandler) : handlers.push(newHandler); |
|
} else if (handlers) { |
|
events[name] = important ? [newHandler, handlers] : [handlers, newHandler]; |
|
} else { |
|
events[name] = newHandler; |
|
} |
|
|
|
el.plain = false; |
|
} |
|
|
|
function getBindingAttr ( |
|
el, |
|
name, |
|
getStatic |
|
) { |
|
var dynamicValue = |
|
getAndRemoveAttr(el, ':' + name) || |
|
getAndRemoveAttr(el, 'v-bind:' + name); |
|
if (dynamicValue != null) { |
|
return parseFilters(dynamicValue) |
|
} else if (getStatic !== false) { |
|
var staticValue = getAndRemoveAttr(el, name); |
|
if (staticValue != null) { |
|
return JSON.stringify(staticValue) |
|
} |
|
} |
|
} |
|
|
|
// note: this only removes the attr from the Array (attrsList) so that it |
|
// doesn't get processed by processAttrs. |
|
// By default it does NOT remove it from the map (attrsMap) because the map is |
|
// needed during codegen. |
|
function getAndRemoveAttr ( |
|
el, |
|
name, |
|
removeFromMap |
|
) { |
|
var val; |
|
if ((val = el.attrsMap[name]) != null) { |
|
var list = el.attrsList; |
|
for (var i = 0, l = list.length; i < l; i++) { |
|
if (list[i].name === name) { |
|
list.splice(i, 1); |
|
break |
|
} |
|
} |
|
} |
|
if (removeFromMap) { |
|
delete el.attrsMap[name]; |
|
} |
|
return val |
|
} |
|
|
|
/* */ |
|
|
|
/** |
|
* Cross-platform code generation for component v-model |
|
*/ |
|
function genComponentModel ( |
|
el, |
|
value, |
|
modifiers |
|
) { |
|
var ref = modifiers || {}; |
|
var number = ref.number; |
|
var trim = ref.trim; |
|
|
|
var baseValueExpression = '$$v'; |
|
var valueExpression = baseValueExpression; |
|
if (trim) { |
|
valueExpression = |
|
"(typeof " + baseValueExpression + " === 'string'" + |
|
"? " + baseValueExpression + ".trim()" + |
|
": " + baseValueExpression + ")"; |
|
} |
|
if (number) { |
|
valueExpression = "_n(" + valueExpression + ")"; |
|
} |
|
var assignment = genAssignmentCode(value, valueExpression); |
|
|
|
el.model = { |
|
value: ("(" + value + ")"), |
|
expression: ("\"" + value + "\""), |
|
callback: ("function (" + baseValueExpression + ") {" + assignment + "}") |
|
}; |
|
} |
|
|
|
/** |
|
* Cross-platform codegen helper for generating v-model value assignment code. |
|
*/ |
|
function genAssignmentCode ( |
|
value, |
|
assignment |
|
) { |
|
var res = parseModel(value); |
|
if (res.key === null) { |
|
return (value + "=" + assignment) |
|
} else { |
|
return ("$set(" + (res.exp) + ", " + (res.key) + ", " + assignment + ")") |
|
} |
|
} |
|
|
|
/** |
|
* Parse a v-model expression into a base path and a final key segment. |
|
* Handles both dot-path and possible square brackets. |
|
* |
|
* Possible cases: |
|
* |
|
* - test |
|
* - test[key] |
|
* - test[test1[key]] |
|
* - test["a"][key] |
|
* - xxx.test[a[a].test1[key]] |
|
* - test.xxx.a["asa"][test1[key]] |
|
* |
|
*/ |
|
|
|
var len; |
|
var str; |
|
var chr; |
|
var index$1; |
|
var expressionPos; |
|
var expressionEndPos; |
|
|
|
|
|
|
|
function parseModel (val) { |
|
// Fix https://github.com/vuejs/vue/pull/7730 |
|
// allow v-model="obj.val " (trailing whitespace) |
|
val = val.trim(); |
|
len = val.length; |
|
|
|
if (val.indexOf('[') < 0 || val.lastIndexOf(']') < len - 1) { |
|
index$1 = val.lastIndexOf('.'); |
|
if (index$1 > -1) { |
|
return { |
|
exp: val.slice(0, index$1), |
|
key: '"' + val.slice(index$1 + 1) + '"' |
|
} |
|
} else { |
|
return { |
|
exp: val, |
|
key: null |
|
} |
|
} |
|
} |
|
|
|
str = val; |
|
index$1 = expressionPos = expressionEndPos = 0; |
|
|
|
while (!eof()) { |
|
chr = next(); |
|
/* istanbul ignore if */ |
|
if (isStringStart(chr)) { |
|
parseString(chr); |
|
} else if (chr === 0x5B) { |
|
parseBracket(chr); |
|
} |
|
} |
|
|
|
return { |
|
exp: val.slice(0, expressionPos), |
|
key: val.slice(expressionPos + 1, expressionEndPos) |
|
} |
|
} |
|
|
|
function next () { |
|
return str.charCodeAt(++index$1) |
|
} |
|
|
|
function eof () { |
|
return index$1 >= len |
|
} |
|
|
|
function isStringStart (chr) { |
|
return chr === 0x22 || chr === 0x27 |
|
} |
|
|
|
function parseBracket (chr) { |
|
var inBracket = 1; |
|
expressionPos = index$1; |
|
while (!eof()) { |
|
chr = next(); |
|
if (isStringStart(chr)) { |
|
parseString(chr); |
|
continue |
|
} |
|
if (chr === 0x5B) { inBracket++; } |
|
if (chr === 0x5D) { inBracket--; } |
|
if (inBracket === 0) { |
|
expressionEndPos = index$1; |
|
break |
|
} |
|
} |
|
} |
|
|
|
function parseString (chr) { |
|
var stringQuote = chr; |
|
while (!eof()) { |
|
chr = next(); |
|
if (chr === stringQuote) { |
|
break |
|
} |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
var warn$1; |
|
|
|
// in some cases, the event used has to be determined at runtime |
|
// so we used some reserved tokens during compile. |
|
var RANGE_TOKEN = '__r'; |
|
var CHECKBOX_RADIO_TOKEN = '__c'; |
|
|
|
function model ( |
|
el, |
|
dir, |
|
_warn |
|
) { |
|
warn$1 = _warn; |
|
var value = dir.value; |
|
var modifiers = dir.modifiers; |
|
var tag = el.tag; |
|
var type = el.attrsMap.type; |
|
|
|
if (true) { |
|
// inputs with type="file" are read only and setting the input's |
|
// value will throw an error. |
|
if (tag === 'input' && type === 'file') { |
|
warn$1( |
|
"<" + (el.tag) + " v-model=\"" + value + "\" type=\"file\">:\n" + |
|
"File inputs are read only. Use a v-on:change listener instead." |
|
); |
|
} |
|
} |
|
|
|
if (el.component) { |
|
genComponentModel(el, value, modifiers); |
|
// component v-model doesn't need extra runtime |
|
return false |
|
} else if (tag === 'select') { |
|
genSelect(el, value, modifiers); |
|
} else if (tag === 'input' && type === 'checkbox') { |
|
genCheckboxModel(el, value, modifiers); |
|
} else if (tag === 'input' && type === 'radio') { |
|
genRadioModel(el, value, modifiers); |
|
} else if (tag === 'input' || tag === 'textarea') { |
|
genDefaultModel(el, value, modifiers); |
|
} else if (!config.isReservedTag(tag)) { |
|
genComponentModel(el, value, modifiers); |
|
// component v-model doesn't need extra runtime |
|
return false |
|
} else if (true) { |
|
warn$1( |
|
"<" + (el.tag) + " v-model=\"" + value + "\">: " + |
|
"v-model is not supported on this element type. " + |
|
'If you are working with contenteditable, it\'s recommended to ' + |
|
'wrap a library dedicated for that purpose inside a custom component.' |
|
); |
|
} |
|
|
|
// ensure runtime directive metadata |
|
return true |
|
} |
|
|
|
function genCheckboxModel ( |
|
el, |
|
value, |
|
modifiers |
|
) { |
|
var number = modifiers && modifiers.number; |
|
var valueBinding = getBindingAttr(el, 'value') || 'null'; |
|
var trueValueBinding = getBindingAttr(el, 'true-value') || 'true'; |
|
var falseValueBinding = getBindingAttr(el, 'false-value') || 'false'; |
|
addProp(el, 'checked', |
|
"Array.isArray(" + value + ")" + |
|
"?_i(" + value + "," + valueBinding + ")>-1" + ( |
|
trueValueBinding === 'true' |
|
? (":(" + value + ")") |
|
: (":_q(" + value + "," + trueValueBinding + ")") |
|
) |
|
); |
|
addHandler(el, 'change', |
|
"var $$a=" + value + "," + |
|
'$$el=$event.target,' + |
|
"$$c=$$el.checked?(" + trueValueBinding + "):(" + falseValueBinding + ");" + |
|
'if(Array.isArray($$a)){' + |
|
"var $$v=" + (number ? '_n(' + valueBinding + ')' : valueBinding) + "," + |
|
'$$i=_i($$a,$$v);' + |
|
"if($$el.checked){$$i<0&&(" + (genAssignmentCode(value, '$$a.concat([$$v])')) + ")}" + |
|
"else{$$i>-1&&(" + (genAssignmentCode(value, '$$a.slice(0,$$i).concat($$a.slice($$i+1))')) + ")}" + |
|
"}else{" + (genAssignmentCode(value, '$$c')) + "}", |
|
null, true |
|
); |
|
} |
|
|
|
function genRadioModel ( |
|
el, |
|
value, |
|
modifiers |
|
) { |
|
var number = modifiers && modifiers.number; |
|
var valueBinding = getBindingAttr(el, 'value') || 'null'; |
|
valueBinding = number ? ("_n(" + valueBinding + ")") : valueBinding; |
|
addProp(el, 'checked', ("_q(" + value + "," + valueBinding + ")")); |
|
addHandler(el, 'change', genAssignmentCode(value, valueBinding), null, true); |
|
} |
|
|
|
function genSelect ( |
|
el, |
|
value, |
|
modifiers |
|
) { |
|
var number = modifiers && modifiers.number; |
|
var selectedVal = "Array.prototype.filter" + |
|
".call($event.target.options,function(o){return o.selected})" + |
|
".map(function(o){var val = \"_value\" in o ? o._value : o.value;" + |
|
"return " + (number ? '_n(val)' : 'val') + "})"; |
|
|
|
var assignment = '$event.target.multiple ? $$selectedVal : $$selectedVal[0]'; |
|
var code = "var $$selectedVal = " + selectedVal + ";"; |
|
code = code + " " + (genAssignmentCode(value, assignment)); |
|
addHandler(el, 'change', code, null, true); |
|
} |
|
|
|
function genDefaultModel ( |
|
el, |
|
value, |
|
modifiers |
|
) { |
|
var type = el.attrsMap.type; |
|
|
|
// warn if v-bind:value conflicts with v-model |
|
// except for inputs with v-bind:type |
|
if (true) { |
|
var value$1 = el.attrsMap['v-bind:value'] || el.attrsMap[':value']; |
|
var typeBinding = el.attrsMap['v-bind:type'] || el.attrsMap[':type']; |
|
if (value$1 && !typeBinding) { |
|
var binding = el.attrsMap['v-bind:value'] ? 'v-bind:value' : ':value'; |
|
warn$1( |
|
binding + "=\"" + value$1 + "\" conflicts with v-model on the same element " + |
|
'because the latter already expands to a value binding internally' |
|
); |
|
} |
|
} |
|
|
|
var ref = modifiers || {}; |
|
var lazy = ref.lazy; |
|
var number = ref.number; |
|
var trim = ref.trim; |
|
var needCompositionGuard = !lazy && type !== 'range'; |
|
var event = lazy |
|
? 'change' |
|
: type === 'range' |
|
? RANGE_TOKEN |
|
: 'input'; |
|
|
|
var valueExpression = '$event.target.value'; |
|
if (trim) { |
|
valueExpression = "$event.target.value.trim()"; |
|
} |
|
if (number) { |
|
valueExpression = "_n(" + valueExpression + ")"; |
|
} |
|
|
|
var code = genAssignmentCode(value, valueExpression); |
|
if (needCompositionGuard) { |
|
code = "if($event.target.composing)return;" + code; |
|
} |
|
|
|
addProp(el, 'value', ("(" + value + ")")); |
|
addHandler(el, event, code, null, true); |
|
if (trim || number) { |
|
addHandler(el, 'blur', '$forceUpdate()'); |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
// normalize v-model event tokens that can only be determined at runtime. |
|
// it's important to place the event as the first in the array because |
|
// the whole point is ensuring the v-model callback gets called before |
|
// user-attached handlers. |
|
function normalizeEvents (on) { |
|
/* istanbul ignore if */ |
|
if (isDef(on[RANGE_TOKEN])) { |
|
// IE input[type=range] only supports `change` event |
|
var event = isIE ? 'change' : 'input'; |
|
on[event] = [].concat(on[RANGE_TOKEN], on[event] || []); |
|
delete on[RANGE_TOKEN]; |
|
} |
|
// This was originally intended to fix #4521 but no longer necessary |
|
// after 2.5. Keeping it for backwards compat with generated code from < 2.4 |
|
/* istanbul ignore if */ |
|
if (isDef(on[CHECKBOX_RADIO_TOKEN])) { |
|
on.change = [].concat(on[CHECKBOX_RADIO_TOKEN], on.change || []); |
|
delete on[CHECKBOX_RADIO_TOKEN]; |
|
} |
|
} |
|
|
|
var target$1; |
|
|
|
function createOnceHandler (handler, event, capture) { |
|
var _target = target$1; // save current target element in closure |
|
return function onceHandler () { |
|
var res = handler.apply(null, arguments); |
|
if (res !== null) { |
|
remove$2(event, onceHandler, capture, _target); |
|
} |
|
} |
|
} |
|
|
|
function add$1 ( |
|
event, |
|
handler, |
|
once$$1, |
|
capture, |
|
passive |
|
) { |
|
handler = withMacroTask(handler); |
|
if (once$$1) { handler = createOnceHandler(handler, event, capture); } |
|
target$1.addEventListener( |
|
event, |
|
handler, |
|
supportsPassive |
|
? { capture: capture, passive: passive } |
|
: capture |
|
); |
|
} |
|
|
|
function remove$2 ( |
|
event, |
|
handler, |
|
capture, |
|
_target |
|
) { |
|
(_target || target$1).removeEventListener( |
|
event, |
|
handler._withTask || handler, |
|
capture |
|
); |
|
} |
|
|
|
function updateDOMListeners (oldVnode, vnode) { |
|
if (isUndef(oldVnode.data.on) && isUndef(vnode.data.on)) { |
|
return |
|
} |
|
var on = vnode.data.on || {}; |
|
var oldOn = oldVnode.data.on || {}; |
|
target$1 = vnode.elm; |
|
normalizeEvents(on); |
|
updateListeners(on, oldOn, add$1, remove$2, vnode.context); |
|
target$1 = undefined; |
|
} |
|
|
|
var events = { |
|
create: updateDOMListeners, |
|
update: updateDOMListeners |
|
} |
|
|
|
/* */ |
|
|
|
function updateDOMProps (oldVnode, vnode) { |
|
if (isUndef(oldVnode.data.domProps) && isUndef(vnode.data.domProps)) { |
|
return |
|
} |
|
var key, cur; |
|
var elm = vnode.elm; |
|
var oldProps = oldVnode.data.domProps || {}; |
|
var props = vnode.data.domProps || {}; |
|
// clone observed objects, as the user probably wants to mutate it |
|
if (isDef(props.__ob__)) { |
|
props = vnode.data.domProps = extend({}, props); |
|
} |
|
|
|
for (key in oldProps) { |
|
if (isUndef(props[key])) { |
|
elm[key] = ''; |
|
} |
|
} |
|
for (key in props) { |
|
cur = props[key]; |
|
// ignore children if the node has textContent or innerHTML, |
|
// as these will throw away existing DOM nodes and cause removal errors |
|
// on subsequent patches (#3360) |
|
if (key === 'textContent' || key === 'innerHTML') { |
|
if (vnode.children) { vnode.children.length = 0; } |
|
if (cur === oldProps[key]) { continue } |
|
// #6601 work around Chrome version <= 55 bug where single textNode |
|
// replaced by innerHTML/textContent retains its parentNode property |
|
if (elm.childNodes.length === 1) { |
|
elm.removeChild(elm.childNodes[0]); |
|
} |
|
} |
|
|
|
if (key === 'value') { |
|
// store value as _value as well since |
|
// non-string values will be stringified |
|
elm._value = cur; |
|
// avoid resetting cursor position when value is the same |
|
var strCur = isUndef(cur) ? '' : String(cur); |
|
if (shouldUpdateValue(elm, strCur)) { |
|
elm.value = strCur; |
|
} |
|
} else { |
|
elm[key] = cur; |
|
} |
|
} |
|
} |
|
|
|
// check platforms/web/util/attrs.js acceptValue |
|
|
|
|
|
function shouldUpdateValue (elm, checkVal) { |
|
return (!elm.composing && ( |
|
elm.tagName === 'OPTION' || |
|
isNotInFocusAndDirty(elm, checkVal) || |
|
isDirtyWithModifiers(elm, checkVal) |
|
)) |
|
} |
|
|
|
function isNotInFocusAndDirty (elm, checkVal) { |
|
// return true when textbox (.number and .trim) loses focus and its value is |
|
// not equal to the updated value |
|
var notInFocus = true; |
|
// #6157 |
|
// work around IE bug when accessing document.activeElement in an iframe |
|
try { notInFocus = document.activeElement !== elm; } catch (e) {} |
|
return notInFocus && elm.value !== checkVal |
|
} |
|
|
|
function isDirtyWithModifiers (elm, newVal) { |
|
var value = elm.value; |
|
var modifiers = elm._vModifiers; // injected by v-model runtime |
|
if (isDef(modifiers)) { |
|
if (modifiers.lazy) { |
|
// inputs with lazy should only be updated when not in focus |
|
return false |
|
} |
|
if (modifiers.number) { |
|
return toNumber(value) !== toNumber(newVal) |
|
} |
|
if (modifiers.trim) { |
|
return value.trim() !== newVal.trim() |
|
} |
|
} |
|
return value !== newVal |
|
} |
|
|
|
var domProps = { |
|
create: updateDOMProps, |
|
update: updateDOMProps |
|
} |
|
|
|
/* */ |
|
|
|
var parseStyleText = cached(function (cssText) { |
|
var res = {}; |
|
var listDelimiter = /;(?![^(]*\))/g; |
|
var propertyDelimiter = /:(.+)/; |
|
cssText.split(listDelimiter).forEach(function (item) { |
|
if (item) { |
|
var tmp = item.split(propertyDelimiter); |
|
tmp.length > 1 && (res[tmp[0].trim()] = tmp[1].trim()); |
|
} |
|
}); |
|
return res |
|
}); |
|
|
|
// merge static and dynamic style data on the same vnode |
|
function normalizeStyleData (data) { |
|
var style = normalizeStyleBinding(data.style); |
|
// static style is pre-processed into an object during compilation |
|
// and is always a fresh object, so it's safe to merge into it |
|
return data.staticStyle |
|
? extend(data.staticStyle, style) |
|
: style |
|
} |
|
|
|
// normalize possible array / string values into Object |
|
function normalizeStyleBinding (bindingStyle) { |
|
if (Array.isArray(bindingStyle)) { |
|
return toObject(bindingStyle) |
|
} |
|
if (typeof bindingStyle === 'string') { |
|
return parseStyleText(bindingStyle) |
|
} |
|
return bindingStyle |
|
} |
|
|
|
/** |
|
* parent component style should be after child's |
|
* so that parent component's style could override it |
|
*/ |
|
function getStyle (vnode, checkChild) { |
|
var res = {}; |
|
var styleData; |
|
|
|
if (checkChild) { |
|
var childNode = vnode; |
|
while (childNode.componentInstance) { |
|
childNode = childNode.componentInstance._vnode; |
|
if ( |
|
childNode && childNode.data && |
|
(styleData = normalizeStyleData(childNode.data)) |
|
) { |
|
extend(res, styleData); |
|
} |
|
} |
|
} |
|
|
|
if ((styleData = normalizeStyleData(vnode.data))) { |
|
extend(res, styleData); |
|
} |
|
|
|
var parentNode = vnode; |
|
while ((parentNode = parentNode.parent)) { |
|
if (parentNode.data && (styleData = normalizeStyleData(parentNode.data))) { |
|
extend(res, styleData); |
|
} |
|
} |
|
return res |
|
} |
|
|
|
/* */ |
|
|
|
var cssVarRE = /^--/; |
|
var importantRE = /\s*!important$/; |
|
var setProp = function (el, name, val) { |
|
/* istanbul ignore if */ |
|
if (cssVarRE.test(name)) { |
|
el.style.setProperty(name, val); |
|
} else if (importantRE.test(val)) { |
|
el.style.setProperty(name, val.replace(importantRE, ''), 'important'); |
|
} else { |
|
var normalizedName = normalize(name); |
|
if (Array.isArray(val)) { |
|
// Support values array created by autoprefixer, e.g. |
|
// {display: ["-webkit-box", "-ms-flexbox", "flex"]} |
|
// Set them one by one, and the browser will only set those it can recognize |
|
for (var i = 0, len = val.length; i < len; i++) { |
|
el.style[normalizedName] = val[i]; |
|
} |
|
} else { |
|
el.style[normalizedName] = val; |
|
} |
|
} |
|
}; |
|
|
|
var vendorNames = ['Webkit', 'Moz', 'ms']; |
|
|
|
var emptyStyle; |
|
var normalize = cached(function (prop) { |
|
emptyStyle = emptyStyle || document.createElement('div').style; |
|
prop = camelize(prop); |
|
if (prop !== 'filter' && (prop in emptyStyle)) { |
|
return prop |
|
} |
|
var capName = prop.charAt(0).toUpperCase() + prop.slice(1); |
|
for (var i = 0; i < vendorNames.length; i++) { |
|
var name = vendorNames[i] + capName; |
|
if (name in emptyStyle) { |
|
return name |
|
} |
|
} |
|
}); |
|
|
|
function updateStyle (oldVnode, vnode) { |
|
var data = vnode.data; |
|
var oldData = oldVnode.data; |
|
|
|
if (isUndef(data.staticStyle) && isUndef(data.style) && |
|
isUndef(oldData.staticStyle) && isUndef(oldData.style) |
|
) { |
|
return |
|
} |
|
|
|
var cur, name; |
|
var el = vnode.elm; |
|
var oldStaticStyle = oldData.staticStyle; |
|
var oldStyleBinding = oldData.normalizedStyle || oldData.style || {}; |
|
|
|
// if static style exists, stylebinding already merged into it when doing normalizeStyleData |
|
var oldStyle = oldStaticStyle || oldStyleBinding; |
|
|
|
var style = normalizeStyleBinding(vnode.data.style) || {}; |
|
|
|
// store normalized style under a different key for next diff |
|
// make sure to clone it if it's reactive, since the user likely wants |
|
// to mutate it. |
|
vnode.data.normalizedStyle = isDef(style.__ob__) |
|
? extend({}, style) |
|
: style; |
|
|
|
var newStyle = getStyle(vnode, true); |
|
|
|
for (name in oldStyle) { |
|
if (isUndef(newStyle[name])) { |
|
setProp(el, name, ''); |
|
} |
|
} |
|
for (name in newStyle) { |
|
cur = newStyle[name]; |
|
if (cur !== oldStyle[name]) { |
|
// ie9 setting to null has no effect, must use empty string |
|
setProp(el, name, cur == null ? '' : cur); |
|
} |
|
} |
|
} |
|
|
|
var style = { |
|
create: updateStyle, |
|
update: updateStyle |
|
} |
|
|
|
/* */ |
|
|
|
/** |
|
* Add class with compatibility for SVG since classList is not supported on |
|
* SVG elements in IE |
|
*/ |
|
function addClass (el, cls) { |
|
/* istanbul ignore if */ |
|
if (!cls || !(cls = cls.trim())) { |
|
return |
|
} |
|
|
|
/* istanbul ignore else */ |
|
if (el.classList) { |
|
if (cls.indexOf(' ') > -1) { |
|
cls.split(/\s+/).forEach(function (c) { return el.classList.add(c); }); |
|
} else { |
|
el.classList.add(cls); |
|
} |
|
} else { |
|
var cur = " " + (el.getAttribute('class') || '') + " "; |
|
if (cur.indexOf(' ' + cls + ' ') < 0) { |
|
el.setAttribute('class', (cur + cls).trim()); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* Remove class with compatibility for SVG since classList is not supported on |
|
* SVG elements in IE |
|
*/ |
|
function removeClass (el, cls) { |
|
/* istanbul ignore if */ |
|
if (!cls || !(cls = cls.trim())) { |
|
return |
|
} |
|
|
|
/* istanbul ignore else */ |
|
if (el.classList) { |
|
if (cls.indexOf(' ') > -1) { |
|
cls.split(/\s+/).forEach(function (c) { return el.classList.remove(c); }); |
|
} else { |
|
el.classList.remove(cls); |
|
} |
|
if (!el.classList.length) { |
|
el.removeAttribute('class'); |
|
} |
|
} else { |
|
var cur = " " + (el.getAttribute('class') || '') + " "; |
|
var tar = ' ' + cls + ' '; |
|
while (cur.indexOf(tar) >= 0) { |
|
cur = cur.replace(tar, ' '); |
|
} |
|
cur = cur.trim(); |
|
if (cur) { |
|
el.setAttribute('class', cur); |
|
} else { |
|
el.removeAttribute('class'); |
|
} |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
function resolveTransition (def) { |
|
if (!def) { |
|
return |
|
} |
|
/* istanbul ignore else */ |
|
if (typeof def === 'object') { |
|
var res = {}; |
|
if (def.css !== false) { |
|
extend(res, autoCssTransition(def.name || 'v')); |
|
} |
|
extend(res, def); |
|
return res |
|
} else if (typeof def === 'string') { |
|
return autoCssTransition(def) |
|
} |
|
} |
|
|
|
var autoCssTransition = cached(function (name) { |
|
return { |
|
enterClass: (name + "-enter"), |
|
enterToClass: (name + "-enter-to"), |
|
enterActiveClass: (name + "-enter-active"), |
|
leaveClass: (name + "-leave"), |
|
leaveToClass: (name + "-leave-to"), |
|
leaveActiveClass: (name + "-leave-active") |
|
} |
|
}); |
|
|
|
var hasTransition = inBrowser && !isIE9; |
|
var TRANSITION = 'transition'; |
|
var ANIMATION = 'animation'; |
|
|
|
// Transition property/event sniffing |
|
var transitionProp = 'transition'; |
|
var transitionEndEvent = 'transitionend'; |
|
var animationProp = 'animation'; |
|
var animationEndEvent = 'animationend'; |
|
if (hasTransition) { |
|
/* istanbul ignore if */ |
|
if (window.ontransitionend === undefined && |
|
window.onwebkittransitionend !== undefined |
|
) { |
|
transitionProp = 'WebkitTransition'; |
|
transitionEndEvent = 'webkitTransitionEnd'; |
|
} |
|
if (window.onanimationend === undefined && |
|
window.onwebkitanimationend !== undefined |
|
) { |
|
animationProp = 'WebkitAnimation'; |
|
animationEndEvent = 'webkitAnimationEnd'; |
|
} |
|
} |
|
|
|
// binding to window is necessary to make hot reload work in IE in strict mode |
|
var raf = inBrowser |
|
? window.requestAnimationFrame |
|
? window.requestAnimationFrame.bind(window) |
|
: setTimeout |
|
: /* istanbul ignore next */ function (fn) { return fn(); }; |
|
|
|
function nextFrame (fn) { |
|
raf(function () { |
|
raf(fn); |
|
}); |
|
} |
|
|
|
function addTransitionClass (el, cls) { |
|
var transitionClasses = el._transitionClasses || (el._transitionClasses = []); |
|
if (transitionClasses.indexOf(cls) < 0) { |
|
transitionClasses.push(cls); |
|
addClass(el, cls); |
|
} |
|
} |
|
|
|
function removeTransitionClass (el, cls) { |
|
if (el._transitionClasses) { |
|
remove(el._transitionClasses, cls); |
|
} |
|
removeClass(el, cls); |
|
} |
|
|
|
function whenTransitionEnds ( |
|
el, |
|
expectedType, |
|
cb |
|
) { |
|
var ref = getTransitionInfo(el, expectedType); |
|
var type = ref.type; |
|
var timeout = ref.timeout; |
|
var propCount = ref.propCount; |
|
if (!type) { return cb() } |
|
var event = type === TRANSITION ? transitionEndEvent : animationEndEvent; |
|
var ended = 0; |
|
var end = function () { |
|
el.removeEventListener(event, onEnd); |
|
cb(); |
|
}; |
|
var onEnd = function (e) { |
|
if (e.target === el) { |
|
if (++ended >= propCount) { |
|
end(); |
|
} |
|
} |
|
}; |
|
setTimeout(function () { |
|
if (ended < propCount) { |
|
end(); |
|
} |
|
}, timeout + 1); |
|
el.addEventListener(event, onEnd); |
|
} |
|
|
|
var transformRE = /\b(transform|all)(,|$)/; |
|
|
|
function getTransitionInfo (el, expectedType) { |
|
var styles = window.getComputedStyle(el); |
|
var transitionDelays = styles[transitionProp + 'Delay'].split(', '); |
|
var transitionDurations = styles[transitionProp + 'Duration'].split(', '); |
|
var transitionTimeout = getTimeout(transitionDelays, transitionDurations); |
|
var animationDelays = styles[animationProp + 'Delay'].split(', '); |
|
var animationDurations = styles[animationProp + 'Duration'].split(', '); |
|
var animationTimeout = getTimeout(animationDelays, animationDurations); |
|
|
|
var type; |
|
var timeout = 0; |
|
var propCount = 0; |
|
/* istanbul ignore if */ |
|
if (expectedType === TRANSITION) { |
|
if (transitionTimeout > 0) { |
|
type = TRANSITION; |
|
timeout = transitionTimeout; |
|
propCount = transitionDurations.length; |
|
} |
|
} else if (expectedType === ANIMATION) { |
|
if (animationTimeout > 0) { |
|
type = ANIMATION; |
|
timeout = animationTimeout; |
|
propCount = animationDurations.length; |
|
} |
|
} else { |
|
timeout = Math.max(transitionTimeout, animationTimeout); |
|
type = timeout > 0 |
|
? transitionTimeout > animationTimeout |
|
? TRANSITION |
|
: ANIMATION |
|
: null; |
|
propCount = type |
|
? type === TRANSITION |
|
? transitionDurations.length |
|
: animationDurations.length |
|
: 0; |
|
} |
|
var hasTransform = |
|
type === TRANSITION && |
|
transformRE.test(styles[transitionProp + 'Property']); |
|
return { |
|
type: type, |
|
timeout: timeout, |
|
propCount: propCount, |
|
hasTransform: hasTransform |
|
} |
|
} |
|
|
|
function getTimeout (delays, durations) { |
|
/* istanbul ignore next */ |
|
while (delays.length < durations.length) { |
|
delays = delays.concat(delays); |
|
} |
|
|
|
return Math.max.apply(null, durations.map(function (d, i) { |
|
return toMs(d) + toMs(delays[i]) |
|
})) |
|
} |
|
|
|
function toMs (s) { |
|
return Number(s.slice(0, -1)) * 1000 |
|
} |
|
|
|
/* */ |
|
|
|
function enter (vnode, toggleDisplay) { |
|
var el = vnode.elm; |
|
|
|
// call leave callback now |
|
if (isDef(el._leaveCb)) { |
|
el._leaveCb.cancelled = true; |
|
el._leaveCb(); |
|
} |
|
|
|
var data = resolveTransition(vnode.data.transition); |
|
if (isUndef(data)) { |
|
return |
|
} |
|
|
|
/* istanbul ignore if */ |
|
if (isDef(el._enterCb) || el.nodeType !== 1) { |
|
return |
|
} |
|
|
|
var css = data.css; |
|
var type = data.type; |
|
var enterClass = data.enterClass; |
|
var enterToClass = data.enterToClass; |
|
var enterActiveClass = data.enterActiveClass; |
|
var appearClass = data.appearClass; |
|
var appearToClass = data.appearToClass; |
|
var appearActiveClass = data.appearActiveClass; |
|
var beforeEnter = data.beforeEnter; |
|
var enter = data.enter; |
|
var afterEnter = data.afterEnter; |
|
var enterCancelled = data.enterCancelled; |
|
var beforeAppear = data.beforeAppear; |
|
var appear = data.appear; |
|
var afterAppear = data.afterAppear; |
|
var appearCancelled = data.appearCancelled; |
|
var duration = data.duration; |
|
|
|
// activeInstance will always be the <transition> component managing this |
|
// transition. One edge case to check is when the <transition> is placed |
|
// as the root node of a child component. In that case we need to check |
|
// <transition>'s parent for appear check. |
|
var context = activeInstance; |
|
var transitionNode = activeInstance.$vnode; |
|
while (transitionNode && transitionNode.parent) { |
|
transitionNode = transitionNode.parent; |
|
context = transitionNode.context; |
|
} |
|
|
|
var isAppear = !context._isMounted || !vnode.isRootInsert; |
|
|
|
if (isAppear && !appear && appear !== '') { |
|
return |
|
} |
|
|
|
var startClass = isAppear && appearClass |
|
? appearClass |
|
: enterClass; |
|
var activeClass = isAppear && appearActiveClass |
|
? appearActiveClass |
|
: enterActiveClass; |
|
var toClass = isAppear && appearToClass |
|
? appearToClass |
|
: enterToClass; |
|
|
|
var beforeEnterHook = isAppear |
|
? (beforeAppear || beforeEnter) |
|
: beforeEnter; |
|
var enterHook = isAppear |
|
? (typeof appear === 'function' ? appear : enter) |
|
: enter; |
|
var afterEnterHook = isAppear |
|
? (afterAppear || afterEnter) |
|
: afterEnter; |
|
var enterCancelledHook = isAppear |
|
? (appearCancelled || enterCancelled) |
|
: enterCancelled; |
|
|
|
var explicitEnterDuration = toNumber( |
|
isObject(duration) |
|
? duration.enter |
|
: duration |
|
); |
|
|
|
if ("development" !== 'production' && explicitEnterDuration != null) { |
|
checkDuration(explicitEnterDuration, 'enter', vnode); |
|
} |
|
|
|
var expectsCSS = css !== false && !isIE9; |
|
var userWantsControl = getHookArgumentsLength(enterHook); |
|
|
|
var cb = el._enterCb = once(function () { |
|
if (expectsCSS) { |
|
removeTransitionClass(el, toClass); |
|
removeTransitionClass(el, activeClass); |
|
} |
|
if (cb.cancelled) { |
|
if (expectsCSS) { |
|
removeTransitionClass(el, startClass); |
|
} |
|
enterCancelledHook && enterCancelledHook(el); |
|
} else { |
|
afterEnterHook && afterEnterHook(el); |
|
} |
|
el._enterCb = null; |
|
}); |
|
|
|
if (!vnode.data.show) { |
|
// remove pending leave element on enter by injecting an insert hook |
|
mergeVNodeHook(vnode, 'insert', function () { |
|
var parent = el.parentNode; |
|
var pendingNode = parent && parent._pending && parent._pending[vnode.key]; |
|
if (pendingNode && |
|
pendingNode.tag === vnode.tag && |
|
pendingNode.elm._leaveCb |
|
) { |
|
pendingNode.elm._leaveCb(); |
|
} |
|
enterHook && enterHook(el, cb); |
|
}); |
|
} |
|
|
|
// start enter transition |
|
beforeEnterHook && beforeEnterHook(el); |
|
if (expectsCSS) { |
|
addTransitionClass(el, startClass); |
|
addTransitionClass(el, activeClass); |
|
nextFrame(function () { |
|
removeTransitionClass(el, startClass); |
|
if (!cb.cancelled) { |
|
addTransitionClass(el, toClass); |
|
if (!userWantsControl) { |
|
if (isValidDuration(explicitEnterDuration)) { |
|
setTimeout(cb, explicitEnterDuration); |
|
} else { |
|
whenTransitionEnds(el, type, cb); |
|
} |
|
} |
|
} |
|
}); |
|
} |
|
|
|
if (vnode.data.show) { |
|
toggleDisplay && toggleDisplay(); |
|
enterHook && enterHook(el, cb); |
|
} |
|
|
|
if (!expectsCSS && !userWantsControl) { |
|
cb(); |
|
} |
|
} |
|
|
|
function leave (vnode, rm) { |
|
var el = vnode.elm; |
|
|
|
// call enter callback now |
|
if (isDef(el._enterCb)) { |
|
el._enterCb.cancelled = true; |
|
el._enterCb(); |
|
} |
|
|
|
var data = resolveTransition(vnode.data.transition); |
|
if (isUndef(data) || el.nodeType !== 1) { |
|
return rm() |
|
} |
|
|
|
/* istanbul ignore if */ |
|
if (isDef(el._leaveCb)) { |
|
return |
|
} |
|
|
|
var css = data.css; |
|
var type = data.type; |
|
var leaveClass = data.leaveClass; |
|
var leaveToClass = data.leaveToClass; |
|
var leaveActiveClass = data.leaveActiveClass; |
|
var beforeLeave = data.beforeLeave; |
|
var leave = data.leave; |
|
var afterLeave = data.afterLeave; |
|
var leaveCancelled = data.leaveCancelled; |
|
var delayLeave = data.delayLeave; |
|
var duration = data.duration; |
|
|
|
var expectsCSS = css !== false && !isIE9; |
|
var userWantsControl = getHookArgumentsLength(leave); |
|
|
|
var explicitLeaveDuration = toNumber( |
|
isObject(duration) |
|
? duration.leave |
|
: duration |
|
); |
|
|
|
if ("development" !== 'production' && isDef(explicitLeaveDuration)) { |
|
checkDuration(explicitLeaveDuration, 'leave', vnode); |
|
} |
|
|
|
var cb = el._leaveCb = once(function () { |
|
if (el.parentNode && el.parentNode._pending) { |
|
el.parentNode._pending[vnode.key] = null; |
|
} |
|
if (expectsCSS) { |
|
removeTransitionClass(el, leaveToClass); |
|
removeTransitionClass(el, leaveActiveClass); |
|
} |
|
if (cb.cancelled) { |
|
if (expectsCSS) { |
|
removeTransitionClass(el, leaveClass); |
|
} |
|
leaveCancelled && leaveCancelled(el); |
|
} else { |
|
rm(); |
|
afterLeave && afterLeave(el); |
|
} |
|
el._leaveCb = null; |
|
}); |
|
|
|
if (delayLeave) { |
|
delayLeave(performLeave); |
|
} else { |
|
performLeave(); |
|
} |
|
|
|
function performLeave () { |
|
// the delayed leave may have already been cancelled |
|
if (cb.cancelled) { |
|
return |
|
} |
|
// record leaving element |
|
if (!vnode.data.show) { |
|
(el.parentNode._pending || (el.parentNode._pending = {}))[(vnode.key)] = vnode; |
|
} |
|
beforeLeave && beforeLeave(el); |
|
if (expectsCSS) { |
|
addTransitionClass(el, leaveClass); |
|
addTransitionClass(el, leaveActiveClass); |
|
nextFrame(function () { |
|
removeTransitionClass(el, leaveClass); |
|
if (!cb.cancelled) { |
|
addTransitionClass(el, leaveToClass); |
|
if (!userWantsControl) { |
|
if (isValidDuration(explicitLeaveDuration)) { |
|
setTimeout(cb, explicitLeaveDuration); |
|
} else { |
|
whenTransitionEnds(el, type, cb); |
|
} |
|
} |
|
} |
|
}); |
|
} |
|
leave && leave(el, cb); |
|
if (!expectsCSS && !userWantsControl) { |
|
cb(); |
|
} |
|
} |
|
} |
|
|
|
// only used in dev mode |
|
function checkDuration (val, name, vnode) { |
|
if (typeof val !== 'number') { |
|
warn( |
|
"<transition> explicit " + name + " duration is not a valid number - " + |
|
"got " + (JSON.stringify(val)) + ".", |
|
vnode.context |
|
); |
|
} else if (isNaN(val)) { |
|
warn( |
|
"<transition> explicit " + name + " duration is NaN - " + |
|
'the duration expression might be incorrect.', |
|
vnode.context |
|
); |
|
} |
|
} |
|
|
|
function isValidDuration (val) { |
|
return typeof val === 'number' && !isNaN(val) |
|
} |
|
|
|
/** |
|
* Normalize a transition hook's argument length. The hook may be: |
|
* - a merged hook (invoker) with the original in .fns |
|
* - a wrapped component method (check ._length) |
|
* - a plain function (.length) |
|
*/ |
|
function getHookArgumentsLength (fn) { |
|
if (isUndef(fn)) { |
|
return false |
|
} |
|
var invokerFns = fn.fns; |
|
if (isDef(invokerFns)) { |
|
// invoker |
|
return getHookArgumentsLength( |
|
Array.isArray(invokerFns) |
|
? invokerFns[0] |
|
: invokerFns |
|
) |
|
} else { |
|
return (fn._length || fn.length) > 1 |
|
} |
|
} |
|
|
|
function _enter (_, vnode) { |
|
if (vnode.data.show !== true) { |
|
enter(vnode); |
|
} |
|
} |
|
|
|
var transition = inBrowser ? { |
|
create: _enter, |
|
activate: _enter, |
|
remove: function remove$$1 (vnode, rm) { |
|
/* istanbul ignore else */ |
|
if (vnode.data.show !== true) { |
|
leave(vnode, rm); |
|
} else { |
|
rm(); |
|
} |
|
} |
|
} : {} |
|
|
|
var platformModules = [ |
|
attrs, |
|
klass, |
|
events, |
|
domProps, |
|
style, |
|
transition |
|
] |
|
|
|
/* */ |
|
|
|
// the directive module should be applied last, after all |
|
// built-in modules have been applied. |
|
var modules = platformModules.concat(baseModules); |
|
|
|
var patch = createPatchFunction({ nodeOps: nodeOps, modules: modules }); |
|
|
|
/** |
|
* Not type checking this file because flow doesn't like attaching |
|
* properties to Elements. |
|
*/ |
|
|
|
/* istanbul ignore if */ |
|
if (isIE9) { |
|
// http://www.matts411.com/post/internet-explorer-9-oninput/ |
|
document.addEventListener('selectionchange', function () { |
|
var el = document.activeElement; |
|
if (el && el.vmodel) { |
|
trigger(el, 'input'); |
|
} |
|
}); |
|
} |
|
|
|
var directive = { |
|
inserted: function inserted (el, binding, vnode, oldVnode) { |
|
if (vnode.tag === 'select') { |
|
// #6903 |
|
if (oldVnode.elm && !oldVnode.elm._vOptions) { |
|
mergeVNodeHook(vnode, 'postpatch', function () { |
|
directive.componentUpdated(el, binding, vnode); |
|
}); |
|
} else { |
|
setSelected(el, binding, vnode.context); |
|
} |
|
el._vOptions = [].map.call(el.options, getValue); |
|
} else if (vnode.tag === 'textarea' || isTextInputType(el.type)) { |
|
el._vModifiers = binding.modifiers; |
|
if (!binding.modifiers.lazy) { |
|
el.addEventListener('compositionstart', onCompositionStart); |
|
el.addEventListener('compositionend', onCompositionEnd); |
|
// Safari < 10.2 & UIWebView doesn't fire compositionend when |
|
// switching focus before confirming composition choice |
|
// this also fixes the issue where some browsers e.g. iOS Chrome |
|
// fires "change" instead of "input" on autocomplete. |
|
el.addEventListener('change', onCompositionEnd); |
|
/* istanbul ignore if */ |
|
if (isIE9) { |
|
el.vmodel = true; |
|
} |
|
} |
|
} |
|
}, |
|
|
|
componentUpdated: function componentUpdated (el, binding, vnode) { |
|
if (vnode.tag === 'select') { |
|
setSelected(el, binding, vnode.context); |
|
// in case the options rendered by v-for have changed, |
|
// it's possible that the value is out-of-sync with the rendered options. |
|
// detect such cases and filter out values that no longer has a matching |
|
// option in the DOM. |
|
var prevOptions = el._vOptions; |
|
var curOptions = el._vOptions = [].map.call(el.options, getValue); |
|
if (curOptions.some(function (o, i) { return !looseEqual(o, prevOptions[i]); })) { |
|
// trigger change event if |
|
// no matching option found for at least one value |
|
var needReset = el.multiple |
|
? binding.value.some(function (v) { return hasNoMatchingOption(v, curOptions); }) |
|
: binding.value !== binding.oldValue && hasNoMatchingOption(binding.value, curOptions); |
|
if (needReset) { |
|
trigger(el, 'change'); |
|
} |
|
} |
|
} |
|
} |
|
}; |
|
|
|
function setSelected (el, binding, vm) { |
|
actuallySetSelected(el, binding, vm); |
|
/* istanbul ignore if */ |
|
if (isIE || isEdge) { |
|
setTimeout(function () { |
|
actuallySetSelected(el, binding, vm); |
|
}, 0); |
|
} |
|
} |
|
|
|
function actuallySetSelected (el, binding, vm) { |
|
var value = binding.value; |
|
var isMultiple = el.multiple; |
|
if (isMultiple && !Array.isArray(value)) { |
|
"development" !== 'production' && warn( |
|
"<select multiple v-model=\"" + (binding.expression) + "\"> " + |
|
"expects an Array value for its binding, but got " + (Object.prototype.toString.call(value).slice(8, -1)), |
|
vm |
|
); |
|
return |
|
} |
|
var selected, option; |
|
for (var i = 0, l = el.options.length; i < l; i++) { |
|
option = el.options[i]; |
|
if (isMultiple) { |
|
selected = looseIndexOf(value, getValue(option)) > -1; |
|
if (option.selected !== selected) { |
|
option.selected = selected; |
|
} |
|
} else { |
|
if (looseEqual(getValue(option), value)) { |
|
if (el.selectedIndex !== i) { |
|
el.selectedIndex = i; |
|
} |
|
return |
|
} |
|
} |
|
} |
|
if (!isMultiple) { |
|
el.selectedIndex = -1; |
|
} |
|
} |
|
|
|
function hasNoMatchingOption (value, options) { |
|
return options.every(function (o) { return !looseEqual(o, value); }) |
|
} |
|
|
|
function getValue (option) { |
|
return '_value' in option |
|
? option._value |
|
: option.value |
|
} |
|
|
|
function onCompositionStart (e) { |
|
e.target.composing = true; |
|
} |
|
|
|
function onCompositionEnd (e) { |
|
// prevent triggering an input event for no reason |
|
if (!e.target.composing) { return } |
|
e.target.composing = false; |
|
trigger(e.target, 'input'); |
|
} |
|
|
|
function trigger (el, type) { |
|
var e = document.createEvent('HTMLEvents'); |
|
e.initEvent(type, true, true); |
|
el.dispatchEvent(e); |
|
} |
|
|
|
/* */ |
|
|
|
// recursively search for possible transition defined inside the component root |
|
function locateNode (vnode) { |
|
return vnode.componentInstance && (!vnode.data || !vnode.data.transition) |
|
? locateNode(vnode.componentInstance._vnode) |
|
: vnode |
|
} |
|
|
|
var show = { |
|
bind: function bind (el, ref, vnode) { |
|
var value = ref.value; |
|
|
|
vnode = locateNode(vnode); |
|
var transition$$1 = vnode.data && vnode.data.transition; |
|
var originalDisplay = el.__vOriginalDisplay = |
|
el.style.display === 'none' ? '' : el.style.display; |
|
if (value && transition$$1) { |
|
vnode.data.show = true; |
|
enter(vnode, function () { |
|
el.style.display = originalDisplay; |
|
}); |
|
} else { |
|
el.style.display = value ? originalDisplay : 'none'; |
|
} |
|
}, |
|
|
|
update: function update (el, ref, vnode) { |
|
var value = ref.value; |
|
var oldValue = ref.oldValue; |
|
|
|
/* istanbul ignore if */ |
|
if (!value === !oldValue) { return } |
|
vnode = locateNode(vnode); |
|
var transition$$1 = vnode.data && vnode.data.transition; |
|
if (transition$$1) { |
|
vnode.data.show = true; |
|
if (value) { |
|
enter(vnode, function () { |
|
el.style.display = el.__vOriginalDisplay; |
|
}); |
|
} else { |
|
leave(vnode, function () { |
|
el.style.display = 'none'; |
|
}); |
|
} |
|
} else { |
|
el.style.display = value ? el.__vOriginalDisplay : 'none'; |
|
} |
|
}, |
|
|
|
unbind: function unbind ( |
|
el, |
|
binding, |
|
vnode, |
|
oldVnode, |
|
isDestroy |
|
) { |
|
if (!isDestroy) { |
|
el.style.display = el.__vOriginalDisplay; |
|
} |
|
} |
|
} |
|
|
|
var platformDirectives = { |
|
model: directive, |
|
show: show |
|
} |
|
|
|
/* */ |
|
|
|
// Provides transition support for a single element/component. |
|
// supports transition mode (out-in / in-out) |
|
|
|
var transitionProps = { |
|
name: String, |
|
appear: Boolean, |
|
css: Boolean, |
|
mode: String, |
|
type: String, |
|
enterClass: String, |
|
leaveClass: String, |
|
enterToClass: String, |
|
leaveToClass: String, |
|
enterActiveClass: String, |
|
leaveActiveClass: String, |
|
appearClass: String, |
|
appearActiveClass: String, |
|
appearToClass: String, |
|
duration: [Number, String, Object] |
|
}; |
|
|
|
// in case the child is also an abstract component, e.g. <keep-alive> |
|
// we want to recursively retrieve the real component to be rendered |
|
function getRealChild (vnode) { |
|
var compOptions = vnode && vnode.componentOptions; |
|
if (compOptions && compOptions.Ctor.options.abstract) { |
|
return getRealChild(getFirstComponentChild(compOptions.children)) |
|
} else { |
|
return vnode |
|
} |
|
} |
|
|
|
function extractTransitionData (comp) { |
|
var data = {}; |
|
var options = comp.$options; |
|
// props |
|
for (var key in options.propsData) { |
|
data[key] = comp[key]; |
|
} |
|
// events. |
|
// extract listeners and pass them directly to the transition methods |
|
var listeners = options._parentListeners; |
|
for (var key$1 in listeners) { |
|
data[camelize(key$1)] = listeners[key$1]; |
|
} |
|
return data |
|
} |
|
|
|
function placeholder (h, rawChild) { |
|
if (/\d-keep-alive$/.test(rawChild.tag)) { |
|
return h('keep-alive', { |
|
props: rawChild.componentOptions.propsData |
|
}) |
|
} |
|
} |
|
|
|
function hasParentTransition (vnode) { |
|
while ((vnode = vnode.parent)) { |
|
if (vnode.data.transition) { |
|
return true |
|
} |
|
} |
|
} |
|
|
|
function isSameChild (child, oldChild) { |
|
return oldChild.key === child.key && oldChild.tag === child.tag |
|
} |
|
|
|
var Transition = { |
|
name: 'transition', |
|
props: transitionProps, |
|
abstract: true, |
|
|
|
render: function render (h) { |
|
var this$1 = this; |
|
|
|
var children = this.$slots.default; |
|
if (!children) { |
|
return |
|
} |
|
|
|
// filter out text nodes (possible whitespaces) |
|
children = children.filter(function (c) { return c.tag || isAsyncPlaceholder(c); }); |
|
/* istanbul ignore if */ |
|
if (!children.length) { |
|
return |
|
} |
|
|
|
// warn multiple elements |
|
if ("development" !== 'production' && children.length > 1) { |
|
warn( |
|
'<transition> can only be used on a single element. Use ' + |
|
'<transition-group> for lists.', |
|
this.$parent |
|
); |
|
} |
|
|
|
var mode = this.mode; |
|
|
|
// warn invalid mode |
|
if ("development" !== 'production' && |
|
mode && mode !== 'in-out' && mode !== 'out-in' |
|
) { |
|
warn( |
|
'invalid <transition> mode: ' + mode, |
|
this.$parent |
|
); |
|
} |
|
|
|
var rawChild = children[0]; |
|
|
|
// if this is a component root node and the component's |
|
// parent container node also has transition, skip. |
|
if (hasParentTransition(this.$vnode)) { |
|
return rawChild |
|
} |
|
|
|
// apply transition data to child |
|
// use getRealChild() to ignore abstract components e.g. keep-alive |
|
var child = getRealChild(rawChild); |
|
/* istanbul ignore if */ |
|
if (!child) { |
|
return rawChild |
|
} |
|
|
|
if (this._leaving) { |
|
return placeholder(h, rawChild) |
|
} |
|
|
|
// ensure a key that is unique to the vnode type and to this transition |
|
// component instance. This key will be used to remove pending leaving nodes |
|
// during entering. |
|
var id = "__transition-" + (this._uid) + "-"; |
|
child.key = child.key == null |
|
? child.isComment |
|
? id + 'comment' |
|
: id + child.tag |
|
: isPrimitive(child.key) |
|
? (String(child.key).indexOf(id) === 0 ? child.key : id + child.key) |
|
: child.key; |
|
|
|
var data = (child.data || (child.data = {})).transition = extractTransitionData(this); |
|
var oldRawChild = this._vnode; |
|
var oldChild = getRealChild(oldRawChild); |
|
|
|
// mark v-show |
|
// so that the transition module can hand over the control to the directive |
|
if (child.data.directives && child.data.directives.some(function (d) { return d.name === 'show'; })) { |
|
child.data.show = true; |
|
} |
|
|
|
if ( |
|
oldChild && |
|
oldChild.data && |
|
!isSameChild(child, oldChild) && |
|
!isAsyncPlaceholder(oldChild) && |
|
// #6687 component root is a comment node |
|
!(oldChild.componentInstance && oldChild.componentInstance._vnode.isComment) |
|
) { |
|
// replace old child transition data with fresh one |
|
// important for dynamic transitions! |
|
var oldData = oldChild.data.transition = extend({}, data); |
|
// handle transition mode |
|
if (mode === 'out-in') { |
|
// return placeholder node and queue update when leave finishes |
|
this._leaving = true; |
|
mergeVNodeHook(oldData, 'afterLeave', function () { |
|
this$1._leaving = false; |
|
this$1.$forceUpdate(); |
|
}); |
|
return placeholder(h, rawChild) |
|
} else if (mode === 'in-out') { |
|
if (isAsyncPlaceholder(child)) { |
|
return oldRawChild |
|
} |
|
var delayedLeave; |
|
var performLeave = function () { delayedLeave(); }; |
|
mergeVNodeHook(data, 'afterEnter', performLeave); |
|
mergeVNodeHook(data, 'enterCancelled', performLeave); |
|
mergeVNodeHook(oldData, 'delayLeave', function (leave) { delayedLeave = leave; }); |
|
} |
|
} |
|
|
|
return rawChild |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
// Provides transition support for list items. |
|
// supports move transitions using the FLIP technique. |
|
|
|
// Because the vdom's children update algorithm is "unstable" - i.e. |
|
// it doesn't guarantee the relative positioning of removed elements, |
|
// we force transition-group to update its children into two passes: |
|
// in the first pass, we remove all nodes that need to be removed, |
|
// triggering their leaving transition; in the second pass, we insert/move |
|
// into the final desired state. This way in the second pass removed |
|
// nodes will remain where they should be. |
|
|
|
var props = extend({ |
|
tag: String, |
|
moveClass: String |
|
}, transitionProps); |
|
|
|
delete props.mode; |
|
|
|
var TransitionGroup = { |
|
props: props, |
|
|
|
render: function render (h) { |
|
var tag = this.tag || this.$vnode.data.tag || 'span'; |
|
var map = Object.create(null); |
|
var prevChildren = this.prevChildren = this.children; |
|
var rawChildren = this.$slots.default || []; |
|
var children = this.children = []; |
|
var transitionData = extractTransitionData(this); |
|
|
|
for (var i = 0; i < rawChildren.length; i++) { |
|
var c = rawChildren[i]; |
|
if (c.tag) { |
|
if (c.key != null && String(c.key).indexOf('__vlist') !== 0) { |
|
children.push(c); |
|
map[c.key] = c |
|
;(c.data || (c.data = {})).transition = transitionData; |
|
} else if (true) { |
|
var opts = c.componentOptions; |
|
var name = opts ? (opts.Ctor.options.name || opts.tag || '') : c.tag; |
|
warn(("<transition-group> children must be keyed: <" + name + ">")); |
|
} |
|
} |
|
} |
|
|
|
if (prevChildren) { |
|
var kept = []; |
|
var removed = []; |
|
for (var i$1 = 0; i$1 < prevChildren.length; i$1++) { |
|
var c$1 = prevChildren[i$1]; |
|
c$1.data.transition = transitionData; |
|
c$1.data.pos = c$1.elm.getBoundingClientRect(); |
|
if (map[c$1.key]) { |
|
kept.push(c$1); |
|
} else { |
|
removed.push(c$1); |
|
} |
|
} |
|
this.kept = h(tag, null, kept); |
|
this.removed = removed; |
|
} |
|
|
|
return h(tag, null, children) |
|
}, |
|
|
|
beforeUpdate: function beforeUpdate () { |
|
// force removing pass |
|
this.__patch__( |
|
this._vnode, |
|
this.kept, |
|
false, // hydrating |
|
true // removeOnly (!important, avoids unnecessary moves) |
|
); |
|
this._vnode = this.kept; |
|
}, |
|
|
|
updated: function updated () { |
|
var children = this.prevChildren; |
|
var moveClass = this.moveClass || ((this.name || 'v') + '-move'); |
|
if (!children.length || !this.hasMove(children[0].elm, moveClass)) { |
|
return |
|
} |
|
|
|
// we divide the work into three loops to avoid mixing DOM reads and writes |
|
// in each iteration - which helps prevent layout thrashing. |
|
children.forEach(callPendingCbs); |
|
children.forEach(recordPosition); |
|
children.forEach(applyTranslation); |
|
|
|
// force reflow to put everything in position |
|
// assign to this to avoid being removed in tree-shaking |
|
// $flow-disable-line |
|
this._reflow = document.body.offsetHeight; |
|
|
|
children.forEach(function (c) { |
|
if (c.data.moved) { |
|
var el = c.elm; |
|
var s = el.style; |
|
addTransitionClass(el, moveClass); |
|
s.transform = s.WebkitTransform = s.transitionDuration = ''; |
|
el.addEventListener(transitionEndEvent, el._moveCb = function cb (e) { |
|
if (!e || /transform$/.test(e.propertyName)) { |
|
el.removeEventListener(transitionEndEvent, cb); |
|
el._moveCb = null; |
|
removeTransitionClass(el, moveClass); |
|
} |
|
}); |
|
} |
|
}); |
|
}, |
|
|
|
methods: { |
|
hasMove: function hasMove (el, moveClass) { |
|
/* istanbul ignore if */ |
|
if (!hasTransition) { |
|
return false |
|
} |
|
/* istanbul ignore if */ |
|
if (this._hasMove) { |
|
return this._hasMove |
|
} |
|
// Detect whether an element with the move class applied has |
|
// CSS transitions. Since the element may be inside an entering |
|
// transition at this very moment, we make a clone of it and remove |
|
// all other transition classes applied to ensure only the move class |
|
// is applied. |
|
var clone = el.cloneNode(); |
|
if (el._transitionClasses) { |
|
el._transitionClasses.forEach(function (cls) { removeClass(clone, cls); }); |
|
} |
|
addClass(clone, moveClass); |
|
clone.style.display = 'none'; |
|
this.$el.appendChild(clone); |
|
var info = getTransitionInfo(clone); |
|
this.$el.removeChild(clone); |
|
return (this._hasMove = info.hasTransform) |
|
} |
|
} |
|
} |
|
|
|
function callPendingCbs (c) { |
|
/* istanbul ignore if */ |
|
if (c.elm._moveCb) { |
|
c.elm._moveCb(); |
|
} |
|
/* istanbul ignore if */ |
|
if (c.elm._enterCb) { |
|
c.elm._enterCb(); |
|
} |
|
} |
|
|
|
function recordPosition (c) { |
|
c.data.newPos = c.elm.getBoundingClientRect(); |
|
} |
|
|
|
function applyTranslation (c) { |
|
var oldPos = c.data.pos; |
|
var newPos = c.data.newPos; |
|
var dx = oldPos.left - newPos.left; |
|
var dy = oldPos.top - newPos.top; |
|
if (dx || dy) { |
|
c.data.moved = true; |
|
var s = c.elm.style; |
|
s.transform = s.WebkitTransform = "translate(" + dx + "px," + dy + "px)"; |
|
s.transitionDuration = '0s'; |
|
} |
|
} |
|
|
|
var platformComponents = { |
|
Transition: Transition, |
|
TransitionGroup: TransitionGroup |
|
} |
|
|
|
/* */ |
|
|
|
// install platform specific utils |
|
Vue.config.mustUseProp = mustUseProp; |
|
Vue.config.isReservedTag = isReservedTag; |
|
Vue.config.isReservedAttr = isReservedAttr; |
|
Vue.config.getTagNamespace = getTagNamespace; |
|
Vue.config.isUnknownElement = isUnknownElement; |
|
|
|
// install platform runtime directives & components |
|
extend(Vue.options.directives, platformDirectives); |
|
extend(Vue.options.components, platformComponents); |
|
|
|
// install platform patch function |
|
Vue.prototype.__patch__ = inBrowser ? patch : noop; |
|
|
|
// public mount method |
|
Vue.prototype.$mount = function ( |
|
el, |
|
hydrating |
|
) { |
|
el = el && inBrowser ? query(el) : undefined; |
|
return mountComponent(this, el, hydrating) |
|
}; |
|
|
|
// devtools global hook |
|
/* istanbul ignore next */ |
|
if (inBrowser) { |
|
setTimeout(function () { |
|
if (config.devtools) { |
|
if (devtools) { |
|
devtools.emit('init', Vue); |
|
} else if ( |
|
"development" !== 'production' && |
|
"development" !== 'test' && |
|
isChrome |
|
) { |
|
console[console.info ? 'info' : 'log']( |
|
'Download the Vue Devtools extension for a better development experience:\n' + |
|
'https://github.com/vuejs/vue-devtools' |
|
); |
|
} |
|
} |
|
if ("development" !== 'production' && |
|
"development" !== 'test' && |
|
config.productionTip !== false && |
|
typeof console !== 'undefined' |
|
) { |
|
console[console.info ? 'info' : 'log']( |
|
"You are running Vue in development mode.\n" + |
|
"Make sure to turn on production mode when deploying for production.\n" + |
|
"See more tips at https://vuejs.org/guide/deployment.html" |
|
); |
|
} |
|
}, 0); |
|
} |
|
|
|
/* */ |
|
|
|
var defaultTagRE = /\{\{((?:.|\n)+?)\}\}/g; |
|
var regexEscapeRE = /[-.*+?^${}()|[\]\/\\]/g; |
|
|
|
var buildRegex = cached(function (delimiters) { |
|
var open = delimiters[0].replace(regexEscapeRE, '\\$&'); |
|
var close = delimiters[1].replace(regexEscapeRE, '\\$&'); |
|
return new RegExp(open + '((?:.|\\n)+?)' + close, 'g') |
|
}); |
|
|
|
|
|
|
|
function parseText ( |
|
text, |
|
delimiters |
|
) { |
|
var tagRE = delimiters ? buildRegex(delimiters) : defaultTagRE; |
|
if (!tagRE.test(text)) { |
|
return |
|
} |
|
var tokens = []; |
|
var rawTokens = []; |
|
var lastIndex = tagRE.lastIndex = 0; |
|
var match, index, tokenValue; |
|
while ((match = tagRE.exec(text))) { |
|
index = match.index; |
|
// push text token |
|
if (index > lastIndex) { |
|
rawTokens.push(tokenValue = text.slice(lastIndex, index)); |
|
tokens.push(JSON.stringify(tokenValue)); |
|
} |
|
// tag token |
|
var exp = parseFilters(match[1].trim()); |
|
tokens.push(("_s(" + exp + ")")); |
|
rawTokens.push({ '@binding': exp }); |
|
lastIndex = index + match[0].length; |
|
} |
|
if (lastIndex < text.length) { |
|
rawTokens.push(tokenValue = text.slice(lastIndex)); |
|
tokens.push(JSON.stringify(tokenValue)); |
|
} |
|
return { |
|
expression: tokens.join('+'), |
|
tokens: rawTokens |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
function transformNode (el, options) { |
|
var warn = options.warn || baseWarn; |
|
var staticClass = getAndRemoveAttr(el, 'class'); |
|
if ("development" !== 'production' && staticClass) { |
|
var res = parseText(staticClass, options.delimiters); |
|
if (res) { |
|
warn( |
|
"class=\"" + staticClass + "\": " + |
|
'Interpolation inside attributes has been removed. ' + |
|
'Use v-bind or the colon shorthand instead. For example, ' + |
|
'instead of <div class="{{ val }}">, use <div :class="val">.' |
|
); |
|
} |
|
} |
|
if (staticClass) { |
|
el.staticClass = JSON.stringify(staticClass); |
|
} |
|
var classBinding = getBindingAttr(el, 'class', false /* getStatic */); |
|
if (classBinding) { |
|
el.classBinding = classBinding; |
|
} |
|
} |
|
|
|
function genData (el) { |
|
var data = ''; |
|
if (el.staticClass) { |
|
data += "staticClass:" + (el.staticClass) + ","; |
|
} |
|
if (el.classBinding) { |
|
data += "class:" + (el.classBinding) + ","; |
|
} |
|
return data |
|
} |
|
|
|
var klass$1 = { |
|
staticKeys: ['staticClass'], |
|
transformNode: transformNode, |
|
genData: genData |
|
} |
|
|
|
/* */ |
|
|
|
function transformNode$1 (el, options) { |
|
var warn = options.warn || baseWarn; |
|
var staticStyle = getAndRemoveAttr(el, 'style'); |
|
if (staticStyle) { |
|
/* istanbul ignore if */ |
|
if (true) { |
|
var res = parseText(staticStyle, options.delimiters); |
|
if (res) { |
|
warn( |
|
"style=\"" + staticStyle + "\": " + |
|
'Interpolation inside attributes has been removed. ' + |
|
'Use v-bind or the colon shorthand instead. For example, ' + |
|
'instead of <div style="{{ val }}">, use <div :style="val">.' |
|
); |
|
} |
|
} |
|
el.staticStyle = JSON.stringify(parseStyleText(staticStyle)); |
|
} |
|
|
|
var styleBinding = getBindingAttr(el, 'style', false /* getStatic */); |
|
if (styleBinding) { |
|
el.styleBinding = styleBinding; |
|
} |
|
} |
|
|
|
function genData$1 (el) { |
|
var data = ''; |
|
if (el.staticStyle) { |
|
data += "staticStyle:" + (el.staticStyle) + ","; |
|
} |
|
if (el.styleBinding) { |
|
data += "style:(" + (el.styleBinding) + "),"; |
|
} |
|
return data |
|
} |
|
|
|
var style$1 = { |
|
staticKeys: ['staticStyle'], |
|
transformNode: transformNode$1, |
|
genData: genData$1 |
|
} |
|
|
|
/* */ |
|
|
|
var decoder; |
|
|
|
var he = { |
|
decode: function decode (html) { |
|
decoder = decoder || document.createElement('div'); |
|
decoder.innerHTML = html; |
|
return decoder.textContent |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
var isUnaryTag = makeMap( |
|
'area,base,br,col,embed,frame,hr,img,input,isindex,keygen,' + |
|
'link,meta,param,source,track,wbr' |
|
); |
|
|
|
// Elements that you can, intentionally, leave open |
|
// (and which close themselves) |
|
var canBeLeftOpenTag = makeMap( |
|
'colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source' |
|
); |
|
|
|
// HTML5 tags https://html.spec.whatwg.org/multipage/indices.html#elements-3 |
|
// Phrasing Content https://html.spec.whatwg.org/multipage/dom.html#phrasing-content |
|
var isNonPhrasingTag = makeMap( |
|
'address,article,aside,base,blockquote,body,caption,col,colgroup,dd,' + |
|
'details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,' + |
|
'h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,' + |
|
'optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,' + |
|
'title,tr,track' |
|
); |
|
|
|
/** |
|
* Not type-checking this file because it's mostly vendor code. |
|
*/ |
|
|
|
/*! |
|
* HTML Parser By John Resig (ejohn.org) |
|
* Modified by Juriy "kangax" Zaytsev |
|
* Original code by Erik Arvidsson, Mozilla Public License |
|
* http://erik.eae.net/simplehtmlparser/simplehtmlparser.js |
|
*/ |
|
|
|
// Regular Expressions for parsing tags and attributes |
|
var attribute = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/; |
|
// could use https://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-QName |
|
// but for Vue templates we can enforce a simple charset |
|
var ncname = '[a-zA-Z_][\\w\\-\\.]*'; |
|
var qnameCapture = "((?:" + ncname + "\\:)?" + ncname + ")"; |
|
var startTagOpen = new RegExp(("^<" + qnameCapture)); |
|
var startTagClose = /^\s*(\/?)>/; |
|
var endTag = new RegExp(("^<\\/" + qnameCapture + "[^>]*>")); |
|
var doctype = /^<!DOCTYPE [^>]+>/i; |
|
// #7298: escape - to avoid being pased as HTML comment when inlined in page |
|
var comment = /^<!\--/; |
|
var conditionalComment = /^<!\[/; |
|
|
|
var IS_REGEX_CAPTURING_BROKEN = false; |
|
'x'.replace(/x(.)?/g, function (m, g) { |
|
IS_REGEX_CAPTURING_BROKEN = g === ''; |
|
}); |
|
|
|
// Special Elements (can contain anything) |
|
var isPlainTextElement = makeMap('script,style,textarea', true); |
|
var reCache = {}; |
|
|
|
var decodingMap = { |
|
'<': '<', |
|
'>': '>', |
|
'"': '"', |
|
'&': '&', |
|
' ': '\n', |
|
'	': '\t' |
|
}; |
|
var encodedAttr = /&(?:lt|gt|quot|amp);/g; |
|
var encodedAttrWithNewLines = /&(?:lt|gt|quot|amp|#10|#9);/g; |
|
|
|
// #5992 |
|
var isIgnoreNewlineTag = makeMap('pre,textarea', true); |
|
var shouldIgnoreFirstNewline = function (tag, html) { return tag && isIgnoreNewlineTag(tag) && html[0] === '\n'; }; |
|
|
|
function decodeAttr (value, shouldDecodeNewlines) { |
|
var re = shouldDecodeNewlines ? encodedAttrWithNewLines : encodedAttr; |
|
return value.replace(re, function (match) { return decodingMap[match]; }) |
|
} |
|
|
|
function parseHTML (html, options) { |
|
var stack = []; |
|
var expectHTML = options.expectHTML; |
|
var isUnaryTag$$1 = options.isUnaryTag || no; |
|
var canBeLeftOpenTag$$1 = options.canBeLeftOpenTag || no; |
|
var index = 0; |
|
var last, lastTag; |
|
while (html) { |
|
last = html; |
|
// Make sure we're not in a plaintext content element like script/style |
|
if (!lastTag || !isPlainTextElement(lastTag)) { |
|
var textEnd = html.indexOf('<'); |
|
if (textEnd === 0) { |
|
// Comment: |
|
if (comment.test(html)) { |
|
var commentEnd = html.indexOf('-->'); |
|
|
|
if (commentEnd >= 0) { |
|
if (options.shouldKeepComment) { |
|
options.comment(html.substring(4, commentEnd)); |
|
} |
|
advance(commentEnd + 3); |
|
continue |
|
} |
|
} |
|
|
|
// http://en.wikipedia.org/wiki/Conditional_comment#Downlevel-revealed_conditional_comment |
|
if (conditionalComment.test(html)) { |
|
var conditionalEnd = html.indexOf(']>'); |
|
|
|
if (conditionalEnd >= 0) { |
|
advance(conditionalEnd + 2); |
|
continue |
|
} |
|
} |
|
|
|
// Doctype: |
|
var doctypeMatch = html.match(doctype); |
|
if (doctypeMatch) { |
|
advance(doctypeMatch[0].length); |
|
continue |
|
} |
|
|
|
// End tag: |
|
var endTagMatch = html.match(endTag); |
|
if (endTagMatch) { |
|
var curIndex = index; |
|
advance(endTagMatch[0].length); |
|
parseEndTag(endTagMatch[1], curIndex, index); |
|
continue |
|
} |
|
|
|
// Start tag: |
|
var startTagMatch = parseStartTag(); |
|
if (startTagMatch) { |
|
handleStartTag(startTagMatch); |
|
if (shouldIgnoreFirstNewline(lastTag, html)) { |
|
advance(1); |
|
} |
|
continue |
|
} |
|
} |
|
|
|
var text = (void 0), rest = (void 0), next = (void 0); |
|
if (textEnd >= 0) { |
|
rest = html.slice(textEnd); |
|
while ( |
|
!endTag.test(rest) && |
|
!startTagOpen.test(rest) && |
|
!comment.test(rest) && |
|
!conditionalComment.test(rest) |
|
) { |
|
// < in plain text, be forgiving and treat it as text |
|
next = rest.indexOf('<', 1); |
|
if (next < 0) { break } |
|
textEnd += next; |
|
rest = html.slice(textEnd); |
|
} |
|
text = html.substring(0, textEnd); |
|
advance(textEnd); |
|
} |
|
|
|
if (textEnd < 0) { |
|
text = html; |
|
html = ''; |
|
} |
|
|
|
if (options.chars && text) { |
|
options.chars(text); |
|
} |
|
} else { |
|
var endTagLength = 0; |
|
var stackedTag = lastTag.toLowerCase(); |
|
var reStackedTag = reCache[stackedTag] || (reCache[stackedTag] = new RegExp('([\\s\\S]*?)(</' + stackedTag + '[^>]*>)', 'i')); |
|
var rest$1 = html.replace(reStackedTag, function (all, text, endTag) { |
|
endTagLength = endTag.length; |
|
if (!isPlainTextElement(stackedTag) && stackedTag !== 'noscript') { |
|
text = text |
|
.replace(/<!\--([\s\S]*?)-->/g, '$1') // #7298 |
|
.replace(/<!\[CDATA\[([\s\S]*?)]]>/g, '$1'); |
|
} |
|
if (shouldIgnoreFirstNewline(stackedTag, text)) { |
|
text = text.slice(1); |
|
} |
|
if (options.chars) { |
|
options.chars(text); |
|
} |
|
return '' |
|
}); |
|
index += html.length - rest$1.length; |
|
html = rest$1; |
|
parseEndTag(stackedTag, index - endTagLength, index); |
|
} |
|
|
|
if (html === last) { |
|
options.chars && options.chars(html); |
|
if ("development" !== 'production' && !stack.length && options.warn) { |
|
options.warn(("Mal-formatted tag at end of template: \"" + html + "\"")); |
|
} |
|
break |
|
} |
|
} |
|
|
|
// Clean up any remaining tags |
|
parseEndTag(); |
|
|
|
function advance (n) { |
|
index += n; |
|
html = html.substring(n); |
|
} |
|
|
|
function parseStartTag () { |
|
var start = html.match(startTagOpen); |
|
if (start) { |
|
var match = { |
|
tagName: start[1], |
|
attrs: [], |
|
start: index |
|
}; |
|
advance(start[0].length); |
|
var end, attr; |
|
while (!(end = html.match(startTagClose)) && (attr = html.match(attribute))) { |
|
advance(attr[0].length); |
|
match.attrs.push(attr); |
|
} |
|
if (end) { |
|
match.unarySlash = end[1]; |
|
advance(end[0].length); |
|
match.end = index; |
|
return match |
|
} |
|
} |
|
} |
|
|
|
function handleStartTag (match) { |
|
var tagName = match.tagName; |
|
var unarySlash = match.unarySlash; |
|
|
|
if (expectHTML) { |
|
if (lastTag === 'p' && isNonPhrasingTag(tagName)) { |
|
parseEndTag(lastTag); |
|
} |
|
if (canBeLeftOpenTag$$1(tagName) && lastTag === tagName) { |
|
parseEndTag(tagName); |
|
} |
|
} |
|
|
|
var unary = isUnaryTag$$1(tagName) || !!unarySlash; |
|
|
|
var l = match.attrs.length; |
|
var attrs = new Array(l); |
|
for (var i = 0; i < l; i++) { |
|
var args = match.attrs[i]; |
|
// hackish work around FF bug https://bugzilla.mozilla.org/show_bug.cgi?id=369778 |
|
if (IS_REGEX_CAPTURING_BROKEN && args[0].indexOf('""') === -1) { |
|
if (args[3] === '') { delete args[3]; } |
|
if (args[4] === '') { delete args[4]; } |
|
if (args[5] === '') { delete args[5]; } |
|
} |
|
var value = args[3] || args[4] || args[5] || ''; |
|
var shouldDecodeNewlines = tagName === 'a' && args[1] === 'href' |
|
? options.shouldDecodeNewlinesForHref |
|
: options.shouldDecodeNewlines; |
|
attrs[i] = { |
|
name: args[1], |
|
value: decodeAttr(value, shouldDecodeNewlines) |
|
}; |
|
} |
|
|
|
if (!unary) { |
|
stack.push({ tag: tagName, lowerCasedTag: tagName.toLowerCase(), attrs: attrs }); |
|
lastTag = tagName; |
|
} |
|
|
|
if (options.start) { |
|
options.start(tagName, attrs, unary, match.start, match.end); |
|
} |
|
} |
|
|
|
function parseEndTag (tagName, start, end) { |
|
var pos, lowerCasedTagName; |
|
if (start == null) { start = index; } |
|
if (end == null) { end = index; } |
|
|
|
if (tagName) { |
|
lowerCasedTagName = tagName.toLowerCase(); |
|
} |
|
|
|
// Find the closest opened tag of the same type |
|
if (tagName) { |
|
for (pos = stack.length - 1; pos >= 0; pos--) { |
|
if (stack[pos].lowerCasedTag === lowerCasedTagName) { |
|
break |
|
} |
|
} |
|
} else { |
|
// If no tag name is provided, clean shop |
|
pos = 0; |
|
} |
|
|
|
if (pos >= 0) { |
|
// Close all the open elements, up the stack |
|
for (var i = stack.length - 1; i >= pos; i--) { |
|
if ("development" !== 'production' && |
|
(i > pos || !tagName) && |
|
options.warn |
|
) { |
|
options.warn( |
|
("tag <" + (stack[i].tag) + "> has no matching end tag.") |
|
); |
|
} |
|
if (options.end) { |
|
options.end(stack[i].tag, start, end); |
|
} |
|
} |
|
|
|
// Remove the open elements from the stack |
|
stack.length = pos; |
|
lastTag = pos && stack[pos - 1].tag; |
|
} else if (lowerCasedTagName === 'br') { |
|
if (options.start) { |
|
options.start(tagName, [], true, start, end); |
|
} |
|
} else if (lowerCasedTagName === 'p') { |
|
if (options.start) { |
|
options.start(tagName, [], false, start, end); |
|
} |
|
if (options.end) { |
|
options.end(tagName, start, end); |
|
} |
|
} |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
var onRE = /^@|^v-on:/; |
|
var dirRE = /^v-|^@|^:/; |
|
var forAliasRE = /([^]*?)\s+(?:in|of)\s+([^]*)/; |
|
var forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/; |
|
var stripParensRE = /^\(|\)$/g; |
|
|
|
var argRE = /:(.*)$/; |
|
var bindRE = /^:|^v-bind:/; |
|
var modifierRE = /\.[^.]+/g; |
|
|
|
var decodeHTMLCached = cached(he.decode); |
|
|
|
// configurable state |
|
var warn$2; |
|
var delimiters; |
|
var transforms; |
|
var preTransforms; |
|
var postTransforms; |
|
var platformIsPreTag; |
|
var platformMustUseProp; |
|
var platformGetTagNamespace; |
|
|
|
|
|
|
|
function createASTElement ( |
|
tag, |
|
attrs, |
|
parent |
|
) { |
|
return { |
|
type: 1, |
|
tag: tag, |
|
attrsList: attrs, |
|
attrsMap: makeAttrsMap(attrs), |
|
parent: parent, |
|
children: [] |
|
} |
|
} |
|
|
|
/** |
|
* Convert HTML string to AST. |
|
*/ |
|
function parse ( |
|
template, |
|
options |
|
) { |
|
warn$2 = options.warn || baseWarn; |
|
|
|
platformIsPreTag = options.isPreTag || no; |
|
platformMustUseProp = options.mustUseProp || no; |
|
platformGetTagNamespace = options.getTagNamespace || no; |
|
|
|
transforms = pluckModuleFunction(options.modules, 'transformNode'); |
|
preTransforms = pluckModuleFunction(options.modules, 'preTransformNode'); |
|
postTransforms = pluckModuleFunction(options.modules, 'postTransformNode'); |
|
|
|
delimiters = options.delimiters; |
|
|
|
var stack = []; |
|
var preserveWhitespace = options.preserveWhitespace !== false; |
|
var root; |
|
var currentParent; |
|
var inVPre = false; |
|
var inPre = false; |
|
var warned = false; |
|
|
|
function warnOnce (msg) { |
|
if (!warned) { |
|
warned = true; |
|
warn$2(msg); |
|
} |
|
} |
|
|
|
function closeElement (element) { |
|
// check pre state |
|
if (element.pre) { |
|
inVPre = false; |
|
} |
|
if (platformIsPreTag(element.tag)) { |
|
inPre = false; |
|
} |
|
// apply post-transforms |
|
for (var i = 0; i < postTransforms.length; i++) { |
|
postTransforms[i](element, options); |
|
} |
|
} |
|
|
|
parseHTML(template, { |
|
warn: warn$2, |
|
expectHTML: options.expectHTML, |
|
isUnaryTag: options.isUnaryTag, |
|
canBeLeftOpenTag: options.canBeLeftOpenTag, |
|
shouldDecodeNewlines: options.shouldDecodeNewlines, |
|
shouldDecodeNewlinesForHref: options.shouldDecodeNewlinesForHref, |
|
shouldKeepComment: options.comments, |
|
start: function start (tag, attrs, unary) { |
|
// check namespace. |
|
// inherit parent ns if there is one |
|
var ns = (currentParent && currentParent.ns) || platformGetTagNamespace(tag); |
|
|
|
// handle IE svg bug |
|
/* istanbul ignore if */ |
|
if (isIE && ns === 'svg') { |
|
attrs = guardIESVGBug(attrs); |
|
} |
|
|
|
var element = createASTElement(tag, attrs, currentParent); |
|
if (ns) { |
|
element.ns = ns; |
|
} |
|
|
|
if (isForbiddenTag(element) && !isServerRendering()) { |
|
element.forbidden = true; |
|
"development" !== 'production' && warn$2( |
|
'Templates should only be responsible for mapping the state to the ' + |
|
'UI. Avoid placing tags with side-effects in your templates, such as ' + |
|
"<" + tag + ">" + ', as they will not be parsed.' |
|
); |
|
} |
|
|
|
// apply pre-transforms |
|
for (var i = 0; i < preTransforms.length; i++) { |
|
element = preTransforms[i](element, options) || element; |
|
} |
|
|
|
if (!inVPre) { |
|
processPre(element); |
|
if (element.pre) { |
|
inVPre = true; |
|
} |
|
} |
|
if (platformIsPreTag(element.tag)) { |
|
inPre = true; |
|
} |
|
if (inVPre) { |
|
processRawAttrs(element); |
|
} else if (!element.processed) { |
|
// structural directives |
|
processFor(element); |
|
processIf(element); |
|
processOnce(element); |
|
// element-scope stuff |
|
processElement(element, options); |
|
} |
|
|
|
function checkRootConstraints (el) { |
|
if (true) { |
|
if (el.tag === 'slot' || el.tag === 'template') { |
|
warnOnce( |
|
"Cannot use <" + (el.tag) + "> as component root element because it may " + |
|
'contain multiple nodes.' |
|
); |
|
} |
|
if (el.attrsMap.hasOwnProperty('v-for')) { |
|
warnOnce( |
|
'Cannot use v-for on stateful component root element because ' + |
|
'it renders multiple elements.' |
|
); |
|
} |
|
} |
|
} |
|
|
|
// tree management |
|
if (!root) { |
|
root = element; |
|
checkRootConstraints(root); |
|
} else if (!stack.length) { |
|
// allow root elements with v-if, v-else-if and v-else |
|
if (root.if && (element.elseif || element.else)) { |
|
checkRootConstraints(element); |
|
addIfCondition(root, { |
|
exp: element.elseif, |
|
block: element |
|
}); |
|
} else if (true) { |
|
warnOnce( |
|
"Component template should contain exactly one root element. " + |
|
"If you are using v-if on multiple elements, " + |
|
"use v-else-if to chain them instead." |
|
); |
|
} |
|
} |
|
if (currentParent && !element.forbidden) { |
|
if (element.elseif || element.else) { |
|
processIfConditions(element, currentParent); |
|
} else if (element.slotScope) { // scoped slot |
|
currentParent.plain = false; |
|
var name = element.slotTarget || '"default"';(currentParent.scopedSlots || (currentParent.scopedSlots = {}))[name] = element; |
|
} else { |
|
currentParent.children.push(element); |
|
element.parent = currentParent; |
|
} |
|
} |
|
if (!unary) { |
|
currentParent = element; |
|
stack.push(element); |
|
} else { |
|
closeElement(element); |
|
} |
|
}, |
|
|
|
end: function end () { |
|
// remove trailing whitespace |
|
var element = stack[stack.length - 1]; |
|
var lastNode = element.children[element.children.length - 1]; |
|
if (lastNode && lastNode.type === 3 && lastNode.text === ' ' && !inPre) { |
|
element.children.pop(); |
|
} |
|
// pop stack |
|
stack.length -= 1; |
|
currentParent = stack[stack.length - 1]; |
|
closeElement(element); |
|
}, |
|
|
|
chars: function chars (text) { |
|
if (!currentParent) { |
|
if (true) { |
|
if (text === template) { |
|
warnOnce( |
|
'Component template requires a root element, rather than just text.' |
|
); |
|
} else if ((text = text.trim())) { |
|
warnOnce( |
|
("text \"" + text + "\" outside root element will be ignored.") |
|
); |
|
} |
|
} |
|
return |
|
} |
|
// IE textarea placeholder bug |
|
/* istanbul ignore if */ |
|
if (isIE && |
|
currentParent.tag === 'textarea' && |
|
currentParent.attrsMap.placeholder === text |
|
) { |
|
return |
|
} |
|
var children = currentParent.children; |
|
text = inPre || text.trim() |
|
? isTextTag(currentParent) ? text : decodeHTMLCached(text) |
|
// only preserve whitespace if its not right after a starting tag |
|
: preserveWhitespace && children.length ? ' ' : ''; |
|
if (text) { |
|
var res; |
|
if (!inVPre && text !== ' ' && (res = parseText(text, delimiters))) { |
|
children.push({ |
|
type: 2, |
|
expression: res.expression, |
|
tokens: res.tokens, |
|
text: text |
|
}); |
|
} else if (text !== ' ' || !children.length || children[children.length - 1].text !== ' ') { |
|
children.push({ |
|
type: 3, |
|
text: text |
|
}); |
|
} |
|
} |
|
}, |
|
comment: function comment (text) { |
|
currentParent.children.push({ |
|
type: 3, |
|
text: text, |
|
isComment: true |
|
}); |
|
} |
|
}); |
|
return root |
|
} |
|
|
|
function processPre (el) { |
|
if (getAndRemoveAttr(el, 'v-pre') != null) { |
|
el.pre = true; |
|
} |
|
} |
|
|
|
function processRawAttrs (el) { |
|
var l = el.attrsList.length; |
|
if (l) { |
|
var attrs = el.attrs = new Array(l); |
|
for (var i = 0; i < l; i++) { |
|
attrs[i] = { |
|
name: el.attrsList[i].name, |
|
value: JSON.stringify(el.attrsList[i].value) |
|
}; |
|
} |
|
} else if (!el.pre) { |
|
// non root node in pre blocks with no attributes |
|
el.plain = true; |
|
} |
|
} |
|
|
|
function processElement (element, options) { |
|
processKey(element); |
|
|
|
// determine whether this is a plain element after |
|
// removing structural attributes |
|
element.plain = !element.key && !element.attrsList.length; |
|
|
|
processRef(element); |
|
processSlot(element); |
|
processComponent(element); |
|
for (var i = 0; i < transforms.length; i++) { |
|
element = transforms[i](element, options) || element; |
|
} |
|
processAttrs(element); |
|
} |
|
|
|
function processKey (el) { |
|
var exp = getBindingAttr(el, 'key'); |
|
if (exp) { |
|
if ("development" !== 'production' && el.tag === 'template') { |
|
warn$2("<template> cannot be keyed. Place the key on real elements instead."); |
|
} |
|
el.key = exp; |
|
} |
|
} |
|
|
|
function processRef (el) { |
|
var ref = getBindingAttr(el, 'ref'); |
|
if (ref) { |
|
el.ref = ref; |
|
el.refInFor = checkInFor(el); |
|
} |
|
} |
|
|
|
function processFor (el) { |
|
var exp; |
|
if ((exp = getAndRemoveAttr(el, 'v-for'))) { |
|
var res = parseFor(exp); |
|
if (res) { |
|
extend(el, res); |
|
} else if (true) { |
|
warn$2( |
|
("Invalid v-for expression: " + exp) |
|
); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
function parseFor (exp) { |
|
var inMatch = exp.match(forAliasRE); |
|
if (!inMatch) { return } |
|
var res = {}; |
|
res.for = inMatch[2].trim(); |
|
var alias = inMatch[1].trim().replace(stripParensRE, ''); |
|
var iteratorMatch = alias.match(forIteratorRE); |
|
if (iteratorMatch) { |
|
res.alias = alias.replace(forIteratorRE, ''); |
|
res.iterator1 = iteratorMatch[1].trim(); |
|
if (iteratorMatch[2]) { |
|
res.iterator2 = iteratorMatch[2].trim(); |
|
} |
|
} else { |
|
res.alias = alias; |
|
} |
|
return res |
|
} |
|
|
|
function processIf (el) { |
|
var exp = getAndRemoveAttr(el, 'v-if'); |
|
if (exp) { |
|
el.if = exp; |
|
addIfCondition(el, { |
|
exp: exp, |
|
block: el |
|
}); |
|
} else { |
|
if (getAndRemoveAttr(el, 'v-else') != null) { |
|
el.else = true; |
|
} |
|
var elseif = getAndRemoveAttr(el, 'v-else-if'); |
|
if (elseif) { |
|
el.elseif = elseif; |
|
} |
|
} |
|
} |
|
|
|
function processIfConditions (el, parent) { |
|
var prev = findPrevElement(parent.children); |
|
if (prev && prev.if) { |
|
addIfCondition(prev, { |
|
exp: el.elseif, |
|
block: el |
|
}); |
|
} else if (true) { |
|
warn$2( |
|
"v-" + (el.elseif ? ('else-if="' + el.elseif + '"') : 'else') + " " + |
|
"used on element <" + (el.tag) + "> without corresponding v-if." |
|
); |
|
} |
|
} |
|
|
|
function findPrevElement (children) { |
|
var i = children.length; |
|
while (i--) { |
|
if (children[i].type === 1) { |
|
return children[i] |
|
} else { |
|
if ("development" !== 'production' && children[i].text !== ' ') { |
|
warn$2( |
|
"text \"" + (children[i].text.trim()) + "\" between v-if and v-else(-if) " + |
|
"will be ignored." |
|
); |
|
} |
|
children.pop(); |
|
} |
|
} |
|
} |
|
|
|
function addIfCondition (el, condition) { |
|
if (!el.ifConditions) { |
|
el.ifConditions = []; |
|
} |
|
el.ifConditions.push(condition); |
|
} |
|
|
|
function processOnce (el) { |
|
var once$$1 = getAndRemoveAttr(el, 'v-once'); |
|
if (once$$1 != null) { |
|
el.once = true; |
|
} |
|
} |
|
|
|
function processSlot (el) { |
|
if (el.tag === 'slot') { |
|
el.slotName = getBindingAttr(el, 'name'); |
|
if ("development" !== 'production' && el.key) { |
|
warn$2( |
|
"`key` does not work on <slot> because slots are abstract outlets " + |
|
"and can possibly expand into multiple elements. " + |
|
"Use the key on a wrapping element instead." |
|
); |
|
} |
|
} else { |
|
var slotScope; |
|
if (el.tag === 'template') { |
|
slotScope = getAndRemoveAttr(el, 'scope'); |
|
/* istanbul ignore if */ |
|
if ("development" !== 'production' && slotScope) { |
|
warn$2( |
|
"the \"scope\" attribute for scoped slots have been deprecated and " + |
|
"replaced by \"slot-scope\" since 2.5. The new \"slot-scope\" attribute " + |
|
"can also be used on plain elements in addition to <template> to " + |
|
"denote scoped slots.", |
|
true |
|
); |
|
} |
|
el.slotScope = slotScope || getAndRemoveAttr(el, 'slot-scope'); |
|
} else if ((slotScope = getAndRemoveAttr(el, 'slot-scope'))) { |
|
/* istanbul ignore if */ |
|
if ("development" !== 'production' && el.attrsMap['v-for']) { |
|
warn$2( |
|
"Ambiguous combined usage of slot-scope and v-for on <" + (el.tag) + "> " + |
|
"(v-for takes higher priority). Use a wrapper <template> for the " + |
|
"scoped slot to make it clearer.", |
|
true |
|
); |
|
} |
|
el.slotScope = slotScope; |
|
} |
|
var slotTarget = getBindingAttr(el, 'slot'); |
|
if (slotTarget) { |
|
el.slotTarget = slotTarget === '""' ? '"default"' : slotTarget; |
|
// preserve slot as an attribute for native shadow DOM compat |
|
// only for non-scoped slots. |
|
if (el.tag !== 'template' && !el.slotScope) { |
|
addAttr(el, 'slot', slotTarget); |
|
} |
|
} |
|
} |
|
} |
|
|
|
function processComponent (el) { |
|
var binding; |
|
if ((binding = getBindingAttr(el, 'is'))) { |
|
el.component = binding; |
|
} |
|
if (getAndRemoveAttr(el, 'inline-template') != null) { |
|
el.inlineTemplate = true; |
|
} |
|
} |
|
|
|
function processAttrs (el) { |
|
var list = el.attrsList; |
|
var i, l, name, rawName, value, modifiers, isProp; |
|
for (i = 0, l = list.length; i < l; i++) { |
|
name = rawName = list[i].name; |
|
value = list[i].value; |
|
if (dirRE.test(name)) { |
|
// mark element as dynamic |
|
el.hasBindings = true; |
|
// modifiers |
|
modifiers = parseModifiers(name); |
|
if (modifiers) { |
|
name = name.replace(modifierRE, ''); |
|
} |
|
if (bindRE.test(name)) { // v-bind |
|
name = name.replace(bindRE, ''); |
|
value = parseFilters(value); |
|
isProp = false; |
|
if (modifiers) { |
|
if (modifiers.prop) { |
|
isProp = true; |
|
name = camelize(name); |
|
if (name === 'innerHtml') { name = 'innerHTML'; } |
|
} |
|
if (modifiers.camel) { |
|
name = camelize(name); |
|
} |
|
if (modifiers.sync) { |
|
addHandler( |
|
el, |
|
("update:" + (camelize(name))), |
|
genAssignmentCode(value, "$event") |
|
); |
|
} |
|
} |
|
if (isProp || ( |
|
!el.component && platformMustUseProp(el.tag, el.attrsMap.type, name) |
|
)) { |
|
addProp(el, name, value); |
|
} else { |
|
addAttr(el, name, value); |
|
} |
|
} else if (onRE.test(name)) { // v-on |
|
name = name.replace(onRE, ''); |
|
addHandler(el, name, value, modifiers, false, warn$2); |
|
} else { // normal directives |
|
name = name.replace(dirRE, ''); |
|
// parse arg |
|
var argMatch = name.match(argRE); |
|
var arg = argMatch && argMatch[1]; |
|
if (arg) { |
|
name = name.slice(0, -(arg.length + 1)); |
|
} |
|
addDirective(el, name, rawName, value, arg, modifiers); |
|
if ("development" !== 'production' && name === 'model') { |
|
checkForAliasModel(el, value); |
|
} |
|
} |
|
} else { |
|
// literal attribute |
|
if (true) { |
|
var res = parseText(value, delimiters); |
|
if (res) { |
|
warn$2( |
|
name + "=\"" + value + "\": " + |
|
'Interpolation inside attributes has been removed. ' + |
|
'Use v-bind or the colon shorthand instead. For example, ' + |
|
'instead of <div id="{{ val }}">, use <div :id="val">.' |
|
); |
|
} |
|
} |
|
addAttr(el, name, JSON.stringify(value)); |
|
// #6887 firefox doesn't update muted state if set via attribute |
|
// even immediately after element creation |
|
if (!el.component && |
|
name === 'muted' && |
|
platformMustUseProp(el.tag, el.attrsMap.type, name)) { |
|
addProp(el, name, 'true'); |
|
} |
|
} |
|
} |
|
} |
|
|
|
function checkInFor (el) { |
|
var parent = el; |
|
while (parent) { |
|
if (parent.for !== undefined) { |
|
return true |
|
} |
|
parent = parent.parent; |
|
} |
|
return false |
|
} |
|
|
|
function parseModifiers (name) { |
|
var match = name.match(modifierRE); |
|
if (match) { |
|
var ret = {}; |
|
match.forEach(function (m) { ret[m.slice(1)] = true; }); |
|
return ret |
|
} |
|
} |
|
|
|
function makeAttrsMap (attrs) { |
|
var map = {}; |
|
for (var i = 0, l = attrs.length; i < l; i++) { |
|
if ( |
|
"development" !== 'production' && |
|
map[attrs[i].name] && !isIE && !isEdge |
|
) { |
|
warn$2('duplicate attribute: ' + attrs[i].name); |
|
} |
|
map[attrs[i].name] = attrs[i].value; |
|
} |
|
return map |
|
} |
|
|
|
// for script (e.g. type="x/template") or style, do not decode content |
|
function isTextTag (el) { |
|
return el.tag === 'script' || el.tag === 'style' |
|
} |
|
|
|
function isForbiddenTag (el) { |
|
return ( |
|
el.tag === 'style' || |
|
(el.tag === 'script' && ( |
|
!el.attrsMap.type || |
|
el.attrsMap.type === 'text/javascript' |
|
)) |
|
) |
|
} |
|
|
|
var ieNSBug = /^xmlns:NS\d+/; |
|
var ieNSPrefix = /^NS\d+:/; |
|
|
|
/* istanbul ignore next */ |
|
function guardIESVGBug (attrs) { |
|
var res = []; |
|
for (var i = 0; i < attrs.length; i++) { |
|
var attr = attrs[i]; |
|
if (!ieNSBug.test(attr.name)) { |
|
attr.name = attr.name.replace(ieNSPrefix, ''); |
|
res.push(attr); |
|
} |
|
} |
|
return res |
|
} |
|
|
|
function checkForAliasModel (el, value) { |
|
var _el = el; |
|
while (_el) { |
|
if (_el.for && _el.alias === value) { |
|
warn$2( |
|
"<" + (el.tag) + " v-model=\"" + value + "\">: " + |
|
"You are binding v-model directly to a v-for iteration alias. " + |
|
"This will not be able to modify the v-for source array because " + |
|
"writing to the alias is like modifying a function local variable. " + |
|
"Consider using an array of objects and use v-model on an object property instead." |
|
); |
|
} |
|
_el = _el.parent; |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
/** |
|
* Expand input[v-model] with dyanmic type bindings into v-if-else chains |
|
* Turn this: |
|
* <input v-model="data[type]" :type="type"> |
|
* into this: |
|
* <input v-if="type === 'checkbox'" type="checkbox" v-model="data[type]"> |
|
* <input v-else-if="type === 'radio'" type="radio" v-model="data[type]"> |
|
* <input v-else :type="type" v-model="data[type]"> |
|
*/ |
|
|
|
function preTransformNode (el, options) { |
|
if (el.tag === 'input') { |
|
var map = el.attrsMap; |
|
if (!map['v-model']) { |
|
return |
|
} |
|
|
|
var typeBinding; |
|
if (map[':type'] || map['v-bind:type']) { |
|
typeBinding = getBindingAttr(el, 'type'); |
|
} |
|
if (!map.type && !typeBinding && map['v-bind']) { |
|
typeBinding = "(" + (map['v-bind']) + ").type"; |
|
} |
|
|
|
if (typeBinding) { |
|
var ifCondition = getAndRemoveAttr(el, 'v-if', true); |
|
var ifConditionExtra = ifCondition ? ("&&(" + ifCondition + ")") : ""; |
|
var hasElse = getAndRemoveAttr(el, 'v-else', true) != null; |
|
var elseIfCondition = getAndRemoveAttr(el, 'v-else-if', true); |
|
// 1. checkbox |
|
var branch0 = cloneASTElement(el); |
|
// process for on the main node |
|
processFor(branch0); |
|
addRawAttr(branch0, 'type', 'checkbox'); |
|
processElement(branch0, options); |
|
branch0.processed = true; // prevent it from double-processed |
|
branch0.if = "(" + typeBinding + ")==='checkbox'" + ifConditionExtra; |
|
addIfCondition(branch0, { |
|
exp: branch0.if, |
|
block: branch0 |
|
}); |
|
// 2. add radio else-if condition |
|
var branch1 = cloneASTElement(el); |
|
getAndRemoveAttr(branch1, 'v-for', true); |
|
addRawAttr(branch1, 'type', 'radio'); |
|
processElement(branch1, options); |
|
addIfCondition(branch0, { |
|
exp: "(" + typeBinding + ")==='radio'" + ifConditionExtra, |
|
block: branch1 |
|
}); |
|
// 3. other |
|
var branch2 = cloneASTElement(el); |
|
getAndRemoveAttr(branch2, 'v-for', true); |
|
addRawAttr(branch2, ':type', typeBinding); |
|
processElement(branch2, options); |
|
addIfCondition(branch0, { |
|
exp: ifCondition, |
|
block: branch2 |
|
}); |
|
|
|
if (hasElse) { |
|
branch0.else = true; |
|
} else if (elseIfCondition) { |
|
branch0.elseif = elseIfCondition; |
|
} |
|
|
|
return branch0 |
|
} |
|
} |
|
} |
|
|
|
function cloneASTElement (el) { |
|
return createASTElement(el.tag, el.attrsList.slice(), el.parent) |
|
} |
|
|
|
var model$2 = { |
|
preTransformNode: preTransformNode |
|
} |
|
|
|
var modules$1 = [ |
|
klass$1, |
|
style$1, |
|
model$2 |
|
] |
|
|
|
/* */ |
|
|
|
function text (el, dir) { |
|
if (dir.value) { |
|
addProp(el, 'textContent', ("_s(" + (dir.value) + ")")); |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
function html (el, dir) { |
|
if (dir.value) { |
|
addProp(el, 'innerHTML', ("_s(" + (dir.value) + ")")); |
|
} |
|
} |
|
|
|
var directives$1 = { |
|
model: model, |
|
text: text, |
|
html: html |
|
} |
|
|
|
/* */ |
|
|
|
var baseOptions = { |
|
expectHTML: true, |
|
modules: modules$1, |
|
directives: directives$1, |
|
isPreTag: isPreTag, |
|
isUnaryTag: isUnaryTag, |
|
mustUseProp: mustUseProp, |
|
canBeLeftOpenTag: canBeLeftOpenTag, |
|
isReservedTag: isReservedTag, |
|
getTagNamespace: getTagNamespace, |
|
staticKeys: genStaticKeys(modules$1) |
|
}; |
|
|
|
/* */ |
|
|
|
var isStaticKey; |
|
var isPlatformReservedTag; |
|
|
|
var genStaticKeysCached = cached(genStaticKeys$1); |
|
|
|
/** |
|
* Goal of the optimizer: walk the generated template AST tree |
|
* and detect sub-trees that are purely static, i.e. parts of |
|
* the DOM that never needs to change. |
|
* |
|
* Once we detect these sub-trees, we can: |
|
* |
|
* 1. Hoist them into constants, so that we no longer need to |
|
* create fresh nodes for them on each re-render; |
|
* 2. Completely skip them in the patching process. |
|
*/ |
|
function optimize (root, options) { |
|
if (!root) { return } |
|
isStaticKey = genStaticKeysCached(options.staticKeys || ''); |
|
isPlatformReservedTag = options.isReservedTag || no; |
|
// first pass: mark all non-static nodes. |
|
markStatic$1(root); |
|
// second pass: mark static roots. |
|
markStaticRoots(root, false); |
|
} |
|
|
|
function genStaticKeys$1 (keys) { |
|
return makeMap( |
|
'type,tag,attrsList,attrsMap,plain,parent,children,attrs' + |
|
(keys ? ',' + keys : '') |
|
) |
|
} |
|
|
|
function markStatic$1 (node) { |
|
node.static = isStatic(node); |
|
if (node.type === 1) { |
|
// do not make component slot content static. this avoids |
|
// 1. components not able to mutate slot nodes |
|
// 2. static slot content fails for hot-reloading |
|
if ( |
|
!isPlatformReservedTag(node.tag) && |
|
node.tag !== 'slot' && |
|
node.attrsMap['inline-template'] == null |
|
) { |
|
return |
|
} |
|
for (var i = 0, l = node.children.length; i < l; i++) { |
|
var child = node.children[i]; |
|
markStatic$1(child); |
|
if (!child.static) { |
|
node.static = false; |
|
} |
|
} |
|
if (node.ifConditions) { |
|
for (var i$1 = 1, l$1 = node.ifConditions.length; i$1 < l$1; i$1++) { |
|
var block = node.ifConditions[i$1].block; |
|
markStatic$1(block); |
|
if (!block.static) { |
|
node.static = false; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
function markStaticRoots (node, isInFor) { |
|
if (node.type === 1) { |
|
if (node.static || node.once) { |
|
node.staticInFor = isInFor; |
|
} |
|
// For a node to qualify as a static root, it should have children that |
|
// are not just static text. Otherwise the cost of hoisting out will |
|
// outweigh the benefits and it's better off to just always render it fresh. |
|
if (node.static && node.children.length && !( |
|
node.children.length === 1 && |
|
node.children[0].type === 3 |
|
)) { |
|
node.staticRoot = true; |
|
return |
|
} else { |
|
node.staticRoot = false; |
|
} |
|
if (node.children) { |
|
for (var i = 0, l = node.children.length; i < l; i++) { |
|
markStaticRoots(node.children[i], isInFor || !!node.for); |
|
} |
|
} |
|
if (node.ifConditions) { |
|
for (var i$1 = 1, l$1 = node.ifConditions.length; i$1 < l$1; i$1++) { |
|
markStaticRoots(node.ifConditions[i$1].block, isInFor); |
|
} |
|
} |
|
} |
|
} |
|
|
|
function isStatic (node) { |
|
if (node.type === 2) { // expression |
|
return false |
|
} |
|
if (node.type === 3) { // text |
|
return true |
|
} |
|
return !!(node.pre || ( |
|
!node.hasBindings && // no dynamic bindings |
|
!node.if && !node.for && // not v-if or v-for or v-else |
|
!isBuiltInTag(node.tag) && // not a built-in |
|
isPlatformReservedTag(node.tag) && // not a component |
|
!isDirectChildOfTemplateFor(node) && |
|
Object.keys(node).every(isStaticKey) |
|
)) |
|
} |
|
|
|
function isDirectChildOfTemplateFor (node) { |
|
while (node.parent) { |
|
node = node.parent; |
|
if (node.tag !== 'template') { |
|
return false |
|
} |
|
if (node.for) { |
|
return true |
|
} |
|
} |
|
return false |
|
} |
|
|
|
/* */ |
|
|
|
var fnExpRE = /^([\w$_]+|\([^)]*?\))\s*=>|^function\s*\(/; |
|
var simplePathRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/; |
|
|
|
// KeyboardEvent.keyCode aliases |
|
var keyCodes = { |
|
esc: 27, |
|
tab: 9, |
|
enter: 13, |
|
space: 32, |
|
up: 38, |
|
left: 37, |
|
right: 39, |
|
down: 40, |
|
'delete': [8, 46] |
|
}; |
|
|
|
// KeyboardEvent.key aliases |
|
var keyNames = { |
|
esc: 'Escape', |
|
tab: 'Tab', |
|
enter: 'Enter', |
|
space: ' ', |
|
// #7806: IE11 uses key names without `Arrow` prefix for arrow keys. |
|
up: ['Up', 'ArrowUp'], |
|
left: ['Left', 'ArrowLeft'], |
|
right: ['Right', 'ArrowRight'], |
|
down: ['Down', 'ArrowDown'], |
|
'delete': ['Backspace', 'Delete'] |
|
}; |
|
|
|
// #4868: modifiers that prevent the execution of the listener |
|
// need to explicitly return null so that we can determine whether to remove |
|
// the listener for .once |
|
var genGuard = function (condition) { return ("if(" + condition + ")return null;"); }; |
|
|
|
var modifierCode = { |
|
stop: '$event.stopPropagation();', |
|
prevent: '$event.preventDefault();', |
|
self: genGuard("$event.target !== $event.currentTarget"), |
|
ctrl: genGuard("!$event.ctrlKey"), |
|
shift: genGuard("!$event.shiftKey"), |
|
alt: genGuard("!$event.altKey"), |
|
meta: genGuard("!$event.metaKey"), |
|
left: genGuard("'button' in $event && $event.button !== 0"), |
|
middle: genGuard("'button' in $event && $event.button !== 1"), |
|
right: genGuard("'button' in $event && $event.button !== 2") |
|
}; |
|
|
|
function genHandlers ( |
|
events, |
|
isNative, |
|
warn |
|
) { |
|
var res = isNative ? 'nativeOn:{' : 'on:{'; |
|
for (var name in events) { |
|
res += "\"" + name + "\":" + (genHandler(name, events[name])) + ","; |
|
} |
|
return res.slice(0, -1) + '}' |
|
} |
|
|
|
function genHandler ( |
|
name, |
|
handler |
|
) { |
|
if (!handler) { |
|
return 'function(){}' |
|
} |
|
|
|
if (Array.isArray(handler)) { |
|
return ("[" + (handler.map(function (handler) { return genHandler(name, handler); }).join(',')) + "]") |
|
} |
|
|
|
var isMethodPath = simplePathRE.test(handler.value); |
|
var isFunctionExpression = fnExpRE.test(handler.value); |
|
|
|
if (!handler.modifiers) { |
|
if (isMethodPath || isFunctionExpression) { |
|
return handler.value |
|
} |
|
/* istanbul ignore if */ |
|
return ("function($event){" + (handler.value) + "}") // inline statement |
|
} else { |
|
var code = ''; |
|
var genModifierCode = ''; |
|
var keys = []; |
|
for (var key in handler.modifiers) { |
|
if (modifierCode[key]) { |
|
genModifierCode += modifierCode[key]; |
|
// left/right |
|
if (keyCodes[key]) { |
|
keys.push(key); |
|
} |
|
} else if (key === 'exact') { |
|
var modifiers = (handler.modifiers); |
|
genModifierCode += genGuard( |
|
['ctrl', 'shift', 'alt', 'meta'] |
|
.filter(function (keyModifier) { return !modifiers[keyModifier]; }) |
|
.map(function (keyModifier) { return ("$event." + keyModifier + "Key"); }) |
|
.join('||') |
|
); |
|
} else { |
|
keys.push(key); |
|
} |
|
} |
|
if (keys.length) { |
|
code += genKeyFilter(keys); |
|
} |
|
// Make sure modifiers like prevent and stop get executed after key filtering |
|
if (genModifierCode) { |
|
code += genModifierCode; |
|
} |
|
var handlerCode = isMethodPath |
|
? ("return " + (handler.value) + "($event)") |
|
: isFunctionExpression |
|
? ("return (" + (handler.value) + ")($event)") |
|
: handler.value; |
|
/* istanbul ignore if */ |
|
return ("function($event){" + code + handlerCode + "}") |
|
} |
|
} |
|
|
|
function genKeyFilter (keys) { |
|
return ("if(!('button' in $event)&&" + (keys.map(genFilterCode).join('&&')) + ")return null;") |
|
} |
|
|
|
function genFilterCode (key) { |
|
var keyVal = parseInt(key, 10); |
|
if (keyVal) { |
|
return ("$event.keyCode!==" + keyVal) |
|
} |
|
var keyCode = keyCodes[key]; |
|
var keyName = keyNames[key]; |
|
return ( |
|
"_k($event.keyCode," + |
|
(JSON.stringify(key)) + "," + |
|
(JSON.stringify(keyCode)) + "," + |
|
"$event.key," + |
|
"" + (JSON.stringify(keyName)) + |
|
")" |
|
) |
|
} |
|
|
|
/* */ |
|
|
|
function on (el, dir) { |
|
if ("development" !== 'production' && dir.modifiers) { |
|
warn("v-on without argument does not support modifiers."); |
|
} |
|
el.wrapListeners = function (code) { return ("_g(" + code + "," + (dir.value) + ")"); }; |
|
} |
|
|
|
/* */ |
|
|
|
function bind$1 (el, dir) { |
|
el.wrapData = function (code) { |
|
return ("_b(" + code + ",'" + (el.tag) + "'," + (dir.value) + "," + (dir.modifiers && dir.modifiers.prop ? 'true' : 'false') + (dir.modifiers && dir.modifiers.sync ? ',true' : '') + ")") |
|
}; |
|
} |
|
|
|
/* */ |
|
|
|
var baseDirectives = { |
|
on: on, |
|
bind: bind$1, |
|
cloak: noop |
|
} |
|
|
|
/* */ |
|
|
|
var CodegenState = function CodegenState (options) { |
|
this.options = options; |
|
this.warn = options.warn || baseWarn; |
|
this.transforms = pluckModuleFunction(options.modules, 'transformCode'); |
|
this.dataGenFns = pluckModuleFunction(options.modules, 'genData'); |
|
this.directives = extend(extend({}, baseDirectives), options.directives); |
|
var isReservedTag = options.isReservedTag || no; |
|
this.maybeComponent = function (el) { return !isReservedTag(el.tag); }; |
|
this.onceId = 0; |
|
this.staticRenderFns = []; |
|
}; |
|
|
|
|
|
|
|
function generate ( |
|
ast, |
|
options |
|
) { |
|
var state = new CodegenState(options); |
|
var code = ast ? genElement(ast, state) : '_c("div")'; |
|
return { |
|
render: ("with(this){return " + code + "}"), |
|
staticRenderFns: state.staticRenderFns |
|
} |
|
} |
|
|
|
function genElement (el, state) { |
|
if (el.staticRoot && !el.staticProcessed) { |
|
return genStatic(el, state) |
|
} else if (el.once && !el.onceProcessed) { |
|
return genOnce(el, state) |
|
} else if (el.for && !el.forProcessed) { |
|
return genFor(el, state) |
|
} else if (el.if && !el.ifProcessed) { |
|
return genIf(el, state) |
|
} else if (el.tag === 'template' && !el.slotTarget) { |
|
return genChildren(el, state) || 'void 0' |
|
} else if (el.tag === 'slot') { |
|
return genSlot(el, state) |
|
} else { |
|
// component or element |
|
var code; |
|
if (el.component) { |
|
code = genComponent(el.component, el, state); |
|
} else { |
|
var data = el.plain ? undefined : genData$2(el, state); |
|
|
|
var children = el.inlineTemplate ? null : genChildren(el, state, true); |
|
code = "_c('" + (el.tag) + "'" + (data ? ("," + data) : '') + (children ? ("," + children) : '') + ")"; |
|
} |
|
// module transforms |
|
for (var i = 0; i < state.transforms.length; i++) { |
|
code = state.transforms[i](el, code); |
|
} |
|
return code |
|
} |
|
} |
|
|
|
// hoist static sub-trees out |
|
function genStatic (el, state) { |
|
el.staticProcessed = true; |
|
state.staticRenderFns.push(("with(this){return " + (genElement(el, state)) + "}")); |
|
return ("_m(" + (state.staticRenderFns.length - 1) + (el.staticInFor ? ',true' : '') + ")") |
|
} |
|
|
|
// v-once |
|
function genOnce (el, state) { |
|
el.onceProcessed = true; |
|
if (el.if && !el.ifProcessed) { |
|
return genIf(el, state) |
|
} else if (el.staticInFor) { |
|
var key = ''; |
|
var parent = el.parent; |
|
while (parent) { |
|
if (parent.for) { |
|
key = parent.key; |
|
break |
|
} |
|
parent = parent.parent; |
|
} |
|
if (!key) { |
|
"development" !== 'production' && state.warn( |
|
"v-once can only be used inside v-for that is keyed. " |
|
); |
|
return genElement(el, state) |
|
} |
|
return ("_o(" + (genElement(el, state)) + "," + (state.onceId++) + "," + key + ")") |
|
} else { |
|
return genStatic(el, state) |
|
} |
|
} |
|
|
|
function genIf ( |
|
el, |
|
state, |
|
altGen, |
|
altEmpty |
|
) { |
|
el.ifProcessed = true; // avoid recursion |
|
return genIfConditions(el.ifConditions.slice(), state, altGen, altEmpty) |
|
} |
|
|
|
function genIfConditions ( |
|
conditions, |
|
state, |
|
altGen, |
|
altEmpty |
|
) { |
|
if (!conditions.length) { |
|
return altEmpty || '_e()' |
|
} |
|
|
|
var condition = conditions.shift(); |
|
if (condition.exp) { |
|
return ("(" + (condition.exp) + ")?" + (genTernaryExp(condition.block)) + ":" + (genIfConditions(conditions, state, altGen, altEmpty))) |
|
} else { |
|
return ("" + (genTernaryExp(condition.block))) |
|
} |
|
|
|
// v-if with v-once should generate code like (a)?_m(0):_m(1) |
|
function genTernaryExp (el) { |
|
return altGen |
|
? altGen(el, state) |
|
: el.once |
|
? genOnce(el, state) |
|
: genElement(el, state) |
|
} |
|
} |
|
|
|
function genFor ( |
|
el, |
|
state, |
|
altGen, |
|
altHelper |
|
) { |
|
var exp = el.for; |
|
var alias = el.alias; |
|
var iterator1 = el.iterator1 ? ("," + (el.iterator1)) : ''; |
|
var iterator2 = el.iterator2 ? ("," + (el.iterator2)) : ''; |
|
|
|
if ("development" !== 'production' && |
|
state.maybeComponent(el) && |
|
el.tag !== 'slot' && |
|
el.tag !== 'template' && |
|
!el.key |
|
) { |
|
state.warn( |
|
"<" + (el.tag) + " v-for=\"" + alias + " in " + exp + "\">: component lists rendered with " + |
|
"v-for should have explicit keys. " + |
|
"See https://vuejs.org/guide/list.html#key for more info.", |
|
true /* tip */ |
|
); |
|
} |
|
|
|
el.forProcessed = true; // avoid recursion |
|
return (altHelper || '_l') + "((" + exp + ")," + |
|
"function(" + alias + iterator1 + iterator2 + "){" + |
|
"return " + ((altGen || genElement)(el, state)) + |
|
'})' |
|
} |
|
|
|
function genData$2 (el, state) { |
|
var data = '{'; |
|
|
|
// directives first. |
|
// directives may mutate the el's other properties before they are generated. |
|
var dirs = genDirectives(el, state); |
|
if (dirs) { data += dirs + ','; } |
|
|
|
// key |
|
if (el.key) { |
|
data += "key:" + (el.key) + ","; |
|
} |
|
// ref |
|
if (el.ref) { |
|
data += "ref:" + (el.ref) + ","; |
|
} |
|
if (el.refInFor) { |
|
data += "refInFor:true,"; |
|
} |
|
// pre |
|
if (el.pre) { |
|
data += "pre:true,"; |
|
} |
|
// record original tag name for components using "is" attribute |
|
if (el.component) { |
|
data += "tag:\"" + (el.tag) + "\","; |
|
} |
|
// module data generation functions |
|
for (var i = 0; i < state.dataGenFns.length; i++) { |
|
data += state.dataGenFns[i](el); |
|
} |
|
// attributes |
|
if (el.attrs) { |
|
data += "attrs:{" + (genProps(el.attrs)) + "},"; |
|
} |
|
// DOM props |
|
if (el.props) { |
|
data += "domProps:{" + (genProps(el.props)) + "},"; |
|
} |
|
// event handlers |
|
if (el.events) { |
|
data += (genHandlers(el.events, false, state.warn)) + ","; |
|
} |
|
if (el.nativeEvents) { |
|
data += (genHandlers(el.nativeEvents, true, state.warn)) + ","; |
|
} |
|
// slot target |
|
// only for non-scoped slots |
|
if (el.slotTarget && !el.slotScope) { |
|
data += "slot:" + (el.slotTarget) + ","; |
|
} |
|
// scoped slots |
|
if (el.scopedSlots) { |
|
data += (genScopedSlots(el.scopedSlots, state)) + ","; |
|
} |
|
// component v-model |
|
if (el.model) { |
|
data += "model:{value:" + (el.model.value) + ",callback:" + (el.model.callback) + ",expression:" + (el.model.expression) + "},"; |
|
} |
|
// inline-template |
|
if (el.inlineTemplate) { |
|
var inlineTemplate = genInlineTemplate(el, state); |
|
if (inlineTemplate) { |
|
data += inlineTemplate + ","; |
|
} |
|
} |
|
data = data.replace(/,$/, '') + '}'; |
|
// v-bind data wrap |
|
if (el.wrapData) { |
|
data = el.wrapData(data); |
|
} |
|
// v-on data wrap |
|
if (el.wrapListeners) { |
|
data = el.wrapListeners(data); |
|
} |
|
return data |
|
} |
|
|
|
function genDirectives (el, state) { |
|
var dirs = el.directives; |
|
if (!dirs) { return } |
|
var res = 'directives:['; |
|
var hasRuntime = false; |
|
var i, l, dir, needRuntime; |
|
for (i = 0, l = dirs.length; i < l; i++) { |
|
dir = dirs[i]; |
|
needRuntime = true; |
|
var gen = state.directives[dir.name]; |
|
if (gen) { |
|
// compile-time directive that manipulates AST. |
|
// returns true if it also needs a runtime counterpart. |
|
needRuntime = !!gen(el, dir, state.warn); |
|
} |
|
if (needRuntime) { |
|
hasRuntime = true; |
|
res += "{name:\"" + (dir.name) + "\",rawName:\"" + (dir.rawName) + "\"" + (dir.value ? (",value:(" + (dir.value) + "),expression:" + (JSON.stringify(dir.value))) : '') + (dir.arg ? (",arg:\"" + (dir.arg) + "\"") : '') + (dir.modifiers ? (",modifiers:" + (JSON.stringify(dir.modifiers))) : '') + "},"; |
|
} |
|
} |
|
if (hasRuntime) { |
|
return res.slice(0, -1) + ']' |
|
} |
|
} |
|
|
|
function genInlineTemplate (el, state) { |
|
var ast = el.children[0]; |
|
if ("development" !== 'production' && ( |
|
el.children.length !== 1 || ast.type !== 1 |
|
)) { |
|
state.warn('Inline-template components must have exactly one child element.'); |
|
} |
|
if (ast.type === 1) { |
|
var inlineRenderFns = generate(ast, state.options); |
|
return ("inlineTemplate:{render:function(){" + (inlineRenderFns.render) + "},staticRenderFns:[" + (inlineRenderFns.staticRenderFns.map(function (code) { return ("function(){" + code + "}"); }).join(',')) + "]}") |
|
} |
|
} |
|
|
|
function genScopedSlots ( |
|
slots, |
|
state |
|
) { |
|
return ("scopedSlots:_u([" + (Object.keys(slots).map(function (key) { |
|
return genScopedSlot(key, slots[key], state) |
|
}).join(',')) + "])") |
|
} |
|
|
|
function genScopedSlot ( |
|
key, |
|
el, |
|
state |
|
) { |
|
if (el.for && !el.forProcessed) { |
|
return genForScopedSlot(key, el, state) |
|
} |
|
var fn = "function(" + (String(el.slotScope)) + "){" + |
|
"return " + (el.tag === 'template' |
|
? el.if |
|
? ((el.if) + "?" + (genChildren(el, state) || 'undefined') + ":undefined") |
|
: genChildren(el, state) || 'undefined' |
|
: genElement(el, state)) + "}"; |
|
return ("{key:" + key + ",fn:" + fn + "}") |
|
} |
|
|
|
function genForScopedSlot ( |
|
key, |
|
el, |
|
state |
|
) { |
|
var exp = el.for; |
|
var alias = el.alias; |
|
var iterator1 = el.iterator1 ? ("," + (el.iterator1)) : ''; |
|
var iterator2 = el.iterator2 ? ("," + (el.iterator2)) : ''; |
|
el.forProcessed = true; // avoid recursion |
|
return "_l((" + exp + ")," + |
|
"function(" + alias + iterator1 + iterator2 + "){" + |
|
"return " + (genScopedSlot(key, el, state)) + |
|
'})' |
|
} |
|
|
|
function genChildren ( |
|
el, |
|
state, |
|
checkSkip, |
|
altGenElement, |
|
altGenNode |
|
) { |
|
var children = el.children; |
|
if (children.length) { |
|
var el$1 = children[0]; |
|
// optimize single v-for |
|
if (children.length === 1 && |
|
el$1.for && |
|
el$1.tag !== 'template' && |
|
el$1.tag !== 'slot' |
|
) { |
|
return (altGenElement || genElement)(el$1, state) |
|
} |
|
var normalizationType = checkSkip |
|
? getNormalizationType(children, state.maybeComponent) |
|
: 0; |
|
var gen = altGenNode || genNode; |
|
return ("[" + (children.map(function (c) { return gen(c, state); }).join(',')) + "]" + (normalizationType ? ("," + normalizationType) : '')) |
|
} |
|
} |
|
|
|
// determine the normalization needed for the children array. |
|
// 0: no normalization needed |
|
// 1: simple normalization needed (possible 1-level deep nested array) |
|
// 2: full normalization needed |
|
function getNormalizationType ( |
|
children, |
|
maybeComponent |
|
) { |
|
var res = 0; |
|
for (var i = 0; i < children.length; i++) { |
|
var el = children[i]; |
|
if (el.type !== 1) { |
|
continue |
|
} |
|
if (needsNormalization(el) || |
|
(el.ifConditions && el.ifConditions.some(function (c) { return needsNormalization(c.block); }))) { |
|
res = 2; |
|
break |
|
} |
|
if (maybeComponent(el) || |
|
(el.ifConditions && el.ifConditions.some(function (c) { return maybeComponent(c.block); }))) { |
|
res = 1; |
|
} |
|
} |
|
return res |
|
} |
|
|
|
function needsNormalization (el) { |
|
return el.for !== undefined || el.tag === 'template' || el.tag === 'slot' |
|
} |
|
|
|
function genNode (node, state) { |
|
if (node.type === 1) { |
|
return genElement(node, state) |
|
} if (node.type === 3 && node.isComment) { |
|
return genComment(node) |
|
} else { |
|
return genText(node) |
|
} |
|
} |
|
|
|
function genText (text) { |
|
return ("_v(" + (text.type === 2 |
|
? text.expression // no need for () because already wrapped in _s() |
|
: transformSpecialNewlines(JSON.stringify(text.text))) + ")") |
|
} |
|
|
|
function genComment (comment) { |
|
return ("_e(" + (JSON.stringify(comment.text)) + ")") |
|
} |
|
|
|
function genSlot (el, state) { |
|
var slotName = el.slotName || '"default"'; |
|
var children = genChildren(el, state); |
|
var res = "_t(" + slotName + (children ? ("," + children) : ''); |
|
var attrs = el.attrs && ("{" + (el.attrs.map(function (a) { return ((camelize(a.name)) + ":" + (a.value)); }).join(',')) + "}"); |
|
var bind$$1 = el.attrsMap['v-bind']; |
|
if ((attrs || bind$$1) && !children) { |
|
res += ",null"; |
|
} |
|
if (attrs) { |
|
res += "," + attrs; |
|
} |
|
if (bind$$1) { |
|
res += (attrs ? '' : ',null') + "," + bind$$1; |
|
} |
|
return res + ')' |
|
} |
|
|
|
// componentName is el.component, take it as argument to shun flow's pessimistic refinement |
|
function genComponent ( |
|
componentName, |
|
el, |
|
state |
|
) { |
|
var children = el.inlineTemplate ? null : genChildren(el, state, true); |
|
return ("_c(" + componentName + "," + (genData$2(el, state)) + (children ? ("," + children) : '') + ")") |
|
} |
|
|
|
function genProps (props) { |
|
var res = ''; |
|
for (var i = 0; i < props.length; i++) { |
|
var prop = props[i]; |
|
/* istanbul ignore if */ |
|
{ |
|
res += "\"" + (prop.name) + "\":" + (transformSpecialNewlines(prop.value)) + ","; |
|
} |
|
} |
|
return res.slice(0, -1) |
|
} |
|
|
|
// #3895, #4268 |
|
function transformSpecialNewlines (text) { |
|
return text |
|
.replace(/\u2028/g, '\\u2028') |
|
.replace(/\u2029/g, '\\u2029') |
|
} |
|
|
|
/* */ |
|
|
|
// these keywords should not appear inside expressions, but operators like |
|
// typeof, instanceof and in are allowed |
|
var prohibitedKeywordRE = new RegExp('\\b' + ( |
|
'do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' + |
|
'super,throw,while,yield,delete,export,import,return,switch,default,' + |
|
'extends,finally,continue,debugger,function,arguments' |
|
).split(',').join('\\b|\\b') + '\\b'); |
|
|
|
// these unary operators should not be used as property/method names |
|
var unaryOperatorsRE = new RegExp('\\b' + ( |
|
'delete,typeof,void' |
|
).split(',').join('\\s*\\([^\\)]*\\)|\\b') + '\\s*\\([^\\)]*\\)'); |
|
|
|
// strip strings in expressions |
|
var stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g; |
|
|
|
// detect problematic expressions in a template |
|
function detectErrors (ast) { |
|
var errors = []; |
|
if (ast) { |
|
checkNode(ast, errors); |
|
} |
|
return errors |
|
} |
|
|
|
function checkNode (node, errors) { |
|
if (node.type === 1) { |
|
for (var name in node.attrsMap) { |
|
if (dirRE.test(name)) { |
|
var value = node.attrsMap[name]; |
|
if (value) { |
|
if (name === 'v-for') { |
|
checkFor(node, ("v-for=\"" + value + "\""), errors); |
|
} else if (onRE.test(name)) { |
|
checkEvent(value, (name + "=\"" + value + "\""), errors); |
|
} else { |
|
checkExpression(value, (name + "=\"" + value + "\""), errors); |
|
} |
|
} |
|
} |
|
} |
|
if (node.children) { |
|
for (var i = 0; i < node.children.length; i++) { |
|
checkNode(node.children[i], errors); |
|
} |
|
} |
|
} else if (node.type === 2) { |
|
checkExpression(node.expression, node.text, errors); |
|
} |
|
} |
|
|
|
function checkEvent (exp, text, errors) { |
|
var stipped = exp.replace(stripStringRE, ''); |
|
var keywordMatch = stipped.match(unaryOperatorsRE); |
|
if (keywordMatch && stipped.charAt(keywordMatch.index - 1) !== '$') { |
|
errors.push( |
|
"avoid using JavaScript unary operator as property name: " + |
|
"\"" + (keywordMatch[0]) + "\" in expression " + (text.trim()) |
|
); |
|
} |
|
checkExpression(exp, text, errors); |
|
} |
|
|
|
function checkFor (node, text, errors) { |
|
checkExpression(node.for || '', text, errors); |
|
checkIdentifier(node.alias, 'v-for alias', text, errors); |
|
checkIdentifier(node.iterator1, 'v-for iterator', text, errors); |
|
checkIdentifier(node.iterator2, 'v-for iterator', text, errors); |
|
} |
|
|
|
function checkIdentifier ( |
|
ident, |
|
type, |
|
text, |
|
errors |
|
) { |
|
if (typeof ident === 'string') { |
|
try { |
|
new Function(("var " + ident + "=_")); |
|
} catch (e) { |
|
errors.push(("invalid " + type + " \"" + ident + "\" in expression: " + (text.trim()))); |
|
} |
|
} |
|
} |
|
|
|
function checkExpression (exp, text, errors) { |
|
try { |
|
new Function(("return " + exp)); |
|
} catch (e) { |
|
var keywordMatch = exp.replace(stripStringRE, '').match(prohibitedKeywordRE); |
|
if (keywordMatch) { |
|
errors.push( |
|
"avoid using JavaScript keyword as property name: " + |
|
"\"" + (keywordMatch[0]) + "\"\n Raw expression: " + (text.trim()) |
|
); |
|
} else { |
|
errors.push( |
|
"invalid expression: " + (e.message) + " in\n\n" + |
|
" " + exp + "\n\n" + |
|
" Raw expression: " + (text.trim()) + "\n" |
|
); |
|
} |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
function createFunction (code, errors) { |
|
try { |
|
return new Function(code) |
|
} catch (err) { |
|
errors.push({ err: err, code: code }); |
|
return noop |
|
} |
|
} |
|
|
|
function createCompileToFunctionFn (compile) { |
|
var cache = Object.create(null); |
|
|
|
return function compileToFunctions ( |
|
template, |
|
options, |
|
vm |
|
) { |
|
options = extend({}, options); |
|
var warn$$1 = options.warn || warn; |
|
delete options.warn; |
|
|
|
/* istanbul ignore if */ |
|
if (true) { |
|
// detect possible CSP restriction |
|
try { |
|
new Function('return 1'); |
|
} catch (e) { |
|
if (e.toString().match(/unsafe-eval|CSP/)) { |
|
warn$$1( |
|
'It seems you are using the standalone build of Vue.js in an ' + |
|
'environment with Content Security Policy that prohibits unsafe-eval. ' + |
|
'The template compiler cannot work in this environment. Consider ' + |
|
'relaxing the policy to allow unsafe-eval or pre-compiling your ' + |
|
'templates into render functions.' |
|
); |
|
} |
|
} |
|
} |
|
|
|
// check cache |
|
var key = options.delimiters |
|
? String(options.delimiters) + template |
|
: template; |
|
if (cache[key]) { |
|
return cache[key] |
|
} |
|
|
|
// compile |
|
var compiled = compile(template, options); |
|
|
|
// check compilation errors/tips |
|
if (true) { |
|
if (compiled.errors && compiled.errors.length) { |
|
warn$$1( |
|
"Error compiling template:\n\n" + template + "\n\n" + |
|
compiled.errors.map(function (e) { return ("- " + e); }).join('\n') + '\n', |
|
vm |
|
); |
|
} |
|
if (compiled.tips && compiled.tips.length) { |
|
compiled.tips.forEach(function (msg) { return tip(msg, vm); }); |
|
} |
|
} |
|
|
|
// turn code into functions |
|
var res = {}; |
|
var fnGenErrors = []; |
|
res.render = createFunction(compiled.render, fnGenErrors); |
|
res.staticRenderFns = compiled.staticRenderFns.map(function (code) { |
|
return createFunction(code, fnGenErrors) |
|
}); |
|
|
|
// check function generation errors. |
|
// this should only happen if there is a bug in the compiler itself. |
|
// mostly for codegen development use |
|
/* istanbul ignore if */ |
|
if (true) { |
|
if ((!compiled.errors || !compiled.errors.length) && fnGenErrors.length) { |
|
warn$$1( |
|
"Failed to generate render function:\n\n" + |
|
fnGenErrors.map(function (ref) { |
|
var err = ref.err; |
|
var code = ref.code; |
|
|
|
return ((err.toString()) + " in\n\n" + code + "\n"); |
|
}).join('\n'), |
|
vm |
|
); |
|
} |
|
} |
|
|
|
return (cache[key] = res) |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
function createCompilerCreator (baseCompile) { |
|
return function createCompiler (baseOptions) { |
|
function compile ( |
|
template, |
|
options |
|
) { |
|
var finalOptions = Object.create(baseOptions); |
|
var errors = []; |
|
var tips = []; |
|
finalOptions.warn = function (msg, tip) { |
|
(tip ? tips : errors).push(msg); |
|
}; |
|
|
|
if (options) { |
|
// merge custom modules |
|
if (options.modules) { |
|
finalOptions.modules = |
|
(baseOptions.modules || []).concat(options.modules); |
|
} |
|
// merge custom directives |
|
if (options.directives) { |
|
finalOptions.directives = extend( |
|
Object.create(baseOptions.directives || null), |
|
options.directives |
|
); |
|
} |
|
// copy other options |
|
for (var key in options) { |
|
if (key !== 'modules' && key !== 'directives') { |
|
finalOptions[key] = options[key]; |
|
} |
|
} |
|
} |
|
|
|
var compiled = baseCompile(template, finalOptions); |
|
if (true) { |
|
errors.push.apply(errors, detectErrors(compiled.ast)); |
|
} |
|
compiled.errors = errors; |
|
compiled.tips = tips; |
|
return compiled |
|
} |
|
|
|
return { |
|
compile: compile, |
|
compileToFunctions: createCompileToFunctionFn(compile) |
|
} |
|
} |
|
} |
|
|
|
/* */ |
|
|
|
// `createCompilerCreator` allows creating compilers that use alternative |
|
// parser/optimizer/codegen, e.g the SSR optimizing compiler. |
|
// Here we just export a default compiler using the default parts. |
|
var createCompiler = createCompilerCreator(function baseCompile ( |
|
template, |
|
options |
|
) { |
|
var ast = parse(template.trim(), options); |
|
if (options.optimize !== false) { |
|
optimize(ast, options); |
|
} |
|
var code = generate(ast, options); |
|
return { |
|
ast: ast, |
|
render: code.render, |
|
staticRenderFns: code.staticRenderFns |
|
} |
|
}); |
|
|
|
/* */ |
|
|
|
var ref$1 = createCompiler(baseOptions); |
|
var compileToFunctions = ref$1.compileToFunctions; |
|
|
|
/* */ |
|
|
|
// check whether current browser encodes a char inside attribute values |
|
var div; |
|
function getShouldDecode (href) { |
|
div = div || document.createElement('div'); |
|
div.innerHTML = href ? "<a href=\"\n\"/>" : "<div a=\"\n\"/>"; |
|
return div.innerHTML.indexOf(' ') > 0 |
|
} |
|
|
|
// #3663: IE encodes newlines inside attribute values while other browsers don't |
|
var shouldDecodeNewlines = inBrowser ? getShouldDecode(false) : false; |
|
// #6828: chrome encodes content in a[href] |
|
var shouldDecodeNewlinesForHref = inBrowser ? getShouldDecode(true) : false; |
|
|
|
/* */ |
|
|
|
var idToTemplate = cached(function (id) { |
|
var el = query(id); |
|
return el && el.innerHTML |
|
}); |
|
|
|
var mount = Vue.prototype.$mount; |
|
Vue.prototype.$mount = function ( |
|
el, |
|
hydrating |
|
) { |
|
el = el && query(el); |
|
|
|
/* istanbul ignore if */ |
|
if (el === document.body || el === document.documentElement) { |
|
"development" !== 'production' && warn( |
|
"Do not mount Vue to <html> or <body> - mount to normal elements instead." |
|
); |
|
return this |
|
} |
|
|
|
var options = this.$options; |
|
// resolve template/el and convert to render function |
|
if (!options.render) { |
|
var template = options.template; |
|
if (template) { |
|
if (typeof template === 'string') { |
|
if (template.charAt(0) === '#') { |
|
template = idToTemplate(template); |
|
/* istanbul ignore if */ |
|
if ("development" !== 'production' && !template) { |
|
warn( |
|
("Template element not found or is empty: " + (options.template)), |
|
this |
|
); |
|
} |
|
} |
|
} else if (template.nodeType) { |
|
template = template.innerHTML; |
|
} else { |
|
if (true) { |
|
warn('invalid template option:' + template, this); |
|
} |
|
return this |
|
} |
|
} else if (el) { |
|
template = getOuterHTML(el); |
|
} |
|
if (template) { |
|
/* istanbul ignore if */ |
|
if ("development" !== 'production' && config.performance && mark) { |
|
mark('compile'); |
|
} |
|
|
|
var ref = compileToFunctions(template, { |
|
shouldDecodeNewlines: shouldDecodeNewlines, |
|
shouldDecodeNewlinesForHref: shouldDecodeNewlinesForHref, |
|
delimiters: options.delimiters, |
|
comments: options.comments |
|
}, this); |
|
var render = ref.render; |
|
var staticRenderFns = ref.staticRenderFns; |
|
options.render = render; |
|
options.staticRenderFns = staticRenderFns; |
|
|
|
/* istanbul ignore if */ |
|
if ("development" !== 'production' && config.performance && mark) { |
|
mark('compile end'); |
|
measure(("vue " + (this._name) + " compile"), 'compile', 'compile end'); |
|
} |
|
} |
|
} |
|
return mount.call(this, el, hydrating) |
|
}; |
|
|
|
/** |
|
* Get outerHTML of elements, taking care |
|
* of SVG elements in IE as well. |
|
*/ |
|
function getOuterHTML (el) { |
|
if (el.outerHTML) { |
|
return el.outerHTML |
|
} else { |
|
var container = document.createElement('div'); |
|
container.appendChild(el.cloneNode(true)); |
|
return container.innerHTML |
|
} |
|
} |
|
|
|
Vue.compile = compileToFunctions; |
|
|
|
module.exports = Vue; |
|
|
|
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1), __webpack_require__(37).setImmediate)) |
|
|
|
/***/ }), |
|
/* 37 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
/* WEBPACK VAR INJECTION */(function(global) {var scope = (typeof global !== "undefined" && global) || |
|
(typeof self !== "undefined" && self) || |
|
window; |
|
var apply = Function.prototype.apply; |
|
|
|
// DOM APIs, for completeness |
|
|
|
exports.setTimeout = function() { |
|
return new Timeout(apply.call(setTimeout, scope, arguments), clearTimeout); |
|
}; |
|
exports.setInterval = function() { |
|
return new Timeout(apply.call(setInterval, scope, arguments), clearInterval); |
|
}; |
|
exports.clearTimeout = |
|
exports.clearInterval = function(timeout) { |
|
if (timeout) { |
|
timeout.close(); |
|
} |
|
}; |
|
|
|
function Timeout(id, clearFn) { |
|
this._id = id; |
|
this._clearFn = clearFn; |
|
} |
|
Timeout.prototype.unref = Timeout.prototype.ref = function() {}; |
|
Timeout.prototype.close = function() { |
|
this._clearFn.call(scope, this._id); |
|
}; |
|
|
|
// Does not start the time, just sets up the members needed. |
|
exports.enroll = function(item, msecs) { |
|
clearTimeout(item._idleTimeoutId); |
|
item._idleTimeout = msecs; |
|
}; |
|
|
|
exports.unenroll = function(item) { |
|
clearTimeout(item._idleTimeoutId); |
|
item._idleTimeout = -1; |
|
}; |
|
|
|
exports._unrefActive = exports.active = function(item) { |
|
clearTimeout(item._idleTimeoutId); |
|
|
|
var msecs = item._idleTimeout; |
|
if (msecs >= 0) { |
|
item._idleTimeoutId = setTimeout(function onTimeout() { |
|
if (item._onTimeout) |
|
item._onTimeout(); |
|
}, msecs); |
|
} |
|
}; |
|
|
|
// setimmediate attaches itself to the global object |
|
__webpack_require__(38); |
|
// On some exotic environments, it's not clear which object `setimmediate` was |
|
// able to install onto. Search each possibility in the same order as the |
|
// `setimmediate` library. |
|
exports.setImmediate = (typeof self !== "undefined" && self.setImmediate) || |
|
(typeof global !== "undefined" && global.setImmediate) || |
|
(this && this.setImmediate); |
|
exports.clearImmediate = (typeof self !== "undefined" && self.clearImmediate) || |
|
(typeof global !== "undefined" && global.clearImmediate) || |
|
(this && this.clearImmediate); |
|
|
|
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) |
|
|
|
/***/ }), |
|
/* 38 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
/* WEBPACK VAR INJECTION */(function(global, process) {(function (global, undefined) { |
|
"use strict"; |
|
|
|
if (global.setImmediate) { |
|
return; |
|
} |
|
|
|
var nextHandle = 1; // Spec says greater than zero |
|
var tasksByHandle = {}; |
|
var currentlyRunningATask = false; |
|
var doc = global.document; |
|
var registerImmediate; |
|
|
|
function setImmediate(callback) { |
|
// Callback can either be a function or a string |
|
if (typeof callback !== "function") { |
|
callback = new Function("" + callback); |
|
} |
|
// Copy function arguments |
|
var args = new Array(arguments.length - 1); |
|
for (var i = 0; i < args.length; i++) { |
|
args[i] = arguments[i + 1]; |
|
} |
|
// Store and register the task |
|
var task = { callback: callback, args: args }; |
|
tasksByHandle[nextHandle] = task; |
|
registerImmediate(nextHandle); |
|
return nextHandle++; |
|
} |
|
|
|
function clearImmediate(handle) { |
|
delete tasksByHandle[handle]; |
|
} |
|
|
|
function run(task) { |
|
var callback = task.callback; |
|
var args = task.args; |
|
switch (args.length) { |
|
case 0: |
|
callback(); |
|
break; |
|
case 1: |
|
callback(args[0]); |
|
break; |
|
case 2: |
|
callback(args[0], args[1]); |
|
break; |
|
case 3: |
|
callback(args[0], args[1], args[2]); |
|
break; |
|
default: |
|
callback.apply(undefined, args); |
|
break; |
|
} |
|
} |
|
|
|
function runIfPresent(handle) { |
|
// From the spec: "Wait until any invocations of this algorithm started before this one have completed." |
|
// So if we're currently running a task, we'll need to delay this invocation. |
|
if (currentlyRunningATask) { |
|
// Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a |
|
// "too much recursion" error. |
|
setTimeout(runIfPresent, 0, handle); |
|
} else { |
|
var task = tasksByHandle[handle]; |
|
if (task) { |
|
currentlyRunningATask = true; |
|
try { |
|
run(task); |
|
} finally { |
|
clearImmediate(handle); |
|
currentlyRunningATask = false; |
|
} |
|
} |
|
} |
|
} |
|
|
|
function installNextTickImplementation() { |
|
registerImmediate = function(handle) { |
|
process.nextTick(function () { runIfPresent(handle); }); |
|
}; |
|
} |
|
|
|
function canUsePostMessage() { |
|
// The test against `importScripts` prevents this implementation from being installed inside a web worker, |
|
// where `global.postMessage` means something completely different and can't be used for this purpose. |
|
if (global.postMessage && !global.importScripts) { |
|
var postMessageIsAsynchronous = true; |
|
var oldOnMessage = global.onmessage; |
|
global.onmessage = function() { |
|
postMessageIsAsynchronous = false; |
|
}; |
|
global.postMessage("", "*"); |
|
global.onmessage = oldOnMessage; |
|
return postMessageIsAsynchronous; |
|
} |
|
} |
|
|
|
function installPostMessageImplementation() { |
|
// Installs an event handler on `global` for the `message` event: see |
|
// * https://developer.mozilla.org/en/DOM/window.postMessage |
|
// * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages |
|
|
|
var messagePrefix = "setImmediate$" + Math.random() + "$"; |
|
var onGlobalMessage = function(event) { |
|
if (event.source === global && |
|
typeof event.data === "string" && |
|
event.data.indexOf(messagePrefix) === 0) { |
|
runIfPresent(+event.data.slice(messagePrefix.length)); |
|
} |
|
}; |
|
|
|
if (global.addEventListener) { |
|
global.addEventListener("message", onGlobalMessage, false); |
|
} else { |
|
global.attachEvent("onmessage", onGlobalMessage); |
|
} |
|
|
|
registerImmediate = function(handle) { |
|
global.postMessage(messagePrefix + handle, "*"); |
|
}; |
|
} |
|
|
|
function installMessageChannelImplementation() { |
|
var channel = new MessageChannel(); |
|
channel.port1.onmessage = function(event) { |
|
var handle = event.data; |
|
runIfPresent(handle); |
|
}; |
|
|
|
registerImmediate = function(handle) { |
|
channel.port2.postMessage(handle); |
|
}; |
|
} |
|
|
|
function installReadyStateChangeImplementation() { |
|
var html = doc.documentElement; |
|
registerImmediate = function(handle) { |
|
// Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted |
|
// into the document. Do so, thus queuing up the task. Remember to clean up once it's been called. |
|
var script = doc.createElement("script"); |
|
script.onreadystatechange = function () { |
|
runIfPresent(handle); |
|
script.onreadystatechange = null; |
|
html.removeChild(script); |
|
script = null; |
|
}; |
|
html.appendChild(script); |
|
}; |
|
} |
|
|
|
function installSetTimeoutImplementation() { |
|
registerImmediate = function(handle) { |
|
setTimeout(runIfPresent, 0, handle); |
|
}; |
|
} |
|
|
|
// If supported, we should attach to the prototype of global, since that is where setTimeout et al. live. |
|
var attachTo = Object.getPrototypeOf && Object.getPrototypeOf(global); |
|
attachTo = attachTo && attachTo.setTimeout ? attachTo : global; |
|
|
|
// Don't get fooled by e.g. browserify environments. |
|
if ({}.toString.call(global.process) === "[object process]") { |
|
// For Node.js before 0.9 |
|
installNextTickImplementation(); |
|
|
|
} else if (canUsePostMessage()) { |
|
// For non-IE10 modern browsers |
|
installPostMessageImplementation(); |
|
|
|
} else if (global.MessageChannel) { |
|
// For web workers, where supported |
|
installMessageChannelImplementation(); |
|
|
|
} else if (doc && "onreadystatechange" in doc.createElement("script")) { |
|
// For IE 6–8 |
|
installReadyStateChangeImplementation(); |
|
|
|
} else { |
|
// For older browsers |
|
installSetTimeoutImplementation(); |
|
} |
|
|
|
attachTo.setImmediate = setImmediate; |
|
attachTo.clearImmediate = clearImmediate; |
|
}(typeof self === "undefined" ? typeof global === "undefined" ? this : global : self)); |
|
|
|
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1), __webpack_require__(6))) |
|
|
|
/***/ }), |
|
/* 39 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
var disposed = false |
|
var normalizeComponent = __webpack_require__(40) |
|
/* script */ |
|
var __vue_script__ = __webpack_require__(41) |
|
/* template */ |
|
var __vue_template__ = __webpack_require__(42) |
|
/* template functional */ |
|
var __vue_template_functional__ = false |
|
/* styles */ |
|
var __vue_styles__ = null |
|
/* scopeId */ |
|
var __vue_scopeId__ = null |
|
/* moduleIdentifier (server only) */ |
|
var __vue_module_identifier__ = null |
|
var Component = normalizeComponent( |
|
__vue_script__, |
|
__vue_template__, |
|
__vue_template_functional__, |
|
__vue_styles__, |
|
__vue_scopeId__, |
|
__vue_module_identifier__ |
|
) |
|
Component.options.__file = "resources/assets/js/components/ExampleComponent.vue" |
|
|
|
/* hot reload */ |
|
if (false) {(function () { |
|
var hotAPI = require("vue-hot-reload-api") |
|
hotAPI.install(require("vue"), false) |
|
if (!hotAPI.compatible) return |
|
module.hot.accept() |
|
if (!module.hot.data) { |
|
hotAPI.createRecord("data-v-7168fb6a", Component.options) |
|
} else { |
|
hotAPI.reload("data-v-7168fb6a", Component.options) |
|
} |
|
module.hot.dispose(function (data) { |
|
disposed = true |
|
}) |
|
})()} |
|
|
|
module.exports = Component.exports |
|
|
|
|
|
/***/ }), |
|
/* 40 */ |
|
/***/ (function(module, exports) { |
|
|
|
/* globals __VUE_SSR_CONTEXT__ */ |
|
|
|
// IMPORTANT: Do NOT use ES2015 features in this file. |
|
// This module is a runtime utility for cleaner component module output and will |
|
// be included in the final webpack user bundle. |
|
|
|
module.exports = function normalizeComponent ( |
|
rawScriptExports, |
|
compiledTemplate, |
|
functionalTemplate, |
|
injectStyles, |
|
scopeId, |
|
moduleIdentifier /* server only */ |
|
) { |
|
var esModule |
|
var scriptExports = rawScriptExports = rawScriptExports || {} |
|
|
|
// ES6 modules interop |
|
var type = typeof rawScriptExports.default |
|
if (type === 'object' || type === 'function') { |
|
esModule = rawScriptExports |
|
scriptExports = rawScriptExports.default |
|
} |
|
|
|
// Vue.extend constructor export interop |
|
var options = typeof scriptExports === 'function' |
|
? scriptExports.options |
|
: scriptExports |
|
|
|
// render functions |
|
if (compiledTemplate) { |
|
options.render = compiledTemplate.render |
|
options.staticRenderFns = compiledTemplate.staticRenderFns |
|
options._compiled = true |
|
} |
|
|
|
// functional template |
|
if (functionalTemplate) { |
|
options.functional = true |
|
} |
|
|
|
// scopedId |
|
if (scopeId) { |
|
options._scopeId = scopeId |
|
} |
|
|
|
var hook |
|
if (moduleIdentifier) { // server build |
|
hook = function (context) { |
|
// 2.3 injection |
|
context = |
|
context || // cached call |
|
(this.$vnode && this.$vnode.ssrContext) || // stateful |
|
(this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext) // functional |
|
// 2.2 with runInNewContext: true |
|
if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') { |
|
context = __VUE_SSR_CONTEXT__ |
|
} |
|
// inject component styles |
|
if (injectStyles) { |
|
injectStyles.call(this, context) |
|
} |
|
// register component module identifier for async chunk inferrence |
|
if (context && context._registeredComponents) { |
|
context._registeredComponents.add(moduleIdentifier) |
|
} |
|
} |
|
// used by ssr in case component is cached and beforeCreate |
|
// never gets called |
|
options._ssrRegister = hook |
|
} else if (injectStyles) { |
|
hook = injectStyles |
|
} |
|
|
|
if (hook) { |
|
var functional = options.functional |
|
var existing = functional |
|
? options.render |
|
: options.beforeCreate |
|
|
|
if (!functional) { |
|
// inject component registration as beforeCreate hook |
|
options.beforeCreate = existing |
|
? [].concat(existing, hook) |
|
: [hook] |
|
} else { |
|
// for template-only hot-reload because in that case the render fn doesn't |
|
// go through the normalizer |
|
options._injectStyles = hook |
|
// register for functioal component in vue file |
|
options.render = function renderWithStyleInjection (h, context) { |
|
hook.call(context) |
|
return existing(h, context) |
|
} |
|
} |
|
} |
|
|
|
return { |
|
esModule: esModule, |
|
exports: scriptExports, |
|
options: options |
|
} |
|
} |
|
|
|
|
|
/***/ }), |
|
/* 41 */ |
|
/***/ (function(module, __webpack_exports__, __webpack_require__) { |
|
|
|
"use strict"; |
|
Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
|
|
/* harmony default export */ __webpack_exports__["default"] = ({ |
|
mounted: function mounted() { |
|
console.log('Component mounted.'); |
|
} |
|
}); |
|
|
|
/***/ }), |
|
/* 42 */ |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
var render = function() { |
|
var _vm = this |
|
var _h = _vm.$createElement |
|
var _c = _vm._self._c || _h |
|
return _vm._m(0) |
|
} |
|
var staticRenderFns = [ |
|
function() { |
|
var _vm = this |
|
var _h = _vm.$createElement |
|
var _c = _vm._self._c || _h |
|
return _c("div", { staticClass: "container" }, [ |
|
_c("div", { staticClass: "row justify-content-center" }, [ |
|
_c("div", { staticClass: "col-md-8" }, [ |
|
_c("div", { staticClass: "card card-default" }, [ |
|
_c("div", { staticClass: "card-header" }, [ |
|
_vm._v("Example Component") |
|
]), |
|
_vm._v(" "), |
|
_c("div", { staticClass: "card-body" }, [ |
|
_vm._v( |
|
"\n I'm an example component.\n " |
|
) |
|
]) |
|
]) |
|
]) |
|
]) |
|
]) |
|
} |
|
] |
|
render._withStripped = true |
|
module.exports = { render: render, staticRenderFns: staticRenderFns } |
|
if (false) { |
|
module.hot.accept() |
|
if (module.hot.data) { |
|
require("vue-hot-reload-api") .rerender("data-v-7168fb6a", module.exports) |
|
} |
|
} |
|
|
|
/***/ }), |
|
/* 43 */ |
|
/***/ (function(module, exports) { |
|
|
|
// removed by extract-text-webpack-plugin |
|
|
|
/***/ }) |
|
/******/ ]); |