lodash1.3.1.js 183 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555
  1. /**
  2. * @license
  3. * Lo-Dash 1.3.1 (Custom Build) <http://lodash.com/>
  4. * Build: `lodash modern -o ./dist/lodash.js`
  5. * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
  6. * Based on Underscore.js 1.4.4 <http://underscorejs.org/>
  7. * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
  8. * Available under MIT license <http://lodash.com/license>
  9. */
  10. ;(function(window) {
  11. /** Used as a safe reference for `undefined` in pre ES5 environments */
  12. var undefined;
  13. /** Used to pool arrays and objects used internally */
  14. var arrayPool = [],
  15. objectPool = [];
  16. /** Used to generate unique IDs */
  17. var idCounter = 0;
  18. /** Used internally to indicate various things */
  19. var indicatorObject = {};
  20. /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */
  21. var keyPrefix = +new Date + '';
  22. /** Used as the size when optimizations are enabled for large arrays */
  23. var largeArraySize = 75;
  24. /** Used as the max size of the `arrayPool` and `objectPool` */
  25. var maxPoolSize = 40;
  26. /** Used to match empty string literals in compiled template source */
  27. var reEmptyStringLeading = /\b__p \+= '';/g,
  28. reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
  29. reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
  30. /** Used to match HTML entities */
  31. var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g;
  32. /**
  33. * Used to match ES6 template delimiters
  34. * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6
  35. */
  36. var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
  37. /** Used to match regexp flags from their coerced string values */
  38. var reFlags = /\w*$/;
  39. /** Used to match "interpolate" template delimiters */
  40. var reInterpolate = /<%=([\s\S]+?)%>/g;
  41. /** Used to detect functions containing a `this` reference */
  42. var reThis = (reThis = /\bthis\b/) && reThis.test(runInContext) && reThis;
  43. /** Used to detect and test whitespace */
  44. var whitespace = (
  45. // whitespace
  46. ' \t\x0B\f\xA0\ufeff' +
  47. // line terminators
  48. '\n\r\u2028\u2029' +
  49. // unicode category "Zs" space separators
  50. '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000'
  51. );
  52. /** Used to match leading whitespace and zeros to be removed */
  53. var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)');
  54. /** Used to ensure capturing order of template delimiters */
  55. var reNoMatch = /($^)/;
  56. /** Used to match HTML characters */
  57. var reUnescapedHtml = /[&<>"']/g;
  58. /** Used to match unescaped characters in compiled string literals */
  59. var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
  60. /** Used to assign default `context` object properties */
  61. var contextProps = [
  62. 'Array', 'Boolean', 'Date', 'Function', 'Math', 'Number', 'Object',
  63. 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN',
  64. 'parseInt', 'setImmediate', 'setTimeout'
  65. ];
  66. /** Used to make template sourceURLs easier to identify */
  67. var templateCounter = 0;
  68. /** `Object#toString` result shortcuts */
  69. var argsClass = '[object Arguments]',
  70. arrayClass = '[object Array]',
  71. boolClass = '[object Boolean]',
  72. dateClass = '[object Date]',
  73. errorClass = '[object Error]',
  74. funcClass = '[object Function]',
  75. numberClass = '[object Number]',
  76. objectClass = '[object Object]',
  77. regexpClass = '[object RegExp]',
  78. stringClass = '[object String]';
  79. /** Used to identify object classifications that `_.clone` supports */
  80. var cloneableClasses = {};
  81. cloneableClasses[funcClass] = false;
  82. cloneableClasses[argsClass] = cloneableClasses[arrayClass] =
  83. cloneableClasses[boolClass] = cloneableClasses[dateClass] =
  84. cloneableClasses[numberClass] = cloneableClasses[objectClass] =
  85. cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true;
  86. /** Used to determine if values are of the language type Object */
  87. var objectTypes = {
  88. 'boolean': false,
  89. 'function': true,
  90. 'object': true,
  91. 'number': false,
  92. 'string': false,
  93. 'undefined': false
  94. };
  95. /** Used to escape characters for inclusion in compiled string literals */
  96. var stringEscapes = {
  97. '\\': '\\',
  98. "'": "'",
  99. '\n': 'n',
  100. '\r': 'r',
  101. '\t': 't',
  102. '\u2028': 'u2028',
  103. '\u2029': 'u2029'
  104. };
  105. /** Detect free variable `exports` */
  106. var freeExports = objectTypes[typeof exports] && exports;
  107. /** Detect free variable `module` */
  108. var freeModule = objectTypes[typeof module] && module && module.exports == freeExports && module;
  109. /** Detect free variable `global`, from Node.js or Browserified code, and use it as `window` */
  110. var freeGlobal = objectTypes[typeof global] && global;
  111. if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
  112. window = freeGlobal;
  113. }
  114. /*--------------------------------------------------------------------------*/
  115. /**
  116. * A basic implementation of `_.indexOf` without support for binary searches
  117. * or `fromIndex` constraints.
  118. *
  119. * @private
  120. * @param {Array} array The array to search.
  121. * @param {Mixed} value The value to search for.
  122. * @param {Number} [fromIndex=0] The index to search from.
  123. * @returns {Number} Returns the index of the matched value or `-1`.
  124. */
  125. function basicIndexOf(array, value, fromIndex) {
  126. var index = (fromIndex || 0) - 1,
  127. length = array.length;
  128. while (++index < length) {
  129. if (array[index] === value) {
  130. return index;
  131. }
  132. }
  133. return -1;
  134. }
  135. /**
  136. * An implementation of `_.contains` for cache objects that mimics the return
  137. * signature of `_.indexOf` by returning `0` if the value is found, else `-1`.
  138. *
  139. * @private
  140. * @param {Object} cache The cache object to inspect.
  141. * @param {Mixed} value The value to search for.
  142. * @returns {Number} Returns `0` if `value` is found, else `-1`.
  143. */
  144. function cacheIndexOf(cache, value) {
  145. var type = typeof value;
  146. cache = cache.cache;
  147. if (type == 'boolean' || value == null) {
  148. return cache[value];
  149. }
  150. if (type != 'number' && type != 'string') {
  151. type = 'object';
  152. }
  153. var key = type == 'number' ? value : keyPrefix + value;
  154. cache = cache[type] || (cache[type] = {});
  155. return type == 'object'
  156. ? (cache[key] && basicIndexOf(cache[key], value) > -1 ? 0 : -1)
  157. : (cache[key] ? 0 : -1);
  158. }
  159. /**
  160. * Adds a given `value` to the corresponding cache object.
  161. *
  162. * @private
  163. * @param {Mixed} value The value to add to the cache.
  164. */
  165. function cachePush(value) {
  166. var cache = this.cache,
  167. type = typeof value;
  168. if (type == 'boolean' || value == null) {
  169. cache[value] = true;
  170. } else {
  171. if (type != 'number' && type != 'string') {
  172. type = 'object';
  173. }
  174. var key = type == 'number' ? value : keyPrefix + value,
  175. typeCache = cache[type] || (cache[type] = {});
  176. if (type == 'object') {
  177. if ((typeCache[key] || (typeCache[key] = [])).push(value) == this.array.length) {
  178. cache[type] = false;
  179. }
  180. } else {
  181. typeCache[key] = true;
  182. }
  183. }
  184. }
  185. /**
  186. * Used by `_.max` and `_.min` as the default `callback` when a given
  187. * `collection` is a string value.
  188. *
  189. * @private
  190. * @param {String} value The character to inspect.
  191. * @returns {Number} Returns the code unit of given character.
  192. */
  193. function charAtCallback(value) {
  194. return value.charCodeAt(0);
  195. }
  196. /**
  197. * Used by `sortBy` to compare transformed `collection` values, stable sorting
  198. * them in ascending order.
  199. *
  200. * @private
  201. * @param {Object} a The object to compare to `b`.
  202. * @param {Object} b The object to compare to `a`.
  203. * @returns {Number} Returns the sort order indicator of `1` or `-1`.
  204. */
  205. function compareAscending(a, b) {
  206. var ai = a.index,
  207. bi = b.index;
  208. a = a.criteria;
  209. b = b.criteria;
  210. // ensure a stable sort in V8 and other engines
  211. // http://code.google.com/p/v8/issues/detail?id=90
  212. if (a !== b) {
  213. if (a > b || typeof a == 'undefined') {
  214. return 1;
  215. }
  216. if (a < b || typeof b == 'undefined') {
  217. return -1;
  218. }
  219. }
  220. return ai < bi ? -1 : 1;
  221. }
  222. /**
  223. * Creates a cache object to optimize linear searches of large arrays.
  224. *
  225. * @private
  226. * @param {Array} [array=[]] The array to search.
  227. * @returns {Null|Object} Returns the cache object or `null` if caching should not be used.
  228. */
  229. function createCache(array) {
  230. var index = -1,
  231. length = array.length;
  232. var cache = getObject();
  233. cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false;
  234. var result = getObject();
  235. result.array = array;
  236. result.cache = cache;
  237. result.push = cachePush;
  238. while (++index < length) {
  239. result.push(array[index]);
  240. }
  241. return cache.object === false
  242. ? (releaseObject(result), null)
  243. : result;
  244. }
  245. /**
  246. * Used by `template` to escape characters for inclusion in compiled
  247. * string literals.
  248. *
  249. * @private
  250. * @param {String} match The matched character to escape.
  251. * @returns {String} Returns the escaped character.
  252. */
  253. function escapeStringChar(match) {
  254. return '\\' + stringEscapes[match];
  255. }
  256. /**
  257. * Gets an array from the array pool or creates a new one if the pool is empty.
  258. *
  259. * @private
  260. * @returns {Array} The array from the pool.
  261. */
  262. function getArray() {
  263. return arrayPool.pop() || [];
  264. }
  265. /**
  266. * Gets an object from the object pool or creates a new one if the pool is empty.
  267. *
  268. * @private
  269. * @returns {Object} The object from the pool.
  270. */
  271. function getObject() {
  272. return objectPool.pop() || {
  273. 'array': null,
  274. 'cache': null,
  275. 'criteria': null,
  276. 'false': false,
  277. 'index': 0,
  278. 'leading': false,
  279. 'maxWait': 0,
  280. 'null': false,
  281. 'number': null,
  282. 'object': null,
  283. 'push': null,
  284. 'string': null,
  285. 'trailing': false,
  286. 'true': false,
  287. 'undefined': false,
  288. 'value': null
  289. };
  290. }
  291. /**
  292. * A no-operation function.
  293. *
  294. * @private
  295. */
  296. function noop() {
  297. // no operation performed
  298. }
  299. /**
  300. * Releases the given `array` back to the array pool.
  301. *
  302. * @private
  303. * @param {Array} [array] The array to release.
  304. */
  305. function releaseArray(array) {
  306. array.length = 0;
  307. if (arrayPool.length < maxPoolSize) {
  308. arrayPool.push(array);
  309. }
  310. }
  311. /**
  312. * Releases the given `object` back to the object pool.
  313. *
  314. * @private
  315. * @param {Object} [object] The object to release.
  316. */
  317. function releaseObject(object) {
  318. var cache = object.cache;
  319. if (cache) {
  320. releaseObject(cache);
  321. }
  322. object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null;
  323. if (objectPool.length < maxPoolSize) {
  324. objectPool.push(object);
  325. }
  326. }
  327. /**
  328. * Slices the `collection` from the `start` index up to, but not including,
  329. * the `end` index.
  330. *
  331. * Note: This function is used, instead of `Array#slice`, to support node lists
  332. * in IE < 9 and to ensure dense arrays are returned.
  333. *
  334. * @private
  335. * @param {Array|Object|String} collection The collection to slice.
  336. * @param {Number} start The start index.
  337. * @param {Number} end The end index.
  338. * @returns {Array} Returns the new array.
  339. */
  340. function slice(array, start, end) {
  341. start || (start = 0);
  342. if (typeof end == 'undefined') {
  343. end = array ? array.length : 0;
  344. }
  345. var index = -1,
  346. length = end - start || 0,
  347. result = Array(length < 0 ? 0 : length);
  348. while (++index < length) {
  349. result[index] = array[start + index];
  350. }
  351. return result;
  352. }
  353. /*--------------------------------------------------------------------------*/
  354. /**
  355. * Create a new `lodash` function using the given `context` object.
  356. *
  357. * @static
  358. * @memberOf _
  359. * @category Utilities
  360. * @param {Object} [context=window] The context object.
  361. * @returns {Function} Returns the `lodash` function.
  362. */
  363. function runInContext(context) {
  364. // Avoid issues with some ES3 environments that attempt to use values, named
  365. // after built-in constructors like `Object`, for the creation of literals.
  366. // ES5 clears this up by stating that literals must use built-in constructors.
  367. // See http://es5.github.com/#x11.1.5.
  368. context = context ? _.defaults(window.Object(), context, _.pick(window, contextProps)) : window;
  369. /** Native constructor references */
  370. var Array = context.Array,
  371. Boolean = context.Boolean,
  372. Date = context.Date,
  373. Function = context.Function,
  374. Math = context.Math,
  375. Number = context.Number,
  376. Object = context.Object,
  377. RegExp = context.RegExp,
  378. String = context.String,
  379. TypeError = context.TypeError;
  380. /**
  381. * Used for `Array` method references.
  382. *
  383. * Normally `Array.prototype` would suffice, however, using an array literal
  384. * avoids issues in Narwhal.
  385. */
  386. var arrayRef = [];
  387. /** Used for native method references */
  388. var objectProto = Object.prototype,
  389. stringProto = String.prototype;
  390. /** Used to restore the original `_` reference in `noConflict` */
  391. var oldDash = context._;
  392. /** Used to detect if a method is native */
  393. var reNative = RegExp('^' +
  394. String(objectProto.valueOf)
  395. .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
  396. .replace(/valueOf|for [^\]]+/g, '.+?') + '$'
  397. );
  398. /** Native method shortcuts */
  399. var ceil = Math.ceil,
  400. clearTimeout = context.clearTimeout,
  401. concat = arrayRef.concat,
  402. floor = Math.floor,
  403. fnToString = Function.prototype.toString,
  404. getPrototypeOf = reNative.test(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
  405. hasOwnProperty = objectProto.hasOwnProperty,
  406. push = arrayRef.push,
  407. propertyIsEnumerable = objectProto.propertyIsEnumerable,
  408. setImmediate = context.setImmediate,
  409. setTimeout = context.setTimeout,
  410. toString = objectProto.toString;
  411. /* Native method shortcuts for methods with the same name as other `lodash` methods */
  412. var nativeBind = reNative.test(nativeBind = toString.bind) && nativeBind,
  413. nativeCreate = reNative.test(nativeCreate = Object.create) && nativeCreate,
  414. nativeIsArray = reNative.test(nativeIsArray = Array.isArray) && nativeIsArray,
  415. nativeIsFinite = context.isFinite,
  416. nativeIsNaN = context.isNaN,
  417. nativeKeys = reNative.test(nativeKeys = Object.keys) && nativeKeys,
  418. nativeMax = Math.max,
  419. nativeMin = Math.min,
  420. nativeParseInt = context.parseInt,
  421. nativeRandom = Math.random,
  422. nativeSlice = arrayRef.slice;
  423. /** Detect various environments */
  424. var isIeOpera = reNative.test(context.attachEvent),
  425. isV8 = nativeBind && !/\n|true/.test(nativeBind + isIeOpera);
  426. /** Used to lookup a built-in constructor by [[Class]] */
  427. var ctorByClass = {};
  428. ctorByClass[arrayClass] = Array;
  429. ctorByClass[boolClass] = Boolean;
  430. ctorByClass[dateClass] = Date;
  431. ctorByClass[funcClass] = Function;
  432. ctorByClass[objectClass] = Object;
  433. ctorByClass[numberClass] = Number;
  434. ctorByClass[regexpClass] = RegExp;
  435. ctorByClass[stringClass] = String;
  436. /*--------------------------------------------------------------------------*/
  437. /**
  438. * Creates a `lodash` object, which wraps the given `value`, to enable method
  439. * chaining.
  440. *
  441. * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
  442. * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
  443. * and `unshift`
  444. *
  445. * Chaining is supported in custom builds as long as the `value` method is
  446. * implicitly or explicitly included in the build.
  447. *
  448. * The chainable wrapper functions are:
  449. * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
  450. * `compose`, `concat`, `countBy`, `createCallback`, `debounce`, `defaults`,
  451. * `defer`, `delay`, `difference`, `filter`, `flatten`, `forEach`, `forIn`,
  452. * `forOwn`, `functions`, `groupBy`, `initial`, `intersection`, `invert`,
  453. * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`,
  454. * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `push`, `range`,
  455. * `reject`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`,
  456. * `tap`, `throttle`, `times`, `toArray`, `transform`, `union`, `uniq`, `unshift`,
  457. * `unzip`, `values`, `where`, `without`, `wrap`, and `zip`
  458. *
  459. * The non-chainable wrapper functions are:
  460. * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `has`,
  461. * `identity`, `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`,
  462. * `isElement`, `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`,
  463. * `isNull`, `isNumber`, `isObject`, `isPlainObject`, `isRegExp`, `isString`,
  464. * `isUndefined`, `join`, `lastIndexOf`, `mixin`, `noConflict`, `parseInt`,
  465. * `pop`, `random`, `reduce`, `reduceRight`, `result`, `shift`, `size`, `some`,
  466. * `sortedIndex`, `runInContext`, `template`, `unescape`, `uniqueId`, and `value`
  467. *
  468. * The wrapper functions `first` and `last` return wrapped values when `n` is
  469. * passed, otherwise they return unwrapped values.
  470. *
  471. * @name _
  472. * @constructor
  473. * @alias chain
  474. * @category Chaining
  475. * @param {Mixed} value The value to wrap in a `lodash` instance.
  476. * @returns {Object} Returns a `lodash` instance.
  477. * @example
  478. *
  479. * var wrapped = _([1, 2, 3]);
  480. *
  481. * // returns an unwrapped value
  482. * wrapped.reduce(function(sum, num) {
  483. * return sum + num;
  484. * });
  485. * // => 6
  486. *
  487. * // returns a wrapped value
  488. * var squares = wrapped.map(function(num) {
  489. * return num * num;
  490. * });
  491. *
  492. * _.isArray(squares);
  493. * // => false
  494. *
  495. * _.isArray(squares.value());
  496. * // => true
  497. */
  498. function lodash(value) {
  499. // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor
  500. return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__'))
  501. ? value
  502. : new lodashWrapper(value);
  503. }
  504. /**
  505. * A fast path for creating `lodash` wrapper objects.
  506. *
  507. * @private
  508. * @param {Mixed} value The value to wrap in a `lodash` instance.
  509. * @returns {Object} Returns a `lodash` instance.
  510. */
  511. function lodashWrapper(value) {
  512. this.__wrapped__ = value;
  513. }
  514. // ensure `new lodashWrapper` is an instance of `lodash`
  515. lodashWrapper.prototype = lodash.prototype;
  516. /**
  517. * An object used to flag environments features.
  518. *
  519. * @static
  520. * @memberOf _
  521. * @type Object
  522. */
  523. var support = lodash.support = {};
  524. /**
  525. * Detect if `Function#bind` exists and is inferred to be fast (all but V8).
  526. *
  527. * @memberOf _.support
  528. * @type Boolean
  529. */
  530. support.fastBind = nativeBind && !isV8;
  531. /**
  532. * By default, the template delimiters used by Lo-Dash are similar to those in
  533. * embedded Ruby (ERB). Change the following template settings to use alternative
  534. * delimiters.
  535. *
  536. * @static
  537. * @memberOf _
  538. * @type Object
  539. */
  540. lodash.templateSettings = {
  541. /**
  542. * Used to detect `data` property values to be HTML-escaped.
  543. *
  544. * @memberOf _.templateSettings
  545. * @type RegExp
  546. */
  547. 'escape': /<%-([\s\S]+?)%>/g,
  548. /**
  549. * Used to detect code to be evaluated.
  550. *
  551. * @memberOf _.templateSettings
  552. * @type RegExp
  553. */
  554. 'evaluate': /<%([\s\S]+?)%>/g,
  555. /**
  556. * Used to detect `data` property values to inject.
  557. *
  558. * @memberOf _.templateSettings
  559. * @type RegExp
  560. */
  561. 'interpolate': reInterpolate,
  562. /**
  563. * Used to reference the data object in the template text.
  564. *
  565. * @memberOf _.templateSettings
  566. * @type String
  567. */
  568. 'variable': '',
  569. /**
  570. * Used to import variables into the compiled template.
  571. *
  572. * @memberOf _.templateSettings
  573. * @type Object
  574. */
  575. 'imports': {
  576. /**
  577. * A reference to the `lodash` function.
  578. *
  579. * @memberOf _.templateSettings.imports
  580. * @type Function
  581. */
  582. '_': lodash
  583. }
  584. };
  585. /*--------------------------------------------------------------------------*/
  586. /**
  587. * Creates a function that, when called, invokes `func` with the `this` binding
  588. * of `thisArg` and prepends any `partialArgs` to the arguments passed to the
  589. * bound function.
  590. *
  591. * @private
  592. * @param {Function|String} func The function to bind or the method name.
  593. * @param {Mixed} [thisArg] The `this` binding of `func`.
  594. * @param {Array} partialArgs An array of arguments to be partially applied.
  595. * @param {Object} [idicator] Used to indicate binding by key or partially
  596. * applying arguments from the right.
  597. * @returns {Function} Returns the new bound function.
  598. */
  599. function createBound(func, thisArg, partialArgs, indicator) {
  600. var isFunc = isFunction(func),
  601. isPartial = !partialArgs,
  602. key = thisArg;
  603. // juggle arguments
  604. if (isPartial) {
  605. var rightIndicator = indicator;
  606. partialArgs = thisArg;
  607. }
  608. else if (!isFunc) {
  609. if (!indicator) {
  610. throw new TypeError;
  611. }
  612. thisArg = func;
  613. }
  614. function bound() {
  615. // `Function#bind` spec
  616. // http://es5.github.com/#x15.3.4.5
  617. var args = arguments,
  618. thisBinding = isPartial ? this : thisArg;
  619. if (!isFunc) {
  620. func = thisArg[key];
  621. }
  622. if (partialArgs.length) {
  623. args = args.length
  624. ? (args = nativeSlice.call(args), rightIndicator ? args.concat(partialArgs) : partialArgs.concat(args))
  625. : partialArgs;
  626. }
  627. if (this instanceof bound) {
  628. // ensure `new bound` is an instance of `func`
  629. thisBinding = createObject(func.prototype);
  630. // mimic the constructor's `return` behavior
  631. // http://es5.github.com/#x13.2.2
  632. var result = func.apply(thisBinding, args);
  633. return isObject(result) ? result : thisBinding;
  634. }
  635. return func.apply(thisBinding, args);
  636. }
  637. return bound;
  638. }
  639. /**
  640. * Creates a new object with the specified `prototype`.
  641. *
  642. * @private
  643. * @param {Object} prototype The prototype object.
  644. * @returns {Object} Returns the new object.
  645. */
  646. function createObject(prototype) {
  647. return isObject(prototype) ? nativeCreate(prototype) : {};
  648. }
  649. /**
  650. * Used by `escape` to convert characters to HTML entities.
  651. *
  652. * @private
  653. * @param {String} match The matched character to escape.
  654. * @returns {String} Returns the escaped character.
  655. */
  656. function escapeHtmlChar(match) {
  657. return htmlEscapes[match];
  658. }
  659. /**
  660. * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
  661. * customized, this method returns the custom method, otherwise it returns
  662. * the `basicIndexOf` function.
  663. *
  664. * @private
  665. * @returns {Function} Returns the "indexOf" function.
  666. */
  667. function getIndexOf(array, value, fromIndex) {
  668. var result = (result = lodash.indexOf) === indexOf ? basicIndexOf : result;
  669. return result;
  670. }
  671. /**
  672. * Creates a function that juggles arguments, allowing argument overloading
  673. * for `_.flatten` and `_.uniq`, before passing them to the given `func`.
  674. *
  675. * @private
  676. * @param {Function} func The function to wrap.
  677. * @returns {Function} Returns the new function.
  678. */
  679. function overloadWrapper(func) {
  680. return function(array, flag, callback, thisArg) {
  681. // juggle arguments
  682. if (typeof flag != 'boolean' && flag != null) {
  683. thisArg = callback;
  684. callback = !(thisArg && thisArg[flag] === array) ? flag : undefined;
  685. flag = false;
  686. }
  687. if (callback != null) {
  688. callback = lodash.createCallback(callback, thisArg);
  689. }
  690. return func(array, flag, callback, thisArg);
  691. };
  692. }
  693. /**
  694. * A fallback implementation of `isPlainObject` which checks if a given `value`
  695. * is an object created by the `Object` constructor, assuming objects created
  696. * by the `Object` constructor have no inherited enumerable properties and that
  697. * there are no `Object.prototype` extensions.
  698. *
  699. * @private
  700. * @param {Mixed} value The value to check.
  701. * @returns {Boolean} Returns `true`, if `value` is a plain object, else `false`.
  702. */
  703. function shimIsPlainObject(value) {
  704. var ctor,
  705. result;
  706. // avoid non Object objects, `arguments` objects, and DOM elements
  707. if (!(value && toString.call(value) == objectClass) ||
  708. (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor))) {
  709. return false;
  710. }
  711. // In most environments an object's own properties are iterated before
  712. // its inherited properties. If the last iterated property is an object's
  713. // own property then there are no inherited enumerable properties.
  714. forIn(value, function(value, key) {
  715. result = key;
  716. });
  717. return result === undefined || hasOwnProperty.call(value, result);
  718. }
  719. /**
  720. * Used by `unescape` to convert HTML entities to characters.
  721. *
  722. * @private
  723. * @param {String} match The matched character to unescape.
  724. * @returns {String} Returns the unescaped character.
  725. */
  726. function unescapeHtmlChar(match) {
  727. return htmlUnescapes[match];
  728. }
  729. /*--------------------------------------------------------------------------*/
  730. /**
  731. * Checks if `value` is an `arguments` object.
  732. *
  733. * @static
  734. * @memberOf _
  735. * @category Objects
  736. * @param {Mixed} value The value to check.
  737. * @returns {Boolean} Returns `true`, if the `value` is an `arguments` object, else `false`.
  738. * @example
  739. *
  740. * (function() { return _.isArguments(arguments); })(1, 2, 3);
  741. * // => true
  742. *
  743. * _.isArguments([1, 2, 3]);
  744. * // => false
  745. */
  746. function isArguments(value) {
  747. return toString.call(value) == argsClass;
  748. }
  749. /**
  750. * Checks if `value` is an array.
  751. *
  752. * @static
  753. * @memberOf _
  754. * @category Objects
  755. * @param {Mixed} value The value to check.
  756. * @returns {Boolean} Returns `true`, if the `value` is an array, else `false`.
  757. * @example
  758. *
  759. * (function() { return _.isArray(arguments); })();
  760. * // => false
  761. *
  762. * _.isArray([1, 2, 3]);
  763. * // => true
  764. */
  765. var isArray = nativeIsArray;
  766. /**
  767. * A fallback implementation of `Object.keys` which produces an array of the
  768. * given object's own enumerable property names.
  769. *
  770. * @private
  771. * @type Function
  772. * @param {Object} object The object to inspect.
  773. * @returns {Array} Returns a new array of property names.
  774. */
  775. var shimKeys = function (object) {
  776. var index, iterable = object, result = [];
  777. if (!iterable) return result;
  778. if (!(objectTypes[typeof object])) return result;
  779. for (index in iterable) {
  780. if (hasOwnProperty.call(iterable, index)) {
  781. result.push(index);
  782. }
  783. }
  784. return result
  785. };
  786. /**
  787. * Creates an array composed of the own enumerable property names of `object`.
  788. *
  789. * @static
  790. * @memberOf _
  791. * @category Objects
  792. * @param {Object} object The object to inspect.
  793. * @returns {Array} Returns a new array of property names.
  794. * @example
  795. *
  796. * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
  797. * // => ['one', 'two', 'three'] (order is not guaranteed)
  798. */
  799. var keys = !nativeKeys ? shimKeys : function(object) {
  800. if (!isObject(object)) {
  801. return [];
  802. }
  803. return nativeKeys(object);
  804. };
  805. /**
  806. * Used to convert characters to HTML entities:
  807. *
  808. * Though the `>` character is escaped for symmetry, characters like `>` and `/`
  809. * don't require escaping in HTML and have no special meaning unless they're part
  810. * of a tag or an unquoted attribute value.
  811. * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
  812. */
  813. var htmlEscapes = {
  814. '&': '&amp;',
  815. '<': '&lt;',
  816. '>': '&gt;',
  817. '"': '&quot;',
  818. "'": '&#39;'
  819. };
  820. /** Used to convert HTML entities to characters */
  821. var htmlUnescapes = invert(htmlEscapes);
  822. /*--------------------------------------------------------------------------*/
  823. /**
  824. * Assigns own enumerable properties of source object(s) to the destination
  825. * object. Subsequent sources will overwrite property assignments of previous
  826. * sources. If a `callback` function is passed, it will be executed to produce
  827. * the assigned values. The `callback` is bound to `thisArg` and invoked with
  828. * two arguments; (objectValue, sourceValue).
  829. *
  830. * @static
  831. * @memberOf _
  832. * @type Function
  833. * @alias extend
  834. * @category Objects
  835. * @param {Object} object The destination object.
  836. * @param {Object} [source1, source2, ...] The source objects.
  837. * @param {Function} [callback] The function to customize assigning values.
  838. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  839. * @returns {Object} Returns the destination object.
  840. * @example
  841. *
  842. * _.assign({ 'name': 'moe' }, { 'age': 40 });
  843. * // => { 'name': 'moe', 'age': 40 }
  844. *
  845. * var defaults = _.partialRight(_.assign, function(a, b) {
  846. * return typeof a == 'undefined' ? b : a;
  847. * });
  848. *
  849. * var food = { 'name': 'apple' };
  850. * defaults(food, { 'name': 'banana', 'type': 'fruit' });
  851. * // => { 'name': 'apple', 'type': 'fruit' }
  852. */
  853. var assign = function (object, source, guard) {
  854. var index, iterable = object, result = iterable;
  855. if (!iterable) return result;
  856. var args = arguments,
  857. argsIndex = 0,
  858. argsLength = typeof guard == 'number' ? 2 : args.length;
  859. if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {
  860. var callback = lodash.createCallback(args[--argsLength - 1], args[argsLength--], 2);
  861. } else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {
  862. callback = args[--argsLength];
  863. }
  864. while (++argsIndex < argsLength) {
  865. iterable = args[argsIndex];
  866. if (iterable && objectTypes[typeof iterable]) {
  867. var ownIndex = -1,
  868. ownProps = objectTypes[typeof iterable] && keys(iterable),
  869. length = ownProps ? ownProps.length : 0;
  870. while (++ownIndex < length) {
  871. index = ownProps[ownIndex];
  872. result[index] = callback ? callback(result[index], iterable[index]) : iterable[index];
  873. }
  874. }
  875. }
  876. return result
  877. };
  878. /**
  879. * Creates a clone of `value`. If `deep` is `true`, nested objects will also
  880. * be cloned, otherwise they will be assigned by reference. If a `callback`
  881. * function is passed, it will be executed to produce the cloned values. If
  882. * `callback` returns `undefined`, cloning will be handled by the method instead.
  883. * The `callback` is bound to `thisArg` and invoked with one argument; (value).
  884. *
  885. * @static
  886. * @memberOf _
  887. * @category Objects
  888. * @param {Mixed} value The value to clone.
  889. * @param {Boolean} [deep=false] A flag to indicate a deep clone.
  890. * @param {Function} [callback] The function to customize cloning values.
  891. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  892. * @param- {Array} [stackA=[]] Tracks traversed source objects.
  893. * @param- {Array} [stackB=[]] Associates clones with source counterparts.
  894. * @returns {Mixed} Returns the cloned `value`.
  895. * @example
  896. *
  897. * var stooges = [
  898. * { 'name': 'moe', 'age': 40 },
  899. * { 'name': 'larry', 'age': 50 }
  900. * ];
  901. *
  902. * var shallow = _.clone(stooges);
  903. * shallow[0] === stooges[0];
  904. * // => true
  905. *
  906. * var deep = _.clone(stooges, true);
  907. * deep[0] === stooges[0];
  908. * // => false
  909. *
  910. * _.mixin({
  911. * 'clone': _.partialRight(_.clone, function(value) {
  912. * return _.isElement(value) ? value.cloneNode(false) : undefined;
  913. * })
  914. * });
  915. *
  916. * var clone = _.clone(document.body);
  917. * clone.childNodes.length;
  918. * // => 0
  919. */
  920. function clone(value, deep, callback, thisArg, stackA, stackB) {
  921. var result = value;
  922. // allows working with "Collections" methods without using their `callback`
  923. // argument, `index|key`, for this method's `callback`
  924. if (typeof deep != 'boolean' && deep != null) {
  925. thisArg = callback;
  926. callback = deep;
  927. deep = false;
  928. }
  929. if (typeof callback == 'function') {
  930. callback = (typeof thisArg == 'undefined')
  931. ? callback
  932. : lodash.createCallback(callback, thisArg, 1);
  933. result = callback(result);
  934. if (typeof result != 'undefined') {
  935. return result;
  936. }
  937. result = value;
  938. }
  939. // inspect [[Class]]
  940. var isObj = isObject(result);
  941. if (isObj) {
  942. var className = toString.call(result);
  943. if (!cloneableClasses[className]) {
  944. return result;
  945. }
  946. var isArr = isArray(result);
  947. }
  948. // shallow clone
  949. if (!isObj || !deep) {
  950. return isObj
  951. ? (isArr ? slice(result) : assign({}, result))
  952. : result;
  953. }
  954. var ctor = ctorByClass[className];
  955. switch (className) {
  956. case boolClass:
  957. case dateClass:
  958. return new ctor(+result);
  959. case numberClass:
  960. case stringClass:
  961. return new ctor(result);
  962. case regexpClass:
  963. return ctor(result.source, reFlags.exec(result));
  964. }
  965. // check for circular references and return corresponding clone
  966. var initedStack = !stackA;
  967. stackA || (stackA = getArray());
  968. stackB || (stackB = getArray());
  969. var length = stackA.length;
  970. while (length--) {
  971. if (stackA[length] == value) {
  972. return stackB[length];
  973. }
  974. }
  975. // init cloned object
  976. result = isArr ? ctor(result.length) : {};
  977. // add array properties assigned by `RegExp#exec`
  978. if (isArr) {
  979. if (hasOwnProperty.call(value, 'index')) {
  980. result.index = value.index;
  981. }
  982. if (hasOwnProperty.call(value, 'input')) {
  983. result.input = value.input;
  984. }
  985. }
  986. // add the source value to the stack of traversed objects
  987. // and associate it with its clone
  988. stackA.push(value);
  989. stackB.push(result);
  990. // recursively populate clone (susceptible to call stack limits)
  991. (isArr ? forEach : forOwn)(value, function(objValue, key) {
  992. result[key] = clone(objValue, deep, callback, undefined, stackA, stackB);
  993. });
  994. if (initedStack) {
  995. releaseArray(stackA);
  996. releaseArray(stackB);
  997. }
  998. return result;
  999. }
  1000. /**
  1001. * Creates a deep clone of `value`. If a `callback` function is passed,
  1002. * it will be executed to produce the cloned values. If `callback` returns
  1003. * `undefined`, cloning will be handled by the method instead. The `callback`
  1004. * is bound to `thisArg` and invoked with one argument; (value).
  1005. *
  1006. * Note: This method is loosely based on the structured clone algorithm. Functions
  1007. * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
  1008. * objects created by constructors other than `Object` are cloned to plain `Object` objects.
  1009. * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm.
  1010. *
  1011. * @static
  1012. * @memberOf _
  1013. * @category Objects
  1014. * @param {Mixed} value The value to deep clone.
  1015. * @param {Function} [callback] The function to customize cloning values.
  1016. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1017. * @returns {Mixed} Returns the deep cloned `value`.
  1018. * @example
  1019. *
  1020. * var stooges = [
  1021. * { 'name': 'moe', 'age': 40 },
  1022. * { 'name': 'larry', 'age': 50 }
  1023. * ];
  1024. *
  1025. * var deep = _.cloneDeep(stooges);
  1026. * deep[0] === stooges[0];
  1027. * // => false
  1028. *
  1029. * var view = {
  1030. * 'label': 'docs',
  1031. * 'node': element
  1032. * };
  1033. *
  1034. * var clone = _.cloneDeep(view, function(value) {
  1035. * return _.isElement(value) ? value.cloneNode(true) : undefined;
  1036. * });
  1037. *
  1038. * clone.node == view.node;
  1039. * // => false
  1040. */
  1041. function cloneDeep(value, callback, thisArg) {
  1042. return clone(value, true, callback, thisArg);
  1043. }
  1044. /**
  1045. * Assigns own enumerable properties of source object(s) to the destination
  1046. * object for all destination properties that resolve to `undefined`. Once a
  1047. * property is set, additional defaults of the same property will be ignored.
  1048. *
  1049. * @static
  1050. * @memberOf _
  1051. * @type Function
  1052. * @category Objects
  1053. * @param {Object} object The destination object.
  1054. * @param {Object} [source1, source2, ...] The source objects.
  1055. * @param- {Object} [guard] Allows working with `_.reduce` without using its
  1056. * callback's `key` and `object` arguments as sources.
  1057. * @returns {Object} Returns the destination object.
  1058. * @example
  1059. *
  1060. * var food = { 'name': 'apple' };
  1061. * _.defaults(food, { 'name': 'banana', 'type': 'fruit' });
  1062. * // => { 'name': 'apple', 'type': 'fruit' }
  1063. */
  1064. var defaults = function (object, source, guard) {
  1065. var index, iterable = object, result = iterable;
  1066. if (!iterable) return result;
  1067. var args = arguments,
  1068. argsIndex = 0,
  1069. argsLength = typeof guard == 'number' ? 2 : args.length;
  1070. while (++argsIndex < argsLength) {
  1071. iterable = args[argsIndex];
  1072. if (iterable && objectTypes[typeof iterable]) {
  1073. var ownIndex = -1,
  1074. ownProps = objectTypes[typeof iterable] && keys(iterable),
  1075. length = ownProps ? ownProps.length : 0;
  1076. while (++ownIndex < length) {
  1077. index = ownProps[ownIndex];
  1078. if (typeof result[index] == 'undefined') result[index] = iterable[index];
  1079. }
  1080. }
  1081. }
  1082. return result
  1083. };
  1084. /**
  1085. * This method is similar to `_.find`, except that it returns the key of the
  1086. * element that passes the callback check, instead of the element itself.
  1087. *
  1088. * @static
  1089. * @memberOf _
  1090. * @category Objects
  1091. * @param {Object} object The object to search.
  1092. * @param {Function|Object|String} [callback=identity] The function called per
  1093. * iteration. If a property name or object is passed, it will be used to create
  1094. * a "_.pluck" or "_.where" style callback, respectively.
  1095. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1096. * @returns {Mixed} Returns the key of the found element, else `undefined`.
  1097. * @example
  1098. *
  1099. * _.findKey({ 'a': 1, 'b': 2, 'c': 3, 'd': 4 }, function(num) {
  1100. * return num % 2 == 0;
  1101. * });
  1102. * // => 'b'
  1103. */
  1104. function findKey(object, callback, thisArg) {
  1105. var result;
  1106. callback = lodash.createCallback(callback, thisArg);
  1107. forOwn(object, function(value, key, object) {
  1108. if (callback(value, key, object)) {
  1109. result = key;
  1110. return false;
  1111. }
  1112. });
  1113. return result;
  1114. }
  1115. /**
  1116. * Iterates over `object`'s own and inherited enumerable properties, executing
  1117. * the `callback` for each property. The `callback` is bound to `thisArg` and
  1118. * invoked with three arguments; (value, key, object). Callbacks may exit iteration
  1119. * early by explicitly returning `false`.
  1120. *
  1121. * @static
  1122. * @memberOf _
  1123. * @type Function
  1124. * @category Objects
  1125. * @param {Object} object The object to iterate over.
  1126. * @param {Function} [callback=identity] The function called per iteration.
  1127. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1128. * @returns {Object} Returns `object`.
  1129. * @example
  1130. *
  1131. * function Dog(name) {
  1132. * this.name = name;
  1133. * }
  1134. *
  1135. * Dog.prototype.bark = function() {
  1136. * alert('Woof, woof!');
  1137. * };
  1138. *
  1139. * _.forIn(new Dog('Dagny'), function(value, key) {
  1140. * alert(key);
  1141. * });
  1142. * // => alerts 'name' and 'bark' (order is not guaranteed)
  1143. */
  1144. var forIn = function (collection, callback, thisArg) {
  1145. var index, iterable = collection, result = iterable;
  1146. if (!iterable) return result;
  1147. if (!objectTypes[typeof iterable]) return result;
  1148. callback = callback && typeof thisArg == 'undefined' ? callback : lodash.createCallback(callback, thisArg);
  1149. for (index in iterable) {
  1150. if (callback(iterable[index], index, collection) === false) return result;
  1151. }
  1152. return result
  1153. };
  1154. /**
  1155. * Iterates over an object's own enumerable properties, executing the `callback`
  1156. * for each property. The `callback` is bound to `thisArg` and invoked with three
  1157. * arguments; (value, key, object). Callbacks may exit iteration early by explicitly
  1158. * returning `false`.
  1159. *
  1160. * @static
  1161. * @memberOf _
  1162. * @type Function
  1163. * @category Objects
  1164. * @param {Object} object The object to iterate over.
  1165. * @param {Function} [callback=identity] The function called per iteration.
  1166. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1167. * @returns {Object} Returns `object`.
  1168. * @example
  1169. *
  1170. * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
  1171. * alert(key);
  1172. * });
  1173. * // => alerts '0', '1', and 'length' (order is not guaranteed)
  1174. */
  1175. var forOwn = function (collection, callback, thisArg) {
  1176. var index, iterable = collection, result = iterable;
  1177. if (!iterable) return result;
  1178. if (!objectTypes[typeof iterable]) return result;
  1179. callback = callback && typeof thisArg == 'undefined' ? callback : lodash.createCallback(callback, thisArg);
  1180. var ownIndex = -1,
  1181. ownProps = objectTypes[typeof iterable] && keys(iterable),
  1182. length = ownProps ? ownProps.length : 0;
  1183. while (++ownIndex < length) {
  1184. index = ownProps[ownIndex];
  1185. if (callback(iterable[index], index, collection) === false) return result;
  1186. }
  1187. return result
  1188. };
  1189. /**
  1190. * Creates a sorted array of all enumerable properties, own and inherited,
  1191. * of `object` that have function values.
  1192. *
  1193. * @static
  1194. * @memberOf _
  1195. * @alias methods
  1196. * @category Objects
  1197. * @param {Object} object The object to inspect.
  1198. * @returns {Array} Returns a new array of property names that have function values.
  1199. * @example
  1200. *
  1201. * _.functions(_);
  1202. * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
  1203. */
  1204. function functions(object) {
  1205. var result = [];
  1206. forIn(object, function(value, key) {
  1207. if (isFunction(value)) {
  1208. result.push(key);
  1209. }
  1210. });
  1211. return result.sort();
  1212. }
  1213. /**
  1214. * Checks if the specified object `property` exists and is a direct property,
  1215. * instead of an inherited property.
  1216. *
  1217. * @static
  1218. * @memberOf _
  1219. * @category Objects
  1220. * @param {Object} object The object to check.
  1221. * @param {String} property The property to check for.
  1222. * @returns {Boolean} Returns `true` if key is a direct property, else `false`.
  1223. * @example
  1224. *
  1225. * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
  1226. * // => true
  1227. */
  1228. function has(object, property) {
  1229. return object ? hasOwnProperty.call(object, property) : false;
  1230. }
  1231. /**
  1232. * Creates an object composed of the inverted keys and values of the given `object`.
  1233. *
  1234. * @static
  1235. * @memberOf _
  1236. * @category Objects
  1237. * @param {Object} object The object to invert.
  1238. * @returns {Object} Returns the created inverted object.
  1239. * @example
  1240. *
  1241. * _.invert({ 'first': 'moe', 'second': 'larry' });
  1242. * // => { 'moe': 'first', 'larry': 'second' }
  1243. */
  1244. function invert(object) {
  1245. var index = -1,
  1246. props = keys(object),
  1247. length = props.length,
  1248. result = {};
  1249. while (++index < length) {
  1250. var key = props[index];
  1251. result[object[key]] = key;
  1252. }
  1253. return result;
  1254. }
  1255. /**
  1256. * Checks if `value` is a boolean value.
  1257. *
  1258. * @static
  1259. * @memberOf _
  1260. * @category Objects
  1261. * @param {Mixed} value The value to check.
  1262. * @returns {Boolean} Returns `true`, if the `value` is a boolean value, else `false`.
  1263. * @example
  1264. *
  1265. * _.isBoolean(null);
  1266. * // => false
  1267. */
  1268. function isBoolean(value) {
  1269. return value === true || value === false || toString.call(value) == boolClass;
  1270. }
  1271. /**
  1272. * Checks if `value` is a date.
  1273. *
  1274. * @static
  1275. * @memberOf _
  1276. * @category Objects
  1277. * @param {Mixed} value The value to check.
  1278. * @returns {Boolean} Returns `true`, if the `value` is a date, else `false`.
  1279. * @example
  1280. *
  1281. * _.isDate(new Date);
  1282. * // => true
  1283. */
  1284. function isDate(value) {
  1285. return value ? (typeof value == 'object' && toString.call(value) == dateClass) : false;
  1286. }
  1287. /**
  1288. * Checks if `value` is a DOM element.
  1289. *
  1290. * @static
  1291. * @memberOf _
  1292. * @category Objects
  1293. * @param {Mixed} value The value to check.
  1294. * @returns {Boolean} Returns `true`, if the `value` is a DOM element, else `false`.
  1295. * @example
  1296. *
  1297. * _.isElement(document.body);
  1298. * // => true
  1299. */
  1300. function isElement(value) {
  1301. return value ? value.nodeType === 1 : false;
  1302. }
  1303. /**
  1304. * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
  1305. * length of `0` and objects with no own enumerable properties are considered
  1306. * "empty".
  1307. *
  1308. * @static
  1309. * @memberOf _
  1310. * @category Objects
  1311. * @param {Array|Object|String} value The value to inspect.
  1312. * @returns {Boolean} Returns `true`, if the `value` is empty, else `false`.
  1313. * @example
  1314. *
  1315. * _.isEmpty([1, 2, 3]);
  1316. * // => false
  1317. *
  1318. * _.isEmpty({});
  1319. * // => true
  1320. *
  1321. * _.isEmpty('');
  1322. * // => true
  1323. */
  1324. function isEmpty(value) {
  1325. var result = true;
  1326. if (!value) {
  1327. return result;
  1328. }
  1329. var className = toString.call(value),
  1330. length = value.length;
  1331. if ((className == arrayClass || className == stringClass || className == argsClass ) ||
  1332. (className == objectClass && typeof length == 'number' && isFunction(value.splice))) {
  1333. return !length;
  1334. }
  1335. forOwn(value, function() {
  1336. return (result = false);
  1337. });
  1338. return result;
  1339. }
  1340. /**
  1341. * Performs a deep comparison between two values to determine if they are
  1342. * equivalent to each other. If `callback` is passed, it will be executed to
  1343. * compare values. If `callback` returns `undefined`, comparisons will be handled
  1344. * by the method instead. The `callback` is bound to `thisArg` and invoked with
  1345. * two arguments; (a, b).
  1346. *
  1347. * @static
  1348. * @memberOf _
  1349. * @category Objects
  1350. * @param {Mixed} a The value to compare.
  1351. * @param {Mixed} b The other value to compare.
  1352. * @param {Function} [callback] The function to customize comparing values.
  1353. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1354. * @param- {Array} [stackA=[]] Tracks traversed `a` objects.
  1355. * @param- {Array} [stackB=[]] Tracks traversed `b` objects.
  1356. * @returns {Boolean} Returns `true`, if the values are equivalent, else `false`.
  1357. * @example
  1358. *
  1359. * var moe = { 'name': 'moe', 'age': 40 };
  1360. * var copy = { 'name': 'moe', 'age': 40 };
  1361. *
  1362. * moe == copy;
  1363. * // => false
  1364. *
  1365. * _.isEqual(moe, copy);
  1366. * // => true
  1367. *
  1368. * var words = ['hello', 'goodbye'];
  1369. * var otherWords = ['hi', 'goodbye'];
  1370. *
  1371. * _.isEqual(words, otherWords, function(a, b) {
  1372. * var reGreet = /^(?:hello|hi)$/i,
  1373. * aGreet = _.isString(a) && reGreet.test(a),
  1374. * bGreet = _.isString(b) && reGreet.test(b);
  1375. *
  1376. * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
  1377. * });
  1378. * // => true
  1379. */
  1380. function isEqual(a, b, callback, thisArg, stackA, stackB) {
  1381. // used to indicate that when comparing objects, `a` has at least the properties of `b`
  1382. var whereIndicator = callback === indicatorObject;
  1383. if (typeof callback == 'function' && !whereIndicator) {
  1384. callback = lodash.createCallback(callback, thisArg, 2);
  1385. var result = callback(a, b);
  1386. if (typeof result != 'undefined') {
  1387. return !!result;
  1388. }
  1389. }
  1390. // exit early for identical values
  1391. if (a === b) {
  1392. // treat `+0` vs. `-0` as not equal
  1393. return a !== 0 || (1 / a == 1 / b);
  1394. }
  1395. var type = typeof a,
  1396. otherType = typeof b;
  1397. // exit early for unlike primitive values
  1398. if (a === a &&
  1399. (!a || (type != 'function' && type != 'object')) &&
  1400. (!b || (otherType != 'function' && otherType != 'object'))) {
  1401. return false;
  1402. }
  1403. // exit early for `null` and `undefined`, avoiding ES3's Function#call behavior
  1404. // http://es5.github.com/#x15.3.4.4
  1405. if (a == null || b == null) {
  1406. return a === b;
  1407. }
  1408. // compare [[Class]] names
  1409. var className = toString.call(a),
  1410. otherClass = toString.call(b);
  1411. if (className == argsClass) {
  1412. className = objectClass;
  1413. }
  1414. if (otherClass == argsClass) {
  1415. otherClass = objectClass;
  1416. }
  1417. if (className != otherClass) {
  1418. return false;
  1419. }
  1420. switch (className) {
  1421. case boolClass:
  1422. case dateClass:
  1423. // coerce dates and booleans to numbers, dates to milliseconds and booleans
  1424. // to `1` or `0`, treating invalid dates coerced to `NaN` as not equal
  1425. return +a == +b;
  1426. case numberClass:
  1427. // treat `NaN` vs. `NaN` as equal
  1428. return (a != +a)
  1429. ? b != +b
  1430. // but treat `+0` vs. `-0` as not equal
  1431. : (a == 0 ? (1 / a == 1 / b) : a == +b);
  1432. case regexpClass:
  1433. case stringClass:
  1434. // coerce regexes to strings (http://es5.github.com/#x15.10.6.4)
  1435. // treat string primitives and their corresponding object instances as equal
  1436. return a == String(b);
  1437. }
  1438. var isArr = className == arrayClass;
  1439. if (!isArr) {
  1440. // unwrap any `lodash` wrapped values
  1441. if (hasOwnProperty.call(a, '__wrapped__ ') || hasOwnProperty.call(b, '__wrapped__')) {
  1442. return isEqual(a.__wrapped__ || a, b.__wrapped__ || b, callback, thisArg, stackA, stackB);
  1443. }
  1444. // exit for functions and DOM nodes
  1445. if (className != objectClass) {
  1446. return false;
  1447. }
  1448. // in older versions of Opera, `arguments` objects have `Array` constructors
  1449. var ctorA = a.constructor,
  1450. ctorB = b.constructor;
  1451. // non `Object` object instances with different constructors are not equal
  1452. if (ctorA != ctorB && !(
  1453. isFunction(ctorA) && ctorA instanceof ctorA &&
  1454. isFunction(ctorB) && ctorB instanceof ctorB
  1455. )) {
  1456. return false;
  1457. }
  1458. }
  1459. // assume cyclic structures are equal
  1460. // the algorithm for detecting cyclic structures is adapted from ES 5.1
  1461. // section 15.12.3, abstract operation `JO` (http://es5.github.com/#x15.12.3)
  1462. var initedStack = !stackA;
  1463. stackA || (stackA = getArray());
  1464. stackB || (stackB = getArray());
  1465. var length = stackA.length;
  1466. while (length--) {
  1467. if (stackA[length] == a) {
  1468. return stackB[length] == b;
  1469. }
  1470. }
  1471. var size = 0;
  1472. result = true;
  1473. // add `a` and `b` to the stack of traversed objects
  1474. stackA.push(a);
  1475. stackB.push(b);
  1476. // recursively compare objects and arrays (susceptible to call stack limits)
  1477. if (isArr) {
  1478. length = a.length;
  1479. size = b.length;
  1480. // compare lengths to determine if a deep comparison is necessary
  1481. result = size == a.length;
  1482. if (!result && !whereIndicator) {
  1483. return result;
  1484. }
  1485. // deep compare the contents, ignoring non-numeric properties
  1486. while (size--) {
  1487. var index = length,
  1488. value = b[size];
  1489. if (whereIndicator) {
  1490. while (index--) {
  1491. if ((result = isEqual(a[index], value, callback, thisArg, stackA, stackB))) {
  1492. break;
  1493. }
  1494. }
  1495. } else if (!(result = isEqual(a[size], value, callback, thisArg, stackA, stackB))) {
  1496. break;
  1497. }
  1498. }
  1499. return result;
  1500. }
  1501. // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys`
  1502. // which, in this case, is more costly
  1503. forIn(b, function(value, key, b) {
  1504. if (hasOwnProperty.call(b, key)) {
  1505. // count the number of properties.
  1506. size++;
  1507. // deep compare each property value.
  1508. return (result = hasOwnProperty.call(a, key) && isEqual(a[key], value, callback, thisArg, stackA, stackB));
  1509. }
  1510. });
  1511. if (result && !whereIndicator) {
  1512. // ensure both objects have the same number of properties
  1513. forIn(a, function(value, key, a) {
  1514. if (hasOwnProperty.call(a, key)) {
  1515. // `size` will be `-1` if `a` has more properties than `b`
  1516. return (result = --size > -1);
  1517. }
  1518. });
  1519. }
  1520. if (initedStack) {
  1521. releaseArray(stackA);
  1522. releaseArray(stackB);
  1523. }
  1524. return result;
  1525. }
  1526. /**
  1527. * Checks if `value` is, or can be coerced to, a finite number.
  1528. *
  1529. * Note: This is not the same as native `isFinite`, which will return true for
  1530. * booleans and empty strings. See http://es5.github.com/#x15.1.2.5.
  1531. *
  1532. * @static
  1533. * @memberOf _
  1534. * @category Objects
  1535. * @param {Mixed} value The value to check.
  1536. * @returns {Boolean} Returns `true`, if the `value` is finite, else `false`.
  1537. * @example
  1538. *
  1539. * _.isFinite(-101);
  1540. * // => true
  1541. *
  1542. * _.isFinite('10');
  1543. * // => true
  1544. *
  1545. * _.isFinite(true);
  1546. * // => false
  1547. *
  1548. * _.isFinite('');
  1549. * // => false
  1550. *
  1551. * _.isFinite(Infinity);
  1552. * // => false
  1553. */
  1554. function isFinite(value) {
  1555. return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
  1556. }
  1557. /**
  1558. * Checks if `value` is a function.
  1559. *
  1560. * @static
  1561. * @memberOf _
  1562. * @category Objects
  1563. * @param {Mixed} value The value to check.
  1564. * @returns {Boolean} Returns `true`, if the `value` is a function, else `false`.
  1565. * @example
  1566. *
  1567. * _.isFunction(_);
  1568. * // => true
  1569. */
  1570. function isFunction(value) {
  1571. return typeof value == 'function';
  1572. }
  1573. /**
  1574. * Checks if `value` is the language type of Object.
  1575. * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
  1576. *
  1577. * @static
  1578. * @memberOf _
  1579. * @category Objects
  1580. * @param {Mixed} value The value to check.
  1581. * @returns {Boolean} Returns `true`, if the `value` is an object, else `false`.
  1582. * @example
  1583. *
  1584. * _.isObject({});
  1585. * // => true
  1586. *
  1587. * _.isObject([1, 2, 3]);
  1588. * // => true
  1589. *
  1590. * _.isObject(1);
  1591. * // => false
  1592. */
  1593. function isObject(value) {
  1594. // check if the value is the ECMAScript language type of Object
  1595. // http://es5.github.com/#x8
  1596. // and avoid a V8 bug
  1597. // http://code.google.com/p/v8/issues/detail?id=2291
  1598. return !!(value && objectTypes[typeof value]);
  1599. }
  1600. /**
  1601. * Checks if `value` is `NaN`.
  1602. *
  1603. * Note: This is not the same as native `isNaN`, which will return `true` for
  1604. * `undefined` and other values. See http://es5.github.com/#x15.1.2.4.
  1605. *
  1606. * @static
  1607. * @memberOf _
  1608. * @category Objects
  1609. * @param {Mixed} value The value to check.
  1610. * @returns {Boolean} Returns `true`, if the `value` is `NaN`, else `false`.
  1611. * @example
  1612. *
  1613. * _.isNaN(NaN);
  1614. * // => true
  1615. *
  1616. * _.isNaN(new Number(NaN));
  1617. * // => true
  1618. *
  1619. * isNaN(undefined);
  1620. * // => true
  1621. *
  1622. * _.isNaN(undefined);
  1623. * // => false
  1624. */
  1625. function isNaN(value) {
  1626. // `NaN` as a primitive is the only value that is not equal to itself
  1627. // (perform the [[Class]] check first to avoid errors with some host objects in IE)
  1628. return isNumber(value) && value != +value
  1629. }
  1630. /**
  1631. * Checks if `value` is `null`.
  1632. *
  1633. * @static
  1634. * @memberOf _
  1635. * @category Objects
  1636. * @param {Mixed} value The value to check.
  1637. * @returns {Boolean} Returns `true`, if the `value` is `null`, else `false`.
  1638. * @example
  1639. *
  1640. * _.isNull(null);
  1641. * // => true
  1642. *
  1643. * _.isNull(undefined);
  1644. * // => false
  1645. */
  1646. function isNull(value) {
  1647. return value === null;
  1648. }
  1649. /**
  1650. * Checks if `value` is a number.
  1651. *
  1652. * @static
  1653. * @memberOf _
  1654. * @category Objects
  1655. * @param {Mixed} value The value to check.
  1656. * @returns {Boolean} Returns `true`, if the `value` is a number, else `false`.
  1657. * @example
  1658. *
  1659. * _.isNumber(8.4 * 5);
  1660. * // => true
  1661. */
  1662. function isNumber(value) {
  1663. return typeof value == 'number' || toString.call(value) == numberClass;
  1664. }
  1665. /**
  1666. * Checks if a given `value` is an object created by the `Object` constructor.
  1667. *
  1668. * @static
  1669. * @memberOf _
  1670. * @category Objects
  1671. * @param {Mixed} value The value to check.
  1672. * @returns {Boolean} Returns `true`, if `value` is a plain object, else `false`.
  1673. * @example
  1674. *
  1675. * function Stooge(name, age) {
  1676. * this.name = name;
  1677. * this.age = age;
  1678. * }
  1679. *
  1680. * _.isPlainObject(new Stooge('moe', 40));
  1681. * // => false
  1682. *
  1683. * _.isPlainObject([1, 2, 3]);
  1684. * // => false
  1685. *
  1686. * _.isPlainObject({ 'name': 'moe', 'age': 40 });
  1687. * // => true
  1688. */
  1689. var isPlainObject = function(value) {
  1690. if (!(value && toString.call(value) == objectClass)) {
  1691. return false;
  1692. }
  1693. var valueOf = value.valueOf,
  1694. objProto = typeof valueOf == 'function' && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
  1695. return objProto
  1696. ? (value == objProto || getPrototypeOf(value) == objProto)
  1697. : shimIsPlainObject(value);
  1698. };
  1699. /**
  1700. * Checks if `value` is a regular expression.
  1701. *
  1702. * @static
  1703. * @memberOf _
  1704. * @category Objects
  1705. * @param {Mixed} value The value to check.
  1706. * @returns {Boolean} Returns `true`, if the `value` is a regular expression, else `false`.
  1707. * @example
  1708. *
  1709. * _.isRegExp(/moe/);
  1710. * // => true
  1711. */
  1712. function isRegExp(value) {
  1713. return value ? (typeof value == 'object' && toString.call(value) == regexpClass) : false;
  1714. }
  1715. /**
  1716. * Checks if `value` is a string.
  1717. *
  1718. * @static
  1719. * @memberOf _
  1720. * @category Objects
  1721. * @param {Mixed} value The value to check.
  1722. * @returns {Boolean} Returns `true`, if the `value` is a string, else `false`.
  1723. * @example
  1724. *
  1725. * _.isString('moe');
  1726. * // => true
  1727. */
  1728. function isString(value) {
  1729. return typeof value == 'string' || toString.call(value) == stringClass;
  1730. }
  1731. /**
  1732. * Checks if `value` is `undefined`.
  1733. *
  1734. * @static
  1735. * @memberOf _
  1736. * @category Objects
  1737. * @param {Mixed} value The value to check.
  1738. * @returns {Boolean} Returns `true`, if the `value` is `undefined`, else `false`.
  1739. * @example
  1740. *
  1741. * _.isUndefined(void 0);
  1742. * // => true
  1743. */
  1744. function isUndefined(value) {
  1745. return typeof value == 'undefined';
  1746. }
  1747. /**
  1748. * Recursively merges own enumerable properties of the source object(s), that
  1749. * don't resolve to `undefined`, into the destination object. Subsequent sources
  1750. * will overwrite property assignments of previous sources. If a `callback` function
  1751. * is passed, it will be executed to produce the merged values of the destination
  1752. * and source properties. If `callback` returns `undefined`, merging will be
  1753. * handled by the method instead. The `callback` is bound to `thisArg` and
  1754. * invoked with two arguments; (objectValue, sourceValue).
  1755. *
  1756. * @static
  1757. * @memberOf _
  1758. * @category Objects
  1759. * @param {Object} object The destination object.
  1760. * @param {Object} [source1, source2, ...] The source objects.
  1761. * @param {Function} [callback] The function to customize merging properties.
  1762. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1763. * @param- {Object} [deepIndicator] Indicates that `stackA` and `stackB` are
  1764. * arrays of traversed objects, instead of source objects.
  1765. * @param- {Array} [stackA=[]] Tracks traversed source objects.
  1766. * @param- {Array} [stackB=[]] Associates values with source counterparts.
  1767. * @returns {Object} Returns the destination object.
  1768. * @example
  1769. *
  1770. * var names = {
  1771. * 'stooges': [
  1772. * { 'name': 'moe' },
  1773. * { 'name': 'larry' }
  1774. * ]
  1775. * };
  1776. *
  1777. * var ages = {
  1778. * 'stooges': [
  1779. * { 'age': 40 },
  1780. * { 'age': 50 }
  1781. * ]
  1782. * };
  1783. *
  1784. * _.merge(names, ages);
  1785. * // => { 'stooges': [{ 'name': 'moe', 'age': 40 }, { 'name': 'larry', 'age': 50 }] }
  1786. *
  1787. * var food = {
  1788. * 'fruits': ['apple'],
  1789. * 'vegetables': ['beet']
  1790. * };
  1791. *
  1792. * var otherFood = {
  1793. * 'fruits': ['banana'],
  1794. * 'vegetables': ['carrot']
  1795. * };
  1796. *
  1797. * _.merge(food, otherFood, function(a, b) {
  1798. * return _.isArray(a) ? a.concat(b) : undefined;
  1799. * });
  1800. * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] }
  1801. */
  1802. function merge(object, source, deepIndicator) {
  1803. var args = arguments,
  1804. index = 0,
  1805. length = 2;
  1806. if (!isObject(object)) {
  1807. return object;
  1808. }
  1809. if (deepIndicator === indicatorObject) {
  1810. var callback = args[3],
  1811. stackA = args[4],
  1812. stackB = args[5];
  1813. } else {
  1814. var initedStack = true;
  1815. stackA = getArray();
  1816. stackB = getArray();
  1817. // allows working with `_.reduce` and `_.reduceRight` without
  1818. // using their `callback` arguments, `index|key` and `collection`
  1819. if (typeof deepIndicator != 'number') {
  1820. length = args.length;
  1821. }
  1822. if (length > 3 && typeof args[length - 2] == 'function') {
  1823. callback = lodash.createCallback(args[--length - 1], args[length--], 2);
  1824. } else if (length > 2 && typeof args[length - 1] == 'function') {
  1825. callback = args[--length];
  1826. }
  1827. }
  1828. while (++index < length) {
  1829. (isArray(args[index]) ? forEach : forOwn)(args[index], function(source, key) {
  1830. var found,
  1831. isArr,
  1832. result = source,
  1833. value = object[key];
  1834. if (source && ((isArr = isArray(source)) || isPlainObject(source))) {
  1835. // avoid merging previously merged cyclic sources
  1836. var stackLength = stackA.length;
  1837. while (stackLength--) {
  1838. if ((found = stackA[stackLength] == source)) {
  1839. value = stackB[stackLength];
  1840. break;
  1841. }
  1842. }
  1843. if (!found) {
  1844. var isShallow;
  1845. if (callback) {
  1846. result = callback(value, source);
  1847. if ((isShallow = typeof result != 'undefined')) {
  1848. value = result;
  1849. }
  1850. }
  1851. if (!isShallow) {
  1852. value = isArr
  1853. ? (isArray(value) ? value : [])
  1854. : (isPlainObject(value) ? value : {});
  1855. }
  1856. // add `source` and associated `value` to the stack of traversed objects
  1857. stackA.push(source);
  1858. stackB.push(value);
  1859. // recursively merge objects and arrays (susceptible to call stack limits)
  1860. if (!isShallow) {
  1861. value = merge(value, source, indicatorObject, callback, stackA, stackB);
  1862. }
  1863. }
  1864. }
  1865. else {
  1866. if (callback) {
  1867. result = callback(value, source);
  1868. if (typeof result == 'undefined') {
  1869. result = source;
  1870. }
  1871. }
  1872. if (typeof result != 'undefined') {
  1873. value = result;
  1874. }
  1875. }
  1876. object[key] = value;
  1877. });
  1878. }
  1879. if (initedStack) {
  1880. releaseArray(stackA);
  1881. releaseArray(stackB);
  1882. }
  1883. return object;
  1884. }
  1885. /**
  1886. * Creates a shallow clone of `object` excluding the specified properties.
  1887. * Property names may be specified as individual arguments or as arrays of
  1888. * property names. If a `callback` function is passed, it will be executed
  1889. * for each property in the `object`, omitting the properties `callback`
  1890. * returns truthy for. The `callback` is bound to `thisArg` and invoked
  1891. * with three arguments; (value, key, object).
  1892. *
  1893. * @static
  1894. * @memberOf _
  1895. * @category Objects
  1896. * @param {Object} object The source object.
  1897. * @param {Function|String} callback|[prop1, prop2, ...] The properties to omit
  1898. * or the function called per iteration.
  1899. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1900. * @returns {Object} Returns an object without the omitted properties.
  1901. * @example
  1902. *
  1903. * _.omit({ 'name': 'moe', 'age': 40 }, 'age');
  1904. * // => { 'name': 'moe' }
  1905. *
  1906. * _.omit({ 'name': 'moe', 'age': 40 }, function(value) {
  1907. * return typeof value == 'number';
  1908. * });
  1909. * // => { 'name': 'moe' }
  1910. */
  1911. function omit(object, callback, thisArg) {
  1912. var indexOf = getIndexOf(),
  1913. isFunc = typeof callback == 'function',
  1914. result = {};
  1915. if (isFunc) {
  1916. callback = lodash.createCallback(callback, thisArg);
  1917. } else {
  1918. var props = concat.apply(arrayRef, nativeSlice.call(arguments, 1));
  1919. }
  1920. forIn(object, function(value, key, object) {
  1921. if (isFunc
  1922. ? !callback(value, key, object)
  1923. : indexOf(props, key) < 0
  1924. ) {
  1925. result[key] = value;
  1926. }
  1927. });
  1928. return result;
  1929. }
  1930. /**
  1931. * Creates a two dimensional array of the given object's key-value pairs,
  1932. * i.e. `[[key1, value1], [key2, value2]]`.
  1933. *
  1934. * @static
  1935. * @memberOf _
  1936. * @category Objects
  1937. * @param {Object} object The object to inspect.
  1938. * @returns {Array} Returns new array of key-value pairs.
  1939. * @example
  1940. *
  1941. * _.pairs({ 'moe': 30, 'larry': 40 });
  1942. * // => [['moe', 30], ['larry', 40]] (order is not guaranteed)
  1943. */
  1944. function pairs(object) {
  1945. var index = -1,
  1946. props = keys(object),
  1947. length = props.length,
  1948. result = Array(length);
  1949. while (++index < length) {
  1950. var key = props[index];
  1951. result[index] = [key, object[key]];
  1952. }
  1953. return result;
  1954. }
  1955. /**
  1956. * Creates a shallow clone of `object` composed of the specified properties.
  1957. * Property names may be specified as individual arguments or as arrays of property
  1958. * names. If `callback` is passed, it will be executed for each property in the
  1959. * `object`, picking the properties `callback` returns truthy for. The `callback`
  1960. * is bound to `thisArg` and invoked with three arguments; (value, key, object).
  1961. *
  1962. * @static
  1963. * @memberOf _
  1964. * @category Objects
  1965. * @param {Object} object The source object.
  1966. * @param {Array|Function|String} callback|[prop1, prop2, ...] The function called
  1967. * per iteration or properties to pick, either as individual arguments or arrays.
  1968. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1969. * @returns {Object} Returns an object composed of the picked properties.
  1970. * @example
  1971. *
  1972. * _.pick({ 'name': 'moe', '_userid': 'moe1' }, 'name');
  1973. * // => { 'name': 'moe' }
  1974. *
  1975. * _.pick({ 'name': 'moe', '_userid': 'moe1' }, function(value, key) {
  1976. * return key.charAt(0) != '_';
  1977. * });
  1978. * // => { 'name': 'moe' }
  1979. */
  1980. function pick(object, callback, thisArg) {
  1981. var result = {};
  1982. if (typeof callback != 'function') {
  1983. var index = -1,
  1984. props = concat.apply(arrayRef, nativeSlice.call(arguments, 1)),
  1985. length = isObject(object) ? props.length : 0;
  1986. while (++index < length) {
  1987. var key = props[index];
  1988. if (key in object) {
  1989. result[key] = object[key];
  1990. }
  1991. }
  1992. } else {
  1993. callback = lodash.createCallback(callback, thisArg);
  1994. forIn(object, function(value, key, object) {
  1995. if (callback(value, key, object)) {
  1996. result[key] = value;
  1997. }
  1998. });
  1999. }
  2000. return result;
  2001. }
  2002. /**
  2003. * An alternative to `_.reduce`, this method transforms an `object` to a new
  2004. * `accumulator` object which is the result of running each of its elements
  2005. * through the `callback`, with each `callback` execution potentially mutating
  2006. * the `accumulator` object. The `callback` is bound to `thisArg` and invoked
  2007. * with four arguments; (accumulator, value, key, object). Callbacks may exit
  2008. * iteration early by explicitly returning `false`.
  2009. *
  2010. * @static
  2011. * @memberOf _
  2012. * @category Objects
  2013. * @param {Array|Object} collection The collection to iterate over.
  2014. * @param {Function} [callback=identity] The function called per iteration.
  2015. * @param {Mixed} [accumulator] The custom accumulator value.
  2016. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  2017. * @returns {Mixed} Returns the accumulated value.
  2018. * @example
  2019. *
  2020. * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) {
  2021. * num *= num;
  2022. * if (num % 2) {
  2023. * return result.push(num) < 3;
  2024. * }
  2025. * });
  2026. * // => [1, 9, 25]
  2027. *
  2028. * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
  2029. * result[key] = num * 3;
  2030. * });
  2031. * // => { 'a': 3, 'b': 6, 'c': 9 }
  2032. */
  2033. function transform(object, callback, accumulator, thisArg) {
  2034. var isArr = isArray(object);
  2035. callback = lodash.createCallback(callback, thisArg, 4);
  2036. if (accumulator == null) {
  2037. if (isArr) {
  2038. accumulator = [];
  2039. } else {
  2040. var ctor = object && object.constructor,
  2041. proto = ctor && ctor.prototype;
  2042. accumulator = createObject(proto);
  2043. }
  2044. }
  2045. (isArr ? forEach : forOwn)(object, function(value, index, object) {
  2046. return callback(accumulator, value, index, object);
  2047. });
  2048. return accumulator;
  2049. }
  2050. /**
  2051. * Creates an array composed of the own enumerable property values of `object`.
  2052. *
  2053. * @static
  2054. * @memberOf _
  2055. * @category Objects
  2056. * @param {Object} object The object to inspect.
  2057. * @returns {Array} Returns a new array of property values.
  2058. * @example
  2059. *
  2060. * _.values({ 'one': 1, 'two': 2, 'three': 3 });
  2061. * // => [1, 2, 3] (order is not guaranteed)
  2062. */
  2063. function values(object) {
  2064. var index = -1,
  2065. props = keys(object),
  2066. length = props.length,
  2067. result = Array(length);
  2068. while (++index < length) {
  2069. result[index] = object[props[index]];
  2070. }
  2071. return result;
  2072. }
  2073. /*--------------------------------------------------------------------------*/
  2074. /**
  2075. * Creates an array of elements from the specified indexes, or keys, of the
  2076. * `collection`. Indexes may be specified as individual arguments or as arrays
  2077. * of indexes.
  2078. *
  2079. * @static
  2080. * @memberOf _
  2081. * @category Collections
  2082. * @param {Array|Object|String} collection The collection to iterate over.
  2083. * @param {Array|Number|String} [index1, index2, ...] The indexes of
  2084. * `collection` to retrieve, either as individual arguments or arrays.
  2085. * @returns {Array} Returns a new array of elements corresponding to the
  2086. * provided indexes.
  2087. * @example
  2088. *
  2089. * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]);
  2090. * // => ['a', 'c', 'e']
  2091. *
  2092. * _.at(['moe', 'larry', 'curly'], 0, 2);
  2093. * // => ['moe', 'curly']
  2094. */
  2095. function at(collection) {
  2096. var index = -1,
  2097. props = concat.apply(arrayRef, nativeSlice.call(arguments, 1)),
  2098. length = props.length,
  2099. result = Array(length);
  2100. while(++index < length) {
  2101. result[index] = collection[props[index]];
  2102. }
  2103. return result;
  2104. }
  2105. /**
  2106. * Checks if a given `target` element is present in a `collection` using strict
  2107. * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
  2108. * as the offset from the end of the collection.
  2109. *
  2110. * @static
  2111. * @memberOf _
  2112. * @alias include
  2113. * @category Collections
  2114. * @param {Array|Object|String} collection The collection to iterate over.
  2115. * @param {Mixed} target The value to check for.
  2116. * @param {Number} [fromIndex=0] The index to search from.
  2117. * @returns {Boolean} Returns `true` if the `target` element is found, else `false`.
  2118. * @example
  2119. *
  2120. * _.contains([1, 2, 3], 1);
  2121. * // => true
  2122. *
  2123. * _.contains([1, 2, 3], 1, 2);
  2124. * // => false
  2125. *
  2126. * _.contains({ 'name': 'moe', 'age': 40 }, 'moe');
  2127. * // => true
  2128. *
  2129. * _.contains('curly', 'ur');
  2130. * // => true
  2131. */
  2132. function contains(collection, target, fromIndex) {
  2133. var index = -1,
  2134. indexOf = getIndexOf(),
  2135. length = collection ? collection.length : 0,
  2136. result = false;
  2137. fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0;
  2138. if (length && typeof length == 'number') {
  2139. result = (isString(collection)
  2140. ? collection.indexOf(target, fromIndex)
  2141. : indexOf(collection, target, fromIndex)
  2142. ) > -1;
  2143. } else {
  2144. forOwn(collection, function(value) {
  2145. if (++index >= fromIndex) {
  2146. return !(result = value === target);
  2147. }
  2148. });
  2149. }
  2150. return result;
  2151. }
  2152. /**
  2153. * Creates an object composed of keys returned from running each element of the
  2154. * `collection` through the given `callback`. The corresponding value of each key
  2155. * is the number of times the key was returned by the `callback`. The `callback`
  2156. * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection).
  2157. *
  2158. * If a property name is passed for `callback`, the created "_.pluck" style
  2159. * callback will return the property value of the given element.
  2160. *
  2161. * If an object is passed for `callback`, the created "_.where" style callback
  2162. * will return `true` for elements that have the properties of the given object,
  2163. * else `false`.
  2164. *
  2165. * @static
  2166. * @memberOf _
  2167. * @category Collections
  2168. * @param {Array|Object|String} collection The collection to iterate over.
  2169. * @param {Function|Object|String} [callback=identity] The function called per
  2170. * iteration. If a property name or object is passed, it will be used to create
  2171. * a "_.pluck" or "_.where" style callback, respectively.
  2172. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  2173. * @returns {Object} Returns the composed aggregate object.
  2174. * @example
  2175. *
  2176. * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); });
  2177. * // => { '4': 1, '6': 2 }
  2178. *
  2179. * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
  2180. * // => { '4': 1, '6': 2 }
  2181. *
  2182. * _.countBy(['one', 'two', 'three'], 'length');
  2183. * // => { '3': 2, '5': 1 }
  2184. */
  2185. function countBy(collection, callback, thisArg) {
  2186. var result = {};
  2187. callback = lodash.createCallback(callback, thisArg);
  2188. forEach(collection, function(value, key, collection) {
  2189. key = String(callback(value, key, collection));
  2190. (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
  2191. });
  2192. return result;
  2193. }
  2194. /**
  2195. * Checks if the `callback` returns a truthy value for **all** elements of a
  2196. * `collection`. The `callback` is bound to `thisArg` and invoked with three
  2197. * arguments; (value, index|key, collection).
  2198. *
  2199. * If a property name is passed for `callback`, the created "_.pluck" style
  2200. * callback will return the property value of the given element.
  2201. *
  2202. * If an object is passed for `callback`, the created "_.where" style callback
  2203. * will return `true` for elements that have the properties of the given object,
  2204. * else `false`.
  2205. *
  2206. * @static
  2207. * @memberOf _
  2208. * @alias all
  2209. * @category Collections
  2210. * @param {Array|Object|String} collection The collection to iterate over.
  2211. * @param {Function|Object|String} [callback=identity] The function called per
  2212. * iteration. If a property name or object is passed, it will be used to create
  2213. * a "_.pluck" or "_.where" style callback, respectively.
  2214. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  2215. * @returns {Boolean} Returns `true` if all elements pass the callback check,
  2216. * else `false`.
  2217. * @example
  2218. *
  2219. * _.every([true, 1, null, 'yes'], Boolean);
  2220. * // => false
  2221. *
  2222. * var stooges = [
  2223. * { 'name': 'moe', 'age': 40 },
  2224. * { 'name': 'larry', 'age': 50 }
  2225. * ];
  2226. *
  2227. * // using "_.pluck" callback shorthand
  2228. * _.every(stooges, 'age');
  2229. * // => true
  2230. *
  2231. * // using "_.where" callback shorthand
  2232. * _.every(stooges, { 'age': 50 });
  2233. * // => false
  2234. */
  2235. function every(collection, callback, thisArg) {
  2236. var result = true;
  2237. callback = lodash.createCallback(callback, thisArg);
  2238. var index = -1,
  2239. length = collection ? collection.length : 0;
  2240. if (typeof length == 'number') {
  2241. while (++index < length) {
  2242. if (!(result = !!callback(collection[index], index, collection))) {
  2243. break;
  2244. }
  2245. }
  2246. } else {
  2247. forOwn(collection, function(value, index, collection) {
  2248. return (result = !!callback(value, index, collection));
  2249. });
  2250. }
  2251. return result;
  2252. }
  2253. /**
  2254. * Examines each element in a `collection`, returning an array of all elements
  2255. * the `callback` returns truthy for. The `callback` is bound to `thisArg` and
  2256. * invoked with three arguments; (value, index|key, collection).
  2257. *
  2258. * If a property name is passed for `callback`, the created "_.pluck" style
  2259. * callback will return the property value of the given element.
  2260. *
  2261. * If an object is passed for `callback`, the created "_.where" style callback
  2262. * will return `true` for elements that have the properties of the given object,
  2263. * else `false`.
  2264. *
  2265. * @static
  2266. * @memberOf _
  2267. * @alias select
  2268. * @category Collections
  2269. * @param {Array|Object|String} collection The collection to iterate over.
  2270. * @param {Function|Object|String} [callback=identity] The function called per
  2271. * iteration. If a property name or object is passed, it will be used to create
  2272. * a "_.pluck" or "_.where" style callback, respectively.
  2273. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  2274. * @returns {Array} Returns a new array of elements that passed the callback check.
  2275. * @example
  2276. *
  2277. * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
  2278. * // => [2, 4, 6]
  2279. *
  2280. * var food = [
  2281. * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
  2282. * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
  2283. * ];
  2284. *
  2285. * // using "_.pluck" callback shorthand
  2286. * _.filter(food, 'organic');
  2287. * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }]
  2288. *
  2289. * // using "_.where" callback shorthand
  2290. * _.filter(food, { 'type': 'fruit' });
  2291. * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }]
  2292. */
  2293. function filter(collection, callback, thisArg) {
  2294. var result = [];
  2295. callback = lodash.createCallback(callback, thisArg);
  2296. var index = -1,
  2297. length = collection ? collection.length : 0;
  2298. if (typeof length == 'number') {
  2299. while (++index < length) {
  2300. var value = collection[index];
  2301. if (callback(value, index, collection)) {
  2302. result.push(value);
  2303. }
  2304. }
  2305. } else {
  2306. forOwn(collection, function(value, index, collection) {
  2307. if (callback(value, index, collection)) {
  2308. result.push(value);
  2309. }
  2310. });
  2311. }
  2312. return result;
  2313. }
  2314. /**
  2315. * Examines each element in a `collection`, returning the first that the `callback`
  2316. * returns truthy for. The `callback` is bound to `thisArg` and invoked with three
  2317. * arguments; (value, index|key, collection).
  2318. *
  2319. * If a property name is passed for `callback`, the created "_.pluck" style
  2320. * callback will return the property value of the given element.
  2321. *
  2322. * If an object is passed for `callback`, the created "_.where" style callback
  2323. * will return `true` for elements that have the properties of the given object,
  2324. * else `false`.
  2325. *
  2326. * @static
  2327. * @memberOf _
  2328. * @alias detect, findWhere
  2329. * @category Collections
  2330. * @param {Array|Object|String} collection The collection to iterate over.
  2331. * @param {Function|Object|String} [callback=identity] The function called per
  2332. * iteration. If a property name or object is passed, it will be used to create
  2333. * a "_.pluck" or "_.where" style callback, respectively.
  2334. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  2335. * @returns {Mixed} Returns the found element, else `undefined`.
  2336. * @example
  2337. *
  2338. * _.find([1, 2, 3, 4], function(num) {
  2339. * return num % 2 == 0;
  2340. * });
  2341. * // => 2
  2342. *
  2343. * var food = [
  2344. * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
  2345. * { 'name': 'banana', 'organic': true, 'type': 'fruit' },
  2346. * { 'name': 'beet', 'organic': false, 'type': 'vegetable' }
  2347. * ];
  2348. *
  2349. * // using "_.where" callback shorthand
  2350. * _.find(food, { 'type': 'vegetable' });
  2351. * // => { 'name': 'beet', 'organic': false, 'type': 'vegetable' }
  2352. *
  2353. * // using "_.pluck" callback shorthand
  2354. * _.find(food, 'organic');
  2355. * // => { 'name': 'banana', 'organic': true, 'type': 'fruit' }
  2356. */
  2357. function find(collection, callback, thisArg) {
  2358. callback = lodash.createCallback(callback, thisArg);
  2359. var index = -1,
  2360. length = collection ? collection.length : 0;
  2361. if (typeof length == 'number') {
  2362. while (++index < length) {
  2363. var value = collection[index];
  2364. if (callback(value, index, collection)) {
  2365. return value;
  2366. }
  2367. }
  2368. } else {
  2369. var result;
  2370. forOwn(collection, function(value, index, collection) {
  2371. if (callback(value, index, collection)) {
  2372. result = value;
  2373. return false;
  2374. }
  2375. });
  2376. return result;
  2377. }
  2378. }
  2379. /**
  2380. * Iterates over a `collection`, executing the `callback` for each element in
  2381. * the `collection`. The `callback` is bound to `thisArg` and invoked with three
  2382. * arguments; (value, index|key, collection). Callbacks may exit iteration early
  2383. * by explicitly returning `false`.
  2384. *
  2385. * @static
  2386. * @memberOf _
  2387. * @alias each
  2388. * @category Collections
  2389. * @param {Array|Object|String} collection The collection to iterate over.
  2390. * @param {Function} [callback=identity] The function called per iteration.
  2391. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  2392. * @returns {Array|Object|String} Returns `collection`.
  2393. * @example
  2394. *
  2395. * _([1, 2, 3]).forEach(alert).join(',');
  2396. * // => alerts each number and returns '1,2,3'
  2397. *
  2398. * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, alert);
  2399. * // => alerts each number value (order is not guaranteed)
  2400. */
  2401. function forEach(collection, callback, thisArg) {
  2402. var index = -1,
  2403. length = collection ? collection.length : 0;
  2404. callback = callback && typeof thisArg == 'undefined' ? callback : lodash.createCallback(callback, thisArg);
  2405. if (typeof length == 'number') {
  2406. while (++index < length) {
  2407. if (callback(collection[index], index, collection) === false) {
  2408. break;
  2409. }
  2410. }
  2411. } else {
  2412. forOwn(collection, callback);
  2413. }
  2414. return collection;
  2415. }
  2416. /**
  2417. * Creates an object composed of keys returned from running each element of the
  2418. * `collection` through the `callback`. The corresponding value of each key is
  2419. * an array of elements passed to `callback` that returned the key. The `callback`
  2420. * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection).
  2421. *
  2422. * If a property name is passed for `callback`, the created "_.pluck" style
  2423. * callback will return the property value of the given element.
  2424. *
  2425. * If an object is passed for `callback`, the created "_.where" style callback
  2426. * will return `true` for elements that have the properties of the given object,
  2427. * else `false`
  2428. *
  2429. * @static
  2430. * @memberOf _
  2431. * @category Collections
  2432. * @param {Array|Object|String} collection The collection to iterate over.
  2433. * @param {Function|Object|String} [callback=identity] The function called per
  2434. * iteration. If a property name or object is passed, it will be used to create
  2435. * a "_.pluck" or "_.where" style callback, respectively.
  2436. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  2437. * @returns {Object} Returns the composed aggregate object.
  2438. * @example
  2439. *
  2440. * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); });
  2441. * // => { '4': [4.2], '6': [6.1, 6.4] }
  2442. *
  2443. * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
  2444. * // => { '4': [4.2], '6': [6.1, 6.4] }
  2445. *
  2446. * // using "_.pluck" callback shorthand
  2447. * _.groupBy(['one', 'two', 'three'], 'length');
  2448. * // => { '3': ['one', 'two'], '5': ['three'] }
  2449. */
  2450. function groupBy(collection, callback, thisArg) {
  2451. var result = {};
  2452. callback = lodash.createCallback(callback, thisArg);
  2453. forEach(collection, function(value, key, collection) {
  2454. key = String(callback(value, key, collection));
  2455. (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value);
  2456. });
  2457. return result;
  2458. }
  2459. /**
  2460. * Invokes the method named by `methodName` on each element in the `collection`,
  2461. * returning an array of the results of each invoked method. Additional arguments
  2462. * will be passed to each invoked method. If `methodName` is a function, it will
  2463. * be invoked for, and `this` bound to, each element in the `collection`.
  2464. *
  2465. * @static
  2466. * @memberOf _
  2467. * @category Collections
  2468. * @param {Array|Object|String} collection The collection to iterate over.
  2469. * @param {Function|String} methodName The name of the method to invoke or
  2470. * the function invoked per iteration.
  2471. * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the method with.
  2472. * @returns {Array} Returns a new array of the results of each invoked method.
  2473. * @example
  2474. *
  2475. * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
  2476. * // => [[1, 5, 7], [1, 2, 3]]
  2477. *
  2478. * _.invoke([123, 456], String.prototype.split, '');
  2479. * // => [['1', '2', '3'], ['4', '5', '6']]
  2480. */
  2481. function invoke(collection, methodName) {
  2482. var args = nativeSlice.call(arguments, 2),
  2483. index = -1,
  2484. isFunc = typeof methodName == 'function',
  2485. length = collection ? collection.length : 0,
  2486. result = Array(typeof length == 'number' ? length : 0);
  2487. forEach(collection, function(value) {
  2488. result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args);
  2489. });
  2490. return result;
  2491. }
  2492. /**
  2493. * Creates an array of values by running each element in the `collection`
  2494. * through the `callback`. The `callback` is bound to `thisArg` and invoked with
  2495. * three arguments; (value, index|key, collection).
  2496. *
  2497. * If a property name is passed for `callback`, the created "_.pluck" style
  2498. * callback will return the property value of the given element.
  2499. *
  2500. * If an object is passed for `callback`, the created "_.where" style callback
  2501. * will return `true` for elements that have the properties of the given object,
  2502. * else `false`.
  2503. *
  2504. * @static
  2505. * @memberOf _
  2506. * @alias collect
  2507. * @category Collections
  2508. * @param {Array|Object|String} collection The collection to iterate over.
  2509. * @param {Function|Object|String} [callback=identity] The function called per
  2510. * iteration. If a property name or object is passed, it will be used to create
  2511. * a "_.pluck" or "_.where" style callback, respectively.
  2512. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  2513. * @returns {Array} Returns a new array of the results of each `callback` execution.
  2514. * @example
  2515. *
  2516. * _.map([1, 2, 3], function(num) { return num * 3; });
  2517. * // => [3, 6, 9]
  2518. *
  2519. * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
  2520. * // => [3, 6, 9] (order is not guaranteed)
  2521. *
  2522. * var stooges = [
  2523. * { 'name': 'moe', 'age': 40 },
  2524. * { 'name': 'larry', 'age': 50 }
  2525. * ];
  2526. *
  2527. * // using "_.pluck" callback shorthand
  2528. * _.map(stooges, 'name');
  2529. * // => ['moe', 'larry']
  2530. */
  2531. function map(collection, callback, thisArg) {
  2532. var index = -1,
  2533. length = collection ? collection.length : 0;
  2534. callback = lodash.createCallback(callback, thisArg);
  2535. if (typeof length == 'number') {
  2536. var result = Array(length);
  2537. while (++index < length) {
  2538. result[index] = callback(collection[index], index, collection);
  2539. }
  2540. } else {
  2541. result = [];
  2542. forOwn(collection, function(value, key, collection) {
  2543. result[++index] = callback(value, key, collection);
  2544. });
  2545. }
  2546. return result;
  2547. }
  2548. /**
  2549. * Retrieves the maximum value of an `array`. If `callback` is passed,
  2550. * it will be executed for each value in the `array` to generate the
  2551. * criterion by which the value is ranked. The `callback` is bound to
  2552. * `thisArg` and invoked with three arguments; (value, index, collection).
  2553. *
  2554. * If a property name is passed for `callback`, the created "_.pluck" style
  2555. * callback will return the property value of the given element.
  2556. *
  2557. * If an object is passed for `callback`, the created "_.where" style callback
  2558. * will return `true` for elements that have the properties of the given object,
  2559. * else `false`.
  2560. *
  2561. * @static
  2562. * @memberOf _
  2563. * @category Collections
  2564. * @param {Array|Object|String} collection The collection to iterate over.
  2565. * @param {Function|Object|String} [callback=identity] The function called per
  2566. * iteration. If a property name or object is passed, it will be used to create
  2567. * a "_.pluck" or "_.where" style callback, respectively.
  2568. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  2569. * @returns {Mixed} Returns the maximum value.
  2570. * @example
  2571. *
  2572. * _.max([4, 2, 8, 6]);
  2573. * // => 8
  2574. *
  2575. * var stooges = [
  2576. * { 'name': 'moe', 'age': 40 },
  2577. * { 'name': 'larry', 'age': 50 }
  2578. * ];
  2579. *
  2580. * _.max(stooges, function(stooge) { return stooge.age; });
  2581. * // => { 'name': 'larry', 'age': 50 };
  2582. *
  2583. * // using "_.pluck" callback shorthand
  2584. * _.max(stooges, 'age');
  2585. * // => { 'name': 'larry', 'age': 50 };
  2586. */
  2587. function max(collection, callback, thisArg) {
  2588. var computed = -Infinity,
  2589. result = computed;
  2590. if (!callback && isArray(collection)) {
  2591. var index = -1,
  2592. length = collection.length;
  2593. while (++index < length) {
  2594. var value = collection[index];
  2595. if (value > result) {
  2596. result = value;
  2597. }
  2598. }
  2599. } else {
  2600. callback = (!callback && isString(collection))
  2601. ? charAtCallback
  2602. : lodash.createCallback(callback, thisArg);
  2603. forEach(collection, function(value, index, collection) {
  2604. var current = callback(value, index, collection);
  2605. if (current > computed) {
  2606. computed = current;
  2607. result = value;
  2608. }
  2609. });
  2610. }
  2611. return result;
  2612. }
  2613. /**
  2614. * Retrieves the minimum value of an `array`. If `callback` is passed,
  2615. * it will be executed for each value in the `array` to generate the
  2616. * criterion by which the value is ranked. The `callback` is bound to `thisArg`
  2617. * and invoked with three arguments; (value, index, collection).
  2618. *
  2619. * If a property name is passed for `callback`, the created "_.pluck" style
  2620. * callback will return the property value of the given element.
  2621. *
  2622. * If an object is passed for `callback`, the created "_.where" style callback
  2623. * will return `true` for elements that have the properties of the given object,
  2624. * else `false`.
  2625. *
  2626. * @static
  2627. * @memberOf _
  2628. * @category Collections
  2629. * @param {Array|Object|String} collection The collection to iterate over.
  2630. * @param {Function|Object|String} [callback=identity] The function called per
  2631. * iteration. If a property name or object is passed, it will be used to create
  2632. * a "_.pluck" or "_.where" style callback, respectively.
  2633. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  2634. * @returns {Mixed} Returns the minimum value.
  2635. * @example
  2636. *
  2637. * _.min([4, 2, 8, 6]);
  2638. * // => 2
  2639. *
  2640. * var stooges = [
  2641. * { 'name': 'moe', 'age': 40 },
  2642. * { 'name': 'larry', 'age': 50 }
  2643. * ];
  2644. *
  2645. * _.min(stooges, function(stooge) { return stooge.age; });
  2646. * // => { 'name': 'moe', 'age': 40 };
  2647. *
  2648. * // using "_.pluck" callback shorthand
  2649. * _.min(stooges, 'age');
  2650. * // => { 'name': 'moe', 'age': 40 };
  2651. */
  2652. function min(collection, callback, thisArg) {
  2653. var computed = Infinity,
  2654. result = computed;
  2655. if (!callback && isArray(collection)) {
  2656. var index = -1,
  2657. length = collection.length;
  2658. while (++index < length) {
  2659. var value = collection[index];
  2660. if (value < result) {
  2661. result = value;
  2662. }
  2663. }
  2664. } else {
  2665. callback = (!callback && isString(collection))
  2666. ? charAtCallback
  2667. : lodash.createCallback(callback, thisArg);
  2668. forEach(collection, function(value, index, collection) {
  2669. var current = callback(value, index, collection);
  2670. if (current < computed) {
  2671. computed = current;
  2672. result = value;
  2673. }
  2674. });
  2675. }
  2676. return result;
  2677. }
  2678. /**
  2679. * Retrieves the value of a specified property from all elements in the `collection`.
  2680. *
  2681. * @static
  2682. * @memberOf _
  2683. * @type Function
  2684. * @category Collections
  2685. * @param {Array|Object|String} collection The collection to iterate over.
  2686. * @param {String} property The property to pluck.
  2687. * @returns {Array} Returns a new array of property values.
  2688. * @example
  2689. *
  2690. * var stooges = [
  2691. * { 'name': 'moe', 'age': 40 },
  2692. * { 'name': 'larry', 'age': 50 }
  2693. * ];
  2694. *
  2695. * _.pluck(stooges, 'name');
  2696. * // => ['moe', 'larry']
  2697. */
  2698. function pluck(collection, property) {
  2699. var index = -1,
  2700. length = collection ? collection.length : 0;
  2701. if (typeof length == 'number') {
  2702. var result = Array(length);
  2703. while (++index < length) {
  2704. result[index] = collection[index][property];
  2705. }
  2706. }
  2707. return result || map(collection, property);
  2708. }
  2709. /**
  2710. * Reduces a `collection` to a value which is the accumulated result of running
  2711. * each element in the `collection` through the `callback`, where each successive
  2712. * `callback` execution consumes the return value of the previous execution.
  2713. * If `accumulator` is not passed, the first element of the `collection` will be
  2714. * used as the initial `accumulator` value. The `callback` is bound to `thisArg`
  2715. * and invoked with four arguments; (accumulator, value, index|key, collection).
  2716. *
  2717. * @static
  2718. * @memberOf _
  2719. * @alias foldl, inject
  2720. * @category Collections
  2721. * @param {Array|Object|String} collection The collection to iterate over.
  2722. * @param {Function} [callback=identity] The function called per iteration.
  2723. * @param {Mixed} [accumulator] Initial value of the accumulator.
  2724. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  2725. * @returns {Mixed} Returns the accumulated value.
  2726. * @example
  2727. *
  2728. * var sum = _.reduce([1, 2, 3], function(sum, num) {
  2729. * return sum + num;
  2730. * });
  2731. * // => 6
  2732. *
  2733. * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
  2734. * result[key] = num * 3;
  2735. * return result;
  2736. * }, {});
  2737. * // => { 'a': 3, 'b': 6, 'c': 9 }
  2738. */
  2739. function reduce(collection, callback, accumulator, thisArg) {
  2740. if (!collection) return accumulator;
  2741. var noaccum = arguments.length < 3;
  2742. callback = lodash.createCallback(callback, thisArg, 4);
  2743. var index = -1,
  2744. length = collection.length;
  2745. if (typeof length == 'number') {
  2746. if (noaccum) {
  2747. accumulator = collection[++index];
  2748. }
  2749. while (++index < length) {
  2750. accumulator = callback(accumulator, collection[index], index, collection);
  2751. }
  2752. } else {
  2753. forOwn(collection, function(value, index, collection) {
  2754. accumulator = noaccum
  2755. ? (noaccum = false, value)
  2756. : callback(accumulator, value, index, collection)
  2757. });
  2758. }
  2759. return accumulator;
  2760. }
  2761. /**
  2762. * This method is similar to `_.reduce`, except that it iterates over a
  2763. * `collection` from right to left.
  2764. *
  2765. * @static
  2766. * @memberOf _
  2767. * @alias foldr
  2768. * @category Collections
  2769. * @param {Array|Object|String} collection The collection to iterate over.
  2770. * @param {Function} [callback=identity] The function called per iteration.
  2771. * @param {Mixed} [accumulator] Initial value of the accumulator.
  2772. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  2773. * @returns {Mixed} Returns the accumulated value.
  2774. * @example
  2775. *
  2776. * var list = [[0, 1], [2, 3], [4, 5]];
  2777. * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
  2778. * // => [4, 5, 2, 3, 0, 1]
  2779. */
  2780. function reduceRight(collection, callback, accumulator, thisArg) {
  2781. var iterable = collection,
  2782. length = collection ? collection.length : 0,
  2783. noaccum = arguments.length < 3;
  2784. if (typeof length != 'number') {
  2785. var props = keys(collection);
  2786. length = props.length;
  2787. }
  2788. callback = lodash.createCallback(callback, thisArg, 4);
  2789. forEach(collection, function(value, index, collection) {
  2790. index = props ? props[--length] : --length;
  2791. accumulator = noaccum
  2792. ? (noaccum = false, iterable[index])
  2793. : callback(accumulator, iterable[index], index, collection);
  2794. });
  2795. return accumulator;
  2796. }
  2797. /**
  2798. * The opposite of `_.filter`, this method returns the elements of a
  2799. * `collection` that `callback` does **not** return truthy for.
  2800. *
  2801. * If a property name is passed for `callback`, the created "_.pluck" style
  2802. * callback will return the property value of the given element.
  2803. *
  2804. * If an object is passed for `callback`, the created "_.where" style callback
  2805. * will return `true` for elements that have the properties of the given object,
  2806. * else `false`.
  2807. *
  2808. * @static
  2809. * @memberOf _
  2810. * @category Collections
  2811. * @param {Array|Object|String} collection The collection to iterate over.
  2812. * @param {Function|Object|String} [callback=identity] The function called per
  2813. * iteration. If a property name or object is passed, it will be used to create
  2814. * a "_.pluck" or "_.where" style callback, respectively.
  2815. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  2816. * @returns {Array} Returns a new array of elements that did **not** pass the
  2817. * callback check.
  2818. * @example
  2819. *
  2820. * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
  2821. * // => [1, 3, 5]
  2822. *
  2823. * var food = [
  2824. * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
  2825. * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
  2826. * ];
  2827. *
  2828. * // using "_.pluck" callback shorthand
  2829. * _.reject(food, 'organic');
  2830. * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }]
  2831. *
  2832. * // using "_.where" callback shorthand
  2833. * _.reject(food, { 'type': 'fruit' });
  2834. * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }]
  2835. */
  2836. function reject(collection, callback, thisArg) {
  2837. callback = lodash.createCallback(callback, thisArg);
  2838. return filter(collection, function(value, index, collection) {
  2839. return !callback(value, index, collection);
  2840. });
  2841. }
  2842. /**
  2843. * Creates an array of shuffled `array` values, using a version of the
  2844. * Fisher-Yates shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle.
  2845. *
  2846. * @static
  2847. * @memberOf _
  2848. * @category Collections
  2849. * @param {Array|Object|String} collection The collection to shuffle.
  2850. * @returns {Array} Returns a new shuffled collection.
  2851. * @example
  2852. *
  2853. * _.shuffle([1, 2, 3, 4, 5, 6]);
  2854. * // => [4, 1, 6, 3, 5, 2]
  2855. */
  2856. function shuffle(collection) {
  2857. var index = -1,
  2858. length = collection ? collection.length : 0,
  2859. result = Array(typeof length == 'number' ? length : 0);
  2860. forEach(collection, function(value) {
  2861. var rand = floor(nativeRandom() * (++index + 1));
  2862. result[index] = result[rand];
  2863. result[rand] = value;
  2864. });
  2865. return result;
  2866. }
  2867. /**
  2868. * Gets the size of the `collection` by returning `collection.length` for arrays
  2869. * and array-like objects or the number of own enumerable properties for objects.
  2870. *
  2871. * @static
  2872. * @memberOf _
  2873. * @category Collections
  2874. * @param {Array|Object|String} collection The collection to inspect.
  2875. * @returns {Number} Returns `collection.length` or number of own enumerable properties.
  2876. * @example
  2877. *
  2878. * _.size([1, 2]);
  2879. * // => 2
  2880. *
  2881. * _.size({ 'one': 1, 'two': 2, 'three': 3 });
  2882. * // => 3
  2883. *
  2884. * _.size('curly');
  2885. * // => 5
  2886. */
  2887. function size(collection) {
  2888. var length = collection ? collection.length : 0;
  2889. return typeof length == 'number' ? length : keys(collection).length;
  2890. }
  2891. /**
  2892. * Checks if the `callback` returns a truthy value for **any** element of a
  2893. * `collection`. The function returns as soon as it finds passing value, and
  2894. * does not iterate over the entire `collection`. The `callback` is bound to
  2895. * `thisArg` and invoked with three arguments; (value, index|key, collection).
  2896. *
  2897. * If a property name is passed for `callback`, the created "_.pluck" style
  2898. * callback will return the property value of the given element.
  2899. *
  2900. * If an object is passed for `callback`, the created "_.where" style callback
  2901. * will return `true` for elements that have the properties of the given object,
  2902. * else `false`.
  2903. *
  2904. * @static
  2905. * @memberOf _
  2906. * @alias any
  2907. * @category Collections
  2908. * @param {Array|Object|String} collection The collection to iterate over.
  2909. * @param {Function|Object|String} [callback=identity] The function called per
  2910. * iteration. If a property name or object is passed, it will be used to create
  2911. * a "_.pluck" or "_.where" style callback, respectively.
  2912. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  2913. * @returns {Boolean} Returns `true` if any element passes the callback check,
  2914. * else `false`.
  2915. * @example
  2916. *
  2917. * _.some([null, 0, 'yes', false], Boolean);
  2918. * // => true
  2919. *
  2920. * var food = [
  2921. * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
  2922. * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
  2923. * ];
  2924. *
  2925. * // using "_.pluck" callback shorthand
  2926. * _.some(food, 'organic');
  2927. * // => true
  2928. *
  2929. * // using "_.where" callback shorthand
  2930. * _.some(food, { 'type': 'meat' });
  2931. * // => false
  2932. */
  2933. function some(collection, callback, thisArg) {
  2934. var result;
  2935. callback = lodash.createCallback(callback, thisArg);
  2936. var index = -1,
  2937. length = collection ? collection.length : 0;
  2938. if (typeof length == 'number') {
  2939. while (++index < length) {
  2940. if ((result = callback(collection[index], index, collection))) {
  2941. break;
  2942. }
  2943. }
  2944. } else {
  2945. forOwn(collection, function(value, index, collection) {
  2946. return !(result = callback(value, index, collection));
  2947. });
  2948. }
  2949. return !!result;
  2950. }
  2951. /**
  2952. * Creates an array of elements, sorted in ascending order by the results of
  2953. * running each element in the `collection` through the `callback`. This method
  2954. * performs a stable sort, that is, it will preserve the original sort order of
  2955. * equal elements. The `callback` is bound to `thisArg` and invoked with three
  2956. * arguments; (value, index|key, collection).
  2957. *
  2958. * If a property name is passed for `callback`, the created "_.pluck" style
  2959. * callback will return the property value of the given element.
  2960. *
  2961. * If an object is passed for `callback`, the created "_.where" style callback
  2962. * will return `true` for elements that have the properties of the given object,
  2963. * else `false`.
  2964. *
  2965. * @static
  2966. * @memberOf _
  2967. * @category Collections
  2968. * @param {Array|Object|String} collection The collection to iterate over.
  2969. * @param {Function|Object|String} [callback=identity] The function called per
  2970. * iteration. If a property name or object is passed, it will be used to create
  2971. * a "_.pluck" or "_.where" style callback, respectively.
  2972. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  2973. * @returns {Array} Returns a new array of sorted elements.
  2974. * @example
  2975. *
  2976. * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); });
  2977. * // => [3, 1, 2]
  2978. *
  2979. * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math);
  2980. * // => [3, 1, 2]
  2981. *
  2982. * // using "_.pluck" callback shorthand
  2983. * _.sortBy(['banana', 'strawberry', 'apple'], 'length');
  2984. * // => ['apple', 'banana', 'strawberry']
  2985. */
  2986. function sortBy(collection, callback, thisArg) {
  2987. var index = -1,
  2988. length = collection ? collection.length : 0,
  2989. result = Array(typeof length == 'number' ? length : 0);
  2990. callback = lodash.createCallback(callback, thisArg);
  2991. forEach(collection, function(value, key, collection) {
  2992. var object = result[++index] = getObject();
  2993. object.criteria = callback(value, key, collection);
  2994. object.index = index;
  2995. object.value = value;
  2996. });
  2997. length = result.length;
  2998. result.sort(compareAscending);
  2999. while (length--) {
  3000. var object = result[length];
  3001. result[length] = object.value;
  3002. releaseObject(object);
  3003. }
  3004. return result;
  3005. }
  3006. /**
  3007. * Converts the `collection` to an array.
  3008. *
  3009. * @static
  3010. * @memberOf _
  3011. * @category Collections
  3012. * @param {Array|Object|String} collection The collection to convert.
  3013. * @returns {Array} Returns the new converted array.
  3014. * @example
  3015. *
  3016. * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
  3017. * // => [2, 3, 4]
  3018. */
  3019. function toArray(collection) {
  3020. if (collection && typeof collection.length == 'number') {
  3021. return slice(collection);
  3022. }
  3023. return values(collection);
  3024. }
  3025. /**
  3026. * Examines each element in a `collection`, returning an array of all elements
  3027. * that have the given `properties`. When checking `properties`, this method
  3028. * performs a deep comparison between values to determine if they are equivalent
  3029. * to each other.
  3030. *
  3031. * @static
  3032. * @memberOf _
  3033. * @type Function
  3034. * @category Collections
  3035. * @param {Array|Object|String} collection The collection to iterate over.
  3036. * @param {Object} properties The object of property values to filter by.
  3037. * @returns {Array} Returns a new array of elements that have the given `properties`.
  3038. * @example
  3039. *
  3040. * var stooges = [
  3041. * { 'name': 'moe', 'age': 40 },
  3042. * { 'name': 'larry', 'age': 50 }
  3043. * ];
  3044. *
  3045. * _.where(stooges, { 'age': 40 });
  3046. * // => [{ 'name': 'moe', 'age': 40 }]
  3047. */
  3048. var where = filter;
  3049. /*--------------------------------------------------------------------------*/
  3050. /**
  3051. * Creates an array with all falsey values of `array` removed. The values
  3052. * `false`, `null`, `0`, `""`, `undefined` and `NaN` are all falsey.
  3053. *
  3054. * @static
  3055. * @memberOf _
  3056. * @category Arrays
  3057. * @param {Array} array The array to compact.
  3058. * @returns {Array} Returns a new filtered array.
  3059. * @example
  3060. *
  3061. * _.compact([0, 1, false, 2, '', 3]);
  3062. * // => [1, 2, 3]
  3063. */
  3064. function compact(array) {
  3065. var index = -1,
  3066. length = array ? array.length : 0,
  3067. result = [];
  3068. while (++index < length) {
  3069. var value = array[index];
  3070. if (value) {
  3071. result.push(value);
  3072. }
  3073. }
  3074. return result;
  3075. }
  3076. /**
  3077. * Creates an array of `array` elements not present in the other arrays
  3078. * using strict equality for comparisons, i.e. `===`.
  3079. *
  3080. * @static
  3081. * @memberOf _
  3082. * @category Arrays
  3083. * @param {Array} array The array to process.
  3084. * @param {Array} [array1, array2, ...] Arrays to check.
  3085. * @returns {Array} Returns a new array of `array` elements not present in the
  3086. * other arrays.
  3087. * @example
  3088. *
  3089. * _.difference([1, 2, 3, 4, 5], [5, 2, 10]);
  3090. * // => [1, 3, 4]
  3091. */
  3092. function difference(array) {
  3093. var index = -1,
  3094. indexOf = getIndexOf(),
  3095. length = array ? array.length : 0,
  3096. seen = concat.apply(arrayRef, nativeSlice.call(arguments, 1)),
  3097. result = [];
  3098. var isLarge = length >= largeArraySize && indexOf === basicIndexOf;
  3099. if (isLarge) {
  3100. var cache = createCache(seen);
  3101. if (cache) {
  3102. indexOf = cacheIndexOf;
  3103. seen = cache;
  3104. } else {
  3105. isLarge = false;
  3106. }
  3107. }
  3108. while (++index < length) {
  3109. var value = array[index];
  3110. if (indexOf(seen, value) < 0) {
  3111. result.push(value);
  3112. }
  3113. }
  3114. if (isLarge) {
  3115. releaseObject(seen);
  3116. }
  3117. return result;
  3118. }
  3119. /**
  3120. * This method is similar to `_.find`, except that it returns the index of
  3121. * the element that passes the callback check, instead of the element itself.
  3122. *
  3123. * @static
  3124. * @memberOf _
  3125. * @category Arrays
  3126. * @param {Array} array The array to search.
  3127. * @param {Function|Object|String} [callback=identity] The function called per
  3128. * iteration. If a property name or object is passed, it will be used to create
  3129. * a "_.pluck" or "_.where" style callback, respectively.
  3130. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  3131. * @returns {Mixed} Returns the index of the found element, else `-1`.
  3132. * @example
  3133. *
  3134. * _.findIndex(['apple', 'banana', 'beet'], function(food) {
  3135. * return /^b/.test(food);
  3136. * });
  3137. * // => 1
  3138. */
  3139. function findIndex(array, callback, thisArg) {
  3140. var index = -1,
  3141. length = array ? array.length : 0;
  3142. callback = lodash.createCallback(callback, thisArg);
  3143. while (++index < length) {
  3144. if (callback(array[index], index, array)) {
  3145. return index;
  3146. }
  3147. }
  3148. return -1;
  3149. }
  3150. /**
  3151. * Gets the first element of the `array`. If a number `n` is passed, the first
  3152. * `n` elements of the `array` are returned. If a `callback` function is passed,
  3153. * elements at the beginning of the array are returned as long as the `callback`
  3154. * returns truthy. The `callback` is bound to `thisArg` and invoked with three
  3155. * arguments; (value, index, array).
  3156. *
  3157. * If a property name is passed for `callback`, the created "_.pluck" style
  3158. * callback will return the property value of the given element.
  3159. *
  3160. * If an object is passed for `callback`, the created "_.where" style callback
  3161. * will return `true` for elements that have the properties of the given object,
  3162. * else `false`.
  3163. *
  3164. * @static
  3165. * @memberOf _
  3166. * @alias head, take
  3167. * @category Arrays
  3168. * @param {Array} array The array to query.
  3169. * @param {Function|Object|Number|String} [callback|n] The function called
  3170. * per element or the number of elements to return. If a property name or
  3171. * object is passed, it will be used to create a "_.pluck" or "_.where"
  3172. * style callback, respectively.
  3173. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  3174. * @returns {Mixed} Returns the first element(s) of `array`.
  3175. * @example
  3176. *
  3177. * _.first([1, 2, 3]);
  3178. * // => 1
  3179. *
  3180. * _.first([1, 2, 3], 2);
  3181. * // => [1, 2]
  3182. *
  3183. * _.first([1, 2, 3], function(num) {
  3184. * return num < 3;
  3185. * });
  3186. * // => [1, 2]
  3187. *
  3188. * var food = [
  3189. * { 'name': 'banana', 'organic': true },
  3190. * { 'name': 'beet', 'organic': false },
  3191. * ];
  3192. *
  3193. * // using "_.pluck" callback shorthand
  3194. * _.first(food, 'organic');
  3195. * // => [{ 'name': 'banana', 'organic': true }]
  3196. *
  3197. * var food = [
  3198. * { 'name': 'apple', 'type': 'fruit' },
  3199. * { 'name': 'banana', 'type': 'fruit' },
  3200. * { 'name': 'beet', 'type': 'vegetable' }
  3201. * ];
  3202. *
  3203. * // using "_.where" callback shorthand
  3204. * _.first(food, { 'type': 'fruit' });
  3205. * // => [{ 'name': 'apple', 'type': 'fruit' }, { 'name': 'banana', 'type': 'fruit' }]
  3206. */
  3207. function first(array, callback, thisArg) {
  3208. if (array) {
  3209. var n = 0,
  3210. length = array.length;
  3211. if (typeof callback != 'number' && callback != null) {
  3212. var index = -1;
  3213. callback = lodash.createCallback(callback, thisArg);
  3214. while (++index < length && callback(array[index], index, array)) {
  3215. n++;
  3216. }
  3217. } else {
  3218. n = callback;
  3219. if (n == null || thisArg) {
  3220. return array[0];
  3221. }
  3222. }
  3223. return slice(array, 0, nativeMin(nativeMax(0, n), length));
  3224. }
  3225. }
  3226. /**
  3227. * Flattens a nested array (the nesting can be to any depth). If `isShallow`
  3228. * is truthy, `array` will only be flattened a single level. If `callback`
  3229. * is passed, each element of `array` is passed through a `callback` before
  3230. * flattening. The `callback` is bound to `thisArg` and invoked with three
  3231. * arguments; (value, index, array).
  3232. *
  3233. * If a property name is passed for `callback`, the created "_.pluck" style
  3234. * callback will return the property value of the given element.
  3235. *
  3236. * If an object is passed for `callback`, the created "_.where" style callback
  3237. * will return `true` for elements that have the properties of the given object,
  3238. * else `false`.
  3239. *
  3240. * @static
  3241. * @memberOf _
  3242. * @category Arrays
  3243. * @param {Array} array The array to flatten.
  3244. * @param {Boolean} [isShallow=false] A flag to indicate only flattening a single level.
  3245. * @param {Function|Object|String} [callback=identity] The function called per
  3246. * iteration. If a property name or object is passed, it will be used to create
  3247. * a "_.pluck" or "_.where" style callback, respectively.
  3248. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  3249. * @returns {Array} Returns a new flattened array.
  3250. * @example
  3251. *
  3252. * _.flatten([1, [2], [3, [[4]]]]);
  3253. * // => [1, 2, 3, 4];
  3254. *
  3255. * _.flatten([1, [2], [3, [[4]]]], true);
  3256. * // => [1, 2, 3, [[4]]];
  3257. *
  3258. * var stooges = [
  3259. * { 'name': 'curly', 'quotes': ['Oh, a wise guy, eh?', 'Poifect!'] },
  3260. * { 'name': 'moe', 'quotes': ['Spread out!', 'You knucklehead!'] }
  3261. * ];
  3262. *
  3263. * // using "_.pluck" callback shorthand
  3264. * _.flatten(stooges, 'quotes');
  3265. * // => ['Oh, a wise guy, eh?', 'Poifect!', 'Spread out!', 'You knucklehead!']
  3266. */
  3267. var flatten = overloadWrapper(function flatten(array, isShallow, callback) {
  3268. var index = -1,
  3269. length = array ? array.length : 0,
  3270. result = [];
  3271. while (++index < length) {
  3272. var value = array[index];
  3273. if (callback) {
  3274. value = callback(value, index, array);
  3275. }
  3276. // recursively flatten arrays (susceptible to call stack limits)
  3277. if (isArray(value)) {
  3278. push.apply(result, isShallow ? value : flatten(value));
  3279. } else {
  3280. result.push(value);
  3281. }
  3282. }
  3283. return result;
  3284. });
  3285. /**
  3286. * Gets the index at which the first occurrence of `value` is found using
  3287. * strict equality for comparisons, i.e. `===`. If the `array` is already
  3288. * sorted, passing `true` for `fromIndex` will run a faster binary search.
  3289. *
  3290. * @static
  3291. * @memberOf _
  3292. * @category Arrays
  3293. * @param {Array} array The array to search.
  3294. * @param {Mixed} value The value to search for.
  3295. * @param {Boolean|Number} [fromIndex=0] The index to search from or `true` to
  3296. * perform a binary search on a sorted `array`.
  3297. * @returns {Number} Returns the index of the matched value or `-1`.
  3298. * @example
  3299. *
  3300. * _.indexOf([1, 2, 3, 1, 2, 3], 2);
  3301. * // => 1
  3302. *
  3303. * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3);
  3304. * // => 4
  3305. *
  3306. * _.indexOf([1, 1, 2, 2, 3, 3], 2, true);
  3307. * // => 2
  3308. */
  3309. function indexOf(array, value, fromIndex) {
  3310. if (typeof fromIndex == 'number') {
  3311. var length = array ? array.length : 0;
  3312. fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0);
  3313. } else if (fromIndex) {
  3314. var index = sortedIndex(array, value);
  3315. return array[index] === value ? index : -1;
  3316. }
  3317. return array ? basicIndexOf(array, value, fromIndex) : -1;
  3318. }
  3319. /**
  3320. * Gets all but the last element of `array`. If a number `n` is passed, the
  3321. * last `n` elements are excluded from the result. If a `callback` function
  3322. * is passed, elements at the end of the array are excluded from the result
  3323. * as long as the `callback` returns truthy. The `callback` is bound to
  3324. * `thisArg` and invoked with three arguments; (value, index, array).
  3325. *
  3326. * If a property name is passed for `callback`, the created "_.pluck" style
  3327. * callback will return the property value of the given element.
  3328. *
  3329. * If an object is passed for `callback`, the created "_.where" style callback
  3330. * will return `true` for elements that have the properties of the given object,
  3331. * else `false`.
  3332. *
  3333. * @static
  3334. * @memberOf _
  3335. * @category Arrays
  3336. * @param {Array} array The array to query.
  3337. * @param {Function|Object|Number|String} [callback|n=1] The function called
  3338. * per element or the number of elements to exclude. If a property name or
  3339. * object is passed, it will be used to create a "_.pluck" or "_.where"
  3340. * style callback, respectively.
  3341. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  3342. * @returns {Array} Returns a slice of `array`.
  3343. * @example
  3344. *
  3345. * _.initial([1, 2, 3]);
  3346. * // => [1, 2]
  3347. *
  3348. * _.initial([1, 2, 3], 2);
  3349. * // => [1]
  3350. *
  3351. * _.initial([1, 2, 3], function(num) {
  3352. * return num > 1;
  3353. * });
  3354. * // => [1]
  3355. *
  3356. * var food = [
  3357. * { 'name': 'beet', 'organic': false },
  3358. * { 'name': 'carrot', 'organic': true }
  3359. * ];
  3360. *
  3361. * // using "_.pluck" callback shorthand
  3362. * _.initial(food, 'organic');
  3363. * // => [{ 'name': 'beet', 'organic': false }]
  3364. *
  3365. * var food = [
  3366. * { 'name': 'banana', 'type': 'fruit' },
  3367. * { 'name': 'beet', 'type': 'vegetable' },
  3368. * { 'name': 'carrot', 'type': 'vegetable' }
  3369. * ];
  3370. *
  3371. * // using "_.where" callback shorthand
  3372. * _.initial(food, { 'type': 'vegetable' });
  3373. * // => [{ 'name': 'banana', 'type': 'fruit' }]
  3374. */
  3375. function initial(array, callback, thisArg) {
  3376. if (!array) {
  3377. return [];
  3378. }
  3379. var n = 0,
  3380. length = array.length;
  3381. if (typeof callback != 'number' && callback != null) {
  3382. var index = length;
  3383. callback = lodash.createCallback(callback, thisArg);
  3384. while (index-- && callback(array[index], index, array)) {
  3385. n++;
  3386. }
  3387. } else {
  3388. n = (callback == null || thisArg) ? 1 : callback || n;
  3389. }
  3390. return slice(array, 0, nativeMin(nativeMax(0, length - n), length));
  3391. }
  3392. /**
  3393. * Computes the intersection of all the passed-in arrays using strict equality
  3394. * for comparisons, i.e. `===`.
  3395. *
  3396. * @static
  3397. * @memberOf _
  3398. * @category Arrays
  3399. * @param {Array} [array1, array2, ...] Arrays to process.
  3400. * @returns {Array} Returns a new array of unique elements that are present
  3401. * in **all** of the arrays.
  3402. * @example
  3403. *
  3404. * _.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
  3405. * // => [1, 2]
  3406. */
  3407. function intersection(array) {
  3408. var args = arguments,
  3409. argsLength = args.length,
  3410. argsIndex = -1,
  3411. caches = getArray(),
  3412. index = -1,
  3413. indexOf = getIndexOf(),
  3414. length = array ? array.length : 0,
  3415. result = [],
  3416. seen = getArray();
  3417. while (++argsIndex < argsLength) {
  3418. var value = args[argsIndex];
  3419. caches[argsIndex] = indexOf === basicIndexOf &&
  3420. (value ? value.length : 0) >= largeArraySize &&
  3421. createCache(argsIndex ? args[argsIndex] : seen);
  3422. }
  3423. outer:
  3424. while (++index < length) {
  3425. var cache = caches[0];
  3426. value = array[index];
  3427. if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) {
  3428. argsIndex = argsLength;
  3429. (cache || seen).push(value);
  3430. while (--argsIndex) {
  3431. cache = caches[argsIndex];
  3432. if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) {
  3433. continue outer;
  3434. }
  3435. }
  3436. result.push(value);
  3437. }
  3438. }
  3439. while (argsLength--) {
  3440. cache = caches[argsLength];
  3441. if (cache) {
  3442. releaseObject(cache);
  3443. }
  3444. }
  3445. releaseArray(caches);
  3446. releaseArray(seen);
  3447. return result;
  3448. }
  3449. /**
  3450. * Gets the last element of the `array`. If a number `n` is passed, the
  3451. * last `n` elements of the `array` are returned. If a `callback` function
  3452. * is passed, elements at the end of the array are returned as long as the
  3453. * `callback` returns truthy. The `callback` is bound to `thisArg` and
  3454. * invoked with three arguments;(value, index, array).
  3455. *
  3456. *
  3457. * If a property name is passed for `callback`, the created "_.pluck" style
  3458. * callback will return the property value of the given element.
  3459. *
  3460. * If an object is passed for `callback`, the created "_.where" style callback
  3461. * will return `true` for elements that have the properties of the given object,
  3462. * else `false`.
  3463. *
  3464. * @static
  3465. * @memberOf _
  3466. * @category Arrays
  3467. * @param {Array} array The array to query.
  3468. * @param {Function|Object|Number|String} [callback|n] The function called
  3469. * per element or the number of elements to return. If a property name or
  3470. * object is passed, it will be used to create a "_.pluck" or "_.where"
  3471. * style callback, respectively.
  3472. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  3473. * @returns {Mixed} Returns the last element(s) of `array`.
  3474. * @example
  3475. *
  3476. * _.last([1, 2, 3]);
  3477. * // => 3
  3478. *
  3479. * _.last([1, 2, 3], 2);
  3480. * // => [2, 3]
  3481. *
  3482. * _.last([1, 2, 3], function(num) {
  3483. * return num > 1;
  3484. * });
  3485. * // => [2, 3]
  3486. *
  3487. * var food = [
  3488. * { 'name': 'beet', 'organic': false },
  3489. * { 'name': 'carrot', 'organic': true }
  3490. * ];
  3491. *
  3492. * // using "_.pluck" callback shorthand
  3493. * _.last(food, 'organic');
  3494. * // => [{ 'name': 'carrot', 'organic': true }]
  3495. *
  3496. * var food = [
  3497. * { 'name': 'banana', 'type': 'fruit' },
  3498. * { 'name': 'beet', 'type': 'vegetable' },
  3499. * { 'name': 'carrot', 'type': 'vegetable' }
  3500. * ];
  3501. *
  3502. * // using "_.where" callback shorthand
  3503. * _.last(food, { 'type': 'vegetable' });
  3504. * // => [{ 'name': 'beet', 'type': 'vegetable' }, { 'name': 'carrot', 'type': 'vegetable' }]
  3505. */
  3506. function last(array, callback, thisArg) {
  3507. if (array) {
  3508. var n = 0,
  3509. length = array.length;
  3510. if (typeof callback != 'number' && callback != null) {
  3511. var index = length;
  3512. callback = lodash.createCallback(callback, thisArg);
  3513. while (index-- && callback(array[index], index, array)) {
  3514. n++;
  3515. }
  3516. } else {
  3517. n = callback;
  3518. if (n == null || thisArg) {
  3519. return array[length - 1];
  3520. }
  3521. }
  3522. return slice(array, nativeMax(0, length - n));
  3523. }
  3524. }
  3525. /**
  3526. * Gets the index at which the last occurrence of `value` is found using strict
  3527. * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
  3528. * as the offset from the end of the collection.
  3529. *
  3530. * @static
  3531. * @memberOf _
  3532. * @category Arrays
  3533. * @param {Array} array The array to search.
  3534. * @param {Mixed} value The value to search for.
  3535. * @param {Number} [fromIndex=array.length-1] The index to search from.
  3536. * @returns {Number} Returns the index of the matched value or `-1`.
  3537. * @example
  3538. *
  3539. * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
  3540. * // => 4
  3541. *
  3542. * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3);
  3543. * // => 1
  3544. */
  3545. function lastIndexOf(array, value, fromIndex) {
  3546. var index = array ? array.length : 0;
  3547. if (typeof fromIndex == 'number') {
  3548. index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1;
  3549. }
  3550. while (index--) {
  3551. if (array[index] === value) {
  3552. return index;
  3553. }
  3554. }
  3555. return -1;
  3556. }
  3557. /**
  3558. * Creates an array of numbers (positive and/or negative) progressing from
  3559. * `start` up to but not including `end`.
  3560. *
  3561. * @static
  3562. * @memberOf _
  3563. * @category Arrays
  3564. * @param {Number} [start=0] The start of the range.
  3565. * @param {Number} end The end of the range.
  3566. * @param {Number} [step=1] The value to increment or decrement by.
  3567. * @returns {Array} Returns a new range array.
  3568. * @example
  3569. *
  3570. * _.range(10);
  3571. * // => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  3572. *
  3573. * _.range(1, 11);
  3574. * // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  3575. *
  3576. * _.range(0, 30, 5);
  3577. * // => [0, 5, 10, 15, 20, 25]
  3578. *
  3579. * _.range(0, -10, -1);
  3580. * // => [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
  3581. *
  3582. * _.range(0);
  3583. * // => []
  3584. */
  3585. function range(start, end, step) {
  3586. start = +start || 0;
  3587. step = +step || 1;
  3588. if (end == null) {
  3589. end = start;
  3590. start = 0;
  3591. }
  3592. // use `Array(length)` so V8 will avoid the slower "dictionary" mode
  3593. // http://youtu.be/XAqIpGU8ZZk#t=17m25s
  3594. var index = -1,
  3595. length = nativeMax(0, ceil((end - start) / step)),
  3596. result = Array(length);
  3597. while (++index < length) {
  3598. result[index] = start;
  3599. start += step;
  3600. }
  3601. return result;
  3602. }
  3603. /**
  3604. * The opposite of `_.initial`, this method gets all but the first value of
  3605. * `array`. If a number `n` is passed, the first `n` values are excluded from
  3606. * the result. If a `callback` function is passed, elements at the beginning
  3607. * of the array are excluded from the result as long as the `callback` returns
  3608. * truthy. The `callback` is bound to `thisArg` and invoked with three
  3609. * arguments; (value, index, array).
  3610. *
  3611. * If a property name is passed for `callback`, the created "_.pluck" style
  3612. * callback will return the property value of the given element.
  3613. *
  3614. * If an object is passed for `callback`, the created "_.where" style callback
  3615. * will return `true` for elements that have the properties of the given object,
  3616. * else `false`.
  3617. *
  3618. * @static
  3619. * @memberOf _
  3620. * @alias drop, tail
  3621. * @category Arrays
  3622. * @param {Array} array The array to query.
  3623. * @param {Function|Object|Number|String} [callback|n=1] The function called
  3624. * per element or the number of elements to exclude. If a property name or
  3625. * object is passed, it will be used to create a "_.pluck" or "_.where"
  3626. * style callback, respectively.
  3627. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  3628. * @returns {Array} Returns a slice of `array`.
  3629. * @example
  3630. *
  3631. * _.rest([1, 2, 3]);
  3632. * // => [2, 3]
  3633. *
  3634. * _.rest([1, 2, 3], 2);
  3635. * // => [3]
  3636. *
  3637. * _.rest([1, 2, 3], function(num) {
  3638. * return num < 3;
  3639. * });
  3640. * // => [3]
  3641. *
  3642. * var food = [
  3643. * { 'name': 'banana', 'organic': true },
  3644. * { 'name': 'beet', 'organic': false },
  3645. * ];
  3646. *
  3647. * // using "_.pluck" callback shorthand
  3648. * _.rest(food, 'organic');
  3649. * // => [{ 'name': 'beet', 'organic': false }]
  3650. *
  3651. * var food = [
  3652. * { 'name': 'apple', 'type': 'fruit' },
  3653. * { 'name': 'banana', 'type': 'fruit' },
  3654. * { 'name': 'beet', 'type': 'vegetable' }
  3655. * ];
  3656. *
  3657. * // using "_.where" callback shorthand
  3658. * _.rest(food, { 'type': 'fruit' });
  3659. * // => [{ 'name': 'beet', 'type': 'vegetable' }]
  3660. */
  3661. function rest(array, callback, thisArg) {
  3662. if (typeof callback != 'number' && callback != null) {
  3663. var n = 0,
  3664. index = -1,
  3665. length = array ? array.length : 0;
  3666. callback = lodash.createCallback(callback, thisArg);
  3667. while (++index < length && callback(array[index], index, array)) {
  3668. n++;
  3669. }
  3670. } else {
  3671. n = (callback == null || thisArg) ? 1 : nativeMax(0, callback);
  3672. }
  3673. return slice(array, n);
  3674. }
  3675. /**
  3676. * Uses a binary search to determine the smallest index at which the `value`
  3677. * should be inserted into `array` in order to maintain the sort order of the
  3678. * sorted `array`. If `callback` is passed, it will be executed for `value` and
  3679. * each element in `array` to compute their sort ranking. The `callback` is
  3680. * bound to `thisArg` and invoked with one argument; (value).
  3681. *
  3682. * If a property name is passed for `callback`, the created "_.pluck" style
  3683. * callback will return the property value of the given element.
  3684. *
  3685. * If an object is passed for `callback`, the created "_.where" style callback
  3686. * will return `true` for elements that have the properties of the given object,
  3687. * else `false`.
  3688. *
  3689. * @static
  3690. * @memberOf _
  3691. * @category Arrays
  3692. * @param {Array} array The array to inspect.
  3693. * @param {Mixed} value The value to evaluate.
  3694. * @param {Function|Object|String} [callback=identity] The function called per
  3695. * iteration. If a property name or object is passed, it will be used to create
  3696. * a "_.pluck" or "_.where" style callback, respectively.
  3697. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  3698. * @returns {Number} Returns the index at which the value should be inserted
  3699. * into `array`.
  3700. * @example
  3701. *
  3702. * _.sortedIndex([20, 30, 50], 40);
  3703. * // => 2
  3704. *
  3705. * // using "_.pluck" callback shorthand
  3706. * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
  3707. * // => 2
  3708. *
  3709. * var dict = {
  3710. * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 }
  3711. * };
  3712. *
  3713. * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
  3714. * return dict.wordToNumber[word];
  3715. * });
  3716. * // => 2
  3717. *
  3718. * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
  3719. * return this.wordToNumber[word];
  3720. * }, dict);
  3721. * // => 2
  3722. */
  3723. function sortedIndex(array, value, callback, thisArg) {
  3724. var low = 0,
  3725. high = array ? array.length : low;
  3726. // explicitly reference `identity` for better inlining in Firefox
  3727. callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity;
  3728. value = callback(value);
  3729. while (low < high) {
  3730. var mid = (low + high) >>> 1;
  3731. (callback(array[mid]) < value)
  3732. ? low = mid + 1
  3733. : high = mid;
  3734. }
  3735. return low;
  3736. }
  3737. /**
  3738. * Computes the union of the passed-in arrays using strict equality for
  3739. * comparisons, i.e. `===`.
  3740. *
  3741. * @static
  3742. * @memberOf _
  3743. * @category Arrays
  3744. * @param {Array} [array1, array2, ...] Arrays to process.
  3745. * @returns {Array} Returns a new array of unique values, in order, that are
  3746. * present in one or more of the arrays.
  3747. * @example
  3748. *
  3749. * _.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
  3750. * // => [1, 2, 3, 101, 10]
  3751. */
  3752. function union(array) {
  3753. if (!isArray(array)) {
  3754. arguments[0] = array ? nativeSlice.call(array) : arrayRef;
  3755. }
  3756. return uniq(concat.apply(arrayRef, arguments));
  3757. }
  3758. /**
  3759. * Creates a duplicate-value-free version of the `array` using strict equality
  3760. * for comparisons, i.e. `===`. If the `array` is already sorted, passing `true`
  3761. * for `isSorted` will run a faster algorithm. If `callback` is passed, each
  3762. * element of `array` is passed through the `callback` before uniqueness is computed.
  3763. * The `callback` is bound to `thisArg` and invoked with three arguments; (value, index, array).
  3764. *
  3765. * If a property name is passed for `callback`, the created "_.pluck" style
  3766. * callback will return the property value of the given element.
  3767. *
  3768. * If an object is passed for `callback`, the created "_.where" style callback
  3769. * will return `true` for elements that have the properties of the given object,
  3770. * else `false`.
  3771. *
  3772. * @static
  3773. * @memberOf _
  3774. * @alias unique
  3775. * @category Arrays
  3776. * @param {Array} array The array to process.
  3777. * @param {Boolean} [isSorted=false] A flag to indicate that the `array` is already sorted.
  3778. * @param {Function|Object|String} [callback=identity] The function called per
  3779. * iteration. If a property name or object is passed, it will be used to create
  3780. * a "_.pluck" or "_.where" style callback, respectively.
  3781. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  3782. * @returns {Array} Returns a duplicate-value-free array.
  3783. * @example
  3784. *
  3785. * _.uniq([1, 2, 1, 3, 1]);
  3786. * // => [1, 2, 3]
  3787. *
  3788. * _.uniq([1, 1, 2, 2, 3], true);
  3789. * // => [1, 2, 3]
  3790. *
  3791. * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); });
  3792. * // => ['A', 'b', 'C']
  3793. *
  3794. * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math);
  3795. * // => [1, 2.5, 3]
  3796. *
  3797. * // using "_.pluck" callback shorthand
  3798. * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
  3799. * // => [{ 'x': 1 }, { 'x': 2 }]
  3800. */
  3801. var uniq = overloadWrapper(function(array, isSorted, callback) {
  3802. var index = -1,
  3803. indexOf = getIndexOf(),
  3804. length = array ? array.length : 0,
  3805. result = [];
  3806. var isLarge = !isSorted && length >= largeArraySize && indexOf === basicIndexOf,
  3807. seen = (callback || isLarge) ? getArray() : result;
  3808. if (isLarge) {
  3809. var cache = createCache(seen);
  3810. if (cache) {
  3811. indexOf = cacheIndexOf;
  3812. seen = cache;
  3813. } else {
  3814. isLarge = false;
  3815. seen = callback ? seen : (releaseArray(seen), result);
  3816. }
  3817. }
  3818. while (++index < length) {
  3819. var value = array[index],
  3820. computed = callback ? callback(value, index, array) : value;
  3821. if (isSorted
  3822. ? !index || seen[seen.length - 1] !== computed
  3823. : indexOf(seen, computed) < 0
  3824. ) {
  3825. if (callback || isLarge) {
  3826. seen.push(computed);
  3827. }
  3828. result.push(value);
  3829. }
  3830. }
  3831. if (isLarge) {
  3832. releaseArray(seen.array);
  3833. releaseObject(seen);
  3834. } else if (callback) {
  3835. releaseArray(seen);
  3836. }
  3837. return result;
  3838. });
  3839. /**
  3840. * The inverse of `_.zip`, this method splits groups of elements into arrays
  3841. * composed of elements from each group at their corresponding indexes.
  3842. *
  3843. * @static
  3844. * @memberOf _
  3845. * @category Arrays
  3846. * @param {Array} array The array to process.
  3847. * @returns {Array} Returns a new array of the composed arrays.
  3848. * @example
  3849. *
  3850. * _.unzip([['moe', 30, true], ['larry', 40, false]]);
  3851. * // => [['moe', 'larry'], [30, 40], [true, false]];
  3852. */
  3853. function unzip(array) {
  3854. var index = -1,
  3855. length = array ? max(pluck(array, 'length')) : 0,
  3856. result = Array(length < 0 ? 0 : length);
  3857. while (++index < length) {
  3858. result[index] = pluck(array, index);
  3859. }
  3860. return result;
  3861. }
  3862. /**
  3863. * Creates an array with all occurrences of the passed values removed using
  3864. * strict equality for comparisons, i.e. `===`.
  3865. *
  3866. * @static
  3867. * @memberOf _
  3868. * @category Arrays
  3869. * @param {Array} array The array to filter.
  3870. * @param {Mixed} [value1, value2, ...] Values to remove.
  3871. * @returns {Array} Returns a new filtered array.
  3872. * @example
  3873. *
  3874. * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
  3875. * // => [2, 3, 4]
  3876. */
  3877. function without(array) {
  3878. return difference(array, nativeSlice.call(arguments, 1));
  3879. }
  3880. /**
  3881. * Groups the elements of each array at their corresponding indexes. Useful for
  3882. * separate data sources that are coordinated through matching array indexes.
  3883. * For a matrix of nested arrays, `_.zip.apply(...)` can transpose the matrix
  3884. * in a similar fashion.
  3885. *
  3886. * @static
  3887. * @memberOf _
  3888. * @category Arrays
  3889. * @param {Array} [array1, array2, ...] Arrays to process.
  3890. * @returns {Array} Returns a new array of grouped elements.
  3891. * @example
  3892. *
  3893. * _.zip(['moe', 'larry'], [30, 40], [true, false]);
  3894. * // => [['moe', 30, true], ['larry', 40, false]]
  3895. */
  3896. function zip(array) {
  3897. return array ? unzip(arguments) : [];
  3898. }
  3899. /**
  3900. * Creates an object composed from arrays of `keys` and `values`. Pass either
  3901. * a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`, or
  3902. * two arrays, one of `keys` and one of corresponding `values`.
  3903. *
  3904. * @static
  3905. * @memberOf _
  3906. * @alias object
  3907. * @category Arrays
  3908. * @param {Array} keys The array of keys.
  3909. * @param {Array} [values=[]] The array of values.
  3910. * @returns {Object} Returns an object composed of the given keys and
  3911. * corresponding values.
  3912. * @example
  3913. *
  3914. * _.zipObject(['moe', 'larry'], [30, 40]);
  3915. * // => { 'moe': 30, 'larry': 40 }
  3916. */
  3917. function zipObject(keys, values) {
  3918. var index = -1,
  3919. length = keys ? keys.length : 0,
  3920. result = {};
  3921. while (++index < length) {
  3922. var key = keys[index];
  3923. if (values) {
  3924. result[key] = values[index];
  3925. } else {
  3926. result[key[0]] = key[1];
  3927. }
  3928. }
  3929. return result;
  3930. }
  3931. /*--------------------------------------------------------------------------*/
  3932. /**
  3933. * If `n` is greater than `0`, a function is created that is restricted to
  3934. * executing `func`, with the `this` binding and arguments of the created
  3935. * function, only after it is called `n` times. If `n` is less than `1`,
  3936. * `func` is executed immediately, without a `this` binding or additional
  3937. * arguments, and its result is returned.
  3938. *
  3939. * @static
  3940. * @memberOf _
  3941. * @category Functions
  3942. * @param {Number} n The number of times the function must be called before
  3943. * it is executed.
  3944. * @param {Function} func The function to restrict.
  3945. * @returns {Function} Returns the new restricted function.
  3946. * @example
  3947. *
  3948. * var renderNotes = _.after(notes.length, render);
  3949. * _.forEach(notes, function(note) {
  3950. * note.asyncSave({ 'success': renderNotes });
  3951. * });
  3952. * // `renderNotes` is run once, after all notes have saved
  3953. */
  3954. function after(n, func) {
  3955. if (n < 1) {
  3956. return func();
  3957. }
  3958. return function() {
  3959. if (--n < 1) {
  3960. return func.apply(this, arguments);
  3961. }
  3962. };
  3963. }
  3964. /**
  3965. * Creates a function that, when called, invokes `func` with the `this`
  3966. * binding of `thisArg` and prepends any additional `bind` arguments to those
  3967. * passed to the bound function.
  3968. *
  3969. * @static
  3970. * @memberOf _
  3971. * @category Functions
  3972. * @param {Function} func The function to bind.
  3973. * @param {Mixed} [thisArg] The `this` binding of `func`.
  3974. * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied.
  3975. * @returns {Function} Returns the new bound function.
  3976. * @example
  3977. *
  3978. * var func = function(greeting) {
  3979. * return greeting + ' ' + this.name;
  3980. * };
  3981. *
  3982. * func = _.bind(func, { 'name': 'moe' }, 'hi');
  3983. * func();
  3984. * // => 'hi moe'
  3985. */
  3986. function bind(func, thisArg) {
  3987. // use `Function#bind` if it exists and is fast
  3988. // (in V8 `Function#bind` is slower except when partially applied)
  3989. return support.fastBind || (nativeBind && arguments.length > 2)
  3990. ? nativeBind.call.apply(nativeBind, arguments)
  3991. : createBound(func, thisArg, nativeSlice.call(arguments, 2));
  3992. }
  3993. /**
  3994. * Binds methods on `object` to `object`, overwriting the existing method.
  3995. * Method names may be specified as individual arguments or as arrays of method
  3996. * names. If no method names are provided, all the function properties of `object`
  3997. * will be bound.
  3998. *
  3999. * @static
  4000. * @memberOf _
  4001. * @category Functions
  4002. * @param {Object} object The object to bind and assign the bound methods to.
  4003. * @param {String} [methodName1, methodName2, ...] Method names on the object to bind.
  4004. * @returns {Object} Returns `object`.
  4005. * @example
  4006. *
  4007. * var view = {
  4008. * 'label': 'docs',
  4009. * 'onClick': function() { alert('clicked ' + this.label); }
  4010. * };
  4011. *
  4012. * _.bindAll(view);
  4013. * jQuery('#docs').on('click', view.onClick);
  4014. * // => alerts 'clicked docs', when the button is clicked
  4015. */
  4016. function bindAll(object) {
  4017. var funcs = arguments.length > 1 ? concat.apply(arrayRef, nativeSlice.call(arguments, 1)) : functions(object),
  4018. index = -1,
  4019. length = funcs.length;
  4020. while (++index < length) {
  4021. var key = funcs[index];
  4022. object[key] = bind(object[key], object);
  4023. }
  4024. return object;
  4025. }
  4026. /**
  4027. * Creates a function that, when called, invokes the method at `object[key]`
  4028. * and prepends any additional `bindKey` arguments to those passed to the bound
  4029. * function. This method differs from `_.bind` by allowing bound functions to
  4030. * reference methods that will be redefined or don't yet exist.
  4031. * See http://michaux.ca/articles/lazy-function-definition-pattern.
  4032. *
  4033. * @static
  4034. * @memberOf _
  4035. * @category Functions
  4036. * @param {Object} object The object the method belongs to.
  4037. * @param {String} key The key of the method.
  4038. * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied.
  4039. * @returns {Function} Returns the new bound function.
  4040. * @example
  4041. *
  4042. * var object = {
  4043. * 'name': 'moe',
  4044. * 'greet': function(greeting) {
  4045. * return greeting + ' ' + this.name;
  4046. * }
  4047. * };
  4048. *
  4049. * var func = _.bindKey(object, 'greet', 'hi');
  4050. * func();
  4051. * // => 'hi moe'
  4052. *
  4053. * object.greet = function(greeting) {
  4054. * return greeting + ', ' + this.name + '!';
  4055. * };
  4056. *
  4057. * func();
  4058. * // => 'hi, moe!'
  4059. */
  4060. function bindKey(object, key) {
  4061. return createBound(object, key, nativeSlice.call(arguments, 2), indicatorObject);
  4062. }
  4063. /**
  4064. * Creates a function that is the composition of the passed functions,
  4065. * where each function consumes the return value of the function that follows.
  4066. * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`.
  4067. * Each function is executed with the `this` binding of the composed function.
  4068. *
  4069. * @static
  4070. * @memberOf _
  4071. * @category Functions
  4072. * @param {Function} [func1, func2, ...] Functions to compose.
  4073. * @returns {Function} Returns the new composed function.
  4074. * @example
  4075. *
  4076. * var greet = function(name) { return 'hi ' + name; };
  4077. * var exclaim = function(statement) { return statement + '!'; };
  4078. * var welcome = _.compose(exclaim, greet);
  4079. * welcome('moe');
  4080. * // => 'hi moe!'
  4081. */
  4082. function compose() {
  4083. var funcs = arguments;
  4084. return function() {
  4085. var args = arguments,
  4086. length = funcs.length;
  4087. while (length--) {
  4088. args = [funcs[length].apply(this, args)];
  4089. }
  4090. return args[0];
  4091. };
  4092. }
  4093. /**
  4094. * Produces a callback bound to an optional `thisArg`. If `func` is a property
  4095. * name, the created callback will return the property value for a given element.
  4096. * If `func` is an object, the created callback will return `true` for elements
  4097. * that contain the equivalent object properties, otherwise it will return `false`.
  4098. *
  4099. * Note: All Lo-Dash methods, that accept a `callback` argument, use `_.createCallback`.
  4100. *
  4101. * @static
  4102. * @memberOf _
  4103. * @category Functions
  4104. * @param {Mixed} [func=identity] The value to convert to a callback.
  4105. * @param {Mixed} [thisArg] The `this` binding of the created callback.
  4106. * @param {Number} [argCount=3] The number of arguments the callback accepts.
  4107. * @returns {Function} Returns a callback function.
  4108. * @example
  4109. *
  4110. * var stooges = [
  4111. * { 'name': 'moe', 'age': 40 },
  4112. * { 'name': 'larry', 'age': 50 }
  4113. * ];
  4114. *
  4115. * // wrap to create custom callback shorthands
  4116. * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) {
  4117. * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback);
  4118. * return !match ? func(callback, thisArg) : function(object) {
  4119. * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3];
  4120. * };
  4121. * });
  4122. *
  4123. * _.filter(stooges, 'age__gt45');
  4124. * // => [{ 'name': 'larry', 'age': 50 }]
  4125. *
  4126. * // create mixins with support for "_.pluck" and "_.where" callback shorthands
  4127. * _.mixin({
  4128. * 'toLookup': function(collection, callback, thisArg) {
  4129. * callback = _.createCallback(callback, thisArg);
  4130. * return _.reduce(collection, function(result, value, index, collection) {
  4131. * return (result[callback(value, index, collection)] = value, result);
  4132. * }, {});
  4133. * }
  4134. * });
  4135. *
  4136. * _.toLookup(stooges, 'name');
  4137. * // => { 'moe': { 'name': 'moe', 'age': 40 }, 'larry': { 'name': 'larry', 'age': 50 } }
  4138. */
  4139. function createCallback(func, thisArg, argCount) {
  4140. if (func == null) {
  4141. return identity;
  4142. }
  4143. var type = typeof func;
  4144. if (type != 'function') {
  4145. if (type != 'object') {
  4146. return function(object) {
  4147. return object[func];
  4148. };
  4149. }
  4150. var props = keys(func);
  4151. return function(object) {
  4152. var length = props.length,
  4153. result = false;
  4154. while (length--) {
  4155. if (!(result = isEqual(object[props[length]], func[props[length]], indicatorObject))) {
  4156. break;
  4157. }
  4158. }
  4159. return result;
  4160. };
  4161. }
  4162. if (typeof thisArg == 'undefined' || (reThis && !reThis.test(fnToString.call(func)))) {
  4163. return func;
  4164. }
  4165. if (argCount === 1) {
  4166. return function(value) {
  4167. return func.call(thisArg, value);
  4168. };
  4169. }
  4170. if (argCount === 2) {
  4171. return function(a, b) {
  4172. return func.call(thisArg, a, b);
  4173. };
  4174. }
  4175. if (argCount === 4) {
  4176. return function(accumulator, value, index, collection) {
  4177. return func.call(thisArg, accumulator, value, index, collection);
  4178. };
  4179. }
  4180. return function(value, index, collection) {
  4181. return func.call(thisArg, value, index, collection);
  4182. };
  4183. }
  4184. /**
  4185. * Creates a function that will delay the execution of `func` until after
  4186. * `wait` milliseconds have elapsed since the last time it was invoked. Pass
  4187. * an `options` object to indicate that `func` should be invoked on the leading
  4188. * and/or trailing edge of the `wait` timeout. Subsequent calls to the debounced
  4189. * function will return the result of the last `func` call.
  4190. *
  4191. * Note: If `leading` and `trailing` options are `true`, `func` will be called
  4192. * on the trailing edge of the timeout only if the the debounced function is
  4193. * invoked more than once during the `wait` timeout.
  4194. *
  4195. * @static
  4196. * @memberOf _
  4197. * @category Functions
  4198. * @param {Function} func The function to debounce.
  4199. * @param {Number} wait The number of milliseconds to delay.
  4200. * @param {Object} options The options object.
  4201. * [leading=false] A boolean to specify execution on the leading edge of the timeout.
  4202. * [maxWait] The maximum time `func` is allowed to be delayed before it's called.
  4203. * [trailing=true] A boolean to specify execution on the trailing edge of the timeout.
  4204. * @returns {Function} Returns the new debounced function.
  4205. * @example
  4206. *
  4207. * var lazyLayout = _.debounce(calculateLayout, 300);
  4208. * jQuery(window).on('resize', lazyLayout);
  4209. *
  4210. * jQuery('#postbox').on('click', _.debounce(sendMail, 200, {
  4211. * 'leading': true,
  4212. * 'trailing': false
  4213. * });
  4214. */
  4215. function debounce(func, wait, options) {
  4216. var args,
  4217. result,
  4218. thisArg,
  4219. callCount = 0,
  4220. lastCalled = 0,
  4221. maxWait = false,
  4222. maxTimeoutId = null,
  4223. timeoutId = null,
  4224. trailing = true;
  4225. function clear() {
  4226. clearTimeout(maxTimeoutId);
  4227. clearTimeout(timeoutId);
  4228. callCount = 0;
  4229. maxTimeoutId = timeoutId = null;
  4230. }
  4231. function delayed() {
  4232. var isCalled = trailing && (!leading || callCount > 1);
  4233. clear();
  4234. if (isCalled) {
  4235. if (maxWait !== false) {
  4236. lastCalled = new Date;
  4237. }
  4238. result = func.apply(thisArg, args);
  4239. }
  4240. }
  4241. function maxDelayed() {
  4242. clear();
  4243. if (trailing || (maxWait !== wait)) {
  4244. lastCalled = new Date;
  4245. result = func.apply(thisArg, args);
  4246. }
  4247. }
  4248. wait = nativeMax(0, wait || 0);
  4249. if (options === true) {
  4250. var leading = true;
  4251. trailing = false;
  4252. } else if (isObject(options)) {
  4253. leading = options.leading;
  4254. maxWait = 'maxWait' in options && nativeMax(wait, options.maxWait || 0);
  4255. trailing = 'trailing' in options ? options.trailing : trailing;
  4256. }
  4257. return function() {
  4258. args = arguments;
  4259. thisArg = this;
  4260. callCount++;
  4261. // avoid issues with Titanium and `undefined` timeout ids
  4262. // https://github.com/appcelerator/titanium_mobile/blob/3_1_0_GA/android/titanium/src/java/ti/modules/titanium/TitaniumModule.java#L185-L192
  4263. clearTimeout(timeoutId);
  4264. if (maxWait === false) {
  4265. if (leading && callCount < 2) {
  4266. result = func.apply(thisArg, args);
  4267. }
  4268. } else {
  4269. var now = new Date;
  4270. if (!maxTimeoutId && !leading) {
  4271. lastCalled = now;
  4272. }
  4273. var remaining = maxWait - (now - lastCalled);
  4274. if (remaining <= 0) {
  4275. clearTimeout(maxTimeoutId);
  4276. maxTimeoutId = null;
  4277. lastCalled = now;
  4278. result = func.apply(thisArg, args);
  4279. }
  4280. else if (!maxTimeoutId) {
  4281. maxTimeoutId = setTimeout(maxDelayed, remaining);
  4282. }
  4283. }
  4284. if (wait !== maxWait) {
  4285. timeoutId = setTimeout(delayed, wait);
  4286. }
  4287. return result;
  4288. };
  4289. }
  4290. /**
  4291. * Defers executing the `func` function until the current call stack has cleared.
  4292. * Additional arguments will be passed to `func` when it is invoked.
  4293. *
  4294. * @static
  4295. * @memberOf _
  4296. * @category Functions
  4297. * @param {Function} func The function to defer.
  4298. * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the function with.
  4299. * @returns {Number} Returns the timer id.
  4300. * @example
  4301. *
  4302. * _.defer(function() { alert('deferred'); });
  4303. * // returns from the function before `alert` is called
  4304. */
  4305. function defer(func) {
  4306. var args = nativeSlice.call(arguments, 1);
  4307. return setTimeout(function() { func.apply(undefined, args); }, 1);
  4308. }
  4309. // use `setImmediate` if it's available in Node.js
  4310. if (isV8 && freeModule && typeof setImmediate == 'function') {
  4311. defer = bind(setImmediate, context);
  4312. }
  4313. /**
  4314. * Executes the `func` function after `wait` milliseconds. Additional arguments
  4315. * will be passed to `func` when it is invoked.
  4316. *
  4317. * @static
  4318. * @memberOf _
  4319. * @category Functions
  4320. * @param {Function} func The function to delay.
  4321. * @param {Number} wait The number of milliseconds to delay execution.
  4322. * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the function with.
  4323. * @returns {Number} Returns the timer id.
  4324. * @example
  4325. *
  4326. * var log = _.bind(console.log, console);
  4327. * _.delay(log, 1000, 'logged later');
  4328. * // => 'logged later' (Appears after one second.)
  4329. */
  4330. function delay(func, wait) {
  4331. var args = nativeSlice.call(arguments, 2);
  4332. return setTimeout(function() { func.apply(undefined, args); }, wait);
  4333. }
  4334. /**
  4335. * Creates a function that memoizes the result of `func`. If `resolver` is
  4336. * passed, it will be used to determine the cache key for storing the result
  4337. * based on the arguments passed to the memoized function. By default, the first
  4338. * argument passed to the memoized function is used as the cache key. The `func`
  4339. * is executed with the `this` binding of the memoized function. The result
  4340. * cache is exposed as the `cache` property on the memoized function.
  4341. *
  4342. * @static
  4343. * @memberOf _
  4344. * @category Functions
  4345. * @param {Function} func The function to have its output memoized.
  4346. * @param {Function} [resolver] A function used to resolve the cache key.
  4347. * @returns {Function} Returns the new memoizing function.
  4348. * @example
  4349. *
  4350. * var fibonacci = _.memoize(function(n) {
  4351. * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
  4352. * });
  4353. */
  4354. function memoize(func, resolver) {
  4355. function memoized() {
  4356. var cache = memoized.cache,
  4357. key = keyPrefix + (resolver ? resolver.apply(this, arguments) : arguments[0]);
  4358. return hasOwnProperty.call(cache, key)
  4359. ? cache[key]
  4360. : (cache[key] = func.apply(this, arguments));
  4361. }
  4362. memoized.cache = {};
  4363. return memoized;
  4364. }
  4365. /**
  4366. * Creates a function that is restricted to execute `func` once. Repeat calls to
  4367. * the function will return the value of the first call. The `func` is executed
  4368. * with the `this` binding of the created function.
  4369. *
  4370. * @static
  4371. * @memberOf _
  4372. * @category Functions
  4373. * @param {Function} func The function to restrict.
  4374. * @returns {Function} Returns the new restricted function.
  4375. * @example
  4376. *
  4377. * var initialize = _.once(createApplication);
  4378. * initialize();
  4379. * initialize();
  4380. * // `initialize` executes `createApplication` once
  4381. */
  4382. function once(func) {
  4383. var ran,
  4384. result;
  4385. return function() {
  4386. if (ran) {
  4387. return result;
  4388. }
  4389. ran = true;
  4390. result = func.apply(this, arguments);
  4391. // clear the `func` variable so the function may be garbage collected
  4392. func = null;
  4393. return result;
  4394. };
  4395. }
  4396. /**
  4397. * Creates a function that, when called, invokes `func` with any additional
  4398. * `partial` arguments prepended to those passed to the new function. This
  4399. * method is similar to `_.bind`, except it does **not** alter the `this` binding.
  4400. *
  4401. * @static
  4402. * @memberOf _
  4403. * @category Functions
  4404. * @param {Function} func The function to partially apply arguments to.
  4405. * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied.
  4406. * @returns {Function} Returns the new partially applied function.
  4407. * @example
  4408. *
  4409. * var greet = function(greeting, name) { return greeting + ' ' + name; };
  4410. * var hi = _.partial(greet, 'hi');
  4411. * hi('moe');
  4412. * // => 'hi moe'
  4413. */
  4414. function partial(func) {
  4415. return createBound(func, nativeSlice.call(arguments, 1));
  4416. }
  4417. /**
  4418. * This method is similar to `_.partial`, except that `partial` arguments are
  4419. * appended to those passed to the new function.
  4420. *
  4421. * @static
  4422. * @memberOf _
  4423. * @category Functions
  4424. * @param {Function} func The function to partially apply arguments to.
  4425. * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied.
  4426. * @returns {Function} Returns the new partially applied function.
  4427. * @example
  4428. *
  4429. * var defaultsDeep = _.partialRight(_.merge, _.defaults);
  4430. *
  4431. * var options = {
  4432. * 'variable': 'data',
  4433. * 'imports': { 'jq': $ }
  4434. * };
  4435. *
  4436. * defaultsDeep(options, _.templateSettings);
  4437. *
  4438. * options.variable
  4439. * // => 'data'
  4440. *
  4441. * options.imports
  4442. * // => { '_': _, 'jq': $ }
  4443. */
  4444. function partialRight(func) {
  4445. return createBound(func, nativeSlice.call(arguments, 1), null, indicatorObject);
  4446. }
  4447. /**
  4448. * Creates a function that, when executed, will only call the `func` function
  4449. * at most once per every `wait` milliseconds. Pass an `options` object to
  4450. * indicate that `func` should be invoked on the leading and/or trailing edge
  4451. * of the `wait` timeout. Subsequent calls to the throttled function will
  4452. * return the result of the last `func` call.
  4453. *
  4454. * Note: If `leading` and `trailing` options are `true`, `func` will be called
  4455. * on the trailing edge of the timeout only if the the throttled function is
  4456. * invoked more than once during the `wait` timeout.
  4457. *
  4458. * @static
  4459. * @memberOf _
  4460. * @category Functions
  4461. * @param {Function} func The function to throttle.
  4462. * @param {Number} wait The number of milliseconds to throttle executions to.
  4463. * @param {Object} options The options object.
  4464. * [leading=true] A boolean to specify execution on the leading edge of the timeout.
  4465. * [trailing=true] A boolean to specify execution on the trailing edge of the timeout.
  4466. * @returns {Function} Returns the new throttled function.
  4467. * @example
  4468. *
  4469. * var throttled = _.throttle(updatePosition, 100);
  4470. * jQuery(window).on('scroll', throttled);
  4471. *
  4472. * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
  4473. * 'trailing': false
  4474. * }));
  4475. */
  4476. function throttle(func, wait, options) {
  4477. var leading = true,
  4478. trailing = true;
  4479. if (options === false) {
  4480. leading = false;
  4481. } else if (isObject(options)) {
  4482. leading = 'leading' in options ? options.leading : leading;
  4483. trailing = 'trailing' in options ? options.trailing : trailing;
  4484. }
  4485. options = getObject();
  4486. options.leading = leading;
  4487. options.maxWait = wait;
  4488. options.trailing = trailing;
  4489. var result = debounce(func, wait, options);
  4490. releaseObject(options);
  4491. return result;
  4492. }
  4493. /**
  4494. * Creates a function that passes `value` to the `wrapper` function as its
  4495. * first argument. Additional arguments passed to the function are appended
  4496. * to those passed to the `wrapper` function. The `wrapper` is executed with
  4497. * the `this` binding of the created function.
  4498. *
  4499. * @static
  4500. * @memberOf _
  4501. * @category Functions
  4502. * @param {Mixed} value The value to wrap.
  4503. * @param {Function} wrapper The wrapper function.
  4504. * @returns {Function} Returns the new function.
  4505. * @example
  4506. *
  4507. * var hello = function(name) { return 'hello ' + name; };
  4508. * hello = _.wrap(hello, function(func) {
  4509. * return 'before, ' + func('moe') + ', after';
  4510. * });
  4511. * hello();
  4512. * // => 'before, hello moe, after'
  4513. */
  4514. function wrap(value, wrapper) {
  4515. return function() {
  4516. var args = [value];
  4517. push.apply(args, arguments);
  4518. return wrapper.apply(this, args);
  4519. };
  4520. }
  4521. /*--------------------------------------------------------------------------*/
  4522. /**
  4523. * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their
  4524. * corresponding HTML entities.
  4525. *
  4526. * @static
  4527. * @memberOf _
  4528. * @category Utilities
  4529. * @param {String} string The string to escape.
  4530. * @returns {String} Returns the escaped string.
  4531. * @example
  4532. *
  4533. * _.escape('Moe, Larry & Curly');
  4534. * // => 'Moe, Larry &amp; Curly'
  4535. */
  4536. function escape(string) {
  4537. return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar);
  4538. }
  4539. /**
  4540. * This method returns the first argument passed to it.
  4541. *
  4542. * @static
  4543. * @memberOf _
  4544. * @category Utilities
  4545. * @param {Mixed} value Any value.
  4546. * @returns {Mixed} Returns `value`.
  4547. * @example
  4548. *
  4549. * var moe = { 'name': 'moe' };
  4550. * moe === _.identity(moe);
  4551. * // => true
  4552. */
  4553. function identity(value) {
  4554. return value;
  4555. }
  4556. /**
  4557. * Adds functions properties of `object` to the `lodash` function and chainable
  4558. * wrapper.
  4559. *
  4560. * @static
  4561. * @memberOf _
  4562. * @category Utilities
  4563. * @param {Object} object The object of function properties to add to `lodash`.
  4564. * @example
  4565. *
  4566. * _.mixin({
  4567. * 'capitalize': function(string) {
  4568. * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
  4569. * }
  4570. * });
  4571. *
  4572. * _.capitalize('moe');
  4573. * // => 'Moe'
  4574. *
  4575. * _('moe').capitalize();
  4576. * // => 'Moe'
  4577. */
  4578. function mixin(object) {
  4579. forEach(functions(object), function(methodName) {
  4580. var func = lodash[methodName] = object[methodName];
  4581. lodash.prototype[methodName] = function() {
  4582. var value = this.__wrapped__,
  4583. args = [value];
  4584. push.apply(args, arguments);
  4585. var result = func.apply(lodash, args);
  4586. return (value && typeof value == 'object' && value === result)
  4587. ? this
  4588. : new lodashWrapper(result);
  4589. };
  4590. });
  4591. }
  4592. /**
  4593. * Reverts the '_' variable to its previous value and returns a reference to
  4594. * the `lodash` function.
  4595. *
  4596. * @static
  4597. * @memberOf _
  4598. * @category Utilities
  4599. * @returns {Function} Returns the `lodash` function.
  4600. * @example
  4601. *
  4602. * var lodash = _.noConflict();
  4603. */
  4604. function noConflict() {
  4605. context._ = oldDash;
  4606. return this;
  4607. }
  4608. /**
  4609. * Converts the given `value` into an integer of the specified `radix`.
  4610. * If `radix` is `undefined` or `0`, a `radix` of `10` is used unless the
  4611. * `value` is a hexadecimal, in which case a `radix` of `16` is used.
  4612. *
  4613. * Note: This method avoids differences in native ES3 and ES5 `parseInt`
  4614. * implementations. See http://es5.github.com/#E.
  4615. *
  4616. * @static
  4617. * @memberOf _
  4618. * @category Utilities
  4619. * @param {String} value The value to parse.
  4620. * @param {Number} [radix] The radix used to interpret the value to parse.
  4621. * @returns {Number} Returns the new integer value.
  4622. * @example
  4623. *
  4624. * _.parseInt('08');
  4625. * // => 8
  4626. */
  4627. var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) {
  4628. // Firefox and Opera still follow the ES3 specified implementation of `parseInt`
  4629. return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0);
  4630. };
  4631. /**
  4632. * Produces a random number between `min` and `max` (inclusive). If only one
  4633. * argument is passed, a number between `0` and the given number will be returned.
  4634. *
  4635. * @static
  4636. * @memberOf _
  4637. * @category Utilities
  4638. * @param {Number} [min=0] The minimum possible value.
  4639. * @param {Number} [max=1] The maximum possible value.
  4640. * @returns {Number} Returns a random number.
  4641. * @example
  4642. *
  4643. * _.random(0, 5);
  4644. * // => a number between 0 and 5
  4645. *
  4646. * _.random(5);
  4647. * // => also a number between 0 and 5
  4648. */
  4649. function random(min, max) {
  4650. if (min == null && max == null) {
  4651. max = 1;
  4652. }
  4653. min = +min || 0;
  4654. if (max == null) {
  4655. max = min;
  4656. min = 0;
  4657. } else {
  4658. max = +max || 0;
  4659. }
  4660. var rand = nativeRandom();
  4661. return (min % 1 || max % 1)
  4662. ? min + nativeMin(rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1))), max)
  4663. : min + floor(rand * (max - min + 1));
  4664. }
  4665. /**
  4666. * Resolves the value of `property` on `object`. If `property` is a function,
  4667. * it will be invoked with the `this` binding of `object` and its result returned,
  4668. * else the property value is returned. If `object` is falsey, then `undefined`
  4669. * is returned.
  4670. *
  4671. * @static
  4672. * @memberOf _
  4673. * @category Utilities
  4674. * @param {Object} object The object to inspect.
  4675. * @param {String} property The property to get the value of.
  4676. * @returns {Mixed} Returns the resolved value.
  4677. * @example
  4678. *
  4679. * var object = {
  4680. * 'cheese': 'crumpets',
  4681. * 'stuff': function() {
  4682. * return 'nonsense';
  4683. * }
  4684. * };
  4685. *
  4686. * _.result(object, 'cheese');
  4687. * // => 'crumpets'
  4688. *
  4689. * _.result(object, 'stuff');
  4690. * // => 'nonsense'
  4691. */
  4692. function result(object, property) {
  4693. var value = object ? object[property] : undefined;
  4694. return isFunction(value) ? object[property]() : value;
  4695. }
  4696. /**
  4697. * A micro-templating method that handles arbitrary delimiters, preserves
  4698. * whitespace, and correctly escapes quotes within interpolated code.
  4699. *
  4700. * Note: In the development build, `_.template` utilizes sourceURLs for easier
  4701. * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
  4702. *
  4703. * For more information on precompiling templates see:
  4704. * http://lodash.com/#custom-builds
  4705. *
  4706. * For more information on Chrome extension sandboxes see:
  4707. * http://developer.chrome.com/stable/extensions/sandboxingEval.html
  4708. *
  4709. * @static
  4710. * @memberOf _
  4711. * @category Utilities
  4712. * @param {String} text The template text.
  4713. * @param {Object} data The data object used to populate the text.
  4714. * @param {Object} options The options object.
  4715. * escape - The "escape" delimiter regexp.
  4716. * evaluate - The "evaluate" delimiter regexp.
  4717. * interpolate - The "interpolate" delimiter regexp.
  4718. * sourceURL - The sourceURL of the template's compiled source.
  4719. * variable - The data object variable name.
  4720. * @returns {Function|String} Returns a compiled function when no `data` object
  4721. * is given, else it returns the interpolated text.
  4722. * @example
  4723. *
  4724. * // using a compiled template
  4725. * var compiled = _.template('hello <%= name %>');
  4726. * compiled({ 'name': 'moe' });
  4727. * // => 'hello moe'
  4728. *
  4729. * var list = '<% _.forEach(people, function(name) { %><li><%= name %></li><% }); %>';
  4730. * _.template(list, { 'people': ['moe', 'larry'] });
  4731. * // => '<li>moe</li><li>larry</li>'
  4732. *
  4733. * // using the "escape" delimiter to escape HTML in data property values
  4734. * _.template('<b><%- value %></b>', { 'value': '<script>' });
  4735. * // => '<b>&lt;script&gt;</b>'
  4736. *
  4737. * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter
  4738. * _.template('hello ${ name }', { 'name': 'curly' });
  4739. * // => 'hello curly'
  4740. *
  4741. * // using the internal `print` function in "evaluate" delimiters
  4742. * _.template('<% print("hello " + epithet); %>!', { 'epithet': 'stooge' });
  4743. * // => 'hello stooge!'
  4744. *
  4745. * // using custom template delimiters
  4746. * _.templateSettings = {
  4747. * 'interpolate': /{{([\s\S]+?)}}/g
  4748. * };
  4749. *
  4750. * _.template('hello {{ name }}!', { 'name': 'mustache' });
  4751. * // => 'hello mustache!'
  4752. *
  4753. * // using the `sourceURL` option to specify a custom sourceURL for the template
  4754. * var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' });
  4755. * compiled(data);
  4756. * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
  4757. *
  4758. * // using the `variable` option to ensure a with-statement isn't used in the compiled template
  4759. * var compiled = _.template('hi <%= data.name %>!', null, { 'variable': 'data' });
  4760. * compiled.source;
  4761. * // => function(data) {
  4762. * var __t, __p = '', __e = _.escape;
  4763. * __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!';
  4764. * return __p;
  4765. * }
  4766. *
  4767. * // using the `source` property to inline compiled templates for meaningful
  4768. * // line numbers in error messages and a stack trace
  4769. * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
  4770. * var JST = {\
  4771. * "main": ' + _.template(mainText).source + '\
  4772. * };\
  4773. * ');
  4774. */
  4775. function template(text, data, options) {
  4776. // based on John Resig's `tmpl` implementation
  4777. // http://ejohn.org/blog/javascript-micro-templating/
  4778. // and Laura Doktorova's doT.js
  4779. // https://github.com/olado/doT
  4780. var settings = lodash.templateSettings;
  4781. text || (text = '');
  4782. // avoid missing dependencies when `iteratorTemplate` is not defined
  4783. options = defaults({}, options, settings);
  4784. var imports = defaults({}, options.imports, settings.imports),
  4785. importsKeys = keys(imports),
  4786. importsValues = values(imports);
  4787. var isEvaluating,
  4788. index = 0,
  4789. interpolate = options.interpolate || reNoMatch,
  4790. source = "__p += '";
  4791. // compile the regexp to match each delimiter
  4792. var reDelimiters = RegExp(
  4793. (options.escape || reNoMatch).source + '|' +
  4794. interpolate.source + '|' +
  4795. (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
  4796. (options.evaluate || reNoMatch).source + '|$'
  4797. , 'g');
  4798. text.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
  4799. interpolateValue || (interpolateValue = esTemplateValue);
  4800. // escape characters that cannot be included in string literals
  4801. source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar);
  4802. // replace delimiters with snippets
  4803. if (escapeValue) {
  4804. source += "' +\n__e(" + escapeValue + ") +\n'";
  4805. }
  4806. if (evaluateValue) {
  4807. isEvaluating = true;
  4808. source += "';\n" + evaluateValue + ";\n__p += '";
  4809. }
  4810. if (interpolateValue) {
  4811. source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
  4812. }
  4813. index = offset + match.length;
  4814. // the JS engine embedded in Adobe products requires returning the `match`
  4815. // string in order to produce the correct `offset` value
  4816. return match;
  4817. });
  4818. source += "';\n";
  4819. // if `variable` is not specified, wrap a with-statement around the generated
  4820. // code to add the data object to the top of the scope chain
  4821. var variable = options.variable,
  4822. hasVariable = variable;
  4823. if (!hasVariable) {
  4824. variable = 'obj';
  4825. source = 'with (' + variable + ') {\n' + source + '\n}\n';
  4826. }
  4827. // cleanup code by stripping empty strings
  4828. source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
  4829. .replace(reEmptyStringMiddle, '$1')
  4830. .replace(reEmptyStringTrailing, '$1;');
  4831. // frame code as the function body
  4832. source = 'function(' + variable + ') {\n' +
  4833. (hasVariable ? '' : variable + ' || (' + variable + ' = {});\n') +
  4834. "var __t, __p = '', __e = _.escape" +
  4835. (isEvaluating
  4836. ? ', __j = Array.prototype.join;\n' +
  4837. "function print() { __p += __j.call(arguments, '') }\n"
  4838. : ';\n'
  4839. ) +
  4840. source +
  4841. 'return __p\n}';
  4842. // Use a sourceURL for easier debugging and wrap in a multi-line comment to
  4843. // avoid issues with Narwhal, IE conditional compilation, and the JS engine
  4844. // embedded in Adobe products.
  4845. // http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
  4846. var sourceURL = '\n/*\n//@ sourceURL=' + (options.sourceURL || '/lodash/template/source[' + (templateCounter++) + ']') + '\n*/';
  4847. try {
  4848. var result = Function(importsKeys, 'return ' + source + sourceURL).apply(undefined, importsValues);
  4849. } catch(e) {
  4850. e.source = source;
  4851. throw e;
  4852. }
  4853. if (data) {
  4854. return result(data);
  4855. }
  4856. // provide the compiled function's source via its `toString` method, in
  4857. // supported environments, or the `source` property as a convenience for
  4858. // inlining compiled templates during the build process
  4859. result.source = source;
  4860. return result;
  4861. }
  4862. /**
  4863. * Executes the `callback` function `n` times, returning an array of the results
  4864. * of each `callback` execution. The `callback` is bound to `thisArg` and invoked
  4865. * with one argument; (index).
  4866. *
  4867. * @static
  4868. * @memberOf _
  4869. * @category Utilities
  4870. * @param {Number} n The number of times to execute the callback.
  4871. * @param {Function} callback The function called per iteration.
  4872. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  4873. * @returns {Array} Returns a new array of the results of each `callback` execution.
  4874. * @example
  4875. *
  4876. * var diceRolls = _.times(3, _.partial(_.random, 1, 6));
  4877. * // => [3, 6, 4]
  4878. *
  4879. * _.times(3, function(n) { mage.castSpell(n); });
  4880. * // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`, and `2` respectively
  4881. *
  4882. * _.times(3, function(n) { this.cast(n); }, mage);
  4883. * // => also calls `mage.castSpell(n)` three times
  4884. */
  4885. function times(n, callback, thisArg) {
  4886. n = (n = +n) > -1 ? n : 0;
  4887. var index = -1,
  4888. result = Array(n);
  4889. callback = lodash.createCallback(callback, thisArg, 1);
  4890. while (++index < n) {
  4891. result[index] = callback(index);
  4892. }
  4893. return result;
  4894. }
  4895. /**
  4896. * The inverse of `_.escape`, this method converts the HTML entities
  4897. * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to their
  4898. * corresponding characters.
  4899. *
  4900. * @static
  4901. * @memberOf _
  4902. * @category Utilities
  4903. * @param {String} string The string to unescape.
  4904. * @returns {String} Returns the unescaped string.
  4905. * @example
  4906. *
  4907. * _.unescape('Moe, Larry &amp; Curly');
  4908. * // => 'Moe, Larry & Curly'
  4909. */
  4910. function unescape(string) {
  4911. return string == null ? '' : String(string).replace(reEscapedHtml, unescapeHtmlChar);
  4912. }
  4913. /**
  4914. * Generates a unique ID. If `prefix` is passed, the ID will be appended to it.
  4915. *
  4916. * @static
  4917. * @memberOf _
  4918. * @category Utilities
  4919. * @param {String} [prefix] The value to prefix the ID with.
  4920. * @returns {String} Returns the unique ID.
  4921. * @example
  4922. *
  4923. * _.uniqueId('contact_');
  4924. * // => 'contact_104'
  4925. *
  4926. * _.uniqueId();
  4927. * // => '105'
  4928. */
  4929. function uniqueId(prefix) {
  4930. var id = ++idCounter;
  4931. return String(prefix == null ? '' : prefix) + id;
  4932. }
  4933. /*--------------------------------------------------------------------------*/
  4934. /**
  4935. * Invokes `interceptor` with the `value` as the first argument, and then
  4936. * returns `value`. The purpose of this method is to "tap into" a method chain,
  4937. * in order to perform operations on intermediate results within the chain.
  4938. *
  4939. * @static
  4940. * @memberOf _
  4941. * @category Chaining
  4942. * @param {Mixed} value The value to pass to `interceptor`.
  4943. * @param {Function} interceptor The function to invoke.
  4944. * @returns {Mixed} Returns `value`.
  4945. * @example
  4946. *
  4947. * _([1, 2, 3, 4])
  4948. * .filter(function(num) { return num % 2 == 0; })
  4949. * .tap(alert)
  4950. * .map(function(num) { return num * num; })
  4951. * .value();
  4952. * // => // [2, 4] (alerted)
  4953. * // => [4, 16]
  4954. */
  4955. function tap(value, interceptor) {
  4956. interceptor(value);
  4957. return value;
  4958. }
  4959. /**
  4960. * Produces the `toString` result of the wrapped value.
  4961. *
  4962. * @name toString
  4963. * @memberOf _
  4964. * @category Chaining
  4965. * @returns {String} Returns the string result.
  4966. * @example
  4967. *
  4968. * _([1, 2, 3]).toString();
  4969. * // => '1,2,3'
  4970. */
  4971. function wrapperToString() {
  4972. return String(this.__wrapped__);
  4973. }
  4974. /**
  4975. * Extracts the wrapped value.
  4976. *
  4977. * @name valueOf
  4978. * @memberOf _
  4979. * @alias value
  4980. * @category Chaining
  4981. * @returns {Mixed} Returns the wrapped value.
  4982. * @example
  4983. *
  4984. * _([1, 2, 3]).valueOf();
  4985. * // => [1, 2, 3]
  4986. */
  4987. function wrapperValueOf() {
  4988. return this.__wrapped__;
  4989. }
  4990. /*--------------------------------------------------------------------------*/
  4991. // add functions that return wrapped values when chaining
  4992. lodash.after = after;
  4993. lodash.assign = assign;
  4994. lodash.at = at;
  4995. lodash.bind = bind;
  4996. lodash.bindAll = bindAll;
  4997. lodash.bindKey = bindKey;
  4998. lodash.compact = compact;
  4999. lodash.compose = compose;
  5000. lodash.countBy = countBy;
  5001. lodash.createCallback = createCallback;
  5002. lodash.debounce = debounce;
  5003. lodash.defaults = defaults;
  5004. lodash.defer = defer;
  5005. lodash.delay = delay;
  5006. lodash.difference = difference;
  5007. lodash.filter = filter;
  5008. lodash.flatten = flatten;
  5009. lodash.forEach = forEach;
  5010. lodash.forIn = forIn;
  5011. lodash.forOwn = forOwn;
  5012. lodash.functions = functions;
  5013. lodash.groupBy = groupBy;
  5014. lodash.initial = initial;
  5015. lodash.intersection = intersection;
  5016. lodash.invert = invert;
  5017. lodash.invoke = invoke;
  5018. lodash.keys = keys;
  5019. lodash.map = map;
  5020. lodash.max = max;
  5021. lodash.memoize = memoize;
  5022. lodash.merge = merge;
  5023. lodash.min = min;
  5024. lodash.omit = omit;
  5025. lodash.once = once;
  5026. lodash.pairs = pairs;
  5027. lodash.partial = partial;
  5028. lodash.partialRight = partialRight;
  5029. lodash.pick = pick;
  5030. lodash.pluck = pluck;
  5031. lodash.range = range;
  5032. lodash.reject = reject;
  5033. lodash.rest = rest;
  5034. lodash.shuffle = shuffle;
  5035. lodash.sortBy = sortBy;
  5036. lodash.tap = tap;
  5037. lodash.throttle = throttle;
  5038. lodash.times = times;
  5039. lodash.toArray = toArray;
  5040. lodash.transform = transform;
  5041. lodash.union = union;
  5042. lodash.uniq = uniq;
  5043. lodash.unzip = unzip;
  5044. lodash.values = values;
  5045. lodash.where = where;
  5046. lodash.without = without;
  5047. lodash.wrap = wrap;
  5048. lodash.zip = zip;
  5049. lodash.zipObject = zipObject;
  5050. // add aliases
  5051. lodash.collect = map;
  5052. lodash.drop = rest;
  5053. lodash.each = forEach;
  5054. lodash.extend = assign;
  5055. lodash.methods = functions;
  5056. lodash.object = zipObject;
  5057. lodash.select = filter;
  5058. lodash.tail = rest;
  5059. lodash.unique = uniq;
  5060. // add functions to `lodash.prototype`
  5061. mixin(lodash);
  5062. // add Underscore compat
  5063. lodash.chain = lodash;
  5064. lodash.prototype.chain = function() { return this; };
  5065. /*--------------------------------------------------------------------------*/
  5066. // add functions that return unwrapped values when chaining
  5067. lodash.clone = clone;
  5068. lodash.cloneDeep = cloneDeep;
  5069. lodash.contains = contains;
  5070. lodash.escape = escape;
  5071. lodash.every = every;
  5072. lodash.find = find;
  5073. lodash.findIndex = findIndex;
  5074. lodash.findKey = findKey;
  5075. lodash.has = has;
  5076. lodash.identity = identity;
  5077. lodash.indexOf = indexOf;
  5078. lodash.isArguments = isArguments;
  5079. lodash.isArray = isArray;
  5080. lodash.isBoolean = isBoolean;
  5081. lodash.isDate = isDate;
  5082. lodash.isElement = isElement;
  5083. lodash.isEmpty = isEmpty;
  5084. lodash.isEqual = isEqual;
  5085. lodash.isFinite = isFinite;
  5086. lodash.isFunction = isFunction;
  5087. lodash.isNaN = isNaN;
  5088. lodash.isNull = isNull;
  5089. lodash.isNumber = isNumber;
  5090. lodash.isObject = isObject;
  5091. lodash.isPlainObject = isPlainObject;
  5092. lodash.isRegExp = isRegExp;
  5093. lodash.isString = isString;
  5094. lodash.isUndefined = isUndefined;
  5095. lodash.lastIndexOf = lastIndexOf;
  5096. lodash.mixin = mixin;
  5097. lodash.noConflict = noConflict;
  5098. lodash.parseInt = parseInt;
  5099. lodash.random = random;
  5100. lodash.reduce = reduce;
  5101. lodash.reduceRight = reduceRight;
  5102. lodash.result = result;
  5103. lodash.runInContext = runInContext;
  5104. lodash.size = size;
  5105. lodash.some = some;
  5106. lodash.sortedIndex = sortedIndex;
  5107. lodash.template = template;
  5108. lodash.unescape = unescape;
  5109. lodash.uniqueId = uniqueId;
  5110. // add aliases
  5111. lodash.all = every;
  5112. lodash.any = some;
  5113. lodash.detect = find;
  5114. lodash.findWhere = find;
  5115. lodash.foldl = reduce;
  5116. lodash.foldr = reduceRight;
  5117. lodash.include = contains;
  5118. lodash.inject = reduce;
  5119. forOwn(lodash, function(func, methodName) {
  5120. if (!lodash.prototype[methodName]) {
  5121. lodash.prototype[methodName] = function() {
  5122. var args = [this.__wrapped__];
  5123. push.apply(args, arguments);
  5124. return func.apply(lodash, args);
  5125. };
  5126. }
  5127. });
  5128. /*--------------------------------------------------------------------------*/
  5129. // add functions capable of returning wrapped and unwrapped values when chaining
  5130. lodash.first = first;
  5131. lodash.last = last;
  5132. // add aliases
  5133. lodash.take = first;
  5134. lodash.head = first;
  5135. forOwn(lodash, function(func, methodName) {
  5136. if (!lodash.prototype[methodName]) {
  5137. lodash.prototype[methodName]= function(callback, thisArg) {
  5138. var result = func(this.__wrapped__, callback, thisArg);
  5139. return callback == null || (thisArg && typeof callback != 'function')
  5140. ? result
  5141. : new lodashWrapper(result);
  5142. };
  5143. }
  5144. });
  5145. /*--------------------------------------------------------------------------*/
  5146. /**
  5147. * The semantic version number.
  5148. *
  5149. * @static
  5150. * @memberOf _
  5151. * @type String
  5152. */
  5153. lodash.VERSION = '1.3.1';
  5154. // add "Chaining" functions to the wrapper
  5155. lodash.prototype.toString = wrapperToString;
  5156. lodash.prototype.value = wrapperValueOf;
  5157. lodash.prototype.valueOf = wrapperValueOf;
  5158. // add `Array` functions that return unwrapped values
  5159. forEach(['join', 'pop', 'shift'], function(methodName) {
  5160. var func = arrayRef[methodName];
  5161. lodash.prototype[methodName] = function() {
  5162. return func.apply(this.__wrapped__, arguments);
  5163. };
  5164. });
  5165. // add `Array` functions that return the wrapped value
  5166. forEach(['push', 'reverse', 'sort', 'unshift'], function(methodName) {
  5167. var func = arrayRef[methodName];
  5168. lodash.prototype[methodName] = function() {
  5169. func.apply(this.__wrapped__, arguments);
  5170. return this;
  5171. };
  5172. });
  5173. // add `Array` functions that return new wrapped values
  5174. forEach(['concat', 'slice', 'splice'], function(methodName) {
  5175. var func = arrayRef[methodName];
  5176. lodash.prototype[methodName] = function() {
  5177. return new lodashWrapper(func.apply(this.__wrapped__, arguments));
  5178. };
  5179. });
  5180. return lodash;
  5181. }
  5182. /*--------------------------------------------------------------------------*/
  5183. // expose Lo-Dash
  5184. var _ = runInContext();
  5185. // some AMD build optimizers, like r.js, check for specific condition patterns like the following:
  5186. if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
  5187. // Expose Lo-Dash to the global object even when an AMD loader is present in
  5188. // case Lo-Dash was injected by a third-party script and not intended to be
  5189. // loaded as a module. The global assignment can be reverted in the Lo-Dash
  5190. // module via its `noConflict()` method.
  5191. window._ = _;
  5192. // define as an anonymous module so, through path mapping, it can be
  5193. // referenced as the "underscore" module
  5194. define(function() {
  5195. return _;
  5196. });
  5197. }
  5198. // check for `exports` after `define` in case a build optimizer adds an `exports` object
  5199. else if (freeExports && !freeExports.nodeType) {
  5200. // in Node.js or RingoJS v0.8.0+
  5201. if (freeModule) {
  5202. (freeModule.exports = _)._ = _;
  5203. }
  5204. // in Narwhal or RingoJS v0.7.0-
  5205. else {
  5206. freeExports._ = _;
  5207. }
  5208. }
  5209. else {
  5210. // in a browser or Rhino
  5211. window._ = _;
  5212. }
  5213. }(this));