graphlib-dot.js 327 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626
  1. (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  2. (function (global){
  3. /*
  4. * Copyright (c) 2012-2013 Chris Pettitt
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. */
  24. graphlibDot = require("./index");
  25. graphlibDot.graphlib = require("graphlib");
  26. global.graphlibDot = graphlibDot;
  27. }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  28. },{"./index":2,"graphlib":9}],2:[function(require,module,exports){
  29. var read = require("./lib/read-one"),
  30. readMany = require("./lib/read-many"),
  31. write = require("./lib/write-one"),
  32. version = require("./lib/version");
  33. module.exports = {
  34. // Parsing
  35. read: read,
  36. readMany: readMany,
  37. // Writing
  38. write: write,
  39. // Version
  40. version: version,
  41. // For levelup encoding
  42. type: "dot",
  43. buffer: false
  44. };
  45. },{"./lib/read-many":5,"./lib/read-one":6,"./lib/version":7,"./lib/write-one":8}],3:[function(require,module,exports){
  46. "use strict";
  47. var _ = require("lodash"),
  48. Graph = require("graphlib").Graph;
  49. module.exports = buildGraph;
  50. function buildGraph(parseTree) {
  51. var isDirected = parseTree.type !== "graph",
  52. isMultigraph = !parseTree.strict,
  53. defaultStack = [{ node: {}, edge: {} }],
  54. g = new Graph({ directed: isDirected, multigraph: isMultigraph, compound: true });
  55. g.setGraph({});
  56. _.each(parseTree.stmts, function(stmt) { handleStmt(g, stmt, defaultStack); });
  57. return g;
  58. }
  59. function handleStmt(g, stmt, defaultStack, sg) {
  60. switch(stmt.type) {
  61. case "node": handleNodeStmt(g, stmt, defaultStack, sg); break;
  62. case "edge": handleEdgeStmt(g, stmt, defaultStack, sg); break;
  63. case "subgraph": handleSubgraphStmt(g, stmt, defaultStack, sg); break;
  64. case "attr": handleAttrStmt(g, stmt, defaultStack); break;
  65. case "inlineAttr": handleInlineAttrsStmt(g, stmt, defaultStack, sg); break;
  66. }
  67. }
  68. function handleNodeStmt(g, stmt, defaultStack, sg) {
  69. var v = stmt.id,
  70. attrs = stmt.attrs;
  71. maybeCreateNode(g, v, defaultStack, sg);
  72. _.merge(g.node(v), attrs);
  73. }
  74. function handleEdgeStmt(g, stmt, defaultStack, sg) {
  75. var attrs = stmt.attrs,
  76. prev, curr;
  77. _.each(stmt.elems, function(elem) {
  78. handleStmt(g, elem, defaultStack, sg);
  79. switch(elem.type) {
  80. case "node": curr = [elem.id]; break;
  81. case "subgraph": curr = collectNodeIds(elem); break;
  82. }
  83. _.each(prev, function(v) {
  84. _.each(curr, function(w) {
  85. var name;
  86. if (g.hasEdge(v, w) && g.isMultigraph()) {
  87. name = _.uniqueId("edge");
  88. }
  89. if (!g.hasEdge(v, w, name)) {
  90. g.setEdge(v, w, _.clone(_.last(defaultStack).edge), name);
  91. }
  92. _.merge(g.edge(v, w, name), attrs);
  93. });
  94. });
  95. prev = curr;
  96. });
  97. }
  98. function handleSubgraphStmt(g, stmt, defaultStack, sg) {
  99. var id = stmt.id;
  100. if (id === undefined) {
  101. id = generateSubgraphId(g);
  102. }
  103. defaultStack.push(_.clone(_.last(defaultStack)));
  104. maybeCreateNode(g, id, defaultStack, sg);
  105. _.each(stmt.stmts, function(s) {
  106. handleStmt(g, s, defaultStack, id);
  107. });
  108. // If there are no statements remove the subgraph
  109. if (!g.children(id).length) {
  110. g.removeNode(id);
  111. }
  112. defaultStack.pop();
  113. }
  114. function handleAttrStmt(g, stmt, defaultStack) {
  115. _.merge(_.last(defaultStack)[stmt.attrType], stmt.attrs);
  116. }
  117. function handleInlineAttrsStmt(g, stmt, defaultStack, sg) {
  118. _.merge(sg ? g.node(sg) : g.graph(), stmt.attrs);
  119. }
  120. function generateSubgraphId(g) {
  121. var id;
  122. do {
  123. id = _.uniqueId("sg");
  124. } while (g.hasNode(id));
  125. return id;
  126. }
  127. function maybeCreateNode(g, v, defaultStack, sg) {
  128. if (!g.hasNode(v)) {
  129. g.setNode(v, _.clone(_.last(defaultStack).node));
  130. g.setParent(v, sg);
  131. }
  132. }
  133. // Collect all nodes involved in a subgraph statement
  134. function collectNodeIds(stmt) {
  135. var ids = {},
  136. stack = [],
  137. curr;
  138. var push = stack.push.bind(stack);
  139. push(stmt);
  140. while(stack.length) {
  141. curr = stack.pop();
  142. switch(curr.type) {
  143. case "node": ids[curr.id] = true; break;
  144. case "edge": _.each(curr.elems, push); break;
  145. case "subgraph": _.each(curr.stmts, push); break;
  146. }
  147. }
  148. return _.keys(ids);
  149. }
  150. },{"graphlib":9,"lodash":28}],4:[function(require,module,exports){
  151. module.exports = (function() {
  152. /*
  153. * Generated by PEG.js 0.8.0.
  154. *
  155. * http://pegjs.majda.cz/
  156. */
  157. function peg$subclass(child, parent) {
  158. function ctor() { this.constructor = child; }
  159. ctor.prototype = parent.prototype;
  160. child.prototype = new ctor();
  161. }
  162. function SyntaxError(message, expected, found, offset, line, column) {
  163. this.message = message;
  164. this.expected = expected;
  165. this.found = found;
  166. this.offset = offset;
  167. this.line = line;
  168. this.column = column;
  169. this.name = "SyntaxError";
  170. }
  171. peg$subclass(SyntaxError, Error);
  172. function parse(input) {
  173. var options = arguments.length > 1 ? arguments[1] : {},
  174. peg$FAILED = {},
  175. peg$startRuleFunctions = { start: peg$parsestart, graphStmt: peg$parsegraphStmt },
  176. peg$startRuleFunction = peg$parsestart,
  177. peg$c0 = [],
  178. peg$c1 = peg$FAILED,
  179. peg$c2 = null,
  180. peg$c3 = "{",
  181. peg$c4 = { type: "literal", value: "{", description: "\"{\"" },
  182. peg$c5 = "}",
  183. peg$c6 = { type: "literal", value: "}", description: "\"}\"" },
  184. peg$c7 = function(strict, type, id, stmts) {
  185. return {type: type, id: id, strict: strict !== null, stmts: stmts};
  186. },
  187. peg$c8 = ";",
  188. peg$c9 = { type: "literal", value: ";", description: "\";\"" },
  189. peg$c10 = function(first, rest) {
  190. var result = [first];
  191. for (var i = 0; i < rest.length; ++i) {
  192. result.push(rest[i][1]);
  193. }
  194. return result;
  195. },
  196. peg$c11 = function(type, attrs) {
  197. return { type: "attr", attrType: type, attrs: attrs || {}};
  198. },
  199. peg$c12 = "=",
  200. peg$c13 = { type: "literal", value: "=", description: "\"=\"" },
  201. peg$c14 = function(k, v) {
  202. var attrs = {};
  203. attrs[k] = v;
  204. return { type: "inlineAttr", attrs: attrs };
  205. },
  206. peg$c15 = function(id, attrs) { return {type: "node", id: id, attrs: attrs || {}}; },
  207. peg$c16 = function(lhs, rhs, attrs) {
  208. var elems = [lhs];
  209. for (var i = 0; i < rhs.length; ++i) {
  210. elems.push(rhs[i]);
  211. }
  212. return { type: "edge", elems: elems, attrs: attrs || {} };
  213. },
  214. peg$c17 = function(id, stmts) {
  215. id = (id && id[2]) || [];
  216. return { type: "subgraph", id: id[0], stmts: stmts };
  217. },
  218. peg$c18 = function(first, rest) {
  219. var result = first;
  220. for (var i = 0; i < rest.length; ++i) {
  221. _.merge(result, rest[i][1]);
  222. }
  223. return result;
  224. },
  225. peg$c19 = "[",
  226. peg$c20 = { type: "literal", value: "[", description: "\"[\"" },
  227. peg$c21 = "]",
  228. peg$c22 = { type: "literal", value: "]", description: "\"]\"" },
  229. peg$c23 = function(aList) { return aList; },
  230. peg$c24 = ",",
  231. peg$c25 = { type: "literal", value: ",", description: "\",\"" },
  232. peg$c26 = function(first, rest) {
  233. var result = first;
  234. for (var i = 0; i < rest.length; ++i) {
  235. _.merge(result, rest[i][3]);
  236. }
  237. return result;
  238. },
  239. peg$c27 = "--",
  240. peg$c28 = { type: "literal", value: "--", description: "\"--\"" },
  241. peg$c29 = function() { return directed; },
  242. peg$c30 = void 0,
  243. peg$c31 = "->",
  244. peg$c32 = { type: "literal", value: "->", description: "\"->\"" },
  245. peg$c33 = function(rhs, rest) {
  246. var result = [rhs];
  247. if (rest) {
  248. for (var i = 0; i < rest.length; ++i) {
  249. result.push(rest[i]);
  250. }
  251. }
  252. return result;
  253. },
  254. peg$c34 = function(k, v) {
  255. var result = {};
  256. result[k] = v[3];
  257. return result;
  258. },
  259. peg$c35 = function(id) { return { type: "node", id: id, attrs: {} }; },
  260. peg$c36 = function(id) { return id; },
  261. peg$c37 = ":",
  262. peg$c38 = { type: "literal", value: ":", description: "\":\"" },
  263. peg$c39 = "ne",
  264. peg$c40 = { type: "literal", value: "ne", description: "\"ne\"" },
  265. peg$c41 = "se",
  266. peg$c42 = { type: "literal", value: "se", description: "\"se\"" },
  267. peg$c43 = "sw",
  268. peg$c44 = { type: "literal", value: "sw", description: "\"sw\"" },
  269. peg$c45 = "nw",
  270. peg$c46 = { type: "literal", value: "nw", description: "\"nw\"" },
  271. peg$c47 = "n",
  272. peg$c48 = { type: "literal", value: "n", description: "\"n\"" },
  273. peg$c49 = "e",
  274. peg$c50 = { type: "literal", value: "e", description: "\"e\"" },
  275. peg$c51 = "s",
  276. peg$c52 = { type: "literal", value: "s", description: "\"s\"" },
  277. peg$c53 = "w",
  278. peg$c54 = { type: "literal", value: "w", description: "\"w\"" },
  279. peg$c55 = "c",
  280. peg$c56 = { type: "literal", value: "c", description: "\"c\"" },
  281. peg$c57 = "_",
  282. peg$c58 = { type: "literal", value: "_", description: "\"_\"" },
  283. peg$c59 = { type: "other", description: "identifier" },
  284. peg$c60 = /^[a-zA-Z\u0200-\u0377_]/,
  285. peg$c61 = { type: "class", value: "[a-zA-Z\\u0200-\\u0377_]", description: "[a-zA-Z\\u0200-\\u0377_]" },
  286. peg$c62 = /^[a-zA-Z\u0200-\u0377_0-9]/,
  287. peg$c63 = { type: "class", value: "[a-zA-Z\\u0200-\\u0377_0-9]", description: "[a-zA-Z\\u0200-\\u0377_0-9]" },
  288. peg$c64 = function(fst, rest) { return fst + rest.join(""); },
  289. peg$c65 = "-",
  290. peg$c66 = { type: "literal", value: "-", description: "\"-\"" },
  291. peg$c67 = ".",
  292. peg$c68 = { type: "literal", value: ".", description: "\".\"" },
  293. peg$c69 = /^[0-9]/,
  294. peg$c70 = { type: "class", value: "[0-9]", description: "[0-9]" },
  295. peg$c71 = function(sign, dot, after) {
  296. return (sign || "") + dot + after.join("");
  297. },
  298. peg$c72 = function(sign, before, after) {
  299. return (sign || "") + before.join("") + (after ? after[0] : "") + (after ? after[1].join("") : "");
  300. },
  301. peg$c73 = "\"",
  302. peg$c74 = { type: "literal", value: "\"", description: "\"\\\"\"" },
  303. peg$c75 = "\\\"",
  304. peg$c76 = { type: "literal", value: "\\\"", description: "\"\\\\\\\"\"" },
  305. peg$c77 = function() { return '"'; },
  306. peg$c78 = "\\",
  307. peg$c79 = { type: "literal", value: "\\", description: "\"\\\\\"" },
  308. peg$c80 = /^[^"]/,
  309. peg$c81 = { type: "class", value: "[^\"]", description: "[^\"]" },
  310. peg$c82 = function(ch) { return "\\" + ch; },
  311. peg$c83 = function(id) {
  312. return id.join("");
  313. },
  314. peg$c84 = "node",
  315. peg$c85 = { type: "literal", value: "node", description: "\"node\"" },
  316. peg$c86 = function(k) { return k.toLowerCase(); },
  317. peg$c87 = "edge",
  318. peg$c88 = { type: "literal", value: "edge", description: "\"edge\"" },
  319. peg$c89 = "graph",
  320. peg$c90 = { type: "literal", value: "graph", description: "\"graph\"" },
  321. peg$c91 = "digraph",
  322. peg$c92 = { type: "literal", value: "digraph", description: "\"digraph\"" },
  323. peg$c93 = "subgraph",
  324. peg$c94 = { type: "literal", value: "subgraph", description: "\"subgraph\"" },
  325. peg$c95 = "strict",
  326. peg$c96 = { type: "literal", value: "strict", description: "\"strict\"" },
  327. peg$c97 = function(graph) {
  328. directed = graph === "digraph";
  329. return graph;
  330. },
  331. peg$c98 = { type: "other", description: "whitespace" },
  332. peg$c99 = /^[ \t\r\n]/,
  333. peg$c100 = { type: "class", value: "[ \\t\\r\\n]", description: "[ \\t\\r\\n]" },
  334. peg$c101 = { type: "other", description: "comment" },
  335. peg$c102 = "//",
  336. peg$c103 = { type: "literal", value: "//", description: "\"//\"" },
  337. peg$c104 = /^[^\n]/,
  338. peg$c105 = { type: "class", value: "[^\\n]", description: "[^\\n]" },
  339. peg$c106 = "/*",
  340. peg$c107 = { type: "literal", value: "/*", description: "\"/*\"" },
  341. peg$c108 = "*/",
  342. peg$c109 = { type: "literal", value: "*/", description: "\"*/\"" },
  343. peg$c110 = { type: "any", description: "any character" },
  344. peg$currPos = 0,
  345. peg$reportedPos = 0,
  346. peg$cachedPos = 0,
  347. peg$cachedPosDetails = { line: 1, column: 1, seenCR: false },
  348. peg$maxFailPos = 0,
  349. peg$maxFailExpected = [],
  350. peg$silentFails = 0,
  351. peg$result;
  352. if ("startRule" in options) {
  353. if (!(options.startRule in peg$startRuleFunctions)) {
  354. throw new Error("Can't start parsing from rule \"" + options.startRule + "\".");
  355. }
  356. peg$startRuleFunction = peg$startRuleFunctions[options.startRule];
  357. }
  358. function text() {
  359. return input.substring(peg$reportedPos, peg$currPos);
  360. }
  361. function offset() {
  362. return peg$reportedPos;
  363. }
  364. function line() {
  365. return peg$computePosDetails(peg$reportedPos).line;
  366. }
  367. function column() {
  368. return peg$computePosDetails(peg$reportedPos).column;
  369. }
  370. function expected(description) {
  371. throw peg$buildException(
  372. null,
  373. [{ type: "other", description: description }],
  374. peg$reportedPos
  375. );
  376. }
  377. function error(message) {
  378. throw peg$buildException(message, null, peg$reportedPos);
  379. }
  380. function peg$computePosDetails(pos) {
  381. function advance(details, startPos, endPos) {
  382. var p, ch;
  383. for (p = startPos; p < endPos; p++) {
  384. ch = input.charAt(p);
  385. if (ch === "\n") {
  386. if (!details.seenCR) { details.line++; }
  387. details.column = 1;
  388. details.seenCR = false;
  389. } else if (ch === "\r" || ch === "\u2028" || ch === "\u2029") {
  390. details.line++;
  391. details.column = 1;
  392. details.seenCR = true;
  393. } else {
  394. details.column++;
  395. details.seenCR = false;
  396. }
  397. }
  398. }
  399. if (peg$cachedPos !== pos) {
  400. if (peg$cachedPos > pos) {
  401. peg$cachedPos = 0;
  402. peg$cachedPosDetails = { line: 1, column: 1, seenCR: false };
  403. }
  404. advance(peg$cachedPosDetails, peg$cachedPos, pos);
  405. peg$cachedPos = pos;
  406. }
  407. return peg$cachedPosDetails;
  408. }
  409. function peg$fail(expected) {
  410. if (peg$currPos < peg$maxFailPos) { return; }
  411. if (peg$currPos > peg$maxFailPos) {
  412. peg$maxFailPos = peg$currPos;
  413. peg$maxFailExpected = [];
  414. }
  415. peg$maxFailExpected.push(expected);
  416. }
  417. function peg$buildException(message, expected, pos) {
  418. function cleanupExpected(expected) {
  419. var i = 1;
  420. expected.sort(function(a, b) {
  421. if (a.description < b.description) {
  422. return -1;
  423. } else if (a.description > b.description) {
  424. return 1;
  425. } else {
  426. return 0;
  427. }
  428. });
  429. while (i < expected.length) {
  430. if (expected[i - 1] === expected[i]) {
  431. expected.splice(i, 1);
  432. } else {
  433. i++;
  434. }
  435. }
  436. }
  437. function buildMessage(expected, found) {
  438. function stringEscape(s) {
  439. function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); }
  440. return s
  441. .replace(/\\/g, '\\\\')
  442. .replace(/"/g, '\\"')
  443. .replace(/\x08/g, '\\b')
  444. .replace(/\t/g, '\\t')
  445. .replace(/\n/g, '\\n')
  446. .replace(/\f/g, '\\f')
  447. .replace(/\r/g, '\\r')
  448. .replace(/[\x00-\x07\x0B\x0E\x0F]/g, function(ch) { return '\\x0' + hex(ch); })
  449. .replace(/[\x10-\x1F\x80-\xFF]/g, function(ch) { return '\\x' + hex(ch); })
  450. .replace(/[\u0180-\u0FFF]/g, function(ch) { return '\\u0' + hex(ch); })
  451. .replace(/[\u1080-\uFFFF]/g, function(ch) { return '\\u' + hex(ch); });
  452. }
  453. var expectedDescs = new Array(expected.length),
  454. expectedDesc, foundDesc, i;
  455. for (i = 0; i < expected.length; i++) {
  456. expectedDescs[i] = expected[i].description;
  457. }
  458. expectedDesc = expected.length > 1
  459. ? expectedDescs.slice(0, -1).join(", ")
  460. + " or "
  461. + expectedDescs[expected.length - 1]
  462. : expectedDescs[0];
  463. foundDesc = found ? "\"" + stringEscape(found) + "\"" : "end of input";
  464. return "Expected " + expectedDesc + " but " + foundDesc + " found.";
  465. }
  466. var posDetails = peg$computePosDetails(pos),
  467. found = pos < input.length ? input.charAt(pos) : null;
  468. if (expected !== null) {
  469. cleanupExpected(expected);
  470. }
  471. return new SyntaxError(
  472. message !== null ? message : buildMessage(expected, found),
  473. expected,
  474. found,
  475. pos,
  476. posDetails.line,
  477. posDetails.column
  478. );
  479. }
  480. function peg$parsestart() {
  481. var s0, s1;
  482. s0 = [];
  483. s1 = peg$parsegraphStmt();
  484. if (s1 !== peg$FAILED) {
  485. while (s1 !== peg$FAILED) {
  486. s0.push(s1);
  487. s1 = peg$parsegraphStmt();
  488. }
  489. } else {
  490. s0 = peg$c1;
  491. }
  492. return s0;
  493. }
  494. function peg$parsegraphStmt() {
  495. var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13;
  496. s0 = peg$currPos;
  497. s1 = [];
  498. s2 = peg$parse_();
  499. while (s2 !== peg$FAILED) {
  500. s1.push(s2);
  501. s2 = peg$parse_();
  502. }
  503. if (s1 !== peg$FAILED) {
  504. s2 = peg$currPos;
  505. s3 = peg$parsestrict();
  506. if (s3 !== peg$FAILED) {
  507. s4 = peg$parse_();
  508. if (s4 !== peg$FAILED) {
  509. s3 = [s3, s4];
  510. s2 = s3;
  511. } else {
  512. peg$currPos = s2;
  513. s2 = peg$c1;
  514. }
  515. } else {
  516. peg$currPos = s2;
  517. s2 = peg$c1;
  518. }
  519. if (s2 === peg$FAILED) {
  520. s2 = peg$c2;
  521. }
  522. if (s2 !== peg$FAILED) {
  523. s3 = peg$parsegraphType();
  524. if (s3 !== peg$FAILED) {
  525. s4 = [];
  526. s5 = peg$parse_();
  527. while (s5 !== peg$FAILED) {
  528. s4.push(s5);
  529. s5 = peg$parse_();
  530. }
  531. if (s4 !== peg$FAILED) {
  532. s5 = peg$parseid();
  533. if (s5 === peg$FAILED) {
  534. s5 = peg$c2;
  535. }
  536. if (s5 !== peg$FAILED) {
  537. s6 = [];
  538. s7 = peg$parse_();
  539. while (s7 !== peg$FAILED) {
  540. s6.push(s7);
  541. s7 = peg$parse_();
  542. }
  543. if (s6 !== peg$FAILED) {
  544. if (input.charCodeAt(peg$currPos) === 123) {
  545. s7 = peg$c3;
  546. peg$currPos++;
  547. } else {
  548. s7 = peg$FAILED;
  549. if (peg$silentFails === 0) { peg$fail(peg$c4); }
  550. }
  551. if (s7 !== peg$FAILED) {
  552. s8 = [];
  553. s9 = peg$parse_();
  554. while (s9 !== peg$FAILED) {
  555. s8.push(s9);
  556. s9 = peg$parse_();
  557. }
  558. if (s8 !== peg$FAILED) {
  559. s9 = peg$parsestmtList();
  560. if (s9 === peg$FAILED) {
  561. s9 = peg$c2;
  562. }
  563. if (s9 !== peg$FAILED) {
  564. s10 = [];
  565. s11 = peg$parse_();
  566. while (s11 !== peg$FAILED) {
  567. s10.push(s11);
  568. s11 = peg$parse_();
  569. }
  570. if (s10 !== peg$FAILED) {
  571. if (input.charCodeAt(peg$currPos) === 125) {
  572. s11 = peg$c5;
  573. peg$currPos++;
  574. } else {
  575. s11 = peg$FAILED;
  576. if (peg$silentFails === 0) { peg$fail(peg$c6); }
  577. }
  578. if (s11 !== peg$FAILED) {
  579. s12 = [];
  580. s13 = peg$parse_();
  581. while (s13 !== peg$FAILED) {
  582. s12.push(s13);
  583. s13 = peg$parse_();
  584. }
  585. if (s12 !== peg$FAILED) {
  586. peg$reportedPos = s0;
  587. s1 = peg$c7(s2, s3, s5, s9);
  588. s0 = s1;
  589. } else {
  590. peg$currPos = s0;
  591. s0 = peg$c1;
  592. }
  593. } else {
  594. peg$currPos = s0;
  595. s0 = peg$c1;
  596. }
  597. } else {
  598. peg$currPos = s0;
  599. s0 = peg$c1;
  600. }
  601. } else {
  602. peg$currPos = s0;
  603. s0 = peg$c1;
  604. }
  605. } else {
  606. peg$currPos = s0;
  607. s0 = peg$c1;
  608. }
  609. } else {
  610. peg$currPos = s0;
  611. s0 = peg$c1;
  612. }
  613. } else {
  614. peg$currPos = s0;
  615. s0 = peg$c1;
  616. }
  617. } else {
  618. peg$currPos = s0;
  619. s0 = peg$c1;
  620. }
  621. } else {
  622. peg$currPos = s0;
  623. s0 = peg$c1;
  624. }
  625. } else {
  626. peg$currPos = s0;
  627. s0 = peg$c1;
  628. }
  629. } else {
  630. peg$currPos = s0;
  631. s0 = peg$c1;
  632. }
  633. } else {
  634. peg$currPos = s0;
  635. s0 = peg$c1;
  636. }
  637. return s0;
  638. }
  639. function peg$parsestmtList() {
  640. var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9;
  641. s0 = peg$currPos;
  642. s1 = peg$parsestmt();
  643. if (s1 !== peg$FAILED) {
  644. s2 = [];
  645. s3 = peg$parse_();
  646. while (s3 !== peg$FAILED) {
  647. s2.push(s3);
  648. s3 = peg$parse_();
  649. }
  650. if (s2 !== peg$FAILED) {
  651. if (input.charCodeAt(peg$currPos) === 59) {
  652. s3 = peg$c8;
  653. peg$currPos++;
  654. } else {
  655. s3 = peg$FAILED;
  656. if (peg$silentFails === 0) { peg$fail(peg$c9); }
  657. }
  658. if (s3 === peg$FAILED) {
  659. s3 = peg$c2;
  660. }
  661. if (s3 !== peg$FAILED) {
  662. s4 = [];
  663. s5 = peg$currPos;
  664. s6 = [];
  665. s7 = peg$parse_();
  666. while (s7 !== peg$FAILED) {
  667. s6.push(s7);
  668. s7 = peg$parse_();
  669. }
  670. if (s6 !== peg$FAILED) {
  671. s7 = peg$parsestmt();
  672. if (s7 !== peg$FAILED) {
  673. s8 = [];
  674. s9 = peg$parse_();
  675. while (s9 !== peg$FAILED) {
  676. s8.push(s9);
  677. s9 = peg$parse_();
  678. }
  679. if (s8 !== peg$FAILED) {
  680. if (input.charCodeAt(peg$currPos) === 59) {
  681. s9 = peg$c8;
  682. peg$currPos++;
  683. } else {
  684. s9 = peg$FAILED;
  685. if (peg$silentFails === 0) { peg$fail(peg$c9); }
  686. }
  687. if (s9 === peg$FAILED) {
  688. s9 = peg$c2;
  689. }
  690. if (s9 !== peg$FAILED) {
  691. s6 = [s6, s7, s8, s9];
  692. s5 = s6;
  693. } else {
  694. peg$currPos = s5;
  695. s5 = peg$c1;
  696. }
  697. } else {
  698. peg$currPos = s5;
  699. s5 = peg$c1;
  700. }
  701. } else {
  702. peg$currPos = s5;
  703. s5 = peg$c1;
  704. }
  705. } else {
  706. peg$currPos = s5;
  707. s5 = peg$c1;
  708. }
  709. while (s5 !== peg$FAILED) {
  710. s4.push(s5);
  711. s5 = peg$currPos;
  712. s6 = [];
  713. s7 = peg$parse_();
  714. while (s7 !== peg$FAILED) {
  715. s6.push(s7);
  716. s7 = peg$parse_();
  717. }
  718. if (s6 !== peg$FAILED) {
  719. s7 = peg$parsestmt();
  720. if (s7 !== peg$FAILED) {
  721. s8 = [];
  722. s9 = peg$parse_();
  723. while (s9 !== peg$FAILED) {
  724. s8.push(s9);
  725. s9 = peg$parse_();
  726. }
  727. if (s8 !== peg$FAILED) {
  728. if (input.charCodeAt(peg$currPos) === 59) {
  729. s9 = peg$c8;
  730. peg$currPos++;
  731. } else {
  732. s9 = peg$FAILED;
  733. if (peg$silentFails === 0) { peg$fail(peg$c9); }
  734. }
  735. if (s9 === peg$FAILED) {
  736. s9 = peg$c2;
  737. }
  738. if (s9 !== peg$FAILED) {
  739. s6 = [s6, s7, s8, s9];
  740. s5 = s6;
  741. } else {
  742. peg$currPos = s5;
  743. s5 = peg$c1;
  744. }
  745. } else {
  746. peg$currPos = s5;
  747. s5 = peg$c1;
  748. }
  749. } else {
  750. peg$currPos = s5;
  751. s5 = peg$c1;
  752. }
  753. } else {
  754. peg$currPos = s5;
  755. s5 = peg$c1;
  756. }
  757. }
  758. if (s4 !== peg$FAILED) {
  759. peg$reportedPos = s0;
  760. s1 = peg$c10(s1, s4);
  761. s0 = s1;
  762. } else {
  763. peg$currPos = s0;
  764. s0 = peg$c1;
  765. }
  766. } else {
  767. peg$currPos = s0;
  768. s0 = peg$c1;
  769. }
  770. } else {
  771. peg$currPos = s0;
  772. s0 = peg$c1;
  773. }
  774. } else {
  775. peg$currPos = s0;
  776. s0 = peg$c1;
  777. }
  778. return s0;
  779. }
  780. function peg$parsestmt() {
  781. var s0;
  782. s0 = peg$parseattrStmt();
  783. if (s0 === peg$FAILED) {
  784. s0 = peg$parseedgeStmt();
  785. if (s0 === peg$FAILED) {
  786. s0 = peg$parsesubgraphStmt();
  787. if (s0 === peg$FAILED) {
  788. s0 = peg$parseinlineAttrStmt();
  789. if (s0 === peg$FAILED) {
  790. s0 = peg$parsenodeStmt();
  791. }
  792. }
  793. }
  794. }
  795. return s0;
  796. }
  797. function peg$parseattrStmt() {
  798. var s0, s1, s2, s3;
  799. s0 = peg$currPos;
  800. s1 = peg$parsegraph();
  801. if (s1 === peg$FAILED) {
  802. s1 = peg$parsenode();
  803. if (s1 === peg$FAILED) {
  804. s1 = peg$parseedge();
  805. }
  806. }
  807. if (s1 !== peg$FAILED) {
  808. s2 = [];
  809. s3 = peg$parse_();
  810. while (s3 !== peg$FAILED) {
  811. s2.push(s3);
  812. s3 = peg$parse_();
  813. }
  814. if (s2 !== peg$FAILED) {
  815. s3 = peg$parseattrList();
  816. if (s3 !== peg$FAILED) {
  817. peg$reportedPos = s0;
  818. s1 = peg$c11(s1, s3);
  819. s0 = s1;
  820. } else {
  821. peg$currPos = s0;
  822. s0 = peg$c1;
  823. }
  824. } else {
  825. peg$currPos = s0;
  826. s0 = peg$c1;
  827. }
  828. } else {
  829. peg$currPos = s0;
  830. s0 = peg$c1;
  831. }
  832. return s0;
  833. }
  834. function peg$parseinlineAttrStmt() {
  835. var s0, s1, s2, s3, s4, s5;
  836. s0 = peg$currPos;
  837. s1 = peg$parseid();
  838. if (s1 !== peg$FAILED) {
  839. s2 = [];
  840. s3 = peg$parse_();
  841. while (s3 !== peg$FAILED) {
  842. s2.push(s3);
  843. s3 = peg$parse_();
  844. }
  845. if (s2 !== peg$FAILED) {
  846. if (input.charCodeAt(peg$currPos) === 61) {
  847. s3 = peg$c12;
  848. peg$currPos++;
  849. } else {
  850. s3 = peg$FAILED;
  851. if (peg$silentFails === 0) { peg$fail(peg$c13); }
  852. }
  853. if (s3 !== peg$FAILED) {
  854. s4 = [];
  855. s5 = peg$parse_();
  856. while (s5 !== peg$FAILED) {
  857. s4.push(s5);
  858. s5 = peg$parse_();
  859. }
  860. if (s4 !== peg$FAILED) {
  861. s5 = peg$parseid();
  862. if (s5 !== peg$FAILED) {
  863. peg$reportedPos = s0;
  864. s1 = peg$c14(s1, s5);
  865. s0 = s1;
  866. } else {
  867. peg$currPos = s0;
  868. s0 = peg$c1;
  869. }
  870. } else {
  871. peg$currPos = s0;
  872. s0 = peg$c1;
  873. }
  874. } else {
  875. peg$currPos = s0;
  876. s0 = peg$c1;
  877. }
  878. } else {
  879. peg$currPos = s0;
  880. s0 = peg$c1;
  881. }
  882. } else {
  883. peg$currPos = s0;
  884. s0 = peg$c1;
  885. }
  886. return s0;
  887. }
  888. function peg$parsenodeStmt() {
  889. var s0, s1, s2, s3;
  890. s0 = peg$currPos;
  891. s1 = peg$parsenodeId();
  892. if (s1 !== peg$FAILED) {
  893. s2 = [];
  894. s3 = peg$parse_();
  895. while (s3 !== peg$FAILED) {
  896. s2.push(s3);
  897. s3 = peg$parse_();
  898. }
  899. if (s2 !== peg$FAILED) {
  900. s3 = peg$parseattrList();
  901. if (s3 === peg$FAILED) {
  902. s3 = peg$c2;
  903. }
  904. if (s3 !== peg$FAILED) {
  905. peg$reportedPos = s0;
  906. s1 = peg$c15(s1, s3);
  907. s0 = s1;
  908. } else {
  909. peg$currPos = s0;
  910. s0 = peg$c1;
  911. }
  912. } else {
  913. peg$currPos = s0;
  914. s0 = peg$c1;
  915. }
  916. } else {
  917. peg$currPos = s0;
  918. s0 = peg$c1;
  919. }
  920. return s0;
  921. }
  922. function peg$parseedgeStmt() {
  923. var s0, s1, s2, s3, s4, s5;
  924. s0 = peg$currPos;
  925. s1 = peg$parsenodeIdOrSubgraph();
  926. if (s1 !== peg$FAILED) {
  927. s2 = [];
  928. s3 = peg$parse_();
  929. while (s3 !== peg$FAILED) {
  930. s2.push(s3);
  931. s3 = peg$parse_();
  932. }
  933. if (s2 !== peg$FAILED) {
  934. s3 = peg$parseedgeRHS();
  935. if (s3 !== peg$FAILED) {
  936. s4 = [];
  937. s5 = peg$parse_();
  938. while (s5 !== peg$FAILED) {
  939. s4.push(s5);
  940. s5 = peg$parse_();
  941. }
  942. if (s4 !== peg$FAILED) {
  943. s5 = peg$parseattrList();
  944. if (s5 === peg$FAILED) {
  945. s5 = peg$c2;
  946. }
  947. if (s5 !== peg$FAILED) {
  948. peg$reportedPos = s0;
  949. s1 = peg$c16(s1, s3, s5);
  950. s0 = s1;
  951. } else {
  952. peg$currPos = s0;
  953. s0 = peg$c1;
  954. }
  955. } else {
  956. peg$currPos = s0;
  957. s0 = peg$c1;
  958. }
  959. } else {
  960. peg$currPos = s0;
  961. s0 = peg$c1;
  962. }
  963. } else {
  964. peg$currPos = s0;
  965. s0 = peg$c1;
  966. }
  967. } else {
  968. peg$currPos = s0;
  969. s0 = peg$c1;
  970. }
  971. return s0;
  972. }
  973. function peg$parsesubgraphStmt() {
  974. var s0, s1, s2, s3, s4, s5, s6, s7;
  975. s0 = peg$currPos;
  976. s1 = peg$currPos;
  977. s2 = peg$parsesubgraph();
  978. if (s2 !== peg$FAILED) {
  979. s3 = [];
  980. s4 = peg$parse_();
  981. while (s4 !== peg$FAILED) {
  982. s3.push(s4);
  983. s4 = peg$parse_();
  984. }
  985. if (s3 !== peg$FAILED) {
  986. s4 = peg$currPos;
  987. s5 = peg$parseid();
  988. if (s5 !== peg$FAILED) {
  989. s6 = [];
  990. s7 = peg$parse_();
  991. while (s7 !== peg$FAILED) {
  992. s6.push(s7);
  993. s7 = peg$parse_();
  994. }
  995. if (s6 !== peg$FAILED) {
  996. s5 = [s5, s6];
  997. s4 = s5;
  998. } else {
  999. peg$currPos = s4;
  1000. s4 = peg$c1;
  1001. }
  1002. } else {
  1003. peg$currPos = s4;
  1004. s4 = peg$c1;
  1005. }
  1006. if (s4 === peg$FAILED) {
  1007. s4 = peg$c2;
  1008. }
  1009. if (s4 !== peg$FAILED) {
  1010. s2 = [s2, s3, s4];
  1011. s1 = s2;
  1012. } else {
  1013. peg$currPos = s1;
  1014. s1 = peg$c1;
  1015. }
  1016. } else {
  1017. peg$currPos = s1;
  1018. s1 = peg$c1;
  1019. }
  1020. } else {
  1021. peg$currPos = s1;
  1022. s1 = peg$c1;
  1023. }
  1024. if (s1 === peg$FAILED) {
  1025. s1 = peg$c2;
  1026. }
  1027. if (s1 !== peg$FAILED) {
  1028. if (input.charCodeAt(peg$currPos) === 123) {
  1029. s2 = peg$c3;
  1030. peg$currPos++;
  1031. } else {
  1032. s2 = peg$FAILED;
  1033. if (peg$silentFails === 0) { peg$fail(peg$c4); }
  1034. }
  1035. if (s2 !== peg$FAILED) {
  1036. s3 = [];
  1037. s4 = peg$parse_();
  1038. while (s4 !== peg$FAILED) {
  1039. s3.push(s4);
  1040. s4 = peg$parse_();
  1041. }
  1042. if (s3 !== peg$FAILED) {
  1043. s4 = peg$parsestmtList();
  1044. if (s4 === peg$FAILED) {
  1045. s4 = peg$c2;
  1046. }
  1047. if (s4 !== peg$FAILED) {
  1048. s5 = [];
  1049. s6 = peg$parse_();
  1050. while (s6 !== peg$FAILED) {
  1051. s5.push(s6);
  1052. s6 = peg$parse_();
  1053. }
  1054. if (s5 !== peg$FAILED) {
  1055. if (input.charCodeAt(peg$currPos) === 125) {
  1056. s6 = peg$c5;
  1057. peg$currPos++;
  1058. } else {
  1059. s6 = peg$FAILED;
  1060. if (peg$silentFails === 0) { peg$fail(peg$c6); }
  1061. }
  1062. if (s6 !== peg$FAILED) {
  1063. peg$reportedPos = s0;
  1064. s1 = peg$c17(s1, s4);
  1065. s0 = s1;
  1066. } else {
  1067. peg$currPos = s0;
  1068. s0 = peg$c1;
  1069. }
  1070. } else {
  1071. peg$currPos = s0;
  1072. s0 = peg$c1;
  1073. }
  1074. } else {
  1075. peg$currPos = s0;
  1076. s0 = peg$c1;
  1077. }
  1078. } else {
  1079. peg$currPos = s0;
  1080. s0 = peg$c1;
  1081. }
  1082. } else {
  1083. peg$currPos = s0;
  1084. s0 = peg$c1;
  1085. }
  1086. } else {
  1087. peg$currPos = s0;
  1088. s0 = peg$c1;
  1089. }
  1090. return s0;
  1091. }
  1092. function peg$parseattrList() {
  1093. var s0, s1, s2, s3, s4, s5;
  1094. s0 = peg$currPos;
  1095. s1 = peg$parseattrListBlock();
  1096. if (s1 !== peg$FAILED) {
  1097. s2 = [];
  1098. s3 = peg$currPos;
  1099. s4 = [];
  1100. s5 = peg$parse_();
  1101. while (s5 !== peg$FAILED) {
  1102. s4.push(s5);
  1103. s5 = peg$parse_();
  1104. }
  1105. if (s4 !== peg$FAILED) {
  1106. s5 = peg$parseattrListBlock();
  1107. if (s5 !== peg$FAILED) {
  1108. s4 = [s4, s5];
  1109. s3 = s4;
  1110. } else {
  1111. peg$currPos = s3;
  1112. s3 = peg$c1;
  1113. }
  1114. } else {
  1115. peg$currPos = s3;
  1116. s3 = peg$c1;
  1117. }
  1118. while (s3 !== peg$FAILED) {
  1119. s2.push(s3);
  1120. s3 = peg$currPos;
  1121. s4 = [];
  1122. s5 = peg$parse_();
  1123. while (s5 !== peg$FAILED) {
  1124. s4.push(s5);
  1125. s5 = peg$parse_();
  1126. }
  1127. if (s4 !== peg$FAILED) {
  1128. s5 = peg$parseattrListBlock();
  1129. if (s5 !== peg$FAILED) {
  1130. s4 = [s4, s5];
  1131. s3 = s4;
  1132. } else {
  1133. peg$currPos = s3;
  1134. s3 = peg$c1;
  1135. }
  1136. } else {
  1137. peg$currPos = s3;
  1138. s3 = peg$c1;
  1139. }
  1140. }
  1141. if (s2 !== peg$FAILED) {
  1142. peg$reportedPos = s0;
  1143. s1 = peg$c18(s1, s2);
  1144. s0 = s1;
  1145. } else {
  1146. peg$currPos = s0;
  1147. s0 = peg$c1;
  1148. }
  1149. } else {
  1150. peg$currPos = s0;
  1151. s0 = peg$c1;
  1152. }
  1153. return s0;
  1154. }
  1155. function peg$parseattrListBlock() {
  1156. var s0, s1, s2, s3, s4, s5;
  1157. s0 = peg$currPos;
  1158. if (input.charCodeAt(peg$currPos) === 91) {
  1159. s1 = peg$c19;
  1160. peg$currPos++;
  1161. } else {
  1162. s1 = peg$FAILED;
  1163. if (peg$silentFails === 0) { peg$fail(peg$c20); }
  1164. }
  1165. if (s1 !== peg$FAILED) {
  1166. s2 = [];
  1167. s3 = peg$parse_();
  1168. while (s3 !== peg$FAILED) {
  1169. s2.push(s3);
  1170. s3 = peg$parse_();
  1171. }
  1172. if (s2 !== peg$FAILED) {
  1173. s3 = peg$parseaList();
  1174. if (s3 === peg$FAILED) {
  1175. s3 = peg$c2;
  1176. }
  1177. if (s3 !== peg$FAILED) {
  1178. s4 = [];
  1179. s5 = peg$parse_();
  1180. while (s5 !== peg$FAILED) {
  1181. s4.push(s5);
  1182. s5 = peg$parse_();
  1183. }
  1184. if (s4 !== peg$FAILED) {
  1185. if (input.charCodeAt(peg$currPos) === 93) {
  1186. s5 = peg$c21;
  1187. peg$currPos++;
  1188. } else {
  1189. s5 = peg$FAILED;
  1190. if (peg$silentFails === 0) { peg$fail(peg$c22); }
  1191. }
  1192. if (s5 !== peg$FAILED) {
  1193. peg$reportedPos = s0;
  1194. s1 = peg$c23(s3);
  1195. s0 = s1;
  1196. } else {
  1197. peg$currPos = s0;
  1198. s0 = peg$c1;
  1199. }
  1200. } else {
  1201. peg$currPos = s0;
  1202. s0 = peg$c1;
  1203. }
  1204. } else {
  1205. peg$currPos = s0;
  1206. s0 = peg$c1;
  1207. }
  1208. } else {
  1209. peg$currPos = s0;
  1210. s0 = peg$c1;
  1211. }
  1212. } else {
  1213. peg$currPos = s0;
  1214. s0 = peg$c1;
  1215. }
  1216. return s0;
  1217. }
  1218. function peg$parseaList() {
  1219. var s0, s1, s2, s3, s4, s5, s6, s7;
  1220. s0 = peg$currPos;
  1221. s1 = peg$parseidDef();
  1222. if (s1 !== peg$FAILED) {
  1223. s2 = [];
  1224. s3 = peg$currPos;
  1225. s4 = [];
  1226. s5 = peg$parse_();
  1227. while (s5 !== peg$FAILED) {
  1228. s4.push(s5);
  1229. s5 = peg$parse_();
  1230. }
  1231. if (s4 !== peg$FAILED) {
  1232. if (input.charCodeAt(peg$currPos) === 44) {
  1233. s5 = peg$c24;
  1234. peg$currPos++;
  1235. } else {
  1236. s5 = peg$FAILED;
  1237. if (peg$silentFails === 0) { peg$fail(peg$c25); }
  1238. }
  1239. if (s5 === peg$FAILED) {
  1240. s5 = peg$c2;
  1241. }
  1242. if (s5 !== peg$FAILED) {
  1243. s6 = [];
  1244. s7 = peg$parse_();
  1245. while (s7 !== peg$FAILED) {
  1246. s6.push(s7);
  1247. s7 = peg$parse_();
  1248. }
  1249. if (s6 !== peg$FAILED) {
  1250. s7 = peg$parseidDef();
  1251. if (s7 !== peg$FAILED) {
  1252. s4 = [s4, s5, s6, s7];
  1253. s3 = s4;
  1254. } else {
  1255. peg$currPos = s3;
  1256. s3 = peg$c1;
  1257. }
  1258. } else {
  1259. peg$currPos = s3;
  1260. s3 = peg$c1;
  1261. }
  1262. } else {
  1263. peg$currPos = s3;
  1264. s3 = peg$c1;
  1265. }
  1266. } else {
  1267. peg$currPos = s3;
  1268. s3 = peg$c1;
  1269. }
  1270. while (s3 !== peg$FAILED) {
  1271. s2.push(s3);
  1272. s3 = peg$currPos;
  1273. s4 = [];
  1274. s5 = peg$parse_();
  1275. while (s5 !== peg$FAILED) {
  1276. s4.push(s5);
  1277. s5 = peg$parse_();
  1278. }
  1279. if (s4 !== peg$FAILED) {
  1280. if (input.charCodeAt(peg$currPos) === 44) {
  1281. s5 = peg$c24;
  1282. peg$currPos++;
  1283. } else {
  1284. s5 = peg$FAILED;
  1285. if (peg$silentFails === 0) { peg$fail(peg$c25); }
  1286. }
  1287. if (s5 === peg$FAILED) {
  1288. s5 = peg$c2;
  1289. }
  1290. if (s5 !== peg$FAILED) {
  1291. s6 = [];
  1292. s7 = peg$parse_();
  1293. while (s7 !== peg$FAILED) {
  1294. s6.push(s7);
  1295. s7 = peg$parse_();
  1296. }
  1297. if (s6 !== peg$FAILED) {
  1298. s7 = peg$parseidDef();
  1299. if (s7 !== peg$FAILED) {
  1300. s4 = [s4, s5, s6, s7];
  1301. s3 = s4;
  1302. } else {
  1303. peg$currPos = s3;
  1304. s3 = peg$c1;
  1305. }
  1306. } else {
  1307. peg$currPos = s3;
  1308. s3 = peg$c1;
  1309. }
  1310. } else {
  1311. peg$currPos = s3;
  1312. s3 = peg$c1;
  1313. }
  1314. } else {
  1315. peg$currPos = s3;
  1316. s3 = peg$c1;
  1317. }
  1318. }
  1319. if (s2 !== peg$FAILED) {
  1320. peg$reportedPos = s0;
  1321. s1 = peg$c26(s1, s2);
  1322. s0 = s1;
  1323. } else {
  1324. peg$currPos = s0;
  1325. s0 = peg$c1;
  1326. }
  1327. } else {
  1328. peg$currPos = s0;
  1329. s0 = peg$c1;
  1330. }
  1331. return s0;
  1332. }
  1333. function peg$parseedgeRHS() {
  1334. var s0, s1, s2, s3, s4, s5;
  1335. s0 = peg$currPos;
  1336. s1 = peg$currPos;
  1337. if (input.substr(peg$currPos, 2) === peg$c27) {
  1338. s2 = peg$c27;
  1339. peg$currPos += 2;
  1340. } else {
  1341. s2 = peg$FAILED;
  1342. if (peg$silentFails === 0) { peg$fail(peg$c28); }
  1343. }
  1344. if (s2 !== peg$FAILED) {
  1345. peg$reportedPos = peg$currPos;
  1346. s3 = peg$c29();
  1347. if (s3) {
  1348. s3 = peg$c1;
  1349. } else {
  1350. s3 = peg$c30;
  1351. }
  1352. if (s3 !== peg$FAILED) {
  1353. s2 = [s2, s3];
  1354. s1 = s2;
  1355. } else {
  1356. peg$currPos = s1;
  1357. s1 = peg$c1;
  1358. }
  1359. } else {
  1360. peg$currPos = s1;
  1361. s1 = peg$c1;
  1362. }
  1363. if (s1 === peg$FAILED) {
  1364. s1 = peg$currPos;
  1365. if (input.substr(peg$currPos, 2) === peg$c31) {
  1366. s2 = peg$c31;
  1367. peg$currPos += 2;
  1368. } else {
  1369. s2 = peg$FAILED;
  1370. if (peg$silentFails === 0) { peg$fail(peg$c32); }
  1371. }
  1372. if (s2 !== peg$FAILED) {
  1373. peg$reportedPos = peg$currPos;
  1374. s3 = peg$c29();
  1375. if (s3) {
  1376. s3 = peg$c30;
  1377. } else {
  1378. s3 = peg$c1;
  1379. }
  1380. if (s3 !== peg$FAILED) {
  1381. s2 = [s2, s3];
  1382. s1 = s2;
  1383. } else {
  1384. peg$currPos = s1;
  1385. s1 = peg$c1;
  1386. }
  1387. } else {
  1388. peg$currPos = s1;
  1389. s1 = peg$c1;
  1390. }
  1391. }
  1392. if (s1 !== peg$FAILED) {
  1393. s2 = [];
  1394. s3 = peg$parse_();
  1395. while (s3 !== peg$FAILED) {
  1396. s2.push(s3);
  1397. s3 = peg$parse_();
  1398. }
  1399. if (s2 !== peg$FAILED) {
  1400. s3 = peg$parsenodeIdOrSubgraph();
  1401. if (s3 !== peg$FAILED) {
  1402. s4 = [];
  1403. s5 = peg$parse_();
  1404. while (s5 !== peg$FAILED) {
  1405. s4.push(s5);
  1406. s5 = peg$parse_();
  1407. }
  1408. if (s4 !== peg$FAILED) {
  1409. s5 = peg$parseedgeRHS();
  1410. if (s5 === peg$FAILED) {
  1411. s5 = peg$c2;
  1412. }
  1413. if (s5 !== peg$FAILED) {
  1414. peg$reportedPos = s0;
  1415. s1 = peg$c33(s3, s5);
  1416. s0 = s1;
  1417. } else {
  1418. peg$currPos = s0;
  1419. s0 = peg$c1;
  1420. }
  1421. } else {
  1422. peg$currPos = s0;
  1423. s0 = peg$c1;
  1424. }
  1425. } else {
  1426. peg$currPos = s0;
  1427. s0 = peg$c1;
  1428. }
  1429. } else {
  1430. peg$currPos = s0;
  1431. s0 = peg$c1;
  1432. }
  1433. } else {
  1434. peg$currPos = s0;
  1435. s0 = peg$c1;
  1436. }
  1437. return s0;
  1438. }
  1439. function peg$parseidDef() {
  1440. var s0, s1, s2, s3, s4, s5, s6;
  1441. s0 = peg$currPos;
  1442. s1 = peg$parseid();
  1443. if (s1 !== peg$FAILED) {
  1444. s2 = peg$currPos;
  1445. s3 = [];
  1446. s4 = peg$parse_();
  1447. while (s4 !== peg$FAILED) {
  1448. s3.push(s4);
  1449. s4 = peg$parse_();
  1450. }
  1451. if (s3 !== peg$FAILED) {
  1452. if (input.charCodeAt(peg$currPos) === 61) {
  1453. s4 = peg$c12;
  1454. peg$currPos++;
  1455. } else {
  1456. s4 = peg$FAILED;
  1457. if (peg$silentFails === 0) { peg$fail(peg$c13); }
  1458. }
  1459. if (s4 !== peg$FAILED) {
  1460. s5 = [];
  1461. s6 = peg$parse_();
  1462. while (s6 !== peg$FAILED) {
  1463. s5.push(s6);
  1464. s6 = peg$parse_();
  1465. }
  1466. if (s5 !== peg$FAILED) {
  1467. s6 = peg$parseid();
  1468. if (s6 !== peg$FAILED) {
  1469. s3 = [s3, s4, s5, s6];
  1470. s2 = s3;
  1471. } else {
  1472. peg$currPos = s2;
  1473. s2 = peg$c1;
  1474. }
  1475. } else {
  1476. peg$currPos = s2;
  1477. s2 = peg$c1;
  1478. }
  1479. } else {
  1480. peg$currPos = s2;
  1481. s2 = peg$c1;
  1482. }
  1483. } else {
  1484. peg$currPos = s2;
  1485. s2 = peg$c1;
  1486. }
  1487. if (s2 === peg$FAILED) {
  1488. s2 = peg$c2;
  1489. }
  1490. if (s2 !== peg$FAILED) {
  1491. peg$reportedPos = s0;
  1492. s1 = peg$c34(s1, s2);
  1493. s0 = s1;
  1494. } else {
  1495. peg$currPos = s0;
  1496. s0 = peg$c1;
  1497. }
  1498. } else {
  1499. peg$currPos = s0;
  1500. s0 = peg$c1;
  1501. }
  1502. return s0;
  1503. }
  1504. function peg$parsenodeIdOrSubgraph() {
  1505. var s0, s1;
  1506. s0 = peg$parsesubgraphStmt();
  1507. if (s0 === peg$FAILED) {
  1508. s0 = peg$currPos;
  1509. s1 = peg$parsenodeId();
  1510. if (s1 !== peg$FAILED) {
  1511. peg$reportedPos = s0;
  1512. s1 = peg$c35(s1);
  1513. }
  1514. s0 = s1;
  1515. }
  1516. return s0;
  1517. }
  1518. function peg$parsenodeId() {
  1519. var s0, s1, s2, s3;
  1520. s0 = peg$currPos;
  1521. s1 = peg$parseid();
  1522. if (s1 !== peg$FAILED) {
  1523. s2 = [];
  1524. s3 = peg$parse_();
  1525. while (s3 !== peg$FAILED) {
  1526. s2.push(s3);
  1527. s3 = peg$parse_();
  1528. }
  1529. if (s2 !== peg$FAILED) {
  1530. s3 = peg$parseport();
  1531. if (s3 === peg$FAILED) {
  1532. s3 = peg$c2;
  1533. }
  1534. if (s3 !== peg$FAILED) {
  1535. peg$reportedPos = s0;
  1536. s1 = peg$c36(s1);
  1537. s0 = s1;
  1538. } else {
  1539. peg$currPos = s0;
  1540. s0 = peg$c1;
  1541. }
  1542. } else {
  1543. peg$currPos = s0;
  1544. s0 = peg$c1;
  1545. }
  1546. } else {
  1547. peg$currPos = s0;
  1548. s0 = peg$c1;
  1549. }
  1550. return s0;
  1551. }
  1552. function peg$parseport() {
  1553. var s0, s1, s2, s3, s4, s5, s6, s7, s8;
  1554. s0 = peg$currPos;
  1555. if (input.charCodeAt(peg$currPos) === 58) {
  1556. s1 = peg$c37;
  1557. peg$currPos++;
  1558. } else {
  1559. s1 = peg$FAILED;
  1560. if (peg$silentFails === 0) { peg$fail(peg$c38); }
  1561. }
  1562. if (s1 !== peg$FAILED) {
  1563. s2 = [];
  1564. s3 = peg$parse_();
  1565. while (s3 !== peg$FAILED) {
  1566. s2.push(s3);
  1567. s3 = peg$parse_();
  1568. }
  1569. if (s2 !== peg$FAILED) {
  1570. s3 = peg$parseid();
  1571. if (s3 !== peg$FAILED) {
  1572. s4 = [];
  1573. s5 = peg$parse_();
  1574. while (s5 !== peg$FAILED) {
  1575. s4.push(s5);
  1576. s5 = peg$parse_();
  1577. }
  1578. if (s4 !== peg$FAILED) {
  1579. s5 = peg$currPos;
  1580. if (input.charCodeAt(peg$currPos) === 58) {
  1581. s6 = peg$c37;
  1582. peg$currPos++;
  1583. } else {
  1584. s6 = peg$FAILED;
  1585. if (peg$silentFails === 0) { peg$fail(peg$c38); }
  1586. }
  1587. if (s6 !== peg$FAILED) {
  1588. s7 = [];
  1589. s8 = peg$parse_();
  1590. while (s8 !== peg$FAILED) {
  1591. s7.push(s8);
  1592. s8 = peg$parse_();
  1593. }
  1594. if (s7 !== peg$FAILED) {
  1595. s8 = peg$parsecompassPt();
  1596. if (s8 !== peg$FAILED) {
  1597. s6 = [s6, s7, s8];
  1598. s5 = s6;
  1599. } else {
  1600. peg$currPos = s5;
  1601. s5 = peg$c1;
  1602. }
  1603. } else {
  1604. peg$currPos = s5;
  1605. s5 = peg$c1;
  1606. }
  1607. } else {
  1608. peg$currPos = s5;
  1609. s5 = peg$c1;
  1610. }
  1611. if (s5 === peg$FAILED) {
  1612. s5 = peg$c2;
  1613. }
  1614. if (s5 !== peg$FAILED) {
  1615. s1 = [s1, s2, s3, s4, s5];
  1616. s0 = s1;
  1617. } else {
  1618. peg$currPos = s0;
  1619. s0 = peg$c1;
  1620. }
  1621. } else {
  1622. peg$currPos = s0;
  1623. s0 = peg$c1;
  1624. }
  1625. } else {
  1626. peg$currPos = s0;
  1627. s0 = peg$c1;
  1628. }
  1629. } else {
  1630. peg$currPos = s0;
  1631. s0 = peg$c1;
  1632. }
  1633. } else {
  1634. peg$currPos = s0;
  1635. s0 = peg$c1;
  1636. }
  1637. return s0;
  1638. }
  1639. function peg$parsecompassPt() {
  1640. var s0;
  1641. if (input.substr(peg$currPos, 2) === peg$c39) {
  1642. s0 = peg$c39;
  1643. peg$currPos += 2;
  1644. } else {
  1645. s0 = peg$FAILED;
  1646. if (peg$silentFails === 0) { peg$fail(peg$c40); }
  1647. }
  1648. if (s0 === peg$FAILED) {
  1649. if (input.substr(peg$currPos, 2) === peg$c41) {
  1650. s0 = peg$c41;
  1651. peg$currPos += 2;
  1652. } else {
  1653. s0 = peg$FAILED;
  1654. if (peg$silentFails === 0) { peg$fail(peg$c42); }
  1655. }
  1656. if (s0 === peg$FAILED) {
  1657. if (input.substr(peg$currPos, 2) === peg$c43) {
  1658. s0 = peg$c43;
  1659. peg$currPos += 2;
  1660. } else {
  1661. s0 = peg$FAILED;
  1662. if (peg$silentFails === 0) { peg$fail(peg$c44); }
  1663. }
  1664. if (s0 === peg$FAILED) {
  1665. if (input.substr(peg$currPos, 2) === peg$c45) {
  1666. s0 = peg$c45;
  1667. peg$currPos += 2;
  1668. } else {
  1669. s0 = peg$FAILED;
  1670. if (peg$silentFails === 0) { peg$fail(peg$c46); }
  1671. }
  1672. if (s0 === peg$FAILED) {
  1673. if (input.charCodeAt(peg$currPos) === 110) {
  1674. s0 = peg$c47;
  1675. peg$currPos++;
  1676. } else {
  1677. s0 = peg$FAILED;
  1678. if (peg$silentFails === 0) { peg$fail(peg$c48); }
  1679. }
  1680. if (s0 === peg$FAILED) {
  1681. if (input.charCodeAt(peg$currPos) === 101) {
  1682. s0 = peg$c49;
  1683. peg$currPos++;
  1684. } else {
  1685. s0 = peg$FAILED;
  1686. if (peg$silentFails === 0) { peg$fail(peg$c50); }
  1687. }
  1688. if (s0 === peg$FAILED) {
  1689. if (input.charCodeAt(peg$currPos) === 115) {
  1690. s0 = peg$c51;
  1691. peg$currPos++;
  1692. } else {
  1693. s0 = peg$FAILED;
  1694. if (peg$silentFails === 0) { peg$fail(peg$c52); }
  1695. }
  1696. if (s0 === peg$FAILED) {
  1697. if (input.charCodeAt(peg$currPos) === 119) {
  1698. s0 = peg$c53;
  1699. peg$currPos++;
  1700. } else {
  1701. s0 = peg$FAILED;
  1702. if (peg$silentFails === 0) { peg$fail(peg$c54); }
  1703. }
  1704. if (s0 === peg$FAILED) {
  1705. if (input.charCodeAt(peg$currPos) === 99) {
  1706. s0 = peg$c55;
  1707. peg$currPos++;
  1708. } else {
  1709. s0 = peg$FAILED;
  1710. if (peg$silentFails === 0) { peg$fail(peg$c56); }
  1711. }
  1712. if (s0 === peg$FAILED) {
  1713. if (input.charCodeAt(peg$currPos) === 95) {
  1714. s0 = peg$c57;
  1715. peg$currPos++;
  1716. } else {
  1717. s0 = peg$FAILED;
  1718. if (peg$silentFails === 0) { peg$fail(peg$c58); }
  1719. }
  1720. }
  1721. }
  1722. }
  1723. }
  1724. }
  1725. }
  1726. }
  1727. }
  1728. }
  1729. return s0;
  1730. }
  1731. function peg$parseid() {
  1732. var s0, s1, s2, s3, s4, s5, s6;
  1733. peg$silentFails++;
  1734. s0 = peg$currPos;
  1735. if (peg$c60.test(input.charAt(peg$currPos))) {
  1736. s1 = input.charAt(peg$currPos);
  1737. peg$currPos++;
  1738. } else {
  1739. s1 = peg$FAILED;
  1740. if (peg$silentFails === 0) { peg$fail(peg$c61); }
  1741. }
  1742. if (s1 !== peg$FAILED) {
  1743. s2 = [];
  1744. if (peg$c62.test(input.charAt(peg$currPos))) {
  1745. s3 = input.charAt(peg$currPos);
  1746. peg$currPos++;
  1747. } else {
  1748. s3 = peg$FAILED;
  1749. if (peg$silentFails === 0) { peg$fail(peg$c63); }
  1750. }
  1751. while (s3 !== peg$FAILED) {
  1752. s2.push(s3);
  1753. if (peg$c62.test(input.charAt(peg$currPos))) {
  1754. s3 = input.charAt(peg$currPos);
  1755. peg$currPos++;
  1756. } else {
  1757. s3 = peg$FAILED;
  1758. if (peg$silentFails === 0) { peg$fail(peg$c63); }
  1759. }
  1760. }
  1761. if (s2 !== peg$FAILED) {
  1762. peg$reportedPos = s0;
  1763. s1 = peg$c64(s1, s2);
  1764. s0 = s1;
  1765. } else {
  1766. peg$currPos = s0;
  1767. s0 = peg$c1;
  1768. }
  1769. } else {
  1770. peg$currPos = s0;
  1771. s0 = peg$c1;
  1772. }
  1773. if (s0 === peg$FAILED) {
  1774. s0 = peg$currPos;
  1775. if (input.charCodeAt(peg$currPos) === 45) {
  1776. s1 = peg$c65;
  1777. peg$currPos++;
  1778. } else {
  1779. s1 = peg$FAILED;
  1780. if (peg$silentFails === 0) { peg$fail(peg$c66); }
  1781. }
  1782. if (s1 === peg$FAILED) {
  1783. s1 = peg$c2;
  1784. }
  1785. if (s1 !== peg$FAILED) {
  1786. if (input.charCodeAt(peg$currPos) === 46) {
  1787. s2 = peg$c67;
  1788. peg$currPos++;
  1789. } else {
  1790. s2 = peg$FAILED;
  1791. if (peg$silentFails === 0) { peg$fail(peg$c68); }
  1792. }
  1793. if (s2 !== peg$FAILED) {
  1794. s3 = [];
  1795. if (peg$c69.test(input.charAt(peg$currPos))) {
  1796. s4 = input.charAt(peg$currPos);
  1797. peg$currPos++;
  1798. } else {
  1799. s4 = peg$FAILED;
  1800. if (peg$silentFails === 0) { peg$fail(peg$c70); }
  1801. }
  1802. if (s4 !== peg$FAILED) {
  1803. while (s4 !== peg$FAILED) {
  1804. s3.push(s4);
  1805. if (peg$c69.test(input.charAt(peg$currPos))) {
  1806. s4 = input.charAt(peg$currPos);
  1807. peg$currPos++;
  1808. } else {
  1809. s4 = peg$FAILED;
  1810. if (peg$silentFails === 0) { peg$fail(peg$c70); }
  1811. }
  1812. }
  1813. } else {
  1814. s3 = peg$c1;
  1815. }
  1816. if (s3 !== peg$FAILED) {
  1817. peg$reportedPos = s0;
  1818. s1 = peg$c71(s1, s2, s3);
  1819. s0 = s1;
  1820. } else {
  1821. peg$currPos = s0;
  1822. s0 = peg$c1;
  1823. }
  1824. } else {
  1825. peg$currPos = s0;
  1826. s0 = peg$c1;
  1827. }
  1828. } else {
  1829. peg$currPos = s0;
  1830. s0 = peg$c1;
  1831. }
  1832. if (s0 === peg$FAILED) {
  1833. s0 = peg$currPos;
  1834. if (input.charCodeAt(peg$currPos) === 45) {
  1835. s1 = peg$c65;
  1836. peg$currPos++;
  1837. } else {
  1838. s1 = peg$FAILED;
  1839. if (peg$silentFails === 0) { peg$fail(peg$c66); }
  1840. }
  1841. if (s1 === peg$FAILED) {
  1842. s1 = peg$c2;
  1843. }
  1844. if (s1 !== peg$FAILED) {
  1845. s2 = [];
  1846. if (peg$c69.test(input.charAt(peg$currPos))) {
  1847. s3 = input.charAt(peg$currPos);
  1848. peg$currPos++;
  1849. } else {
  1850. s3 = peg$FAILED;
  1851. if (peg$silentFails === 0) { peg$fail(peg$c70); }
  1852. }
  1853. if (s3 !== peg$FAILED) {
  1854. while (s3 !== peg$FAILED) {
  1855. s2.push(s3);
  1856. if (peg$c69.test(input.charAt(peg$currPos))) {
  1857. s3 = input.charAt(peg$currPos);
  1858. peg$currPos++;
  1859. } else {
  1860. s3 = peg$FAILED;
  1861. if (peg$silentFails === 0) { peg$fail(peg$c70); }
  1862. }
  1863. }
  1864. } else {
  1865. s2 = peg$c1;
  1866. }
  1867. if (s2 !== peg$FAILED) {
  1868. s3 = peg$currPos;
  1869. if (input.charCodeAt(peg$currPos) === 46) {
  1870. s4 = peg$c67;
  1871. peg$currPos++;
  1872. } else {
  1873. s4 = peg$FAILED;
  1874. if (peg$silentFails === 0) { peg$fail(peg$c68); }
  1875. }
  1876. if (s4 !== peg$FAILED) {
  1877. s5 = [];
  1878. if (peg$c69.test(input.charAt(peg$currPos))) {
  1879. s6 = input.charAt(peg$currPos);
  1880. peg$currPos++;
  1881. } else {
  1882. s6 = peg$FAILED;
  1883. if (peg$silentFails === 0) { peg$fail(peg$c70); }
  1884. }
  1885. while (s6 !== peg$FAILED) {
  1886. s5.push(s6);
  1887. if (peg$c69.test(input.charAt(peg$currPos))) {
  1888. s6 = input.charAt(peg$currPos);
  1889. peg$currPos++;
  1890. } else {
  1891. s6 = peg$FAILED;
  1892. if (peg$silentFails === 0) { peg$fail(peg$c70); }
  1893. }
  1894. }
  1895. if (s5 !== peg$FAILED) {
  1896. s4 = [s4, s5];
  1897. s3 = s4;
  1898. } else {
  1899. peg$currPos = s3;
  1900. s3 = peg$c1;
  1901. }
  1902. } else {
  1903. peg$currPos = s3;
  1904. s3 = peg$c1;
  1905. }
  1906. if (s3 === peg$FAILED) {
  1907. s3 = peg$c2;
  1908. }
  1909. if (s3 !== peg$FAILED) {
  1910. peg$reportedPos = s0;
  1911. s1 = peg$c72(s1, s2, s3);
  1912. s0 = s1;
  1913. } else {
  1914. peg$currPos = s0;
  1915. s0 = peg$c1;
  1916. }
  1917. } else {
  1918. peg$currPos = s0;
  1919. s0 = peg$c1;
  1920. }
  1921. } else {
  1922. peg$currPos = s0;
  1923. s0 = peg$c1;
  1924. }
  1925. if (s0 === peg$FAILED) {
  1926. s0 = peg$currPos;
  1927. if (input.charCodeAt(peg$currPos) === 34) {
  1928. s1 = peg$c73;
  1929. peg$currPos++;
  1930. } else {
  1931. s1 = peg$FAILED;
  1932. if (peg$silentFails === 0) { peg$fail(peg$c74); }
  1933. }
  1934. if (s1 !== peg$FAILED) {
  1935. s2 = [];
  1936. s3 = peg$currPos;
  1937. if (input.substr(peg$currPos, 2) === peg$c75) {
  1938. s4 = peg$c75;
  1939. peg$currPos += 2;
  1940. } else {
  1941. s4 = peg$FAILED;
  1942. if (peg$silentFails === 0) { peg$fail(peg$c76); }
  1943. }
  1944. if (s4 !== peg$FAILED) {
  1945. peg$reportedPos = s3;
  1946. s4 = peg$c77();
  1947. }
  1948. s3 = s4;
  1949. if (s3 === peg$FAILED) {
  1950. s3 = peg$currPos;
  1951. if (input.charCodeAt(peg$currPos) === 92) {
  1952. s4 = peg$c78;
  1953. peg$currPos++;
  1954. } else {
  1955. s4 = peg$FAILED;
  1956. if (peg$silentFails === 0) { peg$fail(peg$c79); }
  1957. }
  1958. if (s4 !== peg$FAILED) {
  1959. if (peg$c80.test(input.charAt(peg$currPos))) {
  1960. s5 = input.charAt(peg$currPos);
  1961. peg$currPos++;
  1962. } else {
  1963. s5 = peg$FAILED;
  1964. if (peg$silentFails === 0) { peg$fail(peg$c81); }
  1965. }
  1966. if (s5 !== peg$FAILED) {
  1967. peg$reportedPos = s3;
  1968. s4 = peg$c82(s5);
  1969. s3 = s4;
  1970. } else {
  1971. peg$currPos = s3;
  1972. s3 = peg$c1;
  1973. }
  1974. } else {
  1975. peg$currPos = s3;
  1976. s3 = peg$c1;
  1977. }
  1978. if (s3 === peg$FAILED) {
  1979. if (peg$c80.test(input.charAt(peg$currPos))) {
  1980. s3 = input.charAt(peg$currPos);
  1981. peg$currPos++;
  1982. } else {
  1983. s3 = peg$FAILED;
  1984. if (peg$silentFails === 0) { peg$fail(peg$c81); }
  1985. }
  1986. }
  1987. }
  1988. while (s3 !== peg$FAILED) {
  1989. s2.push(s3);
  1990. s3 = peg$currPos;
  1991. if (input.substr(peg$currPos, 2) === peg$c75) {
  1992. s4 = peg$c75;
  1993. peg$currPos += 2;
  1994. } else {
  1995. s4 = peg$FAILED;
  1996. if (peg$silentFails === 0) { peg$fail(peg$c76); }
  1997. }
  1998. if (s4 !== peg$FAILED) {
  1999. peg$reportedPos = s3;
  2000. s4 = peg$c77();
  2001. }
  2002. s3 = s4;
  2003. if (s3 === peg$FAILED) {
  2004. s3 = peg$currPos;
  2005. if (input.charCodeAt(peg$currPos) === 92) {
  2006. s4 = peg$c78;
  2007. peg$currPos++;
  2008. } else {
  2009. s4 = peg$FAILED;
  2010. if (peg$silentFails === 0) { peg$fail(peg$c79); }
  2011. }
  2012. if (s4 !== peg$FAILED) {
  2013. if (peg$c80.test(input.charAt(peg$currPos))) {
  2014. s5 = input.charAt(peg$currPos);
  2015. peg$currPos++;
  2016. } else {
  2017. s5 = peg$FAILED;
  2018. if (peg$silentFails === 0) { peg$fail(peg$c81); }
  2019. }
  2020. if (s5 !== peg$FAILED) {
  2021. peg$reportedPos = s3;
  2022. s4 = peg$c82(s5);
  2023. s3 = s4;
  2024. } else {
  2025. peg$currPos = s3;
  2026. s3 = peg$c1;
  2027. }
  2028. } else {
  2029. peg$currPos = s3;
  2030. s3 = peg$c1;
  2031. }
  2032. if (s3 === peg$FAILED) {
  2033. if (peg$c80.test(input.charAt(peg$currPos))) {
  2034. s3 = input.charAt(peg$currPos);
  2035. peg$currPos++;
  2036. } else {
  2037. s3 = peg$FAILED;
  2038. if (peg$silentFails === 0) { peg$fail(peg$c81); }
  2039. }
  2040. }
  2041. }
  2042. }
  2043. if (s2 !== peg$FAILED) {
  2044. if (input.charCodeAt(peg$currPos) === 34) {
  2045. s3 = peg$c73;
  2046. peg$currPos++;
  2047. } else {
  2048. s3 = peg$FAILED;
  2049. if (peg$silentFails === 0) { peg$fail(peg$c74); }
  2050. }
  2051. if (s3 !== peg$FAILED) {
  2052. peg$reportedPos = s0;
  2053. s1 = peg$c83(s2);
  2054. s0 = s1;
  2055. } else {
  2056. peg$currPos = s0;
  2057. s0 = peg$c1;
  2058. }
  2059. } else {
  2060. peg$currPos = s0;
  2061. s0 = peg$c1;
  2062. }
  2063. } else {
  2064. peg$currPos = s0;
  2065. s0 = peg$c1;
  2066. }
  2067. }
  2068. }
  2069. }
  2070. peg$silentFails--;
  2071. if (s0 === peg$FAILED) {
  2072. s1 = peg$FAILED;
  2073. if (peg$silentFails === 0) { peg$fail(peg$c59); }
  2074. }
  2075. return s0;
  2076. }
  2077. function peg$parsenode() {
  2078. var s0, s1;
  2079. s0 = peg$currPos;
  2080. if (input.substr(peg$currPos, 4).toLowerCase() === peg$c84) {
  2081. s1 = input.substr(peg$currPos, 4);
  2082. peg$currPos += 4;
  2083. } else {
  2084. s1 = peg$FAILED;
  2085. if (peg$silentFails === 0) { peg$fail(peg$c85); }
  2086. }
  2087. if (s1 !== peg$FAILED) {
  2088. peg$reportedPos = s0;
  2089. s1 = peg$c86(s1);
  2090. }
  2091. s0 = s1;
  2092. return s0;
  2093. }
  2094. function peg$parseedge() {
  2095. var s0, s1;
  2096. s0 = peg$currPos;
  2097. if (input.substr(peg$currPos, 4).toLowerCase() === peg$c87) {
  2098. s1 = input.substr(peg$currPos, 4);
  2099. peg$currPos += 4;
  2100. } else {
  2101. s1 = peg$FAILED;
  2102. if (peg$silentFails === 0) { peg$fail(peg$c88); }
  2103. }
  2104. if (s1 !== peg$FAILED) {
  2105. peg$reportedPos = s0;
  2106. s1 = peg$c86(s1);
  2107. }
  2108. s0 = s1;
  2109. return s0;
  2110. }
  2111. function peg$parsegraph() {
  2112. var s0, s1;
  2113. s0 = peg$currPos;
  2114. if (input.substr(peg$currPos, 5).toLowerCase() === peg$c89) {
  2115. s1 = input.substr(peg$currPos, 5);
  2116. peg$currPos += 5;
  2117. } else {
  2118. s1 = peg$FAILED;
  2119. if (peg$silentFails === 0) { peg$fail(peg$c90); }
  2120. }
  2121. if (s1 !== peg$FAILED) {
  2122. peg$reportedPos = s0;
  2123. s1 = peg$c86(s1);
  2124. }
  2125. s0 = s1;
  2126. return s0;
  2127. }
  2128. function peg$parsedigraph() {
  2129. var s0, s1;
  2130. s0 = peg$currPos;
  2131. if (input.substr(peg$currPos, 7).toLowerCase() === peg$c91) {
  2132. s1 = input.substr(peg$currPos, 7);
  2133. peg$currPos += 7;
  2134. } else {
  2135. s1 = peg$FAILED;
  2136. if (peg$silentFails === 0) { peg$fail(peg$c92); }
  2137. }
  2138. if (s1 !== peg$FAILED) {
  2139. peg$reportedPos = s0;
  2140. s1 = peg$c86(s1);
  2141. }
  2142. s0 = s1;
  2143. return s0;
  2144. }
  2145. function peg$parsesubgraph() {
  2146. var s0, s1;
  2147. s0 = peg$currPos;
  2148. if (input.substr(peg$currPos, 8).toLowerCase() === peg$c93) {
  2149. s1 = input.substr(peg$currPos, 8);
  2150. peg$currPos += 8;
  2151. } else {
  2152. s1 = peg$FAILED;
  2153. if (peg$silentFails === 0) { peg$fail(peg$c94); }
  2154. }
  2155. if (s1 !== peg$FAILED) {
  2156. peg$reportedPos = s0;
  2157. s1 = peg$c86(s1);
  2158. }
  2159. s0 = s1;
  2160. return s0;
  2161. }
  2162. function peg$parsestrict() {
  2163. var s0, s1;
  2164. s0 = peg$currPos;
  2165. if (input.substr(peg$currPos, 6).toLowerCase() === peg$c95) {
  2166. s1 = input.substr(peg$currPos, 6);
  2167. peg$currPos += 6;
  2168. } else {
  2169. s1 = peg$FAILED;
  2170. if (peg$silentFails === 0) { peg$fail(peg$c96); }
  2171. }
  2172. if (s1 !== peg$FAILED) {
  2173. peg$reportedPos = s0;
  2174. s1 = peg$c86(s1);
  2175. }
  2176. s0 = s1;
  2177. return s0;
  2178. }
  2179. function peg$parsegraphType() {
  2180. var s0, s1;
  2181. s0 = peg$parsegraph();
  2182. if (s0 === peg$FAILED) {
  2183. s0 = peg$currPos;
  2184. s1 = peg$parsedigraph();
  2185. if (s1 !== peg$FAILED) {
  2186. peg$reportedPos = s0;
  2187. s1 = peg$c97(s1);
  2188. }
  2189. s0 = s1;
  2190. }
  2191. return s0;
  2192. }
  2193. function peg$parsewhitespace() {
  2194. var s0, s1;
  2195. peg$silentFails++;
  2196. s0 = [];
  2197. if (peg$c99.test(input.charAt(peg$currPos))) {
  2198. s1 = input.charAt(peg$currPos);
  2199. peg$currPos++;
  2200. } else {
  2201. s1 = peg$FAILED;
  2202. if (peg$silentFails === 0) { peg$fail(peg$c100); }
  2203. }
  2204. if (s1 !== peg$FAILED) {
  2205. while (s1 !== peg$FAILED) {
  2206. s0.push(s1);
  2207. if (peg$c99.test(input.charAt(peg$currPos))) {
  2208. s1 = input.charAt(peg$currPos);
  2209. peg$currPos++;
  2210. } else {
  2211. s1 = peg$FAILED;
  2212. if (peg$silentFails === 0) { peg$fail(peg$c100); }
  2213. }
  2214. }
  2215. } else {
  2216. s0 = peg$c1;
  2217. }
  2218. peg$silentFails--;
  2219. if (s0 === peg$FAILED) {
  2220. s1 = peg$FAILED;
  2221. if (peg$silentFails === 0) { peg$fail(peg$c98); }
  2222. }
  2223. return s0;
  2224. }
  2225. function peg$parsecomment() {
  2226. var s0, s1, s2, s3, s4, s5;
  2227. peg$silentFails++;
  2228. s0 = peg$currPos;
  2229. if (input.substr(peg$currPos, 2) === peg$c102) {
  2230. s1 = peg$c102;
  2231. peg$currPos += 2;
  2232. } else {
  2233. s1 = peg$FAILED;
  2234. if (peg$silentFails === 0) { peg$fail(peg$c103); }
  2235. }
  2236. if (s1 !== peg$FAILED) {
  2237. s2 = [];
  2238. if (peg$c104.test(input.charAt(peg$currPos))) {
  2239. s3 = input.charAt(peg$currPos);
  2240. peg$currPos++;
  2241. } else {
  2242. s3 = peg$FAILED;
  2243. if (peg$silentFails === 0) { peg$fail(peg$c105); }
  2244. }
  2245. while (s3 !== peg$FAILED) {
  2246. s2.push(s3);
  2247. if (peg$c104.test(input.charAt(peg$currPos))) {
  2248. s3 = input.charAt(peg$currPos);
  2249. peg$currPos++;
  2250. } else {
  2251. s3 = peg$FAILED;
  2252. if (peg$silentFails === 0) { peg$fail(peg$c105); }
  2253. }
  2254. }
  2255. if (s2 !== peg$FAILED) {
  2256. s1 = [s1, s2];
  2257. s0 = s1;
  2258. } else {
  2259. peg$currPos = s0;
  2260. s0 = peg$c1;
  2261. }
  2262. } else {
  2263. peg$currPos = s0;
  2264. s0 = peg$c1;
  2265. }
  2266. if (s0 === peg$FAILED) {
  2267. s0 = peg$currPos;
  2268. if (input.substr(peg$currPos, 2) === peg$c106) {
  2269. s1 = peg$c106;
  2270. peg$currPos += 2;
  2271. } else {
  2272. s1 = peg$FAILED;
  2273. if (peg$silentFails === 0) { peg$fail(peg$c107); }
  2274. }
  2275. if (s1 !== peg$FAILED) {
  2276. s2 = [];
  2277. s3 = peg$currPos;
  2278. s4 = peg$currPos;
  2279. peg$silentFails++;
  2280. if (input.substr(peg$currPos, 2) === peg$c108) {
  2281. s5 = peg$c108;
  2282. peg$currPos += 2;
  2283. } else {
  2284. s5 = peg$FAILED;
  2285. if (peg$silentFails === 0) { peg$fail(peg$c109); }
  2286. }
  2287. peg$silentFails--;
  2288. if (s5 === peg$FAILED) {
  2289. s4 = peg$c30;
  2290. } else {
  2291. peg$currPos = s4;
  2292. s4 = peg$c1;
  2293. }
  2294. if (s4 !== peg$FAILED) {
  2295. if (input.length > peg$currPos) {
  2296. s5 = input.charAt(peg$currPos);
  2297. peg$currPos++;
  2298. } else {
  2299. s5 = peg$FAILED;
  2300. if (peg$silentFails === 0) { peg$fail(peg$c110); }
  2301. }
  2302. if (s5 !== peg$FAILED) {
  2303. s4 = [s4, s5];
  2304. s3 = s4;
  2305. } else {
  2306. peg$currPos = s3;
  2307. s3 = peg$c1;
  2308. }
  2309. } else {
  2310. peg$currPos = s3;
  2311. s3 = peg$c1;
  2312. }
  2313. while (s3 !== peg$FAILED) {
  2314. s2.push(s3);
  2315. s3 = peg$currPos;
  2316. s4 = peg$currPos;
  2317. peg$silentFails++;
  2318. if (input.substr(peg$currPos, 2) === peg$c108) {
  2319. s5 = peg$c108;
  2320. peg$currPos += 2;
  2321. } else {
  2322. s5 = peg$FAILED;
  2323. if (peg$silentFails === 0) { peg$fail(peg$c109); }
  2324. }
  2325. peg$silentFails--;
  2326. if (s5 === peg$FAILED) {
  2327. s4 = peg$c30;
  2328. } else {
  2329. peg$currPos = s4;
  2330. s4 = peg$c1;
  2331. }
  2332. if (s4 !== peg$FAILED) {
  2333. if (input.length > peg$currPos) {
  2334. s5 = input.charAt(peg$currPos);
  2335. peg$currPos++;
  2336. } else {
  2337. s5 = peg$FAILED;
  2338. if (peg$silentFails === 0) { peg$fail(peg$c110); }
  2339. }
  2340. if (s5 !== peg$FAILED) {
  2341. s4 = [s4, s5];
  2342. s3 = s4;
  2343. } else {
  2344. peg$currPos = s3;
  2345. s3 = peg$c1;
  2346. }
  2347. } else {
  2348. peg$currPos = s3;
  2349. s3 = peg$c1;
  2350. }
  2351. }
  2352. if (s2 !== peg$FAILED) {
  2353. if (input.substr(peg$currPos, 2) === peg$c108) {
  2354. s3 = peg$c108;
  2355. peg$currPos += 2;
  2356. } else {
  2357. s3 = peg$FAILED;
  2358. if (peg$silentFails === 0) { peg$fail(peg$c109); }
  2359. }
  2360. if (s3 !== peg$FAILED) {
  2361. s1 = [s1, s2, s3];
  2362. s0 = s1;
  2363. } else {
  2364. peg$currPos = s0;
  2365. s0 = peg$c1;
  2366. }
  2367. } else {
  2368. peg$currPos = s0;
  2369. s0 = peg$c1;
  2370. }
  2371. } else {
  2372. peg$currPos = s0;
  2373. s0 = peg$c1;
  2374. }
  2375. }
  2376. peg$silentFails--;
  2377. if (s0 === peg$FAILED) {
  2378. s1 = peg$FAILED;
  2379. if (peg$silentFails === 0) { peg$fail(peg$c101); }
  2380. }
  2381. return s0;
  2382. }
  2383. function peg$parse_() {
  2384. var s0;
  2385. s0 = peg$parsewhitespace();
  2386. if (s0 === peg$FAILED) {
  2387. s0 = peg$parsecomment();
  2388. }
  2389. return s0;
  2390. }
  2391. var _ = require("lodash");
  2392. var directed;
  2393. peg$result = peg$startRuleFunction();
  2394. if (peg$result !== peg$FAILED && peg$currPos === input.length) {
  2395. return peg$result;
  2396. } else {
  2397. if (peg$result !== peg$FAILED && peg$currPos < input.length) {
  2398. peg$fail({ type: "end", description: "end of input" });
  2399. }
  2400. throw peg$buildException(null, peg$maxFailExpected, peg$maxFailPos);
  2401. }
  2402. }
  2403. return {
  2404. SyntaxError: SyntaxError,
  2405. parse: parse
  2406. };
  2407. })();
  2408. },{"lodash":28}],5:[function(require,module,exports){
  2409. var _ = require("lodash"),
  2410. grammar = require("./dot-grammar"),
  2411. buildGraph = require("./build-graph");
  2412. module.exports = function readMany(str) {
  2413. var parseTree = grammar.parse(str);
  2414. return _.map(parseTree, buildGraph);
  2415. };
  2416. },{"./build-graph":3,"./dot-grammar":4,"lodash":28}],6:[function(require,module,exports){
  2417. var grammar = require("./dot-grammar"),
  2418. buildGraph = require("./build-graph");
  2419. module.exports = function readOne(str) {
  2420. var parseTree = grammar.parse(str, { startRule: "graphStmt" });
  2421. return buildGraph(parseTree);
  2422. };
  2423. },{"./build-graph":3,"./dot-grammar":4}],7:[function(require,module,exports){
  2424. module.exports = '0.5.2';
  2425. },{}],8:[function(require,module,exports){
  2426. var _ = require("lodash");
  2427. module.exports = writeOne;
  2428. var UNESCAPED_ID_PATTERN = /^[a-zA-Z\200-\377_][a-zA-Z\200-\377_0-9]*$/;
  2429. function writeOne(g) {
  2430. var ec = g.isDirected() ? "->" : "--",
  2431. writer = new Writer();
  2432. if (!g.isMultigraph()) {
  2433. writer.write("strict ");
  2434. }
  2435. writer.writeLine((g.isDirected() ? "digraph" : "graph") + " {");
  2436. writer.indent();
  2437. var graphAttrs = g.graph();
  2438. if (_.isObject(graphAttrs)) {
  2439. _.each(graphAttrs, function(v, k) {
  2440. writer.writeLine(id(k) + "=" + id(v) + ";");
  2441. });
  2442. }
  2443. writeSubgraph(g, undefined, writer);
  2444. g.edges().forEach(function(edge) {
  2445. writeEdge(g, edge, ec, writer);
  2446. });
  2447. writer.unindent();
  2448. writer.writeLine("}");
  2449. return writer.toString();
  2450. }
  2451. function writeSubgraph(g, v, writer) {
  2452. var children = g.isCompound() ? g.children(v) : g.nodes();
  2453. _.each(children, function(w) {
  2454. if (!g.isCompound() || !g.children(w).length) {
  2455. writeNode(g, w, writer);
  2456. } else {
  2457. writer.writeLine("subgraph " + id(w) + " {");
  2458. writer.indent();
  2459. if (_.isObject(g.node(w))) {
  2460. _.map(g.node(w), function(val, key) {
  2461. writer.writeLine(id(key) + "=" + id(val) + ";");
  2462. });
  2463. }
  2464. writeSubgraph(g, w, writer);
  2465. writer.unindent();
  2466. writer.writeLine("}");
  2467. }
  2468. });
  2469. }
  2470. function writeNode(g, v, writer) {
  2471. writer.write(id(v));
  2472. writeAttrs(g.node(v), writer);
  2473. writer.writeLine();
  2474. }
  2475. function writeEdge(g, edge, ec, writer) {
  2476. var v = edge.v,
  2477. w = edge.w,
  2478. attrs = g.edge(edge);
  2479. writer.write(id(v) + " " + ec + " " + id(w));
  2480. writeAttrs(attrs, writer);
  2481. writer.writeLine();
  2482. }
  2483. function writeAttrs(attrs, writer) {
  2484. if (_.isObject(attrs)) {
  2485. var attrStrs = _.map(attrs, function(val, key) {
  2486. return id(key) + "=" + id(val);
  2487. });
  2488. if (attrStrs.length) {
  2489. writer.write(" [" + attrStrs.join(",") + "]");
  2490. }
  2491. }
  2492. }
  2493. function id(obj) {
  2494. if (typeof obj === "number" || obj.toString().match(UNESCAPED_ID_PATTERN)) {
  2495. return obj;
  2496. }
  2497. return "\"" + obj.toString().replace(/"/g, "\\\"") + "\"";
  2498. }
  2499. // Helper object for making a pretty printer
  2500. function Writer() {
  2501. this._indent = "";
  2502. this._content = "";
  2503. this._shouldIndent = true;
  2504. }
  2505. Writer.prototype.INDENT = " ";
  2506. Writer.prototype.indent = function() {
  2507. this._indent += this.INDENT;
  2508. };
  2509. Writer.prototype.unindent = function() {
  2510. this._indent = this._indent.slice(this.INDENT.length);
  2511. };
  2512. Writer.prototype.writeLine = function(line) {
  2513. this.write((line || "") + "\n");
  2514. this._shouldIndent = true;
  2515. };
  2516. Writer.prototype.write = function(str) {
  2517. if (this._shouldIndent) {
  2518. this._shouldIndent = false;
  2519. this._content += this._indent;
  2520. }
  2521. this._content += str;
  2522. };
  2523. Writer.prototype.toString = function() {
  2524. return this._content;
  2525. };
  2526. },{"lodash":28}],9:[function(require,module,exports){
  2527. /**
  2528. * Copyright (c) 2014, Chris Pettitt
  2529. * All rights reserved.
  2530. *
  2531. * Redistribution and use in source and binary forms, with or without
  2532. * modification, are permitted provided that the following conditions are met:
  2533. *
  2534. * 1. Redistributions of source code must retain the above copyright notice, this
  2535. * list of conditions and the following disclaimer.
  2536. *
  2537. * 2. Redistributions in binary form must reproduce the above copyright notice,
  2538. * this list of conditions and the following disclaimer in the documentation
  2539. * and/or other materials provided with the distribution.
  2540. *
  2541. * 3. Neither the name of the copyright holder nor the names of its contributors
  2542. * may be used to endorse or promote products derived from this software without
  2543. * specific prior written permission.
  2544. *
  2545. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  2546. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  2547. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  2548. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  2549. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  2550. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  2551. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  2552. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  2553. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  2554. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  2555. */
  2556. var _ = require("lodash");
  2557. module.exports = _.clone(require("./lib"));
  2558. module.exports.json = require("./lib/json");
  2559. module.exports.alg = require("./lib/alg");
  2560. },{"./lib":25,"./lib/alg":16,"./lib/json":26,"lodash":28}],10:[function(require,module,exports){
  2561. var _ = require("lodash");
  2562. module.exports = components;
  2563. function components(g) {
  2564. var visited = {},
  2565. cmpts = [],
  2566. cmpt;
  2567. function dfs(v) {
  2568. if (_.has(visited, v)) return;
  2569. visited[v] = true;
  2570. cmpt.push(v);
  2571. _.each(g.successors(v), dfs);
  2572. _.each(g.predecessors(v), dfs);
  2573. }
  2574. _.each(g.nodes(), function(v) {
  2575. cmpt = [];
  2576. dfs(v);
  2577. if (cmpt.length) {
  2578. cmpts.push(cmpt);
  2579. }
  2580. });
  2581. return cmpts;
  2582. }
  2583. },{"lodash":28}],11:[function(require,module,exports){
  2584. var _ = require("lodash");
  2585. module.exports = dfs;
  2586. /*
  2587. * A helper that preforms a pre- or post-order traversal on the input graph
  2588. * and returns the nodes in the order they were visited. This algorithm treats
  2589. * the input as undirected.
  2590. *
  2591. * Order must be one of "pre" or "post".
  2592. */
  2593. function dfs(g, vs, order) {
  2594. if (!_.isArray(vs)) {
  2595. vs = [vs];
  2596. }
  2597. var acc = [],
  2598. visited = {};
  2599. _.each(vs, function(v) {
  2600. if (!g.hasNode(v)) {
  2601. throw new Error("Graph does not have node: " + v);
  2602. }
  2603. doDfs(g, v, order === "post", visited, acc);
  2604. });
  2605. return acc;
  2606. }
  2607. function doDfs(g, v, postorder, visited, acc) {
  2608. if (!_.has(visited, v)) {
  2609. visited[v] = true;
  2610. if (!postorder) { acc.push(v); }
  2611. _.each(g.neighbors(v), function(w) {
  2612. doDfs(g, w, postorder, visited, acc);
  2613. });
  2614. if (postorder) { acc.push(v); }
  2615. }
  2616. }
  2617. },{"lodash":28}],12:[function(require,module,exports){
  2618. var dijkstra = require("./dijkstra"),
  2619. _ = require("lodash");
  2620. module.exports = dijkstraAll;
  2621. function dijkstraAll(g, weightFunc, edgeFunc) {
  2622. return _.transform(g.nodes(), function(acc, v) {
  2623. acc[v] = dijkstra(g, v, weightFunc, edgeFunc);
  2624. }, {});
  2625. }
  2626. },{"./dijkstra":13,"lodash":28}],13:[function(require,module,exports){
  2627. var _ = require("lodash"),
  2628. PriorityQueue = require("../data/priority-queue");
  2629. module.exports = dijkstra;
  2630. var DEFAULT_WEIGHT_FUNC = _.constant(1);
  2631. function dijkstra(g, source, weightFn, edgeFn) {
  2632. return runDijkstra(g, String(source),
  2633. weightFn || DEFAULT_WEIGHT_FUNC,
  2634. edgeFn || function(v) { return g.outEdges(v); });
  2635. }
  2636. function runDijkstra(g, source, weightFn, edgeFn) {
  2637. var results = {},
  2638. pq = new PriorityQueue(),
  2639. v, vEntry;
  2640. var updateNeighbors = function(edge) {
  2641. var w = edge.v !== v ? edge.v : edge.w,
  2642. wEntry = results[w],
  2643. weight = weightFn(edge),
  2644. distance = vEntry.distance + weight;
  2645. if (weight < 0) {
  2646. throw new Error("dijkstra does not allow negative edge weights. " +
  2647. "Bad edge: " + edge + " Weight: " + weight);
  2648. }
  2649. if (distance < wEntry.distance) {
  2650. wEntry.distance = distance;
  2651. wEntry.predecessor = v;
  2652. pq.decrease(w, distance);
  2653. }
  2654. };
  2655. g.nodes().forEach(function(v) {
  2656. var distance = v === source ? 0 : Number.POSITIVE_INFINITY;
  2657. results[v] = { distance: distance };
  2658. pq.add(v, distance);
  2659. });
  2660. while (pq.size() > 0) {
  2661. v = pq.removeMin();
  2662. vEntry = results[v];
  2663. if (vEntry.distance === Number.POSITIVE_INFINITY) {
  2664. break;
  2665. }
  2666. edgeFn(v).forEach(updateNeighbors);
  2667. }
  2668. return results;
  2669. }
  2670. },{"../data/priority-queue":23,"lodash":28}],14:[function(require,module,exports){
  2671. var _ = require("lodash"),
  2672. tarjan = require("./tarjan");
  2673. module.exports = findCycles;
  2674. function findCycles(g) {
  2675. return _.filter(tarjan(g), function(cmpt) { return cmpt.length > 1; });
  2676. }
  2677. },{"./tarjan":21,"lodash":28}],15:[function(require,module,exports){
  2678. var _ = require("lodash");
  2679. module.exports = floydWarshall;
  2680. var DEFAULT_WEIGHT_FUNC = _.constant(1);
  2681. function floydWarshall(g, weightFn, edgeFn) {
  2682. return runFloydWarshall(g,
  2683. weightFn || DEFAULT_WEIGHT_FUNC,
  2684. edgeFn || function(v) { return g.outEdges(v); });
  2685. }
  2686. function runFloydWarshall(g, weightFn, edgeFn) {
  2687. var results = {},
  2688. nodes = g.nodes();
  2689. nodes.forEach(function(v) {
  2690. results[v] = {};
  2691. results[v][v] = { distance: 0 };
  2692. nodes.forEach(function(w) {
  2693. if (v !== w) {
  2694. results[v][w] = { distance: Number.POSITIVE_INFINITY };
  2695. }
  2696. });
  2697. edgeFn(v).forEach(function(edge) {
  2698. var w = edge.v === v ? edge.w : edge.v,
  2699. d = weightFn(edge);
  2700. results[v][w] = { distance: d, predecessor: v };
  2701. });
  2702. });
  2703. nodes.forEach(function(k) {
  2704. var rowK = results[k];
  2705. nodes.forEach(function(i) {
  2706. var rowI = results[i];
  2707. nodes.forEach(function(j) {
  2708. var ik = rowI[k];
  2709. var kj = rowK[j];
  2710. var ij = rowI[j];
  2711. var altDistance = ik.distance + kj.distance;
  2712. if (altDistance < ij.distance) {
  2713. ij.distance = altDistance;
  2714. ij.predecessor = kj.predecessor;
  2715. }
  2716. });
  2717. });
  2718. });
  2719. return results;
  2720. }
  2721. },{"lodash":28}],16:[function(require,module,exports){
  2722. module.exports = {
  2723. components: require("./components"),
  2724. dijkstra: require("./dijkstra"),
  2725. dijkstraAll: require("./dijkstra-all"),
  2726. findCycles: require("./find-cycles"),
  2727. floydWarshall: require("./floyd-warshall"),
  2728. isAcyclic: require("./is-acyclic"),
  2729. postorder: require("./postorder"),
  2730. preorder: require("./preorder"),
  2731. prim: require("./prim"),
  2732. tarjan: require("./tarjan"),
  2733. topsort: require("./topsort")
  2734. };
  2735. },{"./components":10,"./dijkstra":13,"./dijkstra-all":12,"./find-cycles":14,"./floyd-warshall":15,"./is-acyclic":17,"./postorder":18,"./preorder":19,"./prim":20,"./tarjan":21,"./topsort":22}],17:[function(require,module,exports){
  2736. var topsort = require("./topsort");
  2737. module.exports = isAcyclic;
  2738. function isAcyclic(g) {
  2739. try {
  2740. topsort(g);
  2741. } catch (e) {
  2742. if (e instanceof topsort.CycleException) {
  2743. return false;
  2744. }
  2745. throw e;
  2746. }
  2747. return true;
  2748. }
  2749. },{"./topsort":22}],18:[function(require,module,exports){
  2750. var dfs = require("./dfs");
  2751. module.exports = postorder;
  2752. function postorder(g, vs) {
  2753. return dfs(g, vs, "post");
  2754. }
  2755. },{"./dfs":11}],19:[function(require,module,exports){
  2756. var dfs = require("./dfs");
  2757. module.exports = preorder;
  2758. function preorder(g, vs) {
  2759. return dfs(g, vs, "pre");
  2760. }
  2761. },{"./dfs":11}],20:[function(require,module,exports){
  2762. var _ = require("lodash"),
  2763. Graph = require("../graph"),
  2764. PriorityQueue = require("../data/priority-queue");
  2765. module.exports = prim;
  2766. function prim(g, weightFunc) {
  2767. var result = new Graph(),
  2768. parents = {},
  2769. pq = new PriorityQueue(),
  2770. v;
  2771. function updateNeighbors(edge) {
  2772. var w = edge.v === v ? edge.w : edge.v,
  2773. pri = pq.priority(w);
  2774. if (pri !== undefined) {
  2775. var edgeWeight = weightFunc(edge);
  2776. if (edgeWeight < pri) {
  2777. parents[w] = v;
  2778. pq.decrease(w, edgeWeight);
  2779. }
  2780. }
  2781. }
  2782. if (g.nodeCount() === 0) {
  2783. return result;
  2784. }
  2785. _.each(g.nodes(), function(v) {
  2786. pq.add(v, Number.POSITIVE_INFINITY);
  2787. result.setNode(v);
  2788. });
  2789. // Start from an arbitrary node
  2790. pq.decrease(g.nodes()[0], 0);
  2791. var init = false;
  2792. while (pq.size() > 0) {
  2793. v = pq.removeMin();
  2794. if (_.has(parents, v)) {
  2795. result.setEdge(v, parents[v]);
  2796. } else if (init) {
  2797. throw new Error("Input graph is not connected: " + g);
  2798. } else {
  2799. init = true;
  2800. }
  2801. g.nodeEdges(v).forEach(updateNeighbors);
  2802. }
  2803. return result;
  2804. }
  2805. },{"../data/priority-queue":23,"../graph":24,"lodash":28}],21:[function(require,module,exports){
  2806. var _ = require("lodash");
  2807. module.exports = tarjan;
  2808. function tarjan(g) {
  2809. var index = 0,
  2810. stack = [],
  2811. visited = {}, // node id -> { onStack, lowlink, index }
  2812. results = [];
  2813. function dfs(v) {
  2814. var entry = visited[v] = {
  2815. onStack: true,
  2816. lowlink: index,
  2817. index: index++
  2818. };
  2819. stack.push(v);
  2820. g.successors(v).forEach(function(w) {
  2821. if (!_.has(visited, w)) {
  2822. dfs(w);
  2823. entry.lowlink = Math.min(entry.lowlink, visited[w].lowlink);
  2824. } else if (visited[w].onStack) {
  2825. entry.lowlink = Math.min(entry.lowlink, visited[w].index);
  2826. }
  2827. });
  2828. if (entry.lowlink === entry.index) {
  2829. var cmpt = [],
  2830. w;
  2831. do {
  2832. w = stack.pop();
  2833. visited[w].onStack = false;
  2834. cmpt.push(w);
  2835. } while (v !== w);
  2836. results.push(cmpt);
  2837. }
  2838. }
  2839. g.nodes().forEach(function(v) {
  2840. if (!_.has(visited, v)) {
  2841. dfs(v);
  2842. }
  2843. });
  2844. return results;
  2845. }
  2846. },{"lodash":28}],22:[function(require,module,exports){
  2847. var _ = require("lodash");
  2848. module.exports = topsort;
  2849. topsort.CycleException = CycleException;
  2850. function topsort(g) {
  2851. var visited = {},
  2852. stack = {},
  2853. results = [];
  2854. function visit(node) {
  2855. if (_.has(stack, node)) {
  2856. throw new CycleException();
  2857. }
  2858. if (!_.has(visited, node)) {
  2859. stack[node] = true;
  2860. visited[node] = true;
  2861. _.each(g.predecessors(node), visit);
  2862. delete stack[node];
  2863. results.push(node);
  2864. }
  2865. }
  2866. _.each(g.sinks(), visit);
  2867. if (_.size(visited) !== g.nodeCount()) {
  2868. throw new CycleException();
  2869. }
  2870. return results;
  2871. }
  2872. function CycleException() {}
  2873. },{"lodash":28}],23:[function(require,module,exports){
  2874. var _ = require("lodash");
  2875. module.exports = PriorityQueue;
  2876. /**
  2877. * A min-priority queue data structure. This algorithm is derived from Cormen,
  2878. * et al., "Introduction to Algorithms". The basic idea of a min-priority
  2879. * queue is that you can efficiently (in O(1) time) get the smallest key in
  2880. * the queue. Adding and removing elements takes O(log n) time. A key can
  2881. * have its priority decreased in O(log n) time.
  2882. */
  2883. function PriorityQueue() {
  2884. this._arr = [];
  2885. this._keyIndices = {};
  2886. }
  2887. /**
  2888. * Returns the number of elements in the queue. Takes `O(1)` time.
  2889. */
  2890. PriorityQueue.prototype.size = function() {
  2891. return this._arr.length;
  2892. };
  2893. /**
  2894. * Returns the keys that are in the queue. Takes `O(n)` time.
  2895. */
  2896. PriorityQueue.prototype.keys = function() {
  2897. return this._arr.map(function(x) { return x.key; });
  2898. };
  2899. /**
  2900. * Returns `true` if **key** is in the queue and `false` if not.
  2901. */
  2902. PriorityQueue.prototype.has = function(key) {
  2903. return _.has(this._keyIndices, key);
  2904. };
  2905. /**
  2906. * Returns the priority for **key**. If **key** is not present in the queue
  2907. * then this function returns `undefined`. Takes `O(1)` time.
  2908. *
  2909. * @param {Object} key
  2910. */
  2911. PriorityQueue.prototype.priority = function(key) {
  2912. var index = this._keyIndices[key];
  2913. if (index !== undefined) {
  2914. return this._arr[index].priority;
  2915. }
  2916. };
  2917. /**
  2918. * Returns the key for the minimum element in this queue. If the queue is
  2919. * empty this function throws an Error. Takes `O(1)` time.
  2920. */
  2921. PriorityQueue.prototype.min = function() {
  2922. if (this.size() === 0) {
  2923. throw new Error("Queue underflow");
  2924. }
  2925. return this._arr[0].key;
  2926. };
  2927. /**
  2928. * Inserts a new key into the priority queue. If the key already exists in
  2929. * the queue this function returns `false`; otherwise it will return `true`.
  2930. * Takes `O(n)` time.
  2931. *
  2932. * @param {Object} key the key to add
  2933. * @param {Number} priority the initial priority for the key
  2934. */
  2935. PriorityQueue.prototype.add = function(key, priority) {
  2936. var keyIndices = this._keyIndices;
  2937. key = String(key);
  2938. if (!_.has(keyIndices, key)) {
  2939. var arr = this._arr;
  2940. var index = arr.length;
  2941. keyIndices[key] = index;
  2942. arr.push({key: key, priority: priority});
  2943. this._decrease(index);
  2944. return true;
  2945. }
  2946. return false;
  2947. };
  2948. /**
  2949. * Removes and returns the smallest key in the queue. Takes `O(log n)` time.
  2950. */
  2951. PriorityQueue.prototype.removeMin = function() {
  2952. this._swap(0, this._arr.length - 1);
  2953. var min = this._arr.pop();
  2954. delete this._keyIndices[min.key];
  2955. this._heapify(0);
  2956. return min.key;
  2957. };
  2958. /**
  2959. * Decreases the priority for **key** to **priority**. If the new priority is
  2960. * greater than the previous priority, this function will throw an Error.
  2961. *
  2962. * @param {Object} key the key for which to raise priority
  2963. * @param {Number} priority the new priority for the key
  2964. */
  2965. PriorityQueue.prototype.decrease = function(key, priority) {
  2966. var index = this._keyIndices[key];
  2967. if (priority > this._arr[index].priority) {
  2968. throw new Error("New priority is greater than current priority. " +
  2969. "Key: " + key + " Old: " + this._arr[index].priority + " New: " + priority);
  2970. }
  2971. this._arr[index].priority = priority;
  2972. this._decrease(index);
  2973. };
  2974. PriorityQueue.prototype._heapify = function(i) {
  2975. var arr = this._arr;
  2976. var l = 2 * i,
  2977. r = l + 1,
  2978. largest = i;
  2979. if (l < arr.length) {
  2980. largest = arr[l].priority < arr[largest].priority ? l : largest;
  2981. if (r < arr.length) {
  2982. largest = arr[r].priority < arr[largest].priority ? r : largest;
  2983. }
  2984. if (largest !== i) {
  2985. this._swap(i, largest);
  2986. this._heapify(largest);
  2987. }
  2988. }
  2989. };
  2990. PriorityQueue.prototype._decrease = function(index) {
  2991. var arr = this._arr;
  2992. var priority = arr[index].priority;
  2993. var parent;
  2994. while (index !== 0) {
  2995. parent = index >> 1;
  2996. if (arr[parent].priority < priority) {
  2997. break;
  2998. }
  2999. this._swap(index, parent);
  3000. index = parent;
  3001. }
  3002. };
  3003. PriorityQueue.prototype._swap = function(i, j) {
  3004. var arr = this._arr;
  3005. var keyIndices = this._keyIndices;
  3006. var origArrI = arr[i];
  3007. var origArrJ = arr[j];
  3008. arr[i] = origArrJ;
  3009. arr[j] = origArrI;
  3010. keyIndices[origArrJ.key] = i;
  3011. keyIndices[origArrI.key] = j;
  3012. };
  3013. },{"lodash":28}],24:[function(require,module,exports){
  3014. "use strict";
  3015. var _ = require("lodash");
  3016. module.exports = Graph;
  3017. var DEFAULT_EDGE_NAME = "\x00",
  3018. GRAPH_NODE = "\x00",
  3019. EDGE_KEY_DELIM = "\x01";
  3020. // Implementation notes:
  3021. //
  3022. // * Node id query functions should return string ids for the nodes
  3023. // * Edge id query functions should return an "edgeObj", edge object, that is
  3024. // composed of enough information to uniquely identify an edge: {v, w, name}.
  3025. // * Internally we use an "edgeId", a stringified form of the edgeObj, to
  3026. // reference edges. This is because we need a performant way to look these
  3027. // edges up and, object properties, which have string keys, are the closest
  3028. // we're going to get to a performant hashtable in JavaScript.
  3029. function Graph(opts) {
  3030. this._isDirected = _.has(opts, "directed") ? opts.directed : true;
  3031. this._isMultigraph = _.has(opts, "multigraph") ? opts.multigraph : false;
  3032. this._isCompound = _.has(opts, "compound") ? opts.compound : false;
  3033. // Label for the graph itself
  3034. this._label = undefined;
  3035. // Defaults to be set when creating a new node
  3036. this._defaultNodeLabelFn = _.constant(undefined);
  3037. // Defaults to be set when creating a new edge
  3038. this._defaultEdgeLabelFn = _.constant(undefined);
  3039. // v -> label
  3040. this._nodes = {};
  3041. if (this._isCompound) {
  3042. // v -> parent
  3043. this._parent = {};
  3044. // v -> children
  3045. this._children = {};
  3046. this._children[GRAPH_NODE] = {};
  3047. }
  3048. // v -> edgeObj
  3049. this._in = {};
  3050. // u -> v -> Number
  3051. this._preds = {};
  3052. // v -> edgeObj
  3053. this._out = {};
  3054. // v -> w -> Number
  3055. this._sucs = {};
  3056. // e -> edgeObj
  3057. this._edgeObjs = {};
  3058. // e -> label
  3059. this._edgeLabels = {};
  3060. }
  3061. /* Number of nodes in the graph. Should only be changed by the implementation. */
  3062. Graph.prototype._nodeCount = 0;
  3063. /* Number of edges in the graph. Should only be changed by the implementation. */
  3064. Graph.prototype._edgeCount = 0;
  3065. /* === Graph functions ========= */
  3066. Graph.prototype.isDirected = function() {
  3067. return this._isDirected;
  3068. };
  3069. Graph.prototype.isMultigraph = function() {
  3070. return this._isMultigraph;
  3071. };
  3072. Graph.prototype.isCompound = function() {
  3073. return this._isCompound;
  3074. };
  3075. Graph.prototype.setGraph = function(label) {
  3076. this._label = label;
  3077. return this;
  3078. };
  3079. Graph.prototype.graph = function() {
  3080. return this._label;
  3081. };
  3082. /* === Node functions ========== */
  3083. Graph.prototype.setDefaultNodeLabel = function(newDefault) {
  3084. if (!_.isFunction(newDefault)) {
  3085. newDefault = _.constant(newDefault);
  3086. }
  3087. this._defaultNodeLabelFn = newDefault;
  3088. return this;
  3089. };
  3090. Graph.prototype.nodeCount = function() {
  3091. return this._nodeCount;
  3092. };
  3093. Graph.prototype.nodes = function() {
  3094. return _.keys(this._nodes);
  3095. };
  3096. Graph.prototype.sources = function() {
  3097. return _.filter(this.nodes(), function(v) {
  3098. return _.isEmpty(this._in[v]);
  3099. }, this);
  3100. };
  3101. Graph.prototype.sinks = function() {
  3102. return _.filter(this.nodes(), function(v) {
  3103. return _.isEmpty(this._out[v]);
  3104. }, this);
  3105. };
  3106. Graph.prototype.setNodes = function(vs, value) {
  3107. var args = arguments;
  3108. _.each(vs, function(v) {
  3109. if (args.length > 1) {
  3110. this.setNode(v, value);
  3111. } else {
  3112. this.setNode(v);
  3113. }
  3114. }, this);
  3115. return this;
  3116. };
  3117. Graph.prototype.setNode = function(v, value) {
  3118. if (_.has(this._nodes, v)) {
  3119. if (arguments.length > 1) {
  3120. this._nodes[v] = value;
  3121. }
  3122. return this;
  3123. }
  3124. this._nodes[v] = arguments.length > 1 ? value : this._defaultNodeLabelFn(v);
  3125. if (this._isCompound) {
  3126. this._parent[v] = GRAPH_NODE;
  3127. this._children[v] = {};
  3128. this._children[GRAPH_NODE][v] = true;
  3129. }
  3130. this._in[v] = {};
  3131. this._preds[v] = {};
  3132. this._out[v] = {};
  3133. this._sucs[v] = {};
  3134. ++this._nodeCount;
  3135. return this;
  3136. };
  3137. Graph.prototype.node = function(v) {
  3138. return this._nodes[v];
  3139. };
  3140. Graph.prototype.hasNode = function(v) {
  3141. return _.has(this._nodes, v);
  3142. };
  3143. Graph.prototype.removeNode = function(v) {
  3144. var self = this;
  3145. if (_.has(this._nodes, v)) {
  3146. var removeEdge = function(e) { self.removeEdge(self._edgeObjs[e]); };
  3147. delete this._nodes[v];
  3148. if (this._isCompound) {
  3149. this._removeFromParentsChildList(v);
  3150. delete this._parent[v];
  3151. _.each(this.children(v), function(child) {
  3152. this.setParent(child);
  3153. }, this);
  3154. delete this._children[v];
  3155. }
  3156. _.each(_.keys(this._in[v]), removeEdge);
  3157. delete this._in[v];
  3158. delete this._preds[v];
  3159. _.each(_.keys(this._out[v]), removeEdge);
  3160. delete this._out[v];
  3161. delete this._sucs[v];
  3162. --this._nodeCount;
  3163. }
  3164. return this;
  3165. };
  3166. Graph.prototype.setParent = function(v, parent) {
  3167. if (!this._isCompound) {
  3168. throw new Error("Cannot set parent in a non-compound graph");
  3169. }
  3170. if (_.isUndefined(parent)) {
  3171. parent = GRAPH_NODE;
  3172. } else {
  3173. for (var ancestor = parent;
  3174. !_.isUndefined(ancestor);
  3175. ancestor = this.parent(ancestor)) {
  3176. if (ancestor === v) {
  3177. throw new Error("Setting " + parent+ " as parent of " + v +
  3178. " would create create a cycle");
  3179. }
  3180. }
  3181. this.setNode(parent);
  3182. }
  3183. this.setNode(v);
  3184. this._removeFromParentsChildList(v);
  3185. this._parent[v] = parent;
  3186. this._children[parent][v] = true;
  3187. return this;
  3188. };
  3189. Graph.prototype._removeFromParentsChildList = function(v) {
  3190. delete this._children[this._parent[v]][v];
  3191. };
  3192. Graph.prototype.parent = function(v) {
  3193. if (this._isCompound) {
  3194. var parent = this._parent[v];
  3195. if (parent !== GRAPH_NODE) {
  3196. return parent;
  3197. }
  3198. }
  3199. };
  3200. Graph.prototype.children = function(v) {
  3201. if (_.isUndefined(v)) {
  3202. v = GRAPH_NODE;
  3203. }
  3204. if (this._isCompound) {
  3205. var children = this._children[v];
  3206. if (children) {
  3207. return _.keys(children);
  3208. }
  3209. } else if (v === GRAPH_NODE) {
  3210. return this.nodes();
  3211. } else if (this.hasNode(v)) {
  3212. return [];
  3213. }
  3214. };
  3215. Graph.prototype.predecessors = function(v) {
  3216. var predsV = this._preds[v];
  3217. if (predsV) {
  3218. return _.keys(predsV);
  3219. }
  3220. };
  3221. Graph.prototype.successors = function(v) {
  3222. var sucsV = this._sucs[v];
  3223. if (sucsV) {
  3224. return _.keys(sucsV);
  3225. }
  3226. };
  3227. Graph.prototype.neighbors = function(v) {
  3228. var preds = this.predecessors(v);
  3229. if (preds) {
  3230. return _.union(preds, this.successors(v));
  3231. }
  3232. };
  3233. /* === Edge functions ========== */
  3234. Graph.prototype.setDefaultEdgeLabel = function(newDefault) {
  3235. if (!_.isFunction(newDefault)) {
  3236. newDefault = _.constant(newDefault);
  3237. }
  3238. this._defaultEdgeLabelFn = newDefault;
  3239. return this;
  3240. };
  3241. Graph.prototype.edgeCount = function() {
  3242. return this._edgeCount;
  3243. };
  3244. Graph.prototype.edges = function() {
  3245. return _.values(this._edgeObjs);
  3246. };
  3247. Graph.prototype.setPath = function(vs, value) {
  3248. var self = this,
  3249. args = arguments;
  3250. _.reduce(vs, function(v, w) {
  3251. if (args.length > 1) {
  3252. self.setEdge(v, w, value);
  3253. } else {
  3254. self.setEdge(v, w);
  3255. }
  3256. return w;
  3257. });
  3258. return this;
  3259. };
  3260. /*
  3261. * setEdge(v, w, [value, [name]])
  3262. * setEdge({ v, w, [name] }, [value])
  3263. */
  3264. Graph.prototype.setEdge = function(v, w, value, name) {
  3265. var valueSpecified = arguments.length > 2;
  3266. if (_.isPlainObject(arguments[0])) {
  3267. v = arguments[0].v;
  3268. w = arguments[0].w;
  3269. name = arguments[0].name;
  3270. if (arguments.length === 2) {
  3271. value = arguments[1];
  3272. valueSpecified = true;
  3273. }
  3274. }
  3275. var e = edgeArgsToId(this._isDirected, v, w, name);
  3276. if (_.has(this._edgeLabels, e)) {
  3277. if (valueSpecified) {
  3278. this._edgeLabels[e] = value;
  3279. }
  3280. return this;
  3281. }
  3282. if (!_.isUndefined(name) && !this._isMultigraph) {
  3283. throw new Error("Cannot set a named edge when isMultigraph = false");
  3284. }
  3285. // It didn't exist, so we need to create it.
  3286. // First ensure the nodes exist.
  3287. this.setNode(v);
  3288. this.setNode(w);
  3289. this._edgeLabels[e] = valueSpecified ? value : this._defaultEdgeLabelFn(v, w, name);
  3290. var edgeObj = edgeArgsToObj(this._isDirected, v, w, name);
  3291. // Ensure we add undirected edges in a consistent way.
  3292. v = edgeObj.v;
  3293. w = edgeObj.w;
  3294. Object.freeze(edgeObj);
  3295. this._edgeObjs[e] = edgeObj;
  3296. incrementOrInitEntry(this._preds[w], v);
  3297. incrementOrInitEntry(this._sucs[v], w);
  3298. this._in[w][e] = edgeObj;
  3299. this._out[v][e] = edgeObj;
  3300. this._edgeCount++;
  3301. return this;
  3302. };
  3303. Graph.prototype.edge = function(v, w, name) {
  3304. var e = (arguments.length === 1
  3305. ? edgeObjToId(this._isDirected, arguments[0])
  3306. : edgeArgsToId(this._isDirected, v, w, name));
  3307. return this._edgeLabels[e];
  3308. };
  3309. Graph.prototype.hasEdge = function(v, w, name) {
  3310. var e = (arguments.length === 1
  3311. ? edgeObjToId(this._isDirected, arguments[0])
  3312. : edgeArgsToId(this._isDirected, v, w, name));
  3313. return _.has(this._edgeLabels, e);
  3314. };
  3315. Graph.prototype.removeEdge = function(v, w, name) {
  3316. var e = (arguments.length === 1
  3317. ? edgeObjToId(this._isDirected, arguments[0])
  3318. : edgeArgsToId(this._isDirected, v, w, name)),
  3319. edge = this._edgeObjs[e];
  3320. if (edge) {
  3321. v = edge.v;
  3322. w = edge.w;
  3323. delete this._edgeLabels[e];
  3324. delete this._edgeObjs[e];
  3325. decrementOrRemoveEntry(this._preds[w], v);
  3326. decrementOrRemoveEntry(this._sucs[v], w);
  3327. delete this._in[w][e];
  3328. delete this._out[v][e];
  3329. this._edgeCount--;
  3330. }
  3331. return this;
  3332. };
  3333. Graph.prototype.inEdges = function(v, u) {
  3334. var inV = this._in[v];
  3335. if (inV) {
  3336. var edges = _.values(inV);
  3337. if (!u) {
  3338. return edges;
  3339. }
  3340. return _.filter(edges, function(edge) { return edge.v === u; });
  3341. }
  3342. };
  3343. Graph.prototype.outEdges = function(v, w) {
  3344. var outV = this._out[v];
  3345. if (outV) {
  3346. var edges = _.values(outV);
  3347. if (!w) {
  3348. return edges;
  3349. }
  3350. return _.filter(edges, function(edge) { return edge.w === w; });
  3351. }
  3352. };
  3353. Graph.prototype.nodeEdges = function(v, w) {
  3354. var inEdges = this.inEdges(v, w);
  3355. if (inEdges) {
  3356. return inEdges.concat(this.outEdges(v, w));
  3357. }
  3358. };
  3359. function incrementOrInitEntry(map, k) {
  3360. if (_.has(map, k)) {
  3361. map[k]++;
  3362. } else {
  3363. map[k] = 1;
  3364. }
  3365. }
  3366. function decrementOrRemoveEntry(map, k) {
  3367. if (!--map[k]) { delete map[k]; }
  3368. }
  3369. function edgeArgsToId(isDirected, v, w, name) {
  3370. if (!isDirected && v > w) {
  3371. var tmp = v;
  3372. v = w;
  3373. w = tmp;
  3374. }
  3375. return v + EDGE_KEY_DELIM + w + EDGE_KEY_DELIM +
  3376. (_.isUndefined(name) ? DEFAULT_EDGE_NAME : name);
  3377. }
  3378. function edgeArgsToObj(isDirected, v, w, name) {
  3379. if (!isDirected && v > w) {
  3380. var tmp = v;
  3381. v = w;
  3382. w = tmp;
  3383. }
  3384. var edgeObj = { v: v, w: w };
  3385. if (name) {
  3386. edgeObj.name = name;
  3387. }
  3388. return edgeObj;
  3389. }
  3390. function edgeObjToId(isDirected, edgeObj) {
  3391. return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name);
  3392. }
  3393. },{"lodash":28}],25:[function(require,module,exports){
  3394. // Includes only the "core" of graphlib
  3395. module.exports = {
  3396. Graph: require("./graph"),
  3397. version: require("./version")
  3398. };
  3399. },{"./graph":24,"./version":27}],26:[function(require,module,exports){
  3400. var _ = require("lodash"),
  3401. Graph = require("./graph");
  3402. module.exports = {
  3403. write: write,
  3404. read: read
  3405. };
  3406. function write(g) {
  3407. var json = {
  3408. options: {
  3409. directed: g.isDirected(),
  3410. multigraph: g.isMultigraph(),
  3411. compound: g.isCompound()
  3412. },
  3413. nodes: writeNodes(g),
  3414. edges: writeEdges(g)
  3415. };
  3416. if (!_.isUndefined(g.graph())) {
  3417. json.value = _.clone(g.graph());
  3418. }
  3419. return json;
  3420. }
  3421. function writeNodes(g) {
  3422. return _.map(g.nodes(), function(v) {
  3423. var nodeValue = g.node(v),
  3424. parent = g.parent(v),
  3425. node = { v: v };
  3426. if (!_.isUndefined(nodeValue)) {
  3427. node.value = nodeValue;
  3428. }
  3429. if (!_.isUndefined(parent)) {
  3430. node.parent = parent;
  3431. }
  3432. return node;
  3433. });
  3434. }
  3435. function writeEdges(g) {
  3436. return _.map(g.edges(), function(e) {
  3437. var edgeValue = g.edge(e),
  3438. edge = { v: e.v, w: e.w };
  3439. if (!_.isUndefined(e.name)) {
  3440. edge.name = e.name;
  3441. }
  3442. if (!_.isUndefined(edgeValue)) {
  3443. edge.value = edgeValue;
  3444. }
  3445. return edge;
  3446. });
  3447. }
  3448. function read(json) {
  3449. var g = new Graph(json.options).setGraph(json.value);
  3450. _.each(json.nodes, function(entry) {
  3451. g.setNode(entry.v, entry.value);
  3452. if (entry.parent) {
  3453. g.setParent(entry.v, entry.parent);
  3454. }
  3455. });
  3456. _.each(json.edges, function(entry) {
  3457. g.setEdge({ v: entry.v, w: entry.w, name: entry.name }, entry.value);
  3458. });
  3459. return g;
  3460. }
  3461. },{"./graph":24,"lodash":28}],27:[function(require,module,exports){
  3462. module.exports = '0.8.1';
  3463. },{}],28:[function(require,module,exports){
  3464. (function (global){
  3465. /**
  3466. * @license
  3467. * Lo-Dash 2.4.1 (Custom Build) <http://lodash.com/>
  3468. * Build: `lodash modern -o ./dist/lodash.js`
  3469. * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
  3470. * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE>
  3471. * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
  3472. * Available under MIT license <http://lodash.com/license>
  3473. */
  3474. ;(function() {
  3475. /** Used as a safe reference for `undefined` in pre ES5 environments */
  3476. var undefined;
  3477. /** Used to pool arrays and objects used internally */
  3478. var arrayPool = [],
  3479. objectPool = [];
  3480. /** Used to generate unique IDs */
  3481. var idCounter = 0;
  3482. /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */
  3483. var keyPrefix = +new Date + '';
  3484. /** Used as the size when optimizations are enabled for large arrays */
  3485. var largeArraySize = 75;
  3486. /** Used as the max size of the `arrayPool` and `objectPool` */
  3487. var maxPoolSize = 40;
  3488. /** Used to detect and test whitespace */
  3489. var whitespace = (
  3490. // whitespace
  3491. ' \t\x0B\f\xA0\ufeff' +
  3492. // line terminators
  3493. '\n\r\u2028\u2029' +
  3494. // unicode category "Zs" space separators
  3495. '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000'
  3496. );
  3497. /** Used to match empty string literals in compiled template source */
  3498. var reEmptyStringLeading = /\b__p \+= '';/g,
  3499. reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
  3500. reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
  3501. /**
  3502. * Used to match ES6 template delimiters
  3503. * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals
  3504. */
  3505. var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
  3506. /** Used to match regexp flags from their coerced string values */
  3507. var reFlags = /\w*$/;
  3508. /** Used to detected named functions */
  3509. var reFuncName = /^\s*function[ \n\r\t]+\w/;
  3510. /** Used to match "interpolate" template delimiters */
  3511. var reInterpolate = /<%=([\s\S]+?)%>/g;
  3512. /** Used to match leading whitespace and zeros to be removed */
  3513. var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)');
  3514. /** Used to ensure capturing order of template delimiters */
  3515. var reNoMatch = /($^)/;
  3516. /** Used to detect functions containing a `this` reference */
  3517. var reThis = /\bthis\b/;
  3518. /** Used to match unescaped characters in compiled string literals */
  3519. var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
  3520. /** Used to assign default `context` object properties */
  3521. var contextProps = [
  3522. 'Array', 'Boolean', 'Date', 'Function', 'Math', 'Number', 'Object',
  3523. 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN',
  3524. 'parseInt', 'setTimeout'
  3525. ];
  3526. /** Used to make template sourceURLs easier to identify */
  3527. var templateCounter = 0;
  3528. /** `Object#toString` result shortcuts */
  3529. var argsClass = '[object Arguments]',
  3530. arrayClass = '[object Array]',
  3531. boolClass = '[object Boolean]',
  3532. dateClass = '[object Date]',
  3533. funcClass = '[object Function]',
  3534. numberClass = '[object Number]',
  3535. objectClass = '[object Object]',
  3536. regexpClass = '[object RegExp]',
  3537. stringClass = '[object String]';
  3538. /** Used to identify object classifications that `_.clone` supports */
  3539. var cloneableClasses = {};
  3540. cloneableClasses[funcClass] = false;
  3541. cloneableClasses[argsClass] = cloneableClasses[arrayClass] =
  3542. cloneableClasses[boolClass] = cloneableClasses[dateClass] =
  3543. cloneableClasses[numberClass] = cloneableClasses[objectClass] =
  3544. cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true;
  3545. /** Used as an internal `_.debounce` options object */
  3546. var debounceOptions = {
  3547. 'leading': false,
  3548. 'maxWait': 0,
  3549. 'trailing': false
  3550. };
  3551. /** Used as the property descriptor for `__bindData__` */
  3552. var descriptor = {
  3553. 'configurable': false,
  3554. 'enumerable': false,
  3555. 'value': null,
  3556. 'writable': false
  3557. };
  3558. /** Used to determine if values are of the language type Object */
  3559. var objectTypes = {
  3560. 'boolean': false,
  3561. 'function': true,
  3562. 'object': true,
  3563. 'number': false,
  3564. 'string': false,
  3565. 'undefined': false
  3566. };
  3567. /** Used to escape characters for inclusion in compiled string literals */
  3568. var stringEscapes = {
  3569. '\\': '\\',
  3570. "'": "'",
  3571. '\n': 'n',
  3572. '\r': 'r',
  3573. '\t': 't',
  3574. '\u2028': 'u2028',
  3575. '\u2029': 'u2029'
  3576. };
  3577. /** Used as a reference to the global object */
  3578. var root = (objectTypes[typeof window] && window) || this;
  3579. /** Detect free variable `exports` */
  3580. var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
  3581. /** Detect free variable `module` */
  3582. var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
  3583. /** Detect the popular CommonJS extension `module.exports` */
  3584. var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;
  3585. /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */
  3586. var freeGlobal = objectTypes[typeof global] && global;
  3587. if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
  3588. root = freeGlobal;
  3589. }
  3590. /*--------------------------------------------------------------------------*/
  3591. /**
  3592. * The base implementation of `_.indexOf` without support for binary searches
  3593. * or `fromIndex` constraints.
  3594. *
  3595. * @private
  3596. * @param {Array} array The array to search.
  3597. * @param {*} value The value to search for.
  3598. * @param {number} [fromIndex=0] The index to search from.
  3599. * @returns {number} Returns the index of the matched value or `-1`.
  3600. */
  3601. function baseIndexOf(array, value, fromIndex) {
  3602. var index = (fromIndex || 0) - 1,
  3603. length = array ? array.length : 0;
  3604. while (++index < length) {
  3605. if (array[index] === value) {
  3606. return index;
  3607. }
  3608. }
  3609. return -1;
  3610. }
  3611. /**
  3612. * An implementation of `_.contains` for cache objects that mimics the return
  3613. * signature of `_.indexOf` by returning `0` if the value is found, else `-1`.
  3614. *
  3615. * @private
  3616. * @param {Object} cache The cache object to inspect.
  3617. * @param {*} value The value to search for.
  3618. * @returns {number} Returns `0` if `value` is found, else `-1`.
  3619. */
  3620. function cacheIndexOf(cache, value) {
  3621. var type = typeof value;
  3622. cache = cache.cache;
  3623. if (type == 'boolean' || value == null) {
  3624. return cache[value] ? 0 : -1;
  3625. }
  3626. if (type != 'number' && type != 'string') {
  3627. type = 'object';
  3628. }
  3629. var key = type == 'number' ? value : keyPrefix + value;
  3630. cache = (cache = cache[type]) && cache[key];
  3631. return type == 'object'
  3632. ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1)
  3633. : (cache ? 0 : -1);
  3634. }
  3635. /**
  3636. * Adds a given value to the corresponding cache object.
  3637. *
  3638. * @private
  3639. * @param {*} value The value to add to the cache.
  3640. */
  3641. function cachePush(value) {
  3642. var cache = this.cache,
  3643. type = typeof value;
  3644. if (type == 'boolean' || value == null) {
  3645. cache[value] = true;
  3646. } else {
  3647. if (type != 'number' && type != 'string') {
  3648. type = 'object';
  3649. }
  3650. var key = type == 'number' ? value : keyPrefix + value,
  3651. typeCache = cache[type] || (cache[type] = {});
  3652. if (type == 'object') {
  3653. (typeCache[key] || (typeCache[key] = [])).push(value);
  3654. } else {
  3655. typeCache[key] = true;
  3656. }
  3657. }
  3658. }
  3659. /**
  3660. * Used by `_.max` and `_.min` as the default callback when a given
  3661. * collection is a string value.
  3662. *
  3663. * @private
  3664. * @param {string} value The character to inspect.
  3665. * @returns {number} Returns the code unit of given character.
  3666. */
  3667. function charAtCallback(value) {
  3668. return value.charCodeAt(0);
  3669. }
  3670. /**
  3671. * Used by `sortBy` to compare transformed `collection` elements, stable sorting
  3672. * them in ascending order.
  3673. *
  3674. * @private
  3675. * @param {Object} a The object to compare to `b`.
  3676. * @param {Object} b The object to compare to `a`.
  3677. * @returns {number} Returns the sort order indicator of `1` or `-1`.
  3678. */
  3679. function compareAscending(a, b) {
  3680. var ac = a.criteria,
  3681. bc = b.criteria,
  3682. index = -1,
  3683. length = ac.length;
  3684. while (++index < length) {
  3685. var value = ac[index],
  3686. other = bc[index];
  3687. if (value !== other) {
  3688. if (value > other || typeof value == 'undefined') {
  3689. return 1;
  3690. }
  3691. if (value < other || typeof other == 'undefined') {
  3692. return -1;
  3693. }
  3694. }
  3695. }
  3696. // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
  3697. // that causes it, under certain circumstances, to return the same value for
  3698. // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247
  3699. //
  3700. // This also ensures a stable sort in V8 and other engines.
  3701. // See http://code.google.com/p/v8/issues/detail?id=90
  3702. return a.index - b.index;
  3703. }
  3704. /**
  3705. * Creates a cache object to optimize linear searches of large arrays.
  3706. *
  3707. * @private
  3708. * @param {Array} [array=[]] The array to search.
  3709. * @returns {null|Object} Returns the cache object or `null` if caching should not be used.
  3710. */
  3711. function createCache(array) {
  3712. var index = -1,
  3713. length = array.length,
  3714. first = array[0],
  3715. mid = array[(length / 2) | 0],
  3716. last = array[length - 1];
  3717. if (first && typeof first == 'object' &&
  3718. mid && typeof mid == 'object' && last && typeof last == 'object') {
  3719. return false;
  3720. }
  3721. var cache = getObject();
  3722. cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false;
  3723. var result = getObject();
  3724. result.array = array;
  3725. result.cache = cache;
  3726. result.push = cachePush;
  3727. while (++index < length) {
  3728. result.push(array[index]);
  3729. }
  3730. return result;
  3731. }
  3732. /**
  3733. * Used by `template` to escape characters for inclusion in compiled
  3734. * string literals.
  3735. *
  3736. * @private
  3737. * @param {string} match The matched character to escape.
  3738. * @returns {string} Returns the escaped character.
  3739. */
  3740. function escapeStringChar(match) {
  3741. return '\\' + stringEscapes[match];
  3742. }
  3743. /**
  3744. * Gets an array from the array pool or creates a new one if the pool is empty.
  3745. *
  3746. * @private
  3747. * @returns {Array} The array from the pool.
  3748. */
  3749. function getArray() {
  3750. return arrayPool.pop() || [];
  3751. }
  3752. /**
  3753. * Gets an object from the object pool or creates a new one if the pool is empty.
  3754. *
  3755. * @private
  3756. * @returns {Object} The object from the pool.
  3757. */
  3758. function getObject() {
  3759. return objectPool.pop() || {
  3760. 'array': null,
  3761. 'cache': null,
  3762. 'criteria': null,
  3763. 'false': false,
  3764. 'index': 0,
  3765. 'null': false,
  3766. 'number': null,
  3767. 'object': null,
  3768. 'push': null,
  3769. 'string': null,
  3770. 'true': false,
  3771. 'undefined': false,
  3772. 'value': null
  3773. };
  3774. }
  3775. /**
  3776. * Releases the given array back to the array pool.
  3777. *
  3778. * @private
  3779. * @param {Array} [array] The array to release.
  3780. */
  3781. function releaseArray(array) {
  3782. array.length = 0;
  3783. if (arrayPool.length < maxPoolSize) {
  3784. arrayPool.push(array);
  3785. }
  3786. }
  3787. /**
  3788. * Releases the given object back to the object pool.
  3789. *
  3790. * @private
  3791. * @param {Object} [object] The object to release.
  3792. */
  3793. function releaseObject(object) {
  3794. var cache = object.cache;
  3795. if (cache) {
  3796. releaseObject(cache);
  3797. }
  3798. object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null;
  3799. if (objectPool.length < maxPoolSize) {
  3800. objectPool.push(object);
  3801. }
  3802. }
  3803. /**
  3804. * Slices the `collection` from the `start` index up to, but not including,
  3805. * the `end` index.
  3806. *
  3807. * Note: This function is used instead of `Array#slice` to support node lists
  3808. * in IE < 9 and to ensure dense arrays are returned.
  3809. *
  3810. * @private
  3811. * @param {Array|Object|string} collection The collection to slice.
  3812. * @param {number} start The start index.
  3813. * @param {number} end The end index.
  3814. * @returns {Array} Returns the new array.
  3815. */
  3816. function slice(array, start, end) {
  3817. start || (start = 0);
  3818. if (typeof end == 'undefined') {
  3819. end = array ? array.length : 0;
  3820. }
  3821. var index = -1,
  3822. length = end - start || 0,
  3823. result = Array(length < 0 ? 0 : length);
  3824. while (++index < length) {
  3825. result[index] = array[start + index];
  3826. }
  3827. return result;
  3828. }
  3829. /*--------------------------------------------------------------------------*/
  3830. /**
  3831. * Create a new `lodash` function using the given context object.
  3832. *
  3833. * @static
  3834. * @memberOf _
  3835. * @category Utilities
  3836. * @param {Object} [context=root] The context object.
  3837. * @returns {Function} Returns the `lodash` function.
  3838. */
  3839. function runInContext(context) {
  3840. // Avoid issues with some ES3 environments that attempt to use values, named
  3841. // after built-in constructors like `Object`, for the creation of literals.
  3842. // ES5 clears this up by stating that literals must use built-in constructors.
  3843. // See http://es5.github.io/#x11.1.5.
  3844. context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root;
  3845. /** Native constructor references */
  3846. var Array = context.Array,
  3847. Boolean = context.Boolean,
  3848. Date = context.Date,
  3849. Function = context.Function,
  3850. Math = context.Math,
  3851. Number = context.Number,
  3852. Object = context.Object,
  3853. RegExp = context.RegExp,
  3854. String = context.String,
  3855. TypeError = context.TypeError;
  3856. /**
  3857. * Used for `Array` method references.
  3858. *
  3859. * Normally `Array.prototype` would suffice, however, using an array literal
  3860. * avoids issues in Narwhal.
  3861. */
  3862. var arrayRef = [];
  3863. /** Used for native method references */
  3864. var objectProto = Object.prototype;
  3865. /** Used to restore the original `_` reference in `noConflict` */
  3866. var oldDash = context._;
  3867. /** Used to resolve the internal [[Class]] of values */
  3868. var toString = objectProto.toString;
  3869. /** Used to detect if a method is native */
  3870. var reNative = RegExp('^' +
  3871. String(toString)
  3872. .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
  3873. .replace(/toString| for [^\]]+/g, '.*?') + '$'
  3874. );
  3875. /** Native method shortcuts */
  3876. var ceil = Math.ceil,
  3877. clearTimeout = context.clearTimeout,
  3878. floor = Math.floor,
  3879. fnToString = Function.prototype.toString,
  3880. getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
  3881. hasOwnProperty = objectProto.hasOwnProperty,
  3882. push = arrayRef.push,
  3883. setTimeout = context.setTimeout,
  3884. splice = arrayRef.splice,
  3885. unshift = arrayRef.unshift;
  3886. /** Used to set meta data on functions */
  3887. var defineProperty = (function() {
  3888. // IE 8 only accepts DOM elements
  3889. try {
  3890. var o = {},
  3891. func = isNative(func = Object.defineProperty) && func,
  3892. result = func(o, o, o) && func;
  3893. } catch(e) { }
  3894. return result;
  3895. }());
  3896. /* Native method shortcuts for methods with the same name as other `lodash` methods */
  3897. var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate,
  3898. nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray,
  3899. nativeIsFinite = context.isFinite,
  3900. nativeIsNaN = context.isNaN,
  3901. nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys,
  3902. nativeMax = Math.max,
  3903. nativeMin = Math.min,
  3904. nativeParseInt = context.parseInt,
  3905. nativeRandom = Math.random;
  3906. /** Used to lookup a built-in constructor by [[Class]] */
  3907. var ctorByClass = {};
  3908. ctorByClass[arrayClass] = Array;
  3909. ctorByClass[boolClass] = Boolean;
  3910. ctorByClass[dateClass] = Date;
  3911. ctorByClass[funcClass] = Function;
  3912. ctorByClass[objectClass] = Object;
  3913. ctorByClass[numberClass] = Number;
  3914. ctorByClass[regexpClass] = RegExp;
  3915. ctorByClass[stringClass] = String;
  3916. /*--------------------------------------------------------------------------*/
  3917. /**
  3918. * Creates a `lodash` object which wraps the given value to enable intuitive
  3919. * method chaining.
  3920. *
  3921. * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
  3922. * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
  3923. * and `unshift`
  3924. *
  3925. * Chaining is supported in custom builds as long as the `value` method is
  3926. * implicitly or explicitly included in the build.
  3927. *
  3928. * The chainable wrapper functions are:
  3929. * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
  3930. * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`,
  3931. * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`,
  3932. * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,
  3933. * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
  3934. * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`,
  3935. * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`,
  3936. * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`,
  3937. * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`,
  3938. * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`,
  3939. * and `zip`
  3940. *
  3941. * The non-chainable wrapper functions are:
  3942. * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`,
  3943. * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`,
  3944. * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
  3945. * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`,
  3946. * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`,
  3947. * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`,
  3948. * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`,
  3949. * `template`, `unescape`, `uniqueId`, and `value`
  3950. *
  3951. * The wrapper functions `first` and `last` return wrapped values when `n` is
  3952. * provided, otherwise they return unwrapped values.
  3953. *
  3954. * Explicit chaining can be enabled by using the `_.chain` method.
  3955. *
  3956. * @name _
  3957. * @constructor
  3958. * @category Chaining
  3959. * @param {*} value The value to wrap in a `lodash` instance.
  3960. * @returns {Object} Returns a `lodash` instance.
  3961. * @example
  3962. *
  3963. * var wrapped = _([1, 2, 3]);
  3964. *
  3965. * // returns an unwrapped value
  3966. * wrapped.reduce(function(sum, num) {
  3967. * return sum + num;
  3968. * });
  3969. * // => 6
  3970. *
  3971. * // returns a wrapped value
  3972. * var squares = wrapped.map(function(num) {
  3973. * return num * num;
  3974. * });
  3975. *
  3976. * _.isArray(squares);
  3977. * // => false
  3978. *
  3979. * _.isArray(squares.value());
  3980. * // => true
  3981. */
  3982. function lodash(value) {
  3983. // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor
  3984. return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__'))
  3985. ? value
  3986. : new lodashWrapper(value);
  3987. }
  3988. /**
  3989. * A fast path for creating `lodash` wrapper objects.
  3990. *
  3991. * @private
  3992. * @param {*} value The value to wrap in a `lodash` instance.
  3993. * @param {boolean} chainAll A flag to enable chaining for all methods
  3994. * @returns {Object} Returns a `lodash` instance.
  3995. */
  3996. function lodashWrapper(value, chainAll) {
  3997. this.__chain__ = !!chainAll;
  3998. this.__wrapped__ = value;
  3999. }
  4000. // ensure `new lodashWrapper` is an instance of `lodash`
  4001. lodashWrapper.prototype = lodash.prototype;
  4002. /**
  4003. * An object used to flag environments features.
  4004. *
  4005. * @static
  4006. * @memberOf _
  4007. * @type Object
  4008. */
  4009. var support = lodash.support = {};
  4010. /**
  4011. * Detect if functions can be decompiled by `Function#toString`
  4012. * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps).
  4013. *
  4014. * @memberOf _.support
  4015. * @type boolean
  4016. */
  4017. support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext);
  4018. /**
  4019. * Detect if `Function#name` is supported (all but IE).
  4020. *
  4021. * @memberOf _.support
  4022. * @type boolean
  4023. */
  4024. support.funcNames = typeof Function.name == 'string';
  4025. /**
  4026. * By default, the template delimiters used by Lo-Dash are similar to those in
  4027. * embedded Ruby (ERB). Change the following template settings to use alternative
  4028. * delimiters.
  4029. *
  4030. * @static
  4031. * @memberOf _
  4032. * @type Object
  4033. */
  4034. lodash.templateSettings = {
  4035. /**
  4036. * Used to detect `data` property values to be HTML-escaped.
  4037. *
  4038. * @memberOf _.templateSettings
  4039. * @type RegExp
  4040. */
  4041. 'escape': /<%-([\s\S]+?)%>/g,
  4042. /**
  4043. * Used to detect code to be evaluated.
  4044. *
  4045. * @memberOf _.templateSettings
  4046. * @type RegExp
  4047. */
  4048. 'evaluate': /<%([\s\S]+?)%>/g,
  4049. /**
  4050. * Used to detect `data` property values to inject.
  4051. *
  4052. * @memberOf _.templateSettings
  4053. * @type RegExp
  4054. */
  4055. 'interpolate': reInterpolate,
  4056. /**
  4057. * Used to reference the data object in the template text.
  4058. *
  4059. * @memberOf _.templateSettings
  4060. * @type string
  4061. */
  4062. 'variable': '',
  4063. /**
  4064. * Used to import variables into the compiled template.
  4065. *
  4066. * @memberOf _.templateSettings
  4067. * @type Object
  4068. */
  4069. 'imports': {
  4070. /**
  4071. * A reference to the `lodash` function.
  4072. *
  4073. * @memberOf _.templateSettings.imports
  4074. * @type Function
  4075. */
  4076. '_': lodash
  4077. }
  4078. };
  4079. /*--------------------------------------------------------------------------*/
  4080. /**
  4081. * The base implementation of `_.bind` that creates the bound function and
  4082. * sets its meta data.
  4083. *
  4084. * @private
  4085. * @param {Array} bindData The bind data array.
  4086. * @returns {Function} Returns the new bound function.
  4087. */
  4088. function baseBind(bindData) {
  4089. var func = bindData[0],
  4090. partialArgs = bindData[2],
  4091. thisArg = bindData[4];
  4092. function bound() {
  4093. // `Function#bind` spec
  4094. // http://es5.github.io/#x15.3.4.5
  4095. if (partialArgs) {
  4096. // avoid `arguments` object deoptimizations by using `slice` instead
  4097. // of `Array.prototype.slice.call` and not assigning `arguments` to a
  4098. // variable as a ternary expression
  4099. var args = slice(partialArgs);
  4100. push.apply(args, arguments);
  4101. }
  4102. // mimic the constructor's `return` behavior
  4103. // http://es5.github.io/#x13.2.2
  4104. if (this instanceof bound) {
  4105. // ensure `new bound` is an instance of `func`
  4106. var thisBinding = baseCreate(func.prototype),
  4107. result = func.apply(thisBinding, args || arguments);
  4108. return isObject(result) ? result : thisBinding;
  4109. }
  4110. return func.apply(thisArg, args || arguments);
  4111. }
  4112. setBindData(bound, bindData);
  4113. return bound;
  4114. }
  4115. /**
  4116. * The base implementation of `_.clone` without argument juggling or support
  4117. * for `thisArg` binding.
  4118. *
  4119. * @private
  4120. * @param {*} value The value to clone.
  4121. * @param {boolean} [isDeep=false] Specify a deep clone.
  4122. * @param {Function} [callback] The function to customize cloning values.
  4123. * @param {Array} [stackA=[]] Tracks traversed source objects.
  4124. * @param {Array} [stackB=[]] Associates clones with source counterparts.
  4125. * @returns {*} Returns the cloned value.
  4126. */
  4127. function baseClone(value, isDeep, callback, stackA, stackB) {
  4128. if (callback) {
  4129. var result = callback(value);
  4130. if (typeof result != 'undefined') {
  4131. return result;
  4132. }
  4133. }
  4134. // inspect [[Class]]
  4135. var isObj = isObject(value);
  4136. if (isObj) {
  4137. var className = toString.call(value);
  4138. if (!cloneableClasses[className]) {
  4139. return value;
  4140. }
  4141. var ctor = ctorByClass[className];
  4142. switch (className) {
  4143. case boolClass:
  4144. case dateClass:
  4145. return new ctor(+value);
  4146. case numberClass:
  4147. case stringClass:
  4148. return new ctor(value);
  4149. case regexpClass:
  4150. result = ctor(value.source, reFlags.exec(value));
  4151. result.lastIndex = value.lastIndex;
  4152. return result;
  4153. }
  4154. } else {
  4155. return value;
  4156. }
  4157. var isArr = isArray(value);
  4158. if (isDeep) {
  4159. // check for circular references and return corresponding clone
  4160. var initedStack = !stackA;
  4161. stackA || (stackA = getArray());
  4162. stackB || (stackB = getArray());
  4163. var length = stackA.length;
  4164. while (length--) {
  4165. if (stackA[length] == value) {
  4166. return stackB[length];
  4167. }
  4168. }
  4169. result = isArr ? ctor(value.length) : {};
  4170. }
  4171. else {
  4172. result = isArr ? slice(value) : assign({}, value);
  4173. }
  4174. // add array properties assigned by `RegExp#exec`
  4175. if (isArr) {
  4176. if (hasOwnProperty.call(value, 'index')) {
  4177. result.index = value.index;
  4178. }
  4179. if (hasOwnProperty.call(value, 'input')) {
  4180. result.input = value.input;
  4181. }
  4182. }
  4183. // exit for shallow clone
  4184. if (!isDeep) {
  4185. return result;
  4186. }
  4187. // add the source value to the stack of traversed objects
  4188. // and associate it with its clone
  4189. stackA.push(value);
  4190. stackB.push(result);
  4191. // recursively populate clone (susceptible to call stack limits)
  4192. (isArr ? forEach : forOwn)(value, function(objValue, key) {
  4193. result[key] = baseClone(objValue, isDeep, callback, stackA, stackB);
  4194. });
  4195. if (initedStack) {
  4196. releaseArray(stackA);
  4197. releaseArray(stackB);
  4198. }
  4199. return result;
  4200. }
  4201. /**
  4202. * The base implementation of `_.create` without support for assigning
  4203. * properties to the created object.
  4204. *
  4205. * @private
  4206. * @param {Object} prototype The object to inherit from.
  4207. * @returns {Object} Returns the new object.
  4208. */
  4209. function baseCreate(prototype, properties) {
  4210. return isObject(prototype) ? nativeCreate(prototype) : {};
  4211. }
  4212. // fallback for browsers without `Object.create`
  4213. if (!nativeCreate) {
  4214. baseCreate = (function() {
  4215. function Object() {}
  4216. return function(prototype) {
  4217. if (isObject(prototype)) {
  4218. Object.prototype = prototype;
  4219. var result = new Object;
  4220. Object.prototype = null;
  4221. }
  4222. return result || context.Object();
  4223. };
  4224. }());
  4225. }
  4226. /**
  4227. * The base implementation of `_.createCallback` without support for creating
  4228. * "_.pluck" or "_.where" style callbacks.
  4229. *
  4230. * @private
  4231. * @param {*} [func=identity] The value to convert to a callback.
  4232. * @param {*} [thisArg] The `this` binding of the created callback.
  4233. * @param {number} [argCount] The number of arguments the callback accepts.
  4234. * @returns {Function} Returns a callback function.
  4235. */
  4236. function baseCreateCallback(func, thisArg, argCount) {
  4237. if (typeof func != 'function') {
  4238. return identity;
  4239. }
  4240. // exit early for no `thisArg` or already bound by `Function#bind`
  4241. if (typeof thisArg == 'undefined' || !('prototype' in func)) {
  4242. return func;
  4243. }
  4244. var bindData = func.__bindData__;
  4245. if (typeof bindData == 'undefined') {
  4246. if (support.funcNames) {
  4247. bindData = !func.name;
  4248. }
  4249. bindData = bindData || !support.funcDecomp;
  4250. if (!bindData) {
  4251. var source = fnToString.call(func);
  4252. if (!support.funcNames) {
  4253. bindData = !reFuncName.test(source);
  4254. }
  4255. if (!bindData) {
  4256. // checks if `func` references the `this` keyword and stores the result
  4257. bindData = reThis.test(source);
  4258. setBindData(func, bindData);
  4259. }
  4260. }
  4261. }
  4262. // exit early if there are no `this` references or `func` is bound
  4263. if (bindData === false || (bindData !== true && bindData[1] & 1)) {
  4264. return func;
  4265. }
  4266. switch (argCount) {
  4267. case 1: return function(value) {
  4268. return func.call(thisArg, value);
  4269. };
  4270. case 2: return function(a, b) {
  4271. return func.call(thisArg, a, b);
  4272. };
  4273. case 3: return function(value, index, collection) {
  4274. return func.call(thisArg, value, index, collection);
  4275. };
  4276. case 4: return function(accumulator, value, index, collection) {
  4277. return func.call(thisArg, accumulator, value, index, collection);
  4278. };
  4279. }
  4280. return bind(func, thisArg);
  4281. }
  4282. /**
  4283. * The base implementation of `createWrapper` that creates the wrapper and
  4284. * sets its meta data.
  4285. *
  4286. * @private
  4287. * @param {Array} bindData The bind data array.
  4288. * @returns {Function} Returns the new function.
  4289. */
  4290. function baseCreateWrapper(bindData) {
  4291. var func = bindData[0],
  4292. bitmask = bindData[1],
  4293. partialArgs = bindData[2],
  4294. partialRightArgs = bindData[3],
  4295. thisArg = bindData[4],
  4296. arity = bindData[5];
  4297. var isBind = bitmask & 1,
  4298. isBindKey = bitmask & 2,
  4299. isCurry = bitmask & 4,
  4300. isCurryBound = bitmask & 8,
  4301. key = func;
  4302. function bound() {
  4303. var thisBinding = isBind ? thisArg : this;
  4304. if (partialArgs) {
  4305. var args = slice(partialArgs);
  4306. push.apply(args, arguments);
  4307. }
  4308. if (partialRightArgs || isCurry) {
  4309. args || (args = slice(arguments));
  4310. if (partialRightArgs) {
  4311. push.apply(args, partialRightArgs);
  4312. }
  4313. if (isCurry && args.length < arity) {
  4314. bitmask |= 16 & ~32;
  4315. return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]);
  4316. }
  4317. }
  4318. args || (args = arguments);
  4319. if (isBindKey) {
  4320. func = thisBinding[key];
  4321. }
  4322. if (this instanceof bound) {
  4323. thisBinding = baseCreate(func.prototype);
  4324. var result = func.apply(thisBinding, args);
  4325. return isObject(result) ? result : thisBinding;
  4326. }
  4327. return func.apply(thisBinding, args);
  4328. }
  4329. setBindData(bound, bindData);
  4330. return bound;
  4331. }
  4332. /**
  4333. * The base implementation of `_.difference` that accepts a single array
  4334. * of values to exclude.
  4335. *
  4336. * @private
  4337. * @param {Array} array The array to process.
  4338. * @param {Array} [values] The array of values to exclude.
  4339. * @returns {Array} Returns a new array of filtered values.
  4340. */
  4341. function baseDifference(array, values) {
  4342. var index = -1,
  4343. indexOf = getIndexOf(),
  4344. length = array ? array.length : 0,
  4345. isLarge = length >= largeArraySize && indexOf === baseIndexOf,
  4346. result = [];
  4347. if (isLarge) {
  4348. var cache = createCache(values);
  4349. if (cache) {
  4350. indexOf = cacheIndexOf;
  4351. values = cache;
  4352. } else {
  4353. isLarge = false;
  4354. }
  4355. }
  4356. while (++index < length) {
  4357. var value = array[index];
  4358. if (indexOf(values, value) < 0) {
  4359. result.push(value);
  4360. }
  4361. }
  4362. if (isLarge) {
  4363. releaseObject(values);
  4364. }
  4365. return result;
  4366. }
  4367. /**
  4368. * The base implementation of `_.flatten` without support for callback
  4369. * shorthands or `thisArg` binding.
  4370. *
  4371. * @private
  4372. * @param {Array} array The array to flatten.
  4373. * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
  4374. * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects.
  4375. * @param {number} [fromIndex=0] The index to start from.
  4376. * @returns {Array} Returns a new flattened array.
  4377. */
  4378. function baseFlatten(array, isShallow, isStrict, fromIndex) {
  4379. var index = (fromIndex || 0) - 1,
  4380. length = array ? array.length : 0,
  4381. result = [];
  4382. while (++index < length) {
  4383. var value = array[index];
  4384. if (value && typeof value == 'object' && typeof value.length == 'number'
  4385. && (isArray(value) || isArguments(value))) {
  4386. // recursively flatten arrays (susceptible to call stack limits)
  4387. if (!isShallow) {
  4388. value = baseFlatten(value, isShallow, isStrict);
  4389. }
  4390. var valIndex = -1,
  4391. valLength = value.length,
  4392. resIndex = result.length;
  4393. result.length += valLength;
  4394. while (++valIndex < valLength) {
  4395. result[resIndex++] = value[valIndex];
  4396. }
  4397. } else if (!isStrict) {
  4398. result.push(value);
  4399. }
  4400. }
  4401. return result;
  4402. }
  4403. /**
  4404. * The base implementation of `_.isEqual`, without support for `thisArg` binding,
  4405. * that allows partial "_.where" style comparisons.
  4406. *
  4407. * @private
  4408. * @param {*} a The value to compare.
  4409. * @param {*} b The other value to compare.
  4410. * @param {Function} [callback] The function to customize comparing values.
  4411. * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons.
  4412. * @param {Array} [stackA=[]] Tracks traversed `a` objects.
  4413. * @param {Array} [stackB=[]] Tracks traversed `b` objects.
  4414. * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
  4415. */
  4416. function baseIsEqual(a, b, callback, isWhere, stackA, stackB) {
  4417. // used to indicate that when comparing objects, `a` has at least the properties of `b`
  4418. if (callback) {
  4419. var result = callback(a, b);
  4420. if (typeof result != 'undefined') {
  4421. return !!result;
  4422. }
  4423. }
  4424. // exit early for identical values
  4425. if (a === b) {
  4426. // treat `+0` vs. `-0` as not equal
  4427. return a !== 0 || (1 / a == 1 / b);
  4428. }
  4429. var type = typeof a,
  4430. otherType = typeof b;
  4431. // exit early for unlike primitive values
  4432. if (a === a &&
  4433. !(a && objectTypes[type]) &&
  4434. !(b && objectTypes[otherType])) {
  4435. return false;
  4436. }
  4437. // exit early for `null` and `undefined` avoiding ES3's Function#call behavior
  4438. // http://es5.github.io/#x15.3.4.4
  4439. if (a == null || b == null) {
  4440. return a === b;
  4441. }
  4442. // compare [[Class]] names
  4443. var className = toString.call(a),
  4444. otherClass = toString.call(b);
  4445. if (className == argsClass) {
  4446. className = objectClass;
  4447. }
  4448. if (otherClass == argsClass) {
  4449. otherClass = objectClass;
  4450. }
  4451. if (className != otherClass) {
  4452. return false;
  4453. }
  4454. switch (className) {
  4455. case boolClass:
  4456. case dateClass:
  4457. // coerce dates and booleans to numbers, dates to milliseconds and booleans
  4458. // to `1` or `0` treating invalid dates coerced to `NaN` as not equal
  4459. return +a == +b;
  4460. case numberClass:
  4461. // treat `NaN` vs. `NaN` as equal
  4462. return (a != +a)
  4463. ? b != +b
  4464. // but treat `+0` vs. `-0` as not equal
  4465. : (a == 0 ? (1 / a == 1 / b) : a == +b);
  4466. case regexpClass:
  4467. case stringClass:
  4468. // coerce regexes to strings (http://es5.github.io/#x15.10.6.4)
  4469. // treat string primitives and their corresponding object instances as equal
  4470. return a == String(b);
  4471. }
  4472. var isArr = className == arrayClass;
  4473. if (!isArr) {
  4474. // unwrap any `lodash` wrapped values
  4475. var aWrapped = hasOwnProperty.call(a, '__wrapped__'),
  4476. bWrapped = hasOwnProperty.call(b, '__wrapped__');
  4477. if (aWrapped || bWrapped) {
  4478. return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB);
  4479. }
  4480. // exit for functions and DOM nodes
  4481. if (className != objectClass) {
  4482. return false;
  4483. }
  4484. // in older versions of Opera, `arguments` objects have `Array` constructors
  4485. var ctorA = a.constructor,
  4486. ctorB = b.constructor;
  4487. // non `Object` object instances with different constructors are not equal
  4488. if (ctorA != ctorB &&
  4489. !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) &&
  4490. ('constructor' in a && 'constructor' in b)
  4491. ) {
  4492. return false;
  4493. }
  4494. }
  4495. // assume cyclic structures are equal
  4496. // the algorithm for detecting cyclic structures is adapted from ES 5.1
  4497. // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3)
  4498. var initedStack = !stackA;
  4499. stackA || (stackA = getArray());
  4500. stackB || (stackB = getArray());
  4501. var length = stackA.length;
  4502. while (length--) {
  4503. if (stackA[length] == a) {
  4504. return stackB[length] == b;
  4505. }
  4506. }
  4507. var size = 0;
  4508. result = true;
  4509. // add `a` and `b` to the stack of traversed objects
  4510. stackA.push(a);
  4511. stackB.push(b);
  4512. // recursively compare objects and arrays (susceptible to call stack limits)
  4513. if (isArr) {
  4514. // compare lengths to determine if a deep comparison is necessary
  4515. length = a.length;
  4516. size = b.length;
  4517. result = size == length;
  4518. if (result || isWhere) {
  4519. // deep compare the contents, ignoring non-numeric properties
  4520. while (size--) {
  4521. var index = length,
  4522. value = b[size];
  4523. if (isWhere) {
  4524. while (index--) {
  4525. if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) {
  4526. break;
  4527. }
  4528. }
  4529. } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) {
  4530. break;
  4531. }
  4532. }
  4533. }
  4534. }
  4535. else {
  4536. // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys`
  4537. // which, in this case, is more costly
  4538. forIn(b, function(value, key, b) {
  4539. if (hasOwnProperty.call(b, key)) {
  4540. // count the number of properties.
  4541. size++;
  4542. // deep compare each property value.
  4543. return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB));
  4544. }
  4545. });
  4546. if (result && !isWhere) {
  4547. // ensure both objects have the same number of properties
  4548. forIn(a, function(value, key, a) {
  4549. if (hasOwnProperty.call(a, key)) {
  4550. // `size` will be `-1` if `a` has more properties than `b`
  4551. return (result = --size > -1);
  4552. }
  4553. });
  4554. }
  4555. }
  4556. stackA.pop();
  4557. stackB.pop();
  4558. if (initedStack) {
  4559. releaseArray(stackA);
  4560. releaseArray(stackB);
  4561. }
  4562. return result;
  4563. }
  4564. /**
  4565. * The base implementation of `_.merge` without argument juggling or support
  4566. * for `thisArg` binding.
  4567. *
  4568. * @private
  4569. * @param {Object} object The destination object.
  4570. * @param {Object} source The source object.
  4571. * @param {Function} [callback] The function to customize merging properties.
  4572. * @param {Array} [stackA=[]] Tracks traversed source objects.
  4573. * @param {Array} [stackB=[]] Associates values with source counterparts.
  4574. */
  4575. function baseMerge(object, source, callback, stackA, stackB) {
  4576. (isArray(source) ? forEach : forOwn)(source, function(source, key) {
  4577. var found,
  4578. isArr,
  4579. result = source,
  4580. value = object[key];
  4581. if (source && ((isArr = isArray(source)) || isPlainObject(source))) {
  4582. // avoid merging previously merged cyclic sources
  4583. var stackLength = stackA.length;
  4584. while (stackLength--) {
  4585. if ((found = stackA[stackLength] == source)) {
  4586. value = stackB[stackLength];
  4587. break;
  4588. }
  4589. }
  4590. if (!found) {
  4591. var isShallow;
  4592. if (callback) {
  4593. result = callback(value, source);
  4594. if ((isShallow = typeof result != 'undefined')) {
  4595. value = result;
  4596. }
  4597. }
  4598. if (!isShallow) {
  4599. value = isArr
  4600. ? (isArray(value) ? value : [])
  4601. : (isPlainObject(value) ? value : {});
  4602. }
  4603. // add `source` and associated `value` to the stack of traversed objects
  4604. stackA.push(source);
  4605. stackB.push(value);
  4606. // recursively merge objects and arrays (susceptible to call stack limits)
  4607. if (!isShallow) {
  4608. baseMerge(value, source, callback, stackA, stackB);
  4609. }
  4610. }
  4611. }
  4612. else {
  4613. if (callback) {
  4614. result = callback(value, source);
  4615. if (typeof result == 'undefined') {
  4616. result = source;
  4617. }
  4618. }
  4619. if (typeof result != 'undefined') {
  4620. value = result;
  4621. }
  4622. }
  4623. object[key] = value;
  4624. });
  4625. }
  4626. /**
  4627. * The base implementation of `_.random` without argument juggling or support
  4628. * for returning floating-point numbers.
  4629. *
  4630. * @private
  4631. * @param {number} min The minimum possible value.
  4632. * @param {number} max The maximum possible value.
  4633. * @returns {number} Returns a random number.
  4634. */
  4635. function baseRandom(min, max) {
  4636. return min + floor(nativeRandom() * (max - min + 1));
  4637. }
  4638. /**
  4639. * The base implementation of `_.uniq` without support for callback shorthands
  4640. * or `thisArg` binding.
  4641. *
  4642. * @private
  4643. * @param {Array} array The array to process.
  4644. * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
  4645. * @param {Function} [callback] The function called per iteration.
  4646. * @returns {Array} Returns a duplicate-value-free array.
  4647. */
  4648. function baseUniq(array, isSorted, callback) {
  4649. var index = -1,
  4650. indexOf = getIndexOf(),
  4651. length = array ? array.length : 0,
  4652. result = [];
  4653. var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf,
  4654. seen = (callback || isLarge) ? getArray() : result;
  4655. if (isLarge) {
  4656. var cache = createCache(seen);
  4657. indexOf = cacheIndexOf;
  4658. seen = cache;
  4659. }
  4660. while (++index < length) {
  4661. var value = array[index],
  4662. computed = callback ? callback(value, index, array) : value;
  4663. if (isSorted
  4664. ? !index || seen[seen.length - 1] !== computed
  4665. : indexOf(seen, computed) < 0
  4666. ) {
  4667. if (callback || isLarge) {
  4668. seen.push(computed);
  4669. }
  4670. result.push(value);
  4671. }
  4672. }
  4673. if (isLarge) {
  4674. releaseArray(seen.array);
  4675. releaseObject(seen);
  4676. } else if (callback) {
  4677. releaseArray(seen);
  4678. }
  4679. return result;
  4680. }
  4681. /**
  4682. * Creates a function that aggregates a collection, creating an object composed
  4683. * of keys generated from the results of running each element of the collection
  4684. * through a callback. The given `setter` function sets the keys and values
  4685. * of the composed object.
  4686. *
  4687. * @private
  4688. * @param {Function} setter The setter function.
  4689. * @returns {Function} Returns the new aggregator function.
  4690. */
  4691. function createAggregator(setter) {
  4692. return function(collection, callback, thisArg) {
  4693. var result = {};
  4694. callback = lodash.createCallback(callback, thisArg, 3);
  4695. var index = -1,
  4696. length = collection ? collection.length : 0;
  4697. if (typeof length == 'number') {
  4698. while (++index < length) {
  4699. var value = collection[index];
  4700. setter(result, value, callback(value, index, collection), collection);
  4701. }
  4702. } else {
  4703. forOwn(collection, function(value, key, collection) {
  4704. setter(result, value, callback(value, key, collection), collection);
  4705. });
  4706. }
  4707. return result;
  4708. };
  4709. }
  4710. /**
  4711. * Creates a function that, when called, either curries or invokes `func`
  4712. * with an optional `this` binding and partially applied arguments.
  4713. *
  4714. * @private
  4715. * @param {Function|string} func The function or method name to reference.
  4716. * @param {number} bitmask The bitmask of method flags to compose.
  4717. * The bitmask may be composed of the following flags:
  4718. * 1 - `_.bind`
  4719. * 2 - `_.bindKey`
  4720. * 4 - `_.curry`
  4721. * 8 - `_.curry` (bound)
  4722. * 16 - `_.partial`
  4723. * 32 - `_.partialRight`
  4724. * @param {Array} [partialArgs] An array of arguments to prepend to those
  4725. * provided to the new function.
  4726. * @param {Array} [partialRightArgs] An array of arguments to append to those
  4727. * provided to the new function.
  4728. * @param {*} [thisArg] The `this` binding of `func`.
  4729. * @param {number} [arity] The arity of `func`.
  4730. * @returns {Function} Returns the new function.
  4731. */
  4732. function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) {
  4733. var isBind = bitmask & 1,
  4734. isBindKey = bitmask & 2,
  4735. isCurry = bitmask & 4,
  4736. isCurryBound = bitmask & 8,
  4737. isPartial = bitmask & 16,
  4738. isPartialRight = bitmask & 32;
  4739. if (!isBindKey && !isFunction(func)) {
  4740. throw new TypeError;
  4741. }
  4742. if (isPartial && !partialArgs.length) {
  4743. bitmask &= ~16;
  4744. isPartial = partialArgs = false;
  4745. }
  4746. if (isPartialRight && !partialRightArgs.length) {
  4747. bitmask &= ~32;
  4748. isPartialRight = partialRightArgs = false;
  4749. }
  4750. var bindData = func && func.__bindData__;
  4751. if (bindData && bindData !== true) {
  4752. // clone `bindData`
  4753. bindData = slice(bindData);
  4754. if (bindData[2]) {
  4755. bindData[2] = slice(bindData[2]);
  4756. }
  4757. if (bindData[3]) {
  4758. bindData[3] = slice(bindData[3]);
  4759. }
  4760. // set `thisBinding` is not previously bound
  4761. if (isBind && !(bindData[1] & 1)) {
  4762. bindData[4] = thisArg;
  4763. }
  4764. // set if previously bound but not currently (subsequent curried functions)
  4765. if (!isBind && bindData[1] & 1) {
  4766. bitmask |= 8;
  4767. }
  4768. // set curried arity if not yet set
  4769. if (isCurry && !(bindData[1] & 4)) {
  4770. bindData[5] = arity;
  4771. }
  4772. // append partial left arguments
  4773. if (isPartial) {
  4774. push.apply(bindData[2] || (bindData[2] = []), partialArgs);
  4775. }
  4776. // append partial right arguments
  4777. if (isPartialRight) {
  4778. unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs);
  4779. }
  4780. // merge flags
  4781. bindData[1] |= bitmask;
  4782. return createWrapper.apply(null, bindData);
  4783. }
  4784. // fast path for `_.bind`
  4785. var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper;
  4786. return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]);
  4787. }
  4788. /**
  4789. * Used by `escape` to convert characters to HTML entities.
  4790. *
  4791. * @private
  4792. * @param {string} match The matched character to escape.
  4793. * @returns {string} Returns the escaped character.
  4794. */
  4795. function escapeHtmlChar(match) {
  4796. return htmlEscapes[match];
  4797. }
  4798. /**
  4799. * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
  4800. * customized, this method returns the custom method, otherwise it returns
  4801. * the `baseIndexOf` function.
  4802. *
  4803. * @private
  4804. * @returns {Function} Returns the "indexOf" function.
  4805. */
  4806. function getIndexOf() {
  4807. var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result;
  4808. return result;
  4809. }
  4810. /**
  4811. * Checks if `value` is a native function.
  4812. *
  4813. * @private
  4814. * @param {*} value The value to check.
  4815. * @returns {boolean} Returns `true` if the `value` is a native function, else `false`.
  4816. */
  4817. function isNative(value) {
  4818. return typeof value == 'function' && reNative.test(value);
  4819. }
  4820. /**
  4821. * Sets `this` binding data on a given function.
  4822. *
  4823. * @private
  4824. * @param {Function} func The function to set data on.
  4825. * @param {Array} value The data array to set.
  4826. */
  4827. var setBindData = !defineProperty ? noop : function(func, value) {
  4828. descriptor.value = value;
  4829. defineProperty(func, '__bindData__', descriptor);
  4830. };
  4831. /**
  4832. * A fallback implementation of `isPlainObject` which checks if a given value
  4833. * is an object created by the `Object` constructor, assuming objects created
  4834. * by the `Object` constructor have no inherited enumerable properties and that
  4835. * there are no `Object.prototype` extensions.
  4836. *
  4837. * @private
  4838. * @param {*} value The value to check.
  4839. * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
  4840. */
  4841. function shimIsPlainObject(value) {
  4842. var ctor,
  4843. result;
  4844. // avoid non Object objects, `arguments` objects, and DOM elements
  4845. if (!(value && toString.call(value) == objectClass) ||
  4846. (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor))) {
  4847. return false;
  4848. }
  4849. // In most environments an object's own properties are iterated before
  4850. // its inherited properties. If the last iterated property is an object's
  4851. // own property then there are no inherited enumerable properties.
  4852. forIn(value, function(value, key) {
  4853. result = key;
  4854. });
  4855. return typeof result == 'undefined' || hasOwnProperty.call(value, result);
  4856. }
  4857. /**
  4858. * Used by `unescape` to convert HTML entities to characters.
  4859. *
  4860. * @private
  4861. * @param {string} match The matched character to unescape.
  4862. * @returns {string} Returns the unescaped character.
  4863. */
  4864. function unescapeHtmlChar(match) {
  4865. return htmlUnescapes[match];
  4866. }
  4867. /*--------------------------------------------------------------------------*/
  4868. /**
  4869. * Checks if `value` is an `arguments` object.
  4870. *
  4871. * @static
  4872. * @memberOf _
  4873. * @category Objects
  4874. * @param {*} value The value to check.
  4875. * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`.
  4876. * @example
  4877. *
  4878. * (function() { return _.isArguments(arguments); })(1, 2, 3);
  4879. * // => true
  4880. *
  4881. * _.isArguments([1, 2, 3]);
  4882. * // => false
  4883. */
  4884. function isArguments(value) {
  4885. return value && typeof value == 'object' && typeof value.length == 'number' &&
  4886. toString.call(value) == argsClass || false;
  4887. }
  4888. /**
  4889. * Checks if `value` is an array.
  4890. *
  4891. * @static
  4892. * @memberOf _
  4893. * @type Function
  4894. * @category Objects
  4895. * @param {*} value The value to check.
  4896. * @returns {boolean} Returns `true` if the `value` is an array, else `false`.
  4897. * @example
  4898. *
  4899. * (function() { return _.isArray(arguments); })();
  4900. * // => false
  4901. *
  4902. * _.isArray([1, 2, 3]);
  4903. * // => true
  4904. */
  4905. var isArray = nativeIsArray || function(value) {
  4906. return value && typeof value == 'object' && typeof value.length == 'number' &&
  4907. toString.call(value) == arrayClass || false;
  4908. };
  4909. /**
  4910. * A fallback implementation of `Object.keys` which produces an array of the
  4911. * given object's own enumerable property names.
  4912. *
  4913. * @private
  4914. * @type Function
  4915. * @param {Object} object The object to inspect.
  4916. * @returns {Array} Returns an array of property names.
  4917. */
  4918. var shimKeys = function(object) {
  4919. var index, iterable = object, result = [];
  4920. if (!iterable) return result;
  4921. if (!(objectTypes[typeof object])) return result;
  4922. for (index in iterable) {
  4923. if (hasOwnProperty.call(iterable, index)) {
  4924. result.push(index);
  4925. }
  4926. }
  4927. return result
  4928. };
  4929. /**
  4930. * Creates an array composed of the own enumerable property names of an object.
  4931. *
  4932. * @static
  4933. * @memberOf _
  4934. * @category Objects
  4935. * @param {Object} object The object to inspect.
  4936. * @returns {Array} Returns an array of property names.
  4937. * @example
  4938. *
  4939. * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
  4940. * // => ['one', 'two', 'three'] (property order is not guaranteed across environments)
  4941. */
  4942. var keys = !nativeKeys ? shimKeys : function(object) {
  4943. if (!isObject(object)) {
  4944. return [];
  4945. }
  4946. return nativeKeys(object);
  4947. };
  4948. /**
  4949. * Used to convert characters to HTML entities:
  4950. *
  4951. * Though the `>` character is escaped for symmetry, characters like `>` and `/`
  4952. * don't require escaping in HTML and have no special meaning unless they're part
  4953. * of a tag or an unquoted attribute value.
  4954. * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
  4955. */
  4956. var htmlEscapes = {
  4957. '&': '&amp;',
  4958. '<': '&lt;',
  4959. '>': '&gt;',
  4960. '"': '&quot;',
  4961. "'": '&#39;'
  4962. };
  4963. /** Used to convert HTML entities to characters */
  4964. var htmlUnescapes = invert(htmlEscapes);
  4965. /** Used to match HTML entities and HTML characters */
  4966. var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'),
  4967. reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g');
  4968. /*--------------------------------------------------------------------------*/
  4969. /**
  4970. * Assigns own enumerable properties of source object(s) to the destination
  4971. * object. Subsequent sources will overwrite property assignments of previous
  4972. * sources. If a callback is provided it will be executed to produce the
  4973. * assigned values. The callback is bound to `thisArg` and invoked with two
  4974. * arguments; (objectValue, sourceValue).
  4975. *
  4976. * @static
  4977. * @memberOf _
  4978. * @type Function
  4979. * @alias extend
  4980. * @category Objects
  4981. * @param {Object} object The destination object.
  4982. * @param {...Object} [source] The source objects.
  4983. * @param {Function} [callback] The function to customize assigning values.
  4984. * @param {*} [thisArg] The `this` binding of `callback`.
  4985. * @returns {Object} Returns the destination object.
  4986. * @example
  4987. *
  4988. * _.assign({ 'name': 'fred' }, { 'employer': 'slate' });
  4989. * // => { 'name': 'fred', 'employer': 'slate' }
  4990. *
  4991. * var defaults = _.partialRight(_.assign, function(a, b) {
  4992. * return typeof a == 'undefined' ? b : a;
  4993. * });
  4994. *
  4995. * var object = { 'name': 'barney' };
  4996. * defaults(object, { 'name': 'fred', 'employer': 'slate' });
  4997. * // => { 'name': 'barney', 'employer': 'slate' }
  4998. */
  4999. var assign = function(object, source, guard) {
  5000. var index, iterable = object, result = iterable;
  5001. if (!iterable) return result;
  5002. var args = arguments,
  5003. argsIndex = 0,
  5004. argsLength = typeof guard == 'number' ? 2 : args.length;
  5005. if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {
  5006. var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);
  5007. } else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {
  5008. callback = args[--argsLength];
  5009. }
  5010. while (++argsIndex < argsLength) {
  5011. iterable = args[argsIndex];
  5012. if (iterable && objectTypes[typeof iterable]) {
  5013. var ownIndex = -1,
  5014. ownProps = objectTypes[typeof iterable] && keys(iterable),
  5015. length = ownProps ? ownProps.length : 0;
  5016. while (++ownIndex < length) {
  5017. index = ownProps[ownIndex];
  5018. result[index] = callback ? callback(result[index], iterable[index]) : iterable[index];
  5019. }
  5020. }
  5021. }
  5022. return result
  5023. };
  5024. /**
  5025. * Creates a clone of `value`. If `isDeep` is `true` nested objects will also
  5026. * be cloned, otherwise they will be assigned by reference. If a callback
  5027. * is provided it will be executed to produce the cloned values. If the
  5028. * callback returns `undefined` cloning will be handled by the method instead.
  5029. * The callback is bound to `thisArg` and invoked with one argument; (value).
  5030. *
  5031. * @static
  5032. * @memberOf _
  5033. * @category Objects
  5034. * @param {*} value The value to clone.
  5035. * @param {boolean} [isDeep=false] Specify a deep clone.
  5036. * @param {Function} [callback] The function to customize cloning values.
  5037. * @param {*} [thisArg] The `this` binding of `callback`.
  5038. * @returns {*} Returns the cloned value.
  5039. * @example
  5040. *
  5041. * var characters = [
  5042. * { 'name': 'barney', 'age': 36 },
  5043. * { 'name': 'fred', 'age': 40 }
  5044. * ];
  5045. *
  5046. * var shallow = _.clone(characters);
  5047. * shallow[0] === characters[0];
  5048. * // => true
  5049. *
  5050. * var deep = _.clone(characters, true);
  5051. * deep[0] === characters[0];
  5052. * // => false
  5053. *
  5054. * _.mixin({
  5055. * 'clone': _.partialRight(_.clone, function(value) {
  5056. * return _.isElement(value) ? value.cloneNode(false) : undefined;
  5057. * })
  5058. * });
  5059. *
  5060. * var clone = _.clone(document.body);
  5061. * clone.childNodes.length;
  5062. * // => 0
  5063. */
  5064. function clone(value, isDeep, callback, thisArg) {
  5065. // allows working with "Collections" methods without using their `index`
  5066. // and `collection` arguments for `isDeep` and `callback`
  5067. if (typeof isDeep != 'boolean' && isDeep != null) {
  5068. thisArg = callback;
  5069. callback = isDeep;
  5070. isDeep = false;
  5071. }
  5072. return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
  5073. }
  5074. /**
  5075. * Creates a deep clone of `value`. If a callback is provided it will be
  5076. * executed to produce the cloned values. If the callback returns `undefined`
  5077. * cloning will be handled by the method instead. The callback is bound to
  5078. * `thisArg` and invoked with one argument; (value).
  5079. *
  5080. * Note: This method is loosely based on the structured clone algorithm. Functions
  5081. * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
  5082. * objects created by constructors other than `Object` are cloned to plain `Object` objects.
  5083. * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm.
  5084. *
  5085. * @static
  5086. * @memberOf _
  5087. * @category Objects
  5088. * @param {*} value The value to deep clone.
  5089. * @param {Function} [callback] The function to customize cloning values.
  5090. * @param {*} [thisArg] The `this` binding of `callback`.
  5091. * @returns {*} Returns the deep cloned value.
  5092. * @example
  5093. *
  5094. * var characters = [
  5095. * { 'name': 'barney', 'age': 36 },
  5096. * { 'name': 'fred', 'age': 40 }
  5097. * ];
  5098. *
  5099. * var deep = _.cloneDeep(characters);
  5100. * deep[0] === characters[0];
  5101. * // => false
  5102. *
  5103. * var view = {
  5104. * 'label': 'docs',
  5105. * 'node': element
  5106. * };
  5107. *
  5108. * var clone = _.cloneDeep(view, function(value) {
  5109. * return _.isElement(value) ? value.cloneNode(true) : undefined;
  5110. * });
  5111. *
  5112. * clone.node == view.node;
  5113. * // => false
  5114. */
  5115. function cloneDeep(value, callback, thisArg) {
  5116. return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
  5117. }
  5118. /**
  5119. * Creates an object that inherits from the given `prototype` object. If a
  5120. * `properties` object is provided its own enumerable properties are assigned
  5121. * to the created object.
  5122. *
  5123. * @static
  5124. * @memberOf _
  5125. * @category Objects
  5126. * @param {Object} prototype The object to inherit from.
  5127. * @param {Object} [properties] The properties to assign to the object.
  5128. * @returns {Object} Returns the new object.
  5129. * @example
  5130. *
  5131. * function Shape() {
  5132. * this.x = 0;
  5133. * this.y = 0;
  5134. * }
  5135. *
  5136. * function Circle() {
  5137. * Shape.call(this);
  5138. * }
  5139. *
  5140. * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle });
  5141. *
  5142. * var circle = new Circle;
  5143. * circle instanceof Circle;
  5144. * // => true
  5145. *
  5146. * circle instanceof Shape;
  5147. * // => true
  5148. */
  5149. function create(prototype, properties) {
  5150. var result = baseCreate(prototype);
  5151. return properties ? assign(result, properties) : result;
  5152. }
  5153. /**
  5154. * Assigns own enumerable properties of source object(s) to the destination
  5155. * object for all destination properties that resolve to `undefined`. Once a
  5156. * property is set, additional defaults of the same property will be ignored.
  5157. *
  5158. * @static
  5159. * @memberOf _
  5160. * @type Function
  5161. * @category Objects
  5162. * @param {Object} object The destination object.
  5163. * @param {...Object} [source] The source objects.
  5164. * @param- {Object} [guard] Allows working with `_.reduce` without using its
  5165. * `key` and `object` arguments as sources.
  5166. * @returns {Object} Returns the destination object.
  5167. * @example
  5168. *
  5169. * var object = { 'name': 'barney' };
  5170. * _.defaults(object, { 'name': 'fred', 'employer': 'slate' });
  5171. * // => { 'name': 'barney', 'employer': 'slate' }
  5172. */
  5173. var defaults = function(object, source, guard) {
  5174. var index, iterable = object, result = iterable;
  5175. if (!iterable) return result;
  5176. var args = arguments,
  5177. argsIndex = 0,
  5178. argsLength = typeof guard == 'number' ? 2 : args.length;
  5179. while (++argsIndex < argsLength) {
  5180. iterable = args[argsIndex];
  5181. if (iterable && objectTypes[typeof iterable]) {
  5182. var ownIndex = -1,
  5183. ownProps = objectTypes[typeof iterable] && keys(iterable),
  5184. length = ownProps ? ownProps.length : 0;
  5185. while (++ownIndex < length) {
  5186. index = ownProps[ownIndex];
  5187. if (typeof result[index] == 'undefined') result[index] = iterable[index];
  5188. }
  5189. }
  5190. }
  5191. return result
  5192. };
  5193. /**
  5194. * This method is like `_.findIndex` except that it returns the key of the
  5195. * first element that passes the callback check, instead of the element itself.
  5196. *
  5197. * If a property name is provided for `callback` the created "_.pluck" style
  5198. * callback will return the property value of the given element.
  5199. *
  5200. * If an object is provided for `callback` the created "_.where" style callback
  5201. * will return `true` for elements that have the properties of the given object,
  5202. * else `false`.
  5203. *
  5204. * @static
  5205. * @memberOf _
  5206. * @category Objects
  5207. * @param {Object} object The object to search.
  5208. * @param {Function|Object|string} [callback=identity] The function called per
  5209. * iteration. If a property name or object is provided it will be used to
  5210. * create a "_.pluck" or "_.where" style callback, respectively.
  5211. * @param {*} [thisArg] The `this` binding of `callback`.
  5212. * @returns {string|undefined} Returns the key of the found element, else `undefined`.
  5213. * @example
  5214. *
  5215. * var characters = {
  5216. * 'barney': { 'age': 36, 'blocked': false },
  5217. * 'fred': { 'age': 40, 'blocked': true },
  5218. * 'pebbles': { 'age': 1, 'blocked': false }
  5219. * };
  5220. *
  5221. * _.findKey(characters, function(chr) {
  5222. * return chr.age < 40;
  5223. * });
  5224. * // => 'barney' (property order is not guaranteed across environments)
  5225. *
  5226. * // using "_.where" callback shorthand
  5227. * _.findKey(characters, { 'age': 1 });
  5228. * // => 'pebbles'
  5229. *
  5230. * // using "_.pluck" callback shorthand
  5231. * _.findKey(characters, 'blocked');
  5232. * // => 'fred'
  5233. */
  5234. function findKey(object, callback, thisArg) {
  5235. var result;
  5236. callback = lodash.createCallback(callback, thisArg, 3);
  5237. forOwn(object, function(value, key, object) {
  5238. if (callback(value, key, object)) {
  5239. result = key;
  5240. return false;
  5241. }
  5242. });
  5243. return result;
  5244. }
  5245. /**
  5246. * This method is like `_.findKey` except that it iterates over elements
  5247. * of a `collection` in the opposite order.
  5248. *
  5249. * If a property name is provided for `callback` the created "_.pluck" style
  5250. * callback will return the property value of the given element.
  5251. *
  5252. * If an object is provided for `callback` the created "_.where" style callback
  5253. * will return `true` for elements that have the properties of the given object,
  5254. * else `false`.
  5255. *
  5256. * @static
  5257. * @memberOf _
  5258. * @category Objects
  5259. * @param {Object} object The object to search.
  5260. * @param {Function|Object|string} [callback=identity] The function called per
  5261. * iteration. If a property name or object is provided it will be used to
  5262. * create a "_.pluck" or "_.where" style callback, respectively.
  5263. * @param {*} [thisArg] The `this` binding of `callback`.
  5264. * @returns {string|undefined} Returns the key of the found element, else `undefined`.
  5265. * @example
  5266. *
  5267. * var characters = {
  5268. * 'barney': { 'age': 36, 'blocked': true },
  5269. * 'fred': { 'age': 40, 'blocked': false },
  5270. * 'pebbles': { 'age': 1, 'blocked': true }
  5271. * };
  5272. *
  5273. * _.findLastKey(characters, function(chr) {
  5274. * return chr.age < 40;
  5275. * });
  5276. * // => returns `pebbles`, assuming `_.findKey` returns `barney`
  5277. *
  5278. * // using "_.where" callback shorthand
  5279. * _.findLastKey(characters, { 'age': 40 });
  5280. * // => 'fred'
  5281. *
  5282. * // using "_.pluck" callback shorthand
  5283. * _.findLastKey(characters, 'blocked');
  5284. * // => 'pebbles'
  5285. */
  5286. function findLastKey(object, callback, thisArg) {
  5287. var result;
  5288. callback = lodash.createCallback(callback, thisArg, 3);
  5289. forOwnRight(object, function(value, key, object) {
  5290. if (callback(value, key, object)) {
  5291. result = key;
  5292. return false;
  5293. }
  5294. });
  5295. return result;
  5296. }
  5297. /**
  5298. * Iterates over own and inherited enumerable properties of an object,
  5299. * executing the callback for each property. The callback is bound to `thisArg`
  5300. * and invoked with three arguments; (value, key, object). Callbacks may exit
  5301. * iteration early by explicitly returning `false`.
  5302. *
  5303. * @static
  5304. * @memberOf _
  5305. * @type Function
  5306. * @category Objects
  5307. * @param {Object} object The object to iterate over.
  5308. * @param {Function} [callback=identity] The function called per iteration.
  5309. * @param {*} [thisArg] The `this` binding of `callback`.
  5310. * @returns {Object} Returns `object`.
  5311. * @example
  5312. *
  5313. * function Shape() {
  5314. * this.x = 0;
  5315. * this.y = 0;
  5316. * }
  5317. *
  5318. * Shape.prototype.move = function(x, y) {
  5319. * this.x += x;
  5320. * this.y += y;
  5321. * };
  5322. *
  5323. * _.forIn(new Shape, function(value, key) {
  5324. * console.log(key);
  5325. * });
  5326. * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments)
  5327. */
  5328. var forIn = function(collection, callback, thisArg) {
  5329. var index, iterable = collection, result = iterable;
  5330. if (!iterable) return result;
  5331. if (!objectTypes[typeof iterable]) return result;
  5332. callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
  5333. for (index in iterable) {
  5334. if (callback(iterable[index], index, collection) === false) return result;
  5335. }
  5336. return result
  5337. };
  5338. /**
  5339. * This method is like `_.forIn` except that it iterates over elements
  5340. * of a `collection` in the opposite order.
  5341. *
  5342. * @static
  5343. * @memberOf _
  5344. * @category Objects
  5345. * @param {Object} object The object to iterate over.
  5346. * @param {Function} [callback=identity] The function called per iteration.
  5347. * @param {*} [thisArg] The `this` binding of `callback`.
  5348. * @returns {Object} Returns `object`.
  5349. * @example
  5350. *
  5351. * function Shape() {
  5352. * this.x = 0;
  5353. * this.y = 0;
  5354. * }
  5355. *
  5356. * Shape.prototype.move = function(x, y) {
  5357. * this.x += x;
  5358. * this.y += y;
  5359. * };
  5360. *
  5361. * _.forInRight(new Shape, function(value, key) {
  5362. * console.log(key);
  5363. * });
  5364. * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move'
  5365. */
  5366. function forInRight(object, callback, thisArg) {
  5367. var pairs = [];
  5368. forIn(object, function(value, key) {
  5369. pairs.push(key, value);
  5370. });
  5371. var length = pairs.length;
  5372. callback = baseCreateCallback(callback, thisArg, 3);
  5373. while (length--) {
  5374. if (callback(pairs[length--], pairs[length], object) === false) {
  5375. break;
  5376. }
  5377. }
  5378. return object;
  5379. }
  5380. /**
  5381. * Iterates over own enumerable properties of an object, executing the callback
  5382. * for each property. The callback is bound to `thisArg` and invoked with three
  5383. * arguments; (value, key, object). Callbacks may exit iteration early by
  5384. * explicitly returning `false`.
  5385. *
  5386. * @static
  5387. * @memberOf _
  5388. * @type Function
  5389. * @category Objects
  5390. * @param {Object} object The object to iterate over.
  5391. * @param {Function} [callback=identity] The function called per iteration.
  5392. * @param {*} [thisArg] The `this` binding of `callback`.
  5393. * @returns {Object} Returns `object`.
  5394. * @example
  5395. *
  5396. * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
  5397. * console.log(key);
  5398. * });
  5399. * // => logs '0', '1', and 'length' (property order is not guaranteed across environments)
  5400. */
  5401. var forOwn = function(collection, callback, thisArg) {
  5402. var index, iterable = collection, result = iterable;
  5403. if (!iterable) return result;
  5404. if (!objectTypes[typeof iterable]) return result;
  5405. callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
  5406. var ownIndex = -1,
  5407. ownProps = objectTypes[typeof iterable] && keys(iterable),
  5408. length = ownProps ? ownProps.length : 0;
  5409. while (++ownIndex < length) {
  5410. index = ownProps[ownIndex];
  5411. if (callback(iterable[index], index, collection) === false) return result;
  5412. }
  5413. return result
  5414. };
  5415. /**
  5416. * This method is like `_.forOwn` except that it iterates over elements
  5417. * of a `collection` in the opposite order.
  5418. *
  5419. * @static
  5420. * @memberOf _
  5421. * @category Objects
  5422. * @param {Object} object The object to iterate over.
  5423. * @param {Function} [callback=identity] The function called per iteration.
  5424. * @param {*} [thisArg] The `this` binding of `callback`.
  5425. * @returns {Object} Returns `object`.
  5426. * @example
  5427. *
  5428. * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
  5429. * console.log(key);
  5430. * });
  5431. * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length'
  5432. */
  5433. function forOwnRight(object, callback, thisArg) {
  5434. var props = keys(object),
  5435. length = props.length;
  5436. callback = baseCreateCallback(callback, thisArg, 3);
  5437. while (length--) {
  5438. var key = props[length];
  5439. if (callback(object[key], key, object) === false) {
  5440. break;
  5441. }
  5442. }
  5443. return object;
  5444. }
  5445. /**
  5446. * Creates a sorted array of property names of all enumerable properties,
  5447. * own and inherited, of `object` that have function values.
  5448. *
  5449. * @static
  5450. * @memberOf _
  5451. * @alias methods
  5452. * @category Objects
  5453. * @param {Object} object The object to inspect.
  5454. * @returns {Array} Returns an array of property names that have function values.
  5455. * @example
  5456. *
  5457. * _.functions(_);
  5458. * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
  5459. */
  5460. function functions(object) {
  5461. var result = [];
  5462. forIn(object, function(value, key) {
  5463. if (isFunction(value)) {
  5464. result.push(key);
  5465. }
  5466. });
  5467. return result.sort();
  5468. }
  5469. /**
  5470. * Checks if the specified property name exists as a direct property of `object`,
  5471. * instead of an inherited property.
  5472. *
  5473. * @static
  5474. * @memberOf _
  5475. * @category Objects
  5476. * @param {Object} object The object to inspect.
  5477. * @param {string} key The name of the property to check.
  5478. * @returns {boolean} Returns `true` if key is a direct property, else `false`.
  5479. * @example
  5480. *
  5481. * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
  5482. * // => true
  5483. */
  5484. function has(object, key) {
  5485. return object ? hasOwnProperty.call(object, key) : false;
  5486. }
  5487. /**
  5488. * Creates an object composed of the inverted keys and values of the given object.
  5489. *
  5490. * @static
  5491. * @memberOf _
  5492. * @category Objects
  5493. * @param {Object} object The object to invert.
  5494. * @returns {Object} Returns the created inverted object.
  5495. * @example
  5496. *
  5497. * _.invert({ 'first': 'fred', 'second': 'barney' });
  5498. * // => { 'fred': 'first', 'barney': 'second' }
  5499. */
  5500. function invert(object) {
  5501. var index = -1,
  5502. props = keys(object),
  5503. length = props.length,
  5504. result = {};
  5505. while (++index < length) {
  5506. var key = props[index];
  5507. result[object[key]] = key;
  5508. }
  5509. return result;
  5510. }
  5511. /**
  5512. * Checks if `value` is a boolean value.
  5513. *
  5514. * @static
  5515. * @memberOf _
  5516. * @category Objects
  5517. * @param {*} value The value to check.
  5518. * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`.
  5519. * @example
  5520. *
  5521. * _.isBoolean(null);
  5522. * // => false
  5523. */
  5524. function isBoolean(value) {
  5525. return value === true || value === false ||
  5526. value && typeof value == 'object' && toString.call(value) == boolClass || false;
  5527. }
  5528. /**
  5529. * Checks if `value` is a date.
  5530. *
  5531. * @static
  5532. * @memberOf _
  5533. * @category Objects
  5534. * @param {*} value The value to check.
  5535. * @returns {boolean} Returns `true` if the `value` is a date, else `false`.
  5536. * @example
  5537. *
  5538. * _.isDate(new Date);
  5539. * // => true
  5540. */
  5541. function isDate(value) {
  5542. return value && typeof value == 'object' && toString.call(value) == dateClass || false;
  5543. }
  5544. /**
  5545. * Checks if `value` is a DOM element.
  5546. *
  5547. * @static
  5548. * @memberOf _
  5549. * @category Objects
  5550. * @param {*} value The value to check.
  5551. * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`.
  5552. * @example
  5553. *
  5554. * _.isElement(document.body);
  5555. * // => true
  5556. */
  5557. function isElement(value) {
  5558. return value && value.nodeType === 1 || false;
  5559. }
  5560. /**
  5561. * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
  5562. * length of `0` and objects with no own enumerable properties are considered
  5563. * "empty".
  5564. *
  5565. * @static
  5566. * @memberOf _
  5567. * @category Objects
  5568. * @param {Array|Object|string} value The value to inspect.
  5569. * @returns {boolean} Returns `true` if the `value` is empty, else `false`.
  5570. * @example
  5571. *
  5572. * _.isEmpty([1, 2, 3]);
  5573. * // => false
  5574. *
  5575. * _.isEmpty({});
  5576. * // => true
  5577. *
  5578. * _.isEmpty('');
  5579. * // => true
  5580. */
  5581. function isEmpty(value) {
  5582. var result = true;
  5583. if (!value) {
  5584. return result;
  5585. }
  5586. var className = toString.call(value),
  5587. length = value.length;
  5588. if ((className == arrayClass || className == stringClass || className == argsClass ) ||
  5589. (className == objectClass && typeof length == 'number' && isFunction(value.splice))) {
  5590. return !length;
  5591. }
  5592. forOwn(value, function() {
  5593. return (result = false);
  5594. });
  5595. return result;
  5596. }
  5597. /**
  5598. * Performs a deep comparison between two values to determine if they are
  5599. * equivalent to each other. If a callback is provided it will be executed
  5600. * to compare values. If the callback returns `undefined` comparisons will
  5601. * be handled by the method instead. The callback is bound to `thisArg` and
  5602. * invoked with two arguments; (a, b).
  5603. *
  5604. * @static
  5605. * @memberOf _
  5606. * @category Objects
  5607. * @param {*} a The value to compare.
  5608. * @param {*} b The other value to compare.
  5609. * @param {Function} [callback] The function to customize comparing values.
  5610. * @param {*} [thisArg] The `this` binding of `callback`.
  5611. * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
  5612. * @example
  5613. *
  5614. * var object = { 'name': 'fred' };
  5615. * var copy = { 'name': 'fred' };
  5616. *
  5617. * object == copy;
  5618. * // => false
  5619. *
  5620. * _.isEqual(object, copy);
  5621. * // => true
  5622. *
  5623. * var words = ['hello', 'goodbye'];
  5624. * var otherWords = ['hi', 'goodbye'];
  5625. *
  5626. * _.isEqual(words, otherWords, function(a, b) {
  5627. * var reGreet = /^(?:hello|hi)$/i,
  5628. * aGreet = _.isString(a) && reGreet.test(a),
  5629. * bGreet = _.isString(b) && reGreet.test(b);
  5630. *
  5631. * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
  5632. * });
  5633. * // => true
  5634. */
  5635. function isEqual(a, b, callback, thisArg) {
  5636. return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2));
  5637. }
  5638. /**
  5639. * Checks if `value` is, or can be coerced to, a finite number.
  5640. *
  5641. * Note: This is not the same as native `isFinite` which will return true for
  5642. * booleans and empty strings. See http://es5.github.io/#x15.1.2.5.
  5643. *
  5644. * @static
  5645. * @memberOf _
  5646. * @category Objects
  5647. * @param {*} value The value to check.
  5648. * @returns {boolean} Returns `true` if the `value` is finite, else `false`.
  5649. * @example
  5650. *
  5651. * _.isFinite(-101);
  5652. * // => true
  5653. *
  5654. * _.isFinite('10');
  5655. * // => true
  5656. *
  5657. * _.isFinite(true);
  5658. * // => false
  5659. *
  5660. * _.isFinite('');
  5661. * // => false
  5662. *
  5663. * _.isFinite(Infinity);
  5664. * // => false
  5665. */
  5666. function isFinite(value) {
  5667. return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
  5668. }
  5669. /**
  5670. * Checks if `value` is a function.
  5671. *
  5672. * @static
  5673. * @memberOf _
  5674. * @category Objects
  5675. * @param {*} value The value to check.
  5676. * @returns {boolean} Returns `true` if the `value` is a function, else `false`.
  5677. * @example
  5678. *
  5679. * _.isFunction(_);
  5680. * // => true
  5681. */
  5682. function isFunction(value) {
  5683. return typeof value == 'function';
  5684. }
  5685. /**
  5686. * Checks if `value` is the language type of Object.
  5687. * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
  5688. *
  5689. * @static
  5690. * @memberOf _
  5691. * @category Objects
  5692. * @param {*} value The value to check.
  5693. * @returns {boolean} Returns `true` if the `value` is an object, else `false`.
  5694. * @example
  5695. *
  5696. * _.isObject({});
  5697. * // => true
  5698. *
  5699. * _.isObject([1, 2, 3]);
  5700. * // => true
  5701. *
  5702. * _.isObject(1);
  5703. * // => false
  5704. */
  5705. function isObject(value) {
  5706. // check if the value is the ECMAScript language type of Object
  5707. // http://es5.github.io/#x8
  5708. // and avoid a V8 bug
  5709. // http://code.google.com/p/v8/issues/detail?id=2291
  5710. return !!(value && objectTypes[typeof value]);
  5711. }
  5712. /**
  5713. * Checks if `value` is `NaN`.
  5714. *
  5715. * Note: This is not the same as native `isNaN` which will return `true` for
  5716. * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4.
  5717. *
  5718. * @static
  5719. * @memberOf _
  5720. * @category Objects
  5721. * @param {*} value The value to check.
  5722. * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`.
  5723. * @example
  5724. *
  5725. * _.isNaN(NaN);
  5726. * // => true
  5727. *
  5728. * _.isNaN(new Number(NaN));
  5729. * // => true
  5730. *
  5731. * isNaN(undefined);
  5732. * // => true
  5733. *
  5734. * _.isNaN(undefined);
  5735. * // => false
  5736. */
  5737. function isNaN(value) {
  5738. // `NaN` as a primitive is the only value that is not equal to itself
  5739. // (perform the [[Class]] check first to avoid errors with some host objects in IE)
  5740. return isNumber(value) && value != +value;
  5741. }
  5742. /**
  5743. * Checks if `value` is `null`.
  5744. *
  5745. * @static
  5746. * @memberOf _
  5747. * @category Objects
  5748. * @param {*} value The value to check.
  5749. * @returns {boolean} Returns `true` if the `value` is `null`, else `false`.
  5750. * @example
  5751. *
  5752. * _.isNull(null);
  5753. * // => true
  5754. *
  5755. * _.isNull(undefined);
  5756. * // => false
  5757. */
  5758. function isNull(value) {
  5759. return value === null;
  5760. }
  5761. /**
  5762. * Checks if `value` is a number.
  5763. *
  5764. * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5.
  5765. *
  5766. * @static
  5767. * @memberOf _
  5768. * @category Objects
  5769. * @param {*} value The value to check.
  5770. * @returns {boolean} Returns `true` if the `value` is a number, else `false`.
  5771. * @example
  5772. *
  5773. * _.isNumber(8.4 * 5);
  5774. * // => true
  5775. */
  5776. function isNumber(value) {
  5777. return typeof value == 'number' ||
  5778. value && typeof value == 'object' && toString.call(value) == numberClass || false;
  5779. }
  5780. /**
  5781. * Checks if `value` is an object created by the `Object` constructor.
  5782. *
  5783. * @static
  5784. * @memberOf _
  5785. * @category Objects
  5786. * @param {*} value The value to check.
  5787. * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
  5788. * @example
  5789. *
  5790. * function Shape() {
  5791. * this.x = 0;
  5792. * this.y = 0;
  5793. * }
  5794. *
  5795. * _.isPlainObject(new Shape);
  5796. * // => false
  5797. *
  5798. * _.isPlainObject([1, 2, 3]);
  5799. * // => false
  5800. *
  5801. * _.isPlainObject({ 'x': 0, 'y': 0 });
  5802. * // => true
  5803. */
  5804. var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) {
  5805. if (!(value && toString.call(value) == objectClass)) {
  5806. return false;
  5807. }
  5808. var valueOf = value.valueOf,
  5809. objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
  5810. return objProto
  5811. ? (value == objProto || getPrototypeOf(value) == objProto)
  5812. : shimIsPlainObject(value);
  5813. };
  5814. /**
  5815. * Checks if `value` is a regular expression.
  5816. *
  5817. * @static
  5818. * @memberOf _
  5819. * @category Objects
  5820. * @param {*} value The value to check.
  5821. * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`.
  5822. * @example
  5823. *
  5824. * _.isRegExp(/fred/);
  5825. * // => true
  5826. */
  5827. function isRegExp(value) {
  5828. return value && typeof value == 'object' && toString.call(value) == regexpClass || false;
  5829. }
  5830. /**
  5831. * Checks if `value` is a string.
  5832. *
  5833. * @static
  5834. * @memberOf _
  5835. * @category Objects
  5836. * @param {*} value The value to check.
  5837. * @returns {boolean} Returns `true` if the `value` is a string, else `false`.
  5838. * @example
  5839. *
  5840. * _.isString('fred');
  5841. * // => true
  5842. */
  5843. function isString(value) {
  5844. return typeof value == 'string' ||
  5845. value && typeof value == 'object' && toString.call(value) == stringClass || false;
  5846. }
  5847. /**
  5848. * Checks if `value` is `undefined`.
  5849. *
  5850. * @static
  5851. * @memberOf _
  5852. * @category Objects
  5853. * @param {*} value The value to check.
  5854. * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`.
  5855. * @example
  5856. *
  5857. * _.isUndefined(void 0);
  5858. * // => true
  5859. */
  5860. function isUndefined(value) {
  5861. return typeof value == 'undefined';
  5862. }
  5863. /**
  5864. * Creates an object with the same keys as `object` and values generated by
  5865. * running each own enumerable property of `object` through the callback.
  5866. * The callback is bound to `thisArg` and invoked with three arguments;
  5867. * (value, key, object).
  5868. *
  5869. * If a property name is provided for `callback` the created "_.pluck" style
  5870. * callback will return the property value of the given element.
  5871. *
  5872. * If an object is provided for `callback` the created "_.where" style callback
  5873. * will return `true` for elements that have the properties of the given object,
  5874. * else `false`.
  5875. *
  5876. * @static
  5877. * @memberOf _
  5878. * @category Objects
  5879. * @param {Object} object The object to iterate over.
  5880. * @param {Function|Object|string} [callback=identity] The function called
  5881. * per iteration. If a property name or object is provided it will be used
  5882. * to create a "_.pluck" or "_.where" style callback, respectively.
  5883. * @param {*} [thisArg] The `this` binding of `callback`.
  5884. * @returns {Array} Returns a new object with values of the results of each `callback` execution.
  5885. * @example
  5886. *
  5887. * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; });
  5888. * // => { 'a': 3, 'b': 6, 'c': 9 }
  5889. *
  5890. * var characters = {
  5891. * 'fred': { 'name': 'fred', 'age': 40 },
  5892. * 'pebbles': { 'name': 'pebbles', 'age': 1 }
  5893. * };
  5894. *
  5895. * // using "_.pluck" callback shorthand
  5896. * _.mapValues(characters, 'age');
  5897. * // => { 'fred': 40, 'pebbles': 1 }
  5898. */
  5899. function mapValues(object, callback, thisArg) {
  5900. var result = {};
  5901. callback = lodash.createCallback(callback, thisArg, 3);
  5902. forOwn(object, function(value, key, object) {
  5903. result[key] = callback(value, key, object);
  5904. });
  5905. return result;
  5906. }
  5907. /**
  5908. * Recursively merges own enumerable properties of the source object(s), that
  5909. * don't resolve to `undefined` into the destination object. Subsequent sources
  5910. * will overwrite property assignments of previous sources. If a callback is
  5911. * provided it will be executed to produce the merged values of the destination
  5912. * and source properties. If the callback returns `undefined` merging will
  5913. * be handled by the method instead. The callback is bound to `thisArg` and
  5914. * invoked with two arguments; (objectValue, sourceValue).
  5915. *
  5916. * @static
  5917. * @memberOf _
  5918. * @category Objects
  5919. * @param {Object} object The destination object.
  5920. * @param {...Object} [source] The source objects.
  5921. * @param {Function} [callback] The function to customize merging properties.
  5922. * @param {*} [thisArg] The `this` binding of `callback`.
  5923. * @returns {Object} Returns the destination object.
  5924. * @example
  5925. *
  5926. * var names = {
  5927. * 'characters': [
  5928. * { 'name': 'barney' },
  5929. * { 'name': 'fred' }
  5930. * ]
  5931. * };
  5932. *
  5933. * var ages = {
  5934. * 'characters': [
  5935. * { 'age': 36 },
  5936. * { 'age': 40 }
  5937. * ]
  5938. * };
  5939. *
  5940. * _.merge(names, ages);
  5941. * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] }
  5942. *
  5943. * var food = {
  5944. * 'fruits': ['apple'],
  5945. * 'vegetables': ['beet']
  5946. * };
  5947. *
  5948. * var otherFood = {
  5949. * 'fruits': ['banana'],
  5950. * 'vegetables': ['carrot']
  5951. * };
  5952. *
  5953. * _.merge(food, otherFood, function(a, b) {
  5954. * return _.isArray(a) ? a.concat(b) : undefined;
  5955. * });
  5956. * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] }
  5957. */
  5958. function merge(object) {
  5959. var args = arguments,
  5960. length = 2;
  5961. if (!isObject(object)) {
  5962. return object;
  5963. }
  5964. // allows working with `_.reduce` and `_.reduceRight` without using
  5965. // their `index` and `collection` arguments
  5966. if (typeof args[2] != 'number') {
  5967. length = args.length;
  5968. }
  5969. if (length > 3 && typeof args[length - 2] == 'function') {
  5970. var callback = baseCreateCallback(args[--length - 1], args[length--], 2);
  5971. } else if (length > 2 && typeof args[length - 1] == 'function') {
  5972. callback = args[--length];
  5973. }
  5974. var sources = slice(arguments, 1, length),
  5975. index = -1,
  5976. stackA = getArray(),
  5977. stackB = getArray();
  5978. while (++index < length) {
  5979. baseMerge(object, sources[index], callback, stackA, stackB);
  5980. }
  5981. releaseArray(stackA);
  5982. releaseArray(stackB);
  5983. return object;
  5984. }
  5985. /**
  5986. * Creates a shallow clone of `object` excluding the specified properties.
  5987. * Property names may be specified as individual arguments or as arrays of
  5988. * property names. If a callback is provided it will be executed for each
  5989. * property of `object` omitting the properties the callback returns truey
  5990. * for. The callback is bound to `thisArg` and invoked with three arguments;
  5991. * (value, key, object).
  5992. *
  5993. * @static
  5994. * @memberOf _
  5995. * @category Objects
  5996. * @param {Object} object The source object.
  5997. * @param {Function|...string|string[]} [callback] The properties to omit or the
  5998. * function called per iteration.
  5999. * @param {*} [thisArg] The `this` binding of `callback`.
  6000. * @returns {Object} Returns an object without the omitted properties.
  6001. * @example
  6002. *
  6003. * _.omit({ 'name': 'fred', 'age': 40 }, 'age');
  6004. * // => { 'name': 'fred' }
  6005. *
  6006. * _.omit({ 'name': 'fred', 'age': 40 }, function(value) {
  6007. * return typeof value == 'number';
  6008. * });
  6009. * // => { 'name': 'fred' }
  6010. */
  6011. function omit(object, callback, thisArg) {
  6012. var result = {};
  6013. if (typeof callback != 'function') {
  6014. var props = [];
  6015. forIn(object, function(value, key) {
  6016. props.push(key);
  6017. });
  6018. props = baseDifference(props, baseFlatten(arguments, true, false, 1));
  6019. var index = -1,
  6020. length = props.length;
  6021. while (++index < length) {
  6022. var key = props[index];
  6023. result[key] = object[key];
  6024. }
  6025. } else {
  6026. callback = lodash.createCallback(callback, thisArg, 3);
  6027. forIn(object, function(value, key, object) {
  6028. if (!callback(value, key, object)) {
  6029. result[key] = value;
  6030. }
  6031. });
  6032. }
  6033. return result;
  6034. }
  6035. /**
  6036. * Creates a two dimensional array of an object's key-value pairs,
  6037. * i.e. `[[key1, value1], [key2, value2]]`.
  6038. *
  6039. * @static
  6040. * @memberOf _
  6041. * @category Objects
  6042. * @param {Object} object The object to inspect.
  6043. * @returns {Array} Returns new array of key-value pairs.
  6044. * @example
  6045. *
  6046. * _.pairs({ 'barney': 36, 'fred': 40 });
  6047. * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments)
  6048. */
  6049. function pairs(object) {
  6050. var index = -1,
  6051. props = keys(object),
  6052. length = props.length,
  6053. result = Array(length);
  6054. while (++index < length) {
  6055. var key = props[index];
  6056. result[index] = [key, object[key]];
  6057. }
  6058. return result;
  6059. }
  6060. /**
  6061. * Creates a shallow clone of `object` composed of the specified properties.
  6062. * Property names may be specified as individual arguments or as arrays of
  6063. * property names. If a callback is provided it will be executed for each
  6064. * property of `object` picking the properties the callback returns truey
  6065. * for. The callback is bound to `thisArg` and invoked with three arguments;
  6066. * (value, key, object).
  6067. *
  6068. * @static
  6069. * @memberOf _
  6070. * @category Objects
  6071. * @param {Object} object The source object.
  6072. * @param {Function|...string|string[]} [callback] The function called per
  6073. * iteration or property names to pick, specified as individual property
  6074. * names or arrays of property names.
  6075. * @param {*} [thisArg] The `this` binding of `callback`.
  6076. * @returns {Object} Returns an object composed of the picked properties.
  6077. * @example
  6078. *
  6079. * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name');
  6080. * // => { 'name': 'fred' }
  6081. *
  6082. * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) {
  6083. * return key.charAt(0) != '_';
  6084. * });
  6085. * // => { 'name': 'fred' }
  6086. */
  6087. function pick(object, callback, thisArg) {
  6088. var result = {};
  6089. if (typeof callback != 'function') {
  6090. var index = -1,
  6091. props = baseFlatten(arguments, true, false, 1),
  6092. length = isObject(object) ? props.length : 0;
  6093. while (++index < length) {
  6094. var key = props[index];
  6095. if (key in object) {
  6096. result[key] = object[key];
  6097. }
  6098. }
  6099. } else {
  6100. callback = lodash.createCallback(callback, thisArg, 3);
  6101. forIn(object, function(value, key, object) {
  6102. if (callback(value, key, object)) {
  6103. result[key] = value;
  6104. }
  6105. });
  6106. }
  6107. return result;
  6108. }
  6109. /**
  6110. * An alternative to `_.reduce` this method transforms `object` to a new
  6111. * `accumulator` object which is the result of running each of its own
  6112. * enumerable properties through a callback, with each callback execution
  6113. * potentially mutating the `accumulator` object. The callback is bound to
  6114. * `thisArg` and invoked with four arguments; (accumulator, value, key, object).
  6115. * Callbacks may exit iteration early by explicitly returning `false`.
  6116. *
  6117. * @static
  6118. * @memberOf _
  6119. * @category Objects
  6120. * @param {Array|Object} object The object to iterate over.
  6121. * @param {Function} [callback=identity] The function called per iteration.
  6122. * @param {*} [accumulator] The custom accumulator value.
  6123. * @param {*} [thisArg] The `this` binding of `callback`.
  6124. * @returns {*} Returns the accumulated value.
  6125. * @example
  6126. *
  6127. * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) {
  6128. * num *= num;
  6129. * if (num % 2) {
  6130. * return result.push(num) < 3;
  6131. * }
  6132. * });
  6133. * // => [1, 9, 25]
  6134. *
  6135. * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
  6136. * result[key] = num * 3;
  6137. * });
  6138. * // => { 'a': 3, 'b': 6, 'c': 9 }
  6139. */
  6140. function transform(object, callback, accumulator, thisArg) {
  6141. var isArr = isArray(object);
  6142. if (accumulator == null) {
  6143. if (isArr) {
  6144. accumulator = [];
  6145. } else {
  6146. var ctor = object && object.constructor,
  6147. proto = ctor && ctor.prototype;
  6148. accumulator = baseCreate(proto);
  6149. }
  6150. }
  6151. if (callback) {
  6152. callback = lodash.createCallback(callback, thisArg, 4);
  6153. (isArr ? forEach : forOwn)(object, function(value, index, object) {
  6154. return callback(accumulator, value, index, object);
  6155. });
  6156. }
  6157. return accumulator;
  6158. }
  6159. /**
  6160. * Creates an array composed of the own enumerable property values of `object`.
  6161. *
  6162. * @static
  6163. * @memberOf _
  6164. * @category Objects
  6165. * @param {Object} object The object to inspect.
  6166. * @returns {Array} Returns an array of property values.
  6167. * @example
  6168. *
  6169. * _.values({ 'one': 1, 'two': 2, 'three': 3 });
  6170. * // => [1, 2, 3] (property order is not guaranteed across environments)
  6171. */
  6172. function values(object) {
  6173. var index = -1,
  6174. props = keys(object),
  6175. length = props.length,
  6176. result = Array(length);
  6177. while (++index < length) {
  6178. result[index] = object[props[index]];
  6179. }
  6180. return result;
  6181. }
  6182. /*--------------------------------------------------------------------------*/
  6183. /**
  6184. * Creates an array of elements from the specified indexes, or keys, of the
  6185. * `collection`. Indexes may be specified as individual arguments or as arrays
  6186. * of indexes.
  6187. *
  6188. * @static
  6189. * @memberOf _
  6190. * @category Collections
  6191. * @param {Array|Object|string} collection The collection to iterate over.
  6192. * @param {...(number|number[]|string|string[])} [index] The indexes of `collection`
  6193. * to retrieve, specified as individual indexes or arrays of indexes.
  6194. * @returns {Array} Returns a new array of elements corresponding to the
  6195. * provided indexes.
  6196. * @example
  6197. *
  6198. * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]);
  6199. * // => ['a', 'c', 'e']
  6200. *
  6201. * _.at(['fred', 'barney', 'pebbles'], 0, 2);
  6202. * // => ['fred', 'pebbles']
  6203. */
  6204. function at(collection) {
  6205. var args = arguments,
  6206. index = -1,
  6207. props = baseFlatten(args, true, false, 1),
  6208. length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length,
  6209. result = Array(length);
  6210. while(++index < length) {
  6211. result[index] = collection[props[index]];
  6212. }
  6213. return result;
  6214. }
  6215. /**
  6216. * Checks if a given value is present in a collection using strict equality
  6217. * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the
  6218. * offset from the end of the collection.
  6219. *
  6220. * @static
  6221. * @memberOf _
  6222. * @alias include
  6223. * @category Collections
  6224. * @param {Array|Object|string} collection The collection to iterate over.
  6225. * @param {*} target The value to check for.
  6226. * @param {number} [fromIndex=0] The index to search from.
  6227. * @returns {boolean} Returns `true` if the `target` element is found, else `false`.
  6228. * @example
  6229. *
  6230. * _.contains([1, 2, 3], 1);
  6231. * // => true
  6232. *
  6233. * _.contains([1, 2, 3], 1, 2);
  6234. * // => false
  6235. *
  6236. * _.contains({ 'name': 'fred', 'age': 40 }, 'fred');
  6237. * // => true
  6238. *
  6239. * _.contains('pebbles', 'eb');
  6240. * // => true
  6241. */
  6242. function contains(collection, target, fromIndex) {
  6243. var index = -1,
  6244. indexOf = getIndexOf(),
  6245. length = collection ? collection.length : 0,
  6246. result = false;
  6247. fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0;
  6248. if (isArray(collection)) {
  6249. result = indexOf(collection, target, fromIndex) > -1;
  6250. } else if (typeof length == 'number') {
  6251. result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1;
  6252. } else {
  6253. forOwn(collection, function(value) {
  6254. if (++index >= fromIndex) {
  6255. return !(result = value === target);
  6256. }
  6257. });
  6258. }
  6259. return result;
  6260. }
  6261. /**
  6262. * Creates an object composed of keys generated from the results of running
  6263. * each element of `collection` through the callback. The corresponding value
  6264. * of each key is the number of times the key was returned by the callback.
  6265. * The callback is bound to `thisArg` and invoked with three arguments;
  6266. * (value, index|key, collection).
  6267. *
  6268. * If a property name is provided for `callback` the created "_.pluck" style
  6269. * callback will return the property value of the given element.
  6270. *
  6271. * If an object is provided for `callback` the created "_.where" style callback
  6272. * will return `true` for elements that have the properties of the given object,
  6273. * else `false`.
  6274. *
  6275. * @static
  6276. * @memberOf _
  6277. * @category Collections
  6278. * @param {Array|Object|string} collection The collection to iterate over.
  6279. * @param {Function|Object|string} [callback=identity] The function called
  6280. * per iteration. If a property name or object is provided it will be used
  6281. * to create a "_.pluck" or "_.where" style callback, respectively.
  6282. * @param {*} [thisArg] The `this` binding of `callback`.
  6283. * @returns {Object} Returns the composed aggregate object.
  6284. * @example
  6285. *
  6286. * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); });
  6287. * // => { '4': 1, '6': 2 }
  6288. *
  6289. * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
  6290. * // => { '4': 1, '6': 2 }
  6291. *
  6292. * _.countBy(['one', 'two', 'three'], 'length');
  6293. * // => { '3': 2, '5': 1 }
  6294. */
  6295. var countBy = createAggregator(function(result, value, key) {
  6296. (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
  6297. });
  6298. /**
  6299. * Checks if the given callback returns truey value for **all** elements of
  6300. * a collection. The callback is bound to `thisArg` and invoked with three
  6301. * arguments; (value, index|key, collection).
  6302. *
  6303. * If a property name is provided for `callback` the created "_.pluck" style
  6304. * callback will return the property value of the given element.
  6305. *
  6306. * If an object is provided for `callback` the created "_.where" style callback
  6307. * will return `true` for elements that have the properties of the given object,
  6308. * else `false`.
  6309. *
  6310. * @static
  6311. * @memberOf _
  6312. * @alias all
  6313. * @category Collections
  6314. * @param {Array|Object|string} collection The collection to iterate over.
  6315. * @param {Function|Object|string} [callback=identity] The function called
  6316. * per iteration. If a property name or object is provided it will be used
  6317. * to create a "_.pluck" or "_.where" style callback, respectively.
  6318. * @param {*} [thisArg] The `this` binding of `callback`.
  6319. * @returns {boolean} Returns `true` if all elements passed the callback check,
  6320. * else `false`.
  6321. * @example
  6322. *
  6323. * _.every([true, 1, null, 'yes']);
  6324. * // => false
  6325. *
  6326. * var characters = [
  6327. * { 'name': 'barney', 'age': 36 },
  6328. * { 'name': 'fred', 'age': 40 }
  6329. * ];
  6330. *
  6331. * // using "_.pluck" callback shorthand
  6332. * _.every(characters, 'age');
  6333. * // => true
  6334. *
  6335. * // using "_.where" callback shorthand
  6336. * _.every(characters, { 'age': 36 });
  6337. * // => false
  6338. */
  6339. function every(collection, callback, thisArg) {
  6340. var result = true;
  6341. callback = lodash.createCallback(callback, thisArg, 3);
  6342. var index = -1,
  6343. length = collection ? collection.length : 0;
  6344. if (typeof length == 'number') {
  6345. while (++index < length) {
  6346. if (!(result = !!callback(collection[index], index, collection))) {
  6347. break;
  6348. }
  6349. }
  6350. } else {
  6351. forOwn(collection, function(value, index, collection) {
  6352. return (result = !!callback(value, index, collection));
  6353. });
  6354. }
  6355. return result;
  6356. }
  6357. /**
  6358. * Iterates over elements of a collection, returning an array of all elements
  6359. * the callback returns truey for. The callback is bound to `thisArg` and
  6360. * invoked with three arguments; (value, index|key, collection).
  6361. *
  6362. * If a property name is provided for `callback` the created "_.pluck" style
  6363. * callback will return the property value of the given element.
  6364. *
  6365. * If an object is provided for `callback` the created "_.where" style callback
  6366. * will return `true` for elements that have the properties of the given object,
  6367. * else `false`.
  6368. *
  6369. * @static
  6370. * @memberOf _
  6371. * @alias select
  6372. * @category Collections
  6373. * @param {Array|Object|string} collection The collection to iterate over.
  6374. * @param {Function|Object|string} [callback=identity] The function called
  6375. * per iteration. If a property name or object is provided it will be used
  6376. * to create a "_.pluck" or "_.where" style callback, respectively.
  6377. * @param {*} [thisArg] The `this` binding of `callback`.
  6378. * @returns {Array} Returns a new array of elements that passed the callback check.
  6379. * @example
  6380. *
  6381. * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
  6382. * // => [2, 4, 6]
  6383. *
  6384. * var characters = [
  6385. * { 'name': 'barney', 'age': 36, 'blocked': false },
  6386. * { 'name': 'fred', 'age': 40, 'blocked': true }
  6387. * ];
  6388. *
  6389. * // using "_.pluck" callback shorthand
  6390. * _.filter(characters, 'blocked');
  6391. * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
  6392. *
  6393. * // using "_.where" callback shorthand
  6394. * _.filter(characters, { 'age': 36 });
  6395. * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
  6396. */
  6397. function filter(collection, callback, thisArg) {
  6398. var result = [];
  6399. callback = lodash.createCallback(callback, thisArg, 3);
  6400. var index = -1,
  6401. length = collection ? collection.length : 0;
  6402. if (typeof length == 'number') {
  6403. while (++index < length) {
  6404. var value = collection[index];
  6405. if (callback(value, index, collection)) {
  6406. result.push(value);
  6407. }
  6408. }
  6409. } else {
  6410. forOwn(collection, function(value, index, collection) {
  6411. if (callback(value, index, collection)) {
  6412. result.push(value);
  6413. }
  6414. });
  6415. }
  6416. return result;
  6417. }
  6418. /**
  6419. * Iterates over elements of a collection, returning the first element that
  6420. * the callback returns truey for. The callback is bound to `thisArg` and
  6421. * invoked with three arguments; (value, index|key, collection).
  6422. *
  6423. * If a property name is provided for `callback` the created "_.pluck" style
  6424. * callback will return the property value of the given element.
  6425. *
  6426. * If an object is provided for `callback` the created "_.where" style callback
  6427. * will return `true` for elements that have the properties of the given object,
  6428. * else `false`.
  6429. *
  6430. * @static
  6431. * @memberOf _
  6432. * @alias detect, findWhere
  6433. * @category Collections
  6434. * @param {Array|Object|string} collection The collection to iterate over.
  6435. * @param {Function|Object|string} [callback=identity] The function called
  6436. * per iteration. If a property name or object is provided it will be used
  6437. * to create a "_.pluck" or "_.where" style callback, respectively.
  6438. * @param {*} [thisArg] The `this` binding of `callback`.
  6439. * @returns {*} Returns the found element, else `undefined`.
  6440. * @example
  6441. *
  6442. * var characters = [
  6443. * { 'name': 'barney', 'age': 36, 'blocked': false },
  6444. * { 'name': 'fred', 'age': 40, 'blocked': true },
  6445. * { 'name': 'pebbles', 'age': 1, 'blocked': false }
  6446. * ];
  6447. *
  6448. * _.find(characters, function(chr) {
  6449. * return chr.age < 40;
  6450. * });
  6451. * // => { 'name': 'barney', 'age': 36, 'blocked': false }
  6452. *
  6453. * // using "_.where" callback shorthand
  6454. * _.find(characters, { 'age': 1 });
  6455. * // => { 'name': 'pebbles', 'age': 1, 'blocked': false }
  6456. *
  6457. * // using "_.pluck" callback shorthand
  6458. * _.find(characters, 'blocked');
  6459. * // => { 'name': 'fred', 'age': 40, 'blocked': true }
  6460. */
  6461. function find(collection, callback, thisArg) {
  6462. callback = lodash.createCallback(callback, thisArg, 3);
  6463. var index = -1,
  6464. length = collection ? collection.length : 0;
  6465. if (typeof length == 'number') {
  6466. while (++index < length) {
  6467. var value = collection[index];
  6468. if (callback(value, index, collection)) {
  6469. return value;
  6470. }
  6471. }
  6472. } else {
  6473. var result;
  6474. forOwn(collection, function(value, index, collection) {
  6475. if (callback(value, index, collection)) {
  6476. result = value;
  6477. return false;
  6478. }
  6479. });
  6480. return result;
  6481. }
  6482. }
  6483. /**
  6484. * This method is like `_.find` except that it iterates over elements
  6485. * of a `collection` from right to left.
  6486. *
  6487. * @static
  6488. * @memberOf _
  6489. * @category Collections
  6490. * @param {Array|Object|string} collection The collection to iterate over.
  6491. * @param {Function|Object|string} [callback=identity] The function called
  6492. * per iteration. If a property name or object is provided it will be used
  6493. * to create a "_.pluck" or "_.where" style callback, respectively.
  6494. * @param {*} [thisArg] The `this` binding of `callback`.
  6495. * @returns {*} Returns the found element, else `undefined`.
  6496. * @example
  6497. *
  6498. * _.findLast([1, 2, 3, 4], function(num) {
  6499. * return num % 2 == 1;
  6500. * });
  6501. * // => 3
  6502. */
  6503. function findLast(collection, callback, thisArg) {
  6504. var result;
  6505. callback = lodash.createCallback(callback, thisArg, 3);
  6506. forEachRight(collection, function(value, index, collection) {
  6507. if (callback(value, index, collection)) {
  6508. result = value;
  6509. return false;
  6510. }
  6511. });
  6512. return result;
  6513. }
  6514. /**
  6515. * Iterates over elements of a collection, executing the callback for each
  6516. * element. The callback is bound to `thisArg` and invoked with three arguments;
  6517. * (value, index|key, collection). Callbacks may exit iteration early by
  6518. * explicitly returning `false`.
  6519. *
  6520. * Note: As with other "Collections" methods, objects with a `length` property
  6521. * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
  6522. * may be used for object iteration.
  6523. *
  6524. * @static
  6525. * @memberOf _
  6526. * @alias each
  6527. * @category Collections
  6528. * @param {Array|Object|string} collection The collection to iterate over.
  6529. * @param {Function} [callback=identity] The function called per iteration.
  6530. * @param {*} [thisArg] The `this` binding of `callback`.
  6531. * @returns {Array|Object|string} Returns `collection`.
  6532. * @example
  6533. *
  6534. * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(',');
  6535. * // => logs each number and returns '1,2,3'
  6536. *
  6537. * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); });
  6538. * // => logs each number and returns the object (property order is not guaranteed across environments)
  6539. */
  6540. function forEach(collection, callback, thisArg) {
  6541. var index = -1,
  6542. length = collection ? collection.length : 0;
  6543. callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
  6544. if (typeof length == 'number') {
  6545. while (++index < length) {
  6546. if (callback(collection[index], index, collection) === false) {
  6547. break;
  6548. }
  6549. }
  6550. } else {
  6551. forOwn(collection, callback);
  6552. }
  6553. return collection;
  6554. }
  6555. /**
  6556. * This method is like `_.forEach` except that it iterates over elements
  6557. * of a `collection` from right to left.
  6558. *
  6559. * @static
  6560. * @memberOf _
  6561. * @alias eachRight
  6562. * @category Collections
  6563. * @param {Array|Object|string} collection The collection to iterate over.
  6564. * @param {Function} [callback=identity] The function called per iteration.
  6565. * @param {*} [thisArg] The `this` binding of `callback`.
  6566. * @returns {Array|Object|string} Returns `collection`.
  6567. * @example
  6568. *
  6569. * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(',');
  6570. * // => logs each number from right to left and returns '3,2,1'
  6571. */
  6572. function forEachRight(collection, callback, thisArg) {
  6573. var length = collection ? collection.length : 0;
  6574. callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
  6575. if (typeof length == 'number') {
  6576. while (length--) {
  6577. if (callback(collection[length], length, collection) === false) {
  6578. break;
  6579. }
  6580. }
  6581. } else {
  6582. var props = keys(collection);
  6583. length = props.length;
  6584. forOwn(collection, function(value, key, collection) {
  6585. key = props ? props[--length] : --length;
  6586. return callback(collection[key], key, collection);
  6587. });
  6588. }
  6589. return collection;
  6590. }
  6591. /**
  6592. * Creates an object composed of keys generated from the results of running
  6593. * each element of a collection through the callback. The corresponding value
  6594. * of each key is an array of the elements responsible for generating the key.
  6595. * The callback is bound to `thisArg` and invoked with three arguments;
  6596. * (value, index|key, collection).
  6597. *
  6598. * If a property name is provided for `callback` the created "_.pluck" style
  6599. * callback will return the property value of the given element.
  6600. *
  6601. * If an object is provided for `callback` the created "_.where" style callback
  6602. * will return `true` for elements that have the properties of the given object,
  6603. * else `false`
  6604. *
  6605. * @static
  6606. * @memberOf _
  6607. * @category Collections
  6608. * @param {Array|Object|string} collection The collection to iterate over.
  6609. * @param {Function|Object|string} [callback=identity] The function called
  6610. * per iteration. If a property name or object is provided it will be used
  6611. * to create a "_.pluck" or "_.where" style callback, respectively.
  6612. * @param {*} [thisArg] The `this` binding of `callback`.
  6613. * @returns {Object} Returns the composed aggregate object.
  6614. * @example
  6615. *
  6616. * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); });
  6617. * // => { '4': [4.2], '6': [6.1, 6.4] }
  6618. *
  6619. * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
  6620. * // => { '4': [4.2], '6': [6.1, 6.4] }
  6621. *
  6622. * // using "_.pluck" callback shorthand
  6623. * _.groupBy(['one', 'two', 'three'], 'length');
  6624. * // => { '3': ['one', 'two'], '5': ['three'] }
  6625. */
  6626. var groupBy = createAggregator(function(result, value, key) {
  6627. (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value);
  6628. });
  6629. /**
  6630. * Creates an object composed of keys generated from the results of running
  6631. * each element of the collection through the given callback. The corresponding
  6632. * value of each key is the last element responsible for generating the key.
  6633. * The callback is bound to `thisArg` and invoked with three arguments;
  6634. * (value, index|key, collection).
  6635. *
  6636. * If a property name is provided for `callback` the created "_.pluck" style
  6637. * callback will return the property value of the given element.
  6638. *
  6639. * If an object is provided for `callback` the created "_.where" style callback
  6640. * will return `true` for elements that have the properties of the given object,
  6641. * else `false`.
  6642. *
  6643. * @static
  6644. * @memberOf _
  6645. * @category Collections
  6646. * @param {Array|Object|string} collection The collection to iterate over.
  6647. * @param {Function|Object|string} [callback=identity] The function called
  6648. * per iteration. If a property name or object is provided it will be used
  6649. * to create a "_.pluck" or "_.where" style callback, respectively.
  6650. * @param {*} [thisArg] The `this` binding of `callback`.
  6651. * @returns {Object} Returns the composed aggregate object.
  6652. * @example
  6653. *
  6654. * var keys = [
  6655. * { 'dir': 'left', 'code': 97 },
  6656. * { 'dir': 'right', 'code': 100 }
  6657. * ];
  6658. *
  6659. * _.indexBy(keys, 'dir');
  6660. * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
  6661. *
  6662. * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); });
  6663. * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
  6664. *
  6665. * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String);
  6666. * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
  6667. */
  6668. var indexBy = createAggregator(function(result, value, key) {
  6669. result[key] = value;
  6670. });
  6671. /**
  6672. * Invokes the method named by `methodName` on each element in the `collection`
  6673. * returning an array of the results of each invoked method. Additional arguments
  6674. * will be provided to each invoked method. If `methodName` is a function it
  6675. * will be invoked for, and `this` bound to, each element in the `collection`.
  6676. *
  6677. * @static
  6678. * @memberOf _
  6679. * @category Collections
  6680. * @param {Array|Object|string} collection The collection to iterate over.
  6681. * @param {Function|string} methodName The name of the method to invoke or
  6682. * the function invoked per iteration.
  6683. * @param {...*} [arg] Arguments to invoke the method with.
  6684. * @returns {Array} Returns a new array of the results of each invoked method.
  6685. * @example
  6686. *
  6687. * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
  6688. * // => [[1, 5, 7], [1, 2, 3]]
  6689. *
  6690. * _.invoke([123, 456], String.prototype.split, '');
  6691. * // => [['1', '2', '3'], ['4', '5', '6']]
  6692. */
  6693. function invoke(collection, methodName) {
  6694. var args = slice(arguments, 2),
  6695. index = -1,
  6696. isFunc = typeof methodName == 'function',
  6697. length = collection ? collection.length : 0,
  6698. result = Array(typeof length == 'number' ? length : 0);
  6699. forEach(collection, function(value) {
  6700. result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args);
  6701. });
  6702. return result;
  6703. }
  6704. /**
  6705. * Creates an array of values by running each element in the collection
  6706. * through the callback. The callback is bound to `thisArg` and invoked with
  6707. * three arguments; (value, index|key, collection).
  6708. *
  6709. * If a property name is provided for `callback` the created "_.pluck" style
  6710. * callback will return the property value of the given element.
  6711. *
  6712. * If an object is provided for `callback` the created "_.where" style callback
  6713. * will return `true` for elements that have the properties of the given object,
  6714. * else `false`.
  6715. *
  6716. * @static
  6717. * @memberOf _
  6718. * @alias collect
  6719. * @category Collections
  6720. * @param {Array|Object|string} collection The collection to iterate over.
  6721. * @param {Function|Object|string} [callback=identity] The function called
  6722. * per iteration. If a property name or object is provided it will be used
  6723. * to create a "_.pluck" or "_.where" style callback, respectively.
  6724. * @param {*} [thisArg] The `this` binding of `callback`.
  6725. * @returns {Array} Returns a new array of the results of each `callback` execution.
  6726. * @example
  6727. *
  6728. * _.map([1, 2, 3], function(num) { return num * 3; });
  6729. * // => [3, 6, 9]
  6730. *
  6731. * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
  6732. * // => [3, 6, 9] (property order is not guaranteed across environments)
  6733. *
  6734. * var characters = [
  6735. * { 'name': 'barney', 'age': 36 },
  6736. * { 'name': 'fred', 'age': 40 }
  6737. * ];
  6738. *
  6739. * // using "_.pluck" callback shorthand
  6740. * _.map(characters, 'name');
  6741. * // => ['barney', 'fred']
  6742. */
  6743. function map(collection, callback, thisArg) {
  6744. var index = -1,
  6745. length = collection ? collection.length : 0;
  6746. callback = lodash.createCallback(callback, thisArg, 3);
  6747. if (typeof length == 'number') {
  6748. var result = Array(length);
  6749. while (++index < length) {
  6750. result[index] = callback(collection[index], index, collection);
  6751. }
  6752. } else {
  6753. result = [];
  6754. forOwn(collection, function(value, key, collection) {
  6755. result[++index] = callback(value, key, collection);
  6756. });
  6757. }
  6758. return result;
  6759. }
  6760. /**
  6761. * Retrieves the maximum value of a collection. If the collection is empty or
  6762. * falsey `-Infinity` is returned. If a callback is provided it will be executed
  6763. * for each value in the collection to generate the criterion by which the value
  6764. * is ranked. The callback is bound to `thisArg` and invoked with three
  6765. * arguments; (value, index, collection).
  6766. *
  6767. * If a property name is provided for `callback` the created "_.pluck" style
  6768. * callback will return the property value of the given element.
  6769. *
  6770. * If an object is provided for `callback` the created "_.where" style callback
  6771. * will return `true` for elements that have the properties of the given object,
  6772. * else `false`.
  6773. *
  6774. * @static
  6775. * @memberOf _
  6776. * @category Collections
  6777. * @param {Array|Object|string} collection The collection to iterate over.
  6778. * @param {Function|Object|string} [callback=identity] The function called
  6779. * per iteration. If a property name or object is provided it will be used
  6780. * to create a "_.pluck" or "_.where" style callback, respectively.
  6781. * @param {*} [thisArg] The `this` binding of `callback`.
  6782. * @returns {*} Returns the maximum value.
  6783. * @example
  6784. *
  6785. * _.max([4, 2, 8, 6]);
  6786. * // => 8
  6787. *
  6788. * var characters = [
  6789. * { 'name': 'barney', 'age': 36 },
  6790. * { 'name': 'fred', 'age': 40 }
  6791. * ];
  6792. *
  6793. * _.max(characters, function(chr) { return chr.age; });
  6794. * // => { 'name': 'fred', 'age': 40 };
  6795. *
  6796. * // using "_.pluck" callback shorthand
  6797. * _.max(characters, 'age');
  6798. * // => { 'name': 'fred', 'age': 40 };
  6799. */
  6800. function max(collection, callback, thisArg) {
  6801. var computed = -Infinity,
  6802. result = computed;
  6803. // allows working with functions like `_.map` without using
  6804. // their `index` argument as a callback
  6805. if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
  6806. callback = null;
  6807. }
  6808. if (callback == null && isArray(collection)) {
  6809. var index = -1,
  6810. length = collection.length;
  6811. while (++index < length) {
  6812. var value = collection[index];
  6813. if (value > result) {
  6814. result = value;
  6815. }
  6816. }
  6817. } else {
  6818. callback = (callback == null && isString(collection))
  6819. ? charAtCallback
  6820. : lodash.createCallback(callback, thisArg, 3);
  6821. forEach(collection, function(value, index, collection) {
  6822. var current = callback(value, index, collection);
  6823. if (current > computed) {
  6824. computed = current;
  6825. result = value;
  6826. }
  6827. });
  6828. }
  6829. return result;
  6830. }
  6831. /**
  6832. * Retrieves the minimum value of a collection. If the collection is empty or
  6833. * falsey `Infinity` is returned. If a callback is provided it will be executed
  6834. * for each value in the collection to generate the criterion by which the value
  6835. * is ranked. The callback is bound to `thisArg` and invoked with three
  6836. * arguments; (value, index, collection).
  6837. *
  6838. * If a property name is provided for `callback` the created "_.pluck" style
  6839. * callback will return the property value of the given element.
  6840. *
  6841. * If an object is provided for `callback` the created "_.where" style callback
  6842. * will return `true` for elements that have the properties of the given object,
  6843. * else `false`.
  6844. *
  6845. * @static
  6846. * @memberOf _
  6847. * @category Collections
  6848. * @param {Array|Object|string} collection The collection to iterate over.
  6849. * @param {Function|Object|string} [callback=identity] The function called
  6850. * per iteration. If a property name or object is provided it will be used
  6851. * to create a "_.pluck" or "_.where" style callback, respectively.
  6852. * @param {*} [thisArg] The `this` binding of `callback`.
  6853. * @returns {*} Returns the minimum value.
  6854. * @example
  6855. *
  6856. * _.min([4, 2, 8, 6]);
  6857. * // => 2
  6858. *
  6859. * var characters = [
  6860. * { 'name': 'barney', 'age': 36 },
  6861. * { 'name': 'fred', 'age': 40 }
  6862. * ];
  6863. *
  6864. * _.min(characters, function(chr) { return chr.age; });
  6865. * // => { 'name': 'barney', 'age': 36 };
  6866. *
  6867. * // using "_.pluck" callback shorthand
  6868. * _.min(characters, 'age');
  6869. * // => { 'name': 'barney', 'age': 36 };
  6870. */
  6871. function min(collection, callback, thisArg) {
  6872. var computed = Infinity,
  6873. result = computed;
  6874. // allows working with functions like `_.map` without using
  6875. // their `index` argument as a callback
  6876. if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
  6877. callback = null;
  6878. }
  6879. if (callback == null && isArray(collection)) {
  6880. var index = -1,
  6881. length = collection.length;
  6882. while (++index < length) {
  6883. var value = collection[index];
  6884. if (value < result) {
  6885. result = value;
  6886. }
  6887. }
  6888. } else {
  6889. callback = (callback == null && isString(collection))
  6890. ? charAtCallback
  6891. : lodash.createCallback(callback, thisArg, 3);
  6892. forEach(collection, function(value, index, collection) {
  6893. var current = callback(value, index, collection);
  6894. if (current < computed) {
  6895. computed = current;
  6896. result = value;
  6897. }
  6898. });
  6899. }
  6900. return result;
  6901. }
  6902. /**
  6903. * Retrieves the value of a specified property from all elements in the collection.
  6904. *
  6905. * @static
  6906. * @memberOf _
  6907. * @type Function
  6908. * @category Collections
  6909. * @param {Array|Object|string} collection The collection to iterate over.
  6910. * @param {string} property The name of the property to pluck.
  6911. * @returns {Array} Returns a new array of property values.
  6912. * @example
  6913. *
  6914. * var characters = [
  6915. * { 'name': 'barney', 'age': 36 },
  6916. * { 'name': 'fred', 'age': 40 }
  6917. * ];
  6918. *
  6919. * _.pluck(characters, 'name');
  6920. * // => ['barney', 'fred']
  6921. */
  6922. var pluck = map;
  6923. /**
  6924. * Reduces a collection to a value which is the accumulated result of running
  6925. * each element in the collection through the callback, where each successive
  6926. * callback execution consumes the return value of the previous execution. If
  6927. * `accumulator` is not provided the first element of the collection will be
  6928. * used as the initial `accumulator` value. The callback is bound to `thisArg`
  6929. * and invoked with four arguments; (accumulator, value, index|key, collection).
  6930. *
  6931. * @static
  6932. * @memberOf _
  6933. * @alias foldl, inject
  6934. * @category Collections
  6935. * @param {Array|Object|string} collection The collection to iterate over.
  6936. * @param {Function} [callback=identity] The function called per iteration.
  6937. * @param {*} [accumulator] Initial value of the accumulator.
  6938. * @param {*} [thisArg] The `this` binding of `callback`.
  6939. * @returns {*} Returns the accumulated value.
  6940. * @example
  6941. *
  6942. * var sum = _.reduce([1, 2, 3], function(sum, num) {
  6943. * return sum + num;
  6944. * });
  6945. * // => 6
  6946. *
  6947. * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
  6948. * result[key] = num * 3;
  6949. * return result;
  6950. * }, {});
  6951. * // => { 'a': 3, 'b': 6, 'c': 9 }
  6952. */
  6953. function reduce(collection, callback, accumulator, thisArg) {
  6954. if (!collection) return accumulator;
  6955. var noaccum = arguments.length < 3;
  6956. callback = lodash.createCallback(callback, thisArg, 4);
  6957. var index = -1,
  6958. length = collection.length;
  6959. if (typeof length == 'number') {
  6960. if (noaccum) {
  6961. accumulator = collection[++index];
  6962. }
  6963. while (++index < length) {
  6964. accumulator = callback(accumulator, collection[index], index, collection);
  6965. }
  6966. } else {
  6967. forOwn(collection, function(value, index, collection) {
  6968. accumulator = noaccum
  6969. ? (noaccum = false, value)
  6970. : callback(accumulator, value, index, collection)
  6971. });
  6972. }
  6973. return accumulator;
  6974. }
  6975. /**
  6976. * This method is like `_.reduce` except that it iterates over elements
  6977. * of a `collection` from right to left.
  6978. *
  6979. * @static
  6980. * @memberOf _
  6981. * @alias foldr
  6982. * @category Collections
  6983. * @param {Array|Object|string} collection The collection to iterate over.
  6984. * @param {Function} [callback=identity] The function called per iteration.
  6985. * @param {*} [accumulator] Initial value of the accumulator.
  6986. * @param {*} [thisArg] The `this` binding of `callback`.
  6987. * @returns {*} Returns the accumulated value.
  6988. * @example
  6989. *
  6990. * var list = [[0, 1], [2, 3], [4, 5]];
  6991. * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
  6992. * // => [4, 5, 2, 3, 0, 1]
  6993. */
  6994. function reduceRight(collection, callback, accumulator, thisArg) {
  6995. var noaccum = arguments.length < 3;
  6996. callback = lodash.createCallback(callback, thisArg, 4);
  6997. forEachRight(collection, function(value, index, collection) {
  6998. accumulator = noaccum
  6999. ? (noaccum = false, value)
  7000. : callback(accumulator, value, index, collection);
  7001. });
  7002. return accumulator;
  7003. }
  7004. /**
  7005. * The opposite of `_.filter` this method returns the elements of a
  7006. * collection that the callback does **not** return truey for.
  7007. *
  7008. * If a property name is provided for `callback` the created "_.pluck" style
  7009. * callback will return the property value of the given element.
  7010. *
  7011. * If an object is provided for `callback` the created "_.where" style callback
  7012. * will return `true` for elements that have the properties of the given object,
  7013. * else `false`.
  7014. *
  7015. * @static
  7016. * @memberOf _
  7017. * @category Collections
  7018. * @param {Array|Object|string} collection The collection to iterate over.
  7019. * @param {Function|Object|string} [callback=identity] The function called
  7020. * per iteration. If a property name or object is provided it will be used
  7021. * to create a "_.pluck" or "_.where" style callback, respectively.
  7022. * @param {*} [thisArg] The `this` binding of `callback`.
  7023. * @returns {Array} Returns a new array of elements that failed the callback check.
  7024. * @example
  7025. *
  7026. * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
  7027. * // => [1, 3, 5]
  7028. *
  7029. * var characters = [
  7030. * { 'name': 'barney', 'age': 36, 'blocked': false },
  7031. * { 'name': 'fred', 'age': 40, 'blocked': true }
  7032. * ];
  7033. *
  7034. * // using "_.pluck" callback shorthand
  7035. * _.reject(characters, 'blocked');
  7036. * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
  7037. *
  7038. * // using "_.where" callback shorthand
  7039. * _.reject(characters, { 'age': 36 });
  7040. * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
  7041. */
  7042. function reject(collection, callback, thisArg) {
  7043. callback = lodash.createCallback(callback, thisArg, 3);
  7044. return filter(collection, function(value, index, collection) {
  7045. return !callback(value, index, collection);
  7046. });
  7047. }
  7048. /**
  7049. * Retrieves a random element or `n` random elements from a collection.
  7050. *
  7051. * @static
  7052. * @memberOf _
  7053. * @category Collections
  7054. * @param {Array|Object|string} collection The collection to sample.
  7055. * @param {number} [n] The number of elements to sample.
  7056. * @param- {Object} [guard] Allows working with functions like `_.map`
  7057. * without using their `index` arguments as `n`.
  7058. * @returns {Array} Returns the random sample(s) of `collection`.
  7059. * @example
  7060. *
  7061. * _.sample([1, 2, 3, 4]);
  7062. * // => 2
  7063. *
  7064. * _.sample([1, 2, 3, 4], 2);
  7065. * // => [3, 1]
  7066. */
  7067. function sample(collection, n, guard) {
  7068. if (collection && typeof collection.length != 'number') {
  7069. collection = values(collection);
  7070. }
  7071. if (n == null || guard) {
  7072. return collection ? collection[baseRandom(0, collection.length - 1)] : undefined;
  7073. }
  7074. var result = shuffle(collection);
  7075. result.length = nativeMin(nativeMax(0, n), result.length);
  7076. return result;
  7077. }
  7078. /**
  7079. * Creates an array of shuffled values, using a version of the Fisher-Yates
  7080. * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle.
  7081. *
  7082. * @static
  7083. * @memberOf _
  7084. * @category Collections
  7085. * @param {Array|Object|string} collection The collection to shuffle.
  7086. * @returns {Array} Returns a new shuffled collection.
  7087. * @example
  7088. *
  7089. * _.shuffle([1, 2, 3, 4, 5, 6]);
  7090. * // => [4, 1, 6, 3, 5, 2]
  7091. */
  7092. function shuffle(collection) {
  7093. var index = -1,
  7094. length = collection ? collection.length : 0,
  7095. result = Array(typeof length == 'number' ? length : 0);
  7096. forEach(collection, function(value) {
  7097. var rand = baseRandom(0, ++index);
  7098. result[index] = result[rand];
  7099. result[rand] = value;
  7100. });
  7101. return result;
  7102. }
  7103. /**
  7104. * Gets the size of the `collection` by returning `collection.length` for arrays
  7105. * and array-like objects or the number of own enumerable properties for objects.
  7106. *
  7107. * @static
  7108. * @memberOf _
  7109. * @category Collections
  7110. * @param {Array|Object|string} collection The collection to inspect.
  7111. * @returns {number} Returns `collection.length` or number of own enumerable properties.
  7112. * @example
  7113. *
  7114. * _.size([1, 2]);
  7115. * // => 2
  7116. *
  7117. * _.size({ 'one': 1, 'two': 2, 'three': 3 });
  7118. * // => 3
  7119. *
  7120. * _.size('pebbles');
  7121. * // => 7
  7122. */
  7123. function size(collection) {
  7124. var length = collection ? collection.length : 0;
  7125. return typeof length == 'number' ? length : keys(collection).length;
  7126. }
  7127. /**
  7128. * Checks if the callback returns a truey value for **any** element of a
  7129. * collection. The function returns as soon as it finds a passing value and
  7130. * does not iterate over the entire collection. The callback is bound to
  7131. * `thisArg` and invoked with three arguments; (value, index|key, collection).
  7132. *
  7133. * If a property name is provided for `callback` the created "_.pluck" style
  7134. * callback will return the property value of the given element.
  7135. *
  7136. * If an object is provided for `callback` the created "_.where" style callback
  7137. * will return `true` for elements that have the properties of the given object,
  7138. * else `false`.
  7139. *
  7140. * @static
  7141. * @memberOf _
  7142. * @alias any
  7143. * @category Collections
  7144. * @param {Array|Object|string} collection The collection to iterate over.
  7145. * @param {Function|Object|string} [callback=identity] The function called
  7146. * per iteration. If a property name or object is provided it will be used
  7147. * to create a "_.pluck" or "_.where" style callback, respectively.
  7148. * @param {*} [thisArg] The `this` binding of `callback`.
  7149. * @returns {boolean} Returns `true` if any element passed the callback check,
  7150. * else `false`.
  7151. * @example
  7152. *
  7153. * _.some([null, 0, 'yes', false], Boolean);
  7154. * // => true
  7155. *
  7156. * var characters = [
  7157. * { 'name': 'barney', 'age': 36, 'blocked': false },
  7158. * { 'name': 'fred', 'age': 40, 'blocked': true }
  7159. * ];
  7160. *
  7161. * // using "_.pluck" callback shorthand
  7162. * _.some(characters, 'blocked');
  7163. * // => true
  7164. *
  7165. * // using "_.where" callback shorthand
  7166. * _.some(characters, { 'age': 1 });
  7167. * // => false
  7168. */
  7169. function some(collection, callback, thisArg) {
  7170. var result;
  7171. callback = lodash.createCallback(callback, thisArg, 3);
  7172. var index = -1,
  7173. length = collection ? collection.length : 0;
  7174. if (typeof length == 'number') {
  7175. while (++index < length) {
  7176. if ((result = callback(collection[index], index, collection))) {
  7177. break;
  7178. }
  7179. }
  7180. } else {
  7181. forOwn(collection, function(value, index, collection) {
  7182. return !(result = callback(value, index, collection));
  7183. });
  7184. }
  7185. return !!result;
  7186. }
  7187. /**
  7188. * Creates an array of elements, sorted in ascending order by the results of
  7189. * running each element in a collection through the callback. This method
  7190. * performs a stable sort, that is, it will preserve the original sort order
  7191. * of equal elements. The callback is bound to `thisArg` and invoked with
  7192. * three arguments; (value, index|key, collection).
  7193. *
  7194. * If a property name is provided for `callback` the created "_.pluck" style
  7195. * callback will return the property value of the given element.
  7196. *
  7197. * If an array of property names is provided for `callback` the collection
  7198. * will be sorted by each property value.
  7199. *
  7200. * If an object is provided for `callback` the created "_.where" style callback
  7201. * will return `true` for elements that have the properties of the given object,
  7202. * else `false`.
  7203. *
  7204. * @static
  7205. * @memberOf _
  7206. * @category Collections
  7207. * @param {Array|Object|string} collection The collection to iterate over.
  7208. * @param {Array|Function|Object|string} [callback=identity] The function called
  7209. * per iteration. If a property name or object is provided it will be used
  7210. * to create a "_.pluck" or "_.where" style callback, respectively.
  7211. * @param {*} [thisArg] The `this` binding of `callback`.
  7212. * @returns {Array} Returns a new array of sorted elements.
  7213. * @example
  7214. *
  7215. * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); });
  7216. * // => [3, 1, 2]
  7217. *
  7218. * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math);
  7219. * // => [3, 1, 2]
  7220. *
  7221. * var characters = [
  7222. * { 'name': 'barney', 'age': 36 },
  7223. * { 'name': 'fred', 'age': 40 },
  7224. * { 'name': 'barney', 'age': 26 },
  7225. * { 'name': 'fred', 'age': 30 }
  7226. * ];
  7227. *
  7228. * // using "_.pluck" callback shorthand
  7229. * _.map(_.sortBy(characters, 'age'), _.values);
  7230. * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]]
  7231. *
  7232. * // sorting by multiple properties
  7233. * _.map(_.sortBy(characters, ['name', 'age']), _.values);
  7234. * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]]
  7235. */
  7236. function sortBy(collection, callback, thisArg) {
  7237. var index = -1,
  7238. isArr = isArray(callback),
  7239. length = collection ? collection.length : 0,
  7240. result = Array(typeof length == 'number' ? length : 0);
  7241. if (!isArr) {
  7242. callback = lodash.createCallback(callback, thisArg, 3);
  7243. }
  7244. forEach(collection, function(value, key, collection) {
  7245. var object = result[++index] = getObject();
  7246. if (isArr) {
  7247. object.criteria = map(callback, function(key) { return value[key]; });
  7248. } else {
  7249. (object.criteria = getArray())[0] = callback(value, key, collection);
  7250. }
  7251. object.index = index;
  7252. object.value = value;
  7253. });
  7254. length = result.length;
  7255. result.sort(compareAscending);
  7256. while (length--) {
  7257. var object = result[length];
  7258. result[length] = object.value;
  7259. if (!isArr) {
  7260. releaseArray(object.criteria);
  7261. }
  7262. releaseObject(object);
  7263. }
  7264. return result;
  7265. }
  7266. /**
  7267. * Converts the `collection` to an array.
  7268. *
  7269. * @static
  7270. * @memberOf _
  7271. * @category Collections
  7272. * @param {Array|Object|string} collection The collection to convert.
  7273. * @returns {Array} Returns the new converted array.
  7274. * @example
  7275. *
  7276. * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
  7277. * // => [2, 3, 4]
  7278. */
  7279. function toArray(collection) {
  7280. if (collection && typeof collection.length == 'number') {
  7281. return slice(collection);
  7282. }
  7283. return values(collection);
  7284. }
  7285. /**
  7286. * Performs a deep comparison of each element in a `collection` to the given
  7287. * `properties` object, returning an array of all elements that have equivalent
  7288. * property values.
  7289. *
  7290. * @static
  7291. * @memberOf _
  7292. * @type Function
  7293. * @category Collections
  7294. * @param {Array|Object|string} collection The collection to iterate over.
  7295. * @param {Object} props The object of property values to filter by.
  7296. * @returns {Array} Returns a new array of elements that have the given properties.
  7297. * @example
  7298. *
  7299. * var characters = [
  7300. * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] },
  7301. * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }
  7302. * ];
  7303. *
  7304. * _.where(characters, { 'age': 36 });
  7305. * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }]
  7306. *
  7307. * _.where(characters, { 'pets': ['dino'] });
  7308. * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }]
  7309. */
  7310. var where = filter;
  7311. /*--------------------------------------------------------------------------*/
  7312. /**
  7313. * Creates an array with all falsey values removed. The values `false`, `null`,
  7314. * `0`, `""`, `undefined`, and `NaN` are all falsey.
  7315. *
  7316. * @static
  7317. * @memberOf _
  7318. * @category Arrays
  7319. * @param {Array} array The array to compact.
  7320. * @returns {Array} Returns a new array of filtered values.
  7321. * @example
  7322. *
  7323. * _.compact([0, 1, false, 2, '', 3]);
  7324. * // => [1, 2, 3]
  7325. */
  7326. function compact(array) {
  7327. var index = -1,
  7328. length = array ? array.length : 0,
  7329. result = [];
  7330. while (++index < length) {
  7331. var value = array[index];
  7332. if (value) {
  7333. result.push(value);
  7334. }
  7335. }
  7336. return result;
  7337. }
  7338. /**
  7339. * Creates an array excluding all values of the provided arrays using strict
  7340. * equality for comparisons, i.e. `===`.
  7341. *
  7342. * @static
  7343. * @memberOf _
  7344. * @category Arrays
  7345. * @param {Array} array The array to process.
  7346. * @param {...Array} [values] The arrays of values to exclude.
  7347. * @returns {Array} Returns a new array of filtered values.
  7348. * @example
  7349. *
  7350. * _.difference([1, 2, 3, 4, 5], [5, 2, 10]);
  7351. * // => [1, 3, 4]
  7352. */
  7353. function difference(array) {
  7354. return baseDifference(array, baseFlatten(arguments, true, true, 1));
  7355. }
  7356. /**
  7357. * This method is like `_.find` except that it returns the index of the first
  7358. * element that passes the callback check, instead of the element itself.
  7359. *
  7360. * If a property name is provided for `callback` the created "_.pluck" style
  7361. * callback will return the property value of the given element.
  7362. *
  7363. * If an object is provided for `callback` the created "_.where" style callback
  7364. * will return `true` for elements that have the properties of the given object,
  7365. * else `false`.
  7366. *
  7367. * @static
  7368. * @memberOf _
  7369. * @category Arrays
  7370. * @param {Array} array The array to search.
  7371. * @param {Function|Object|string} [callback=identity] The function called
  7372. * per iteration. If a property name or object is provided it will be used
  7373. * to create a "_.pluck" or "_.where" style callback, respectively.
  7374. * @param {*} [thisArg] The `this` binding of `callback`.
  7375. * @returns {number} Returns the index of the found element, else `-1`.
  7376. * @example
  7377. *
  7378. * var characters = [
  7379. * { 'name': 'barney', 'age': 36, 'blocked': false },
  7380. * { 'name': 'fred', 'age': 40, 'blocked': true },
  7381. * { 'name': 'pebbles', 'age': 1, 'blocked': false }
  7382. * ];
  7383. *
  7384. * _.findIndex(characters, function(chr) {
  7385. * return chr.age < 20;
  7386. * });
  7387. * // => 2
  7388. *
  7389. * // using "_.where" callback shorthand
  7390. * _.findIndex(characters, { 'age': 36 });
  7391. * // => 0
  7392. *
  7393. * // using "_.pluck" callback shorthand
  7394. * _.findIndex(characters, 'blocked');
  7395. * // => 1
  7396. */
  7397. function findIndex(array, callback, thisArg) {
  7398. var index = -1,
  7399. length = array ? array.length : 0;
  7400. callback = lodash.createCallback(callback, thisArg, 3);
  7401. while (++index < length) {
  7402. if (callback(array[index], index, array)) {
  7403. return index;
  7404. }
  7405. }
  7406. return -1;
  7407. }
  7408. /**
  7409. * This method is like `_.findIndex` except that it iterates over elements
  7410. * of a `collection` from right to left.
  7411. *
  7412. * If a property name is provided for `callback` the created "_.pluck" style
  7413. * callback will return the property value of the given element.
  7414. *
  7415. * If an object is provided for `callback` the created "_.where" style callback
  7416. * will return `true` for elements that have the properties of the given object,
  7417. * else `false`.
  7418. *
  7419. * @static
  7420. * @memberOf _
  7421. * @category Arrays
  7422. * @param {Array} array The array to search.
  7423. * @param {Function|Object|string} [callback=identity] The function called
  7424. * per iteration. If a property name or object is provided it will be used
  7425. * to create a "_.pluck" or "_.where" style callback, respectively.
  7426. * @param {*} [thisArg] The `this` binding of `callback`.
  7427. * @returns {number} Returns the index of the found element, else `-1`.
  7428. * @example
  7429. *
  7430. * var characters = [
  7431. * { 'name': 'barney', 'age': 36, 'blocked': true },
  7432. * { 'name': 'fred', 'age': 40, 'blocked': false },
  7433. * { 'name': 'pebbles', 'age': 1, 'blocked': true }
  7434. * ];
  7435. *
  7436. * _.findLastIndex(characters, function(chr) {
  7437. * return chr.age > 30;
  7438. * });
  7439. * // => 1
  7440. *
  7441. * // using "_.where" callback shorthand
  7442. * _.findLastIndex(characters, { 'age': 36 });
  7443. * // => 0
  7444. *
  7445. * // using "_.pluck" callback shorthand
  7446. * _.findLastIndex(characters, 'blocked');
  7447. * // => 2
  7448. */
  7449. function findLastIndex(array, callback, thisArg) {
  7450. var length = array ? array.length : 0;
  7451. callback = lodash.createCallback(callback, thisArg, 3);
  7452. while (length--) {
  7453. if (callback(array[length], length, array)) {
  7454. return length;
  7455. }
  7456. }
  7457. return -1;
  7458. }
  7459. /**
  7460. * Gets the first element or first `n` elements of an array. If a callback
  7461. * is provided elements at the beginning of the array are returned as long
  7462. * as the callback returns truey. The callback is bound to `thisArg` and
  7463. * invoked with three arguments; (value, index, array).
  7464. *
  7465. * If a property name is provided for `callback` the created "_.pluck" style
  7466. * callback will return the property value of the given element.
  7467. *
  7468. * If an object is provided for `callback` the created "_.where" style callback
  7469. * will return `true` for elements that have the properties of the given object,
  7470. * else `false`.
  7471. *
  7472. * @static
  7473. * @memberOf _
  7474. * @alias head, take
  7475. * @category Arrays
  7476. * @param {Array} array The array to query.
  7477. * @param {Function|Object|number|string} [callback] The function called
  7478. * per element or the number of elements to return. If a property name or
  7479. * object is provided it will be used to create a "_.pluck" or "_.where"
  7480. * style callback, respectively.
  7481. * @param {*} [thisArg] The `this` binding of `callback`.
  7482. * @returns {*} Returns the first element(s) of `array`.
  7483. * @example
  7484. *
  7485. * _.first([1, 2, 3]);
  7486. * // => 1
  7487. *
  7488. * _.first([1, 2, 3], 2);
  7489. * // => [1, 2]
  7490. *
  7491. * _.first([1, 2, 3], function(num) {
  7492. * return num < 3;
  7493. * });
  7494. * // => [1, 2]
  7495. *
  7496. * var characters = [
  7497. * { 'name': 'barney', 'blocked': true, 'employer': 'slate' },
  7498. * { 'name': 'fred', 'blocked': false, 'employer': 'slate' },
  7499. * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
  7500. * ];
  7501. *
  7502. * // using "_.pluck" callback shorthand
  7503. * _.first(characters, 'blocked');
  7504. * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }]
  7505. *
  7506. * // using "_.where" callback shorthand
  7507. * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name');
  7508. * // => ['barney', 'fred']
  7509. */
  7510. function first(array, callback, thisArg) {
  7511. var n = 0,
  7512. length = array ? array.length : 0;
  7513. if (typeof callback != 'number' && callback != null) {
  7514. var index = -1;
  7515. callback = lodash.createCallback(callback, thisArg, 3);
  7516. while (++index < length && callback(array[index], index, array)) {
  7517. n++;
  7518. }
  7519. } else {
  7520. n = callback;
  7521. if (n == null || thisArg) {
  7522. return array ? array[0] : undefined;
  7523. }
  7524. }
  7525. return slice(array, 0, nativeMin(nativeMax(0, n), length));
  7526. }
  7527. /**
  7528. * Flattens a nested array (the nesting can be to any depth). If `isShallow`
  7529. * is truey, the array will only be flattened a single level. If a callback
  7530. * is provided each element of the array is passed through the callback before
  7531. * flattening. The callback is bound to `thisArg` and invoked with three
  7532. * arguments; (value, index, array).
  7533. *
  7534. * If a property name is provided for `callback` the created "_.pluck" style
  7535. * callback will return the property value of the given element.
  7536. *
  7537. * If an object is provided for `callback` the created "_.where" style callback
  7538. * will return `true` for elements that have the properties of the given object,
  7539. * else `false`.
  7540. *
  7541. * @static
  7542. * @memberOf _
  7543. * @category Arrays
  7544. * @param {Array} array The array to flatten.
  7545. * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
  7546. * @param {Function|Object|string} [callback=identity] The function called
  7547. * per iteration. If a property name or object is provided it will be used
  7548. * to create a "_.pluck" or "_.where" style callback, respectively.
  7549. * @param {*} [thisArg] The `this` binding of `callback`.
  7550. * @returns {Array} Returns a new flattened array.
  7551. * @example
  7552. *
  7553. * _.flatten([1, [2], [3, [[4]]]]);
  7554. * // => [1, 2, 3, 4];
  7555. *
  7556. * _.flatten([1, [2], [3, [[4]]]], true);
  7557. * // => [1, 2, 3, [[4]]];
  7558. *
  7559. * var characters = [
  7560. * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] },
  7561. * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }
  7562. * ];
  7563. *
  7564. * // using "_.pluck" callback shorthand
  7565. * _.flatten(characters, 'pets');
  7566. * // => ['hoppy', 'baby puss', 'dino']
  7567. */
  7568. function flatten(array, isShallow, callback, thisArg) {
  7569. // juggle arguments
  7570. if (typeof isShallow != 'boolean' && isShallow != null) {
  7571. thisArg = callback;
  7572. callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow;
  7573. isShallow = false;
  7574. }
  7575. if (callback != null) {
  7576. array = map(array, callback, thisArg);
  7577. }
  7578. return baseFlatten(array, isShallow);
  7579. }
  7580. /**
  7581. * Gets the index at which the first occurrence of `value` is found using
  7582. * strict equality for comparisons, i.e. `===`. If the array is already sorted
  7583. * providing `true` for `fromIndex` will run a faster binary search.
  7584. *
  7585. * @static
  7586. * @memberOf _
  7587. * @category Arrays
  7588. * @param {Array} array The array to search.
  7589. * @param {*} value The value to search for.
  7590. * @param {boolean|number} [fromIndex=0] The index to search from or `true`
  7591. * to perform a binary search on a sorted array.
  7592. * @returns {number} Returns the index of the matched value or `-1`.
  7593. * @example
  7594. *
  7595. * _.indexOf([1, 2, 3, 1, 2, 3], 2);
  7596. * // => 1
  7597. *
  7598. * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3);
  7599. * // => 4
  7600. *
  7601. * _.indexOf([1, 1, 2, 2, 3, 3], 2, true);
  7602. * // => 2
  7603. */
  7604. function indexOf(array, value, fromIndex) {
  7605. if (typeof fromIndex == 'number') {
  7606. var length = array ? array.length : 0;
  7607. fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0);
  7608. } else if (fromIndex) {
  7609. var index = sortedIndex(array, value);
  7610. return array[index] === value ? index : -1;
  7611. }
  7612. return baseIndexOf(array, value, fromIndex);
  7613. }
  7614. /**
  7615. * Gets all but the last element or last `n` elements of an array. If a
  7616. * callback is provided elements at the end of the array are excluded from
  7617. * the result as long as the callback returns truey. The callback is bound
  7618. * to `thisArg` and invoked with three arguments; (value, index, array).
  7619. *
  7620. * If a property name is provided for `callback` the created "_.pluck" style
  7621. * callback will return the property value of the given element.
  7622. *
  7623. * If an object is provided for `callback` the created "_.where" style callback
  7624. * will return `true` for elements that have the properties of the given object,
  7625. * else `false`.
  7626. *
  7627. * @static
  7628. * @memberOf _
  7629. * @category Arrays
  7630. * @param {Array} array The array to query.
  7631. * @param {Function|Object|number|string} [callback=1] The function called
  7632. * per element or the number of elements to exclude. If a property name or
  7633. * object is provided it will be used to create a "_.pluck" or "_.where"
  7634. * style callback, respectively.
  7635. * @param {*} [thisArg] The `this` binding of `callback`.
  7636. * @returns {Array} Returns a slice of `array`.
  7637. * @example
  7638. *
  7639. * _.initial([1, 2, 3]);
  7640. * // => [1, 2]
  7641. *
  7642. * _.initial([1, 2, 3], 2);
  7643. * // => [1]
  7644. *
  7645. * _.initial([1, 2, 3], function(num) {
  7646. * return num > 1;
  7647. * });
  7648. * // => [1]
  7649. *
  7650. * var characters = [
  7651. * { 'name': 'barney', 'blocked': false, 'employer': 'slate' },
  7652. * { 'name': 'fred', 'blocked': true, 'employer': 'slate' },
  7653. * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
  7654. * ];
  7655. *
  7656. * // using "_.pluck" callback shorthand
  7657. * _.initial(characters, 'blocked');
  7658. * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }]
  7659. *
  7660. * // using "_.where" callback shorthand
  7661. * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name');
  7662. * // => ['barney', 'fred']
  7663. */
  7664. function initial(array, callback, thisArg) {
  7665. var n = 0,
  7666. length = array ? array.length : 0;
  7667. if (typeof callback != 'number' && callback != null) {
  7668. var index = length;
  7669. callback = lodash.createCallback(callback, thisArg, 3);
  7670. while (index-- && callback(array[index], index, array)) {
  7671. n++;
  7672. }
  7673. } else {
  7674. n = (callback == null || thisArg) ? 1 : callback || n;
  7675. }
  7676. return slice(array, 0, nativeMin(nativeMax(0, length - n), length));
  7677. }
  7678. /**
  7679. * Creates an array of unique values present in all provided arrays using
  7680. * strict equality for comparisons, i.e. `===`.
  7681. *
  7682. * @static
  7683. * @memberOf _
  7684. * @category Arrays
  7685. * @param {...Array} [array] The arrays to inspect.
  7686. * @returns {Array} Returns an array of shared values.
  7687. * @example
  7688. *
  7689. * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]);
  7690. * // => [1, 2]
  7691. */
  7692. function intersection() {
  7693. var args = [],
  7694. argsIndex = -1,
  7695. argsLength = arguments.length,
  7696. caches = getArray(),
  7697. indexOf = getIndexOf(),
  7698. trustIndexOf = indexOf === baseIndexOf,
  7699. seen = getArray();
  7700. while (++argsIndex < argsLength) {
  7701. var value = arguments[argsIndex];
  7702. if (isArray(value) || isArguments(value)) {
  7703. args.push(value);
  7704. caches.push(trustIndexOf && value.length >= largeArraySize &&
  7705. createCache(argsIndex ? args[argsIndex] : seen));
  7706. }
  7707. }
  7708. var array = args[0],
  7709. index = -1,
  7710. length = array ? array.length : 0,
  7711. result = [];
  7712. outer:
  7713. while (++index < length) {
  7714. var cache = caches[0];
  7715. value = array[index];
  7716. if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) {
  7717. argsIndex = argsLength;
  7718. (cache || seen).push(value);
  7719. while (--argsIndex) {
  7720. cache = caches[argsIndex];
  7721. if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) {
  7722. continue outer;
  7723. }
  7724. }
  7725. result.push(value);
  7726. }
  7727. }
  7728. while (argsLength--) {
  7729. cache = caches[argsLength];
  7730. if (cache) {
  7731. releaseObject(cache);
  7732. }
  7733. }
  7734. releaseArray(caches);
  7735. releaseArray(seen);
  7736. return result;
  7737. }
  7738. /**
  7739. * Gets the last element or last `n` elements of an array. If a callback is
  7740. * provided elements at the end of the array are returned as long as the
  7741. * callback returns truey. The callback is bound to `thisArg` and invoked
  7742. * with three arguments; (value, index, array).
  7743. *
  7744. * If a property name is provided for `callback` the created "_.pluck" style
  7745. * callback will return the property value of the given element.
  7746. *
  7747. * If an object is provided for `callback` the created "_.where" style callback
  7748. * will return `true` for elements that have the properties of the given object,
  7749. * else `false`.
  7750. *
  7751. * @static
  7752. * @memberOf _
  7753. * @category Arrays
  7754. * @param {Array} array The array to query.
  7755. * @param {Function|Object|number|string} [callback] The function called
  7756. * per element or the number of elements to return. If a property name or
  7757. * object is provided it will be used to create a "_.pluck" or "_.where"
  7758. * style callback, respectively.
  7759. * @param {*} [thisArg] The `this` binding of `callback`.
  7760. * @returns {*} Returns the last element(s) of `array`.
  7761. * @example
  7762. *
  7763. * _.last([1, 2, 3]);
  7764. * // => 3
  7765. *
  7766. * _.last([1, 2, 3], 2);
  7767. * // => [2, 3]
  7768. *
  7769. * _.last([1, 2, 3], function(num) {
  7770. * return num > 1;
  7771. * });
  7772. * // => [2, 3]
  7773. *
  7774. * var characters = [
  7775. * { 'name': 'barney', 'blocked': false, 'employer': 'slate' },
  7776. * { 'name': 'fred', 'blocked': true, 'employer': 'slate' },
  7777. * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
  7778. * ];
  7779. *
  7780. * // using "_.pluck" callback shorthand
  7781. * _.pluck(_.last(characters, 'blocked'), 'name');
  7782. * // => ['fred', 'pebbles']
  7783. *
  7784. * // using "_.where" callback shorthand
  7785. * _.last(characters, { 'employer': 'na' });
  7786. * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
  7787. */
  7788. function last(array, callback, thisArg) {
  7789. var n = 0,
  7790. length = array ? array.length : 0;
  7791. if (typeof callback != 'number' && callback != null) {
  7792. var index = length;
  7793. callback = lodash.createCallback(callback, thisArg, 3);
  7794. while (index-- && callback(array[index], index, array)) {
  7795. n++;
  7796. }
  7797. } else {
  7798. n = callback;
  7799. if (n == null || thisArg) {
  7800. return array ? array[length - 1] : undefined;
  7801. }
  7802. }
  7803. return slice(array, nativeMax(0, length - n));
  7804. }
  7805. /**
  7806. * Gets the index at which the last occurrence of `value` is found using strict
  7807. * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
  7808. * as the offset from the end of the collection.
  7809. *
  7810. * If a property name is provided for `callback` the created "_.pluck" style
  7811. * callback will return the property value of the given element.
  7812. *
  7813. * If an object is provided for `callback` the created "_.where" style callback
  7814. * will return `true` for elements that have the properties of the given object,
  7815. * else `false`.
  7816. *
  7817. * @static
  7818. * @memberOf _
  7819. * @category Arrays
  7820. * @param {Array} array The array to search.
  7821. * @param {*} value The value to search for.
  7822. * @param {number} [fromIndex=array.length-1] The index to search from.
  7823. * @returns {number} Returns the index of the matched value or `-1`.
  7824. * @example
  7825. *
  7826. * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
  7827. * // => 4
  7828. *
  7829. * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3);
  7830. * // => 1
  7831. */
  7832. function lastIndexOf(array, value, fromIndex) {
  7833. var index = array ? array.length : 0;
  7834. if (typeof fromIndex == 'number') {
  7835. index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1;
  7836. }
  7837. while (index--) {
  7838. if (array[index] === value) {
  7839. return index;
  7840. }
  7841. }
  7842. return -1;
  7843. }
  7844. /**
  7845. * Removes all provided values from the given array using strict equality for
  7846. * comparisons, i.e. `===`.
  7847. *
  7848. * @static
  7849. * @memberOf _
  7850. * @category Arrays
  7851. * @param {Array} array The array to modify.
  7852. * @param {...*} [value] The values to remove.
  7853. * @returns {Array} Returns `array`.
  7854. * @example
  7855. *
  7856. * var array = [1, 2, 3, 1, 2, 3];
  7857. * _.pull(array, 2, 3);
  7858. * console.log(array);
  7859. * // => [1, 1]
  7860. */
  7861. function pull(array) {
  7862. var args = arguments,
  7863. argsIndex = 0,
  7864. argsLength = args.length,
  7865. length = array ? array.length : 0;
  7866. while (++argsIndex < argsLength) {
  7867. var index = -1,
  7868. value = args[argsIndex];
  7869. while (++index < length) {
  7870. if (array[index] === value) {
  7871. splice.call(array, index--, 1);
  7872. length--;
  7873. }
  7874. }
  7875. }
  7876. return array;
  7877. }
  7878. /**
  7879. * Creates an array of numbers (positive and/or negative) progressing from
  7880. * `start` up to but not including `end`. If `start` is less than `stop` a
  7881. * zero-length range is created unless a negative `step` is specified.
  7882. *
  7883. * @static
  7884. * @memberOf _
  7885. * @category Arrays
  7886. * @param {number} [start=0] The start of the range.
  7887. * @param {number} end The end of the range.
  7888. * @param {number} [step=1] The value to increment or decrement by.
  7889. * @returns {Array} Returns a new range array.
  7890. * @example
  7891. *
  7892. * _.range(4);
  7893. * // => [0, 1, 2, 3]
  7894. *
  7895. * _.range(1, 5);
  7896. * // => [1, 2, 3, 4]
  7897. *
  7898. * _.range(0, 20, 5);
  7899. * // => [0, 5, 10, 15]
  7900. *
  7901. * _.range(0, -4, -1);
  7902. * // => [0, -1, -2, -3]
  7903. *
  7904. * _.range(1, 4, 0);
  7905. * // => [1, 1, 1]
  7906. *
  7907. * _.range(0);
  7908. * // => []
  7909. */
  7910. function range(start, end, step) {
  7911. start = +start || 0;
  7912. step = typeof step == 'number' ? step : (+step || 1);
  7913. if (end == null) {
  7914. end = start;
  7915. start = 0;
  7916. }
  7917. // use `Array(length)` so engines like Chakra and V8 avoid slower modes
  7918. // http://youtu.be/XAqIpGU8ZZk#t=17m25s
  7919. var index = -1,
  7920. length = nativeMax(0, ceil((end - start) / (step || 1))),
  7921. result = Array(length);
  7922. while (++index < length) {
  7923. result[index] = start;
  7924. start += step;
  7925. }
  7926. return result;
  7927. }
  7928. /**
  7929. * Removes all elements from an array that the callback returns truey for
  7930. * and returns an array of removed elements. The callback is bound to `thisArg`
  7931. * and invoked with three arguments; (value, index, array).
  7932. *
  7933. * If a property name is provided for `callback` the created "_.pluck" style
  7934. * callback will return the property value of the given element.
  7935. *
  7936. * If an object is provided for `callback` the created "_.where" style callback
  7937. * will return `true` for elements that have the properties of the given object,
  7938. * else `false`.
  7939. *
  7940. * @static
  7941. * @memberOf _
  7942. * @category Arrays
  7943. * @param {Array} array The array to modify.
  7944. * @param {Function|Object|string} [callback=identity] The function called
  7945. * per iteration. If a property name or object is provided it will be used
  7946. * to create a "_.pluck" or "_.where" style callback, respectively.
  7947. * @param {*} [thisArg] The `this` binding of `callback`.
  7948. * @returns {Array} Returns a new array of removed elements.
  7949. * @example
  7950. *
  7951. * var array = [1, 2, 3, 4, 5, 6];
  7952. * var evens = _.remove(array, function(num) { return num % 2 == 0; });
  7953. *
  7954. * console.log(array);
  7955. * // => [1, 3, 5]
  7956. *
  7957. * console.log(evens);
  7958. * // => [2, 4, 6]
  7959. */
  7960. function remove(array, callback, thisArg) {
  7961. var index = -1,
  7962. length = array ? array.length : 0,
  7963. result = [];
  7964. callback = lodash.createCallback(callback, thisArg, 3);
  7965. while (++index < length) {
  7966. var value = array[index];
  7967. if (callback(value, index, array)) {
  7968. result.push(value);
  7969. splice.call(array, index--, 1);
  7970. length--;
  7971. }
  7972. }
  7973. return result;
  7974. }
  7975. /**
  7976. * The opposite of `_.initial` this method gets all but the first element or
  7977. * first `n` elements of an array. If a callback function is provided elements
  7978. * at the beginning of the array are excluded from the result as long as the
  7979. * callback returns truey. The callback is bound to `thisArg` and invoked
  7980. * with three arguments; (value, index, array).
  7981. *
  7982. * If a property name is provided for `callback` the created "_.pluck" style
  7983. * callback will return the property value of the given element.
  7984. *
  7985. * If an object is provided for `callback` the created "_.where" style callback
  7986. * will return `true` for elements that have the properties of the given object,
  7987. * else `false`.
  7988. *
  7989. * @static
  7990. * @memberOf _
  7991. * @alias drop, tail
  7992. * @category Arrays
  7993. * @param {Array} array The array to query.
  7994. * @param {Function|Object|number|string} [callback=1] The function called
  7995. * per element or the number of elements to exclude. If a property name or
  7996. * object is provided it will be used to create a "_.pluck" or "_.where"
  7997. * style callback, respectively.
  7998. * @param {*} [thisArg] The `this` binding of `callback`.
  7999. * @returns {Array} Returns a slice of `array`.
  8000. * @example
  8001. *
  8002. * _.rest([1, 2, 3]);
  8003. * // => [2, 3]
  8004. *
  8005. * _.rest([1, 2, 3], 2);
  8006. * // => [3]
  8007. *
  8008. * _.rest([1, 2, 3], function(num) {
  8009. * return num < 3;
  8010. * });
  8011. * // => [3]
  8012. *
  8013. * var characters = [
  8014. * { 'name': 'barney', 'blocked': true, 'employer': 'slate' },
  8015. * { 'name': 'fred', 'blocked': false, 'employer': 'slate' },
  8016. * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
  8017. * ];
  8018. *
  8019. * // using "_.pluck" callback shorthand
  8020. * _.pluck(_.rest(characters, 'blocked'), 'name');
  8021. * // => ['fred', 'pebbles']
  8022. *
  8023. * // using "_.where" callback shorthand
  8024. * _.rest(characters, { 'employer': 'slate' });
  8025. * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
  8026. */
  8027. function rest(array, callback, thisArg) {
  8028. if (typeof callback != 'number' && callback != null) {
  8029. var n = 0,
  8030. index = -1,
  8031. length = array ? array.length : 0;
  8032. callback = lodash.createCallback(callback, thisArg, 3);
  8033. while (++index < length && callback(array[index], index, array)) {
  8034. n++;
  8035. }
  8036. } else {
  8037. n = (callback == null || thisArg) ? 1 : nativeMax(0, callback);
  8038. }
  8039. return slice(array, n);
  8040. }
  8041. /**
  8042. * Uses a binary search to determine the smallest index at which a value
  8043. * should be inserted into a given sorted array in order to maintain the sort
  8044. * order of the array. If a callback is provided it will be executed for
  8045. * `value` and each element of `array` to compute their sort ranking. The
  8046. * callback is bound to `thisArg` and invoked with one argument; (value).
  8047. *
  8048. * If a property name is provided for `callback` the created "_.pluck" style
  8049. * callback will return the property value of the given element.
  8050. *
  8051. * If an object is provided for `callback` the created "_.where" style callback
  8052. * will return `true` for elements that have the properties of the given object,
  8053. * else `false`.
  8054. *
  8055. * @static
  8056. * @memberOf _
  8057. * @category Arrays
  8058. * @param {Array} array The array to inspect.
  8059. * @param {*} value The value to evaluate.
  8060. * @param {Function|Object|string} [callback=identity] The function called
  8061. * per iteration. If a property name or object is provided it will be used
  8062. * to create a "_.pluck" or "_.where" style callback, respectively.
  8063. * @param {*} [thisArg] The `this` binding of `callback`.
  8064. * @returns {number} Returns the index at which `value` should be inserted
  8065. * into `array`.
  8066. * @example
  8067. *
  8068. * _.sortedIndex([20, 30, 50], 40);
  8069. * // => 2
  8070. *
  8071. * // using "_.pluck" callback shorthand
  8072. * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
  8073. * // => 2
  8074. *
  8075. * var dict = {
  8076. * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 }
  8077. * };
  8078. *
  8079. * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
  8080. * return dict.wordToNumber[word];
  8081. * });
  8082. * // => 2
  8083. *
  8084. * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
  8085. * return this.wordToNumber[word];
  8086. * }, dict);
  8087. * // => 2
  8088. */
  8089. function sortedIndex(array, value, callback, thisArg) {
  8090. var low = 0,
  8091. high = array ? array.length : low;
  8092. // explicitly reference `identity` for better inlining in Firefox
  8093. callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity;
  8094. value = callback(value);
  8095. while (low < high) {
  8096. var mid = (low + high) >>> 1;
  8097. (callback(array[mid]) < value)
  8098. ? low = mid + 1
  8099. : high = mid;
  8100. }
  8101. return low;
  8102. }
  8103. /**
  8104. * Creates an array of unique values, in order, of the provided arrays using
  8105. * strict equality for comparisons, i.e. `===`.
  8106. *
  8107. * @static
  8108. * @memberOf _
  8109. * @category Arrays
  8110. * @param {...Array} [array] The arrays to inspect.
  8111. * @returns {Array} Returns an array of combined values.
  8112. * @example
  8113. *
  8114. * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]);
  8115. * // => [1, 2, 3, 5, 4]
  8116. */
  8117. function union() {
  8118. return baseUniq(baseFlatten(arguments, true, true));
  8119. }
  8120. /**
  8121. * Creates a duplicate-value-free version of an array using strict equality
  8122. * for comparisons, i.e. `===`. If the array is sorted, providing
  8123. * `true` for `isSorted` will use a faster algorithm. If a callback is provided
  8124. * each element of `array` is passed through the callback before uniqueness
  8125. * is computed. The callback is bound to `thisArg` and invoked with three
  8126. * arguments; (value, index, array).
  8127. *
  8128. * If a property name is provided for `callback` the created "_.pluck" style
  8129. * callback will return the property value of the given element.
  8130. *
  8131. * If an object is provided for `callback` the created "_.where" style callback
  8132. * will return `true` for elements that have the properties of the given object,
  8133. * else `false`.
  8134. *
  8135. * @static
  8136. * @memberOf _
  8137. * @alias unique
  8138. * @category Arrays
  8139. * @param {Array} array The array to process.
  8140. * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
  8141. * @param {Function|Object|string} [callback=identity] The function called
  8142. * per iteration. If a property name or object is provided it will be used
  8143. * to create a "_.pluck" or "_.where" style callback, respectively.
  8144. * @param {*} [thisArg] The `this` binding of `callback`.
  8145. * @returns {Array} Returns a duplicate-value-free array.
  8146. * @example
  8147. *
  8148. * _.uniq([1, 2, 1, 3, 1]);
  8149. * // => [1, 2, 3]
  8150. *
  8151. * _.uniq([1, 1, 2, 2, 3], true);
  8152. * // => [1, 2, 3]
  8153. *
  8154. * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); });
  8155. * // => ['A', 'b', 'C']
  8156. *
  8157. * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math);
  8158. * // => [1, 2.5, 3]
  8159. *
  8160. * // using "_.pluck" callback shorthand
  8161. * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
  8162. * // => [{ 'x': 1 }, { 'x': 2 }]
  8163. */
  8164. function uniq(array, isSorted, callback, thisArg) {
  8165. // juggle arguments
  8166. if (typeof isSorted != 'boolean' && isSorted != null) {
  8167. thisArg = callback;
  8168. callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted;
  8169. isSorted = false;
  8170. }
  8171. if (callback != null) {
  8172. callback = lodash.createCallback(callback, thisArg, 3);
  8173. }
  8174. return baseUniq(array, isSorted, callback);
  8175. }
  8176. /**
  8177. * Creates an array excluding all provided values using strict equality for
  8178. * comparisons, i.e. `===`.
  8179. *
  8180. * @static
  8181. * @memberOf _
  8182. * @category Arrays
  8183. * @param {Array} array The array to filter.
  8184. * @param {...*} [value] The values to exclude.
  8185. * @returns {Array} Returns a new array of filtered values.
  8186. * @example
  8187. *
  8188. * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
  8189. * // => [2, 3, 4]
  8190. */
  8191. function without(array) {
  8192. return baseDifference(array, slice(arguments, 1));
  8193. }
  8194. /**
  8195. * Creates an array that is the symmetric difference of the provided arrays.
  8196. * See http://en.wikipedia.org/wiki/Symmetric_difference.
  8197. *
  8198. * @static
  8199. * @memberOf _
  8200. * @category Arrays
  8201. * @param {...Array} [array] The arrays to inspect.
  8202. * @returns {Array} Returns an array of values.
  8203. * @example
  8204. *
  8205. * _.xor([1, 2, 3], [5, 2, 1, 4]);
  8206. * // => [3, 5, 4]
  8207. *
  8208. * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]);
  8209. * // => [1, 4, 5]
  8210. */
  8211. function xor() {
  8212. var index = -1,
  8213. length = arguments.length;
  8214. while (++index < length) {
  8215. var array = arguments[index];
  8216. if (isArray(array) || isArguments(array)) {
  8217. var result = result
  8218. ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result)))
  8219. : array;
  8220. }
  8221. }
  8222. return result || [];
  8223. }
  8224. /**
  8225. * Creates an array of grouped elements, the first of which contains the first
  8226. * elements of the given arrays, the second of which contains the second
  8227. * elements of the given arrays, and so on.
  8228. *
  8229. * @static
  8230. * @memberOf _
  8231. * @alias unzip
  8232. * @category Arrays
  8233. * @param {...Array} [array] Arrays to process.
  8234. * @returns {Array} Returns a new array of grouped elements.
  8235. * @example
  8236. *
  8237. * _.zip(['fred', 'barney'], [30, 40], [true, false]);
  8238. * // => [['fred', 30, true], ['barney', 40, false]]
  8239. */
  8240. function zip() {
  8241. var array = arguments.length > 1 ? arguments : arguments[0],
  8242. index = -1,
  8243. length = array ? max(pluck(array, 'length')) : 0,
  8244. result = Array(length < 0 ? 0 : length);
  8245. while (++index < length) {
  8246. result[index] = pluck(array, index);
  8247. }
  8248. return result;
  8249. }
  8250. /**
  8251. * Creates an object composed from arrays of `keys` and `values`. Provide
  8252. * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`
  8253. * or two arrays, one of `keys` and one of corresponding `values`.
  8254. *
  8255. * @static
  8256. * @memberOf _
  8257. * @alias object
  8258. * @category Arrays
  8259. * @param {Array} keys The array of keys.
  8260. * @param {Array} [values=[]] The array of values.
  8261. * @returns {Object} Returns an object composed of the given keys and
  8262. * corresponding values.
  8263. * @example
  8264. *
  8265. * _.zipObject(['fred', 'barney'], [30, 40]);
  8266. * // => { 'fred': 30, 'barney': 40 }
  8267. */
  8268. function zipObject(keys, values) {
  8269. var index = -1,
  8270. length = keys ? keys.length : 0,
  8271. result = {};
  8272. if (!values && length && !isArray(keys[0])) {
  8273. values = [];
  8274. }
  8275. while (++index < length) {
  8276. var key = keys[index];
  8277. if (values) {
  8278. result[key] = values[index];
  8279. } else if (key) {
  8280. result[key[0]] = key[1];
  8281. }
  8282. }
  8283. return result;
  8284. }
  8285. /*--------------------------------------------------------------------------*/
  8286. /**
  8287. * Creates a function that executes `func`, with the `this` binding and
  8288. * arguments of the created function, only after being called `n` times.
  8289. *
  8290. * @static
  8291. * @memberOf _
  8292. * @category Functions
  8293. * @param {number} n The number of times the function must be called before
  8294. * `func` is executed.
  8295. * @param {Function} func The function to restrict.
  8296. * @returns {Function} Returns the new restricted function.
  8297. * @example
  8298. *
  8299. * var saves = ['profile', 'settings'];
  8300. *
  8301. * var done = _.after(saves.length, function() {
  8302. * console.log('Done saving!');
  8303. * });
  8304. *
  8305. * _.forEach(saves, function(type) {
  8306. * asyncSave({ 'type': type, 'complete': done });
  8307. * });
  8308. * // => logs 'Done saving!', after all saves have completed
  8309. */
  8310. function after(n, func) {
  8311. if (!isFunction(func)) {
  8312. throw new TypeError;
  8313. }
  8314. return function() {
  8315. if (--n < 1) {
  8316. return func.apply(this, arguments);
  8317. }
  8318. };
  8319. }
  8320. /**
  8321. * Creates a function that, when called, invokes `func` with the `this`
  8322. * binding of `thisArg` and prepends any additional `bind` arguments to those
  8323. * provided to the bound function.
  8324. *
  8325. * @static
  8326. * @memberOf _
  8327. * @category Functions
  8328. * @param {Function} func The function to bind.
  8329. * @param {*} [thisArg] The `this` binding of `func`.
  8330. * @param {...*} [arg] Arguments to be partially applied.
  8331. * @returns {Function} Returns the new bound function.
  8332. * @example
  8333. *
  8334. * var func = function(greeting) {
  8335. * return greeting + ' ' + this.name;
  8336. * };
  8337. *
  8338. * func = _.bind(func, { 'name': 'fred' }, 'hi');
  8339. * func();
  8340. * // => 'hi fred'
  8341. */
  8342. function bind(func, thisArg) {
  8343. return arguments.length > 2
  8344. ? createWrapper(func, 17, slice(arguments, 2), null, thisArg)
  8345. : createWrapper(func, 1, null, null, thisArg);
  8346. }
  8347. /**
  8348. * Binds methods of an object to the object itself, overwriting the existing
  8349. * method. Method names may be specified as individual arguments or as arrays
  8350. * of method names. If no method names are provided all the function properties
  8351. * of `object` will be bound.
  8352. *
  8353. * @static
  8354. * @memberOf _
  8355. * @category Functions
  8356. * @param {Object} object The object to bind and assign the bound methods to.
  8357. * @param {...string} [methodName] The object method names to
  8358. * bind, specified as individual method names or arrays of method names.
  8359. * @returns {Object} Returns `object`.
  8360. * @example
  8361. *
  8362. * var view = {
  8363. * 'label': 'docs',
  8364. * 'onClick': function() { console.log('clicked ' + this.label); }
  8365. * };
  8366. *
  8367. * _.bindAll(view);
  8368. * jQuery('#docs').on('click', view.onClick);
  8369. * // => logs 'clicked docs', when the button is clicked
  8370. */
  8371. function bindAll(object) {
  8372. var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object),
  8373. index = -1,
  8374. length = funcs.length;
  8375. while (++index < length) {
  8376. var key = funcs[index];
  8377. object[key] = createWrapper(object[key], 1, null, null, object);
  8378. }
  8379. return object;
  8380. }
  8381. /**
  8382. * Creates a function that, when called, invokes the method at `object[key]`
  8383. * and prepends any additional `bindKey` arguments to those provided to the bound
  8384. * function. This method differs from `_.bind` by allowing bound functions to
  8385. * reference methods that will be redefined or don't yet exist.
  8386. * See http://michaux.ca/articles/lazy-function-definition-pattern.
  8387. *
  8388. * @static
  8389. * @memberOf _
  8390. * @category Functions
  8391. * @param {Object} object The object the method belongs to.
  8392. * @param {string} key The key of the method.
  8393. * @param {...*} [arg] Arguments to be partially applied.
  8394. * @returns {Function} Returns the new bound function.
  8395. * @example
  8396. *
  8397. * var object = {
  8398. * 'name': 'fred',
  8399. * 'greet': function(greeting) {
  8400. * return greeting + ' ' + this.name;
  8401. * }
  8402. * };
  8403. *
  8404. * var func = _.bindKey(object, 'greet', 'hi');
  8405. * func();
  8406. * // => 'hi fred'
  8407. *
  8408. * object.greet = function(greeting) {
  8409. * return greeting + 'ya ' + this.name + '!';
  8410. * };
  8411. *
  8412. * func();
  8413. * // => 'hiya fred!'
  8414. */
  8415. function bindKey(object, key) {
  8416. return arguments.length > 2
  8417. ? createWrapper(key, 19, slice(arguments, 2), null, object)
  8418. : createWrapper(key, 3, null, null, object);
  8419. }
  8420. /**
  8421. * Creates a function that is the composition of the provided functions,
  8422. * where each function consumes the return value of the function that follows.
  8423. * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`.
  8424. * Each function is executed with the `this` binding of the composed function.
  8425. *
  8426. * @static
  8427. * @memberOf _
  8428. * @category Functions
  8429. * @param {...Function} [func] Functions to compose.
  8430. * @returns {Function} Returns the new composed function.
  8431. * @example
  8432. *
  8433. * var realNameMap = {
  8434. * 'pebbles': 'penelope'
  8435. * };
  8436. *
  8437. * var format = function(name) {
  8438. * name = realNameMap[name.toLowerCase()] || name;
  8439. * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase();
  8440. * };
  8441. *
  8442. * var greet = function(formatted) {
  8443. * return 'Hiya ' + formatted + '!';
  8444. * };
  8445. *
  8446. * var welcome = _.compose(greet, format);
  8447. * welcome('pebbles');
  8448. * // => 'Hiya Penelope!'
  8449. */
  8450. function compose() {
  8451. var funcs = arguments,
  8452. length = funcs.length;
  8453. while (length--) {
  8454. if (!isFunction(funcs[length])) {
  8455. throw new TypeError;
  8456. }
  8457. }
  8458. return function() {
  8459. var args = arguments,
  8460. length = funcs.length;
  8461. while (length--) {
  8462. args = [funcs[length].apply(this, args)];
  8463. }
  8464. return args[0];
  8465. };
  8466. }
  8467. /**
  8468. * Creates a function which accepts one or more arguments of `func` that when
  8469. * invoked either executes `func` returning its result, if all `func` arguments
  8470. * have been provided, or returns a function that accepts one or more of the
  8471. * remaining `func` arguments, and so on. The arity of `func` can be specified
  8472. * if `func.length` is not sufficient.
  8473. *
  8474. * @static
  8475. * @memberOf _
  8476. * @category Functions
  8477. * @param {Function} func The function to curry.
  8478. * @param {number} [arity=func.length] The arity of `func`.
  8479. * @returns {Function} Returns the new curried function.
  8480. * @example
  8481. *
  8482. * var curried = _.curry(function(a, b, c) {
  8483. * console.log(a + b + c);
  8484. * });
  8485. *
  8486. * curried(1)(2)(3);
  8487. * // => 6
  8488. *
  8489. * curried(1, 2)(3);
  8490. * // => 6
  8491. *
  8492. * curried(1, 2, 3);
  8493. * // => 6
  8494. */
  8495. function curry(func, arity) {
  8496. arity = typeof arity == 'number' ? arity : (+arity || func.length);
  8497. return createWrapper(func, 4, null, null, null, arity);
  8498. }
  8499. /**
  8500. * Creates a function that will delay the execution of `func` until after
  8501. * `wait` milliseconds have elapsed since the last time it was invoked.
  8502. * Provide an options object to indicate that `func` should be invoked on
  8503. * the leading and/or trailing edge of the `wait` timeout. Subsequent calls
  8504. * to the debounced function will return the result of the last `func` call.
  8505. *
  8506. * Note: If `leading` and `trailing` options are `true` `func` will be called
  8507. * on the trailing edge of the timeout only if the the debounced function is
  8508. * invoked more than once during the `wait` timeout.
  8509. *
  8510. * @static
  8511. * @memberOf _
  8512. * @category Functions
  8513. * @param {Function} func The function to debounce.
  8514. * @param {number} wait The number of milliseconds to delay.
  8515. * @param {Object} [options] The options object.
  8516. * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout.
  8517. * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called.
  8518. * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
  8519. * @returns {Function} Returns the new debounced function.
  8520. * @example
  8521. *
  8522. * // avoid costly calculations while the window size is in flux
  8523. * var lazyLayout = _.debounce(calculateLayout, 150);
  8524. * jQuery(window).on('resize', lazyLayout);
  8525. *
  8526. * // execute `sendMail` when the click event is fired, debouncing subsequent calls
  8527. * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
  8528. * 'leading': true,
  8529. * 'trailing': false
  8530. * });
  8531. *
  8532. * // ensure `batchLog` is executed once after 1 second of debounced calls
  8533. * var source = new EventSource('/stream');
  8534. * source.addEventListener('message', _.debounce(batchLog, 250, {
  8535. * 'maxWait': 1000
  8536. * }, false);
  8537. */
  8538. function debounce(func, wait, options) {
  8539. var args,
  8540. maxTimeoutId,
  8541. result,
  8542. stamp,
  8543. thisArg,
  8544. timeoutId,
  8545. trailingCall,
  8546. lastCalled = 0,
  8547. maxWait = false,
  8548. trailing = true;
  8549. if (!isFunction(func)) {
  8550. throw new TypeError;
  8551. }
  8552. wait = nativeMax(0, wait) || 0;
  8553. if (options === true) {
  8554. var leading = true;
  8555. trailing = false;
  8556. } else if (isObject(options)) {
  8557. leading = options.leading;
  8558. maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0);
  8559. trailing = 'trailing' in options ? options.trailing : trailing;
  8560. }
  8561. var delayed = function() {
  8562. var remaining = wait - (now() - stamp);
  8563. if (remaining <= 0) {
  8564. if (maxTimeoutId) {
  8565. clearTimeout(maxTimeoutId);
  8566. }
  8567. var isCalled = trailingCall;
  8568. maxTimeoutId = timeoutId = trailingCall = undefined;
  8569. if (isCalled) {
  8570. lastCalled = now();
  8571. result = func.apply(thisArg, args);
  8572. if (!timeoutId && !maxTimeoutId) {
  8573. args = thisArg = null;
  8574. }
  8575. }
  8576. } else {
  8577. timeoutId = setTimeout(delayed, remaining);
  8578. }
  8579. };
  8580. var maxDelayed = function() {
  8581. if (timeoutId) {
  8582. clearTimeout(timeoutId);
  8583. }
  8584. maxTimeoutId = timeoutId = trailingCall = undefined;
  8585. if (trailing || (maxWait !== wait)) {
  8586. lastCalled = now();
  8587. result = func.apply(thisArg, args);
  8588. if (!timeoutId && !maxTimeoutId) {
  8589. args = thisArg = null;
  8590. }
  8591. }
  8592. };
  8593. return function() {
  8594. args = arguments;
  8595. stamp = now();
  8596. thisArg = this;
  8597. trailingCall = trailing && (timeoutId || !leading);
  8598. if (maxWait === false) {
  8599. var leadingCall = leading && !timeoutId;
  8600. } else {
  8601. if (!maxTimeoutId && !leading) {
  8602. lastCalled = stamp;
  8603. }
  8604. var remaining = maxWait - (stamp - lastCalled),
  8605. isCalled = remaining <= 0;
  8606. if (isCalled) {
  8607. if (maxTimeoutId) {
  8608. maxTimeoutId = clearTimeout(maxTimeoutId);
  8609. }
  8610. lastCalled = stamp;
  8611. result = func.apply(thisArg, args);
  8612. }
  8613. else if (!maxTimeoutId) {
  8614. maxTimeoutId = setTimeout(maxDelayed, remaining);
  8615. }
  8616. }
  8617. if (isCalled && timeoutId) {
  8618. timeoutId = clearTimeout(timeoutId);
  8619. }
  8620. else if (!timeoutId && wait !== maxWait) {
  8621. timeoutId = setTimeout(delayed, wait);
  8622. }
  8623. if (leadingCall) {
  8624. isCalled = true;
  8625. result = func.apply(thisArg, args);
  8626. }
  8627. if (isCalled && !timeoutId && !maxTimeoutId) {
  8628. args = thisArg = null;
  8629. }
  8630. return result;
  8631. };
  8632. }
  8633. /**
  8634. * Defers executing the `func` function until the current call stack has cleared.
  8635. * Additional arguments will be provided to `func` when it is invoked.
  8636. *
  8637. * @static
  8638. * @memberOf _
  8639. * @category Functions
  8640. * @param {Function} func The function to defer.
  8641. * @param {...*} [arg] Arguments to invoke the function with.
  8642. * @returns {number} Returns the timer id.
  8643. * @example
  8644. *
  8645. * _.defer(function(text) { console.log(text); }, 'deferred');
  8646. * // logs 'deferred' after one or more milliseconds
  8647. */
  8648. function defer(func) {
  8649. if (!isFunction(func)) {
  8650. throw new TypeError;
  8651. }
  8652. var args = slice(arguments, 1);
  8653. return setTimeout(function() { func.apply(undefined, args); }, 1);
  8654. }
  8655. /**
  8656. * Executes the `func` function after `wait` milliseconds. Additional arguments
  8657. * will be provided to `func` when it is invoked.
  8658. *
  8659. * @static
  8660. * @memberOf _
  8661. * @category Functions
  8662. * @param {Function} func The function to delay.
  8663. * @param {number} wait The number of milliseconds to delay execution.
  8664. * @param {...*} [arg] Arguments to invoke the function with.
  8665. * @returns {number} Returns the timer id.
  8666. * @example
  8667. *
  8668. * _.delay(function(text) { console.log(text); }, 1000, 'later');
  8669. * // => logs 'later' after one second
  8670. */
  8671. function delay(func, wait) {
  8672. if (!isFunction(func)) {
  8673. throw new TypeError;
  8674. }
  8675. var args = slice(arguments, 2);
  8676. return setTimeout(function() { func.apply(undefined, args); }, wait);
  8677. }
  8678. /**
  8679. * Creates a function that memoizes the result of `func`. If `resolver` is
  8680. * provided it will be used to determine the cache key for storing the result
  8681. * based on the arguments provided to the memoized function. By default, the
  8682. * first argument provided to the memoized function is used as the cache key.
  8683. * The `func` is executed with the `this` binding of the memoized function.
  8684. * The result cache is exposed as the `cache` property on the memoized function.
  8685. *
  8686. * @static
  8687. * @memberOf _
  8688. * @category Functions
  8689. * @param {Function} func The function to have its output memoized.
  8690. * @param {Function} [resolver] A function used to resolve the cache key.
  8691. * @returns {Function} Returns the new memoizing function.
  8692. * @example
  8693. *
  8694. * var fibonacci = _.memoize(function(n) {
  8695. * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
  8696. * });
  8697. *
  8698. * fibonacci(9)
  8699. * // => 34
  8700. *
  8701. * var data = {
  8702. * 'fred': { 'name': 'fred', 'age': 40 },
  8703. * 'pebbles': { 'name': 'pebbles', 'age': 1 }
  8704. * };
  8705. *
  8706. * // modifying the result cache
  8707. * var get = _.memoize(function(name) { return data[name]; }, _.identity);
  8708. * get('pebbles');
  8709. * // => { 'name': 'pebbles', 'age': 1 }
  8710. *
  8711. * get.cache.pebbles.name = 'penelope';
  8712. * get('pebbles');
  8713. * // => { 'name': 'penelope', 'age': 1 }
  8714. */
  8715. function memoize(func, resolver) {
  8716. if (!isFunction(func)) {
  8717. throw new TypeError;
  8718. }
  8719. var memoized = function() {
  8720. var cache = memoized.cache,
  8721. key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0];
  8722. return hasOwnProperty.call(cache, key)
  8723. ? cache[key]
  8724. : (cache[key] = func.apply(this, arguments));
  8725. }
  8726. memoized.cache = {};
  8727. return memoized;
  8728. }
  8729. /**
  8730. * Creates a function that is restricted to execute `func` once. Repeat calls to
  8731. * the function will return the value of the first call. The `func` is executed
  8732. * with the `this` binding of the created function.
  8733. *
  8734. * @static
  8735. * @memberOf _
  8736. * @category Functions
  8737. * @param {Function} func The function to restrict.
  8738. * @returns {Function} Returns the new restricted function.
  8739. * @example
  8740. *
  8741. * var initialize = _.once(createApplication);
  8742. * initialize();
  8743. * initialize();
  8744. * // `initialize` executes `createApplication` once
  8745. */
  8746. function once(func) {
  8747. var ran,
  8748. result;
  8749. if (!isFunction(func)) {
  8750. throw new TypeError;
  8751. }
  8752. return function() {
  8753. if (ran) {
  8754. return result;
  8755. }
  8756. ran = true;
  8757. result = func.apply(this, arguments);
  8758. // clear the `func` variable so the function may be garbage collected
  8759. func = null;
  8760. return result;
  8761. };
  8762. }
  8763. /**
  8764. * Creates a function that, when called, invokes `func` with any additional
  8765. * `partial` arguments prepended to those provided to the new function. This
  8766. * method is similar to `_.bind` except it does **not** alter the `this` binding.
  8767. *
  8768. * @static
  8769. * @memberOf _
  8770. * @category Functions
  8771. * @param {Function} func The function to partially apply arguments to.
  8772. * @param {...*} [arg] Arguments to be partially applied.
  8773. * @returns {Function} Returns the new partially applied function.
  8774. * @example
  8775. *
  8776. * var greet = function(greeting, name) { return greeting + ' ' + name; };
  8777. * var hi = _.partial(greet, 'hi');
  8778. * hi('fred');
  8779. * // => 'hi fred'
  8780. */
  8781. function partial(func) {
  8782. return createWrapper(func, 16, slice(arguments, 1));
  8783. }
  8784. /**
  8785. * This method is like `_.partial` except that `partial` arguments are
  8786. * appended to those provided to the new function.
  8787. *
  8788. * @static
  8789. * @memberOf _
  8790. * @category Functions
  8791. * @param {Function} func The function to partially apply arguments to.
  8792. * @param {...*} [arg] Arguments to be partially applied.
  8793. * @returns {Function} Returns the new partially applied function.
  8794. * @example
  8795. *
  8796. * var defaultsDeep = _.partialRight(_.merge, _.defaults);
  8797. *
  8798. * var options = {
  8799. * 'variable': 'data',
  8800. * 'imports': { 'jq': $ }
  8801. * };
  8802. *
  8803. * defaultsDeep(options, _.templateSettings);
  8804. *
  8805. * options.variable
  8806. * // => 'data'
  8807. *
  8808. * options.imports
  8809. * // => { '_': _, 'jq': $ }
  8810. */
  8811. function partialRight(func) {
  8812. return createWrapper(func, 32, null, slice(arguments, 1));
  8813. }
  8814. /**
  8815. * Creates a function that, when executed, will only call the `func` function
  8816. * at most once per every `wait` milliseconds. Provide an options object to
  8817. * indicate that `func` should be invoked on the leading and/or trailing edge
  8818. * of the `wait` timeout. Subsequent calls to the throttled function will
  8819. * return the result of the last `func` call.
  8820. *
  8821. * Note: If `leading` and `trailing` options are `true` `func` will be called
  8822. * on the trailing edge of the timeout only if the the throttled function is
  8823. * invoked more than once during the `wait` timeout.
  8824. *
  8825. * @static
  8826. * @memberOf _
  8827. * @category Functions
  8828. * @param {Function} func The function to throttle.
  8829. * @param {number} wait The number of milliseconds to throttle executions to.
  8830. * @param {Object} [options] The options object.
  8831. * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout.
  8832. * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
  8833. * @returns {Function} Returns the new throttled function.
  8834. * @example
  8835. *
  8836. * // avoid excessively updating the position while scrolling
  8837. * var throttled = _.throttle(updatePosition, 100);
  8838. * jQuery(window).on('scroll', throttled);
  8839. *
  8840. * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes
  8841. * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
  8842. * 'trailing': false
  8843. * }));
  8844. */
  8845. function throttle(func, wait, options) {
  8846. var leading = true,
  8847. trailing = true;
  8848. if (!isFunction(func)) {
  8849. throw new TypeError;
  8850. }
  8851. if (options === false) {
  8852. leading = false;
  8853. } else if (isObject(options)) {
  8854. leading = 'leading' in options ? options.leading : leading;
  8855. trailing = 'trailing' in options ? options.trailing : trailing;
  8856. }
  8857. debounceOptions.leading = leading;
  8858. debounceOptions.maxWait = wait;
  8859. debounceOptions.trailing = trailing;
  8860. return debounce(func, wait, debounceOptions);
  8861. }
  8862. /**
  8863. * Creates a function that provides `value` to the wrapper function as its
  8864. * first argument. Additional arguments provided to the function are appended
  8865. * to those provided to the wrapper function. The wrapper is executed with
  8866. * the `this` binding of the created function.
  8867. *
  8868. * @static
  8869. * @memberOf _
  8870. * @category Functions
  8871. * @param {*} value The value to wrap.
  8872. * @param {Function} wrapper The wrapper function.
  8873. * @returns {Function} Returns the new function.
  8874. * @example
  8875. *
  8876. * var p = _.wrap(_.escape, function(func, text) {
  8877. * return '<p>' + func(text) + '</p>';
  8878. * });
  8879. *
  8880. * p('Fred, Wilma, & Pebbles');
  8881. * // => '<p>Fred, Wilma, &amp; Pebbles</p>'
  8882. */
  8883. function wrap(value, wrapper) {
  8884. return createWrapper(wrapper, 16, [value]);
  8885. }
  8886. /*--------------------------------------------------------------------------*/
  8887. /**
  8888. * Creates a function that returns `value`.
  8889. *
  8890. * @static
  8891. * @memberOf _
  8892. * @category Utilities
  8893. * @param {*} value The value to return from the new function.
  8894. * @returns {Function} Returns the new function.
  8895. * @example
  8896. *
  8897. * var object = { 'name': 'fred' };
  8898. * var getter = _.constant(object);
  8899. * getter() === object;
  8900. * // => true
  8901. */
  8902. function constant(value) {
  8903. return function() {
  8904. return value;
  8905. };
  8906. }
  8907. /**
  8908. * Produces a callback bound to an optional `thisArg`. If `func` is a property
  8909. * name the created callback will return the property value for a given element.
  8910. * If `func` is an object the created callback will return `true` for elements
  8911. * that contain the equivalent object properties, otherwise it will return `false`.
  8912. *
  8913. * @static
  8914. * @memberOf _
  8915. * @category Utilities
  8916. * @param {*} [func=identity] The value to convert to a callback.
  8917. * @param {*} [thisArg] The `this` binding of the created callback.
  8918. * @param {number} [argCount] The number of arguments the callback accepts.
  8919. * @returns {Function} Returns a callback function.
  8920. * @example
  8921. *
  8922. * var characters = [
  8923. * { 'name': 'barney', 'age': 36 },
  8924. * { 'name': 'fred', 'age': 40 }
  8925. * ];
  8926. *
  8927. * // wrap to create custom callback shorthands
  8928. * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) {
  8929. * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback);
  8930. * return !match ? func(callback, thisArg) : function(object) {
  8931. * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3];
  8932. * };
  8933. * });
  8934. *
  8935. * _.filter(characters, 'age__gt38');
  8936. * // => [{ 'name': 'fred', 'age': 40 }]
  8937. */
  8938. function createCallback(func, thisArg, argCount) {
  8939. var type = typeof func;
  8940. if (func == null || type == 'function') {
  8941. return baseCreateCallback(func, thisArg, argCount);
  8942. }
  8943. // handle "_.pluck" style callback shorthands
  8944. if (type != 'object') {
  8945. return property(func);
  8946. }
  8947. var props = keys(func),
  8948. key = props[0],
  8949. a = func[key];
  8950. // handle "_.where" style callback shorthands
  8951. if (props.length == 1 && a === a && !isObject(a)) {
  8952. // fast path the common case of providing an object with a single
  8953. // property containing a primitive value
  8954. return function(object) {
  8955. var b = object[key];
  8956. return a === b && (a !== 0 || (1 / a == 1 / b));
  8957. };
  8958. }
  8959. return function(object) {
  8960. var length = props.length,
  8961. result = false;
  8962. while (length--) {
  8963. if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) {
  8964. break;
  8965. }
  8966. }
  8967. return result;
  8968. };
  8969. }
  8970. /**
  8971. * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their
  8972. * corresponding HTML entities.
  8973. *
  8974. * @static
  8975. * @memberOf _
  8976. * @category Utilities
  8977. * @param {string} string The string to escape.
  8978. * @returns {string} Returns the escaped string.
  8979. * @example
  8980. *
  8981. * _.escape('Fred, Wilma, & Pebbles');
  8982. * // => 'Fred, Wilma, &amp; Pebbles'
  8983. */
  8984. function escape(string) {
  8985. return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar);
  8986. }
  8987. /**
  8988. * This method returns the first argument provided to it.
  8989. *
  8990. * @static
  8991. * @memberOf _
  8992. * @category Utilities
  8993. * @param {*} value Any value.
  8994. * @returns {*} Returns `value`.
  8995. * @example
  8996. *
  8997. * var object = { 'name': 'fred' };
  8998. * _.identity(object) === object;
  8999. * // => true
  9000. */
  9001. function identity(value) {
  9002. return value;
  9003. }
  9004. /**
  9005. * Adds function properties of a source object to the destination object.
  9006. * If `object` is a function methods will be added to its prototype as well.
  9007. *
  9008. * @static
  9009. * @memberOf _
  9010. * @category Utilities
  9011. * @param {Function|Object} [object=lodash] object The destination object.
  9012. * @param {Object} source The object of functions to add.
  9013. * @param {Object} [options] The options object.
  9014. * @param {boolean} [options.chain=true] Specify whether the functions added are chainable.
  9015. * @example
  9016. *
  9017. * function capitalize(string) {
  9018. * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
  9019. * }
  9020. *
  9021. * _.mixin({ 'capitalize': capitalize });
  9022. * _.capitalize('fred');
  9023. * // => 'Fred'
  9024. *
  9025. * _('fred').capitalize().value();
  9026. * // => 'Fred'
  9027. *
  9028. * _.mixin({ 'capitalize': capitalize }, { 'chain': false });
  9029. * _('fred').capitalize();
  9030. * // => 'Fred'
  9031. */
  9032. function mixin(object, source, options) {
  9033. var chain = true,
  9034. methodNames = source && functions(source);
  9035. if (!source || (!options && !methodNames.length)) {
  9036. if (options == null) {
  9037. options = source;
  9038. }
  9039. ctor = lodashWrapper;
  9040. source = object;
  9041. object = lodash;
  9042. methodNames = functions(source);
  9043. }
  9044. if (options === false) {
  9045. chain = false;
  9046. } else if (isObject(options) && 'chain' in options) {
  9047. chain = options.chain;
  9048. }
  9049. var ctor = object,
  9050. isFunc = isFunction(ctor);
  9051. forEach(methodNames, function(methodName) {
  9052. var func = object[methodName] = source[methodName];
  9053. if (isFunc) {
  9054. ctor.prototype[methodName] = function() {
  9055. var chainAll = this.__chain__,
  9056. value = this.__wrapped__,
  9057. args = [value];
  9058. push.apply(args, arguments);
  9059. var result = func.apply(object, args);
  9060. if (chain || chainAll) {
  9061. if (value === result && isObject(result)) {
  9062. return this;
  9063. }
  9064. result = new ctor(result);
  9065. result.__chain__ = chainAll;
  9066. }
  9067. return result;
  9068. };
  9069. }
  9070. });
  9071. }
  9072. /**
  9073. * Reverts the '_' variable to its previous value and returns a reference to
  9074. * the `lodash` function.
  9075. *
  9076. * @static
  9077. * @memberOf _
  9078. * @category Utilities
  9079. * @returns {Function} Returns the `lodash` function.
  9080. * @example
  9081. *
  9082. * var lodash = _.noConflict();
  9083. */
  9084. function noConflict() {
  9085. context._ = oldDash;
  9086. return this;
  9087. }
  9088. /**
  9089. * A no-operation function.
  9090. *
  9091. * @static
  9092. * @memberOf _
  9093. * @category Utilities
  9094. * @example
  9095. *
  9096. * var object = { 'name': 'fred' };
  9097. * _.noop(object) === undefined;
  9098. * // => true
  9099. */
  9100. function noop() {
  9101. // no operation performed
  9102. }
  9103. /**
  9104. * Gets the number of milliseconds that have elapsed since the Unix epoch
  9105. * (1 January 1970 00:00:00 UTC).
  9106. *
  9107. * @static
  9108. * @memberOf _
  9109. * @category Utilities
  9110. * @example
  9111. *
  9112. * var stamp = _.now();
  9113. * _.defer(function() { console.log(_.now() - stamp); });
  9114. * // => logs the number of milliseconds it took for the deferred function to be called
  9115. */
  9116. var now = isNative(now = Date.now) && now || function() {
  9117. return new Date().getTime();
  9118. };
  9119. /**
  9120. * Converts the given value into an integer of the specified radix.
  9121. * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the
  9122. * `value` is a hexadecimal, in which case a `radix` of `16` is used.
  9123. *
  9124. * Note: This method avoids differences in native ES3 and ES5 `parseInt`
  9125. * implementations. See http://es5.github.io/#E.
  9126. *
  9127. * @static
  9128. * @memberOf _
  9129. * @category Utilities
  9130. * @param {string} value The value to parse.
  9131. * @param {number} [radix] The radix used to interpret the value to parse.
  9132. * @returns {number} Returns the new integer value.
  9133. * @example
  9134. *
  9135. * _.parseInt('08');
  9136. * // => 8
  9137. */
  9138. var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) {
  9139. // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt`
  9140. return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0);
  9141. };
  9142. /**
  9143. * Creates a "_.pluck" style function, which returns the `key` value of a
  9144. * given object.
  9145. *
  9146. * @static
  9147. * @memberOf _
  9148. * @category Utilities
  9149. * @param {string} key The name of the property to retrieve.
  9150. * @returns {Function} Returns the new function.
  9151. * @example
  9152. *
  9153. * var characters = [
  9154. * { 'name': 'fred', 'age': 40 },
  9155. * { 'name': 'barney', 'age': 36 }
  9156. * ];
  9157. *
  9158. * var getName = _.property('name');
  9159. *
  9160. * _.map(characters, getName);
  9161. * // => ['barney', 'fred']
  9162. *
  9163. * _.sortBy(characters, getName);
  9164. * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }]
  9165. */
  9166. function property(key) {
  9167. return function(object) {
  9168. return object[key];
  9169. };
  9170. }
  9171. /**
  9172. * Produces a random number between `min` and `max` (inclusive). If only one
  9173. * argument is provided a number between `0` and the given number will be
  9174. * returned. If `floating` is truey or either `min` or `max` are floats a
  9175. * floating-point number will be returned instead of an integer.
  9176. *
  9177. * @static
  9178. * @memberOf _
  9179. * @category Utilities
  9180. * @param {number} [min=0] The minimum possible value.
  9181. * @param {number} [max=1] The maximum possible value.
  9182. * @param {boolean} [floating=false] Specify returning a floating-point number.
  9183. * @returns {number} Returns a random number.
  9184. * @example
  9185. *
  9186. * _.random(0, 5);
  9187. * // => an integer between 0 and 5
  9188. *
  9189. * _.random(5);
  9190. * // => also an integer between 0 and 5
  9191. *
  9192. * _.random(5, true);
  9193. * // => a floating-point number between 0 and 5
  9194. *
  9195. * _.random(1.2, 5.2);
  9196. * // => a floating-point number between 1.2 and 5.2
  9197. */
  9198. function random(min, max, floating) {
  9199. var noMin = min == null,
  9200. noMax = max == null;
  9201. if (floating == null) {
  9202. if (typeof min == 'boolean' && noMax) {
  9203. floating = min;
  9204. min = 1;
  9205. }
  9206. else if (!noMax && typeof max == 'boolean') {
  9207. floating = max;
  9208. noMax = true;
  9209. }
  9210. }
  9211. if (noMin && noMax) {
  9212. max = 1;
  9213. }
  9214. min = +min || 0;
  9215. if (noMax) {
  9216. max = min;
  9217. min = 0;
  9218. } else {
  9219. max = +max || 0;
  9220. }
  9221. if (floating || min % 1 || max % 1) {
  9222. var rand = nativeRandom();
  9223. return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max);
  9224. }
  9225. return baseRandom(min, max);
  9226. }
  9227. /**
  9228. * Resolves the value of property `key` on `object`. If `key` is a function
  9229. * it will be invoked with the `this` binding of `object` and its result returned,
  9230. * else the property value is returned. If `object` is falsey then `undefined`
  9231. * is returned.
  9232. *
  9233. * @static
  9234. * @memberOf _
  9235. * @category Utilities
  9236. * @param {Object} object The object to inspect.
  9237. * @param {string} key The name of the property to resolve.
  9238. * @returns {*} Returns the resolved value.
  9239. * @example
  9240. *
  9241. * var object = {
  9242. * 'cheese': 'crumpets',
  9243. * 'stuff': function() {
  9244. * return 'nonsense';
  9245. * }
  9246. * };
  9247. *
  9248. * _.result(object, 'cheese');
  9249. * // => 'crumpets'
  9250. *
  9251. * _.result(object, 'stuff');
  9252. * // => 'nonsense'
  9253. */
  9254. function result(object, key) {
  9255. if (object) {
  9256. var value = object[key];
  9257. return isFunction(value) ? object[key]() : value;
  9258. }
  9259. }
  9260. /**
  9261. * A micro-templating method that handles arbitrary delimiters, preserves
  9262. * whitespace, and correctly escapes quotes within interpolated code.
  9263. *
  9264. * Note: In the development build, `_.template` utilizes sourceURLs for easier
  9265. * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
  9266. *
  9267. * For more information on precompiling templates see:
  9268. * http://lodash.com/custom-builds
  9269. *
  9270. * For more information on Chrome extension sandboxes see:
  9271. * http://developer.chrome.com/stable/extensions/sandboxingEval.html
  9272. *
  9273. * @static
  9274. * @memberOf _
  9275. * @category Utilities
  9276. * @param {string} text The template text.
  9277. * @param {Object} data The data object used to populate the text.
  9278. * @param {Object} [options] The options object.
  9279. * @param {RegExp} [options.escape] The "escape" delimiter.
  9280. * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
  9281. * @param {Object} [options.imports] An object to import into the template as local variables.
  9282. * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
  9283. * @param {string} [sourceURL] The sourceURL of the template's compiled source.
  9284. * @param {string} [variable] The data object variable name.
  9285. * @returns {Function|string} Returns a compiled function when no `data` object
  9286. * is given, else it returns the interpolated text.
  9287. * @example
  9288. *
  9289. * // using the "interpolate" delimiter to create a compiled template
  9290. * var compiled = _.template('hello <%= name %>');
  9291. * compiled({ 'name': 'fred' });
  9292. * // => 'hello fred'
  9293. *
  9294. * // using the "escape" delimiter to escape HTML in data property values
  9295. * _.template('<b><%- value %></b>', { 'value': '<script>' });
  9296. * // => '<b>&lt;script&gt;</b>'
  9297. *
  9298. * // using the "evaluate" delimiter to generate HTML
  9299. * var list = '<% _.forEach(people, function(name) { %><li><%- name %></li><% }); %>';
  9300. * _.template(list, { 'people': ['fred', 'barney'] });
  9301. * // => '<li>fred</li><li>barney</li>'
  9302. *
  9303. * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter
  9304. * _.template('hello ${ name }', { 'name': 'pebbles' });
  9305. * // => 'hello pebbles'
  9306. *
  9307. * // using the internal `print` function in "evaluate" delimiters
  9308. * _.template('<% print("hello " + name); %>!', { 'name': 'barney' });
  9309. * // => 'hello barney!'
  9310. *
  9311. * // using a custom template delimiters
  9312. * _.templateSettings = {
  9313. * 'interpolate': /{{([\s\S]+?)}}/g
  9314. * };
  9315. *
  9316. * _.template('hello {{ name }}!', { 'name': 'mustache' });
  9317. * // => 'hello mustache!'
  9318. *
  9319. * // using the `imports` option to import jQuery
  9320. * var list = '<% jq.each(people, function(name) { %><li><%- name %></li><% }); %>';
  9321. * _.template(list, { 'people': ['fred', 'barney'] }, { 'imports': { 'jq': jQuery } });
  9322. * // => '<li>fred</li><li>barney</li>'
  9323. *
  9324. * // using the `sourceURL` option to specify a custom sourceURL for the template
  9325. * var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' });
  9326. * compiled(data);
  9327. * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
  9328. *
  9329. * // using the `variable` option to ensure a with-statement isn't used in the compiled template
  9330. * var compiled = _.template('hi <%= data.name %>!', null, { 'variable': 'data' });
  9331. * compiled.source;
  9332. * // => function(data) {
  9333. * var __t, __p = '', __e = _.escape;
  9334. * __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!';
  9335. * return __p;
  9336. * }
  9337. *
  9338. * // using the `source` property to inline compiled templates for meaningful
  9339. * // line numbers in error messages and a stack trace
  9340. * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
  9341. * var JST = {\
  9342. * "main": ' + _.template(mainText).source + '\
  9343. * };\
  9344. * ');
  9345. */
  9346. function template(text, data, options) {
  9347. // based on John Resig's `tmpl` implementation
  9348. // http://ejohn.org/blog/javascript-micro-templating/
  9349. // and Laura Doktorova's doT.js
  9350. // https://github.com/olado/doT
  9351. var settings = lodash.templateSettings;
  9352. text = String(text || '');
  9353. // avoid missing dependencies when `iteratorTemplate` is not defined
  9354. options = defaults({}, options, settings);
  9355. var imports = defaults({}, options.imports, settings.imports),
  9356. importsKeys = keys(imports),
  9357. importsValues = values(imports);
  9358. var isEvaluating,
  9359. index = 0,
  9360. interpolate = options.interpolate || reNoMatch,
  9361. source = "__p += '";
  9362. // compile the regexp to match each delimiter
  9363. var reDelimiters = RegExp(
  9364. (options.escape || reNoMatch).source + '|' +
  9365. interpolate.source + '|' +
  9366. (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
  9367. (options.evaluate || reNoMatch).source + '|$'
  9368. , 'g');
  9369. text.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
  9370. interpolateValue || (interpolateValue = esTemplateValue);
  9371. // escape characters that cannot be included in string literals
  9372. source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar);
  9373. // replace delimiters with snippets
  9374. if (escapeValue) {
  9375. source += "' +\n__e(" + escapeValue + ") +\n'";
  9376. }
  9377. if (evaluateValue) {
  9378. isEvaluating = true;
  9379. source += "';\n" + evaluateValue + ";\n__p += '";
  9380. }
  9381. if (interpolateValue) {
  9382. source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
  9383. }
  9384. index = offset + match.length;
  9385. // the JS engine embedded in Adobe products requires returning the `match`
  9386. // string in order to produce the correct `offset` value
  9387. return match;
  9388. });
  9389. source += "';\n";
  9390. // if `variable` is not specified, wrap a with-statement around the generated
  9391. // code to add the data object to the top of the scope chain
  9392. var variable = options.variable,
  9393. hasVariable = variable;
  9394. if (!hasVariable) {
  9395. variable = 'obj';
  9396. source = 'with (' + variable + ') {\n' + source + '\n}\n';
  9397. }
  9398. // cleanup code by stripping empty strings
  9399. source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
  9400. .replace(reEmptyStringMiddle, '$1')
  9401. .replace(reEmptyStringTrailing, '$1;');
  9402. // frame code as the function body
  9403. source = 'function(' + variable + ') {\n' +
  9404. (hasVariable ? '' : variable + ' || (' + variable + ' = {});\n') +
  9405. "var __t, __p = '', __e = _.escape" +
  9406. (isEvaluating
  9407. ? ', __j = Array.prototype.join;\n' +
  9408. "function print() { __p += __j.call(arguments, '') }\n"
  9409. : ';\n'
  9410. ) +
  9411. source +
  9412. 'return __p\n}';
  9413. // Use a sourceURL for easier debugging.
  9414. // http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
  9415. var sourceURL = '\n/*\n//# sourceURL=' + (options.sourceURL || '/lodash/template/source[' + (templateCounter++) + ']') + '\n*/';
  9416. try {
  9417. var result = Function(importsKeys, 'return ' + source + sourceURL).apply(undefined, importsValues);
  9418. } catch(e) {
  9419. e.source = source;
  9420. throw e;
  9421. }
  9422. if (data) {
  9423. return result(data);
  9424. }
  9425. // provide the compiled function's source by its `toString` method, in
  9426. // supported environments, or the `source` property as a convenience for
  9427. // inlining compiled templates during the build process
  9428. result.source = source;
  9429. return result;
  9430. }
  9431. /**
  9432. * Executes the callback `n` times, returning an array of the results
  9433. * of each callback execution. The callback is bound to `thisArg` and invoked
  9434. * with one argument; (index).
  9435. *
  9436. * @static
  9437. * @memberOf _
  9438. * @category Utilities
  9439. * @param {number} n The number of times to execute the callback.
  9440. * @param {Function} callback The function called per iteration.
  9441. * @param {*} [thisArg] The `this` binding of `callback`.
  9442. * @returns {Array} Returns an array of the results of each `callback` execution.
  9443. * @example
  9444. *
  9445. * var diceRolls = _.times(3, _.partial(_.random, 1, 6));
  9446. * // => [3, 6, 4]
  9447. *
  9448. * _.times(3, function(n) { mage.castSpell(n); });
  9449. * // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`, and `2` respectively
  9450. *
  9451. * _.times(3, function(n) { this.cast(n); }, mage);
  9452. * // => also calls `mage.castSpell(n)` three times
  9453. */
  9454. function times(n, callback, thisArg) {
  9455. n = (n = +n) > -1 ? n : 0;
  9456. var index = -1,
  9457. result = Array(n);
  9458. callback = baseCreateCallback(callback, thisArg, 1);
  9459. while (++index < n) {
  9460. result[index] = callback(index);
  9461. }
  9462. return result;
  9463. }
  9464. /**
  9465. * The inverse of `_.escape` this method converts the HTML entities
  9466. * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to their
  9467. * corresponding characters.
  9468. *
  9469. * @static
  9470. * @memberOf _
  9471. * @category Utilities
  9472. * @param {string} string The string to unescape.
  9473. * @returns {string} Returns the unescaped string.
  9474. * @example
  9475. *
  9476. * _.unescape('Fred, Barney &amp; Pebbles');
  9477. * // => 'Fred, Barney & Pebbles'
  9478. */
  9479. function unescape(string) {
  9480. return string == null ? '' : String(string).replace(reEscapedHtml, unescapeHtmlChar);
  9481. }
  9482. /**
  9483. * Generates a unique ID. If `prefix` is provided the ID will be appended to it.
  9484. *
  9485. * @static
  9486. * @memberOf _
  9487. * @category Utilities
  9488. * @param {string} [prefix] The value to prefix the ID with.
  9489. * @returns {string} Returns the unique ID.
  9490. * @example
  9491. *
  9492. * _.uniqueId('contact_');
  9493. * // => 'contact_104'
  9494. *
  9495. * _.uniqueId();
  9496. * // => '105'
  9497. */
  9498. function uniqueId(prefix) {
  9499. var id = ++idCounter;
  9500. return String(prefix == null ? '' : prefix) + id;
  9501. }
  9502. /*--------------------------------------------------------------------------*/
  9503. /**
  9504. * Creates a `lodash` object that wraps the given value with explicit
  9505. * method chaining enabled.
  9506. *
  9507. * @static
  9508. * @memberOf _
  9509. * @category Chaining
  9510. * @param {*} value The value to wrap.
  9511. * @returns {Object} Returns the wrapper object.
  9512. * @example
  9513. *
  9514. * var characters = [
  9515. * { 'name': 'barney', 'age': 36 },
  9516. * { 'name': 'fred', 'age': 40 },
  9517. * { 'name': 'pebbles', 'age': 1 }
  9518. * ];
  9519. *
  9520. * var youngest = _.chain(characters)
  9521. * .sortBy('age')
  9522. * .map(function(chr) { return chr.name + ' is ' + chr.age; })
  9523. * .first()
  9524. * .value();
  9525. * // => 'pebbles is 1'
  9526. */
  9527. function chain(value) {
  9528. value = new lodashWrapper(value);
  9529. value.__chain__ = true;
  9530. return value;
  9531. }
  9532. /**
  9533. * Invokes `interceptor` with the `value` as the first argument and then
  9534. * returns `value`. The purpose of this method is to "tap into" a method
  9535. * chain in order to perform operations on intermediate results within
  9536. * the chain.
  9537. *
  9538. * @static
  9539. * @memberOf _
  9540. * @category Chaining
  9541. * @param {*} value The value to provide to `interceptor`.
  9542. * @param {Function} interceptor The function to invoke.
  9543. * @returns {*} Returns `value`.
  9544. * @example
  9545. *
  9546. * _([1, 2, 3, 4])
  9547. * .tap(function(array) { array.pop(); })
  9548. * .reverse()
  9549. * .value();
  9550. * // => [3, 2, 1]
  9551. */
  9552. function tap(value, interceptor) {
  9553. interceptor(value);
  9554. return value;
  9555. }
  9556. /**
  9557. * Enables explicit method chaining on the wrapper object.
  9558. *
  9559. * @name chain
  9560. * @memberOf _
  9561. * @category Chaining
  9562. * @returns {*} Returns the wrapper object.
  9563. * @example
  9564. *
  9565. * var characters = [
  9566. * { 'name': 'barney', 'age': 36 },
  9567. * { 'name': 'fred', 'age': 40 }
  9568. * ];
  9569. *
  9570. * // without explicit chaining
  9571. * _(characters).first();
  9572. * // => { 'name': 'barney', 'age': 36 }
  9573. *
  9574. * // with explicit chaining
  9575. * _(characters).chain()
  9576. * .first()
  9577. * .pick('age')
  9578. * .value();
  9579. * // => { 'age': 36 }
  9580. */
  9581. function wrapperChain() {
  9582. this.__chain__ = true;
  9583. return this;
  9584. }
  9585. /**
  9586. * Produces the `toString` result of the wrapped value.
  9587. *
  9588. * @name toString
  9589. * @memberOf _
  9590. * @category Chaining
  9591. * @returns {string} Returns the string result.
  9592. * @example
  9593. *
  9594. * _([1, 2, 3]).toString();
  9595. * // => '1,2,3'
  9596. */
  9597. function wrapperToString() {
  9598. return String(this.__wrapped__);
  9599. }
  9600. /**
  9601. * Extracts the wrapped value.
  9602. *
  9603. * @name valueOf
  9604. * @memberOf _
  9605. * @alias value
  9606. * @category Chaining
  9607. * @returns {*} Returns the wrapped value.
  9608. * @example
  9609. *
  9610. * _([1, 2, 3]).valueOf();
  9611. * // => [1, 2, 3]
  9612. */
  9613. function wrapperValueOf() {
  9614. return this.__wrapped__;
  9615. }
  9616. /*--------------------------------------------------------------------------*/
  9617. // add functions that return wrapped values when chaining
  9618. lodash.after = after;
  9619. lodash.assign = assign;
  9620. lodash.at = at;
  9621. lodash.bind = bind;
  9622. lodash.bindAll = bindAll;
  9623. lodash.bindKey = bindKey;
  9624. lodash.chain = chain;
  9625. lodash.compact = compact;
  9626. lodash.compose = compose;
  9627. lodash.constant = constant;
  9628. lodash.countBy = countBy;
  9629. lodash.create = create;
  9630. lodash.createCallback = createCallback;
  9631. lodash.curry = curry;
  9632. lodash.debounce = debounce;
  9633. lodash.defaults = defaults;
  9634. lodash.defer = defer;
  9635. lodash.delay = delay;
  9636. lodash.difference = difference;
  9637. lodash.filter = filter;
  9638. lodash.flatten = flatten;
  9639. lodash.forEach = forEach;
  9640. lodash.forEachRight = forEachRight;
  9641. lodash.forIn = forIn;
  9642. lodash.forInRight = forInRight;
  9643. lodash.forOwn = forOwn;
  9644. lodash.forOwnRight = forOwnRight;
  9645. lodash.functions = functions;
  9646. lodash.groupBy = groupBy;
  9647. lodash.indexBy = indexBy;
  9648. lodash.initial = initial;
  9649. lodash.intersection = intersection;
  9650. lodash.invert = invert;
  9651. lodash.invoke = invoke;
  9652. lodash.keys = keys;
  9653. lodash.map = map;
  9654. lodash.mapValues = mapValues;
  9655. lodash.max = max;
  9656. lodash.memoize = memoize;
  9657. lodash.merge = merge;
  9658. lodash.min = min;
  9659. lodash.omit = omit;
  9660. lodash.once = once;
  9661. lodash.pairs = pairs;
  9662. lodash.partial = partial;
  9663. lodash.partialRight = partialRight;
  9664. lodash.pick = pick;
  9665. lodash.pluck = pluck;
  9666. lodash.property = property;
  9667. lodash.pull = pull;
  9668. lodash.range = range;
  9669. lodash.reject = reject;
  9670. lodash.remove = remove;
  9671. lodash.rest = rest;
  9672. lodash.shuffle = shuffle;
  9673. lodash.sortBy = sortBy;
  9674. lodash.tap = tap;
  9675. lodash.throttle = throttle;
  9676. lodash.times = times;
  9677. lodash.toArray = toArray;
  9678. lodash.transform = transform;
  9679. lodash.union = union;
  9680. lodash.uniq = uniq;
  9681. lodash.values = values;
  9682. lodash.where = where;
  9683. lodash.without = without;
  9684. lodash.wrap = wrap;
  9685. lodash.xor = xor;
  9686. lodash.zip = zip;
  9687. lodash.zipObject = zipObject;
  9688. // add aliases
  9689. lodash.collect = map;
  9690. lodash.drop = rest;
  9691. lodash.each = forEach;
  9692. lodash.eachRight = forEachRight;
  9693. lodash.extend = assign;
  9694. lodash.methods = functions;
  9695. lodash.object = zipObject;
  9696. lodash.select = filter;
  9697. lodash.tail = rest;
  9698. lodash.unique = uniq;
  9699. lodash.unzip = zip;
  9700. // add functions to `lodash.prototype`
  9701. mixin(lodash);
  9702. /*--------------------------------------------------------------------------*/
  9703. // add functions that return unwrapped values when chaining
  9704. lodash.clone = clone;
  9705. lodash.cloneDeep = cloneDeep;
  9706. lodash.contains = contains;
  9707. lodash.escape = escape;
  9708. lodash.every = every;
  9709. lodash.find = find;
  9710. lodash.findIndex = findIndex;
  9711. lodash.findKey = findKey;
  9712. lodash.findLast = findLast;
  9713. lodash.findLastIndex = findLastIndex;
  9714. lodash.findLastKey = findLastKey;
  9715. lodash.has = has;
  9716. lodash.identity = identity;
  9717. lodash.indexOf = indexOf;
  9718. lodash.isArguments = isArguments;
  9719. lodash.isArray = isArray;
  9720. lodash.isBoolean = isBoolean;
  9721. lodash.isDate = isDate;
  9722. lodash.isElement = isElement;
  9723. lodash.isEmpty = isEmpty;
  9724. lodash.isEqual = isEqual;
  9725. lodash.isFinite = isFinite;
  9726. lodash.isFunction = isFunction;
  9727. lodash.isNaN = isNaN;
  9728. lodash.isNull = isNull;
  9729. lodash.isNumber = isNumber;
  9730. lodash.isObject = isObject;
  9731. lodash.isPlainObject = isPlainObject;
  9732. lodash.isRegExp = isRegExp;
  9733. lodash.isString = isString;
  9734. lodash.isUndefined = isUndefined;
  9735. lodash.lastIndexOf = lastIndexOf;
  9736. lodash.mixin = mixin;
  9737. lodash.noConflict = noConflict;
  9738. lodash.noop = noop;
  9739. lodash.now = now;
  9740. lodash.parseInt = parseInt;
  9741. lodash.random = random;
  9742. lodash.reduce = reduce;
  9743. lodash.reduceRight = reduceRight;
  9744. lodash.result = result;
  9745. lodash.runInContext = runInContext;
  9746. lodash.size = size;
  9747. lodash.some = some;
  9748. lodash.sortedIndex = sortedIndex;
  9749. lodash.template = template;
  9750. lodash.unescape = unescape;
  9751. lodash.uniqueId = uniqueId;
  9752. // add aliases
  9753. lodash.all = every;
  9754. lodash.any = some;
  9755. lodash.detect = find;
  9756. lodash.findWhere = find;
  9757. lodash.foldl = reduce;
  9758. lodash.foldr = reduceRight;
  9759. lodash.include = contains;
  9760. lodash.inject = reduce;
  9761. mixin(function() {
  9762. var source = {}
  9763. forOwn(lodash, function(func, methodName) {
  9764. if (!lodash.prototype[methodName]) {
  9765. source[methodName] = func;
  9766. }
  9767. });
  9768. return source;
  9769. }(), false);
  9770. /*--------------------------------------------------------------------------*/
  9771. // add functions capable of returning wrapped and unwrapped values when chaining
  9772. lodash.first = first;
  9773. lodash.last = last;
  9774. lodash.sample = sample;
  9775. // add aliases
  9776. lodash.take = first;
  9777. lodash.head = first;
  9778. forOwn(lodash, function(func, methodName) {
  9779. var callbackable = methodName !== 'sample';
  9780. if (!lodash.prototype[methodName]) {
  9781. lodash.prototype[methodName]= function(n, guard) {
  9782. var chainAll = this.__chain__,
  9783. result = func(this.__wrapped__, n, guard);
  9784. return !chainAll && (n == null || (guard && !(callbackable && typeof n == 'function')))
  9785. ? result
  9786. : new lodashWrapper(result, chainAll);
  9787. };
  9788. }
  9789. });
  9790. /*--------------------------------------------------------------------------*/
  9791. /**
  9792. * The semantic version number.
  9793. *
  9794. * @static
  9795. * @memberOf _
  9796. * @type string
  9797. */
  9798. lodash.VERSION = '2.4.1';
  9799. // add "Chaining" functions to the wrapper
  9800. lodash.prototype.chain = wrapperChain;
  9801. lodash.prototype.toString = wrapperToString;
  9802. lodash.prototype.value = wrapperValueOf;
  9803. lodash.prototype.valueOf = wrapperValueOf;
  9804. // add `Array` functions that return unwrapped values
  9805. forEach(['join', 'pop', 'shift'], function(methodName) {
  9806. var func = arrayRef[methodName];
  9807. lodash.prototype[methodName] = function() {
  9808. var chainAll = this.__chain__,
  9809. result = func.apply(this.__wrapped__, arguments);
  9810. return chainAll
  9811. ? new lodashWrapper(result, chainAll)
  9812. : result;
  9813. };
  9814. });
  9815. // add `Array` functions that return the existing wrapped value
  9816. forEach(['push', 'reverse', 'sort', 'unshift'], function(methodName) {
  9817. var func = arrayRef[methodName];
  9818. lodash.prototype[methodName] = function() {
  9819. func.apply(this.__wrapped__, arguments);
  9820. return this;
  9821. };
  9822. });
  9823. // add `Array` functions that return new wrapped values
  9824. forEach(['concat', 'slice', 'splice'], function(methodName) {
  9825. var func = arrayRef[methodName];
  9826. lodash.prototype[methodName] = function() {
  9827. return new lodashWrapper(func.apply(this.__wrapped__, arguments), this.__chain__);
  9828. };
  9829. });
  9830. return lodash;
  9831. }
  9832. /*--------------------------------------------------------------------------*/
  9833. // expose Lo-Dash
  9834. var _ = runInContext();
  9835. // some AMD build optimizers like r.js check for condition patterns like the following:
  9836. if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
  9837. // Expose Lo-Dash to the global object even when an AMD loader is present in
  9838. // case Lo-Dash is loaded with a RequireJS shim config.
  9839. // See http://requirejs.org/docs/api.html#config-shim
  9840. root._ = _;
  9841. // define as an anonymous module so, through path mapping, it can be
  9842. // referenced as the "underscore" module
  9843. define(function() {
  9844. return _;
  9845. });
  9846. }
  9847. // check for `exports` after `define` in case a build optimizer adds an `exports` object
  9848. else if (freeExports && freeModule) {
  9849. // in Node.js or RingoJS
  9850. if (moduleExports) {
  9851. (freeModule.exports = _)._ = _;
  9852. }
  9853. // in Narwhal or Rhino -require
  9854. else {
  9855. freeExports._ = _;
  9856. }
  9857. }
  9858. else {
  9859. // in a browser or Rhino
  9860. root._ = _;
  9861. }
  9862. }.call(this));
  9863. }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  9864. },{}]},{},[1]);