Created
July 6, 2016 20:17
-
-
Save gautiermichelin/7cc1ab91058ed98cd34afc1f7220bf76 to your computer and use it in GitHub Desktop.
vextab-div.js
This file has been truncated, but you can view the full file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* VexTab 2.0.11 built on 2016-02-10. | |
* Copyright (c) 2010 Mohit Muthanna Cheppudira <mohit@muthanna.com> | |
* | |
* http://www.vexflow.com http://github.com/0xfe/vextab | |
*/ | |
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.VexTabDiv = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | |
(function (process){ | |
/* parser generated by jison 0.4.17 */ | |
/* | |
Returns a Parser object of the following structure: | |
Parser: { | |
yy: {} | |
} | |
Parser.prototype: { | |
yy: {}, | |
trace: function(), | |
symbols_: {associative list: name ==> number}, | |
terminals_: {associative list: number ==> name}, | |
productions_: [...], | |
performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$), | |
table: [...], | |
defaultActions: {...}, | |
parseError: function(str, hash), | |
parse: function(input), | |
lexer: { | |
EOF: 1, | |
parseError: function(str, hash), | |
setInput: function(input), | |
input: function(), | |
unput: function(str), | |
more: function(), | |
less: function(n), | |
pastInput: function(), | |
upcomingInput: function(), | |
showPosition: function(), | |
test_match: function(regex_match_array, rule_index), | |
next: function(), | |
lex: function(), | |
begin: function(condition), | |
popState: function(), | |
_currentRules: function(), | |
topState: function(), | |
pushState: function(condition), | |
options: { | |
ranges: boolean (optional: true ==> token location info will include a .range[] member) | |
flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match) | |
backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code) | |
}, | |
performAction: function(yy, yy_, $avoiding_name_collisions, YY_START), | |
rules: [...], | |
conditions: {associative list: name ==> set}, | |
} | |
} | |
token location info (@$, _$, etc.): { | |
first_line: n, | |
last_line: n, | |
first_column: n, | |
last_column: n, | |
range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based) | |
} | |
the parseError function receives a 'hash' object with these members for lexer and parser errors: { | |
text: (matched text) | |
token: (the produced terminal token, if any) | |
line: (yylineno) | |
} | |
while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: { | |
loc: (yylloc) | |
expected: (string describing the set of expected tokens) | |
recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error) | |
} | |
*/ | |
var parser = (function(){ | |
var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,6],$V1=[1,7],$V2=[1,8],$V3=[1,9],$V4=[5,11,13,14,15],$V5=[5,11,13,14,15,17,19,21],$V6=[2,17],$V7=[1,14],$V8=[5,11,13,14,15,17,19,21,22],$V9=[1,18],$Va=[1,19],$Vb=[1,20],$Vc=[1,21],$Vd=[1,43],$Ve=[1,32],$Vf=[1,33],$Vg=[1,42],$Vh=[1,41],$Vi=[1,39],$Vj=[1,48],$Vk=[1,55],$Vl=[1,50],$Vm=[1,51],$Vn=[1,52],$Vo=[1,53],$Vp=[1,54],$Vq=[1,56],$Vr=[1,44],$Vs=[1,45],$Vt=[1,46],$Vu=[1,47],$Vv=[1,57],$Vw=[5,11,13,14,15,17,19,21,25],$Vx=[5,11,13,14,15,17,19,21,23,31,32,37,38,45,48,57,61,62,63,64,65,66,70,71,73,75,76],$Vy=[2,79],$Vz=[1,67],$VA=[1,64],$VB=[1,65],$VC=[1,66],$VD=[1,73],$VE=[1,74],$VF=[1,78],$VG=[1,79],$VH=[1,80],$VI=[1,81],$VJ=[41,57,59,61,62,63,64,65,66,67,68,69],$VK=[38,45,48,76],$VL=[41,48,57,59,61,62,63,64,65,66,67,68,69,81],$VM=[5,11,13,14,15,17,19,21,23,31,32,37,38,41,45,48,57,61,62,63,64,65,66,70,71,73,75,76],$VN=[1,101],$VO=[44,46],$VP=[2,63],$VQ=[1,106],$VR=[5,11,13,14,15,17,19,21,23,31,32,37,38,45,48,57,59,61,62,63,64,65,66,70,71,73,75,76],$VS=[5,11,13,14,15,17,19,21,23,31,32,37,38,45,48,57,59,60,61,62,63,64,65,66,70,71,73,75,76],$VT=[25,71],$VU=[41,48,57,59,61,62,63,64,65,66,67,68,69],$VV=[5,11,13,14,15,17,19,21,23,31,32,37,38,44,45,46,48,57,61,62,63,64,65,66,70,71,73,75,76]; | |
var parser = {trace: function trace() { }, | |
yy: {}, | |
symbols_: {"error":2,"e":3,"maybe_vextab":4,"EOF":5,"vextab":6,"stave":7,"voice":8,"maybe_options":9,"stave_data":10,"OPTIONS":11,"options":12,"TABSTAVE":13,"STAVE":14,"VOICE":15,"stave_additions":16,"TEXT":17,"text":18,"NOTES":19,"notes":20,"SLUR":21,"WORD":22,"=":23,"STR":24,",":25,"lingo":26,"line":27,"chord":28,"time":29,"bar":30,"[":31,"]":32,"tuplets":33,"annotations":34,"command":35,"rest":36,"|":37,":":38,"frets":39,"maybe_decorator":40,"/":41,"string":42,"chord_line":43,".":44,"(":45,")":46,"articulation":47,"NUMBER":48,"abc":49,"_":50,"timed_fret":51,"time_values":52,"maybe_dot":53,"time_unit":54,"maybe_slash":55,"w":56,"h":57,"q":58,"d":59,"S":60,"-":61,"s":62,"t":63,"T":64,"b":65,"p":66,"v":67,"V":68,"u":69,"^":70,"$":71,"annotation_words":72,"!":73,"COMMAND":74,"#":75,"ABC":76,"abc_accidental":77,"accidental_type":78,"@":79,"n":80,"~":81,"$accept":0,"$end":1}, | |
terminals_: {2:"error",5:"EOF",11:"OPTIONS",13:"TABSTAVE",14:"STAVE",15:"VOICE",17:"TEXT",19:"NOTES",21:"SLUR",22:"WORD",23:"=",24:"STR",25:",",31:"[",32:"]",37:"|",38:":",41:"/",44:".",45:"(",46:")",48:"NUMBER",50:"_",56:"w",57:"h",58:"q",59:"d",60:"S",61:"-",62:"s",63:"t",64:"T",65:"b",66:"p",67:"v",68:"V",69:"u",70:"^",71:"$",73:"!",74:"COMMAND",75:"#",76:"ABC",79:"@",80:"n",81:"~"}, | |
productions_: [0,[3,2],[4,0],[4,1],[6,1],[6,2],[7,3],[7,2],[7,2],[8,1],[8,1],[8,1],[10,1],[10,2],[16,2],[16,2],[16,2],[9,0],[9,1],[12,3],[12,4],[18,1],[18,3],[20,1],[20,2],[26,1],[26,1],[26,1],[26,1],[26,1],[26,1],[26,1],[26,1],[26,1],[26,1],[30,1],[30,3],[30,3],[30,3],[30,3],[30,3],[27,4],[43,1],[43,3],[28,4],[28,5],[39,1],[39,1],[39,4],[39,2],[39,4],[51,5],[51,1],[51,5],[51,8],[51,1],[51,4],[29,3],[52,2],[54,1],[54,1],[54,1],[54,1],[53,0],[53,1],[55,0],[55,1],[42,1],[47,1],[47,1],[47,1],[47,1],[47,1],[47,1],[47,1],[40,1],[40,1],[40,1],[40,1],[40,0],[33,3],[33,5],[34,3],[72,1],[72,3],[35,3],[36,2],[36,3],[36,4],[49,3],[77,1],[77,2],[77,1],[77,2],[77,1],[77,0],[78,0],[78,1]], | |
performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) { | |
/* this == yyval */ | |
var $0 = $$.length - 1; | |
switch (yystate) { | |
case 1: | |
return $$[$0-1]; | |
break; | |
case 2: case 17: case 79: | |
this.$ = null | |
break; | |
case 3: case 12: case 18: case 23: case 25: case 26: case 27: case 42: case 59: case 60: case 61: case 62: case 67: | |
this.$ = $$[$0] | |
break; | |
case 4: case 83: | |
this.$ = [$$[$0]] | |
break; | |
case 5: | |
this.$ = [].concat($$[$0-1], $$[$0]) | |
break; | |
case 6: | |
this.$ = { | |
element: $$[$0-2], | |
options: $$[$0-1], | |
notes: $$[$0].notes, | |
text: $$[$0].text, | |
_l: _$[$0-2].first_line, | |
_c: _$[$0-2].first_column | |
} | |
break; | |
case 7: | |
this.$ = { | |
element: $$[$0-1], | |
options: $$[$0], | |
_l: _$[$0-1].first_line, | |
_c: _$[$0-1].first_column | |
} | |
break; | |
case 8: | |
this.$ = { | |
element: "options", | |
params: $$[$0], | |
_l: _$[$0-1].first_line, | |
_c: _$[$0-1].first_column | |
} | |
break; | |
case 13: | |
var text = [].concat($$[$0-1].text, $$[$0].text); | |
var notes = [].concat($$[$0-1].notes, $$[$0].notes); | |
var slurs = [].concat($$[$0-1].slurs, $$[$0].slurs) | |
this.$ = {text: text, notes: notes, slurs: slurs}; | |
break; | |
case 14: | |
this.$ = {text: $$[$0], notes: [], slurs: []} | |
break; | |
case 15: | |
this.$ = {notes: $$[$0], text: [], slurs: []} | |
break; | |
case 16: | |
this.$ = {slurs: $$[$0], notes: [], text: []} | |
break; | |
case 19: | |
this.$ = [{ | |
key: $$[$0-2], | |
value: $$[$0], | |
_l: _$[$0-2].first_line, | |
_c: _$[$0-2].first_column | |
}] | |
break; | |
case 20: | |
this.$ = [].concat($$[$0-3], [{ | |
key: $$[$0-2], | |
value: $$[$0], | |
_l: _$[$0-2].first_line, | |
_c: _$[$0-2].first_column | |
}]) | |
break; | |
case 21: | |
this.$ = [{text: $$[$0], _l: _$[$0].first_line, _c: _$[$0].first_column}] | |
break; | |
case 22: | |
this.$ = [].concat($$[$0-2], {text: $$[$0], _l: _$[$0].first_line, _c: _$[$0].first_column}) | |
break; | |
case 24: | |
this.$ = [].concat($$[$0-1], $$[$0]) | |
break; | |
case 28: | |
this.$ = [{ | |
command: "bar", | |
type: $$[$0], | |
_l: _$[$0].first_line, | |
_c: _$[$0].first_column | |
}] | |
break; | |
case 29: | |
this.$ = [{ | |
command: "open_beam", | |
_l: _$[$0].first_line, | |
_c: _$[$0].first_column | |
}] | |
break; | |
case 30: | |
this.$ = [{ | |
command: "close_beam", | |
_l: _$[$0].first_line, | |
_c: _$[$0].first_column | |
}] | |
break; | |
case 31: | |
this.$ = [{ | |
command: "tuplet", | |
params: $$[$0], | |
_l: _$[$0].first_line, | |
_c: _$[$0].first_column | |
}] | |
break; | |
case 32: | |
this.$ = [{ | |
command: "annotations", | |
params: $$[$0], | |
_l: _$[$0].first_line, | |
_c: _$[$0].first_column | |
}] | |
break; | |
case 33: | |
this.$ = [{ | |
command: "command", | |
params: $$[$0], | |
_l: _$[$0].first_line, | |
_c: _$[$0].first_column | |
}] | |
break; | |
case 34: | |
this.$ = [{ | |
command: "rest", | |
params: $$[$0] | |
}] | |
break; | |
case 35: | |
this.$ = 'single' | |
break; | |
case 36: | |
this.$ = 'double' | |
break; | |
case 37: | |
this.$ = 'end' | |
break; | |
case 38: | |
this.$ = 'repeat-end' | |
break; | |
case 39: | |
this.$ = 'repeat-begin' | |
break; | |
case 40: | |
this.$ = 'repeat-both' | |
break; | |
case 41: | |
_.extend(_.last($$[$0-3]), {decorator: $$[$0-2]}) | |
_.each($$[$0-3], function(fret) { fret['string'] = $$[$0] }) | |
this.$ = $$[$0-3] | |
break; | |
case 43: case 84: | |
this.$ = [].concat($$[$0-2], $$[$0]) | |
break; | |
case 44: | |
this.$ = [{chord: $$[$0-2], decorator: $$[$0]}] | |
break; | |
case 45: | |
this.$ = [{chord: $$[$0-2], articulation: $$[$0-4], decorator: $$[$0]}] | |
break; | |
case 46: | |
this.$ = [{ | |
fret: $$[$0], | |
_l: _$[$0].first_line, | |
_c: _$[$0].first_column}] | |
break; | |
case 47: | |
this.$ = [{abc: $$[$0], _l: _$[$0].first_line, _c: _$[$0].first_column}] | |
break; | |
case 48: | |
this.$ = [{abc: $$[$0-3], octave: $$[$0-2], | |
fret: $$[$0], _l: _$[$0-3].first_line, _c: _$[$0-3].first_column}] | |
break; | |
case 49: | |
this.$ = [_.extend($$[$0], {articulation: $$[$0-1]})] | |
break; | |
case 50: | |
_.extend(_.last($$[$0-3]), {decorator: $$[$0-2]}) | |
_.extend($$[$0], {articulation: $$[$0-1]}) | |
$$[$0-3].push($$[$0]) | |
this.$ = $$[$0-3] | |
break; | |
case 51: | |
this.$ = { | |
time: $$[$0-3], dot: $$[$0-2], fret: $$[$0], | |
_l: _$[$0-4].first_line, _c: _$[$0-4].first_column} | |
break; | |
case 52: | |
this.$ = {fret: $$[$0], _l: _$[$0].first_line, _c: _$[$0].first_column} | |
break; | |
case 53: | |
this.$ = {time: $$[$0-3], dot: $$[$0-2], abc: $$[$0]} | |
break; | |
case 54: | |
this.$ = {time: $$[$0-6], dot: $$[$0-5], abc: $$[$0-3], octave: $$[$0-2], fret: $$[$0]} | |
break; | |
case 55: | |
this.$ = {abc: $$[$0], _l: _$[$0].first_line, _c: _$[$0].first_column} | |
break; | |
case 56: | |
this.$ = {abc: $$[$0-3], octave: $$[$0-2], | |
fret: $$[$0], _l: _$[$0-3].first_line, _c: _$[$0-3].first_column} | |
break; | |
case 57: | |
this.$ = {time: $$[$0-1], dot: $$[$0]} | |
break; | |
case 58: | |
this.$ = $$[$0-1] + $$[$0] | |
break; | |
case 63: | |
this.$ = false | |
break; | |
case 64: | |
this.$ = true | |
break; | |
case 65: | |
this.$ = '' | |
break; | |
case 66: case 69: | |
this.$ = 's' | |
break; | |
case 68: | |
this.$ = '-' | |
break; | |
case 70: | |
this.$ = 't' | |
break; | |
case 71: | |
this.$ = 'T' | |
break; | |
case 72: | |
this.$ = 'b' | |
break; | |
case 73: | |
this.$ = 'h' | |
break; | |
case 74: | |
this.$ = 'p' | |
break; | |
case 75: | |
this.$ = 'v' | |
break; | |
case 76: | |
this.$ = 'V' | |
break; | |
case 77: | |
this.$ = 'u' | |
break; | |
case 78: | |
this.$ = 'd' | |
break; | |
case 80: | |
this.$ = {tuplet: $$[$0-1]} | |
break; | |
case 81: | |
this.$ = {tuplet: $$[$0-3], notes: $$[$0-1]} | |
break; | |
case 82: case 85: | |
this.$ = $$[$0-1] | |
break; | |
case 86: | |
this.$ = {position: 0} | |
break; | |
case 87: | |
this.$ = {position: $$[$0-1]} | |
break; | |
case 88: | |
this.$ = {position: $$[$0-1] * -1} | |
break; | |
case 89: | |
this.$ = {key: $$[$0-2], accidental: $$[$0-1], accidental_type: $$[$0]} | |
break; | |
case 90: | |
this.$ = "#" | |
break; | |
case 91: | |
this.$ = "##" | |
break; | |
case 92: | |
this.$ = "b" | |
break; | |
case 93: | |
this.$ = "bb" | |
break; | |
case 94: | |
this.$ = "n" | |
break; | |
case 96: | |
this.$ = null; | |
break; | |
case 97: | |
this.$ = "c" | |
break; | |
} | |
}, | |
table: [{3:1,4:2,5:[2,2],6:3,7:4,8:5,11:$V0,13:$V1,14:$V2,15:$V3},{1:[3]},{5:[1,10]},{5:[2,3],7:11,8:5,11:$V0,13:$V1,14:$V2,15:$V3},o($V4,[2,4]),o($V5,$V6,{9:12,12:13,22:$V7}),{12:15,22:$V7},o($V8,[2,9]),o($V8,[2,10]),o($V8,[2,11]),{1:[2,1]},o($V4,[2,5]),o($V4,[2,7],{10:16,16:17,17:$V9,19:$Va,21:$Vb}),o($V5,[2,18],{22:$Vc}),{23:[1,22]},o($V4,[2,8],{22:$Vc}),o($V4,[2,6],{16:23,17:$V9,19:$Va,21:$Vb}),o($V5,[2,12]),{18:24,24:[1,25]},{20:26,23:$Vd,26:27,27:28,28:29,29:30,30:31,31:$Ve,32:$Vf,33:34,34:35,35:36,36:37,37:$Vg,38:$Vh,39:38,45:$Vi,47:40,48:$Vj,49:49,57:$Vk,61:$Vl,62:$Vm,63:$Vn,64:$Vo,65:$Vp,66:$Vq,70:$Vr,71:$Vs,73:$Vt,75:$Vu,76:$Vv},o($V5,$V6,{12:13,9:58,22:$V7}),{23:[1,59]},{22:[1,60]},o($V5,[2,13]),o($V5,[2,14],{25:[1,61]}),o($Vw,[2,21]),o($V5,[2,15],{27:28,28:29,29:30,30:31,33:34,34:35,35:36,36:37,39:38,47:40,49:49,26:62,23:$Vd,31:$Ve,32:$Vf,37:$Vg,38:$Vh,45:$Vi,48:$Vj,57:$Vk,61:$Vl,62:$Vm,63:$Vn,64:$Vo,65:$Vp,66:$Vq,70:$Vr,71:$Vs,73:$Vt,75:$Vu,76:$Vv}),o($Vx,[2,23]),o($Vx,[2,25]),o($Vx,[2,26]),o($Vx,[2,27]),o($Vx,[2,28]),o($Vx,[2,29]),o($Vx,[2,30]),o($Vx,[2,31]),o($Vx,[2,32]),o($Vx,[2,33]),o($Vx,[2,34]),o([41,57,61,62,63,64,65,66],$Vy,{40:63,59:$Vz,67:$VA,68:$VB,69:$VC}),{27:69,39:38,43:68,47:70,48:$Vj,49:49,57:$Vk,61:$Vl,62:$Vm,63:$Vn,64:$Vo,65:$Vp,66:$Vq,76:$Vv},{38:$VD,45:[1,71],48:$VE,49:75,51:72,76:$Vv},{48:$VF,52:76,54:77,56:$VG,57:$VH,58:$VI},o($Vx,[2,35]),{37:[1,82],38:[1,83]},{48:[1,84]},{22:[1,86],72:85},{74:[1,87]},{48:[1,89],61:[1,90],75:[1,88]},o($VJ,[2,46]),o($VJ,[2,47],{48:[1,91]}),o($VK,[2,68]),o($VK,[2,69]),o($VK,[2,70]),o($VK,[2,71]),o($VK,[2,72]),o($VK,[2,73]),o($VK,[2,74]),o($VL,[2,95],{77:92,75:[1,93],79:[1,94],80:[1,95]}),o($V5,[2,16]),{22:[1,96]},o($V8,[2,19]),{24:[1,97]},o($Vx,[2,24]),{41:[1,98],47:99,57:$Vk,61:$Vl,62:$Vm,63:$Vn,64:$Vo,65:$Vp,66:$Vq},o($VM,[2,75]),o($VM,[2,76]),o($VM,[2,77]),o($VM,[2,78]),{44:$VN,46:[1,100]},o($VO,[2,42]),{38:$VD,48:$VE,49:75,51:72,76:$Vv},{27:69,39:38,43:102,47:70,48:$Vj,49:49,57:$Vk,61:$Vl,62:$Vm,63:$Vn,64:$Vo,65:$Vp,66:$Vq,76:$Vv},o($VJ,[2,49]),{48:$VF,52:103,54:77,56:$VG,57:$VH,58:$VI},o($VJ,[2,52]),o($VJ,[2,55],{48:[1,104]}),o($Vx,$VP,{53:105,59:$VQ}),o($VR,[2,65],{55:107,60:[1,108]}),o($VS,[2,59]),o($VS,[2,60]),o($VS,[2,61]),o($VS,[2,62]),{23:[1,110],37:[1,109],38:[1,111]},{37:[1,112],38:[1,113]},{25:[1,115],70:[1,114]},{25:[1,117],71:[1,116]},o($VT,[2,83]),{73:[1,118]},o($Vx,[2,86]),{75:[1,119]},{48:[1,120]},{50:[1,121]},o($VU,[2,96],{78:122,81:[1,123]}),o($VL,[2,90],{75:[1,124]}),o($VL,[2,92],{79:[1,125]}),o($VL,[2,94]),o($V8,[2,20]),o($Vw,[2,22]),{42:126,48:[1,127]},{38:$VD,48:$VE,49:75,51:128,76:$Vv},o($Vx,$Vy,{40:129,59:$Vz,67:$VA,68:$VB,69:$VC}),{27:130,39:38,47:70,48:$Vj,49:49,57:$Vk,61:$Vl,62:$Vm,63:$Vn,64:$Vo,65:$Vp,66:$Vq,76:$Vv},{44:$VN,46:[1,131]},{38:$VP,53:132,59:$VQ},{50:[1,133]},o($Vx,[2,57]),o($Vx,[2,64]),o($VR,[2,58]),o($VR,[2,66]),o($Vx,[2,36]),o($Vx,[2,37]),o($Vx,[2,39]),o($Vx,[2,38]),o($Vx,[2,40]),o($Vx,[2,80]),{48:[1,134]},o($Vx,[2,82]),{22:[1,135]},o($Vx,[2,85]),o($Vx,[2,87]),{75:[1,136]},{48:[1,137]},o($VU,[2,89]),o($VU,[2,97]),o($VL,[2,91]),o($VL,[2,93]),o($VV,[2,41]),o($VV,[2,67]),o($VJ,[2,50]),o($Vx,[2,44]),o($VO,[2,43]),o($Vx,$Vy,{40:138,59:$Vz,67:$VA,68:$VB,69:$VC}),{38:[1,139]},{48:[1,140]},{70:[1,141]},o($VT,[2,84]),o($Vx,[2,88]),o($VJ,[2,48]),o($Vx,[2,45]),{48:[1,142],49:143,76:$Vv},o($VJ,[2,56]),o($Vx,[2,81]),o($VJ,[2,51]),o($VJ,[2,53],{48:[1,144]}),{50:[1,145]},{48:[1,146]},o($VJ,[2,54])], | |
defaultActions: {10:[2,1]}, | |
parseError: function parseError(str, hash) { | |
if (hash.recoverable) { | |
this.trace(str); | |
} else { | |
function _parseError (msg, hash) { | |
this.message = msg; | |
this.hash = hash; | |
} | |
_parseError.prototype = Error; | |
throw new _parseError(str, hash); | |
} | |
}, | |
parse: function parse(input) { | |
var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1; | |
var args = lstack.slice.call(arguments, 1); | |
var lexer = Object.create(this.lexer); | |
var sharedState = { yy: {} }; | |
for (var k in this.yy) { | |
if (Object.prototype.hasOwnProperty.call(this.yy, k)) { | |
sharedState.yy[k] = this.yy[k]; | |
} | |
} | |
lexer.setInput(input, sharedState.yy); | |
sharedState.yy.lexer = lexer; | |
sharedState.yy.parser = this; | |
if (typeof lexer.yylloc == 'undefined') { | |
lexer.yylloc = {}; | |
} | |
var yyloc = lexer.yylloc; | |
lstack.push(yyloc); | |
var ranges = lexer.options && lexer.options.ranges; | |
if (typeof sharedState.yy.parseError === 'function') { | |
this.parseError = sharedState.yy.parseError; | |
} else { | |
this.parseError = Object.getPrototypeOf(this).parseError; | |
} | |
function popStack(n) { | |
stack.length = stack.length - 2 * n; | |
vstack.length = vstack.length - n; | |
lstack.length = lstack.length - n; | |
} | |
_token_stack: | |
var lex = function () { | |
var token; | |
token = lexer.lex() || EOF; | |
if (typeof token !== 'number') { | |
token = self.symbols_[token] || token; | |
} | |
return token; | |
}; | |
var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected; | |
while (true) { | |
state = stack[stack.length - 1]; | |
if (this.defaultActions[state]) { | |
action = this.defaultActions[state]; | |
} else { | |
if (symbol === null || typeof symbol == 'undefined') { | |
symbol = lex(); | |
} | |
action = table[state] && table[state][symbol]; | |
} | |
if (typeof action === 'undefined' || !action.length || !action[0]) { | |
var errStr = ''; | |
expected = []; | |
for (p in table[state]) { | |
if (this.terminals_[p] && p > TERROR) { | |
expected.push('\'' + this.terminals_[p] + '\''); | |
} | |
} | |
if (lexer.showPosition) { | |
errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\''; | |
} else { | |
errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\''); | |
} | |
this.parseError(errStr, { | |
text: lexer.match, | |
token: this.terminals_[symbol] || symbol, | |
line: lexer.yylineno, | |
loc: yyloc, | |
expected: expected | |
}); | |
} | |
if (action[0] instanceof Array && action.length > 1) { | |
throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol); | |
} | |
switch (action[0]) { | |
case 1: | |
stack.push(symbol); | |
vstack.push(lexer.yytext); | |
lstack.push(lexer.yylloc); | |
stack.push(action[1]); | |
symbol = null; | |
if (!preErrorSymbol) { | |
yyleng = lexer.yyleng; | |
yytext = lexer.yytext; | |
yylineno = lexer.yylineno; | |
yyloc = lexer.yylloc; | |
if (recovering > 0) { | |
recovering--; | |
} | |
} else { | |
symbol = preErrorSymbol; | |
preErrorSymbol = null; | |
} | |
break; | |
case 2: | |
len = this.productions_[action[1]][1]; | |
yyval.$ = vstack[vstack.length - len]; | |
yyval._$ = { | |
first_line: lstack[lstack.length - (len || 1)].first_line, | |
last_line: lstack[lstack.length - 1].last_line, | |
first_column: lstack[lstack.length - (len || 1)].first_column, | |
last_column: lstack[lstack.length - 1].last_column | |
}; | |
if (ranges) { | |
yyval._$.range = [ | |
lstack[lstack.length - (len || 1)].range[0], | |
lstack[lstack.length - 1].range[1] | |
]; | |
} | |
r = this.performAction.apply(yyval, [ | |
yytext, | |
yyleng, | |
yylineno, | |
sharedState.yy, | |
action[1], | |
vstack, | |
lstack | |
].concat(args)); | |
if (typeof r !== 'undefined') { | |
return r; | |
} | |
if (len) { | |
stack = stack.slice(0, -1 * len * 2); | |
vstack = vstack.slice(0, -1 * len); | |
lstack = lstack.slice(0, -1 * len); | |
} | |
stack.push(this.productions_[action[1]][0]); | |
vstack.push(yyval.$); | |
lstack.push(yyval._$); | |
newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; | |
stack.push(newState); | |
break; | |
case 3: | |
return true; | |
} | |
} | |
return true; | |
}}; | |
var _ = require("lodash"); | |
/* generated by jison-lex 0.3.4 */ | |
var lexer = (function(){ | |
var lexer = ({ | |
EOF:1, | |
parseError:function parseError(str, hash) { | |
if (this.yy.parser) { | |
this.yy.parser.parseError(str, hash); | |
} else { | |
throw new Error(str); | |
} | |
}, | |
// resets the lexer, sets new input | |
setInput:function (input, yy) { | |
this.yy = yy || this.yy || {}; | |
this._input = input; | |
this._more = this._backtrack = this.done = false; | |
this.yylineno = this.yyleng = 0; | |
this.yytext = this.matched = this.match = ''; | |
this.conditionStack = ['INITIAL']; | |
this.yylloc = { | |
first_line: 1, | |
first_column: 0, | |
last_line: 1, | |
last_column: 0 | |
}; | |
if (this.options.ranges) { | |
this.yylloc.range = [0,0]; | |
} | |
this.offset = 0; | |
return this; | |
}, | |
// consumes and returns one char from the input | |
input:function () { | |
var ch = this._input[0]; | |
this.yytext += ch; | |
this.yyleng++; | |
this.offset++; | |
this.match += ch; | |
this.matched += ch; | |
var lines = ch.match(/(?:\r\n?|\n).*/g); | |
if (lines) { | |
this.yylineno++; | |
this.yylloc.last_line++; | |
} else { | |
this.yylloc.last_column++; | |
} | |
if (this.options.ranges) { | |
this.yylloc.range[1]++; | |
} | |
this._input = this._input.slice(1); | |
return ch; | |
}, | |
// unshifts one char (or a string) into the input | |
unput:function (ch) { | |
var len = ch.length; | |
var lines = ch.split(/(?:\r\n?|\n)/g); | |
this._input = ch + this._input; | |
this.yytext = this.yytext.substr(0, this.yytext.length - len); | |
//this.yyleng -= len; | |
this.offset -= len; | |
var oldLines = this.match.split(/(?:\r\n?|\n)/g); | |
this.match = this.match.substr(0, this.match.length - 1); | |
this.matched = this.matched.substr(0, this.matched.length - 1); | |
if (lines.length - 1) { | |
this.yylineno -= lines.length - 1; | |
} | |
var r = this.yylloc.range; | |
this.yylloc = { | |
first_line: this.yylloc.first_line, | |
last_line: this.yylineno + 1, | |
first_column: this.yylloc.first_column, | |
last_column: lines ? | |
(lines.length === oldLines.length ? this.yylloc.first_column : 0) | |
+ oldLines[oldLines.length - lines.length].length - lines[0].length : | |
this.yylloc.first_column - len | |
}; | |
if (this.options.ranges) { | |
this.yylloc.range = [r[0], r[0] + this.yyleng - len]; | |
} | |
this.yyleng = this.yytext.length; | |
return this; | |
}, | |
// When called from action, caches matched text and appends it on next action | |
more:function () { | |
this._more = true; | |
return this; | |
}, | |
// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. | |
reject:function () { | |
if (this.options.backtrack_lexer) { | |
this._backtrack = true; | |
} else { | |
return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), { | |
text: "", | |
token: null, | |
line: this.yylineno | |
}); | |
} | |
return this; | |
}, | |
// retain first n characters of the match | |
less:function (n) { | |
this.unput(this.match.slice(n)); | |
}, | |
// displays already matched input, i.e. for error messages | |
pastInput:function () { | |
var past = this.matched.substr(0, this.matched.length - this.match.length); | |
return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, ""); | |
}, | |
// displays upcoming input, i.e. for error messages | |
upcomingInput:function () { | |
var next = this.match; | |
if (next.length < 20) { | |
next += this._input.substr(0, 20-next.length); | |
} | |
return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, ""); | |
}, | |
// displays the character position where the lexing error occurred, i.e. for error messages | |
showPosition:function () { | |
var pre = this.pastInput(); | |
var c = new Array(pre.length + 1).join("-"); | |
return pre + this.upcomingInput() + "\n" + c + "^"; | |
}, | |
// test the lexed token: return FALSE when not a match, otherwise return token | |
test_match:function (match, indexed_rule) { | |
var token, | |
lines, | |
backup; | |
if (this.options.backtrack_lexer) { | |
// save context | |
backup = { | |
yylineno: this.yylineno, | |
yylloc: { | |
first_line: this.yylloc.first_line, | |
last_line: this.last_line, | |
first_column: this.yylloc.first_column, | |
last_column: this.yylloc.last_column | |
}, | |
yytext: this.yytext, | |
match: this.match, | |
matches: this.matches, | |
matched: this.matched, | |
yyleng: this.yyleng, | |
offset: this.offset, | |
_more: this._more, | |
_input: this._input, | |
yy: this.yy, | |
conditionStack: this.conditionStack.slice(0), | |
done: this.done | |
}; | |
if (this.options.ranges) { | |
backup.yylloc.range = this.yylloc.range.slice(0); | |
} | |
} | |
lines = match[0].match(/(?:\r\n?|\n).*/g); | |
if (lines) { | |
this.yylineno += lines.length; | |
} | |
this.yylloc = { | |
first_line: this.yylloc.last_line, | |
last_line: this.yylineno + 1, | |
first_column: this.yylloc.last_column, | |
last_column: lines ? | |
lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : | |
this.yylloc.last_column + match[0].length | |
}; | |
this.yytext += match[0]; | |
this.match += match[0]; | |
this.matches = match; | |
this.yyleng = this.yytext.length; | |
if (this.options.ranges) { | |
this.yylloc.range = [this.offset, this.offset += this.yyleng]; | |
} | |
this._more = false; | |
this._backtrack = false; | |
this._input = this._input.slice(match[0].length); | |
this.matched += match[0]; | |
token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); | |
if (this.done && this._input) { | |
this.done = false; | |
} | |
if (token) { | |
return token; | |
} else if (this._backtrack) { | |
// recover context | |
for (var k in backup) { | |
this[k] = backup[k]; | |
} | |
return false; // rule action called reject() implying the next rule should be tested instead. | |
} | |
return false; | |
}, | |
// return next match in input | |
next:function () { | |
if (this.done) { | |
return this.EOF; | |
} | |
if (!this._input) { | |
this.done = true; | |
} | |
var token, | |
match, | |
tempMatch, | |
index; | |
if (!this._more) { | |
this.yytext = ''; | |
this.match = ''; | |
} | |
var rules = this._currentRules(); | |
for (var i = 0; i < rules.length; i++) { | |
tempMatch = this._input.match(this.rules[rules[i]]); | |
if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { | |
match = tempMatch; | |
index = i; | |
if (this.options.backtrack_lexer) { | |
token = this.test_match(tempMatch, rules[i]); | |
if (token !== false) { | |
return token; | |
} else if (this._backtrack) { | |
match = false; | |
continue; // rule action called reject() implying a rule MISmatch. | |
} else { | |
// else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) | |
return false; | |
} | |
} else if (!this.options.flex) { | |
break; | |
} | |
} | |
} | |
if (match) { | |
token = this.test_match(match, rules[index]); | |
if (token !== false) { | |
return token; | |
} | |
// else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) | |
return false; | |
} | |
if (this._input === "") { | |
return this.EOF; | |
} else { | |
return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), { | |
text: "", | |
token: null, | |
line: this.yylineno | |
}); | |
} | |
}, | |
// return next match that has a token | |
lex:function lex() { | |
var r = this.next(); | |
if (r) { | |
return r; | |
} else { | |
return this.lex(); | |
} | |
}, | |
// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) | |
begin:function begin(condition) { | |
this.conditionStack.push(condition); | |
}, | |
// pop the previously active lexer condition state off the condition stack | |
popState:function popState() { | |
var n = this.conditionStack.length - 1; | |
if (n > 0) { | |
return this.conditionStack.pop(); | |
} else { | |
return this.conditionStack[0]; | |
} | |
}, | |
// produce the lexer rule set which is active for the currently active lexer condition state | |
_currentRules:function _currentRules() { | |
if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { | |
return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; | |
} else { | |
return this.conditions["INITIAL"].rules; | |
} | |
}, | |
// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available | |
topState:function topState(n) { | |
n = this.conditionStack.length - 1 - Math.abs(n || 0); | |
if (n >= 0) { | |
return this.conditionStack[n]; | |
} else { | |
return "INITIAL"; | |
} | |
}, | |
// alias for begin(condition) | |
pushState:function pushState(condition) { | |
this.begin(condition); | |
}, | |
// return the number of states currently on the stack | |
stateStackSize:function stateStackSize() { | |
return this.conditionStack.length; | |
}, | |
options: {}, | |
performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) { | |
var YYSTATE=YY_START; | |
switch($avoiding_name_collisions) { | |
case 0: this.begin('notes'); return 19; | |
break; | |
case 1: this.begin('options'); return 13; | |
break; | |
case 2: this.begin('options'); return 14; | |
break; | |
case 3: this.begin('options'); return 15; | |
break; | |
case 4: this.begin('options'); return 11; | |
break; | |
case 5: this.begin('text'); return 17; | |
break; | |
case 6: this.begin('options'); return 21; | |
break; | |
case 7:return 22 | |
break; | |
case 8: this.begin('annotations'); return "$" | |
break; | |
case 9: this.begin('notes'); return "$" | |
break; | |
case 10:return 22 | |
break; | |
case 11: this.begin('command'); return "!" | |
break; | |
case 12: this.begin('notes'); return "!" | |
break; | |
case 13:return 74 | |
break; | |
case 14:return 24 | |
break; | |
case 15:return 41 | |
break; | |
case 16:return '+' | |
break; | |
case 17:return 38 | |
break; | |
case 18:return 23 | |
break; | |
case 19:return 45 | |
break; | |
case 20:return 46 | |
break; | |
case 21:return 31 | |
break; | |
case 22:return 32 | |
break; | |
case 23:return 70 | |
break; | |
case 24:return 25 | |
break; | |
case 25:return 37 | |
break; | |
case 26:return 44 | |
break; | |
case 27:return 75 | |
break; | |
case 28:return 79 | |
break; | |
case 29:return 65 | |
break; | |
case 30:return 62 | |
break; | |
case 31:return 57 | |
break; | |
case 32:return 66 | |
break; | |
case 33:return 63 | |
break; | |
case 34:return 64 | |
break; | |
case 35:return 61 | |
break; | |
case 36:return 50 | |
break; | |
case 37:return 67 | |
break; | |
case 38:return 68 | |
break; | |
case 39:return 69 | |
break; | |
case 40:return 59 | |
break; | |
case 41:return 48 | |
break; | |
case 42:return 58 | |
break; | |
case 43:return 56 | |
break; | |
case 44:return 57 | |
break; | |
case 45:return 59 | |
break; | |
case 46:return 60 | |
break; | |
case 47:return 76 | |
break; | |
case 48:return 80 | |
break; | |
case 49:return 81 | |
break; | |
case 50: this.begin('INITIAL'); | |
break; | |
case 51:/* skip whitespace */ | |
break; | |
case 52:return 5 | |
break; | |
case 53:return 'INVALID' | |
break; | |
} | |
}, | |
rules: [/^(?:notes\b)/,/^(?:tabstave\b)/,/^(?:stave\b)/,/^(?:voice\b)/,/^(?:options\b)/,/^(?:text\b)/,/^(?:slur\b)/,/^(?:[^\s=]+)/,/^(?:[$])/,/^(?:[$])/,/^(?:[^,$]+)/,/^(?:[!])/,/^(?:[!])/,/^(?:[^!]+)/,/^(?:[^,\r\n]+)/,/^(?:\/)/,/^(?:\+)/,/^(?::)/,/^(?:=)/,/^(?:\()/,/^(?:\))/,/^(?:\[)/,/^(?:\])/,/^(?:\^)/,/^(?:,)/,/^(?:\|)/,/^(?:\.)/,/^(?:#)/,/^(?:@)/,/^(?:[b])/,/^(?:[s])/,/^(?:[h])/,/^(?:[p])/,/^(?:[t])/,/^(?:[T])/,/^(?:[-])/,/^(?:[_])/,/^(?:[v])/,/^(?:[V])/,/^(?:[u])/,/^(?:[d])/,/^(?:[0-9]+)/,/^(?:[q])/,/^(?:[w])/,/^(?:[h])/,/^(?:[d])/,/^(?:[S])/,/^(?:[A-GXLR])/,/^(?:[n])/,/^(?:[~])/,/^(?:[\r\n]+)/,/^(?:\s+)/,/^(?:$)/,/^(?:.)/], | |
conditions: {"notes":{"rules":[8,11,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53],"inclusive":true},"text":{"rules":[14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,41,42,43,44,45,50,51,52,53],"inclusive":true},"slur":{"rules":[15,16,17,18,19,20,21,22,23,24,25,26,27,28,50,51,52,53],"inclusive":true},"annotations":{"rules":[9,10,15,16,17,18,19,20,21,22,23,24,25,26,27,28,50,51,52,53],"inclusive":true},"options":{"rules":[7,15,16,17,18,19,20,21,22,23,24,25,26,27,28,50,51,52,53],"inclusive":true},"command":{"rules":[12,13,15,16,17,18,19,20,21,22,23,24,25,26,27,28,50,51,52,53],"inclusive":true},"INITIAL":{"rules":[0,1,2,3,4,5,6,7,15,16,17,18,19,20,21,22,23,24,25,26,27,28,50,51,52,53],"inclusive":true}} | |
}); | |
return lexer; | |
})(); | |
parser.lexer = lexer; | |
function Parser () { | |
this.yy = {}; | |
} | |
Parser.prototype = parser;parser.Parser = Parser; | |
return new Parser; | |
})(); | |
if (typeof require !== 'undefined' && typeof exports !== 'undefined') { | |
exports.parser = parser; | |
exports.Parser = parser.Parser; | |
exports.parse = function () { return parser.parse.apply(parser, arguments); }; | |
exports.main = function commonjsMain(args) { | |
if (!args[1]) { | |
console.log('Usage: '+args[0]+' FILE'); | |
process.exit(1); | |
} | |
var source = require('fs').readFileSync(require('path').normalize(args[1]), "utf8"); | |
return exports.parser.parse(source); | |
}; | |
if (typeof module !== 'undefined' && require.main === module) { | |
exports.main(process.argv.slice(1)); | |
} | |
} | |
}).call(this,require('_process')) | |
},{"_process":4,"fs":2,"lodash":6,"path":3}],2:[function(require,module,exports){ | |
},{}],3:[function(require,module,exports){ | |
(function (process){ | |
// Copyright Joyent, Inc. and other Node 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. | |
// resolves . and .. elements in a path array with directory names there | |
// must be no slashes, empty elements, or device names (c:\) in the array | |
// (so also no leading and trailing slashes - it does not distinguish | |
// relative and absolute paths) | |
function normalizeArray(parts, allowAboveRoot) { | |
// if the path tries to go above the root, `up` ends up > 0 | |
var up = 0; | |
for (var i = parts.length - 1; i >= 0; i--) { | |
var last = parts[i]; | |
if (last === '.') { | |
parts.splice(i, 1); | |
} else if (last === '..') { | |
parts.splice(i, 1); | |
up++; | |
} else if (up) { | |
parts.splice(i, 1); | |
up--; | |
} | |
} | |
// if the path is allowed to go above the root, restore leading ..s | |
if (allowAboveRoot) { | |
for (; up--; up) { | |
parts.unshift('..'); | |
} | |
} | |
return parts; | |
} | |
// Split a filename into [root, dir, basename, ext], unix version | |
// 'root' is just a slash, or nothing. | |
var splitPathRe = | |
/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; | |
var splitPath = function(filename) { | |
return splitPathRe.exec(filename).slice(1); | |
}; | |
// path.resolve([from ...], to) | |
// posix version | |
exports.resolve = function() { | |
var resolvedPath = '', | |
resolvedAbsolute = false; | |
for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { | |
var path = (i >= 0) ? arguments[i] : process.cwd(); | |
// Skip empty and invalid entries | |
if (typeof path !== 'string') { | |
throw new TypeError('Arguments to path.resolve must be strings'); | |
} else if (!path) { | |
continue; | |
} | |
resolvedPath = path + '/' + resolvedPath; | |
resolvedAbsolute = path.charAt(0) === '/'; | |
} | |
// At this point the path should be resolved to a full absolute path, but | |
// handle relative paths to be safe (might happen when process.cwd() fails) | |
// Normalize the path | |
resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { | |
return !!p; | |
}), !resolvedAbsolute).join('/'); | |
return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; | |
}; | |
// path.normalize(path) | |
// posix version | |
exports.normalize = function(path) { | |
var isAbsolute = exports.isAbsolute(path), | |
trailingSlash = substr(path, -1) === '/'; | |
// Normalize the path | |
path = normalizeArray(filter(path.split('/'), function(p) { | |
return !!p; | |
}), !isAbsolute).join('/'); | |
if (!path && !isAbsolute) { | |
path = '.'; | |
} | |
if (path && trailingSlash) { | |
path += '/'; | |
} | |
return (isAbsolute ? '/' : '') + path; | |
}; | |
// posix version | |
exports.isAbsolute = function(path) { | |
return path.charAt(0) === '/'; | |
}; | |
// posix version | |
exports.join = function() { | |
var paths = Array.prototype.slice.call(arguments, 0); | |
return exports.normalize(filter(paths, function(p, index) { | |
if (typeof p !== 'string') { | |
throw new TypeError('Arguments to path.join must be strings'); | |
} | |
return p; | |
}).join('/')); | |
}; | |
// path.relative(from, to) | |
// posix version | |
exports.relative = function(from, to) { | |
from = exports.resolve(from).substr(1); | |
to = exports.resolve(to).substr(1); | |
function trim(arr) { | |
var start = 0; | |
for (; start < arr.length; start++) { | |
if (arr[start] !== '') break; | |
} | |
var end = arr.length - 1; | |
for (; end >= 0; end--) { | |
if (arr[end] !== '') break; | |
} | |
if (start > end) return []; | |
return arr.slice(start, end - start + 1); | |
} | |
var fromParts = trim(from.split('/')); | |
var toParts = trim(to.split('/')); | |
var length = Math.min(fromParts.length, toParts.length); | |
var samePartsLength = length; | |
for (var i = 0; i < length; i++) { | |
if (fromParts[i] !== toParts[i]) { | |
samePartsLength = i; | |
break; | |
} | |
} | |
var outputParts = []; | |
for (var i = samePartsLength; i < fromParts.length; i++) { | |
outputParts.push('..'); | |
} | |
outputParts = outputParts.concat(toParts.slice(samePartsLength)); | |
return outputParts.join('/'); | |
}; | |
exports.sep = '/'; | |
exports.delimiter = ':'; | |
exports.dirname = function(path) { | |
var result = splitPath(path), | |
root = result[0], | |
dir = result[1]; | |
if (!root && !dir) { | |
// No dirname whatsoever | |
return '.'; | |
} | |
if (dir) { | |
// It has a dirname, strip trailing slash | |
dir = dir.substr(0, dir.length - 1); | |
} | |
return root + dir; | |
}; | |
exports.basename = function(path, ext) { | |
var f = splitPath(path)[2]; | |
// TODO: make this comparison case-insensitive on windows? | |
if (ext && f.substr(-1 * ext.length) === ext) { | |
f = f.substr(0, f.length - ext.length); | |
} | |
return f; | |
}; | |
exports.extname = function(path) { | |
return splitPath(path)[3]; | |
}; | |
function filter (xs, f) { | |
if (xs.filter) return xs.filter(f); | |
var res = []; | |
for (var i = 0; i < xs.length; i++) { | |
if (f(xs[i], i, xs)) res.push(xs[i]); | |
} | |
return res; | |
} | |
// String.prototype.substr - negative index don't work in IE8 | |
var substr = 'ab'.substr(-1) === 'b' | |
? function (str, start, len) { return str.substr(start, len) } | |
: function (str, start, len) { | |
if (start < 0) start = str.length + start; | |
return str.substr(start, len); | |
} | |
; | |
}).call(this,require('_process')) | |
},{"_process":4}],4:[function(require,module,exports){ | |
// shim for using process in browser | |
var process = module.exports = {}; | |
var queue = []; | |
var draining = false; | |
var currentQueue; | |
var queueIndex = -1; | |
function cleanUpNextTick() { | |
draining = false; | |
if (currentQueue.length) { | |
queue = currentQueue.concat(queue); | |
} else { | |
queueIndex = -1; | |
} | |
if (queue.length) { | |
drainQueue(); | |
} | |
} | |
function drainQueue() { | |
if (draining) { | |
return; | |
} | |
var timeout = setTimeout(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; | |
clearTimeout(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) { | |
setTimeout(drainQueue, 0); | |
} | |
}; | |
// 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.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; }; | |
},{}],5:[function(require,module,exports){ | |
/*! | |
* jQuery JavaScript Library v2.2.0 | |
* http://jquery.com/ | |
* | |
* Includes Sizzle.js | |
* http://sizzlejs.com/ | |
* | |
* Copyright jQuery Foundation and other contributors | |
* Released under the MIT license | |
* http://jquery.org/license | |
* | |
* Date: 2016-01-08T20:02Z | |
*/ | |
(function( global, factory ) { | |
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 ) { | |
// Support: Firefox 18+ | |
// Can't be in strict mode, several libs including ASP.NET trace | |
// the stack via arguments.caller.callee and Firefox dies if | |
// you try to trace through "use strict" call chains. (#13335) | |
//"use strict"; | |
var arr = []; | |
var document = window.document; | |
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 support = {}; | |
var | |
version = "2.2.0", | |
// 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.1 | |
// Make sure we trim BOM and NBSP | |
rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, | |
// Matches dashed string for camelizing | |
rmsPrefix = /^-ms-/, | |
rdashAlpha = /-([\da-z])/gi, | |
// Used by jQuery.camelCase as callback to replace() | |
fcamelCase = function( all, letter ) { | |
return letter.toUpperCase(); | |
}; | |
jQuery.fn = jQuery.prototype = { | |
// The current version of jQuery being used | |
jquery: version, | |
constructor: jQuery, | |
// Start with an empty selector | |
selector: "", | |
// 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 num != null ? | |
// Return just the one element from the set | |
( num < 0 ? this[ num + this.length ] : this[ num ] ) : | |
// Return all the elements in a clean array | |
slice.call( this ); | |
}, | |
// 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; | |
ret.context = this.context; | |
// 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" && !jQuery.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 = jQuery.isArray( copy ) ) ) ) { | |
if ( copyIsArray ) { | |
copyIsArray = false; | |
clone = src && jQuery.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() {}, | |
isFunction: function( obj ) { | |
return jQuery.type( obj ) === "function"; | |
}, | |
isArray: Array.isArray, | |
isWindow: function( obj ) { | |
return obj != null && obj === obj.window; | |
}, | |
isNumeric: function( obj ) { | |
// parseFloat NaNs numeric-cast false positives (null|true|false|"") | |
// ...but misinterprets leading-number strings, particularly hex literals ("0x...") | |
// subtraction forces infinities to NaN | |
// adding 1 corrects loss of precision from parseFloat (#15100) | |
var realStringObj = obj && obj.toString(); | |
return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0; | |
}, | |
isPlainObject: function( obj ) { | |
// Not plain objects: | |
// - Any object or value whose internal [[Class]] property is not "[object Object]" | |
// - DOM nodes | |
// - window | |
if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { | |
return false; | |
} | |
if ( obj.constructor && | |
!hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { | |
return false; | |
} | |
// If the function hasn't returned already, we're confident that | |
// |obj| is a plain object, created by {} or constructed with new Object | |
return true; | |
}, | |
isEmptyObject: function( obj ) { | |
var name; | |
for ( name in obj ) { | |
return false; | |
} | |
return true; | |
}, | |
type: function( obj ) { | |
if ( obj == null ) { | |
return obj + ""; | |
} | |
// Support: Android<4.0, iOS<6 (functionish RegExp) | |
return typeof obj === "object" || typeof obj === "function" ? | |
class2type[ toString.call( obj ) ] || "object" : | |
typeof obj; | |
}, | |
// Evaluates a script in a global context | |
globalEval: function( code ) { | |
var script, | |
indirect = eval; | |
code = jQuery.trim( code ); | |
if ( code ) { | |
// If the code includes a valid, prologue position | |
// strict mode pragma, execute code by injecting a | |
// script tag into the document. | |
if ( code.indexOf( "use strict" ) === 1 ) { | |
script = document.createElement( "script" ); | |
script.text = code; | |
document.head.appendChild( script ).parentNode.removeChild( script ); | |
} else { | |
// Otherwise, avoid the DOM node creation, insertion | |
// and removal by using an indirect global eval | |
indirect( code ); | |
} | |
} | |
}, | |
// Convert dashed to camelCase; used by the css and data modules | |
// Support: IE9-11+ | |
// Microsoft forgot to hump their vendor prefix (#9572) | |
camelCase: function( string ) { | |
return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); | |
}, | |
nodeName: function( elem, name ) { | |
return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); | |
}, | |
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.1 | |
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 ); | |
}, | |
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, | |
// Bind a function to a context, optionally partially applying any | |
// arguments. | |
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 ( !jQuery.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; | |
}, | |
now: Date.now, | |
// jQuery.support is not used in Core but other projects attach their | |
// properties to it so it needs to exist. | |
support: support | |
} ); | |
// JSHint would error on this code due to the Symbol not being defined in ES5. | |
// Defining this global in .jshintrc would create a danger of using the global | |
// unguarded in another place, it seems safer to just disable JSHint for these | |
// three lines. | |
/* jshint ignore: start */ | |
if ( typeof Symbol === "function" ) { | |
jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; | |
} | |
/* jshint ignore: end */ | |
// 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: iOS 8.2 (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 = jQuery.type( obj ); | |
if ( type === "function" || jQuery.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.2.1 | |
* http://sizzlejs.com/ | |
* | |
* Copyright jQuery Foundation and other contributors | |
* Released under the MIT license | |
* http://jquery.org/license | |
* | |
* Date: 2015-10-17 | |
*/ | |
(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; | |
}, | |
// General-purpose constants | |
MAX_NEGATIVE = 1 << 31, | |
// 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 | |
// http://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-]|[^\\x00-\\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 = /[+~]/, | |
rescape = /'|\\/g, | |
// 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 ); | |
}, | |
// Used for iframes | |
// See setDocument() | |
// Removing the function wrapper causes a "Permission Denied" | |
// error in IE | |
unloadHandler = function() { | |
setDocument(); | |
}; | |
// 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, nidselect, 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( rescape, "\\$&" ); | |
} else { | |
context.setAttribute( "id", (nid = expando) ); | |
} | |
// Prefix every selector in the list | |
groups = tokenize( selector ); | |
i = groups.length; | |
nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']"; | |
while ( i-- ) { | |
groups[i] = nidselect + " " + 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 div and expects a boolean result | |
*/ | |
function assert( fn ) { | |
var div = document.createElement("div"); | |
try { | |
return !!fn( div ); | |
} catch (e) { | |
return false; | |
} finally { | |
// Remove from its parent by default | |
if ( div.parentNode ) { | |
div.parentNode.removeChild( div ); | |
} | |
// release memory in IE | |
div = 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 && | |
( ~b.sourceIndex || MAX_NEGATIVE ) - | |
( ~a.sourceIndex || MAX_NEGATIVE ); | |
// 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 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, parent, | |
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 ( (parent = document.defaultView) && parent.top !== parent ) { | |
// Support: IE 11 | |
if ( parent.addEventListener ) { | |
parent.addEventListener( "unload", unloadHandler, false ); | |
// Support: IE 9 - 10 only | |
} else if ( parent.attachEvent ) { | |
parent.attachEvent( "onunload", unloadHandler ); | |
} | |
} | |
/* Attributes | |
---------------------------------------------------------------------- */ | |
// Support: IE<8 | |
// Verify that getAttribute really returns attributes and not properties | |
// (excepting IE8 booleans) | |
support.attributes = assert(function( div ) { | |
div.className = "i"; | |
return !div.getAttribute("className"); | |
}); | |
/* getElement(s)By* | |
---------------------------------------------------------------------- */ | |
// Check if getElementsByTagName("*") returns only elements | |
support.getElementsByTagName = assert(function( div ) { | |
div.appendChild( document.createComment("") ); | |
return !div.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 programatically-set names, | |
// so use a roundabout getElementsByName test | |
support.getById = assert(function( div ) { | |
docElem.appendChild( div ).id = expando; | |
return !document.getElementsByName || !document.getElementsByName( expando ).length; | |
}); | |
// ID find and filter | |
if ( support.getById ) { | |
Expr.find["ID"] = function( id, context ) { | |
if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { | |
var m = context.getElementById( id ); | |
return m ? [ m ] : []; | |
} | |
}; | |
Expr.filter["ID"] = function( id ) { | |
var attrId = id.replace( runescape, funescape ); | |
return function( elem ) { | |
return elem.getAttribute("id") === attrId; | |
}; | |
}; | |
} else { | |
// Support: IE6/7 | |
// getElementById is not reliable as a find shortcut | |
delete Expr.find["ID"]; | |
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; | |
}; | |
}; | |
} | |
// 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 http://bugs.jquery.com/ticket/13378 | |
rbuggyQSA = []; | |
if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { | |
// Build QSA regex | |
// Regex strategy adopted from Diego Perini | |
assert(function( div ) { | |
// 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 | |
// http://bugs.jquery.com/ticket/12359 | |
docElem.appendChild( div ).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 | |
// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section | |
if ( div.querySelectorAll("[msallowcapture^='']").length ) { | |
rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); | |
} | |
// Support: IE8 | |
// Boolean attributes and "value" are not treated correctly | |
if ( !div.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 ( !div.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 ( !div.querySelectorAll(":checked").length ) { | |
rbuggyQSA.push(":checked"); | |
} | |
// Support: Safari 8+, iOS 8+ | |
// https://bugs.webkit.org/show_bug.cgi?id=136851 | |
// In-page `selector#id sibing-combinator selector` fails | |
if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) { | |
rbuggyQSA.push(".#.+[+~]"); | |
} | |
}); | |
assert(function( div ) { | |
// Support: Windows 8 Native Apps | |
// The type and name attributes are restricted during .innerHTML assignment | |
var input = document.createElement("input"); | |
input.setAttribute( "type", "hidden" ); | |
div.appendChild( input ).setAttribute( "name", "D" ); | |
// Support: IE8 | |
// Enforce case-sensitivity of name attribute | |
if ( div.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 ( !div.querySelectorAll(":enabled").length ) { | |
rbuggyQSA.push( ":enabled", ":disabled" ); | |
} | |
// Opera 10-11 does not throw on post-comma invalid pseudos | |
div.querySelectorAll("*,:x"); | |
rbuggyQSA.push(",.*:"); | |
}); | |
} | |
if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || | |
docElem.webkitMatchesSelector || | |
docElem.mozMatchesSelector || | |
docElem.oMatchesSelector || | |
docElem.msMatchesSelector) )) ) { | |
assert(function( div ) { | |
// Check to see if it's possible to do matchesSelector | |
// on a disconnected node (IE 9) | |
support.disconnectedMatch = matches.call( div, "div" ); | |
// This should fail with an exception | |
// Gecko does not error, returns false instead | |
matches.call( div, "[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.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": function( elem ) { | |
return elem.disabled === false; | |
}, | |
"disabled": function( elem ) { | |
return elem.disabled === 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, | |
checkNonElements = base && dir === "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 ); | |
} | |
} | |
} : | |
// 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 ( (oldCache = uniqueCache[ dir ]) && | |
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[ dir ] = newCache; | |
// A match means we're done; a fail means we have to keep checking | |
if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { | |
return true; | |
} | |
} | |
} | |
} | |
} | |
}; | |
} | |
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" && | |
support.getById && 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( div1 ) { | |
// Should return 1, but returns 4 (following) | |
return div1.compareDocumentPosition( document.createElement("div") ) & 1; | |
}); | |
// Support: IE<8 | |
// Prevent attribute/property "interpolation" | |
// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx | |
if ( !assert(function( div ) { | |
div.innerHTML = "<a href='#'></a>"; | |
return div.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( div ) { | |
div.innerHTML = "<input/>"; | |
div.firstChild.setAttribute( "value", "" ); | |
return div.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( div ) { | |
return div.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; | |
jQuery.expr[ ":" ] = jQuery.expr.pseudos; | |
jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; | |
jQuery.text = Sizzle.getText; | |
jQuery.isXMLDoc = Sizzle.isXML; | |
jQuery.contains = Sizzle.contains; | |
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; | |
var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ ); | |
var risSimple = /^.[^:#\[\.,]*$/; | |
// Implement the identical functionality for filter and not | |
function winnow( elements, qualifier, not ) { | |
if ( jQuery.isFunction( qualifier ) ) { | |
return jQuery.grep( elements, function( elem, i ) { | |
/* jshint -W018 */ | |
return !!qualifier.call( elem, i, elem ) !== not; | |
} ); | |
} | |
if ( qualifier.nodeType ) { | |
return jQuery.grep( elements, function( elem ) { | |
return ( elem === qualifier ) !== not; | |
} ); | |
} | |
if ( typeof qualifier === "string" ) { | |
if ( risSimple.test( qualifier ) ) { | |
return jQuery.filter( qualifier, elements, not ); | |
} | |
qualifier = jQuery.filter( qualifier, elements ); | |
} | |
return jQuery.grep( elements, function( elem ) { | |
return ( indexOf.call( qualifier, elem ) > -1 ) !== not; | |
} ); | |
} | |
jQuery.filter = function( expr, elems, not ) { | |
var elem = elems[ 0 ]; | |
if ( not ) { | |
expr = ":not(" + expr + ")"; | |
} | |
return elems.length === 1 && elem.nodeType === 1 ? | |
jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : | |
jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { | |
return elem.nodeType === 1; | |
} ) ); | |
}; | |
jQuery.fn.extend( { | |
find: function( selector ) { | |
var i, | |
len = this.length, | |
ret = [], | |
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; | |
} | |
} | |
} ) ); | |
} | |
for ( i = 0; i < len; i++ ) { | |
jQuery.find( selector, self[ i ], ret ); | |
} | |
// Needed because $( selector, context ) becomes $( context ).find( selector ) | |
ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); | |
ret.selector = this.selector ? this.selector + " " + selector : selector; | |
return 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 <) | |
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 ( jQuery.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 ] ); | |
// Support: Blackberry 4.6 | |
// gEBID returns nodes no longer in the document (#6963) | |
if ( elem && elem.parentNode ) { | |
// Inject the element directly into the jQuery object | |
this.length = 1; | |
this[ 0 ] = elem; | |
} | |
this.context = document; | |
this.selector = selector; | |
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.context = this[ 0 ] = selector; | |
this.length = 1; | |
return this; | |
// HANDLE: $(function) | |
// Shortcut for document ready | |
} else if ( jQuery.isFunction( selector ) ) { | |
return root.ready !== undefined ? | |
root.ready( selector ) : | |
// Execute immediately if ready is not present | |
selector( jQuery ); | |
} | |
if ( selector.selector !== undefined ) { | |
this.selector = selector.selector; | |
this.context = selector.context; | |
} | |
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 = [], | |
pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? | |
jQuery( selectors, context || this.context ) : | |
0; | |
for ( ; i < l; i++ ) { | |
for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { | |
// Always skip document fragments | |
if ( cur.nodeType < 11 && ( pos ? | |
pos.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 ) { | |
return elem.contentDocument || 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 rnotwhite = ( /\S+/g ); | |
// Convert String-formatted options into Object-formatted ones | |
function createOptions( options ) { | |
var object = {}; | |
jQuery.each( options.match( rnotwhite ) || [], 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 = 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 ( jQuery.isFunction( arg ) ) { | |
if ( !options.unique || !self.has( arg ) ) { | |
list.push( arg ); | |
} | |
} else if ( arg && arg.length && jQuery.type( 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 ) { | |
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; | |
}; | |
jQuery.extend( { | |
Deferred: function( func ) { | |
var tuples = [ | |
// action, add listener, listener list, final state | |
[ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ], | |
[ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ], | |
[ "notify", "progress", jQuery.Callbacks( "memory" ) ] | |
], | |
state = "pending", | |
promise = { | |
state: function() { | |
return state; | |
}, | |
always: function() { | |
deferred.done( arguments ).fail( arguments ); | |
return this; | |
}, | |
then: function( /* fnDone, fnFail, fnProgress */ ) { | |
var fns = arguments; | |
return jQuery.Deferred( function( newDefer ) { | |
jQuery.each( tuples, function( i, tuple ) { | |
var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; | |
// deferred[ done | fail | progress ] for forwarding actions to newDefer | |
deferred[ tuple[ 1 ] ]( function() { | |
var returned = fn && fn.apply( this, arguments ); | |
if ( returned && jQuery.isFunction( returned.promise ) ) { | |
returned.promise() | |
.progress( newDefer.notify ) | |
.done( newDefer.resolve ) | |
.fail( newDefer.reject ); | |
} else { | |
newDefer[ tuple[ 0 ] + "With" ]( | |
this === promise ? newDefer.promise() : this, | |
fn ? [ returned ] : arguments | |
); | |
} | |
} ); | |
} ); | |
fns = null; | |
} ).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 = {}; | |
// Keep pipe for back-compat | |
promise.pipe = promise.then; | |
// Add list-specific methods | |
jQuery.each( tuples, function( i, tuple ) { | |
var list = tuple[ 2 ], | |
stateString = tuple[ 3 ]; | |
// promise[ done | fail | progress ] = list.add | |
promise[ tuple[ 1 ] ] = list.add; | |
// Handle state | |
if ( stateString ) { | |
list.add( function() { | |
// state = [ resolved | rejected ] | |
state = stateString; | |
// [ reject_list | resolve_list ].disable; progress_list.lock | |
}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); | |
} | |
// deferred[ resolve | reject | notify ] | |
deferred[ tuple[ 0 ] ] = function() { | |
deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments ); | |
return this; | |
}; | |
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( subordinate /* , ..., subordinateN */ ) { | |
var i = 0, | |
resolveValues = slice.call( arguments ), | |
length = resolveValues.length, | |
// the count of uncompleted subordinates | |
remaining = length !== 1 || | |
( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, | |
// the master Deferred. | |
// If resolveValues consist of only a single Deferred, just use that. | |
deferred = remaining === 1 ? subordinate : jQuery.Deferred(), | |
// Update function for both resolve and progress values | |
updateFunc = function( i, contexts, values ) { | |
return function( value ) { | |
contexts[ i ] = this; | |
values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; | |
if ( values === progressValues ) { | |
deferred.notifyWith( contexts, values ); | |
} else if ( !( --remaining ) ) { | |
deferred.resolveWith( contexts, values ); | |
} | |
}; | |
}, | |
progressValues, progressContexts, resolveContexts; | |
// Add listeners to Deferred subordinates; treat others as resolved | |
if ( length > 1 ) { | |
progressValues = new Array( length ); | |
progressContexts = new Array( length ); | |
resolveContexts = new Array( length ); | |
for ( ; i < length; i++ ) { | |
if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { | |
resolveValues[ i ].promise() | |
.progress( updateFunc( i, progressContexts, progressValues ) ) | |
.done( updateFunc( i, resolveContexts, resolveValues ) ) | |
.fail( deferred.reject ); | |
} else { | |
--remaining; | |
} | |
} | |
} | |
// If we're not waiting on anything, resolve the master | |
if ( !remaining ) { | |
deferred.resolveWith( resolveContexts, resolveValues ); | |
} | |
return deferred.promise(); | |
} | |
} ); | |
// The deferred used on DOM ready | |
var readyList; | |
jQuery.fn.ready = function( fn ) { | |
// Add the callback | |
jQuery.ready.promise().done( fn ); | |
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, | |
// Hold (or release) the ready event | |
holdReady: function( hold ) { | |
if ( hold ) { | |
jQuery.readyWait++; | |
} else { | |
jQuery.ready( true ); | |
} | |
}, | |
// 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 ] ); | |
// Trigger any bound ready events | |
if ( jQuery.fn.triggerHandler ) { | |
jQuery( document ).triggerHandler( "ready" ); | |
jQuery( document ).off( "ready" ); | |
} | |
} | |
} ); | |
/** | |
* The ready event handler and self cleanup method | |
*/ | |
function completed() { | |
document.removeEventListener( "DOMContentLoaded", completed ); | |
window.removeEventListener( "load", completed ); | |
jQuery.ready(); | |
} | |
jQuery.ready.promise = function( obj ) { | |
if ( !readyList ) { | |
readyList = jQuery.Deferred(); | |
// Catch cases where $(document).ready() is called | |
// after the browser event has already occurred. | |
// Support: IE9-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 ); | |
} | |
} | |
return readyList.promise( obj ); | |
}; | |
// Kick off the DOM ready check even if the user does not | |
jQuery.ready.promise(); | |
// 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 ( jQuery.type( 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 ( !jQuery.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 ) ) | |
); | |
} | |
} | |
} | |
return chainable ? | |
elems : | |
// Gets | |
bulk ? | |
fn.call( elems ) : | |
len ? fn( elems[ 0 ], key ) : emptyGet; | |
}; | |
var acceptData = function( owner ) { | |
// Accepts only: | |
// - Node | |
// - Node.ELEMENT_NODE | |
// - Node.DOCUMENT_NODE | |
// - Object | |
// - Any | |
/* jshint -W018 */ | |
return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); | |
}; | |
function Data() { | |
this.expando = jQuery.expando + Data.uid++; | |
} | |
Data.uid = 1; | |
Data.prototype = { | |
register: function( owner, initial ) { | |
var value = initial || {}; | |
// 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, non-writable property | |
// configurability must be true to allow the property to be | |
// deleted with the delete operator | |
} else { | |
Object.defineProperty( owner, this.expando, { | |
value: value, | |
writable: true, | |
configurable: true | |
} ); | |
} | |
return owner[ this.expando ]; | |
}, | |
cache: function( owner ) { | |
// 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 ) ) { | |
return {}; | |
} | |
// 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 | |
if ( typeof data === "string" ) { | |
cache[ data ] = value; | |
// Handle: [ owner, { properties } ] args | |
} else { | |
// Copy the properties one-by-one to the cache object | |
for ( prop in data ) { | |
cache[ prop ] = data[ prop ]; | |
} | |
} | |
return cache; | |
}, | |
get: function( owner, key ) { | |
return key === undefined ? | |
this.cache( owner ) : | |
owner[ this.expando ] && owner[ this.expando ][ key ]; | |
}, | |
access: function( owner, key, value ) { | |
var stored; | |
// 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 ) ) { | |
stored = this.get( owner, key ); | |
return stored !== undefined ? | |
stored : this.get( owner, jQuery.camelCase( 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, name, camel, | |
cache = owner[ this.expando ]; | |
if ( cache === undefined ) { | |
return; | |
} | |
if ( key === undefined ) { | |
this.register( owner ); | |
} else { | |
// Support array or space separated string of keys | |
if ( jQuery.isArray( key ) ) { | |
// If "name" is an array of keys... | |
// When data is initially created, via ("key", "val") signature, | |
// keys will be converted to camelCase. | |
// Since there is no way to tell _how_ a key was added, remove | |
// both plain key and camelCase key. #12786 | |
// This will only penalize the array argument path. | |
name = key.concat( key.map( jQuery.camelCase ) ); | |
} else { | |
camel = jQuery.camelCase( key ); | |
// Try the string as a key before any manipulation | |
if ( key in cache ) { | |
name = [ key, camel ]; | |
} else { | |
// If a key with the spaces exists, use it. | |
// Otherwise, create an array by matching non-whitespace | |
name = camel; | |
name = name in cache ? | |
[ name ] : ( name.match( rnotwhite ) || [] ); | |
} | |
} | |
i = name.length; | |
while ( i-- ) { | |
delete cache[ name[ 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://code.google.com/p/chromium/issues/detail?id=378607 | |
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 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 = data === "true" ? true : | |
data === "false" ? false : | |
data === "null" ? null : | |
// Only convert to a number if it doesn't change the string | |
+data + "" === data ? +data : | |
rbrace.test( data ) ? jQuery.parseJSON( data ) : | |
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: IE11+ | |
// The attrs elements can be null (#14894) | |
if ( attrs[ i ] ) { | |
name = attrs[ i ].name; | |
if ( name.indexOf( "data-" ) === 0 ) { | |
name = jQuery.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, camelKey; | |
// 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 | |
// with the key as-is | |
data = dataUser.get( elem, key ) || | |
// Try to find dashed key if it exists (gh-2779) | |
// This is for 2.2.x only | |
dataUser.get( elem, key.replace( rmultiDash, "-$&" ).toLowerCase() ); | |
if ( data !== undefined ) { | |
return data; | |
} | |
camelKey = jQuery.camelCase( key ); | |
// Attempt to get data from the cache | |
// with the key camelized | |
data = dataUser.get( elem, camelKey ); | |
if ( data !== undefined ) { | |
return data; | |
} | |
// Attempt to "discover" the data in | |
// HTML5 custom data-* attrs | |
data = dataAttr( elem, camelKey, undefined ); | |
if ( data !== undefined ) { | |
return data; | |
} | |
// We tried really hard, but the data doesn't exist. | |
return; | |
} | |
// Set the data... | |
camelKey = jQuery.camelCase( key ); | |
this.each( function() { | |
// First, attempt to store a copy or reference of any | |
// data that might've been store with a camelCased key. | |
var data = dataUser.get( this, camelKey ); | |
// For HTML5 data-* attribute interop, we have to | |
// store property names with dashes in a camelCase form. | |
// This might not apply to all properties...* | |
dataUser.set( this, camelKey, value ); | |
// *... In the case of properties that might _actually_ | |
// have dashes, we need to also store a copy of that | |
// unchanged property. | |
if ( key.indexOf( "-" ) > -1 && data !== undefined ) { | |
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 || jQuery.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 isHidden = function( elem, el ) { | |
// isHidden might be called from jQuery#filter function; | |
// in that case, element will be second argument | |
elem = el || elem; | |
return jQuery.css( elem, "display" ) === "none" || | |
!jQuery.contains( elem.ownerDocument, elem ); | |
}; | |
function adjustCSS( elem, prop, valueParts, tween ) { | |
var adjusted, | |
scale = 1, | |
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 ) { | |
// Trust units reported by jQuery.css | |
unit = unit || initialInUnit[ 3 ]; | |
// Make sure we update the tween properties later on | |
valueParts = valueParts || []; | |
// Iteratively approximate from a nonzero starting point | |
initialInUnit = +initial || 1; | |
do { | |
// If previous iteration zeroed out, double until we get *something*. | |
// Use string for doubling so we don't accidentally see scale as unchanged below | |
scale = scale || ".5"; | |
// Adjust and apply | |
initialInUnit = initialInUnit / scale; | |
jQuery.style( elem, prop, initialInUnit + unit ); | |
// Update scale, tolerating zero or NaN from tween.cur() | |
// Break the loop if scale is unchanged or perfect, or if we've just had enough. | |
} while ( | |
scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations | |
); | |
} | |
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 rcheckableType = ( /^(?:checkbox|radio)$/i ); | |
var rtagName = ( /<([\w:-]+)/ ); | |
var rscriptType = ( /^$|\/(?:java|ecma)script/i ); | |
// We have to close these tags to support XHTML (#13200) | |
var wrapMap = { | |
// Support: IE9 | |
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: IE9 | |
wrapMap.optgroup = wrapMap.option; | |
wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; | |
wrapMap.th = wrapMap.td; | |
function getAll( context, tag ) { | |
// Support: IE9-11+ | |
// Use typeof to avoid zero-argument method invocation on host objects (#15151) | |
var ret = typeof context.getElementsByTagName !== "undefined" ? | |
context.getElementsByTagName( tag || "*" ) : | |
typeof context.querySelectorAll !== "undefined" ? | |
context.querySelectorAll( tag || "*" ) : | |
[]; | |
return tag === undefined || tag && jQuery.nodeName( context, tag ) ? | |
jQuery.merge( [ context ], ret ) : | |
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 ( jQuery.type( elem ) === "object" ) { | |
// Support: Android<4.1, PhantomJS<2 | |
// 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.1, PhantomJS<2 | |
// 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, Safari<=5.1 | |
// 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: Safari<=5.1, Android<4.2 | |
// Older WebKit doesn't clone checked state correctly in fragments | |
support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; | |
// Support: IE<=11+ | |
// Make sure textarea (and checkbox) defaultValue is properly cloned | |
div.innerHTML = "<textarea>x</textarea>"; | |
support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; | |
} )(); | |
var | |
rkeyEvent = /^key/, | |
rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, | |
rtypenamespace = /^([^.]*)(?:\.(.+)|)/; | |
function returnTrue() { | |
return true; | |
} | |
function returnFalse() { | |
return false; | |
} | |
// Support: IE9 | |
// 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 this; | |
} | |
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; | |
} | |
// 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( rnotwhite ) || [ "" ]; | |
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( rnotwhite ) || [ "" ]; | |
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( event ) { | |
// Make a writable jQuery.Event from the native event object | |
event = jQuery.event.fix( event ); | |
var i, j, ret, matched, handleObj, | |
handlerQueue = [], | |
args = slice.call( arguments ), | |
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; | |
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, matches, sel, handleObj, | |
handlerQueue = [], | |
delegateCount = handlers.delegateCount, | |
cur = event.target; | |
// Support (at least): Chrome, IE9 | |
// Find delegate handlers | |
// Black-hole SVG <use> instance trees (#13180) | |
// | |
// Support: Firefox<=42+ | |
// Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343) | |
if ( delegateCount && cur.nodeType && | |
( event.type !== "click" || isNaN( event.button ) || 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 && ( cur.disabled !== true || event.type !== "click" ) ) { | |
matches = []; | |
for ( i = 0; i < delegateCount; i++ ) { | |
handleObj = handlers[ i ]; | |
// Don't conflict with Object.prototype properties (#13203) | |
sel = handleObj.selector + " "; | |
if ( matches[ sel ] === undefined ) { | |
matches[ sel ] = handleObj.needsContext ? | |
jQuery( sel, this ).index( cur ) > -1 : | |
jQuery.find( sel, this, null, [ cur ] ).length; | |
} | |
if ( matches[ sel ] ) { | |
matches.push( handleObj ); | |
} | |
} | |
if ( matches.length ) { | |
handlerQueue.push( { elem: cur, handlers: matches } ); | |
} | |
} | |
} | |
} | |
// Add the remaining (directly-bound) handlers | |
if ( delegateCount < handlers.length ) { | |
handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } ); | |
} | |
return handlerQueue; | |
}, | |
// Includes some event props shared by KeyEvent and MouseEvent | |
props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " + | |
"metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ), | |
fixHooks: {}, | |
keyHooks: { | |
props: "char charCode key keyCode".split( " " ), | |
filter: function( event, original ) { | |
// Add which for key events | |
if ( event.which == null ) { | |
event.which = original.charCode != null ? original.charCode : original.keyCode; | |
} | |
return event; | |
} | |
}, | |
mouseHooks: { | |
props: ( "button buttons clientX clientY offsetX offsetY pageX pageY " + | |
"screenX screenY toElement" ).split( " " ), | |
filter: function( event, original ) { | |
var eventDoc, doc, body, | |
button = original.button; | |
// Calculate pageX/Y if missing and clientX/Y available | |
if ( event.pageX == null && original.clientX != null ) { | |
eventDoc = event.target.ownerDocument || document; | |
doc = eventDoc.documentElement; | |
body = eventDoc.body; | |
event.pageX = original.clientX + | |
( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - | |
( doc && doc.clientLeft || body && body.clientLeft || 0 ); | |
event.pageY = original.clientY + | |
( doc && doc.scrollTop || body && body.scrollTop || 0 ) - | |
( doc && doc.clientTop || body && body.clientTop || 0 ); | |
} | |
// Add which for click: 1 === left; 2 === middle; 3 === right | |
// Note: button is not normalized, so don't use it | |
if ( !event.which && button !== undefined ) { | |
event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); | |
} | |
return event; | |
} | |
}, | |
fix: function( event ) { | |
if ( event[ jQuery.expando ] ) { | |
return event; | |
} | |
// Create a writable copy of the event object and normalize some properties | |
var i, prop, copy, | |
type = event.type, | |
originalEvent = event, | |
fixHook = this.fixHooks[ type ]; | |
if ( !fixHook ) { | |
this.fixHooks[ type ] = fixHook = | |
rmouseEvent.test( type ) ? this.mouseHooks : | |
rkeyEvent.test( type ) ? this.keyHooks : | |
{}; | |
} | |
copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; | |
event = new jQuery.Event( originalEvent ); | |
i = copy.length; | |
while ( i-- ) { | |
prop = copy[ i ]; | |
event[ prop ] = originalEvent[ prop ]; | |
} | |
// Support: Cordova 2.5 (WebKit) (#13255) | |
// All events should have a target; Cordova deviceready doesn't | |
if ( !event.target ) { | |
event.target = document; | |
} | |
// Support: Safari 6.0+, Chrome<28 | |
// Target should not be a text node (#504, #13143) | |
if ( event.target.nodeType === 3 ) { | |
event.target = event.target.parentNode; | |
} | |
return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; | |
}, | |
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 && jQuery.nodeName( this, "input" ) ) { | |
this.click(); | |
return false; | |
} | |
}, | |
// For cross-browser consistency, don't fire native .click() on links | |
_default: function( event ) { | |
return jQuery.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<4.0 | |
src.returnValue === false ? | |
returnTrue : | |
returnFalse; | |
// 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 || jQuery.now(); | |
// Mark it as fixed | |
this[ jQuery.expando ] = true; | |
}; | |
// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding | |
// http://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, | |
preventDefault: function() { | |
var e = this.originalEvent; | |
this.isDefaultPrevented = returnTrue; | |
if ( e ) { | |
e.preventDefault(); | |
} | |
}, | |
stopPropagation: function() { | |
var e = this.originalEvent; | |
this.isPropagationStopped = returnTrue; | |
if ( e ) { | |
e.stopPropagation(); | |
} | |
}, | |
stopImmediatePropagation: function() { | |
var e = this.originalEvent; | |
this.isImmediatePropagationStopped = returnTrue; | |
if ( e ) { | |
e.stopImmediatePropagation(); | |
} | |
this.stopPropagation(); | |
} | |
}; | |
// 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://code.google.com/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 | |
rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi, | |
// Support: IE 10-11, Edge 10240+ | |
// 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, | |
rscriptTypeMasked = /^true\/(.*)/, | |
rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g; | |
function manipulationTarget( elem, content ) { | |
if ( jQuery.nodeName( elem, "table" ) && | |
jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { | |
return elem.getElementsByTagName( "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 ) { | |
var match = rscriptTypeMasked.exec( elem.type ); | |
if ( match ) { | |
elem.type = match[ 1 ]; | |
} 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 ], | |
isFunction = jQuery.isFunction( value ); | |
// We can't cloneNode fragments that contain checked, in WebKit | |
if ( isFunction || | |
( l > 1 && typeof value === "string" && | |
!support.checkClone && rchecked.test( value ) ) ) { | |
return collection.each( function( index ) { | |
var self = collection.eq( index ); | |
if ( isFunction ) { | |
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.1, PhantomJS<2 | |
// 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 ) { | |
// Optional AJAX dependency, but won't run scripts if not present | |
if ( jQuery._evalUrl ) { | |
jQuery._evalUrl( node.src ); | |
} | |
} else { | |
jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) ); | |
} | |
} | |
} | |
} | |
} | |
} | |
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: http://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( { | |
// Keep domManip exposed until 3.0 (gh-2225) | |
domManip: domManip, | |
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: QtWebKit | |
// .get() because push.apply(_, arraylike) throws | |
push.apply( ret, elems.get() ); | |
} | |
return this.pushStack( ret ); | |
}; | |
} ); | |
var iframe, | |
elemdisplay = { | |
// Support: Firefox | |
// We have to pre-define these values for FF (#10227) | |
HTML: "block", | |
BODY: "block" | |
}; | |
/** | |
* Retrieve the actual display of a element | |
* @param {String} name nodeName of the element | |
* @param {Object} doc Document object | |
*/ | |
// Called only from within defaultDisplay | |
function actualDisplay( name, doc ) { | |
var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), | |
display = jQuery.css( elem[ 0 ], "display" ); | |
// We don't have any data stored on the element, | |
// so use "detach" method as fast way to get rid of the element | |
elem.detach(); | |
return display; | |
} | |
/** | |
* Try to determine the default display value of an element | |
* @param {String} nodeName | |
*/ | |
function defaultDisplay( nodeName ) { | |
var doc = document, | |
display = elemdisplay[ nodeName ]; | |
if ( !display ) { | |
display = actualDisplay( nodeName, doc ); | |
// If the simple way fails, read from inside an iframe | |
if ( display === "none" || !display ) { | |
// Use the already-created iframe if possible | |
iframe = ( iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" ) ) | |
.appendTo( doc.documentElement ); | |
// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse | |
doc = iframe[ 0 ].contentDocument; | |
// Support: IE | |
doc.write(); | |
doc.close(); | |
display = actualDisplay( nodeName, doc ); | |
iframe.detach(); | |
} | |
// Store the correct default display | |
elemdisplay[ nodeName ] = display; | |
} | |
return display; | |
} | |
var rmargin = ( /^margin/ ); | |
var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); | |
var getStyles = function( elem ) { | |
// Support: IE<=11+, 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.opener ) { | |
view = window; | |
} | |
return view.getComputedStyle( elem ); | |
}; | |
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; | |
}; | |
var documentElement = document.documentElement; | |
( function() { | |
var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal, | |
container = document.createElement( "div" ), | |
div = document.createElement( "div" ); | |
// Finish early in limited (non-browser) environments | |
if ( !div.style ) { | |
return; | |
} | |
// Support: IE9-11+ | |
// 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"; | |
container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" + | |
"padding:0;margin-top:1px;position:absolute"; | |
container.appendChild( div ); | |
// Executing both pixelPosition & boxSizingReliable tests require only one layout | |
// so they're executed at the same time to save the second computation. | |
function computeStyleTests() { | |
div.style.cssText = | |
// Support: Firefox<29, Android 2.3 | |
// Vendor-prefix box-sizing | |
"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;" + | |
"position:relative;display:block;" + | |
"margin:auto;border:1px;padding:1px;" + | |
"top:1%;width:50%"; | |
div.innerHTML = ""; | |
documentElement.appendChild( container ); | |
var divStyle = window.getComputedStyle( div ); | |
pixelPositionVal = divStyle.top !== "1%"; | |
reliableMarginLeftVal = divStyle.marginLeft === "2px"; | |
boxSizingReliableVal = divStyle.width === "4px"; | |
// Support: Android 4.0 - 4.3 only | |
// Some styles come back with percentage values, even though they shouldn't | |
div.style.marginRight = "50%"; | |
pixelMarginRightVal = divStyle.marginRight === "4px"; | |
documentElement.removeChild( container ); | |
} | |
jQuery.extend( support, { | |
pixelPosition: function() { | |
// This test is executed only once but we still do memoizing | |
// since we can use the boxSizingReliable pre-computing. | |
// No need to check if the test was already performed, though. | |
computeStyleTests(); | |
return pixelPositionVal; | |
}, | |
boxSizingReliable: function() { | |
if ( boxSizingReliableVal == null ) { | |
computeStyleTests(); | |
} | |
return boxSizingReliableVal; | |
}, | |
pixelMarginRight: function() { | |
// Support: Android 4.0-4.3 | |
// We're checking for boxSizingReliableVal here instead of pixelMarginRightVal | |
// since that compresses better and they're computed together anyway. | |
if ( boxSizingReliableVal == null ) { | |
computeStyleTests(); | |
} | |
return pixelMarginRightVal; | |
}, | |
reliableMarginLeft: function() { | |
// Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37 | |
if ( boxSizingReliableVal == null ) { | |
computeStyleTests(); | |
} | |
return reliableMarginLeftVal; | |
}, | |
reliableMarginRight: function() { | |
// Support: Android 2.3 | |
// Check if div with explicit width and no margin-right incorrectly | |
// gets computed margin-right based on width of container. (#3333) | |
// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right | |
// This support function is only executed once so no memoizing is needed. | |
var ret, | |
marginDiv = div.appendChild( document.createElement( "div" ) ); | |
// Reset CSS: box-sizing; display; margin; border; padding | |
marginDiv.style.cssText = div.style.cssText = | |
// Support: Android 2.3 | |
// Vendor-prefix box-sizing | |
"-webkit-box-sizing:content-box;box-sizing:content-box;" + | |
"display:block;margin:0;border:0;padding:0"; | |
marginDiv.style.marginRight = marginDiv.style.width = "0"; | |
div.style.width = "1px"; | |
documentElement.appendChild( container ); | |
ret = !parseFloat( window.getComputedStyle( marginDiv ).marginRight ); | |
documentElement.removeChild( container ); | |
div.removeChild( marginDiv ); | |
return ret; | |
} | |
} ); | |
} )(); | |
function curCSS( elem, name, computed ) { | |
var width, minWidth, maxWidth, ret, | |
style = elem.style; | |
computed = computed || getStyles( elem ); | |
// Support: IE9 | |
// getPropertyValue is only needed for .css('filter') (#12537) | |
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: | |
// http://dev.w3.org/csswg/cssom/#resolved-values | |
if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.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: IE9-11+ | |
// 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]).+)/, | |
cssShow = { position: "absolute", visibility: "hidden", display: "block" }, | |
cssNormalTransform = { | |
letterSpacing: "0", | |
fontWeight: "400" | |
}, | |
cssPrefixes = [ "Webkit", "O", "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; | |
} | |
} | |
} | |
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 augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { | |
var i = extra === ( isBorderBox ? "border" : "content" ) ? | |
// If we already have the right measurement, avoid augmentation | |
4 : | |
// Otherwise initialize for horizontal or vertical properties | |
name === "width" ? 1 : 0, | |
val = 0; | |
for ( ; i < 4; i += 2 ) { | |
// Both box models exclude margin, so add it if we want it | |
if ( extra === "margin" ) { | |
val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); | |
} | |
if ( isBorderBox ) { | |
// border-box includes padding, so remove it if we want content | |
if ( extra === "content" ) { | |
val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); | |
} | |
// At this point, extra isn't border nor margin, so remove border | |
if ( extra !== "margin" ) { | |
val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); | |
} | |
} else { | |
// At this point, extra isn't content, so add padding | |
val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); | |
// At this point, extra isn't content nor padding, so add border | |
if ( extra !== "padding" ) { | |
val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); | |
} | |
} | |
} | |
return val; | |
} | |
function getWidthOrHeight( elem, name, extra ) { | |
// Start with offset property, which is equivalent to the border-box value | |
var valueIsBorderBox = true, | |
val = name === "width" ? elem.offsetWidth : elem.offsetHeight, | |
styles = getStyles( elem ), | |
isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; | |
// Support: IE11 only | |
// In IE 11 fullscreen elements inside of an iframe have | |
// 100x too small dimensions (gh-1764). | |
if ( document.msFullscreenElement && window.top !== window ) { | |
// Support: IE11 only | |
// Running getBoundingClientRect on a disconnected node | |
// in IE throws an error. | |
if ( elem.getClientRects().length ) { | |
val = Math.round( elem.getBoundingClientRect()[ name ] * 100 ); | |
} | |
} | |
// Some non-html elements return undefined for offsetWidth, so check for null/undefined | |
// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 | |
// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 | |
if ( val <= 0 || val == null ) { | |
// Fall back to computed then uncomputed css if necessary | |
val = curCSS( elem, name, styles ); | |
if ( val < 0 || val == null ) { | |
val = elem.style[ name ]; | |
} | |
// Computed unit is not pixels. Stop here and return. | |
if ( rnumnonpx.test( val ) ) { | |
return val; | |
} | |
// Check for style in case a browser which returns unreliable values | |
// for getComputedStyle silently falls back to the reliable elem.style | |
valueIsBorderBox = isBorderBox && | |
( support.boxSizingReliable() || val === elem.style[ name ] ); | |
// Normalize "", auto, and prepare for extra | |
val = parseFloat( val ) || 0; | |
} | |
// Use the active box-sizing model to add/subtract irrelevant styles | |
return ( val + | |
augmentWidthOrHeight( | |
elem, | |
name, | |
extra || ( isBorderBox ? "border" : "content" ), | |
valueIsBorderBox, | |
styles | |
) | |
) + "px"; | |
} | |
function showHide( elements, show ) { | |
var display, elem, hidden, | |
values = [], | |
index = 0, | |
length = elements.length; | |
for ( ; index < length; index++ ) { | |
elem = elements[ index ]; | |
if ( !elem.style ) { | |
continue; | |
} | |
values[ index ] = dataPriv.get( elem, "olddisplay" ); | |
display = elem.style.display; | |
if ( show ) { | |
// Reset the inline display of this element to learn if it is | |
// being hidden by cascaded rules or not | |
if ( !values[ index ] && display === "none" ) { | |
elem.style.display = ""; | |
} | |
// Set elements which have been overridden with display: none | |
// in a stylesheet to whatever the default browser style is | |
// for such an element | |
if ( elem.style.display === "" && isHidden( elem ) ) { | |
values[ index ] = dataPriv.access( | |
elem, | |
"olddisplay", | |
defaultDisplay( elem.nodeName ) | |
); | |
} | |
} else { | |
hidden = isHidden( elem ); | |
if ( display !== "none" || !hidden ) { | |
dataPriv.set( | |
elem, | |
"olddisplay", | |
hidden ? display : jQuery.css( elem, "display" ) | |
); | |
} | |
} | |
} | |
// Set the display of most of the elements in a second loop | |
// to avoid the constant reflow | |
for ( index = 0; index < length; index++ ) { | |
elem = elements[ index ]; | |
if ( !elem.style ) { | |
continue; | |
} | |
if ( !show || elem.style.display === "none" || elem.style.display === "" ) { | |
elem.style.display = show ? values[ index ] || "" : "none"; | |
} | |
} | |
return elements; | |
} | |
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: { | |
"float": "cssFloat" | |
}, | |
// 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 = jQuery.camelCase( name ), | |
style = elem.style; | |
name = jQuery.cssProps[ origName ] || | |
( jQuery.cssProps[ origName ] = vendorPropName( origName ) || 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" ); | |
} | |
// Support: IE9-11+ | |
// 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 ) { | |
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 = jQuery.camelCase( name ); | |
// Make sure that we're working with the right name | |
name = jQuery.cssProps[ origName ] || | |
( jQuery.cssProps[ origName ] = vendorPropName( origName ) || 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, name ) { | |
jQuery.cssHooks[ name ] = { | |
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" ) ) && | |
elem.offsetWidth === 0 ? | |
swap( elem, cssShow, function() { | |
return getWidthOrHeight( elem, name, extra ); | |
} ) : | |
getWidthOrHeight( elem, name, extra ); | |
} | |
}, | |
set: function( elem, value, extra ) { | |
var matches, | |
styles = extra && getStyles( elem ), | |
subtract = extra && augmentWidthOrHeight( | |
elem, | |
name, | |
extra, | |
jQuery.css( elem, "boxSizing", false, styles ) === "border-box", | |
styles | |
); | |
// Convert to pixels if value adjustment is needed | |
if ( subtract && ( matches = rcssNum.exec( value ) ) && | |
( matches[ 3 ] || "px" ) !== "px" ) { | |
elem.style[ name ] = value; | |
value = jQuery.css( elem, name ); | |
} | |
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"; | |
} | |
} | |
); | |
// Support: Android 2.3 | |
jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight, | |
function( elem, computed ) { | |
if ( computed ) { | |
return swap( elem, { "display": "inline-block" }, | |
curCSS, [ elem, "marginRight" ] ); | |
} | |
} | |
); | |
// 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 ( !rmargin.test( prefix ) ) { | |
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 ( jQuery.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 ); | |
}, | |
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 ( isHidden( this ) ) { | |
jQuery( this ).show(); | |
} else { | |
jQuery( this ).hide(); | |
} | |
} ); | |
} | |
} ); | |
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: IE9 | |
// 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, timerId, | |
rfxtypes = /^(?:toggle|show|hide)$/, | |
rrun = /queueHooks$/; | |
// Animations created synchronously will run synchronously | |
function createFxNow() { | |
window.setTimeout( function() { | |
fxNow = undefined; | |
} ); | |
return ( fxNow = jQuery.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 ) { | |
/* jshint validthis: true */ | |
var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay, | |
anim = this, | |
orig = {}, | |
style = elem.style, | |
hidden = elem.nodeType && isHidden( elem ), | |
dataShow = dataPriv.get( elem, "fxshow" ); | |
// Handle queue: false promises | |
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(); | |
} | |
} ); | |
} ); | |
} | |
// Height/width overflow pass | |
if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) { | |
// Make sure that nothing sneaks out | |
// Record all 3 overflow attributes because IE9-10 do not | |
// change the overflow attribute when overflowX and | |
// overflowY are set to the same value | |
opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; | |
// Set display property to inline-block for height/width | |
// animations on inline elements that are having width/height animated | |
display = jQuery.css( elem, "display" ); | |
// Test default display if display is currently "none" | |
checkDisplay = display === "none" ? | |
dataPriv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display; | |
if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) { | |
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 ]; | |
} ); | |
} | |
// show/hide pass | |
for ( prop in props ) { | |
value = props[ prop ]; | |
if ( rfxtypes.exec( value ) ) { | |
delete props[ prop ]; | |
toggle = toggle || value === "toggle"; | |
if ( value === ( hidden ? "hide" : "show" ) ) { | |
// If there is dataShow left over from a stopped hide or show | |
// and we are going to proceed with show, we should pretend to be hidden | |
if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { | |
hidden = true; | |
} else { | |
continue; | |
} | |
} | |
orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); | |
// Any non-fx value stops us from restoring the original display value | |
} else { | |
display = undefined; | |
} | |
} | |
if ( !jQuery.isEmptyObject( orig ) ) { | |
if ( dataShow ) { | |
if ( "hidden" in dataShow ) { | |
hidden = dataShow.hidden; | |
} | |
} else { | |
dataShow = dataPriv.access( elem, "fxshow", {} ); | |
} | |
// Store state if its toggle - enables .stop().toggle() to "reverse" | |
if ( toggle ) { | |
dataShow.hidden = !hidden; | |
} | |
if ( hidden ) { | |
jQuery( elem ).show(); | |
} else { | |
anim.done( function() { | |
jQuery( elem ).hide(); | |
} ); | |
} | |
anim.done( function() { | |
var prop; | |
dataPriv.remove( elem, "fxshow" ); | |
for ( prop in orig ) { | |
jQuery.style( elem, prop, orig[ prop ] ); | |
} | |
} ); | |
for ( prop in orig ) { | |
tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); | |
if ( !( prop in dataShow ) ) { | |
dataShow[ prop ] = tween.start; | |
if ( hidden ) { | |
tween.end = tween.start; | |
tween.start = prop === "width" || prop === "height" ? 1 : 0; | |
} | |
} | |
} | |
// If this is a noop like .hide().hide(), restore an overwritten display value | |
} else if ( ( display === "none" ? defaultDisplay( elem.nodeName ) : display ) === "inline" ) { | |
style.display = display; | |
} | |
} | |
function propFilter( props, specialEasing ) { | |
var index, name, easing, value, hooks; | |
// camelCase, specialEasing and expand cssHook pass | |
for ( index in props ) { | |
name = jQuery.camelCase( index ); | |
easing = specialEasing[ name ]; | |
value = props[ index ]; | |
if ( jQuery.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 | |
// 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 ( percent < 1 && length ) { | |
return remaining; | |
} else { | |
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 ( jQuery.isFunction( result.stop ) ) { | |
jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = | |
jQuery.proxy( result.stop, result ); | |
} | |
return result; | |
} | |
} | |
jQuery.map( props, createTween, animation ); | |
if ( jQuery.isFunction( animation.opts.start ) ) { | |
animation.opts.start.call( elem, animation ); | |
} | |
jQuery.fx.timer( | |
jQuery.extend( tick, { | |
elem: elem, | |
anim: animation, | |
queue: animation.opts.queue | |
} ) | |
); | |
// attach callbacks from options | |
return animation.progress( animation.opts.progress ) | |
.done( animation.opts.done, animation.opts.complete ) | |
.fail( animation.opts.fail ) | |
.always( animation.opts.always ); | |
} | |
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 ( jQuery.isFunction( props ) ) { | |
callback = props; | |
props = [ "*" ]; | |
} else { | |
props = props.match( rnotwhite ); | |
} | |
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 || | |
jQuery.isFunction( speed ) && speed, | |
duration: speed, | |
easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing | |
}; | |
opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? | |
opt.duration : opt.duration in jQuery.fx.speeds ? | |
jQuery.fx.speeds[ 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 ( jQuery.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( isHidden ).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 = jQuery.now(); | |
for ( ; i < timers.length; i++ ) { | |
timer = timers[ i ]; | |
// Checks the timer has not already been removed | |
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 ); | |
if ( timer() ) { | |
jQuery.fx.start(); | |
} else { | |
jQuery.timers.pop(); | |
} | |
}; | |
jQuery.fx.interval = 13; | |
jQuery.fx.start = function() { | |
if ( !timerId ) { | |
timerId = window.setInterval( jQuery.fx.tick, jQuery.fx.interval ); | |
} | |
}; | |
jQuery.fx.stop = function() { | |
window.clearInterval( timerId ); | |
timerId = null; | |
}; | |
jQuery.fx.speeds = { | |
slow: 600, | |
fast: 200, | |
// Default speed | |
_default: 400 | |
}; | |
// Based off of the plugin by Clint Helfers, with permission. | |
// http://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: iOS<=5.1, Android<=4.2+ | |
// Default value for a checkbox should be "on" | |
support.checkOn = input.value !== ""; | |
// Support: IE<=11+ | |
// Must access selectedIndex to make default options select | |
support.optSelected = opt.selected; | |
// Support: Android<=2.3 | |
// Options inside disabled selects are incorrectly marked as disabled | |
select.disabled = true; | |
support.optDisabled = !opt.disabled; | |
// Support: IE<=11+ | |
// 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 ); | |
} | |
// All attributes are lowercase | |
// Grab necessary hook if one is defined | |
if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { | |
name = name.toLowerCase(); | |
hooks = jQuery.attrHooks[ name ] || | |
( 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" && | |
jQuery.nodeName( elem, "input" ) ) { | |
var val = elem.value; | |
elem.setAttribute( "type", value ); | |
if ( val ) { | |
elem.value = val; | |
} | |
return value; | |
} | |
} | |
} | |
}, | |
removeAttr: function( elem, value ) { | |
var name, propName, | |
i = 0, | |
attrNames = value && value.match( rnotwhite ); | |
if ( attrNames && elem.nodeType === 1 ) { | |
while ( ( name = attrNames[ i++ ] ) ) { | |
propName = jQuery.propFix[ name ] || name; | |
// Boolean attributes get special treatment (#10870) | |
if ( jQuery.expr.match.bool.test( name ) ) { | |
// Set corresponding property to false | |
elem[ propName ] = false; | |
} | |
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; | |
if ( !isXML ) { | |
// Avoid an infinite loop by temporarily removing this function from the getter | |
handle = attrHandle[ name ]; | |
attrHandle[ name ] = ret; | |
ret = getter( elem, name, isXML ) != null ? | |
name.toLowerCase() : | |
null; | |
attrHandle[ name ] = 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 ) { | |
// elem.tabIndex doesn't always return the | |
// correct value when it hasn't been explicitly set | |
// 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" ); | |
return tabindex ? | |
parseInt( tabindex, 10 ) : | |
rfocusable.test( elem.nodeName ) || | |
rclickable.test( elem.nodeName ) && elem.href ? | |
0 : | |
-1; | |
} | |
} | |
}, | |
propFix: { | |
"for": "htmlFor", | |
"class": "className" | |
} | |
} ); | |
if ( !support.optSelected ) { | |
jQuery.propHooks.selected = { | |
get: function( elem ) { | |
var parent = elem.parentNode; | |
if ( parent && parent.parentNode ) { | |
parent.parentNode.selectedIndex; | |
} | |
return null; | |
} | |
}; | |
} | |
jQuery.each( [ | |
"tabIndex", | |
"readOnly", | |
"maxLength", | |
"cellSpacing", | |
"cellPadding", | |
"rowSpan", | |
"colSpan", | |
"useMap", | |
"frameBorder", | |
"contentEditable" | |
], function() { | |
jQuery.propFix[ this.toLowerCase() ] = this; | |
} ); | |
var rclass = /[\t\r\n\f]/g; | |
function getClass( elem ) { | |
return elem.getAttribute && elem.getAttribute( "class" ) || ""; | |
} | |
jQuery.fn.extend( { | |
addClass: function( value ) { | |
var classes, elem, cur, curValue, clazz, j, finalValue, | |
i = 0; | |
if ( jQuery.isFunction( value ) ) { | |
return this.each( function( j ) { | |
jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); | |
} ); | |
} | |
if ( typeof value === "string" && value ) { | |
classes = value.match( rnotwhite ) || []; | |
while ( ( elem = this[ i++ ] ) ) { | |
curValue = getClass( elem ); | |
cur = elem.nodeType === 1 && | |
( " " + curValue + " " ).replace( rclass, " " ); | |
if ( cur ) { | |
j = 0; | |
while ( ( clazz = classes[ j++ ] ) ) { | |
if ( cur.indexOf( " " + clazz + " " ) < 0 ) { | |
cur += clazz + " "; | |
} | |
} | |
// Only assign if different to avoid unneeded rendering. | |
finalValue = jQuery.trim( cur ); | |
if ( curValue !== finalValue ) { | |
elem.setAttribute( "class", finalValue ); | |
} | |
} | |
} | |
} | |
return this; | |
}, | |
removeClass: function( value ) { | |
var classes, elem, cur, curValue, clazz, j, finalValue, | |
i = 0; | |
if ( jQuery.isFunction( value ) ) { | |
return this.each( function( j ) { | |
jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); | |
} ); | |
} | |
if ( !arguments.length ) { | |
return this.attr( "class", "" ); | |
} | |
if ( typeof value === "string" && value ) { | |
classes = value.match( rnotwhite ) || []; | |
while ( ( elem = this[ i++ ] ) ) { | |
curValue = getClass( elem ); | |
// This expression is here for better compressibility (see addClass) | |
cur = elem.nodeType === 1 && | |
( " " + curValue + " " ).replace( rclass, " " ); | |
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 = jQuery.trim( cur ); | |
if ( curValue !== finalValue ) { | |
elem.setAttribute( "class", finalValue ); | |
} | |
} | |
} | |
} | |
return this; | |
}, | |
toggleClass: function( value, stateVal ) { | |
var type = typeof value; | |
if ( typeof stateVal === "boolean" && type === "string" ) { | |
return stateVal ? this.addClass( value ) : this.removeClass( value ); | |
} | |
if ( jQuery.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 ( type === "string" ) { | |
// Toggle individual class names | |
i = 0; | |
self = jQuery( this ); | |
classNames = value.match( rnotwhite ) || []; | |
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 && | |
( " " + getClass( elem ) + " " ).replace( rclass, " " ) | |
.indexOf( className ) > -1 | |
) { | |
return true; | |
} | |
} | |
return false; | |
} | |
} ); | |
var rreturn = /\r/g; | |
jQuery.fn.extend( { | |
val: function( value ) { | |
var hooks, ret, isFunction, | |
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; | |
return typeof ret === "string" ? | |
// Handle most common string cases | |
ret.replace( rreturn, "" ) : | |
// Handle cases where value is null/undef or number | |
ret == null ? "" : ret; | |
} | |
return; | |
} | |
isFunction = jQuery.isFunction( value ); | |
return this.each( function( i ) { | |
var val; | |
if ( this.nodeType !== 1 ) { | |
return; | |
} | |
if ( isFunction ) { | |
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 ( jQuery.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 ) { | |
// Support: IE<11 | |
// option.value not trimmed (#14858) | |
return jQuery.trim( elem.value ); | |
} | |
}, | |
select: { | |
get: function( elem ) { | |
var value, option, | |
options = elem.options, | |
index = elem.selectedIndex, | |
one = elem.type === "select-one" || index < 0, | |
values = one ? null : [], | |
max = one ? index + 1 : options.length, | |
i = index < 0 ? | |
max : | |
one ? index : 0; | |
// Loop through all the selected options | |
for ( ; i < max; i++ ) { | |
option = options[ i ]; | |
// 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 | |
( support.optDisabled ? | |
!option.disabled : option.getAttribute( "disabled" ) === null ) && | |
( !option.parentNode.disabled || | |
!jQuery.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 ]; | |
if ( option.selected = | |
jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 | |
) { | |
optionSet = true; | |
} | |
} | |
// 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 ( jQuery.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 | |
var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/; | |
jQuery.extend( jQuery.event, { | |
trigger: function( event, data, elem, onlyHandlers ) { | |
var i, cur, tmp, bubbleType, ontype, handle, special, | |
eventPath = [ elem || document ], | |
type = hasOwn.call( event, "type" ) ? event.type : event, | |
namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; | |
cur = 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 && !jQuery.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() ) { | |
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 name as the event. | |
// Don't do default actions on window, that's where global variables be (#6170) | |
if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.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; | |
elem[ type ](); | |
jQuery.event.triggered = undefined; | |
if ( tmp ) { | |
elem[ ontype ] = tmp; | |
} | |
} | |
} | |
} | |
return event.result; | |
}, | |
// Piggyback on a donor event to simulate a different one | |
simulate: function( type, elem, event ) { | |
var e = jQuery.extend( | |
new jQuery.Event(), | |
event, | |
{ | |
type: type, | |
isSimulated: true | |
// Previously, `originalEvent: {}` was set here, so stopPropagation call | |
// would not be triggered on donor event, since in our own | |
// jQuery.event.stopPropagation function we had a check for existence of | |
// originalEvent.stopPropagation method, so, consequently it would be a noop. | |
// | |
// But now, this "simulate" function is used only for events | |
// for which stopPropagation() is noop, so there is no need for that anymore. | |
// | |
// For the compat branch though, guard for "click" and "submit" | |
// events is still used, but was moved to jQuery.event.stopPropagation function | |
// because `originalEvent` should point to the original event for the constancy | |
// with other events and for more focused logic | |
} | |
); | |
jQuery.event.trigger( e, null, elem ); | |
if ( e.isDefaultPrevented() ) { | |
event.preventDefault(); | |
} | |
} | |
} ); | |
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 ); | |
} | |
} | |
} ); | |
jQuery.each( ( "blur focus focusin focusout load resize scroll unload click dblclick " + | |
"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + | |
"change select submit keydown keypress keyup error 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 ); | |
} | |
} ); | |
support.focusin = "onfocusin" in window; | |
// Support: Firefox | |
// Firefox doesn't have focus(in | out) events | |
// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 | |
// | |
// Support: Chrome, Safari | |
// 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://code.google.com/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 = jQuery.now(); | |
var rquery = ( /\?/ ); | |
// Support: Android 2.3 | |
// Workaround failure to string-cast null input | |
jQuery.parseJSON = function( data ) { | |
return JSON.parse( data + "" ); | |
}; | |
// Cross-browser xml parsing | |
jQuery.parseXML = function( data ) { | |
var xml; | |
if ( !data || typeof data !== "string" ) { | |
return null; | |
} | |
// Support: IE9 | |
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 | |
rhash = /#.*$/, | |
rts = /([?&])_=[^&]*/, | |
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( rnotwhite ) || []; | |
if ( jQuery.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": jQuery.parseJSON, | |
// 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, | |
// To know if global events are to be dispatched | |
fireGlobals, | |
// Loop variable | |
i, | |
// 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 = {}, | |
// The jqXHR state | |
state = 0, | |
// Default abort message | |
strAbort = "canceled", | |
// Fake xhr | |
jqXHR = { | |
readyState: 0, | |
// Builds headers hashtable if needed | |
getResponseHeader: function( key ) { | |
var match; | |
if ( state === 2 ) { | |
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 state === 2 ? responseHeadersString : null; | |
}, | |
// Caches the header | |
setRequestHeader: function( name, value ) { | |
var lname = name.toLowerCase(); | |
if ( !state ) { | |
name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; | |
requestHeaders[ name ] = value; | |
} | |
return this; | |
}, | |
// Overrides response content-type header | |
overrideMimeType: function( type ) { | |
if ( !state ) { | |
s.mimeType = type; | |
} | |
return this; | |
}, | |
// Status-dependent callbacks | |
statusCode: function( map ) { | |
var code; | |
if ( map ) { | |
if ( state < 2 ) { | |
for ( code in map ) { | |
// Lazy-add the new callback in a way that preserves old ones | |
statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; | |
} | |
} else { | |
// Execute the appropriate callbacks | |
jqXHR.always( map[ jqXHR.status ] ); | |
} | |
} | |
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 ).complete = completeDeferred.add; | |
jqXHR.success = jqXHR.done; | |
jqXHR.error = jqXHR.fail; | |
// Remove hash character (#7531: and string promotion) | |
// 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( rhash, "" ) | |
.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 = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ]; | |
// 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: IE8-11+ | |
// IE throws exception if url is malformed, e.g. http://example.com:80x/ | |
try { | |
urlAnchor.href = s.url; | |
// Support: IE8-11+ | |
// 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 ( state === 2 ) { | |
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 | |
cacheURL = s.url; | |
// More options handling for requests with no content | |
if ( !s.hasContent ) { | |
// If data is available, append data to url | |
if ( s.data ) { | |
cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data ); | |
// #9682: remove data so that it's not used in an eventual retry | |
delete s.data; | |
} | |
// Add anti-cache in url if needed | |
if ( s.cache === false ) { | |
s.url = rts.test( cacheURL ) ? | |
// If there is already a '_' parameter, set its value | |
cacheURL.replace( rts, "$1_=" + nonce++ ) : | |
// Otherwise add one to the end | |
cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++; | |
} | |
} | |
// 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 || state === 2 ) ) { | |
// Abort if not done already and return | |
return jqXHR.abort(); | |
} | |
// Aborting is no longer a cancellation | |
strAbort = "abort"; | |
// Install callbacks on deferreds | |
for ( i in { success: 1, error: 1, complete: 1 } ) { | |
jqXHR[ i ]( s[ i ] ); | |
} | |
// 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 ( state === 2 ) { | |
return jqXHR; | |
} | |
// Timeout | |
if ( s.async && s.timeout > 0 ) { | |
timeoutTimer = window.setTimeout( function() { | |
jqXHR.abort( "timeout" ); | |
}, s.timeout ); | |
} | |
try { | |
state = 1; | |
transport.send( requestHeaders, done ); | |
} catch ( e ) { | |
// Propagate exception as error if not done | |
if ( state < 2 ) { | |
done( -1, e ); | |
// Simply rethrow otherwise | |
} else { | |
throw e; | |
} | |
} | |
} | |
// Callback for when everything is done | |
function done( status, nativeStatusText, responses, headers ) { | |
var isSuccess, success, error, response, modified, | |
statusText = nativeStatusText; | |
// Called once | |
if ( state === 2 ) { | |
return; | |
} | |
// State is "done" now | |
state = 2; | |
// 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 ( jQuery.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", | |
async: false, | |
global: false, | |
"throws": true | |
} ); | |
}; | |
jQuery.fn.extend( { | |
wrapAll: function( html ) { | |
var wrap; | |
if ( jQuery.isFunction( html ) ) { | |
return this.each( function( i ) { | |
jQuery( this ).wrapAll( html.call( this, i ) ); | |
} ); | |
} | |
if ( 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 ( jQuery.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 isFunction = jQuery.isFunction( html ); | |
return this.each( function( i ) { | |
jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html ); | |
} ); | |
}, | |
unwrap: function() { | |
return this.parent().each( function() { | |
if ( !jQuery.nodeName( this, "body" ) ) { | |
jQuery( this ).replaceWith( this.childNodes ); | |
} | |
} ).end(); | |
} | |
} ); | |
jQuery.expr.filters.hidden = function( elem ) { | |
return !jQuery.expr.filters.visible( elem ); | |
}; | |
jQuery.expr.filters.visible = function( elem ) { | |
// Support: Opera <= 12.12 | |
// Opera reports offsetWidths and offsetHeights less than zero on some elements | |
// Use OR instead of AND as the element is not visible if either is true | |
// See tickets #10406 and #13132 | |
return elem.offsetWidth > 0 || elem.offsetHeight > 0 || elem.getClientRects().length > 0; | |
}; | |
var r20 = /%20/g, | |
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 ( jQuery.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 && jQuery.type( 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, value ) { | |
// If value is a function, invoke it and return its value | |
value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); | |
s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); | |
}; | |
// Set traditional to true for jQuery <= 1.3.2 behavior. | |
if ( traditional === undefined ) { | |
traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; | |
} | |
// If an array was passed in, assume that it is an array of form elements. | |
if ( jQuery.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( "&" ).replace( r20, "+" ); | |
}; | |
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(); | |
return val == null ? | |
null : | |
jQuery.isArray( val ) ? | |
jQuery.map( val, function( val ) { | |
return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; | |
} ) : | |
{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; | |
} ).get(); | |
} | |
} ); | |
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: IE9 | |
// #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.onreadystatechange = null; | |
if ( type === "abort" ) { | |
xhr.abort(); | |
} else if ( type === "error" ) { | |
// Support: IE9 | |
// 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: IE9 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 = callback( "error" ); | |
// Support: IE9 | |
// 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(); | |
} | |
} | |
}; | |
} | |
} ); | |
// 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 = jQuery.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 && jQuery.isFunction( overwritten ) ) { | |
overwritten( responseContainer[ 0 ] ); | |
} | |
responseContainer = overwritten = undefined; | |
} ); | |
// Delegate to script | |
return "script"; | |
} | |
} ); | |
// Support: Safari 8+ | |
// 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 ( !data || typeof data !== "string" ) { | |
return null; | |
} | |
if ( typeof context === "boolean" ) { | |
keepScripts = context; | |
context = false; | |
} | |
// Stop scripts or inline event handlers from being executed immediately | |
// by using document.implementation | |
context = context || ( support.createHTMLDocument ? | |
document.implementation.createHTMLDocument( "" ) : | |
document ); | |
var 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 ); | |
}; | |
// Keep a copy of the old load method | |
var _load = jQuery.fn.load; | |
/** | |
* Load a url into a page | |
*/ | |
jQuery.fn.load = function( url, params, callback ) { | |
if ( typeof url !== "string" && _load ) { | |
return _load.apply( this, arguments ); | |
} | |
var selector, type, response, | |
self = this, | |
off = url.indexOf( " " ); | |
if ( off > -1 ) { | |
selector = jQuery.trim( url.slice( off ) ); | |
url = url.slice( 0, off ); | |
} | |
// If it's a function | |
if ( jQuery.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( self, 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.filters.animated = function( elem ) { | |
return jQuery.grep( jQuery.timers, function( fn ) { | |
return elem === fn.elem; | |
} ).length; | |
}; | |
/** | |
* Gets a window from an element | |
*/ | |
function getWindow( elem ) { | |
return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView; | |
} | |
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 ( jQuery.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: function( options ) { | |
if ( arguments.length ) { | |
return options === undefined ? | |
this : | |
this.each( function( i ) { | |
jQuery.offset.setOffset( this, options, i ); | |
} ); | |
} | |
var docElem, win, | |
elem = this[ 0 ], | |
box = { top: 0, left: 0 }, | |
doc = elem && elem.ownerDocument; | |
if ( !doc ) { | |
return; | |
} | |
docElem = doc.documentElement; | |
// Make sure it's not a disconnected DOM node | |
if ( !jQuery.contains( docElem, elem ) ) { | |
return box; | |
} | |
box = elem.getBoundingClientRect(); | |
win = getWindow( doc ); | |
return { | |
top: box.top + win.pageYOffset - docElem.clientTop, | |
left: box.left + win.pageXOffset - docElem.clientLeft | |
}; | |
}, | |
position: function() { | |
if ( !this[ 0 ] ) { | |
return; | |
} | |
var offsetParent, offset, | |
elem = this[ 0 ], | |
parentOffset = { top: 0, left: 0 }; | |
// Fixed elements are offset from window (parentOffset = {top:0, left: 0}, | |
// because it is its only offset parent | |
if ( jQuery.css( elem, "position" ) === "fixed" ) { | |
// Assume getBoundingClientRect is there when computed position is fixed | |
offset = elem.getBoundingClientRect(); | |
} else { | |
// Get *real* offsetParent | |
offsetParent = this.offsetParent(); | |
// Get correct offsets | |
offset = this.offset(); | |
if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) { | |
parentOffset = offsetParent.offset(); | |
} | |
// Add offsetParent borders | |
// Subtract offsetParent scroll positions | |
parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ) - | |
offsetParent.scrollTop(); | |
parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true ) - | |
offsetParent.scrollLeft(); | |
} | |
// 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 ) { | |
var win = getWindow( elem ); | |
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-8+, Chrome<37-44+ | |
// Add the top/left cssHooks using jQuery.fn.position | |
// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 | |
// Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280 | |
// 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 ( jQuery.isWindow( elem ) ) { | |
// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there | |
// isn't a whole lot we can do. See pull request at this URL for discussion: | |
// https://github.com/jquery/jquery/pull/764 | |
return 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, null ); | |
}; | |
} ); | |
} ); | |
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 ); | |
}, | |
size: function() { | |
return this.length; | |
} | |
} ); | |
jQuery.fn.andSelf = jQuery.fn.addBack; | |
// 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 ( typeof define === "function" && define.amd ) { | |
define( "jquery", [], function() { | |
return jQuery; | |
} ); | |
} | |
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; | |
})); | |
},{}],6:[function(require,module,exports){ | |
(function (global){ | |
/** | |
* @license | |
* lodash 4.3.0 (Custom Build) <https://lodash.com/> | |
* Build: `lodash -d -o ./foo/lodash.js` | |
* Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/> | |
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE> | |
* Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors | |
* Available under MIT license <https://lodash.com/license> | |
*/ | |
;(function() { | |
/** Used as a safe reference for `undefined` in pre-ES5 environments. */ | |
var undefined; | |
/** Used as the semantic version number. */ | |
var VERSION = '4.3.0'; | |
/** Used to compose bitmasks for wrapper metadata. */ | |
var BIND_FLAG = 1, | |
BIND_KEY_FLAG = 2, | |
CURRY_BOUND_FLAG = 4, | |
CURRY_FLAG = 8, | |
CURRY_RIGHT_FLAG = 16, | |
PARTIAL_FLAG = 32, | |
PARTIAL_RIGHT_FLAG = 64, | |
ARY_FLAG = 128, | |
REARG_FLAG = 256, | |
FLIP_FLAG = 512; | |
/** Used to compose bitmasks for comparison styles. */ | |
var UNORDERED_COMPARE_FLAG = 1, | |
PARTIAL_COMPARE_FLAG = 2; | |
/** 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 = 150, | |
HOT_SPAN = 16; | |
/** Used as the size to enable large array optimizations. */ | |
var LARGE_ARRAY_SIZE = 200; | |
/** Used to indicate the type of lazy iteratees. */ | |
var LAZY_FILTER_FLAG = 1, | |
LAZY_MAP_FLAG = 2, | |
LAZY_WHILE_FLAG = 3; | |
/** Used as the `TypeError` message for "Functions" methods. */ | |
var FUNC_ERROR_TEXT = 'Expected a function'; | |
/** Used to stand-in for `undefined` hash values. */ | |
var HASH_UNDEFINED = '__lodash_hash_undefined__'; | |
/** 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 as the internal argument placeholder. */ | |
var PLACEHOLDER = '__lodash_placeholder__'; | |
/** `Object#toString` result references. */ | |
var argsTag = '[object Arguments]', | |
arrayTag = '[object Array]', | |
boolTag = '[object Boolean]', | |
dateTag = '[object Date]', | |
errorTag = '[object Error]', | |
funcTag = '[object Function]', | |
genTag = '[object GeneratorFunction]', | |
mapTag = '[object Map]', | |
numberTag = '[object Number]', | |
objectTag = '[object Object]', | |
regexpTag = '[object RegExp]', | |
setTag = '[object Set]', | |
stringTag = '[object String]', | |
symbolTag = '[object Symbol]', | |
weakMapTag = '[object WeakMap]', | |
weakSetTag = '[object WeakSet]'; | |
var arrayBufferTag = '[object ArrayBuffer]', | |
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|#96);/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/6.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 backslashes in property paths. */ | |
var reEscapeChar = /\\(\\)?/g; | |
/** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.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 hexadecimal string values. */ | |
var reHasHexPrefix = /^0x/i; | |
/** 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 > 5). */ | |
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-1 supplementary letters (excluding mathematical operators). */ | |
var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/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\\ufe20-\\ufe23', | |
rsComboSymbolsRange = '\\u20d0-\\u20f0', | |
rsDingbatRange = '\\u2700-\\u27bf', | |
rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff', | |
rsMathOpRange = '\\xac\\xb1\\xd7\\xf7', | |
rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf', | |
rsQuoteRange = '\\u2018\\u2019\\u201c\\u201d', | |
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 + rsQuoteRange + rsSpaceRange; | |
/** Used to compose unicode capture groups. */ | |
var rsAstral = '[' + rsAstralRange + ']', | |
rsBreak = '[' + rsBreakRange + ']', | |
rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']', | |
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 rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')', | |
rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')', | |
reOptMod = rsModifier + '?', | |
rsOptVar = '[' + rsVarRange + ']?', | |
rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', | |
rsSeq = rsOptVar + reOptMod + rsOptJoin, | |
rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq, | |
rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; | |
/** | |
* 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 reComplexSymbol = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, '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 reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']'); | |
/** Used to match non-compound words composed of alphanumeric characters. */ | |
var reBasicWord = /[a-zA-Z0-9]+/g; | |
/** Used to match complex or compound words. */ | |
var reComplexWord = RegExp([ | |
rsUpper + '?' + rsLower + '+(?=' + [rsBreak, rsUpper, '$'].join('|') + ')', | |
rsUpperMisc + '+(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')', | |
rsUpper + '?' + rsLowerMisc + '+', | |
rsUpper + '+', | |
rsDigits, | |
rsEmoji | |
].join('|'), 'g'); | |
/** Used to detect strings that need a more robust regexp to match words. */ | |
var reHasComplexWord = /[a-z][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', 'Date', 'Error', 'Float32Array', 'Float64Array', | |
'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object', | |
'Reflect', '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[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[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-1 supplementary letters to basic latin letters. */ | |
var deburredLetters = { | |
'\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' | |
}; | |
/** Used to map characters to HTML entities. */ | |
var htmlEscapes = { | |
'&': '&', | |
'<': '<', | |
'>': '>', | |
'"': '"', | |
"'": ''', | |
'`': '`' | |
}; | |
/** Used to map HTML entities to characters. */ | |
var htmlUnescapes = { | |
'&': '&', | |
'<': '<', | |
'>': '>', | |
'"': '"', | |
''': "'", | |
'`': '`' | |
}; | |
/** Used to determine if values are of the language type `Object`. */ | |
var objectTypes = { | |
'function': true, | |
'object': true | |
}; | |
/** 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 `exports`. */ | |
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null; | |
/** Detect free variable `module`. */ | |
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null; | |
/** Detect free variable `global` from Node.js. */ | |
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global); | |
/** Detect free variable `self`. */ | |
var freeSelf = checkGlobal(objectTypes[typeof self] && self); | |
/** Detect free variable `window`. */ | |
var freeWindow = checkGlobal(objectTypes[typeof window] && window); | |
/** Detect the popular CommonJS extension `module.exports`. */ | |
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null; | |
/** Detect `this` as the global object. */ | |
var thisGlobal = checkGlobal(objectTypes[typeof this] && this); | |
/** | |
* Used as a reference to the global object. | |
* | |
* The `this` value is used if it's the global object to avoid Greasemonkey's | |
* restricted `window` object, otherwise the `window` object is used. | |
*/ | |
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')(); | |
/*--------------------------------------------------------------------------*/ | |
/** | |
* Adds the key-value `pair` to `map`. | |
* | |
* @private | |
* @param {Object} map The map to modify. | |
* @param {Array} pair The key-value pair to add. | |
* @returns {Object} Returns `map`. | |
*/ | |
function addMapEntry(map, pair) { | |
map.set(pair[0], pair[1]); | |
return map; | |
} | |
/** | |
* Adds `value` to `set`. | |
* | |
* @private | |
* @param {Object} set The set to modify. | |
* @param {*} value The value to add. | |
* @returns {Object} Returns `set`. | |
*/ | |
function addSetEntry(set, value) { | |
set.add(value); | |
return set; | |
} | |
/** | |
* 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 {...*} args The arguments to invoke `func` with. | |
* @returns {*} Returns the result of `func`. | |
*/ | |
function apply(func, thisArg, args) { | |
var length = args.length; | |
switch (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.length; | |
while (++index < length) { | |
var value = array[index]; | |
setter(accumulator, value, iteratee(value), array); | |
} | |
return accumulator; | |
} | |
/** | |
* Creates a new array concatenating `array` with `other`. | |
* | |
* @private | |
* @param {Array} array The first array to concatenate. | |
* @param {Array} other The second array to concatenate. | |
* @returns {Array} Returns the new concatenated array. | |
*/ | |
function arrayConcat(array, other) { | |
var index = -1, | |
length = array.length, | |
othIndex = -1, | |
othLength = other.length, | |
result = Array(length + othLength); | |
while (++index < length) { | |
result[index] = array[index]; | |
} | |
while (++othIndex < othLength) { | |
result[index++] = other[othIndex]; | |
} | |
return result; | |
} | |
/** | |
* 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.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.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.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.length, | |
resIndex = -1, | |
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 search. | |
* @param {*} target The value to search for. | |
* @returns {boolean} Returns `true` if `target` is found, else `false`. | |
*/ | |
function arrayIncludes(array, value) { | |
return !!array.length && baseIndexOf(array, value, 0) > -1; | |
} | |
/** | |
* A specialized version of `_.includesWith` for arrays without support for | |
* specifying an index to search from. | |
* | |
* @private | |
* @param {Array} array The array to search. | |
* @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.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.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.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.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.length; | |
while (++index < length) { | |
if (predicate(array[index], index, array)) { | |
return true; | |
} | |
} | |
return false; | |
} | |
/** | |
* 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 | |
: comparator(current, computed) | |
)) { | |
var computed = current, | |
result = value; | |
} | |
} | |
return result; | |
} | |
/** | |
* The base implementation of methods like `_.find` and `_.findKey`, without | |
* support for iteratee shorthands, which iterates over `collection` using | |
* `eachFunc`. | |
* | |
* @private | |
* @param {Array|Object} collection The collection to search. | |
* @param {Function} predicate The function invoked per iteration. | |
* @param {Function} eachFunc The function to iterate over `collection`. | |
* @param {boolean} [retKey] Specify returning the key of the found element instead of the element itself. | |
* @returns {*} Returns the found element or its key, else `undefined`. | |
*/ | |
function baseFind(collection, predicate, eachFunc, retKey) { | |
var result; | |
eachFunc(collection, function(value, key, collection) { | |
if (predicate(value, key, collection)) { | |
result = retKey ? key : value; | |
return false; | |
} | |
}); | |
return result; | |
} | |
/** | |
* The base implementation of `_.findIndex` and `_.findLastIndex` without | |
* support for iteratee shorthands. | |
* | |
* @private | |
* @param {Array} array The array to search. | |
* @param {Function} predicate The function invoked per iteration. | |
* @param {boolean} [fromRight] Specify iterating from right to left. | |
* @returns {number} Returns the index of the matched value, else `-1`. | |
*/ | |
function baseFindIndex(array, predicate, fromRight) { | |
var length = array.length, | |
index = fromRight ? length : -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 search. | |
* @param {*} value The value to search for. | |
* @param {number} fromIndex The index to search from. | |
* @returns {number} Returns the index of the matched value, else `-1`. | |
*/ | |
function baseIndexOf(array, value, fromIndex) { | |
if (value !== value) { | |
return indexOfNaN(array, fromIndex); | |
} | |
var index = fromIndex - 1, | |
length = array.length; | |
while (++index < length) { | |
if (array[index] === value) { | |
return index; | |
} | |
} | |
return -1; | |
} | |
/** | |
* 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` 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 new array of 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 wrapper metadata. | |
* | |
* @private | |
* @param {Function} func The function to cap arguments for. | |
* @returns {Function} Returns the new 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]; | |
}); | |
} | |
/** | |
* 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; | |
} | |
/** | |
* Checks if `value` is a global object. | |
* | |
* @private | |
* @param {*} value The value to check. | |
* @returns {null|Object} Returns `value` if it's a global object, else `null`. | |
*/ | |
function checkGlobal(value) { | |
return (value && value.Object === Object) ? value : null; | |
} | |
/** | |
* 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 valIsNull = value === null, | |
valIsUndef = value === undefined, | |
valIsReflexive = value === value; | |
var othIsNull = other === null, | |
othIsUndef = other === undefined, | |
othIsReflexive = other === other; | |
if ((value > other && !othIsNull) || !valIsReflexive || | |
(valIsNull && !othIsUndef && othIsReflexive) || | |
(valIsUndef && othIsReflexive)) { | |
return 1; | |
} | |
if ((value < other && !valIsNull) || !othIsReflexive || | |
(othIsNull && !valIsUndef && valIsReflexive) || | |
(othIsUndef && valIsReflexive)) { | |
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://code.google.com/p/v8/issues/detail?id=90 for more details. | |
return object.index - other.index; | |
} | |
/** | |
* Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters. | |
* | |
* @private | |
* @param {string} letter The matched letter to deburr. | |
* @returns {string} Returns the deburred letter. | |
*/ | |
function deburrLetter(letter) { | |
return deburredLetters[letter]; | |
} | |
/** | |
* Used by `_.escape` to convert characters to HTML entities. | |
* | |
* @private | |
* @param {string} chr The matched character to escape. | |
* @returns {string} Returns the escaped character. | |
*/ | |
function escapeHtmlChar(chr) { | |
return htmlEscapes[chr]; | |
} | |
/** | |
* 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 index at which the first occurrence of `NaN` is found in `array`. | |
* | |
* @private | |
* @param {Array} array The array to search. | |
* @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 `NaN`, else `-1`. | |
*/ | |
function indexOfNaN(array, fromIndex, fromRight) { | |
var length = array.length, | |
index = fromIndex + (fromRight ? 0 : -1); | |
while ((fromRight ? index-- : ++index < length)) { | |
var other = array[index]; | |
if (other !== other) { | |
return index; | |
} | |
} | |
return -1; | |
} | |
/** | |
* Checks if `value` is a host object in IE < 9. | |
* | |
* @private | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is a host object, else `false`. | |
*/ | |
function isHostObject(value) { | |
// Many host objects are `Object` objects that can coerce to strings | |
// despite having improperly defined `toString` methods. | |
var result = false; | |
if (value != null && typeof value.toString != 'function') { | |
try { | |
result = !!(value + ''); | |
} catch (e) {} | |
} | |
return result; | |
} | |
/** | |
* 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) { | |
value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; | |
length = length == null ? MAX_SAFE_INTEGER : length; | |
return value > -1 && value % 1 == 0 && value < length; | |
} | |
/** | |
* 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 an array. | |
* | |
* @private | |
* @param {Object} map The map to convert. | |
* @returns {Array} Returns the converted array. | |
*/ | |
function mapToArray(map) { | |
var index = -1, | |
result = Array(map.size); | |
map.forEach(function(value, key) { | |
result[++index] = [key, value]; | |
}); | |
return result; | |
} | |
/** | |
* Replaces all `placeholder` elements in `array` with an internal placeholder | |
* and returns an array of their indexes. | |
* | |
* @private | |
* @param {Array} array The array to modify. | |
* @param {*} placeholder The placeholder to replace. | |
* @returns {Array} Returns the new array of placeholder indexes. | |
*/ | |
function replaceHolders(array, placeholder) { | |
var index = -1, | |
length = array.length, | |
resIndex = -1, | |
result = []; | |
while (++index < length) { | |
if (array[index] === placeholder) { | |
array[index] = PLACEHOLDER; | |
result[++resIndex] = index; | |
} | |
} | |
return result; | |
} | |
/** | |
* Converts `set` to an array. | |
* | |
* @private | |
* @param {Object} set The set to convert. | |
* @returns {Array} Returns the converted array. | |
*/ | |
function setToArray(set) { | |
var index = -1, | |
result = Array(set.size); | |
set.forEach(function(value) { | |
result[++index] = value; | |
}); | |
return result; | |
} | |
/** | |
* Gets the number of symbols in `string`. | |
* | |
* @private | |
* @param {string} string The string to inspect. | |
* @returns {number} Returns the string size. | |
*/ | |
function stringSize(string) { | |
if (!(string && reHasComplexSymbol.test(string))) { | |
return string.length; | |
} | |
var result = reComplexSymbol.lastIndex = 0; | |
while (reComplexSymbol.test(string)) { | |
result++; | |
} | |
return result; | |
} | |
/** | |
* Converts `string` to an array. | |
* | |
* @private | |
* @param {string} string The string to convert. | |
* @returns {Array} Returns the converted array. | |
*/ | |
function stringToArray(string) { | |
return string.match(reComplexSymbol); | |
} | |
/** | |
* Used by `_.unescape` to convert HTML entities to characters. | |
* | |
* @private | |
* @param {string} chr The matched character to unescape. | |
* @returns {string} Returns the unescaped character. | |
*/ | |
function unescapeHtmlChar(chr) { | |
return htmlUnescapes[chr]; | |
} | |
/*--------------------------------------------------------------------------*/ | |
/** | |
* Create a new pristine `lodash` function using the `context` object. | |
* | |
* @static | |
* @memberOf _ | |
* @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 | |
* | |
* // Use `context` to mock `Date#getTime` use in `_.now`. | |
* var mock = _.runInContext({ | |
* 'Date': function() { | |
* return { 'getTime': getTimeMock }; | |
* } | |
* }); | |
* | |
* // Create a suped-up `defer` in Node.js. | |
* var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; | |
*/ | |
function runInContext(context) { | |
context = context ? _.defaults({}, context, _.pick(root, contextProps)) : root; | |
/** Built-in constructor references. */ | |
var Date = context.Date, | |
Error = context.Error, | |
Math = context.Math, | |
RegExp = context.RegExp, | |
TypeError = context.TypeError; | |
/** Used for built-in method references. */ | |
var arrayProto = context.Array.prototype, | |
objectProto = context.Object.prototype; | |
/** Used to resolve the decompiled source of functions. */ | |
var funcToString = context.Function.prototype.toString; | |
/** Used to check objects for own properties. */ | |
var hasOwnProperty = objectProto.hasOwnProperty; | |
/** Used to generate unique IDs. */ | |
var idCounter = 0; | |
/** Used to infer the `Object` constructor. */ | |
var objectCtorString = funcToString.call(Object); | |
/** | |
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) | |
* of values. | |
*/ | |
var objectToString = objectProto.toString; | |
/** 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, | |
Reflect = context.Reflect, | |
Symbol = context.Symbol, | |
Uint8Array = context.Uint8Array, | |
clearTimeout = context.clearTimeout, | |
enumerate = Reflect ? Reflect.enumerate : undefined, | |
getPrototypeOf = Object.getPrototypeOf, | |
getOwnPropertySymbols = Object.getOwnPropertySymbols, | |
iteratorSymbol = typeof (iteratorSymbol = Symbol && Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined, | |
propertyIsEnumerable = objectProto.propertyIsEnumerable, | |
setTimeout = context.setTimeout, | |
splice = arrayProto.splice; | |
/* Built-in method references for those with the same name as other `lodash` methods. */ | |
var nativeCeil = Math.ceil, | |
nativeFloor = Math.floor, | |
nativeIsFinite = context.isFinite, | |
nativeJoin = arrayProto.join, | |
nativeKeys = Object.keys, | |
nativeMax = Math.max, | |
nativeMin = Math.min, | |
nativeParseInt = context.parseInt, | |
nativeRandom = Math.random, | |
nativeReverse = arrayProto.reverse; | |
/* Built-in method references that are verified to be native. */ | |
var Map = getNative(context, 'Map'), | |
Set = getNative(context, 'Set'), | |
WeakMap = getNative(context, 'WeakMap'), | |
nativeCreate = getNative(Object, 'create'); | |
/** Used to store function metadata. */ | |
var metaMap = WeakMap && new WeakMap; | |
/** Used to detect maps, sets, and weakmaps. */ | |
var mapCtorString = Map ? funcToString.call(Map) : '', | |
setCtorString = Set ? funcToString.call(Set) : '', | |
weakMapCtorString = WeakMap ? funcToString.call(WeakMap) : ''; | |
/** Used to convert symbols to primitives and strings. */ | |
var symbolProto = Symbol ? Symbol.prototype : undefined, | |
symbolValueOf = Symbol ? symbolProto.valueOf : undefined, | |
symbolToString = Symbol ? symbolProto.toString : undefined; | |
/** Used to lookup unminified function names. */ | |
var realNames = {}; | |
/*------------------------------------------------------------------------*/ | |
/** | |
* Creates a `lodash` object which wraps `value` to enable implicit method | |
* chaining. 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 chaining, which must be unwrapped with `_#value` in all cases, | |
* 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 of at least two hundred elements and any 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`, `chain`, `chunk`, `commit`, | |
* `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, `curry`, | |
* `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`, | |
* `differenceBy`, `differenceWith`, `drop`, `dropRight`, `dropRightWhile`, | |
* `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `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`, `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`, `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`, `deburr`, `endsWith`, `eq`, | |
* `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, | |
* `findLast`, `findLastIndex`, `findLastKey`, `floor`, `forEach`, `forEachRight`, | |
* `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`, | |
* `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`, | |
* `isArguments`, `isArray`, `isArrayLike`, `isArrayLikeObject`, `isBoolean`, | |
* `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`, `isError`, | |
* `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMatch`, `isMatchWith`, | |
* `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`, `isObject`, `isObjectLike`, | |
* `isPlainObject`, `isRegExp`, `isSafeInteger`, `isString`, `isUndefined`, | |
* `isTypedArray`, `join`, `kebabCase`, `last`, `lastIndexOf`, `lowerCase`, | |
* `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `min`, `minBy`, | |
* `noConflict`, `noop`, `now`, `pad`, `padEnd`, `padStart`, `parseInt`, | |
* `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`, `round`, | |
* `runInContext`, `sample`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, | |
* `sortedIndexBy`, `sortedLastIndex`, `sortedLastIndexBy`, `startCase`, | |
* `startsWith`, `subtract`, `sum`, `sumBy`, `template`, `times`, `toLower`, | |
* `toInteger`, `toLength`, `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 function whose prototype all chaining 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 chaining for all wrapper methods. | |
*/ | |
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). 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 | |
} | |
}; | |
/*------------------------------------------------------------------------*/ | |
/** | |
* Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. | |
* | |
* @private | |
* @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 || arrLength < LARGE_ARRAY_SIZE || (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; | |
} | |
/*------------------------------------------------------------------------*/ | |
/** | |
* Creates an hash object. | |
* | |
* @private | |
* @returns {Object} Returns the new hash object. | |
*/ | |
function Hash() {} | |
/** | |
* Removes `key` and its value from the hash. | |
* | |
* @private | |
* @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(hash, key) { | |
return hashHas(hash, key) && delete hash[key]; | |
} | |
/** | |
* Gets the hash value for `key`. | |
* | |
* @private | |
* @param {Object} hash The hash to query. | |
* @param {string} key The key of the value to get. | |
* @returns {*} Returns the entry value. | |
*/ | |
function hashGet(hash, key) { | |
if (nativeCreate) { | |
var result = hash[key]; | |
return result === HASH_UNDEFINED ? undefined : result; | |
} | |
return hasOwnProperty.call(hash, key) ? hash[key] : undefined; | |
} | |
/** | |
* Checks if a hash value for `key` exists. | |
* | |
* @private | |
* @param {Object} hash The hash 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 hashHas(hash, key) { | |
return nativeCreate ? hash[key] !== undefined : hasOwnProperty.call(hash, key); | |
} | |
/** | |
* Sets the hash `key` to `value`. | |
* | |
* @private | |
* @param {Object} hash The hash to modify. | |
* @param {string} key The key of the value to set. | |
* @param {*} value The value to set. | |
*/ | |
function hashSet(hash, key, value) { | |
hash[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; | |
} | |
/*------------------------------------------------------------------------*/ | |
/** | |
* Creates a map cache object to store key-value pairs. | |
* | |
* @private | |
* @param {Array} [values] The values to cache. | |
*/ | |
function MapCache(values) { | |
var index = -1, | |
length = values ? values.length : 0; | |
this.clear(); | |
while (++index < length) { | |
var entry = values[index]; | |
this.set(entry[0], entry[1]); | |
} | |
} | |
/** | |
* Removes all key-value entries from the map. | |
* | |
* @private | |
* @name clear | |
* @memberOf MapCache | |
*/ | |
function mapClear() { | |
this.__data__ = { 'hash': new Hash, 'map': Map ? new Map : [], '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 mapDelete(key) { | |
var data = this.__data__; | |
if (isKeyable(key)) { | |
return hashDelete(typeof key == 'string' ? data.string : data.hash, key); | |
} | |
return Map ? data.map['delete'](key) : assocDelete(data.map, key); | |
} | |
/** | |
* 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 mapGet(key) { | |
var data = this.__data__; | |
if (isKeyable(key)) { | |
return hashGet(typeof key == 'string' ? data.string : data.hash, key); | |
} | |
return Map ? data.map.get(key) : assocGet(data.map, 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 mapHas(key) { | |
var data = this.__data__; | |
if (isKeyable(key)) { | |
return hashHas(typeof key == 'string' ? data.string : data.hash, key); | |
} | |
return Map ? data.map.has(key) : assocHas(data.map, 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 object. | |
*/ | |
function mapSet(key, value) { | |
var data = this.__data__; | |
if (isKeyable(key)) { | |
hashSet(typeof key == 'string' ? data.string : data.hash, key, value); | |
} else if (Map) { | |
data.map.set(key, value); | |
} else { | |
assocSet(data.map, key, value); | |
} | |
return this; | |
} | |
/*------------------------------------------------------------------------*/ | |
/** | |
* | |
* Creates a set cache object to store unique values. | |
* | |
* @private | |
* @param {Array} [values] The values to cache. | |
*/ | |
function SetCache(values) { | |
var index = -1, | |
length = values ? values.length : 0; | |
this.__data__ = new MapCache; | |
while (++index < length) { | |
this.push(values[index]); | |
} | |
} | |
/** | |
* Checks if `value` is in `cache`. | |
* | |
* @private | |
* @param {Object} cache The set cache to search. | |
* @param {*} value The value to search for. | |
* @returns {number} Returns `true` if `value` is found, else `false`. | |
*/ | |
function cacheHas(cache, value) { | |
var map = cache.__data__; | |
if (isKeyable(value)) { | |
var data = map.__data__, | |
hash = typeof value == 'string' ? data.string : data.hash; | |
return hash[value] === HASH_UNDEFINED; | |
} | |
return map.has(value); | |
} | |
/** | |
* Adds `value` to the set cache. | |
* | |
* @private | |
* @name push | |
* @memberOf SetCache | |
* @param {*} value The value to cache. | |
*/ | |
function cachePush(value) { | |
var map = this.__data__; | |
if (isKeyable(value)) { | |
var data = map.__data__, | |
hash = typeof value == 'string' ? data.string : data.hash; | |
hash[value] = HASH_UNDEFINED; | |
} | |
else { | |
map.set(value, HASH_UNDEFINED); | |
} | |
} | |
/*------------------------------------------------------------------------*/ | |
/** | |
* Creates a stack cache object to store key-value pairs. | |
* | |
* @private | |
* @param {Array} [values] The values to cache. | |
*/ | |
function Stack(values) { | |
var index = -1, | |
length = values ? values.length : 0; | |
this.clear(); | |
while (++index < length) { | |
var entry = values[index]; | |
this.set(entry[0], entry[1]); | |
} | |
} | |
/** | |
* Removes all key-value entries from the stack. | |
* | |
* @private | |
* @name clear | |
* @memberOf Stack | |
*/ | |
function stackClear() { | |
this.__data__ = { 'array': [], 'map': null }; | |
} | |
/** | |
* 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__, | |
array = data.array; | |
return array ? assocDelete(array, key) : data.map['delete'](key); | |
} | |
/** | |
* 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) { | |
var data = this.__data__, | |
array = data.array; | |
return array ? assocGet(array, key) : data.map.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) { | |
var data = this.__data__, | |
array = data.array; | |
return array ? assocHas(array, key) : data.map.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 object. | |
*/ | |
function stackSet(key, value) { | |
var data = this.__data__, | |
array = data.array; | |
if (array) { | |
if (array.length < (LARGE_ARRAY_SIZE - 1)) { | |
assocSet(array, key, value); | |
} else { | |
data.array = null; | |
data.map = new MapCache(array); | |
} | |
} | |
var map = data.map; | |
if (map) { | |
map.set(key, value); | |
} | |
return this; | |
} | |
/*------------------------------------------------------------------------*/ | |
/** | |
* Removes `key` and its value from the associative array. | |
* | |
* @private | |
* @param {Array} array The array to query. | |
* @param {string} key The key of the value to remove. | |
* @returns {boolean} Returns `true` if the entry was removed, else `false`. | |
*/ | |
function assocDelete(array, key) { | |
var index = assocIndexOf(array, key); | |
if (index < 0) { | |
return false; | |
} | |
var lastIndex = array.length - 1; | |
if (index == lastIndex) { | |
array.pop(); | |
} else { | |
splice.call(array, index, 1); | |
} | |
return true; | |
} | |
/** | |
* Gets the associative array value for `key`. | |
* | |
* @private | |
* @param {Array} array The array to query. | |
* @param {string} key The key of the value to get. | |
* @returns {*} Returns the entry value. | |
*/ | |
function assocGet(array, key) { | |
var index = assocIndexOf(array, key); | |
return index < 0 ? undefined : array[index][1]; | |
} | |
/** | |
* Checks if an associative array value for `key` exists. | |
* | |
* @private | |
* @param {Array} array The array 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 assocHas(array, key) { | |
return assocIndexOf(array, key) > -1; | |
} | |
/** | |
* Gets the index at which the first occurrence of `key` is found in `array` | |
* of key-value pairs. | |
* | |
* @private | |
* @param {Array} array The array to search. | |
* @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; | |
} | |
/** | |
* Sets the associative array `key` to `value`. | |
* | |
* @private | |
* @param {Array} array The array to modify. | |
* @param {string} key The key of the value to set. | |
* @param {*} value The value to set. | |
*/ | |
function assocSet(array, key, value) { | |
var index = assocIndexOf(array, key); | |
if (index < 0) { | |
array.push([key, value]); | |
} else { | |
array[index][1] = value; | |
} | |
} | |
/*------------------------------------------------------------------------*/ | |
/** | |
* Used by `_.defaults` to customize its `_.assignIn` use. | |
* | |
* @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 assignInDefaults(objValue, srcValue, key, object) { | |
if (objValue === undefined || | |
(eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) { | |
return srcValue; | |
} | |
return objValue; | |
} | |
/** | |
* 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)) || | |
(typeof key == 'number' && value === undefined && !(key in object))) { | |
object[key] = value; | |
} | |
} | |
/** | |
* Assigns `value` to `key` of `object` if the existing value is not equivalent | |
* using [`SameValueZero`](http://ecma-international.org/ecma-262/6.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 ((!eq(objValue, value) || | |
(eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) || | |
(value === undefined && !(key in object))) { | |
object[key] = value; | |
} | |
} | |
/** | |
* 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 `_.at` without support for individual paths. | |
* | |
* @private | |
* @param {Object} object The object to iterate over. | |
* @param {string[]} paths The property paths of elements to pick. | |
* @returns {Array} Returns the new array of picked elements. | |
*/ | |
function baseAt(object, paths) { | |
var index = -1, | |
isNil = object == null, | |
length = paths.length, | |
result = Array(length); | |
while (++index < length) { | |
result[index] = isNil ? undefined : get(object, paths[index]); | |
} | |
return result; | |
} | |
/** | |
* The base implementation of `_.clamp` which doesn't coerce arguments to numbers. | |
* | |
* @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} [isDeep] Specify a deep clone. | |
* @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, isDeep, customizer, key, object, stack) { | |
var result; | |
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)) { | |
if (isHostObject(value)) { | |
return object ? value : {}; | |
} | |
result = initCloneObject(isFunc ? {} : value); | |
if (!isDeep) { | |
return copySymbols(value, baseAssign(result, value)); | |
} | |
} else { | |
return cloneableTags[tag] | |
? initCloneByTag(value, tag, isDeep) | |
: (object ? value : {}); | |
} | |
} | |
// 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); | |
// Recursively populate clone (susceptible to call stack limits). | |
(isArr ? arrayEach : baseForOwn)(value, function(subValue, key) { | |
assignValue(result, key, baseClone(subValue, isDeep, customizer, key, value, stack)); | |
}); | |
return isArr ? result : copySymbols(value, 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 function. | |
*/ | |
function baseConforms(source) { | |
var props = keys(source), | |
length = props.length; | |
return function(object) { | |
if (object == null) { | |
return !length; | |
} | |
var index = length; | |
while (index--) { | |
var key = props[index], | |
predicate = source[key], | |
value = object[key]; | |
if ((value === undefined && !(key in Object(object))) || !predicate(value)) { | |
return false; | |
} | |
} | |
return true; | |
}; | |
} | |
/** | |
* The base implementation of `_.create` without support for assigning | |
* properties to the created object. | |
* | |
* @private | |
* @param {Object} prototype The object to inherit from. | |
* @returns {Object} Returns the new object. | |
*/ | |
var baseCreate = (function() { | |
function object() {} | |
return function(prototype) { | |
if (isObject(prototype)) { | |
object.prototype = prototype; | |
var result = new object; | |
object.prototype = undefined; | |
} | |
return result || {}; | |
}; | |
}()); | |
/** | |
* The base implementation of `_.delay` and `_.defer` which accepts an array | |
* of `func` arguments. | |
* | |
* @private | |
* @param {Function} func The function to delay. | |
* @param {number} wait The number of milliseconds to delay invocation. | |
* @param {Object} args The arguments to provide to `func`. | |
* @returns {number} Returns the timer id. | |
*/ | |
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 ? iteratee(value) : value; | |
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 `_.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 {boolean} [isDeep] Specify a deep flatten. | |
* @param {boolean} [isStrict] Restrict flattening to arrays-like objects. | |
* @param {Array} [result=[]] The initial result value. | |
* @returns {Array} Returns the new flattened array. | |
*/ | |
function baseFlatten(array, isDeep, isStrict, result) { | |
result || (result = []); | |
var index = -1, | |
length = array.length; | |
while (++index < length) { | |
var value = array[index]; | |
if (isArrayLikeObject(value) && | |
(isStrict || isArray(value) || isArguments(value))) { | |
if (isDeep) { | |
// Recursively flatten arrays (susceptible to call stack limits). | |
baseFlatten(value, isDeep, isStrict, result); | |
} else { | |
arrayPush(result, value); | |
} | |
} else if (!isStrict) { | |
result[result.length] = value; | |
} | |
} | |
return result; | |
} | |
/** | |
* The base implementation of `baseForIn` and `baseForOwn` which iterates | |
* over `object` properties returned by `keysFunc` invoking `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 `_.forIn` 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 baseForIn(object, iteratee) { | |
return object == null ? object : baseFor(object, iteratee, keysIn); | |
} | |
/** | |
* 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 new array of filtered property 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 = isKey(path, object) ? [path + ''] : baseToPath(path); | |
var index = 0, | |
length = path.length; | |
while (object != null && index < length) { | |
object = object[path[index++]]; | |
} | |
return (index && index == length) ? object : undefined; | |
} | |
/** | |
* 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) { | |
// Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`, | |
// that are composed entirely of index properties, return `false` for | |
// `hasOwnProperty` checks of them. | |
return hasOwnProperty.call(object, key) || | |
(typeof object == 'object' && key in object && getPrototypeOf(object) === null); | |
} | |
/** | |
* 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 key in Object(object); | |
} | |
/** | |
* The base implementation of `_.inRange` which doesn't coerce arguments to numbers. | |
* | |
* @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, | |
othLength = arrays.length, | |
othIndex = othLength, | |
caches = Array(othLength), | |
result = []; | |
while (othIndex--) { | |
var array = arrays[othIndex]; | |
if (othIndex && iteratee) { | |
array = arrayMap(array, baseUnary(iteratee)); | |
} | |
caches[othIndex] = !comparator && (iteratee || array.length >= 120) | |
? new SetCache(othIndex && array) | |
: undefined; | |
} | |
array = arrays[0]; | |
var index = -1, | |
length = array.length, | |
seen = caches[0]; | |
outer: | |
while (++index < length) { | |
var value = array[index], | |
computed = iteratee ? iteratee(value) : value; | |
if (!(seen ? cacheHas(seen, computed) : includes(result, computed, comparator))) { | |
var 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) { | |
if (!isKey(path, object)) { | |
path = baseToPath(path); | |
object = parent(object, path); | |
path = last(path); | |
} | |
var func = object == null ? object : object[path]; | |
return func == null ? undefined : apply(func, object, args); | |
} | |
/** | |
* 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 {Function} [customizer] The function to customize comparisons. | |
* @param {boolean} [bitmask] The bitmask of comparison flags. | |
* The bitmask may be composed of the following flags: | |
* 1 - Unordered comparison | |
* 2 - Partial comparison | |
* @param {Object} [stack] Tracks traversed `value` and `other` objects. | |
* @returns {boolean} Returns `true` if the values are equivalent, else `false`. | |
*/ | |
function baseIsEqual(value, other, customizer, bitmask, stack) { | |
if (value === other) { | |
return true; | |
} | |
if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) { | |
return value !== value && other !== other; | |
} | |
return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, 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 {Function} equalFunc The function to determine equivalents of values. | |
* @param {Function} [customizer] The function to customize comparisons. | |
* @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details. | |
* @param {Object} [stack] Tracks traversed `object` and `other` objects. | |
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`. | |
*/ | |
function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) { | |
var objIsArr = isArray(object), | |
othIsArr = isArray(other), | |
objTag = arrayTag, | |
othTag = arrayTag; | |
if (!objIsArr) { | |
objTag = getTag(object); | |
if (objTag == argsTag) { | |
objTag = objectTag; | |
} else if (objTag != objectTag) { | |
objIsArr = isTypedArray(object); | |
} | |
} | |
if (!othIsArr) { | |
othTag = getTag(other); | |
if (othTag == argsTag) { | |
othTag = objectTag; | |
} else if (othTag != objectTag) { | |
othIsArr = isTypedArray(other); | |
} | |
} | |
var objIsObj = objTag == objectTag && !isHostObject(object), | |
othIsObj = othTag == objectTag && !isHostObject(other), | |
isSameTag = objTag == othTag; | |
if (isSameTag && !(objIsArr || objIsObj)) { | |
return equalByTag(object, other, objTag, equalFunc, customizer, bitmask); | |
} | |
var isPartial = bitmask & PARTIAL_COMPARE_FLAG; | |
if (!isPartial) { | |
var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), | |
othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); | |
if (objIsWrapped || othIsWrapped) { | |
return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, bitmask, stack); | |
} | |
} | |
if (!isSameTag) { | |
return false; | |
} | |
stack || (stack = new Stack); | |
return (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, bitmask, stack); | |
} | |
/** | |
* 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, | |
result = customizer ? customizer(objValue, srcValue, key, object, source, stack) : undefined; | |
if (!(result === undefined | |
? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack) | |
: result | |
)) { | |
return false; | |
} | |
} | |
} | |
return true; | |
} | |
/** | |
* The base implementation of `_.iteratee`. | |
* | |
* @private | |
* @param {*} [value=_.identity] The value to convert to an iteratee. | |
* @returns {Function} Returns the iteratee. | |
*/ | |
function baseIteratee(value) { | |
var type = typeof value; | |
if (type == 'function') { | |
return value; | |
} | |
if (value == null) { | |
return identity; | |
} | |
if (type == 'object') { | |
return isArray(value) | |
? baseMatchesProperty(value[0], value[1]) | |
: baseMatches(value); | |
} | |
return property(value); | |
} | |
/** | |
* The base implementation of `_.keys` which doesn't skip the constructor | |
* property of prototypes or treat sparse arrays as dense. | |
* | |
* @private | |
* @type Function | |
* @param {Object} object The object to query. | |
* @returns {Array} Returns the array of property names. | |
*/ | |
function baseKeys(object) { | |
return nativeKeys(Object(object)); | |
} | |
/** | |
* The base implementation of `_.keysIn` which doesn't skip the constructor | |
* property of prototypes or treat sparse arrays as dense. | |
* | |
* @private | |
* @param {Object} object The object to query. | |
* @returns {Array} Returns the array of property names. | |
*/ | |
function baseKeysIn(object) { | |
object = object == null ? object : Object(object); | |
var result = []; | |
for (var key in object) { | |
result.push(key); | |
} | |
return result; | |
} | |
// Fallback for IE < 9 with es6-shim. | |
if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) { | |
baseKeysIn = function(object) { | |
return iteratorToArray(enumerate(object)); | |
}; | |
} | |
/** | |
* 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 function. | |
*/ | |
function baseMatches(source) { | |
var matchData = getMatchData(source); | |
if (matchData.length == 1 && matchData[0][2]) { | |
var key = matchData[0][0], | |
value = matchData[0][1]; | |
return function(object) { | |
if (object == null) { | |
return false; | |
} | |
return object[key] === value && | |
(value !== undefined || (key in Object(object))); | |
}; | |
} | |
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 function. | |
*/ | |
function baseMatchesProperty(path, srcValue) { | |
return function(object) { | |
var objValue = get(object, path); | |
return (objValue === undefined && objValue === srcValue) | |
? hasIn(object, path) | |
: baseIsEqual(srcValue, objValue, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_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; | |
} | |
var props = (isArray(source) || isTypedArray(source)) ? undefined : keysIn(source); | |
arrayEach(props || source, function(srcValue, key) { | |
if (props) { | |
key = srcValue; | |
srcValue = source[key]; | |
} | |
if (isObject(srcValue)) { | |
stack || (stack = new Stack); | |
baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); | |
} | |
else { | |
var newValue = customizer ? customizer(object[key], srcValue, (key + ''), object, source, stack) : undefined; | |
if (newValue === undefined) { | |
newValue = srcValue; | |
} | |
assignMergeValue(object, key, newValue); | |
} | |
}); | |
} | |
/** | |
* 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 = object[key], | |
srcValue = source[key], | |
stacked = stack.get(srcValue); | |
if (stacked) { | |
assignMergeValue(object, key, stacked); | |
return; | |
} | |
var newValue = customizer ? customizer(objValue, srcValue, (key + ''), object, source, stack) : undefined, | |
isCommon = newValue === undefined; | |
if (isCommon) { | |
newValue = srcValue; | |
if (isArray(srcValue) || isTypedArray(srcValue)) { | |
if (isArray(objValue)) { | |
newValue = srcIndex ? copyArray(objValue) : objValue; | |
} | |
else if (isArrayLikeObject(objValue)) { | |
newValue = copyArray(objValue); | |
} | |
else { | |
isCommon = false; | |
newValue = baseClone(srcValue); | |
} | |
} | |
else if (isPlainObject(srcValue) || isArguments(srcValue)) { | |
if (isArguments(objValue)) { | |
newValue = toPlainObject(objValue); | |
} | |
else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) { | |
isCommon = false; | |
newValue = baseClone(srcValue); | |
} | |
else { | |
newValue = srcIndex ? baseClone(objValue) : objValue; | |
} | |
} | |
else { | |
isCommon = false; | |
} | |
} | |
stack.set(srcValue, newValue); | |
if (isCommon) { | |
// Recursively merge objects and arrays (susceptible to call stack limits). | |
mergeFunc(newValue, srcValue, srcIndex, customizer, stack); | |
} | |
assignMergeValue(object, key, newValue); | |
} | |
/** | |
* 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, | |
toIteratee = getIteratee(); | |
iteratees = arrayMap(iteratees.length ? iteratees : Array(1), function(iteratee) { | |
return toIteratee(iteratee); | |
}); | |
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 names. | |
* | |
* @private | |
* @param {Object} object The source object. | |
* @param {string[]} props The property names to pick. | |
* @returns {Object} Returns the new object. | |
*/ | |
function basePick(object, props) { | |
object = Object(object); | |
return arrayReduce(props, function(result, key) { | |
if (key in object) { | |
result[key] = object[key]; | |
} | |
return result; | |
}, {}); | |
} | |
/** | |
* The base implementation of `_.pickBy` without support for iteratee shorthands. | |
* | |
* @private | |
* @param {Object} object The source object. | |
* @param {Function} predicate The function invoked per property. | |
* @returns {Object} Returns the new object. | |
*/ | |
function basePickBy(object, predicate) { | |
var result = {}; | |
baseForIn(object, function(value, key) { | |
if (predicate(value, key)) { | |
result[key] = value; | |
} | |
}); | |
return result; | |
} | |
/** | |
* 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 function. | |
*/ | |
function baseProperty(key) { | |
return function(object) { | |
return object == null ? undefined : object[key]; | |
}; | |
} | |
/** | |
* 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 function. | |
*/ | |
function basePropertyDeep(path) { | |
return function(object) { | |
return baseGet(object, path); | |
}; | |
} | |
/** | |
* The base implementation of `_.pullAll`. | |
* | |
* @private | |
* @param {Array} array The array to modify. | |
* @param {Array} values The values to remove. | |
* @returns {Array} Returns `array`. | |
*/ | |
function basePullAll(array, values) { | |
return basePullAllBy(array, values); | |
} | |
/** | |
* 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. | |
* @returns {Array} Returns `array`. | |
*/ | |
function basePullAllBy(array, values, iteratee) { | |
var index = -1, | |
length = values.length, | |
seen = array; | |
if (iteratee) { | |
seen = arrayMap(array, function(value) { return iteratee(value); }); | |
} | |
while (++index < length) { | |
var fromIndex = 0, | |
value = values[index], | |
computed = iteratee ? iteratee(value) : value; | |
while ((fromIndex = baseIndexOf(seen, computed, fromIndex)) > -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 (lastIndex == length || index != previous) { | |
var previous = index; | |
if (isIndex(index)) { | |
splice.call(array, index, 1); | |
} | |
else if (!isKey(index, array)) { | |
var path = baseToPath(index), | |
object = parent(array, path); | |
if (object != null) { | |
delete object[last(path)]; | |
} | |
} | |
else { | |
delete 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 to numbers. | |
* | |
* @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 new array 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 `_.set`. | |
* | |
* @private | |
* @param {Object} object The object to query. | |
* @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) { | |
path = isKey(path, object) ? [path + ''] : baseToPath(path); | |
var index = -1, | |
length = path.length, | |
lastIndex = length - 1, | |
nested = object; | |
while (nested != null && ++index < length) { | |
var key = path[index]; | |
if (isObject(nested)) { | |
var newValue = value; | |
if (index != lastIndex) { | |
var objValue = nested[key]; | |
newValue = customizer ? customizer(objValue, key, nested) : undefined; | |
if (newValue === undefined) { | |
newValue = objValue == null ? (isIndex(path[index + 1]) ? [] : {}) : objValue; | |
} | |
} | |
assignValue(nested, key, newValue); | |
} | |
nested = nested[key]; | |
} | |
return object; | |
} | |
/** | |
* The base implementation of `setData` without support for hot loop detection. | |
* | |
* @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 `_.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 ? array.length : low; | |
if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { | |
while (low < high) { | |
var mid = (low + high) >>> 1, | |
computed = array[mid]; | |
if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) { | |
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 ? array.length : 0, | |
valIsNaN = value !== value, | |
valIsNull = value === null, | |
valIsUndef = value === undefined; | |
while (low < high) { | |
var mid = nativeFloor((low + high) / 2), | |
computed = iteratee(array[mid]), | |
isDef = computed !== undefined, | |
isReflexive = computed === computed; | |
if (valIsNaN) { | |
var setLow = isReflexive || retHighest; | |
} else if (valIsNull) { | |
setLow = isReflexive && isDef && (retHighest || computed != null); | |
} else if (valIsUndef) { | |
setLow = isReflexive && (retHighest || isDef); | |
} else if (computed == null) { | |
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`. | |
* | |
* @private | |
* @param {Array} array The array to inspect. | |
* @returns {Array} Returns the new duplicate free array. | |
*/ | |
function baseSortedUniq(array) { | |
return baseSortedUniqBy(array); | |
} | |
/** | |
* The base implementation of `_.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 baseSortedUniqBy(array, iteratee) { | |
var index = 0, | |
length = array.length, | |
value = array[0], | |
computed = iteratee ? iteratee(value) : value, | |
seen = computed, | |
resIndex = 0, | |
result = [value]; | |
while (++index < length) { | |
value = array[index], | |
computed = iteratee ? iteratee(value) : value; | |
if (!eq(computed, seen)) { | |
seen = computed; | |
result[++resIndex] = value; | |
} | |
} | |
return result; | |
} | |
/** | |
* The base implementation of `_.toPath` which only converts `value` to a | |
* path if it's not one. | |
* | |
* @private | |
* @param {*} value The value to process. | |
* @returns {Array} Returns the property path array. | |
*/ | |
function baseToPath(value) { | |
return isArray(value) ? value : stringToPath(value); | |
} | |
/** | |
* 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; | |
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 path of the property to unset. | |
* @returns {boolean} Returns `true` if the property is deleted, else `false`. | |
*/ | |
function baseUnset(object, path) { | |
path = isKey(path, object) ? [path + ''] : baseToPath(path); | |
object = parent(object, path); | |
var key = last(path); | |
return (object != null && has(object, key)) ? delete object[key] : true; | |
} | |
/** | |
* 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 index = -1, | |
length = arrays.length; | |
while (++index < length) { | |
var result = result | |
? arrayPush( | |
baseDifference(result, arrays[index], iteratee, comparator), | |
baseDifference(arrays[index], result, iteratee, comparator) | |
) | |
: arrays[index]; | |
} | |
return (result && result.length) ? baseUniq(result, iteratee, comparator) : []; | |
} | |
/** | |
* This base implementation of `_.zipObject` which assigns values using `assignFunc`. | |
* | |
* @private | |
* @param {Array} props The property names. | |
* @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) { | |
assignFunc(result, props[index], index < valsLength ? values[index] : undefined); | |
} | |
return result; | |
} | |
/** | |
* 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 Ctor = buffer.constructor, | |
result = new Ctor(buffer.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 Ctor = arrayBuffer.constructor, | |
result = new Ctor(arrayBuffer.byteLength), | |
view = new Uint8Array(result); | |
view.set(new Uint8Array(arrayBuffer)); | |
return result; | |
} | |
/** | |
* Creates a clone of `map`. | |
* | |
* @private | |
* @param {Object} map The map to clone. | |
* @returns {Object} Returns the cloned map. | |
*/ | |
function cloneMap(map) { | |
var Ctor = map.constructor; | |
return arrayReduce(mapToArray(map), addMapEntry, new Ctor); | |
} | |
/** | |
* Creates a clone of `regexp`. | |
* | |
* @private | |
* @param {Object} regexp The regexp to clone. | |
* @returns {Object} Returns the cloned regexp. | |
*/ | |
function cloneRegExp(regexp) { | |
var Ctor = regexp.constructor, | |
result = new Ctor(regexp.source, reFlags.exec(regexp)); | |
result.lastIndex = regexp.lastIndex; | |
return result; | |
} | |
/** | |
* Creates a clone of `set`. | |
* | |
* @private | |
* @param {Object} set The set to clone. | |
* @returns {Object} Returns the cloned set. | |
*/ | |
function cloneSet(set) { | |
var Ctor = set.constructor; | |
return arrayReduce(setToArray(set), addSetEntry, new Ctor); | |
} | |
/** | |
* 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 Symbol ? 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 = typedArray.buffer, | |
Ctor = typedArray.constructor; | |
return new Ctor(isDeep ? cloneArrayBuffer(buffer) : buffer, typedArray.byteOffset, typedArray.length); | |
} | |
/** | |
* Creates an array that is the composition of partially applied arguments, | |
* placeholders, and provided arguments into a single array of arguments. | |
* | |
* @private | |
* @param {Array|Object} args The provided arguments. | |
* @param {Array} partials The arguments to prepend to those provided. | |
* @param {Array} holders The `partials` placeholder indexes. | |
* @returns {Array} Returns the new array of composed arguments. | |
*/ | |
function composeArgs(args, partials, holders) { | |
var holdersLength = holders.length, | |
argsIndex = -1, | |
argsLength = nativeMax(args.length - holdersLength, 0), | |
leftIndex = -1, | |
leftLength = partials.length, | |
result = Array(leftLength + argsLength); | |
while (++leftIndex < leftLength) { | |
result[leftIndex] = partials[leftIndex]; | |
} | |
while (++argsIndex < holdersLength) { | |
result[holders[argsIndex]] = args[argsIndex]; | |
} | |
while (argsLength--) { | |
result[leftIndex++] = args[argsIndex++]; | |
} | |
return result; | |
} | |
/** | |
* This function is like `composeArgs` except that the arguments composition | |
* is tailored for `_.partialRight`. | |
* | |
* @private | |
* @param {Array|Object} args The provided arguments. | |
* @param {Array} partials The arguments to append to those provided. | |
* @param {Array} holders The `partials` placeholder indexes. | |
* @returns {Array} Returns the new array of composed arguments. | |
*/ | |
function composeArgsRight(args, partials, holders) { | |
var holdersIndex = -1, | |
holdersLength = holders.length, | |
argsIndex = -1, | |
argsLength = nativeMax(args.length - holdersLength, 0), | |
rightIndex = -1, | |
rightLength = partials.length, | |
result = Array(argsLength + rightLength); | |
while (++argsIndex < argsLength) { | |
result[argsIndex] = args[argsIndex]; | |
} | |
var offset = argsIndex; | |
while (++rightIndex < rightLength) { | |
result[offset + rightIndex] = partials[rightIndex]; | |
} | |
while (++holdersIndex < holdersLength) { | |
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 names to copy. | |
* @param {Object} [object={}] The object to copy properties to. | |
* @returns {Object} Returns `object`. | |
*/ | |
function copyObject(source, props, object) { | |
return copyObjectWith(source, props, object); | |
} | |
/** | |
* This function is like `copyObject` except that it accepts a function to | |
* customize copied values. | |
* | |
* @private | |
* @param {Object} source The object to copy properties from. | |
* @param {Array} props The property names 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 copyObjectWith(source, props, object, customizer) { | |
object || (object = {}); | |
var index = -1, | |
length = props.length; | |
while (++index < length) { | |
var key = props[index], | |
newValue = customizer ? customizer(object[key], source[key], key, object, source) : source[key]; | |
assignValue(object, key, newValue); | |
} | |
return object; | |
} | |
/** | |
* Copies own symbol properties 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); | |
} | |
/** | |
* 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), 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 rest(function(object, sources) { | |
var index = -1, | |
length = sources.length, | |
customizer = length > 1 ? sources[length - 1] : undefined, | |
guard = length > 2 ? sources[2] : undefined; | |
customizer = 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`. | |
* | |
* @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 of wrapper flags. See `createWrapper` for more details. | |
* @param {*} [thisArg] The `this` binding of `func`. | |
* @returns {Function} Returns the new wrapped function. | |
*/ | |
function createBaseWrapper(func, bitmask, thisArg) { | |
var isBind = bitmask & BIND_FLAG, | |
Ctor = createCtorWrapper(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 function. | |
*/ | |
function createCaseFirst(methodName) { | |
return function(string) { | |
string = toString(string); | |
var strSymbols = reHasComplexSymbol.test(string) ? stringToArray(string) : undefined, | |
chr = strSymbols ? strSymbols[0] : string.charAt(0), | |
trailing = strSymbols ? strSymbols.slice(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)), 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 createCtorWrapper(Ctor) { | |
return function() { | |
// Use a `switch` statement to work with class constructors. | |
// See http://ecma-international.org/ecma-262/6.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 of wrapper flags. See `createWrapper` for more details. | |
* @param {number} arity The arity of `func`. | |
* @returns {Function} Returns the new wrapped function. | |
*/ | |
function createCurryWrapper(func, bitmask, arity) { | |
var Ctor = createCtorWrapper(func); | |
function wrapper() { | |
var length = arguments.length, | |
index = length, | |
args = Array(length), | |
fn = (this && this !== root && this instanceof wrapper) ? Ctor : func, | |
placeholder = lodash.placeholder || wrapper.placeholder; | |
while (index--) { | |
args[index] = arguments[index]; | |
} | |
var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder) | |
? [] | |
: replaceHolders(args, placeholder); | |
length -= holders.length; | |
return length < arity | |
? createRecurryWrapper(func, bitmask, createHybridWrapper, placeholder, undefined, args, holders, undefined, undefined, arity - length) | |
: apply(fn, this, args); | |
} | |
return wrapper; | |
} | |
/** | |
* 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 rest(function(funcs) { | |
funcs = baseFlatten(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] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | 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) && value.length >= LARGE_ARRAY_SIZE) { | |
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 of wrapper flags. See `createWrapper` 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 createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { | |
var isAry = bitmask & ARY_FLAG, | |
isBind = bitmask & BIND_FLAG, | |
isBindKey = bitmask & BIND_KEY_FLAG, | |
isCurry = bitmask & CURRY_FLAG, | |
isCurryRight = bitmask & CURRY_RIGHT_FLAG, | |
isFlip = bitmask & FLIP_FLAG, | |
Ctor = isBindKey ? undefined : createCtorWrapper(func); | |
function wrapper() { | |
var length = arguments.length, | |
index = length, | |
args = Array(length); | |
while (index--) { | |
args[index] = arguments[index]; | |
} | |
if (partials) { | |
args = composeArgs(args, partials, holders); | |
} | |
if (partialsRight) { | |
args = composeArgsRight(args, partialsRight, holdersRight); | |
} | |
if (isCurry || isCurryRight) { | |
var placeholder = lodash.placeholder || wrapper.placeholder, | |
argsHolders = replaceHolders(args, placeholder); | |
length -= argsHolders.length; | |
if (length < arity) { | |
return createRecurryWrapper(func, bitmask, createHybridWrapper, placeholder, thisArg, args, argsHolders, argPos, ary, arity - length); | |
} | |
} | |
var thisBinding = isBind ? thisArg : this, | |
fn = isBindKey ? thisBinding[func] : func; | |
if (argPos) { | |
args = reorder(args, argPos); | |
} else if (isFlip && args.length > 1) { | |
args.reverse(); | |
} | |
if (isAry && ary < args.length) { | |
args.length = ary; | |
} | |
if (this && this !== root && this instanceof wrapper) { | |
fn = Ctor || createCtorWrapper(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 like `_.over`. | |
* | |
* @private | |
* @param {Function} arrayFunc The function to iterate over iteratees. | |
* @returns {Function} Returns the new invoker function. | |
*/ | |
function createOver(arrayFunc) { | |
return rest(function(iteratees) { | |
iteratees = arrayMap(baseFlatten(iteratees), getIteratee()); | |
return rest(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 {string} string The string to create padding for. | |
* @param {number} [length=0] The padding length. | |
* @param {string} [chars=' '] The string used as padding. | |
* @returns {string} Returns the padding for `string`. | |
*/ | |
function createPadding(string, length, chars) { | |
length = toInteger(length); | |
var strLength = stringSize(string); | |
if (!length || strLength >= length) { | |
return ''; | |
} | |
var padLength = length - strLength; | |
chars = chars === undefined ? ' ' : (chars + ''); | |
var result = repeat(chars, nativeCeil(padLength / stringSize(chars))); | |
return reHasComplexSymbol.test(chars) | |
? stringToArray(result).slice(0, padLength).join('') | |
: result.slice(0, padLength); | |
} | |
/** | |
* Creates a function that wraps `func` to invoke it with the optional `this` | |
* binding of `thisArg` and the `partials` prepended to those provided to | |
* the wrapper. | |
* | |
* @private | |
* @param {Function} func The function to wrap. | |
* @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` 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 createPartialWrapper(func, bitmask, thisArg, partials) { | |
var isBind = bitmask & BIND_FLAG, | |
Ctor = createCtorWrapper(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 = toNumber(start); | |
start = start === start ? start : 0; | |
if (end === undefined) { | |
end = start; | |
start = 0; | |
} else { | |
end = toNumber(end) || 0; | |
} | |
step = step === undefined ? (start < end ? 1 : -1) : (toNumber(step) || 0); | |
return baseRange(start, end, step, fromRight); | |
}; | |
} | |
/** | |
* Creates a function that wraps `func` to continue currying. | |
* | |
* @private | |
* @param {Function} func The function to wrap. | |
* @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. | |
* @param {Function} wrapFunc The function to create the `func` wrapper. | |
* @param {*} placeholder The placeholder to replace. | |
* @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 createRecurryWrapper(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) { | |
var isCurry = bitmask & CURRY_FLAG, | |
newArgPos = argPos ? copyArray(argPos) : undefined, | |
newsHolders = isCurry ? holders : undefined, | |
newHoldersRight = isCurry ? undefined : holders, | |
newPartials = isCurry ? partials : undefined, | |
newPartialsRight = isCurry ? undefined : partials; | |
bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); | |
bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); | |
if (!(bitmask & CURRY_BOUND_FLAG)) { | |
bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); | |
} | |
var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, arity], | |
result = wrapFunc.apply(undefined, newData); | |
if (isLaziable(func)) { | |
setData(result, newData); | |
} | |
result.placeholder = placeholder; | |
return result; | |
} | |
/** | |
* 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 = toInteger(precision); | |
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 of `values`. | |
* | |
* @private | |
* @param {Array} values The values to add to the set. | |
* @returns {Object} Returns the new set. | |
*/ | |
var createSet = !(Set && new Set([1, 2]).size === 2) ? noop : function(values) { | |
return new Set(values); | |
}; | |
/** | |
* 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 of wrapper flags. | |
* The bitmask may be composed of the following flags: | |
* 1 - `_.bind` | |
* 2 - `_.bindKey` | |
* 4 - `_.curry` or `_.curryRight` of a bound function | |
* 8 - `_.curry` | |
* 16 - `_.curryRight` | |
* 32 - `_.partial` | |
* 64 - `_.partialRight` | |
* 128 - `_.rearg` | |
* 256 - `_.ary` | |
* @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 createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { | |
var isBindKey = bitmask & BIND_KEY_FLAG; | |
if (!isBindKey && typeof func != 'function') { | |
throw new TypeError(FUNC_ERROR_TEXT); | |
} | |
var length = partials ? partials.length : 0; | |
if (!length) { | |
bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); | |
partials = holders = undefined; | |
} | |
ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0); | |
arity = arity === undefined ? arity : toInteger(arity); | |
length -= holders ? holders.length : 0; | |
if (bitmask & PARTIAL_RIGHT_FLAG) { | |
var partialsRight = partials, | |
holdersRight = holders; | |
partials = holders = undefined; | |
} | |
var data = isBindKey ? undefined : getData(func), | |
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] == null | |
? (isBindKey ? 0 : func.length) | |
: nativeMax(newData[9] - length, 0); | |
if (!arity && bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG)) { | |
bitmask &= ~(CURRY_FLAG | CURRY_RIGHT_FLAG); | |
} | |
if (!bitmask || bitmask == BIND_FLAG) { | |
var result = createBaseWrapper(func, bitmask, thisArg); | |
} else if (bitmask == CURRY_FLAG || bitmask == CURRY_RIGHT_FLAG) { | |
result = createCurryWrapper(func, bitmask, arity); | |
} else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !holders.length) { | |
result = createPartialWrapper(func, bitmask, thisArg, partials); | |
} else { | |
result = createHybridWrapper.apply(undefined, newData); | |
} | |
var setter = data ? baseSetData : setData; | |
return setter(result, newData); | |
} | |
/** | |
* 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 {Function} equalFunc The function to determine equivalents of values. | |
* @param {Function} [customizer] The function to customize comparisons. | |
* @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details. | |
* @param {Object} [stack] Tracks traversed `array` and `other` objects. | |
* @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. | |
*/ | |
function equalArrays(array, other, equalFunc, customizer, bitmask, stack) { | |
var index = -1, | |
isPartial = bitmask & PARTIAL_COMPARE_FLAG, | |
isUnordered = bitmask & UNORDERED_COMPARE_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) { | |
return stacked == other; | |
} | |
var result = true; | |
stack.set(array, other); | |
// 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 (isUnordered) { | |
if (!arraySome(other, function(othValue) { | |
return arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack); | |
})) { | |
result = false; | |
break; | |
} | |
} else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) { | |
result = false; | |
break; | |
} | |
} | |
stack['delete'](array); | |
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 {Function} equalFunc The function to determine equivalents of values. | |
* @param {Function} [customizer] The function to customize comparisons. | |
* @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details. | |
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`. | |
*/ | |
function equalByTag(object, other, tag, equalFunc, customizer, bitmask) { | |
switch (tag) { | |
case arrayBufferTag: | |
if ((object.byteLength != other.byteLength) || | |
!equalFunc(new Uint8Array(object), new Uint8Array(other))) { | |
return false; | |
} | |
return true; | |
case boolTag: | |
case dateTag: | |
// Coerce dates and booleans to numbers, dates to milliseconds and booleans | |
// to `1` or `0` treating invalid dates coerced to `NaN` as not equal. | |
return +object == +other; | |
case errorTag: | |
return object.name == other.name && object.message == other.message; | |
case numberTag: | |
// Treat `NaN` vs. `NaN` as equal. | |
return (object != +object) ? other != +other : object == +other; | |
case regexpTag: | |
case stringTag: | |
// Coerce regexes to strings and treat strings primitives and string | |
// objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. | |
return object == (other + ''); | |
case mapTag: | |
var convert = mapToArray; | |
case setTag: | |
var isPartial = bitmask & PARTIAL_COMPARE_FLAG; | |
convert || (convert = setToArray); | |
// Recursively compare objects (susceptible to call stack limits). | |
return (isPartial || object.size == other.size) && | |
equalFunc(convert(object), convert(other), customizer, bitmask | UNORDERED_COMPARE_FLAG); | |
case symbolTag: | |
return !!Symbol && (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 {Function} equalFunc The function to determine equivalents of values. | |
* @param {Function} [customizer] The function to customize comparisons. | |
* @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details. | |
* @param {Object} [stack] Tracks traversed `object` and `other` objects. | |
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`. | |
*/ | |
function equalObjects(object, other, equalFunc, customizer, bitmask, stack) { | |
var isPartial = bitmask & PARTIAL_COMPARE_FLAG, | |
objProps = keys(object), | |
objLength = objProps.length, | |
othProps = keys(other), | |
othLength = othProps.length; | |
if (objLength != othLength && !isPartial) { | |
return false; | |
} | |
var index = objLength; | |
while (index--) { | |
var key = objProps[index]; | |
if (!(isPartial ? key in other : baseHas(other, key))) { | |
return false; | |
} | |
} | |
// Assume cyclic values are equal. | |
var stacked = stack.get(object); | |
if (stacked) { | |
return stacked == other; | |
} | |
var result = true; | |
stack.set(object, other); | |
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, customizer, bitmask, 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); | |
return result; | |
} | |
/** | |
* 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 appropriate "iteratee" function. If the `_.iteratee` method 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 "length" property value of `object`. | |
* | |
* **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) | |
* that affects Safari on at least iOS 8.1-8.3 ARM64. | |
* | |
* @private | |
* @param {Object} object The object to query. | |
* @returns {*} Returns the "length" value. | |
*/ | |
var getLength = baseProperty('length'); | |
/** | |
* 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 = toPairs(object), | |
length = result.length; | |
while (length--) { | |
result[length][2] = isStrictComparable(result[length][1]); | |
} | |
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 = object == null ? undefined : object[key]; | |
return isNative(value) ? value : undefined; | |
} | |
/** | |
* Creates an array of the own symbol properties of `object`. | |
* | |
* @private | |
* @param {Object} object The object to query. | |
* @returns {Array} Returns the array of symbols. | |
*/ | |
var getSymbols = getOwnPropertySymbols || function() { | |
return []; | |
}; | |
/** | |
* Gets the `toStringTag` of `value`. | |
* | |
* @private | |
* @param {*} value The value to query. | |
* @returns {string} Returns the `toStringTag`. | |
*/ | |
function getTag(value) { | |
return objectToString.call(value); | |
} | |
// Fallback for IE 11 providing `toStringTag` values for maps, sets, and weakmaps. | |
if ((Map && getTag(new Map) != mapTag) || | |
(Set && getTag(new Set) != setTag) || | |
(WeakMap && getTag(new WeakMap) != weakMapTag)) { | |
getTag = function(value) { | |
var result = objectToString.call(value), | |
Ctor = result == objectTag ? value.constructor : null, | |
ctorString = typeof Ctor == 'function' ? funcToString.call(Ctor) : ''; | |
if (ctorString) { | |
switch (ctorString) { | |
case mapCtorString: return mapTag; | |
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 }; | |
} | |
/** | |
* 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) { | |
if (object == null) { | |
return false; | |
} | |
var result = hasFunc(object, path); | |
if (!result && !isKey(path)) { | |
path = baseToPath(path); | |
object = parent(object, path); | |
if (object != null) { | |
path = last(path); | |
result = hasFunc(object, path); | |
} | |
} | |
var length = object ? object.length : undefined; | |
return result || ( | |
!!length && isLength(length) && isIndex(path, length) && | |
(isArray(object) || isString(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 = 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) { | |
if (isPrototype(object)) { | |
return {}; | |
} | |
var Ctor = object.constructor; | |
return baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined); | |
} | |
/** | |
* Initializes an object clone based on its `toStringTag`. | |
* | |
* **Note:** This function only supports cloning values with tags of | |
* `Boolean`, `Date`, `Error`, `Number`, `RegExp`, 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 float32Tag: case float64Tag: | |
case int8Tag: case int16Tag: case int32Tag: | |
case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: | |
return cloneTypedArray(object, isDeep); | |
case mapTag: | |
return cloneMap(object); | |
case numberTag: | |
case stringTag: | |
return new Ctor(object); | |
case regexpTag: | |
return cloneRegExp(object); | |
case setTag: | |
return cloneSet(object); | |
case symbolTag: | |
return cloneSymbol(object); | |
} | |
} | |
/** | |
* Creates an array of index keys for `object` values of arrays, | |
* `arguments` objects, and strings, otherwise `null` is returned. | |
* | |
* @private | |
* @param {Object} object The object to query. | |
* @returns {Array|null} Returns index keys, else `null`. | |
*/ | |
function indexKeys(object) { | |
var length = object ? object.length : undefined; | |
if (isLength(length) && | |
(isArray(object) || isString(object) || isArguments(object))) { | |
return baseTimes(length, String); | |
} | |
return null; | |
} | |
/** | |
* 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 (typeof value == 'number') { | |
return true; | |
} | |
return !isArray(value) && | |
(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 == 'number' || type == 'boolean' || | |
(type == 'string' && 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 `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); | |
} | |
/** | |
* 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 < (BIND_FLAG | BIND_KEY_FLAG | ARY_FLAG); | |
var isCombo = | |
(srcBitmask == ARY_FLAG && (bitmask == CURRY_FLAG)) || | |
(srcBitmask == ARY_FLAG && (bitmask == REARG_FLAG) && (data[7].length <= source[8])) || | |
(srcBitmask == (ARY_FLAG | REARG_FLAG) && (source[7].length <= source[8]) && (bitmask == CURRY_FLAG)); | |
// Exit early if metadata can't be merged. | |
if (!(isCommon || isCombo)) { | |
return data; | |
} | |
// Use source `thisArg` if available. | |
if (srcBitmask & BIND_FLAG) { | |
data[2] = source[2]; | |
// Set when currying a bound function. | |
newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG; | |
} | |
// Compose partial arguments. | |
var value = source[3]; | |
if (value) { | |
var partials = data[3]; | |
data[3] = partials ? composeArgs(partials, value, source[4]) : copyArray(value); | |
data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : copyArray(source[4]); | |
} | |
// Compose partial right arguments. | |
value = source[5]; | |
if (value) { | |
partials = data[5]; | |
data[5] = partials ? composeArgsRight(partials, value, source[6]) : copyArray(value); | |
data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : copyArray(source[6]); | |
} | |
// Use source `argPos` if available. | |
value = source[7]; | |
if (value) { | |
data[7] = copyArray(value); | |
} | |
// Use source `ary` if it's smaller. | |
if (srcBitmask & 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; | |
} | |
/** | |
* Used by `_.defaultsDeep` to customize its `_.merge` use. | |
* | |
* @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 mergeDefaults(objValue, srcValue, key, object, source, stack) { | |
if (isObject(objValue) && isObject(srcValue)) { | |
stack.set(srcValue, objValue); | |
baseMerge(objValue, srcValue, undefined, mergeDefaults, stack); | |
} | |
return objValue; | |
} | |
/** | |
* 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 == 1 ? object : get(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://code.google.com/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 = (function() { | |
var count = 0, | |
lastCalled = 0; | |
return function(key, value) { | |
var stamp = now(), | |
remaining = HOT_SPAN - (stamp - lastCalled); | |
lastCalled = stamp; | |
if (remaining > 0) { | |
if (++count >= HOT_COUNT) { | |
return key; | |
} | |
} else { | |
count = 0; | |
} | |
return baseSetData(key, value); | |
}; | |
}()); | |
/** | |
* Converts `string` to a property path array. | |
* | |
* @private | |
* @param {string} string The string to convert. | |
* @returns {Array} Returns the property path array. | |
*/ | |
function stringToPath(string) { | |
var result = []; | |
toString(string).replace(rePropName, function(match, number, quote, string) { | |
result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); | |
}); | |
return result; | |
} | |
/** | |
* Converts `value` to an array-like object if it's not one. | |
* | |
* @private | |
* @param {*} value The value to process. | |
* @returns {Array} Returns the array-like object. | |
*/ | |
function toArrayLikeObject(value) { | |
return isArrayLikeObject(value) ? value : []; | |
} | |
/** | |
* Converts `value` to a function if it's not one. | |
* | |
* @private | |
* @param {*} value The value to process. | |
* @returns {Function} Returns the function. | |
*/ | |
function toFunction(value) { | |
return typeof value == 'function' ? value : identity; | |
} | |
/** | |
* 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 _ | |
* @category Array | |
* @param {Array} array The array to process. | |
* @param {number} [size=0] The length of each chunk. | |
* @returns {Array} Returns the new array containing 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) { | |
size = nativeMax(toInteger(size), 0); | |
var length = array ? array.length : 0; | |
if (!length || size < 1) { | |
return []; | |
} | |
var index = 0, | |
resIndex = -1, | |
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 _ | |
* @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 ? array.length : 0, | |
resIndex = -1, | |
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 _ | |
* @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] | |
*/ | |
var concat = rest(function(array, values) { | |
if (!isArray(array)) { | |
array = array == null ? [] : [Object(array)]; | |
} | |
values = baseFlatten(values); | |
return arrayConcat(array, values); | |
}); | |
/** | |
* Creates an array of unique `array` values not included in the other | |
* given arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) | |
* for equality comparisons. | |
* | |
* @static | |
* @memberOf _ | |
* @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. | |
* @example | |
* | |
* _.difference([3, 2, 1], [4, 2]); | |
* // => [3, 1] | |
*/ | |
var difference = rest(function(array, values) { | |
return isArrayLikeObject(array) | |
? baseDifference(array, baseFlatten(values, false, 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 uniqueness is computed. The iteratee is invoked with one argument: (value). | |
* | |
* @static | |
* @memberOf _ | |
* @category Array | |
* @param {Array} array The array to inspect. | |
* @param {...Array} [values] The values to exclude. | |
* @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. | |
* @returns {Array} Returns the new array of filtered values. | |
* @example | |
* | |
* _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor); | |
* // => [3.1, 1.3] | |
* | |
* // The `_.property` iteratee shorthand. | |
* _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x'); | |
* // => [{ 'x': 2 }] | |
*/ | |
var differenceBy = rest(function(array, values) { | |
var iteratee = last(values); | |
if (isArrayLikeObject(iteratee)) { | |
iteratee = undefined; | |
} | |
return isArrayLikeObject(array) | |
? baseDifference(array, baseFlatten(values, false, true), getIteratee(iteratee)) | |
: []; | |
}); | |
/** | |
* This method is like `_.difference` except that it accepts `comparator` | |
* which is invoked to compare elements of `array` to `values`. The comparator | |
* is invoked with two arguments: (arrVal, othVal). | |
* | |
* @static | |
* @memberOf _ | |
* @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 = rest(function(array, values) { | |
var comparator = last(values); | |
if (isArrayLikeObject(comparator)) { | |
comparator = undefined; | |
} | |
return isArrayLikeObject(array) | |
? baseDifference(array, baseFlatten(values, false, true), undefined, comparator) | |
: []; | |
}); | |
/** | |
* Creates a slice of `array` with `n` elements dropped from the beginning. | |
* | |
* @static | |
* @memberOf _ | |
* @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 functions 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 ? array.length : 0; | |
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 _ | |
* @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 functions 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 ? array.length : 0; | |
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 _ | |
* @category Array | |
* @param {Array} array The array to query. | |
* @param {Function|Object|string} [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 _ | |
* @category Array | |
* @param {Array} array The array to query. | |
* @param {Function|Object|string} [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 _ | |
* @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 ? array.length : 0; | |
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 _ | |
* @category Array | |
* @param {Array} array The array to search. | |
* @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. | |
* @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) { | |
return (array && array.length) | |
? baseFindIndex(array, getIteratee(predicate, 3)) | |
: -1; | |
} | |
/** | |
* This method is like `_.findIndex` except that it iterates over elements | |
* of `collection` from right to left. | |
* | |
* @static | |
* @memberOf _ | |
* @category Array | |
* @param {Array} array The array to search. | |
* @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. | |
* @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) { | |
return (array && array.length) | |
? baseFindIndex(array, getIteratee(predicate, 3), true) | |
: -1; | |
} | |
/** | |
* Flattens `array` a single level. | |
* | |
* @static | |
* @memberOf _ | |
* @category Array | |
* @param {Array} array The array to flatten. | |
* @returns {Array} Returns the new flattened array. | |
* @example | |
* | |
* _.flatten([1, [2, 3, [4]]]); | |
* // => [1, 2, 3, [4]] | |
*/ | |
function flatten(array) { | |
var length = array ? array.length : 0; | |
return length ? baseFlatten(array) : []; | |
} | |
/** | |
* This method is like `_.flatten` except that it recursively flattens `array`. | |
* | |
* @static | |
* @memberOf _ | |
* @category Array | |
* @param {Array} array The array to recursively flatten. | |
* @returns {Array} Returns the new flattened array. | |
* @example | |
* | |
* _.flattenDeep([1, [2, 3, [4]]]); | |
* // => [1, 2, 3, 4] | |
*/ | |
function flattenDeep(array) { | |
var length = array ? array.length : 0; | |
return length ? baseFlatten(array, true) : []; | |
} | |
/** | |
* The inverse of `_.toPairs`; this method returns an object composed | |
* from key-value `pairs`. | |
* | |
* @static | |
* @memberOf _ | |
* @category Array | |
* @param {Array} pairs The key-value pairs. | |
* @returns {Object} Returns the new object. | |
* @example | |
* | |
* _.fromPairs([['fred', 30], ['barney', 40]]); | |
* // => { 'fred': 30, 'barney': 40 } | |
*/ | |
function fromPairs(pairs) { | |
var index = -1, | |
length = pairs ? pairs.length : 0, | |
result = {}; | |
while (++index < length) { | |
var pair = pairs[index]; | |
result[pair[0]] = pair[1]; | |
} | |
return result; | |
} | |
/** | |
* Gets the first element of `array`. | |
* | |
* @static | |
* @memberOf _ | |
* @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[0] : undefined; | |
} | |
/** | |
* Gets the index at which the first occurrence of `value` is found in `array` | |
* using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) | |
* for equality comparisons. If `fromIndex` is negative, it's used as the offset | |
* from the end of `array`. | |
* | |
* @static | |
* @memberOf _ | |
* @category Array | |
* @param {Array} array The array to search. | |
* @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 ? array.length : 0; | |
if (!length) { | |
return -1; | |
} | |
fromIndex = toInteger(fromIndex); | |
if (fromIndex < 0) { | |
fromIndex = nativeMax(length + fromIndex, 0); | |
} | |
return baseIndexOf(array, value, fromIndex); | |
} | |
/** | |
* Gets all but the last element of `array`. | |
* | |
* @static | |
* @memberOf _ | |
* @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) { | |
return dropRight(array, 1); | |
} | |
/** | |
* Creates an array of unique values that are included in all given arrays | |
* using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) | |
* for equality comparisons. | |
* | |
* @static | |
* @memberOf _ | |
* @category Array | |
* @param {...Array} [arrays] The arrays to inspect. | |
* @returns {Array} Returns the new array of shared values. | |
* @example | |
* | |
* _.intersection([2, 1], [4, 2], [1, 2]); | |
* // => [2] | |
*/ | |
var intersection = rest(function(arrays) { | |
var mapped = arrayMap(arrays, toArrayLikeObject); | |
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 uniqueness is computed. The iteratee is invoked with one argument: (value). | |
* | |
* @static | |
* @memberOf _ | |
* @category Array | |
* @param {...Array} [arrays] The arrays to inspect. | |
* @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. | |
* @returns {Array} Returns the new array of shared values. | |
* @example | |
* | |
* _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor); | |
* // => [2.1] | |
* | |
* // The `_.property` iteratee shorthand. | |
* _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); | |
* // => [{ 'x': 1 }] | |
*/ | |
var intersectionBy = rest(function(arrays) { | |
var iteratee = last(arrays), | |
mapped = arrayMap(arrays, toArrayLikeObject); | |
if (iteratee === last(mapped)) { | |
iteratee = undefined; | |
} else { | |
mapped.pop(); | |
} | |
return (mapped.length && mapped[0] === arrays[0]) | |
? baseIntersection(mapped, getIteratee(iteratee)) | |
: []; | |
}); | |
/** | |
* This method is like `_.intersection` except that it accepts `comparator` | |
* which is invoked to compare elements of `arrays`. The comparator is invoked | |
* with two arguments: (arrVal, othVal). | |
* | |
* @static | |
* @memberOf _ | |
* @category Array | |
* @param {...Array} [arrays] The arrays to inspect. | |
* @param {Function} [comparator] The comparator invoked per element. | |
* @returns {Array} Returns the new array of shared 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 = rest(function(arrays) { | |
var comparator = last(arrays), | |
mapped = arrayMap(arrays, toArrayLikeObject); | |
if (comparator === last(mapped)) { | |
comparator = undefined; | |
} else { | |
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 _ | |
* @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 ? nativeJoin.call(array, separator) : ''; | |
} | |
/** | |
* Gets the last element of `array`. | |
* | |
* @static | |
* @memberOf _ | |
* @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 ? array.length : 0; | |
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 _ | |
* @category Array | |
* @param {Array} array The array to search. | |
* @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 ? array.length : 0; | |
if (!length) { | |
return -1; | |
} | |
var index = length; | |
if (fromIndex !== undefined) { | |
index = toInteger(fromIndex); | |
index = (index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1)) + 1; | |
} | |
if (value !== value) { | |
return indexOfNaN(array, index, true); | |
} | |
while (index--) { | |
if (array[index] === value) { | |
return index; | |
} | |
} | |
return -1; | |
} | |
/** | |
* Removes all given values from `array` using | |
* [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) | |
* for equality comparisons. | |
* | |
* **Note:** Unlike `_.without`, this method mutates `array`. | |
* | |
* @static | |
* @memberOf _ | |
* @category Array | |
* @param {Array} array The array to modify. | |
* @param {...*} [values] The values to remove. | |
* @returns {Array} Returns `array`. | |
* @example | |
* | |
* var array = [1, 2, 3, 1, 2, 3]; | |
* | |
* _.pull(array, 2, 3); | |
* console.log(array); | |
* // => [1, 1] | |
*/ | |
var pull = rest(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 _ | |
* @category Array | |
* @param {Array} array The array to modify. | |
* @param {Array} values The values to remove. | |
* @returns {Array} Returns `array`. | |
* @example | |
* | |
* var array = [1, 2, 3, 1, 2, 3]; | |
* | |
* _.pullAll(array, [2, 3]); | |
* console.log(array); | |
* // => [1, 1] | |
*/ | |
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 uniqueness is computed. The iteratee is invoked with one argument: (value). | |
* | |
* **Note:** Unlike `_.differenceBy`, this method mutates `array`. | |
* | |
* @static | |
* @memberOf _ | |
* @category Array | |
* @param {Array} array The array to modify. | |
* @param {Array} values The values to remove. | |
* @param {Function|Object|string} [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) | |
? basePullAllBy(array, values, getIteratee(iteratee)) | |
: array; | |
} | |
/** | |
* Removes elements from `array` corresponding to `indexes` and returns an | |
* array of removed elements. | |
* | |
* **Note:** Unlike `_.at`, this method mutates `array`. | |
* | |
* @static | |
* @memberOf _ | |
* @category Array | |
* @param {Array} array The array to modify. | |
* @param {...(number|number[])} [indexes] The indexes of elements to remove, | |
* specified individually or in arrays. | |
* @returns {Array} Returns the new array of removed elements. | |
* @example | |
* | |
* var array = [5, 10, 15, 20]; | |
* var evens = _.pullAt(array, 1, 3); | |
* | |
* console.log(array); | |
* // => [5, 15] | |
* | |
* console.log(evens); | |
* // => [10, 20] | |
*/ | |
var pullAt = rest(function(array, indexes) { | |
indexes = arrayMap(baseFlatten(indexes), String); | |
var result = baseAt(array, indexes); | |
basePullAt(array, indexes.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`. | |
* | |
* @static | |
* @memberOf _ | |
* @category Array | |
* @param {Array} array The array to modify. | |
* @param {Function|Object|string} [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 _ | |
* @category Array | |
* @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 ? nativeReverse.call(array) : 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 _ | |
* @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 ? array.length : 0; | |
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 _ | |
* @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 | |
* | |
* _.sortedIndex([4, 5], 4); | |
* // => 0 | |
*/ | |
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 _ | |
* @category Array | |
* @param {Array} array The sorted array to inspect. | |
* @param {*} value The value to evaluate. | |
* @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. | |
* @returns {number} Returns the index at which `value` should be inserted into `array`. | |
* @example | |
* | |
* var dict = { 'thirty': 30, 'forty': 40, 'fifty': 50 }; | |
* | |
* _.sortedIndexBy(['thirty', 'fifty'], 'forty', _.propertyOf(dict)); | |
* // => 1 | |
* | |
* // The `_.property` iteratee shorthand. | |
* _.sortedIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x'); | |
* // => 0 | |
*/ | |
function sortedIndexBy(array, value, iteratee) { | |
return baseSortedIndexBy(array, value, getIteratee(iteratee)); | |
} | |
/** | |
* This method is like `_.indexOf` except that it performs a binary | |
* search on a sorted `array`. | |
* | |
* @static | |
* @memberOf _ | |
* @category Array | |
* @param {Array} array The array to search. | |
* @param {*} value The value to search for. | |
* @returns {number} Returns the index of the matched value, else `-1`. | |
* @example | |
* | |
* _.sortedIndexOf([1, 1, 2, 2], 2); | |
* // => 2 | |
*/ | |
function sortedIndexOf(array, value) { | |
var length = array ? array.length : 0; | |
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 _ | |
* @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], 4); | |
* // => 1 | |
*/ | |
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 _ | |
* @category Array | |
* @param {Array} array The sorted array to inspect. | |
* @param {*} value The value to evaluate. | |
* @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. | |
* @returns {number} Returns the index at which `value` should be inserted into `array`. | |
* @example | |
* | |
* // The `_.property` iteratee shorthand. | |
* _.sortedLastIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x'); | |
* // => 1 | |
*/ | |
function sortedLastIndexBy(array, value, iteratee) { | |
return baseSortedIndexBy(array, value, getIteratee(iteratee), true); | |
} | |
/** | |
* This method is like `_.lastIndexOf` except that it performs a binary | |
* search on a sorted `array`. | |
* | |
* @static | |
* @memberOf _ | |
* @category Array | |
* @param {Array} array The array to search. | |
* @param {*} value The value to search for. | |
* @returns {number} Returns the index of the matched value, else `-1`. | |
* @example | |
* | |
* _.sortedLastIndexOf([1, 1, 2, 2], 2); | |
* // => 3 | |
*/ | |
function sortedLastIndexOf(array, value) { | |
var length = array ? array.length : 0; | |
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 _ | |
* @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 _ | |
* @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) | |
? baseSortedUniqBy(array, getIteratee(iteratee)) | |
: []; | |
} | |
/** | |
* Gets all but the first element of `array`. | |
* | |
* @static | |
* @memberOf _ | |
* @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) { | |
return drop(array, 1); | |
} | |
/** | |
* Creates a slice of `array` with `n` elements taken from the beginning. | |
* | |
* @static | |
* @memberOf _ | |
* @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 functions 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 _ | |
* @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 functions 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 ? array.length : 0; | |
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 _ | |
* @category Array | |
* @param {Array} array The array to query. | |
* @param {Function|Object|string} [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 _ | |
* @category Array | |
* @param {Array} array The array to query. | |
* @param {Function|Object|string} [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/6.0/#sec-samevaluezero) | |
* for equality comparisons. | |
* | |
* @static | |
* @memberOf _ | |
* @category Array | |
* @param {...Array} [arrays] The arrays to inspect. | |
* @returns {Array} Returns the new array of combined values. | |
* @example | |
* | |
* _.union([2, 1], [4, 2], [1, 2]); | |
* // => [2, 1, 4] | |
*/ | |
var union = rest(function(arrays) { | |
return baseUniq(baseFlatten(arrays, false, 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. The iteratee is invoked with one argument: (value). | |
* | |
* @static | |
* @memberOf _ | |
* @category Array | |
* @param {...Array} [arrays] The arrays to inspect. | |
* @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. | |
* @returns {Array} Returns the new array of combined values. | |
* @example | |
* | |
* _.unionBy([2.1, 1.2], [4.3, 2.4], Math.floor); | |
* // => [2.1, 1.2, 4.3] | |
* | |
* // The `_.property` iteratee shorthand. | |
* _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); | |
* // => [{ 'x': 1 }, { 'x': 2 }] | |
*/ | |
var unionBy = rest(function(arrays) { | |
var iteratee = last(arrays); | |
if (isArrayLikeObject(iteratee)) { | |
iteratee = undefined; | |
} | |
return baseUniq(baseFlatten(arrays, false, true), getIteratee(iteratee)); | |
}); | |
/** | |
* This method is like `_.union` except that it accepts `comparator` which | |
* is invoked to compare elements of `arrays`. The comparator is invoked | |
* with two arguments: (arrVal, othVal). | |
* | |
* @static | |
* @memberOf _ | |
* @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 = rest(function(arrays) { | |
var comparator = last(arrays); | |
if (isArrayLikeObject(comparator)) { | |
comparator = undefined; | |
} | |
return baseUniq(baseFlatten(arrays, false, true), undefined, comparator); | |
}); | |
/** | |
* Creates a duplicate-free version of an array, using | |
* [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) | |
* for equality comparisons, in which only the first occurrence of each element | |
* is kept. | |
* | |
* @static | |
* @memberOf _ | |
* @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 iteratee is invoked with one argument: (value). | |
* | |
* @static | |
* @memberOf _ | |
* @category Array | |
* @param {Array} array The array to inspect. | |
* @param {Function|Object|string} [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)) | |
: []; | |
} | |
/** | |
* This method is like `_.uniq` except that it accepts `comparator` which | |
* is invoked to compare elements of `array`. The comparator is invoked with | |
* two arguments: (arrVal, othVal). | |
* | |
* @static | |
* @memberOf _ | |
* @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) { | |
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 _ | |
* @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(['fred', 'barney'], [30, 40], [true, false]); | |
* // => [['fred', 30, true], ['barney', 40, false]] | |
* | |
* _.unzip(zipped); | |
* // => [['fred', 'barney'], [30, 40], [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 _ | |
* @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/6.0/#sec-samevaluezero) | |
* for equality comparisons. | |
* | |
* @static | |
* @memberOf _ | |
* @category Array | |
* @param {Array} array The array to filter. | |
* @param {...*} [values] The values to exclude. | |
* @returns {Array} Returns the new array of filtered values. | |
* @example | |
* | |
* _.without([1, 2, 1, 3], 1, 2); | |
* // => [3] | |
*/ | |
var without = rest(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. | |
* | |
* @static | |
* @memberOf _ | |
* @category Array | |
* @param {...Array} [arrays] The arrays to inspect. | |
* @returns {Array} Returns the new array of values. | |
* @example | |
* | |
* _.xor([2, 1], [4, 2]); | |
* // => [1, 4] | |
*/ | |
var xor = rest(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 | |
* uniqueness is computed. The iteratee is invoked with one argument: (value). | |
* | |
* @static | |
* @memberOf _ | |
* @category Array | |
* @param {...Array} [arrays] The arrays to inspect. | |
* @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. | |
* @returns {Array} Returns the new array of values. | |
* @example | |
* | |
* _.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor); | |
* // => [1.2, 4.3] | |
* | |
* // The `_.property` iteratee shorthand. | |
* _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); | |
* // => [{ 'x': 2 }] | |
*/ | |
var xorBy = rest(function(arrays) { | |
var iteratee = last(arrays); | |
if (isArrayLikeObject(iteratee)) { | |
iteratee = undefined; | |
} | |
return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee)); | |
}); | |
/** | |
* This method is like `_.xor` except that it accepts `comparator` which is | |
* invoked to compare elements of `arrays`. The comparator is invoked with | |
* two arguments: (arrVal, othVal). | |
* | |
* @static | |
* @memberOf _ | |
* @category Array | |
* @param {...Array} [arrays] The arrays to inspect. | |
* @param {Function} [comparator] The comparator invoked per element. | |
* @returns {Array} Returns the new array of 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 = rest(function(arrays) { | |
var comparator = last(arrays); | |
if (isArrayLikeObject(comparator)) { | |
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 _ | |
* @category Array | |
* @param {...Array} [arrays] The arrays to process. | |
* @returns {Array} Returns the new array of grouped elements. | |
* @example | |
* | |
* _.zip(['fred', 'barney'], [30, 40], [true, false]); | |
* // => [['fred', 30, true], ['barney', 40, false]] | |
*/ | |
var zip = rest(unzip); | |
/** | |
* This method is like `_.fromPairs` except that it accepts two arrays, | |
* one of property names and one of corresponding values. | |
* | |
* @static | |
* @memberOf _ | |
* @category Array | |
* @param {Array} [props=[]] The property names. | |
* @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 _ | |
* @category Array | |
* @param {Array} [props=[]] The property names. | |
* @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 _ | |
* @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 = rest(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` object that wraps `value` with explicit method chaining enabled. | |
* The result of such method chaining must be unwrapped with `_#value`. | |
* | |
* @static | |
* @memberOf _ | |
* @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 in order to modify intermediate results. | |
* | |
* @static | |
* @memberOf _ | |
* @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. | |
* | |
* @static | |
* @memberOf _ | |
* @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 _ | |
* @category Seq | |
* @param {...(string|string[])} [paths] The property paths of elements to pick, | |
* specified individually or in arrays. | |
* @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] | |
* | |
* _(['a', 'b', 'c']).at(0, 2).value(); | |
* // => ['a', 'c'] | |
*/ | |
var wrapperAt = rest(function(paths) { | |
paths = baseFlatten(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; | |
}); | |
}); | |
/** | |
* Enables explicit method chaining on the wrapper object. | |
* | |
* @name chain | |
* @memberOf _ | |
* @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 chained sequence and returns the wrapped result. | |
* | |
* @name commit | |
* @memberOf _ | |
* @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__); | |
} | |
/** | |
* This method is the wrapper version of `_.flatMap`. | |
* | |
* @name flatMap | |
* @memberOf _ | |
* @category Seq | |
* @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration. | |
* @returns {Object} Returns the new `lodash` wrapper instance. | |
* @example | |
* | |
* function duplicate(n) { | |
* return [n, n]; | |
* } | |
* | |
* _([1, 2]).flatMap(duplicate).value(); | |
* // => [1, 1, 2, 2] | |
*/ | |
function wrapperFlatMap(iteratee) { | |
return this.map(iteratee).flatten(); | |
} | |
/** | |
* Gets the next value on a wrapped object following the | |
* [iterator protocol](https://mdn.io/iteration_protocols#iterator). | |
* | |
* @name next | |
* @memberOf _ | |
* @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 _ | |
* @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 chained sequence planting `value` as the wrapped value. | |
* | |
* @name plant | |
* @memberOf _ | |
* @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 _ | |
* @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 chained sequence to extract the unwrapped value. | |
* | |
* @name value | |
* @memberOf _ | |
* @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` through `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 _ | |
* @category Collection | |
* @param {Array|Object} collection The collection to iterate over. | |
* @param {Function|Object|string} [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 } | |
* | |
* _.countBy(['one', 'two', 'three'], 'length'); | |
* // => { '3': 2, '5': 1 } | |
*/ | |
var countBy = createAggregator(function(result, value, key) { | |
hasOwnProperty.call(result, key) ? ++result[key] : (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). | |
* | |
* @static | |
* @memberOf _ | |
* @category Collection | |
* @param {Array|Object} collection The collection to iterate over. | |
* @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. | |
* @param- {Object} [guard] Enables use as an iteratee for functions 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', 'active': false }, | |
* { 'user': 'fred', '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). | |
* | |
* @static | |
* @memberOf _ | |
* @category Collection | |
* @param {Array|Object} collection The collection to iterate over. | |
* @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. | |
* @returns {Array} Returns the new filtered array. | |
* @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 _ | |
* @category Collection | |
* @param {Array|Object} collection The collection to search. | |
* @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. | |
* @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' | |
*/ | |
function find(collection, predicate) { | |
predicate = getIteratee(predicate, 3); | |
if (isArray(collection)) { | |
var index = baseFindIndex(collection, predicate); | |
return index > -1 ? collection[index] : undefined; | |
} | |
return baseFind(collection, predicate, baseEach); | |
} | |
/** | |
* This method is like `_.find` except that it iterates over elements of | |
* `collection` from right to left. | |
* | |
* @static | |
* @memberOf _ | |
* @category Collection | |
* @param {Array|Object} collection The collection to search. | |
* @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. | |
* @returns {*} Returns the matched element, else `undefined`. | |
* @example | |
* | |
* _.findLast([1, 2, 3, 4], function(n) { | |
* return n % 2 == 1; | |
* }); | |
* // => 3 | |
*/ | |
function findLast(collection, predicate) { | |
predicate = getIteratee(predicate, 3); | |
if (isArray(collection)) { | |
var index = baseFindIndex(collection, predicate, true); | |
return index > -1 ? collection[index] : undefined; | |
} | |
return baseFind(collection, predicate, baseEachRight); | |
} | |
/** | |
* Creates an array of flattened values by running each element in `collection` | |
* through `iteratee` and concating its result to the other mapped values. | |
* The iteratee is invoked with three arguments: (value, index|key, collection). | |
* | |
* @static | |
* @memberOf _ | |
* @category Collection | |
* @param {Array|Object} collection The collection to iterate over. | |
* @param {Function|Object|string} [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)); | |
} | |
/** | |
* Iterates over elements of `collection` invoking `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 _ | |
* @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`. | |
* @example | |
* | |
* _([1, 2]).forEach(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) { | |
return (typeof iteratee == 'function' && isArray(collection)) | |
? arrayEach(collection, iteratee) | |
: baseEach(collection, toFunction(iteratee)); | |
} | |
/** | |
* This method is like `_.forEach` except that it iterates over elements of | |
* `collection` from right to left. | |
* | |
* @static | |
* @memberOf _ | |
* @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`. | |
* @example | |
* | |
* _.forEachRight([1, 2], function(value) { | |
* console.log(value); | |
* }); | |
* // => logs `2` then `1` | |
*/ | |
function forEachRight(collection, iteratee) { | |
return (typeof iteratee == 'function' && isArray(collection)) | |
? arrayEachRight(collection, iteratee) | |
: baseEachRight(collection, toFunction(iteratee)); | |
} | |
/** | |
* Creates an object composed of keys generated from the results of running | |
* each element of `collection` through `iteratee`. 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 _ | |
* @category Collection | |
* @param {Array|Object} collection The collection to iterate over. | |
* @param {Function|Object|string} [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 { | |
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/6.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 _ | |
* @category Collection | |
* @param {Array|Object|string} collection The collection to search. | |
* @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 functions 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({ 'user': 'fred', 'age': 40 }, 'fred'); | |
* // => true | |
* | |
* _.includes('pebbles', 'eb'); | |
* // => 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 `methodName` is a function it's | |
* invoked for, and `this` bound to, each element in `collection`. | |
* | |
* @static | |
* @memberOf _ | |
* @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 = rest(function(collection, path, args) { | |
var index = -1, | |
isFunc = typeof path == 'function', | |
isProp = isKey(path), | |
result = isArrayLike(collection) ? Array(collection.length) : []; | |
baseEach(collection, function(value) { | |
var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined); | |
result[++index] = func ? apply(func, value, args) : baseInvoke(value, path, args); | |
}); | |
return result; | |
}); | |
/** | |
* Creates an object composed of keys generated from the results of running | |
* each element of `collection` through `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 _ | |
* @category Collection | |
* @param {Array|Object} collection The collection to iterate over. | |
* @param {Function|Object|string} [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) { | |
result[key] = value; | |
}); | |
/** | |
* Creates an array of values by running each element in `collection` through | |
* `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`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, `fill`, | |
* `invert`, `parseInt`, `random`, `range`, `rangeRight`, `slice`, `some`, | |
* `sortBy`, `take`, `takeRight`, `template`, `trim`, `trimEnd`, `trimStart`, | |
* and `words` | |
* | |
* @static | |
* @memberOf _ | |
* @category Collection | |
* @param {Array|Object} collection The collection to iterate over. | |
* @param {Function|Object|string} [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 _ | |
* @category Collection | |
* @param {Array|Object} collection The collection to iterate over. | |
* @param {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 functions like `_.reduce`. | |
* @returns {Array} Returns the new sorted array. | |
* @example | |
* | |
* var users = [ | |
* { 'user': 'fred', 'age': 48 }, | |
* { 'user': 'barney', 'age': 34 }, | |
* { 'user': 'fred', 'age': 42 }, | |
* { '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', 42]] | |
*/ | |
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 _ | |
* @category Collection | |
* @param {Array|Object} collection The collection to iterate over. | |
* @param {Function|Object|string} [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` through `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 _ | |
* @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. | |
* @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 _ | |
* @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. | |
* @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 _ | |
* @category Collection | |
* @param {Array|Object} collection The collection to iterate over. | |
* @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. | |
* @returns {Array} Returns the new filtered array. | |
* @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; | |
predicate = getIteratee(predicate, 3); | |
return func(collection, function(value, index, collection) { | |
return !predicate(value, index, collection); | |
}); | |
} | |
/** | |
* Gets a random element from `collection`. | |
* | |
* @static | |
* @memberOf _ | |
* @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 array = isArrayLike(collection) ? collection : values(collection), | |
length = array.length; | |
return length > 0 ? array[baseRandom(0, length - 1)] : undefined; | |
} | |
/** | |
* Gets `n` random elements at unique keys from `collection` up to the | |
* size of `collection`. | |
* | |
* @static | |
* @memberOf _ | |
* @category Collection | |
* @param {Array|Object} collection The collection to sample. | |
* @param {number} [n=0] The number of elements to sample. | |
* @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) { | |
var index = -1, | |
result = toArray(collection), | |
length = result.length, | |
lastIndex = length - 1; | |
n = baseClamp(toInteger(n), 0, length); | |
while (++index < n) { | |
var rand = baseRandom(index, lastIndex), | |
value = result[rand]; | |
result[rand] = result[index]; | |
result[index] = value; | |
} | |
result.length = n; | |
return result; | |
} | |
/** | |
* Creates an array of shuffled values, using a version of the | |
* [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). | |
* | |
* @static | |
* @memberOf _ | |
* @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) { | |
return sampleSize(collection, MAX_ARRAY_LENGTH); | |
} | |
/** | |
* Gets the size of `collection` by returning its length for array-like | |
* values or the number of own enumerable properties for objects. | |
* | |
* @static | |
* @memberOf _ | |
* @category Collection | |
* @param {Array|Object} 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)) { | |
var result = collection.length; | |
return (result && isString(collection)) ? stringSize(collection) : result; | |
} | |
return keys(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 _ | |
* @category Collection | |
* @param {Array|Object} collection The collection to iterate over. | |
* @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. | |
* @param- {Object} [guard] Enables use as an iteratee for functions 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 through 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 _ | |
* @category Collection | |
* @param {Array|Object} collection The collection to iterate over. | |
* @param {...(Function|Function[]|Object|Object[]|string|string[])} [iteratees=[_.identity]] | |
* The iteratees to sort by, specified individually or in arrays. | |
* @returns {Array} Returns the new sorted array. | |
* @example | |
* | |
* var users = [ | |
* { 'user': 'fred', 'age': 48 }, | |
* { 'user': 'barney', 'age': 36 }, | |
* { 'user': 'fred', 'age': 42 }, | |
* { 'user': 'barney', 'age': 34 } | |
* ]; | |
* | |
* _.sortBy(users, function(o) { return o.user; }); | |
* // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] | |
* | |
* _.sortBy(users, ['user', 'age']); | |
* // => objects for [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]] | |
* | |
* _.sortBy(users, 'user', function(o) { | |
* return Math.floor(o.age / 10); | |
* }); | |
* // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] | |
*/ | |
var sortBy = rest(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.length = 1; | |
} | |
return baseOrderBy(collection, baseFlatten(iteratees), []); | |
}); | |
/*------------------------------------------------------------------------*/ | |
/** | |
* Gets the timestamp of the number of milliseconds that have elapsed since | |
* the Unix epoch (1 January 1970 00:00:00 UTC). | |
* | |
* @static | |
* @memberOf _ | |
* @type Function | |
* @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 function to be invoked | |
*/ | |
var now = Date.now; | |
/*------------------------------------------------------------------------*/ | |
/** | |
* The opposite of `_.before`; this method creates a function that invokes | |
* `func` once it's called `n` or more times. | |
* | |
* @static | |
* @memberOf _ | |
* @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 accepts up to `n` arguments, ignoring any | |
* additional arguments. | |
* | |
* @static | |
* @memberOf _ | |
* @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 functions like `_.map`. | |
* @returns {Function} Returns the new 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 createWrapper(func, 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 _ | |
* @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 prepends any additional `_.bind` arguments to those provided to the | |
* bound function. | |
* | |
* 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 _ | |
* @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 | |
* | |
* var greet = function(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 = rest(function(func, thisArg, partials) { | |
var bitmask = BIND_FLAG; | |
if (partials.length) { | |
var placeholder = lodash.placeholder || bind.placeholder, | |
holders = replaceHolders(partials, placeholder); | |
bitmask |= PARTIAL_FLAG; | |
} | |
return createWrapper(func, bitmask, thisArg, partials, holders); | |
}); | |
/** | |
* Creates a function that invokes the method at `object[key]` and prepends | |
* any additional `_.bindKey` arguments to those provided to the bound function. | |
* | |
* 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 _ | |
* @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 = rest(function(object, key, partials) { | |
var bitmask = BIND_FLAG | BIND_KEY_FLAG; | |
if (partials.length) { | |
var placeholder = lodash.placeholder || bindKey.placeholder, | |
holders = replaceHolders(partials, placeholder); | |
bitmask |= PARTIAL_FLAG; | |
} | |
return createWrapper(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 _ | |
* @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 functions 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 = createWrapper(func, CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity); | |
result.placeholder = lodash.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 _ | |
* @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 functions 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 = createWrapper(func, CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity); | |
result.placeholder = lodash.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 an options object 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. | |
* | |
* See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) | |
* for details over the differences between `_.debounce` and `_.throttle`. | |
* | |
* @static | |
* @memberOf _ | |
* @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 args, | |
maxTimeoutId, | |
result, | |
stamp, | |
thisArg, | |
timeoutId, | |
trailingCall, | |
lastCalled = 0, | |
leading = false, | |
maxWait = false, | |
trailing = true; | |
if (typeof func != 'function') { | |
throw new TypeError(FUNC_ERROR_TEXT); | |
} | |
wait = toNumber(wait) || 0; | |
if (isObject(options)) { | |
leading = !!options.leading; | |
maxWait = 'maxWait' in options && nativeMax(toNumber(options.maxWait) || 0, wait); | |
trailing = 'trailing' in options ? !!options.trailing : trailing; | |
} | |
function cancel() { | |
if (timeoutId) { | |
clearTimeout(timeoutId); | |
} | |
if (maxTimeoutId) { | |
clearTimeout(maxTimeoutId); | |
} | |
lastCalled = 0; | |
args = maxTimeoutId = thisArg = timeoutId = trailingCall = undefined; | |
} | |
function complete(isCalled, id) { | |
if (id) { | |
clearTimeout(id); | |
} | |
maxTimeoutId = timeoutId = trailingCall = undefined; | |
if (isCalled) { | |
lastCalled = now(); | |
result = func.apply(thisArg, args); | |
if (!timeoutId && !maxTimeoutId) { | |
args = thisArg = undefined; | |
} | |
} | |
} | |
function delayed() { | |
var remaining = wait - (now() - stamp); | |
if (remaining <= 0 || remaining > wait) { | |
complete(trailingCall, maxTimeoutId); | |
} else { | |
timeoutId = setTimeout(delayed, remaining); | |
} | |
} | |
function flush() { | |
if ((timeoutId && trailingCall) || (maxTimeoutId && trailing)) { | |
result = func.apply(thisArg, args); | |
} | |
cancel(); | |
return result; | |
} | |
function maxDelayed() { | |
complete(trailing, timeoutId); | |
} | |
function debounced() { | |
args = arguments; | |
stamp = now(); | |
thisArg = this; | |
trailingCall = trailing && (timeoutId || !leading); | |
if (maxWait === false) { | |
var leadingCall = leading && !timeoutId; | |
} else { | |
if (!lastCalled && !maxTimeoutId && !leading) { | |
lastCalled = stamp; | |
} | |
var remaining = maxWait - (stamp - lastCalled), | |
isCalled = remaining <= 0 || remaining > maxWait; | |
if (isCalled) { | |
if (maxTimeoutId) { | |
maxTimeoutId = clearTimeout(maxTimeoutId); | |
} | |
lastCalled = stamp; | |
result = func.apply(thisArg, args); | |
} | |
else if (!maxTimeoutId) { | |
maxTimeoutId = setTimeout(maxDelayed, remaining); | |
} | |
} | |
if (isCalled && timeoutId) { | |
timeoutId = clearTimeout(timeoutId); | |
} | |
else if (!timeoutId && wait !== maxWait) { | |
timeoutId = setTimeout(delayed, wait); | |
} | |
if (leadingCall) { | |
isCalled = true; | |
result = func.apply(thisArg, args); | |
} | |
if (isCalled && !timeoutId && !maxTimeoutId) { | |
args = thisArg = undefined; | |
} | |
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 _ | |
* @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 or more milliseconds | |
*/ | |
var defer = rest(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 _ | |
* @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 = rest(function(func, wait, args) { | |
return baseDelay(func, toNumber(wait) || 0, args); | |
}); | |
/** | |
* Creates a function that invokes `func` with arguments reversed. | |
* | |
* @static | |
* @memberOf _ | |
* @category Function | |
* @param {Function} func The function to flip arguments for. | |
* @returns {Function} Returns the new function. | |
* @example | |
* | |
* var flipped = _.flip(function() { | |
* return _.toArray(arguments); | |
* }); | |
* | |
* flipped('a', 'b', 'c', 'd'); | |
* // => ['d', 'c', 'b', 'a'] | |
*/ | |
function flip(func) { | |
return createWrapper(func, 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/6.0/#sec-properties-of-the-map-prototype-object) | |
* method interface of `delete`, `get`, `has`, and `set`. | |
* | |
* @static | |
* @memberOf _ | |
* @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 memoizing 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 && 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); | |
return result; | |
}; | |
memoized.cache = new memoize.Cache; | |
return memoized; | |
} | |
/** | |
* 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 _ | |
* @category Function | |
* @param {Function} predicate The predicate to negate. | |
* @returns {Function} Returns the new 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() { | |
return !predicate.apply(this, arguments); | |
}; | |
} | |
/** | |
* 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 _ | |
* @category Function | |
* @param {Function} func The function to restrict. | |
* @returns {Function} Returns the new restricted function. | |
* @example | |
* | |
* var initialize = _.once(createApplication); | |
* initialize(); | |
* initialize(); | |
* // `initialize` invokes `createApplication` once | |
*/ | |
function once(func) { | |
return before(2, func); | |
} | |
/** | |
* Creates a function that invokes `func` with arguments transformed by | |
* corresponding `transforms`. | |
* | |
* @static | |
* @memberOf _ | |
* @category Function | |
* @param {Function} func The function to wrap. | |
* @param {...(Function|Function[])} [transforms] The functions to transform | |
* arguments, specified individually or in arrays. | |
* @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 = rest(function(func, transforms) { | |
transforms = arrayMap(baseFlatten(transforms), getIteratee()); | |
var funcsLength = transforms.length; | |
return rest(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 `partial` arguments prepended | |
* to those provided to the new function. 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 _ | |
* @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 | |
* | |
* var greet = function(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 = rest(function(func, partials) { | |
var placeholder = lodash.placeholder || partial.placeholder, | |
holders = replaceHolders(partials, placeholder); | |
return createWrapper(func, PARTIAL_FLAG, undefined, partials, holders); | |
}); | |
/** | |
* This method is like `_.partial` except that partially applied arguments | |
* are appended to those provided to the new function. | |
* | |
* 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 _ | |
* @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 | |
* | |
* var greet = function(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 = rest(function(func, partials) { | |
var placeholder = lodash.placeholder || partialRight.placeholder, | |
holders = replaceHolders(partials, placeholder); | |
return createWrapper(func, 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 _ | |
* @category Function | |
* @param {Function} func The function to rearrange arguments for. | |
* @param {...(number|number[])} indexes The arranged argument indexes, | |
* specified individually or in arrays. | |
* @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 = rest(function(func, indexes) { | |
return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(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 _ | |
* @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 = nativeMax(start === undefined ? (func.length - 1) : toInteger(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]; | |
} | |
switch (start) { | |
case 0: return func.call(this, array); | |
case 1: return func.call(this, args[0], array); | |
case 2: return func.call(this, args[0], args[1], array); | |
} | |
var otherArgs = Array(start + 1); | |
index = -1; | |
while (++index < start) { | |
otherArgs[index] = args[index]; | |
} | |
otherArgs[start] = array; | |
return apply(func, this, otherArgs); | |
}; | |
} | |
/** | |
* Creates a function that invokes `func` with the `this` binding of the created | |
* function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3). | |
* | |
* **Note:** This method is based on the [spread operator](https://mdn.io/spread_operator). | |
* | |
* @static | |
* @memberOf _ | |
* @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 === undefined ? 0 : nativeMax(toInteger(start), 0); | |
return rest(function(args) { | |
var array = args[start], | |
otherArgs = args.slice(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 an options object 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. | |
* | |
* See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) | |
* for details over the differences between `_.throttle` and `_.debounce`. | |
* | |
* @static | |
* @memberOf _ | |
* @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 _ | |
* @category Function | |
* @param {Function} func The function to cap arguments for. | |
* @returns {Function} Returns the new 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 the wrapper function as its | |
* first argument. Any additional arguments provided to the function are | |
* appended to those provided to the wrapper function. The wrapper is invoked | |
* with the `this` binding of the created function. | |
* | |
* @static | |
* @memberOf _ | |
* @category Function | |
* @param {*} value The value to wrap. | |
* @param {Function} wrapper 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) { | |
wrapper = wrapper == null ? identity : wrapper; | |
return partial(wrapper, 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 _ | |
* @category Lang | |
* @param {*} value The value to clone. | |
* @returns {*} Returns the cloned value. | |
* @example | |
* | |
* var objects = [{ 'a': 1 }, { 'b': 2 }]; | |
* | |
* var shallow = _.clone(objects); | |
* console.log(shallow[0] === objects[0]); | |
* // => true | |
*/ | |
function clone(value) { | |
return baseClone(value); | |
} | |
/** | |
* 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 _ | |
* @category Lang | |
* @param {*} value The value to clone. | |
* @param {Function} [customizer] The function to customize cloning. | |
* @returns {*} Returns the cloned value. | |
* @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) { | |
return baseClone(value, false, customizer); | |
} | |
/** | |
* This method is like `_.clone` except that it recursively clones `value`. | |
* | |
* @static | |
* @memberOf _ | |
* @category Lang | |
* @param {*} value The value to recursively clone. | |
* @returns {*} Returns the deep cloned value. | |
* @example | |
* | |
* var objects = [{ 'a': 1 }, { 'b': 2 }]; | |
* | |
* var deep = _.cloneDeep(objects); | |
* console.log(deep[0] === objects[0]); | |
* // => false | |
*/ | |
function cloneDeep(value) { | |
return baseClone(value, true); | |
} | |
/** | |
* This method is like `_.cloneWith` except that it recursively clones `value`. | |
* | |
* @static | |
* @memberOf _ | |
* @category Lang | |
* @param {*} value The value to recursively clone. | |
* @param {Function} [customizer] The function to customize cloning. | |
* @returns {*} Returns the deep cloned value. | |
* @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) { | |
return baseClone(value, true, customizer); | |
} | |
/** | |
* Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) | |
* comparison between two values to determine if they are equivalent. | |
* | |
* @static | |
* @memberOf _ | |
* @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 = { 'user': 'fred' }; | |
* var other = { 'user': 'fred' }; | |
* | |
* _.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 _ | |
* @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`. | |
* @example | |
* | |
* _.gt(3, 1); | |
* // => true | |
* | |
* _.gt(3, 3); | |
* // => false | |
* | |
* _.gt(1, 3); | |
* // => false | |
*/ | |
function gt(value, other) { | |
return value > other; | |
} | |
/** | |
* Checks if `value` is greater than or equal to `other`. | |
* | |
* @static | |
* @memberOf _ | |
* @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`. | |
* @example | |
* | |
* _.gte(3, 1); | |
* // => true | |
* | |
* _.gte(3, 3); | |
* // => true | |
* | |
* _.gte(1, 3); | |
* // => false | |
*/ | |
function gte(value, other) { | |
return value >= other; | |
} | |
/** | |
* Checks if `value` is likely an `arguments` object. | |
* | |
* @static | |
* @memberOf _ | |
* @category Lang | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. | |
* @example | |
* | |
* _.isArguments(function() { return arguments; }()); | |
* // => true | |
* | |
* _.isArguments([1, 2, 3]); | |
* // => false | |
*/ | |
function isArguments(value) { | |
// Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode. | |
return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && | |
(!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); | |
} | |
/** | |
* Checks if `value` is classified as an `Array` object. | |
* | |
* @static | |
* @memberOf _ | |
* @type Function | |
* @category Lang | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is correctly classified, 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 _ | |
* @type Function | |
* @category Lang | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. | |
* @example | |
* | |
* _.isArrayBuffer(new ArrayBuffer(2)); | |
* // => true | |
* | |
* _.isArrayBuffer(new Array(2)); | |
* // => false | |
*/ | |
function isArrayBuffer(value) { | |
return isObjectLike(value) && objectToString.call(value) == arrayBufferTag; | |
} | |
/** | |
* 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 _ | |
* @type Function | |
* @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 && | |
!(typeof value == 'function' && isFunction(value)) && isLength(getLength(value)); | |
} | |
/** | |
* This method is like `_.isArrayLike` except that it also checks if `value` | |
* is an object. | |
* | |
* @static | |
* @memberOf _ | |
* @type Function | |
* @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 _ | |
* @category Lang | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. | |
* @example | |
* | |
* _.isBoolean(false); | |
* // => true | |
* | |
* _.isBoolean(null); | |
* // => false | |
*/ | |
function isBoolean(value) { | |
return value === true || value === false || | |
(isObjectLike(value) && objectToString.call(value) == boolTag); | |
} | |
/** | |
* Checks if `value` is a buffer. | |
* | |
* @static | |
* @memberOf _ | |
* @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 = !Buffer ? constant(false) : function(value) { | |
return value instanceof Buffer; | |
}; | |
/** | |
* Checks if `value` is classified as a `Date` object. | |
* | |
* @static | |
* @memberOf _ | |
* @category Lang | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. | |
* @example | |
* | |
* _.isDate(new Date); | |
* // => true | |
* | |
* _.isDate('Mon April 23 2012'); | |
* // => false | |
*/ | |
function isDate(value) { | |
return isObjectLike(value) && objectToString.call(value) == dateTag; | |
} | |
/** | |
* Checks if `value` is likely a DOM element. | |
* | |
* @static | |
* @memberOf _ | |
* @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 !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value); | |
} | |
/** | |
* Checks if `value` is empty. A value is considered empty unless it's an | |
* `arguments` object, array, string, or jQuery-like collection with a length | |
* greater than `0` or an object with own enumerable properties. | |
* | |
* @static | |
* @memberOf _ | |
* @category Lang | |
* @param {Array|Object|string} value The value to inspect. | |
* @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 (isArrayLike(value) && | |
(isArray(value) || isString(value) || isFunction(value.splice) || isArguments(value))) { | |
return !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 **not** supported. | |
* | |
* @static | |
* @memberOf _ | |
* @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 = { 'user': 'fred' }; | |
* var other = { 'user': 'fred' }; | |
* | |
* _.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 _ | |
* @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, customizer) : !!result; | |
} | |
/** | |
* Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, | |
* `SyntaxError`, `TypeError`, or `URIError` object. | |
* | |
* @static | |
* @memberOf _ | |
* @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) { | |
return isObjectLike(value) && | |
typeof value.message == 'string' && objectToString.call(value) == errorTag; | |
} | |
/** | |
* Checks if `value` is a finite primitive number. | |
* | |
* **Note:** This method is based on [`Number.isFinite`](https://mdn.io/Number/isFinite). | |
* | |
* @static | |
* @memberOf _ | |
* @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.MAX_VALUE); | |
* // => true | |
* | |
* _.isFinite(3.14); | |
* // => true | |
* | |
* _.isFinite(Infinity); | |
* // => false | |
*/ | |
function isFinite(value) { | |
return typeof value == 'number' && nativeIsFinite(value); | |
} | |
/** | |
* Checks if `value` is classified as a `Function` object. | |
* | |
* @static | |
* @memberOf _ | |
* @category Lang | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. | |
* @example | |
* | |
* _.isFunction(_); | |
* // => true | |
* | |
* _.isFunction(/abc/); | |
* // => false | |
*/ | |
function isFunction(value) { | |
// The use of `Object#toString` avoids issues with the `typeof` operator | |
// in Safari 8 which returns 'object' for typed array constructors, and | |
// PhantomJS 1.9 which returns 'function' for `NodeList` instances. | |
var tag = isObject(value) ? objectToString.call(value) : ''; | |
return tag == funcTag || tag == genTag; | |
} | |
/** | |
* Checks if `value` is an integer. | |
* | |
* **Note:** This method is based on [`Number.isInteger`](https://mdn.io/Number/isInteger). | |
* | |
* @static | |
* @memberOf _ | |
* @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 function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). | |
* | |
* @static | |
* @memberOf _ | |
* @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](https://es5.github.io/#x8) of `Object`. | |
* (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) | |
* | |
* @static | |
* @memberOf _ | |
* @category Lang | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is an object, else `false`. | |
* @example | |
* | |
* _.isObject({}); | |
* // => true | |
* | |
* _.isObject([1, 2, 3]); | |
* // => true | |
* | |
* _.isObject(_.noop); | |
* // => true | |
* | |
* _.isObject(null); | |
* // => false | |
*/ | |
function isObject(value) { | |
var type = typeof value; | |
return !!value && (type == 'object' || type == 'function'); | |
} | |
/** | |
* Checks if `value` is object-like. A value is object-like if it's not `null` | |
* and has a `typeof` result of "object". | |
* | |
* @static | |
* @memberOf _ | |
* @category Lang | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is object-like, else `false`. | |
* @example | |
* | |
* _.isObjectLike({}); | |
* // => true | |
* | |
* _.isObjectLike([1, 2, 3]); | |
* // => true | |
* | |
* _.isObjectLike(_.noop); | |
* // => false | |
* | |
* _.isObjectLike(null); | |
* // => false | |
*/ | |
function isObjectLike(value) { | |
return !!value && typeof value == 'object'; | |
} | |
/** | |
* Checks if `value` is classified as a `Map` object. | |
* | |
* @static | |
* @memberOf _ | |
* @category Lang | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. | |
* @example | |
* | |
* _.isMap(new Map); | |
* // => true | |
* | |
* _.isMap(new WeakMap); | |
* // => false | |
*/ | |
function isMap(value) { | |
return isObjectLike(value) && getTag(value) == mapTag; | |
} | |
/** | |
* Performs a deep comparison between `object` and `source` to determine if | |
* `object` contains equivalent property values. | |
* | |
* **Note:** This method supports comparing the same values as `_.isEqual`. | |
* | |
* @static | |
* @memberOf _ | |
* @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 = { 'user': 'fred', 'age': 40 }; | |
* | |
* _.isMatch(object, { 'age': 40 }); | |
* // => true | |
* | |
* _.isMatch(object, { 'age': 36 }); | |
* // => 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 _ | |
* @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 not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4) | |
* which returns `true` for `undefined` and other non-numeric values. | |
* | |
* @static | |
* @memberOf _ | |
* @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 native function. | |
* | |
* @static | |
* @memberOf _ | |
* @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 (value == null) { | |
return false; | |
} | |
if (isFunction(value)) { | |
return reIsNative.test(funcToString.call(value)); | |
} | |
return isObjectLike(value) && | |
(isHostObject(value) ? reIsNative : reIsHostCtor).test(value); | |
} | |
/** | |
* Checks if `value` is `null`. | |
* | |
* @static | |
* @memberOf _ | |
* @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 _ | |
* @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 _ | |
* @category Lang | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is correctly classified, 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) && objectToString.call(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 _ | |
* @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) || objectToString.call(value) != objectTag || isHostObject(value)) { | |
return false; | |
} | |
var proto = objectProto; | |
if (typeof value.constructor == 'function') { | |
proto = getPrototypeOf(value); | |
} | |
if (proto === null) { | |
return true; | |
} | |
var Ctor = proto.constructor; | |
return (typeof Ctor == 'function' && | |
Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString); | |
} | |
/** | |
* Checks if `value` is classified as a `RegExp` object. | |
* | |
* @static | |
* @memberOf _ | |
* @category Lang | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. | |
* @example | |
* | |
* _.isRegExp(/abc/); | |
* // => true | |
* | |
* _.isRegExp('/abc/'); | |
* // => false | |
*/ | |
function isRegExp(value) { | |
return isObject(value) && objectToString.call(value) == regexpTag; | |
} | |
/** | |
* 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 _ | |
* @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 _ | |
* @category Lang | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. | |
* @example | |
* | |
* _.isSet(new Set); | |
* // => true | |
* | |
* _.isSet(new WeakSet); | |
* // => false | |
*/ | |
function isSet(value) { | |
return isObjectLike(value) && getTag(value) == setTag; | |
} | |
/** | |
* Checks if `value` is classified as a `String` primitive or object. | |
* | |
* @static | |
* @memberOf _ | |
* @category Lang | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. | |
* @example | |
* | |
* _.isString('abc'); | |
* // => true | |
* | |
* _.isString(1); | |
* // => false | |
*/ | |
function isString(value) { | |
return typeof value == 'string' || | |
(!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag); | |
} | |
/** | |
* Checks if `value` is classified as a `Symbol` primitive or object. | |
* | |
* @static | |
* @memberOf _ | |
* @category Lang | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. | |
* @example | |
* | |
* _.isSymbol(Symbol.iterator); | |
* // => true | |
* | |
* _.isSymbol('abc'); | |
* // => false | |
*/ | |
function isSymbol(value) { | |
return typeof value == 'symbol' || | |
(isObjectLike(value) && objectToString.call(value) == symbolTag); | |
} | |
/** | |
* Checks if `value` is classified as a typed array. | |
* | |
* @static | |
* @memberOf _ | |
* @category Lang | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. | |
* @example | |
* | |
* _.isTypedArray(new Uint8Array); | |
* // => true | |
* | |
* _.isTypedArray([]); | |
* // => false | |
*/ | |
function isTypedArray(value) { | |
return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objectToString.call(value)]; | |
} | |
/** | |
* Checks if `value` is `undefined`. | |
* | |
* @static | |
* @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 _ | |
* @category Lang | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is correctly classified, 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 _ | |
* @category Lang | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. | |
* @example | |
* | |
* _.isWeakSet(new WeakSet); | |
* // => true | |
* | |
* _.isWeakSet(new Set); | |
* // => false | |
*/ | |
function isWeakSet(value) { | |
return isObjectLike(value) && objectToString.call(value) == weakSetTag; | |
} | |
/** | |
* Checks if `value` is less than `other`. | |
* | |
* @static | |
* @memberOf _ | |
* @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`. | |
* @example | |
* | |
* _.lt(1, 3); | |
* // => true | |
* | |
* _.lt(3, 3); | |
* // => false | |
* | |
* _.lt(3, 1); | |
* // => false | |
*/ | |
function lt(value, other) { | |
return value < other; | |
} | |
/** | |
* Checks if `value` is less than or equal to `other`. | |
* | |
* @static | |
* @memberOf _ | |
* @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`. | |
* @example | |
* | |
* _.lte(1, 3); | |
* // => true | |
* | |
* _.lte(3, 3); | |
* // => true | |
* | |
* _.lte(3, 1); | |
* // => false | |
*/ | |
function lte(value, other) { | |
return value <= other; | |
} | |
/** | |
* Converts `value` to an array. | |
* | |
* @static | |
* @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 (iteratorSymbol && value[iteratorSymbol]) { | |
return iteratorToArray(value[iteratorSymbol]()); | |
} | |
var tag = getTag(value), | |
func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values); | |
return func(value); | |
} | |
/** | |
* Converts `value` to an integer. | |
* | |
* **Note:** This function is loosely based on [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger). | |
* | |
* @static | |
* @memberOf _ | |
* @category Lang | |
* @param {*} value The value to convert. | |
* @returns {number} Returns the converted integer. | |
* @example | |
* | |
* _.toInteger(3); | |
* // => 3 | |
* | |
* _.toInteger(Number.MIN_VALUE); | |
* // => 0 | |
* | |
* _.toInteger(Infinity); | |
* // => 1.7976931348623157e+308 | |
* | |
* _.toInteger('3'); | |
* // => 3 | |
*/ | |
function toInteger(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; | |
} | |
var remainder = value % 1; | |
return value === value ? (remainder ? value - remainder : value) : 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/6.0/#sec-tolength). | |
* | |
* @static | |
* @memberOf _ | |
* @category Lang | |
* @param {*} value The value to convert. | |
* @returns {number} Returns the converted integer. | |
* @example | |
* | |
* _.toLength(3); | |
* // => 3 | |
* | |
* _.toLength(Number.MIN_VALUE); | |
* // => 0 | |
* | |
* _.toLength(Infinity); | |
* // => 4294967295 | |
* | |
* _.toLength('3'); | |
* // => 3 | |
*/ | |
function toLength(value) { | |
return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0; | |
} | |
/** | |
* Converts `value` to a number. | |
* | |
* @static | |
* @memberOf _ | |
* @category Lang | |
* @param {*} value The value to process. | |
* @returns {number} Returns the number. | |
* @example | |
* | |
* _.toNumber(3); | |
* // => 3 | |
* | |
* _.toNumber(Number.MIN_VALUE); | |
* // => 5e-324 | |
* | |
* _.toNumber(Infinity); | |
* // => Infinity | |
* | |
* _.toNumber('3'); | |
* // => 3 | |
*/ | |
function toNumber(value) { | |
if (isObject(value)) { | |
var other = isFunction(value.valueOf) ? 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 | |
* properties of `value` to own properties of the plain object. | |
* | |
* @static | |
* @memberOf _ | |
* @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 _ | |
* @category Lang | |
* @param {*} value The value to convert. | |
* @returns {number} Returns the converted integer. | |
* @example | |
* | |
* _.toSafeInteger(3); | |
* // => 3 | |
* | |
* _.toSafeInteger(Number.MIN_VALUE); | |
* // => 0 | |
* | |
* _.toSafeInteger(Infinity); | |
* // => 9007199254740991 | |
* | |
* _.toSafeInteger('3'); | |
* // => 3 | |
*/ | |
function toSafeInteger(value) { | |
return baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER); | |
} | |
/** | |
* Converts `value` to a string if it's not one. An empty string is returned | |
* for `null` and `undefined` values. The sign of `-0` is preserved. | |
* | |
* @static | |
* @memberOf _ | |
* @category Lang | |
* @param {*} value The value to process. | |
* @returns {string} Returns the string. | |
* @example | |
* | |
* _.toString(null); | |
* // => '' | |
* | |
* _.toString(-0); | |
* // => '-0' | |
* | |
* _.toString([1, 2, 3]); | |
* // => '1,2,3' | |
*/ | |
function toString(value) { | |
// Exit early for strings to avoid a performance hit in some environments. | |
if (typeof value == 'string') { | |
return value; | |
} | |
if (value == null) { | |
return ''; | |
} | |
if (isSymbol(value)) { | |
return Symbol ? symbolToString.call(value) : ''; | |
} | |
var result = (value + ''); | |
return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; | |
} | |
/*------------------------------------------------------------------------*/ | |
/** | |
* Assigns own enumerable 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 _ | |
* @category Object | |
* @param {Object} object The destination object. | |
* @param {...Object} [sources] The source objects. | |
* @returns {Object} Returns `object`. | |
* @example | |
* | |
* function Foo() { | |
* this.c = 3; | |
* } | |
* | |
* function Bar() { | |
* this.e = 5; | |
* } | |
* | |
* Foo.prototype.d = 4; | |
* Bar.prototype.f = 6; | |
* | |
* _.assign({ 'a': 1 }, new Foo, new Bar); | |
* // => { 'a': 1, 'c': 3, 'e': 5 } | |
*/ | |
var assign = createAssigner(function(object, source) { | |
copyObject(source, keys(source), object); | |
}); | |
/** | |
* This method is like `_.assign` except that it iterates over own and | |
* inherited source properties. | |
* | |
* **Note:** This method mutates `object`. | |
* | |
* @static | |
* @memberOf _ | |
* @alias extend | |
* @category Object | |
* @param {Object} object The destination object. | |
* @param {...Object} [sources] The source objects. | |
* @returns {Object} Returns `object`. | |
* @example | |
* | |
* function Foo() { | |
* this.b = 2; | |
* } | |
* | |
* function Bar() { | |
* this.d = 4; | |
* } | |
* | |
* Foo.prototype.c = 3; | |
* Bar.prototype.e = 5; | |
* | |
* _.assignIn({ 'a': 1 }, new Foo, new Bar); | |
* // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 } | |
*/ | |
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 _ | |
* @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`. | |
* @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) { | |
copyObjectWith(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 _ | |
* @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) { | |
* 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) { | |
copyObjectWith(source, keys(source), object, customizer); | |
}); | |
/** | |
* Creates an array of values corresponding to `paths` of `object`. | |
* | |
* @static | |
* @memberOf _ | |
* @category Object | |
* @param {Object} object The object to iterate over. | |
* @param {...(string|string[])} [paths] The property paths of elements to pick, | |
* specified individually or in arrays. | |
* @returns {Array} Returns the new array of picked elements. | |
* @example | |
* | |
* var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; | |
* | |
* _.at(object, ['a[0].b.c', 'a[1]']); | |
* // => [3, 4] | |
* | |
* _.at(['a', 'b', 'c'], 0, 2); | |
* // => ['a', 'c'] | |
*/ | |
var at = rest(function(object, paths) { | |
return baseAt(object, baseFlatten(paths)); | |
}); | |
/** | |
* Creates an object that inherits from the `prototype` object. If a `properties` | |
* object is given its own enumerable properties are assigned to the created object. | |
* | |
* @static | |
* @memberOf _ | |
* @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 ? baseAssign(result, properties) : result; | |
} | |
/** | |
* Assigns own and inherited enumerable 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 | |
* @memberOf _ | |
* @category Object | |
* @param {Object} object The destination object. | |
* @param {...Object} [sources] The source objects. | |
* @returns {Object} Returns `object`. | |
* @example | |
* | |
* _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); | |
* // => { 'user': 'barney', 'age': 36 } | |
*/ | |
var defaults = rest(function(args) { | |
args.push(undefined, assignInDefaults); | |
return apply(assignInWith, undefined, args); | |
}); | |
/** | |
* This method is like `_.defaults` except that it recursively assigns | |
* default properties. | |
* | |
* **Note:** This method mutates `object`. | |
* | |
* @static | |
* @memberOf _ | |
* @category Object | |
* @param {Object} object The destination object. | |
* @param {...Object} [sources] The source objects. | |
* @returns {Object} Returns `object`. | |
* @example | |
* | |
* _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } }); | |
* // => { 'user': { 'name': 'barney', 'age': 36 } } | |
* | |
*/ | |
var defaultsDeep = rest(function(args) { | |
args.push(undefined, mergeDefaults); | |
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 _ | |
* @category Object | |
* @param {Object} object The object to search. | |
* @param {Function|Object|string} [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 baseFind(object, getIteratee(predicate, 3), baseForOwn, true); | |
} | |
/** | |
* This method is like `_.findKey` except that it iterates over elements of | |
* a collection in the opposite order. | |
* | |
* @static | |
* @memberOf _ | |
* @category Object | |
* @param {Object} object The object to search. | |
* @param {Function|Object|string} [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 baseFind(object, getIteratee(predicate, 3), baseForOwnRight, true); | |
} | |
/** | |
* Iterates over own and inherited enumerable properties of an object invoking | |
* `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 _ | |
* @category Object | |
* @param {Object} object The object to iterate over. | |
* @param {Function} [iteratee=_.identity] The function invoked per iteration. | |
* @returns {Object} Returns `object`. | |
* @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, toFunction(iteratee), keysIn); | |
} | |
/** | |
* This method is like `_.forIn` except that it iterates over properties of | |
* `object` in the opposite order. | |
* | |
* @static | |
* @memberOf _ | |
* @category Object | |
* @param {Object} object The object to iterate over. | |
* @param {Function} [iteratee=_.identity] The function invoked per iteration. | |
* @returns {Object} Returns `object`. | |
* @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, toFunction(iteratee), keysIn); | |
} | |
/** | |
* Iterates over own enumerable properties of an object invoking `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 _ | |
* @category Object | |
* @param {Object} object The object to iterate over. | |
* @param {Function} [iteratee=_.identity] The function invoked per iteration. | |
* @returns {Object} Returns `object`. | |
* @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, toFunction(iteratee)); | |
} | |
/** | |
* This method is like `_.forOwn` except that it iterates over properties of | |
* `object` in the opposite order. | |
* | |
* @static | |
* @memberOf _ | |
* @category Object | |
* @param {Object} object The object to iterate over. | |
* @param {Function} [iteratee=_.identity] The function invoked per iteration. | |
* @returns {Object} Returns `object`. | |
* @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, toFunction(iteratee)); | |
} | |
/** | |
* Creates an array of function property names from own enumerable properties | |
* of `object`. | |
* | |
* @static | |
* @memberOf _ | |
* @category Object | |
* @param {Object} object The object to inspect. | |
* @returns {Array} Returns the new array of property names. | |
* @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 _ | |
* @category Object | |
* @param {Object} object The object to inspect. | |
* @returns {Array} Returns the new array of property names. | |
* @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 used in its place. | |
* | |
* @static | |
* @memberOf _ | |
* @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 if the resolved value is `undefined`. | |
* @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 | |
* @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': { 'c': 3 } } }; | |
* var other = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) }); | |
* | |
* _.has(object, 'a'); | |
* // => true | |
* | |
* _.has(object, 'a.b.c'); | |
* // => true | |
* | |
* _.has(object, ['a', 'b', 'c']); | |
* // => true | |
* | |
* _.has(other, 'a'); | |
* // => false | |
*/ | |
function has(object, path) { | |
return hasPath(object, path, baseHas); | |
} | |
/** | |
* Checks if `path` is a direct or inherited property of `object`. | |
* | |
* @static | |
* @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 = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) }); | |
* | |
* _.hasIn(object, 'a'); | |
* // => true | |
* | |
* _.hasIn(object, 'a.b.c'); | |
* // => true | |
* | |
* _.hasIn(object, ['a', 'b', 'c']); | |
* // => true | |
* | |
* _.hasIn(object, 'b'); | |
* // => false | |
*/ | |
function hasIn(object, path) { | |
return 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 _ | |
* @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) { | |
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` through `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 _ | |
* @category Object | |
* @param {Object} object The object to invert. | |
* @param {Function|Object|string} [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 (hasOwnProperty.call(result, value)) { | |
result[value].push(key); | |
} else { | |
result[value] = [key]; | |
} | |
}, getIteratee); | |
/** | |
* Invokes the method at `path` of `object`. | |
* | |
* @static | |
* @memberOf _ | |
* @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 = rest(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/6.0/#sec-object.keys) | |
* for more details. | |
* | |
* @static | |
* @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) { | |
var isProto = isPrototype(object); | |
if (!(isProto || isArrayLike(object))) { | |
return baseKeys(object); | |
} | |
var indexes = indexKeys(object), | |
skipIndexes = !!indexes, | |
result = indexes || [], | |
length = result.length; | |
for (var key in object) { | |
if (baseHas(object, key) && | |
!(skipIndexes && (key == 'length' || isIndex(key, length))) && | |
!(isProto && key == 'constructor')) { | |
result.push(key); | |
} | |
} | |
return result; | |
} | |
/** | |
* Creates an array of the own and inherited enumerable property names of `object`. | |
* | |
* **Note:** Non-object values are coerced to objects. | |
* | |
* @static | |
* @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; | |
* | |
* _.keysIn(new Foo); | |
* // => ['a', 'b', 'c'] (iteration order is not guaranteed) | |
*/ | |
function keysIn(object) { | |
var index = -1, | |
isProto = isPrototype(object), | |
props = baseKeysIn(object), | |
propsLength = props.length, | |
indexes = indexKeys(object), | |
skipIndexes = !!indexes, | |
result = indexes || [], | |
length = result.length; | |
while (++index < propsLength) { | |
var key = props[index]; | |
if (!(skipIndexes && (key == 'length' || isIndex(key, length))) && | |
!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { | |
result.push(key); | |
} | |
} | |
return result; | |
} | |
/** | |
* The opposite of `_.mapValues`; this method creates an object with the | |
* same values as `object` and keys generated by running each own enumerable | |
* property of `object` through `iteratee`. | |
* | |
* @static | |
* @memberOf _ | |
* @category Object | |
* @param {Object} object The object to iterate over. | |
* @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration. | |
* @returns {Object} Returns the new mapped object. | |
* @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) { | |
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 property of `object` through `iteratee`. The | |
* iteratee function is invoked with three arguments: (value, key, object). | |
* | |
* @static | |
* @memberOf _ | |
* @category Object | |
* @param {Object} object The object to iterate over. | |
* @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration. | |
* @returns {Object} Returns the new mapped object. | |
* @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) { | |
result[key] = iteratee(value, key, object); | |
}); | |
return result; | |
} | |
/** | |
* Recursively merges own and inherited enumerable properties of source | |
* objects into the destination object, skipping source properties that resolve | |
* to `undefined`. 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 _ | |
* @category Object | |
* @param {Object} object The destination object. | |
* @param {...Object} [sources] The source objects. | |
* @returns {Object} Returns `object`. | |
* @example | |
* | |
* var users = { | |
* 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] | |
* }; | |
* | |
* var ages = { | |
* 'data': [{ 'age': 36 }, { 'age': 40 }] | |
* }; | |
* | |
* _.merge(users, ages); | |
* // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } | |
*/ | |
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 seven arguments: | |
* (objValue, srcValue, key, object, source, stack). | |
* | |
* **Note:** This method mutates `object`. | |
* | |
* @static | |
* @memberOf _ | |
* @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 = { | |
* 'fruits': ['apple'], | |
* 'vegetables': ['beet'] | |
* }; | |
* | |
* var other = { | |
* 'fruits': ['banana'], | |
* 'vegetables': ['carrot'] | |
* }; | |
* | |
* _.mergeWith(object, other, customizer); | |
* // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } | |
*/ | |
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 properties of `object` that are not omitted. | |
* | |
* @static | |
* @memberOf _ | |
* @category Object | |
* @param {Object} object The source object. | |
* @param {...(string|string[])} [props] The property names to omit, specified | |
* individually or in arrays.. | |
* @returns {Object} Returns the new object. | |
* @example | |
* | |
* var object = { 'a': 1, 'b': '2', 'c': 3 }; | |
* | |
* _.omit(object, ['a', 'c']); | |
* // => { 'b': '2' } | |
*/ | |
var omit = rest(function(object, props) { | |
if (object == null) { | |
return {}; | |
} | |
props = arrayMap(baseFlatten(props), String); | |
return basePick(object, baseDifference(keysIn(object), props)); | |
}); | |
/** | |
* The opposite of `_.pickBy`; this method creates an object composed of the | |
* own and inherited enumerable properties of `object` that `predicate` | |
* doesn't return truthy for. | |
* | |
* @static | |
* @memberOf _ | |
* @category Object | |
* @param {Object} object The source object. | |
* @param {Function|Object|string} [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) { | |
predicate = getIteratee(predicate, 2); | |
return basePickBy(object, function(value, key) { | |
return !predicate(value, key); | |
}); | |
} | |
/** | |
* Creates an object composed of the picked `object` properties. | |
* | |
* @static | |
* @memberOf _ | |
* @category Object | |
* @param {Object} object The source object. | |
* @param {...(string|string[])} [props] The property names to pick, specified | |
* individually or in arrays. | |
* @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 = rest(function(object, props) { | |
return object == null ? {} : basePick(object, baseFlatten(props)); | |
}); | |
/** | |
* Creates an object composed of the `object` properties `predicate` returns | |
* truthy for. The predicate is invoked with two arguments: (value, key). | |
* | |
* @static | |
* @memberOf _ | |
* @category Object | |
* @param {Object} object The source object. | |
* @param {Function|Object|string} [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) { | |
return object == null ? {} : basePickBy(object, getIteratee(predicate, 2)); | |
} | |
/** | |
* 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 | |
* @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 if the resolved value is `undefined`. | |
* @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) { | |
if (!isKey(path, object)) { | |
path = baseToPath(path); | |
var result = get(object, path); | |
object = parent(object, path); | |
} else { | |
result = object == null ? undefined : object[path]; | |
} | |
if (result === undefined) { | |
result = defaultValue; | |
} | |
return isFunction(result) ? result.call(object) : result; | |
} | |
/** | |
* 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 _ | |
* @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 _ | |
* @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 | |
* | |
* _.setWith({ '0': { 'length': 2 } }, '[0][1][2]', 3, Object); | |
* // => { '0': { '1': { '2': 3 }, 'length': 2 } } | |
*/ | |
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 key-value pairs for `object`. | |
* | |
* @static | |
* @memberOf _ | |
* @category Object | |
* @param {Object} object The object to query. | |
* @returns {Array} Returns the new array of 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) | |
*/ | |
function toPairs(object) { | |
return baseToPairs(object, keys(object)); | |
} | |
/** | |
* Creates an array of own and inherited enumerable key-value pairs for `object`. | |
* | |
* @static | |
* @memberOf _ | |
* @category Object | |
* @param {Object} object The object to query. | |
* @returns {Array} Returns the new array of key-value pairs. | |
* @example | |
* | |
* function Foo() { | |
* this.a = 1; | |
* this.b = 2; | |
* } | |
* | |
* Foo.prototype.c = 3; | |
* | |
* _.toPairsIn(new Foo); | |
* // => [['a', 1], ['b', 2], ['c', 1]] (iteration order is not guaranteed) | |
*/ | |
function toPairsIn(object) { | |
return baseToPairs(object, keysIn(object)); | |
} | |
/** | |
* An alternative to `_.reduce`; this method transforms `object` to a new | |
* `accumulator` object which is the result of running each of its own enumerable | |
* properties through `iteratee`, with each invocation potentially mutating | |
* the `accumulator` object. The iteratee is invoked with four arguments: | |
* (accumulator, value, key, object). Iteratee functions may exit iteration | |
* early by explicitly returning `false`. | |
* | |
* @static | |
* @memberOf _ | |
* @category Object | |
* @param {Array|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) || isTypedArray(object); | |
iteratee = getIteratee(iteratee, 4); | |
if (accumulator == null) { | |
if (isArr || isObject(object)) { | |
var Ctor = object.constructor; | |
if (isArr) { | |
accumulator = isArray(object) ? new Ctor : []; | |
} else { | |
accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined); | |
} | |
} else { | |
accumulator = {}; | |
} | |
} | |
(isArr ? 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 _ | |
* @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); | |
} | |
/** | |
* Creates an array of the own enumerable property values of `object`. | |
* | |
* **Note:** Non-object values are coerced to objects. | |
* | |
* @static | |
* @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 ? baseValues(object, keys(object)) : []; | |
} | |
/** | |
* Creates an array of the own and inherited enumerable property values of `object`. | |
* | |
* **Note:** Non-object values are coerced to objects. | |
* | |
* @static | |
* @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; | |
* | |
* _.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 _ | |
* @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 _ | |
* @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`. | |
* @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 = toNumber(start) || 0; | |
if (end === undefined) { | |
end = start; | |
start = 0; | |
} else { | |
end = toNumber(end) || 0; | |
} | |
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 _ | |
* @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 = toNumber(lower) || 0; | |
if (upper === undefined) { | |
upper = lower; | |
lower = 0; | |
} else { | |
upper = toNumber(upper) || 0; | |
} | |
} | |
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 _ | |
* @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 _ | |
* @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 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) | |
* to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). | |
* | |
* @static | |
* @memberOf _ | |
* @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(reLatin1, deburrLetter).replace(reComboMark, ''); | |
} | |
/** | |
* Checks if `string` ends with the given target string. | |
* | |
* @static | |
* @memberOf _ | |
* @category String | |
* @param {string} [string=''] The string to search. | |
* @param {string} [target] The string to search for. | |
* @param {number} [position=string.length] The position to search from. | |
* @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 = typeof target == 'string' ? target : (target + ''); | |
var length = string.length; | |
position = position === undefined | |
? length | |
: baseClamp(toInteger(position), 0, length); | |
position -= target.length; | |
return position >= 0 && string.indexOf(target, position) == position; | |
} | |
/** | |
* 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. | |
* | |
* Backticks are escaped because in IE < 9, they can break out of | |
* attribute values or HTML comments. See [#59](https://html5sec.org/#59), | |
* [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and | |
* [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/) | |
* for more details. | |
* | |
* When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping) | |
* to reduce XSS vectors. | |
* | |
* @static | |
* @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 _ | |
* @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 _ | |
* @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 _ | |
* @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 _ | |
* @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'); | |
/** | |
* Converts the first character of `string` to upper case. | |
* | |
* @static | |
* @memberOf _ | |
* @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'); | |
/** | |
* 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 _ | |
* @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 = stringSize(string); | |
if (!length || strLength >= length) { | |
return string; | |
} | |
var mid = (length - strLength) / 2, | |
leftLength = nativeFloor(mid), | |
rightLength = nativeCeil(mid); | |
return createPadding('', leftLength, chars) + string + createPadding('', rightLength, chars); | |
} | |
/** | |
* Pads `string` on the right side if it's shorter than `length`. Padding | |
* characters are truncated if they exceed `length`. | |
* | |
* @static | |
* @memberOf _ | |
* @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); | |
return string + createPadding(string, length, chars); | |
} | |
/** | |
* Pads `string` on the left side if it's shorter than `length`. Padding | |
* characters are truncated if they exceed `length`. | |
* | |
* @static | |
* @memberOf _ | |
* @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); | |
return createPadding(string, length, chars) + 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 _ | |
* @category String | |
* @param {string} string The string to convert. | |
* @param {number} [radix] The radix to interpret `value` by. | |
* @param- {Object} [guard] Enables use as an iteratee for functions 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) { | |
// Chrome fails to trim leading <BOM> whitespace characters. | |
// See https://code.google.com/p/v8/issues/detail?id=3109 for more details. | |
if (guard || radix == null) { | |
radix = 0; | |
} else if (radix) { | |
radix = +radix; | |
} | |
string = toString(string).replace(reTrim, ''); | |
return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10)); | |
} | |
/** | |
* Repeats the given string `n` times. | |
* | |
* @static | |
* @memberOf _ | |
* @category String | |
* @param {string} [string=''] The string to repeat. | |
* @param {number} [n=0] The number of times to repeat the string. | |
* @returns {string} Returns the repeated string. | |
* @example | |
* | |
* _.repeat('*', 3); | |
* // => '***' | |
* | |
* _.repeat('abc', 2); | |
* // => 'abcabc' | |
* | |
* _.repeat('abc', 0); | |
* // => '' | |
*/ | |
function repeat(string, n) { | |
string = toString(string); | |
n = toInteger(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); | |
string += string; | |
} while (n); | |
return result; | |
} | |
/** | |
* Replaces matches for `pattern` in `string` with `replacement`. | |
* | |
* **Note:** This method is based on [`String#replace`](https://mdn.io/String/replace). | |
* | |
* @static | |
* @memberOf _ | |
* @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 _ | |
* @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 _ | |
* @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 new array of string segments. | |
* @example | |
* | |
* _.split('a-b-c', '-', 2); | |
* // => ['a', 'b'] | |
*/ | |
function split(string, separator, limit) { | |
return toString(string).split(separator, limit); | |
} | |
/** | |
* Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). | |
* | |
* @static | |
* @memberOf _ | |
* @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 ? ' ' : '') + capitalize(word); | |
}); | |
/** | |
* Checks if `string` starts with the given target string. | |
* | |
* @static | |
* @memberOf _ | |
* @category String | |
* @param {string} [string=''] The string to search. | |
* @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 = baseClamp(toInteger(position), 0, string.length); | |
return string.lastIndexOf(target, position) == position; | |
} | |
/** | |
* 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 | |
* @memberOf _ | |
* @category String | |
* @param {string} [string=''] The template string. | |
* @param {Object} [options] The options object. | |
* @param {RegExp} [options.escape] The HTML "escape" delimiter. | |
* @param {RegExp} [options.evaluate] The "evaluate" delimiter. | |
* @param {Object} [options.imports] An object to import into the template as free variables. | |
* @param {RegExp} [options.interpolate] The "interpolate" delimiter. | |
* @param {string} [options.sourceURL] The sourceURL of the template's compiled source. | |
* @param {string} [options.variable] The data object variable name. | |
* @param- {Object} [guard] Enables use as an iteratee for functions 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 delimiter as an alternative to the default "interpolate" delimiter. | |
* var compiled = _.template('hello ${ user }!'); | |
* compiled({ 'user': 'pebbles' }); | |
* // => 'hello pebbles!' | |
* | |
* // Use custom template delimiters. | |
* _.templateSettings.interpolate = /{{([\s\S]+?)}}/g; | |
* var compiled = _.template('hello {{ user }}!'); | |
* compiled({ 'user': 'mustache' }); | |
* // => 'hello mustache!' | |
* | |
* // 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 the `source` property to inline compiled templates for meaningful | |
* // line numbers in error messages and stack traces. | |
* fs.writeFileSync(path.join(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, assignInDefaults); | |
var imports = assignInWith({}, options.imports, settings.imports, assignInDefaults), | |
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. | |
* | |
* @static | |
* @memberOf _ | |
* @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. | |
* | |
* @static | |
* @memberOf _ | |
* @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 _ | |
* @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 functions 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) { | |
return string; | |
} | |
if (guard || chars === undefined) { | |
return string.replace(reTrim, ''); | |
} | |
chars = (chars + ''); | |
if (!chars) { | |
return string; | |
} | |
var strSymbols = stringToArray(string), | |
chrSymbols = stringToArray(chars); | |
return strSymbols.slice(charsStartIndex(strSymbols, chrSymbols), charsEndIndex(strSymbols, chrSymbols) + 1).join(''); | |
} | |
/** | |
* Removes trailing whitespace or specified characters from `string`. | |
* | |
* @static | |
* @memberOf _ | |
* @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 functions 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) { | |
return string; | |
} | |
if (guard || chars === undefined) { | |
return string.replace(reTrimEnd, ''); | |
} | |
chars = (chars + ''); | |
if (!chars) { | |
return string; | |
} | |
var strSymbols = stringToArray(string); | |
return strSymbols.slice(0, charsEndIndex(strSymbols, stringToArray(chars)) + 1).join(''); | |
} | |
/** | |
* Removes leading whitespace or specified characters from `string`. | |
* | |
* @static | |
* @memberOf _ | |
* @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 functions 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) { | |
return string; | |
} | |
if (guard || chars === undefined) { | |
return string.replace(reTrimStart, ''); | |
} | |
chars = (chars + ''); | |
if (!chars) { | |
return string; | |
} | |
var strSymbols = stringToArray(string); | |
return strSymbols.slice(charsStartIndex(strSymbols, stringToArray(chars))).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 _ | |
* @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 ? toString(options.omission) : omission; | |
} | |
string = toString(string); | |
var strLength = string.length; | |
if (reHasComplexSymbol.test(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 | |
? strSymbols.slice(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(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 _ | |
* @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 _ | |
* @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(); | |
}); | |
/** | |
* Splits `string` into an array of its words. | |
* | |
* @static | |
* @memberOf _ | |
* @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 functions 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) { | |
pattern = reHasComplexWord.test(string) ? reComplexWord : reBasicWord; | |
} | |
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 _ | |
* @category Util | |
* @param {Function} func The function to attempt. | |
* @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 = rest(function(func, args) { | |
try { | |
return apply(func, undefined, args); | |
} catch (e) { | |
return isObject(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 | |
* @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, | |
* specified individually or in arrays. | |
* @returns {Object} Returns `object`. | |
* @example | |
* | |
* var view = { | |
* 'label': 'docs', | |
* 'onClick': function() { | |
* console.log('clicked ' + this.label); | |
* } | |
* }; | |
* | |
* _.bindAll(view, 'onClick'); | |
* jQuery(element).on('click', view.onClick); | |
* // => logs 'clicked docs' when clicked | |
*/ | |
var bindAll = rest(function(object, methodNames) { | |
arrayEach(baseFlatten(methodNames), function(key) { | |
object[key] = bind(object[key], object); | |
}); | |
return object; | |
}); | |
/** | |
* Creates a function that iterates over `pairs` invoking 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 _ | |
* @category Util | |
* @param {Array} pairs The predicate-function pairs. | |
* @returns {Function} Returns the new function. | |
* @example | |
* | |
* var func = _.cond([ | |
* [_.matches({ 'a': 1 }), _.constant('matches A')], | |
* [_.conforms({ 'b': _.isNumber }), _.constant('matches B')], | |
* [_.constant(true), _.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 ? pairs.length : 0, | |
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 rest(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`. | |
* | |
* @static | |
* @memberOf _ | |
* @category Util | |
* @param {Object} source The object of property predicates to conform to. | |
* @returns {Function} Returns the new function. | |
* @example | |
* | |
* var users = [ | |
* { 'user': 'barney', 'age': 36 }, | |
* { 'user': 'fred', 'age': 40 } | |
* ]; | |
* | |
* _.filter(users, _.conforms({ 'age': _.partial(_.gt, _, 38) })); | |
* // => [{ 'user': 'fred', 'age': 40 }] | |
*/ | |
function conforms(source) { | |
return baseConforms(baseClone(source, true)); | |
} | |
/** | |
* Creates a function that returns `value`. | |
* | |
* @static | |
* @memberOf _ | |
* @category Util | |
* @param {*} value The value to return from the new function. | |
* @returns {Function} Returns the new function. | |
* @example | |
* | |
* var object = { 'user': 'fred' }; | |
* var getter = _.constant(object); | |
* | |
* getter() === object; | |
* // => true | |
*/ | |
function constant(value) { | |
return function() { | |
return 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 _ | |
* @category Util | |
* @param {...(Function|Function[])} [funcs] Functions to invoke. | |
* @returns {Function} Returns the new function. | |
* @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 | |
* @memberOf _ | |
* @category Util | |
* @param {...(Function|Function[])} [funcs] Functions to invoke. | |
* @returns {Function} Returns the new function. | |
* @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 given to it. | |
* | |
* @static | |
* @memberOf _ | |
* @category Util | |
* @param {*} value Any value. | |
* @returns {*} Returns `value`. | |
* @example | |
* | |
* var object = { 'user': 'fred' }; | |
* | |
* _.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 callback returns the | |
* property value for a given element. If `func` is an object the created | |
* callback returns `true` for elements that contain the equivalent object properties, otherwise it returns `false`. | |
* | |
* @static | |
* @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 }, | |
* { 'user': 'fred', 'age': 40 } | |
* ]; | |
* | |
* // Create custom iteratee shorthands. | |
* _.iteratee = _.wrap(_.iteratee, function(callback, func) { | |
* var p = /^(\S+)\s*([<>])\s*(\S+)$/.exec(func); | |
* return !p ? callback(func) : function(object) { | |
* return (p[2] == '>' ? object[p[1]] > p[3] : object[p[1]] < p[3]); | |
* }; | |
* }); | |
* | |
* _.filter(users, 'age > 36'); | |
* // => [{ 'user': 'fred', 'age': 40 }] | |
*/ | |
function iteratee(func) { | |
return baseIteratee(typeof func == 'function' ? func : baseClone(func, true)); | |
} | |
/** | |
* Creates a function that performs a deep partial comparison between a given | |
* object and `source`, returning `true` if the given object has equivalent | |
* property values, else `false`. | |
* | |
* **Note:** This method supports comparing the same values as `_.isEqual`. | |
* | |
* @static | |
* @memberOf _ | |
* @category Util | |
* @param {Object} source The object of property values to match. | |
* @returns {Function} Returns the new function. | |
* @example | |
* | |
* var users = [ | |
* { 'user': 'barney', 'age': 36, 'active': true }, | |
* { 'user': 'fred', 'age': 40, 'active': false } | |
* ]; | |
* | |
* _.filter(users, _.matches({ 'age': 40, 'active': false })); | |
* // => [{ 'user': 'fred', 'age': 40, 'active': false }] | |
*/ | |
function matches(source) { | |
return baseMatches(baseClone(source, true)); | |
} | |
/** | |
* Creates a function that performs a deep partial comparison between the | |
* value at `path` of a given object to `srcValue`, returning `true` if the | |
* object value is equivalent, else `false`. | |
* | |
* **Note:** This method supports comparing the same values as `_.isEqual`. | |
* | |
* @static | |
* @memberOf _ | |
* @category Util | |
* @param {Array|string} path The path of the property to get. | |
* @param {*} srcValue The value to match. | |
* @returns {Function} Returns the new function. | |
* @example | |
* | |
* var users = [ | |
* { 'user': 'barney' }, | |
* { 'user': 'fred' } | |
* ]; | |
* | |
* _.find(users, _.matchesProperty('user', 'fred')); | |
* // => { 'user': 'fred' } | |
*/ | |
function matchesProperty(path, srcValue) { | |
return baseMatchesProperty(path, baseClone(srcValue, true)); | |
} | |
/** | |
* Creates a function that invokes the method at `path` of a given object. | |
* Any additional arguments are provided to the invoked method. | |
* | |
* @static | |
* @memberOf _ | |
* @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 function. | |
* @example | |
* | |
* var objects = [ | |
* { 'a': { 'b': { 'c': _.constant(2) } } }, | |
* { 'a': { 'b': { 'c': _.constant(1) } } } | |
* ]; | |
* | |
* _.map(objects, _.method('a.b.c')); | |
* // => [2, 1] | |
* | |
* _.invokeMap(_.sortBy(objects, _.method(['a', 'b', 'c'])), 'a.b.c'); | |
* // => [1, 2] | |
*/ | |
var method = rest(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 _ | |
* @category Util | |
* @param {Object} object The object to query. | |
* @param {...*} [args] The arguments to invoke the method with. | |
* @returns {Function} Returns the new 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 = rest(function(object, args) { | |
return function(path) { | |
return baseInvoke(object, path, args); | |
}; | |
}); | |
/** | |
* Adds all own enumerable 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 | |
* @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 the functions added | |
* 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 : true, | |
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 | |
* @memberOf _ | |
* @category Util | |
* @returns {Function} Returns the `lodash` function. | |
* @example | |
* | |
* var lodash = _.noConflict(); | |
*/ | |
function noConflict() { | |
if (root._ === this) { | |
root._ = oldDash; | |
} | |
return this; | |
} | |
/** | |
* A no-operation function that returns `undefined` regardless of the | |
* arguments it receives. | |
* | |
* @static | |
* @memberOf _ | |
* @category Util | |
* @example | |
* | |
* var object = { 'user': 'fred' }; | |
* | |
* _.noop(object) === undefined; | |
* // => true | |
*/ | |
function noop() { | |
// No operation performed. | |
} | |
/** | |
* Creates a function that returns its nth argument. | |
* | |
* @static | |
* @memberOf _ | |
* @category Util | |
* @param {number} [n=0] The index of the argument to return. | |
* @returns {Function} Returns the new function. | |
* @example | |
* | |
* var func = _.nthArg(1); | |
* | |
* func('a', 'b', 'c'); | |
* // => 'b' | |
*/ | |
function nthArg(n) { | |
n = toInteger(n); | |
return function() { | |
return arguments[n]; | |
}; | |
} | |
/** | |
* Creates a function that invokes `iteratees` with the arguments provided | |
* to the created function and returns their results. | |
* | |
* @static | |
* @memberOf _ | |
* @category Util | |
* @param {...(Function|Function[])} iteratees 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 provided to the created function. | |
* | |
* @static | |
* @memberOf _ | |
* @category Util | |
* @param {...(Function|Function[])} predicates 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 provided to the created function. | |
* | |
* @static | |
* @memberOf _ | |
* @category Util | |
* @param {...(Function|Function[])} predicates 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 _ | |
* @category Util | |
* @param {Array|string} path The path of the property to get. | |
* @returns {Function} Returns the new function. | |
* @example | |
* | |
* var objects = [ | |
* { 'a': { 'b': { 'c': 2 } } }, | |
* { 'a': { 'b': { 'c': 1 } } } | |
* ]; | |
* | |
* _.map(objects, _.property('a.b.c')); | |
* // => [2, 1] | |
* | |
* _.map(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c'); | |
* // => [1, 2] | |
*/ | |
function property(path) { | |
return isKey(path) ? baseProperty(path) : basePropertyDeep(path); | |
} | |
/** | |
* The opposite of `_.property`; this method creates a function that returns | |
* the value at a given path of `object`. | |
* | |
* @static | |
* @memberOf _ | |
* @category Util | |
* @param {Object} object The object to query. | |
* @returns {Function} Returns the new 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 | |
* @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 new array of numbers. | |
* @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 _ | |
* @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 new array of numbers. | |
* @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); | |
/** | |
* Invokes the iteratee function `n` times, returning an array of the results | |
* of each invocation. The iteratee is invoked with one argument; (index). | |
* | |
* @static | |
* @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(true)); | |
* // => [true, true, true, true] | |
*/ | |
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 = toFunction(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 _ | |
* @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'] | |
* | |
* var path = ['a', 'b', 'c'], | |
* newPath = _.toPath(path); | |
* | |
* console.log(newPath); | |
* // => ['a', 'b', 'c'] | |
* | |
* console.log(path === newPath); | |
* // => false | |
*/ | |
function toPath(value) { | |
return isArray(value) ? arrayMap(value, String) : stringToPath(value); | |
} | |
/** | |
* Generates a unique ID. If `prefix` is given the ID is appended to it. | |
* | |
* @static | |
* @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 _ | |
* @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 | |
*/ | |
function add(augend, addend) { | |
var result; | |
if (augend === undefined && addend === undefined) { | |
return 0; | |
} | |
if (augend !== undefined) { | |
result = augend; | |
} | |
if (addend !== undefined) { | |
result = result === undefined ? addend : (result + addend); | |
} | |
return result; | |
} | |
/** | |
* Computes `number` rounded up to `precision`. | |
* | |
* @static | |
* @memberOf _ | |
* @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'); | |
/** | |
* Computes `number` rounded down to `precision`. | |
* | |
* @static | |
* @memberOf _ | |
* @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 | |
* @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, gt) | |
: 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 _ | |
* @category Math | |
* @param {Array} array The array to iterate over. | |
* @param {Function|Object|string} [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), gt) | |
: undefined; | |
} | |
/** | |
* Computes the mean of the values in `array`. | |
* | |
* @static | |
* @memberOf _ | |
* @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 sum(array) / (array ? array.length : 0); | |
} | |
/** | |
* Computes the minimum value of `array`. If `array` is empty or falsey | |
* `undefined` is returned. | |
* | |
* @static | |
* @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, lt) | |
: 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 _ | |
* @category Math | |
* @param {Array} array The array to iterate over. | |
* @param {Function|Object|string} [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), lt) | |
: undefined; | |
} | |
/** | |
* Computes `number` rounded to `precision`. | |
* | |
* @static | |
* @memberOf _ | |
* @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 _ | |
* @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 | |
*/ | |
function subtract(minuend, subtrahend) { | |
var result; | |
if (minuend === undefined && subtrahend === undefined) { | |
return 0; | |
} | |
if (minuend !== undefined) { | |
result = minuend; | |
} | |
if (subtrahend !== undefined) { | |
result = result === undefined ? subtrahend : (result - subtrahend); | |
} | |
return result; | |
} | |
/** | |
* Computes the sum of the values in `array`. | |
* | |
* @static | |
* @memberOf _ | |
* @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 _ | |
* @category Math | |
* @param {Array} array The array to iterate over. | |
* @param {Function|Object|string} [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)) | |
: 0; | |
} | |
/*------------------------------------------------------------------------*/ | |
// Ensure wrappers are instances of `baseLodash`. | |
lodash.prototype = baseLodash.prototype; | |
LodashWrapper.prototype = baseCreate(baseLodash.prototype); | |
LodashWrapper.prototype.constructor = LodashWrapper; | |
LazyWrapper.prototype = baseCreate(baseLodash.prototype); | |
LazyWrapper.prototype.constructor = LazyWrapper; | |
// Avoid inheriting from `Object.prototype` when possible. | |
Hash.prototype = nativeCreate ? nativeCreate(null) : objectProto; | |
// Add functions to the `MapCache`. | |
MapCache.prototype.clear = mapClear; | |
MapCache.prototype['delete'] = mapDelete; | |
MapCache.prototype.get = mapGet; | |
MapCache.prototype.has = mapHas; | |
MapCache.prototype.set = mapSet; | |
// Add functions to the `SetCache`. | |
SetCache.prototype.push = cachePush; | |
// Add functions to the `Stack` cache. | |
Stack.prototype.clear = stackClear; | |
Stack.prototype['delete'] = stackDelete; | |
Stack.prototype.get = stackGet; | |
Stack.prototype.has = stackHas; | |
Stack.prototype.set = stackSet; | |
// Assign cache to `_.memoize`. | |
memoize.Cache = MapCache; | |
// Add functions that return wrapped values when chaining. | |
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.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.flatten = flatten; | |
lodash.flattenDeep = flattenDeep; | |
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.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.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.extend = assignIn; | |
lodash.extendWith = assignInWith; | |
// Add functions to `lodash.prototype`. | |
mixin(lodash, lodash); | |
/*------------------------------------------------------------------------*/ | |
// Add functions that return unwrapped values when chaining. | |
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.deburr = deburr; | |
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.min = min; | |
lodash.minBy = minBy; | |
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.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) { | |
var filtered = this.__filtered__; | |
if (filtered && !index) { | |
return new LazyWrapper(this); | |
} | |
n = n === undefined ? 1 : nativeMax(toInteger(n), 0); | |
var result = this.clone(); | |
if (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 = rest(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) { | |
predicate = getIteratee(predicate, 3); | |
return this.filter(function(value) { | |
return !predicate(value); | |
}); | |
}; | |
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` and `String` 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__) { | |
return func.apply(this.value(), args); | |
} | |
return this[chainName](function(value) { | |
return func.apply(value, args); | |
}); | |
}; | |
}); | |
// Map minified function 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[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{ 'name': 'wrapper', 'func': undefined }]; | |
// Add functions to the lazy wrapper. | |
LazyWrapper.prototype.clone = lazyClone; | |
LazyWrapper.prototype.reverse = lazyReverse; | |
LazyWrapper.prototype.value = lazyValue; | |
// Add chaining functions to the `lodash` wrapper. | |
lodash.prototype.at = wrapperAt; | |
lodash.prototype.chain = wrapperChain; | |
lodash.prototype.commit = wrapperCommit; | |
lodash.prototype.flatMap = wrapperFlatMap; | |
lodash.prototype.next = wrapperNext; | |
lodash.prototype.plant = wrapperPlant; | |
lodash.prototype.reverse = wrapperReverse; | |
lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue; | |
if (iteratorSymbol) { | |
lodash.prototype[iteratorSymbol] = wrapperToIterator; | |
} | |
return lodash; | |
} | |
/*--------------------------------------------------------------------------*/ | |
// Export lodash. | |
var _ = runInContext(); | |
// Expose lodash on the free variable `window` or `self` when available. This | |
// prevents errors in cases where 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. | |
(freeWindow || freeSelf || {})._ = _; | |
// Some AMD build optimizers like r.js check for condition patterns like the following: | |
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { | |
// Define as an anonymous module so, through path mapping, it can be | |
// referenced as the "underscore" module. | |
define(function() { | |
return _; | |
}); | |
} | |
// Check for `exports` after `define` in case a build optimizer adds an `exports` object. | |
else if (freeExports && freeModule) { | |
// Export for Node.js. | |
if (moduleExports) { | |
(freeModule.exports = _)._ = _; | |
} | |
// Export for CommonJS support. | |
freeExports._ = _; | |
} | |
else { | |
// Export to the global object. | |
root._ = _; | |
} | |
}.call(this)); | |
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) | |
},{}],7:[function(require,module,exports){ | |
/** | |
* VexFlow 1.2.41 built on 2016-02-10. | |
* Copyright (c) 2010 Mohit Muthanna Cheppudira <mohit@muthanna.com> | |
* | |
* http://www.vexflow.com http://github.com/0xfe/vexflow | |
*/ | |
// [VexFlow](http://vexflow.com) - Copyright (c) Mohit Muthanna 2010. | |
// | |
// ## Description | |
// | |
// This file implements utility methods used by the rest of the VexFlow | |
// codebase. | |
// | |
// ## JSHint Settings | |
// | |
/* global window: false */ | |
/* global document: false */ | |
if (typeof Vex === 'undefined') { | |
/* global Vex: true */ | |
Vex = function() {}; | |
} | |
// Default log function sends all arguments to console. | |
Vex.L = function(block, args) { | |
if (!args) return; | |
var line = Array.prototype.slice.call(args).join(" "); | |
window.console.log(block + ": " + line); | |
}; | |
// Default runtime exception. | |
Vex.RuntimeError = function(code, message) { | |
this.code = code; | |
this.message = message; | |
}; | |
Vex.RuntimeError.prototype.toString = function() { | |
return "RuntimeError: " + this.message; | |
}; | |
// Shortcut method for `RuntimeError`. | |
Vex.RERR = Vex.RuntimeError; | |
// Merge `destination` hash with `source` hash, overwriting like keys | |
// in `source` if necessary. | |
Vex.Merge = function(destination, source) { | |
for (var property in source) | |
destination[property] = source[property]; | |
return destination; | |
}; | |
// DEPRECATED. Use `Math.*`. | |
Vex.Min = Math.min; | |
Vex.Max = Math.max; | |
Vex.forEach = function(a, fn) { | |
for (var i=0; i<a.length; i++) { | |
fn(a[i],i); | |
} | |
}; | |
// Round number to nearest fractional value (`.5`, `.25`, etc.) | |
Vex.RoundN = function(x, n) { | |
return (x % n) >= (n/2) ? | |
parseInt(x / n, 10) * n + n : parseInt(x / n, 10) * n; | |
}; | |
// Locate the mid point between stave lines. Returns a fractional line if a space. | |
Vex.MidLine = function(a, b) { | |
var mid_line = b + (a - b) / 2; | |
if (mid_line % 2 > 0) { | |
mid_line = Vex.RoundN(mid_line * 10, 5) / 10; | |
} | |
return mid_line; | |
}; | |
// Take `arr` and return a new list consisting of the sorted, unique, | |
// contents of arr. Does not modify `arr`. | |
Vex.SortAndUnique = function(arr, cmp, eq) { | |
if (arr.length > 1) { | |
var newArr = []; | |
var last; | |
arr.sort(cmp); | |
for (var i = 0; i < arr.length; ++i) { | |
if (i === 0 || !eq(arr[i], last)) { | |
newArr.push(arr[i]); | |
} | |
last = arr[i]; | |
} | |
return newArr; | |
} else { | |
return arr; | |
} | |
}; | |
// Check if array `a` contains `obj`. | |
Vex.Contains = function(a, obj) { | |
var i = a.length; | |
while (i--) { | |
if (a[i] === obj) { | |
return true; | |
} | |
} | |
return false; | |
}; | |
// Get the 2D Canvas context from DOM element `canvas_sel`. | |
Vex.getCanvasContext = function(canvas_sel) { | |
if (!canvas_sel) | |
throw new Vex.RERR("BadArgument", "Invalid canvas selector: " + canvas_sel); | |
var canvas = document.getElementById(canvas_sel); | |
if (!(canvas && canvas.getContext)) { | |
throw new Vex.RERR("UnsupportedBrowserError", | |
"This browser does not support HTML5 Canvas"); | |
} | |
return canvas.getContext('2d'); | |
}; | |
// Draw a tiny dot marker on the specified canvas. A great debugging aid. | |
// | |
// `ctx`: Canvas context. | |
// `x`, `y`: Dot coordinates. | |
Vex.drawDot = function(ctx, x, y, color) { | |
var c = color || "#f55"; | |
ctx.save(); | |
ctx.setFillStyle(c); | |
//draw a circle | |
ctx.beginPath(); | |
ctx.arc(x, y, 3, 0, Math.PI*2, true); | |
ctx.closePath(); | |
ctx.fill(); | |
ctx.restore(); | |
}; | |
// Benchmark. Run function `f` once and report time elapsed shifted by `s` milliseconds. | |
Vex.BM = function(s, f) { | |
var start_time = new Date().getTime(); | |
f(); | |
var elapsed = new Date().getTime() - start_time; | |
Vex.L(s + elapsed + "ms"); | |
}; | |
// Basic classical inheritance helper. Usage: | |
// ``` | |
// // Vex.Inherit(Child, Parent, { | |
// // getName: function() {return this.name;}, | |
// // setName: function(name) {this.name = name} | |
// // }); | |
// // | |
// // Returns 'Child'. | |
// ``` | |
Vex.Inherit = (function () { | |
var F = function () {}; | |
// `C` is Child. `P` is parent. `O` is an object to | |
// to extend `C` with. | |
return function (C, P, O) { | |
F.prototype = P.prototype; | |
C.prototype = new F(); | |
C.superclass = P.prototype; | |
C.prototype.constructor = C; | |
Vex.Merge(C.prototype, O); | |
return C; | |
}; | |
}()); | |
// Get stack trace. | |
Vex.StackTrace = function() { | |
var err = new Error(); | |
return err.stack; | |
}; | |
// Dump warning to console. | |
Vex.W = function() { | |
var line = Array.prototype.slice.call(arguments).join(" "); | |
window.console.log("Warning: ", line, Vex.StackTrace()); | |
}; | |
// Used by various classes (e.g., SVGContext) to provide a | |
// unique prefix to element names (or other keys in shared namespaces). | |
Vex.Prefix = function(text) { | |
return Vex.Prefix.prefix + text; | |
}; | |
Vex.Prefix.prefix = "vf-"; | |
// UMD to export Vex. | |
// | |
/* global require: false */ | |
/* global define: false */ | |
/* global module: false */ | |
if (typeof require == "function") { | |
try { | |
module.exports = Vex; | |
} catch (e) {} | |
} else if (typeof define == "function" && define.amd) { | |
define("Vex", [], function(){ return Vex; }); | |
} else { | |
(this || window)["Vex"] = Vex; | |
} | |
/** | |
* Vex Flow - Mohit Muthanna <mohit@muthanna.com> | |
*/ | |
/** | |
* New namespace. | |
*/ | |
if (typeof Vex.Flow === 'undefined') { | |
Vex.Flow = { | |
/** | |
* The resolution used for all the rhythm timing in this | |
* library. | |
* | |
* @const | |
* @type {number} | |
*/ | |
RESOLUTION: 16384, | |
/* Kerning (DEPRECATED) */ | |
IsKerned: true | |
}; | |
} | |
// Fraction class that represents a rational number | |
// @author zz85 | |
// @author incompleteopus (modifications) | |
Vex.Flow.Fraction = (function() { | |
function Fraction(numerator, denominator) { | |
this.set(numerator, denominator); | |
} | |
/** | |
* GCD: Find greatest common divisor using Euclidean algorithm | |
*/ | |
Fraction.GCD = function(a, b) { | |
if (typeof a !== "number" || typeof b !== "number") { | |
throw new Vex.RERR("BadArgument", "Invalid numbers: " + a + ", " + b); | |
} | |
var t; | |
while (b !== 0) { | |
t = b; | |
b = a % b; | |
a = t; | |
} | |
return a; | |
}; | |
/** | |
* LCM: Lowest common multiple | |
*/ | |
Fraction.LCM = function(a, b) { | |
return ((a * b) / Fraction.GCD(a, b)); | |
}; | |
/** | |
* LCMM: Lowest common multiple for more than two numbers | |
*/ | |
Fraction.LCMM = function(args) { | |
if (args.length === 0) { | |
return 0; | |
} else if (args.length == 1) { | |
return args[0]; | |
} else if (args.length == 2) { | |
return Vex.Flow.Fraction.LCM(args[0], args[1]); | |
} else { | |
var arg0 = args[0]; | |
args.shift(); | |
return Fraction.LCM(arg0, Vex.Flow.Fraction.LCMM(args)); | |
} | |
}; | |
Fraction.prototype = { | |
set: function(numerator, denominator) { | |
this.numerator = numerator === undefined ? 1 : numerator; | |
this.denominator = denominator === undefined ? 1 : denominator; | |
return this; | |
}, | |
value: function() { | |
return this.numerator / this.denominator; | |
}, | |
simplify: function() { | |
var u = this.numerator; | |
var d = this.denominator; | |
var gcd = Vex.Flow.Fraction.GCD(u, d); | |
u /= gcd; | |
d /= gcd; | |
if (d < 0) { | |
d = -d; | |
u = -u; | |
} | |
return this.set(u, d); | |
}, | |
add: function(param1, param2) { | |
var otherNumerator; | |
var otherDenominator; | |
if (param1 instanceof Vex.Flow.Fraction) { | |
otherNumerator = param1.numerator; | |
otherDenominator = param1.denominator; | |
} else { | |
if (param1 !== undefined) { | |
otherNumerator = param1; | |
} else { | |
otherNumerator = 0; | |
} | |
if (param2 !== undefined) { | |
otherDenominator = param2; | |
} else { | |
otherDenominator = 1; | |
} | |
} | |
var lcm = Vex.Flow.Fraction.LCM(this.denominator, otherDenominator); | |
var a = lcm / this.denominator; | |
var b = lcm / otherDenominator; | |
var u = this.numerator * a + otherNumerator * b; | |
return this.set(u, lcm); | |
}, | |
subtract: function(param1, param2) { | |
var otherNumerator; | |
var otherDenominator; | |
if (param1 instanceof Vex.Flow.Fraction) { | |
otherNumerator = param1.numerator; | |
otherDenominator = param1.denominator; | |
} else { | |
if (param1 !== undefined) { | |
otherNumerator = param1; | |
} else { | |
otherNumerator = 0; | |
} | |
if (param2 !== undefined) { | |
otherDenominator = param2; | |
} else { | |
otherDenominator = 1; | |
} | |
} | |
var lcm = Vex.Flow.Fraction.LCM(this.denominator, otherDenominator); | |
var a = lcm / this.denominator; | |
var b = lcm / otherDenominator; | |
var u = this.numerator * a - otherNumerator * b; | |
return this.set(u, lcm); | |
}, | |
multiply: function(param1, param2) { | |
var otherNumerator; | |
var otherDenominator; | |
if (param1 instanceof Vex.Flow.Fraction) { | |
otherNumerator = param1.numerator; | |
otherDenominator = param1.denominator; | |
} else { | |
if (param1 !== undefined) { | |
otherNumerator = param1; | |
} else { | |
otherNumerator = 1; | |
} | |
if (param2 !== undefined) { | |
otherDenominator = param2; | |
} else { | |
otherDenominator = 1; | |
} | |
} | |
return this.set(this.numerator * otherNumerator, this.denominator * otherDenominator); | |
}, | |
divide: function(param1, param2) { | |
var otherNumerator; | |
var otherDenominator; | |
if (param1 instanceof Vex.Flow.Fraction) { | |
otherNumerator = param1.numerator; | |
otherDenominator = param1.denominator; | |
} else { | |
if (param1 !== undefined) { | |
otherNumerator = param1; | |
} else { | |
otherNumerator = 1; | |
} | |
if (param2 !== undefined) { | |
otherDenominator = param2; | |
} else { | |
otherDenominator = 1; | |
} | |
} | |
return this.set(this.numerator * otherDenominator, this.denominator * otherNumerator); | |
}, | |
// Simplifies both sides and checks if they are equal. | |
equals: function(compare) { | |
var a = Vex.Flow.Fraction.__compareA.copy(compare).simplify(); | |
var b = Vex.Flow.Fraction.__compareB.copy(this).simplify(); | |
return (a.numerator === b.numerator) && (a.denominator === b.denominator); | |
}, | |
// Greater than operator. | |
greaterThan: function(compare) { | |
var a = Vex.Flow.Fraction.__compareB.copy(this); | |
a.subtract(compare); | |
return (a.numerator > 0); | |
}, | |
// Greater than or equals operator. | |
greaterThanEquals: function(compare) { | |
var a = Vex.Flow.Fraction.__compareB.copy(this); | |
a.subtract(compare); | |
return (a.numerator >= 0); | |
}, | |
// Less than operator. | |
lessThan: function(compare) { | |
return !(this.greaterThanEquals(compare)); | |
}, | |
// Less than or equals operator. | |
lessThanEquals: function(compare) { | |
return !(this.greaterThan(compare)); | |
}, | |
// Creates a new copy with this current values. | |
clone: function() { | |
return new Vex.Flow.Fraction(this.numerator, this.denominator); | |
}, | |
// Copies value of another Fraction into itself. | |
copy: function(copy) { | |
return this.set(copy.numerator, copy.denominator); | |
}, | |
// Returns the integer component eg. (4/2) == 2 | |
quotient: function() { | |
return Math.floor(this.numerator / this.denominator); | |
}, | |
// Returns the fraction component when reduced to a mixed number | |
fraction: function() { | |
return this.numerator % this.denominator; | |
}, | |
// Returns the absolute value | |
abs: function() { | |
this.denominator = Math.abs(this.denominator); | |
this.numerator = Math.abs(this.numerator); | |
return this; | |
}, | |
// Returns a raw string representation | |
toString: function() { | |
return this.numerator + '/' + this.denominator; | |
}, | |
// Returns a simplified string respresentation | |
toSimplifiedString: function() { | |
return Vex.Flow.Fraction.__tmp.copy(this).simplify().toString(); | |
}, | |
// Returns string representation in mixed form | |
toMixedString: function() { | |
var s = ''; | |
var q = this.quotient(); | |
var f = Vex.Flow.Fraction.__tmp.copy(this); | |
if (q < 0) { | |
f.abs().fraction(); | |
} else { | |
f.fraction(); | |
} | |
if (q !== 0) { | |
s += q; | |
if (f.numerator !== 0) { | |
s += ' ' + f.toSimplifiedString(); | |
} | |
} else { | |
if (f.numerator === 0) { | |
s = '0'; | |
} else { | |
s = f.toSimplifiedString(); | |
} | |
} | |
return s; | |
}, | |
// Parses a fraction string | |
parse: function(str) { | |
var i = str.split('/'); | |
var n = parseInt(i[0], 10); | |
var d = (i[1]) ? parseInt(i[1], 10) : 1; | |
return this.set(n, d); | |
} | |
}; | |
// Temporary cached objects | |
Fraction.__compareA = new Fraction(); | |
Fraction.__compareB = new Fraction(); | |
Fraction.__tmp = new Fraction(); | |
return Fraction; | |
}()); | |
// Vex Flow Notation | |
// Mohit Muthanna <mohit@muthanna.com> | |
// | |
// Copyright Mohit Muthanna 2010 | |
// | |
// Requires vex.js. | |
Vex.Flow.STEM_WIDTH = 1.5; | |
Vex.Flow.STEM_HEIGHT = 32; | |
Vex.Flow.STAVE_LINE_THICKNESS = 2; | |
Vex.Flow.clefProperties = function(clef) { | |
if (!clef) throw new Vex.RERR("BadArgument", "Invalid clef: " + clef); | |
var props = Vex.Flow.clefProperties.values[clef]; | |
if (!props) throw new Vex.RERR("BadArgument", "Invalid clef: " + clef); | |
return props; | |
}; | |
Vex.Flow.clefProperties.values = { | |
'treble': { line_shift: 0 }, | |
'bass': { line_shift: 6 }, | |
'tenor': { line_shift: 4 }, | |
'alto': { line_shift: 3 }, | |
'soprano': { line_shift: 1 }, | |
'percussion': { line_shift: 0 }, | |
'mezzo-soprano': { line_shift: 2 }, | |
'baritone-c': { line_shift: 5 }, | |
'baritone-f': { line_shift: 5 }, | |
'subbass': { line_shift: 7 }, | |
'french': { line_shift: -1 } | |
}; | |
/* | |
Take a note in the format "Key/Octave" (e.g., "C/5") and return properties. | |
The last argument, params, is a struct the currently can contain one option, | |
octave_shift for clef ottavation (0 = default; 1 = 8va; -1 = 8vb, etc.). | |
*/ | |
Vex.Flow.keyProperties = function(key, clef, params) { | |
if (clef === undefined) { | |
clef = 'treble'; | |
} | |
var options = { | |
octave_shift: 0 | |
}; | |
if (typeof params == "object") { | |
Vex.Merge(options, params); | |
} | |
var pieces = key.split("/"); | |
if (pieces.length < 2) { | |
throw new Vex.RERR("BadArguments", | |
"Key must have note + octave and an optional glyph: " + key); | |
} | |
var k = pieces[0].toUpperCase(); | |
var value = Vex.Flow.keyProperties.note_values[k]; | |
if (!value) throw new Vex.RERR("BadArguments", "Invalid key name: " + k); | |
if (value.octave) pieces[1] = value.octave; | |
var o = parseInt(pieces[1]); | |
// Octave_shift is the shift to compensate for clef 8va/8vb. | |
o += -1 * options.octave_shift; | |
var base_index = (o * 7) - (4 * 7); | |
var line = (base_index + value.index) / 2; | |
line += Vex.Flow.clefProperties(clef).line_shift; | |
var stroke = 0; | |
if (line <= 0 && (((line * 2) % 2) === 0)) stroke = 1; // stroke up | |
if (line >= 6 && (((line * 2) % 2) === 0)) stroke = -1; // stroke down | |
// Integer value for note arithmetic. | |
var int_value = (typeof(value.int_val)!='undefined') ? (o * 12) + | |
value.int_val : null; | |
/* Check if the user specified a glyph. */ | |
var code = value.code; | |
var shift_right = value.shift_right; | |
if ((pieces.length > 2) && (pieces[2])) { | |
var glyph_name = pieces[2].toUpperCase(); | |
var note_glyph = Vex.Flow.keyProperties.note_glyph[glyph_name]; | |
if (note_glyph) { | |
code = note_glyph.code; | |
shift_right = note_glyph.shift_right; | |
} | |
} | |
return { | |
key: k, | |
octave: o, | |
line: line, | |
int_value: int_value, | |
accidental: value.accidental, | |
code: code, | |
stroke: stroke, | |
shift_right: shift_right, | |
displaced: false | |
}; | |
}; | |
Vex.Flow.keyProperties.note_values = { | |
'C': { index: 0, int_val: 0, accidental: null }, | |
'CN': { index: 0, int_val: 0, accidental: "n" }, | |
'C#': { index: 0, int_val: 1, accidental: "#" }, | |
'C##': { index: 0, int_val: 2, accidental: "##" }, | |
'CB': { index: 0, int_val: -1, accidental: "b" }, | |
'CBB': { index: 0, int_val: -2, accidental: "bb" }, | |
'D': { index: 1, int_val: 2, accidental: null }, | |
'DN': { index: 1, int_val: 2, accidental: "n" }, | |
'D#': { index: 1, int_val: 3, accidental: "#" }, | |
'D##': { index: 1, int_val: 4, accidental: "##" }, | |
'DB': { index: 1, int_val: 1, accidental: "b" }, | |
'DBB': { index: 1, int_val: 0, accidental: "bb" }, | |
'E': { index: 2, int_val: 4, accidental: null }, | |
'EN': { index: 2, int_val: 4, accidental: "n" }, | |
'E#': { index: 2, int_val: 5, accidental: "#" }, | |
'E##': { index: 2, int_val: 6, accidental: "##" }, | |
'EB': { index: 2, int_val: 3, accidental: "b" }, | |
'EBB': { index: 2, int_val: 2, accidental: "bb" }, | |
'F': { index: 3, int_val: 5, accidental: null }, | |
'FN': { index: 3, int_val: 5, accidental: "n" }, | |
'F#': { index: 3, int_val: 6, accidental: "#" }, | |
'F##': { index: 3, int_val: 7, accidental: "##" }, | |
'FB': { index: 3, int_val: 4, accidental: "b" }, | |
'FBB': { index: 3, int_val: 3, accidental: "bb" }, | |
'G': { index: 4, int_val: 7, accidental: null }, | |
'GN': { index: 4, int_val: 7, accidental: "n" }, | |
'G#': { index: 4, int_val: 8, accidental: "#" }, | |
'G##': { index: 4, int_val: 9, accidental: "##" }, | |
'GB': { index: 4, int_val: 6, accidental: "b" }, | |
'GBB': { index: 4, int_val: 5, accidental: "bb" }, | |
'A': { index: 5, int_val: 9, accidental: null }, | |
'AN': { index: 5, int_val: 9, accidental: "n" }, | |
'A#': { index: 5, int_val: 10, accidental: "#" }, | |
'A##': { index: 5, int_val: 11, accidental: "##" }, | |
'AB': { index: 5, int_val: 8, accidental: "b" }, | |
'ABB': { index: 5, int_val: 7, accidental: "bb" }, | |
'B': { index: 6, int_val: 11, accidental: null }, | |
'BN': { index: 6, int_val: 11, accidental: "n" }, | |
'B#': { index: 6, int_val: 12, accidental: "#" }, | |
'B##': { index: 6, int_val: 13, accidental: "##" }, | |
'BB': { index: 6, int_val: 10, accidental: "b" }, | |
'BBB': { index: 6, int_val: 9, accidental: "bb" }, | |
'R': { index: 6, int_val: 9, rest: true }, // Rest | |
'X': { | |
index: 6, | |
accidental: "", | |
octave: 4, | |
code: "v3e", | |
shift_right: 5.5 | |
} | |
}; | |
Vex.Flow.keyProperties.note_glyph = { | |
/* Diamond */ | |
'D0': { code: "v27", shift_right: -0.5 }, | |
'D1': { code: "v2d", shift_right: -0.5 }, | |
'D2': { code: "v22", shift_right: -0.5 }, | |
'D3': { code: "v70", shift_right: -0.5 }, | |
/* Triangle */ | |
'T0': { code: "v49", shift_right: -2 }, | |
'T1': { code: "v93", shift_right: 0.5 }, | |
'T2': { code: "v40", shift_right: 0.5 }, | |
'T3': { code: "v7d", shift_right: 0.5 }, | |
/* Cross */ | |
'X0': { code: "v92", shift_right: -2 }, | |
'X1': { code: "v95", shift_right: -0.5 }, | |
'X2': { code: "v7f", shift_right: 0.5 }, | |
'X3': { code: "v3b", shift_right: -2 } | |
}; | |
Vex.Flow.integerToNote = function(integer) { | |
if (typeof(integer) == "undefined") | |
throw new Vex.RERR("BadArguments", "Undefined integer for integerToNote"); | |
if (integer < -2) | |
throw new Vex.RERR("BadArguments", | |
"integerToNote requires integer > -2: " + integer); | |
var noteValue = Vex.Flow.integerToNote.table[integer]; | |
if (!noteValue) | |
throw new Vex.RERR("BadArguments", "Unknown note value for integer: " + | |
integer); | |
return noteValue; | |
}; | |
Vex.Flow.integerToNote.table = { | |
0: "C", | |
1: "C#", | |
2: "D", | |
3: "D#", | |
4: "E", | |
5: "F", | |
6: "F#", | |
7: "G", | |
8: "G#", | |
9: "A", | |
10: "A#", | |
11: "B" | |
}; | |
Vex.Flow.tabToGlyph = function(fret) { | |
var glyph = null; | |
var width = 0; | |
var shift_y = 0; | |
if (fret.toString().toUpperCase() == "X") { | |
glyph = "v7f"; | |
width = 7; | |
shift_y = -4.5; | |
} else { | |
width = Vex.Flow.textWidth(fret.toString()); | |
} | |
return { | |
text: fret, | |
code: glyph, | |
width: width, | |
shift_y: shift_y | |
}; | |
}; | |
Vex.Flow.textWidth = function(text) { | |
return 6 * text.toString().length; | |
}; | |
Vex.Flow.articulationCodes = function(artic) { | |
return Vex.Flow.articulationCodes.articulations[artic]; | |
}; | |
Vex.Flow.articulationCodes.articulations = { | |
"a.": { // Staccato | |
code: "v23", | |
width: 4, | |
shift_right: -2, | |
shift_up: 8, | |
shift_down: 0, | |
between_lines: true | |
}, | |
"av": { // Staccatissimo | |
code: "v28", | |
width: 4, | |
shift_right: 0, | |
shift_up: 11, | |
shift_down: 5, | |
between_lines: true | |
}, | |
"a>": { // Accent | |
code: "v42", | |
width: 10, | |
shift_right: 5, | |
shift_up: 8, | |
shift_down: 1, | |
between_lines: true | |
}, | |
"a-": { // Tenuto | |
code: "v25", | |
width: 9, | |
shift_right: -4, | |
shift_up: 17, | |
shift_down: 10, | |
between_lines: true | |
}, | |
"a^": { // Marcato | |
code: "va", | |
width: 8, | |
shift_right: 0, | |
shift_up: -4, | |
shift_down: -2, | |
between_lines: false | |
}, | |
"a+": { // Left hand pizzicato | |
code: "v8b", | |
width: 9, | |
shift_right: -4, | |
shift_up: 12, | |
shift_down: 12, | |
between_lines: false | |
}, | |
"ao": { // Snap pizzicato | |
code: "v94", | |
width: 8, | |
shift_right: 0, | |
shift_up: -4, | |
shift_down: 6, | |
between_lines: false | |
}, | |
"ah": { // Natural harmonic or open note | |
code: "vb9", | |
width: 7, | |
shift_right: 0, | |
shift_up: -4, | |
shift_down: 4, | |
between_lines: false | |
}, | |
"a@a": { // Fermata above staff | |
code: "v43", | |
width: 25, | |
shift_right: 0, | |
shift_up: 8, | |
shift_down: 10, | |
between_lines: false | |
}, | |
"a@u": { // Fermata below staff | |
code: "v5b", | |
width: 25, | |
shift_right: 0, | |
shift_up: 0, | |
shift_down: -4, | |
between_lines: false | |
}, | |
"a|": { // Bow up - up stroke | |
code: "v75", | |
width: 8, | |
shift_right: 0, | |
shift_up: 8, | |
shift_down: 10, | |
between_lines: false | |
}, | |
"am": { // Bow down - down stroke | |
code: "v97", | |
width: 13, | |
shift_right: 0, | |
shift_up: 10, | |
shift_down: 12, | |
between_lines: false | |
}, | |
"a,": { // Choked | |
code: "vb3", | |
width: 6, | |
shift_right: 8, | |
shift_up: -4, | |
shift_down: 4, | |
between_lines: false | |
} | |
}; | |
Vex.Flow.accidentalCodes = function(acc) { | |
return Vex.Flow.accidentalCodes.accidentals[acc]; | |
}; | |
Vex.Flow.accidentalCodes.accidentals = { | |
"#": { | |
code: "v18", | |
width: 10, | |
gracenote_width: 4.5, | |
shift_right: 0, | |
shift_down: 0 | |
}, | |
"##": { | |
code: "v7f", | |
width: 13, | |
gracenote_width: 6, | |
shift_right: -1, | |
shift_down: 0 | |
}, | |
"b": { | |
code: "v44", | |
width: 8, | |
gracenote_width: 4.5, | |
shift_right: 0, | |
shift_down: 0 | |
}, | |
"bb": { | |
code: "v26", | |
width: 14, | |
gracenote_width: 8, | |
shift_right: -3, | |
shift_down: 0 | |
}, | |
"n": { | |
code: "v4e", | |
width: 8, | |
gracenote_width: 4.5, | |
shift_right: 0, | |
shift_down: 0 | |
}, | |
"{": { // Left paren for cautionary accidentals | |
code: "v9c", | |
width: 5, | |
shift_right: 2, | |
shift_down: 0 | |
}, | |
"}": { // Right paren for cautionary accidentals | |
code: "v84", | |
width: 5, | |
shift_right: 0, | |
shift_down: 0 | |
}, | |
"db": { | |
code: "v9e", | |
width: 16, | |
shift_right: 0, | |
shift_down: 0 | |
}, | |
"d": { | |
code: "vab", | |
width: 10, | |
shift_right: 0, | |
shift_down: 0 | |
}, | |
"bbs": { | |
code: "v90", | |
width: 13, | |
shift_right: 0, | |
shift_down: 0 | |
}, | |
"++": { | |
code: "v51", | |
width: 13, | |
shift_right: 0, | |
shift_down: 0 | |
}, | |
"+": { | |
code: "v78", | |
width: 8, | |
shift_right: 0, | |
shift_down: 0 | |
} | |
}; | |
Vex.Flow.accidentalColumnsTable = { | |
1 : { a : [1], b : [1]}, | |
2 : { a : [1, 2] }, | |
3 : { a : [1, 3, 2], b : [1, 2, 1], second_on_bottom : [1, 2, 3] }, | |
4 : { a : [1, 3, 4, 2], b : [1, 2, 3, 1], spaced_out_tetrachord : [1, 2, 1, 2] }, | |
5 : { a : [1, 3, 5, 4, 2], b : [1, 2, 4, 3, 1], | |
spaced_out_pentachord : [1, 2, 3, 2, 1], | |
very_spaced_out_pentachord : [1, 2, 1, 2, 1] }, | |
6 : { a : [1, 3, 5, 6, 4, 2], b : [1, 2, 4, 5, 3, 1], | |
spaced_out_hexachord : [1, 3, 2, 1, 3, 2], | |
very_spaced_out_hexachord : [1, 2, 1, 2, 1, 2] } | |
}; | |
Vex.Flow.ornamentCodes = function(acc) { | |
return Vex.Flow.ornamentCodes.ornaments[acc]; | |
}; | |
Vex.Flow.ornamentCodes.ornaments = { | |
"mordent": { | |
code: "v1e", | |
shift_right: 1, | |
shift_up: 0, | |
shift_down: 5, | |
width: 14, | |
}, | |
"mordent_inverted": { | |
code: "v45", | |
shift_right: 1, | |
shift_up: 0, | |
shift_down: 5, | |
width: 14, | |
}, | |
"turn": { | |
code: "v72", | |
shift_right: 1, | |
shift_up: 0, | |
shift_down: 5, | |
width: 20, | |
}, | |
"turn_inverted": { | |
code: "v33", | |
shift_right: 1, | |
shift_up: 0, | |
shift_down: 6, | |
width: 20, | |
}, | |
"tr": { | |
code: "v1f", | |
shift_right: 0, | |
shift_up: 5, | |
shift_down: 15, | |
width: 10, | |
}, | |
"upprall": { | |
code: "v60", | |
shift_right: 1, | |
shift_up: -3, | |
shift_down: 6, | |
width: 20, | |
}, | |
"downprall": { | |
code: "vb4", | |
shift_right: 1, | |
shift_up: -3, | |
shift_down: 6, | |
width: 20, | |
}, | |
"prallup": { | |
code: "v6d", | |
shift_right: 1, | |
shift_up: -3, | |
shift_down: 6, | |
width: 20, | |
}, | |
"pralldown": { | |
code: "v2c", | |
shift_right: 1, | |
shift_up: -3, | |
shift_down: 6, | |
width: 20, | |
}, | |
"upmordent": { | |
code: "v29", | |
shift_right: 1, | |
shift_up: -3, | |
shift_down: 6, | |
width: 20, | |
}, | |
"downmordent": { | |
code: "v68", | |
shift_right: 1, | |
shift_up: -3, | |
shift_down: 6, | |
width: 20, | |
}, | |
"lineprall": { | |
code: "v20", | |
shift_right: 1, | |
shift_up: -3, | |
shift_down: 6, | |
width: 20, | |
}, | |
"prallprall": { | |
code: "v86", | |
shift_right: 1, | |
shift_up: -3, | |
shift_down: 6, | |
width: 20, | |
} | |
}; | |
Vex.Flow.keySignature = function(spec) { | |
var keySpec = Vex.Flow.keySignature.keySpecs[spec]; | |
if (!keySpec) { | |
throw new Vex.RERR("BadKeySignature", | |
"Bad key signature spec: '" + spec + "'"); | |
} | |
if (!keySpec.acc) { | |
return []; | |
} | |
var notes = Vex.Flow.keySignature.accidentalList(keySpec.acc); | |
var acc_list = []; | |
for (var i = 0; i < keySpec.num; ++i) { | |
var line = notes[i]; | |
acc_list.push({type: keySpec.acc, line: line}); | |
} | |
return acc_list; | |
}; | |
Vex.Flow.keySignature.keySpecs = { | |
"C": {acc: null, num: 0}, | |
"Am": {acc: null, num: 0}, | |
"F": {acc: "b", num: 1}, | |
"Dm": {acc: "b", num: 1}, | |
"Bb": {acc: "b", num: 2}, | |
"Gm": {acc: "b", num: 2}, | |
"Eb": {acc: "b", num: 3}, | |
"Cm": {acc: "b", num: 3}, | |
"Ab": {acc: "b", num: 4}, | |
"Fm": {acc: "b", num: 4}, | |
"Db": {acc: "b", num: 5}, | |
"Bbm": {acc: "b", num: 5}, | |
"Gb": {acc: "b", num: 6}, | |
"Ebm": {acc: "b", num: 6}, | |
"Cb": {acc: "b", num: 7}, | |
"Abm": {acc: "b", num: 7}, | |
"G": {acc: "#", num: 1}, | |
"Em": {acc: "#", num: 1}, | |
"D": {acc: "#", num: 2}, | |
"Bm": {acc: "#", num: 2}, | |
"A": {acc: "#", num: 3}, | |
"F#m": {acc: "#", num: 3}, | |
"E": {acc: "#", num: 4}, | |
"C#m": {acc: "#", num: 4}, | |
"B": {acc: "#", num: 5}, | |
"G#m": {acc: "#", num: 5}, | |
"F#": {acc: "#", num: 6}, | |
"D#m": {acc: "#", num: 6}, | |
"C#": {acc: "#", num: 7}, | |
"A#m": {acc: "#", num: 7} | |
}; | |
Vex.Flow.unicode = { | |
// Unicode accidentals | |
"sharp": String.fromCharCode(parseInt('266F', 16)), | |
"flat" : String.fromCharCode(parseInt('266D', 16)), | |
"natural": String.fromCharCode(parseInt('266E', 16)), | |
// Major Chord | |
"triangle": String.fromCharCode(parseInt('25B3', 16)), | |
// half-diminished | |
"o-with-slash": String.fromCharCode(parseInt('00F8', 16)), | |
// Diminished | |
"degrees": String.fromCharCode(parseInt('00B0', 16)), | |
"circle": String.fromCharCode(parseInt('25CB', 16)) | |
}; | |
Vex.Flow.keySignature.accidentalList = function(acc) { | |
if (acc == "b") { | |
return [2, 0.5, 2.5, 1, 3, 1.5, 3.5]; | |
} | |
else if (acc == "#") { | |
return [0, 1.5, -0.5, 1, 2.5, 0.5, 2]; } | |
}; | |
Vex.Flow.parseNoteDurationString = function(durationString) { | |
if (typeof(durationString) !== "string") { | |
return null; | |
} | |
var regexp = /(\d*\/?\d+|[a-z])(d*)([nrhms]|$)/; | |
var result = regexp.exec(durationString); | |
if (!result) { | |
return null; | |
} | |
var duration = result[1]; | |
var dots = result[2].length; | |
var type = result[3]; | |
if (type.length === 0) { | |
type = "n"; | |
} | |
return { | |
duration: duration, | |
dots: dots, | |
type: type | |
}; | |
}; | |
Vex.Flow.parseNoteData = function(noteData) { | |
var duration = noteData.duration; | |
// Preserve backwards-compatibility | |
var durationStringData = Vex.Flow.parseNoteDurationString(duration); | |
if (!durationStringData) { | |
return null; | |
} | |
var ticks = Vex.Flow.durationToTicks(durationStringData.duration); | |
if (ticks == null) { | |
return null; | |
} | |
var type = noteData.type; | |
if (type) { | |
if (!(type === "n" || type === "r" || type === "h" || | |
type === "m" || type === "s")) { | |
return null; | |
} | |
} else { | |
type = durationStringData.type; | |
if (!type) { | |
type = "n"; | |
} | |
} | |
var dots = 0; | |
if (noteData.dots) { | |
dots = noteData.dots; | |
} else { | |
dots = durationStringData.dots; | |
} | |
if (typeof(dots) !== "number") { | |
return null; | |
} | |
var currentTicks = ticks; | |
for (var i = 0; i < dots; i++) { | |
if (currentTicks <= 1) { | |
return null; | |
} | |
currentTicks = currentTicks / 2; | |
ticks += currentTicks; | |
} | |
return { | |
duration: durationStringData.duration, | |
type: type, | |
dots: dots, | |
ticks: ticks | |
}; | |
}; | |
// Used to convert duration aliases to the number based duration. | |
// If the input isn't an alias, simply return the input. | |
// | |
// example: 'q' -> '4', '8' -> '8' | |
Vex.Flow.sanitizeDuration = function(duration) { | |
var alias = Vex.Flow.durationAliases[duration]; | |
if (alias !== undefined) { | |
duration = alias; | |
} | |
if (Vex.Flow.durationToTicks.durations[duration] === undefined) { | |
throw new Vex.RERR('BadArguments', | |
'The provided duration is not valid'); | |
} | |
return duration; | |
}; | |
// Convert the `duration` to an fraction | |
Vex.Flow.durationToFraction = function(duration) { | |
return new Vex.Flow.Fraction().parse(Vex.Flow.sanitizeDuration(duration)); | |
}; | |
// Convert the `duration` to an number | |
Vex.Flow.durationToNumber = function(duration) { | |
return Vex.Flow.durationToFraction(duration).value(); | |
}; | |
// Convert the `duration` to total ticks | |
Vex.Flow.durationToTicks = function(duration) { | |
duration = Vex.Flow.sanitizeDuration(duration); | |
var ticks = Vex.Flow.durationToTicks.durations[duration]; | |
if (ticks === undefined) { | |
return null; | |
} | |
return ticks; | |
}; | |
Vex.Flow.durationToTicks.durations = { | |
"1/2": Vex.Flow.RESOLUTION * 2, | |
"1": Vex.Flow.RESOLUTION / 1, | |
"2": Vex.Flow.RESOLUTION / 2, | |
"4": Vex.Flow.RESOLUTION / 4, | |
"8": Vex.Flow.RESOLUTION / 8, | |
"16": Vex.Flow.RESOLUTION / 16, | |
"32": Vex.Flow.RESOLUTION / 32, | |
"64": Vex.Flow.RESOLUTION / 64, | |
"128": Vex.Flow.RESOLUTION / 128, | |
"256": Vex.Flow.RESOLUTION / 256 | |
}; | |
Vex.Flow.durationAliases = { | |
"w": "1", | |
"h": "2", | |
"q": "4", | |
// This is the default duration used to render bars (BarNote). Bars no longer | |
// consume ticks, so this should be a no-op. | |
// | |
// TODO(0xfe): This needs to be cleaned up. | |
"b": "256" | |
}; | |
Vex.Flow.durationToGlyph = function(duration, type) { | |
duration = Vex.Flow.sanitizeDuration(duration); | |
var code = Vex.Flow.durationToGlyph.duration_codes[duration]; | |
if (code === undefined) { | |
return null; | |
} | |
if (!type) { | |
type = "n"; | |
} | |
var glyphTypeProperties = code.type[type]; | |
if (glyphTypeProperties === undefined) { | |
return null; | |
} | |
return Vex.Merge(Vex.Merge({}, code.common), glyphTypeProperties); | |
}; | |
Vex.Flow.durationToGlyph.duration_codes = { | |
"1/2": { | |
common: { | |
head_width: 22, | |
stem: false, | |
stem_offset: 0, | |
flag: false, | |
stem_up_extension: -Vex.Flow.STEM_HEIGHT, | |
stem_down_extension: -Vex.Flow.STEM_HEIGHT, | |
gracenote_stem_up_extension: -Vex.Flow.STEM_HEIGHT, | |
gracenote_stem_down_extension: -Vex.Flow.STEM_HEIGHT, | |
tabnote_stem_up_extension: -Vex.Flow.STEM_HEIGHT, | |
tabnote_stem_down_extension: -Vex.Flow.STEM_HEIGHT, | |
dot_shiftY: 0, | |
line_above: 0, | |
line_below: 0 | |
}, | |
type: { | |
"n": { // Breve note | |
code_head: "v53" | |
}, | |
"h": { // Breve note harmonic | |
code_head: "v59" | |
}, | |
"m": { // Breve note muted - | |
code_head: "vf", | |
stem_offset: 0 | |
}, | |
"r": { // Breve rest | |
code_head: "v31", | |
head_width: 24, | |
rest: true, | |
position: "B/5", | |
dot_shiftY: 0.5 | |
}, | |
"s": { // Breve note slash - | |
// Drawn with canvas primitives | |
head_width: 15, | |
position: "B/4" | |
} | |
} | |
}, | |
"1": { | |
common: { | |
head_width: 16, | |
stem: false, | |
stem_offset: 0, | |
flag: false, | |
stem_up_extension: -Vex.Flow.STEM_HEIGHT, | |
stem_down_extension: -Vex.Flow.STEM_HEIGHT, | |
gracenote_stem_up_extension: -Vex.Flow.STEM_HEIGHT, | |
gracenote_stem_down_extension: -Vex.Flow.STEM_HEIGHT, | |
tabnote_stem_up_extension: -Vex.Flow.STEM_HEIGHT, | |
tabnote_stem_down_extension: -Vex.Flow.STEM_HEIGHT, | |
dot_shiftY: 0, | |
line_above: 0, | |
line_below: 0 | |
}, | |
type: { | |
"n": { // Whole note | |
code_head: "v1d" | |
}, | |
"h": { // Whole note harmonic | |
code_head: "v46" | |
}, | |
"m": { // Whole note muted | |
code_head: "v92", | |
stem_offset: -3 | |
}, | |
"r": { // Whole rest | |
code_head: "v5c", | |
head_width: 12, | |
rest: true, | |
position: "D/5", | |
dot_shiftY: 0.5 | |
}, | |
"s": { // Whole note slash | |
// Drawn with canvas primitives | |
head_width: 15, | |
position: "B/4" | |
} | |
} | |
}, | |
"2": { | |
common: { | |
head_width: 10, | |
stem: true, | |
stem_offset: 0, | |
flag: false, | |
stem_up_extension: 0, | |
stem_down_extension: 0, | |
gracenote_stem_up_extension: -14, | |
gracenote_stem_down_extension: -14, | |
tabnote_stem_up_extension: 0, | |
tabnote_stem_down_extension: 0, | |
dot_shiftY: 0, | |
line_above: 0, | |
line_below: 0 | |
}, | |
type: { | |
"n": { // Half note | |
code_head: "v81" | |
}, | |
"h": { // Half note harmonic | |
code_head: "v2d" | |
}, | |
"m": { // Half note muted | |
code_head: "v95", | |
stem_offset: -3 | |
}, | |
"r": { // Half rest | |
code_head: "vc", | |
head_width: 12, | |
stem: false, | |
rest: true, | |
position: "B/4", | |
dot_shiftY: -0.5 | |
}, | |
"s": { // Half note slash | |
// Drawn with canvas primitives | |
head_width: 15, | |
position: "B/4" | |
} | |
} | |
}, | |
"4": { | |
common: { | |
head_width: 10, | |
stem: true, | |
stem_offset: 0, | |
flag: false, | |
stem_up_extension: 0, | |
stem_down_extension: 0, | |
gracenote_stem_up_extension: -14, | |
gracenote_stem_down_extension: -14, | |
tabnote_stem_up_extension: 0, | |
tabnote_stem_down_extension: 0, | |
dot_shiftY: 0, | |
line_above: 0, | |
line_below: 0 | |
}, | |
type: { | |
"n": { // Quarter note | |
code_head: "vb" | |
}, | |
"h": { // Quarter harmonic | |
code_head: "v22" | |
}, | |
"m": { // Quarter muted | |
code_head: "v3e", | |
stem_offset: -3 | |
}, | |
"r": { // Quarter rest | |
code_head: "v7c", | |
head_width: 8, | |
stem: false, | |
rest: true, | |
position: "B/4", | |
dot_shiftY: -0.5, | |
line_above: 1.5, | |
line_below: 1.5 | |
}, | |
"s": { // Quarter slash | |
// Drawn with canvas primitives | |
head_width: 15, | |
position: "B/4" | |
} | |
} | |
}, | |
"8": { | |
common: { | |
head_width: 10, | |
stem: true, | |
stem_offset: 0, | |
flag: true, | |
beam_count: 1, | |
code_flag_upstem: "v54", | |
code_flag_downstem: "v9a", | |
stem_up_extension: 0, | |
stem_down_extension: 0, | |
gracenote_stem_up_extension: -14, | |
gracenote_stem_down_extension: -14, | |
tabnote_stem_up_extension: 0, | |
tabnote_stem_down_extension: 0, | |
dot_shiftY: 0, | |
line_above: 0, | |
line_below: 0 | |
}, | |
type: { | |
"n": { // Eighth note | |
code_head: "vb" | |
}, | |
"h": { // Eighth note harmonic | |
code_head: "v22" | |
}, | |
"m": { // Eighth note muted | |
code_head: "v3e" | |
}, | |
"r": { // Eighth rest | |
code_head: "va5", | |
stem: false, | |
flag: false, | |
rest: true, | |
position: "B/4", | |
dot_shiftY: -0.5, | |
line_above: 1.0, | |
line_below: 1.0 | |
}, | |
"s": { // Eight slash | |
// Drawn with canvas primitives | |
head_width: 15, | |
position: "B/4" | |
} | |
} | |
}, | |
"16": { | |
common: { | |
beam_count: 2, | |
head_width: 10, | |
stem: true, | |
stem_offset: 0, | |
flag: true, | |
code_flag_upstem: "v3f", | |
code_flag_downstem: "v8f", | |
stem_up_extension: 4, | |
stem_down_extension: 0, | |
gracenote_stem_up_extension: -14, | |
gracenote_stem_down_extension: -14, | |
tabnote_stem_up_extension: 0, | |
tabnote_stem_down_extension: 0, | |
dot_shiftY: 0, | |
line_above: 0, | |
line_below: 0 | |
}, | |
type: { | |
"n": { // Sixteenth note | |
code_head: "vb" | |
}, | |
"h": { // Sixteenth note harmonic | |
code_head: "v22" | |
}, | |
"m": { // Sixteenth note muted | |
code_head: "v3e" | |
}, | |
"r": { // Sixteenth rest | |
code_head: "v3c", | |
head_width: 13, | |
stem: false, | |
flag: false, | |
rest: true, | |
position: "B/4", | |
dot_shiftY: -0.5, | |
line_above: 1.0, | |
line_below: 2.0 | |
}, | |
"s": { // Sixteenth slash | |
// Drawn with canvas primitives | |
head_width: 15, | |
position: "B/4" | |
} | |
} | |
}, | |
"32": { | |
common: { | |
beam_count: 3, | |
head_width: 10, | |
stem: true, | |
stem_offset: 0, | |
flag: true, | |
code_flag_upstem: "v47", | |
code_flag_downstem: "v2a", | |
stem_up_extension: 13, | |
stem_down_extension: 9, | |
gracenote_stem_up_extension: -12, | |
gracenote_stem_down_extension: -12, | |
tabnote_stem_up_extension: 9, | |
tabnote_stem_down_extension: 5, | |
dot_shiftY: 0, | |
line_above: 0, | |
line_below: 0 | |
}, | |
type: { | |
"n": { // Thirty-second note | |
code_head: "vb" | |
}, | |
"h": { // Thirty-second harmonic | |
code_head: "v22" | |
}, | |
"m": { // Thirty-second muted | |
code_head: "v3e" | |
}, | |
"r": { // Thirty-second rest | |
code_head: "v55", | |
head_width: 16, | |
stem: false, | |
flag: false, | |
rest: true, | |
position: "B/4", | |
dot_shiftY: -1.5, | |
line_above: 2.0, | |
line_below: 2.0 | |
}, | |
"s": { // Thirty-second slash | |
// Drawn with canvas primitives | |
head_width: 15, | |
position: "B/4" | |
} | |
} | |
}, | |
"64": { | |
common: { | |
beam_count: 4, | |
head_width: 10, | |
stem: true, | |
stem_offset: 0, | |
flag: true, | |
code_flag_upstem: "va9", | |
code_flag_downstem: "v58", | |
stem_up_extension: 17, | |
stem_down_extension: 13, | |
gracenote_stem_up_extension: -10, | |
gracenote_stem_down_extension: -10, | |
tabnote_stem_up_extension: 13, | |
tabnote_stem_down_extension: 9, | |
dot_shiftY: 0, | |
line_above: 0, | |
line_below: 0 | |
}, | |
type: { | |
"n": { // Sixty-fourth note | |
code_head: "vb" | |
}, | |
"h": { // Sixty-fourth harmonic | |
code_head: "v22" | |
}, | |
"m": { // Sixty-fourth muted | |
code_head: "v3e" | |
}, | |
"r": { // Sixty-fourth rest | |
code_head: "v38", | |
head_width: 18, | |
stem: false, | |
flag: false, | |
rest: true, | |
position: "B/4", | |
dot_shiftY: -1.5, | |
line_above: 2.0, | |
line_below: 3.0 | |
}, | |
"s": { // Sixty-fourth slash | |
// Drawn with canvas primitives | |
head_width: 15, | |
position: "B/4" | |
} | |
} | |
}, | |
"128": { | |
common: { | |
beam_count: 5, | |
head_width: 10, | |
stem: true, | |
stem_offset:0, | |
flag: true, | |
code_flag_upstem: "v9b", | |
code_flag_downstem: "v30", | |
stem_up_extension: 26, | |
stem_down_extension: 22, | |
gracenote_stem_up_extension: -8, | |
gracenote_stem_down_extension: -8, | |
tabnote_stem_up_extension: 22, | |
tabnote_stem_down_extension: 18, | |
dot_shiftY: 0, | |
line_above: 0, | |
line_below: 0 | |
}, | |
type: { | |
"n": { // Hundred-twenty-eight note | |
code_head: "vb" | |
}, | |
"h": { // Hundred-twenty-eight harmonic | |
code_head: "v22" | |
}, | |
"m": { // Hundred-twenty-eight muted | |
code_head: "v3e" | |
}, | |
"r": { // Hundred-twenty-eight rest | |
code_head: "vaa", | |
head_width: 20, | |
stem: false, | |
flag: false, | |
rest: true, | |
position: "B/4", | |
dot_shiftY: 1.5, | |
line_above: 3.0, | |
line_below: 3.0 | |
}, | |
"s": { // Hundred-twenty-eight rest | |
// Drawn with canvas primitives | |
head_width: 15, | |
position: "B/4" | |
} | |
} | |
} | |
}; | |
// Some defaults | |
Vex.Flow.TIME4_4 = { | |
num_beats: 4, | |
beat_value: 4, | |
resolution: Vex.Flow.RESOLUTION | |
}; | |
Vex.Flow.Font = {"glyphs":{"v0":{"x_min":0,"x_max":514.5,"ha":525,"o":"m 236 648 b 246 648 238 648 242 648 b 288 646 261 648 283 648 b 472 513 364 634 428 587 b 514 347 502 464 514 413 b 462 163 514 272 499 217 b 257 44 409 83 333 44 b 50 163 181 44 103 83 b 0 347 14 217 0 272 b 40 513 0 413 12 464 b 236 648 87 591 155 638 m 277 614 b 253 616 273 616 261 616 b 242 616 247 616 243 616 b 170 499 193 609 181 589 b 159 348 163 446 159 398 b 166 222 159 308 161 266 b 201 91 174 138 183 106 b 257 76 215 81 235 76 b 311 91 277 76 299 81 b 347 222 330 106 338 138 b 353 348 352 266 353 308 b 344 499 353 398 351 446 b 277 614 333 587 322 606 m 257 -1 l 258 -1 l 255 -1 l 257 -1 m 257 673 l 258 673 l 255 673 l 257 673 "},"v1":{"x_min":-1.359375,"x_max":344.359375,"ha":351,"o":"m 126 637 l 129 638 l 198 638 l 266 638 l 269 635 b 274 631 272 634 273 632 l 277 627 l 277 395 b 279 156 277 230 277 161 b 329 88 281 123 295 106 b 344 69 341 81 344 79 b 337 55 344 62 343 59 l 333 54 l 197 54 l 61 54 l 58 55 b 50 69 53 59 50 62 b 65 88 50 79 53 81 b 80 97 72 91 74 93 b 117 156 103 113 112 129 b 117 345 117 161 117 222 l 117 528 l 100 503 l 38 406 b 14 383 24 384 23 383 b -1 398 5 383 -1 390 b 4 415 -1 403 1 409 b 16 437 5 416 10 426 l 72 539 l 100 596 b 121 632 119 631 119 631 b 126 637 122 634 125 635 m 171 -1 l 172 -1 l 170 -1 l 171 -1 m 171 673 l 172 673 l 170 673 l 171 673 "},"v2":{"x_min":-1.359375,"x_max":458.6875,"ha":468,"o":"m 197 648 b 216 648 201 648 208 648 b 258 646 232 648 253 648 b 419 546 333 637 393 599 b 432 489 428 528 432 509 b 356 342 432 440 405 384 b 235 278 322 313 288 295 b 69 170 166 256 107 217 b 69 169 69 170 69 169 b 69 169 69 169 69 169 b 74 173 69 169 72 170 b 209 222 112 204 163 222 b 310 195 247 222 274 215 b 371 179 332 184 352 179 b 396 181 379 179 387 179 b 428 202 409 184 423 194 b 442 212 431 209 436 212 b 458 197 450 212 458 206 b 441 148 458 190 449 165 b 299 44 409 84 353 44 b 288 45 295 44 292 44 b 250 61 274 45 268 49 b 122 99 212 86 164 99 b 73 91 104 99 88 97 b 28 63 53 84 34 72 b 14 54 25 56 20 54 b 1 62 9 54 4 56 l -1 65 l -1 79 b 0 99 -1 91 0 95 b 2 113 1 102 2 108 b 164 309 20 197 81 272 b 285 470 232 341 277 398 b 287 487 287 476 287 481 b 171 595 287 551 239 595 b 155 595 166 595 160 595 b 142 592 145 594 142 594 b 145 589 142 592 142 591 b 179 527 168 576 179 551 b 132 455 179 496 163 467 b 104 451 122 452 112 451 b 27 530 62 451 27 487 b 29 555 27 538 27 546 b 197 648 44 601 115 639 m 228 -1 l 230 -1 l 227 -1 l 228 -1 m 228 673 l 230 673 l 227 673 l 228 673 "},"v3":{"x_min":-1.359375,"x_max":409.6875,"ha":418,"o":"m 174 648 b 191 648 176 648 183 648 b 225 648 204 648 220 648 b 402 523 317 638 389 588 b 404 503 404 517 404 510 b 402 484 404 495 404 488 b 264 373 389 437 334 394 b 257 370 259 371 257 371 b 257 370 257 370 257 370 b 264 369 258 370 261 369 b 409 202 359 334 409 267 b 318 72 409 152 381 104 b 200 43 281 52 240 43 b 23 113 134 43 69 68 b 0 169 6 129 0 149 b 77 249 0 210 29 249 l 77 249 b 152 174 125 249 152 212 b 103 102 152 145 137 116 b 103 102 103 102 103 102 b 147 94 103 101 132 95 b 153 94 149 94 151 94 b 265 206 219 94 265 141 b 264 226 265 213 265 219 b 147 355 253 299 204 353 b 126 371 133 356 126 362 b 147 388 126 383 132 388 b 254 474 196 391 238 424 b 259 502 258 484 259 494 b 182 592 259 544 228 582 b 156 595 175 595 166 595 b 115 592 142 595 129 594 l 111 591 l 115 588 b 152 524 141 574 152 549 b 92 449 152 491 130 458 b 76 448 87 448 81 448 b -1 530 32 448 -1 488 b 20 581 -1 548 5 566 b 174 648 55 619 108 641 m 204 -1 l 205 -1 l 202 -1 l 204 -1 m 204 673 l 205 673 l 202 673 l 204 673 "},"v4":{"x_min":0,"x_max":468.21875,"ha":478,"o":"m 174 637 b 232 638 175 638 189 638 b 277 638 245 638 259 638 l 378 638 l 381 635 b 389 623 386 632 389 627 b 382 609 389 617 386 613 b 366 589 381 606 372 598 l 313 528 l 245 451 l 209 410 l 155 348 l 84 267 b 59 240 72 252 59 240 b 59 240 59 240 59 240 b 151 238 59 238 68 238 l 242 238 l 242 303 b 243 371 242 369 242 370 b 289 426 245 374 254 385 l 303 441 l 317 456 l 338 483 l 360 506 l 371 520 b 386 527 375 526 381 527 b 400 519 392 527 397 524 b 401 440 401 516 401 514 b 401 377 401 423 401 402 l 401 238 l 426 238 b 453 237 449 238 450 238 b 465 217 461 234 465 226 b 460 202 465 212 464 206 b 426 197 454 197 453 197 l 401 197 l 401 180 b 451 88 402 129 412 109 b 468 69 465 81 468 79 b 461 55 468 62 466 59 l 458 54 l 321 54 l 185 54 l 182 55 b 175 69 176 59 175 62 b 191 88 175 79 176 81 b 240 180 230 109 240 129 l 240 197 l 125 197 b 73 195 104 195 87 195 b 8 197 10 195 9 197 b 0 212 2 199 0 205 b 0 212 0 212 0 212 b 20 242 0 219 0 219 b 163 610 104 344 163 492 b 174 637 163 628 166 634 m 234 -1 l 235 -1 l 232 -1 l 234 -1 m 234 673 l 235 673 l 232 673 l 234 673 "},"v5":{"x_min":0,"x_max":409.6875,"ha":418,"o":"m 47 637 b 53 638 49 638 50 638 b 69 634 55 638 61 637 b 210 610 114 619 161 610 b 363 634 259 610 311 619 b 382 638 372 637 378 638 b 392 634 386 638 389 637 b 397 623 396 630 397 627 b 393 610 397 620 396 616 b 298 505 368 552 338 520 b 212 494 277 498 246 494 b 65 517 163 494 106 502 b 61 517 62 517 61 517 b 61 517 61 517 61 517 b 51 408 61 517 51 412 b 51 408 51 408 51 408 b 51 408 51 408 51 408 b 61 412 53 408 55 409 b 125 434 80 421 103 430 b 185 441 145 440 166 441 b 409 244 310 441 409 353 b 401 191 409 227 406 209 b 197 43 375 105 287 43 b 159 47 183 43 171 44 b 23 123 112 56 61 86 b 0 180 6 140 0 159 b 76 260 0 220 31 260 b 92 259 81 260 87 259 b 152 183 132 251 152 216 b 100 112 152 152 134 122 b 95 111 98 112 95 111 b 95 111 95 111 95 111 b 129 98 95 109 119 101 b 148 97 136 97 141 97 b 264 235 206 97 261 158 b 265 248 265 240 265 244 b 210 398 265 312 243 373 b 179 408 201 406 194 408 b 174 408 178 408 176 408 b 53 369 130 408 88 394 b 34 359 39 359 38 359 b 17 374 24 359 17 365 b 39 628 17 384 38 625 b 47 637 40 631 43 635 m 204 -1 l 205 -1 l 202 -1 l 204 -1 m 204 673 l 205 673 l 202 673 l 204 673 "},"v6":{"x_min":0,"x_max":475.03125,"ha":485,"o":"m 255 648 b 274 648 259 648 266 648 b 314 646 288 648 307 648 b 450 555 374 637 438 594 b 454 530 453 546 454 538 b 375 451 454 485 416 451 b 328 467 359 451 343 455 b 300 526 310 483 300 503 b 352 598 300 557 319 589 b 356 599 355 598 356 599 b 352 602 356 599 355 601 b 288 616 330 612 308 616 b 210 584 257 616 230 605 b 164 433 189 559 174 508 b 160 374 163 415 160 381 b 160 374 160 374 160 374 b 160 374 160 374 160 374 b 168 377 160 374 164 376 b 258 395 200 390 228 395 b 366 367 294 395 328 387 b 475 223 436 333 475 283 b 472 197 475 215 473 206 b 349 65 462 141 419 95 b 259 43 317 51 288 43 b 167 69 230 43 200 52 b 4 290 80 113 20 195 b 0 349 1 309 0 328 b 20 467 0 391 6 433 b 255 648 58 563 155 637 m 269 363 b 257 363 265 363 261 363 b 210 345 236 363 220 356 b 186 226 196 324 186 272 b 187 198 186 216 186 206 b 213 95 191 151 202 112 b 257 76 221 83 238 76 b 270 77 261 76 266 76 b 321 156 299 81 310 99 b 329 229 326 183 329 206 b 321 301 329 252 326 274 b 269 363 311 342 298 359 m 236 -1 l 238 -1 l 235 -1 l 236 -1 m 236 673 l 238 673 l 235 673 l 236 673 "},"v7":{"x_min":0,"x_max":442.359375,"ha":451,"o":"m 147 648 b 166 649 153 649 160 649 b 313 598 217 649 273 630 b 340 587 323 588 328 587 l 341 587 b 412 628 367 587 390 601 b 427 638 416 635 421 638 b 439 632 431 638 435 637 b 442 623 441 630 442 628 b 430 569 442 616 439 603 b 352 369 408 492 377 410 b 300 259 325 324 313 298 b 273 84 283 205 273 140 b 265 55 273 65 272 59 l 261 54 l 181 54 l 99 54 l 96 55 b 91 61 95 56 92 59 l 89 63 l 89 77 b 147 263 89 133 111 202 b 261 401 176 313 212 355 b 378 541 315 449 349 489 l 382 548 l 375 544 b 240 495 333 512 285 495 b 129 535 198 495 160 509 b 84 560 108 552 95 560 b 76 559 81 560 78 560 b 31 487 59 555 43 530 b 14 470 27 473 24 470 b 1 477 8 470 4 471 l 0 480 l 0 553 l 0 627 l 1 630 b 16 638 4 635 9 638 b 23 635 17 638 20 637 b 49 626 36 626 39 626 b 96 638 59 626 80 630 b 104 639 99 638 102 639 b 117 644 107 641 112 642 b 147 648 125 645 137 648 m 220 -1 l 221 -1 l 219 -1 l 220 -1 m 220 673 l 221 673 l 219 673 l 220 673 "},"v8":{"x_min":0,"x_max":488.640625,"ha":499,"o":"m 217 648 b 245 649 225 648 235 649 b 453 516 343 649 430 595 b 458 478 455 503 458 491 b 412 370 458 440 441 398 b 411 369 412 369 411 369 b 415 365 411 367 412 367 b 488 231 462 331 488 281 b 472 165 488 208 483 186 b 243 43 434 86 338 43 b 63 104 178 43 112 62 b 0 233 20 140 0 186 b 73 365 0 283 24 331 l 77 369 l 72 374 b 29 476 42 406 29 441 b 217 648 29 557 103 635 m 258 605 b 242 606 253 605 247 606 b 157 552 198 606 157 580 b 160 541 157 548 159 544 b 319 413 176 503 242 452 l 337 403 l 338 406 b 359 476 352 428 359 452 b 258 605 359 537 318 595 m 138 326 b 130 330 134 328 130 330 b 130 330 130 330 130 330 b 107 305 127 330 112 313 b 84 231 91 281 84 256 b 243 86 84 156 151 86 b 249 87 245 86 246 87 b 347 156 303 88 347 120 b 344 172 347 162 345 167 b 156 319 325 227 257 281 b 138 326 151 322 144 324 m 243 -1 l 245 -1 l 242 -1 l 243 -1 m 243 673 l 245 673 l 242 673 l 243 673 "},"v9":{"x_min":0,"x_max":475.03125,"ha":485,"o":"m 191 646 b 212 649 198 648 205 649 b 255 644 227 649 243 646 b 458 448 348 616 428 539 b 475 342 469 415 475 378 b 460 244 475 308 469 274 b 193 44 421 124 303 44 b 91 69 157 44 122 51 b 19 161 43 97 19 126 b 21 181 19 167 20 174 b 98 241 32 220 65 241 b 170 186 129 241 160 223 b 172 166 171 179 172 173 b 121 94 172 134 152 102 b 117 93 118 94 117 93 b 121 90 117 93 118 91 b 185 76 142 80 164 76 b 270 119 220 76 251 91 b 308 259 287 145 300 194 b 313 317 310 277 313 310 b 313 317 313 317 313 317 b 313 317 313 317 313 317 b 304 315 313 317 308 316 b 216 295 273 302 245 295 b 145 308 193 295 170 299 b 19 398 88 327 42 360 b 0 469 5 420 0 444 b 24 551 0 496 8 526 b 191 646 54 596 125 637 m 227 614 b 215 616 224 616 220 616 b 202 614 210 616 206 616 b 152 535 174 610 163 592 b 144 463 147 509 144 485 b 152 391 144 440 147 417 b 216 328 163 344 179 328 b 280 391 253 328 269 344 b 288 463 285 417 288 440 b 280 535 288 485 285 509 b 227 614 269 594 258 610 m 236 -1 l 238 -1 l 235 -1 l 236 -1 m 236 673 l 238 673 l 235 673 l 236 673 "},"va":{"x_min":-149.71875,"x_max":148.359375,"ha":151,"o":"m -8 -1 b -1 0 -5 -1 -4 0 b 16 -11 5 0 13 -4 b 83 -186 17 -12 47 -90 l 148 -358 l 148 -363 b 127 -385 148 -376 138 -385 b 112 -378 122 -385 118 -383 b 54 -226 110 -374 114 -385 b 0 -81 24 -147 0 -81 b -55 -226 -1 -81 -25 -147 b -114 -378 -115 -385 -111 -374 b -129 -385 -119 -383 -123 -385 b -149 -363 -140 -385 -149 -376 l -149 -358 l -84 -186 b -19 -11 -49 -90 -19 -12 b -8 -1 -17 -8 -12 -4 "},"vb":{"x_min":0,"x_max":428.75,"ha":438,"o":"m 262 186 b 273 186 266 186 272 186 b 274 186 273 186 274 186 b 285 186 274 186 280 186 b 428 48 375 181 428 122 b 386 -68 428 12 416 -29 b 155 -187 329 -145 236 -187 b 12 -111 92 -187 38 -162 b 0 -51 4 -91 0 -72 b 262 186 0 58 122 179 "},"vc":{"x_min":0,"x_max":447.8125,"ha":457,"o":"m 0 86 l 0 173 l 223 173 l 447 173 l 447 86 l 447 0 l 223 0 l 0 0 l 0 86 "},"vf":{"x_min":0,"x_max":370.21875,"ha":378,"o":"m 0 0 l 0 277 l 61 277 l 122 277 l 122 0 l 122 -278 l 61 -278 l 0 -278 l 0 0 m 246 -1 l 246 277 l 308 277 l 370 277 l 370 -1 l 370 -278 l 308 -278 l 246 -278 l 246 -1 "},"v10":{"x_min":0,"x_max":559.421875,"ha":571,"o":"m 5 127 b 14 127 6 127 9 127 b 51 126 25 127 43 127 b 175 98 93 122 138 112 l 186 94 b 279 51 210 86 255 65 b 285 47 280 51 283 48 b 319 27 291 44 311 31 l 326 22 b 359 0 332 19 352 4 l 367 -6 b 371 -9 368 -6 370 -8 l 379 -15 b 387 -22 383 -18 386 -20 l 398 -30 l 411 -40 l 417 -47 l 427 -55 l 434 -61 b 441 -66 436 -62 439 -65 l 446 -72 l 453 -77 l 462 -87 b 558 -188 490 -113 549 -176 b 559 -195 559 -191 559 -194 b 548 -205 559 -201 555 -205 b 541 -204 547 -205 544 -205 b 534 -198 539 -201 536 -199 l 525 -191 b 481 -162 518 -187 490 -167 b 472 -155 477 -159 472 -156 b 468 -152 470 -155 469 -154 b 461 -149 466 -152 464 -151 b 428 -130 454 -145 441 -137 b 371 -99 413 -122 372 -99 b 363 -95 371 -99 367 -98 b 353 -91 357 -94 353 -91 b 348 -90 353 -91 352 -91 b 332 -81 343 -87 341 -86 b 27 -12 230 -37 127 -13 b 0 -5 4 -11 2 -11 b 0 58 0 -2 0 27 b 0 122 0 88 0 120 b 5 127 1 124 4 126 "},"v11":{"x_min":-155.171875,"x_max":153.8125,"ha":157,"o":"m -137 353 b -130 353 -136 353 -133 353 b -112 349 -125 353 -119 352 b -100 342 -110 347 -104 344 b 0 317 -69 326 -35 317 b 111 349 38 317 76 328 b 129 353 117 352 123 353 b 153 327 142 353 153 344 b 144 302 153 320 153 317 b 27 6 93 226 50 113 b 21 -13 24 -11 24 -11 b 0 -26 17 -22 8 -26 b -24 -12 -9 -26 -19 -22 b -28 5 -24 -9 -27 -2 b -145 302 -53 117 -95 224 b -155 327 -155 317 -155 320 b -137 353 -155 340 -148 349 "},"v18":{"x_min":0,"x_max":323.9375,"ha":331,"o":"m 217 535 b 225 537 220 537 221 537 b 245 524 235 537 242 533 l 246 521 l 247 390 l 247 258 l 273 265 b 306 270 288 269 299 270 b 322 259 315 270 319 267 b 323 208 323 256 323 233 b 322 158 323 184 323 159 b 288 140 318 148 315 147 b 247 130 254 131 247 130 b 247 65 247 130 247 104 b 247 20 247 51 247 36 l 247 -88 l 273 -81 b 306 -76 289 -77 299 -76 b 318 -81 311 -76 315 -77 b 323 -123 323 -87 323 -86 l 323 -138 l 323 -154 b 318 -195 323 -191 323 -190 b 269 -210 314 -199 315 -199 b 249 -216 259 -213 250 -216 l 247 -216 l 247 -349 l 246 -483 l 245 -487 b 225 -499 242 -495 234 -499 b 206 -487 219 -499 210 -495 l 205 -483 l 205 -355 l 205 -227 l 204 -227 l 181 -233 l 138 -244 b 117 -249 127 -247 117 -249 b 115 -385 115 -249 115 -256 l 115 -523 l 114 -526 b 95 -538 110 -534 102 -538 b 74 -526 87 -538 78 -534 l 73 -523 l 73 -391 b 72 -260 73 -269 73 -260 b 72 -260 72 -260 72 -260 b 19 -273 61 -263 23 -273 b 0 -260 10 -273 4 -267 b 0 -209 0 -256 0 -256 l 0 -162 l 1 -158 b 61 -134 5 -148 5 -148 l 73 -131 l 73 -22 b 72 86 73 79 73 86 b 72 86 72 86 72 86 b 19 74 61 83 23 74 b 0 86 10 74 4 79 b 0 137 0 90 0 90 l 0 184 l 1 188 b 61 212 5 198 5 198 l 73 215 l 73 348 l 73 481 l 74 485 b 95 498 78 492 87 498 b 103 495 98 498 100 496 b 114 485 107 494 111 489 l 115 481 l 115 353 l 115 226 l 121 226 b 159 235 123 227 141 231 l 198 247 l 205 248 l 205 384 l 205 521 l 206 524 b 217 535 209 528 212 533 m 205 9 b 205 119 205 70 205 119 l 205 119 b 182 113 204 119 194 116 l 138 102 b 117 97 127 99 117 97 b 115 -12 115 97 115 91 l 115 -122 l 121 -120 b 159 -111 123 -119 141 -115 l 198 -101 l 205 -98 l 205 9 "},"v1b":{"x_min":0,"x_max":559.421875,"ha":571,"o":"m 544 204 b 548 204 545 204 547 204 b 559 194 555 204 559 199 b 559 190 559 192 559 191 b 530 156 559 188 556 184 b 462 86 510 134 481 104 b 453 76 458 81 454 77 l 446 70 l 441 65 b 434 59 439 63 436 61 l 427 54 b 409 37 426 51 416 44 b 392 23 398 29 394 26 b 387 19 389 22 387 20 b 379 13 386 19 383 16 l 371 8 l 367 5 l 359 -1 l 337 -16 b 285 -48 319 -29 298 -41 l 279 -52 b 186 -95 255 -66 210 -87 l 175 -99 b 23 -129 127 -117 68 -129 b 17 -129 20 -129 19 -129 b 1 -123 2 -129 2 -129 b 0 -49 0 -122 0 -83 b 0 4 0 -22 0 1 b 27 11 2 9 4 9 b 185 31 78 12 145 20 b 198 34 186 31 193 33 b 314 73 234 44 277 58 b 349 88 328 79 340 84 b 353 90 352 90 353 90 b 363 94 353 90 357 93 b 371 98 367 97 371 98 b 428 129 372 98 413 120 b 461 148 441 136 454 144 b 468 151 464 149 466 151 b 472 154 469 152 470 154 b 481 161 473 155 477 158 b 525 190 490 166 518 186 l 534 197 b 540 201 536 198 539 199 b 544 204 541 202 544 204 "},"v1d":{"x_min":0,"x_max":619.3125,"ha":632,"o":"m 274 184 b 307 186 285 186 296 186 b 616 22 465 186 597 116 b 619 -1 617 13 619 5 b 308 -187 619 -104 483 -187 b 0 -1 133 -187 0 -102 b 5 36 0 11 1 23 b 274 184 29 115 141 176 m 289 161 b 272 162 284 162 277 162 b 171 41 209 162 171 108 b 205 -73 171 5 182 -34 b 345 -163 243 -133 298 -163 b 436 -98 385 -163 420 -142 b 446 -43 443 -80 446 -62 b 289 161 446 47 377 147 "},"v1e":{"x_min":-402.890625,"x_max":401.53125,"ha":410,"o":"m -219 173 b -213 174 -217 174 -215 174 b -202 173 -209 174 -205 173 b -114 86 -200 172 -179 151 b -28 0 -66 37 -28 0 b 40 84 -28 0 2 37 b 117 174 111 173 110 172 b 122 174 118 174 119 174 b 132 173 125 174 129 173 b 295 11 134 172 171 134 l 307 -1 l 336 34 b 374 76 366 72 368 74 b 381 77 375 77 378 77 b 401 56 392 77 401 68 b 400 48 401 54 401 51 b 223 -172 397 41 230 -166 b 210 -176 220 -174 215 -176 b 201 -174 206 -176 204 -176 b 112 -87 198 -173 178 -152 b 27 0 65 -38 27 0 b -42 -86 27 0 -4 -38 b -118 -174 -112 -174 -111 -173 b -123 -176 -119 -176 -121 -176 b -133 -174 -126 -176 -130 -174 b -296 -12 -136 -173 -172 -137 l -308 0 l -337 -34 b -375 -77 -367 -73 -370 -76 b -382 -79 -377 -79 -379 -79 b -402 -58 -393 -79 -402 -69 b -401 -49 -402 -55 -402 -52 b -224 172 -398 -43 -228 167 b -219 173 -223 172 -220 173 "},"v1f":{"x_min":-340.28125,"x_max":338.921875,"ha":346,"o":"m -32 520 b -29 521 -31 520 -31 521 b -23 519 -27 521 -24 520 b -20 513 -21 517 -20 516 b -21 506 -20 512 -20 509 b -31 474 -23 502 -27 488 l -53 402 l -66 352 l -68 349 l -57 349 b -32 351 -51 349 -40 351 b 123 370 19 352 74 359 b 137 371 127 370 133 371 b 170 356 152 371 164 366 b 171 355 170 355 170 355 b 216 366 174 355 183 358 b 280 378 268 377 266 377 b 287 378 283 378 284 378 b 332 349 307 378 322 369 b 338 319 336 341 338 330 b 332 301 338 310 336 302 b 242 280 329 299 246 280 b 242 280 242 280 242 280 b 235 288 236 280 235 283 b 235 292 235 290 235 291 b 236 302 236 297 236 299 b 220 337 236 316 230 330 l 216 340 l 210 335 b 159 276 189 322 172 301 b 118 149 152 265 156 274 b 81 34 84 36 85 36 b -8 13 78 33 -4 13 b -8 13 -8 13 -8 13 b -14 20 -12 15 -14 15 b -8 44 -14 24 -12 31 b -2 66 -5 55 -2 65 b -2 66 -2 66 -2 66 l -2 66 b -43 41 -2 66 -21 55 b -114 4 -98 8 -98 8 b -144 0 -123 0 -134 0 b -242 99 -197 0 -242 43 b -242 109 -242 102 -242 105 b -212 219 -240 122 -242 116 b -185 312 -197 270 -185 312 l -185 312 b -189 312 -185 312 -186 312 b -259 312 -200 312 -227 312 b -321 310 -291 312 -310 310 b -334 312 -330 310 -334 312 b -340 319 -338 313 -340 316 b -336 326 -340 322 -338 324 b -291 337 -334 326 -314 331 l -247 347 l -210 348 b -172 348 -190 348 -172 348 b -168 363 -172 348 -171 355 b -145 442 -151 424 -145 441 b -133 452 -144 444 -140 446 l -77 489 b -32 520 -53 506 -32 520 m 57 334 b 53 335 55 335 54 335 b 44 334 50 335 49 335 b -70 316 8 326 -28 320 b -78 309 -78 316 -78 316 b -108 202 -80 305 -88 274 b -141 81 -136 112 -141 93 b -140 74 -141 79 -141 77 b -117 49 -137 59 -127 49 b -107 52 -114 49 -110 51 b 16 127 -106 54 14 126 b 42 217 16 127 42 215 b 49 241 42 222 44 229 b 73 320 53 251 73 317 b 57 334 73 327 65 333 "},"v20":{"x_min":-571.671875,"x_max":570.3125,"ha":582,"o":"m -559 351 b -551 352 -556 352 -553 352 b -530 338 -543 352 -533 348 b -529 169 -530 337 -529 291 l -529 1 l -507 27 l -441 112 b -382 174 -394 169 -390 174 b -378 174 -381 174 -379 174 b -281 86 -370 174 -375 179 b -196 0 -234 37 -196 0 b -126 84 -196 0 -164 37 b -50 174 -55 173 -57 172 b -44 174 -49 174 -47 174 b -35 173 -42 174 -38 173 b 53 86 -32 172 -12 151 b 138 0 100 37 138 0 b 208 84 140 0 170 37 b 284 174 279 173 279 172 b 289 174 285 174 288 174 b 300 173 294 174 298 173 b 462 11 303 172 340 134 l 475 -1 l 503 34 b 541 76 534 72 536 74 b 548 77 544 77 545 77 b 570 56 560 77 570 68 b 567 48 570 54 568 51 b 392 -172 564 41 397 -166 b 378 -176 387 -174 382 -176 b 368 -174 375 -176 371 -176 b 280 -87 367 -173 347 -152 b 194 0 234 -38 194 0 b 126 -86 194 0 163 -38 b 49 -174 54 -174 55 -173 b 44 -176 47 -176 46 -176 b 34 -174 40 -176 36 -174 b -54 -87 31 -173 10 -152 b -140 0 -102 -38 -140 0 b -209 -86 -140 0 -171 -38 b -285 -174 -280 -174 -279 -173 b -291 -176 -287 -176 -288 -176 b -300 -174 -294 -176 -298 -174 b -464 -11 -303 -173 -374 -102 l -476 0 l -506 -37 b -539 -76 -528 -65 -537 -74 b -551 -80 -543 -79 -547 -80 b -570 -68 -558 -80 -566 -76 l -571 -65 l -571 136 b -570 340 -571 331 -571 337 b -559 351 -568 344 -564 348 "},"v22":{"x_min":0,"x_max":432.828125,"ha":442,"o":"m 209 186 b 213 187 210 187 212 187 b 216 187 215 187 216 187 b 224 174 216 186 220 180 b 420 -1 269 105 338 43 b 432 -12 431 -8 432 -9 b 421 -23 432 -15 432 -16 b 228 -180 345 -70 264 -137 b 219 -188 221 -188 221 -188 l 219 -188 b 208 -177 215 -188 215 -188 b 10 1 163 -106 93 -44 b 0 11 0 6 0 8 b 10 22 0 13 0 15 b 202 179 87 69 167 136 b 209 186 206 183 209 186 "},"v23":{"x_min":0,"x_max":133.390625,"ha":136,"o":"m 54 66 b 65 68 58 68 61 68 b 122 37 88 68 110 56 b 133 -1 130 26 133 12 b 104 -58 133 -23 123 -44 b 66 -69 92 -65 78 -69 b 10 -38 44 -69 23 -58 b 0 -1 2 -27 0 -13 b 54 66 0 30 20 61 "},"v25":{"x_min":0,"x_max":318.5,"ha":325,"o":"m 20 376 b 167 377 23 377 96 377 b 296 376 231 377 294 377 b 318 347 311 371 318 359 b 296 316 318 333 311 320 b 159 315 294 315 227 315 b 21 316 91 315 24 315 b 0 345 6 320 0 333 b 20 376 0 359 6 371 "},"v26":{"x_min":-21.78125,"x_max":483.1875,"ha":493,"o":"m -8 631 b -1 632 -6 632 -4 632 b 19 620 8 632 16 628 b 20 383 20 616 20 616 l 20 148 l 21 151 b 140 199 59 183 102 199 b 206 179 164 199 187 192 l 210 176 l 210 396 l 210 617 l 212 621 b 231 632 216 628 223 632 b 250 620 239 632 247 628 b 251 383 251 616 251 616 l 251 148 l 254 151 b 370 199 291 183 332 199 b 415 191 385 199 400 197 b 483 84 458 176 483 134 b 461 0 483 58 476 29 b 332 -142 439 -40 411 -72 l 255 -215 b 231 -229 240 -229 239 -229 b 216 -223 224 -229 220 -227 b 210 -158 210 -217 210 -223 b 210 -120 210 -148 210 -136 l 210 -29 l 205 -34 b 100 -142 182 -65 159 -88 l 23 -215 b -1 -229 9 -229 6 -229 b -20 -216 -9 -229 -17 -224 l -21 -212 l -21 201 l -21 616 l -20 620 b -8 631 -17 624 -13 630 m 110 131 b 96 133 106 133 100 133 b 89 133 93 133 91 133 b 24 87 63 129 40 113 l 20 80 l 20 -37 l 20 -156 l 23 -152 b 144 81 96 -72 144 20 l 144 83 b 110 131 144 113 134 126 m 341 131 b 328 133 337 133 332 133 b 322 133 326 133 323 133 b 257 87 296 129 273 113 l 251 80 l 251 -37 l 251 -156 l 255 -152 b 375 81 328 -72 375 20 l 375 83 b 341 131 375 113 367 126 "},"v27":{"x_min":0,"x_max":432.828125,"ha":442,"o":"m 208 184 b 213 187 209 186 212 187 b 224 176 217 187 221 183 b 245 147 225 172 235 159 b 419 -1 288 90 347 38 b 431 -8 424 -4 431 -8 b 432 -12 432 -9 432 -11 b 430 -18 432 -13 432 -16 b 364 -61 424 -20 383 -47 b 225 -183 307 -102 250 -152 b 223 -187 224 -184 223 -187 b 220 -188 221 -188 220 -188 b 208 -176 216 -188 210 -184 b 187 -148 205 -173 197 -159 b 12 0 144 -90 84 -38 b 0 11 4 5 0 8 b 16 24 0 13 4 18 b 183 158 83 69 141 115 b 208 184 194 169 198 173 m 183 105 b 176 113 181 109 176 113 b 172 109 176 113 175 112 b 92 45 149 90 117 62 l 88 41 l 102 31 b 247 -105 160 -6 210 -55 l 254 -115 l 257 -112 l 269 -102 b 340 -45 287 -87 319 -61 l 344 -43 l 330 -33 b 183 105 272 6 221 54 "},"v28":{"x_min":-73.5,"x_max":72.140625,"ha":74,"o":"m -72 252 l -73 254 l 0 254 l 72 254 l 70 252 b 0 -1 70 248 0 -1 b -72 252 -1 -1 -72 248 "},"v29":{"x_min":-590.71875,"x_max":589.359375,"ha":601,"o":"m 175 273 b 182 274 178 273 181 274 b 202 262 190 274 198 269 b 204 158 204 259 204 259 l 204 56 l 250 112 b 303 174 296 172 298 172 b 308 174 304 174 307 174 b 318 173 313 174 317 173 b 481 11 322 172 357 134 l 494 -1 l 522 34 b 560 76 553 72 555 74 b 567 77 563 77 564 77 b 589 56 579 77 589 68 b 586 48 589 54 588 51 b 411 -172 583 41 416 -166 b 397 -176 406 -174 401 -176 b 387 -174 393 -176 390 -176 b 299 -87 386 -173 366 -152 b 213 0 253 -38 213 0 b 208 -6 213 0 210 -2 l 204 -12 l 204 -147 b 204 -210 204 -173 204 -194 b 198 -292 204 -297 204 -287 b 183 -299 194 -297 189 -299 b 164 -287 175 -299 167 -295 b 163 -174 163 -284 163 -284 l 161 -63 l 119 -117 b 65 -176 76 -170 73 -176 b 61 -176 63 -176 62 -176 b -35 -87 51 -174 57 -180 b -121 0 -83 -38 -121 0 b -190 -86 -122 0 -152 -38 b -266 -174 -261 -174 -259 -173 b -272 -176 -268 -176 -270 -176 b -281 -174 -276 -176 -280 -174 b -371 -86 -284 -173 -304 -152 b -457 0 -417 -38 -457 0 l -457 0 b -477 -26 -457 0 -470 -16 b -548 -227 -524 -88 -548 -161 b -536 -303 -548 -254 -544 -280 b -533 -317 -534 -309 -533 -313 b -553 -338 -533 -330 -541 -338 b -577 -315 -566 -338 -571 -333 b -590 -227 -586 -287 -590 -258 b -518 -9 -590 -154 -564 -77 b -465 56 -509 2 -504 8 l -402 134 b -363 174 -374 170 -371 174 b -359 174 -362 174 -360 174 b -262 86 -351 174 -356 179 b -176 0 -216 37 -176 0 b -107 84 -176 0 -145 37 b -31 174 -36 173 -38 172 b -25 174 -29 174 -28 174 b -16 173 -23 174 -19 173 b 147 11 -13 172 35 123 l 157 -1 l 160 1 l 163 4 l 163 130 b 164 260 163 256 163 258 b 175 273 166 266 170 270 "},"v2a":{"x_min":-21.78125,"x_max":366.140625,"ha":374,"o":"m 276 1378 b 284 1379 279 1379 281 1379 b 306 1360 292 1379 298 1374 b 352 1247 326 1326 343 1286 b 366 1139 362 1213 366 1175 b 347 1009 366 1093 359 1049 l 344 1002 l 347 992 b 352 971 348 986 351 977 b 366 863 362 936 366 899 b 347 732 366 818 359 773 l 344 725 l 347 716 b 352 695 348 710 351 700 b 366 588 362 659 366 623 b 223 262 366 464 314 345 b 189 233 212 252 212 252 b 35 76 126 183 73 129 b -1 16 20 56 2 27 b -19 4 -4 9 -12 4 l -21 4 l -21 137 l -21 270 l -17 270 b 186 344 59 281 134 308 b 319 606 270 399 319 499 b 317 650 319 620 319 635 l 315 659 l 314 655 b 223 537 288 607 258 570 b 189 509 212 528 212 528 b 35 352 126 459 73 405 b -1 292 20 333 2 303 b -19 280 -4 285 -12 280 l -21 280 l -21 413 l -21 546 l -17 546 b 186 620 59 557 134 584 b 319 882 270 675 319 775 b 317 925 319 896 319 911 l 315 935 l 314 931 b 223 813 288 884 258 846 b 189 785 212 805 212 805 b 35 628 126 735 73 681 b -1 569 20 609 2 580 b -19 556 -4 562 -12 556 l -21 556 l -21 689 l -21 823 l -17 823 b 202 907 68 835 152 867 b 319 1157 280 968 319 1061 b 270 1338 319 1218 303 1281 b 262 1358 264 1349 262 1353 b 262 1364 262 1360 262 1363 b 276 1378 265 1371 269 1376 "},"v2c":{"x_min":-597.53125,"x_max":596.171875,"ha":608,"o":"m -413 173 b -408 174 -412 174 -409 174 b -397 173 -404 174 -400 173 b -308 86 -394 172 -374 151 b -223 0 -261 37 -223 0 b -153 84 -223 0 -191 37 b -77 174 -83 173 -84 172 b -72 174 -76 174 -74 174 b -62 173 -68 174 -63 173 b 25 86 -59 172 -39 151 b 112 0 73 37 111 0 b 181 84 112 0 144 37 b 257 174 251 173 251 172 b 262 174 258 174 261 174 b 273 173 266 174 270 173 b 436 9 276 172 347 101 l 447 -1 l 477 36 b 522 79 511 79 513 79 l 522 79 b 552 51 533 79 539 73 b 596 -112 582 6 596 -51 b 567 -262 596 -161 586 -213 b 539 -322 558 -287 544 -316 b 524 -327 534 -326 529 -327 b 504 -315 515 -327 507 -323 b 503 -308 503 -312 503 -309 b 511 -285 503 -302 504 -297 b 555 -113 540 -227 555 -169 b 544 -34 555 -86 551 -59 b 522 19 540 -16 530 8 l 521 22 l 481 -26 l 405 -122 b 353 -176 366 -172 362 -176 b 349 -176 352 -176 351 -176 b 253 -87 341 -176 347 -180 b 167 0 206 -38 167 0 b 99 -86 167 0 136 -38 b 21 -174 27 -174 28 -173 b 17 -176 20 -176 19 -176 b 6 -174 13 -176 9 -174 b -81 -87 4 -173 -14 -152 b -167 0 -129 -38 -167 0 b -236 -86 -167 0 -198 -38 b -313 -174 -307 -174 -306 -173 b -318 -176 -314 -176 -315 -176 b -328 -174 -321 -176 -325 -174 b -491 -12 -330 -173 -367 -137 l -503 0 l -530 -34 b -570 -77 -562 -73 -564 -76 b -577 -79 -571 -79 -574 -79 b -597 -58 -588 -79 -597 -69 b -596 -49 -597 -55 -597 -52 b -417 172 -593 -43 -423 167 b -413 173 -417 172 -415 173 "},"v2d":{"x_min":0,"x_max":438.28125,"ha":447,"o":"m 212 190 b 219 191 213 191 216 191 b 236 176 225 191 228 190 b 419 18 277 105 341 49 b 436 5 431 13 434 11 b 438 -1 438 4 438 1 b 424 -16 438 -8 432 -13 b 356 -49 409 -20 379 -36 b 234 -180 306 -83 258 -133 b 219 -192 230 -188 224 -192 b 200 -176 213 -192 206 -187 b 9 -15 157 -102 89 -45 b 0 0 2 -12 0 -6 b 16 18 0 9 2 12 b 200 176 93 48 159 104 b 212 190 205 186 208 188 m 239 113 b 236 117 238 116 238 117 b 230 108 235 117 234 115 b 92 -15 196 58 140 8 b 88 -18 91 -16 88 -18 b 92 -20 88 -18 91 -19 b 198 -116 130 -43 166 -74 b 200 -117 200 -117 200 -117 b 201 -117 200 -117 201 -117 b 264 -43 212 -98 242 -62 b 345 15 288 -19 321 4 b 348 18 347 16 348 16 b 344 20 348 18 347 19 b 239 113 307 41 266 79 "},"v2f":{"x_min":-1.359375,"x_max":680.5625,"ha":694,"o":"m 597 1042 b 604 1042 600 1042 602 1042 b 642 1002 627 1042 642 1022 b 619 966 642 988 635 974 b 439 927 574 942 503 927 l 426 927 l 426 921 b 430 838 428 893 430 866 b 345 480 430 696 398 560 b 179 391 307 423 249 391 b 156 392 171 391 164 392 b 138 394 149 394 142 394 b 103 434 115 396 103 416 b 129 471 103 451 111 466 b 141 474 133 473 137 474 b 172 459 153 474 164 469 b 181 455 175 456 176 455 b 187 456 182 455 185 455 b 253 520 212 460 234 483 b 315 836 294 605 315 714 b 311 928 315 867 314 898 b 302 945 310 943 311 942 b 245 953 283 950 262 953 b 130 891 193 953 149 931 b 84 860 119 870 102 860 b 36 905 61 860 39 877 b 36 910 36 907 36 909 b 80 970 36 931 50 949 b 249 1017 125 1000 187 1017 b 322 1009 273 1017 299 1014 l 341 1003 b 436 991 372 995 406 991 b 577 1031 495 991 545 1004 b 597 1042 583 1038 590 1041 m 416 360 b 424 360 419 360 421 360 b 481 309 454 360 479 338 b 503 145 484 280 495 199 b 585 -185 525 16 555 -106 b 630 -245 596 -213 613 -237 l 634 -247 l 638 -245 b 647 -244 641 -245 645 -244 b 680 -278 666 -244 680 -262 b 664 -308 680 -290 675 -301 b 638 -312 658 -310 650 -312 b 613 -309 631 -312 623 -310 b 477 -201 555 -303 502 -260 b 417 -2 460 -159 434 -72 b 416 5 417 1 416 5 b 416 5 416 5 416 5 b 411 -5 415 5 413 0 b 359 -97 397 -33 377 -70 b 353 -106 355 -102 353 -105 b 359 -112 353 -108 355 -109 b 409 -130 375 -123 390 -129 b 426 -134 420 -130 421 -131 b 431 -147 428 -137 431 -141 b 420 -162 431 -152 427 -159 b 382 -169 409 -166 396 -169 b 323 -155 363 -169 341 -165 l 317 -152 l 314 -155 b 62 -303 240 -240 148 -295 b 36 -305 55 -305 44 -305 b 23 -303 29 -305 24 -305 b -1 -273 6 -299 -1 -287 b 31 -240 -1 -256 10 -240 b 36 -240 32 -240 34 -240 b 42 -241 38 -241 39 -241 b 134 -204 63 -241 99 -226 b 367 288 265 -115 357 81 b 375 330 368 313 370 320 b 416 360 383 347 400 358 m 360 -359 b 379 -359 363 -359 371 -359 b 424 -360 396 -359 416 -359 b 646 -502 536 -373 624 -430 b 649 -527 649 -510 649 -519 b 530 -673 649 -578 604 -635 l 521 -677 l 529 -681 b 653 -811 592 -714 637 -762 b 660 -853 658 -827 660 -839 b 645 -911 660 -873 656 -892 b 426 -1021 608 -981 519 -1021 b 283 -989 377 -1021 328 -1011 b 235 -949 249 -972 239 -964 b 234 -936 234 -946 234 -941 b 234 -928 234 -934 234 -931 l 235 -925 l 234 -927 l 225 -934 b 87 -982 186 -966 138 -982 b 80 -982 85 -982 83 -982 b 55 -981 70 -981 58 -981 b 17 -943 32 -981 17 -964 b 54 -904 17 -921 35 -904 b 78 -914 62 -904 72 -909 l 83 -918 l 88 -918 b 190 -831 122 -918 166 -881 b 269 -506 242 -727 269 -612 b 268 -462 269 -492 269 -477 b 266 -449 266 -458 266 -452 b 265 -444 266 -445 266 -444 b 257 -446 264 -444 261 -445 b 132 -545 196 -470 152 -505 b 88 -573 122 -563 104 -573 b 39 -523 63 -573 39 -553 b 63 -476 39 -505 44 -494 b 360 -359 136 -408 235 -369 m 419 -424 b 393 -423 411 -423 406 -423 l 375 -423 l 377 -426 b 379 -439 377 -427 378 -434 b 383 -510 382 -463 383 -487 b 314 -811 383 -609 360 -710 b 266 -893 296 -850 285 -870 b 264 -898 265 -896 264 -898 l 264 -898 b 264 -898 264 -898 264 -898 b 268 -898 264 -898 266 -898 b 273 -898 270 -898 272 -898 b 300 -909 283 -898 291 -900 b 426 -957 340 -941 385 -957 b 476 -949 443 -957 460 -954 b 547 -853 522 -931 547 -893 b 485 -745 547 -816 526 -775 b 397 -707 460 -727 432 -714 b 366 -675 375 -703 366 -692 b 396 -642 366 -657 377 -645 b 530 -557 455 -637 511 -601 b 536 -527 534 -548 536 -537 b 419 -424 536 -480 490 -437 "},"v30":{"x_min":-21.78125,"x_max":367.5,"ha":375,"o":"m 276 1900 b 284 1901 279 1900 281 1901 b 306 1883 291 1901 298 1896 b 367 1686 347 1825 367 1757 b 343 1558 367 1643 359 1600 l 338 1549 l 343 1537 b 367 1411 359 1497 367 1454 b 343 1282 367 1367 359 1324 l 338 1272 l 343 1261 b 367 1135 359 1221 367 1178 b 343 1007 367 1090 359 1047 l 338 996 l 343 985 b 367 859 359 945 367 902 b 343 731 367 814 359 771 l 338 720 l 343 709 b 367 582 359 667 367 626 b 289 362 367 503 340 426 b 239 312 276 345 259 330 b 29 77 152 237 76 152 b -1 18 14 54 2 30 b -19 4 -4 11 -12 4 l -21 4 l -21 133 l -20 260 l -13 262 b 98 299 17 269 62 284 b 111 305 103 302 110 305 b 167 334 123 310 156 327 b 319 595 264 391 319 491 b 313 659 319 616 318 638 b 310 667 311 664 311 667 b 307 663 310 667 308 666 b 240 588 289 637 269 614 b 16 331 141 505 62 413 b -1 294 8 316 1 302 b -19 280 -4 287 -12 280 l -21 280 l -21 408 l -20 537 l -13 538 b 98 576 17 545 62 560 b 111 581 103 578 110 581 b 167 610 123 587 156 603 b 319 871 264 667 319 767 b 313 935 319 892 318 913 b 310 942 311 941 311 942 b 307 939 310 942 308 941 b 240 864 289 913 269 889 b 16 607 141 781 62 689 b -1 570 8 592 1 578 b -19 556 -4 563 -12 556 l -21 556 l -21 684 l -20 813 l -13 814 b 98 852 17 821 62 836 b 111 857 103 855 110 857 b 167 886 123 863 156 880 b 319 1147 264 943 319 1043 b 313 1211 319 1168 318 1189 b 310 1218 311 1217 311 1218 b 307 1215 310 1218 308 1217 b 240 1140 289 1188 269 1165 b 16 884 141 1057 62 966 b -1 846 8 868 1 855 b -19 832 -4 839 -12 832 l -21 832 l -21 960 l -20 1089 l -13 1090 b 98 1128 17 1097 62 1111 b 111 1134 103 1131 110 1134 b 167 1163 123 1139 156 1156 b 319 1424 264 1220 319 1320 b 313 1486 319 1444 318 1465 b 310 1494 311 1493 311 1494 b 307 1492 310 1494 308 1493 b 240 1417 289 1464 269 1442 b 16 1160 141 1333 62 1242 b -1 1121 8 1145 1 1131 b -19 1109 -4 1115 -12 1109 l -21 1109 l -21 1236 l -20 1365 l -13 1367 b 98 1404 17 1374 62 1388 b 111 1410 103 1407 110 1410 b 250 1508 172 1437 215 1467 b 319 1701 296 1564 319 1633 b 270 1859 319 1757 303 1814 b 262 1882 265 1868 262 1875 b 276 1900 262 1890 266 1896 "},"v31":{"x_min":0,"x_max":386.5625,"ha":394,"o":"m 0 173 l 0 347 l 193 347 l 386 347 l 386 173 l 386 0 l 193 0 l 0 0 l 0 173 "},"v33":{"x_min":-423.3125,"x_max":421.9375,"ha":431,"o":"m -10 276 b -2 277 -8 277 -5 277 b 17 265 5 277 13 273 b 19 163 19 260 19 260 l 19 68 l 39 45 b 277 -95 122 -34 200 -81 b 289 -97 281 -97 285 -97 b 378 0 332 -97 371 -54 b 378 11 378 4 378 6 b 302 83 378 55 345 83 b 242 66 283 83 262 77 b 208 56 231 59 219 56 b 148 120 175 56 148 81 b 200 186 148 151 164 172 b 261 198 220 194 240 198 b 420 45 341 198 411 137 b 421 22 421 37 421 29 b 257 -198 421 -86 347 -188 b 242 -198 251 -198 247 -198 b 20 -105 181 -198 95 -163 l 19 -104 l 19 -183 b 19 -216 19 -195 19 -206 b 12 -273 19 -272 17 -267 b -2 -278 8 -277 2 -278 b -21 -266 -10 -278 -19 -274 b -23 -165 -23 -263 -23 -262 l -23 -69 l -44 -47 b -250 86 -117 23 -183 66 b -295 94 -270 93 -284 94 b -315 91 -302 94 -308 94 b -381 5 -356 81 -381 43 b -355 -56 -381 -16 -372 -40 b -299 -81 -338 -73 -319 -81 b -246 -68 -283 -81 -265 -77 b -212 -58 -234 -61 -223 -58 b -168 -77 -196 -58 -179 -65 b -151 -122 -156 -90 -151 -105 b -179 -174 -151 -141 -160 -162 b -239 -195 -194 -184 -217 -192 b -257 -197 -245 -195 -250 -197 b -423 -5 -349 -197 -423 -113 b -423 0 -423 -4 -423 -1 b -277 194 -420 97 -362 173 b -247 197 -268 197 -258 197 b -24 104 -185 197 -100 162 l -23 102 l -23 181 b -21 265 -23 260 -23 260 b -10 276 -20 269 -14 274 "},"v34":{"x_min":0,"x_max":622.03125,"ha":635,"o":"m 398 417 b 406 419 401 419 404 419 b 427 398 417 419 427 409 b 427 391 427 395 427 392 b 34 -274 424 385 38 -272 b 20 -280 29 -278 25 -280 b 0 -259 9 -280 0 -270 b 0 -252 0 -256 0 -254 b 393 413 2 -247 389 410 b 398 417 394 415 397 416 m 592 417 b 600 419 594 419 597 419 b 622 398 611 419 622 409 b 620 391 622 395 620 392 b 227 -274 617 385 231 -272 b 213 -280 223 -278 219 -280 b 193 -259 202 -280 193 -270 b 194 -252 193 -256 193 -254 b 586 413 196 -247 582 410 b 592 417 588 415 590 416 "},"v36":{"x_min":-1.359375,"x_max":1064.390625,"ha":1086,"o":"m 296 692 b 314 694 302 694 307 694 b 386 685 337 694 366 689 b 548 498 480 660 548 580 b 548 481 548 492 548 487 b 455 395 541 426 499 395 b 370 462 420 395 383 417 b 362 496 364 477 362 488 b 377 514 362 509 367 514 b 393 501 386 514 390 510 b 432 474 397 484 413 474 b 470 487 445 474 458 478 b 491 530 484 496 491 510 b 490 544 491 534 491 539 b 333 660 479 606 411 657 l 323 662 l 315 646 b 269 524 285 591 269 556 b 321 431 269 492 287 466 b 349 395 338 413 343 408 b 363 342 359 378 363 362 b 359 312 363 333 362 322 b 285 158 348 266 318 206 b 281 152 283 155 281 152 b 281 152 281 152 281 152 b 287 154 283 152 284 152 b 318 155 298 154 308 155 b 461 98 371 155 419 136 l 464 97 l 483 112 b 503 129 494 120 503 127 b 504 130 503 129 504 129 b 503 138 504 131 503 134 b 500 180 500 152 500 166 b 553 326 500 238 518 288 b 604 366 560 331 592 358 b 649 381 617 376 632 381 b 696 362 665 381 681 374 b 724 302 714 347 724 324 b 695 238 724 278 714 255 b 660 210 691 234 662 212 b 579 148 658 209 582 151 b 579 148 579 148 579 148 b 596 106 579 144 589 119 b 622 77 604 88 609 83 b 657 69 632 72 645 69 b 748 112 688 69 721 84 b 755 123 754 117 755 120 b 755 127 755 124 755 126 b 751 165 752 137 751 151 b 758 219 751 183 754 202 b 894 387 774 290 820 347 b 896 390 896 388 896 388 b 891 398 896 391 895 392 b 622 560 827 477 730 535 b 600 580 605 564 600 569 b 617 596 600 591 607 596 b 628 595 622 596 624 596 b 1057 248 846 552 1020 412 b 1064 191 1061 229 1064 209 b 922 0 1064 94 1005 9 b 902 -1 916 -1 909 -1 b 774 76 847 -1 800 26 b 769 83 770 81 770 83 b 769 81 769 83 769 83 b 627 -1 733 29 677 -1 b 548 27 597 -1 570 8 b 515 88 537 37 525 61 l 513 95 l 510 93 l 453 45 b 390 0 396 0 396 0 b 390 0 390 0 390 0 b 374 15 381 0 377 4 b 268 105 359 69 314 105 b 250 104 262 105 257 105 l 243 102 l 234 90 b 155 1 201 49 159 2 b 147 -1 152 0 149 -1 b 130 15 138 -1 130 6 b 132 20 130 18 132 19 b 136 31 133 22 134 27 b 220 131 149 74 178 109 b 231 137 225 134 230 136 b 302 278 280 202 302 244 b 265 335 302 299 295 309 b 209 442 234 363 213 402 b 209 455 209 446 209 451 b 279 648 209 502 232 564 l 285 659 l 283 659 b 176 627 238 653 210 645 b 57 477 111 594 66 538 b 55 459 55 471 55 464 b 72 409 55 437 61 415 b 93 403 78 405 87 403 b 152 467 123 403 151 431 b 168 488 153 483 157 488 b 185 462 181 488 185 483 l 185 460 b 137 344 183 409 168 369 b 78 322 119 328 98 322 b 13 360 50 322 25 335 b -1 426 4 380 -1 402 b 89 610 -1 488 32 559 b 296 692 147 659 210 685 m 926 348 b 921 353 924 351 922 353 b 914 348 920 353 918 351 b 823 167 857 306 823 237 b 828 124 823 154 826 138 b 890 31 837 79 862 40 b 896 31 892 31 894 31 b 956 104 916 31 940 59 b 970 191 965 129 970 159 b 966 241 970 208 969 224 b 926 348 959 277 945 313 m 627 326 b 619 326 624 326 622 326 b 598 316 611 326 604 323 b 568 215 579 288 568 255 b 568 208 568 213 568 210 b 571 183 570 195 570 184 l 571 183 b 594 201 571 183 582 191 l 634 231 b 660 259 653 247 656 248 b 664 278 662 266 664 272 b 627 326 664 299 649 320 "},"v38":{"x_min":-1.359375,"x_max":651.96875,"ha":665,"o":"m 389 644 b 405 645 394 645 400 645 b 504 566 450 645 492 613 b 507 541 506 557 507 549 b 480 471 507 514 498 489 l 477 467 l 483 470 b 609 591 539 485 586 531 b 613 601 611 595 613 599 b 631 609 619 607 624 609 b 651 588 641 609 651 602 b 200 -946 651 584 204 -941 b 182 -957 197 -953 190 -957 b 163 -945 174 -957 166 -953 b 161 -939 161 -942 161 -942 b 217 -743 161 -931 170 -904 b 272 -555 247 -639 272 -555 b 272 -555 272 -555 272 -555 b 264 -560 272 -555 268 -557 b 140 -603 227 -589 182 -603 b 36 -567 102 -603 65 -592 b -1 -487 12 -548 -1 -517 b 17 -427 -1 -466 5 -445 b 103 -380 38 -395 70 -380 b 191 -433 137 -380 172 -398 b 205 -484 201 -448 205 -466 b 178 -553 205 -509 196 -535 l 175 -557 l 182 -555 b 307 -435 236 -539 284 -494 b 372 -213 308 -430 372 -215 b 372 -213 372 -213 372 -213 b 364 -219 372 -213 368 -216 b 240 -262 328 -247 283 -262 b 137 -226 202 -262 166 -249 b 99 -145 112 -206 99 -176 b 118 -84 99 -124 106 -104 b 204 -38 138 -54 171 -38 b 292 -91 238 -38 273 -56 b 306 -141 302 -106 306 -124 b 279 -212 306 -167 296 -194 l 276 -215 l 281 -213 b 408 -93 336 -198 385 -151 b 473 129 409 -88 473 127 b 473 129 473 129 473 129 b 465 122 473 129 469 126 b 341 80 428 94 383 80 b 236 115 303 80 266 91 b 200 195 213 136 200 165 b 217 256 200 217 206 238 b 304 303 239 287 272 303 b 393 249 338 303 374 285 b 406 199 402 234 406 217 b 379 129 406 173 397 148 l 377 126 l 382 127 b 509 248 436 142 485 190 b 574 470 510 254 574 469 b 574 470 574 470 574 470 b 566 464 574 470 570 467 b 442 421 529 435 484 421 b 337 458 404 421 367 433 b 300 537 313 478 300 508 b 389 644 300 585 334 635 "},"v3b":{"x_min":0,"x_max":484.5625,"ha":494,"o":"m 228 245 b 239 247 234 247 239 247 b 243 247 240 247 242 247 b 303 238 257 247 287 242 b 484 -2 417 208 484 104 b 412 -177 484 -65 461 -127 b 243 -248 363 -226 303 -248 b 6 -63 138 -248 36 -180 b 0 -1 1 -41 0 -20 b 228 245 0 127 98 240 m 255 181 b 240 183 247 183 245 183 b 232 181 238 183 235 183 b 142 152 200 180 168 170 l 138 149 l 190 97 l 242 44 l 294 97 l 345 149 l 340 152 b 255 181 315 169 284 180 m 147 -54 l 197 -1 l 147 51 l 95 104 l 91 99 b 62 -1 72 70 62 34 b 66 -43 62 -15 63 -29 b 91 -101 72 -63 80 -84 l 95 -106 l 147 -54 m 393 99 b 389 104 390 102 389 104 b 337 51 389 104 366 80 l 285 -1 l 337 -54 l 389 -106 l 393 -101 b 421 -1 412 -72 421 -36 b 393 99 421 34 412 69 m 294 -98 b 242 -45 265 -69 242 -45 b 190 -98 242 -45 219 -69 l 138 -151 l 142 -154 b 242 -184 172 -174 206 -184 b 340 -154 276 -184 311 -174 l 345 -151 l 294 -98 "},"v3c":{"x_min":0,"x_max":450.53125,"ha":460,"o":"m 189 302 b 204 303 193 302 198 303 b 303 224 250 303 292 270 b 306 199 304 216 306 208 b 279 129 306 173 296 147 l 276 126 l 281 127 b 408 249 337 142 385 190 b 412 259 409 254 412 258 b 430 267 417 265 423 267 b 450 247 441 267 450 259 b 200 -605 450 242 204 -599 b 182 -616 197 -612 190 -616 b 163 -602 174 -616 166 -610 b 161 -598 161 -601 161 -601 b 217 -402 161 -589 170 -562 b 272 -213 247 -298 272 -213 b 272 -213 272 -213 272 -213 b 264 -219 272 -213 268 -216 b 140 -262 227 -247 182 -262 b 36 -226 102 -262 65 -249 b 0 -145 12 -206 0 -176 b 17 -84 0 -124 5 -104 b 103 -38 38 -54 70 -38 b 191 -91 137 -38 172 -56 b 205 -141 201 -106 205 -124 b 178 -212 205 -167 196 -194 l 175 -215 l 182 -213 b 307 -93 236 -198 284 -151 b 372 129 308 -88 372 127 b 372 129 372 129 372 129 b 364 122 372 129 368 126 b 240 80 328 94 283 80 b 137 115 202 80 166 91 b 99 194 111 136 99 165 b 189 302 99 244 133 292 "},"v3e":{"x_min":0,"x_max":406.96875,"ha":415,"o":"m 21 183 b 28 183 24 183 25 183 b 42 181 34 183 39 183 b 127 108 47 179 47 179 b 202 41 168 72 202 41 b 279 108 204 41 238 72 b 357 177 321 145 356 176 b 375 183 363 181 370 183 b 406 151 392 183 406 169 b 404 137 406 147 405 141 b 322 62 401 131 398 129 b 251 0 284 27 251 0 b 322 -63 251 -1 284 -29 b 404 -138 398 -130 401 -133 b 406 -152 405 -142 406 -148 b 375 -184 406 -170 392 -184 b 357 -179 370 -184 363 -183 b 279 -109 356 -177 321 -147 b 202 -43 238 -73 204 -43 b 127 -109 202 -43 168 -73 b 49 -179 85 -147 50 -177 b 31 -184 43 -183 36 -184 b 0 -152 13 -184 0 -170 b 2 -138 0 -148 0 -142 b 83 -63 5 -133 8 -130 b 155 0 122 -29 155 -1 b 83 62 155 0 122 27 b 8 129 43 97 10 127 b 0 151 2 136 0 144 b 21 183 0 165 8 177 "},"v3f":{"x_min":-24.5,"x_max":317.140625,"ha":324,"o":"m -24 -147 l -24 -5 l -20 -5 b -1 -19 -12 -5 -4 -11 b 58 -123 6 -43 31 -86 b 196 -278 93 -173 134 -219 b 317 -570 274 -356 317 -460 b 294 -713 317 -617 308 -666 l 289 -724 l 294 -735 b 317 -873 308 -780 317 -827 b 235 -1132 317 -963 288 -1054 b 209 -1165 228 -1140 224 -1146 b 189 -1177 204 -1172 196 -1177 b 171 -1164 182 -1177 175 -1172 b 168 -1154 170 -1161 168 -1159 b 181 -1132 168 -1149 172 -1142 b 269 -891 238 -1064 269 -975 b 269 -881 269 -886 269 -884 b 262 -814 269 -857 265 -827 b 258 -800 261 -811 259 -806 b 142 -628 240 -731 198 -667 b -8 -589 112 -606 47 -589 b -20 -589 -13 -589 -19 -589 l -24 -589 l -24 -449 l -24 -308 l -20 -308 b -1 -322 -12 -308 -4 -313 b 58 -424 6 -345 31 -388 b 194 -580 93 -476 136 -523 b 259 -660 221 -606 245 -635 b 261 -663 259 -662 261 -663 b 264 -656 262 -663 262 -660 b 269 -587 268 -632 269 -610 b 264 -521 269 -566 268 -544 b 262 -512 264 -517 262 -513 b 258 -498 261 -509 259 -503 b 142 -326 240 -428 198 -365 b -8 -287 112 -303 47 -288 b -20 -287 -13 -287 -19 -287 l -24 -287 l -24 -147 "},"v40":{"x_min":-1.359375,"x_max":436.921875,"ha":446,"o":"m 213 205 b 217 205 215 205 216 205 b 234 194 224 205 234 199 b 236 187 234 194 235 190 l 245 167 l 261 129 l 270 106 b 355 -61 294 54 329 -13 b 420 -163 381 -105 402 -138 b 436 -188 435 -184 436 -184 b 436 -191 436 -190 436 -190 b 421 -206 436 -201 431 -206 l 421 -206 l 416 -206 l 405 -201 b 217 -158 347 -172 283 -158 b 31 -201 153 -158 88 -172 l 20 -206 l 14 -206 l 14 -206 b 0 -191 5 -206 0 -201 b -1 -188 0 -190 -1 -190 b 14 -163 -1 -186 0 -184 b 95 -34 36 -136 72 -77 b 166 106 119 8 148 68 l 175 129 l 183 148 l 200 188 b 213 205 205 199 208 202 "},"v41":{"x_min":-1.359375,"x_max":556.6875,"ha":568,"o":"m 294 322 b 318 323 299 322 308 323 b 360 320 334 323 352 322 b 526 217 430 310 490 273 b 543 166 537 202 543 184 b 447 70 543 117 503 70 b 445 70 447 70 446 70 b 359 159 394 72 359 113 b 368 201 359 173 362 187 b 442 245 382 229 412 245 b 455 244 446 245 451 245 b 460 244 458 244 460 244 b 460 244 460 244 460 244 b 454 248 460 244 458 245 b 325 291 417 276 372 291 b 285 287 313 291 299 290 b 144 -2 183 269 144 190 b 281 -290 144 -208 179 -280 b 304 -291 289 -291 298 -291 b 524 -105 412 -291 506 -212 b 541 -84 526 -88 530 -84 b 556 -101 551 -84 556 -90 b 549 -138 556 -111 553 -122 b 334 -322 521 -237 435 -310 b 302 -324 323 -323 313 -324 b 13 -101 172 -324 54 -234 b -1 -1 4 -68 -1 -34 b 294 322 -1 161 121 303 "},"v42":{"x_min":-348.4375,"x_max":24.5,"ha":25,"o":"m -330 155 b -322 156 -329 156 -326 156 b -315 156 -319 156 -317 156 b -298 147 -311 155 -308 154 b -19 30 -224 98 -122 55 l 2 26 b 24 -1 17 22 24 13 b 2 -27 24 -15 17 -23 l -19 -31 b -298 -148 -122 -56 -224 -99 b -322 -158 -313 -158 -315 -158 b -348 -131 -338 -158 -348 -145 b -344 -117 -348 -127 -347 -122 b -328 -104 -341 -112 -338 -111 b -127 -8 -269 -65 -202 -33 b -106 0 -115 -4 -106 -1 b -127 6 -106 0 -115 2 b -328 102 -202 31 -269 63 b -344 116 -338 109 -341 111 b -348 130 -347 120 -348 124 b -330 155 -348 141 -341 152 "},"v43":{"x_min":-442.359375,"x_max":441,"ha":450,"o":"m -31 487 b -1 488 -21 488 -10 488 b 434 104 216 488 397 330 b 441 27 438 79 441 47 b 439 12 441 20 439 15 b 419 0 435 4 427 0 b 404 5 413 0 408 1 b 398 30 400 11 398 13 b 0 351 390 213 213 351 b -59 348 -20 351 -39 349 b -400 30 -251 324 -393 191 b -405 5 -400 13 -401 11 b -420 0 -409 1 -415 0 b -441 12 -428 0 -436 4 b -442 27 -441 15 -442 20 b -435 104 -442 47 -439 79 b -31 487 -401 316 -235 474 m -13 131 b -1 133 -9 133 -5 133 b 51 105 19 133 39 123 b 61 70 58 95 61 83 b 51 34 61 58 58 45 b -1 6 39 16 19 6 b -46 27 -17 6 -34 13 b -62 69 -57 38 -62 54 b -13 131 -62 98 -44 124 "},"v44":{"x_min":-21.78125,"x_max":251.8125,"ha":257,"o":"m -8 631 b -1 632 -6 632 -4 632 b 19 620 8 632 16 628 b 20 383 20 616 20 616 l 20 148 l 21 151 b 137 199 59 183 99 199 b 182 191 152 199 167 197 b 251 84 227 176 251 134 b 228 0 251 58 243 29 b 100 -142 206 -40 178 -72 l 23 -215 b 0 -229 9 -229 6 -229 b -20 -216 -9 -229 -17 -224 l -21 -212 l -21 201 l -21 616 l -20 620 b -8 631 -17 624 -13 630 m 110 131 b 96 133 106 133 100 133 b 89 133 93 133 91 133 b 24 87 63 129 40 113 l 20 80 l 20 -37 l 20 -156 l 23 -152 b 144 81 96 -72 144 20 l 144 83 b 110 131 144 113 134 126 "},"v45":{"x_min":-402.890625,"x_max":401.53125,"ha":410,"o":"m -10 273 b -4 274 -9 273 -6 274 b 16 262 4 274 12 269 b 17 158 17 259 17 259 l 17 56 l 62 112 b 117 174 110 172 110 172 b 122 174 118 174 119 174 b 132 173 125 174 129 173 b 295 11 134 172 171 134 l 307 -1 l 336 34 b 374 76 366 72 368 74 b 381 77 375 77 378 77 b 401 56 392 77 401 68 b 400 48 401 54 401 51 b 223 -172 397 41 230 -166 b 210 -176 220 -174 215 -176 b 201 -174 206 -176 204 -176 b 112 -87 198 -173 178 -152 b 27 0 65 -38 27 0 b 21 -6 27 0 24 -2 l 17 -12 l 17 -147 b 17 -210 17 -173 17 -194 b 10 -292 17 -297 16 -287 b -2 -299 6 -297 2 -299 b -21 -287 -10 -299 -19 -295 b -24 -174 -23 -284 -23 -284 l -24 -63 l -66 -117 b -121 -176 -110 -170 -114 -176 b -125 -176 -122 -176 -123 -176 b -296 -12 -134 -174 -125 -184 l -308 0 l -337 -34 b -375 -77 -367 -73 -370 -76 b -382 -79 -377 -79 -379 -79 b -402 -58 -393 -79 -402 -69 b -401 -49 -402 -55 -402 -52 b -224 170 -398 -43 -231 165 b -212 174 -221 173 -216 174 b -202 173 -208 174 -205 174 b -39 11 -200 172 -151 122 l -28 -1 l -25 1 l -24 4 l -24 130 b -23 260 -24 256 -24 258 b -10 273 -20 266 -16 270 "},"v46":{"x_min":0,"x_max":627.46875,"ha":640,"o":"m 306 190 b 314 191 308 191 311 191 b 326 184 318 191 322 190 l 336 173 b 510 52 377 127 442 80 b 515 49 513 51 515 49 b 611 16 537 40 579 24 b 627 0 624 13 627 9 b 607 -18 627 -11 624 -13 b 330 -181 490 -49 389 -109 b 314 -192 323 -190 319 -192 b 306 -191 311 -192 308 -192 b 294 -177 302 -188 302 -188 b 257 -140 287 -170 265 -148 b 19 -18 193 -84 114 -44 b 0 0 2 -13 0 -11 b 16 16 0 9 2 13 b 110 49 47 24 89 40 b 117 52 111 49 114 51 b 145 65 126 56 130 58 b 281 163 200 93 245 124 b 300 186 288 170 291 174 b 306 190 300 187 303 188 m 317 137 b 313 142 315 141 314 142 b 308 137 313 142 311 141 b 161 4 276 84 220 33 b 155 0 159 1 155 0 b 163 -4 155 0 159 -2 b 308 -138 220 -34 276 -84 b 313 -142 311 -141 313 -142 b 317 -138 314 -142 315 -141 b 464 -4 351 -84 406 -34 b 470 0 468 -2 470 0 b 464 4 470 0 468 1 b 317 137 406 33 351 84 "},"v47":{"x_min":-24.5,"x_max":315.78125,"ha":322,"o":"m -24 -145 l -24 -5 l -20 -5 b 1 -26 -10 -5 -6 -9 b 175 -241 31 -86 96 -166 b 314 -548 259 -323 304 -420 b 315 -589 315 -555 315 -571 b 314 -630 315 -606 315 -623 b 298 -730 311 -664 306 -699 l 295 -742 l 296 -748 b 314 -850 304 -778 311 -813 b 315 -892 315 -857 315 -874 b 314 -932 315 -909 315 -925 b 298 -1032 311 -967 306 -1002 l 295 -1045 l 296 -1050 b 314 -1153 304 -1081 311 -1115 b 315 -1193 315 -1160 315 -1177 b 314 -1235 315 -1211 315 -1228 b 217 -1526 306 -1338 270 -1444 b 201 -1533 213 -1532 208 -1533 b 182 -1522 193 -1533 185 -1529 b 179 -1514 181 -1518 179 -1517 b 189 -1489 179 -1508 182 -1501 b 266 -1217 240 -1403 266 -1308 b 262 -1156 266 -1196 265 -1177 b 110 -907 247 -1043 190 -950 b 0 -889 87 -895 50 -889 l -1 -889 l -24 -889 l -24 -749 l -24 -610 l -20 -610 b 1 -631 -10 -610 -6 -614 b 175 -846 31 -691 96 -771 b 259 -956 213 -884 236 -914 b 265 -966 262 -961 264 -966 b 265 -966 265 -966 265 -966 b 265 -953 265 -964 265 -959 b 266 -920 266 -943 266 -932 b 262 -853 266 -898 265 -873 b 110 -605 247 -741 190 -648 b 0 -587 87 -592 50 -587 l -1 -587 l -24 -587 l -24 -448 l -24 -308 l -20 -308 b 1 -328 -10 -308 -6 -312 b 175 -544 31 -388 96 -469 b 259 -655 213 -581 236 -612 b 265 -663 262 -659 264 -663 b 265 -663 265 -663 265 -663 b 265 -650 265 -663 265 -657 b 266 -617 266 -641 266 -630 b 262 -551 266 -595 265 -570 b 110 -303 247 -438 190 -345 b 0 -284 87 -290 50 -284 l -1 -284 l -24 -284 l -24 -145 "},"v49":{"x_min":0,"x_max":630.203125,"ha":643,"o":"m 308 204 b 314 205 310 205 313 205 b 326 201 319 205 323 204 b 355 154 328 199 338 180 b 401 83 362 142 392 95 l 409 72 b 431 41 412 66 424 49 b 619 -174 498 -51 570 -134 b 630 -192 626 -180 630 -186 b 626 -202 630 -195 628 -199 b 616 -206 623 -205 620 -206 b 552 -188 608 -206 592 -202 b 310 -155 488 -169 392 -155 b 268 -156 295 -155 281 -155 b 77 -188 197 -161 126 -173 b 13 -206 35 -202 20 -206 b 9 -206 12 -206 10 -206 b 0 -191 2 -202 0 -197 b 8 -176 0 -186 2 -180 b 204 49 58 -136 138 -43 l 220 72 l 227 83 b 295 188 245 108 281 166 b 308 204 299 197 304 202 m 315 147 b 314 147 315 147 314 147 b 314 147 314 147 314 147 b 306 129 314 145 310 138 l 296 105 b 281 72 292 97 284 77 l 274 56 b 181 -123 247 -4 212 -72 l 174 -134 l 176 -133 b 314 -123 215 -127 272 -123 b 451 -133 356 -123 413 -127 l 454 -134 l 449 -123 b 353 56 417 -72 381 -4 l 347 72 b 332 105 344 77 336 97 l 322 129 b 315 147 318 138 315 145 "},"v4a":{"x_min":70.78125,"x_max":378.390625,"ha":315,"o":"m 246 373 b 254 373 249 373 251 373 b 372 324 303 373 360 351 b 378 302 377 317 378 309 b 338 251 378 278 362 255 b 328 249 334 249 332 249 b 283 294 303 249 283 270 b 288 315 283 301 284 308 b 289 319 289 317 289 319 b 289 319 289 319 289 319 b 283 320 289 320 287 320 b 270 322 279 322 274 322 b 206 288 242 322 215 308 b 206 283 206 287 206 285 b 257 223 206 267 230 238 b 284 206 272 213 277 210 b 351 90 328 173 351 130 b 340 47 351 74 348 59 b 205 -30 314 -2 264 -30 b 182 -29 198 -30 190 -30 b 84 15 147 -24 103 -5 b 70 48 74 24 70 36 b 108 99 70 70 85 94 b 121 102 112 101 117 102 b 167 56 147 102 167 80 b 159 31 167 48 164 40 l 156 26 l 157 26 b 190 20 167 22 178 20 b 220 26 201 20 212 22 b 258 65 243 34 258 51 b 257 70 258 66 258 69 b 204 126 249 94 234 109 b 114 258 148 158 114 209 b 125 302 114 273 118 288 b 246 373 147 342 193 370 "},"v4b":{"x_min":0,"x_max":503.609375,"ha":514,"o":"m 274 430 b 277 430 276 430 277 430 b 310 394 296 430 310 415 b 308 383 310 391 308 387 b 306 367 307 381 307 374 b 236 120 298 305 272 210 b 40 -273 189 -5 125 -134 b 20 -287 35 -283 27 -287 b 5 -281 14 -287 9 -285 b 0 -267 1 -277 0 -273 b 9 -242 0 -262 2 -255 b 246 395 137 -12 232 242 b 274 430 249 416 257 427 m 468 430 b 472 430 469 430 470 430 b 503 394 490 430 503 415 b 502 383 503 391 503 387 b 499 367 502 381 500 374 b 431 120 491 305 465 210 b 234 -273 382 -5 318 -134 b 213 -287 228 -283 220 -287 b 198 -281 208 -287 202 -285 b 193 -267 194 -277 193 -273 b 202 -242 193 -262 196 -255 b 439 395 330 -12 426 242 b 468 430 442 416 451 427 "},"v4d":{"x_min":-311.6875,"x_max":310.328125,"ha":317,"o":"m -9 388 b -2 390 -8 390 -5 390 b 5 388 1 390 4 390 b 19 378 10 387 16 383 b 23 333 23 371 23 371 b 24 298 23 299 24 298 b 81 276 34 298 65 285 b 213 91 145 240 190 177 b 224 24 217 76 224 36 b 257 24 224 24 235 24 b 299 19 292 24 292 24 b 310 -1 306 15 310 6 b 299 -23 310 -11 306 -19 b 257 -27 292 -27 292 -27 b 224 -29 235 -27 224 -29 b 213 -95 224 -40 217 -80 b 81 -280 190 -181 145 -244 b 24 -301 65 -290 34 -301 b 23 -335 24 -301 23 -303 l 23 -340 b 17 -381 23 -374 23 -374 b -1 -391 13 -388 5 -391 b -21 -381 -9 -391 -17 -388 b -27 -340 -27 -374 -27 -374 l -27 -335 b -28 -301 -27 -303 -27 -301 b -85 -280 -38 -301 -69 -290 b -217 -95 -149 -244 -194 -181 b -228 -29 -221 -80 -228 -40 b -259 -27 -228 -29 -238 -27 b -300 -23 -294 -27 -294 -27 b -311 -2 -307 -19 -311 -11 b -294 23 -311 8 -304 19 b -259 24 -291 23 -284 24 b -228 24 -239 24 -228 24 b -217 91 -228 36 -221 76 b -85 276 -194 177 -149 240 b -28 298 -69 285 -38 298 b -27 333 -27 298 -27 299 b -27 371 -27 362 -27 369 b -9 388 -24 378 -17 385 m -27 136 b -28 247 -27 197 -28 247 b -61 216 -31 247 -53 226 b -123 33 -95 172 -121 98 l -125 24 l -76 24 l -27 24 l -27 136 m 29 242 b 24 247 27 245 24 247 b 23 136 24 247 23 197 l 23 24 l 72 24 l 121 24 l 119 33 b 29 242 115 116 77 206 m -27 -140 l -27 -27 l -76 -27 l -125 -27 l -123 -36 b -61 -220 -121 -102 -95 -176 b -28 -251 -53 -230 -31 -251 b -27 -140 -28 -251 -27 -201 m 119 -36 l 121 -27 l 72 -27 l 23 -27 l 23 -140 b 24 -251 23 -201 24 -251 b 57 -220 27 -251 49 -230 b 119 -36 91 -176 117 -102 "},"v4e":{"x_min":0,"x_max":239.5625,"ha":244,"o":"m 10 460 b 20 462 13 462 14 462 b 39 449 28 462 35 458 l 40 446 l 40 326 b 40 205 40 259 40 205 b 127 227 40 205 80 215 b 220 249 196 244 213 249 b 227 247 224 249 225 248 b 238 237 231 245 235 241 l 239 233 l 239 -106 l 239 -448 l 238 -451 b 219 -463 234 -459 225 -463 b 198 -451 210 -463 202 -459 l 197 -448 l 197 -324 b 197 -201 197 -248 197 -201 b 110 -223 196 -201 157 -210 b 17 -245 42 -240 24 -245 b 10 -242 13 -245 13 -244 b 0 -233 6 -241 2 -237 l 0 -230 l 0 108 l 0 446 l 0 449 b 10 460 2 453 6 458 m 197 22 b 197 70 197 41 197 58 b 196 116 197 113 197 116 l 196 116 b 118 97 196 116 160 106 l 40 77 l 40 -18 b 40 -112 40 -69 40 -112 l 119 -93 l 197 -73 l 197 22 "},"v51":{"x_min":-1.359375,"x_max":455.96875,"ha":465,"o":"m 352 541 b 357 542 353 542 355 542 b 377 530 364 542 372 537 l 378 526 l 378 394 l 379 262 l 404 266 b 436 270 420 269 430 270 b 450 265 443 270 446 269 b 455 220 455 259 455 260 l 455 208 l 455 161 l 454 156 b 411 140 449 147 447 147 b 378 133 393 137 379 134 b 378 68 378 133 378 106 b 378 22 378 54 378 38 l 379 -87 l 404 -83 b 436 -79 420 -80 430 -79 b 450 -84 443 -79 446 -80 b 455 -129 455 -90 455 -88 l 455 -141 l 455 -188 l 454 -192 b 413 -209 449 -202 447 -202 b 382 -215 398 -212 383 -215 l 378 -215 l 378 -345 l 378 -380 b 375 -485 378 -484 378 -480 b 357 -494 371 -491 364 -494 b 340 -485 351 -494 344 -491 b 336 -383 337 -480 336 -484 l 336 -349 l 336 -223 l 334 -223 b 291 -231 334 -223 314 -227 l 247 -240 l 247 -371 l 246 -503 l 245 -506 b 225 -519 242 -514 234 -519 b 206 -506 219 -519 210 -514 l 205 -503 l 205 -376 l 205 -248 l 160 -256 l 115 -265 l 115 -396 l 115 -527 l 114 -531 b 95 -544 110 -539 102 -544 b 76 -531 87 -544 78 -539 l 73 -527 l 73 -399 b 73 -273 73 -330 73 -273 b 49 -277 73 -273 61 -274 b 17 -281 32 -280 24 -281 b 4 -276 10 -281 8 -280 b -1 -234 0 -269 -1 -272 b 0 -219 -1 -229 0 -224 l 0 -170 l 1 -167 b 10 -158 2 -163 6 -159 b 49 -149 13 -156 16 -155 l 73 -145 l 73 -34 b 73 76 73 26 73 76 b 49 72 73 76 61 74 b 17 68 32 69 24 68 b 4 73 10 68 8 69 b -1 115 0 80 -1 77 b 0 130 -1 120 0 124 l 0 179 l 1 181 b 10 191 2 186 6 190 b 49 199 13 192 16 194 l 73 204 l 73 338 b 73 374 73 352 73 365 b 77 483 73 484 73 477 b 95 492 81 489 88 492 b 111 483 100 492 107 489 b 115 378 115 477 115 483 l 115 342 b 117 212 115 223 115 212 b 204 229 117 212 200 227 l 205 229 l 205 365 l 205 502 l 206 505 b 225 517 210 513 219 517 b 245 505 234 517 242 513 l 246 502 l 247 369 l 247 237 l 249 237 b 336 254 253 238 336 254 b 337 390 336 254 337 302 l 337 526 l 338 530 b 352 541 341 535 347 539 m 336 15 b 336 126 336 102 336 126 l 336 126 b 291 117 336 126 315 122 l 247 109 l 247 -1 l 247 -112 l 249 -112 b 336 -95 253 -111 336 -95 b 336 15 336 -95 336 -56 m 205 -120 b 205 -55 205 -120 205 -93 b 205 -9 205 -41 205 -24 l 205 101 l 160 93 l 115 84 l 115 -26 b 115 -83 115 -49 115 -69 b 117 -137 115 -133 115 -137 b 205 -120 118 -137 204 -120 "},"v52":{"x_min":-10.890625,"x_max":298.078125,"ha":294,"o":"m 138 473 b 142 474 140 473 141 474 b 164 459 148 474 153 470 b 191 402 183 442 191 423 b 181 353 191 388 187 371 b 178 349 179 352 178 349 b 179 348 178 348 179 348 b 185 349 181 348 182 348 b 255 376 210 355 234 363 b 272 381 264 381 266 381 b 298 355 287 381 298 370 b 288 330 298 348 298 345 b 171 34 238 254 194 141 b 166 13 168 16 168 16 b 144 1 161 5 152 1 b 121 15 134 1 125 5 b 115 33 119 18 117 24 b 0 330 91 145 49 252 b -10 355 -9 345 -10 348 b 13 381 -10 371 0 381 b 31 376 19 381 25 380 b 132 345 61 358 103 345 l 136 345 l 137 355 b 145 378 138 359 142 370 b 152 415 149 394 152 405 b 137 452 152 427 148 438 b 133 464 134 458 133 460 b 138 473 133 467 134 470 "},"v53":{"x_min":0,"x_max":902.421875,"ha":921,"o":"m 17 240 b 24 241 19 241 21 241 b 32 240 28 241 31 241 b 46 229 38 238 43 234 b 50 88 50 223 50 237 b 50 -1 50 63 50 34 b 50 -90 50 -36 50 -65 b 46 -231 50 -238 50 -224 b 25 -242 42 -238 34 -242 b 0 -224 14 -242 4 -235 b 0 2 0 -222 0 -108 b 0 223 0 112 0 220 b 17 240 2 230 9 237 m 110 240 b 118 241 111 241 114 241 b 126 240 121 241 123 241 b 142 223 133 237 140 230 b 144 123 144 220 144 205 b 144 29 144 45 144 29 b 144 29 144 29 144 29 b 393 183 166 106 264 167 b 450 186 412 184 431 186 b 756 29 600 186 732 120 b 756 29 756 29 756 29 b 758 123 758 29 758 45 b 760 227 758 226 758 223 b 784 241 766 237 774 241 b 804 229 792 241 800 237 b 809 88 808 223 809 237 l 809 -1 l 809 -90 b 804 -231 809 -238 808 -224 b 784 -242 800 -238 792 -242 b 762 -231 775 -242 766 -238 b 758 -124 756 -224 758 -231 b 756 -30 758 -47 758 -30 b 756 -30 756 -30 756 -30 b 509 -184 736 -108 637 -169 b 450 -187 488 -187 469 -187 b 144 -30 300 -187 168 -122 b 144 -30 144 -30 144 -30 b 144 -124 144 -30 144 -47 b 140 -231 144 -231 144 -224 b 118 -242 134 -238 126 -242 b 92 -224 107 -242 96 -235 b 92 2 92 -222 92 -108 b 92 223 92 112 92 220 b 110 240 95 230 102 237 m 432 161 b 413 162 426 162 420 162 b 313 41 351 162 313 109 b 347 -73 313 5 323 -34 b 487 -163 385 -133 439 -163 b 578 -97 526 -163 562 -142 b 588 -43 585 -80 588 -62 b 432 161 588 47 518 147 m 868 240 b 876 241 869 241 872 241 b 884 240 879 241 882 241 b 898 229 890 238 894 234 b 902 88 902 223 902 237 l 902 -1 l 902 -90 b 898 -231 902 -238 902 -224 b 876 -242 892 -238 884 -242 b 852 -224 865 -242 854 -235 b 850 2 850 -222 850 -108 b 852 223 850 112 850 220 b 868 240 853 230 860 237 "},"v54":{"x_min":-24.5,"x_max":317.140625,"ha":324,"o":"m -24 -161 l -24 -5 l -20 -5 b 0 -24 -9 -5 -2 -12 b 171 -315 21 -124 84 -233 b 317 -660 268 -406 317 -531 b 187 -1014 317 -782 274 -909 b 161 -1034 172 -1034 171 -1034 b 141 -1013 149 -1034 141 -1025 b 152 -991 141 -1004 142 -1002 b 266 -682 228 -899 266 -788 b 174 -430 266 -588 236 -498 b -23 -317 136 -388 66 -348 b -24 -161 -23 -316 -24 -285 "},"v55":{"x_min":0,"x_max":551.25,"ha":563,"o":"m 289 644 b 304 645 294 645 299 645 b 404 566 349 645 392 613 b 406 541 405 557 406 549 b 379 471 406 514 397 489 l 377 467 l 382 470 b 509 591 438 485 485 531 b 513 601 510 595 513 599 b 530 609 518 607 524 609 b 551 588 540 609 551 602 b 200 -605 551 584 204 -599 b 182 -616 197 -612 190 -616 b 163 -602 174 -616 166 -610 b 161 -598 161 -601 161 -601 b 217 -402 161 -589 170 -562 b 272 -213 247 -298 272 -213 b 272 -213 272 -213 272 -213 b 264 -219 272 -213 268 -216 b 140 -262 227 -247 182 -262 b 36 -226 102 -262 65 -249 b 0 -145 12 -206 0 -176 b 17 -84 0 -124 5 -104 b 103 -38 38 -54 70 -38 b 191 -91 137 -38 172 -56 b 205 -141 201 -106 205 -124 b 178 -212 205 -167 196 -194 l 175 -215 l 182 -213 b 307 -93 236 -198 284 -151 b 372 129 308 -88 372 127 b 372 129 372 129 372 129 b 364 122 372 129 368 126 b 240 80 328 94 283 80 b 137 115 202 80 166 91 b 99 195 112 136 99 165 b 118 256 99 217 106 238 b 204 303 138 287 171 303 b 292 249 238 303 273 285 b 306 199 302 234 306 217 b 279 129 306 173 296 148 l 276 126 l 281 127 b 408 248 336 142 385 190 b 473 470 409 254 473 469 b 473 470 473 470 473 470 b 465 464 473 470 469 467 b 341 421 428 435 383 421 b 236 458 303 421 266 433 b 200 537 212 478 200 508 b 289 644 200 585 234 635 "},"v58":{"x_min":-21.78125,"x_max":367.5,"ha":375,"o":"m 259 1553 b 265 1553 261 1553 264 1553 b 288 1540 272 1553 277 1550 b 367 1351 340 1493 367 1424 b 336 1221 367 1308 357 1263 l 332 1211 l 333 1208 b 367 1077 356 1170 367 1124 b 336 945 367 1032 357 986 l 332 935 l 333 932 b 367 800 356 893 367 848 b 336 669 367 756 357 710 l 332 659 l 333 656 b 367 523 356 617 367 571 b 345 412 367 485 360 446 b 231 273 322 356 284 310 b -1 19 121 195 27 93 b -17 4 -4 11 -10 5 l -21 4 l -21 134 l -21 265 l -17 265 b 133 291 20 265 96 278 b 318 537 245 328 318 433 b 307 603 318 559 315 582 b 303 614 304 612 304 614 b 298 609 302 614 300 613 b 231 549 281 589 258 567 b -1 295 121 471 27 369 b -17 280 -4 287 -10 281 l -21 280 l -21 410 l -21 541 l -17 541 b 133 567 20 541 96 555 b 318 813 245 605 318 709 b 307 880 318 835 315 859 b 303 891 304 888 304 891 b 298 885 302 891 300 888 b 231 825 281 866 258 843 b -1 571 121 748 27 645 b -17 556 -4 563 -10 557 l -21 556 l -21 687 l -21 817 l -17 817 b 133 843 20 817 96 830 b 318 1089 245 881 318 985 b 307 1156 318 1111 315 1134 b 303 1167 304 1164 304 1167 b 298 1161 302 1167 300 1164 b 231 1102 281 1140 258 1120 b -1 848 121 1024 27 921 b -17 832 -4 839 -10 834 l -21 832 l -21 963 l -21 1093 l -17 1093 b 114 1113 12 1093 78 1103 b 313 1314 215 1142 289 1218 b 318 1364 317 1331 318 1347 b 255 1511 318 1422 295 1478 b 243 1532 247 1519 243 1525 b 259 1553 243 1540 250 1550 "},"v59":{"x_min":0,"x_max":464.140625,"ha":474,"o":"m 0 0 l 0 347 l 76 347 l 153 347 l 153 0 l 153 -348 l 76 -348 l 0 -348 l 0 0 m 308 -1 l 308 347 l 386 347 l 464 347 l 464 -1 l 464 -348 l 386 -348 l 308 -348 l 308 -1 "},"v5a":{"x_min":-171.5,"x_max":170.140625,"ha":174,"o":"m -6 566 b 0 567 -5 567 -2 567 b 14 556 6 567 12 563 b 92 285 14 555 50 433 b 170 13 166 33 170 19 b 168 13 170 13 170 13 b 161 1 168 8 167 4 l 159 0 l 122 0 l 84 0 l 81 1 b 21 195 76 5 78 -5 b -32 381 -8 297 -32 381 b -87 197 -32 381 -57 298 b -141 8 -115 94 -140 9 b -155 0 -142 2 -149 0 b -171 15 -163 0 -171 5 b -14 556 -171 18 -24 528 b -6 566 -14 560 -10 564 "},"v5b":{"x_min":-441,"x_max":439.640625,"ha":449,"o":"m -428 -2 b -421 0 -427 -1 -424 0 b -406 -6 -416 0 -409 -2 b -400 -31 -401 -12 -400 -15 b -1 -352 -392 -215 -215 -352 b 58 -349 19 -352 38 -351 b 398 -31 250 -326 392 -192 b 404 -6 398 -15 400 -12 b 419 -1 408 -2 413 -1 b 439 -13 427 -1 435 -5 b 439 -29 439 -16 439 -22 b 434 -105 439 -48 438 -80 b 0 -489 397 -333 213 -489 b -68 -484 -23 -489 -44 -488 b -441 -36 -280 -452 -436 -263 b -441 -30 -441 -34 -441 -31 b -428 -2 -441 -11 -439 -5 m -13 -9 b -1 -8 -9 -8 -5 -8 b 50 -36 19 -8 39 -19 b 61 -72 57 -47 61 -59 b 50 -106 61 -84 57 -97 b -1 -134 39 -124 19 -134 b -46 -115 -17 -134 -34 -129 b -62 -72 -57 -102 -62 -87 b -13 -9 -62 -44 -44 -16 "},"v5c":{"x_min":0,"x_max":447.8125,"ha":457,"o":"m 0 -87 l 0 0 l 223 0 l 447 0 l 447 -87 l 447 -174 l 223 -174 l 0 -174 l 0 -87 "},"v5d":{"x_min":-1.359375,"x_max":592.078125,"ha":604,"o":"m 280 692 b 295 694 283 692 289 694 b 310 692 300 694 307 692 b 357 630 340 684 357 657 b 336 580 357 612 351 594 b 311 538 321 566 311 549 b 352 492 311 512 330 492 b 366 495 357 492 362 492 b 397 553 390 503 397 517 b 415 603 397 576 402 591 b 460 623 427 617 443 623 b 509 599 479 623 498 614 b 522 559 518 587 522 573 b 494 506 522 538 513 519 b 451 495 481 498 473 496 b 415 488 432 495 426 494 b 394 449 404 483 394 464 b 394 448 394 448 394 448 l 394 440 l 397 433 b 428 409 404 420 413 413 b 438 408 431 408 435 408 b 479 431 450 408 462 415 b 528 455 495 448 510 455 b 548 452 534 455 541 453 b 592 391 577 442 592 416 b 549 331 592 365 577 340 b 528 327 541 328 534 327 b 479 351 510 327 495 335 b 438 374 464 367 450 374 b 417 369 431 374 424 373 b 394 333 402 360 394 348 b 400 312 394 326 396 319 b 451 287 408 294 420 288 b 513 258 484 285 499 278 b 522 223 519 247 522 234 b 461 159 522 190 496 159 b 449 161 457 159 453 159 b 397 229 416 167 397 191 b 366 288 397 265 390 278 b 352 290 362 290 357 290 b 315 262 336 290 321 280 b 311 245 313 256 311 251 b 334 204 311 233 318 220 b 355 170 348 190 351 184 b 357 152 356 166 357 159 b 355 136 357 147 356 140 b 295 88 345 104 321 88 b 232 152 264 88 232 112 b 255 204 232 174 238 186 b 279 244 273 222 279 231 l 279 245 b 238 290 279 270 259 290 b 224 288 234 290 228 290 b 193 229 200 278 193 265 b 141 161 193 191 174 167 b 129 159 137 159 133 159 b 68 223 93 159 68 190 b 77 258 68 234 70 247 b 138 287 91 278 106 285 b 185 302 166 287 175 291 b 196 333 193 312 196 323 b 174 369 196 347 187 360 b 152 374 166 373 159 374 b 111 351 140 374 126 367 b 62 327 95 335 80 327 b 51 328 58 327 54 327 b -1 391 16 334 -1 363 b 53 455 -1 420 17 449 b 62 455 57 455 59 455 b 111 431 80 455 95 448 b 152 408 127 415 140 408 b 161 409 155 408 159 408 b 193 433 176 413 186 420 l 196 440 l 196 448 b 196 451 196 449 196 449 b 190 471 196 459 194 463 b 137 495 182 489 167 495 l 134 495 l 134 495 b 68 560 95 495 68 521 b 129 623 68 596 95 623 b 144 621 134 623 138 623 b 193 553 175 614 193 589 b 224 495 193 517 200 503 b 238 492 228 492 234 492 b 279 538 259 492 279 512 b 254 580 279 549 269 566 b 232 630 239 594 232 612 b 280 692 232 657 250 684 m 307 456 b 295 458 303 458 299 458 b 230 391 258 458 230 426 b 236 360 230 381 231 371 b 295 324 249 337 272 324 b 353 360 318 324 341 337 b 360 391 357 370 360 381 b 307 456 360 421 340 451 "},"v60":{"x_min":-590.71875,"x_max":589.359375,"ha":601,"o":"m -367 173 b -362 174 -366 174 -364 174 b -351 173 -357 174 -353 173 b -262 86 -348 172 -328 151 b -176 0 -216 37 -176 0 b -107 84 -176 0 -145 37 b -31 174 -36 173 -38 172 b -25 174 -29 174 -28 174 b -16 173 -23 174 -19 173 b 72 86 -13 172 6 151 b 157 0 119 37 157 0 b 227 84 159 0 189 37 b 303 174 298 173 296 172 b 308 174 304 174 307 174 b 318 173 313 174 317 173 b 481 11 322 172 357 134 l 494 -1 l 522 34 b 560 76 553 72 555 74 b 567 77 563 77 564 77 b 589 56 579 77 589 68 b 586 48 589 54 588 51 b 411 -172 583 41 416 -166 b 397 -176 406 -174 401 -176 b 387 -174 393 -176 390 -176 b 299 -87 386 -173 366 -152 b 213 0 253 -38 213 0 b 144 -86 213 0 182 -38 b 68 -174 73 -174 74 -173 b 62 -176 66 -176 65 -176 b 53 -174 59 -176 55 -174 b -35 -87 50 -173 29 -152 b -121 0 -83 -38 -121 0 b -190 -86 -122 0 -152 -38 b -266 -174 -261 -174 -259 -173 b -272 -176 -268 -176 -270 -176 b -281 -174 -276 -176 -280 -174 b -371 -86 -284 -173 -304 -152 b -457 0 -417 -38 -457 0 l -457 0 b -477 -26 -457 0 -470 -16 b -548 -227 -524 -88 -548 -161 b -536 -303 -548 -254 -544 -280 b -533 -317 -534 -309 -533 -313 b -553 -338 -533 -330 -541 -338 b -577 -315 -566 -338 -571 -333 b -590 -227 -586 -287 -590 -258 b -518 -9 -590 -154 -564 -77 b -465 56 -509 2 -504 8 l -402 134 b -367 173 -375 169 -372 172 "},"v62":{"x_min":46.28125,"x_max":669.671875,"ha":563,"o":"m 183 376 b 189 376 185 376 187 376 b 212 374 197 376 208 376 b 265 337 234 369 253 355 b 274 317 268 331 273 320 b 274 316 274 317 274 316 b 280 323 276 316 276 319 b 311 358 288 337 299 348 b 319 366 315 360 318 365 b 356 376 326 373 340 376 b 382 371 364 376 374 374 b 428 337 400 366 417 352 b 436 317 431 331 436 320 b 438 316 436 317 436 316 b 442 323 438 316 439 319 b 475 358 451 337 462 348 b 483 366 477 360 481 365 b 518 376 488 373 503 376 b 544 373 528 376 536 376 b 604 285 579 360 604 326 b 597 249 604 273 601 258 b 543 63 596 247 544 70 b 541 54 543 61 541 55 b 540 44 540 51 540 47 b 552 23 540 33 545 23 b 552 23 552 23 552 23 b 647 126 586 29 627 72 b 658 138 651 136 653 138 b 660 138 660 138 660 138 b 669 129 666 137 669 136 b 654 88 669 122 665 109 b 562 -12 631 43 602 9 l 549 -19 b 521 -27 540 -24 530 -27 b 447 30 490 -27 458 -4 b 443 58 445 38 443 48 b 450 93 443 72 446 84 b 504 278 453 97 504 272 b 507 288 506 283 506 287 b 509 298 507 292 509 295 b 491 326 509 310 502 320 b 487 327 490 327 488 327 b 479 324 484 327 483 326 b 441 270 462 316 443 288 b 435 249 441 265 436 254 b 398 127 434 248 419 195 b 362 4 379 61 362 5 b 328 -1 359 -1 362 -1 b 314 -1 323 -1 319 -1 b 302 -1 310 -1 306 -1 b 266 4 266 -1 269 -1 b 265 6 265 5 265 5 b 303 144 265 13 272 34 b 343 278 325 216 343 276 b 344 288 343 281 344 285 b 345 298 345 291 345 295 b 330 326 345 310 340 320 b 323 327 328 327 325 327 b 317 324 322 327 321 326 b 279 270 300 316 281 288 b 273 249 279 265 274 254 b 236 127 272 248 255 195 b 200 4 216 61 200 5 b 164 -1 197 -1 198 -1 b 151 -1 161 -1 156 -1 b 140 -1 147 -1 142 -1 b 103 4 104 -1 106 -1 b 103 6 103 5 103 5 b 141 144 103 13 108 34 b 181 278 161 216 179 276 b 182 288 181 281 181 285 b 183 298 182 291 183 295 b 168 324 183 310 178 320 b 160 327 166 326 163 327 b 141 320 156 327 151 324 b 69 230 112 305 85 272 b 57 215 65 217 62 215 b 55 215 57 215 55 215 b 46 224 49 215 46 217 b 59 260 46 231 50 242 b 151 363 81 306 112 341 b 161 369 155 365 160 367 b 183 376 166 371 174 374 "},"v68":{"x_min":-597.53125,"x_max":596.171875,"ha":608,"o":"m -533 324 b -525 327 -530 326 -528 327 b -504 305 -514 327 -504 317 b -504 305 -504 305 -504 305 b -513 284 -504 299 -504 299 b -556 112 -541 226 -556 167 b -545 33 -556 84 -552 58 b -524 -20 -541 15 -532 -9 l -522 -23 l -491 15 l -413 111 b -355 174 -367 169 -363 174 b -351 174 -353 174 -352 174 b -254 86 -343 174 -348 179 b -168 -1 -208 37 -168 -1 b -100 84 -168 -1 -137 37 b -23 173 -28 173 -29 172 b -19 174 -21 174 -20 174 b -8 173 -14 174 -10 173 b 155 11 -5 172 43 123 l 166 -1 l 168 1 l 170 4 l 170 130 b 171 260 170 256 170 258 b 191 274 175 269 183 274 b 205 267 196 274 201 272 b 212 158 212 262 210 273 l 212 56 l 257 112 b 311 173 304 172 304 172 b 317 174 313 174 314 174 b 326 173 319 174 323 173 b 490 11 329 172 366 134 l 502 -1 l 530 34 b 568 76 560 72 563 74 b 575 77 570 77 573 77 b 596 56 586 77 596 68 b 594 48 596 54 596 51 b 417 -172 592 41 424 -166 b 405 -176 415 -174 409 -176 b 396 -174 401 -176 398 -176 b 307 -87 393 -173 372 -152 b 221 -1 259 -38 221 -1 b 216 -6 221 -1 219 -2 l 212 -12 l 212 -147 b 212 -210 212 -173 212 -194 b 205 -292 212 -297 210 -287 b 191 -299 201 -297 196 -299 b 172 -287 183 -299 175 -295 b 170 -174 171 -284 171 -284 l 170 -63 l 127 -117 b 73 -176 84 -170 80 -176 b 68 -176 72 -176 70 -176 b -27 -87 59 -174 65 -180 b -114 0 -74 -38 -112 0 b -182 -86 -114 0 -145 -38 b -258 -174 -253 -174 -253 -173 b -264 -176 -259 -176 -262 -176 b -274 -174 -268 -176 -272 -174 b -438 -11 -277 -173 -348 -102 l -449 0 l -479 -37 b -524 -80 -513 -80 -514 -80 l -524 -80 b -553 -52 -534 -80 -540 -74 b -597 109 -583 -8 -597 48 b -560 280 -597 165 -585 224 b -533 324 -548 310 -540 322 "},"v6c":{"x_min":-1.359375,"x_max":193.28125,"ha":197,"o":"m 78 233 b 87 233 81 233 84 233 b 187 140 132 233 174 195 b 193 102 190 127 193 115 b 43 -113 193 22 136 -62 b 27 -119 36 -116 31 -119 b 19 -108 21 -119 19 -115 b 29 -97 19 -102 20 -101 b 102 13 73 -72 102 -27 b 92 51 102 26 98 40 l 91 54 l 84 54 b 8 104 53 54 21 74 b -1 142 1 116 -1 130 b 78 233 -1 187 31 227 "},"v6d":{"x_min":-590.71875,"x_max":589.359375,"ha":601,"o":"m 544 335 b 553 337 548 337 551 337 b 575 313 563 337 570 330 b 589 226 583 285 589 256 b 517 8 589 152 563 76 b 464 -58 507 -4 503 -9 l 401 -136 b 362 -176 372 -172 370 -176 b 357 -176 360 -176 359 -176 b 261 -87 349 -174 355 -180 b 175 0 215 -38 175 0 b 106 -86 175 0 144 -38 b 29 -174 35 -174 36 -173 b 24 -176 28 -176 27 -176 b 14 -174 21 -176 17 -174 b -73 -87 12 -173 -8 -152 b -159 0 -121 -38 -159 0 b -228 -86 -160 0 -190 -38 b -304 -174 -299 -174 -298 -173 b -310 -176 -306 -176 -308 -176 b -319 -174 -314 -176 -318 -174 b -483 -12 -323 -173 -359 -137 l -495 0 l -524 -34 b -562 -77 -553 -73 -556 -76 b -568 -79 -564 -79 -566 -79 b -590 -58 -581 -79 -590 -69 b -588 -49 -590 -55 -589 -52 b -412 170 -585 -43 -417 165 b -398 174 -408 173 -402 174 b -389 173 -394 174 -392 174 b -300 86 -387 172 -366 151 b -215 -1 -254 37 -215 -1 b -145 84 -215 -1 -183 37 b -69 173 -74 173 -76 172 b -63 174 -68 174 -66 174 b -54 173 -61 174 -57 173 b 34 86 -51 172 -31 151 b 119 -1 81 37 119 -1 b 189 84 121 -1 151 37 b 265 173 259 173 258 172 b 270 174 266 174 269 174 b 280 173 274 174 279 173 b 370 84 283 172 303 151 b 455 -1 416 37 455 -1 l 455 -1 b 476 24 455 -1 469 15 b 547 226 522 87 547 159 b 534 302 547 252 543 278 b 532 317 533 308 532 313 b 544 335 532 326 536 333 "},"v6f":{"x_min":-80.3125,"x_max":78.9375,"ha":81,"o":"m 63 191 b 69 192 65 192 66 192 b 77 188 72 192 76 191 b 78 183 78 187 78 186 b 74 158 78 179 77 172 l 66 115 b 9 -161 49 30 10 -158 b -10 -187 6 -172 -1 -181 b -34 -194 -17 -191 -25 -194 b -80 -147 -58 -194 -80 -174 b -80 -141 -80 -144 -80 -142 b 9 70 -80 -134 -73 -117 l 49 163 b 63 191 59 188 61 190 "},"v70":{"x_min":0,"x_max":436.921875,"ha":446,"o":"m 213 190 b 217 191 215 191 216 191 b 231 184 223 191 228 188 b 249 154 240 167 246 159 b 419 18 292 91 348 45 b 436 -1 435 11 436 8 b 424 -16 436 -9 434 -13 b 308 -87 394 -26 340 -59 b 231 -186 276 -117 257 -142 b 219 -192 228 -191 225 -192 b 198 -174 209 -192 208 -191 b 47 -33 161 -113 110 -63 b 10 -16 34 -26 17 -19 b 0 -1 2 -13 0 -9 b 17 18 0 8 1 11 b 198 173 95 48 156 101 b 213 190 206 187 208 188 "},"v72":{"x_min":-423.3125,"x_max":421.9375,"ha":431,"o":"m -262 197 b -247 197 -257 197 -253 197 b -118 162 -210 197 -163 184 b 40 45 -61 134 -13 98 b 277 -95 119 -33 200 -81 b 289 -97 281 -97 285 -97 b 378 0 332 -97 371 -55 b 378 11 378 4 378 6 b 302 83 378 55 345 83 b 242 66 283 83 262 77 b 208 56 231 59 219 56 b 148 120 175 56 148 81 b 201 186 148 151 164 172 b 261 198 220 194 240 198 b 420 45 341 198 411 136 b 421 22 421 37 421 29 b 245 -199 421 -93 338 -199 b 238 -198 243 -199 240 -199 b -44 -47 148 -194 50 -141 b -250 86 -114 22 -183 66 b -295 94 -270 91 -283 94 b -315 91 -302 94 -307 94 b -381 4 -356 81 -381 43 b -355 -56 -381 -18 -372 -40 b -298 -81 -338 -73 -319 -81 b -246 -68 -283 -81 -265 -77 b -212 -58 -234 -61 -223 -58 b -178 -69 -200 -58 -189 -62 b -151 -122 -160 -81 -151 -101 b -171 -167 -151 -138 -157 -155 b -239 -195 -185 -181 -213 -192 b -257 -197 -245 -197 -250 -197 b -423 -5 -352 -197 -423 -109 b -412 65 -423 16 -419 40 b -262 197 -389 137 -329 188 "},"v74":{"x_min":-206.890625,"x_max":428.75,"ha":438,"o":"m 389 -351 b 394 -351 390 -351 393 -351 b 428 -385 413 -351 428 -367 b 428 -394 428 -388 428 -391 b 394 -428 426 -406 421 -410 l 332 -473 l 269 -516 l 205 -560 l 141 -603 l 77 -648 l 13 -692 l -50 -737 l -114 -780 l -145 -802 b -171 -813 -157 -810 -163 -813 b -175 -813 -172 -813 -174 -813 b -206 -777 -194 -811 -206 -795 b -202 -760 -206 -771 -205 -766 b -87 -675 -197 -752 -206 -757 l -34 -639 l 83 -557 l 145 -514 l 209 -470 l 272 -427 b 389 -351 375 -356 381 -352 "},"v75":{"x_min":-149.71875,"x_max":148.359375,"ha":151,"o":"m -137 381 b -130 383 -134 383 -133 383 b -111 371 -122 383 -114 378 b -55 224 -110 370 -85 305 b 0 80 -25 145 -1 80 b 54 224 0 80 24 145 b 112 377 114 384 110 373 b 127 384 118 381 122 384 b 148 362 138 384 148 374 l 148 356 l 83 183 b 16 9 47 88 17 11 b -1 0 12 2 5 0 b -14 5 -5 0 -10 1 b -84 183 -19 9 -13 -6 l -149 356 l -149 362 b -137 381 -149 371 -145 378 "},"v78":{"x_min":0,"x_max":193.28125,"ha":197,"o":"m 85 514 b 95 517 88 517 89 517 b 114 505 103 517 110 513 l 115 502 l 115 376 b 115 249 115 306 115 249 b 141 258 117 249 127 252 l 167 266 l 172 266 b 190 254 181 265 187 262 l 193 251 l 193 202 l 193 188 b 187 147 193 149 191 152 b 147 130 183 142 182 141 l 115 119 l 115 9 b 115 -99 115 -51 115 -99 b 141 -91 115 -99 127 -95 b 171 -81 166 -81 167 -81 l 171 -81 b 191 -94 181 -81 189 -87 b 193 -142 191 -97 193 -120 b 191 -195 193 -167 191 -194 b 125 -227 187 -205 187 -204 l 115 -230 l 115 -366 l 115 -503 l 114 -506 b 95 -519 110 -514 102 -519 b 74 -506 87 -519 78 -514 l 73 -503 l 73 -374 b 73 -245 73 -260 73 -245 b 73 -245 73 -245 73 -245 b 55 -252 72 -245 63 -249 l 32 -260 b 19 -263 27 -262 23 -263 b 4 -256 13 -263 8 -260 b 0 -215 0 -251 0 -254 b 0 -199 0 -210 0 -206 l 0 -152 l 1 -149 b 8 -140 2 -145 5 -141 b 42 -127 9 -140 24 -133 l 73 -116 l 73 -5 b 73 23 73 4 73 15 b 73 105 73 70 73 105 b 49 97 73 105 61 101 b 17 88 32 91 23 88 b 4 95 10 88 8 91 b 0 137 0 101 0 98 b 0 151 0 141 0 145 l 0 199 l 1 202 b 43 224 5 212 5 212 l 73 234 l 73 367 l 73 502 l 74 505 b 85 514 77 509 81 513 "},"v79":{"x_min":-1.359375,"x_max":899.703125,"ha":918,"o":"m 307 349 b 332 351 315 351 323 351 b 443 340 367 351 408 347 b 741 47 607 306 720 195 b 744 0 743 31 744 16 b 660 -303 744 -90 713 -206 b 28 -755 534 -531 304 -695 b 14 -756 23 -755 19 -756 b -1 -741 4 -756 -1 -750 b 21 -720 -1 -731 1 -728 b 567 -56 337 -601 548 -344 b 568 -11 568 -41 568 -24 b 442 285 568 129 525 233 b 325 319 406 308 367 319 b 93 177 232 319 137 266 b 84 154 91 170 84 155 b 84 154 84 154 84 154 b 88 156 84 154 85 155 b 159 177 110 170 134 177 b 257 134 194 177 231 162 b 294 41 281 108 294 73 b 171 -97 294 -24 246 -90 b 156 -98 166 -97 161 -98 b 6 74 73 -98 6 -22 b 6 80 6 76 6 79 b 307 349 10 223 141 340 m 839 215 b 845 216 841 216 842 216 b 862 213 852 216 860 215 b 899 163 887 206 899 184 b 872 117 899 145 890 127 b 847 111 865 112 856 111 b 808 130 833 111 818 117 b 796 162 800 140 796 151 b 839 215 796 187 812 212 m 839 -112 b 845 -112 841 -112 842 -112 b 862 -115 852 -112 860 -113 b 899 -165 887 -122 899 -144 b 872 -210 899 -183 890 -201 b 847 -217 865 -215 856 -217 b 808 -198 833 -217 818 -210 b 796 -165 800 -188 796 -177 b 839 -112 796 -140 812 -116 "},"v7c":{"x_min":0,"x_max":300.8125,"ha":307,"o":"m 49 505 b 53 506 50 505 51 506 b 70 496 58 506 62 503 b 81 485 73 492 78 488 l 96 473 l 111 459 l 122 449 l 134 438 l 182 396 l 255 330 b 292 291 292 298 292 298 l 292 290 l 292 284 l 283 270 b 209 36 234 197 209 113 b 288 -170 209 -44 235 -119 b 299 -184 295 -179 299 -181 b 300 -191 300 -187 300 -188 b 285 -206 300 -199 294 -206 b 280 -206 283 -206 281 -206 b 247 -201 270 -202 259 -201 b 176 -222 223 -201 197 -208 b 114 -340 136 -249 114 -292 b 172 -471 114 -384 134 -433 b 185 -492 182 -481 185 -487 b 181 -502 185 -496 183 -499 b 171 -508 176 -505 174 -508 b 152 -498 166 -508 160 -503 b 0 -284 65 -428 12 -352 b 0 -260 0 -278 0 -270 b 1 -238 0 -252 0 -242 b 148 -140 16 -177 73 -140 b 209 -148 167 -140 189 -142 b 215 -149 212 -148 215 -149 b 215 -149 215 -149 215 -149 l 215 -149 b 201 -136 215 -148 209 -142 l 157 -97 l 96 -41 b 17 34 21 24 17 29 b 17 37 17 36 17 36 b 17 38 17 37 17 38 b 25 56 17 44 17 44 b 110 298 81 131 110 219 b 46 474 110 367 88 431 b 38 491 40 480 38 487 b 49 505 38 498 42 502 "},"v7d":{"x_min":-1.359375,"x_max":436.921875,"ha":446,"o":"m 213 205 b 217 205 215 205 216 205 b 234 194 224 205 234 199 b 236 187 234 194 235 190 l 245 167 l 261 129 l 270 106 b 355 -61 294 54 329 -13 b 420 -163 381 -105 402 -138 b 436 -188 435 -184 436 -184 b 436 -191 436 -190 436 -190 b 421 -206 436 -201 431 -206 l 421 -206 l 416 -206 l 405 -201 b 217 -158 347 -172 283 -158 b 31 -201 153 -158 88 -172 l 20 -206 l 14 -206 l 14 -206 b 0 -191 5 -206 0 -201 b -1 -188 0 -190 -1 -190 b 14 -163 -1 -186 0 -184 b 95 -34 36 -136 72 -77 b 166 106 119 8 148 68 l 175 129 l 183 148 l 200 188 b 213 205 205 199 208 202 "},"v7f":{"x_min":0,"x_max":367.5,"ha":375,"o":"m 0 124 l 0 187 l 61 187 l 122 187 l 122 138 l 122 91 l 153 61 l 183 30 l 213 61 l 243 91 l 243 138 l 243 187 l 306 187 l 367 187 l 367 124 l 367 61 l 321 61 l 274 61 l 243 30 l 213 0 l 243 -31 l 274 -62 l 321 -62 l 367 -62 l 367 -124 l 367 -188 l 306 -188 l 243 -188 l 243 -140 l 243 -93 l 213 -62 l 183 -31 l 153 -62 l 122 -93 l 122 -140 l 122 -188 l 61 -188 l 0 -188 l 0 -124 l 0 -62 l 46 -62 l 92 -62 l 123 -31 l 153 0 l 123 30 l 92 61 l 46 61 l 0 61 l 0 124 "},"v80":{"x_min":29.9375,"x_max":420.578125,"ha":371,"o":"m 115 345 b 221 347 117 345 166 347 b 411 345 306 347 409 345 b 420 330 416 342 420 335 b 415 319 420 326 419 321 b 178 118 397 303 179 118 b 178 117 178 118 178 117 b 181 117 178 117 178 117 b 189 117 182 117 185 117 b 193 117 190 117 191 117 b 247 98 215 117 232 111 b 296 75 266 83 280 76 b 302 75 299 75 300 75 b 322 91 311 75 315 79 b 322 91 322 91 322 91 b 322 91 322 91 322 91 b 319 91 322 91 321 91 b 313 90 318 90 315 90 b 283 107 300 90 288 97 b 277 126 279 114 277 121 b 319 167 277 149 295 167 b 319 167 319 167 319 167 b 362 118 347 167 362 147 b 355 82 362 108 359 96 b 311 33 349 65 340 55 b 224 1 284 12 253 1 b 194 5 213 1 204 2 b 168 18 183 8 178 11 b 110 36 151 30 130 36 b 57 15 88 36 68 29 b 47 11 54 12 51 11 b 31 20 40 11 34 13 b 29 26 31 22 29 25 b 68 66 29 36 39 45 b 285 250 73 71 281 248 b 285 250 285 250 285 250 b 231 252 285 252 261 252 b 137 250 190 252 141 250 b 93 227 122 248 110 241 b 78 220 88 222 83 220 b 66 227 74 220 70 222 b 63 234 65 229 63 231 b 85 291 63 241 69 252 b 115 345 108 342 108 344 "},"v81":{"x_min":0,"x_max":428.75,"ha":438,"o":"m 262 186 b 273 186 266 186 272 186 b 274 186 273 186 274 186 b 285 186 274 186 280 186 b 428 48 375 181 428 122 b 386 -68 428 12 416 -29 b 155 -187 329 -145 236 -187 b 12 -111 92 -187 38 -162 b 0 -51 4 -91 0 -72 b 262 186 0 58 122 179 m 366 131 b 352 134 362 133 357 134 b 219 81 321 134 269 115 b 47 -111 126 23 50 -62 b 47 -112 47 -111 47 -112 b 77 -136 47 -129 58 -136 b 264 -45 118 -136 194 -101 b 382 109 336 12 382 76 b 366 131 382 120 377 129 "},"v83":{"x_min":-1.359375,"x_max":847.96875,"ha":865,"o":"m 488 1499 b 495 1500 490 1500 492 1500 b 541 1465 507 1500 521 1490 b 679 1078 622 1372 679 1210 b 677 1050 679 1068 677 1060 b 477 642 668 893 604 764 l 443 609 l 431 596 l 431 592 l 438 562 l 449 508 l 460 458 b 481 355 475 390 481 355 b 481 355 481 355 481 355 b 490 356 481 355 485 355 b 528 358 495 356 511 358 b 558 356 540 358 552 356 b 839 95 699 338 808 237 b 847 22 845 72 847 47 b 631 -303 847 -113 766 -242 b 620 -309 623 -308 620 -309 l 620 -310 b 631 -359 620 -310 626 -333 l 646 -435 l 660 -496 b 672 -588 668 -535 672 -563 b 664 -653 672 -610 669 -630 b 383 -875 630 -792 509 -875 b 201 -810 321 -875 257 -855 b 129 -680 151 -768 129 -730 b 274 -530 129 -592 200 -530 b 351 -553 300 -530 326 -538 b 412 -669 393 -582 412 -626 b 287 -805 412 -735 366 -800 l 279 -805 l 285 -809 b 383 -830 318 -823 351 -830 b 586 -718 464 -830 540 -789 b 626 -584 612 -678 626 -631 b 619 -528 626 -566 623 -548 b 612 -495 619 -526 616 -510 b 577 -324 590 -387 577 -324 b 577 -324 577 -324 577 -324 b 568 -326 575 -324 571 -324 b 528 -334 558 -328 537 -333 b 465 -338 506 -337 485 -338 b 24 -11 269 -338 87 -206 b -1 145 8 41 -1 93 b 96 442 -1 249 32 351 b 322 714 166 541 236 626 l 352 745 l 345 782 l 332 843 l 315 921 b 303 984 310 950 304 978 b 295 1082 298 1017 295 1049 b 413 1426 295 1208 336 1329 b 488 1499 436 1456 477 1496 m 549 1301 b 541 1301 547 1301 544 1301 b 411 1207 500 1301 447 1263 b 355 1004 374 1152 355 1079 b 359 942 355 984 356 963 b 371 881 362 927 363 917 l 385 818 b 392 782 389 799 392 784 l 392 782 b 434 828 393 782 424 816 b 607 1165 534 941 594 1060 b 608 1193 608 1175 608 1183 b 597 1270 608 1224 604 1254 b 549 1301 589 1286 571 1299 m 398 528 b 393 555 396 542 393 553 b 392 555 393 555 393 555 b 317 470 390 555 347 505 b 190 298 266 408 212 334 b 127 70 148 227 127 148 b 155 -77 127 19 137 -30 b 468 -303 209 -216 333 -303 b 519 -299 484 -303 502 -302 b 568 -284 541 -295 568 -287 l 568 -284 b 563 -263 568 -284 566 -274 l 534 -120 l 511 -13 l 496 61 l 480 133 b 469 187 472 176 469 187 b 468 188 469 187 469 188 b 416 162 462 188 430 172 b 337 13 364 126 337 69 b 413 -124 337 -40 363 -93 b 428 -144 424 -131 428 -137 b 428 -149 428 -145 428 -148 b 409 -166 426 -161 419 -166 b 394 -162 405 -166 400 -165 b 240 77 302 -122 240 -27 l 240 77 b 430 342 240 197 315 301 l 436 344 l 426 394 l 398 528 m 548 194 b 526 195 540 195 532 195 b 519 195 524 195 521 195 l 514 195 l 518 177 l 539 79 l 552 15 l 566 -48 l 594 -187 l 605 -240 b 612 -266 609 -254 611 -266 b 612 -266 612 -266 612 -266 b 641 -248 613 -266 630 -256 b 744 -98 692 -212 730 -156 b 751 -40 749 -79 751 -59 b 548 194 751 76 665 181 "},"v84":{"x_min":25.859375,"x_max":164.6875,"ha":168,"o":"m 34 369 b 40 370 35 370 38 370 b 59 353 49 370 50 367 b 164 40 122 254 155 158 b 164 0 164 33 164 16 b 164 -40 164 -16 164 -34 b 59 -353 155 -158 122 -254 b 40 -371 53 -366 47 -371 b 34 -370 38 -371 36 -370 b 25 -358 28 -367 25 -363 b 31 -337 25 -352 27 -347 b 92 0 72 -234 92 -117 b 31 335 92 116 72 233 b 25 356 27 345 25 352 b 34 369 25 363 28 366 "},"v86":{"x_min":-571.671875,"x_max":570.3125,"ha":582,"o":"m -386 173 b -381 174 -385 174 -383 174 b -370 173 -377 174 -372 173 b -281 86 -367 172 -347 151 b -196 0 -235 37 -196 0 b -126 84 -196 0 -164 37 b -50 174 -55 173 -57 172 b -44 174 -49 174 -47 174 b -35 173 -42 174 -38 173 b 53 86 -32 172 -12 151 b 138 0 100 37 138 0 b 208 84 140 0 170 37 b 284 174 279 173 277 172 b 289 174 285 174 288 174 b 299 173 294 174 298 173 b 462 11 303 172 338 134 l 475 -1 l 503 34 b 541 76 534 72 536 74 b 548 77 544 77 545 77 b 570 56 560 77 570 68 b 567 48 570 54 568 51 b 392 -172 564 41 397 -166 b 378 -176 387 -174 382 -176 b 368 -174 374 -176 371 -176 b 280 -87 367 -173 345 -152 b 194 0 234 -38 194 0 b 125 -86 194 0 163 -38 b 49 -174 54 -174 55 -173 b 43 -176 47 -176 46 -176 b 34 -174 40 -176 36 -174 b -54 -87 31 -173 10 -152 b -140 0 -102 -38 -140 0 b -209 -86 -141 0 -171 -38 b -285 -174 -280 -174 -279 -173 b -291 -176 -287 -176 -289 -176 b -300 -174 -295 -176 -299 -174 b -464 -12 -304 -173 -340 -137 l -476 0 l -504 -34 b -543 -77 -534 -73 -537 -76 b -549 -79 -545 -79 -547 -79 b -571 -58 -562 -79 -571 -69 b -568 -49 -571 -55 -570 -52 b -392 172 -566 -43 -396 167 b -386 173 -390 172 -387 173 "},"v8a":{"x_min":-170.140625,"x_max":168.78125,"ha":172,"o":"m -160 567 b -122 567 -159 567 -149 567 l -87 567 l -84 566 b -74 553 -78 563 -77 560 b -20 366 -73 551 -49 466 b 31 186 8 267 31 186 b 85 371 31 186 55 269 b 140 559 114 473 138 557 b 153 567 141 564 148 567 b 168 559 159 567 166 564 b 168 555 168 557 168 557 b 92 281 168 548 159 513 b 14 13 50 134 14 13 b 0 0 14 6 6 0 b -17 15 -8 0 -17 8 b -93 283 -17 15 -51 136 b -170 552 -166 533 -170 548 b -170 553 -170 552 -170 552 b -160 567 -170 560 -167 564 "},"v8b":{"x_min":0,"x_max":319.859375,"ha":326,"o":"m 149 508 b 159 509 152 509 155 509 b 186 494 170 509 181 503 b 190 440 190 487 190 488 l 190 430 l 190 377 l 242 377 l 251 377 b 303 373 298 377 296 377 b 319 345 314 367 319 356 b 304 319 319 335 314 324 b 250 315 296 315 299 315 l 242 315 l 190 315 l 190 262 l 190 252 b 186 198 190 204 190 205 b 159 183 179 188 170 183 b 132 198 148 183 138 188 b 127 252 127 205 127 204 l 127 262 l 127 315 l 76 315 l 68 315 b 14 319 20 315 21 315 b 0 347 4 324 0 335 b 14 373 0 356 4 367 b 68 377 21 377 20 377 l 76 377 l 127 377 l 127 430 l 127 440 b 132 494 127 488 127 487 b 149 508 136 501 142 505 "},"v8c":{"x_min":-330.75,"x_max":329.390625,"ha":336,"o":"m -133 483 b -117 484 -127 484 -122 484 b 31 373 -51 484 9 440 b 35 348 34 365 35 356 b -25 285 35 313 10 285 b -87 331 -55 285 -76 302 b -167 402 -100 376 -133 402 b -191 398 -175 402 -183 401 b -227 341 -215 388 -227 369 b -225 320 -227 334 -227 327 b -13 74 -209 230 -125 133 b 6 65 -4 70 5 66 l 9 63 l 10 65 b 117 231 12 68 40 112 l 189 341 l 242 424 b 268 460 262 456 264 458 b 283 464 273 463 277 464 b 308 438 296 464 308 453 l 308 437 b 287 396 308 430 308 428 l 95 98 l 59 43 l 58 41 l 65 37 b 253 -156 151 -8 217 -77 b 281 -285 272 -199 281 -244 b 148 -481 281 -381 231 -463 b 115 -485 137 -484 126 -485 b -32 -376 51 -485 -9 -442 b -36 -349 -35 -366 -36 -358 b 25 -287 -36 -315 -12 -287 b 85 -333 54 -287 74 -302 b 166 -403 99 -377 133 -403 b 190 -399 174 -403 182 -402 b 225 -342 215 -390 225 -370 b 224 -322 225 -335 225 -328 b 12 -76 208 -231 125 -134 b -8 -66 2 -72 -6 -68 l -10 -65 l -12 -66 b -118 -231 -13 -68 -42 -113 l -190 -342 l -243 -426 b -269 -462 -264 -458 -265 -458 b -284 -466 -274 -464 -279 -466 b -310 -440 -298 -466 -310 -455 l -310 -438 b -288 -398 -310 -430 -308 -430 l -96 -99 l -59 -44 l -59 -43 l -66 -38 b -281 284 -198 33 -281 158 l -281 284 b -133 483 -281 392 -220 474 m 254 177 b 266 179 258 177 262 179 b 319 149 287 179 307 167 b 329 115 326 140 329 127 b 319 79 329 102 326 90 b 268 51 307 61 287 51 b 221 72 250 51 234 58 b 205 115 210 84 205 99 b 254 177 205 142 223 170 m -281 -54 b -269 -52 -277 -52 -273 -52 b -223 -73 -253 -52 -235 -59 b -206 -116 -212 -84 -206 -101 b -216 -151 -206 -129 -209 -141 b -269 -179 -228 -170 -249 -179 b -314 -159 -285 -179 -302 -173 b -330 -116 -325 -147 -330 -131 b -281 -54 -330 -88 -313 -61 "},"v8f":{"x_min":-21.78125,"x_max":362.0625,"ha":369,"o":"m 302 1031 b 308 1032 304 1032 307 1032 b 330 1016 318 1032 325 1027 b 362 867 351 970 362 920 b 340 738 362 824 353 780 l 336 727 l 340 717 b 362 591 355 677 362 634 b 257 323 362 496 325 401 b 204 272 243 306 227 290 b 20 56 129 206 66 133 b -1 18 12 44 0 22 b -19 4 -4 9 -12 4 l -21 4 l -21 140 l -21 276 l -12 277 b 167 333 61 288 127 309 b 319 598 262 388 319 491 b 311 664 319 620 317 642 l 310 673 l 304 664 b 204 548 279 620 250 587 b 20 333 129 483 66 409 b -1 292 12 320 0 298 b -19 280 -4 285 -12 280 l -21 280 l -21 416 l -21 552 l -12 553 b 167 609 61 564 127 585 b 319 874 264 666 319 770 b 294 992 319 914 311 954 b 288 1011 288 1004 288 1007 b 302 1031 288 1021 294 1028 "},"v90":{"x_min":-171.5,"x_max":483.1875,"ha":493,"o":"m -8 631 b -1 632 -6 632 -4 632 b 19 620 8 632 16 628 b 20 495 20 616 20 616 b 20 373 20 427 20 373 b 115 410 20 373 63 390 l 210 448 l 210 531 b 212 620 210 614 210 616 b 231 632 215 628 223 632 b 246 627 236 632 242 631 b 251 541 251 620 251 628 l 251 463 l 315 489 b 387 514 368 509 381 514 b 393 513 390 514 392 514 b 406 494 402 510 406 502 b 397 476 406 487 404 480 b 323 446 396 474 363 462 l 251 417 l 251 283 l 251 148 l 254 151 b 370 199 291 183 332 199 b 415 191 385 199 400 197 b 483 84 458 176 483 134 b 461 0 483 58 476 29 b 332 -142 439 -40 411 -72 l 255 -215 b 231 -229 240 -229 239 -229 b 216 -223 224 -229 220 -227 b 210 -158 210 -217 210 -223 b 210 -120 210 -148 210 -136 l 210 -29 l 205 -34 b 100 -142 182 -65 159 -88 l 23 -215 b -1 -229 9 -229 6 -229 b -19 -217 -9 -229 -16 -224 l -20 -215 l -21 48 l -21 310 l -83 287 b -152 262 -133 266 -145 262 b -157 263 -153 262 -155 262 b -171 283 -166 266 -171 274 b -161 301 -171 290 -167 297 b -91 328 -160 302 -129 315 l -21 356 l -21 487 l -20 617 l -19 621 b -8 631 -17 626 -12 630 m 210 288 b 210 401 210 351 210 401 b 114 365 209 401 167 384 l 20 327 l 20 238 l 20 148 l 21 151 b 140 199 59 183 102 199 b 206 180 164 199 187 192 l 209 177 b 209 177 209 177 209 177 b 210 288 210 177 210 199 m 110 131 b 96 133 106 133 100 133 b 89 133 93 133 91 133 b 24 87 63 129 40 113 l 20 80 l 20 -37 l 20 -156 l 23 -152 b 144 81 96 -72 144 20 l 144 83 b 110 131 144 113 134 126 m 341 131 b 328 133 337 133 332 133 b 322 133 326 133 323 133 b 257 87 296 129 273 113 l 251 80 l 251 -37 l 251 -156 l 255 -152 b 375 81 328 -72 375 20 l 375 83 b 341 131 375 113 367 126 "},"v92":{"x_min":0,"x_max":598.890625,"ha":611,"o":"m 62 181 b 77 183 66 183 72 183 b 91 181 83 183 88 183 b 202 131 100 180 106 177 l 299 87 l 394 131 b 517 183 499 181 502 183 b 519 183 517 183 518 183 b 598 104 567 183 598 144 b 577 49 598 84 592 65 b 518 15 567 38 563 37 b 484 0 499 6 484 0 b 518 -16 484 -1 499 -8 b 577 -51 563 -38 567 -40 b 598 -105 592 -66 598 -86 b 519 -184 598 -145 567 -184 b 517 -184 518 -184 517 -184 b 394 -133 502 -184 499 -183 l 299 -88 l 202 -133 b 81 -184 99 -183 95 -184 b 77 -184 80 -184 78 -184 b 0 -105 29 -184 0 -145 b 20 -51 0 -86 5 -66 b 80 -16 29 -40 34 -38 b 114 -1 98 -8 114 -1 b 80 15 114 0 98 6 b 20 49 34 37 29 38 b 0 104 6 65 0 84 b 62 181 0 140 23 174 m 88 134 b 74 136 85 134 80 136 b 68 134 72 136 69 136 b 46 104 54 130 46 117 b 55 81 46 95 49 88 b 149 34 59 76 53 80 b 224 -1 190 15 224 0 b 144 -38 224 -1 187 -18 b 54 -84 59 -79 58 -79 b 46 -105 49 -90 46 -98 b 76 -137 46 -122 58 -137 b 78 -137 77 -137 77 -137 b 194 -86 87 -137 76 -141 b 298 -36 250 -58 298 -36 b 298 -36 298 -36 298 -36 b 402 -84 299 -36 345 -58 b 518 -137 522 -141 510 -137 b 521 -137 519 -137 519 -137 b 551 -105 539 -137 551 -122 b 541 -83 551 -98 548 -90 b 447 -36 537 -77 544 -81 b 374 -1 406 -16 374 -1 b 447 34 374 0 406 15 b 541 81 544 80 537 76 b 551 104 548 88 551 97 b 521 136 551 120 539 136 b 518 136 519 136 519 136 b 517 136 518 136 517 136 l 517 136 b 402 83 511 136 511 136 b 298 34 345 56 299 34 b 298 34 298 34 298 34 b 194 84 298 34 250 56 b 88 134 137 111 89 133 "},"v93":{"x_min":0,"x_max":438.28125,"ha":447,"o":"m 212 205 b 219 205 213 205 216 205 b 239 183 228 205 231 204 b 421 -163 298 40 363 -83 b 438 -191 434 -180 438 -186 b 436 -197 438 -192 438 -195 b 424 -206 434 -204 431 -206 b 406 -201 420 -206 415 -205 b 216 -156 347 -172 281 -156 b 23 -205 148 -156 80 -173 b 14 -206 20 -206 17 -206 b 0 -191 6 -206 0 -201 b 6 -176 0 -187 1 -183 b 202 192 63 -104 142 45 b 212 205 205 199 208 202 m 264 48 l 249 81 l 243 94 l 242 91 b 89 -126 208 36 137 -66 b 81 -138 85 -133 81 -138 b 81 -138 81 -138 81 -138 b 81 -138 81 -138 81 -138 b 95 -133 81 -138 87 -136 b 280 -94 156 -108 221 -94 b 334 -98 299 -94 317 -95 b 343 -99 338 -99 343 -99 b 343 -99 343 -99 343 -99 b 338 -94 343 -99 341 -97 b 264 48 318 -58 287 1 "},"v94":{"x_min":-149.71875,"x_max":148.359375,"ha":151,"o":"m -9 215 b 0 217 -6 217 -4 217 b 19 205 8 217 14 213 b 20 142 20 202 20 201 l 20 84 l 23 84 b 144 -27 81 74 129 30 b 148 -66 147 -40 148 -54 b 36 -213 148 -134 103 -197 b 0 -219 24 -217 12 -219 b -145 -104 -68 -219 -129 -173 b -149 -68 -148 -91 -149 -79 b -24 84 -149 6 -98 74 l -21 84 l -21 142 b -19 205 -20 201 -20 202 b -9 215 -17 209 -13 213 m -21 -15 b -23 41 -21 37 -21 41 b -23 41 -23 41 -23 41 b -76 11 -35 40 -62 26 b -108 -65 -98 -11 -108 -38 b -1 -176 -108 -122 -65 -176 b 107 -65 63 -176 107 -122 b 74 11 107 -38 96 -11 b 20 41 61 26 32 41 b 20 -15 20 41 20 15 b 19 -74 20 -72 20 -72 b 0 -87 14 -83 6 -87 b -19 -74 -8 -87 -16 -83 b -21 -15 -20 -72 -20 -72 "},"v95":{"x_min":0,"x_max":406.96875,"ha":415,"o":"m 55 181 b 70 183 61 183 66 183 b 111 170 85 183 99 179 b 160 130 115 167 137 149 l 202 95 l 245 130 b 319 181 299 176 302 179 b 334 183 325 183 330 183 b 406 109 375 183 406 148 b 401 81 406 99 405 91 b 348 24 394 65 390 59 b 318 -1 332 11 318 0 b 348 -26 318 -1 332 -12 b 401 -83 390 -61 394 -66 b 406 -111 405 -93 406 -101 b 334 -184 406 -149 375 -184 b 319 -183 330 -184 325 -184 b 245 -131 302 -180 299 -177 l 202 -97 l 160 -131 b 85 -183 107 -177 103 -180 b 70 -184 80 -184 76 -184 b 0 -111 31 -184 0 -149 b 4 -83 0 -101 1 -93 b 58 -26 10 -66 16 -61 b 88 -1 74 -12 88 -1 b 58 24 88 0 74 11 b 10 69 23 54 17 59 b 0 109 2 81 0 95 b 55 181 0 142 21 173 m 83 133 b 72 136 78 136 76 136 b 57 131 66 136 61 134 b 46 109 49 126 46 117 b 50 93 46 104 47 98 b 107 45 51 91 77 70 b 160 0 137 20 160 0 b 107 -47 160 -1 137 -22 b 50 -94 77 -72 51 -93 b 46 -111 47 -99 46 -105 b 59 -134 46 -120 50 -130 b 72 -137 62 -136 68 -137 b 83 -136 76 -137 80 -136 b 144 -84 84 -134 107 -116 b 202 -36 176 -58 202 -36 b 261 -84 202 -36 230 -58 b 323 -136 299 -116 321 -134 b 334 -137 326 -136 330 -137 b 345 -134 338 -137 343 -136 b 360 -111 355 -130 360 -120 b 355 -94 360 -105 359 -99 b 299 -47 353 -93 329 -72 b 245 0 269 -22 245 -1 b 299 45 245 0 269 20 b 355 93 329 70 353 91 b 360 109 359 98 360 104 b 345 133 360 119 355 129 b 334 136 343 134 338 136 b 323 134 330 136 326 134 b 261 83 321 133 299 115 b 202 34 230 56 202 34 b 144 83 202 34 176 56 b 83 133 106 115 84 133 "},"v97":{"x_min":-228.671875,"x_max":227.3125,"ha":232,"o":"m -217 487 l -213 488 l 0 488 l 212 488 l 216 487 b 225 476 220 484 224 480 l 227 473 l 227 244 l 227 15 l 225 12 b 206 0 223 4 215 0 b 197 1 204 0 200 0 b 187 12 193 4 189 6 l 186 15 l 186 138 l 186 262 l -1 262 l -187 262 l -187 138 l -187 15 l -189 12 b -208 0 -193 4 -200 0 b -227 12 -216 0 -223 4 l -228 15 l -228 244 l -228 473 l -227 476 b -217 487 -225 480 -221 484 "},"v9a":{"x_min":-21.78125,"x_max":367.5,"ha":375,"o":"m 230 1031 b 238 1032 232 1032 235 1032 b 259 1014 245 1032 251 1027 b 367 662 330 906 367 782 b 364 602 367 641 367 621 b 232 317 352 488 304 384 b 57 120 155 245 103 187 b -1 18 31 84 6 40 b -19 4 -4 11 -12 4 l -21 4 l -21 159 l -21 315 l -16 315 b 96 335 10 315 62 324 b 315 695 227 380 315 527 b 313 738 315 709 314 724 b 224 991 304 825 273 916 b 216 1013 219 999 216 1007 b 230 1031 216 1021 220 1028 "},"v9b":{"x_min":-24.5,"x_max":313.0625,"ha":319,"o":"m -24 -133 l -24 -5 l -20 -5 b -1 -19 -12 -5 -4 -11 b 142 -213 13 -61 74 -144 b 258 -376 196 -269 230 -315 b 313 -605 295 -449 313 -528 b 292 -742 313 -652 306 -699 b 288 -752 289 -748 288 -752 b 288 -752 288 -752 288 -752 b 292 -764 289 -753 291 -757 b 313 -907 306 -811 313 -860 b 292 -1045 313 -954 306 -1002 b 288 -1054 289 -1050 288 -1054 b 288 -1054 288 -1054 288 -1054 b 292 -1067 289 -1054 291 -1060 b 313 -1210 306 -1113 313 -1161 b 292 -1346 313 -1257 306 -1304 b 288 -1357 289 -1353 288 -1357 b 288 -1357 288 -1357 288 -1357 b 292 -1368 289 -1357 291 -1363 b 313 -1512 306 -1415 313 -1464 b 292 -1648 313 -1560 306 -1605 b 288 -1660 289 -1654 288 -1660 b 288 -1660 288 -1660 288 -1660 b 292 -1671 289 -1660 291 -1665 b 313 -1814 306 -1719 313 -1766 b 250 -2040 313 -1897 291 -1977 b 232 -2062 238 -2057 236 -2059 b 221 -2065 230 -2063 225 -2065 b 200 -2045 210 -2065 201 -2057 b 200 -2043 200 -2044 200 -2044 b 208 -2026 200 -2037 202 -2034 b 269 -1826 249 -1966 269 -1897 b 153 -1544 269 -1726 230 -1625 b -9 -1472 115 -1506 58 -1481 b -21 -1471 -14 -1471 -19 -1471 l -24 -1471 l -24 -1343 l -24 -1215 l -20 -1215 b -1 -1229 -12 -1215 -4 -1221 b 142 -1424 13 -1270 74 -1353 b 257 -1582 196 -1478 228 -1524 b 264 -1594 261 -1589 264 -1594 l 264 -1594 b 265 -1582 264 -1594 264 -1589 b 270 -1525 268 -1562 270 -1544 b 153 -1243 270 -1424 228 -1321 b -9 -1170 115 -1203 58 -1178 b -21 -1168 -14 -1170 -19 -1168 l -24 -1168 l -24 -1041 l -24 -913 l -20 -913 b -1 -927 -12 -913 -4 -918 b 142 -1121 13 -967 74 -1050 b 257 -1281 196 -1175 228 -1221 b 264 -1292 261 -1286 264 -1292 l 264 -1292 b 265 -1279 264 -1292 264 -1286 b 270 -1222 268 -1261 270 -1242 b 153 -941 270 -1121 228 -1018 b -9 -867 115 -900 58 -875 b -21 -866 -14 -867 -19 -866 l -24 -866 l -24 -738 l -24 -610 l -20 -610 b -1 -624 -12 -610 -4 -616 b 142 -818 13 -664 74 -749 b 257 -978 196 -873 228 -918 b 264 -989 261 -984 264 -989 l 264 -989 b 265 -977 264 -989 264 -984 b 270 -920 268 -959 270 -939 b 153 -638 270 -818 228 -716 b -9 -564 115 -598 58 -573 b -21 -563 -14 -564 -19 -563 l -24 -563 l -24 -435 l -24 -308 l -20 -308 b -1 -322 -12 -308 -4 -313 b 142 -516 13 -363 74 -446 b 257 -675 196 -571 228 -616 b 264 -687 261 -681 264 -687 l 264 -687 b 265 -674 264 -687 264 -681 b 270 -617 268 -656 270 -637 b 153 -335 270 -516 228 -413 b -9 -262 115 -295 58 -270 b -21 -260 -14 -262 -19 -260 l -24 -260 l -24 -133 "},"v9c":{"x_min":-166.0625,"x_max":-25.859375,"ha":0,"o":"m -49 369 b -42 370 -46 369 -44 370 b -27 360 -36 370 -29 366 b -25 355 -27 359 -25 358 b -32 335 -25 351 -28 347 b -92 52 -66 248 -87 159 b -93 -1 -93 43 -93 20 b -92 -54 -93 -23 -93 -45 b -32 -337 -85 -162 -66 -251 b -25 -355 -27 -349 -25 -352 b -42 -371 -25 -365 -32 -371 b -61 -353 -50 -371 -51 -369 b -163 -63 -119 -262 -153 -165 b -166 -1 -166 -37 -166 -31 b -163 62 -166 30 -166 36 b -61 352 -153 163 -119 260 b -49 369 -54 365 -51 366 "},"v9e":{"x_min":0,"x_max":607.0625,"ha":619,"o":"m 243 631 b 250 632 246 632 249 632 b 270 620 259 632 268 628 l 272 616 l 272 201 l 272 -212 l 270 -216 b 251 -229 268 -224 259 -229 b 227 -215 243 -229 240 -229 l 151 -142 b 32 -16 81 -80 53 -49 b 0 84 9 18 0 52 b 111 199 0 149 42 199 b 137 197 119 199 127 198 b 228 151 168 191 197 177 l 231 148 l 231 383 b 232 620 231 616 231 616 b 243 631 234 624 238 630 m 168 131 b 152 133 163 133 157 133 b 107 102 130 133 111 120 b 106 86 107 97 106 91 b 111 41 106 73 108 56 b 227 -152 125 -13 171 -90 l 231 -156 l 231 -37 l 231 80 l 225 87 b 168 131 210 111 190 126 m 347 631 b 353 632 348 632 351 632 b 374 620 363 632 371 628 b 375 383 375 616 375 616 l 375 148 l 377 151 b 492 199 415 183 454 199 b 537 191 507 199 522 197 b 607 84 582 176 607 134 b 583 0 607 58 598 29 b 455 -142 562 -40 533 -72 l 378 -215 b 355 -229 364 -229 362 -229 b 334 -216 345 -229 337 -224 l 333 -212 l 333 201 l 333 616 l 334 620 b 347 631 337 624 341 630 m 465 131 b 451 133 461 133 455 133 b 445 133 449 133 446 133 b 379 87 419 129 396 113 l 375 80 l 375 -37 l 375 -156 l 378 -152 b 499 81 451 -72 499 20 l 499 83 b 465 131 499 113 490 126 "},"va3":{"x_min":58.53125,"x_max":228.671875,"ha":294,"o":"m 138 371 b 142 373 140 371 141 373 b 178 342 149 373 156 366 b 228 251 217 297 228 278 b 228 244 228 248 228 247 b 176 147 227 212 212 184 b 123 73 152 122 132 93 b 121 62 122 70 121 66 b 145 13 121 48 129 31 b 153 -2 151 6 153 1 b 149 -9 153 -5 152 -6 b 144 -11 148 -11 145 -11 b 129 -1 140 -11 136 -8 b 61 87 89 37 68 68 b 58 113 59 95 58 105 b 110 215 58 144 74 177 b 163 287 134 240 155 269 b 166 299 166 291 166 295 b 141 348 166 313 157 330 b 133 360 134 356 133 358 b 133 363 133 362 133 362 b 138 371 133 367 136 370 "},"va5":{"x_min":0,"x_max":349.8125,"ha":357,"o":"m 88 302 b 103 303 93 302 98 303 b 202 224 149 303 191 270 b 205 199 204 216 205 208 b 178 129 205 173 196 147 l 175 126 l 182 127 b 307 249 236 142 284 190 b 313 259 308 254 311 258 b 329 267 317 265 323 267 b 349 247 340 267 349 259 b 201 -263 349 242 204 -258 b 182 -273 197 -270 190 -273 b 163 -260 174 -273 166 -269 b 161 -256 161 -259 161 -258 b 217 -59 161 -248 170 -220 b 272 129 247 43 272 127 b 272 129 272 129 272 129 b 264 122 272 129 268 126 b 140 80 227 94 183 80 b 36 115 102 80 65 91 b 0 194 10 136 0 165 b 88 302 0 244 32 292 "},"va9":{"x_min":-24.5,"x_max":314.421875,"ha":321,"o":"m -24 -145 l -24 -5 l -20 -5 b 0 -23 -9 -5 -2 -12 b 27 -87 4 -38 14 -66 b 138 -220 53 -136 88 -177 b 235 -328 179 -255 208 -288 b 314 -592 287 -409 314 -501 b 292 -732 314 -639 307 -687 l 289 -742 l 294 -756 b 314 -896 307 -802 314 -849 b 292 -1035 314 -943 307 -991 l 289 -1045 l 294 -1057 b 314 -1197 307 -1104 314 -1152 b 292 -1338 314 -1246 307 -1292 l 289 -1347 l 294 -1360 b 314 -1500 307 -1407 314 -1454 b 273 -1689 314 -1565 300 -1628 b 250 -1712 265 -1710 261 -1712 b 228 -1691 236 -1712 228 -1704 l 228 -1685 l 234 -1675 b 270 -1507 258 -1621 270 -1564 b 98 -1193 270 -1381 209 -1261 b 40 -1174 76 -1179 58 -1174 b -10 -1189 24 -1174 8 -1178 b -20 -1192 -14 -1192 -16 -1192 l -24 -1192 l -24 -1052 l -24 -913 l -20 -913 b 0 -931 -9 -913 -2 -920 b 27 -995 4 -946 14 -974 b 138 -1128 53 -1043 88 -1085 b 257 -1275 190 -1172 228 -1220 b 262 -1283 259 -1279 262 -1283 l 262 -1283 b 269 -1249 264 -1282 268 -1260 b 270 -1206 270 -1233 270 -1220 b 98 -891 270 -1075 206 -957 b 40 -871 76 -877 58 -871 b -10 -886 24 -871 8 -875 b -20 -889 -14 -889 -16 -889 l -24 -889 l -24 -749 l -24 -610 l -20 -610 b 0 -628 -9 -610 -2 -617 b 27 -692 4 -644 14 -671 b 138 -825 53 -741 88 -782 b 257 -973 190 -870 228 -917 b 262 -981 259 -977 262 -981 l 262 -981 b 269 -946 264 -979 268 -957 b 270 -903 270 -931 270 -917 b 98 -588 270 -774 206 -655 b 40 -569 76 -574 58 -569 b -10 -584 24 -569 8 -574 b -20 -587 -14 -587 -16 -587 l -24 -587 l -24 -448 l -24 -308 l -20 -308 b 0 -326 -9 -308 -2 -315 b 27 -390 4 -341 14 -369 b 138 -523 53 -438 88 -480 b 257 -670 190 -567 228 -614 b 262 -678 259 -674 262 -678 b 262 -678 262 -678 262 -678 b 269 -644 264 -677 268 -656 b 270 -601 270 -628 270 -614 b 98 -285 270 -471 206 -352 b 40 -266 76 -273 58 -266 b -10 -281 24 -266 8 -272 b -20 -284 -14 -284 -16 -284 l -24 -284 l -24 -145 "},"vaa":{"x_min":-1.359375,"x_max":752.703125,"ha":768,"o":"m 490 985 b 504 986 495 986 500 986 b 604 907 551 986 593 954 b 607 884 607 900 607 892 b 581 813 607 857 597 831 l 578 810 l 583 811 b 710 932 638 827 687 873 b 714 943 711 936 713 942 b 730 952 720 949 725 952 b 752 931 741 952 752 943 b 200 -946 752 927 204 -941 b 182 -957 197 -953 190 -957 b 163 -945 174 -957 166 -953 b 161 -939 161 -942 161 -942 b 217 -743 161 -931 170 -904 b 272 -555 247 -639 272 -555 b 272 -555 272 -555 272 -555 b 264 -560 272 -555 268 -557 b 140 -603 227 -589 182 -603 b 36 -567 102 -603 65 -592 b -1 -487 12 -548 -1 -517 b 17 -427 -1 -466 5 -445 b 103 -380 38 -395 70 -380 b 191 -433 137 -380 172 -398 b 205 -484 201 -448 205 -466 b 178 -553 205 -509 196 -535 l 175 -557 l 182 -555 b 307 -435 236 -539 284 -494 b 372 -213 308 -430 372 -215 b 372 -213 372 -213 372 -213 b 364 -219 372 -213 368 -216 b 240 -262 328 -247 283 -262 b 137 -226 202 -262 166 -249 b 99 -145 112 -206 99 -176 b 118 -84 99 -124 106 -104 b 204 -38 138 -54 171 -38 b 292 -91 238 -38 273 -56 b 306 -141 302 -106 306 -124 b 279 -212 306 -167 296 -194 l 276 -215 l 281 -213 b 408 -93 336 -198 385 -151 b 473 129 409 -88 473 127 b 473 129 473 129 473 129 b 465 122 473 129 469 126 b 341 80 428 94 383 80 b 236 115 303 80 266 91 b 200 195 213 136 200 165 b 217 256 200 217 206 238 b 304 303 239 287 272 303 b 393 249 338 303 374 285 b 406 199 402 234 406 217 b 379 129 406 173 397 148 l 377 126 l 382 127 b 509 248 436 142 485 190 b 574 470 510 254 574 469 b 574 470 574 470 574 470 b 566 464 574 470 570 467 b 442 421 529 435 484 421 b 337 458 404 421 367 433 b 300 538 314 477 300 508 b 318 598 300 559 306 580 b 404 645 340 630 372 645 b 494 592 439 645 475 627 b 507 541 502 577 507 559 b 480 471 507 516 498 489 l 477 467 l 483 470 b 608 589 537 485 586 531 b 675 811 611 595 675 810 b 675 811 675 811 675 811 b 666 806 675 811 671 809 b 543 763 628 777 585 763 b 438 799 504 763 468 775 b 401 878 412 820 401 849 b 490 985 401 928 434 977 "},"vab":{"x_min":0,"x_max":272.21875,"ha":278,"o":"m 243 631 b 250 632 246 632 249 632 b 270 620 259 632 268 628 l 272 616 l 272 201 l 272 -212 l 270 -216 b 251 -229 268 -224 259 -229 b 227 -215 243 -229 240 -229 l 151 -142 b 32 -16 81 -80 53 -49 b 0 84 9 18 0 52 b 111 199 0 149 42 199 b 137 197 119 199 127 198 b 228 151 168 191 197 177 l 231 148 l 231 383 b 232 620 231 616 231 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment