| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557 | /** * @license * lodash 3.10.1 (Custom Build) <https://lodash.com/> * Build: `lodash compat -o ./lodash.js` * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/> * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE> * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors * Available under MIT license <https://lodash.com/license> */;(function() {  /** Used as a safe reference for `undefined` in pre-ES5 environments. */  var undefined;  /** Used as the semantic version number. */  var VERSION = '3.10.1';  /** Used to compose bitmasks for wrapper metadata. */  var BIND_FLAG = 1,      BIND_KEY_FLAG = 2,      CURRY_BOUND_FLAG = 4,      CURRY_FLAG = 8,      CURRY_RIGHT_FLAG = 16,      PARTIAL_FLAG = 32,      PARTIAL_RIGHT_FLAG = 64,      ARY_FLAG = 128,      REARG_FLAG = 256;  /** Used as default options for `_.trunc`. */  var DEFAULT_TRUNC_LENGTH = 30,      DEFAULT_TRUNC_OMISSION = '...';  /** Used to detect when a function becomes hot. */  var HOT_COUNT = 150,      HOT_SPAN = 16;  /** Used as the size to enable large array optimizations. */  var LARGE_ARRAY_SIZE = 200;  /** Used to indicate the type of lazy iteratees. */  var LAZY_FILTER_FLAG = 1,      LAZY_MAP_FLAG = 2;  /** Used as the `TypeError` message for "Functions" methods. */  var FUNC_ERROR_TEXT = 'Expected a function';  /** Used as the internal argument placeholder. */  var PLACEHOLDER = '__lodash_placeholder__';  /** `Object#toString` result references. */  var argsTag = '[object Arguments]',      arrayTag = '[object Array]',      boolTag = '[object Boolean]',      dateTag = '[object Date]',      errorTag = '[object Error]',      funcTag = '[object Function]',      mapTag = '[object Map]',      numberTag = '[object Number]',      objectTag = '[object Object]',      regexpTag = '[object RegExp]',      setTag = '[object Set]',      stringTag = '[object String]',      weakMapTag = '[object WeakMap]';  var arrayBufferTag = '[object ArrayBuffer]',      float32Tag = '[object Float32Array]',      float64Tag = '[object Float64Array]',      int8Tag = '[object Int8Array]',      int16Tag = '[object Int16Array]',      int32Tag = '[object Int32Array]',      uint8Tag = '[object Uint8Array]',      uint8ClampedTag = '[object Uint8ClampedArray]',      uint16Tag = '[object Uint16Array]',      uint32Tag = '[object Uint32Array]';  /** Used to match empty string literals in compiled template source. */  var reEmptyStringLeading = /\b__p \+= '';/g,      reEmptyStringMiddle = /\b(__p \+=) '' \+/g,      reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;  /** Used to match HTML entities and HTML characters. */  var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g,      reUnescapedHtml = /[&<>"'`]/g,      reHasEscapedHtml = RegExp(reEscapedHtml.source),      reHasUnescapedHtml = RegExp(reUnescapedHtml.source);  /** Used to match template delimiters. */  var reEscape = /<%-([\s\S]+?)%>/g,      reEvaluate = /<%([\s\S]+?)%>/g,      reInterpolate = /<%=([\s\S]+?)%>/g;  /** Used to match property names within property paths. */  var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,      reIsPlainProp = /^\w*$/,      rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g;  /**   * Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns)   * and those outlined by [`EscapeRegExpPattern`](http://ecma-international.org/ecma-262/6.0/#sec-escaperegexppattern).   */  var reRegExpChars = /^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g,      reHasRegExpChars = RegExp(reRegExpChars.source);  /** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */  var reComboMark = /[\u0300-\u036f\ufe20-\ufe23]/g;  /** Used to match backslashes in property paths. */  var reEscapeChar = /\\(\\)?/g;  /** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */  var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;  /** Used to match `RegExp` flags from their coerced string values. */  var reFlags = /\w*$/;  /** Used to detect hexadecimal string values. */  var reHasHexPrefix = /^0[xX]/;  /** Used to detect host constructors (Safari > 5). */  var reIsHostCtor = /^\[object .+?Constructor\]$/;  /** Used to detect unsigned integer values. */  var reIsUint = /^\d+$/;  /** Used to match latin-1 supplementary letters (excluding mathematical operators). */  var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g;  /** Used to ensure capturing order of template delimiters. */  var reNoMatch = /($^)/;  /** Used to match unescaped characters in compiled string literals. */  var reUnescapedString = /['\n\r\u2028\u2029\\]/g;  /** Used to match words to create compound words. */  var reWords = (function() {    var upper = '[A-Z\\xc0-\\xd6\\xd8-\\xde]',        lower = '[a-z\\xdf-\\xf6\\xf8-\\xff]+';    return RegExp(upper + '+(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g');  }());  /** Used to assign default `context` object properties. */  var contextProps = [    'Array', 'ArrayBuffer', 'Date', 'Error', 'Float32Array', 'Float64Array',    'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number',    'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'isFinite',    'parseFloat', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array',    'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap'  ];  /** Used to fix the JScript `[[DontEnum]]` bug. */  var shadowProps = [    'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',    'toLocaleString', 'toString', 'valueOf'  ];  /** Used to make template sourceURLs easier to identify. */  var templateCounter = -1;  /** Used to identify `toStringTag` values of typed arrays. */  var typedArrayTags = {};  typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =  typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =  typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =  typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =  typedArrayTags[uint32Tag] = true;  typedArrayTags[argsTag] = typedArrayTags[arrayTag] =  typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =  typedArrayTags[dateTag] = typedArrayTags[errorTag] =  typedArrayTags[funcTag] = typedArrayTags[mapTag] =  typedArrayTags[numberTag] = typedArrayTags[objectTag] =  typedArrayTags[regexpTag] = typedArrayTags[setTag] =  typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;  /** Used to identify `toStringTag` values supported by `_.clone`. */  var cloneableTags = {};  cloneableTags[argsTag] = cloneableTags[arrayTag] =  cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =  cloneableTags[dateTag] = cloneableTags[float32Tag] =  cloneableTags[float64Tag] = cloneableTags[int8Tag] =  cloneableTags[int16Tag] = cloneableTags[int32Tag] =  cloneableTags[numberTag] = cloneableTags[objectTag] =  cloneableTags[regexpTag] = cloneableTags[stringTag] =  cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =  cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;  cloneableTags[errorTag] = cloneableTags[funcTag] =  cloneableTags[mapTag] = cloneableTags[setTag] =  cloneableTags[weakMapTag] = false;  /** Used to map latin-1 supplementary letters to basic latin letters. */  var deburredLetters = {    '\xc0': 'A',  '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',    '\xe0': 'a',  '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',    '\xc7': 'C',  '\xe7': 'c',    '\xd0': 'D',  '\xf0': 'd',    '\xc8': 'E',  '\xc9': 'E', '\xca': 'E', '\xcb': 'E',    '\xe8': 'e',  '\xe9': 'e', '\xea': 'e', '\xeb': 'e',    '\xcC': 'I',  '\xcd': 'I', '\xce': 'I', '\xcf': 'I',    '\xeC': 'i',  '\xed': 'i', '\xee': 'i', '\xef': 'i',    '\xd1': 'N',  '\xf1': 'n',    '\xd2': 'O',  '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',    '\xf2': 'o',  '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',    '\xd9': 'U',  '\xda': 'U', '\xdb': 'U', '\xdc': 'U',    '\xf9': 'u',  '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',    '\xdd': 'Y',  '\xfd': 'y', '\xff': 'y',    '\xc6': 'Ae', '\xe6': 'ae',    '\xde': 'Th', '\xfe': 'th',    '\xdf': 'ss'  };  /** Used to map characters to HTML entities. */  var htmlEscapes = {    '&': '&',    '<': '<',    '>': '>',    '"': '"',    "'": ''',    '`': '`'  };  /** Used to map HTML entities to characters. */  var htmlUnescapes = {    '&': '&',    '<': '<',    '>': '>',    '"': '"',    ''': "'",    '`': '`'  };  /** Used to determine if values are of the language type `Object`. */  var objectTypes = {    'function': true,    'object': true  };  /** Used to escape characters for inclusion in compiled regexes. */  var regexpEscapes = {    '0': 'x30', '1': 'x31', '2': 'x32', '3': 'x33', '4': 'x34',    '5': 'x35', '6': 'x36', '7': 'x37', '8': 'x38', '9': 'x39',    'A': 'x41', 'B': 'x42', 'C': 'x43', 'D': 'x44', 'E': 'x45', 'F': 'x46',    'a': 'x61', 'b': 'x62', 'c': 'x63', 'd': 'x64', 'e': 'x65', 'f': 'x66',    'n': 'x6e', 'r': 'x72', 't': 'x74', 'u': 'x75', 'v': 'x76', 'x': 'x78'  };  /** Used to escape characters for inclusion in compiled string literals. */  var stringEscapes = {    '\\': '\\',    "'": "'",    '\n': 'n',    '\r': 'r',    '\u2028': 'u2028',    '\u2029': 'u2029'  };  /** Detect free variable `exports`. */  var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;  /** Detect free variable `module`. */  var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;  /** Detect free variable `global` from Node.js. */  var freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global;  /** Detect free variable `self`. */  var freeSelf = objectTypes[typeof self] && self && self.Object && self;  /** Detect free variable `window`. */  var freeWindow = objectTypes[typeof window] && window && window.Object && window;  /** Detect the popular CommonJS extension `module.exports`. */  var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;  /**   * Used as a reference to the global object.   *   * The `this` value is used if it's the global object to avoid Greasemonkey's   * restricted `window` object, otherwise the `window` object is used.   */  var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this;  /*--------------------------------------------------------------------------*/  /**   * The base implementation of `compareAscending` which compares values and   * sorts them in ascending order without guaranteeing a stable sort.   *   * @private   * @param {*} value The value to compare.   * @param {*} other The other value to compare.   * @returns {number} Returns the sort order indicator for `value`.   */  function baseCompareAscending(value, other) {    if (value !== other) {      var valIsNull = value === null,          valIsUndef = value === undefined,          valIsReflexive = value === value;      var othIsNull = other === null,          othIsUndef = other === undefined,          othIsReflexive = other === other;      if ((value > other && !othIsNull) || !valIsReflexive ||          (valIsNull && !othIsUndef && othIsReflexive) ||          (valIsUndef && othIsReflexive)) {        return 1;      }      if ((value < other && !valIsNull) || !othIsReflexive ||          (othIsNull && !valIsUndef && valIsReflexive) ||          (othIsUndef && valIsReflexive)) {        return -1;      }    }    return 0;  }  /**   * The base implementation of `_.findIndex` and `_.findLastIndex` without   * support for callback shorthands and `this` binding.   *   * @private   * @param {Array} array The array to search.   * @param {Function} predicate The function invoked per iteration.   * @param {boolean} [fromRight] Specify iterating from right to left.   * @returns {number} Returns the index of the matched value, else `-1`.   */  function baseFindIndex(array, predicate, fromRight) {    var length = array.length,        index = fromRight ? length : -1;    while ((fromRight ? index-- : ++index < length)) {      if (predicate(array[index], index, array)) {        return index;      }    }    return -1;  }  /**   * The base implementation of `_.indexOf` without support for binary searches.   *   * @private   * @param {Array} array The array to search.   * @param {*} value The value to search for.   * @param {number} fromIndex The index to search from.   * @returns {number} Returns the index of the matched value, else `-1`.   */  function baseIndexOf(array, value, fromIndex) {    if (value !== value) {      return indexOfNaN(array, fromIndex);    }    var index = fromIndex - 1,        length = array.length;    while (++index < length) {      if (array[index] === value) {        return index;      }    }    return -1;  }  /**   * The base implementation of `_.isFunction` without support for environments   * with incorrect `typeof` results.   *   * @private   * @param {*} value The value to check.   * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.   */  function baseIsFunction(value) {    // Avoid a Chakra JIT bug in compatibility modes of IE 11.    // See https://github.com/jashkenas/underscore/issues/1621 for more details.    return typeof value == 'function' || false;  }  /**   * Converts `value` to a string if it's not one. An empty string is returned   * for `null` or `undefined` values.   *   * @private   * @param {*} value The value to process.   * @returns {string} Returns the string.   */  function baseToString(value) {    return value == null ? '' : (value + '');  }  /**   * Used by `_.trim` and `_.trimLeft` to get the index of the first character   * of `string` that is not found in `chars`.   *   * @private   * @param {string} string The string to inspect.   * @param {string} chars The characters to find.   * @returns {number} Returns the index of the first character not found in `chars`.   */  function charsLeftIndex(string, chars) {    var index = -1,        length = string.length;    while (++index < length && chars.indexOf(string.charAt(index)) > -1) {}    return index;  }  /**   * Used by `_.trim` and `_.trimRight` to get the index of the last character   * of `string` that is not found in `chars`.   *   * @private   * @param {string} string The string to inspect.   * @param {string} chars The characters to find.   * @returns {number} Returns the index of the last character not found in `chars`.   */  function charsRightIndex(string, chars) {    var index = string.length;    while (index-- && chars.indexOf(string.charAt(index)) > -1) {}    return index;  }  /**   * Used by `_.sortBy` to compare transformed elements of a collection and stable   * sort them in ascending order.   *   * @private   * @param {Object} object The object to compare.   * @param {Object} other The other object to compare.   * @returns {number} Returns the sort order indicator for `object`.   */  function compareAscending(object, other) {    return baseCompareAscending(object.criteria, other.criteria) || (object.index - other.index);  }  /**   * Used by `_.sortByOrder` to compare multiple properties of a value to another   * and stable sort them.   *   * If `orders` is unspecified, all valuess are sorted in ascending order. Otherwise,   * a value is sorted in ascending order if its corresponding order is "asc", and   * descending if "desc".   *   * @private   * @param {Object} object The object to compare.   * @param {Object} other The other object to compare.   * @param {boolean[]} orders The order to sort by for each property.   * @returns {number} Returns the sort order indicator for `object`.   */  function compareMultiple(object, other, orders) {    var index = -1,        objCriteria = object.criteria,        othCriteria = other.criteria,        length = objCriteria.length,        ordersLength = orders.length;    while (++index < length) {      var result = baseCompareAscending(objCriteria[index], othCriteria[index]);      if (result) {        if (index >= ordersLength) {          return result;        }        var order = orders[index];        return result * ((order === 'asc' || order === true) ? 1 : -1);      }    }    // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications    // that causes it, under certain circumstances, to provide the same value for    // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247    // for more details.    //    // This also ensures a stable sort in V8 and other engines.    // See https://code.google.com/p/v8/issues/detail?id=90 for more details.    return object.index - other.index;  }  /**   * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters.   *   * @private   * @param {string} letter The matched letter to deburr.   * @returns {string} Returns the deburred letter.   */  function deburrLetter(letter) {    return deburredLetters[letter];  }  /**   * Used by `_.escape` to convert characters to HTML entities.   *   * @private   * @param {string} chr The matched character to escape.   * @returns {string} Returns the escaped character.   */  function escapeHtmlChar(chr) {    return htmlEscapes[chr];  }  /**   * Used by `_.escapeRegExp` to escape characters for inclusion in compiled regexes.   *   * @private   * @param {string} chr The matched character to escape.   * @param {string} leadingChar The capture group for a leading character.   * @param {string} whitespaceChar The capture group for a whitespace character.   * @returns {string} Returns the escaped character.   */  function escapeRegExpChar(chr, leadingChar, whitespaceChar) {    if (leadingChar) {      chr = regexpEscapes[chr];    } else if (whitespaceChar) {      chr = stringEscapes[chr];    }    return '\\' + chr;  }  /**   * Used by `_.template` to escape characters for inclusion in compiled string literals.   *   * @private   * @param {string} chr The matched character to escape.   * @returns {string} Returns the escaped character.   */  function escapeStringChar(chr) {    return '\\' + stringEscapes[chr];  }  /**   * Gets the index at which the first occurrence of `NaN` is found in `array`.   *   * @private   * @param {Array} array The array to search.   * @param {number} fromIndex The index to search from.   * @param {boolean} [fromRight] Specify iterating from right to left.   * @returns {number} Returns the index of the matched `NaN`, else `-1`.   */  function indexOfNaN(array, fromIndex, fromRight) {    var length = array.length,        index = fromIndex + (fromRight ? 0 : -1);    while ((fromRight ? index-- : ++index < length)) {      var other = array[index];      if (other !== other) {        return index;      }    }    return -1;  }  /**   * Checks if `value` is a host object in IE < 9.   *   * @private   * @param {*} value The value to check.   * @returns {boolean} Returns `true` if `value` is a host object, else `false`.   */  var isHostObject = (function() {    try {      Object({ 'toString': 0 } + '');    } catch(e) {      return function() { return false; };    }    return function(value) {      // IE < 9 presents many host objects as `Object` objects that can coerce      // to strings despite having improperly defined `toString` methods.      return typeof value.toString != 'function' && typeof (value + '') == 'string';    };  }());  /**   * Checks if `value` is object-like.   *   * @private   * @param {*} value The value to check.   * @returns {boolean} Returns `true` if `value` is object-like, else `false`.   */  function isObjectLike(value) {    return !!value && typeof value == 'object';  }  /**   * Used by `trimmedLeftIndex` and `trimmedRightIndex` to determine if a   * character code is whitespace.   *   * @private   * @param {number} charCode The character code to inspect.   * @returns {boolean} Returns `true` if `charCode` is whitespace, else `false`.   */  function isSpace(charCode) {    return ((charCode <= 160 && (charCode >= 9 && charCode <= 13) || charCode == 32 || charCode == 160) || charCode == 5760 || charCode == 6158 ||      (charCode >= 8192 && (charCode <= 8202 || charCode == 8232 || charCode == 8233 || charCode == 8239 || charCode == 8287 || charCode == 12288 || charCode == 65279)));  }  /**   * Replaces all `placeholder` elements in `array` with an internal placeholder   * and returns an array of their indexes.   *   * @private   * @param {Array} array The array to modify.   * @param {*} placeholder The placeholder to replace.   * @returns {Array} Returns the new array of placeholder indexes.   */  function replaceHolders(array, placeholder) {    var index = -1,        length = array.length,        resIndex = -1,        result = [];    while (++index < length) {      if (array[index] === placeholder) {        array[index] = PLACEHOLDER;        result[++resIndex] = index;      }    }    return result;  }  /**   * An implementation of `_.uniq` optimized for sorted arrays without support   * for callback shorthands and `this` binding.   *   * @private   * @param {Array} array The array to inspect.   * @param {Function} [iteratee] The function invoked per iteration.   * @returns {Array} Returns the new duplicate free array.   */  function sortedUniq(array, iteratee) {    var seen,        index = -1,        length = array.length,        resIndex = -1,        result = [];    while (++index < length) {      var value = array[index],          computed = iteratee ? iteratee(value, index, array) : value;      if (!index || seen !== computed) {        seen = computed;        result[++resIndex] = value;      }    }    return result;  }  /**   * Used by `_.trim` and `_.trimLeft` to get the index of the first non-whitespace   * character of `string`.   *   * @private   * @param {string} string The string to inspect.   * @returns {number} Returns the index of the first non-whitespace character.   */  function trimmedLeftIndex(string) {    var index = -1,        length = string.length;    while (++index < length && isSpace(string.charCodeAt(index))) {}    return index;  }  /**   * Used by `_.trim` and `_.trimRight` to get the index of the last non-whitespace   * character of `string`.   *   * @private   * @param {string} string The string to inspect.   * @returns {number} Returns the index of the last non-whitespace character.   */  function trimmedRightIndex(string) {    var index = string.length;    while (index-- && isSpace(string.charCodeAt(index))) {}    return index;  }  /**   * Used by `_.unescape` to convert HTML entities to characters.   *   * @private   * @param {string} chr The matched character to unescape.   * @returns {string} Returns the unescaped character.   */  function unescapeHtmlChar(chr) {    return htmlUnescapes[chr];  }  /*--------------------------------------------------------------------------*/  /**   * Create a new pristine `lodash` function using the given `context` object.   *   * @static   * @memberOf _   * @category Utility   * @param {Object} [context=root] The context object.   * @returns {Function} Returns a new `lodash` function.   * @example   *   * _.mixin({ 'foo': _.constant('foo') });   *   * var lodash = _.runInContext();   * lodash.mixin({ 'bar': lodash.constant('bar') });   *   * _.isFunction(_.foo);   * // => true   * _.isFunction(_.bar);   * // => false   *   * lodash.isFunction(lodash.foo);   * // => false   * lodash.isFunction(lodash.bar);   * // => true   *   * // using `context` to mock `Date#getTime` use in `_.now`   * var mock = _.runInContext({   *   'Date': function() {   *     return { 'getTime': getTimeMock };   *   }   * });   *   * // or creating a suped-up `defer` in Node.js   * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;   */  function runInContext(context) {    // Avoid issues with some ES3 environments that attempt to use values, named    // after built-in constructors like `Object`, for the creation of literals.    // ES5 clears this up by stating that literals must use built-in constructors.    // See https://es5.github.io/#x11.1.5 for more details.    context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root;    /** Native constructor references. */    var Array = context.Array,        Date = context.Date,        Error = context.Error,        Function = context.Function,        Math = context.Math,        Number = context.Number,        Object = context.Object,        RegExp = context.RegExp,        String = context.String,        TypeError = context.TypeError;    /** Used for native method references. */    var arrayProto = Array.prototype,        errorProto = Error.prototype,        objectProto = Object.prototype,        stringProto = String.prototype;    /** Used to resolve the decompiled source of functions. */    var fnToString = Function.prototype.toString;    /** Used to check objects for own properties. */    var hasOwnProperty = objectProto.hasOwnProperty;    /** Used to generate unique IDs. */    var idCounter = 0;    /**     * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)     * of values.     */    var objToString = objectProto.toString;    /** Used to restore the original `_` reference in `_.noConflict`. */    var oldDash = root._;    /** Used to detect if a method is native. */    var reIsNative = RegExp('^' +      fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')      .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'    );    /** Native method references. */    var ArrayBuffer = context.ArrayBuffer,        clearTimeout = context.clearTimeout,        parseFloat = context.parseFloat,        pow = Math.pow,        propertyIsEnumerable = objectProto.propertyIsEnumerable,        Set = getNative(context, 'Set'),        setTimeout = context.setTimeout,        splice = arrayProto.splice,        Uint8Array = context.Uint8Array,        WeakMap = getNative(context, 'WeakMap');    /* Native method references for those with the same name as other `lodash` methods. */    var nativeCeil = Math.ceil,        nativeCreate = getNative(Object, 'create'),        nativeFloor = Math.floor,        nativeIsArray = getNative(Array, 'isArray'),        nativeIsFinite = context.isFinite,        nativeKeys = getNative(Object, 'keys'),        nativeMax = Math.max,        nativeMin = Math.min,        nativeNow = getNative(Date, 'now'),        nativeParseInt = context.parseInt,        nativeRandom = Math.random;    /** Used as references for `-Infinity` and `Infinity`. */    var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY,        POSITIVE_INFINITY = Number.POSITIVE_INFINITY;    /** Used as references for the maximum length and index of an array. */    var MAX_ARRAY_LENGTH = 4294967295,        MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,        HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;    /**     * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)     * of an array-like value.     */    var MAX_SAFE_INTEGER = 9007199254740991;    /** Used to store function metadata. */    var metaMap = WeakMap && new WeakMap;    /** Used to lookup unminified function names. */    var realNames = {};    /** Used to lookup a type array constructors by `toStringTag`. */    var ctorByTag = {};    ctorByTag[float32Tag] = context.Float32Array;    ctorByTag[float64Tag] = context.Float64Array;    ctorByTag[int8Tag] = context.Int8Array;    ctorByTag[int16Tag] = context.Int16Array;    ctorByTag[int32Tag] = context.Int32Array;    ctorByTag[uint8Tag] = Uint8Array;    ctorByTag[uint8ClampedTag] = context.Uint8ClampedArray;    ctorByTag[uint16Tag] = context.Uint16Array;    ctorByTag[uint32Tag] = context.Uint32Array;    /** Used to avoid iterating over non-enumerable properties in IE < 9. */    var nonEnumProps = {};    nonEnumProps[arrayTag] = nonEnumProps[dateTag] = nonEnumProps[numberTag] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true };    nonEnumProps[boolTag] = nonEnumProps[stringTag] = { 'constructor': true, 'toString': true, 'valueOf': true };    nonEnumProps[errorTag] = nonEnumProps[funcTag] = nonEnumProps[regexpTag] = { 'constructor': true, 'toString': true };    nonEnumProps[objectTag] = { 'constructor': true };    arrayEach(shadowProps, function(key) {      for (var tag in nonEnumProps) {        if (hasOwnProperty.call(nonEnumProps, tag)) {          var props = nonEnumProps[tag];          props[key] = hasOwnProperty.call(props, key);        }      }    });    /*------------------------------------------------------------------------*/    /**     * Creates a `lodash` object which wraps `value` to enable implicit chaining.     * Methods that operate on and return arrays, collections, and functions can     * be chained together. Methods that retrieve a single value or may return a     * primitive value will automatically end the chain returning the unwrapped     * value. Explicit chaining may be enabled using `_.chain`. The execution of     * chained methods is lazy, that is, execution is deferred until `_#value`     * is implicitly or explicitly called.     *     * Lazy evaluation allows several methods to support shortcut fusion. Shortcut     * fusion is an optimization strategy which merge iteratee calls; this can help     * to avoid the creation of intermediate data structures and greatly reduce the     * number of iteratee executions.     *     * Chaining is supported in custom builds as long as the `_#value` method is     * directly or indirectly included in the build.     *     * In addition to lodash methods, wrappers have `Array` and `String` methods.     *     * The wrapper `Array` methods are:     * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`,     * `splice`, and `unshift`     *     * The wrapper `String` methods are:     * `replace` and `split`     *     * The wrapper methods that support shortcut fusion are:     * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`,     * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`,     * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`,     * and `where`     *     * The chainable wrapper methods are:     * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`,     * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`,     * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`,     * `defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`,     * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`,     * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,     * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,     * `invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`,     * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`,     * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`,     * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`,     * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`,     * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`,     * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`,     * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`,     * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`,     * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith`     *     * The wrapper methods that are **not** chainable by default are:     * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`,     * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`,     * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`,     * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`,     * `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,     * `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`,     * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`,     * `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`,     * `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`,     * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`,     * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`,     * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`,     * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`,     * `unescape`, `uniqueId`, `value`, and `words`     *     * The wrapper method `sample` will return a wrapped value when `n` is provided,     * otherwise an unwrapped value is returned.     *     * @name _     * @constructor     * @category Chain     * @param {*} value The value to wrap in a `lodash` instance.     * @returns {Object} Returns the new `lodash` wrapper instance.     * @example     *     * var wrapped = _([1, 2, 3]);     *     * // returns an unwrapped value     * wrapped.reduce(function(total, n) {     *   return total + n;     * });     * // => 6     *     * // returns a wrapped value     * var squares = wrapped.map(function(n) {     *   return n * n;     * });     *     * _.isArray(squares);     * // => false     *     * _.isArray(squares.value());     * // => true     */    function lodash(value) {      if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {        if (value instanceof LodashWrapper) {          return value;        }        if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) {          return wrapperClone(value);        }      }      return new LodashWrapper(value);    }    /**     * The function whose prototype all chaining wrappers inherit from.     *     * @private     */    function baseLodash() {      // No operation performed.    }    /**     * The base constructor for creating `lodash` wrapper objects.     *     * @private     * @param {*} value The value to wrap.     * @param {boolean} [chainAll] Enable chaining for all wrapper methods.     * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value.     */    function LodashWrapper(value, chainAll, actions) {      this.__wrapped__ = value;      this.__actions__ = actions || [];      this.__chain__ = !!chainAll;    }    /**     * An object environment feature flags.     *     * @static     * @memberOf _     * @type Object     */    var support = lodash.support = {};    (function(x) {      var Ctor = function() { this.x = x; },          object = { '0': x, 'length': x },          props = [];      Ctor.prototype = { 'valueOf': x, 'y': x };      for (var key in new Ctor) { props.push(key); }      /**       * Detect if `name` or `message` properties of `Error.prototype` are       * enumerable by default (IE < 9, Safari < 5.1).       *       * @memberOf _.support       * @type boolean       */      support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') ||        propertyIsEnumerable.call(errorProto, 'name');      /**       * Detect if `prototype` properties are enumerable by default.       *       * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1       * (if the prototype or a property on the prototype has been set)       * incorrectly set the `[[Enumerable]]` value of a function's `prototype`       * property to `true`.       *       * @memberOf _.support       * @type boolean       */      support.enumPrototypes = propertyIsEnumerable.call(Ctor, 'prototype');      /**       * Detect if properties shadowing those on `Object.prototype` are non-enumerable.       *       * In IE < 9 an object's own properties, shadowing non-enumerable ones,       * are made non-enumerable as well (a.k.a the JScript `[[DontEnum]]` bug).       *       * @memberOf _.support       * @type boolean       */      support.nonEnumShadows = !/valueOf/.test(props);      /**       * Detect if own properties are iterated after inherited properties (IE < 9).       *       * @memberOf _.support       * @type boolean       */      support.ownLast = props[0] != 'x';      /**       * Detect if `Array#shift` and `Array#splice` augment array-like objects       * correctly.       *       * Firefox < 10, compatibility modes of IE 8, and IE < 9 have buggy Array       * `shift()` and `splice()` functions that fail to remove the last element,       * `value[0]`, of array-like objects even though the "length" property is       * set to `0`. The `shift()` method is buggy in compatibility modes of IE 8,       * while `splice()` is buggy regardless of mode in IE < 9.       *       * @memberOf _.support       * @type boolean       */      support.spliceObjects = (splice.call(object, 0, 1), !object[0]);      /**       * Detect lack of support for accessing string characters by index.       *       * IE < 8 can't access characters by index. IE 8 can only access characters       * by index on string literals, not string objects.       *       * @memberOf _.support       * @type boolean       */      support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx';    }(1, 0));    /**     * By default, the template delimiters used by lodash are like those in     * embedded Ruby (ERB). Change the following template settings to use     * alternative delimiters.     *     * @static     * @memberOf _     * @type Object     */    lodash.templateSettings = {      /**       * Used to detect `data` property values to be HTML-escaped.       *       * @memberOf _.templateSettings       * @type RegExp       */      'escape': reEscape,      /**       * Used to detect code to be evaluated.       *       * @memberOf _.templateSettings       * @type RegExp       */      'evaluate': reEvaluate,      /**       * Used to detect `data` property values to inject.       *       * @memberOf _.templateSettings       * @type RegExp       */      'interpolate': reInterpolate,      /**       * Used to reference the data object in the template text.       *       * @memberOf _.templateSettings       * @type string       */      'variable': '',      /**       * Used to import variables into the compiled template.       *       * @memberOf _.templateSettings       * @type Object       */      'imports': {        /**         * A reference to the `lodash` function.         *         * @memberOf _.templateSettings.imports         * @type Function         */        '_': lodash      }    };    /*------------------------------------------------------------------------*/    /**     * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.     *     * @private     * @param {*} value The value to wrap.     */    function LazyWrapper(value) {      this.__wrapped__ = value;      this.__actions__ = [];      this.__dir__ = 1;      this.__filtered__ = false;      this.__iteratees__ = [];      this.__takeCount__ = POSITIVE_INFINITY;      this.__views__ = [];    }    /**     * Creates a clone of the lazy wrapper object.     *     * @private     * @name clone     * @memberOf LazyWrapper     * @returns {Object} Returns the cloned `LazyWrapper` object.     */    function lazyClone() {      var result = new LazyWrapper(this.__wrapped__);      result.__actions__ = arrayCopy(this.__actions__);      result.__dir__ = this.__dir__;      result.__filtered__ = this.__filtered__;      result.__iteratees__ = arrayCopy(this.__iteratees__);      result.__takeCount__ = this.__takeCount__;      result.__views__ = arrayCopy(this.__views__);      return result;    }    /**     * Reverses the direction of lazy iteration.     *     * @private     * @name reverse     * @memberOf LazyWrapper     * @returns {Object} Returns the new reversed `LazyWrapper` object.     */    function lazyReverse() {      if (this.__filtered__) {        var result = new LazyWrapper(this);        result.__dir__ = -1;        result.__filtered__ = true;      } else {        result = this.clone();        result.__dir__ *= -1;      }      return result;    }    /**     * Extracts the unwrapped value from its lazy wrapper.     *     * @private     * @name value     * @memberOf LazyWrapper     * @returns {*} Returns the unwrapped value.     */    function lazyValue() {      var array = this.__wrapped__.value(),          dir = this.__dir__,          isArr = isArray(array),          isRight = dir < 0,          arrLength = isArr ? array.length : 0,          view = getView(0, arrLength, this.__views__),          start = view.start,          end = view.end,          length = end - start,          index = isRight ? end : (start - 1),          iteratees = this.__iteratees__,          iterLength = iteratees.length,          resIndex = 0,          takeCount = nativeMin(length, this.__takeCount__);      if (!isArr || arrLength < LARGE_ARRAY_SIZE || (arrLength == length && takeCount == length)) {        return baseWrapperValue(array, this.__actions__);      }      var result = [];      outer:      while (length-- && resIndex < takeCount) {        index += dir;        var iterIndex = -1,            value = array[index];        while (++iterIndex < iterLength) {          var data = iteratees[iterIndex],              iteratee = data.iteratee,              type = data.type,              computed = iteratee(value);          if (type == LAZY_MAP_FLAG) {            value = computed;          } else if (!computed) {            if (type == LAZY_FILTER_FLAG) {              continue outer;            } else {              break outer;            }          }        }        result[resIndex++] = value;      }      return result;    }    /*------------------------------------------------------------------------*/    /**     * Creates a cache object to store key/value pairs.     *     * @private     * @static     * @name Cache     * @memberOf _.memoize     */    function MapCache() {      this.__data__ = {};    }    /**     * Removes `key` and its value from the cache.     *     * @private     * @name delete     * @memberOf _.memoize.Cache     * @param {string} key The key of the value to remove.     * @returns {boolean} Returns `true` if the entry was removed successfully, else `false`.     */    function mapDelete(key) {      return this.has(key) && delete this.__data__[key];    }    /**     * Gets the cached value for `key`.     *     * @private     * @name get     * @memberOf _.memoize.Cache     * @param {string} key The key of the value to get.     * @returns {*} Returns the cached value.     */    function mapGet(key) {      return key == '__proto__' ? undefined : this.__data__[key];    }    /**     * Checks if a cached value for `key` exists.     *     * @private     * @name has     * @memberOf _.memoize.Cache     * @param {string} key The key of the entry to check.     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.     */    function mapHas(key) {      return key != '__proto__' && hasOwnProperty.call(this.__data__, key);    }    /**     * Sets `value` to `key` of the cache.     *     * @private     * @name set     * @memberOf _.memoize.Cache     * @param {string} key The key of the value to cache.     * @param {*} value The value to cache.     * @returns {Object} Returns the cache object.     */    function mapSet(key, value) {      if (key != '__proto__') {        this.__data__[key] = value;      }      return this;    }    /*------------------------------------------------------------------------*/    /**     *     * Creates a cache object to store unique values.     *     * @private     * @param {Array} [values] The values to cache.     */    function SetCache(values) {      var length = values ? values.length : 0;      this.data = { 'hash': nativeCreate(null), 'set': new Set };      while (length--) {        this.push(values[length]);      }    }    /**     * Checks if `value` is in `cache` mimicking the return signature of     * `_.indexOf` by returning `0` if the value is found, else `-1`.     *     * @private     * @param {Object} cache The cache to search.     * @param {*} value The value to search for.     * @returns {number} Returns `0` if `value` is found, else `-1`.     */    function cacheIndexOf(cache, value) {      var data = cache.data,          result = (typeof value == 'string' || isObject(value)) ? data.set.has(value) : data.hash[value];      return result ? 0 : -1;    }    /**     * Adds `value` to the cache.     *     * @private     * @name push     * @memberOf SetCache     * @param {*} value The value to cache.     */    function cachePush(value) {      var data = this.data;      if (typeof value == 'string' || isObject(value)) {        data.set.add(value);      } else {        data.hash[value] = true;      }    }    /*------------------------------------------------------------------------*/    /**     * Creates a new array joining `array` with `other`.     *     * @private     * @param {Array} array The array to join.     * @param {Array} other The other array to join.     * @returns {Array} Returns the new concatenated array.     */    function arrayConcat(array, other) {      var index = -1,          length = array.length,          othIndex = -1,          othLength = other.length,          result = Array(length + othLength);      while (++index < length) {        result[index] = array[index];      }      while (++othIndex < othLength) {        result[index++] = other[othIndex];      }      return result;    }    /**     * Copies the values of `source` to `array`.     *     * @private     * @param {Array} source The array to copy values from.     * @param {Array} [array=[]] The array to copy values to.     * @returns {Array} Returns `array`.     */    function arrayCopy(source, array) {      var index = -1,          length = source.length;      array || (array = Array(length));      while (++index < length) {        array[index] = source[index];      }      return array;    }    /**     * A specialized version of `_.forEach` for arrays without support for callback     * shorthands and `this` binding.     *     * @private     * @param {Array} array The array to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @returns {Array} Returns `array`.     */    function arrayEach(array, iteratee) {      var index = -1,          length = array.length;      while (++index < length) {        if (iteratee(array[index], index, array) === false) {          break;        }      }      return array;    }    /**     * A specialized version of `_.forEachRight` for arrays without support for     * callback shorthands and `this` binding.     *     * @private     * @param {Array} array The array to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @returns {Array} Returns `array`.     */    function arrayEachRight(array, iteratee) {      var length = array.length;      while (length--) {        if (iteratee(array[length], length, array) === false) {          break;        }      }      return array;    }    /**     * A specialized version of `_.every` for arrays without support for callback     * shorthands and `this` binding.     *     * @private     * @param {Array} array The array to iterate over.     * @param {Function} predicate The function invoked per iteration.     * @returns {boolean} Returns `true` if all elements pass the predicate check,     *  else `false`.     */    function arrayEvery(array, predicate) {      var index = -1,          length = array.length;      while (++index < length) {        if (!predicate(array[index], index, array)) {          return false;        }      }      return true;    }    /**     * A specialized version of `baseExtremum` for arrays which invokes `iteratee`     * with one argument: (value).     *     * @private     * @param {Array} array The array to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @param {Function} comparator The function used to compare values.     * @param {*} exValue The initial extremum value.     * @returns {*} Returns the extremum value.     */    function arrayExtremum(array, iteratee, comparator, exValue) {      var index = -1,          length = array.length,          computed = exValue,          result = computed;      while (++index < length) {        var value = array[index],            current = +iteratee(value);        if (comparator(current, computed)) {          computed = current;          result = value;        }      }      return result;    }    /**     * A specialized version of `_.filter` for arrays without support for callback     * shorthands and `this` binding.     *     * @private     * @param {Array} array The array to iterate over.     * @param {Function} predicate The function invoked per iteration.     * @returns {Array} Returns the new filtered array.     */    function arrayFilter(array, predicate) {      var index = -1,          length = array.length,          resIndex = -1,          result = [];      while (++index < length) {        var value = array[index];        if (predicate(value, index, array)) {          result[++resIndex] = value;        }      }      return result;    }    /**     * A specialized version of `_.map` for arrays without support for callback     * shorthands and `this` binding.     *     * @private     * @param {Array} array The array to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @returns {Array} Returns the new mapped array.     */    function arrayMap(array, iteratee) {      var index = -1,          length = array.length,          result = Array(length);      while (++index < length) {        result[index] = iteratee(array[index], index, array);      }      return result;    }    /**     * Appends the elements of `values` to `array`.     *     * @private     * @param {Array} array The array to modify.     * @param {Array} values The values to append.     * @returns {Array} Returns `array`.     */    function arrayPush(array, values) {      var index = -1,          length = values.length,          offset = array.length;      while (++index < length) {        array[offset + index] = values[index];      }      return array;    }    /**     * A specialized version of `_.reduce` for arrays without support for callback     * shorthands and `this` binding.     *     * @private     * @param {Array} array The array to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @param {*} [accumulator] The initial value.     * @param {boolean} [initFromArray] Specify using the first element of `array`     *  as the initial value.     * @returns {*} Returns the accumulated value.     */    function arrayReduce(array, iteratee, accumulator, initFromArray) {      var index = -1,          length = array.length;      if (initFromArray && length) {        accumulator = array[++index];      }      while (++index < length) {        accumulator = iteratee(accumulator, array[index], index, array);      }      return accumulator;    }    /**     * A specialized version of `_.reduceRight` for arrays without support for     * callback shorthands and `this` binding.     *     * @private     * @param {Array} array The array to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @param {*} [accumulator] The initial value.     * @param {boolean} [initFromArray] Specify using the last element of `array`     *  as the initial value.     * @returns {*} Returns the accumulated value.     */    function arrayReduceRight(array, iteratee, accumulator, initFromArray) {      var length = array.length;      if (initFromArray && length) {        accumulator = array[--length];      }      while (length--) {        accumulator = iteratee(accumulator, array[length], length, array);      }      return accumulator;    }    /**     * A specialized version of `_.some` for arrays without support for callback     * shorthands and `this` binding.     *     * @private     * @param {Array} array The array to iterate over.     * @param {Function} predicate The function invoked per iteration.     * @returns {boolean} Returns `true` if any element passes the predicate check,     *  else `false`.     */    function arraySome(array, predicate) {      var index = -1,          length = array.length;      while (++index < length) {        if (predicate(array[index], index, array)) {          return true;        }      }      return false;    }    /**     * A specialized version of `_.sum` for arrays without support for callback     * shorthands and `this` binding..     *     * @private     * @param {Array} array The array to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @returns {number} Returns the sum.     */    function arraySum(array, iteratee) {      var length = array.length,          result = 0;      while (length--) {        result += +iteratee(array[length]) || 0;      }      return result;    }    /**     * Used by `_.defaults` to customize its `_.assign` use.     *     * @private     * @param {*} objectValue The destination object property value.     * @param {*} sourceValue The source object property value.     * @returns {*} Returns the value to assign to the destination object.     */    function assignDefaults(objectValue, sourceValue) {      return objectValue === undefined ? sourceValue : objectValue;    }    /**     * Used by `_.template` to customize its `_.assign` use.     *     * **Note:** This function is like `assignDefaults` except that it ignores     * inherited property values when checking if a property is `undefined`.     *     * @private     * @param {*} objectValue The destination object property value.     * @param {*} sourceValue The source object property value.     * @param {string} key The key associated with the object and source values.     * @param {Object} object The destination object.     * @returns {*} Returns the value to assign to the destination object.     */    function assignOwnDefaults(objectValue, sourceValue, key, object) {      return (objectValue === undefined || !hasOwnProperty.call(object, key))        ? sourceValue        : objectValue;    }    /**     * A specialized version of `_.assign` for customizing assigned values without     * support for argument juggling, multiple sources, and `this` binding `customizer`     * functions.     *     * @private     * @param {Object} object The destination object.     * @param {Object} source The source object.     * @param {Function} customizer The function to customize assigned values.     * @returns {Object} Returns `object`.     */    function assignWith(object, source, customizer) {      var index = -1,          props = keys(source),          length = props.length;      while (++index < length) {        var key = props[index],            value = object[key],            result = customizer(value, source[key], key, object, source);        if ((result === result ? (result !== value) : (value === value)) ||            (value === undefined && !(key in object))) {          object[key] = result;        }      }      return object;    }    /**     * The base implementation of `_.assign` without support for argument juggling,     * multiple sources, and `customizer` functions.     *     * @private     * @param {Object} object The destination object.     * @param {Object} source The source object.     * @returns {Object} Returns `object`.     */    function baseAssign(object, source) {      return source == null        ? object        : baseCopy(source, keys(source), object);    }    /**     * The base implementation of `_.at` without support for string collections     * and individual key arguments.     *     * @private     * @param {Array|Object} collection The collection to iterate over.     * @param {number[]|string[]} props The property names or indexes of elements to pick.     * @returns {Array} Returns the new array of picked elements.     */    function baseAt(collection, props) {      var index = -1,          isNil = collection == null,          isArr = !isNil && isArrayLike(collection),          length = isArr ? collection.length : 0,          propsLength = props.length,          result = Array(propsLength);      while(++index < propsLength) {        var key = props[index];        if (isArr) {          result[index] = isIndex(key, length) ? collection[key] : undefined;        } else {          result[index] = isNil ? undefined : collection[key];        }      }      return result;    }    /**     * Copies properties of `source` to `object`.     *     * @private     * @param {Object} source The object to copy properties from.     * @param {Array} props The property names to copy.     * @param {Object} [object={}] The object to copy properties to.     * @returns {Object} Returns `object`.     */    function baseCopy(source, props, object) {      object || (object = {});      var index = -1,          length = props.length;      while (++index < length) {        var key = props[index];        object[key] = source[key];      }      return object;    }    /**     * The base implementation of `_.callback` which supports specifying the     * number of arguments to provide to `func`.     *     * @private     * @param {*} [func=_.identity] The value to convert to a callback.     * @param {*} [thisArg] The `this` binding of `func`.     * @param {number} [argCount] The number of arguments to provide to `func`.     * @returns {Function} Returns the callback.     */    function baseCallback(func, thisArg, argCount) {      var type = typeof func;      if (type == 'function') {        return thisArg === undefined          ? func          : bindCallback(func, thisArg, argCount);      }      if (func == null) {        return identity;      }      if (type == 'object') {        return baseMatches(func);      }      return thisArg === undefined        ? property(func)        : baseMatchesProperty(func, thisArg);    }    /**     * The base implementation of `_.clone` without support for argument juggling     * and `this` binding `customizer` functions.     *     * @private     * @param {*} value The value to clone.     * @param {boolean} [isDeep] Specify a deep clone.     * @param {Function} [customizer] The function to customize cloning values.     * @param {string} [key] The key of `value`.     * @param {Object} [object] The object `value` belongs to.     * @param {Array} [stackA=[]] Tracks traversed source objects.     * @param {Array} [stackB=[]] Associates clones with source counterparts.     * @returns {*} Returns the cloned value.     */    function baseClone(value, isDeep, customizer, key, object, stackA, stackB) {      var result;      if (customizer) {        result = object ? customizer(value, key, object) : customizer(value);      }      if (result !== undefined) {        return result;      }      if (!isObject(value)) {        return value;      }      var isArr = isArray(value);      if (isArr) {        result = initCloneArray(value);        if (!isDeep) {          return arrayCopy(value, result);        }      } else {        var tag = objToString.call(value),            isFunc = tag == funcTag;        if (tag == objectTag || tag == argsTag || (isFunc && !object)) {          if (isHostObject(value)) {            return object ? value : {};          }          result = initCloneObject(isFunc ? {} : value);          if (!isDeep) {            return baseAssign(result, value);          }        } else {          return cloneableTags[tag]            ? initCloneByTag(value, tag, isDeep)            : (object ? value : {});        }      }      // Check for circular references and return its corresponding clone.      stackA || (stackA = []);      stackB || (stackB = []);      var length = stackA.length;      while (length--) {        if (stackA[length] == value) {          return stackB[length];        }      }      // Add the source value to the stack of traversed objects and associate it with its clone.      stackA.push(value);      stackB.push(result);      // Recursively populate clone (susceptible to call stack limits).      (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {        result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB);      });      return result;    }    /**     * The base implementation of `_.create` without support for assigning     * properties to the created object.     *     * @private     * @param {Object} prototype The object to inherit from.     * @returns {Object} Returns the new object.     */    var baseCreate = (function() {      function object() {}      return function(prototype) {        if (isObject(prototype)) {          object.prototype = prototype;          var result = new object;          object.prototype = undefined;        }        return result || {};      };    }());    /**     * The base implementation of `_.delay` and `_.defer` which accepts an index     * of where to slice the arguments to provide to `func`.     *     * @private     * @param {Function} func The function to delay.     * @param {number} wait The number of milliseconds to delay invocation.     * @param {Object} args The arguments provide to `func`.     * @returns {number} Returns the timer id.     */    function baseDelay(func, wait, args) {      if (typeof func != 'function') {        throw new TypeError(FUNC_ERROR_TEXT);      }      return setTimeout(function() { func.apply(undefined, args); }, wait);    }    /**     * The base implementation of `_.difference` which accepts a single array     * of values to exclude.     *     * @private     * @param {Array} array The array to inspect.     * @param {Array} values The values to exclude.     * @returns {Array} Returns the new array of filtered values.     */    function baseDifference(array, values) {      var length = array ? array.length : 0,          result = [];      if (!length) {        return result;      }      var index = -1,          indexOf = getIndexOf(),          isCommon = indexOf === baseIndexOf,          cache = (isCommon && values.length >= LARGE_ARRAY_SIZE) ? createCache(values) : null,          valuesLength = values.length;      if (cache) {        indexOf = cacheIndexOf;        isCommon = false;        values = cache;      }      outer:      while (++index < length) {        var value = array[index];        if (isCommon && value === value) {          var valuesIndex = valuesLength;          while (valuesIndex--) {            if (values[valuesIndex] === value) {              continue outer;            }          }          result.push(value);        }        else if (indexOf(values, value, 0) < 0) {          result.push(value);        }      }      return result;    }    /**     * The base implementation of `_.forEach` without support for callback     * shorthands and `this` binding.     *     * @private     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @returns {Array|Object|string} Returns `collection`.     */    var baseEach = createBaseEach(baseForOwn);    /**     * The base implementation of `_.forEachRight` without support for callback     * shorthands and `this` binding.     *     * @private     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @returns {Array|Object|string} Returns `collection`.     */    var baseEachRight = createBaseEach(baseForOwnRight, true);    /**     * The base implementation of `_.every` without support for callback     * shorthands and `this` binding.     *     * @private     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function} predicate The function invoked per iteration.     * @returns {boolean} Returns `true` if all elements pass the predicate check,     *  else `false`     */    function baseEvery(collection, predicate) {      var result = true;      baseEach(collection, function(value, index, collection) {        result = !!predicate(value, index, collection);        return result;      });      return result;    }    /**     * Gets the extremum value of `collection` invoking `iteratee` for each value     * in `collection` to generate the criterion by which the value is ranked.     * The `iteratee` is invoked with three arguments: (value, index|key, collection).     *     * @private     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @param {Function} comparator The function used to compare values.     * @param {*} exValue The initial extremum value.     * @returns {*} Returns the extremum value.     */    function baseExtremum(collection, iteratee, comparator, exValue) {      var computed = exValue,          result = computed;      baseEach(collection, function(value, index, collection) {        var current = +iteratee(value, index, collection);        if (comparator(current, computed) || (current === exValue && current === result)) {          computed = current;          result = value;        }      });      return result;    }    /**     * The base implementation of `_.fill` without an iteratee call guard.     *     * @private     * @param {Array} array The array to fill.     * @param {*} value The value to fill `array` with.     * @param {number} [start=0] The start position.     * @param {number} [end=array.length] The end position.     * @returns {Array} Returns `array`.     */    function baseFill(array, value, start, end) {      var length = array.length;      start = start == null ? 0 : (+start || 0);      if (start < 0) {        start = -start > length ? 0 : (length + start);      }      end = (end === undefined || end > length) ? length : (+end || 0);      if (end < 0) {        end += length;      }      length = start > end ? 0 : (end >>> 0);      start >>>= 0;      while (start < length) {        array[start++] = value;      }      return array;    }    /**     * The base implementation of `_.filter` without support for callback     * shorthands and `this` binding.     *     * @private     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function} predicate The function invoked per iteration.     * @returns {Array} Returns the new filtered array.     */    function baseFilter(collection, predicate) {      var result = [];      baseEach(collection, function(value, index, collection) {        if (predicate(value, index, collection)) {          result.push(value);        }      });      return result;    }    /**     * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`,     * without support for callback shorthands and `this` binding, which iterates     * over `collection` using the provided `eachFunc`.     *     * @private     * @param {Array|Object|string} collection The collection to search.     * @param {Function} predicate The function invoked per iteration.     * @param {Function} eachFunc The function to iterate over `collection`.     * @param {boolean} [retKey] Specify returning the key of the found element     *  instead of the element itself.     * @returns {*} Returns the found element or its key, else `undefined`.     */    function baseFind(collection, predicate, eachFunc, retKey) {      var result;      eachFunc(collection, function(value, key, collection) {        if (predicate(value, key, collection)) {          result = retKey ? key : value;          return false;        }      });      return result;    }    /**     * The base implementation of `_.flatten` with added support for restricting     * flattening and specifying the start index.     *     * @private     * @param {Array} array The array to flatten.     * @param {boolean} [isDeep] Specify a deep flatten.     * @param {boolean} [isStrict] Restrict flattening to arrays-like objects.     * @param {Array} [result=[]] The initial result value.     * @returns {Array} Returns the new flattened array.     */    function baseFlatten(array, isDeep, isStrict, result) {      result || (result = []);      var index = -1,          length = array.length;      while (++index < length) {        var value = array[index];        if (isObjectLike(value) && isArrayLike(value) &&            (isStrict || isArray(value) || isArguments(value))) {          if (isDeep) {            // Recursively flatten arrays (susceptible to call stack limits).            baseFlatten(value, isDeep, isStrict, result);          } else {            arrayPush(result, value);          }        } else if (!isStrict) {          result[result.length] = value;        }      }      return result;    }    /**     * The base implementation of `baseForIn` and `baseForOwn` which iterates     * over `object` properties returned by `keysFunc` invoking `iteratee` for     * each property. Iteratee functions may exit iteration early by explicitly     * returning `false`.     *     * @private     * @param {Object} object The object to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @param {Function} keysFunc The function to get the keys of `object`.     * @returns {Object} Returns `object`.     */    var baseFor = createBaseFor();    /**     * This function is like `baseFor` except that it iterates over properties     * in the opposite order.     *     * @private     * @param {Object} object The object to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @param {Function} keysFunc The function to get the keys of `object`.     * @returns {Object} Returns `object`.     */    var baseForRight = createBaseFor(true);    /**     * The base implementation of `_.forIn` without support for callback     * shorthands and `this` binding.     *     * @private     * @param {Object} object The object to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @returns {Object} Returns `object`.     */    function baseForIn(object, iteratee) {      return baseFor(object, iteratee, keysIn);    }    /**     * The base implementation of `_.forOwn` without support for callback     * shorthands and `this` binding.     *     * @private     * @param {Object} object The object to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @returns {Object} Returns `object`.     */    function baseForOwn(object, iteratee) {      return baseFor(object, iteratee, keys);    }    /**     * The base implementation of `_.forOwnRight` without support for callback     * shorthands and `this` binding.     *     * @private     * @param {Object} object The object to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @returns {Object} Returns `object`.     */    function baseForOwnRight(object, iteratee) {      return baseForRight(object, iteratee, keys);    }    /**     * The base implementation of `_.functions` which creates an array of     * `object` function property names filtered from those provided.     *     * @private     * @param {Object} object The object to inspect.     * @param {Array} props The property names to filter.     * @returns {Array} Returns the new array of filtered property names.     */    function baseFunctions(object, props) {      var index = -1,          length = props.length,          resIndex = -1,          result = [];      while (++index < length) {        var key = props[index];        if (isFunction(object[key])) {          result[++resIndex] = key;        }      }      return result;    }    /**     * The base implementation of `get` without support for string paths     * and default values.     *     * @private     * @param {Object} object The object to query.     * @param {Array} path The path of the property to get.     * @param {string} [pathKey] The key representation of path.     * @returns {*} Returns the resolved value.     */    function baseGet(object, path, pathKey) {      if (object == null) {        return;      }      object = toObject(object);      if (pathKey !== undefined && pathKey in object) {        path = [pathKey];      }      var index = 0,          length = path.length;      while (object != null && index < length) {        object = toObject(object)[path[index++]];      }      return (index && index == length) ? object : undefined;    }    /**     * The base implementation of `_.isEqual` without support for `this` binding     * `customizer` functions.     *     * @private     * @param {*} value The value to compare.     * @param {*} other The other value to compare.     * @param {Function} [customizer] The function to customize comparing values.     * @param {boolean} [isLoose] Specify performing partial comparisons.     * @param {Array} [stackA] Tracks traversed `value` objects.     * @param {Array} [stackB] Tracks traversed `other` objects.     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.     */    function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) {      if (value === other) {        return true;      }      if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {        return value !== value && other !== other;      }      return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB);    }    /**     * A specialized version of `baseIsEqual` for arrays and objects which performs     * deep comparisons and tracks traversed objects enabling objects with circular     * references to be compared.     *     * @private     * @param {Object} object The object to compare.     * @param {Object} other The other object to compare.     * @param {Function} equalFunc The function to determine equivalents of values.     * @param {Function} [customizer] The function to customize comparing objects.     * @param {boolean} [isLoose] Specify performing partial comparisons.     * @param {Array} [stackA=[]] Tracks traversed `value` objects.     * @param {Array} [stackB=[]] Tracks traversed `other` objects.     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.     */    function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) {      var objIsArr = isArray(object),          othIsArr = isArray(other),          objTag = arrayTag,          othTag = arrayTag;      if (!objIsArr) {        objTag = objToString.call(object);        if (objTag == argsTag) {          objTag = objectTag;        } else if (objTag != objectTag) {          objIsArr = isTypedArray(object);        }      }      if (!othIsArr) {        othTag = objToString.call(other);        if (othTag == argsTag) {          othTag = objectTag;        } else if (othTag != objectTag) {          othIsArr = isTypedArray(other);        }      }      var objIsObj = objTag == objectTag && !isHostObject(object),          othIsObj = othTag == objectTag && !isHostObject(other),          isSameTag = objTag == othTag;      if (isSameTag && !(objIsArr || objIsObj)) {        return equalByTag(object, other, objTag);      }      if (!isLoose) {        var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),            othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');        if (objIsWrapped || othIsWrapped) {          return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB);        }      }      if (!isSameTag) {        return false;      }      // Assume cyclic values are equal.      // For more information on detecting circular references see https://es5.github.io/#JO.      stackA || (stackA = []);      stackB || (stackB = []);      var length = stackA.length;      while (length--) {        if (stackA[length] == object) {          return stackB[length] == other;        }      }      // Add `object` and `other` to the stack of traversed objects.      stackA.push(object);      stackB.push(other);      var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB);      stackA.pop();      stackB.pop();      return result;    }    /**     * The base implementation of `_.isMatch` without support for callback     * shorthands and `this` binding.     *     * @private     * @param {Object} object The object to inspect.     * @param {Array} matchData The propery names, values, and compare flags to match.     * @param {Function} [customizer] The function to customize comparing objects.     * @returns {boolean} Returns `true` if `object` is a match, else `false`.     */    function baseIsMatch(object, matchData, customizer) {      var index = matchData.length,          length = index,          noCustomizer = !customizer;      if (object == null) {        return !length;      }      object = toObject(object);      while (index--) {        var data = matchData[index];        if ((noCustomizer && data[2])              ? data[1] !== object[data[0]]              : !(data[0] in object)            ) {          return false;        }      }      while (++index < length) {        data = matchData[index];        var key = data[0],            objValue = object[key],            srcValue = data[1];        if (noCustomizer && data[2]) {          if (objValue === undefined && !(key in object)) {            return false;          }        } else {          var result = customizer ? customizer(objValue, srcValue, key) : undefined;          if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) {            return false;          }        }      }      return true;    }    /**     * The base implementation of `_.map` without support for callback shorthands     * and `this` binding.     *     * @private     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @returns {Array} Returns the new mapped array.     */    function baseMap(collection, iteratee) {      var index = -1,          result = isArrayLike(collection) ? Array(collection.length) : [];      baseEach(collection, function(value, key, collection) {        result[++index] = iteratee(value, key, collection);      });      return result;    }    /**     * The base implementation of `_.matches` which does not clone `source`.     *     * @private     * @param {Object} source The object of property values to match.     * @returns {Function} Returns the new function.     */    function baseMatches(source) {      var matchData = getMatchData(source);      if (matchData.length == 1 && matchData[0][2]) {        var key = matchData[0][0],            value = matchData[0][1];        return function(object) {          if (object == null) {            return false;          }          object = toObject(object);          return object[key] === value && (value !== undefined || (key in object));        };      }      return function(object) {        return baseIsMatch(object, matchData);      };    }    /**     * The base implementation of `_.matchesProperty` which does not clone `srcValue`.     *     * @private     * @param {string} path The path of the property to get.     * @param {*} srcValue The value to compare.     * @returns {Function} Returns the new function.     */    function baseMatchesProperty(path, srcValue) {      var isArr = isArray(path),          isCommon = isKey(path) && isStrictComparable(srcValue),          pathKey = (path + '');      path = toPath(path);      return function(object) {        if (object == null) {          return false;        }        var key = pathKey;        object = toObject(object);        if ((isArr || !isCommon) && !(key in object)) {          object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));          if (object == null) {            return false;          }          key = last(path);          object = toObject(object);        }        return object[key] === srcValue          ? (srcValue !== undefined || (key in object))          : baseIsEqual(srcValue, object[key], undefined, true);      };    }    /**     * The base implementation of `_.merge` without support for argument juggling,     * multiple sources, and `this` binding `customizer` functions.     *     * @private     * @param {Object} object The destination object.     * @param {Object} source The source object.     * @param {Function} [customizer] The function to customize merged values.     * @param {Array} [stackA=[]] Tracks traversed source objects.     * @param {Array} [stackB=[]] Associates values with source counterparts.     * @returns {Object} Returns `object`.     */    function baseMerge(object, source, customizer, stackA, stackB) {      if (!isObject(object)) {        return object;      }      var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)),          props = isSrcArr ? undefined : keys(source);      arrayEach(props || source, function(srcValue, key) {        if (props) {          key = srcValue;          srcValue = source[key];        }        if (isObjectLike(srcValue)) {          stackA || (stackA = []);          stackB || (stackB = []);          baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB);        }        else {          var value = object[key],              result = customizer ? customizer(value, srcValue, key, object, source) : undefined,              isCommon = result === undefined;          if (isCommon) {            result = srcValue;          }          if ((result !== undefined || (isSrcArr && !(key in object))) &&              (isCommon || (result === result ? (result !== value) : (value === value)))) {            object[key] = result;          }        }      });      return object;    }    /**     * A specialized version of `baseMerge` for arrays and objects which performs     * deep merges and tracks traversed objects enabling objects with circular     * references to be merged.     *     * @private     * @param {Object} object The destination object.     * @param {Object} source The source object.     * @param {string} key The key of the value to merge.     * @param {Function} mergeFunc The function to merge values.     * @param {Function} [customizer] The function to customize merged values.     * @param {Array} [stackA=[]] Tracks traversed source objects.     * @param {Array} [stackB=[]] Associates values with source counterparts.     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.     */    function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) {      var length = stackA.length,          srcValue = source[key];      while (length--) {        if (stackA[length] == srcValue) {          object[key] = stackB[length];          return;        }      }      var value = object[key],          result = customizer ? customizer(value, srcValue, key, object, source) : undefined,          isCommon = result === undefined;      if (isCommon) {        result = srcValue;        if (isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue))) {          result = isArray(value)            ? value            : (isArrayLike(value) ? arrayCopy(value) : []);        }        else if (isPlainObject(srcValue) || isArguments(srcValue)) {          result = isArguments(value)            ? toPlainObject(value)            : (isPlainObject(value) ? value : {});        }        else {          isCommon = false;        }      }      // Add the source value to the stack of traversed objects and associate      // it with its merged value.      stackA.push(srcValue);      stackB.push(result);      if (isCommon) {        // Recursively merge objects and arrays (susceptible to call stack limits).        object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB);      } else if (result === result ? (result !== value) : (value === value)) {        object[key] = result;      }    }    /**     * The base implementation of `_.property` without support for deep paths.     *     * @private     * @param {string} key The key of the property to get.     * @returns {Function} Returns the new function.     */    function baseProperty(key) {      return function(object) {        return object == null ? undefined : toObject(object)[key];      };    }    /**     * A specialized version of `baseProperty` which supports deep paths.     *     * @private     * @param {Array|string} path The path of the property to get.     * @returns {Function} Returns the new function.     */    function basePropertyDeep(path) {      var pathKey = (path + '');      path = toPath(path);      return function(object) {        return baseGet(object, path, pathKey);      };    }    /**     * The base implementation of `_.pullAt` without support for individual     * index arguments and capturing the removed elements.     *     * @private     * @param {Array} array The array to modify.     * @param {number[]} indexes The indexes of elements to remove.     * @returns {Array} Returns `array`.     */    function basePullAt(array, indexes) {      var length = array ? indexes.length : 0;      while (length--) {        var index = indexes[length];        if (index != previous && isIndex(index)) {          var previous = index;          splice.call(array, index, 1);        }      }      return array;    }    /**     * The base implementation of `_.random` without support for argument juggling     * and returning floating-point numbers.     *     * @private     * @param {number} min The minimum possible value.     * @param {number} max The maximum possible value.     * @returns {number} Returns the random number.     */    function baseRandom(min, max) {      return min + nativeFloor(nativeRandom() * (max - min + 1));    }    /**     * The base implementation of `_.reduce` and `_.reduceRight` without support     * for callback shorthands and `this` binding, which iterates over `collection`     * using the provided `eachFunc`.     *     * @private     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @param {*} accumulator The initial value.     * @param {boolean} initFromCollection Specify using the first or last element     *  of `collection` as the initial value.     * @param {Function} eachFunc The function to iterate over `collection`.     * @returns {*} Returns the accumulated value.     */    function baseReduce(collection, iteratee, accumulator, initFromCollection, eachFunc) {      eachFunc(collection, function(value, index, collection) {        accumulator = initFromCollection          ? (initFromCollection = false, value)          : iteratee(accumulator, value, index, collection);      });      return accumulator;    }    /**     * The base implementation of `setData` without support for hot loop detection.     *     * @private     * @param {Function} func The function to associate metadata with.     * @param {*} data The metadata.     * @returns {Function} Returns `func`.     */    var baseSetData = !metaMap ? identity : function(func, data) {      metaMap.set(func, data);      return func;    };    /**     * The base implementation of `_.slice` without an iteratee call guard.     *     * @private     * @param {Array} array The array to slice.     * @param {number} [start=0] The start position.     * @param {number} [end=array.length] The end position.     * @returns {Array} Returns the slice of `array`.     */    function baseSlice(array, start, end) {      var index = -1,          length = array.length;      start = start == null ? 0 : (+start || 0);      if (start < 0) {        start = -start > length ? 0 : (length + start);      }      end = (end === undefined || end > length) ? length : (+end || 0);      if (end < 0) {        end += length;      }      length = start > end ? 0 : ((end - start) >>> 0);      start >>>= 0;      var result = Array(length);      while (++index < length) {        result[index] = array[index + start];      }      return result;    }    /**     * The base implementation of `_.some` without support for callback shorthands     * and `this` binding.     *     * @private     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function} predicate The function invoked per iteration.     * @returns {boolean} Returns `true` if any element passes the predicate check,     *  else `false`.     */    function baseSome(collection, predicate) {      var result;      baseEach(collection, function(value, index, collection) {        result = predicate(value, index, collection);        return !result;      });      return !!result;    }    /**     * The base implementation of `_.sortBy` which uses `comparer` to define     * the sort order of `array` and replaces criteria objects with their     * corresponding values.     *     * @private     * @param {Array} array The array to sort.     * @param {Function} comparer The function to define sort order.     * @returns {Array} Returns `array`.     */    function baseSortBy(array, comparer) {      var length = array.length;      array.sort(comparer);      while (length--) {        array[length] = array[length].value;      }      return array;    }    /**     * The base implementation of `_.sortByOrder` without param guards.     *     * @private     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.     * @param {boolean[]} orders The sort orders of `iteratees`.     * @returns {Array} Returns the new sorted array.     */    function baseSortByOrder(collection, iteratees, orders) {      var callback = getCallback(),          index = -1;      iteratees = arrayMap(iteratees, function(iteratee) { return callback(iteratee); });      var result = baseMap(collection, function(value) {        var criteria = arrayMap(iteratees, function(iteratee) { return iteratee(value); });        return { 'criteria': criteria, 'index': ++index, 'value': value };      });      return baseSortBy(result, function(object, other) {        return compareMultiple(object, other, orders);      });    }    /**     * The base implementation of `_.sum` without support for callback shorthands     * and `this` binding.     *     * @private     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @returns {number} Returns the sum.     */    function baseSum(collection, iteratee) {      var result = 0;      baseEach(collection, function(value, index, collection) {        result += +iteratee(value, index, collection) || 0;      });      return result;    }    /**     * The base implementation of `_.uniq` without support for callback shorthands     * and `this` binding.     *     * @private     * @param {Array} array The array to inspect.     * @param {Function} [iteratee] The function invoked per iteration.     * @returns {Array} Returns the new duplicate free array.     */    function baseUniq(array, iteratee) {      var index = -1,          indexOf = getIndexOf(),          length = array.length,          isCommon = indexOf === baseIndexOf,          isLarge = isCommon && length >= LARGE_ARRAY_SIZE,          seen = isLarge ? createCache() : null,          result = [];      if (seen) {        indexOf = cacheIndexOf;        isCommon = false;      } else {        isLarge = false;        seen = iteratee ? [] : result;      }      outer:      while (++index < length) {        var value = array[index],            computed = iteratee ? iteratee(value, index, array) : value;        if (isCommon && value === value) {          var seenIndex = seen.length;          while (seenIndex--) {            if (seen[seenIndex] === computed) {              continue outer;            }          }          if (iteratee) {            seen.push(computed);          }          result.push(value);        }        else if (indexOf(seen, computed, 0) < 0) {          if (iteratee || isLarge) {            seen.push(computed);          }          result.push(value);        }      }      return result;    }    /**     * The base implementation of `_.values` and `_.valuesIn` which creates an     * array of `object` property values corresponding to the property names     * of `props`.     *     * @private     * @param {Object} object The object to query.     * @param {Array} props The property names to get values for.     * @returns {Object} Returns the array of property values.     */    function baseValues(object, props) {      var index = -1,          length = props.length,          result = Array(length);      while (++index < length) {        result[index] = object[props[index]];      }      return result;    }    /**     * The base implementation of `_.dropRightWhile`, `_.dropWhile`, `_.takeRightWhile`,     * and `_.takeWhile` without support for callback shorthands and `this` binding.     *     * @private     * @param {Array} array The array to query.     * @param {Function} predicate The function invoked per iteration.     * @param {boolean} [isDrop] Specify dropping elements instead of taking them.     * @param {boolean} [fromRight] Specify iterating from right to left.     * @returns {Array} Returns the slice of `array`.     */    function baseWhile(array, predicate, isDrop, fromRight) {      var length = array.length,          index = fromRight ? length : -1;      while ((fromRight ? index-- : ++index < length) && predicate(array[index], index, array)) {}      return isDrop        ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))        : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));    }    /**     * The base implementation of `wrapperValue` which returns the result of     * performing a sequence of actions on the unwrapped `value`, where each     * successive action is supplied the return value of the previous.     *     * @private     * @param {*} value The unwrapped value.     * @param {Array} actions Actions to peform to resolve the unwrapped value.     * @returns {*} Returns the resolved value.     */    function baseWrapperValue(value, actions) {      var result = value;      if (result instanceof LazyWrapper) {        result = result.value();      }      var index = -1,          length = actions.length;      while (++index < length) {        var action = actions[index];        result = action.func.apply(action.thisArg, arrayPush([result], action.args));      }      return result;    }    /**     * Performs a binary search of `array` to determine the index at which `value`     * should be inserted into `array` in order to maintain its sort order.     *     * @private     * @param {Array} array The sorted array to inspect.     * @param {*} value The value to evaluate.     * @param {boolean} [retHighest] Specify returning the highest qualified index.     * @returns {number} Returns the index at which `value` should be inserted     *  into `array`.     */    function binaryIndex(array, value, retHighest) {      var low = 0,          high = array ? array.length : low;      if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {        while (low < high) {          var mid = (low + high) >>> 1,              computed = array[mid];          if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) {            low = mid + 1;          } else {            high = mid;          }        }        return high;      }      return binaryIndexBy(array, value, identity, retHighest);    }    /**     * This function is like `binaryIndex` except that it invokes `iteratee` for     * `value` and each element of `array` to compute their sort ranking. The     * iteratee is invoked with one argument; (value).     *     * @private     * @param {Array} array The sorted array to inspect.     * @param {*} value The value to evaluate.     * @param {Function} iteratee The function invoked per iteration.     * @param {boolean} [retHighest] Specify returning the highest qualified index.     * @returns {number} Returns the index at which `value` should be inserted     *  into `array`.     */    function binaryIndexBy(array, value, iteratee, retHighest) {      value = iteratee(value);      var low = 0,          high = array ? array.length : 0,          valIsNaN = value !== value,          valIsNull = value === null,          valIsUndef = value === undefined;      while (low < high) {        var mid = nativeFloor((low + high) / 2),            computed = iteratee(array[mid]),            isDef = computed !== undefined,            isReflexive = computed === computed;        if (valIsNaN) {          var setLow = isReflexive || retHighest;        } else if (valIsNull) {          setLow = isReflexive && isDef && (retHighest || computed != null);        } else if (valIsUndef) {          setLow = isReflexive && (retHighest || isDef);        } else if (computed == null) {          setLow = false;        } else {          setLow = retHighest ? (computed <= value) : (computed < value);        }        if (setLow) {          low = mid + 1;        } else {          high = mid;        }      }      return nativeMin(high, MAX_ARRAY_INDEX);    }    /**     * A specialized version of `baseCallback` which only supports `this` binding     * and specifying the number of arguments to provide to `func`.     *     * @private     * @param {Function} func The function to bind.     * @param {*} thisArg The `this` binding of `func`.     * @param {number} [argCount] The number of arguments to provide to `func`.     * @returns {Function} Returns the callback.     */    function bindCallback(func, thisArg, argCount) {      if (typeof func != 'function') {        return identity;      }      if (thisArg === undefined) {        return func;      }      switch (argCount) {        case 1: return function(value) {          return func.call(thisArg, value);        };        case 3: return function(value, index, collection) {          return func.call(thisArg, value, index, collection);        };        case 4: return function(accumulator, value, index, collection) {          return func.call(thisArg, accumulator, value, index, collection);        };        case 5: return function(value, other, key, object, source) {          return func.call(thisArg, value, other, key, object, source);        };      }      return function() {        return func.apply(thisArg, arguments);      };    }    /**     * Creates a clone of the given array buffer.     *     * @private     * @param {ArrayBuffer} buffer The array buffer to clone.     * @returns {ArrayBuffer} Returns the cloned array buffer.     */    function bufferClone(buffer) {      var result = new ArrayBuffer(buffer.byteLength),          view = new Uint8Array(result);      view.set(new Uint8Array(buffer));      return result;    }    /**     * Creates an array that is the composition of partially applied arguments,     * placeholders, and provided arguments into a single array of arguments.     *     * @private     * @param {Array|Object} args The provided arguments.     * @param {Array} partials The arguments to prepend to those provided.     * @param {Array} holders The `partials` placeholder indexes.     * @returns {Array} Returns the new array of composed arguments.     */    function composeArgs(args, partials, holders) {      var holdersLength = holders.length,          argsIndex = -1,          argsLength = nativeMax(args.length - holdersLength, 0),          leftIndex = -1,          leftLength = partials.length,          result = Array(leftLength + argsLength);      while (++leftIndex < leftLength) {        result[leftIndex] = partials[leftIndex];      }      while (++argsIndex < holdersLength) {        result[holders[argsIndex]] = args[argsIndex];      }      while (argsLength--) {        result[leftIndex++] = args[argsIndex++];      }      return result;    }    /**     * This function is like `composeArgs` except that the arguments composition     * is tailored for `_.partialRight`.     *     * @private     * @param {Array|Object} args The provided arguments.     * @param {Array} partials The arguments to append to those provided.     * @param {Array} holders The `partials` placeholder indexes.     * @returns {Array} Returns the new array of composed arguments.     */    function composeArgsRight(args, partials, holders) {      var holdersIndex = -1,          holdersLength = holders.length,          argsIndex = -1,          argsLength = nativeMax(args.length - holdersLength, 0),          rightIndex = -1,          rightLength = partials.length,          result = Array(argsLength + rightLength);      while (++argsIndex < argsLength) {        result[argsIndex] = args[argsIndex];      }      var offset = argsIndex;      while (++rightIndex < rightLength) {        result[offset + rightIndex] = partials[rightIndex];      }      while (++holdersIndex < holdersLength) {        result[offset + holders[holdersIndex]] = args[argsIndex++];      }      return result;    }    /**     * Creates a `_.countBy`, `_.groupBy`, `_.indexBy`, or `_.partition` function.     *     * @private     * @param {Function} setter The function to set keys and values of the accumulator object.     * @param {Function} [initializer] The function to initialize the accumulator object.     * @returns {Function} Returns the new aggregator function.     */    function createAggregator(setter, initializer) {      return function(collection, iteratee, thisArg) {        var result = initializer ? initializer() : {};        iteratee = getCallback(iteratee, thisArg, 3);        if (isArray(collection)) {          var index = -1,              length = collection.length;          while (++index < length) {            var value = collection[index];            setter(result, value, iteratee(value, index, collection), collection);          }        } else {          baseEach(collection, function(value, key, collection) {            setter(result, value, iteratee(value, key, collection), collection);          });        }        return result;      };    }    /**     * Creates a `_.assign`, `_.defaults`, or `_.merge` function.     *     * @private     * @param {Function} assigner The function to assign values.     * @returns {Function} Returns the new assigner function.     */    function createAssigner(assigner) {      return restParam(function(object, sources) {        var index = -1,            length = object == null ? 0 : sources.length,            customizer = length > 2 ? sources[length - 2] : undefined,            guard = length > 2 ? sources[2] : undefined,            thisArg = length > 1 ? sources[length - 1] : undefined;        if (typeof customizer == 'function') {          customizer = bindCallback(customizer, thisArg, 5);          length -= 2;        } else {          customizer = typeof thisArg == 'function' ? thisArg : undefined;          length -= (customizer ? 1 : 0);        }        if (guard && isIterateeCall(sources[0], sources[1], guard)) {          customizer = length < 3 ? undefined : customizer;          length = 1;        }        while (++index < length) {          var source = sources[index];          if (source) {            assigner(object, source, customizer);          }        }        return object;      });    }    /**     * Creates a `baseEach` or `baseEachRight` function.     *     * @private     * @param {Function} eachFunc The function to iterate over a collection.     * @param {boolean} [fromRight] Specify iterating from right to left.     * @returns {Function} Returns the new base function.     */    function createBaseEach(eachFunc, fromRight) {      return function(collection, iteratee) {        var length = collection ? getLength(collection) : 0;        if (!isLength(length)) {          return eachFunc(collection, iteratee);        }        var index = fromRight ? length : -1,            iterable = toObject(collection);        while ((fromRight ? index-- : ++index < length)) {          if (iteratee(iterable[index], index, iterable) === false) {            break;          }        }        return collection;      };    }    /**     * Creates a base function for `_.forIn` or `_.forInRight`.     *     * @private     * @param {boolean} [fromRight] Specify iterating from right to left.     * @returns {Function} Returns the new base function.     */    function createBaseFor(fromRight) {      return function(object, iteratee, keysFunc) {        var iterable = toObject(object),            props = keysFunc(object),            length = props.length,            index = fromRight ? length : -1;        while ((fromRight ? index-- : ++index < length)) {          var key = props[index];          if (iteratee(iterable[key], key, iterable) === false) {            break;          }        }        return object;      };    }    /**     * Creates a function that wraps `func` and invokes it with the `this`     * binding of `thisArg`.     *     * @private     * @param {Function} func The function to bind.     * @param {*} [thisArg] The `this` binding of `func`.     * @returns {Function} Returns the new bound function.     */    function createBindWrapper(func, thisArg) {      var Ctor = createCtorWrapper(func);      function wrapper() {        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;        return fn.apply(thisArg, arguments);      }      return wrapper;    }    /**     * Creates a `Set` cache object to optimize linear searches of large arrays.     *     * @private     * @param {Array} [values] The values to cache.     * @returns {null|Object} Returns the new cache object if `Set` is supported, else `null`.     */    function createCache(values) {      return (nativeCreate && Set) ? new SetCache(values) : null;    }    /**     * Creates a function that produces compound words out of the words in a     * given string.     *     * @private     * @param {Function} callback The function to combine each word.     * @returns {Function} Returns the new compounder function.     */    function createCompounder(callback) {      return function(string) {        var index = -1,            array = words(deburr(string)),            length = array.length,            result = '';        while (++index < length) {          result = callback(result, array[index], index);        }        return result;      };    }    /**     * Creates a function that produces an instance of `Ctor` regardless of     * whether it was invoked as part of a `new` expression or by `call` or `apply`.     *     * @private     * @param {Function} Ctor The constructor to wrap.     * @returns {Function} Returns the new wrapped function.     */    function createCtorWrapper(Ctor) {      return function() {        // Use a `switch` statement to work with class constructors.        // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist        // for more details.        var args = arguments;        switch (args.length) {          case 0: return new Ctor;          case 1: return new Ctor(args[0]);          case 2: return new Ctor(args[0], args[1]);          case 3: return new Ctor(args[0], args[1], args[2]);          case 4: return new Ctor(args[0], args[1], args[2], args[3]);          case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);          case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);          case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);        }        var thisBinding = baseCreate(Ctor.prototype),            result = Ctor.apply(thisBinding, args);        // Mimic the constructor's `return` behavior.        // See https://es5.github.io/#x13.2.2 for more details.        return isObject(result) ? result : thisBinding;      };    }    /**     * Creates a `_.curry` or `_.curryRight` function.     *     * @private     * @param {boolean} flag The curry bit flag.     * @returns {Function} Returns the new curry function.     */    function createCurry(flag) {      function curryFunc(func, arity, guard) {        if (guard && isIterateeCall(func, arity, guard)) {          arity = undefined;        }        var result = createWrapper(func, flag, undefined, undefined, undefined, undefined, undefined, arity);        result.placeholder = curryFunc.placeholder;        return result;      }      return curryFunc;    }    /**     * Creates a `_.defaults` or `_.defaultsDeep` function.     *     * @private     * @param {Function} assigner The function to assign values.     * @param {Function} customizer The function to customize assigned values.     * @returns {Function} Returns the new defaults function.     */    function createDefaults(assigner, customizer) {      return restParam(function(args) {        var object = args[0];        if (object == null) {          return object;        }        args.push(customizer);        return assigner.apply(undefined, args);      });    }    /**     * Creates a `_.max` or `_.min` function.     *     * @private     * @param {Function} comparator The function used to compare values.     * @param {*} exValue The initial extremum value.     * @returns {Function} Returns the new extremum function.     */    function createExtremum(comparator, exValue) {      return function(collection, iteratee, thisArg) {        if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {          iteratee = undefined;        }        iteratee = getCallback(iteratee, thisArg, 3);        if (iteratee.length == 1) {          collection = isArray(collection) ? collection : toIterable(collection);          var result = arrayExtremum(collection, iteratee, comparator, exValue);          if (!(collection.length && result === exValue)) {            return result;          }        }        return baseExtremum(collection, iteratee, comparator, exValue);      };    }    /**     * Creates a `_.find` or `_.findLast` function.     *     * @private     * @param {Function} eachFunc The function to iterate over a collection.     * @param {boolean} [fromRight] Specify iterating from right to left.     * @returns {Function} Returns the new find function.     */    function createFind(eachFunc, fromRight) {      return function(collection, predicate, thisArg) {        predicate = getCallback(predicate, thisArg, 3);        if (isArray(collection)) {          var index = baseFindIndex(collection, predicate, fromRight);          return index > -1 ? collection[index] : undefined;        }        return baseFind(collection, predicate, eachFunc);      };    }    /**     * Creates a `_.findIndex` or `_.findLastIndex` function.     *     * @private     * @param {boolean} [fromRight] Specify iterating from right to left.     * @returns {Function} Returns the new find function.     */    function createFindIndex(fromRight) {      return function(array, predicate, thisArg) {        if (!(array && array.length)) {          return -1;        }        predicate = getCallback(predicate, thisArg, 3);        return baseFindIndex(array, predicate, fromRight);      };    }    /**     * Creates a `_.findKey` or `_.findLastKey` function.     *     * @private     * @param {Function} objectFunc The function to iterate over an object.     * @returns {Function} Returns the new find function.     */    function createFindKey(objectFunc) {      return function(object, predicate, thisArg) {        predicate = getCallback(predicate, thisArg, 3);        return baseFind(object, predicate, objectFunc, true);      };    }    /**     * Creates a `_.flow` or `_.flowRight` function.     *     * @private     * @param {boolean} [fromRight] Specify iterating from right to left.     * @returns {Function} Returns the new flow function.     */    function createFlow(fromRight) {      return function() {        var wrapper,            length = arguments.length,            index = fromRight ? length : -1,            leftIndex = 0,            funcs = Array(length);        while ((fromRight ? index-- : ++index < length)) {          var func = funcs[leftIndex++] = arguments[index];          if (typeof func != 'function') {            throw new TypeError(FUNC_ERROR_TEXT);          }          if (!wrapper && LodashWrapper.prototype.thru && getFuncName(func) == 'wrapper') {            wrapper = new LodashWrapper([], true);          }        }        index = wrapper ? -1 : length;        while (++index < length) {          func = funcs[index];          var funcName = getFuncName(func),              data = funcName == 'wrapper' ? getData(func) : undefined;          if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) {            wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);          } else {            wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func);          }        }        return function() {          var args = arguments,              value = args[0];          if (wrapper && args.length == 1 && isArray(value) && value.length >= LARGE_ARRAY_SIZE) {            return wrapper.plant(value).value();          }          var index = 0,              result = length ? funcs[index].apply(this, args) : value;          while (++index < length) {            result = funcs[index].call(this, result);          }          return result;        };      };    }    /**     * Creates a function for `_.forEach` or `_.forEachRight`.     *     * @private     * @param {Function} arrayFunc The function to iterate over an array.     * @param {Function} eachFunc The function to iterate over a collection.     * @returns {Function} Returns the new each function.     */    function createForEach(arrayFunc, eachFunc) {      return function(collection, iteratee, thisArg) {        return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection))          ? arrayFunc(collection, iteratee)          : eachFunc(collection, bindCallback(iteratee, thisArg, 3));      };    }    /**     * Creates a function for `_.forIn` or `_.forInRight`.     *     * @private     * @param {Function} objectFunc The function to iterate over an object.     * @returns {Function} Returns the new each function.     */    function createForIn(objectFunc) {      return function(object, iteratee, thisArg) {        if (typeof iteratee != 'function' || thisArg !== undefined) {          iteratee = bindCallback(iteratee, thisArg, 3);        }        return objectFunc(object, iteratee, keysIn);      };    }    /**     * Creates a function for `_.forOwn` or `_.forOwnRight`.     *     * @private     * @param {Function} objectFunc The function to iterate over an object.     * @returns {Function} Returns the new each function.     */    function createForOwn(objectFunc) {      return function(object, iteratee, thisArg) {        if (typeof iteratee != 'function' || thisArg !== undefined) {          iteratee = bindCallback(iteratee, thisArg, 3);        }        return objectFunc(object, iteratee);      };    }    /**     * Creates a function for `_.mapKeys` or `_.mapValues`.     *     * @private     * @param {boolean} [isMapKeys] Specify mapping keys instead of values.     * @returns {Function} Returns the new map function.     */    function createObjectMapper(isMapKeys) {      return function(object, iteratee, thisArg) {        var result = {};        iteratee = getCallback(iteratee, thisArg, 3);        baseForOwn(object, function(value, key, object) {          var mapped = iteratee(value, key, object);          key = isMapKeys ? mapped : key;          value = isMapKeys ? value : mapped;          result[key] = value;        });        return result;      };    }    /**     * Creates a function for `_.padLeft` or `_.padRight`.     *     * @private     * @param {boolean} [fromRight] Specify padding from the right.     * @returns {Function} Returns the new pad function.     */    function createPadDir(fromRight) {      return function(string, length, chars) {        string = baseToString(string);        return (fromRight ? string : '') + createPadding(string, length, chars) + (fromRight ? '' : string);      };    }    /**     * Creates a `_.partial` or `_.partialRight` function.     *     * @private     * @param {boolean} flag The partial bit flag.     * @returns {Function} Returns the new partial function.     */    function createPartial(flag) {      var partialFunc = restParam(function(func, partials) {        var holders = replaceHolders(partials, partialFunc.placeholder);        return createWrapper(func, flag, undefined, partials, holders);      });      return partialFunc;    }    /**     * Creates a function for `_.reduce` or `_.reduceRight`.     *     * @private     * @param {Function} arrayFunc The function to iterate over an array.     * @param {Function} eachFunc The function to iterate over a collection.     * @returns {Function} Returns the new each function.     */    function createReduce(arrayFunc, eachFunc) {      return function(collection, iteratee, accumulator, thisArg) {        var initFromArray = arguments.length < 3;        return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection))          ? arrayFunc(collection, iteratee, accumulator, initFromArray)          : baseReduce(collection, getCallback(iteratee, thisArg, 4), accumulator, initFromArray, eachFunc);      };    }    /**     * Creates a function that wraps `func` and invokes it with optional `this`     * binding of, partial application, and currying.     *     * @private     * @param {Function|string} func The function or method name to reference.     * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details.     * @param {*} [thisArg] The `this` binding of `func`.     * @param {Array} [partials] The arguments to prepend to those provided to the new function.     * @param {Array} [holders] The `partials` placeholder indexes.     * @param {Array} [partialsRight] The arguments to append to those provided to the new function.     * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.     * @param {Array} [argPos] The argument positions of the new function.     * @param {number} [ary] The arity cap of `func`.     * @param {number} [arity] The arity of `func`.     * @returns {Function} Returns the new wrapped function.     */    function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {      var isAry = bitmask & ARY_FLAG,          isBind = bitmask & BIND_FLAG,          isBindKey = bitmask & BIND_KEY_FLAG,          isCurry = bitmask & CURRY_FLAG,          isCurryBound = bitmask & CURRY_BOUND_FLAG,          isCurryRight = bitmask & CURRY_RIGHT_FLAG,          Ctor = isBindKey ? undefined : createCtorWrapper(func);      function wrapper() {        // Avoid `arguments` object use disqualifying optimizations by        // converting it to an array before providing it to other functions.        var length = arguments.length,            index = length,            args = Array(length);        while (index--) {          args[index] = arguments[index];        }        if (partials) {          args = composeArgs(args, partials, holders);        }        if (partialsRight) {          args = composeArgsRight(args, partialsRight, holdersRight);        }        if (isCurry || isCurryRight) {          var placeholder = wrapper.placeholder,              argsHolders = replaceHolders(args, placeholder);          length -= argsHolders.length;          if (length < arity) {            var newArgPos = argPos ? arrayCopy(argPos) : undefined,                newArity = nativeMax(arity - length, 0),                newsHolders = isCurry ? argsHolders : undefined,                newHoldersRight = isCurry ? undefined : argsHolders,                newPartials = isCurry ? args : undefined,                newPartialsRight = isCurry ? undefined : args;            bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);            bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);            if (!isCurryBound) {              bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);            }            var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity],                result = createHybridWrapper.apply(undefined, newData);            if (isLaziable(func)) {              setData(result, newData);            }            result.placeholder = placeholder;            return result;          }        }        var thisBinding = isBind ? thisArg : this,            fn = isBindKey ? thisBinding[func] : func;        if (argPos) {          args = reorder(args, argPos);        }        if (isAry && ary < args.length) {          args.length = ary;        }        if (this && this !== root && this instanceof wrapper) {          fn = Ctor || createCtorWrapper(func);        }        return fn.apply(thisBinding, args);      }      return wrapper;    }    /**     * Creates the padding required for `string` based on the given `length`.     * The `chars` string is truncated if the number of characters exceeds `length`.     *     * @private     * @param {string} string The string to create padding for.     * @param {number} [length=0] The padding length.     * @param {string} [chars=' '] The string used as padding.     * @returns {string} Returns the pad for `string`.     */    function createPadding(string, length, chars) {      var strLength = string.length;      length = +length;      if (strLength >= length || !nativeIsFinite(length)) {        return '';      }      var padLength = length - strLength;      chars = chars == null ? ' ' : (chars + '');      return repeat(chars, nativeCeil(padLength / chars.length)).slice(0, padLength);    }    /**     * Creates a function that wraps `func` and invokes it with the optional `this`     * binding of `thisArg` and the `partials` prepended to those provided to     * the wrapper.     *     * @private     * @param {Function} func The function to partially apply arguments to.     * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details.     * @param {*} thisArg The `this` binding of `func`.     * @param {Array} partials The arguments to prepend to those provided to the new function.     * @returns {Function} Returns the new bound function.     */    function createPartialWrapper(func, bitmask, thisArg, partials) {      var isBind = bitmask & BIND_FLAG,          Ctor = createCtorWrapper(func);      function wrapper() {        // Avoid `arguments` object use disqualifying optimizations by        // converting it to an array before providing it `func`.        var argsIndex = -1,            argsLength = arguments.length,            leftIndex = -1,            leftLength = partials.length,            args = Array(leftLength + argsLength);        while (++leftIndex < leftLength) {          args[leftIndex] = partials[leftIndex];        }        while (argsLength--) {          args[leftIndex++] = arguments[++argsIndex];        }        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;        return fn.apply(isBind ? thisArg : this, args);      }      return wrapper;    }    /**     * Creates a `_.ceil`, `_.floor`, or `_.round` function.     *     * @private     * @param {string} methodName The name of the `Math` method to use when rounding.     * @returns {Function} Returns the new round function.     */    function createRound(methodName) {      var func = Math[methodName];      return function(number, precision) {        precision = precision === undefined ? 0 : (+precision || 0);        if (precision) {          precision = pow(10, precision);          return func(number * precision) / precision;        }        return func(number);      };    }    /**     * Creates a `_.sortedIndex` or `_.sortedLastIndex` function.     *     * @private     * @param {boolean} [retHighest] Specify returning the highest qualified index.     * @returns {Function} Returns the new index function.     */    function createSortedIndex(retHighest) {      return function(array, value, iteratee, thisArg) {        var callback = getCallback(iteratee);        return (iteratee == null && callback === baseCallback)          ? binaryIndex(array, value, retHighest)          : binaryIndexBy(array, value, callback(iteratee, thisArg, 1), retHighest);      };    }    /**     * Creates a function that either curries or invokes `func` with optional     * `this` binding and partially applied arguments.     *     * @private     * @param {Function|string} func The function or method name to reference.     * @param {number} bitmask The bitmask of flags.     *  The bitmask may be composed of the following flags:     *     1 - `_.bind`     *     2 - `_.bindKey`     *     4 - `_.curry` or `_.curryRight` of a bound function     *     8 - `_.curry`     *    16 - `_.curryRight`     *    32 - `_.partial`     *    64 - `_.partialRight`     *   128 - `_.rearg`     *   256 - `_.ary`     * @param {*} [thisArg] The `this` binding of `func`.     * @param {Array} [partials] The arguments to be partially applied.     * @param {Array} [holders] The `partials` placeholder indexes.     * @param {Array} [argPos] The argument positions of the new function.     * @param {number} [ary] The arity cap of `func`.     * @param {number} [arity] The arity of `func`.     * @returns {Function} Returns the new wrapped function.     */    function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {      var isBindKey = bitmask & BIND_KEY_FLAG;      if (!isBindKey && typeof func != 'function') {        throw new TypeError(FUNC_ERROR_TEXT);      }      var length = partials ? partials.length : 0;      if (!length) {        bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);        partials = holders = undefined;      }      length -= (holders ? holders.length : 0);      if (bitmask & PARTIAL_RIGHT_FLAG) {        var partialsRight = partials,            holdersRight = holders;        partials = holders = undefined;      }      var data = isBindKey ? undefined : getData(func),          newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity];      if (data) {        mergeData(newData, data);        bitmask = newData[1];        arity = newData[9];      }      newData[9] = arity == null        ? (isBindKey ? 0 : func.length)        : (nativeMax(arity - length, 0) || 0);      if (bitmask == BIND_FLAG) {        var result = createBindWrapper(newData[0], newData[2]);      } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) {        result = createPartialWrapper.apply(undefined, newData);      } else {        result = createHybridWrapper.apply(undefined, newData);      }      var setter = data ? baseSetData : setData;      return setter(result, newData);    }    /**     * A specialized version of `baseIsEqualDeep` for arrays with support for     * partial deep comparisons.     *     * @private     * @param {Array} array The array to compare.     * @param {Array} other The other array to compare.     * @param {Function} equalFunc The function to determine equivalents of values.     * @param {Function} [customizer] The function to customize comparing arrays.     * @param {boolean} [isLoose] Specify performing partial comparisons.     * @param {Array} [stackA] Tracks traversed `value` objects.     * @param {Array} [stackB] Tracks traversed `other` objects.     * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.     */    function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) {      var index = -1,          arrLength = array.length,          othLength = other.length;      if (arrLength != othLength && !(isLoose && othLength > arrLength)) {        return false;      }      // Ignore non-index properties.      while (++index < arrLength) {        var arrValue = array[index],            othValue = other[index],            result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined;        if (result !== undefined) {          if (result) {            continue;          }          return false;        }        // Recursively compare arrays (susceptible to call stack limits).        if (isLoose) {          if (!arraySome(other, function(othValue) {                return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB);              })) {            return false;          }        } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) {          return false;        }      }      return true;    }    /**     * A specialized version of `baseIsEqualDeep` for comparing objects of     * the same `toStringTag`.     *     * **Note:** This function only supports comparing values with tags of     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.     *     * @private     * @param {Object} object The object to compare.     * @param {Object} other The other object to compare.     * @param {string} tag The `toStringTag` of the objects to compare.     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.     */    function equalByTag(object, other, tag) {      switch (tag) {        case boolTag:        case dateTag:          // Coerce dates and booleans to numbers, dates to milliseconds and booleans          // to `1` or `0` treating invalid dates coerced to `NaN` as not equal.          return +object == +other;        case errorTag:          return object.name == other.name && object.message == other.message;        case numberTag:          // Treat `NaN` vs. `NaN` as equal.          return (object != +object)            ? other != +other            : object == +other;        case regexpTag:        case stringTag:          // Coerce regexes to strings and treat strings primitives and string          // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details.          return object == (other + '');      }      return false;    }    /**     * A specialized version of `baseIsEqualDeep` for objects with support for     * partial deep comparisons.     *     * @private     * @param {Object} object The object to compare.     * @param {Object} other The other object to compare.     * @param {Function} equalFunc The function to determine equivalents of values.     * @param {Function} [customizer] The function to customize comparing values.     * @param {boolean} [isLoose] Specify performing partial comparisons.     * @param {Array} [stackA] Tracks traversed `value` objects.     * @param {Array} [stackB] Tracks traversed `other` objects.     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.     */    function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) {      var objProps = keys(object),          objLength = objProps.length,          othProps = keys(other),          othLength = othProps.length;      if (objLength != othLength && !isLoose) {        return false;      }      var index = objLength;      while (index--) {        var key = objProps[index];        if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {          return false;        }      }      var skipCtor = isLoose;      while (++index < objLength) {        key = objProps[index];        var objValue = object[key],            othValue = other[key],            result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined;        // Recursively compare objects (susceptible to call stack limits).        if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) {          return false;        }        skipCtor || (skipCtor = key == 'constructor');      }      if (!skipCtor) {        var objCtor = object.constructor,            othCtor = other.constructor;        // Non `Object` object instances with different constructors are not equal.        if (objCtor != othCtor &&            ('constructor' in object && 'constructor' in other) &&            !(typeof objCtor == 'function' && objCtor instanceof objCtor &&              typeof othCtor == 'function' && othCtor instanceof othCtor)) {          return false;        }      }      return true;    }    /**     * Gets the appropriate "callback" function. If the `_.callback` method is     * customized this function returns the custom method, otherwise it returns     * the `baseCallback` function. If arguments are provided the chosen function     * is invoked with them and its result is returned.     *     * @private     * @returns {Function} Returns the chosen function or its result.     */    function getCallback(func, thisArg, argCount) {      var result = lodash.callback || callback;      result = result === callback ? baseCallback : result;      return argCount ? result(func, thisArg, argCount) : result;    }    /**     * Gets metadata for `func`.     *     * @private     * @param {Function} func The function to query.     * @returns {*} Returns the metadata for `func`.     */    var getData = !metaMap ? noop : function(func) {      return metaMap.get(func);    };    /**     * Gets the name of `func`.     *     * @private     * @param {Function} func The function to query.     * @returns {string} Returns the function name.     */    function getFuncName(func) {      var result = (func.name + ''),          array = realNames[result],          length = array ? array.length : 0;      while (length--) {        var data = array[length],            otherFunc = data.func;        if (otherFunc == null || otherFunc == func) {          return data.name;        }      }      return result;    }    /**     * Gets the appropriate "indexOf" function. If the `_.indexOf` method is     * customized this function returns the custom method, otherwise it returns     * the `baseIndexOf` function. If arguments are provided the chosen function     * is invoked with them and its result is returned.     *     * @private     * @returns {Function|number} Returns the chosen function or its result.     */    function getIndexOf(collection, target, fromIndex) {      var result = lodash.indexOf || indexOf;      result = result === indexOf ? baseIndexOf : result;      return collection ? result(collection, target, fromIndex) : result;    }    /**     * Gets the "length" property value of `object`.     *     * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)     * that affects Safari on at least iOS 8.1-8.3 ARM64.     *     * @private     * @param {Object} object The object to query.     * @returns {*} Returns the "length" value.     */    var getLength = baseProperty('length');    /**     * Gets the propery names, values, and compare flags of `object`.     *     * @private     * @param {Object} object The object to query.     * @returns {Array} Returns the match data of `object`.     */    function getMatchData(object) {      var result = pairs(object),          length = result.length;      while (length--) {        result[length][2] = isStrictComparable(result[length][1]);      }      return result;    }    /**     * Gets the native function at `key` of `object`.     *     * @private     * @param {Object} object The object to query.     * @param {string} key The key of the method to get.     * @returns {*} Returns the function if it's native, else `undefined`.     */    function getNative(object, key) {      var value = object == null ? undefined : object[key];      return isNative(value) ? value : undefined;    }    /**     * Gets the view, applying any `transforms` to the `start` and `end` positions.     *     * @private     * @param {number} start The start of the view.     * @param {number} end The end of the view.     * @param {Array} transforms The transformations to apply to the view.     * @returns {Object} Returns an object containing the `start` and `end`     *  positions of the view.     */    function getView(start, end, transforms) {      var index = -1,          length = transforms.length;      while (++index < length) {        var data = transforms[index],            size = data.size;        switch (data.type) {          case 'drop':      start += size; break;          case 'dropRight': end -= size; break;          case 'take':      end = nativeMin(end, start + size); break;          case 'takeRight': start = nativeMax(start, end - size); break;        }      }      return { 'start': start, 'end': end };    }    /**     * Initializes an array clone.     *     * @private     * @param {Array} array The array to clone.     * @returns {Array} Returns the initialized clone.     */    function initCloneArray(array) {      var length = array.length,          result = new array.constructor(length);      // Add array properties assigned by `RegExp#exec`.      if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {        result.index = array.index;        result.input = array.input;      }      return result;    }    /**     * Initializes an object clone.     *     * @private     * @param {Object} object The object to clone.     * @returns {Object} Returns the initialized clone.     */    function initCloneObject(object) {      var Ctor = object.constructor;      if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) {        Ctor = Object;      }      return new Ctor;    }    /**     * Initializes an object clone based on its `toStringTag`.     *     * **Note:** This function only supports cloning values with tags of     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.     *     * @private     * @param {Object} object The object to clone.     * @param {string} tag The `toStringTag` of the object to clone.     * @param {boolean} [isDeep] Specify a deep clone.     * @returns {Object} Returns the initialized clone.     */    function initCloneByTag(object, tag, isDeep) {      var Ctor = object.constructor;      switch (tag) {        case arrayBufferTag:          return bufferClone(object);        case boolTag:        case dateTag:          return new Ctor(+object);        case float32Tag: case float64Tag:        case int8Tag: case int16Tag: case int32Tag:        case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:          // Safari 5 mobile incorrectly has `Object` as the constructor of typed arrays.          if (Ctor instanceof Ctor) {            Ctor = ctorByTag[tag];          }          var buffer = object.buffer;          return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length);        case numberTag:        case stringTag:          return new Ctor(object);        case regexpTag:          var result = new Ctor(object.source, reFlags.exec(object));          result.lastIndex = object.lastIndex;      }      return result;    }    /**     * Invokes the method at `path` on `object`.     *     * @private     * @param {Object} object The object to query.     * @param {Array|string} path The path of the method to invoke.     * @param {Array} args The arguments to invoke the method with.     * @returns {*} Returns the result of the invoked method.     */    function invokePath(object, path, args) {      if (object != null && !isKey(path, object)) {        path = toPath(path);        object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));        path = last(path);      }      var func = object == null ? object : object[path];      return func == null ? undefined : func.apply(object, args);    }    /**     * Checks if `value` is array-like.     *     * @private     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is array-like, else `false`.     */    function isArrayLike(value) {      return value != null && isLength(getLength(value));    }    /**     * Checks if `value` is a valid array-like index.     *     * @private     * @param {*} value The value to check.     * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.     * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.     */    function isIndex(value, length) {      value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;      length = length == null ? MAX_SAFE_INTEGER : length;      return value > -1 && value % 1 == 0 && value < length;    }    /**     * Checks if the provided arguments are from an iteratee call.     *     * @private     * @param {*} value The potential iteratee value argument.     * @param {*} index The potential iteratee index or key argument.     * @param {*} object The potential iteratee object argument.     * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.     */    function isIterateeCall(value, index, object) {      if (!isObject(object)) {        return false;      }      var type = typeof index;      if (type == 'number'          ? (isArrayLike(object) && isIndex(index, object.length))          : (type == 'string' && index in object)) {        var other = object[index];        return value === value ? (value === other) : (other !== other);      }      return false;    }    /**     * Checks if `value` is a property name and not a property path.     *     * @private     * @param {*} value The value to check.     * @param {Object} [object] The object to query keys on.     * @returns {boolean} Returns `true` if `value` is a property name, else `false`.     */    function isKey(value, object) {      var type = typeof value;      if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') {        return true;      }      if (isArray(value)) {        return false;      }      var result = !reIsDeepProp.test(value);      return result || (object != null && value in toObject(object));    }    /**     * Checks if `func` has a lazy counterpart.     *     * @private     * @param {Function} func The function to check.     * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`.     */    function isLaziable(func) {      var funcName = getFuncName(func),          other = lodash[funcName];      if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {        return false;      }      if (func === other) {        return true;      }      var data = getData(other);      return !!data && func === data[0];    }    /**     * Checks if `value` is a valid array-like length.     *     * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).     *     * @private     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.     */    function isLength(value) {      return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;    }    /**     * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.     *     * @private     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` if suitable for strict     *  equality comparisons, else `false`.     */    function isStrictComparable(value) {      return value === value && !isObject(value);    }    /**     * Merges the function metadata of `source` into `data`.     *     * Merging metadata reduces the number of wrappers required to invoke a function.     * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`     * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg`     * augment function arguments, making the order in which they are executed important,     * preventing the merging of metadata. However, we make an exception for a safe     * common case where curried functions have `_.ary` and or `_.rearg` applied.     *     * @private     * @param {Array} data The destination metadata.     * @param {Array} source The source metadata.     * @returns {Array} Returns `data`.     */    function mergeData(data, source) {      var bitmask = data[1],          srcBitmask = source[1],          newBitmask = bitmask | srcBitmask,          isCommon = newBitmask < ARY_FLAG;      var isCombo =        (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) ||        (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) ||        (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG);      // Exit early if metadata can't be merged.      if (!(isCommon || isCombo)) {        return data;      }      // Use source `thisArg` if available.      if (srcBitmask & BIND_FLAG) {        data[2] = source[2];        // Set when currying a bound function.        newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG;      }      // Compose partial arguments.      var value = source[3];      if (value) {        var partials = data[3];        data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value);        data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]);      }      // Compose partial right arguments.      value = source[5];      if (value) {        partials = data[5];        data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value);        data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]);      }      // Use source `argPos` if available.      value = source[7];      if (value) {        data[7] = arrayCopy(value);      }      // Use source `ary` if it's smaller.      if (srcBitmask & ARY_FLAG) {        data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);      }      // Use source `arity` if one is not provided.      if (data[9] == null) {        data[9] = source[9];      }      // Use source `func` and merge bitmasks.      data[0] = source[0];      data[1] = newBitmask;      return data;    }    /**     * Used by `_.defaultsDeep` to customize its `_.merge` use.     *     * @private     * @param {*} objectValue The destination object property value.     * @param {*} sourceValue The source object property value.     * @returns {*} Returns the value to assign to the destination object.     */    function mergeDefaults(objectValue, sourceValue) {      return objectValue === undefined ? sourceValue : merge(objectValue, sourceValue, mergeDefaults);    }    /**     * A specialized version of `_.pick` which picks `object` properties specified     * by `props`.     *     * @private     * @param {Object} object The source object.     * @param {string[]} props The property names to pick.     * @returns {Object} Returns the new object.     */    function pickByArray(object, props) {      object = toObject(object);      var index = -1,          length = props.length,          result = {};      while (++index < length) {        var key = props[index];        if (key in object) {          result[key] = object[key];        }      }      return result;    }    /**     * A specialized version of `_.pick` which picks `object` properties `predicate`     * returns truthy for.     *     * @private     * @param {Object} object The source object.     * @param {Function} predicate The function invoked per iteration.     * @returns {Object} Returns the new object.     */    function pickByCallback(object, predicate) {      var result = {};      baseForIn(object, function(value, key, object) {        if (predicate(value, key, object)) {          result[key] = value;        }      });      return result;    }    /**     * Reorder `array` according to the specified indexes where the element at     * the first index is assigned as the first element, the element at     * the second index is assigned as the second element, and so on.     *     * @private     * @param {Array} array The array to reorder.     * @param {Array} indexes The arranged array indexes.     * @returns {Array} Returns `array`.     */    function reorder(array, indexes) {      var arrLength = array.length,          length = nativeMin(indexes.length, arrLength),          oldArray = arrayCopy(array);      while (length--) {        var index = indexes[length];        array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;      }      return array;    }    /**     * Sets metadata for `func`.     *     * **Note:** If this function becomes hot, i.e. is invoked a lot in a short     * period of time, it will trip its breaker and transition to an identity function     * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070)     * for more details.     *     * @private     * @param {Function} func The function to associate metadata with.     * @param {*} data The metadata.     * @returns {Function} Returns `func`.     */    var setData = (function() {      var count = 0,          lastCalled = 0;      return function(key, value) {        var stamp = now(),            remaining = HOT_SPAN - (stamp - lastCalled);        lastCalled = stamp;        if (remaining > 0) {          if (++count >= HOT_COUNT) {            return key;          }        } else {          count = 0;        }        return baseSetData(key, value);      };    }());    /**     * A fallback implementation of `Object.keys` which creates an array of the     * own enumerable property names of `object`.     *     * @private     * @param {Object} object The object to query.     * @returns {Array} Returns the array of property names.     */    function shimKeys(object) {      var props = keysIn(object),          propsLength = props.length,          length = propsLength && object.length;      var allowIndexes = !!length && isLength(length) &&        (isArray(object) || isArguments(object) || isString(object));      var index = -1,          result = [];      while (++index < propsLength) {        var key = props[index];        if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {          result.push(key);        }      }      return result;    }    /**     * Converts `value` to an array-like object if it's not one.     *     * @private     * @param {*} value The value to process.     * @returns {Array|Object} Returns the array-like object.     */    function toIterable(value) {      if (value == null) {        return [];      }      if (!isArrayLike(value)) {        return values(value);      }      if (lodash.support.unindexedChars && isString(value)) {        return value.split('');      }      return isObject(value) ? value : Object(value);    }    /**     * Converts `value` to an object if it's not one.     *     * @private     * @param {*} value The value to process.     * @returns {Object} Returns the object.     */    function toObject(value) {      if (lodash.support.unindexedChars && isString(value)) {        var index = -1,            length = value.length,            result = Object(value);        while (++index < length) {          result[index] = value.charAt(index);        }        return result;      }      return isObject(value) ? value : Object(value);    }    /**     * Converts `value` to property path array if it's not one.     *     * @private     * @param {*} value The value to process.     * @returns {Array} Returns the property path array.     */    function toPath(value) {      if (isArray(value)) {        return value;      }      var result = [];      baseToString(value).replace(rePropName, function(match, number, quote, string) {        result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));      });      return result;    }    /**     * Creates a clone of `wrapper`.     *     * @private     * @param {Object} wrapper The wrapper to clone.     * @returns {Object} Returns the cloned wrapper.     */    function wrapperClone(wrapper) {      return wrapper instanceof LazyWrapper        ? wrapper.clone()        : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__));    }    /*------------------------------------------------------------------------*/    /**     * Creates an array of elements split into groups the length of `size`.     * If `collection` can't be split evenly, the final chunk will be the remaining     * elements.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The array to process.     * @param {number} [size=1] The length of each chunk.     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.     * @returns {Array} Returns the new array containing chunks.     * @example     *     * _.chunk(['a', 'b', 'c', 'd'], 2);     * // => [['a', 'b'], ['c', 'd']]     *     * _.chunk(['a', 'b', 'c', 'd'], 3);     * // => [['a', 'b', 'c'], ['d']]     */    function chunk(array, size, guard) {      if (guard ? isIterateeCall(array, size, guard) : size == null) {        size = 1;      } else {        size = nativeMax(nativeFloor(size) || 1, 1);      }      var index = 0,          length = array ? array.length : 0,          resIndex = -1,          result = Array(nativeCeil(length / size));      while (index < length) {        result[++resIndex] = baseSlice(array, index, (index += size));      }      return result;    }    /**     * Creates an array with all falsey values removed. The values `false`, `null`,     * `0`, `""`, `undefined`, and `NaN` are falsey.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The array to compact.     * @returns {Array} Returns the new array of filtered values.     * @example     *     * _.compact([0, 1, false, 2, '', 3]);     * // => [1, 2, 3]     */    function compact(array) {      var index = -1,          length = array ? array.length : 0,          resIndex = -1,          result = [];      while (++index < length) {        var value = array[index];        if (value) {          result[++resIndex] = value;        }      }      return result;    }    /**     * Creates an array of unique `array` values not included in the other     * provided arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)     * for equality comparisons.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The array to inspect.     * @param {...Array} [values] The arrays of values to exclude.     * @returns {Array} Returns the new array of filtered values.     * @example     *     * _.difference([1, 2, 3], [4, 2]);     * // => [1, 3]     */    var difference = restParam(function(array, values) {      return (isObjectLike(array) && isArrayLike(array))        ? baseDifference(array, baseFlatten(values, false, true))        : [];    });    /**     * Creates a slice of `array` with `n` elements dropped from the beginning.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The array to query.     * @param {number} [n=1] The number of elements to drop.     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.     * @returns {Array} Returns the slice of `array`.     * @example     *     * _.drop([1, 2, 3]);     * // => [2, 3]     *     * _.drop([1, 2, 3], 2);     * // => [3]     *     * _.drop([1, 2, 3], 5);     * // => []     *     * _.drop([1, 2, 3], 0);     * // => [1, 2, 3]     */    function drop(array, n, guard) {      var length = array ? array.length : 0;      if (!length) {        return [];      }      if (guard ? isIterateeCall(array, n, guard) : n == null) {        n = 1;      }      return baseSlice(array, n < 0 ? 0 : n);    }    /**     * Creates a slice of `array` with `n` elements dropped from the end.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The array to query.     * @param {number} [n=1] The number of elements to drop.     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.     * @returns {Array} Returns the slice of `array`.     * @example     *     * _.dropRight([1, 2, 3]);     * // => [1, 2]     *     * _.dropRight([1, 2, 3], 2);     * // => [1]     *     * _.dropRight([1, 2, 3], 5);     * // => []     *     * _.dropRight([1, 2, 3], 0);     * // => [1, 2, 3]     */    function dropRight(array, n, guard) {      var length = array ? array.length : 0;      if (!length) {        return [];      }      if (guard ? isIterateeCall(array, n, guard) : n == null) {        n = 1;      }      n = length - (+n || 0);      return baseSlice(array, 0, n < 0 ? 0 : n);    }    /**     * Creates a slice of `array` excluding elements dropped from the end.     * Elements are dropped until `predicate` returns falsey. The predicate is     * bound to `thisArg` and invoked with three arguments: (value, index, array).     *     * If a property name is provided for `predicate` the created `_.property`     * style callback returns the property value of the given element.     *     * If a value is also provided for `thisArg` the created `_.matchesProperty`     * style callback returns `true` for elements that have a matching property     * value, else `false`.     *     * If an object is provided for `predicate` the created `_.matches` style     * callback returns `true` for elements that match the properties of the given     * object, else `false`.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The array to query.     * @param {Function|Object|string} [predicate=_.identity] The function invoked     *  per iteration.     * @param {*} [thisArg] The `this` binding of `predicate`.     * @returns {Array} Returns the slice of `array`.     * @example     *     * _.dropRightWhile([1, 2, 3], function(n) {     *   return n > 1;     * });     * // => [1]     *     * var users = [     *   { 'user': 'barney',  'active': true },     *   { 'user': 'fred',    'active': false },     *   { 'user': 'pebbles', 'active': false }     * ];     *     * // using the `_.matches` callback shorthand     * _.pluck(_.dropRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user');     * // => ['barney', 'fred']     *     * // using the `_.matchesProperty` callback shorthand     * _.pluck(_.dropRightWhile(users, 'active', false), 'user');     * // => ['barney']     *     * // using the `_.property` callback shorthand     * _.pluck(_.dropRightWhile(users, 'active'), 'user');     * // => ['barney', 'fred', 'pebbles']     */    function dropRightWhile(array, predicate, thisArg) {      return (array && array.length)        ? baseWhile(array, getCallback(predicate, thisArg, 3), true, true)        : [];    }    /**     * Creates a slice of `array` excluding elements dropped from the beginning.     * Elements are dropped until `predicate` returns falsey. The predicate is     * bound to `thisArg` and invoked with three arguments: (value, index, array).     *     * If a property name is provided for `predicate` the created `_.property`     * style callback returns the property value of the given element.     *     * If a value is also provided for `thisArg` the created `_.matchesProperty`     * style callback returns `true` for elements that have a matching property     * value, else `false`.     *     * If an object is provided for `predicate` the created `_.matches` style     * callback returns `true` for elements that have the properties of the given     * object, else `false`.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The array to query.     * @param {Function|Object|string} [predicate=_.identity] The function invoked     *  per iteration.     * @param {*} [thisArg] The `this` binding of `predicate`.     * @returns {Array} Returns the slice of `array`.     * @example     *     * _.dropWhile([1, 2, 3], function(n) {     *   return n < 3;     * });     * // => [3]     *     * var users = [     *   { 'user': 'barney',  'active': false },     *   { 'user': 'fred',    'active': false },     *   { 'user': 'pebbles', 'active': true }     * ];     *     * // using the `_.matches` callback shorthand     * _.pluck(_.dropWhile(users, { 'user': 'barney', 'active': false }), 'user');     * // => ['fred', 'pebbles']     *     * // using the `_.matchesProperty` callback shorthand     * _.pluck(_.dropWhile(users, 'active', false), 'user');     * // => ['pebbles']     *     * // using the `_.property` callback shorthand     * _.pluck(_.dropWhile(users, 'active'), 'user');     * // => ['barney', 'fred', 'pebbles']     */    function dropWhile(array, predicate, thisArg) {      return (array && array.length)        ? baseWhile(array, getCallback(predicate, thisArg, 3), true)        : [];    }    /**     * Fills elements of `array` with `value` from `start` up to, but not     * including, `end`.     *     * **Note:** This method mutates `array`.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The array to fill.     * @param {*} value The value to fill `array` with.     * @param {number} [start=0] The start position.     * @param {number} [end=array.length] The end position.     * @returns {Array} Returns `array`.     * @example     *     * var array = [1, 2, 3];     *     * _.fill(array, 'a');     * console.log(array);     * // => ['a', 'a', 'a']     *     * _.fill(Array(3), 2);     * // => [2, 2, 2]     *     * _.fill([4, 6, 8], '*', 1, 2);     * // => [4, '*', 8]     */    function fill(array, value, start, end) {      var length = array ? array.length : 0;      if (!length) {        return [];      }      if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {        start = 0;        end = length;      }      return baseFill(array, value, start, end);    }    /**     * This method is like `_.find` except that it returns the index of the first     * element `predicate` returns truthy for instead of the element itself.     *     * If a property name is provided for `predicate` the created `_.property`     * style callback returns the property value of the given element.     *     * If a value is also provided for `thisArg` the created `_.matchesProperty`     * style callback returns `true` for elements that have a matching property     * value, else `false`.     *     * If an object is provided for `predicate` the created `_.matches` style     * callback returns `true` for elements that have the properties of the given     * object, else `false`.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The array to search.     * @param {Function|Object|string} [predicate=_.identity] The function invoked     *  per iteration.     * @param {*} [thisArg] The `this` binding of `predicate`.     * @returns {number} Returns the index of the found element, else `-1`.     * @example     *     * var users = [     *   { 'user': 'barney',  'active': false },     *   { 'user': 'fred',    'active': false },     *   { 'user': 'pebbles', 'active': true }     * ];     *     * _.findIndex(users, function(chr) {     *   return chr.user == 'barney';     * });     * // => 0     *     * // using the `_.matches` callback shorthand     * _.findIndex(users, { 'user': 'fred', 'active': false });     * // => 1     *     * // using the `_.matchesProperty` callback shorthand     * _.findIndex(users, 'active', false);     * // => 0     *     * // using the `_.property` callback shorthand     * _.findIndex(users, 'active');     * // => 2     */    var findIndex = createFindIndex();    /**     * This method is like `_.findIndex` except that it iterates over elements     * of `collection` from right to left.     *     * If a property name is provided for `predicate` the created `_.property`     * style callback returns the property value of the given element.     *     * If a value is also provided for `thisArg` the created `_.matchesProperty`     * style callback returns `true` for elements that have a matching property     * value, else `false`.     *     * If an object is provided for `predicate` the created `_.matches` style     * callback returns `true` for elements that have the properties of the given     * object, else `false`.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The array to search.     * @param {Function|Object|string} [predicate=_.identity] The function invoked     *  per iteration.     * @param {*} [thisArg] The `this` binding of `predicate`.     * @returns {number} Returns the index of the found element, else `-1`.     * @example     *     * var users = [     *   { 'user': 'barney',  'active': true },     *   { 'user': 'fred',    'active': false },     *   { 'user': 'pebbles', 'active': false }     * ];     *     * _.findLastIndex(users, function(chr) {     *   return chr.user == 'pebbles';     * });     * // => 2     *     * // using the `_.matches` callback shorthand     * _.findLastIndex(users, { 'user': 'barney', 'active': true });     * // => 0     *     * // using the `_.matchesProperty` callback shorthand     * _.findLastIndex(users, 'active', false);     * // => 2     *     * // using the `_.property` callback shorthand     * _.findLastIndex(users, 'active');     * // => 0     */    var findLastIndex = createFindIndex(true);    /**     * Gets the first element of `array`.     *     * @static     * @memberOf _     * @alias head     * @category Array     * @param {Array} array The array to query.     * @returns {*} Returns the first element of `array`.     * @example     *     * _.first([1, 2, 3]);     * // => 1     *     * _.first([]);     * // => undefined     */    function first(array) {      return array ? array[0] : undefined;    }    /**     * Flattens a nested array. If `isDeep` is `true` the array is recursively     * flattened, otherwise it's only flattened a single level.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The array to flatten.     * @param {boolean} [isDeep] Specify a deep flatten.     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.     * @returns {Array} Returns the new flattened array.     * @example     *     * _.flatten([1, [2, 3, [4]]]);     * // => [1, 2, 3, [4]]     *     * // using `isDeep`     * _.flatten([1, [2, 3, [4]]], true);     * // => [1, 2, 3, 4]     */    function flatten(array, isDeep, guard) {      var length = array ? array.length : 0;      if (guard && isIterateeCall(array, isDeep, guard)) {        isDeep = false;      }      return length ? baseFlatten(array, isDeep) : [];    }    /**     * Recursively flattens a nested array.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The array to recursively flatten.     * @returns {Array} Returns the new flattened array.     * @example     *     * _.flattenDeep([1, [2, 3, [4]]]);     * // => [1, 2, 3, 4]     */    function flattenDeep(array) {      var length = array ? array.length : 0;      return length ? baseFlatten(array, true) : [];    }    /**     * Gets the index at which the first occurrence of `value` is found in `array`     * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)     * for equality comparisons. If `fromIndex` is negative, it's used as the offset     * from the end of `array`. If `array` is sorted providing `true` for `fromIndex`     * performs a faster binary search.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The array to search.     * @param {*} value The value to search for.     * @param {boolean|number} [fromIndex=0] The index to search from or `true`     *  to perform a binary search on a sorted array.     * @returns {number} Returns the index of the matched value, else `-1`.     * @example     *     * _.indexOf([1, 2, 1, 2], 2);     * // => 1     *     * // using `fromIndex`     * _.indexOf([1, 2, 1, 2], 2, 2);     * // => 3     *     * // performing a binary search     * _.indexOf([1, 1, 2, 2], 2, true);     * // => 2     */    function indexOf(array, value, fromIndex) {      var length = array ? array.length : 0;      if (!length) {        return -1;      }      if (typeof fromIndex == 'number') {        fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex;      } else if (fromIndex) {        var index = binaryIndex(array, value);        if (index < length &&            (value === value ? (value === array[index]) : (array[index] !== array[index]))) {          return index;        }        return -1;      }      return baseIndexOf(array, value, fromIndex || 0);    }    /**     * Gets all but the last element of `array`.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The array to query.     * @returns {Array} Returns the slice of `array`.     * @example     *     * _.initial([1, 2, 3]);     * // => [1, 2]     */    function initial(array) {      return dropRight(array, 1);    }    /**     * Creates an array of unique values that are included in all of the provided     * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)     * for equality comparisons.     *     * @static     * @memberOf _     * @category Array     * @param {...Array} [arrays] The arrays to inspect.     * @returns {Array} Returns the new array of shared values.     * @example     * _.intersection([1, 2], [4, 2], [2, 1]);     * // => [2]     */    var intersection = restParam(function(arrays) {      var othLength = arrays.length,          othIndex = othLength,          caches = Array(length),          indexOf = getIndexOf(),          isCommon = indexOf === baseIndexOf,          result = [];      while (othIndex--) {        var value = arrays[othIndex] = isArrayLike(value = arrays[othIndex]) ? value : [];        caches[othIndex] = (isCommon && value.length >= 120) ? createCache(othIndex && value) : null;      }      var array = arrays[0],          index = -1,          length = array ? array.length : 0,          seen = caches[0];      outer:      while (++index < length) {        value = array[index];        if ((seen ? cacheIndexOf(seen, value) : indexOf(result, value, 0)) < 0) {          var othIndex = othLength;          while (--othIndex) {            var cache = caches[othIndex];            if ((cache ? cacheIndexOf(cache, value) : indexOf(arrays[othIndex], value, 0)) < 0) {              continue outer;            }          }          if (seen) {            seen.push(value);          }          result.push(value);        }      }      return result;    });    /**     * Gets the last element of `array`.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The array to query.     * @returns {*} Returns the last element of `array`.     * @example     *     * _.last([1, 2, 3]);     * // => 3     */    function last(array) {      var length = array ? array.length : 0;      return length ? array[length - 1] : undefined;    }    /**     * This method is like `_.indexOf` except that it iterates over elements of     * `array` from right to left.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The array to search.     * @param {*} value The value to search for.     * @param {boolean|number} [fromIndex=array.length-1] The index to search from     *  or `true` to perform a binary search on a sorted array.     * @returns {number} Returns the index of the matched value, else `-1`.     * @example     *     * _.lastIndexOf([1, 2, 1, 2], 2);     * // => 3     *     * // using `fromIndex`     * _.lastIndexOf([1, 2, 1, 2], 2, 2);     * // => 1     *     * // performing a binary search     * _.lastIndexOf([1, 1, 2, 2], 2, true);     * // => 3     */    function lastIndexOf(array, value, fromIndex) {      var length = array ? array.length : 0;      if (!length) {        return -1;      }      var index = length;      if (typeof fromIndex == 'number') {        index = (fromIndex < 0 ? nativeMax(length + fromIndex, 0) : nativeMin(fromIndex || 0, length - 1)) + 1;      } else if (fromIndex) {        index = binaryIndex(array, value, true) - 1;        var other = array[index];        if (value === value ? (value === other) : (other !== other)) {          return index;        }        return -1;      }      if (value !== value) {        return indexOfNaN(array, index, true);      }      while (index--) {        if (array[index] === value) {          return index;        }      }      return -1;    }    /**     * Removes all provided values from `array` using     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)     * for equality comparisons.     *     * **Note:** Unlike `_.without`, this method mutates `array`.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The array to modify.     * @param {...*} [values] The values to remove.     * @returns {Array} Returns `array`.     * @example     *     * var array = [1, 2, 3, 1, 2, 3];     *     * _.pull(array, 2, 3);     * console.log(array);     * // => [1, 1]     */    function pull() {      var args = arguments,          array = args[0];      if (!(array && array.length)) {        return array;      }      var index = 0,          indexOf = getIndexOf(),          length = args.length;      while (++index < length) {        var fromIndex = 0,            value = args[index];        while ((fromIndex = indexOf(array, value, fromIndex)) > -1) {          splice.call(array, fromIndex, 1);        }      }      return array;    }    /**     * Removes elements from `array` corresponding to the given indexes and returns     * an array of the removed elements. Indexes may be specified as an array of     * indexes or as individual arguments.     *     * **Note:** Unlike `_.at`, this method mutates `array`.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The array to modify.     * @param {...(number|number[])} [indexes] The indexes of elements to remove,     *  specified as individual indexes or arrays of indexes.     * @returns {Array} Returns the new array of removed elements.     * @example     *     * var array = [5, 10, 15, 20];     * var evens = _.pullAt(array, 1, 3);     *     * console.log(array);     * // => [5, 15]     *     * console.log(evens);     * // => [10, 20]     */    var pullAt = restParam(function(array, indexes) {      indexes = baseFlatten(indexes);      var result = baseAt(array, indexes);      basePullAt(array, indexes.sort(baseCompareAscending));      return result;    });    /**     * Removes all elements from `array` that `predicate` returns truthy for     * and returns an array of the removed elements. The predicate is bound to     * `thisArg` and invoked with three arguments: (value, index, array).     *     * If a property name is provided for `predicate` the created `_.property`     * style callback returns the property value of the given element.     *     * If a value is also provided for `thisArg` the created `_.matchesProperty`     * style callback returns `true` for elements that have a matching property     * value, else `false`.     *     * If an object is provided for `predicate` the created `_.matches` style     * callback returns `true` for elements that have the properties of the given     * object, else `false`.     *     * **Note:** Unlike `_.filter`, this method mutates `array`.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The array to modify.     * @param {Function|Object|string} [predicate=_.identity] The function invoked     *  per iteration.     * @param {*} [thisArg] The `this` binding of `predicate`.     * @returns {Array} Returns the new array of removed elements.     * @example     *     * var array = [1, 2, 3, 4];     * var evens = _.remove(array, function(n) {     *   return n % 2 == 0;     * });     *     * console.log(array);     * // => [1, 3]     *     * console.log(evens);     * // => [2, 4]     */    function remove(array, predicate, thisArg) {      var result = [];      if (!(array && array.length)) {        return result;      }      var index = -1,          indexes = [],          length = array.length;      predicate = getCallback(predicate, thisArg, 3);      while (++index < length) {        var value = array[index];        if (predicate(value, index, array)) {          result.push(value);          indexes.push(index);        }      }      basePullAt(array, indexes);      return result;    }    /**     * Gets all but the first element of `array`.     *     * @static     * @memberOf _     * @alias tail     * @category Array     * @param {Array} array The array to query.     * @returns {Array} Returns the slice of `array`.     * @example     *     * _.rest([1, 2, 3]);     * // => [2, 3]     */    function rest(array) {      return drop(array, 1);    }    /**     * Creates a slice of `array` from `start` up to, but not including, `end`.     *     * **Note:** This method is used instead of `Array#slice` to support node     * lists in IE < 9 and to ensure dense arrays are returned.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The array to slice.     * @param {number} [start=0] The start position.     * @param {number} [end=array.length] The end position.     * @returns {Array} Returns the slice of `array`.     */    function slice(array, start, end) {      var length = array ? array.length : 0;      if (!length) {        return [];      }      if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {        start = 0;        end = length;      }      return baseSlice(array, start, end);    }    /**     * Uses a binary search to determine the lowest index at which `value` should     * be inserted into `array` in order to maintain its sort order. If an iteratee     * function is provided it's invoked for `value` and each element of `array`     * to compute their sort ranking. The iteratee is bound to `thisArg` and     * invoked with one argument; (value).     *     * If a property name is provided for `iteratee` the created `_.property`     * style callback returns the property value of the given element.     *     * If a value is also provided for `thisArg` the created `_.matchesProperty`     * style callback returns `true` for elements that have a matching property     * value, else `false`.     *     * If an object is provided for `iteratee` the created `_.matches` style     * callback returns `true` for elements that have the properties of the given     * object, else `false`.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The sorted array to inspect.     * @param {*} value The value to evaluate.     * @param {Function|Object|string} [iteratee=_.identity] The function invoked     *  per iteration.     * @param {*} [thisArg] The `this` binding of `iteratee`.     * @returns {number} Returns the index at which `value` should be inserted     *  into `array`.     * @example     *     * _.sortedIndex([30, 50], 40);     * // => 1     *     * _.sortedIndex([4, 4, 5, 5], 5);     * // => 2     *     * var dict = { 'data': { 'thirty': 30, 'forty': 40, 'fifty': 50 } };     *     * // using an iteratee function     * _.sortedIndex(['thirty', 'fifty'], 'forty', function(word) {     *   return this.data[word];     * }, dict);     * // => 1     *     * // using the `_.property` callback shorthand     * _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');     * // => 1     */    var sortedIndex = createSortedIndex();    /**     * This method is like `_.sortedIndex` except that it returns the highest     * index at which `value` should be inserted into `array` in order to     * maintain its sort order.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The sorted array to inspect.     * @param {*} value The value to evaluate.     * @param {Function|Object|string} [iteratee=_.identity] The function invoked     *  per iteration.     * @param {*} [thisArg] The `this` binding of `iteratee`.     * @returns {number} Returns the index at which `value` should be inserted     *  into `array`.     * @example     *     * _.sortedLastIndex([4, 4, 5, 5], 5);     * // => 4     */    var sortedLastIndex = createSortedIndex(true);    /**     * Creates a slice of `array` with `n` elements taken from the beginning.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The array to query.     * @param {number} [n=1] The number of elements to take.     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.     * @returns {Array} Returns the slice of `array`.     * @example     *     * _.take([1, 2, 3]);     * // => [1]     *     * _.take([1, 2, 3], 2);     * // => [1, 2]     *     * _.take([1, 2, 3], 5);     * // => [1, 2, 3]     *     * _.take([1, 2, 3], 0);     * // => []     */    function take(array, n, guard) {      var length = array ? array.length : 0;      if (!length) {        return [];      }      if (guard ? isIterateeCall(array, n, guard) : n == null) {        n = 1;      }      return baseSlice(array, 0, n < 0 ? 0 : n);    }    /**     * Creates a slice of `array` with `n` elements taken from the end.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The array to query.     * @param {number} [n=1] The number of elements to take.     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.     * @returns {Array} Returns the slice of `array`.     * @example     *     * _.takeRight([1, 2, 3]);     * // => [3]     *     * _.takeRight([1, 2, 3], 2);     * // => [2, 3]     *     * _.takeRight([1, 2, 3], 5);     * // => [1, 2, 3]     *     * _.takeRight([1, 2, 3], 0);     * // => []     */    function takeRight(array, n, guard) {      var length = array ? array.length : 0;      if (!length) {        return [];      }      if (guard ? isIterateeCall(array, n, guard) : n == null) {        n = 1;      }      n = length - (+n || 0);      return baseSlice(array, n < 0 ? 0 : n);    }    /**     * Creates a slice of `array` with elements taken from the end. Elements are     * taken until `predicate` returns falsey. The predicate is bound to `thisArg`     * and invoked with three arguments: (value, index, array).     *     * If a property name is provided for `predicate` the created `_.property`     * style callback returns the property value of the given element.     *     * If a value is also provided for `thisArg` the created `_.matchesProperty`     * style callback returns `true` for elements that have a matching property     * value, else `false`.     *     * If an object is provided for `predicate` the created `_.matches` style     * callback returns `true` for elements that have the properties of the given     * object, else `false`.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The array to query.     * @param {Function|Object|string} [predicate=_.identity] The function invoked     *  per iteration.     * @param {*} [thisArg] The `this` binding of `predicate`.     * @returns {Array} Returns the slice of `array`.     * @example     *     * _.takeRightWhile([1, 2, 3], function(n) {     *   return n > 1;     * });     * // => [2, 3]     *     * var users = [     *   { 'user': 'barney',  'active': true },     *   { 'user': 'fred',    'active': false },     *   { 'user': 'pebbles', 'active': false }     * ];     *     * // using the `_.matches` callback shorthand     * _.pluck(_.takeRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user');     * // => ['pebbles']     *     * // using the `_.matchesProperty` callback shorthand     * _.pluck(_.takeRightWhile(users, 'active', false), 'user');     * // => ['fred', 'pebbles']     *     * // using the `_.property` callback shorthand     * _.pluck(_.takeRightWhile(users, 'active'), 'user');     * // => []     */    function takeRightWhile(array, predicate, thisArg) {      return (array && array.length)        ? baseWhile(array, getCallback(predicate, thisArg, 3), false, true)        : [];    }    /**     * Creates a slice of `array` with elements taken from the beginning. Elements     * are taken until `predicate` returns falsey. The predicate is bound to     * `thisArg` and invoked with three arguments: (value, index, array).     *     * If a property name is provided for `predicate` the created `_.property`     * style callback returns the property value of the given element.     *     * If a value is also provided for `thisArg` the created `_.matchesProperty`     * style callback returns `true` for elements that have a matching property     * value, else `false`.     *     * If an object is provided for `predicate` the created `_.matches` style     * callback returns `true` for elements that have the properties of the given     * object, else `false`.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The array to query.     * @param {Function|Object|string} [predicate=_.identity] The function invoked     *  per iteration.     * @param {*} [thisArg] The `this` binding of `predicate`.     * @returns {Array} Returns the slice of `array`.     * @example     *     * _.takeWhile([1, 2, 3], function(n) {     *   return n < 3;     * });     * // => [1, 2]     *     * var users = [     *   { 'user': 'barney',  'active': false },     *   { 'user': 'fred',    'active': false},     *   { 'user': 'pebbles', 'active': true }     * ];     *     * // using the `_.matches` callback shorthand     * _.pluck(_.takeWhile(users, { 'user': 'barney', 'active': false }), 'user');     * // => ['barney']     *     * // using the `_.matchesProperty` callback shorthand     * _.pluck(_.takeWhile(users, 'active', false), 'user');     * // => ['barney', 'fred']     *     * // using the `_.property` callback shorthand     * _.pluck(_.takeWhile(users, 'active'), 'user');     * // => []     */    function takeWhile(array, predicate, thisArg) {      return (array && array.length)        ? baseWhile(array, getCallback(predicate, thisArg, 3))        : [];    }    /**     * Creates an array of unique values, in order, from all of the provided arrays     * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)     * for equality comparisons.     *     * @static     * @memberOf _     * @category Array     * @param {...Array} [arrays] The arrays to inspect.     * @returns {Array} Returns the new array of combined values.     * @example     *     * _.union([1, 2], [4, 2], [2, 1]);     * // => [1, 2, 4]     */    var union = restParam(function(arrays) {      return baseUniq(baseFlatten(arrays, false, true));    });    /**     * Creates a duplicate-free version of an array, using     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)     * for equality comparisons, in which only the first occurence of each element     * is kept. Providing `true` for `isSorted` performs a faster search algorithm     * for sorted arrays. If an iteratee function is provided it's invoked for     * each element in the array to generate the criterion by which uniqueness     * is computed. The `iteratee` is bound to `thisArg` and invoked with three     * arguments: (value, index, array).     *     * If a property name is provided for `iteratee` the created `_.property`     * style callback returns the property value of the given element.     *     * If a value is also provided for `thisArg` the created `_.matchesProperty`     * style callback returns `true` for elements that have a matching property     * value, else `false`.     *     * If an object is provided for `iteratee` the created `_.matches` style     * callback returns `true` for elements that have the properties of the given     * object, else `false`.     *     * @static     * @memberOf _     * @alias unique     * @category Array     * @param {Array} array The array to inspect.     * @param {boolean} [isSorted] Specify the array is sorted.     * @param {Function|Object|string} [iteratee] The function invoked per iteration.     * @param {*} [thisArg] The `this` binding of `iteratee`.     * @returns {Array} Returns the new duplicate-value-free array.     * @example     *     * _.uniq([2, 1, 2]);     * // => [2, 1]     *     * // using `isSorted`     * _.uniq([1, 1, 2], true);     * // => [1, 2]     *     * // using an iteratee function     * _.uniq([1, 2.5, 1.5, 2], function(n) {     *   return this.floor(n);     * }, Math);     * // => [1, 2.5]     *     * // using the `_.property` callback shorthand     * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');     * // => [{ 'x': 1 }, { 'x': 2 }]     */    function uniq(array, isSorted, iteratee, thisArg) {      var length = array ? array.length : 0;      if (!length) {        return [];      }      if (isSorted != null && typeof isSorted != 'boolean') {        thisArg = iteratee;        iteratee = isIterateeCall(array, isSorted, thisArg) ? undefined : isSorted;        isSorted = false;      }      var callback = getCallback();      if (!(iteratee == null && callback === baseCallback)) {        iteratee = callback(iteratee, thisArg, 3);      }      return (isSorted && getIndexOf() === baseIndexOf)        ? sortedUniq(array, iteratee)        : baseUniq(array, iteratee);    }    /**     * This method is like `_.zip` except that it accepts an array of grouped     * elements and creates an array regrouping the elements to their pre-zip     * configuration.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The array of grouped elements to process.     * @returns {Array} Returns the new array of regrouped elements.     * @example     *     * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]);     * // => [['fred', 30, true], ['barney', 40, false]]     *     * _.unzip(zipped);     * // => [['fred', 'barney'], [30, 40], [true, false]]     */    function unzip(array) {      if (!(array && array.length)) {        return [];      }      var index = -1,          length = 0;      array = arrayFilter(array, function(group) {        if (isArrayLike(group)) {          length = nativeMax(group.length, length);          return true;        }      });      var result = Array(length);      while (++index < length) {        result[index] = arrayMap(array, baseProperty(index));      }      return result;    }    /**     * This method is like `_.unzip` except that it accepts an iteratee to specify     * how regrouped values should be combined. The `iteratee` is bound to `thisArg`     * and invoked with four arguments: (accumulator, value, index, group).     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The array of grouped elements to process.     * @param {Function} [iteratee] The function to combine regrouped values.     * @param {*} [thisArg] The `this` binding of `iteratee`.     * @returns {Array} Returns the new array of regrouped elements.     * @example     *     * var zipped = _.zip([1, 2], [10, 20], [100, 200]);     * // => [[1, 10, 100], [2, 20, 200]]     *     * _.unzipWith(zipped, _.add);     * // => [3, 30, 300]     */    function unzipWith(array, iteratee, thisArg) {      var length = array ? array.length : 0;      if (!length) {        return [];      }      var result = unzip(array);      if (iteratee == null) {        return result;      }      iteratee = bindCallback(iteratee, thisArg, 4);      return arrayMap(result, function(group) {        return arrayReduce(group, iteratee, undefined, true);      });    }    /**     * Creates an array excluding all provided values using     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)     * for equality comparisons.     *     * @static     * @memberOf _     * @category Array     * @param {Array} array The array to filter.     * @param {...*} [values] The values to exclude.     * @returns {Array} Returns the new array of filtered values.     * @example     *     * _.without([1, 2, 1, 3], 1, 2);     * // => [3]     */    var without = restParam(function(array, values) {      return isArrayLike(array)        ? baseDifference(array, values)        : [];    });    /**     * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)     * of the provided arrays.     *     * @static     * @memberOf _     * @category Array     * @param {...Array} [arrays] The arrays to inspect.     * @returns {Array} Returns the new array of values.     * @example     *     * _.xor([1, 2], [4, 2]);     * // => [1, 4]     */    function xor() {      var index = -1,          length = arguments.length;      while (++index < length) {        var array = arguments[index];        if (isArrayLike(array)) {          var result = result            ? arrayPush(baseDifference(result, array), baseDifference(array, result))            : array;        }      }      return result ? baseUniq(result) : [];    }    /**     * Creates an array of grouped elements, the first of which contains the first     * elements of the given arrays, the second of which contains the second elements     * of the given arrays, and so on.     *     * @static     * @memberOf _     * @category Array     * @param {...Array} [arrays] The arrays to process.     * @returns {Array} Returns the new array of grouped elements.     * @example     *     * _.zip(['fred', 'barney'], [30, 40], [true, false]);     * // => [['fred', 30, true], ['barney', 40, false]]     */    var zip = restParam(unzip);    /**     * The inverse of `_.pairs`; this method returns an object composed from arrays     * of property names and values. Provide either a single two dimensional array,     * e.g. `[[key1, value1], [key2, value2]]` or two arrays, one of property names     * and one of corresponding values.     *     * @static     * @memberOf _     * @alias object     * @category Array     * @param {Array} props The property names.     * @param {Array} [values=[]] The property values.     * @returns {Object} Returns the new object.     * @example     *     * _.zipObject([['fred', 30], ['barney', 40]]);     * // => { 'fred': 30, 'barney': 40 }     *     * _.zipObject(['fred', 'barney'], [30, 40]);     * // => { 'fred': 30, 'barney': 40 }     */    function zipObject(props, values) {      var index = -1,          length = props ? props.length : 0,          result = {};      if (length && !values && !isArray(props[0])) {        values = [];      }      while (++index < length) {        var key = props[index];        if (values) {          result[key] = values[index];        } else if (key) {          result[key[0]] = key[1];        }      }      return result;    }    /**     * This method is like `_.zip` except that it accepts an iteratee to specify     * how grouped values should be combined. The `iteratee` is bound to `thisArg`     * and invoked with four arguments: (accumulator, value, index, group).     *     * @static     * @memberOf _     * @category Array     * @param {...Array} [arrays] The arrays to process.     * @param {Function} [iteratee] The function to combine grouped values.     * @param {*} [thisArg] The `this` binding of `iteratee`.     * @returns {Array} Returns the new array of grouped elements.     * @example     *     * _.zipWith([1, 2], [10, 20], [100, 200], _.add);     * // => [111, 222]     */    var zipWith = restParam(function(arrays) {      var length = arrays.length,          iteratee = length > 2 ? arrays[length - 2] : undefined,          thisArg = length > 1 ? arrays[length - 1] : undefined;      if (length > 2 && typeof iteratee == 'function') {        length -= 2;      } else {        iteratee = (length > 1 && typeof thisArg == 'function') ? (--length, thisArg) : undefined;        thisArg = undefined;      }      arrays.length = length;      return unzipWith(arrays, iteratee, thisArg);    });    /*------------------------------------------------------------------------*/    /**     * Creates a `lodash` object that wraps `value` with explicit method     * chaining enabled.     *     * @static     * @memberOf _     * @category Chain     * @param {*} value The value to wrap.     * @returns {Object} Returns the new `lodash` wrapper instance.     * @example     *     * var users = [     *   { 'user': 'barney',  'age': 36 },     *   { 'user': 'fred',    'age': 40 },     *   { 'user': 'pebbles', 'age': 1 }     * ];     *     * var youngest = _.chain(users)     *   .sortBy('age')     *   .map(function(chr) {     *     return chr.user + ' is ' + chr.age;     *   })     *   .first()     *   .value();     * // => 'pebbles is 1'     */    function chain(value) {      var result = lodash(value);      result.__chain__ = true;      return result;    }    /**     * This method invokes `interceptor` and returns `value`. The interceptor is     * bound to `thisArg` and invoked with one argument; (value). The purpose of     * this method is to "tap into" a method chain in order to perform operations     * on intermediate results within the chain.     *     * @static     * @memberOf _     * @category Chain     * @param {*} value The value to provide to `interceptor`.     * @param {Function} interceptor The function to invoke.     * @param {*} [thisArg] The `this` binding of `interceptor`.     * @returns {*} Returns `value`.     * @example     *     * _([1, 2, 3])     *  .tap(function(array) {     *    array.pop();     *  })     *  .reverse()     *  .value();     * // => [2, 1]     */    function tap(value, interceptor, thisArg) {      interceptor.call(thisArg, value);      return value;    }    /**     * This method is like `_.tap` except that it returns the result of `interceptor`.     *     * @static     * @memberOf _     * @category Chain     * @param {*} value The value to provide to `interceptor`.     * @param {Function} interceptor The function to invoke.     * @param {*} [thisArg] The `this` binding of `interceptor`.     * @returns {*} Returns the result of `interceptor`.     * @example     *     * _('  abc  ')     *  .chain()     *  .trim()     *  .thru(function(value) {     *    return [value];     *  })     *  .value();     * // => ['abc']     */    function thru(value, interceptor, thisArg) {      return interceptor.call(thisArg, value);    }    /**     * Enables explicit method chaining on the wrapper object.     *     * @name chain     * @memberOf _     * @category Chain     * @returns {Object} Returns the new `lodash` wrapper instance.     * @example     *     * var users = [     *   { 'user': 'barney', 'age': 36 },     *   { 'user': 'fred',   'age': 40 }     * ];     *     * // without explicit chaining     * _(users).first();     * // => { 'user': 'barney', 'age': 36 }     *     * // with explicit chaining     * _(users).chain()     *   .first()     *   .pick('user')     *   .value();     * // => { 'user': 'barney' }     */    function wrapperChain() {      return chain(this);    }    /**     * Executes the chained sequence and returns the wrapped result.     *     * @name commit     * @memberOf _     * @category Chain     * @returns {Object} Returns the new `lodash` wrapper instance.     * @example     *     * var array = [1, 2];     * var wrapped = _(array).push(3);     *     * console.log(array);     * // => [1, 2]     *     * wrapped = wrapped.commit();     * console.log(array);     * // => [1, 2, 3]     *     * wrapped.last();     * // => 3     *     * console.log(array);     * // => [1, 2, 3]     */    function wrapperCommit() {      return new LodashWrapper(this.value(), this.__chain__);    }    /**     * Creates a new array joining a wrapped array with any additional arrays     * and/or values.     *     * @name concat     * @memberOf _     * @category Chain     * @param {...*} [values] The values to concatenate.     * @returns {Array} Returns the new concatenated array.     * @example     *     * var array = [1];     * var wrapped = _(array).concat(2, [3], [[4]]);     *     * console.log(wrapped.value());     * // => [1, 2, 3, [4]]     *     * console.log(array);     * // => [1]     */    var wrapperConcat = restParam(function(values) {      values = baseFlatten(values);      return this.thru(function(array) {        return arrayConcat(isArray(array) ? array : [toObject(array)], values);      });    });    /**     * Creates a clone of the chained sequence planting `value` as the wrapped value.     *     * @name plant     * @memberOf _     * @category Chain     * @returns {Object} Returns the new `lodash` wrapper instance.     * @example     *     * var array = [1, 2];     * var wrapped = _(array).map(function(value) {     *   return Math.pow(value, 2);     * });     *     * var other = [3, 4];     * var otherWrapped = wrapped.plant(other);     *     * otherWrapped.value();     * // => [9, 16]     *     * wrapped.value();     * // => [1, 4]     */    function wrapperPlant(value) {      var result,          parent = this;      while (parent instanceof baseLodash) {        var clone = wrapperClone(parent);        if (result) {          previous.__wrapped__ = clone;        } else {          result = clone;        }        var previous = clone;        parent = parent.__wrapped__;      }      previous.__wrapped__ = value;      return result;    }    /**     * Reverses the wrapped array so the first element becomes the last, the     * second element becomes the second to last, and so on.     *     * **Note:** This method mutates the wrapped array.     *     * @name reverse     * @memberOf _     * @category Chain     * @returns {Object} Returns the new reversed `lodash` wrapper instance.     * @example     *     * var array = [1, 2, 3];     *     * _(array).reverse().value()     * // => [3, 2, 1]     *     * console.log(array);     * // => [3, 2, 1]     */    function wrapperReverse() {      var value = this.__wrapped__;      var interceptor = function(value) {        return value.reverse();      };      if (value instanceof LazyWrapper) {        var wrapped = value;        if (this.__actions__.length) {          wrapped = new LazyWrapper(this);        }        wrapped = wrapped.reverse();        wrapped.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });        return new LodashWrapper(wrapped, this.__chain__);      }      return this.thru(interceptor);    }    /**     * Produces the result of coercing the unwrapped value to a string.     *     * @name toString     * @memberOf _     * @category Chain     * @returns {string} Returns the coerced string value.     * @example     *     * _([1, 2, 3]).toString();     * // => '1,2,3'     */    function wrapperToString() {      return (this.value() + '');    }    /**     * Executes the chained sequence to extract the unwrapped value.     *     * @name value     * @memberOf _     * @alias run, toJSON, valueOf     * @category Chain     * @returns {*} Returns the resolved unwrapped value.     * @example     *     * _([1, 2, 3]).value();     * // => [1, 2, 3]     */    function wrapperValue() {      return baseWrapperValue(this.__wrapped__, this.__actions__);    }    /*------------------------------------------------------------------------*/    /**     * Creates an array of elements corresponding to the given keys, or indexes,     * of `collection`. Keys may be specified as individual arguments or as arrays     * of keys.     *     * @static     * @memberOf _     * @category Collection     * @param {Array|Object|string} collection The collection to iterate over.     * @param {...(number|number[]|string|string[])} [props] The property names     *  or indexes of elements to pick, specified individually or in arrays.     * @returns {Array} Returns the new array of picked elements.     * @example     *     * _.at(['a', 'b', 'c'], [0, 2]);     * // => ['a', 'c']     *     * _.at(['barney', 'fred', 'pebbles'], 0, 2);     * // => ['barney', 'pebbles']     */    var at = restParam(function(collection, props) {      if (isArrayLike(collection)) {        collection = toIterable(collection);      }      return baseAt(collection, baseFlatten(props));    });    /**     * Creates an object composed of keys generated from the results of running     * each element of `collection` through `iteratee`. The corresponding value     * of each key is the number of times the key was returned by `iteratee`.     * The `iteratee` is bound to `thisArg` and invoked with three arguments:     * (value, index|key, collection).     *     * If a property name is provided for `iteratee` the created `_.property`     * style callback returns the property value of the given element.     *     * If a value is also provided for `thisArg` the created `_.matchesProperty`     * style callback returns `true` for elements that have a matching property     * value, else `false`.     *     * If an object is provided for `iteratee` the created `_.matches` style     * callback returns `true` for elements that have the properties of the given     * object, else `false`.     *     * @static     * @memberOf _     * @category Collection     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function|Object|string} [iteratee=_.identity] The function invoked     *  per iteration.     * @param {*} [thisArg] The `this` binding of `iteratee`.     * @returns {Object} Returns the composed aggregate object.     * @example     *     * _.countBy([4.3, 6.1, 6.4], function(n) {     *   return Math.floor(n);     * });     * // => { '4': 1, '6': 2 }     *     * _.countBy([4.3, 6.1, 6.4], function(n) {     *   return this.floor(n);     * }, Math);     * // => { '4': 1, '6': 2 }     *     * _.countBy(['one', 'two', 'three'], 'length');     * // => { '3': 2, '5': 1 }     */    var countBy = createAggregator(function(result, value, key) {      hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1);    });    /**     * Checks if `predicate` returns truthy for **all** elements of `collection`.     * The predicate is bound to `thisArg` and invoked with three arguments:     * (value, index|key, collection).     *     * If a property name is provided for `predicate` the created `_.property`     * style callback returns the property value of the given element.     *     * If a value is also provided for `thisArg` the created `_.matchesProperty`     * style callback returns `true` for elements that have a matching property     * value, else `false`.     *     * If an object is provided for `predicate` the created `_.matches` style     * callback returns `true` for elements that have the properties of the given     * object, else `false`.     *     * @static     * @memberOf _     * @alias all     * @category Collection     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function|Object|string} [predicate=_.identity] The function invoked     *  per iteration.     * @param {*} [thisArg] The `this` binding of `predicate`.     * @returns {boolean} Returns `true` if all elements pass the predicate check,     *  else `false`.     * @example     *     * _.every([true, 1, null, 'yes'], Boolean);     * // => false     *     * var users = [     *   { 'user': 'barney', 'active': false },     *   { 'user': 'fred',   'active': false }     * ];     *     * // using the `_.matches` callback shorthand     * _.every(users, { 'user': 'barney', 'active': false });     * // => false     *     * // using the `_.matchesProperty` callback shorthand     * _.every(users, 'active', false);     * // => true     *     * // using the `_.property` callback shorthand     * _.every(users, 'active');     * // => false     */    function every(collection, predicate, thisArg) {      var func = isArray(collection) ? arrayEvery : baseEvery;      if (thisArg && isIterateeCall(collection, predicate, thisArg)) {        predicate = undefined;      }      if (typeof predicate != 'function' || thisArg !== undefined) {        predicate = getCallback(predicate, thisArg, 3);      }      return func(collection, predicate);    }    /**     * Iterates over elements of `collection`, returning an array of all elements     * `predicate` returns truthy for. The predicate is bound to `thisArg` and     * invoked with three arguments: (value, index|key, collection).     *     * If a property name is provided for `predicate` the created `_.property`     * style callback returns the property value of the given element.     *     * If a value is also provided for `thisArg` the created `_.matchesProperty`     * style callback returns `true` for elements that have a matching property     * value, else `false`.     *     * If an object is provided for `predicate` the created `_.matches` style     * callback returns `true` for elements that have the properties of the given     * object, else `false`.     *     * @static     * @memberOf _     * @alias select     * @category Collection     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function|Object|string} [predicate=_.identity] The function invoked     *  per iteration.     * @param {*} [thisArg] The `this` binding of `predicate`.     * @returns {Array} Returns the new filtered array.     * @example     *     * _.filter([4, 5, 6], function(n) {     *   return n % 2 == 0;     * });     * // => [4, 6]     *     * var users = [     *   { 'user': 'barney', 'age': 36, 'active': true },     *   { 'user': 'fred',   'age': 40, 'active': false }     * ];     *     * // using the `_.matches` callback shorthand     * _.pluck(_.filter(users, { 'age': 36, 'active': true }), 'user');     * // => ['barney']     *     * // using the `_.matchesProperty` callback shorthand     * _.pluck(_.filter(users, 'active', false), 'user');     * // => ['fred']     *     * // using the `_.property` callback shorthand     * _.pluck(_.filter(users, 'active'), 'user');     * // => ['barney']     */    function filter(collection, predicate, thisArg) {      var func = isArray(collection) ? arrayFilter : baseFilter;      predicate = getCallback(predicate, thisArg, 3);      return func(collection, predicate);    }    /**     * Iterates over elements of `collection`, returning the first element     * `predicate` returns truthy for. The predicate is bound to `thisArg` and     * invoked with three arguments: (value, index|key, collection).     *     * If a property name is provided for `predicate` the created `_.property`     * style callback returns the property value of the given element.     *     * If a value is also provided for `thisArg` the created `_.matchesProperty`     * style callback returns `true` for elements that have a matching property     * value, else `false`.     *     * If an object is provided for `predicate` the created `_.matches` style     * callback returns `true` for elements that have the properties of the given     * object, else `false`.     *     * @static     * @memberOf _     * @alias detect     * @category Collection     * @param {Array|Object|string} collection The collection to search.     * @param {Function|Object|string} [predicate=_.identity] The function invoked     *  per iteration.     * @param {*} [thisArg] The `this` binding of `predicate`.     * @returns {*} Returns the matched element, else `undefined`.     * @example     *     * var users = [     *   { 'user': 'barney',  'age': 36, 'active': true },     *   { 'user': 'fred',    'age': 40, 'active': false },     *   { 'user': 'pebbles', 'age': 1,  'active': true }     * ];     *     * _.result(_.find(users, function(chr) {     *   return chr.age < 40;     * }), 'user');     * // => 'barney'     *     * // using the `_.matches` callback shorthand     * _.result(_.find(users, { 'age': 1, 'active': true }), 'user');     * // => 'pebbles'     *     * // using the `_.matchesProperty` callback shorthand     * _.result(_.find(users, 'active', false), 'user');     * // => 'fred'     *     * // using the `_.property` callback shorthand     * _.result(_.find(users, 'active'), 'user');     * // => 'barney'     */    var find = createFind(baseEach);    /**     * This method is like `_.find` except that it iterates over elements of     * `collection` from right to left.     *     * @static     * @memberOf _     * @category Collection     * @param {Array|Object|string} collection The collection to search.     * @param {Function|Object|string} [predicate=_.identity] The function invoked     *  per iteration.     * @param {*} [thisArg] The `this` binding of `predicate`.     * @returns {*} Returns the matched element, else `undefined`.     * @example     *     * _.findLast([1, 2, 3, 4], function(n) {     *   return n % 2 == 1;     * });     * // => 3     */    var findLast = createFind(baseEachRight, true);    /**     * Performs a deep comparison between each element in `collection` and the     * source object, returning the first element that has equivalent property     * values.     *     * **Note:** This method supports comparing arrays, booleans, `Date` objects,     * numbers, `Object` objects, regexes, and strings. Objects are compared by     * their own, not inherited, enumerable properties. For comparing a single     * own or inherited property value see `_.matchesProperty`.     *     * @static     * @memberOf _     * @category Collection     * @param {Array|Object|string} collection The collection to search.     * @param {Object} source The object of property values to match.     * @returns {*} Returns the matched element, else `undefined`.     * @example     *     * var users = [     *   { 'user': 'barney', 'age': 36, 'active': true },     *   { 'user': 'fred',   'age': 40, 'active': false }     * ];     *     * _.result(_.findWhere(users, { 'age': 36, 'active': true }), 'user');     * // => 'barney'     *     * _.result(_.findWhere(users, { 'age': 40, 'active': false }), 'user');     * // => 'fred'     */    function findWhere(collection, source) {      return find(collection, baseMatches(source));    }    /**     * Iterates over elements of `collection` invoking `iteratee` for each element.     * The `iteratee` is bound to `thisArg` and invoked with three arguments:     * (value, index|key, collection). Iteratee functions may exit iteration early     * by explicitly returning `false`.     *     * **Note:** As with other "Collections" methods, objects with a "length" property     * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`     * may be used for object iteration.     *     * @static     * @memberOf _     * @alias each     * @category Collection     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function} [iteratee=_.identity] The function invoked per iteration.     * @param {*} [thisArg] The `this` binding of `iteratee`.     * @returns {Array|Object|string} Returns `collection`.     * @example     *     * _([1, 2]).forEach(function(n) {     *   console.log(n);     * }).value();     * // => logs each value from left to right and returns the array     *     * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) {     *   console.log(n, key);     * });     * // => logs each value-key pair and returns the object (iteration order is not guaranteed)     */    var forEach = createForEach(arrayEach, baseEach);    /**     * This method is like `_.forEach` except that it iterates over elements of     * `collection` from right to left.     *     * @static     * @memberOf _     * @alias eachRight     * @category Collection     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function} [iteratee=_.identity] The function invoked per iteration.     * @param {*} [thisArg] The `this` binding of `iteratee`.     * @returns {Array|Object|string} Returns `collection`.     * @example     *     * _([1, 2]).forEachRight(function(n) {     *   console.log(n);     * }).value();     * // => logs each value from right to left and returns the array     */    var forEachRight = createForEach(arrayEachRight, baseEachRight);    /**     * Creates an object composed of keys generated from the results of running     * each element of `collection` through `iteratee`. The corresponding value     * of each key is an array of the elements responsible for generating the key.     * The `iteratee` is bound to `thisArg` and invoked with three arguments:     * (value, index|key, collection).     *     * If a property name is provided for `iteratee` the created `_.property`     * style callback returns the property value of the given element.     *     * If a value is also provided for `thisArg` the created `_.matchesProperty`     * style callback returns `true` for elements that have a matching property     * value, else `false`.     *     * If an object is provided for `iteratee` the created `_.matches` style     * callback returns `true` for elements that have the properties of the given     * object, else `false`.     *     * @static     * @memberOf _     * @category Collection     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function|Object|string} [iteratee=_.identity] The function invoked     *  per iteration.     * @param {*} [thisArg] The `this` binding of `iteratee`.     * @returns {Object} Returns the composed aggregate object.     * @example     *     * _.groupBy([4.2, 6.1, 6.4], function(n) {     *   return Math.floor(n);     * });     * // => { '4': [4.2], '6': [6.1, 6.4] }     *     * _.groupBy([4.2, 6.1, 6.4], function(n) {     *   return this.floor(n);     * }, Math);     * // => { '4': [4.2], '6': [6.1, 6.4] }     *     * // using the `_.property` callback shorthand     * _.groupBy(['one', 'two', 'three'], 'length');     * // => { '3': ['one', 'two'], '5': ['three'] }     */    var groupBy = createAggregator(function(result, value, key) {      if (hasOwnProperty.call(result, key)) {        result[key].push(value);      } else {        result[key] = [value];      }    });    /**     * Checks if `target` is in `collection` using     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)     * for equality comparisons. If `fromIndex` is negative, it's used as the offset     * from the end of `collection`.     *     * @static     * @memberOf _     * @alias contains, include     * @category Collection     * @param {Array|Object|string} collection The collection to search.     * @param {*} target The value to search for.     * @param {number} [fromIndex=0] The index to search from.     * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`.     * @returns {boolean} Returns `true` if a matching element is found, else `false`.     * @example     *     * _.includes([1, 2, 3], 1);     * // => true     *     * _.includes([1, 2, 3], 1, 2);     * // => false     *     * _.includes({ 'user': 'fred', 'age': 40 }, 'fred');     * // => true     *     * _.includes('pebbles', 'eb');     * // => true     */    function includes(collection, target, fromIndex, guard) {      var length = collection ? getLength(collection) : 0;      if (!isLength(length)) {        collection = values(collection);        length = collection.length;      }      if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) {        fromIndex = 0;      } else {        fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0);      }      return (typeof collection == 'string' || !isArray(collection) && isString(collection))        ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1)        : (!!length && getIndexOf(collection, target, fromIndex) > -1);    }    /**     * Creates an object composed of keys generated from the results of running     * each element of `collection` through `iteratee`. The corresponding value     * of each key is the last element responsible for generating the key. The     * iteratee function is bound to `thisArg` and invoked with three arguments:     * (value, index|key, collection).     *     * If a property name is provided for `iteratee` the created `_.property`     * style callback returns the property value of the given element.     *     * If a value is also provided for `thisArg` the created `_.matchesProperty`     * style callback returns `true` for elements that have a matching property     * value, else `false`.     *     * If an object is provided for `iteratee` the created `_.matches` style     * callback returns `true` for elements that have the properties of the given     * object, else `false`.     *     * @static     * @memberOf _     * @category Collection     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function|Object|string} [iteratee=_.identity] The function invoked     *  per iteration.     * @param {*} [thisArg] The `this` binding of `iteratee`.     * @returns {Object} Returns the composed aggregate object.     * @example     *     * var keyData = [     *   { 'dir': 'left', 'code': 97 },     *   { 'dir': 'right', 'code': 100 }     * ];     *     * _.indexBy(keyData, 'dir');     * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }     *     * _.indexBy(keyData, function(object) {     *   return String.fromCharCode(object.code);     * });     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }     *     * _.indexBy(keyData, function(object) {     *   return this.fromCharCode(object.code);     * }, String);     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }     */    var indexBy = createAggregator(function(result, value, key) {      result[key] = value;    });    /**     * Invokes the method at `path` of each element in `collection`, returning     * an array of the results of each invoked method. Any additional arguments     * are provided to each invoked method. If `methodName` is a function it's     * invoked for, and `this` bound to, each element in `collection`.     *     * @static     * @memberOf _     * @category Collection     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Array|Function|string} path The path of the method to invoke or     *  the function invoked per iteration.     * @param {...*} [args] The arguments to invoke the method with.     * @returns {Array} Returns the array of results.     * @example     *     * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');     * // => [[1, 5, 7], [1, 2, 3]]     *     * _.invoke([123, 456], String.prototype.split, '');     * // => [['1', '2', '3'], ['4', '5', '6']]     */    var invoke = restParam(function(collection, path, args) {      var index = -1,          isFunc = typeof path == 'function',          isProp = isKey(path),          result = isArrayLike(collection) ? Array(collection.length) : [];      baseEach(collection, function(value) {        var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined);        result[++index] = func ? func.apply(value, args) : invokePath(value, path, args);      });      return result;    });    /**     * Creates an array of values by running each element in `collection` through     * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three     * arguments: (value, index|key, collection).     *     * If a property name is provided for `iteratee` the created `_.property`     * style callback returns the property value of the given element.     *     * If a value is also provided for `thisArg` the created `_.matchesProperty`     * style callback returns `true` for elements that have a matching property     * value, else `false`.     *     * If an object is provided for `iteratee` the created `_.matches` style     * callback returns `true` for elements that have the properties of the given     * object, else `false`.     *     * Many lodash methods are guarded to work as iteratees for methods like     * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.     *     * The guarded methods are:     * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`,     * `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`,     * `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`,     * `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`,     * `sum`, `uniq`, and `words`     *     * @static     * @memberOf _     * @alias collect     * @category Collection     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function|Object|string} [iteratee=_.identity] The function invoked     *  per iteration.     * @param {*} [thisArg] The `this` binding of `iteratee`.     * @returns {Array} Returns the new mapped array.     * @example     *     * function timesThree(n) {     *   return n * 3;     * }     *     * _.map([1, 2], timesThree);     * // => [3, 6]     *     * _.map({ 'a': 1, 'b': 2 }, timesThree);     * // => [3, 6] (iteration order is not guaranteed)     *     * var users = [     *   { 'user': 'barney' },     *   { 'user': 'fred' }     * ];     *     * // using the `_.property` callback shorthand     * _.map(users, 'user');     * // => ['barney', 'fred']     */    function map(collection, iteratee, thisArg) {      var func = isArray(collection) ? arrayMap : baseMap;      iteratee = getCallback(iteratee, thisArg, 3);      return func(collection, iteratee);    }    /**     * Creates an array of elements split into two groups, the first of which     * contains elements `predicate` returns truthy for, while the second of which     * contains elements `predicate` returns falsey for. The predicate is bound     * to `thisArg` and invoked with three arguments: (value, index|key, collection).     *     * If a property name is provided for `predicate` the created `_.property`     * style callback returns the property value of the given element.     *     * If a value is also provided for `thisArg` the created `_.matchesProperty`     * style callback returns `true` for elements that have a matching property     * value, else `false`.     *     * If an object is provided for `predicate` the created `_.matches` style     * callback returns `true` for elements that have the properties of the given     * object, else `false`.     *     * @static     * @memberOf _     * @category Collection     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function|Object|string} [predicate=_.identity] The function invoked     *  per iteration.     * @param {*} [thisArg] The `this` binding of `predicate`.     * @returns {Array} Returns the array of grouped elements.     * @example     *     * _.partition([1, 2, 3], function(n) {     *   return n % 2;     * });     * // => [[1, 3], [2]]     *     * _.partition([1.2, 2.3, 3.4], function(n) {     *   return this.floor(n) % 2;     * }, Math);     * // => [[1.2, 3.4], [2.3]]     *     * var users = [     *   { 'user': 'barney',  'age': 36, 'active': false },     *   { 'user': 'fred',    'age': 40, 'active': true },     *   { 'user': 'pebbles', 'age': 1,  'active': false }     * ];     *     * var mapper = function(array) {     *   return _.pluck(array, 'user');     * };     *     * // using the `_.matches` callback shorthand     * _.map(_.partition(users, { 'age': 1, 'active': false }), mapper);     * // => [['pebbles'], ['barney', 'fred']]     *     * // using the `_.matchesProperty` callback shorthand     * _.map(_.partition(users, 'active', false), mapper);     * // => [['barney', 'pebbles'], ['fred']]     *     * // using the `_.property` callback shorthand     * _.map(_.partition(users, 'active'), mapper);     * // => [['fred'], ['barney', 'pebbles']]     */    var partition = createAggregator(function(result, value, key) {      result[key ? 0 : 1].push(value);    }, function() { return [[], []]; });    /**     * Gets the property value of `path` from all elements in `collection`.     *     * @static     * @memberOf _     * @category Collection     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Array|string} path The path of the property to pluck.     * @returns {Array} Returns the property values.     * @example     *     * var users = [     *   { 'user': 'barney', 'age': 36 },     *   { 'user': 'fred',   'age': 40 }     * ];     *     * _.pluck(users, 'user');     * // => ['barney', 'fred']     *     * var userIndex = _.indexBy(users, 'user');     * _.pluck(userIndex, 'age');     * // => [36, 40] (iteration order is not guaranteed)     */    function pluck(collection, path) {      return map(collection, property(path));    }    /**     * Reduces `collection` to a value which is the accumulated result of running     * each element in `collection` through `iteratee`, where each successive     * invocation is supplied the return value of the previous. If `accumulator`     * is not provided the first element of `collection` is used as the initial     * value. The `iteratee` is bound to `thisArg` and invoked with four arguments:     * (accumulator, value, index|key, collection).     *     * Many lodash methods are guarded to work as iteratees for methods like     * `_.reduce`, `_.reduceRight`, and `_.transform`.     *     * The guarded methods are:     * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `sortByAll`,     * and `sortByOrder`     *     * @static     * @memberOf _     * @alias foldl, inject     * @category Collection     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function} [iteratee=_.identity] The function invoked per iteration.     * @param {*} [accumulator] The initial value.     * @param {*} [thisArg] The `this` binding of `iteratee`.     * @returns {*} Returns the accumulated value.     * @example     *     * _.reduce([1, 2], function(total, n) {     *   return total + n;     * });     * // => 3     *     * _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) {     *   result[key] = n * 3;     *   return result;     * }, {});     * // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed)     */    var reduce = createReduce(arrayReduce, baseEach);    /**     * This method is like `_.reduce` except that it iterates over elements of     * `collection` from right to left.     *     * @static     * @memberOf _     * @alias foldr     * @category Collection     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function} [iteratee=_.identity] The function invoked per iteration.     * @param {*} [accumulator] The initial value.     * @param {*} [thisArg] The `this` binding of `iteratee`.     * @returns {*} Returns the accumulated value.     * @example     *     * var array = [[0, 1], [2, 3], [4, 5]];     *     * _.reduceRight(array, function(flattened, other) {     *   return flattened.concat(other);     * }, []);     * // => [4, 5, 2, 3, 0, 1]     */    var reduceRight = createReduce(arrayReduceRight, baseEachRight);    /**     * The opposite of `_.filter`; this method returns the elements of `collection`     * that `predicate` does **not** return truthy for.     *     * @static     * @memberOf _     * @category Collection     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function|Object|string} [predicate=_.identity] The function invoked     *  per iteration.     * @param {*} [thisArg] The `this` binding of `predicate`.     * @returns {Array} Returns the new filtered array.     * @example     *     * _.reject([1, 2, 3, 4], function(n) {     *   return n % 2 == 0;     * });     * // => [1, 3]     *     * var users = [     *   { 'user': 'barney', 'age': 36, 'active': false },     *   { 'user': 'fred',   'age': 40, 'active': true }     * ];     *     * // using the `_.matches` callback shorthand     * _.pluck(_.reject(users, { 'age': 40, 'active': true }), 'user');     * // => ['barney']     *     * // using the `_.matchesProperty` callback shorthand     * _.pluck(_.reject(users, 'active', false), 'user');     * // => ['fred']     *     * // using the `_.property` callback shorthand     * _.pluck(_.reject(users, 'active'), 'user');     * // => ['barney']     */    function reject(collection, predicate, thisArg) {      var func = isArray(collection) ? arrayFilter : baseFilter;      predicate = getCallback(predicate, thisArg, 3);      return func(collection, function(value, index, collection) {        return !predicate(value, index, collection);      });    }    /**     * Gets a random element or `n` random elements from a collection.     *     * @static     * @memberOf _     * @category Collection     * @param {Array|Object|string} collection The collection to sample.     * @param {number} [n] The number of elements to sample.     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.     * @returns {*} Returns the random sample(s).     * @example     *     * _.sample([1, 2, 3, 4]);     * // => 2     *     * _.sample([1, 2, 3, 4], 2);     * // => [3, 1]     */    function sample(collection, n, guard) {      if (guard ? isIterateeCall(collection, n, guard) : n == null) {        collection = toIterable(collection);        var length = collection.length;        return length > 0 ? collection[baseRandom(0, length - 1)] : undefined;      }      var index = -1,          result = toArray(collection),          length = result.length,          lastIndex = length - 1;      n = nativeMin(n < 0 ? 0 : (+n || 0), length);      while (++index < n) {        var rand = baseRandom(index, lastIndex),            value = result[rand];        result[rand] = result[index];        result[index] = value;      }      result.length = n;      return result;    }    /**     * Creates an array of shuffled values, using a version of the     * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).     *     * @static     * @memberOf _     * @category Collection     * @param {Array|Object|string} collection The collection to shuffle.     * @returns {Array} Returns the new shuffled array.     * @example     *     * _.shuffle([1, 2, 3, 4]);     * // => [4, 1, 3, 2]     */    function shuffle(collection) {      return sample(collection, POSITIVE_INFINITY);    }    /**     * Gets the size of `collection` by returning its length for array-like     * values or the number of own enumerable properties for objects.     *     * @static     * @memberOf _     * @category Collection     * @param {Array|Object|string} collection The collection to inspect.     * @returns {number} Returns the size of `collection`.     * @example     *     * _.size([1, 2, 3]);     * // => 3     *     * _.size({ 'a': 1, 'b': 2 });     * // => 2     *     * _.size('pebbles');     * // => 7     */    function size(collection) {      var length = collection ? getLength(collection) : 0;      return isLength(length) ? length : keys(collection).length;    }    /**     * Checks if `predicate` returns truthy for **any** element of `collection`.     * The function returns as soon as it finds a passing value and does not iterate     * over the entire collection. The predicate is bound to `thisArg` and invoked     * with three arguments: (value, index|key, collection).     *     * If a property name is provided for `predicate` the created `_.property`     * style callback returns the property value of the given element.     *     * If a value is also provided for `thisArg` the created `_.matchesProperty`     * style callback returns `true` for elements that have a matching property     * value, else `false`.     *     * If an object is provided for `predicate` the created `_.matches` style     * callback returns `true` for elements that have the properties of the given     * object, else `false`.     *     * @static     * @memberOf _     * @alias any     * @category Collection     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function|Object|string} [predicate=_.identity] The function invoked     *  per iteration.     * @param {*} [thisArg] The `this` binding of `predicate`.     * @returns {boolean} Returns `true` if any element passes the predicate check,     *  else `false`.     * @example     *     * _.some([null, 0, 'yes', false], Boolean);     * // => true     *     * var users = [     *   { 'user': 'barney', 'active': true },     *   { 'user': 'fred',   'active': false }     * ];     *     * // using the `_.matches` callback shorthand     * _.some(users, { 'user': 'barney', 'active': false });     * // => false     *     * // using the `_.matchesProperty` callback shorthand     * _.some(users, 'active', false);     * // => true     *     * // using the `_.property` callback shorthand     * _.some(users, 'active');     * // => true     */    function some(collection, predicate, thisArg) {      var func = isArray(collection) ? arraySome : baseSome;      if (thisArg && isIterateeCall(collection, predicate, thisArg)) {        predicate = undefined;      }      if (typeof predicate != 'function' || thisArg !== undefined) {        predicate = getCallback(predicate, thisArg, 3);      }      return func(collection, predicate);    }    /**     * Creates an array of elements, sorted in ascending order by the results of     * running each element in a collection through `iteratee`. This method performs     * a stable sort, that is, it preserves the original sort order of equal elements.     * The `iteratee` is bound to `thisArg` and invoked with three arguments:     * (value, index|key, collection).     *     * If a property name is provided for `iteratee` the created `_.property`     * style callback returns the property value of the given element.     *     * If a value is also provided for `thisArg` the created `_.matchesProperty`     * style callback returns `true` for elements that have a matching property     * value, else `false`.     *     * If an object is provided for `iteratee` the created `_.matches` style     * callback returns `true` for elements that have the properties of the given     * object, else `false`.     *     * @static     * @memberOf _     * @category Collection     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function|Object|string} [iteratee=_.identity] The function invoked     *  per iteration.     * @param {*} [thisArg] The `this` binding of `iteratee`.     * @returns {Array} Returns the new sorted array.     * @example     *     * _.sortBy([1, 2, 3], function(n) {     *   return Math.sin(n);     * });     * // => [3, 1, 2]     *     * _.sortBy([1, 2, 3], function(n) {     *   return this.sin(n);     * }, Math);     * // => [3, 1, 2]     *     * var users = [     *   { 'user': 'fred' },     *   { 'user': 'pebbles' },     *   { 'user': 'barney' }     * ];     *     * // using the `_.property` callback shorthand     * _.pluck(_.sortBy(users, 'user'), 'user');     * // => ['barney', 'fred', 'pebbles']     */    function sortBy(collection, iteratee, thisArg) {      if (collection == null) {        return [];      }      if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {        iteratee = undefined;      }      var index = -1;      iteratee = getCallback(iteratee, thisArg, 3);      var result = baseMap(collection, function(value, key, collection) {        return { 'criteria': iteratee(value, key, collection), 'index': ++index, 'value': value };      });      return baseSortBy(result, compareAscending);    }    /**     * This method is like `_.sortBy` except that it can sort by multiple iteratees     * or property names.     *     * If a property name is provided for an iteratee the created `_.property`     * style callback returns the property value of the given element.     *     * If an object is provided for an iteratee the created `_.matches` style     * callback returns `true` for elements that have the properties of the given     * object, else `false`.     *     * @static     * @memberOf _     * @category Collection     * @param {Array|Object|string} collection The collection to iterate over.     * @param {...(Function|Function[]|Object|Object[]|string|string[])} iteratees     *  The iteratees to sort by, specified as individual values or arrays of values.     * @returns {Array} Returns the new sorted array.     * @example     *     * var users = [     *   { 'user': 'fred',   'age': 48 },     *   { 'user': 'barney', 'age': 36 },     *   { 'user': 'fred',   'age': 42 },     *   { 'user': 'barney', 'age': 34 }     * ];     *     * _.map(_.sortByAll(users, ['user', 'age']), _.values);     * // => [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]]     *     * _.map(_.sortByAll(users, 'user', function(chr) {     *   return Math.floor(chr.age / 10);     * }), _.values);     * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]     */    var sortByAll = restParam(function(collection, iteratees) {      if (collection == null) {        return [];      }      var guard = iteratees[2];      if (guard && isIterateeCall(iteratees[0], iteratees[1], guard)) {        iteratees.length = 1;      }      return baseSortByOrder(collection, baseFlatten(iteratees), []);    });    /**     * This method is like `_.sortByAll` except that it allows specifying the     * sort orders of the iteratees to sort by. If `orders` is unspecified, all     * values are sorted in ascending order. Otherwise, a value is sorted in     * ascending order if its corresponding order is "asc", and descending if "desc".     *     * If a property name is provided for an iteratee the created `_.property`     * style callback returns the property value of the given element.     *     * If an object is provided for an iteratee the created `_.matches` style     * callback returns `true` for elements that have the properties of the given     * object, else `false`.     *     * @static     * @memberOf _     * @category Collection     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.     * @param {boolean[]} [orders] The sort orders of `iteratees`.     * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`.     * @returns {Array} Returns the new sorted array.     * @example     *     * var users = [     *   { 'user': 'fred',   'age': 48 },     *   { 'user': 'barney', 'age': 34 },     *   { 'user': 'fred',   'age': 42 },     *   { 'user': 'barney', 'age': 36 }     * ];     *     * // sort by `user` in ascending order and by `age` in descending order     * _.map(_.sortByOrder(users, ['user', 'age'], ['asc', 'desc']), _.values);     * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]     */    function sortByOrder(collection, iteratees, orders, guard) {      if (collection == null) {        return [];      }      if (guard && isIterateeCall(iteratees, orders, guard)) {        orders = undefined;      }      if (!isArray(iteratees)) {        iteratees = iteratees == null ? [] : [iteratees];      }      if (!isArray(orders)) {        orders = orders == null ? [] : [orders];      }      return baseSortByOrder(collection, iteratees, orders);    }    /**     * Performs a deep comparison between each element in `collection` and the     * source object, returning an array of all elements that have equivalent     * property values.     *     * **Note:** This method supports comparing arrays, booleans, `Date` objects,     * numbers, `Object` objects, regexes, and strings. Objects are compared by     * their own, not inherited, enumerable properties. For comparing a single     * own or inherited property value see `_.matchesProperty`.     *     * @static     * @memberOf _     * @category Collection     * @param {Array|Object|string} collection The collection to search.     * @param {Object} source The object of property values to match.     * @returns {Array} Returns the new filtered array.     * @example     *     * var users = [     *   { 'user': 'barney', 'age': 36, 'active': false, 'pets': ['hoppy'] },     *   { 'user': 'fred',   'age': 40, 'active': true, 'pets': ['baby puss', 'dino'] }     * ];     *     * _.pluck(_.where(users, { 'age': 36, 'active': false }), 'user');     * // => ['barney']     *     * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user');     * // => ['fred']     */    function where(collection, source) {      return filter(collection, baseMatches(source));    }    /*------------------------------------------------------------------------*/    /**     * Gets the number of milliseconds that have elapsed since the Unix epoch     * (1 January 1970 00:00:00 UTC).     *     * @static     * @memberOf _     * @category Date     * @example     *     * _.defer(function(stamp) {     *   console.log(_.now() - stamp);     * }, _.now());     * // => logs the number of milliseconds it took for the deferred function to be invoked     */    var now = nativeNow || function() {      return new Date().getTime();    };    /*------------------------------------------------------------------------*/    /**     * The opposite of `_.before`; this method creates a function that invokes     * `func` once it's called `n` or more times.     *     * @static     * @memberOf _     * @category Function     * @param {number} n The number of calls before `func` is invoked.     * @param {Function} func The function to restrict.     * @returns {Function} Returns the new restricted function.     * @example     *     * var saves = ['profile', 'settings'];     *     * var done = _.after(saves.length, function() {     *   console.log('done saving!');     * });     *     * _.forEach(saves, function(type) {     *   asyncSave({ 'type': type, 'complete': done });     * });     * // => logs 'done saving!' after the two async saves have completed     */    function after(n, func) {      if (typeof func != 'function') {        if (typeof n == 'function') {          var temp = n;          n = func;          func = temp;        } else {          throw new TypeError(FUNC_ERROR_TEXT);        }      }      n = nativeIsFinite(n = +n) ? n : 0;      return function() {        if (--n < 1) {          return func.apply(this, arguments);        }      };    }    /**     * Creates a function that accepts up to `n` arguments ignoring any     * additional arguments.     *     * @static     * @memberOf _     * @category Function     * @param {Function} func The function to cap arguments for.     * @param {number} [n=func.length] The arity cap.     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.     * @returns {Function} Returns the new function.     * @example     *     * _.map(['6', '8', '10'], _.ary(parseInt, 1));     * // => [6, 8, 10]     */    function ary(func, n, guard) {      if (guard && isIterateeCall(func, n, guard)) {        n = undefined;      }      n = (func && n == null) ? func.length : nativeMax(+n || 0, 0);      return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n);    }    /**     * Creates a function that invokes `func`, with the `this` binding and arguments     * of the created function, while it's called less than `n` times. Subsequent     * calls to the created function return the result of the last `func` invocation.     *     * @static     * @memberOf _     * @category Function     * @param {number} n The number of calls at which `func` is no longer invoked.     * @param {Function} func The function to restrict.     * @returns {Function} Returns the new restricted function.     * @example     *     * jQuery('#add').on('click', _.before(5, addContactToList));     * // => allows adding up to 4 contacts to the list     */    function before(n, func) {      var result;      if (typeof func != 'function') {        if (typeof n == 'function') {          var temp = n;          n = func;          func = temp;        } else {          throw new TypeError(FUNC_ERROR_TEXT);        }      }      return function() {        if (--n > 0) {          result = func.apply(this, arguments);        }        if (n <= 1) {          func = undefined;        }        return result;      };    }    /**     * Creates a function that invokes `func` with the `this` binding of `thisArg`     * and prepends any additional `_.bind` arguments to those provided to the     * bound function.     *     * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,     * may be used as a placeholder for partially applied arguments.     *     * **Note:** Unlike native `Function#bind` this method does not set the "length"     * property of bound functions.     *     * @static     * @memberOf _     * @category Function     * @param {Function} func The function to bind.     * @param {*} thisArg The `this` binding of `func`.     * @param {...*} [partials] The arguments to be partially applied.     * @returns {Function} Returns the new bound function.     * @example     *     * var greet = function(greeting, punctuation) {     *   return greeting + ' ' + this.user + punctuation;     * };     *     * var object = { 'user': 'fred' };     *     * var bound = _.bind(greet, object, 'hi');     * bound('!');     * // => 'hi fred!'     *     * // using placeholders     * var bound = _.bind(greet, object, _, '!');     * bound('hi');     * // => 'hi fred!'     */    var bind = restParam(function(func, thisArg, partials) {      var bitmask = BIND_FLAG;      if (partials.length) {        var holders = replaceHolders(partials, bind.placeholder);        bitmask |= PARTIAL_FLAG;      }      return createWrapper(func, bitmask, thisArg, partials, holders);    });    /**     * Binds methods of an object to the object itself, overwriting the existing     * method. Method names may be specified as individual arguments or as arrays     * of method names. If no method names are provided all enumerable function     * properties, own and inherited, of `object` are bound.     *     * **Note:** This method does not set the "length" property of bound functions.     *     * @static     * @memberOf _     * @category Function     * @param {Object} object The object to bind and assign the bound methods to.     * @param {...(string|string[])} [methodNames] The object method names to bind,     *  specified as individual method names or arrays of method names.     * @returns {Object} Returns `object`.     * @example     *     * var view = {     *   'label': 'docs',     *   'onClick': function() {     *     console.log('clicked ' + this.label);     *   }     * };     *     * _.bindAll(view);     * jQuery('#docs').on('click', view.onClick);     * // => logs 'clicked docs' when the element is clicked     */    var bindAll = restParam(function(object, methodNames) {      methodNames = methodNames.length ? baseFlatten(methodNames) : functions(object);      var index = -1,          length = methodNames.length;      while (++index < length) {        var key = methodNames[index];        object[key] = createWrapper(object[key], BIND_FLAG, object);      }      return object;    });    /**     * Creates a function that invokes the method at `object[key]` and prepends     * any additional `_.bindKey` arguments to those provided to the bound function.     *     * This method differs from `_.bind` by allowing bound functions to reference     * methods that may be redefined or don't yet exist.     * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)     * for more details.     *     * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic     * builds, may be used as a placeholder for partially applied arguments.     *     * @static     * @memberOf _     * @category Function     * @param {Object} object The object the method belongs to.     * @param {string} key The key of the method.     * @param {...*} [partials] The arguments to be partially applied.     * @returns {Function} Returns the new bound function.     * @example     *     * var object = {     *   'user': 'fred',     *   'greet': function(greeting, punctuation) {     *     return greeting + ' ' + this.user + punctuation;     *   }     * };     *     * var bound = _.bindKey(object, 'greet', 'hi');     * bound('!');     * // => 'hi fred!'     *     * object.greet = function(greeting, punctuation) {     *   return greeting + 'ya ' + this.user + punctuation;     * };     *     * bound('!');     * // => 'hiya fred!'     *     * // using placeholders     * var bound = _.bindKey(object, 'greet', _, '!');     * bound('hi');     * // => 'hiya fred!'     */    var bindKey = restParam(function(object, key, partials) {      var bitmask = BIND_FLAG | BIND_KEY_FLAG;      if (partials.length) {        var holders = replaceHolders(partials, bindKey.placeholder);        bitmask |= PARTIAL_FLAG;      }      return createWrapper(key, bitmask, object, partials, holders);    });    /**     * Creates a function that accepts one or more arguments of `func` that when     * called either invokes `func` returning its result, if all `func` arguments     * have been provided, or returns a function that accepts one or more of the     * remaining `func` arguments, and so on. The arity of `func` may be specified     * if `func.length` is not sufficient.     *     * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,     * may be used as a placeholder for provided arguments.     *     * **Note:** This method does not set the "length" property of curried functions.     *     * @static     * @memberOf _     * @category Function     * @param {Function} func The function to curry.     * @param {number} [arity=func.length] The arity of `func`.     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.     * @returns {Function} Returns the new curried function.     * @example     *     * var abc = function(a, b, c) {     *   return [a, b, c];     * };     *     * var curried = _.curry(abc);     *     * curried(1)(2)(3);     * // => [1, 2, 3]     *     * curried(1, 2)(3);     * // => [1, 2, 3]     *     * curried(1, 2, 3);     * // => [1, 2, 3]     *     * // using placeholders     * curried(1)(_, 3)(2);     * // => [1, 2, 3]     */    var curry = createCurry(CURRY_FLAG);    /**     * This method is like `_.curry` except that arguments are applied to `func`     * in the manner of `_.partialRight` instead of `_.partial`.     *     * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic     * builds, may be used as a placeholder for provided arguments.     *     * **Note:** This method does not set the "length" property of curried functions.     *     * @static     * @memberOf _     * @category Function     * @param {Function} func The function to curry.     * @param {number} [arity=func.length] The arity of `func`.     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.     * @returns {Function} Returns the new curried function.     * @example     *     * var abc = function(a, b, c) {     *   return [a, b, c];     * };     *     * var curried = _.curryRight(abc);     *     * curried(3)(2)(1);     * // => [1, 2, 3]     *     * curried(2, 3)(1);     * // => [1, 2, 3]     *     * curried(1, 2, 3);     * // => [1, 2, 3]     *     * // using placeholders     * curried(3)(1, _)(2);     * // => [1, 2, 3]     */    var curryRight = createCurry(CURRY_RIGHT_FLAG);    /**     * Creates a debounced function that delays invoking `func` until after `wait`     * milliseconds have elapsed since the last time the debounced function was     * invoked. The debounced function comes with a `cancel` method to cancel     * delayed invocations. Provide an options object to indicate that `func`     * should be invoked on the leading and/or trailing edge of the `wait` timeout.     * Subsequent calls to the debounced function return the result of the last     * `func` invocation.     *     * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked     * on the trailing edge of the timeout only if the the debounced function is     * invoked more than once during the `wait` timeout.     *     * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)     * for details over the differences between `_.debounce` and `_.throttle`.     *     * @static     * @memberOf _     * @category Function     * @param {Function} func The function to debounce.     * @param {number} [wait=0] The number of milliseconds to delay.     * @param {Object} [options] The options object.     * @param {boolean} [options.leading=false] Specify invoking on the leading     *  edge of the timeout.     * @param {number} [options.maxWait] The maximum time `func` is allowed to be     *  delayed before it's invoked.     * @param {boolean} [options.trailing=true] Specify invoking on the trailing     *  edge of the timeout.     * @returns {Function} Returns the new debounced function.     * @example     *     * // avoid costly calculations while the window size is in flux     * jQuery(window).on('resize', _.debounce(calculateLayout, 150));     *     * // invoke `sendMail` when the click event is fired, debouncing subsequent calls     * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {     *   'leading': true,     *   'trailing': false     * }));     *     * // ensure `batchLog` is invoked once after 1 second of debounced calls     * var source = new EventSource('/stream');     * jQuery(source).on('message', _.debounce(batchLog, 250, {     *   'maxWait': 1000     * }));     *     * // cancel a debounced call     * var todoChanges = _.debounce(batchLog, 1000);     * Object.observe(models.todo, todoChanges);     *     * Object.observe(models, function(changes) {     *   if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) {     *     todoChanges.cancel();     *   }     * }, ['delete']);     *     * // ...at some point `models.todo` is changed     * models.todo.completed = true;     *     * // ...before 1 second has passed `models.todo` is deleted     * // which cancels the debounced `todoChanges` call     * delete models.todo;     */    function debounce(func, wait, options) {      var args,          maxTimeoutId,          result,          stamp,          thisArg,          timeoutId,          trailingCall,          lastCalled = 0,          maxWait = false,          trailing = true;      if (typeof func != 'function') {        throw new TypeError(FUNC_ERROR_TEXT);      }      wait = wait < 0 ? 0 : (+wait || 0);      if (options === true) {        var leading = true;        trailing = false;      } else if (isObject(options)) {        leading = !!options.leading;        maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait);        trailing = 'trailing' in options ? !!options.trailing : trailing;      }      function cancel() {        if (timeoutId) {          clearTimeout(timeoutId);        }        if (maxTimeoutId) {          clearTimeout(maxTimeoutId);        }        lastCalled = 0;        maxTimeoutId = timeoutId = trailingCall = undefined;      }      function complete(isCalled, id) {        if (id) {          clearTimeout(id);        }        maxTimeoutId = timeoutId = trailingCall = undefined;        if (isCalled) {          lastCalled = now();          result = func.apply(thisArg, args);          if (!timeoutId && !maxTimeoutId) {            args = thisArg = undefined;          }        }      }      function delayed() {        var remaining = wait - (now() - stamp);        if (remaining <= 0 || remaining > wait) {          complete(trailingCall, maxTimeoutId);        } else {          timeoutId = setTimeout(delayed, remaining);        }      }      function maxDelayed() {        complete(trailing, timeoutId);      }      function debounced() {        args = arguments;        stamp = now();        thisArg = this;        trailingCall = trailing && (timeoutId || !leading);        if (maxWait === false) {          var leadingCall = leading && !timeoutId;        } else {          if (!maxTimeoutId && !leading) {            lastCalled = stamp;          }          var remaining = maxWait - (stamp - lastCalled),              isCalled = remaining <= 0 || remaining > maxWait;          if (isCalled) {            if (maxTimeoutId) {              maxTimeoutId = clearTimeout(maxTimeoutId);            }            lastCalled = stamp;            result = func.apply(thisArg, args);          }          else if (!maxTimeoutId) {            maxTimeoutId = setTimeout(maxDelayed, remaining);          }        }        if (isCalled && timeoutId) {          timeoutId = clearTimeout(timeoutId);        }        else if (!timeoutId && wait !== maxWait) {          timeoutId = setTimeout(delayed, wait);        }        if (leadingCall) {          isCalled = true;          result = func.apply(thisArg, args);        }        if (isCalled && !timeoutId && !maxTimeoutId) {          args = thisArg = undefined;        }        return result;      }      debounced.cancel = cancel;      return debounced;    }    /**     * Defers invoking the `func` until the current call stack has cleared. Any     * additional arguments are provided to `func` when it's invoked.     *     * @static     * @memberOf _     * @category Function     * @param {Function} func The function to defer.     * @param {...*} [args] The arguments to invoke the function with.     * @returns {number} Returns the timer id.     * @example     *     * _.defer(function(text) {     *   console.log(text);     * }, 'deferred');     * // logs 'deferred' after one or more milliseconds     */    var defer = restParam(function(func, args) {      return baseDelay(func, 1, args);    });    /**     * Invokes `func` after `wait` milliseconds. Any additional arguments are     * provided to `func` when it's invoked.     *     * @static     * @memberOf _     * @category Function     * @param {Function} func The function to delay.     * @param {number} wait The number of milliseconds to delay invocation.     * @param {...*} [args] The arguments to invoke the function with.     * @returns {number} Returns the timer id.     * @example     *     * _.delay(function(text) {     *   console.log(text);     * }, 1000, 'later');     * // => logs 'later' after one second     */    var delay = restParam(function(func, wait, args) {      return baseDelay(func, wait, args);    });    /**     * Creates a function that returns the result of invoking the provided     * functions with the `this` binding of the created function, where each     * successive invocation is supplied the return value of the previous.     *     * @static     * @memberOf _     * @category Function     * @param {...Function} [funcs] Functions to invoke.     * @returns {Function} Returns the new function.     * @example     *     * function square(n) {     *   return n * n;     * }     *     * var addSquare = _.flow(_.add, square);     * addSquare(1, 2);     * // => 9     */    var flow = createFlow();    /**     * This method is like `_.flow` except that it creates a function that     * invokes the provided functions from right to left.     *     * @static     * @memberOf _     * @alias backflow, compose     * @category Function     * @param {...Function} [funcs] Functions to invoke.     * @returns {Function} Returns the new function.     * @example     *     * function square(n) {     *   return n * n;     * }     *     * var addSquare = _.flowRight(square, _.add);     * addSquare(1, 2);     * // => 9     */    var flowRight = createFlow(true);    /**     * Creates a function that memoizes the result of `func`. If `resolver` is     * provided it determines the cache key for storing the result based on the     * arguments provided to the memoized function. By default, the first argument     * provided to the memoized function is coerced to a string and used as the     * cache key. The `func` is invoked with the `this` binding of the memoized     * function.     *     * **Note:** The cache is exposed as the `cache` property on the memoized     * function. Its creation may be customized by replacing the `_.memoize.Cache`     * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object)     * method interface of `get`, `has`, and `set`.     *     * @static     * @memberOf _     * @category Function     * @param {Function} func The function to have its output memoized.     * @param {Function} [resolver] The function to resolve the cache key.     * @returns {Function} Returns the new memoizing function.     * @example     *     * var upperCase = _.memoize(function(string) {     *   return string.toUpperCase();     * });     *     * upperCase('fred');     * // => 'FRED'     *     * // modifying the result cache     * upperCase.cache.set('fred', 'BARNEY');     * upperCase('fred');     * // => 'BARNEY'     *     * // replacing `_.memoize.Cache`     * var object = { 'user': 'fred' };     * var other = { 'user': 'barney' };     * var identity = _.memoize(_.identity);     *     * identity(object);     * // => { 'user': 'fred' }     * identity(other);     * // => { 'user': 'fred' }     *     * _.memoize.Cache = WeakMap;     * var identity = _.memoize(_.identity);     *     * identity(object);     * // => { 'user': 'fred' }     * identity(other);     * // => { 'user': 'barney' }     */    function memoize(func, resolver) {      if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {        throw new TypeError(FUNC_ERROR_TEXT);      }      var memoized = function() {        var args = arguments,            key = resolver ? resolver.apply(this, args) : args[0],            cache = memoized.cache;        if (cache.has(key)) {          return cache.get(key);        }        var result = func.apply(this, args);        memoized.cache = cache.set(key, result);        return result;      };      memoized.cache = new memoize.Cache;      return memoized;    }    /**     * Creates a function that runs each argument through a corresponding     * transform function.     *     * @static     * @memberOf _     * @category Function     * @param {Function} func The function to wrap.     * @param {...(Function|Function[])} [transforms] The functions to transform     * arguments, specified as individual functions or arrays of functions.     * @returns {Function} Returns the new function.     * @example     *     * function doubled(n) {     *   return n * 2;     * }     *     * function square(n) {     *   return n * n;     * }     *     * var modded = _.modArgs(function(x, y) {     *   return [x, y];     * }, square, doubled);     *     * modded(1, 2);     * // => [1, 4]     *     * modded(5, 10);     * // => [25, 20]     */    var modArgs = restParam(function(func, transforms) {      transforms = baseFlatten(transforms);      if (typeof func != 'function' || !arrayEvery(transforms, baseIsFunction)) {        throw new TypeError(FUNC_ERROR_TEXT);      }      var length = transforms.length;      return restParam(function(args) {        var index = nativeMin(args.length, length);        while (index--) {          args[index] = transforms[index](args[index]);        }        return func.apply(this, args);      });    });    /**     * Creates a function that negates the result of the predicate `func`. The     * `func` predicate is invoked with the `this` binding and arguments of the     * created function.     *     * @static     * @memberOf _     * @category Function     * @param {Function} predicate The predicate to negate.     * @returns {Function} Returns the new function.     * @example     *     * function isEven(n) {     *   return n % 2 == 0;     * }     *     * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));     * // => [1, 3, 5]     */    function negate(predicate) {      if (typeof predicate != 'function') {        throw new TypeError(FUNC_ERROR_TEXT);      }      return function() {        return !predicate.apply(this, arguments);      };    }    /**     * Creates a function that is restricted to invoking `func` once. Repeat calls     * to the function return the value of the first call. The `func` is invoked     * with the `this` binding and arguments of the created function.     *     * @static     * @memberOf _     * @category Function     * @param {Function} func The function to restrict.     * @returns {Function} Returns the new restricted function.     * @example     *     * var initialize = _.once(createApplication);     * initialize();     * initialize();     * // `initialize` invokes `createApplication` once     */    function once(func) {      return before(2, func);    }    /**     * Creates a function that invokes `func` with `partial` arguments prepended     * to those provided to the new function. This method is like `_.bind` except     * it does **not** alter the `this` binding.     *     * The `_.partial.placeholder` value, which defaults to `_` in monolithic     * builds, may be used as a placeholder for partially applied arguments.     *     * **Note:** This method does not set the "length" property of partially     * applied functions.     *     * @static     * @memberOf _     * @category Function     * @param {Function} func The function to partially apply arguments to.     * @param {...*} [partials] The arguments to be partially applied.     * @returns {Function} Returns the new partially applied function.     * @example     *     * var greet = function(greeting, name) {     *   return greeting + ' ' + name;     * };     *     * var sayHelloTo = _.partial(greet, 'hello');     * sayHelloTo('fred');     * // => 'hello fred'     *     * // using placeholders     * var greetFred = _.partial(greet, _, 'fred');     * greetFred('hi');     * // => 'hi fred'     */    var partial = createPartial(PARTIAL_FLAG);    /**     * This method is like `_.partial` except that partially applied arguments     * are appended to those provided to the new function.     *     * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic     * builds, may be used as a placeholder for partially applied arguments.     *     * **Note:** This method does not set the "length" property of partially     * applied functions.     *     * @static     * @memberOf _     * @category Function     * @param {Function} func The function to partially apply arguments to.     * @param {...*} [partials] The arguments to be partially applied.     * @returns {Function} Returns the new partially applied function.     * @example     *     * var greet = function(greeting, name) {     *   return greeting + ' ' + name;     * };     *     * var greetFred = _.partialRight(greet, 'fred');     * greetFred('hi');     * // => 'hi fred'     *     * // using placeholders     * var sayHelloTo = _.partialRight(greet, 'hello', _);     * sayHelloTo('fred');     * // => 'hello fred'     */    var partialRight = createPartial(PARTIAL_RIGHT_FLAG);    /**     * Creates a function that invokes `func` with arguments arranged according     * to the specified indexes where the argument value at the first index is     * provided as the first argument, the argument value at the second index is     * provided as the second argument, and so on.     *     * @static     * @memberOf _     * @category Function     * @param {Function} func The function to rearrange arguments for.     * @param {...(number|number[])} indexes The arranged argument indexes,     *  specified as individual indexes or arrays of indexes.     * @returns {Function} Returns the new function.     * @example     *     * var rearged = _.rearg(function(a, b, c) {     *   return [a, b, c];     * }, 2, 0, 1);     *     * rearged('b', 'c', 'a')     * // => ['a', 'b', 'c']     *     * var map = _.rearg(_.map, [1, 0]);     * map(function(n) {     *   return n * 3;     * }, [1, 2, 3]);     * // => [3, 6, 9]     */    var rearg = restParam(function(func, indexes) {      return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes));    });    /**     * Creates a function that invokes `func` with the `this` binding of the     * created function and arguments from `start` and beyond provided as an array.     *     * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/Web/JavaScript/Reference/Functions/rest_parameters).     *     * @static     * @memberOf _     * @category Function     * @param {Function} func The function to apply a rest parameter to.     * @param {number} [start=func.length-1] The start position of the rest parameter.     * @returns {Function} Returns the new function.     * @example     *     * var say = _.restParam(function(what, names) {     *   return what + ' ' + _.initial(names).join(', ') +     *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);     * });     *     * say('hello', 'fred', 'barney', 'pebbles');     * // => 'hello fred, barney, & pebbles'     */    function restParam(func, start) {      if (typeof func != 'function') {        throw new TypeError(FUNC_ERROR_TEXT);      }      start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0);      return function() {        var args = arguments,            index = -1,            length = nativeMax(args.length - start, 0),            rest = Array(length);        while (++index < length) {          rest[index] = args[start + index];        }        switch (start) {          case 0: return func.call(this, rest);          case 1: return func.call(this, args[0], rest);          case 2: return func.call(this, args[0], args[1], rest);        }        var otherArgs = Array(start + 1);        index = -1;        while (++index < start) {          otherArgs[index] = args[index];        }        otherArgs[start] = rest;        return func.apply(this, otherArgs);      };    }    /**     * Creates a function that invokes `func` with the `this` binding of the created     * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3).     *     * **Note:** This method is based on the [spread operator](https://developer.mozilla.org/Web/JavaScript/Reference/Operators/Spread_operator).     *     * @static     * @memberOf _     * @category Function     * @param {Function} func The function to spread arguments over.     * @returns {Function} Returns the new function.     * @example     *     * var say = _.spread(function(who, what) {     *   return who + ' says ' + what;     * });     *     * say(['fred', 'hello']);     * // => 'fred says hello'     *     * // with a Promise     * var numbers = Promise.all([     *   Promise.resolve(40),     *   Promise.resolve(36)     * ]);     *     * numbers.then(_.spread(function(x, y) {     *   return x + y;     * }));     * // => a Promise of 76     */    function spread(func) {      if (typeof func != 'function') {        throw new TypeError(FUNC_ERROR_TEXT);      }      return function(array) {        return func.apply(this, array);      };    }    /**     * Creates a throttled function that only invokes `func` at most once per     * every `wait` milliseconds. The throttled function comes with a `cancel`     * method to cancel delayed invocations. Provide an options object to indicate     * that `func` should be invoked on the leading and/or trailing edge of the     * `wait` timeout. Subsequent calls to the throttled function return the     * result of the last `func` call.     *     * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked     * on the trailing edge of the timeout only if the the throttled function is     * invoked more than once during the `wait` timeout.     *     * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)     * for details over the differences between `_.throttle` and `_.debounce`.     *     * @static     * @memberOf _     * @category Function     * @param {Function} func The function to throttle.     * @param {number} [wait=0] The number of milliseconds to throttle invocations to.     * @param {Object} [options] The options object.     * @param {boolean} [options.leading=true] Specify invoking on the leading     *  edge of the timeout.     * @param {boolean} [options.trailing=true] Specify invoking on the trailing     *  edge of the timeout.     * @returns {Function} Returns the new throttled function.     * @example     *     * // avoid excessively updating the position while scrolling     * jQuery(window).on('scroll', _.throttle(updatePosition, 100));     *     * // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes     * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {     *   'trailing': false     * }));     *     * // cancel a trailing throttled call     * jQuery(window).on('popstate', throttled.cancel);     */    function throttle(func, wait, options) {      var leading = true,          trailing = true;      if (typeof func != 'function') {        throw new TypeError(FUNC_ERROR_TEXT);      }      if (options === false) {        leading = false;      } else if (isObject(options)) {        leading = 'leading' in options ? !!options.leading : leading;        trailing = 'trailing' in options ? !!options.trailing : trailing;      }      return debounce(func, wait, { 'leading': leading, 'maxWait': +wait, 'trailing': trailing });    }    /**     * Creates a function that provides `value` to the wrapper function as its     * first argument. Any additional arguments provided to the function are     * appended to those provided to the wrapper function. The wrapper is invoked     * with the `this` binding of the created function.     *     * @static     * @memberOf _     * @category Function     * @param {*} value The value to wrap.     * @param {Function} wrapper The wrapper function.     * @returns {Function} Returns the new function.     * @example     *     * var p = _.wrap(_.escape, function(func, text) {     *   return '<p>' + func(text) + '</p>';     * });     *     * p('fred, barney, & pebbles');     * // => '<p>fred, barney, & pebbles</p>'     */    function wrap(value, wrapper) {      wrapper = wrapper == null ? identity : wrapper;      return createWrapper(wrapper, PARTIAL_FLAG, undefined, [value], []);    }    /*------------------------------------------------------------------------*/    /**     * Creates a clone of `value`. If `isDeep` is `true` nested objects are cloned,     * otherwise they are assigned by reference. If `customizer` is provided it's     * invoked to produce the cloned values. If `customizer` returns `undefined`     * cloning is handled by the method instead. The `customizer` is bound to     * `thisArg` and invoked with up to three argument; (value [, index|key, object]).     *     * **Note:** This method is loosely based on the     * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm).     * The enumerable properties of `arguments` objects and objects created by     * constructors other than `Object` are cloned to plain `Object` objects. An     * empty object is returned for uncloneable values such as functions, DOM nodes,     * Maps, Sets, and WeakMaps.     *     * @static     * @memberOf _     * @category Lang     * @param {*} value The value to clone.     * @param {boolean} [isDeep] Specify a deep clone.     * @param {Function} [customizer] The function to customize cloning values.     * @param {*} [thisArg] The `this` binding of `customizer`.     * @returns {*} Returns the cloned value.     * @example     *     * var users = [     *   { 'user': 'barney' },     *   { 'user': 'fred' }     * ];     *     * var shallow = _.clone(users);     * shallow[0] === users[0];     * // => true     *     * var deep = _.clone(users, true);     * deep[0] === users[0];     * // => false     *     * // using a customizer callback     * var el = _.clone(document.body, function(value) {     *   if (_.isElement(value)) {     *     return value.cloneNode(false);     *   }     * });     *     * el === document.body     * // => false     * el.nodeName     * // => BODY     * el.childNodes.length;     * // => 0     */    function clone(value, isDeep, customizer, thisArg) {      if (isDeep && typeof isDeep != 'boolean' && isIterateeCall(value, isDeep, customizer)) {        isDeep = false;      }      else if (typeof isDeep == 'function') {        thisArg = customizer;        customizer = isDeep;        isDeep = false;      }      return typeof customizer == 'function'        ? baseClone(value, isDeep, bindCallback(customizer, thisArg, 3))        : baseClone(value, isDeep);    }    /**     * Creates a deep clone of `value`. If `customizer` is provided it's invoked     * to produce the cloned values. If `customizer` returns `undefined` cloning     * is handled by the method instead. The `customizer` is bound to `thisArg`     * and invoked with up to three argument; (value [, index|key, object]).     *     * **Note:** This method is loosely based on the     * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm).     * The enumerable properties of `arguments` objects and objects created by     * constructors other than `Object` are cloned to plain `Object` objects. An     * empty object is returned for uncloneable values such as functions, DOM nodes,     * Maps, Sets, and WeakMaps.     *     * @static     * @memberOf _     * @category Lang     * @param {*} value The value to deep clone.     * @param {Function} [customizer] The function to customize cloning values.     * @param {*} [thisArg] The `this` binding of `customizer`.     * @returns {*} Returns the deep cloned value.     * @example     *     * var users = [     *   { 'user': 'barney' },     *   { 'user': 'fred' }     * ];     *     * var deep = _.cloneDeep(users);     * deep[0] === users[0];     * // => false     *     * // using a customizer callback     * var el = _.cloneDeep(document.body, function(value) {     *   if (_.isElement(value)) {     *     return value.cloneNode(true);     *   }     * });     *     * el === document.body     * // => false     * el.nodeName     * // => BODY     * el.childNodes.length;     * // => 20     */    function cloneDeep(value, customizer, thisArg) {      return typeof customizer == 'function'        ? baseClone(value, true, bindCallback(customizer, thisArg, 3))        : baseClone(value, true);    }    /**     * Checks if `value` is greater than `other`.     *     * @static     * @memberOf _     * @category Lang     * @param {*} value The value to compare.     * @param {*} other The other value to compare.     * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`.     * @example     *     * _.gt(3, 1);     * // => true     *     * _.gt(3, 3);     * // => false     *     * _.gt(1, 3);     * // => false     */    function gt(value, other) {      return value > other;    }    /**     * Checks if `value` is greater than or equal to `other`.     *     * @static     * @memberOf _     * @category Lang     * @param {*} value The value to compare.     * @param {*} other The other value to compare.     * @returns {boolean} Returns `true` if `value` is greater than or equal to `other`, else `false`.     * @example     *     * _.gte(3, 1);     * // => true     *     * _.gte(3, 3);     * // => true     *     * _.gte(1, 3);     * // => false     */    function gte(value, other) {      return value >= other;    }    /**     * Checks if `value` is classified as an `arguments` object.     *     * @static     * @memberOf _     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.     * @example     *     * _.isArguments(function() { return arguments; }());     * // => true     *     * _.isArguments([1, 2, 3]);     * // => false     */    function isArguments(value) {      return isObjectLike(value) && isArrayLike(value) &&        hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee');    }    /**     * Checks if `value` is classified as an `Array` object.     *     * @static     * @memberOf _     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.     * @example     *     * _.isArray([1, 2, 3]);     * // => true     *     * _.isArray(function() { return arguments; }());     * // => false     */    var isArray = nativeIsArray || function(value) {      return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;    };    /**     * Checks if `value` is classified as a boolean primitive or object.     *     * @static     * @memberOf _     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.     * @example     *     * _.isBoolean(false);     * // => true     *     * _.isBoolean(null);     * // => false     */    function isBoolean(value) {      return value === true || value === false || (isObjectLike(value) && objToString.call(value) == boolTag);    }    /**     * Checks if `value` is classified as a `Date` object.     *     * @static     * @memberOf _     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.     * @example     *     * _.isDate(new Date);     * // => true     *     * _.isDate('Mon April 23 2012');     * // => false     */    function isDate(value) {      return isObjectLike(value) && objToString.call(value) == dateTag;    }    /**     * Checks if `value` is a DOM element.     *     * @static     * @memberOf _     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.     * @example     *     * _.isElement(document.body);     * // => true     *     * _.isElement('<body>');     * // => false     */    function isElement(value) {      return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value);    }    /**     * Checks if `value` is empty. A value is considered empty unless it's an     * `arguments` object, array, string, or jQuery-like collection with a length     * greater than `0` or an object with own enumerable properties.     *     * @static     * @memberOf _     * @category Lang     * @param {Array|Object|string} value The value to inspect.     * @returns {boolean} Returns `true` if `value` is empty, else `false`.     * @example     *     * _.isEmpty(null);     * // => true     *     * _.isEmpty(true);     * // => true     *     * _.isEmpty(1);     * // => true     *     * _.isEmpty([1, 2, 3]);     * // => false     *     * _.isEmpty({ 'a': 1 });     * // => false     */    function isEmpty(value) {      if (value == null) {        return true;      }      if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) ||          (isObjectLike(value) && isFunction(value.splice)))) {        return !value.length;      }      return !keys(value).length;    }    /**     * Performs a deep comparison between two values to determine if they are     * equivalent. If `customizer` is provided it's invoked to compare values.     * If `customizer` returns `undefined` comparisons are handled by the method     * instead. The `customizer` is bound to `thisArg` and invoked with up to     * three arguments: (value, other [, index|key]).     *     * **Note:** This method supports comparing arrays, booleans, `Date` objects,     * numbers, `Object` objects, regexes, and strings. Objects are compared by     * their own, not inherited, enumerable properties. Functions and DOM nodes     * are **not** supported. Provide a customizer function to extend support     * for comparing other values.     *     * @static     * @memberOf _     * @alias eq     * @category Lang     * @param {*} value The value to compare.     * @param {*} other The other value to compare.     * @param {Function} [customizer] The function to customize value comparisons.     * @param {*} [thisArg] The `this` binding of `customizer`.     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.     * @example     *     * var object = { 'user': 'fred' };     * var other = { 'user': 'fred' };     *     * object == other;     * // => false     *     * _.isEqual(object, other);     * // => true     *     * // using a customizer callback     * var array = ['hello', 'goodbye'];     * var other = ['hi', 'goodbye'];     *     * _.isEqual(array, other, function(value, other) {     *   if (_.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/)) {     *     return true;     *   }     * });     * // => true     */    function isEqual(value, other, customizer, thisArg) {      customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined;      var result = customizer ? customizer(value, other) : undefined;      return  result === undefined ? baseIsEqual(value, other, customizer) : !!result;    }    /**     * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,     * `SyntaxError`, `TypeError`, or `URIError` object.     *     * @static     * @memberOf _     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is an error object, else `false`.     * @example     *     * _.isError(new Error);     * // => true     *     * _.isError(Error);     * // => false     */    function isError(value) {      return isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag;    }    /**     * Checks if `value` is a finite primitive number.     *     * **Note:** This method is based on [`Number.isFinite`](http://ecma-international.org/ecma-262/6.0/#sec-number.isfinite).     *     * @static     * @memberOf _     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.     * @example     *     * _.isFinite(10);     * // => true     *     * _.isFinite('10');     * // => false     *     * _.isFinite(true);     * // => false     *     * _.isFinite(Object(10));     * // => false     *     * _.isFinite(Infinity);     * // => false     */    function isFinite(value) {      return typeof value == 'number' && nativeIsFinite(value);    }    /**     * Checks if `value` is classified as a `Function` object.     *     * @static     * @memberOf _     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.     * @example     *     * _.isFunction(_);     * // => true     *     * _.isFunction(/abc/);     * // => false     */    function isFunction(value) {      // The use of `Object#toString` avoids issues with the `typeof` operator      // in older versions of Chrome and Safari which return 'function' for regexes      // and Safari 8 which returns 'object' for typed array constructors.      return isObject(value) && objToString.call(value) == funcTag;    }    /**     * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.     * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)     *     * @static     * @memberOf _     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is an object, else `false`.     * @example     *     * _.isObject({});     * // => true     *     * _.isObject([1, 2, 3]);     * // => true     *     * _.isObject(1);     * // => false     */    function isObject(value) {      // Avoid a V8 JIT bug in Chrome 19-20.      // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.      var type = typeof value;      return !!value && (type == 'object' || type == 'function');    }    /**     * Performs a deep comparison between `object` and `source` to determine if     * `object` contains equivalent property values. If `customizer` is provided     * it's invoked to compare values. If `customizer` returns `undefined`     * comparisons are handled by the method instead. The `customizer` is bound     * to `thisArg` and invoked with three arguments: (value, other, index|key).     *     * **Note:** This method supports comparing properties of arrays, booleans,     * `Date` objects, numbers, `Object` objects, regexes, and strings. Functions     * and DOM nodes are **not** supported. Provide a customizer function to extend     * support for comparing other values.     *     * @static     * @memberOf _     * @category Lang     * @param {Object} object The object to inspect.     * @param {Object} source The object of property values to match.     * @param {Function} [customizer] The function to customize value comparisons.     * @param {*} [thisArg] The `this` binding of `customizer`.     * @returns {boolean} Returns `true` if `object` is a match, else `false`.     * @example     *     * var object = { 'user': 'fred', 'age': 40 };     *     * _.isMatch(object, { 'age': 40 });     * // => true     *     * _.isMatch(object, { 'age': 36 });     * // => false     *     * // using a customizer callback     * var object = { 'greeting': 'hello' };     * var source = { 'greeting': 'hi' };     *     * _.isMatch(object, source, function(value, other) {     *   return _.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/) || undefined;     * });     * // => true     */    function isMatch(object, source, customizer, thisArg) {      customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined;      return baseIsMatch(object, getMatchData(source), customizer);    }    /**     * Checks if `value` is `NaN`.     *     * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4)     * which returns `true` for `undefined` and other non-numeric values.     *     * @static     * @memberOf _     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.     * @example     *     * _.isNaN(NaN);     * // => true     *     * _.isNaN(new Number(NaN));     * // => true     *     * isNaN(undefined);     * // => true     *     * _.isNaN(undefined);     * // => false     */    function isNaN(value) {      // An `NaN` primitive is the only value that is not equal to itself.      // Perform the `toStringTag` check first to avoid errors with some host objects in IE.      return isNumber(value) && value != +value;    }    /**     * Checks if `value` is a native function.     *     * @static     * @memberOf _     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a native function, else `false`.     * @example     *     * _.isNative(Array.prototype.push);     * // => true     *     * _.isNative(_);     * // => false     */    function isNative(value) {      if (value == null) {        return false;      }      if (isFunction(value)) {        return reIsNative.test(fnToString.call(value));      }      return isObjectLike(value) && (isHostObject(value) ? reIsNative : reIsHostCtor).test(value);    }    /**     * Checks if `value` is `null`.     *     * @static     * @memberOf _     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is `null`, else `false`.     * @example     *     * _.isNull(null);     * // => true     *     * _.isNull(void 0);     * // => false     */    function isNull(value) {      return value === null;    }    /**     * Checks if `value` is classified as a `Number` primitive or object.     *     * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified     * as numbers, use the `_.isFinite` method.     *     * @static     * @memberOf _     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.     * @example     *     * _.isNumber(8.4);     * // => true     *     * _.isNumber(NaN);     * // => true     *     * _.isNumber('8.4');     * // => false     */    function isNumber(value) {      return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag);    }    /**     * Checks if `value` is a plain object, that is, an object created by the     * `Object` constructor or one with a `[[Prototype]]` of `null`.     *     * **Note:** This method assumes objects created by the `Object` constructor     * have no inherited enumerable properties.     *     * @static     * @memberOf _     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.     * @example     *     * function Foo() {     *   this.a = 1;     * }     *     * _.isPlainObject(new Foo);     * // => false     *     * _.isPlainObject([1, 2, 3]);     * // => false     *     * _.isPlainObject({ 'x': 0, 'y': 0 });     * // => true     *     * _.isPlainObject(Object.create(null));     * // => true     */    function isPlainObject(value) {      var Ctor;      // Exit early for non `Object` objects.      if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isHostObject(value) && !isArguments(value)) ||          (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) {        return false;      }      // IE < 9 iterates inherited properties before own properties. If the first      // iterated property is an object's own property then there are no inherited      // enumerable properties.      var result;      if (lodash.support.ownLast) {        baseForIn(value, function(subValue, key, object) {          result = hasOwnProperty.call(object, key);          return false;        });        return result !== false;      }      // In most environments an object's own properties are iterated before      // its inherited properties. If the last iterated property is an object's      // own property then there are no inherited enumerable properties.      baseForIn(value, function(subValue, key) {        result = key;      });      return result === undefined || hasOwnProperty.call(value, result);    }    /**     * Checks if `value` is classified as a `RegExp` object.     *     * @static     * @memberOf _     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.     * @example     *     * _.isRegExp(/abc/);     * // => true     *     * _.isRegExp('/abc/');     * // => false     */    function isRegExp(value) {      return isObject(value) && objToString.call(value) == regexpTag;    }    /**     * Checks if `value` is classified as a `String` primitive or object.     *     * @static     * @memberOf _     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.     * @example     *     * _.isString('abc');     * // => true     *     * _.isString(1);     * // => false     */    function isString(value) {      return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag);    }    /**     * Checks if `value` is classified as a typed array.     *     * @static     * @memberOf _     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.     * @example     *     * _.isTypedArray(new Uint8Array);     * // => true     *     * _.isTypedArray([]);     * // => false     */    function isTypedArray(value) {      return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];    }    /**     * Checks if `value` is `undefined`.     *     * @static     * @memberOf _     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.     * @example     *     * _.isUndefined(void 0);     * // => true     *     * _.isUndefined(null);     * // => false     */    function isUndefined(value) {      return value === undefined;    }    /**     * Checks if `value` is less than `other`.     *     * @static     * @memberOf _     * @category Lang     * @param {*} value The value to compare.     * @param {*} other The other value to compare.     * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`.     * @example     *     * _.lt(1, 3);     * // => true     *     * _.lt(3, 3);     * // => false     *     * _.lt(3, 1);     * // => false     */    function lt(value, other) {      return value < other;    }    /**     * Checks if `value` is less than or equal to `other`.     *     * @static     * @memberOf _     * @category Lang     * @param {*} value The value to compare.     * @param {*} other The other value to compare.     * @returns {boolean} Returns `true` if `value` is less than or equal to `other`, else `false`.     * @example     *     * _.lte(1, 3);     * // => true     *     * _.lte(3, 3);     * // => true     *     * _.lte(3, 1);     * // => false     */    function lte(value, other) {      return value <= other;    }    /**     * Converts `value` to an array.     *     * @static     * @memberOf _     * @category Lang     * @param {*} value The value to convert.     * @returns {Array} Returns the converted array.     * @example     *     * (function() {     *   return _.toArray(arguments).slice(1);     * }(1, 2, 3));     * // => [2, 3]     */    function toArray(value) {      var length = value ? getLength(value) : 0;      if (!isLength(length)) {        return values(value);      }      if (!length) {        return [];      }      return (lodash.support.unindexedChars && isString(value))        ? value.split('')        : arrayCopy(value);    }    /**     * Converts `value` to a plain object flattening inherited enumerable     * properties of `value` to own properties of the plain object.     *     * @static     * @memberOf _     * @category Lang     * @param {*} value The value to convert.     * @returns {Object} Returns the converted plain object.     * @example     *     * function Foo() {     *   this.b = 2;     * }     *     * Foo.prototype.c = 3;     *     * _.assign({ 'a': 1 }, new Foo);     * // => { 'a': 1, 'b': 2 }     *     * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));     * // => { 'a': 1, 'b': 2, 'c': 3 }     */    function toPlainObject(value) {      return baseCopy(value, keysIn(value));    }    /*------------------------------------------------------------------------*/    /**     * Recursively merges own enumerable properties of the source object(s), that     * don't resolve to `undefined` into the destination object. Subsequent sources     * overwrite property assignments of previous sources. If `customizer` is     * provided it's invoked to produce the merged values of the destination and     * source properties. If `customizer` returns `undefined` merging is handled     * by the method instead. The `customizer` is bound to `thisArg` and invoked     * with five arguments: (objectValue, sourceValue, key, object, source).     *     * @static     * @memberOf _     * @category Object     * @param {Object} object The destination object.     * @param {...Object} [sources] The source objects.     * @param {Function} [customizer] The function to customize assigned values.     * @param {*} [thisArg] The `this` binding of `customizer`.     * @returns {Object} Returns `object`.     * @example     *     * var users = {     *   'data': [{ 'user': 'barney' }, { 'user': 'fred' }]     * };     *     * var ages = {     *   'data': [{ 'age': 36 }, { 'age': 40 }]     * };     *     * _.merge(users, ages);     * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }     *     * // using a customizer callback     * var object = {     *   'fruits': ['apple'],     *   'vegetables': ['beet']     * };     *     * var other = {     *   'fruits': ['banana'],     *   'vegetables': ['carrot']     * };     *     * _.merge(object, other, function(a, b) {     *   if (_.isArray(a)) {     *     return a.concat(b);     *   }     * });     * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }     */    var merge = createAssigner(baseMerge);    /**     * Assigns own enumerable properties of source object(s) to the destination     * object. Subsequent sources overwrite property assignments of previous sources.     * If `customizer` is provided it's invoked to produce the assigned values.     * The `customizer` is bound to `thisArg` and invoked with five arguments:     * (objectValue, sourceValue, key, object, source).     *     * **Note:** This method mutates `object` and is based on     * [`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.assign).     *     * @static     * @memberOf _     * @alias extend     * @category Object     * @param {Object} object The destination object.     * @param {...Object} [sources] The source objects.     * @param {Function} [customizer] The function to customize assigned values.     * @param {*} [thisArg] The `this` binding of `customizer`.     * @returns {Object} Returns `object`.     * @example     *     * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' });     * // => { 'user': 'fred', 'age': 40 }     *     * // using a customizer callback     * var defaults = _.partialRight(_.assign, function(value, other) {     *   return _.isUndefined(value) ? other : value;     * });     *     * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });     * // => { 'user': 'barney', 'age': 36 }     */    var assign = createAssigner(function(object, source, customizer) {      return customizer        ? assignWith(object, source, customizer)        : baseAssign(object, source);    });    /**     * Creates an object that inherits from the given `prototype` object. If a     * `properties` object is provided its own enumerable properties are assigned     * to the created object.     *     * @static     * @memberOf _     * @category Object     * @param {Object} prototype The object to inherit from.     * @param {Object} [properties] The properties to assign to the object.     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.     * @returns {Object} Returns the new object.     * @example     *     * function Shape() {     *   this.x = 0;     *   this.y = 0;     * }     *     * function Circle() {     *   Shape.call(this);     * }     *     * Circle.prototype = _.create(Shape.prototype, {     *   'constructor': Circle     * });     *     * var circle = new Circle;     * circle instanceof Circle;     * // => true     *     * circle instanceof Shape;     * // => true     */    function create(prototype, properties, guard) {      var result = baseCreate(prototype);      if (guard && isIterateeCall(prototype, properties, guard)) {        properties = undefined;      }      return properties ? baseAssign(result, properties) : result;    }    /**     * Assigns own enumerable properties of source object(s) to the destination     * object for all destination properties that resolve to `undefined`. Once a     * property is set, additional values of the same property are ignored.     *     * **Note:** This method mutates `object`.     *     * @static     * @memberOf _     * @category Object     * @param {Object} object The destination object.     * @param {...Object} [sources] The source objects.     * @returns {Object} Returns `object`.     * @example     *     * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });     * // => { 'user': 'barney', 'age': 36 }     */    var defaults = createDefaults(assign, assignDefaults);    /**     * This method is like `_.defaults` except that it recursively assigns     * default properties.     *     * **Note:** This method mutates `object`.     *     * @static     * @memberOf _     * @category Object     * @param {Object} object The destination object.     * @param {...Object} [sources] The source objects.     * @returns {Object} Returns `object`.     * @example     *     * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } });     * // => { 'user': { 'name': 'barney', 'age': 36 } }     *     */    var defaultsDeep = createDefaults(merge, mergeDefaults);    /**     * This method is like `_.find` except that it returns the key of the first     * element `predicate` returns truthy for instead of the element itself.     *     * If a property name is provided for `predicate` the created `_.property`     * style callback returns the property value of the given element.     *     * If a value is also provided for `thisArg` the created `_.matchesProperty`     * style callback returns `true` for elements that have a matching property     * value, else `false`.     *     * If an object is provided for `predicate` the created `_.matches` style     * callback returns `true` for elements that have the properties of the given     * object, else `false`.     *     * @static     * @memberOf _     * @category Object     * @param {Object} object The object to search.     * @param {Function|Object|string} [predicate=_.identity] The function invoked     *  per iteration.     * @param {*} [thisArg] The `this` binding of `predicate`.     * @returns {string|undefined} Returns the key of the matched element, else `undefined`.     * @example     *     * var users = {     *   'barney':  { 'age': 36, 'active': true },     *   'fred':    { 'age': 40, 'active': false },     *   'pebbles': { 'age': 1,  'active': true }     * };     *     * _.findKey(users, function(chr) {     *   return chr.age < 40;     * });     * // => 'barney' (iteration order is not guaranteed)     *     * // using the `_.matches` callback shorthand     * _.findKey(users, { 'age': 1, 'active': true });     * // => 'pebbles'     *     * // using the `_.matchesProperty` callback shorthand     * _.findKey(users, 'active', false);     * // => 'fred'     *     * // using the `_.property` callback shorthand     * _.findKey(users, 'active');     * // => 'barney'     */    var findKey = createFindKey(baseForOwn);    /**     * This method is like `_.findKey` except that it iterates over elements of     * a collection in the opposite order.     *     * If a property name is provided for `predicate` the created `_.property`     * style callback returns the property value of the given element.     *     * If a value is also provided for `thisArg` the created `_.matchesProperty`     * style callback returns `true` for elements that have a matching property     * value, else `false`.     *     * If an object is provided for `predicate` the created `_.matches` style     * callback returns `true` for elements that have the properties of the given     * object, else `false`.     *     * @static     * @memberOf _     * @category Object     * @param {Object} object The object to search.     * @param {Function|Object|string} [predicate=_.identity] The function invoked     *  per iteration.     * @param {*} [thisArg] The `this` binding of `predicate`.     * @returns {string|undefined} Returns the key of the matched element, else `undefined`.     * @example     *     * var users = {     *   'barney':  { 'age': 36, 'active': true },     *   'fred':    { 'age': 40, 'active': false },     *   'pebbles': { 'age': 1,  'active': true }     * };     *     * _.findLastKey(users, function(chr) {     *   return chr.age < 40;     * });     * // => returns `pebbles` assuming `_.findKey` returns `barney`     *     * // using the `_.matches` callback shorthand     * _.findLastKey(users, { 'age': 36, 'active': true });     * // => 'barney'     *     * // using the `_.matchesProperty` callback shorthand     * _.findLastKey(users, 'active', false);     * // => 'fred'     *     * // using the `_.property` callback shorthand     * _.findLastKey(users, 'active');     * // => 'pebbles'     */    var findLastKey = createFindKey(baseForOwnRight);    /**     * Iterates over own and inherited enumerable properties of an object invoking     * `iteratee` for each property. The `iteratee` is bound to `thisArg` and invoked     * with three arguments: (value, key, object). Iteratee functions may exit     * iteration early by explicitly returning `false`.     *     * @static     * @memberOf _     * @category Object     * @param {Object} object The object to iterate over.     * @param {Function} [iteratee=_.identity] The function invoked per iteration.     * @param {*} [thisArg] The `this` binding of `iteratee`.     * @returns {Object} Returns `object`.     * @example     *     * function Foo() {     *   this.a = 1;     *   this.b = 2;     * }     *     * Foo.prototype.c = 3;     *     * _.forIn(new Foo, function(value, key) {     *   console.log(key);     * });     * // => logs 'a', 'b', and 'c' (iteration order is not guaranteed)     */    var forIn = createForIn(baseFor);    /**     * This method is like `_.forIn` except that it iterates over properties of     * `object` in the opposite order.     *     * @static     * @memberOf _     * @category Object     * @param {Object} object The object to iterate over.     * @param {Function} [iteratee=_.identity] The function invoked per iteration.     * @param {*} [thisArg] The `this` binding of `iteratee`.     * @returns {Object} Returns `object`.     * @example     *     * function Foo() {     *   this.a = 1;     *   this.b = 2;     * }     *     * Foo.prototype.c = 3;     *     * _.forInRight(new Foo, function(value, key) {     *   console.log(key);     * });     * // => logs 'c', 'b', and 'a' assuming `_.forIn ` logs 'a', 'b', and 'c'     */    var forInRight = createForIn(baseForRight);    /**     * Iterates over own enumerable properties of an object invoking `iteratee`     * for each property. The `iteratee` is bound to `thisArg` and invoked with     * three arguments: (value, key, object). Iteratee functions may exit iteration     * early by explicitly returning `false`.     *     * @static     * @memberOf _     * @category Object     * @param {Object} object The object to iterate over.     * @param {Function} [iteratee=_.identity] The function invoked per iteration.     * @param {*} [thisArg] The `this` binding of `iteratee`.     * @returns {Object} Returns `object`.     * @example     *     * function Foo() {     *   this.a = 1;     *   this.b = 2;     * }     *     * Foo.prototype.c = 3;     *     * _.forOwn(new Foo, function(value, key) {     *   console.log(key);     * });     * // => logs 'a' and 'b' (iteration order is not guaranteed)     */    var forOwn = createForOwn(baseForOwn);    /**     * This method is like `_.forOwn` except that it iterates over properties of     * `object` in the opposite order.     *     * @static     * @memberOf _     * @category Object     * @param {Object} object The object to iterate over.     * @param {Function} [iteratee=_.identity] The function invoked per iteration.     * @param {*} [thisArg] The `this` binding of `iteratee`.     * @returns {Object} Returns `object`.     * @example     *     * function Foo() {     *   this.a = 1;     *   this.b = 2;     * }     *     * Foo.prototype.c = 3;     *     * _.forOwnRight(new Foo, function(value, key) {     *   console.log(key);     * });     * // => logs 'b' and 'a' assuming `_.forOwn` logs 'a' and 'b'     */    var forOwnRight = createForOwn(baseForOwnRight);    /**     * Creates an array of function property names from all enumerable properties,     * own and inherited, of `object`.     *     * @static     * @memberOf _     * @alias methods     * @category Object     * @param {Object} object The object to inspect.     * @returns {Array} Returns the new array of property names.     * @example     *     * _.functions(_);     * // => ['after', 'ary', 'assign', ...]     */    function functions(object) {      return baseFunctions(object, keysIn(object));    }    /**     * Gets the property value at `path` of `object`. If the resolved value is     * `undefined` the `defaultValue` is used in its place.     *     * @static     * @memberOf _     * @category Object     * @param {Object} object The object to query.     * @param {Array|string} path The path of the property to get.     * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.     * @returns {*} Returns the resolved value.     * @example     *     * var object = { 'a': [{ 'b': { 'c': 3 } }] };     *     * _.get(object, 'a[0].b.c');     * // => 3     *     * _.get(object, ['a', '0', 'b', 'c']);     * // => 3     *     * _.get(object, 'a.b.c', 'default');     * // => 'default'     */    function get(object, path, defaultValue) {      var result = object == null ? undefined : baseGet(object, toPath(path), (path + ''));      return result === undefined ? defaultValue : result;    }    /**     * Checks if `path` is a direct property.     *     * @static     * @memberOf _     * @category Object     * @param {Object} object The object to query.     * @param {Array|string} path The path to check.     * @returns {boolean} Returns `true` if `path` is a direct property, else `false`.     * @example     *     * var object = { 'a': { 'b': { 'c': 3 } } };     *     * _.has(object, 'a');     * // => true     *     * _.has(object, 'a.b.c');     * // => true     *     * _.has(object, ['a', 'b', 'c']);     * // => true     */    function has(object, path) {      if (object == null) {        return false;      }      var result = hasOwnProperty.call(object, path);      if (!result && !isKey(path)) {        path = toPath(path);        object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));        if (object == null) {          return false;        }        path = last(path);        result = hasOwnProperty.call(object, path);      }      return result || (isLength(object.length) && isIndex(path, object.length) &&        (isArray(object) || isArguments(object) || isString(object)));    }    /**     * Creates an object composed of the inverted keys and values of `object`.     * If `object` contains duplicate values, subsequent values overwrite property     * assignments of previous values unless `multiValue` is `true`.     *     * @static     * @memberOf _     * @category Object     * @param {Object} object The object to invert.     * @param {boolean} [multiValue] Allow multiple values per key.     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.     * @returns {Object} Returns the new inverted object.     * @example     *     * var object = { 'a': 1, 'b': 2, 'c': 1 };     *     * _.invert(object);     * // => { '1': 'c', '2': 'b' }     *     * // with `multiValue`     * _.invert(object, true);     * // => { '1': ['a', 'c'], '2': ['b'] }     */    function invert(object, multiValue, guard) {      if (guard && isIterateeCall(object, multiValue, guard)) {        multiValue = undefined;      }      var index = -1,          props = keys(object),          length = props.length,          result = {};      while (++index < length) {        var key = props[index],            value = object[key];        if (multiValue) {          if (hasOwnProperty.call(result, value)) {            result[value].push(key);          } else {            result[value] = [key];          }        }        else {          result[value] = key;        }      }      return result;    }    /**     * Creates an array of the own enumerable property names of `object`.     *     * **Note:** Non-object values are coerced to objects. See the     * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)     * for more details.     *     * @static     * @memberOf _     * @category Object     * @param {Object} object The object to query.     * @returns {Array} Returns the array of property names.     * @example     *     * function Foo() {     *   this.a = 1;     *   this.b = 2;     * }     *     * Foo.prototype.c = 3;     *     * _.keys(new Foo);     * // => ['a', 'b'] (iteration order is not guaranteed)     *     * _.keys('hi');     * // => ['0', '1']     */    var keys = !nativeKeys ? shimKeys : function(object) {      var Ctor = object == null ? undefined : object.constructor;      if ((typeof Ctor == 'function' && Ctor.prototype === object) ||          (typeof object == 'function' ? lodash.support.enumPrototypes : isArrayLike(object))) {        return shimKeys(object);      }      return isObject(object) ? nativeKeys(object) : [];    };    /**     * Creates an array of the own and inherited enumerable property names of `object`.     *     * **Note:** Non-object values are coerced to objects.     *     * @static     * @memberOf _     * @category Object     * @param {Object} object The object to query.     * @returns {Array} Returns the array of property names.     * @example     *     * function Foo() {     *   this.a = 1;     *   this.b = 2;     * }     *     * Foo.prototype.c = 3;     *     * _.keysIn(new Foo);     * // => ['a', 'b', 'c'] (iteration order is not guaranteed)     */    function keysIn(object) {      if (object == null) {        return [];      }      if (!isObject(object)) {        object = Object(object);      }      var length = object.length,          support = lodash.support;      length = (length && isLength(length) &&        (isArray(object) || isArguments(object) || isString(object)) && length) || 0;      var Ctor = object.constructor,          index = -1,          proto = (isFunction(Ctor) && Ctor.prototype) || objectProto,          isProto = proto === object,          result = Array(length),          skipIndexes = length > 0,          skipErrorProps = support.enumErrorProps && (object === errorProto || object instanceof Error),          skipProto = support.enumPrototypes && isFunction(object);      while (++index < length) {        result[index] = (index + '');      }      // lodash skips the `constructor` property when it infers it's iterating      // over a `prototype` object because IE < 9 can't set the `[[Enumerable]]`      // attribute of an existing property and the `constructor` property of a      // prototype defaults to non-enumerable.      for (var key in object) {        if (!(skipProto && key == 'prototype') &&            !(skipErrorProps && (key == 'message' || key == 'name')) &&            !(skipIndexes && isIndex(key, length)) &&            !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {          result.push(key);        }      }      if (support.nonEnumShadows && object !== objectProto) {        var tag = object === stringProto ? stringTag : (object === errorProto ? errorTag : objToString.call(object)),            nonEnums = nonEnumProps[tag] || nonEnumProps[objectTag];        if (tag == objectTag) {          proto = objectProto;        }        length = shadowProps.length;        while (length--) {          key = shadowProps[length];          var nonEnum = nonEnums[key];          if (!(isProto && nonEnum) &&              (nonEnum ? hasOwnProperty.call(object, key) : object[key] !== proto[key])) {            result.push(key);          }        }      }      return result;    }    /**     * The opposite of `_.mapValues`; this method creates an object with the     * same values as `object` and keys generated by running each own enumerable     * property of `object` through `iteratee`.     *     * @static     * @memberOf _     * @category Object     * @param {Object} object The object to iterate over.     * @param {Function|Object|string} [iteratee=_.identity] The function invoked     *  per iteration.     * @param {*} [thisArg] The `this` binding of `iteratee`.     * @returns {Object} Returns the new mapped object.     * @example     *     * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {     *   return key + value;     * });     * // => { 'a1': 1, 'b2': 2 }     */    var mapKeys = createObjectMapper(true);    /**     * Creates an object with the same keys as `object` and values generated by     * running each own enumerable property of `object` through `iteratee`. The     * iteratee function is bound to `thisArg` and invoked with three arguments:     * (value, key, object).     *     * If a property name is provided for `iteratee` the created `_.property`     * style callback returns the property value of the given element.     *     * If a value is also provided for `thisArg` the created `_.matchesProperty`     * style callback returns `true` for elements that have a matching property     * value, else `false`.     *     * If an object is provided for `iteratee` the created `_.matches` style     * callback returns `true` for elements that have the properties of the given     * object, else `false`.     *     * @static     * @memberOf _     * @category Object     * @param {Object} object The object to iterate over.     * @param {Function|Object|string} [iteratee=_.identity] The function invoked     *  per iteration.     * @param {*} [thisArg] The `this` binding of `iteratee`.     * @returns {Object} Returns the new mapped object.     * @example     *     * _.mapValues({ 'a': 1, 'b': 2 }, function(n) {     *   return n * 3;     * });     * // => { 'a': 3, 'b': 6 }     *     * var users = {     *   'fred':    { 'user': 'fred',    'age': 40 },     *   'pebbles': { 'user': 'pebbles', 'age': 1 }     * };     *     * // using the `_.property` callback shorthand     * _.mapValues(users, 'age');     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)     */    var mapValues = createObjectMapper();    /**     * The opposite of `_.pick`; this method creates an object composed of the     * own and inherited enumerable properties of `object` that are not omitted.     *     * @static     * @memberOf _     * @category Object     * @param {Object} object The source object.     * @param {Function|...(string|string[])} [predicate] The function invoked per     *  iteration or property names to omit, specified as individual property     *  names or arrays of property names.     * @param {*} [thisArg] The `this` binding of `predicate`.     * @returns {Object} Returns the new object.     * @example     *     * var object = { 'user': 'fred', 'age': 40 };     *     * _.omit(object, 'age');     * // => { 'user': 'fred' }     *     * _.omit(object, _.isNumber);     * // => { 'user': 'fred' }     */    var omit = restParam(function(object, props) {      if (object == null) {        return {};      }      if (typeof props[0] != 'function') {        var props = arrayMap(baseFlatten(props), String);        return pickByArray(object, baseDifference(keysIn(object), props));      }      var predicate = bindCallback(props[0], props[1], 3);      return pickByCallback(object, function(value, key, object) {        return !predicate(value, key, object);      });    });    /**     * Creates a two dimensional array of the key-value pairs for `object`,     * e.g. `[[key1, value1], [key2, value2]]`.     *     * @static     * @memberOf _     * @category Object     * @param {Object} object The object to query.     * @returns {Array} Returns the new array of key-value pairs.     * @example     *     * _.pairs({ 'barney': 36, 'fred': 40 });     * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed)     */    function pairs(object) {      object = toObject(object);      var index = -1,          props = keys(object),          length = props.length,          result = Array(length);      while (++index < length) {        var key = props[index];        result[index] = [key, object[key]];      }      return result;    }    /**     * Creates an object composed of the picked `object` properties. Property     * names may be specified as individual arguments or as arrays of property     * names. If `predicate` is provided it's invoked for each property of `object`     * picking the properties `predicate` returns truthy for. The predicate is     * bound to `thisArg` and invoked with three arguments: (value, key, object).     *     * @static     * @memberOf _     * @category Object     * @param {Object} object The source object.     * @param {Function|...(string|string[])} [predicate] The function invoked per     *  iteration or property names to pick, specified as individual property     *  names or arrays of property names.     * @param {*} [thisArg] The `this` binding of `predicate`.     * @returns {Object} Returns the new object.     * @example     *     * var object = { 'user': 'fred', 'age': 40 };     *     * _.pick(object, 'user');     * // => { 'user': 'fred' }     *     * _.pick(object, _.isString);     * // => { 'user': 'fred' }     */    var pick = restParam(function(object, props) {      if (object == null) {        return {};      }      return typeof props[0] == 'function'        ? pickByCallback(object, bindCallback(props[0], props[1], 3))        : pickByArray(object, baseFlatten(props));    });    /**     * This method is like `_.get` except that if the resolved value is a function     * it's invoked with the `this` binding of its parent object and its result     * is returned.     *     * @static     * @memberOf _     * @category Object     * @param {Object} object The object to query.     * @param {Array|string} path The path of the property to resolve.     * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.     * @returns {*} Returns the resolved value.     * @example     *     * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };     *     * _.result(object, 'a[0].b.c1');     * // => 3     *     * _.result(object, 'a[0].b.c2');     * // => 4     *     * _.result(object, 'a.b.c', 'default');     * // => 'default'     *     * _.result(object, 'a.b.c', _.constant('default'));     * // => 'default'     */    function result(object, path, defaultValue) {      var result = object == null ? undefined : toObject(object)[path];      if (result === undefined) {        if (object != null && !isKey(path, object)) {          path = toPath(path);          object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));          result = object == null ? undefined : toObject(object)[last(path)];        }        result = result === undefined ? defaultValue : result;      }      return isFunction(result) ? result.call(object) : result;    }    /**     * Sets the property value of `path` on `object`. If a portion of `path`     * does not exist it's created.     *     * @static     * @memberOf _     * @category Object     * @param {Object} object The object to augment.     * @param {Array|string} path The path of the property to set.     * @param {*} value The value to set.     * @returns {Object} Returns `object`.     * @example     *     * var object = { 'a': [{ 'b': { 'c': 3 } }] };     *     * _.set(object, 'a[0].b.c', 4);     * console.log(object.a[0].b.c);     * // => 4     *     * _.set(object, 'x[0].y.z', 5);     * console.log(object.x[0].y.z);     * // => 5     */    function set(object, path, value) {      if (object == null) {        return object;      }      var pathKey = (path + '');      path = (object[pathKey] != null || isKey(path, object)) ? [pathKey] : toPath(path);      var index = -1,          length = path.length,          lastIndex = length - 1,          nested = object;      while (nested != null && ++index < length) {        var key = path[index];        if (isObject(nested)) {          if (index == lastIndex) {            nested[key] = value;          } else if (nested[key] == null) {            nested[key] = isIndex(path[index + 1]) ? [] : {};          }        }        nested = nested[key];      }      return object;    }    /**     * An alternative to `_.reduce`; this method transforms `object` to a new     * `accumulator` object which is the result of running each of its own enumerable     * properties through `iteratee`, with each invocation potentially mutating     * the `accumulator` object. The `iteratee` is bound to `thisArg` and invoked     * with four arguments: (accumulator, value, key, object). Iteratee functions     * may exit iteration early by explicitly returning `false`.     *     * @static     * @memberOf _     * @category Object     * @param {Array|Object} object The object to iterate over.     * @param {Function} [iteratee=_.identity] The function invoked per iteration.     * @param {*} [accumulator] The custom accumulator value.     * @param {*} [thisArg] The `this` binding of `iteratee`.     * @returns {*} Returns the accumulated value.     * @example     *     * _.transform([2, 3, 4], function(result, n) {     *   result.push(n *= n);     *   return n % 2 == 0;     * });     * // => [4, 9]     *     * _.transform({ 'a': 1, 'b': 2 }, function(result, n, key) {     *   result[key] = n * 3;     * });     * // => { 'a': 3, 'b': 6 }     */    function transform(object, iteratee, accumulator, thisArg) {      var isArr = isArray(object) || isTypedArray(object);      iteratee = getCallback(iteratee, thisArg, 4);      if (accumulator == null) {        if (isArr || isObject(object)) {          var Ctor = object.constructor;          if (isArr) {            accumulator = isArray(object) ? new Ctor : [];          } else {            accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined);          }        } else {          accumulator = {};        }      }      (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) {        return iteratee(accumulator, value, index, object);      });      return accumulator;    }    /**     * Creates an array of the own enumerable property values of `object`.     *     * **Note:** Non-object values are coerced to objects.     *     * @static     * @memberOf _     * @category Object     * @param {Object} object The object to query.     * @returns {Array} Returns the array of property values.     * @example     *     * function Foo() {     *   this.a = 1;     *   this.b = 2;     * }     *     * Foo.prototype.c = 3;     *     * _.values(new Foo);     * // => [1, 2] (iteration order is not guaranteed)     *     * _.values('hi');     * // => ['h', 'i']     */    function values(object) {      return baseValues(object, keys(object));    }    /**     * Creates an array of the own and inherited enumerable property values     * of `object`.     *     * **Note:** Non-object values are coerced to objects.     *     * @static     * @memberOf _     * @category Object     * @param {Object} object The object to query.     * @returns {Array} Returns the array of property values.     * @example     *     * function Foo() {     *   this.a = 1;     *   this.b = 2;     * }     *     * Foo.prototype.c = 3;     *     * _.valuesIn(new Foo);     * // => [1, 2, 3] (iteration order is not guaranteed)     */    function valuesIn(object) {      return baseValues(object, keysIn(object));    }    /*------------------------------------------------------------------------*/    /**     * Checks if `n` is between `start` and up to but not including, `end`. If     * `end` is not specified it's set to `start` with `start` then set to `0`.     *     * @static     * @memberOf _     * @category Number     * @param {number} n The number to check.     * @param {number} [start=0] The start of the range.     * @param {number} end The end of the range.     * @returns {boolean} Returns `true` if `n` is in the range, else `false`.     * @example     *     * _.inRange(3, 2, 4);     * // => true     *     * _.inRange(4, 8);     * // => true     *     * _.inRange(4, 2);     * // => false     *     * _.inRange(2, 2);     * // => false     *     * _.inRange(1.2, 2);     * // => true     *     * _.inRange(5.2, 4);     * // => false     */    function inRange(value, start, end) {      start = +start || 0;      if (end === undefined) {        end = start;        start = 0;      } else {        end = +end || 0;      }      return value >= nativeMin(start, end) && value < nativeMax(start, end);    }    /**     * Produces a random number between `min` and `max` (inclusive). If only one     * argument is provided a number between `0` and the given number is returned.     * If `floating` is `true`, or either `min` or `max` are floats, a floating-point     * number is returned instead of an integer.     *     * @static     * @memberOf _     * @category Number     * @param {number} [min=0] The minimum possible value.     * @param {number} [max=1] The maximum possible value.     * @param {boolean} [floating] Specify returning a floating-point number.     * @returns {number} Returns the random number.     * @example     *     * _.random(0, 5);     * // => an integer between 0 and 5     *     * _.random(5);     * // => also an integer between 0 and 5     *     * _.random(5, true);     * // => a floating-point number between 0 and 5     *     * _.random(1.2, 5.2);     * // => a floating-point number between 1.2 and 5.2     */    function random(min, max, floating) {      if (floating && isIterateeCall(min, max, floating)) {        max = floating = undefined;      }      var noMin = min == null,          noMax = max == null;      if (floating == null) {        if (noMax && typeof min == 'boolean') {          floating = min;          min = 1;        }        else if (typeof max == 'boolean') {          floating = max;          noMax = true;        }      }      if (noMin && noMax) {        max = 1;        noMax = false;      }      min = +min || 0;      if (noMax) {        max = min;        min = 0;      } else {        max = +max || 0;      }      if (floating || min % 1 || max % 1) {        var rand = nativeRandom();        return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand + '').length - 1)))), max);      }      return baseRandom(min, max);    }    /*------------------------------------------------------------------------*/    /**     * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).     *     * @static     * @memberOf _     * @category String     * @param {string} [string=''] The string to convert.     * @returns {string} Returns the camel cased string.     * @example     *     * _.camelCase('Foo Bar');     * // => 'fooBar'     *     * _.camelCase('--foo-bar');     * // => 'fooBar'     *     * _.camelCase('__foo_bar__');     * // => 'fooBar'     */    var camelCase = createCompounder(function(result, word, index) {      word = word.toLowerCase();      return result + (index ? (word.charAt(0).toUpperCase() + word.slice(1)) : word);    });    /**     * Capitalizes the first character of `string`.     *     * @static     * @memberOf _     * @category String     * @param {string} [string=''] The string to capitalize.     * @returns {string} Returns the capitalized string.     * @example     *     * _.capitalize('fred');     * // => 'Fred'     */    function capitalize(string) {      string = baseToString(string);      return string && (string.charAt(0).toUpperCase() + string.slice(1));    }    /**     * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)     * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).     *     * @static     * @memberOf _     * @category String     * @param {string} [string=''] The string to deburr.     * @returns {string} Returns the deburred string.     * @example     *     * _.deburr('déjà vu');     * // => 'deja vu'     */    function deburr(string) {      string = baseToString(string);      return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, '');    }    /**     * Checks if `string` ends with the given target string.     *     * @static     * @memberOf _     * @category String     * @param {string} [string=''] The string to search.     * @param {string} [target] The string to search for.     * @param {number} [position=string.length] The position to search from.     * @returns {boolean} Returns `true` if `string` ends with `target`, else `false`.     * @example     *     * _.endsWith('abc', 'c');     * // => true     *     * _.endsWith('abc', 'b');     * // => false     *     * _.endsWith('abc', 'b', 2);     * // => true     */    function endsWith(string, target, position) {      string = baseToString(string);      target = (target + '');      var length = string.length;      position = position === undefined        ? length        : nativeMin(position < 0 ? 0 : (+position || 0), length);      position -= target.length;      return position >= 0 && string.indexOf(target, position) == position;    }    /**     * Converts the characters "&", "<", ">", '"', "'", and "\`", in `string` to     * their corresponding HTML entities.     *     * **Note:** No other characters are escaped. To escape additional characters     * use a third-party library like [_he_](https://mths.be/he).     *     * Though the ">" character is escaped for symmetry, characters like     * ">" and "/" don't need escaping in HTML and have no special meaning     * unless they're part of a tag or unquoted attribute value.     * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)     * (under "semi-related fun fact") for more details.     *     * Backticks are escaped because in Internet Explorer < 9, they can break out     * of attribute values or HTML comments. See [#59](https://html5sec.org/#59),     * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and     * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/)     * for more details.     *     * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping)     * to reduce XSS vectors.     *     * @static     * @memberOf _     * @category String     * @param {string} [string=''] The string to escape.     * @returns {string} Returns the escaped string.     * @example     *     * _.escape('fred, barney, & pebbles');     * // => 'fred, barney, & pebbles'     */    function escape(string) {      // Reset `lastIndex` because in IE < 9 `String#replace` does not.      string = baseToString(string);      return (string && reHasUnescapedHtml.test(string))        ? string.replace(reUnescapedHtml, escapeHtmlChar)        : string;    }    /**     * Escapes the `RegExp` special characters "\", "/", "^", "$", ".", "|", "?",     * "*", "+", "(", ")", "[", "]", "{" and "}" in `string`.     *     * @static     * @memberOf _     * @category String     * @param {string} [string=''] The string to escape.     * @returns {string} Returns the escaped string.     * @example     *     * _.escapeRegExp('[lodash](https://lodash.com/)');     * // => '\[lodash\]\(https:\/\/lodash\.com\/\)'     */    function escapeRegExp(string) {      string = baseToString(string);      return (string && reHasRegExpChars.test(string))        ? string.replace(reRegExpChars, escapeRegExpChar)        : (string || '(?:)');    }    /**     * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).     *     * @static     * @memberOf _     * @category String     * @param {string} [string=''] The string to convert.     * @returns {string} Returns the kebab cased string.     * @example     *     * _.kebabCase('Foo Bar');     * // => 'foo-bar'     *     * _.kebabCase('fooBar');     * // => 'foo-bar'     *     * _.kebabCase('__foo_bar__');     * // => 'foo-bar'     */    var kebabCase = createCompounder(function(result, word, index) {      return result + (index ? '-' : '') + word.toLowerCase();    });    /**     * Pads `string` on the left and right sides if it's shorter than `length`.     * Padding characters are truncated if they can't be evenly divided by `length`.     *     * @static     * @memberOf _     * @category String     * @param {string} [string=''] The string to pad.     * @param {number} [length=0] The padding length.     * @param {string} [chars=' '] The string used as padding.     * @returns {string} Returns the padded string.     * @example     *     * _.pad('abc', 8);     * // => '  abc   '     *     * _.pad('abc', 8, '_-');     * // => '_-abc_-_'     *     * _.pad('abc', 3);     * // => 'abc'     */    function pad(string, length, chars) {      string = baseToString(string);      length = +length;      var strLength = string.length;      if (strLength >= length || !nativeIsFinite(length)) {        return string;      }      var mid = (length - strLength) / 2,          leftLength = nativeFloor(mid),          rightLength = nativeCeil(mid);      chars = createPadding('', rightLength, chars);      return chars.slice(0, leftLength) + string + chars;    }    /**     * Pads `string` on the left side if it's shorter than `length`. Padding     * characters are truncated if they exceed `length`.     *     * @static     * @memberOf _     * @category String     * @param {string} [string=''] The string to pad.     * @param {number} [length=0] The padding length.     * @param {string} [chars=' '] The string used as padding.     * @returns {string} Returns the padded string.     * @example     *     * _.padLeft('abc', 6);     * // => '   abc'     *     * _.padLeft('abc', 6, '_-');     * // => '_-_abc'     *     * _.padLeft('abc', 3);     * // => 'abc'     */    var padLeft = createPadDir();    /**     * Pads `string` on the right side if it's shorter than `length`. Padding     * characters are truncated if they exceed `length`.     *     * @static     * @memberOf _     * @category String     * @param {string} [string=''] The string to pad.     * @param {number} [length=0] The padding length.     * @param {string} [chars=' '] The string used as padding.     * @returns {string} Returns the padded string.     * @example     *     * _.padRight('abc', 6);     * // => 'abc   '     *     * _.padRight('abc', 6, '_-');     * // => 'abc_-_'     *     * _.padRight('abc', 3);     * // => 'abc'     */    var padRight = createPadDir(true);    /**     * Converts `string` to an integer of the specified radix. If `radix` is     * `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal,     * in which case a `radix` of `16` is used.     *     * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#E)     * of `parseInt`.     *     * @static     * @memberOf _     * @category String     * @param {string} string The string to convert.     * @param {number} [radix] The radix to interpret `value` by.     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.     * @returns {number} Returns the converted integer.     * @example     *     * _.parseInt('08');     * // => 8     *     * _.map(['6', '08', '10'], _.parseInt);     * // => [6, 8, 10]     */    function parseInt(string, radix, guard) {      // Firefox < 21 and Opera < 15 follow ES3 for `parseInt`.      // Chrome fails to trim leading <BOM> whitespace characters.      // See https://code.google.com/p/v8/issues/detail?id=3109 for more details.      if (guard ? isIterateeCall(string, radix, guard) : radix == null) {        radix = 0;      } else if (radix) {        radix = +radix;      }      string = trim(string);      return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10));    }    /**     * Repeats the given string `n` times.     *     * @static     * @memberOf _     * @category String     * @param {string} [string=''] The string to repeat.     * @param {number} [n=0] The number of times to repeat the string.     * @returns {string} Returns the repeated string.     * @example     *     * _.repeat('*', 3);     * // => '***'     *     * _.repeat('abc', 2);     * // => 'abcabc'     *     * _.repeat('abc', 0);     * // => ''     */    function repeat(string, n) {      var result = '';      string = baseToString(string);      n = +n;      if (n < 1 || !string || !nativeIsFinite(n)) {        return result;      }      // Leverage the exponentiation by squaring algorithm for a faster repeat.      // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.      do {        if (n % 2) {          result += string;        }        n = nativeFloor(n / 2);        string += string;      } while (n);      return result;    }    /**     * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case).     *     * @static     * @memberOf _     * @category String     * @param {string} [string=''] The string to convert.     * @returns {string} Returns the snake cased string.     * @example     *     * _.snakeCase('Foo Bar');     * // => 'foo_bar'     *     * _.snakeCase('fooBar');     * // => 'foo_bar'     *     * _.snakeCase('--foo-bar');     * // => 'foo_bar'     */    var snakeCase = createCompounder(function(result, word, index) {      return result + (index ? '_' : '') + word.toLowerCase();    });    /**     * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).     *     * @static     * @memberOf _     * @category String     * @param {string} [string=''] The string to convert.     * @returns {string} Returns the start cased string.     * @example     *     * _.startCase('--foo-bar');     * // => 'Foo Bar'     *     * _.startCase('fooBar');     * // => 'Foo Bar'     *     * _.startCase('__foo_bar__');     * // => 'Foo Bar'     */    var startCase = createCompounder(function(result, word, index) {      return result + (index ? ' ' : '') + (word.charAt(0).toUpperCase() + word.slice(1));    });    /**     * Checks if `string` starts with the given target string.     *     * @static     * @memberOf _     * @category String     * @param {string} [string=''] The string to search.     * @param {string} [target] The string to search for.     * @param {number} [position=0] The position to search from.     * @returns {boolean} Returns `true` if `string` starts with `target`, else `false`.     * @example     *     * _.startsWith('abc', 'a');     * // => true     *     * _.startsWith('abc', 'b');     * // => false     *     * _.startsWith('abc', 'b', 1);     * // => true     */    function startsWith(string, target, position) {      string = baseToString(string);      position = position == null        ? 0        : nativeMin(position < 0 ? 0 : (+position || 0), string.length);      return string.lastIndexOf(target, position) == position;    }    /**     * Creates a compiled template function that can interpolate data properties     * in "interpolate" delimiters, HTML-escape interpolated data properties in     * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data     * properties may be accessed as free variables in the template. If a setting     * object is provided it takes precedence over `_.templateSettings` values.     *     * **Note:** In the development build `_.template` utilizes     * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)     * for easier debugging.     *     * For more information on precompiling templates see     * [lodash's custom builds documentation](https://lodash.com/custom-builds).     *     * For more information on Chrome extension sandboxes see     * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).     *     * @static     * @memberOf _     * @category String     * @param {string} [string=''] The template string.     * @param {Object} [options] The options object.     * @param {RegExp} [options.escape] The HTML "escape" delimiter.     * @param {RegExp} [options.evaluate] The "evaluate" delimiter.     * @param {Object} [options.imports] An object to import into the template as free variables.     * @param {RegExp} [options.interpolate] The "interpolate" delimiter.     * @param {string} [options.sourceURL] The sourceURL of the template's compiled source.     * @param {string} [options.variable] The data object variable name.     * @param- {Object} [otherOptions] Enables the legacy `options` param signature.     * @returns {Function} Returns the compiled template function.     * @example     *     * // using the "interpolate" delimiter to create a compiled template     * var compiled = _.template('hello <%= user %>!');     * compiled({ 'user': 'fred' });     * // => 'hello fred!'     *     * // using the HTML "escape" delimiter to escape data property values     * var compiled = _.template('<b><%- value %></b>');     * compiled({ 'value': '<script>' });     * // => '<b><script></b>'     *     * // using the "evaluate" delimiter to execute JavaScript and generate HTML     * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');     * compiled({ 'users': ['fred', 'barney'] });     * // => '<li>fred</li><li>barney</li>'     *     * // using the internal `print` function in "evaluate" delimiters     * var compiled = _.template('<% print("hello " + user); %>!');     * compiled({ 'user': 'barney' });     * // => 'hello barney!'     *     * // using the ES delimiter as an alternative to the default "interpolate" delimiter     * var compiled = _.template('hello ${ user }!');     * compiled({ 'user': 'pebbles' });     * // => 'hello pebbles!'     *     * // using custom template delimiters     * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;     * var compiled = _.template('hello {{ user }}!');     * compiled({ 'user': 'mustache' });     * // => 'hello mustache!'     *     * // using backslashes to treat delimiters as plain text     * var compiled = _.template('<%= "\\<%- value %\\>" %>');     * compiled({ 'value': 'ignored' });     * // => '<%- value %>'     *     * // using the `imports` option to import `jQuery` as `jq`     * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';     * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });     * compiled({ 'users': ['fred', 'barney'] });     * // => '<li>fred</li><li>barney</li>'     *     * // using the `sourceURL` option to specify a custom sourceURL for the template     * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });     * compiled(data);     * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector     *     * // using the `variable` option to ensure a with-statement isn't used in the compiled template     * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });     * compiled.source;     * // => function(data) {     * //   var __t, __p = '';     * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';     * //   return __p;     * // }     *     * // using the `source` property to inline compiled templates for meaningful     * // line numbers in error messages and a stack trace     * fs.writeFileSync(path.join(cwd, 'jst.js'), '\     *   var JST = {\     *     "main": ' + _.template(mainText).source + '\     *   };\     * ');     */    function template(string, options, otherOptions) {      // Based on John Resig's `tmpl` implementation (http://ejohn.org/blog/javascript-micro-templating/)      // and Laura Doktorova's doT.js (https://github.com/olado/doT).      var settings = lodash.templateSettings;      if (otherOptions && isIterateeCall(string, options, otherOptions)) {        options = otherOptions = undefined;      }      string = baseToString(string);      options = assignWith(baseAssign({}, otherOptions || options), settings, assignOwnDefaults);      var imports = assignWith(baseAssign({}, options.imports), settings.imports, assignOwnDefaults),          importsKeys = keys(imports),          importsValues = baseValues(imports, importsKeys);      var isEscaping,          isEvaluating,          index = 0,          interpolate = options.interpolate || reNoMatch,          source = "__p += '";      // Compile the regexp to match each delimiter.      var reDelimiters = RegExp(        (options.escape || reNoMatch).source + '|' +        interpolate.source + '|' +        (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +        (options.evaluate || reNoMatch).source + '|$'      , 'g');      // Use a sourceURL for easier debugging.      var sourceURL = '//# sourceURL=' +        ('sourceURL' in options          ? options.sourceURL          : ('lodash.templateSources[' + (++templateCounter) + ']')        ) + '\n';      string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {        interpolateValue || (interpolateValue = esTemplateValue);        // Escape characters that can't be included in string literals.        source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);        // Replace delimiters with snippets.        if (escapeValue) {          isEscaping = true;          source += "' +\n__e(" + escapeValue + ") +\n'";        }        if (evaluateValue) {          isEvaluating = true;          source += "';\n" + evaluateValue + ";\n__p += '";        }        if (interpolateValue) {          source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";        }        index = offset + match.length;        // The JS engine embedded in Adobe products requires returning the `match`        // string in order to produce the correct `offset` value.        return match;      });      source += "';\n";      // If `variable` is not specified wrap a with-statement around the generated      // code to add the data object to the top of the scope chain.      var variable = options.variable;      if (!variable) {        source = 'with (obj) {\n' + source + '\n}\n';      }      // Cleanup code by stripping empty strings.      source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)        .replace(reEmptyStringMiddle, '$1')        .replace(reEmptyStringTrailing, '$1;');      // Frame code as the function body.      source = 'function(' + (variable || 'obj') + ') {\n' +        (variable          ? ''          : 'obj || (obj = {});\n'        ) +        "var __t, __p = ''" +        (isEscaping           ? ', __e = _.escape'           : ''        ) +        (isEvaluating          ? ', __j = Array.prototype.join;\n' +            "function print() { __p += __j.call(arguments, '') }\n"          : ';\n'        ) +        source +        'return __p\n}';      var result = attempt(function() {        return Function(importsKeys, sourceURL + 'return ' + source).apply(undefined, importsValues);      });      // Provide the compiled function's source by its `toString` method or      // the `source` property as a convenience for inlining compiled templates.      result.source = source;      if (isError(result)) {        throw result;      }      return result;    }    /**     * Removes leading and trailing whitespace or specified characters from `string`.     *     * @static     * @memberOf _     * @category String     * @param {string} [string=''] The string to trim.     * @param {string} [chars=whitespace] The characters to trim.     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.     * @returns {string} Returns the trimmed string.     * @example     *     * _.trim('  abc  ');     * // => 'abc'     *     * _.trim('-_-abc-_-', '_-');     * // => 'abc'     *     * _.map(['  foo  ', '  bar  '], _.trim);     * // => ['foo', 'bar']     */    function trim(string, chars, guard) {      var value = string;      string = baseToString(string);      if (!string) {        return string;      }      if (guard ? isIterateeCall(value, chars, guard) : chars == null) {        return string.slice(trimmedLeftIndex(string), trimmedRightIndex(string) + 1);      }      chars = (chars + '');      return string.slice(charsLeftIndex(string, chars), charsRightIndex(string, chars) + 1);    }    /**     * Removes leading whitespace or specified characters from `string`.     *     * @static     * @memberOf _     * @category String     * @param {string} [string=''] The string to trim.     * @param {string} [chars=whitespace] The characters to trim.     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.     * @returns {string} Returns the trimmed string.     * @example     *     * _.trimLeft('  abc  ');     * // => 'abc  '     *     * _.trimLeft('-_-abc-_-', '_-');     * // => 'abc-_-'     */    function trimLeft(string, chars, guard) {      var value = string;      string = baseToString(string);      if (!string) {        return string;      }      if (guard ? isIterateeCall(value, chars, guard) : chars == null) {        return string.slice(trimmedLeftIndex(string));      }      return string.slice(charsLeftIndex(string, (chars + '')));    }    /**     * Removes trailing whitespace or specified characters from `string`.     *     * @static     * @memberOf _     * @category String     * @param {string} [string=''] The string to trim.     * @param {string} [chars=whitespace] The characters to trim.     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.     * @returns {string} Returns the trimmed string.     * @example     *     * _.trimRight('  abc  ');     * // => '  abc'     *     * _.trimRight('-_-abc-_-', '_-');     * // => '-_-abc'     */    function trimRight(string, chars, guard) {      var value = string;      string = baseToString(string);      if (!string) {        return string;      }      if (guard ? isIterateeCall(value, chars, guard) : chars == null) {        return string.slice(0, trimmedRightIndex(string) + 1);      }      return string.slice(0, charsRightIndex(string, (chars + '')) + 1);    }    /**     * Truncates `string` if it's longer than the given maximum string length.     * The last characters of the truncated string are replaced with the omission     * string which defaults to "...".     *     * @static     * @memberOf _     * @category String     * @param {string} [string=''] The string to truncate.     * @param {Object|number} [options] The options object or maximum string length.     * @param {number} [options.length=30] The maximum string length.     * @param {string} [options.omission='...'] The string to indicate text is omitted.     * @param {RegExp|string} [options.separator] The separator pattern to truncate to.     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.     * @returns {string} Returns the truncated string.     * @example     *     * _.trunc('hi-diddly-ho there, neighborino');     * // => 'hi-diddly-ho there, neighbo...'     *     * _.trunc('hi-diddly-ho there, neighborino', 24);     * // => 'hi-diddly-ho there, n...'     *     * _.trunc('hi-diddly-ho there, neighborino', {     *   'length': 24,     *   'separator': ' '     * });     * // => 'hi-diddly-ho there,...'     *     * _.trunc('hi-diddly-ho there, neighborino', {     *   'length': 24,     *   'separator': /,? +/     * });     * // => 'hi-diddly-ho there...'     *     * _.trunc('hi-diddly-ho there, neighborino', {     *   'omission': ' [...]'     * });     * // => 'hi-diddly-ho there, neig [...]'     */    function trunc(string, options, guard) {      if (guard && isIterateeCall(string, options, guard)) {        options = undefined;      }      var length = DEFAULT_TRUNC_LENGTH,          omission = DEFAULT_TRUNC_OMISSION;      if (options != null) {        if (isObject(options)) {          var separator = 'separator' in options ? options.separator : separator;          length = 'length' in options ? (+options.length || 0) : length;          omission = 'omission' in options ? baseToString(options.omission) : omission;        } else {          length = +options || 0;        }      }      string = baseToString(string);      if (length >= string.length) {        return string;      }      var end = length - omission.length;      if (end < 1) {        return omission;      }      var result = string.slice(0, end);      if (separator == null) {        return result + omission;      }      if (isRegExp(separator)) {        if (string.slice(end).search(separator)) {          var match,              newEnd,              substring = string.slice(0, end);          if (!separator.global) {            separator = RegExp(separator.source, (reFlags.exec(separator) || '') + 'g');          }          separator.lastIndex = 0;          while ((match = separator.exec(substring))) {            newEnd = match.index;          }          result = result.slice(0, newEnd == null ? end : newEnd);        }      } else if (string.indexOf(separator, end) != end) {        var index = result.lastIndexOf(separator);        if (index > -1) {          result = result.slice(0, index);        }      }      return result + omission;    }    /**     * The inverse of `_.escape`; this method converts the HTML entities     * `&`, `<`, `>`, `"`, `'`, and ``` in `string` to their     * corresponding characters.     *     * **Note:** No other HTML entities are unescaped. To unescape additional HTML     * entities use a third-party library like [_he_](https://mths.be/he).     *     * @static     * @memberOf _     * @category String     * @param {string} [string=''] The string to unescape.     * @returns {string} Returns the unescaped string.     * @example     *     * _.unescape('fred, barney, & pebbles');     * // => 'fred, barney, & pebbles'     */    function unescape(string) {      string = baseToString(string);      return (string && reHasEscapedHtml.test(string))        ? string.replace(reEscapedHtml, unescapeHtmlChar)        : string;    }    /**     * Splits `string` into an array of its words.     *     * @static     * @memberOf _     * @category String     * @param {string} [string=''] The string to inspect.     * @param {RegExp|string} [pattern] The pattern to match words.     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.     * @returns {Array} Returns the words of `string`.     * @example     *     * _.words('fred, barney, & pebbles');     * // => ['fred', 'barney', 'pebbles']     *     * _.words('fred, barney, & pebbles', /[^, ]+/g);     * // => ['fred', 'barney', '&', 'pebbles']     */    function words(string, pattern, guard) {      if (guard && isIterateeCall(string, pattern, guard)) {        pattern = undefined;      }      string = baseToString(string);      return string.match(pattern || reWords) || [];    }    /*------------------------------------------------------------------------*/    /**     * Attempts to invoke `func`, returning either the result or the caught error     * object. Any additional arguments are provided to `func` when it's invoked.     *     * @static     * @memberOf _     * @category Utility     * @param {Function} func The function to attempt.     * @returns {*} Returns the `func` result or error object.     * @example     *     * // avoid throwing errors for invalid selectors     * var elements = _.attempt(function(selector) {     *   return document.querySelectorAll(selector);     * }, '>_>');     *     * if (_.isError(elements)) {     *   elements = [];     * }     */    var attempt = restParam(function(func, args) {      try {        return func.apply(undefined, args);      } catch(e) {        return isError(e) ? e : new Error(e);      }    });    /**     * Creates a function that invokes `func` with the `this` binding of `thisArg`     * and arguments of the created function. If `func` is a property name the     * created callback returns the property value for a given element. If `func`     * is an object the created callback returns `true` for elements that contain     * the equivalent object properties, otherwise it returns `false`.     *     * @static     * @memberOf _     * @alias iteratee     * @category Utility     * @param {*} [func=_.identity] The value to convert to a callback.     * @param {*} [thisArg] The `this` binding of `func`.     * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.     * @returns {Function} Returns the callback.     * @example     *     * var users = [     *   { 'user': 'barney', 'age': 36 },     *   { 'user': 'fred',   'age': 40 }     * ];     *     * // wrap to create custom callback shorthands     * _.callback = _.wrap(_.callback, function(callback, func, thisArg) {     *   var match = /^(.+?)__([gl]t)(.+)$/.exec(func);     *   if (!match) {     *     return callback(func, thisArg);     *   }     *   return function(object) {     *     return match[2] == 'gt'     *       ? object[match[1]] > match[3]     *       : object[match[1]] < match[3];     *   };     * });     *     * _.filter(users, 'age__gt36');     * // => [{ 'user': 'fred', 'age': 40 }]     */    function callback(func, thisArg, guard) {      if (guard && isIterateeCall(func, thisArg, guard)) {        thisArg = undefined;      }      return isObjectLike(func)        ? matches(func)        : baseCallback(func, thisArg);    }    /**     * Creates a function that returns `value`.     *     * @static     * @memberOf _     * @category Utility     * @param {*} value The value to return from the new function.     * @returns {Function} Returns the new function.     * @example     *     * var object = { 'user': 'fred' };     * var getter = _.constant(object);     *     * getter() === object;     * // => true     */    function constant(value) {      return function() {        return value;      };    }    /**     * This method returns the first argument provided to it.     *     * @static     * @memberOf _     * @category Utility     * @param {*} value Any value.     * @returns {*} Returns `value`.     * @example     *     * var object = { 'user': 'fred' };     *     * _.identity(object) === object;     * // => true     */    function identity(value) {      return value;    }    /**     * Creates a function that performs a deep comparison between a given object     * and `source`, returning `true` if the given object has equivalent property     * values, else `false`.     *     * **Note:** This method supports comparing arrays, booleans, `Date` objects,     * numbers, `Object` objects, regexes, and strings. Objects are compared by     * their own, not inherited, enumerable properties. For comparing a single     * own or inherited property value see `_.matchesProperty`.     *     * @static     * @memberOf _     * @category Utility     * @param {Object} source The object of property values to match.     * @returns {Function} Returns the new function.     * @example     *     * var users = [     *   { 'user': 'barney', 'age': 36, 'active': true },     *   { 'user': 'fred',   'age': 40, 'active': false }     * ];     *     * _.filter(users, _.matches({ 'age': 40, 'active': false }));     * // => [{ 'user': 'fred', 'age': 40, 'active': false }]     */    function matches(source) {      return baseMatches(baseClone(source, true));    }    /**     * Creates a function that compares the property value of `path` on a given     * object to `value`.     *     * **Note:** This method supports comparing arrays, booleans, `Date` objects,     * numbers, `Object` objects, regexes, and strings. Objects are compared by     * their own, not inherited, enumerable properties.     *     * @static     * @memberOf _     * @category Utility     * @param {Array|string} path The path of the property to get.     * @param {*} srcValue The value to match.     * @returns {Function} Returns the new function.     * @example     *     * var users = [     *   { 'user': 'barney' },     *   { 'user': 'fred' }     * ];     *     * _.find(users, _.matchesProperty('user', 'fred'));     * // => { 'user': 'fred' }     */    function matchesProperty(path, srcValue) {      return baseMatchesProperty(path, baseClone(srcValue, true));    }    /**     * Creates a function that invokes the method at `path` on a given object.     * Any additional arguments are provided to the invoked method.     *     * @static     * @memberOf _     * @category Utility     * @param {Array|string} path The path of the method to invoke.     * @param {...*} [args] The arguments to invoke the method with.     * @returns {Function} Returns the new function.     * @example     *     * var objects = [     *   { 'a': { 'b': { 'c': _.constant(2) } } },     *   { 'a': { 'b': { 'c': _.constant(1) } } }     * ];     *     * _.map(objects, _.method('a.b.c'));     * // => [2, 1]     *     * _.invoke(_.sortBy(objects, _.method(['a', 'b', 'c'])), 'a.b.c');     * // => [1, 2]     */    var method = restParam(function(path, args) {      return function(object) {        return invokePath(object, path, args);      };    });    /**     * The opposite of `_.method`; this method creates a function that invokes     * the method at a given path on `object`. Any additional arguments are     * provided to the invoked method.     *     * @static     * @memberOf _     * @category Utility     * @param {Object} object The object to query.     * @param {...*} [args] The arguments to invoke the method with.     * @returns {Function} Returns the new function.     * @example     *     * var array = _.times(3, _.constant),     *     object = { 'a': array, 'b': array, 'c': array };     *     * _.map(['a[2]', 'c[0]'], _.methodOf(object));     * // => [2, 0]     *     * _.map([['a', '2'], ['c', '0']], _.methodOf(object));     * // => [2, 0]     */    var methodOf = restParam(function(object, args) {      return function(path) {        return invokePath(object, path, args);      };    });    /**     * Adds all own enumerable function properties of a source object to the     * destination object. If `object` is a function then methods are added to     * its prototype as well.     *     * **Note:** Use `_.runInContext` to create a pristine `lodash` function to     * avoid conflicts caused by modifying the original.     *     * @static     * @memberOf _     * @category Utility     * @param {Function|Object} [object=lodash] The destination object.     * @param {Object} source The object of functions to add.     * @param {Object} [options] The options object.     * @param {boolean} [options.chain=true] Specify whether the functions added     *  are chainable.     * @returns {Function|Object} Returns `object`.     * @example     *     * function vowels(string) {     *   return _.filter(string, function(v) {     *     return /[aeiou]/i.test(v);     *   });     * }     *     * _.mixin({ 'vowels': vowels });     * _.vowels('fred');     * // => ['e']     *     * _('fred').vowels().value();     * // => ['e']     *     * _.mixin({ 'vowels': vowels }, { 'chain': false });     * _('fred').vowels();     * // => ['e']     */    function mixin(object, source, options) {      if (options == null) {        var isObj = isObject(source),            props = isObj ? keys(source) : undefined,            methodNames = (props && props.length) ? baseFunctions(source, props) : undefined;        if (!(methodNames ? methodNames.length : isObj)) {          methodNames = false;          options = source;          source = object;          object = this;        }      }      if (!methodNames) {        methodNames = baseFunctions(source, keys(source));      }      var chain = true,          index = -1,          isFunc = isFunction(object),          length = methodNames.length;      if (options === false) {        chain = false;      } else if (isObject(options) && 'chain' in options) {        chain = options.chain;      }      while (++index < length) {        var methodName = methodNames[index],            func = source[methodName];        object[methodName] = func;        if (isFunc) {          object.prototype[methodName] = (function(func) {            return function() {              var chainAll = this.__chain__;              if (chain || chainAll) {                var result = object(this.__wrapped__),                    actions = result.__actions__ = arrayCopy(this.__actions__);                actions.push({ 'func': func, 'args': arguments, 'thisArg': object });                result.__chain__ = chainAll;                return result;              }              return func.apply(object, arrayPush([this.value()], arguments));            };          }(func));        }      }      return object;    }    /**     * Reverts the `_` variable to its previous value and returns a reference to     * the `lodash` function.     *     * @static     * @memberOf _     * @category Utility     * @returns {Function} Returns the `lodash` function.     * @example     *     * var lodash = _.noConflict();     */    function noConflict() {      root._ = oldDash;      return this;    }    /**     * A no-operation function that returns `undefined` regardless of the     * arguments it receives.     *     * @static     * @memberOf _     * @category Utility     * @example     *     * var object = { 'user': 'fred' };     *     * _.noop(object) === undefined;     * // => true     */    function noop() {      // No operation performed.    }    /**     * Creates a function that returns the property value at `path` on a     * given object.     *     * @static     * @memberOf _     * @category Utility     * @param {Array|string} path The path of the property to get.     * @returns {Function} Returns the new function.     * @example     *     * var objects = [     *   { 'a': { 'b': { 'c': 2 } } },     *   { 'a': { 'b': { 'c': 1 } } }     * ];     *     * _.map(objects, _.property('a.b.c'));     * // => [2, 1]     *     * _.pluck(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c');     * // => [1, 2]     */    function property(path) {      return isKey(path) ? baseProperty(path) : basePropertyDeep(path);    }    /**     * The opposite of `_.property`; this method creates a function that returns     * the property value at a given path on `object`.     *     * @static     * @memberOf _     * @category Utility     * @param {Object} object The object to query.     * @returns {Function} Returns the new function.     * @example     *     * var array = [0, 1, 2],     *     object = { 'a': array, 'b': array, 'c': array };     *     * _.map(['a[2]', 'c[0]'], _.propertyOf(object));     * // => [2, 0]     *     * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));     * // => [2, 0]     */    function propertyOf(object) {      return function(path) {        return baseGet(object, toPath(path), (path + ''));      };    }    /**     * Creates an array of numbers (positive and/or negative) progressing from     * `start` up to, but not including, `end`. If `end` is not specified it's     * set to `start` with `start` then set to `0`. If `end` is less than `start`     * a zero-length range is created unless a negative `step` is specified.     *     * @static     * @memberOf _     * @category Utility     * @param {number} [start=0] The start of the range.     * @param {number} end The end of the range.     * @param {number} [step=1] The value to increment or decrement by.     * @returns {Array} Returns the new array of numbers.     * @example     *     * _.range(4);     * // => [0, 1, 2, 3]     *     * _.range(1, 5);     * // => [1, 2, 3, 4]     *     * _.range(0, 20, 5);     * // => [0, 5, 10, 15]     *     * _.range(0, -4, -1);     * // => [0, -1, -2, -3]     *     * _.range(1, 4, 0);     * // => [1, 1, 1]     *     * _.range(0);     * // => []     */    function range(start, end, step) {      if (step && isIterateeCall(start, end, step)) {        end = step = undefined;      }      start = +start || 0;      step = step == null ? 1 : (+step || 0);      if (end == null) {        end = start;        start = 0;      } else {        end = +end || 0;      }      // Use `Array(length)` so engines like Chakra and V8 avoid slower modes.      // See https://youtu.be/XAqIpGU8ZZk#t=17m25s for more details.      var index = -1,          length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),          result = Array(length);      while (++index < length) {        result[index] = start;        start += step;      }      return result;    }    /**     * Invokes the iteratee function `n` times, returning an array of the results     * of each invocation. The `iteratee` is bound to `thisArg` and invoked with     * one argument; (index).     *     * @static     * @memberOf _     * @category Utility     * @param {number} n The number of times to invoke `iteratee`.     * @param {Function} [iteratee=_.identity] The function invoked per iteration.     * @param {*} [thisArg] The `this` binding of `iteratee`.     * @returns {Array} Returns the array of results.     * @example     *     * var diceRolls = _.times(3, _.partial(_.random, 1, 6, false));     * // => [3, 6, 4]     *     * _.times(3, function(n) {     *   mage.castSpell(n);     * });     * // => invokes `mage.castSpell(n)` three times with `n` of `0`, `1`, and `2`     *     * _.times(3, function(n) {     *   this.cast(n);     * }, mage);     * // => also invokes `mage.castSpell(n)` three times     */    function times(n, iteratee, thisArg) {      n = nativeFloor(n);      // Exit early to avoid a JSC JIT bug in Safari 8      // where `Array(0)` is treated as `Array(1)`.      if (n < 1 || !nativeIsFinite(n)) {        return [];      }      var index = -1,          result = Array(nativeMin(n, MAX_ARRAY_LENGTH));      iteratee = bindCallback(iteratee, thisArg, 1);      while (++index < n) {        if (index < MAX_ARRAY_LENGTH) {          result[index] = iteratee(index);        } else {          iteratee(index);        }      }      return result;    }    /**     * Generates a unique ID. If `prefix` is provided the ID is appended to it.     *     * @static     * @memberOf _     * @category Utility     * @param {string} [prefix] The value to prefix the ID with.     * @returns {string} Returns the unique ID.     * @example     *     * _.uniqueId('contact_');     * // => 'contact_104'     *     * _.uniqueId();     * // => '105'     */    function uniqueId(prefix) {      var id = ++idCounter;      return baseToString(prefix) + id;    }    /*------------------------------------------------------------------------*/    /**     * Adds two numbers.     *     * @static     * @memberOf _     * @category Math     * @param {number} augend The first number to add.     * @param {number} addend The second number to add.     * @returns {number} Returns the sum.     * @example     *     * _.add(6, 4);     * // => 10     */    function add(augend, addend) {      return (+augend || 0) + (+addend || 0);    }    /**     * Calculates `n` rounded up to `precision`.     *     * @static     * @memberOf _     * @category Math     * @param {number} n The number to round up.     * @param {number} [precision=0] The precision to round up to.     * @returns {number} Returns the rounded up number.     * @example     *     * _.ceil(4.006);     * // => 5     *     * _.ceil(6.004, 2);     * // => 6.01     *     * _.ceil(6040, -2);     * // => 6100     */    var ceil = createRound('ceil');    /**     * Calculates `n` rounded down to `precision`.     *     * @static     * @memberOf _     * @category Math     * @param {number} n The number to round down.     * @param {number} [precision=0] The precision to round down to.     * @returns {number} Returns the rounded down number.     * @example     *     * _.floor(4.006);     * // => 4     *     * _.floor(0.046, 2);     * // => 0.04     *     * _.floor(4060, -2);     * // => 4000     */    var floor = createRound('floor');    /**     * Gets the maximum value of `collection`. If `collection` is empty or falsey     * `-Infinity` is returned. If an iteratee function is provided it's invoked     * for each value in `collection` to generate the criterion by which the value     * is ranked. The `iteratee` is bound to `thisArg` and invoked with three     * arguments: (value, index, collection).     *     * If a property name is provided for `iteratee` the created `_.property`     * style callback returns the property value of the given element.     *     * If a value is also provided for `thisArg` the created `_.matchesProperty`     * style callback returns `true` for elements that have a matching property     * value, else `false`.     *     * If an object is provided for `iteratee` the created `_.matches` style     * callback returns `true` for elements that have the properties of the given     * object, else `false`.     *     * @static     * @memberOf _     * @category Math     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function|Object|string} [iteratee] The function invoked per iteration.     * @param {*} [thisArg] The `this` binding of `iteratee`.     * @returns {*} Returns the maximum value.     * @example     *     * _.max([4, 2, 8, 6]);     * // => 8     *     * _.max([]);     * // => -Infinity     *     * var users = [     *   { 'user': 'barney', 'age': 36 },     *   { 'user': 'fred',   'age': 40 }     * ];     *     * _.max(users, function(chr) {     *   return chr.age;     * });     * // => { 'user': 'fred', 'age': 40 }     *     * // using the `_.property` callback shorthand     * _.max(users, 'age');     * // => { 'user': 'fred', 'age': 40 }     */    var max = createExtremum(gt, NEGATIVE_INFINITY);    /**     * Gets the minimum value of `collection`. If `collection` is empty or falsey     * `Infinity` is returned. If an iteratee function is provided it's invoked     * for each value in `collection` to generate the criterion by which the value     * is ranked. The `iteratee` is bound to `thisArg` and invoked with three     * arguments: (value, index, collection).     *     * If a property name is provided for `iteratee` the created `_.property`     * style callback returns the property value of the given element.     *     * If a value is also provided for `thisArg` the created `_.matchesProperty`     * style callback returns `true` for elements that have a matching property     * value, else `false`.     *     * If an object is provided for `iteratee` the created `_.matches` style     * callback returns `true` for elements that have the properties of the given     * object, else `false`.     *     * @static     * @memberOf _     * @category Math     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function|Object|string} [iteratee] The function invoked per iteration.     * @param {*} [thisArg] The `this` binding of `iteratee`.     * @returns {*} Returns the minimum value.     * @example     *     * _.min([4, 2, 8, 6]);     * // => 2     *     * _.min([]);     * // => Infinity     *     * var users = [     *   { 'user': 'barney', 'age': 36 },     *   { 'user': 'fred',   'age': 40 }     * ];     *     * _.min(users, function(chr) {     *   return chr.age;     * });     * // => { 'user': 'barney', 'age': 36 }     *     * // using the `_.property` callback shorthand     * _.min(users, 'age');     * // => { 'user': 'barney', 'age': 36 }     */    var min = createExtremum(lt, POSITIVE_INFINITY);    /**     * Calculates `n` rounded to `precision`.     *     * @static     * @memberOf _     * @category Math     * @param {number} n The number to round.     * @param {number} [precision=0] The precision to round to.     * @returns {number} Returns the rounded number.     * @example     *     * _.round(4.006);     * // => 4     *     * _.round(4.006, 2);     * // => 4.01     *     * _.round(4060, -2);     * // => 4100     */    var round = createRound('round');    /**     * Gets the sum of the values in `collection`.     *     * @static     * @memberOf _     * @category Math     * @param {Array|Object|string} collection The collection to iterate over.     * @param {Function|Object|string} [iteratee] The function invoked per iteration.     * @param {*} [thisArg] The `this` binding of `iteratee`.     * @returns {number} Returns the sum.     * @example     *     * _.sum([4, 6]);     * // => 10     *     * _.sum({ 'a': 4, 'b': 6 });     * // => 10     *     * var objects = [     *   { 'n': 4 },     *   { 'n': 6 }     * ];     *     * _.sum(objects, function(object) {     *   return object.n;     * });     * // => 10     *     * // using the `_.property` callback shorthand     * _.sum(objects, 'n');     * // => 10     */    function sum(collection, iteratee, thisArg) {      if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {        iteratee = undefined;      }      iteratee = getCallback(iteratee, thisArg, 3);      return iteratee.length == 1        ? arraySum(isArray(collection) ? collection : toIterable(collection), iteratee)        : baseSum(collection, iteratee);    }    /*------------------------------------------------------------------------*/    // Ensure wrappers are instances of `baseLodash`.    lodash.prototype = baseLodash.prototype;    LodashWrapper.prototype = baseCreate(baseLodash.prototype);    LodashWrapper.prototype.constructor = LodashWrapper;    LazyWrapper.prototype = baseCreate(baseLodash.prototype);    LazyWrapper.prototype.constructor = LazyWrapper;    // Add functions to the `Map` cache.    MapCache.prototype['delete'] = mapDelete;    MapCache.prototype.get = mapGet;    MapCache.prototype.has = mapHas;    MapCache.prototype.set = mapSet;    // Add functions to the `Set` cache.    SetCache.prototype.push = cachePush;    // Assign cache to `_.memoize`.    memoize.Cache = MapCache;    // Add functions that return wrapped values when chaining.    lodash.after = after;    lodash.ary = ary;    lodash.assign = assign;    lodash.at = at;    lodash.before = before;    lodash.bind = bind;    lodash.bindAll = bindAll;    lodash.bindKey = bindKey;    lodash.callback = callback;    lodash.chain = chain;    lodash.chunk = chunk;    lodash.compact = compact;    lodash.constant = constant;    lodash.countBy = countBy;    lodash.create = create;    lodash.curry = curry;    lodash.curryRight = curryRight;    lodash.debounce = debounce;    lodash.defaults = defaults;    lodash.defaultsDeep = defaultsDeep;    lodash.defer = defer;    lodash.delay = delay;    lodash.difference = difference;    lodash.drop = drop;    lodash.dropRight = dropRight;    lodash.dropRightWhile = dropRightWhile;    lodash.dropWhile = dropWhile;    lodash.fill = fill;    lodash.filter = filter;    lodash.flatten = flatten;    lodash.flattenDeep = flattenDeep;    lodash.flow = flow;    lodash.flowRight = flowRight;    lodash.forEach = forEach;    lodash.forEachRight = forEachRight;    lodash.forIn = forIn;    lodash.forInRight = forInRight;    lodash.forOwn = forOwn;    lodash.forOwnRight = forOwnRight;    lodash.functions = functions;    lodash.groupBy = groupBy;    lodash.indexBy = indexBy;    lodash.initial = initial;    lodash.intersection = intersection;    lodash.invert = invert;    lodash.invoke = invoke;    lodash.keys = keys;    lodash.keysIn = keysIn;    lodash.map = map;    lodash.mapKeys = mapKeys;    lodash.mapValues = mapValues;    lodash.matches = matches;    lodash.matchesProperty = matchesProperty;    lodash.memoize = memoize;    lodash.merge = merge;    lodash.method = method;    lodash.methodOf = methodOf;    lodash.mixin = mixin;    lodash.modArgs = modArgs;    lodash.negate = negate;    lodash.omit = omit;    lodash.once = once;    lodash.pairs = pairs;    lodash.partial = partial;    lodash.partialRight = partialRight;    lodash.partition = partition;    lodash.pick = pick;    lodash.pluck = pluck;    lodash.property = property;    lodash.propertyOf = propertyOf;    lodash.pull = pull;    lodash.pullAt = pullAt;    lodash.range = range;    lodash.rearg = rearg;    lodash.reject = reject;    lodash.remove = remove;    lodash.rest = rest;    lodash.restParam = restParam;    lodash.set = set;    lodash.shuffle = shuffle;    lodash.slice = slice;    lodash.sortBy = sortBy;    lodash.sortByAll = sortByAll;    lodash.sortByOrder = sortByOrder;    lodash.spread = spread;    lodash.take = take;    lodash.takeRight = takeRight;    lodash.takeRightWhile = takeRightWhile;    lodash.takeWhile = takeWhile;    lodash.tap = tap;    lodash.throttle = throttle;    lodash.thru = thru;    lodash.times = times;    lodash.toArray = toArray;    lodash.toPlainObject = toPlainObject;    lodash.transform = transform;    lodash.union = union;    lodash.uniq = uniq;    lodash.unzip = unzip;    lodash.unzipWith = unzipWith;    lodash.values = values;    lodash.valuesIn = valuesIn;    lodash.where = where;    lodash.without = without;    lodash.wrap = wrap;    lodash.xor = xor;    lodash.zip = zip;    lodash.zipObject = zipObject;    lodash.zipWith = zipWith;    // Add aliases.    lodash.backflow = flowRight;    lodash.collect = map;    lodash.compose = flowRight;    lodash.each = forEach;    lodash.eachRight = forEachRight;    lodash.extend = assign;    lodash.iteratee = callback;    lodash.methods = functions;    lodash.object = zipObject;    lodash.select = filter;    lodash.tail = rest;    lodash.unique = uniq;    // Add functions to `lodash.prototype`.    mixin(lodash, lodash);    /*------------------------------------------------------------------------*/    // Add functions that return unwrapped values when chaining.    lodash.add = add;    lodash.attempt = attempt;    lodash.camelCase = camelCase;    lodash.capitalize = capitalize;    lodash.ceil = ceil;    lodash.clone = clone;    lodash.cloneDeep = cloneDeep;    lodash.deburr = deburr;    lodash.endsWith = endsWith;    lodash.escape = escape;    lodash.escapeRegExp = escapeRegExp;    lodash.every = every;    lodash.find = find;    lodash.findIndex = findIndex;    lodash.findKey = findKey;    lodash.findLast = findLast;    lodash.findLastIndex = findLastIndex;    lodash.findLastKey = findLastKey;    lodash.findWhere = findWhere;    lodash.first = first;    lodash.floor = floor;    lodash.get = get;    lodash.gt = gt;    lodash.gte = gte;    lodash.has = has;    lodash.identity = identity;    lodash.includes = includes;    lodash.indexOf = indexOf;    lodash.inRange = inRange;    lodash.isArguments = isArguments;    lodash.isArray = isArray;    lodash.isBoolean = isBoolean;    lodash.isDate = isDate;    lodash.isElement = isElement;    lodash.isEmpty = isEmpty;    lodash.isEqual = isEqual;    lodash.isError = isError;    lodash.isFinite = isFinite;    lodash.isFunction = isFunction;    lodash.isMatch = isMatch;    lodash.isNaN = isNaN;    lodash.isNative = isNative;    lodash.isNull = isNull;    lodash.isNumber = isNumber;    lodash.isObject = isObject;    lodash.isPlainObject = isPlainObject;    lodash.isRegExp = isRegExp;    lodash.isString = isString;    lodash.isTypedArray = isTypedArray;    lodash.isUndefined = isUndefined;    lodash.kebabCase = kebabCase;    lodash.last = last;    lodash.lastIndexOf = lastIndexOf;    lodash.lt = lt;    lodash.lte = lte;    lodash.max = max;    lodash.min = min;    lodash.noConflict = noConflict;    lodash.noop = noop;    lodash.now = now;    lodash.pad = pad;    lodash.padLeft = padLeft;    lodash.padRight = padRight;    lodash.parseInt = parseInt;    lodash.random = random;    lodash.reduce = reduce;    lodash.reduceRight = reduceRight;    lodash.repeat = repeat;    lodash.result = result;    lodash.round = round;    lodash.runInContext = runInContext;    lodash.size = size;    lodash.snakeCase = snakeCase;    lodash.some = some;    lodash.sortedIndex = sortedIndex;    lodash.sortedLastIndex = sortedLastIndex;    lodash.startCase = startCase;    lodash.startsWith = startsWith;    lodash.sum = sum;    lodash.template = template;    lodash.trim = trim;    lodash.trimLeft = trimLeft;    lodash.trimRight = trimRight;    lodash.trunc = trunc;    lodash.unescape = unescape;    lodash.uniqueId = uniqueId;    lodash.words = words;    // Add aliases.    lodash.all = every;    lodash.any = some;    lodash.contains = includes;    lodash.eq = isEqual;    lodash.detect = find;    lodash.foldl = reduce;    lodash.foldr = reduceRight;    lodash.head = first;    lodash.include = includes;    lodash.inject = reduce;    mixin(lodash, (function() {      var source = {};      baseForOwn(lodash, function(func, methodName) {        if (!lodash.prototype[methodName]) {          source[methodName] = func;        }      });      return source;    }()), false);    /*------------------------------------------------------------------------*/    // Add functions capable of returning wrapped and unwrapped values when chaining.    lodash.sample = sample;    lodash.prototype.sample = function(n) {      if (!this.__chain__ && n == null) {        return sample(this.value());      }      return this.thru(function(value) {        return sample(value, n);      });    };    /*------------------------------------------------------------------------*/    /**     * The semantic version number.     *     * @static     * @memberOf _     * @type string     */    lodash.VERSION = VERSION;    // Assign default placeholders.    arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {      lodash[methodName].placeholder = lodash;    });    // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.    arrayEach(['drop', 'take'], function(methodName, index) {      LazyWrapper.prototype[methodName] = function(n) {        var filtered = this.__filtered__;        if (filtered && !index) {          return new LazyWrapper(this);        }        n = n == null ? 1 : nativeMax(nativeFloor(n) || 0, 0);        var result = this.clone();        if (filtered) {          result.__takeCount__ = nativeMin(result.__takeCount__, n);        } else {          result.__views__.push({ 'size': n, 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') });        }        return result;      };      LazyWrapper.prototype[methodName + 'Right'] = function(n) {        return this.reverse()[methodName](n).reverse();      };    });    // Add `LazyWrapper` methods that accept an `iteratee` value.    arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {      var type = index + 1,          isFilter = type != LAZY_MAP_FLAG;      LazyWrapper.prototype[methodName] = function(iteratee, thisArg) {        var result = this.clone();        result.__iteratees__.push({ 'iteratee': getCallback(iteratee, thisArg, 1), 'type': type });        result.__filtered__ = result.__filtered__ || isFilter;        return result;      };    });    // Add `LazyWrapper` methods for `_.first` and `_.last`.    arrayEach(['first', 'last'], function(methodName, index) {      var takeName = 'take' + (index ? 'Right' : '');      LazyWrapper.prototype[methodName] = function() {        return this[takeName](1).value()[0];      };    });    // Add `LazyWrapper` methods for `_.initial` and `_.rest`.    arrayEach(['initial', 'rest'], function(methodName, index) {      var dropName = 'drop' + (index ? '' : 'Right');      LazyWrapper.prototype[methodName] = function() {        return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);      };    });    // Add `LazyWrapper` methods for `_.pluck` and `_.where`.    arrayEach(['pluck', 'where'], function(methodName, index) {      var operationName = index ? 'filter' : 'map',          createCallback = index ? baseMatches : property;      LazyWrapper.prototype[methodName] = function(value) {        return this[operationName](createCallback(value));      };    });    LazyWrapper.prototype.compact = function() {      return this.filter(identity);    };    LazyWrapper.prototype.reject = function(predicate, thisArg) {      predicate = getCallback(predicate, thisArg, 1);      return this.filter(function(value) {        return !predicate(value);      });    };    LazyWrapper.prototype.slice = function(start, end) {      start = start == null ? 0 : (+start || 0);      var result = this;      if (result.__filtered__ && (start > 0 || end < 0)) {        return new LazyWrapper(result);      }      if (start < 0) {        result = result.takeRight(-start);      } else if (start) {        result = result.drop(start);      }      if (end !== undefined) {        end = (+end || 0);        result = end < 0 ? result.dropRight(-end) : result.take(end - start);      }      return result;    };    LazyWrapper.prototype.takeRightWhile = function(predicate, thisArg) {      return this.reverse().takeWhile(predicate, thisArg).reverse();    };    LazyWrapper.prototype.toArray = function() {      return this.take(POSITIVE_INFINITY);    };    // Add `LazyWrapper` methods to `lodash.prototype`.    baseForOwn(LazyWrapper.prototype, function(func, methodName) {      var checkIteratee = /^(?:filter|map|reject)|While$/.test(methodName),          retUnwrapped = /^(?:first|last)$/.test(methodName),          lodashFunc = lodash[retUnwrapped ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName];      if (!lodashFunc) {        return;      }      lodash.prototype[methodName] = function() {        var args = retUnwrapped ? [1] : arguments,            chainAll = this.__chain__,            value = this.__wrapped__,            isHybrid = !!this.__actions__.length,            isLazy = value instanceof LazyWrapper,            iteratee = args[0],            useLazy = isLazy || isArray(value);        if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {          // Avoid lazy use if the iteratee has a "length" value other than `1`.          isLazy = useLazy = false;        }        var interceptor = function(value) {          return (retUnwrapped && chainAll)            ? lodashFunc(value, 1)[0]            : lodashFunc.apply(undefined, arrayPush([value], args));        };        var action = { 'func': thru, 'args': [interceptor], 'thisArg': undefined },            onlyLazy = isLazy && !isHybrid;        if (retUnwrapped && !chainAll) {          if (onlyLazy) {            value = value.clone();            value.__actions__.push(action);            return func.call(value);          }          return lodashFunc.call(undefined, this.value())[0];        }        if (!retUnwrapped && useLazy) {          value = onlyLazy ? value : new LazyWrapper(this);          var result = func.apply(value, args);          result.__actions__.push(action);          return new LodashWrapper(result, chainAll);        }        return this.thru(interceptor);      };    });    // Add `Array` and `String` methods to `lodash.prototype`.    arrayEach(['join', 'pop', 'push', 'replace', 'shift', 'sort', 'splice', 'split', 'unshift'], function(methodName) {      var protoFunc = (/^(?:replace|split)$/.test(methodName) ? stringProto : arrayProto)[methodName],          chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',          fixObjects = !support.spliceObjects && /^(?:pop|shift|splice)$/.test(methodName),          retUnwrapped = /^(?:join|pop|replace|shift)$/.test(methodName);      // Avoid array-like object bugs with `Array#shift` and `Array#splice` in      // IE < 9, Firefox < 10, and RingoJS.      var func = !fixObjects ? protoFunc : function() {        var result = protoFunc.apply(this, arguments);        if (this.length === 0) {          delete this[0];        }        return result;      };      lodash.prototype[methodName] = function() {        var args = arguments;        if (retUnwrapped && !this.__chain__) {          return func.apply(this.value(), args);        }        return this[chainName](function(value) {          return func.apply(value, args);        });      };    });    // Map minified function names to their real names.    baseForOwn(LazyWrapper.prototype, function(func, methodName) {      var lodashFunc = lodash[methodName];      if (lodashFunc) {        var key = (lodashFunc.name + ''),            names = realNames[key] || (realNames[key] = []);        names.push({ 'name': methodName, 'func': lodashFunc });      }    });    realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{ 'name': 'wrapper', 'func': undefined }];    // Add functions to the lazy wrapper.    LazyWrapper.prototype.clone = lazyClone;    LazyWrapper.prototype.reverse = lazyReverse;    LazyWrapper.prototype.value = lazyValue;    // Add chaining functions to the `lodash` wrapper.    lodash.prototype.chain = wrapperChain;    lodash.prototype.commit = wrapperCommit;    lodash.prototype.concat = wrapperConcat;    lodash.prototype.plant = wrapperPlant;    lodash.prototype.reverse = wrapperReverse;    lodash.prototype.toString = wrapperToString;    lodash.prototype.run = lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;    // Add function aliases to the `lodash` wrapper.    lodash.prototype.collect = lodash.prototype.map;    lodash.prototype.head = lodash.prototype.first;    lodash.prototype.select = lodash.prototype.filter;    lodash.prototype.tail = lodash.prototype.rest;    return lodash;  }  /*--------------------------------------------------------------------------*/  // Export lodash.  var _ = runInContext();  // Some AMD build optimizers like r.js check for condition patterns like the following:  if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {    // Expose lodash to the global object when an AMD loader is present to avoid    // errors in cases where lodash is loaded by a script tag and not intended    // as an AMD module. See http://requirejs.org/docs/errors.html#mismatch for    // more details.    root._ = _;    // Define as an anonymous module so, through path mapping, it can be    // referenced as the "underscore" module.    define(function() {      return _;    });  }  // Check for `exports` after `define` in case a build optimizer adds an `exports` object.  else if (freeExports && freeModule) {    // Export for Node.js or RingoJS.    if (moduleExports) {      (freeModule.exports = _)._ = _;    }    // Export for Rhino with CommonJS support.    else {      freeExports._ = _;    }  }  else {    // Export for a browser or Rhino.    root._ = _;  }}.call(this));
 |