1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141 |
- ;(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);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.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){
- var AnimatorClasses, BezierCurveAnimator, Config, Defaults, EventEmitter, Frame, LinearAnimator, SpringDHOAnimator, SpringRK4Animator, Utils, evaluateRelativeProperty, isRelativeProperty, numberRE, relativePropertyRE, _, _runningAnimations,
- __slice = [].slice,
- __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
- __hasProp = {}.hasOwnProperty,
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
- _ = require("./Underscore")._;
- Utils = require("./Utils");
- Config = require("./Config").Config;
- Defaults = require("./Defaults").Defaults;
- EventEmitter = require("./EventEmitter").EventEmitter;
- Frame = require("./Frame").Frame;
- LinearAnimator = require("./Animators/LinearAnimator").LinearAnimator;
- BezierCurveAnimator = require("./Animators/BezierCurveAnimator").BezierCurveAnimator;
- SpringRK4Animator = require("./Animators/SpringRK4Animator").SpringRK4Animator;
- SpringDHOAnimator = require("./Animators/SpringDHOAnimator").SpringDHOAnimator;
- AnimatorClasses = {
- "linear": LinearAnimator,
- "bezier-curve": BezierCurveAnimator,
- "spring-rk4": SpringRK4Animator,
- "spring-dho": SpringDHOAnimator
- };
- AnimatorClasses["spring"] = AnimatorClasses["spring-rk4"];
- AnimatorClasses["cubic-bezier"] = AnimatorClasses["bezier-curve"];
- numberRE = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/;
- relativePropertyRE = new RegExp('^(?:([+-])=|)(' + numberRE.source + ')([a-z%]*)$', 'i');
- isRelativeProperty = function(v) {
- return _.isString(v) && relativePropertyRE.test(v);
- };
- evaluateRelativeProperty = function(target, k, v) {
- var match, number, rest, sign, unit, _ref;
- _ref = relativePropertyRE.exec(v), match = _ref[0], sign = _ref[1], number = _ref[2], unit = _ref[3], rest = 5 <= _ref.length ? __slice.call(_ref, 4) : [];
- if (sign) {
- return target[k] + (sign + 1) * number;
- } else {
- return +number;
- }
- };
- _runningAnimations = [];
- exports.Animation = (function(_super) {
- __extends(Animation, _super);
- Animation.runningAnimations = function() {
- return _runningAnimations;
- };
- function Animation(options) {
- if (options == null) {
- options = {};
- }
- this.start = __bind(this.start, this);
- options = Defaults.getDefaults("Animation", options);
- Animation.__super__.constructor.call(this, options);
- this.options = Utils.setDefaultProperties(options, {
- layer: null,
- properties: {},
- curve: "linear",
- curveOptions: {},
- time: 1,
- repeat: 0,
- delay: 0,
- debug: false
- });
- if (options.origin) {
- console.warn("Animation.origin: please use layer.originX and layer.originY");
- }
- if (options.properties instanceof Frame) {
- option.properties = option.properties.properties;
- }
- this.options.properties = this._filterAnimatableProperties(this.options.properties);
- this._parseAnimatorOptions();
- this._originalState = this._currentState();
- this._repeatCounter = this.options.repeat;
- }
- Animation.prototype._filterAnimatableProperties = function(properties) {
- var animatableProperties, k, v;
- animatableProperties = {};
- for (k in properties) {
- v = properties[k];
- if (_.isNumber(v) || isRelativeProperty(v)) {
- animatableProperties[k] = v;
- }
- }
- return animatableProperties;
- };
- Animation.prototype._currentState = function() {
- return _.pick(this.options.layer, _.keys(this.options.properties));
- };
- Animation.prototype._animatorClass = function() {
- var animatorClassName, parsedCurve;
- parsedCurve = Utils.parseFunction(this.options.curve);
- animatorClassName = parsedCurve.name.toLowerCase();
- if (AnimatorClasses.hasOwnProperty(animatorClassName)) {
- return AnimatorClasses[animatorClassName];
- }
- return LinearAnimator;
- };
- Animation.prototype._parseAnimatorOptions = function() {
- var animatorClass, i, k, parsedCurve, value, _base, _i, _j, _len, _len1, _ref, _ref1, _results;
- animatorClass = this._animatorClass();
- parsedCurve = Utils.parseFunction(this.options.curve);
- if (animatorClass === LinearAnimator || animatorClass === BezierCurveAnimator) {
- if (_.isString(this.options.curveOptions) || _.isArray(this.options.curveOptions)) {
- this.options.curveOptions = {
- values: this.options.curveOptions
- };
- }
- if ((_base = this.options.curveOptions).time == null) {
- _base.time = this.options.time;
- }
- }
- if (parsedCurve.args.length) {
- if (animatorClass === BezierCurveAnimator) {
- this.options.curveOptions.values = parsedCurve.args.map(function(v) {
- return parseFloat(v) || 0;
- });
- }
- if (animatorClass === SpringRK4Animator) {
- _ref = ["tension", "friction", "velocity"];
- for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
- k = _ref[i];
- value = parseFloat(parsedCurve.args[i]);
- if (value) {
- this.options.curveOptions[k] = value;
- }
- }
- }
- if (animatorClass === SpringDHOAnimator) {
- _ref1 = ["stiffness", "damping", "mass", "tolerance"];
- _results = [];
- for (i = _j = 0, _len1 = _ref1.length; _j < _len1; i = ++_j) {
- k = _ref1[i];
- value = parseFloat(parsedCurve.args[i]);
- if (value) {
- _results.push(this.options.curveOptions[k] = value);
- } else {
- _results.push(void 0);
- }
- }
- return _results;
- }
- }
- };
- Animation.prototype.start = function() {
- var AnimatorClass, k, start, stateA, stateB, target, v, _ref,
- _this = this;
- if (this.options.layer === null) {
- console.error("Animation: missing layer");
- }
- AnimatorClass = this._animatorClass();
- if (this.options.debug) {
- console.log("Animation.start " + AnimatorClass.name, this.options.curveOptions);
- }
- this._animator = new AnimatorClass(this.options.curveOptions);
- target = this.options.layer;
- stateA = this._currentState();
- stateB = {};
- _ref = this.options.properties;
- for (k in _ref) {
- v = _ref[k];
- if (isRelativeProperty(v)) {
- v = evaluateRelativeProperty(target, k, v);
- }
- if (stateA[k] !== v) {
- stateB[k] = v;
- }
- }
- if (_.isEqual(stateA, stateB)) {
- console.warn("Nothing to animate");
- }
- if (this.options.debug) {
- console.log("Animation.start");
- for (k in stateB) {
- v = stateB[k];
- console.log("\t" + k + ": " + stateA[k] + " -> " + stateB[k]);
- }
- }
- this._animator.on("start", function() {
- return _this.emit("start");
- });
- this._animator.on("stop", function() {
- return _this.emit("stop");
- });
- this._animator.on("end", function() {
- return _this.emit("end");
- });
- if (this._repeatCounter > 0) {
- this._animator.on("end", function() {
- for (k in stateA) {
- v = stateA[k];
- target[k] = v;
- }
- _this._repeatCounter--;
- return _this.start();
- });
- }
- this._animator.on("tick", function(value) {
- for (k in stateB) {
- v = stateB[k];
- target[k] = Utils.mapRange(value, 0, 1, stateA[k], stateB[k]);
- }
- });
- start = function() {
- _runningAnimations.push(_this);
- return _this._animator.start();
- };
- if (this.options.delay) {
- return Utils.delay(this.options.delay, start);
- } else {
- return start();
- }
- };
- Animation.prototype.stop = function() {
- var _ref;
- if ((_ref = this._animator) != null) {
- _ref.stop();
- }
- return _runningAnimations = _.without(_runningAnimations, this);
- };
- Animation.prototype.reverse = function() {
- var animation, options;
- options = _.clone(this.options);
- options.properties = this._originalState;
- animation = new Animation(options);
- return animation;
- };
- Animation.prototype.revert = function() {
- return this.reverse();
- };
- Animation.prototype.inverse = function() {
- return this.reverse();
- };
- Animation.prototype.invert = function() {
- return this.reverse();
- };
- Animation.prototype.emit = function(event) {
- Animation.__super__.emit.apply(this, arguments);
- return this.options.layer.emit(event, this);
- };
- return Animation;
- })(EventEmitter);
- },{"./Animators/BezierCurveAnimator":4,"./Animators/LinearAnimator":5,"./Animators/SpringDHOAnimator":6,"./Animators/SpringRK4Animator":7,"./Config":11,"./Defaults":13,"./EventEmitter":14,"./Frame":18,"./Underscore":28,"./Utils":29}],2:[function(require,module,exports){
- var AnimationLoop, AnimationLoopIndexKey, Config, EventEmitter, Utils, _;
- _ = require("./Underscore")._;
- Utils = require("./Utils");
- Config = require("./Config").Config;
- EventEmitter = require("./EventEmitter").EventEmitter;
- AnimationLoopIndexKey = "_animationLoopIndex";
- AnimationLoop = {
- debug: false,
- _animators: [],
- _running: false,
- _frameCounter: 0,
- _sessionTime: 0,
- _start: function() {
- if (AnimationLoop._running) {
- return;
- }
- if (!AnimationLoop._animators.length) {
- return;
- }
- AnimationLoop._running = true;
- AnimationLoop._time = Utils.getTime();
- AnimationLoop._sessionTime = 0;
- return window.requestAnimationFrame(AnimationLoop._tick);
- },
- _stop: function() {
- return AnimationLoop._running = false;
- },
- _tick: function() {
- var animator, delta, removeAnimators, time, _i, _j, _len, _len1, _ref;
- if (!AnimationLoop._animators.length) {
- return AnimationLoop._stop();
- }
- AnimationLoop._frameCounter++;
- time = Utils.getTime();
- delta = time - AnimationLoop._time;
- AnimationLoop._sessionTime += delta;
- removeAnimators = [];
- _ref = AnimationLoop._animators;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- animator = _ref[_i];
- animator.emit("tick", animator.next(delta));
- if (animator.finished()) {
- animator.emit("tick", 1);
- removeAnimators.push(animator);
- }
- }
- AnimationLoop._time = time;
- for (_j = 0, _len1 = removeAnimators.length; _j < _len1; _j++) {
- animator = removeAnimators[_j];
- AnimationLoop.remove(animator);
- animator.emit("end");
- }
- window.requestAnimationFrame(AnimationLoop._tick);
- },
- add: function(animator) {
- if (animator.hasOwnProperty(AnimationLoopIndexKey)) {
- return;
- }
- animator[AnimationLoopIndexKey] = AnimationLoop._animators.push(animator);
- animator.emit("start");
- return AnimationLoop._start();
- },
- remove: function(animator) {
- AnimationLoop._animators = _.without(AnimationLoop._animators, animator);
- return animator.emit("stop");
- }
- };
- exports.AnimationLoop = AnimationLoop;
- },{"./Config":11,"./EventEmitter":14,"./Underscore":28,"./Utils":29}],3:[function(require,module,exports){
- var AnimationLoop, Config, EventEmitter, Utils,
- __hasProp = {}.hasOwnProperty,
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
- Utils = require("./Utils");
- Config = require("./Config").Config;
- EventEmitter = require("./EventEmitter").EventEmitter;
- AnimationLoop = require("./AnimationLoop").AnimationLoop;
- exports.Animator = (function(_super) {
- __extends(Animator, _super);
- "The animator class is a very simple class that\n - Takes a set of input values at setup({input values})\n - Emits an output value for progress (0 -> 1) in value(progress)";
- function Animator(options) {
- if (options == null) {
- options = {};
- }
- this.setup(options);
- }
- Animator.prototype.setup = function(options) {
- throw Error("Not implemented");
- };
- Animator.prototype.next = function(delta) {
- throw Error("Not implemented");
- };
- Animator.prototype.finished = function() {
- throw Error("Not implemented");
- };
- Animator.prototype.start = function() {
- return AnimationLoop.add(this);
- };
- Animator.prototype.stop = function() {
- return AnimationLoop.remove(this);
- };
- return Animator;
- })(EventEmitter);
- },{"./AnimationLoop":2,"./Config":11,"./EventEmitter":14,"./Utils":29}],4:[function(require,module,exports){
- var Animator, BezierCurveDefaults, UnitBezier, Utils, _, _ref,
- __hasProp = {}.hasOwnProperty,
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
- _ = require("../Underscore")._;
- Utils = require("../Utils");
- Animator = require("../Animator").Animator;
- BezierCurveDefaults = {
- "linear": [0, 0, 1, 1],
- "ease": [.25, .1, .25, 1],
- "ease-in": [.42, 0, 1, 1],
- "ease-out": [0, 0, .58, 1],
- "ease-in-out": [.42, 0, .58, 1]
- };
- exports.BezierCurveAnimator = (function(_super) {
- __extends(BezierCurveAnimator, _super);
- function BezierCurveAnimator() {
- _ref = BezierCurveAnimator.__super__.constructor.apply(this, arguments);
- return _ref;
- }
- BezierCurveAnimator.prototype.setup = function(options) {
- if (_.isString(options) && BezierCurveDefaults.hasOwnProperty(options.toLowerCase())) {
- options = {
- values: BezierCurveDefaults[options.toLowerCase()]
- };
- }
- if (options.values && _.isString(options.values) && BezierCurveDefaults.hasOwnProperty(options.values.toLowerCase())) {
- options = {
- values: BezierCurveDefaults[options.values.toLowerCase()],
- time: options.time
- };
- }
- if (_.isArray(options) && options.length === 4) {
- options = {
- values: options
- };
- }
- this.options = Utils.setDefaultProperties(options, {
- values: BezierCurveDefaults["ease-in-out"],
- time: 1
- });
- return this._unitBezier = new UnitBezier(this.options.values[0], this.options.values[1], this.options.values[2], this.options.values[3], this._time = 0);
- };
- BezierCurveAnimator.prototype.next = function(delta) {
- this._time += delta;
- if (this.finished()) {
- return 1;
- }
- return this._unitBezier.solve(this._time / this.options.time);
- };
- BezierCurveAnimator.prototype.finished = function() {
- return this._time >= this.options.time;
- };
- return BezierCurveAnimator;
- })(Animator);
- UnitBezier = (function() {
- UnitBezier.prototype.epsilon = 1e-6;
- function UnitBezier(p1x, p1y, p2x, p2y) {
- this.cx = 3.0 * p1x;
- this.bx = 3.0 * (p2x - p1x) - this.cx;
- this.ax = 1.0 - this.cx - this.bx;
- this.cy = 3.0 * p1y;
- this.by = 3.0 * (p2y - p1y) - this.cy;
- this.ay = 1.0 - this.cy - this.by;
- }
- UnitBezier.prototype.sampleCurveX = function(t) {
- return ((this.ax * t + this.bx) * t + this.cx) * t;
- };
- UnitBezier.prototype.sampleCurveY = function(t) {
- return ((this.ay * t + this.by) * t + this.cy) * t;
- };
- UnitBezier.prototype.sampleCurveDerivativeX = function(t) {
- return (3.0 * this.ax * t + 2.0 * this.bx) * t + this.cx;
- };
- UnitBezier.prototype.solveCurveX = function(x) {
- var d2, i, t0, t1, t2, x2;
- t2 = x;
- i = 0;
- while (i < 8) {
- x2 = this.sampleCurveX(t2) - x;
- if (Math.abs(x2) < this.epsilon) {
- return t2;
- }
- d2 = this.sampleCurveDerivativeX(t2);
- if (Math.abs(d2) < this.epsilon) {
- break;
- }
- t2 = t2 - x2 / d2;
- i++;
- }
- t0 = 0.0;
- t1 = 1.0;
- t2 = x;
- if (t2 < t0) {
- return t0;
- }
- if (t2 > t1) {
- return t1;
- }
- while (t0 < t1) {
- x2 = this.sampleCurveX(t2);
- if (Math.abs(x2 - x) < this.epsilon) {
- return t2;
- }
- if (x > x2) {
- t0 = t2;
- } else {
- t1 = t2;
- }
- t2 = (t1 - t0) * .5 + t0;
- }
- return t2;
- };
- UnitBezier.prototype.solve = function(x) {
- return this.sampleCurveY(this.solveCurveX(x));
- };
- return UnitBezier;
- })();
- },{"../Animator":3,"../Underscore":28,"../Utils":29}],5:[function(require,module,exports){
- var Animator, Utils, _ref,
- __hasProp = {}.hasOwnProperty,
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
- Utils = require("../Utils");
- Animator = require("../Animator").Animator;
- exports.LinearAnimator = (function(_super) {
- __extends(LinearAnimator, _super);
- function LinearAnimator() {
- _ref = LinearAnimator.__super__.constructor.apply(this, arguments);
- return _ref;
- }
- LinearAnimator.prototype.setup = function(options) {
- this.options = Utils.setDefaultProperties(options, {
- time: 1
- });
- return this._time = 0;
- };
- LinearAnimator.prototype.next = function(delta) {
- if (this.finished()) {
- return 1;
- }
- this._time += delta;
- return this._time / this.options.time;
- };
- LinearAnimator.prototype.finished = function() {
- return this._time >= this.options.time;
- };
- return LinearAnimator;
- })(Animator);
- },{"../Animator":3,"../Utils":29}],6:[function(require,module,exports){
- var Animator, Utils, _ref,
- __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
- __hasProp = {}.hasOwnProperty,
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
- Utils = require("../Utils");
- Animator = require("../Animator").Animator;
- exports.SpringDHOAnimator = (function(_super) {
- __extends(SpringDHOAnimator, _super);
- function SpringDHOAnimator() {
- this.finished = __bind(this.finished, this);
- _ref = SpringDHOAnimator.__super__.constructor.apply(this, arguments);
- return _ref;
- }
- SpringDHOAnimator.prototype.setup = function(options) {
- this.options = Utils.setDefaultProperties(options, {
- velocity: 0,
- tolerance: 1 / 10000,
- stiffness: 50,
- damping: 2,
- mass: 0.2,
- time: null
- });
- console.log("SpringDHOAnimator.options", this.options, options);
- this._time = 0;
- this._value = 0;
- return this._velocity = this.options.velocity;
- };
- SpringDHOAnimator.prototype.next = function(delta) {
- var F_damper, F_spring, b, k;
- if (this.finished()) {
- return 1;
- }
- this._time += delta;
- k = 0 - this.options.stiffness;
- b = 0 - this.options.damping;
- F_spring = k * (this._value - 1);
- F_damper = b * this._velocity;
- this._velocity += ((F_spring + F_damper) / this.options.mass) * delta;
- this._value += this._velocity * delta;
- return this._value;
- };
- SpringDHOAnimator.prototype.finished = function() {
- return this._time > 0 && Math.abs(this._velocity) < this.options.tolerance;
- };
- return SpringDHOAnimator;
- })(Animator);
- },{"../Animator":3,"../Utils":29}],7:[function(require,module,exports){
- var Animator, Utils, springAccelerationForState, springEvaluateState, springEvaluateStateWithDerivative, springIntegrateState, _ref,
- __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
- __hasProp = {}.hasOwnProperty,
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
- Utils = require("../Utils");
- Animator = require("../Animator").Animator;
- exports.SpringRK4Animator = (function(_super) {
- __extends(SpringRK4Animator, _super);
- function SpringRK4Animator() {
- this.finished = __bind(this.finished, this);
- _ref = SpringRK4Animator.__super__.constructor.apply(this, arguments);
- return _ref;
- }
- SpringRK4Animator.prototype.setup = function(options) {
- this.options = Utils.setDefaultProperties(options, {
- tension: 500,
- friction: 10,
- velocity: 0,
- tolerance: 1 / 10000,
- time: null
- });
- this._time = 0;
- this._value = 0;
- this._velocity = this.options.velocity;
- return this._stopSpring = false;
- };
- SpringRK4Animator.prototype.next = function(delta) {
- var finalVelocity, net1DVelocity, netFloat, netValueIsLow, netVelocityIsLow, stateAfter, stateBefore;
- if (this.finished()) {
- return 1;
- }
- this._time += delta;
- stateBefore = {};
- stateAfter = {};
- stateBefore.x = this._value - 1;
- stateBefore.v = this._velocity;
- stateBefore.tension = this.options.tension;
- stateBefore.friction = this.options.friction;
- stateAfter = springIntegrateState(stateBefore, delta);
- this._value = 1 + stateAfter.x;
- finalVelocity = stateAfter.v;
- netFloat = stateAfter.x;
- net1DVelocity = stateAfter.v;
- netValueIsLow = Math.abs(netFloat) < this.options.tolerance;
- netVelocityIsLow = Math.abs(net1DVelocity) < this.options.tolerance;
- this._stopSpring = netValueIsLow && netVelocityIsLow;
- this._velocity = finalVelocity;
- return this._value;
- };
- SpringRK4Animator.prototype.finished = function() {
- return this._stopSpring;
- };
- return SpringRK4Animator;
- })(Animator);
- springAccelerationForState = function(state) {
- return -state.tension * state.x - state.friction * state.v;
- };
- springEvaluateState = function(initialState) {
- var output;
- output = {};
- output.dx = initialState.v;
- output.dv = springAccelerationForState(initialState);
- return output;
- };
- springEvaluateStateWithDerivative = function(initialState, dt, derivative) {
- var output, state;
- state = {};
- state.x = initialState.x + derivative.dx * dt;
- state.v = initialState.v + derivative.dv * dt;
- state.tension = initialState.tension;
- state.friction = initialState.friction;
- output = {};
- output.dx = state.v;
- output.dv = springAccelerationForState(state);
- return output;
- };
- springIntegrateState = function(state, speed) {
- var a, b, c, d, dvdt, dxdt;
- a = springEvaluateState(state);
- b = springEvaluateStateWithDerivative(state, speed * 0.5, a);
- c = springEvaluateStateWithDerivative(state, speed * 0.5, b);
- d = springEvaluateStateWithDerivative(state, speed, c);
- dxdt = 1.0 / 6.0 * (a.dx + 2.0 * (b.dx + c.dx) + d.dx);
- dvdt = 1.0 / 6.0 * (a.dv + 2.0 * (b.dv + c.dv) + d.dv);
- state.x = state.x + dxdt * speed;
- state.v = state.v + dvdt * speed;
- return state;
- };
- },{"../Animator":3,"../Utils":29}],8:[function(require,module,exports){
- var Layer,
- __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
- __hasProp = {}.hasOwnProperty,
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
- Layer = require("./Layer").Layer;
- "Todo: make it work in a parent layer";
- exports.BackgroundLayer = (function(_super) {
- __extends(BackgroundLayer, _super);
- function BackgroundLayer(options) {
- if (options == null) {
- options = {};
- }
- this.layout = __bind(this.layout, this);
- if (options.backgroundColor == null) {
- options.backgroundColor = "#fff";
- }
- options.name = "Background";
- BackgroundLayer.__super__.constructor.call(this, options);
- this.sendToBack();
- this.layout();
- Screen.on("resize", this.layout);
- }
- BackgroundLayer.prototype.layout = function() {
- this.width = Screen.width;
- return this.height = Screen.height;
- };
- return BackgroundLayer;
- })(Layer);
- },{"./Layer":21}],9:[function(require,module,exports){
- var CounterKey, DefinedPropertiesKey, DefinedPropertiesValuesKey, EventEmitter, Utils, _,
- __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
- __hasProp = {}.hasOwnProperty,
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
- _ = require("./Underscore")._;
- Utils = require("./Utils");
- EventEmitter = require("./EventEmitter").EventEmitter;
- CounterKey = "_ObjectCounter";
- DefinedPropertiesKey = "_DefinedPropertiesKey";
- DefinedPropertiesValuesKey = "_DefinedPropertiesValuesKey";
- exports.BaseClass = (function(_super) {
- __extends(BaseClass, _super);
- BaseClass.define = function(propertyName, descriptor) {
- if (this !== BaseClass && descriptor.exportable === true) {
- descriptor.propertyName = propertyName;
- if (this[DefinedPropertiesKey] == null) {
- this[DefinedPropertiesKey] = {};
- }
- this[DefinedPropertiesKey][propertyName] = descriptor;
- }
- Object.defineProperty(this.prototype, propertyName, descriptor);
- return Object.__;
- };
- BaseClass.simpleProperty = function(name, fallback, exportable) {
- if (exportable == null) {
- exportable = true;
- }
- return {
- exportable: exportable,
- "default": fallback,
- get: function() {
- return this._getPropertyValue(name);
- },
- set: function(value) {
- return this._setPropertyValue(name, value);
- }
- };
- };
- BaseClass.prototype._setPropertyValue = function(k, v) {
- return this[DefinedPropertiesValuesKey][k] = v;
- };
- BaseClass.prototype._getPropertyValue = function(k) {
- return Utils.valueOrDefault(this[DefinedPropertiesValuesKey][k], this._getPropertyDefaultValue(k));
- };
- BaseClass.prototype._getPropertyDefaultValue = function(k) {
- return this.constructor[DefinedPropertiesKey][k]["default"];
- };
- BaseClass.prototype._propertyList = function() {
- return this.constructor[DefinedPropertiesKey];
- };
- BaseClass.prototype.keys = function() {
- return _.keys(this.properties);
- };
- BaseClass.define("properties", {
- get: function() {
- var k, properties, v, _ref;
- properties = {};
- _ref = this.constructor[DefinedPropertiesKey];
- for (k in _ref) {
- v = _ref[k];
- if (v.exportable !== false) {
- properties[k] = this[k];
- }
- }
- return properties;
- },
- set: function(value) {
- var k, v, _results;
- _results = [];
- for (k in value) {
- v = value[k];
- if (this.constructor[DefinedPropertiesKey].hasOwnProperty(k)) {
- if (this.constructor[DefinedPropertiesKey].exportable !== false) {
- _results.push(this[k] = v);
- } else {
- _results.push(void 0);
- }
- } else {
- _results.push(void 0);
- }
- }
- return _results;
- }
- });
- BaseClass.define("id", {
- get: function() {
- return this._id;
- }
- });
- BaseClass.prototype.toString = function() {
- var properties;
- properties = _.map(this.properties, (function(v, k) {
- return "" + k + ":" + v;
- }), 4);
- return "[" + this.constructor.name + " id:" + this.id + " " + (properties.join(" ")) + "]";
- };
- function BaseClass(options) {
- var _base,
- _this = this;
- if (options == null) {
- options = {};
- }
- this.toString = __bind(this.toString, this);
- this._getPropertyValue = __bind(this._getPropertyValue, this);
- this._setPropertyValue = __bind(this._setPropertyValue, this);
- BaseClass.__super__.constructor.apply(this, arguments);
- this[DefinedPropertiesValuesKey] = {};
- if ((_base = this.constructor)[CounterKey] == null) {
- _base[CounterKey] = 0;
- }
- this.constructor[CounterKey] += 1;
- this._id = this.constructor[CounterKey];
- _.map(this.constructor[DefinedPropertiesKey], function(descriptor, name) {
- return _this[name] = Utils.valueOrDefault(options[name], _this._getPropertyDefaultValue(name));
- });
- }
- return BaseClass;
- })(EventEmitter);
- },{"./EventEmitter":14,"./Underscore":28,"./Utils":29}],10:[function(require,module,exports){
- var CompatImageView, CompatLayer, CompatScrollView, CompatView, Layer, compatProperty, compatWarning, _ref,
- __hasProp = {}.hasOwnProperty,
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
- Layer = require("./Layer").Layer;
- compatWarning = function(msg) {
- return console.warn(msg);
- };
- compatProperty = function(name, originalName) {
- return {
- exportable: false,
- get: function() {
- compatWarning("" + originalName + " is a deprecated property");
- return this[name];
- },
- set: function(value) {
- compatWarning("" + originalName + " is a deprecated property");
- return this[name] = value;
- }
- };
- };
- CompatLayer = (function(_super) {
- var addSubView, removeSubView;
- __extends(CompatLayer, _super);
- function CompatLayer(options) {
- if (options == null) {
- options = {};
- }
- if (options.hasOwnProperty("superView")) {
- options.superLayer = options.superView;
- }
- CompatLayer.__super__.constructor.call(this, options);
- }
- CompatLayer.define("superView", compatProperty("superLayer", "superView"));
- CompatLayer.define("subViews", compatProperty("subLayers", "subViews"));
- CompatLayer.define("siblingViews", compatProperty("siblingLayers", "siblingViews"));
- addSubView = function(layer) {
- return this.addSubLayer(layer);
- };
- removeSubView = function(layer) {
- return this.removeSubLayer(layer);
- };
- return CompatLayer;
- })(Layer);
- CompatView = (function(_super) {
- __extends(CompatView, _super);
- function CompatView(options) {
- if (options == null) {
- options = {};
- }
- compatWarning("Views are now called Layers");
- CompatView.__super__.constructor.call(this, options);
- }
- return CompatView;
- })(CompatLayer);
- CompatImageView = (function(_super) {
- __extends(CompatImageView, _super);
- function CompatImageView() {
- _ref = CompatImageView.__super__.constructor.apply(this, arguments);
- return _ref;
- }
- return CompatImageView;
- })(CompatView);
- CompatScrollView = (function(_super) {
- __extends(CompatScrollView, _super);
- function CompatScrollView() {
- CompatScrollView.__super__.constructor.apply(this, arguments);
- this.scroll = true;
- }
- return CompatScrollView;
- })(CompatView);
- window.Layer = CompatLayer;
- window.Framer.Layer = CompatLayer;
- window.View = CompatView;
- window.ImageView = CompatImageView;
- window.ScrollView = CompatScrollView;
- window.utils = window.Utils;
- },{"./Layer":21}],11:[function(require,module,exports){
- var Utils;
- Utils = require("./Utils");
- exports.Config = {
- targetFPS: 60,
- rootBaseCSS: {
- "-webkit-perspective": 1000,
- "position": "absolute",
- "left": 0,
- "top": 0,
- "right": 0,
- "bottom": 0
- },
- layerBaseCSS: {
- "display": "block",
- "position": "absolute",
- "-webkit-box-sizing": "border-box",
- "-webkit-user-select": "none",
- "background-repeat": "no-repeat",
- "background-size": "cover",
- "-webkit-overflow-scrolling": "touch"
- }
- };
- },{"./Utils":29}],12:[function(require,module,exports){
- var EventKeys, Utils, createDebugLayer, errorWarning, hideDebug, showDebug, toggleDebug, _debugLayers, _errorWarningLayer;
- Utils = require("./Utils");
- _debugLayers = null;
- createDebugLayer = function(layer) {
- var overLayer;
- overLayer = new Layer({
- frame: layer.screenFrame(),
- backgroundColor: "rgba(50,150,200,.35)"
- });
- overLayer.style = {
- textAlign: "center",
- color: "white",
- font: "10px/1em Monaco",
- lineHeight: "" + (overLayer.height + 1) + "px",
- boxShadow: "inset 0 0 0 1px rgba(255,255,255,.5)"
- };
- overLayer.html = layer.name || layer.id;
- overLayer.on(Events.Click, function(event, layer) {
- layer.scale = 0.8;
- return layer.animate({
- properties: {
- scale: 1
- },
- curve: "spring(1000,10,0)"
- });
- });
- return overLayer;
- };
- showDebug = function() {
- return _debugLayers = Layer.Layers().map(createDebugLayer);
- };
- hideDebug = function() {
- return _debugLayers.map(function(layer) {
- return layer.destroy();
- });
- };
- toggleDebug = Utils.toggle(showDebug, hideDebug);
- EventKeys = {
- Shift: 16,
- Escape: 27
- };
- window.document.onkeyup = function(event) {
- if (event.keyCode === EventKeys.Escape) {
- return toggleDebug()();
- }
- };
- _errorWarningLayer = null;
- errorWarning = function() {
- var layer;
- if (_errorWarningLayer) {
- return;
- }
- layer = new Layer({
- x: 20,
- y: -50,
- width: 300,
- height: 40
- });
- layer.states.add({
- visible: {
- x: 20,
- y: 20,
- width: 300,
- height: 40
- }
- });
- layer.html = "Javascript Error, see the console";
- layer.style = {
- font: "12px/1.35em Menlo",
- color: "white",
- textAlign: "center",
- lineHeight: "" + layer.height + "px",
- borderRadius: "5px",
- backgroundColor: "rgba(255,0,0,.8)"
- };
- layer.states.animationOptions = {
- curve: "spring",
- curveOptions: {
- tension: 1000,
- friction: 30
- }
- };
- layer.states["switch"]("visible");
- layer.on(Events.Click, function() {
- return this.states["switch"]("default");
- });
- return _errorWarningLayer = layer;
- };
- window.onerror = errorWarning;
- },{"./Utils":29}],13:[function(require,module,exports){
- var Originals, Utils, _;
- _ = require("./Underscore")._;
- Utils = require("./Utils");
- Originals = {
- Layer: {
- backgroundColor: "rgba(0,124,255,.5)",
- width: 100,
- height: 100
- },
- Animation: {
- curve: "linear",
- time: 1
- }
- };
- exports.Defaults = {
- getDefaults: function(className, options) {
- var defaults, k, v, _ref;
- defaults = _.clone(Originals[className]);
- _ref = Framer.Defaults[className];
- for (k in _ref) {
- v = _ref[k];
- defaults[k] = _.isFunction(v) ? v() : v;
- }
- for (k in defaults) {
- v = defaults[k];
- if (!options.hasOwnProperty(k)) {
- options[k] = v;
- }
- }
- return options;
- },
- reset: function() {
- return window.Framer.Defaults = _.clone(Originals);
- }
- };
- },{"./Underscore":28,"./Utils":29}],14:[function(require,module,exports){
- var EventEmitterEventsKey, _,
- __slice = [].slice;
- _ = require("./Underscore")._;
- EventEmitterEventsKey = "_events";
- exports.EventEmitter = (function() {
- function EventEmitter() {
- this[EventEmitterEventsKey] = {};
- }
- EventEmitter.prototype._eventCheck = function(event, method) {
- if (!event) {
- return console.warn("" + this.constructor.name + "." + method + " missing event (like 'click')");
- }
- };
- EventEmitter.prototype.emit = function() {
- var args, event, listener, _i, _len, _ref, _ref1;
- event = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
- if (!((_ref = this[EventEmitterEventsKey]) != null ? _ref[event] : void 0)) {
- return;
- }
- _ref1 = this[EventEmitterEventsKey][event];
- for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
- listener = _ref1[_i];
- listener.apply(null, args);
- }
- };
- EventEmitter.prototype.addListener = function(event, listener) {
- var _base;
- this._eventCheck(event, "addListener");
- if (this[EventEmitterEventsKey] == null) {
- this[EventEmitterEventsKey] = {};
- }
- if ((_base = this[EventEmitterEventsKey])[event] == null) {
- _base[event] = [];
- }
- return this[EventEmitterEventsKey][event].push(listener);
- };
- EventEmitter.prototype.removeListener = function(event, listener) {
- this._eventCheck(event, "removeListener");
- if (!this[EventEmitterEventsKey]) {
- return;
- }
- if (!this[EventEmitterEventsKey][event]) {
- return;
- }
- this[EventEmitterEventsKey][event] = _.without(this[EventEmitterEventsKey][event], listener);
- };
- EventEmitter.prototype.once = function(event, listener) {
- var fn,
- _this = this;
- fn = function() {
- _this.removeListener(event, fn);
- return listener.apply(null, arguments);
- };
- return this.on(event, fn);
- };
- EventEmitter.prototype.removeAllListeners = function(event) {
- var listener, _i, _len, _ref;
- if (!this[EventEmitterEventsKey]) {
- return;
- }
- if (!this[EventEmitterEventsKey][event]) {
- return;
- }
- _ref = this[EventEmitterEventsKey][event];
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- listener = _ref[_i];
- this.removeListener(event, listener);
- }
- };
- EventEmitter.prototype.on = EventEmitter.prototype.addListener;
- EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
- return EventEmitter;
- })();
- },{"./Underscore":28}],15:[function(require,module,exports){
- var Events, Utils, _;
- _ = require("./Underscore")._;
- Utils = require("./Utils");
- Events = {};
- if (Utils.isTouch()) {
- Events.TouchStart = "touchstart";
- Events.TouchEnd = "touchend";
- Events.TouchMove = "touchmove";
- } else {
- Events.TouchStart = "mousedown";
- Events.TouchEnd = "mouseup";
- Events.TouchMove = "mousemove";
- }
- Events.Click = Events.TouchEnd;
- Events.MouseOver = "mouseover";
- Events.MouseOut = "mouseout";
- Events.AnimationStart = "start";
- Events.AnimationStop = "stop";
- Events.AnimationEnd = "end";
- Events.Scroll = "scroll";
- Events.touchEvent = function(event) {
- var touchEvent, _ref, _ref1;
- touchEvent = (_ref = event.touches) != null ? _ref[0] : void 0;
- if (touchEvent == null) {
- touchEvent = (_ref1 = event.changedTouches) != null ? _ref1[0] : void 0;
- }
- if (touchEvent == null) {
- touchEvent = event;
- }
- return touchEvent;
- };
- exports.Events = Events;
- },{"./Underscore":28,"./Utils":29}],16:[function(require,module,exports){
- exports.MobileScrollFix = require("./MobileScrollFix");
- },{"./MobileScrollFix":17}],17:[function(require,module,exports){
- var Utils,
- __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
- __hasProp = {}.hasOwnProperty,
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
- Utils = require("../Utils");
- exports.enable = function() {
- var MobileScrollFixLayer, handleScrollingLayerTouchMove, handleScrollingLayerTouchStart;
- handleScrollingLayerTouchMove = function(event) {
- return event.stopPropagation();
- };
- handleScrollingLayerTouchStart = function(event) {
- var element, startTopScroll;
- element = this._element;
- startTopScroll = element.scrollTop;
- if (startTopScroll <= 0) {
- element.scrollTop = 1;
- }
- if (startTopScroll + element.offsetHeight >= element.scrollHeight) {
- return element.scrollTop = element.scrollHeight - element.offsetHeight - 1;
- }
- };
- MobileScrollFixLayer = (function(_super) {
- __extends(MobileScrollFixLayer, _super);
- function MobileScrollFixLayer(options) {
- this.__createRootElement = __bind(this.__createRootElement, this);
- this._updateScrollListeners = __bind(this._updateScrollListeners, this);
- MobileScrollFixLayer.__super__.constructor.call(this, options);
- this.on("change:scrollVertical", this._updateScrollListeners);
- this._updateScrollListeners();
- }
- MobileScrollFixLayer.prototype._updateScrollListeners = function() {
- if (this.scrollVertical === true) {
- this.on("touchmove", handleScrollingLayerTouchMove);
- return this.on("touchstart", handleScrollingLayerTouchStart);
- } else {
- this.off("touchmove", handleScrollingLayerTouchMove);
- return this.off("touchstart", handleScrollingLayerTouchStart);
- }
- };
- MobileScrollFixLayer.prototype.__createRootElement = function() {
- var rootElement;
- rootElement = MobileScrollFixLayer.__super__.__createRootElement.apply(this, arguments);
- rootElement.addEventListener("touchmove", function(event) {
- return event.preventDefault();
- });
- return rootElement;
- };
- return MobileScrollFixLayer;
- })(Framer.Layer);
- return window.Layer = window.Framer.Layer = MobileScrollFixLayer;
- };
- },{"../Utils":29}],18:[function(require,module,exports){
- var BaseClass,
- __hasProp = {}.hasOwnProperty,
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
- BaseClass = require("./BaseClass").BaseClass;
- exports.Frame = (function(_super) {
- __extends(Frame, _super);
- Frame.define("x", Frame.simpleProperty("x", 0));
- Frame.define("y", Frame.simpleProperty("y", 0));
- Frame.define("width", Frame.simpleProperty("width", 0));
- Frame.define("height", Frame.simpleProperty("height", 0));
- Frame.define("minX", Frame.simpleProperty("x", 0, false));
- Frame.define("minY", Frame.simpleProperty("y", 0, false));
- function Frame(options) {
- var k, _i, _len, _ref;
- if (options == null) {
- options = {};
- }
- Frame.__super__.constructor.call(this, options);
- _ref = ["minX", "midX", "maxX", "minY", "midY", "maxY"];
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- k = _ref[_i];
- if (options.hasOwnProperty(k)) {
- this[k] = options[k];
- }
- }
- }
- Frame.define("midX", {
- get: function() {
- return Utils.frameGetMidX(this);
- },
- set: function(value) {
- return Utils.frameSetMidX(this, value);
- }
- });
- Frame.define("maxX", {
- get: function() {
- return Utils.frameGetMaxX(this);
- },
- set: function(value) {
- return Utils.frameSetMaxX(this, value);
- }
- });
- Frame.define("midY", {
- get: function() {
- return Utils.frameGetMidY(this);
- },
- set: function(value) {
- return Utils.frameSetMidY(this, value);
- }
- });
- Frame.define("maxY", {
- get: function() {
- return Utils.frameGetMaxY(this);
- },
- set: function(value) {
- return Utils.frameSetMaxY(this, value);
- }
- });
- return Frame;
- })(BaseClass);
- },{"./BaseClass":9}],19:[function(require,module,exports){
- var Defaults, Framer, _;
- _ = require("./Underscore")._;
- Framer = {};
- Framer._ = _;
- Framer.Utils = require("./Utils");
- Framer.Frame = (require("./Frame")).Frame;
- Framer.Layer = (require("./Layer")).Layer;
- Framer.BackgroundLayer = (require("./BackgroundLayer")).BackgroundLayer;
- Framer.VideoLayer = (require("./VideoLayer")).VideoLayer;
- Framer.Events = (require("./Events")).Events;
- Framer.Animation = (require("./Animation")).Animation;
- Framer.Screen = (require("./Screen")).Screen;
- Framer.print = (require("./Print")).print;
- if (window) {
- _.extend(window, Framer);
- }
- Framer.Config = (require("./Config")).Config;
- Framer.EventEmitter = (require("./EventEmitter")).EventEmitter;
- Framer.BaseClass = (require("./BaseClass")).BaseClass;
- Framer.LayerStyle = (require("./LayerStyle")).LayerStyle;
- Framer.AnimationLoop = (require("./AnimationLoop")).AnimationLoop;
- Framer.LinearAnimator = (require("./Animators/LinearAnimator")).LinearAnimator;
- Framer.BezierCurveAnimator = (require("./Animators/BezierCurveAnimator")).BezierCurveAnimator;
- Framer.SpringDHOAnimator = (require("./Animators/SpringDHOAnimator")).SpringDHOAnimator;
- Framer.SpringRK4Animator = (require("./Animators/SpringRK4Animator")).SpringRK4Animator;
- Framer.Importer = (require("./Importer")).Importer;
- Framer.Debug = (require("./Debug")).Debug;
- Framer.Session = (require("./Session")).Session;
- Framer.Extras = require("./Extras/Extras");
- if (window) {
- window.Framer = Framer;
- }
- require("./Compat");
- if (Utils.isMobile()) {
- Framer.Extras.MobileScrollFix.enable();
- }
- Defaults = (require("./Defaults")).Defaults;
- Framer.resetDefaults = Defaults.reset;
- Framer.resetDefaults();
- },{"./Animation":1,"./AnimationLoop":2,"./Animators/BezierCurveAnimator":4,"./Animators/LinearAnimator":5,"./Animators/SpringDHOAnimator":6,"./Animators/SpringRK4Animator":7,"./BackgroundLayer":8,"./BaseClass":9,"./Compat":10,"./Config":11,"./Debug":12,"./Defaults":13,"./EventEmitter":14,"./Events":15,"./Extras/Extras":16,"./Frame":18,"./Importer":20,"./Layer":21,"./LayerStyle":24,"./Print":25,"./Screen":26,"./Session":27,"./Underscore":28,"./Utils":29,"./VideoLayer":30}],20:[function(require,module,exports){
- var ChromeAlert, Utils, _;
- _ = require("./Underscore")._;
- Utils = require("./Utils");
- ChromeAlert = "Importing layers is currently only supported on Safari. If you really want it to work with Chrome quit it, open a terminal and run:\nopen -a Google\ Chrome -–allow-file-access-from-files";
- exports.Importer = (function() {
- function Importer(path, extraLayerProperties) {
- this.path = path;
- this.extraLayerProperties = extraLayerProperties != null ? extraLayerProperties : {};
- this.paths = {
- layerInfo: Utils.pathJoin(this.path, "layers.json"),
- images: Utils.pathJoin(this.path, "images"),
- documentName: this.path.split("/").pop()
- };
- this._createdLayers = [];
- this._createdLayersByName = {};
- }
- Importer.prototype.load = function() {
- var layer, layerInfo, layersByName, _i, _j, _len, _len1, _ref, _ref1,
- _this = this;
- layersByName = {};
- layerInfo = this._loadlayerInfo();
- layerInfo.map(function(layerItemInfo) {
- return _this._createLayer(layerItemInfo);
- });
- _ref = this._createdLayers;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- layer = _ref[_i];
- this._correctLayer(layer);
- }
- _ref1 = this._createdLayers;
- for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
- layer = _ref1[_j];
- if (!layer.superLayer) {
- layer.superLayer = null;
- }
- }
- return this._createdLayersByName;
- };
- Importer.prototype._loadlayerInfo = function() {
- var importedKey, _ref;
- importedKey = "" + this.paths.documentName + "/layers.json.js";
- if ((_ref = window.__imported__) != null ? _ref.hasOwnProperty(importedKey) : void 0) {
- return window.__imported__[importedKey];
- }
- return Framer.Utils.domLoadJSONSync(this.paths.layerInfo);
- };
- Importer.prototype._createLayer = function(info, superLayer) {
- var LayerClass, layer, layerInfo, _ref,
- _this = this;
- LayerClass = Layer;
- layerInfo = {
- shadow: true,
- name: info.name,
- frame: info.layerFrame,
- clip: false,
- backgroundColor: null,
- visible: (_ref = info.visible) != null ? _ref : true
- };
- _.extend(layerInfo, this.extraLayerProperties);
- if (info.image) {
- layerInfo.frame = info.image.frame;
- layerInfo.image = Utils.pathJoin(this.path, info.image.path);
- }
- if (info.maskFrame) {
- layerInfo.frame = info.maskFrame;
- layerInfo.clip = true;
- }
- if (superLayer != null ? superLayer.contentLayer : void 0) {
- layerInfo.superLayer = superLayer.contentLayer;
- } else if (superLayer) {
- layerInfo.superLayer = superLayer;
- }
- layer = new LayerClass(layerInfo);
- layer.name = layerInfo.name;
- if (!layer.image && !info.children.length && !info.maskFrame) {
- layer.frame = new Frame;
- }
- info.children.reverse().map(function(info) {
- return _this._createLayer(info, layer);
- });
- if (!layer.image && !info.maskFrame) {
- layer.frame = layer.contentFrame();
- }
- layer._info = info;
- this._createdLayers.push(layer);
- return this._createdLayersByName[layer.name] = layer;
- };
- Importer.prototype._correctLayer = function(layer) {
- var traverse;
- traverse = function(layer) {
- var subLayer, _i, _len, _ref, _results;
- if (layer.superLayer) {
- layer.frame = Utils.convertPoint(layer.frame, null, layer.superLayer);
- }
- _ref = layer.subLayers;
- _results = [];
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- subLayer = _ref[_i];
- _results.push(traverse(subLayer));
- }
- return _results;
- };
- if (!layer.superLayer) {
- return traverse(layer);
- }
- };
- return Importer;
- })();
- exports.Importer.load = function(path) {
- var importer;
- importer = new exports.Importer(path);
- return importer.load();
- };
- },{"./Underscore":28,"./Utils":29}],21:[function(require,module,exports){
- var Animation, BaseClass, Config, Defaults, EventEmitter, Frame, LayerDraggable, LayerStates, LayerStyle, Session, Utils, frameProperty, layerProperty, layerStyleProperty, _,
- __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
- __hasProp = {}.hasOwnProperty,
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
- __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
- __slice = [].slice;
- _ = require("./Underscore")._;
- Utils = require("./Utils");
- Config = require("./Config").Config;
- Defaults = require("./Defaults").Defaults;
- Session = require("./Session").Session;
- BaseClass = require("./BaseClass").BaseClass;
- EventEmitter = require("./EventEmitter").EventEmitter;
- Animation = require("./Animation").Animation;
- Frame = require("./Frame").Frame;
- LayerStyle = require("./LayerStyle").LayerStyle;
- LayerStates = require("./LayerStates").LayerStates;
- LayerDraggable = require("./LayerDraggable").LayerDraggable;
- Session._RootElement = null;
- Session._LayerList = [];
- layerProperty = function(name, cssProperty, fallback, validator, set) {
- return {
- exportable: true,
- "default": fallback,
- get: function() {
- return this._getPropertyValue(name);
- },
- set: function(value) {
- if ((typeof validator === "function" ? validator(value) : void 0) === false) {
- throw Error("value '" + value + "' of type " + (typeof value) + " is not valid for a Layer." + name + " property");
- }
- this._setPropertyValue(name, value);
- this.style[cssProperty] = LayerStyle[cssProperty](this);
- this.emit("change:" + name, value);
- if (set) {
- return set(this, value);
- }
- }
- };
- };
- layerStyleProperty = function(cssProperty) {
- return {
- exportable: true,
- get: function() {
- return this.style[cssProperty];
- },
- set: function(value) {
- this.style[cssProperty] = value;
- return this.emit("change:" + cssProperty, value);
- }
- };
- };
- frameProperty = function(name) {
- return {
- exportable: false,
- get: function() {
- return this.frame[name];
- },
- set: function(value) {
- var frame;
- frame = this.frame;
- frame[name] = value;
- return this.frame = frame;
- }
- };
- };
- exports.Layer = (function(_super) {
- __extends(Layer, _super);
- function Layer(options) {
- var frame;
- if (options == null) {
- options = {};
- }
- this.addListener = __bind(this.addListener, this);
- this.__insertElement = __bind(this.__insertElement, this);
- this.__createRootElement = __bind(this.__createRootElement, this);
- Session._LayerList.push(this);
- this._prefer2d = false;
- this._createElement();
- this._setDefaultCSS();
- options = Defaults.getDefaults("Layer", options);
- Layer.__super__.constructor.call(this, options);
- this._element.id = "FramerLayer-" + this.id;
- if (options.hasOwnProperty("frame")) {
- frame = new Frame(options.frame);
- } else {
- frame = new Frame(options);
- }
- this.frame = frame;
- if (!options.superLayer) {
- this.bringToFront();
- if (!options.shadow) {
- this._insertElement();
- }
- } else {
- this.superLayer = options.superLayer;
- }
- this._subLayers = [];
- }
- Layer.define("width", layerProperty("width", "width", 100, _.isNumber));
- Layer.define("height", layerProperty("height", "height", 100, _.isNumber));
- Layer.define("visible", layerProperty("visible", "display", true, _.isBool));
- Layer.define("opacity", layerProperty("opacity", "opacity", 1, _.isNumber));
- Layer.define("index", layerProperty("index", "zIndex", 0, _.isNumber));
- Layer.define("clip", layerProperty("clip", "overflow", true, _.isBool));
- Layer.define("scrollHorizontal", layerProperty("scrollHorizontal", "overflowX", false, _.isBool, function(layer, value) {
- if (value === true) {
- return layer.ignoreEvents = false;
- }
- }));
- Layer.define("scrollVertical", layerProperty("scrollVertical", "overflowY", false, _.isBool, function(layer, value) {
- if (value === true) {
- return layer.ignoreEvents = false;
- }
- }));
- Layer.define("scroll", {
- get: function() {
- return this.scrollHorizontal === true || this.scrollVertical === true;
- },
- set: function(value) {
- return this.scrollHorizontal = this.scrollVertical = true;
- }
- });
- Layer.define("ignoreEvents", layerProperty("ignoreEvents", "pointerEvents", true, _.isBool));
- Layer.define("x", layerProperty("x", "webkitTransform", 0, _.isNumber));
- Layer.define("y", layerProperty("y", "webkitTransform", 0, _.isNumber));
- Layer.define("z", layerProperty("z", "webkitTransform", 0, _.isNumber));
- Layer.define("scaleX", layerProperty("scaleX", "webkitTransform", 1, _.isNumber));
- Layer.define("scaleY", layerProperty("scaleY", "webkitTransform", 1, _.isNumber));
- Layer.define("scaleZ", layerProperty("scaleZ", "webkitTransform", 1, _.isNumber));
- Layer.define("scale", layerProperty("scale", "webkitTransform", 1, _.isNumber));
- Layer.define("skewX", layerProperty("skewX", "webkitTransform", 0, _.isNumber));
- Layer.define("skewY", layerProperty("skewY", "webkitTransform", 0, _.isNumber));
- Layer.define("skew", layerProperty("skew", "webkitTransform", 0, _.isNumber));
- Layer.define("originX", layerProperty("originX", "webkitTransformOrigin", 0.5, _.isNumber));
- Layer.define("originY", layerProperty("originY", "webkitTransformOrigin", 0.5, _.isNumber));
- Layer.define("rotationX", layerProperty("rotationX", "webkitTransform", 0, _.isNumber));
- Layer.define("rotationY", layerProperty("rotationY", "webkitTransform", 0, _.isNumber));
- Layer.define("rotationZ", layerProperty("rotationZ", "webkitTransform", 0, _.isNumber));
- Layer.define("rotation", layerProperty("rotationZ", "webkitTransform", 0, _.isNumber));
- Layer.define("blur", layerProperty("blur", "webkitFilter", 0, _.isNumber));
- Layer.define("brightness", layerProperty("brightness", "webkitFilter", 100, _.isNumber));
- Layer.define("saturate", layerProperty("saturate", "webkitFilter", 100, _.isNumber));
- Layer.define("hueRotate", layerProperty("hueRotate", "webkitFilter", 0, _.isNumber));
- Layer.define("contrast", layerProperty("contrast", "webkitFilter", 100, _.isNumber));
- Layer.define("invert", layerProperty("invert", "webkitFilter", 0, _.isNumber));
- Layer.define("grayscale", layerProperty("grayscale", "webkitFilter", 0, _.isNumber));
- Layer.define("sepia", layerProperty("sepia", "webkitFilter", 0, _.isNumber));
- Layer.define("shadowX", layerProperty("shadowX", "boxShadow", 0, _.isNumber));
- Layer.define("shadowY", layerProperty("shadowY", "boxShadow", 0, _.isNumber));
- Layer.define("shadowBlur", layerProperty("shadowBlur", "boxShadow", 0, _.isNumber));
- Layer.define("shadowSpread", layerProperty("shadowSpread", "boxShadow", 0, _.isNumber));
- Layer.define("shadowColor", layerProperty("shadowColor", "boxShadow", ""));
- Layer.define("backgroundColor", layerStyleProperty("backgroundColor"));
- Layer.define("color", layerStyleProperty("color"));
- Layer.define("borderRadius", layerStyleProperty("borderRadius"));
- Layer.define("borderColor", layerStyleProperty("borderColor"));
- Layer.define("borderWidth", layerStyleProperty("borderWidth"));
- Layer.define("name", {
- exportable: true,
- "default": "",
- get: function() {
- return this._getPropertyValue("name");
- },
- set: function(value) {
- this._setPropertyValue("name", value);
- return this._element.setAttribute("name", value);
- }
- });
- Layer.define("frame", {
- get: function() {
- return new Frame(this);
- },
- set: function(frame) {
- var k, _i, _len, _ref, _results;
- if (!frame) {
- return;
- }
- _ref = ["x", "y", "width", "height"];
- _results = [];
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- k = _ref[_i];
- _results.push(this[k] = frame[k]);
- }
- return _results;
- }
- });
- Layer.define("minX", frameProperty("minX"));
- Layer.define("midX", frameProperty("midX"));
- Layer.define("maxX", frameProperty("maxX"));
- Layer.define("minY", frameProperty("minY"));
- Layer.define("midY", frameProperty("midY"));
- Layer.define("maxY", frameProperty("maxY"));
- Layer.prototype.convertPoint = function(point) {
- return Utils.convertPoint(point, null, this);
- };
- Layer.prototype.screenFrame = function() {
- return Utils.convertPoint(this.frame, this, null);
- };
- Layer.prototype.contentFrame = function() {
- return Utils.frameMerge(this.subLayers.map(function(layer) {
- return layer.frame.properties;
- }));
- };
- Layer.prototype.centerFrame = function() {
- var frame;
- if (this.superLayer) {
- frame = this.frame;
- frame.midX = parseInt(this.superLayer.width / 2.0);
- frame.midY = parseInt(this.superLayer.height / 2.0);
- return frame;
- } else {
- frame = this.frame;
- frame.midX = parseInt(window.innerWidth / 2.0);
- frame.midY = parseInt(window.innerHeight / 2.0);
- return frame;
- }
- };
- Layer.prototype.center = function() {
- return this.frame = this.centerFrame();
- };
- Layer.prototype.centerX = function() {
- return this.x = this.centerFrame().x;
- };
- Layer.prototype.centerY = function() {
- return this.y = this.centerFrame().y;
- };
- Layer.prototype.pixelAlign = function() {
- this.x = parseInt(this.x);
- return this.y = parseInt(this.y);
- };
- Layer.define("style", {
- get: function() {
- return this._element.style;
- },
- set: function(value) {
- _.extend(this._element.style, value);
- return this.emit("change:style");
- }
- });
- Layer.define("html", {
- get: function() {
- var _ref;
- return (_ref = this._elementHTML) != null ? _ref.innerHTML : void 0;
- },
- set: function(value) {
- if (!this._elementHTML) {
- this._elementHTML = document.createElement("div");
- this._element.appendChild(this._elementHTML);
- }
- this._elementHTML.innerHTML = value;
- if (!(this._elementHTML.childNodes.length === 1 && this._elementHTML.childNodes[0].nodeName === "#text")) {
- this.ignoreEvents = false;
- }
- return this.emit("change:html");
- }
- });
- Layer.prototype.computedStyle = function() {
- return document.defaultView.getComputedStyle(this._element);
- };
- Layer.prototype._setDefaultCSS = function() {
- return this.style = Config.layerBaseCSS;
- };
- Layer.define("classList", {
- get: function() {
- return this._element.classList;
- }
- });
- Layer.prototype._createElement = function() {
- if (this._element != null) {
- return;
- }
- return this._element = document.createElement("div");
- };
- Layer.prototype._insertElement = function() {
- return Utils.domComplete(this.__insertElement);
- };
- Layer.prototype.__createRootElement = function() {
- var element;
- element = document.createElement("div");
- element.id = "FramerRoot";
- _.extend(element.style, Config.rootBaseCSS);
- $("#gamemain").append(element);
- return element;
- };
- Layer.prototype.__insertElement = function() {
- if (Session._RootElement == null) {
- Session._RootElement = this.__createRootElement();
- }
- return Session._RootElement.appendChild(this._element);
- };
- Layer.prototype.destroy = function() {
- var _ref;
- if (this.superLayer) {
- this.superLayer._subLayers = _.without(this.superLayer._subLayers, this);
- }
- if ((_ref = this._element.parentNode) != null) {
- _ref.removeChild(this._element);
- }
- this.removeAllListeners();
- return Session._LayerList = _.without(Session._LayerList, this);
- };
- Layer.prototype.copy = function() {
- var copiedSublayer, layer, subLayer, _i, _len, _ref;
- layer = this.copySingle();
- _ref = this.subLayers;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- subLayer = _ref[_i];
- copiedSublayer = subLayer.copy();
- copiedSublayer.superLayer = layer;
- }
- return layer;
- };
- Layer.prototype.copySingle = function() {
- return new Layer(this.properties);
- };
- Layer.prototype.animate = function(options) {
- var animation;
- options.layer = this;
- options.curveOptions = options;
- animation = new Animation(options);
- animation.start();
- return animation;
- };
- Layer.define("image", {
- exportable: true,
- "default": "",
- get: function() {
- return this._getPropertyValue("image");
- },
- set: function(value) {
- var currentValue, imageUrl, loader, _ref, _ref1,
- _this = this;
- currentValue = this._getPropertyValue("image");
- if (currentValue === value) {
- return this.emit("load");
- }
- this.backgroundColor = null;
- this._setPropertyValue("image", value);
- imageUrl = value;
- if (Utils.isLocal() && !imageUrl.match(/^https?:\/\//)) {
- imageUrl += "?nocache=" + (Date.now());
- }
- if ((_ref = this.events) != null ? _ref.hasOwnProperty("load" || ((_ref1 = this.events) != null ? _ref1.hasOwnProperty("error") : void 0)) : void 0) {
- loader = new Image();
- loader.name = imageUrl;
- loader.src = imageUrl;
- loader.onload = function() {
- _this.style["background-image"] = "url('" + imageUrl + "')";
- return _this.emit("load", loader);
- };
- return loader.onerror = function() {
- return _this.emit("error", loader);
- };
- } else {
- return this.style["background-image"] = "url('" + imageUrl + "')";
- }
- }
- });
- Layer.define("superLayer", {
- exportable: false,
- get: function() {
- return this._superLayer || null;
- },
- set: function(layer) {
- if (layer === this._superLayer) {
- return;
- }
- if (!layer instanceof Layer) {
- throw Error("Layer.superLayer needs to be a Layer object");
- }
- Utils.domCompleteCancel(this.__insertElement);
- if (this._superLayer) {
- this._superLayer._subLayers = _.without(this._superLayer._subLayers, this);
- this._superLayer._element.removeChild(this._element);
- this._superLayer.emit("change:subLayers", {
- added: [],
- removed: [this]
- });
- }
- if (layer) {
- layer._element.appendChild(this._element);
- layer._subLayers.push(this);
- layer.emit("change:subLayers", {
- added: [this],
- removed: []
- });
- } else {
- this._insertElement();
- }
- this._superLayer = layer;
- this.bringToFront();
- return this.emit("change:superLayer");
- }
- });
- Layer.prototype.superLayers = function() {
- var recurse, superLayers;
- superLayers = [];
- recurse = function(layer) {
- if (!layer.superLayer) {
- return;
- }
- superLayers.push(layer.superLayer);
- return recurse(layer.superLayer);
- };
- recurse(this);
- return superLayers;
- };
- Layer.define("subLayers", {
- exportable: false,
- get: function() {
- return _.clone(this._subLayers);
- }
- });
- Layer.define("siblingLayers", {
- exportable: false,
- get: function() {
- var _this = this;
- if (this.superLayer === null) {
- return _.filter(Session._LayerList, function(layer) {
- return layer !== _this && layer.superLayer === null;
- });
- }
- return _.without(this.superLayer.subLayers, this);
- }
- });
- Layer.prototype.addSubLayer = function(layer) {
- return layer.superLayer = this;
- };
- Layer.prototype.removeSubLayer = function(layer) {
- if (__indexOf.call(this.subLayers, layer) < 0) {
- return;
- }
- return layer.superLayer = null;
- };
- Layer.prototype.subLayersByName = function(name) {
- return _.filter(this.subLayers, function(layer) {
- return layer.name === name;
- });
- };
- Layer.prototype.animate = function(options) {
- var animation, start;
- start = options.start;
- if (start == null) {
- start = true;
- }
- delete options.start;
- options.layer = this;
- animation = new Animation(options);
- if (start) {
- animation.start();
- }
- return animation;
- };
- Layer.prototype.animations = function() {
- var _this = this;
- return _.filter(Animation.runningAnimations(), function(a) {
- return a.options.layer === _this;
- });
- };
- Layer.prototype.animateStop = function() {
- return _.invoke(this.animations(), "stop");
- };
- Layer.prototype.bringToFront = function() {
- return this.index = _.max(_.union([0], this.siblingLayers.map(function(layer) {
- return layer.index;
- }))) + 1;
- };
- Layer.prototype.sendToBack = function() {
- return this.index = _.min(_.union([0], this.siblingLayers.map(function(layer) {
- return layer.index;
- }))) - 1;
- };
- Layer.prototype.placeBefore = function(layer) {
- var l, _i, _len, _ref;
- if (__indexOf.call(this.siblingLayers, layer) < 0) {
- return;
- }
- _ref = this.siblingLayers;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- l = _ref[_i];
- if (l.index <= layer.index) {
- l.index -= 1;
- }
- }
- return this.index = layer.index + 1;
- };
- Layer.prototype.placeBehind = function(layer) {
- var l, _i, _len, _ref;
- if (__indexOf.call(this.siblingLayers, layer) < 0) {
- return;
- }
- _ref = this.siblingLayers;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- l = _ref[_i];
- if (l.index >= layer.index) {
- l.index += 1;
- }
- }
- return this.index = layer.index - 1;
- };
- Layer.define("states", {
- get: function() {
- return this._states != null ? this._states : this._states = new LayerStates(this);
- }
- });
- Layer.define("draggable", {
- get: function() {
- if (this._draggable == null) {
- this._draggable = new LayerDraggable(this);
- }
- return this._draggable;
- }
- });
- Layer.define("scrollFrame", {
- get: function() {
- return new Frame({
- x: this.scrollX,
- y: this.scrollY,
- width: this.width,
- height: this.height
- });
- },
- set: function(frame) {
- this.scrollX = frame.x;
- return this.scrollY = frame.y;
- }
- });
- Layer.define("scrollX", {
- get: function() {
- return this._element.scrollLeft;
- },
- set: function(value) {
- return this._element.scrollLeft = value;
- }
- });
- Layer.define("scrollY", {
- get: function() {
- return this._element.scrollTop;
- },
- set: function(value) {
- return this._element.scrollTop = value;
- }
- });
- Layer.prototype.addListener = function(eventName, originalListener) {
- var listener, _base,
- _this = this;
- listener = function() {
- var args;
- args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
- return originalListener.call.apply(originalListener, [_this].concat(__slice.call(args), [_this]));
- };
- originalListener.modifiedListener = listener;
- Layer.__super__.addListener.call(this, eventName, listener);
- this._element.addEventListener(eventName, listener);
- if (this._eventListeners == null) {
- this._eventListeners = {};
- }
- if ((_base = this._eventListeners)[eventName] == null) {
- _base[eventName] = [];
- }
- this._eventListeners[eventName].push(listener);
- if (!_.startsWith(eventName, "change:")) {
- return this.ignoreEvents = false;
- }
- };
- Layer.prototype.removeListener = function(eventName, listener) {
- if (listener.modifiedListener) {
- listener = listener.modifiedListener;
- }
- Layer.__super__.removeListener.call(this, eventName, listener);
- this._element.removeEventListener(eventName, listener);
- if (this._eventListeners) {
- return this._eventListeners[eventName] = _.without(this._eventListeners[eventName], listener);
- }
- };
- Layer.prototype.removeAllListeners = function() {
- var eventName, listener, listeners, _ref, _results;
- if (!this._eventListeners) {
- return;
- }
- _ref = this._eventListeners;
- _results = [];
- for (eventName in _ref) {
- listeners = _ref[eventName];
- _results.push((function() {
- var _i, _len, _results1;
- _results1 = [];
- for (_i = 0, _len = listeners.length; _i < _len; _i++) {
- listener = listeners[_i];
- _results1.push(this.removeListener(eventName, listener));
- }
- return _results1;
- }).call(this));
- }
- return _results;
- };
- Layer.prototype.on = Layer.prototype.addListener;
- Layer.prototype.off = Layer.prototype.removeListener;
- return Layer;
- })(BaseClass);
- exports.Layer.Layers = function() {
- return _.clone(Session._LayerList);
- };
- },{"./Animation":1,"./BaseClass":9,"./Config":11,"./Defaults":13,"./EventEmitter":14,"./Frame":18,"./LayerDraggable":22,"./LayerStates":23,"./LayerStyle":24,"./Session":27,"./Underscore":28,"./Utils":29}],22:[function(require,module,exports){
- var EventEmitter, Events, Utils, _,
- __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
- __hasProp = {}.hasOwnProperty,
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
- _ = require("./Underscore")._;
- Utils = require("./Utils");
- EventEmitter = require("./EventEmitter").EventEmitter;
- Events = require("./Events").Events;
- Events.DragStart = "dragstart";
- Events.DragMove = "dragmove";
- Events.DragEnd = "dragend";
- "This takes any layer and makes it draggable by the user on mobile or desktop.\n\nSome interesting things are:\n\n- The draggable.calculateVelocity().x|y contains the current average speed \n in the last 100ms (defined with VelocityTimeOut).\n- You can enable/disable or slowdown/speedup scrolling with\n draggable.speed.x|y\n";
- exports.LayerDraggable = (function(_super) {
- __extends(LayerDraggable, _super);
- LayerDraggable.VelocityTimeOut = 100;
- function LayerDraggable(layer) {
- this.layer = layer;
- this._touchEnd = __bind(this._touchEnd, this);
- this._touchStart = __bind(this._touchStart, this);
- this._updatePosition = __bind(this._updatePosition, this);
- this._deltas = [];
- this._isDragging = false;
- this.enabled = true;
- this.speedX = 1.0;
- this.speedY = 1.0;
- this.maxDragFrame = null;
- this.attach();
- }
- LayerDraggable.prototype.attach = function() {
- return this.layer.on(Events.TouchStart, this._touchStart);
- };
- LayerDraggable.prototype.remove = function() {
- return this.layer.off(Events.TouchStart, this._touchStart);
- };
- LayerDraggable.prototype.emit = function(eventName, event) {
- this.layer.emit(eventName, event);
- return LayerDraggable.__super__.emit.call(this, eventName, event);
- };
- LayerDraggable.prototype.calculateVelocity = function() {
- var curr, prev, time, timeSinceLastMove, velocity;
- if (this._deltas.length < 2) {
- return {
- x: 0,
- y: 0
- };
- }
- curr = this._deltas.slice(-1)[0];
- prev = this._deltas.slice(-2, -1)[0];
- time = curr.t - prev.t;
- timeSinceLastMove = new Date().getTime() - prev.t;
- if (timeSinceLastMove > this.VelocityTimeOut) {
- return {
- x: 0,
- y: 0
- };
- }
- velocity = {
- x: (curr.x - prev.x) / time,
- y: (curr.y - prev.y) / time
- };
- if (velocity.x === Infinity) {
- velocity.x = 0;
- }
- if (velocity.y === Infinity) {
- velocity.y = 0;
- }
- return velocity;
- };
- LayerDraggable.prototype._updatePosition = function(event) {
- var correctedDelta, delta, maxDragFrame, maxX, maxY, minX, minY, newX, newY, touchEvent,
- _this = this;
- if (this.enabled === false) {
- return;
- }
- this.emit(Events.DragMove, event);
- touchEvent = Events.touchEvent(event);
- delta = {
- x: touchEvent.clientX - this._start.x,
- y: touchEvent.clientY - this._start.y
- };
- correctedDelta = {
- x: delta.x * this.speedX,
- y: delta.y * this.speedY,
- t: event.timeStamp
- };
- newX = this._start.x + correctedDelta.x - this._offset.x;
- newY = this._start.y + correctedDelta.y - this._offset.y;
- if (this.maxDragFrame) {
- maxDragFrame = this.maxDragFrame;
- if (_.isFunction(maxDragFrame)) {
- maxDragFrame = maxDragFrame();
- }
- minX = Utils.frameGetMinX(this.maxDragFrame);
- maxX = Utils.frameGetMaxX(this.maxDragFrame) - this.layer.width;
- minY = Utils.frameGetMinY(this.maxDragFrame);
- maxY = Utils.frameGetMaxY(this.maxDragFrame) - this.layer.height;
- if (newX < minX) {
- newX = minX;
- }
- if (newX > maxX) {
- newX = maxX;
- }
- if (newY < minY) {
- newY = minY;
- }
- if (newY > maxY) {
- newY = maxY;
- }
- }
- window.requestAnimationFrame(function() {
- _this.layer.x = newX;
- return _this.layer.y = newY;
- });
- this._deltas.push(correctedDelta);
- return this.emit(Events.DragMove, event);
- };
- LayerDraggable.prototype._touchStart = function(event) {
- var touchEvent;
- this.layer.animateStop();
- this._isDragging = true;
- touchEvent = Events.touchEvent(event);
- this._start = {
- x: touchEvent.clientX,
- y: touchEvent.clientY
- };
- this._offset = {
- x: touchEvent.clientX - this.layer.x,
- y: touchEvent.clientY - this.layer.y
- };
- document.addEventListener(Events.TouchMove, this._updatePosition);
- document.addEventListener(Events.TouchEnd, this._touchEnd);
- return this.emit(Events.DragStart, event);
- };
- LayerDraggable.prototype._touchEnd = function(event) {
- this._isDragging = false;
- document.removeEventListener(Events.TouchMove, this._updatePosition);
- document.removeEventListener(Events.TouchEnd, this._touchEnd);
- this.emit(Events.DragEnd, event);
- return this._deltas = [];
- };
- return LayerDraggable;
- })(EventEmitter);
- },{"./EventEmitter":14,"./Events":15,"./Underscore":28,"./Utils":29}],23:[function(require,module,exports){
- var BaseClass, Defaults, Events, LayerStatesIgnoredKeys, _,
- __hasProp = {}.hasOwnProperty,
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
- __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
- _ = require("./Underscore")._;
- Events = require("./Events").Events;
- BaseClass = require("./BaseClass").BaseClass;
- Defaults = require("./Defaults").Defaults;
- LayerStatesIgnoredKeys = ["ignoreEvents"];
- Events.StateWillSwitch = "willSwitch";
- Events.StateDidSwitch = "didSwitch";
- exports.LayerStates = (function(_super) {
- __extends(LayerStates, _super);
- function LayerStates(layer) {
- this.layer = layer;
- this._states = {};
- this._orderedStates = [];
- this.animationOptions = {};
- this.add("default", this.layer.properties);
- this._currentState = "default";
- this._previousStates = [];
- LayerStates.__super__.constructor.apply(this, arguments);
- }
- LayerStates.prototype.add = function(stateName, properties) {
- var error, k, v;
- if (_.isObject(stateName)) {
- for (k in stateName) {
- v = stateName[k];
- this.add(k, v);
- }
- return;
- }
- error = function() {
- throw Error("Usage example: layer.states.add(\"someName\", {x:500})");
- };
- if (!_.isString(stateName)) {
- error();
- }
- if (!_.isObject(properties)) {
- error();
- }
- this._orderedStates.push(stateName);
- return this._states[stateName] = properties;
- };
- LayerStates.prototype.remove = function(stateName) {
- if (!this._states.hasOwnProperty(stateName)) {
- return;
- }
- delete this._states[stateName];
- return this._orderedStates = _.without(this._orderedStates, stateName);
- };
- LayerStates.prototype["switch"] = function(stateName, animationOptions, instant) {
- var animatingKeys, properties, propertyName, value, _ref,
- _this = this;
- if (instant == null) {
- instant = false;
- }
- if (!this._states.hasOwnProperty(stateName)) {
- throw Error("No such state: '" + stateName + "'");
- }
- this.emit(Events.StateWillSwitch, this._currentState, stateName, this);
- this._previousStates.push(this._currentState);
- this._currentState = stateName;
- properties = {};
- animatingKeys = this.animatingKeys();
- _ref = this._states[stateName];
- for (propertyName in _ref) {
- value = _ref[propertyName];
- if (__indexOf.call(LayerStatesIgnoredKeys, propertyName) >= 0) {
- continue;
- }
- if (__indexOf.call(animatingKeys, propertyName) < 0) {
- continue;
- }
- if (_.isFunction(value)) {
- value = value.call(this.layer, this.layer, stateName);
- }
- properties[propertyName] = value;
- }
- if (instant === true) {
- this.layer.properties = properties;
- return this.emit(Events.StateDidSwitch, _.last(this._previousStates), stateName, this);
- } else {
- if (animationOptions == null) {
- animationOptions = this.animationOptions;
- }
- animationOptions.properties = properties;
- this._animation = this.layer.animate(animationOptions);
- return this._animation.on("stop", function() {
- return _this.emit(Events.StateDidSwitch, _.last(_this._previousStates), stateName, _this);
- });
- }
- };
- LayerStates.prototype.switchInstant = function(stateName) {
- return this["switch"](stateName, null, true);
- };
- LayerStates.define("state", {
- get: function() {
- return this._currentState;
- }
- });
- LayerStates.define("current", {
- get: function() {
- return this._currentState;
- }
- });
- LayerStates.prototype.states = function() {
- return _.clone(this._orderedStates);
- };
- LayerStates.prototype.animatingKeys = function() {
- var keys, state, stateName, _ref;
- keys = [];
- _ref = this._states;
- for (stateName in _ref) {
- state = _ref[stateName];
- if (stateName === "default") {
- continue;
- }
- keys = _.union(keys, _.keys(state));
- }
- return keys;
- };
- LayerStates.prototype.previous = function(states, animationOptions) {
- if (states == null) {
- states = this.states();
- }
- return this["switch"](Utils.arrayPrev(states, this._currentState), animationOptions);
- };
- LayerStates.prototype.next = function() {
- var states;
- states = Utils.arrayFromArguments(arguments);
- if (!states.length) {
- states = this.states();
- }
- return this["switch"](Utils.arrayNext(states, this._currentState));
- };
- LayerStates.prototype.last = function(animationOptions) {
- return this["switch"](_.last(this._previousStates), animationOptions);
- };
- return LayerStates;
- })(BaseClass);
- },{"./BaseClass":9,"./Defaults":13,"./Events":15,"./Underscore":28}],24:[function(require,module,exports){
- var filterFormat, _WebkitProperties;
- filterFormat = function(value, unit) {
- return "" + (Utils.round(value, 2)) + unit;
- };
- _WebkitProperties = [["blur", "blur", 0, "px"], ["brightness", "brightness", 100, "%"], ["saturate", "saturate", 100, "%"], ["hue-rotate", "hueRotate", 0, "deg"], ["contrast", "contrast", 100, "%"], ["invert", "invert", 0, "%"], ["grayscale", "grayscale", 0, "%"], ["sepia", "sepia", 0, "%"]];
- exports.LayerStyle = {
- width: function(layer) {
- return layer.width + "px";
- },
- height: function(layer) {
- return layer.height + "px";
- },
- display: function(layer) {
- if (layer.visible === true) {
- return "block";
- }
- return "none";
- },
- opacity: function(layer) {
- return layer.opacity;
- },
- overflow: function(layer) {
- if (layer.scrollHorizontal === true || layer.scrollVertical === true) {
- return "auto";
- }
- if (layer.clip === true) {
- return "hidden";
- }
- return "visible";
- },
- overflowX: function(layer) {
- if (layer.scrollHorizontal === true) {
- return "scroll";
- }
- if (layer.clip === true) {
- return "hidden";
- }
- return "visible";
- },
- overflowY: function(layer) {
- if (layer.scrollVertical === true) {
- return "scroll";
- }
- if (layer.clip === true) {
- return "hidden";
- }
- return "visible";
- },
- zIndex: function(layer) {
- return layer.index;
- },
- webkitFilter: function(layer) {
- var css, cssName, fallback, layerName, unit, _i, _len, _ref;
- css = [];
- for (_i = 0, _len = _WebkitProperties.length; _i < _len; _i++) {
- _ref = _WebkitProperties[_i], cssName = _ref[0], layerName = _ref[1], fallback = _ref[2], unit = _ref[3];
- if (layer[layerName] !== fallback) {
- css.push("" + cssName + "(" + (filterFormat(layer[layerName], unit)) + ")");
- }
- }
- return css.join(" ");
- },
- webkitTransform: function(layer) {
- if (layer._prefer2d) {
- return exports.LayerStyle.webkitTransformPrefer2d(layer);
- }
- return " translate3d(" + layer.x + "px," + layer.y + "px," + layer.z + "px) scale(" + layer.scale + ") scale3d(" + layer.scaleX + "," + layer.scaleY + "," + layer.scaleZ + ") skew(" + layer.skew + "deg," + layer.skew + "deg) skewX(" + layer.skewX + "deg) skewY(" + layer.skewY + "deg) rotateX(" + layer.rotationX + "deg) rotateY(" + layer.rotationY + "deg) rotateZ(" + layer.rotationZ + "deg) ";
- },
- webkitTransformPrefer2d: function(layer) {
- var css;
- css = [];
- if (layer.z !== 0) {
- css.push("translate3d(" + layer.x + "px," + layer.y + "px," + layer.z + "px)");
- } else {
- css.push("translate(" + layer.x + "px," + layer.y + "px)");
- }
- if (layer.scale !== 1) {
- css.push("scale(" + layer.scale + ")");
- }
- if (layer.scaleX !== 1 || layer.scaleY !== 1 || layer.scaleZ !== 1) {
- css.push("scale3d(" + layer.scaleX + "," + layer.scaleY + "," + layer.scaleZ + ")");
- }
- if (layer.skew) {
- css.push("skew(" + layer.skew + "deg," + layer.skew + "deg)");
- }
- if (layer.skewX) {
- css.push("skewX(" + layer.skewX + "deg)");
- }
- if (layer.skewY) {
- css.push("skewY(" + layer.skewY + "deg)");
- }
- if (layer.rotationX) {
- css.push("rotateX(" + layer.rotationX + "deg)");
- }
- if (layer.rotationY) {
- css.push("rotateY(" + layer.rotationY + "deg)");
- }
- if (layer.rotationZ) {
- css.push("rotateZ(" + layer.rotationZ + "deg)");
- }
- return css.join(" ");
- },
- webkitTransformOrigin: function(layer) {
- return "" + (layer.originX * 100) + "% " + (layer.originY * 100) + "%";
- },
- pointerEvents: function(layer) {
- if (layer.ignoreEvents) {
- return "none";
- } else {
- return "auto";
- }
- },
- boxShadow: function(layer) {
- if (!layer.shadowColor) {
- return "";
- }
- return "" + layer.shadowX + "px " + layer.shadowY + "px " + layer.shadowBlur + "px " + layer.shadowSpread + "px " + layer.shadowColor;
- }
- };
- },{}],25:[function(require,module,exports){
- var Session, Utils,
- __slice = [].slice;
- Utils = require("./Utils");
- Session = require("./Session").Session;
- "\nTodo:\n- Better looks\n- Resizable\n- Live in own space on top of all Framer stuff\n";
- exports.print = function() {
- var args, printLayer, printNode;
- args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
- printLayer = Framer.Session.printLayer;
- if (!printLayer) {
- printLayer = new Layer;
- printLayer.scrollVertical = true;
- printLayer.ignoreEvents = false;
- printLayer.html = "";
- printLayer.style = {
- "font": "12px/1.35em Menlo",
- "color": "rgba(0,0,0,.7)",
- "padding": "8px",
- "padding-bottom": "30px",
- "border-top": "1px solid #d9d9d9"
- };
- printLayer.opacity = 0.9;
- printLayer.style.zIndex = 999;
- printLayer.visible = true;
- printLayer.backgroundColor = "white";
- printLayer.width = window.innerWidth;
- printLayer.height = 160;
- printLayer.maxY = window.innerHeight;
- }
- printNode = document.createElement("div");
- printNode.innerHTML = "» " + args.map(Utils.stringify).join(", ") + "<br>";
- printNode.style["-webkit-user-select"] = "text";
- printNode.style["cursor"] = "auto";
- printLayer._element.appendChild(printNode);
- Framer.Session.printLayer = printLayer;
- return Utils.delay(0, function() {
- return printLayer._element.scrollTop = printLayer._element.scrollHeight;
- });
- };
- },{"./Session":27,"./Utils":29}],26:[function(require,module,exports){
- var BaseClass, ScreenClass,
- __hasProp = {}.hasOwnProperty,
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
- BaseClass = require("./BaseClass").BaseClass;
- ScreenClass = (function(_super) {
- __extends(ScreenClass, _super);
- function ScreenClass(options) {
- ScreenClass.__super__.constructor.call(this, options);
- this._setupResizeListener();
- }
- ScreenClass.define("width", {
- get: function() {
- return window.innerWidth;
- }
- });
- ScreenClass.define("height", {
- get: function() {
- return window.innerHeight;
- }
- });
- ScreenClass.prototype._setupResizeListener = function() {
- var oldResizeFunction,
- _this = this;
- oldResizeFunction = window.onresize;
- return window.onresize = function() {
- _this.emit("resize", _this);
- return typeof oldResizeFunction === "function" ? oldResizeFunction() : void 0;
- };
- };
- return ScreenClass;
- })(BaseClass);
- exports.Screen = new ScreenClass;
- },{"./BaseClass":9}],27:[function(require,module,exports){
- exports.Session = {};
- },{}],28:[function(require,module,exports){
- var _;
- _ = require("lodash");
- _.str = require('underscore.string');
- _.mixin(_.str.exports());
- _.isBool = function(v) {
- return typeof v === 'boolean';
- };
- exports._ = _;
- },{"lodash":31,"underscore.string":32}],29:[function(require,module,exports){
- var Screen, Session, Utils, _, __domComplete, __domReady,
- __slice = [].slice,
- _this = this;
- _ = require("./Underscore")._;
- Session = require("./Session").Session;
- Screen = require("./Screen").Screen;
- Utils = {};
- Utils.reset = function() {
- var delayInterval, delayTimer, layer, __domComplete, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3;
- if (__domReady === false) {
- return;
- }
- __domComplete = [];
- Session.printLayer = null;
- if (Session._LayerList) {
- _ref = Session._LayerList;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- layer = _ref[_i];
- layer.removeAllListeners();
- }
- }
- Session._LayerList = [];
- if ((_ref1 = Session._RootElement) != null) {
- _ref1.innerHTML = "";
- }
- if (Session._delayTimers) {
- _ref2 = Session._delayTimers;
- for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
- delayTimer = _ref2[_j];
- clearTimeout(delayTimer);
- }
- Session._delayTimers = [];
- }
- if (Session._delayIntervals) {
- _ref3 = Session._delayIntervals;
- for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) {
- delayInterval = _ref3[_k];
- clearInterval(delayInterval);
- }
- return Session._delayIntervals = [];
- }
- };
- Utils.getValue = function(value) {
- if (_.isFunction(value)) {
- return value();
- }
- return value;
- };
- Utils.setDefaultProperties = function(obj, defaults, warn) {
- var k, result, v;
- if (warn == null) {
- warn = true;
- }
- result = {};
- for (k in defaults) {
- v = defaults[k];
- if (obj.hasOwnProperty(k)) {
- result[k] = obj[k];
- } else {
- result[k] = defaults[k];
- }
- }
- if (warn) {
- for (k in obj) {
- v = obj[k];
- if (!defaults.hasOwnProperty(k)) {
- console.warn("Utils.setDefaultProperties: got unexpected option: '" + k + " -> " + v + "'", obj);
- }
- }
- }
- return result;
- };
- Utils.valueOrDefault = function(value, defaultValue) {
- if (value === (void 0) || value === null) {
- value = defaultValue;
- }
- return value;
- };
- Utils.arrayToObject = function(arr) {
- var item, obj, _i, _len;
- obj = {};
- for (_i = 0, _len = arr.length; _i < _len; _i++) {
- item = arr[_i];
- obj[item[0]] = item[1];
- }
- return obj;
- };
- Utils.arrayNext = function(arr, item) {
- return arr[arr.indexOf(item) + 1] || _.first(arr);
- };
- Utils.arrayPrev = function(arr, item) {
- return arr[arr.indexOf(item) - 1] || _.last(arr);
- };
- if (window.requestAnimationFrame == null) {
- window.requestAnimationFrame = window.webkitRequestAnimationFrame;
- }
- if (window.requestAnimationFrame == null) {
- window.requestAnimationFrame = function(f) {
- return Utils.delay(1 / 60, f);
- };
- }
- Utils.getTime = function() {
- return Date.now() / 1000;
- };
- Utils.delay = function(time, f) {
- var timer;
- timer = setTimeout(f, time * 1000);
- if (Session._delayTimers == null) {
- Session._delayTimers = [];
- }
- Session._delayTimers.push(timer);
- return timer;
- };
- Utils.interval = function(time, f) {
- var timer;
- timer = setInterval(f, time * 1000);
- if (Session._delayIntervals == null) {
- Session._delayIntervals = [];
- }
- Session._delayIntervals.push(timer);
- return timer;
- };
- Utils.debounce = function(threshold, fn, immediate) {
- var timeout;
- if (threshold == null) {
- threshold = 0.1;
- }
- timeout = null;
- threshold *= 1000;
- return function() {
- var args, delayed, obj;
- args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
- obj = this;
- delayed = function() {
- if (!immediate) {
- fn.apply(obj, args);
- }
- return timeout = null;
- };
- if (timeout) {
- clearTimeout(timeout);
- } else if (immediate) {
- fn.apply(obj, args);
- }
- return timeout = setTimeout(delayed, threshold);
- };
- };
- Utils.throttle = function(delay, fn) {
- var timer;
- if (delay === 0) {
- return fn;
- }
- delay *= 1000;
- timer = false;
- return function() {
- if (timer) {
- return;
- }
- timer = true;
- if (delay !== -1) {
- setTimeout((function() {
- return timer = false;
- }), delay);
- }
- return fn.apply(null, arguments);
- };
- };
- Utils.randomColor = function(alpha) {
- var c;
- if (alpha == null) {
- alpha = 1.0;
- }
- c = function() {
- return parseInt(Math.random() * 255);
- };
- return "rgba(" + (c()) + ", " + (c()) + ", " + (c()) + ", " + alpha + ")";
- };
- Utils.randomChoice = function(arr) {
- return arr[Math.floor(Math.random() * arr.length)];
- };
- Utils.randomNumber = function(a, b) {
- if (a == null) {
- a = 0;
- }
- if (b == null) {
- b = 1;
- }
- return Utils.mapRange(Math.random(), 0, 1, a, b);
- };
- Utils.labelLayer = function(layer, text, style) {
- if (style == null) {
- style = {};
- }
- style = _.extend({
- font: "10px/1em Menlo",
- lineHeight: "" + layer.height + "px",
- textAlign: "center",
- color: "#fff"
- }, style);
- layer.style = style;
- return layer.html = text;
- };
- Utils.stringify = function(obj) {
- try {
- if (_.isObject(obj)) {
- return JSON.stringify(obj);
- }
- } catch (_error) {
- "";
- }
- if (obj === void 0) {
- return "undefined";
- }
- if (obj.toString) {
- return obj.toString();
- }
- return obj;
- };
- Utils.uuid = function() {
- var chars, digit, output, r, random, _i;
- chars = "0123456789abcdefghijklmnopqrstuvwxyz".split("");
- output = new Array(36);
- random = 0;
- for (digit = _i = 1; _i <= 32; digit = ++_i) {
- if (random <= 0x02) {
- random = 0x2000000 + (Math.random() * 0x1000000) | 0;
- }
- r = random & 0xf;
- random = random >> 4;
- output[digit] = chars[digit === 19 ? (r & 0x3) | 0x8 : r];
- }
- return output.join("");
- };
- Utils.arrayFromArguments = function(args) {
- if (_.isArray(args[0])) {
- return args[0];
- }
- return Array.prototype.slice.call(args);
- };
- Utils.cycle = function() {
- var args, curr;
- args = Utils.arrayFromArguments(arguments);
- curr = -1;
- return function() {
- curr++;
- if (curr >= args.length) {
- curr = 0;
- }
- return args[curr];
- };
- };
- Utils.toggle = Utils.cycle;
- Utils.isWebKit = function() {
- return window.WebKitCSSMatrix !== null;
- };
- Utils.isTouch = function() {
- return window.ontouchstart === null;
- };
- Utils.isMobile = function() {
- return /iphone|ipod|ipad|android|ie|blackberry|fennec/.test(navigator.userAgent.toLowerCase());
- };
- Utils.isChrome = function() {
- return /chrome/.test(navigator.userAgent.toLowerCase());
- };
- Utils.isLocal = function() {
- return Utils.isLocalUrl(window.location.href);
- };
- Utils.isLocalUrl = function(url) {
- return url.slice(0, 7) === "file://";
- };
- Utils.devicePixelRatio = function() {
- return window.devicePixelRatio;
- };
- Utils.pathJoin = function() {
- return Utils.arrayFromArguments(arguments).join("/");
- };
- Utils.round = function(value, decimals) {
- var d;
- d = Math.pow(10, decimals);
- return Math.round(value * d) / d;
- };
- Utils.mapRange = function(value, fromLow, fromHigh, toLow, toHigh) {
- return toLow + (((value - fromLow) / (fromHigh - fromLow)) * (toHigh - toLow));
- };
- Utils.modulate = function(value, rangeA, rangeB, limit) {
- var fromHigh, fromLow, result, toHigh, toLow;
- if (limit == null) {
- limit = false;
- }
- fromLow = rangeA[0], fromHigh = rangeA[1];
- toLow = rangeB[0], toHigh = rangeB[1];
- result = toLow + (((value - fromLow) / (fromHigh - fromLow)) * (toHigh - toLow));
- if (limit === true) {
- if (result < toLow) {
- return toLow;
- }
- if (result > toHigh) {
- return toHigh;
- }
- }
- return result;
- };
- Utils.parseFunction = function(str) {
- var result;
- result = {
- name: "",
- args: []
- };
- if (_.endsWith(str, ")")) {
- result.name = str.split("(")[0];
- result.args = str.split("(")[1].split(",").map(function(a) {
- return _.trim(_.rtrim(a, ")"));
- });
- } else {
- result.name = str;
- }
- return result;
- };
- __domComplete = [];
- __domReady = false;
- if (typeof document !== "undefined" && document !== null) {
- document.onreadystatechange = function(event) {
- var f, _results;
- if (document.readyState === "complete") {
- __domReady = true;
- _results = [];
- while (__domComplete.length) {
- _results.push(f = __domComplete.shift()());
- }
- return _results;
- }
- };
- }
- Utils.domComplete = function(f) {
- if (document.readyState === "complete") {
- return f();
- } else {
- return __domComplete.push(f);
- }
- };
- Utils.domCompleteCancel = function(f) {
- return __domComplete = _.without(__domComplete, f);
- };
- Utils.domLoadScript = function(url, callback) {
- var head, script;
- script = document.createElement("script");
- script.type = "text/javascript";
- script.src = url;
- script.onload = callback;
- head = document.getElementsByTagName("head")[0];
- head.appendChild(script);
- return script;
- };
- Utils.domLoadData = function(path, callback) {
- var request;
- request = new XMLHttpRequest();
- request.addEventListener("load", function() {
- return callback(null, request.responseText);
- }, false);
- request.addEventListener("error", function() {
- return callback(true, null);
- }, false);
- request.open("GET", path, true);
- return request.send(null);
- };
- Utils.domLoadJSON = function(path, callback) {
- return Utils.domLoadData(path, function(err, data) {
- return callback(err, JSON.parse(data));
- });
- };
- Utils.domLoadDataSync = function(path) {
- var data, e, request;
- request = new XMLHttpRequest();
- request.open("GET", path, false);
- try {
- request.send(null);
- } catch (_error) {
- e = _error;
- console.debug("XMLHttpRequest.error", e);
- }
- data = request.responseText;
- if (!data) {
- throw Error("Utils.domLoadDataSync: no data was loaded (url not found?)");
- }
- return request.responseText;
- };
- Utils.domLoadJSONSync = function(path) {
- return JSON.parse(Utils.domLoadDataSync(path));
- };
- Utils.domLoadScriptSync = function(path) {
- var scriptData;
- scriptData = Utils.domLoadDataSync(path);
- eval(scriptData);
- return scriptData;
- };
- Utils.pointMin = function() {
- var point, points;
- points = Utils.arrayFromArguments(arguments);
- return point = {
- x: _.min(point.map(function(size) {
- return size.x;
- })),
- y: _.min(point.map(function(size) {
- return size.y;
- }))
- };
- };
- Utils.pointMax = function() {
- var point, points;
- points = Utils.arrayFromArguments(arguments);
- return point = {
- x: _.max(point.map(function(size) {
- return size.x;
- })),
- y: _.max(point.map(function(size) {
- return size.y;
- }))
- };
- };
- Utils.pointDistance = function(pointA, pointB) {
- var distance;
- return distance = {
- x: Math.abs(pointB.x - pointA.x),
- y: Math.abs(pointB.y - pointA.y)
- };
- };
- Utils.pointInvert = function(point) {
- return point = {
- x: 0 - point.x,
- y: 0 - point.y
- };
- };
- Utils.pointTotal = function(point) {
- return point.x + point.y;
- };
- Utils.pointAbs = function(point) {
- return point = {
- x: Math.abs(point.x),
- y: Math.abs(point.y)
- };
- };
- Utils.pointInFrame = function(point, frame) {
- if (point.x < frame.minX || point.x > frame.maxX) {
- return false;
- }
- if (point.y < frame.minY || point.y > frame.maxY) {
- return false;
- }
- return true;
- };
- Utils.sizeMin = function() {
- var size, sizes;
- sizes = Utils.arrayFromArguments(arguments);
- return size = {
- width: _.min(sizes.map(function(size) {
- return size.width;
- })),
- height: _.min(sizes.map(function(size) {
- return size.height;
- }))
- };
- };
- Utils.sizeMax = function() {
- var size, sizes;
- sizes = Utils.arrayFromArguments(arguments);
- return size = {
- width: _.max(sizes.map(function(size) {
- return size.width;
- })),
- height: _.max(sizes.map(function(size) {
- return size.height;
- }))
- };
- };
- Utils.frameGetMinX = function(frame) {
- return frame.x;
- };
- Utils.frameSetMinX = function(frame, value) {
- return frame.x = value;
- };
- Utils.frameGetMidX = function(frame) {
- if (frame.width === 0) {
- return 0;
- } else {
- return frame.x + (frame.width / 2.0);
- }
- };
- Utils.frameSetMidX = function(frame, value) {
- return frame.x = frame.width === 0 ? 0 : value - (frame.width / 2.0);
- };
- Utils.frameGetMaxX = function(frame) {
- if (frame.width === 0) {
- return 0;
- } else {
- return frame.x + frame.width;
- }
- };
- Utils.frameSetMaxX = function(frame, value) {
- return frame.x = frame.width === 0 ? 0 : value - frame.width;
- };
- Utils.frameGetMinY = function(frame) {
- return frame.y;
- };
- Utils.frameSetMinY = function(frame, value) {
- return frame.y = value;
- };
- Utils.frameGetMidY = function(frame) {
- if (frame.height === 0) {
- return 0;
- } else {
- return frame.y + (frame.height / 2.0);
- }
- };
- Utils.frameSetMidY = function(frame, value) {
- return frame.y = frame.height === 0 ? 0 : value - (frame.height / 2.0);
- };
- Utils.frameGetMaxY = function(frame) {
- if (frame.height === 0) {
- return 0;
- } else {
- return frame.y + frame.height;
- }
- };
- Utils.frameSetMaxY = function(frame, value) {
- return frame.y = frame.height === 0 ? 0 : value - frame.height;
- };
- Utils.frameSize = function(frame) {
- var size;
- return size = {
- width: frame.width,
- height: frame.height
- };
- };
- Utils.framePoint = function(frame) {
- var point;
- return point = {
- x: frame.x,
- y: frame.y
- };
- };
- Utils.frameMerge = function() {
- var frame, frames;
- frames = Utils.arrayFromArguments(arguments);
- frame = {
- x: _.min(frames.map(Utils.frameGetMinX)),
- y: _.min(frames.map(Utils.frameGetMinY))
- };
- frame.width = _.max(frames.map(Utils.frameGetMaxX)) - frame.x;
- frame.height = _.max(frames.map(Utils.frameGetMaxY)) - frame.y;
- return frame;
- };
- Utils.convertPoint = function(input, layerA, layerB) {
- var k, layer, point, superLayersA, superLayersB, _i, _j, _k, _len, _len1, _len2, _ref;
- point = {};
- _ref = ["x", "y", "width", "height"];
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- k = _ref[_i];
- point[k] = input[k];
- }
- superLayersA = (layerA != null ? layerA.superLayers() : void 0) || [];
- superLayersB = (layerB != null ? layerB.superLayers() : void 0) || [];
- if (layerB) {
- superLayersB.push(layerB);
- }
- for (_j = 0, _len1 = superLayersA.length; _j < _len1; _j++) {
- layer = superLayersA[_j];
- point.x += layer.x - layer.scrollFrame.x;
- point.y += layer.y - layer.scrollFrame.y;
- }
- for (_k = 0, _len2 = superLayersB.length; _k < _len2; _k++) {
- layer = superLayersB[_k];
- point.x -= layer.x + layer.scrollFrame.x;
- point.y -= layer.y + layer.scrollFrame.y;
- }
- return point;
- };
- _.extend(exports, Utils);
- },{"./Screen":26,"./Session":27,"./Underscore":28}],30:[function(require,module,exports){
- var Layer,
- __hasProp = {}.hasOwnProperty,
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
- Layer = require("./Layer").Layer;
- exports.VideoLayer = (function(_super) {
- __extends(VideoLayer, _super);
- function VideoLayer(options) {
- if (options == null) {
- options = {};
- }
- VideoLayer.__super__.constructor.call(this, options);
- this.player = document.createElement("video");
- this.player.style.width = "100%";
- this.player.style.height = "100%";
- this.player.on = this.player.addEventListener;
- this.player.off = this.player.removeEventListener;
- this.video = options.video;
- this._element.appendChild(this.player);
- }
- VideoLayer.define("video", {
- get: function() {
- return this.player.src;
- },
- set: function(video) {
- return this.player.src = video;
- }
- });
- return VideoLayer;
- })(Layer);
- },{"./Layer":21}],31:[function(require,module,exports){
- var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};/**
- * @license
- * Lo-Dash 2.4.1 (Custom Build) <http://lodash.com/>
- * Build: `lodash modern -o ./dist/lodash.js`
- * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
- * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE>
- * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
- * Available under MIT license <http://lodash.com/license>
- */
- ;(function() {
- /** Used as a safe reference for `undefined` in pre ES5 environments */
- var undefined;
- /** Used to pool arrays and objects used internally */
- var arrayPool = [],
- objectPool = [];
- /** Used to generate unique IDs */
- var idCounter = 0;
- /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */
- var keyPrefix = +new Date + '';
- /** Used as the size when optimizations are enabled for large arrays */
- var largeArraySize = 75;
- /** Used as the max size of the `arrayPool` and `objectPool` */
- var maxPoolSize = 40;
- /** Used to detect and test whitespace */
- var whitespace = (
- // whitespace
- ' \t\x0B\f\xA0\ufeff' +
- // line terminators
- '\n\r\u2028\u2029' +
- // unicode category "Zs" space separators
- '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000'
- );
- /** Used to match empty string literals in compiled template source */
- var reEmptyStringLeading = /\b__p \+= '';/g,
- reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
- reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
- /**
- * Used to match ES6 template delimiters
- * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals
- */
- var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
- /** Used to match regexp flags from their coerced string values */
- var reFlags = /\w*$/;
- /** Used to detected named functions */
- var reFuncName = /^\s*function[ \n\r\t]+\w/;
- /** Used to match "interpolate" template delimiters */
- var reInterpolate = /<%=([\s\S]+?)%>/g;
- /** Used to match leading whitespace and zeros to be removed */
- var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)');
- /** Used to ensure capturing order of template delimiters */
- var reNoMatch = /($^)/;
- /** Used to detect functions containing a `this` reference */
- var reThis = /\bthis\b/;
- /** Used to match unescaped characters in compiled string literals */
- var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
- /** Used to assign default `context` object properties */
- var contextProps = [
- 'Array', 'Boolean', 'Date', 'Function', 'Math', 'Number', 'Object',
- 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN',
- 'parseInt', 'setTimeout'
- ];
- /** Used to make template sourceURLs easier to identify */
- var templateCounter = 0;
- /** `Object#toString` result shortcuts */
- var argsClass = '[object Arguments]',
- arrayClass = '[object Array]',
- boolClass = '[object Boolean]',
- dateClass = '[object Date]',
- funcClass = '[object Function]',
- numberClass = '[object Number]',
- objectClass = '[object Object]',
- regexpClass = '[object RegExp]',
- stringClass = '[object String]';
- /** Used to identify object classifications that `_.clone` supports */
- var cloneableClasses = {};
- cloneableClasses[funcClass] = false;
- cloneableClasses[argsClass] = cloneableClasses[arrayClass] =
- cloneableClasses[boolClass] = cloneableClasses[dateClass] =
- cloneableClasses[numberClass] = cloneableClasses[objectClass] =
- cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true;
- /** Used as an internal `_.debounce` options object */
- var debounceOptions = {
- 'leading': false,
- 'maxWait': 0,
- 'trailing': false
- };
- /** Used as the property descriptor for `__bindData__` */
- var descriptor = {
- 'configurable': false,
- 'enumerable': false,
- 'value': null,
- 'writable': false
- };
- /** Used to determine if values are of the language type Object */
- var objectTypes = {
- 'boolean': false,
- 'function': true,
- 'object': true,
- 'number': false,
- 'string': false,
- 'undefined': false
- };
- /** Used to escape characters for inclusion in compiled string literals */
- var stringEscapes = {
- '\\': '\\',
- "'": "'",
- '\n': 'n',
- '\r': 'r',
- '\t': 't',
- '\u2028': 'u2028',
- '\u2029': 'u2029'
- };
- /** Used as a reference to the global object */
- var root = (objectTypes[typeof window] && window) || this;
- /** Detect free variable `exports` */
- var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
- /** Detect free variable `module` */
- var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
- /** Detect the popular CommonJS extension `module.exports` */
- var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;
- /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */
- var freeGlobal = objectTypes[typeof global] && global;
- if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
- root = freeGlobal;
- }
- /*--------------------------------------------------------------------------*/
- /**
- * The base implementation of `_.indexOf` without support for binary searches
- * or `fromIndex` constraints.
- *
- * @private
- * @param {Array} array The array to search.
- * @param {*} value The value to search for.
- * @param {number} [fromIndex=0] The index to search from.
- * @returns {number} Returns the index of the matched value or `-1`.
- */
- function baseIndexOf(array, value, fromIndex) {
- var index = (fromIndex || 0) - 1,
- length = array ? array.length : 0;
- while (++index < length) {
- if (array[index] === value) {
- return index;
- }
- }
- return -1;
- }
- /**
- * An implementation of `_.contains` for cache objects that mimics the return
- * signature of `_.indexOf` by returning `0` if the value is found, else `-1`.
- *
- * @private
- * @param {Object} cache The cache object to inspect.
- * @param {*} value The value to search for.
- * @returns {number} Returns `0` if `value` is found, else `-1`.
- */
- function cacheIndexOf(cache, value) {
- var type = typeof value;
- cache = cache.cache;
- if (type == 'boolean' || value == null) {
- return cache[value] ? 0 : -1;
- }
- if (type != 'number' && type != 'string') {
- type = 'object';
- }
- var key = type == 'number' ? value : keyPrefix + value;
- cache = (cache = cache[type]) && cache[key];
- return type == 'object'
- ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1)
- : (cache ? 0 : -1);
- }
- /**
- * Adds a given value to the corresponding cache object.
- *
- * @private
- * @param {*} value The value to add to the cache.
- */
- function cachePush(value) {
- var cache = this.cache,
- type = typeof value;
- if (type == 'boolean' || value == null) {
- cache[value] = true;
- } else {
- if (type != 'number' && type != 'string') {
- type = 'object';
- }
- var key = type == 'number' ? value : keyPrefix + value,
- typeCache = cache[type] || (cache[type] = {});
- if (type == 'object') {
- (typeCache[key] || (typeCache[key] = [])).push(value);
- } else {
- typeCache[key] = true;
- }
- }
- }
- /**
- * Used by `_.max` and `_.min` as the default callback when a given
- * collection is a string value.
- *
- * @private
- * @param {string} value The character to inspect.
- * @returns {number} Returns the code unit of given character.
- */
- function charAtCallback(value) {
- return value.charCodeAt(0);
- }
- /**
- * Used by `sortBy` to compare transformed `collection` elements, stable sorting
- * them in ascending order.
- *
- * @private
- * @param {Object} a The object to compare to `b`.
- * @param {Object} b The object to compare to `a`.
- * @returns {number} Returns the sort order indicator of `1` or `-1`.
- */
- function compareAscending(a, b) {
- var ac = a.criteria,
- bc = b.criteria,
- index = -1,
- length = ac.length;
- while (++index < length) {
- var value = ac[index],
- other = bc[index];
- if (value !== other) {
- if (value > other || typeof value == 'undefined') {
- return 1;
- }
- if (value < other || typeof other == 'undefined') {
- return -1;
- }
- }
- }
- // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
- // that causes it, under certain circumstances, to return the same value for
- // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247
- //
- // This also ensures a stable sort in V8 and other engines.
- // See http://code.google.com/p/v8/issues/detail?id=90
- return a.index - b.index;
- }
- /**
- * Creates a cache object to optimize linear searches of large arrays.
- *
- * @private
- * @param {Array} [array=[]] The array to search.
- * @returns {null|Object} Returns the cache object or `null` if caching should not be used.
- */
- function createCache(array) {
- var index = -1,
- length = array.length,
- first = array[0],
- mid = array[(length / 2) | 0],
- last = array[length - 1];
- if (first && typeof first == 'object' &&
- mid && typeof mid == 'object' && last && typeof last == 'object') {
- return false;
- }
- var cache = getObject();
- cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false;
- var result = getObject();
- result.array = array;
- result.cache = cache;
- result.push = cachePush;
- while (++index < length) {
- result.push(array[index]);
- }
- return result;
- }
- /**
- * Used by `template` to escape characters for inclusion in compiled
- * string literals.
- *
- * @private
- * @param {string} match The matched character to escape.
- * @returns {string} Returns the escaped character.
- */
- function escapeStringChar(match) {
- return '\\' + stringEscapes[match];
- }
- /**
- * Gets an array from the array pool or creates a new one if the pool is empty.
- *
- * @private
- * @returns {Array} The array from the pool.
- */
- function getArray() {
- return arrayPool.pop() || [];
- }
- /**
- * Gets an object from the object pool or creates a new one if the pool is empty.
- *
- * @private
- * @returns {Object} The object from the pool.
- */
- function getObject() {
- return objectPool.pop() || {
- 'array': null,
- 'cache': null,
- 'criteria': null,
- 'false': false,
- 'index': 0,
- 'null': false,
- 'number': null,
- 'object': null,
- 'push': null,
- 'string': null,
- 'true': false,
- 'undefined': false,
- 'value': null
- };
- }
- /**
- * Releases the given array back to the array pool.
- *
- * @private
- * @param {Array} [array] The array to release.
- */
- function releaseArray(array) {
- array.length = 0;
- if (arrayPool.length < maxPoolSize) {
- arrayPool.push(array);
- }
- }
- /**
- * Releases the given object back to the object pool.
- *
- * @private
- * @param {Object} [object] The object to release.
- */
- function releaseObject(object) {
- var cache = object.cache;
- if (cache) {
- releaseObject(cache);
- }
- object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null;
- if (objectPool.length < maxPoolSize) {
- objectPool.push(object);
- }
- }
- /**
- * Slices the `collection` from the `start` index up to, but not including,
- * the `end` index.
- *
- * Note: This function is used instead of `Array#slice` to support node lists
- * in IE < 9 and to ensure dense arrays are returned.
- *
- * @private
- * @param {Array|Object|string} collection The collection to slice.
- * @param {number} start The start index.
- * @param {number} end The end index.
- * @returns {Array} Returns the new array.
- */
- function slice(array, start, end) {
- start || (start = 0);
- if (typeof end == 'undefined') {
- end = array ? array.length : 0;
- }
- var index = -1,
- length = end - start || 0,
- result = Array(length < 0 ? 0 : length);
- while (++index < length) {
- result[index] = array[start + index];
- }
- return result;
- }
- /*--------------------------------------------------------------------------*/
- /**
- * Create a new `lodash` function using the given context object.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {Object} [context=root] The context object.
- * @returns {Function} Returns the `lodash` function.
- */
- function runInContext(context) {
- // Avoid issues with some ES3 environments that attempt to use values, named
- // after built-in constructors like `Object`, for the creation of literals.
- // ES5 clears this up by stating that literals must use built-in constructors.
- // See http://es5.github.io/#x11.1.5.
- context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root;
- /** Native constructor references */
- var Array = context.Array,
- Boolean = context.Boolean,
- Date = context.Date,
- Function = context.Function,
- Math = context.Math,
- Number = context.Number,
- Object = context.Object,
- RegExp = context.RegExp,
- String = context.String,
- TypeError = context.TypeError;
- /**
- * Used for `Array` method references.
- *
- * Normally `Array.prototype` would suffice, however, using an array literal
- * avoids issues in Narwhal.
- */
- var arrayRef = [];
- /** Used for native method references */
- var objectProto = Object.prototype;
- /** Used to restore the original `_` reference in `noConflict` */
- var oldDash = context._;
- /** Used to resolve the internal [[Class]] of values */
- var toString = objectProto.toString;
- /** Used to detect if a method is native */
- var reNative = RegExp('^' +
- String(toString)
- .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
- .replace(/toString| for [^\]]+/g, '.*?') + '$'
- );
- /** Native method shortcuts */
- var ceil = Math.ceil,
- clearTimeout = context.clearTimeout,
- floor = Math.floor,
- fnToString = Function.prototype.toString,
- getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
- hasOwnProperty = objectProto.hasOwnProperty,
- push = arrayRef.push,
- setTimeout = context.setTimeout,
- splice = arrayRef.splice,
- unshift = arrayRef.unshift;
- /** Used to set meta data on functions */
- var defineProperty = (function() {
- // IE 8 only accepts DOM elements
- try {
- var o = {},
- func = isNative(func = Object.defineProperty) && func,
- result = func(o, o, o) && func;
- } catch(e) { }
- return result;
- }());
- /* Native method shortcuts for methods with the same name as other `lodash` methods */
- var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate,
- nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray,
- nativeIsFinite = context.isFinite,
- nativeIsNaN = context.isNaN,
- nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys,
- nativeMax = Math.max,
- nativeMin = Math.min,
- nativeParseInt = context.parseInt,
- nativeRandom = Math.random;
- /** Used to lookup a built-in constructor by [[Class]] */
- var ctorByClass = {};
- ctorByClass[arrayClass] = Array;
- ctorByClass[boolClass] = Boolean;
- ctorByClass[dateClass] = Date;
- ctorByClass[funcClass] = Function;
- ctorByClass[objectClass] = Object;
- ctorByClass[numberClass] = Number;
- ctorByClass[regexpClass] = RegExp;
- ctorByClass[stringClass] = String;
- /*--------------------------------------------------------------------------*/
- /**
- * Creates a `lodash` object which wraps the given value to enable intuitive
- * method chaining.
- *
- * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
- * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
- * and `unshift`
- *
- * Chaining is supported in custom builds as long as the `value` method is
- * implicitly or explicitly included in the build.
- *
- * The chainable wrapper functions are:
- * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
- * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`,
- * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`,
- * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,
- * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
- * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`,
- * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`,
- * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`,
- * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`,
- * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`,
- * and `zip`
- *
- * The non-chainable wrapper functions are:
- * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`,
- * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`,
- * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
- * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`,
- * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`,
- * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`,
- * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`,
- * `template`, `unescape`, `uniqueId`, and `value`
- *
- * The wrapper functions `first` and `last` return wrapped values when `n` is
- * provided, otherwise they return unwrapped values.
- *
- * Explicit chaining can be enabled by using the `_.chain` method.
- *
- * @name _
- * @constructor
- * @category Chaining
- * @param {*} value The value to wrap in a `lodash` instance.
- * @returns {Object} Returns a `lodash` instance.
- * @example
- *
- * var wrapped = _([1, 2, 3]);
- *
- * // returns an unwrapped value
- * wrapped.reduce(function(sum, num) {
- * return sum + num;
- * });
- * // => 6
- *
- * // returns a wrapped value
- * var squares = wrapped.map(function(num) {
- * return num * num;
- * });
- *
- * _.isArray(squares);
- * // => false
- *
- * _.isArray(squares.value());
- * // => true
- */
- function lodash(value) {
- // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor
- return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__'))
- ? value
- : new lodashWrapper(value);
- }
- /**
- * A fast path for creating `lodash` wrapper objects.
- *
- * @private
- * @param {*} value The value to wrap in a `lodash` instance.
- * @param {boolean} chainAll A flag to enable chaining for all methods
- * @returns {Object} Returns a `lodash` instance.
- */
- function lodashWrapper(value, chainAll) {
- this.__chain__ = !!chainAll;
- this.__wrapped__ = value;
- }
- // ensure `new lodashWrapper` is an instance of `lodash`
- lodashWrapper.prototype = lodash.prototype;
- /**
- * An object used to flag environments features.
- *
- * @static
- * @memberOf _
- * @type Object
- */
- var support = lodash.support = {};
- /**
- * Detect if functions can be decompiled by `Function#toString`
- * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps).
- *
- * @memberOf _.support
- * @type boolean
- */
- support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext);
- /**
- * Detect if `Function#name` is supported (all but IE).
- *
- * @memberOf _.support
- * @type boolean
- */
- support.funcNames = typeof Function.name == 'string';
- /**
- * By default, the template delimiters used by Lo-Dash are similar to those in
- * embedded Ruby (ERB). Change the following template settings to use alternative
- * delimiters.
- *
- * @static
- * @memberOf _
- * @type Object
- */
- lodash.templateSettings = {
- /**
- * Used to detect `data` property values to be HTML-escaped.
- *
- * @memberOf _.templateSettings
- * @type RegExp
- */
- 'escape': /<%-([\s\S]+?)%>/g,
- /**
- * Used to detect code to be evaluated.
- *
- * @memberOf _.templateSettings
- * @type RegExp
- */
- 'evaluate': /<%([\s\S]+?)%>/g,
- /**
- * Used to detect `data` property values to inject.
- *
- * @memberOf _.templateSettings
- * @type RegExp
- */
- 'interpolate': reInterpolate,
- /**
- * Used to reference the data object in the template text.
- *
- * @memberOf _.templateSettings
- * @type string
- */
- 'variable': '',
- /**
- * Used to import variables into the compiled template.
- *
- * @memberOf _.templateSettings
- * @type Object
- */
- 'imports': {
- /**
- * A reference to the `lodash` function.
- *
- * @memberOf _.templateSettings.imports
- * @type Function
- */
- '_': lodash
- }
- };
- /*--------------------------------------------------------------------------*/
- /**
- * The base implementation of `_.bind` that creates the bound function and
- * sets its meta data.
- *
- * @private
- * @param {Array} bindData The bind data array.
- * @returns {Function} Returns the new bound function.
- */
- function baseBind(bindData) {
- var func = bindData[0],
- partialArgs = bindData[2],
- thisArg = bindData[4];
- function bound() {
- // `Function#bind` spec
- // http://es5.github.io/#x15.3.4.5
- if (partialArgs) {
- // avoid `arguments` object deoptimizations by using `slice` instead
- // of `Array.prototype.slice.call` and not assigning `arguments` to a
- // variable as a ternary expression
- var args = slice(partialArgs);
- push.apply(args, arguments);
- }
- // mimic the constructor's `return` behavior
- // http://es5.github.io/#x13.2.2
- if (this instanceof bound) {
- // ensure `new bound` is an instance of `func`
- var thisBinding = baseCreate(func.prototype),
- result = func.apply(thisBinding, args || arguments);
- return isObject(result) ? result : thisBinding;
- }
- return func.apply(thisArg, args || arguments);
- }
- setBindData(bound, bindData);
- return bound;
- }
- /**
- * The base implementation of `_.clone` without argument juggling or support
- * for `thisArg` binding.
- *
- * @private
- * @param {*} value The value to clone.
- * @param {boolean} [isDeep=false] Specify a deep clone.
- * @param {Function} [callback] The function to customize cloning values.
- * @param {Array} [stackA=[]] Tracks traversed source objects.
- * @param {Array} [stackB=[]] Associates clones with source counterparts.
- * @returns {*} Returns the cloned value.
- */
- function baseClone(value, isDeep, callback, stackA, stackB) {
- if (callback) {
- var result = callback(value);
- if (typeof result != 'undefined') {
- return result;
- }
- }
- // inspect [[Class]]
- var isObj = isObject(value);
- if (isObj) {
- var className = toString.call(value);
- if (!cloneableClasses[className]) {
- return value;
- }
- var ctor = ctorByClass[className];
- switch (className) {
- case boolClass:
- case dateClass:
- return new ctor(+value);
- case numberClass:
- case stringClass:
- return new ctor(value);
- case regexpClass:
- result = ctor(value.source, reFlags.exec(value));
- result.lastIndex = value.lastIndex;
- return result;
- }
- } else {
- return value;
- }
- var isArr = isArray(value);
- if (isDeep) {
- // check for circular references and return corresponding clone
- var initedStack = !stackA;
- stackA || (stackA = getArray());
- stackB || (stackB = getArray());
- var length = stackA.length;
- while (length--) {
- if (stackA[length] == value) {
- return stackB[length];
- }
- }
- result = isArr ? ctor(value.length) : {};
- }
- else {
- result = isArr ? slice(value) : assign({}, value);
- }
- // add array properties assigned by `RegExp#exec`
- if (isArr) {
- if (hasOwnProperty.call(value, 'index')) {
- result.index = value.index;
- }
- if (hasOwnProperty.call(value, 'input')) {
- result.input = value.input;
- }
- }
- // exit for shallow clone
- if (!isDeep) {
- return result;
- }
- // add the source value to the stack of traversed objects
- // and associate it with its clone
- stackA.push(value);
- stackB.push(result);
- // recursively populate clone (susceptible to call stack limits)
- (isArr ? forEach : forOwn)(value, function(objValue, key) {
- result[key] = baseClone(objValue, isDeep, callback, stackA, stackB);
- });
- if (initedStack) {
- releaseArray(stackA);
- releaseArray(stackB);
- }
- return result;
- }
- /**
- * The base implementation of `_.create` without support for assigning
- * properties to the created object.
- *
- * @private
- * @param {Object} prototype The object to inherit from.
- * @returns {Object} Returns the new object.
- */
- function baseCreate(prototype, properties) {
- return isObject(prototype) ? nativeCreate(prototype) : {};
- }
- // fallback for browsers without `Object.create`
- if (!nativeCreate) {
- baseCreate = (function() {
- function Object() {}
- return function(prototype) {
- if (isObject(prototype)) {
- Object.prototype = prototype;
- var result = new Object;
- Object.prototype = null;
- }
- return result || context.Object();
- };
- }());
- }
- /**
- * The base implementation of `_.createCallback` without support for creating
- * "_.pluck" or "_.where" style callbacks.
- *
- * @private
- * @param {*} [func=identity] The value to convert to a callback.
- * @param {*} [thisArg] The `this` binding of the created callback.
- * @param {number} [argCount] The number of arguments the callback accepts.
- * @returns {Function} Returns a callback function.
- */
- function baseCreateCallback(func, thisArg, argCount) {
- if (typeof func != 'function') {
- return identity;
- }
- // exit early for no `thisArg` or already bound by `Function#bind`
- if (typeof thisArg == 'undefined' || !('prototype' in func)) {
- return func;
- }
- var bindData = func.__bindData__;
- if (typeof bindData == 'undefined') {
- if (support.funcNames) {
- bindData = !func.name;
- }
- bindData = bindData || !support.funcDecomp;
- if (!bindData) {
- var source = fnToString.call(func);
- if (!support.funcNames) {
- bindData = !reFuncName.test(source);
- }
- if (!bindData) {
- // checks if `func` references the `this` keyword and stores the result
- bindData = reThis.test(source);
- setBindData(func, bindData);
- }
- }
- }
- // exit early if there are no `this` references or `func` is bound
- if (bindData === false || (bindData !== true && bindData[1] & 1)) {
- return func;
- }
- switch (argCount) {
- case 1: return function(value) {
- return func.call(thisArg, value);
- };
- case 2: return function(a, b) {
- return func.call(thisArg, a, b);
- };
- case 3: return function(value, index, collection) {
- return func.call(thisArg, value, index, collection);
- };
- case 4: return function(accumulator, value, index, collection) {
- return func.call(thisArg, accumulator, value, index, collection);
- };
- }
- return bind(func, thisArg);
- }
- /**
- * The base implementation of `createWrapper` that creates the wrapper and
- * sets its meta data.
- *
- * @private
- * @param {Array} bindData The bind data array.
- * @returns {Function} Returns the new function.
- */
- function baseCreateWrapper(bindData) {
- var func = bindData[0],
- bitmask = bindData[1],
- partialArgs = bindData[2],
- partialRightArgs = bindData[3],
- thisArg = bindData[4],
- arity = bindData[5];
- var isBind = bitmask & 1,
- isBindKey = bitmask & 2,
- isCurry = bitmask & 4,
- isCurryBound = bitmask & 8,
- key = func;
- function bound() {
- var thisBinding = isBind ? thisArg : this;
- if (partialArgs) {
- var args = slice(partialArgs);
- push.apply(args, arguments);
- }
- if (partialRightArgs || isCurry) {
- args || (args = slice(arguments));
- if (partialRightArgs) {
- push.apply(args, partialRightArgs);
- }
- if (isCurry && args.length < arity) {
- bitmask |= 16 & ~32;
- return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]);
- }
- }
- args || (args = arguments);
- if (isBindKey) {
- func = thisBinding[key];
- }
- if (this instanceof bound) {
- thisBinding = baseCreate(func.prototype);
- var result = func.apply(thisBinding, args);
- return isObject(result) ? result : thisBinding;
- }
- return func.apply(thisBinding, args);
- }
- setBindData(bound, bindData);
- return bound;
- }
- /**
- * The base implementation of `_.difference` that accepts a single array
- * of values to exclude.
- *
- * @private
- * @param {Array} array The array to process.
- * @param {Array} [values] The array of values to exclude.
- * @returns {Array} Returns a new array of filtered values.
- */
- function baseDifference(array, values) {
- var index = -1,
- indexOf = getIndexOf(),
- length = array ? array.length : 0,
- isLarge = length >= largeArraySize && indexOf === baseIndexOf,
- result = [];
- if (isLarge) {
- var cache = createCache(values);
- if (cache) {
- indexOf = cacheIndexOf;
- values = cache;
- } else {
- isLarge = false;
- }
- }
- while (++index < length) {
- var value = array[index];
- if (indexOf(values, value) < 0) {
- result.push(value);
- }
- }
- if (isLarge) {
- releaseObject(values);
- }
- return result;
- }
- /**
- * The base implementation of `_.flatten` without support for callback
- * shorthands or `thisArg` binding.
- *
- * @private
- * @param {Array} array The array to flatten.
- * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
- * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects.
- * @param {number} [fromIndex=0] The index to start from.
- * @returns {Array} Returns a new flattened array.
- */
- function baseFlatten(array, isShallow, isStrict, fromIndex) {
- var index = (fromIndex || 0) - 1,
- length = array ? array.length : 0,
- result = [];
- while (++index < length) {
- var value = array[index];
- if (value && typeof value == 'object' && typeof value.length == 'number'
- && (isArray(value) || isArguments(value))) {
- // recursively flatten arrays (susceptible to call stack limits)
- if (!isShallow) {
- value = baseFlatten(value, isShallow, isStrict);
- }
- var valIndex = -1,
- valLength = value.length,
- resIndex = result.length;
- result.length += valLength;
- while (++valIndex < valLength) {
- result[resIndex++] = value[valIndex];
- }
- } else if (!isStrict) {
- result.push(value);
- }
- }
- return result;
- }
- /**
- * The base implementation of `_.isEqual`, without support for `thisArg` binding,
- * that allows partial "_.where" style comparisons.
- *
- * @private
- * @param {*} a The value to compare.
- * @param {*} b The other value to compare.
- * @param {Function} [callback] The function to customize comparing values.
- * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons.
- * @param {Array} [stackA=[]] Tracks traversed `a` objects.
- * @param {Array} [stackB=[]] Tracks traversed `b` objects.
- * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
- */
- function baseIsEqual(a, b, callback, isWhere, stackA, stackB) {
- // used to indicate that when comparing objects, `a` has at least the properties of `b`
- if (callback) {
- var result = callback(a, b);
- if (typeof result != 'undefined') {
- return !!result;
- }
- }
- // exit early for identical values
- if (a === b) {
- // treat `+0` vs. `-0` as not equal
- return a !== 0 || (1 / a == 1 / b);
- }
- var type = typeof a,
- otherType = typeof b;
- // exit early for unlike primitive values
- if (a === a &&
- !(a && objectTypes[type]) &&
- !(b && objectTypes[otherType])) {
- return false;
- }
- // exit early for `null` and `undefined` avoiding ES3's Function#call behavior
- // http://es5.github.io/#x15.3.4.4
- if (a == null || b == null) {
- return a === b;
- }
- // compare [[Class]] names
- var className = toString.call(a),
- otherClass = toString.call(b);
- if (className == argsClass) {
- className = objectClass;
- }
- if (otherClass == argsClass) {
- otherClass = objectClass;
- }
- if (className != otherClass) {
- return false;
- }
- switch (className) {
- case boolClass:
- case dateClass:
- // coerce dates and booleans to numbers, dates to milliseconds and booleans
- // to `1` or `0` treating invalid dates coerced to `NaN` as not equal
- return +a == +b;
- case numberClass:
- // treat `NaN` vs. `NaN` as equal
- return (a != +a)
- ? b != +b
- // but treat `+0` vs. `-0` as not equal
- : (a == 0 ? (1 / a == 1 / b) : a == +b);
- case regexpClass:
- case stringClass:
- // coerce regexes to strings (http://es5.github.io/#x15.10.6.4)
- // treat string primitives and their corresponding object instances as equal
- return a == String(b);
- }
- var isArr = className == arrayClass;
- if (!isArr) {
- // unwrap any `lodash` wrapped values
- var aWrapped = hasOwnProperty.call(a, '__wrapped__'),
- bWrapped = hasOwnProperty.call(b, '__wrapped__');
- if (aWrapped || bWrapped) {
- return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB);
- }
- // exit for functions and DOM nodes
- if (className != objectClass) {
- return false;
- }
- // in older versions of Opera, `arguments` objects have `Array` constructors
- var ctorA = a.constructor,
- ctorB = b.constructor;
- // non `Object` object instances with different constructors are not equal
- if (ctorA != ctorB &&
- !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) &&
- ('constructor' in a && 'constructor' in b)
- ) {
- return false;
- }
- }
- // assume cyclic structures are equal
- // the algorithm for detecting cyclic structures is adapted from ES 5.1
- // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3)
- var initedStack = !stackA;
- stackA || (stackA = getArray());
- stackB || (stackB = getArray());
- var length = stackA.length;
- while (length--) {
- if (stackA[length] == a) {
- return stackB[length] == b;
- }
- }
- var size = 0;
- result = true;
- // add `a` and `b` to the stack of traversed objects
- stackA.push(a);
- stackB.push(b);
- // recursively compare objects and arrays (susceptible to call stack limits)
- if (isArr) {
- // compare lengths to determine if a deep comparison is necessary
- length = a.length;
- size = b.length;
- result = size == length;
- if (result || isWhere) {
- // deep compare the contents, ignoring non-numeric properties
- while (size--) {
- var index = length,
- value = b[size];
- if (isWhere) {
- while (index--) {
- if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) {
- break;
- }
- }
- } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) {
- break;
- }
- }
- }
- }
- else {
- // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys`
- // which, in this case, is more costly
- forIn(b, function(value, key, b) {
- if (hasOwnProperty.call(b, key)) {
- // count the number of properties.
- size++;
- // deep compare each property value.
- return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB));
- }
- });
- if (result && !isWhere) {
- // ensure both objects have the same number of properties
- forIn(a, function(value, key, a) {
- if (hasOwnProperty.call(a, key)) {
- // `size` will be `-1` if `a` has more properties than `b`
- return (result = --size > -1);
- }
- });
- }
- }
- stackA.pop();
- stackB.pop();
- if (initedStack) {
- releaseArray(stackA);
- releaseArray(stackB);
- }
- return result;
- }
- /**
- * The base implementation of `_.merge` without argument juggling or support
- * for `thisArg` binding.
- *
- * @private
- * @param {Object} object The destination object.
- * @param {Object} source The source object.
- * @param {Function} [callback] The function to customize merging properties.
- * @param {Array} [stackA=[]] Tracks traversed source objects.
- * @param {Array} [stackB=[]] Associates values with source counterparts.
- */
- function baseMerge(object, source, callback, stackA, stackB) {
- (isArray(source) ? forEach : forOwn)(source, function(source, key) {
- var found,
- isArr,
- result = source,
- value = object[key];
- if (source && ((isArr = isArray(source)) || isPlainObject(source))) {
- // avoid merging previously merged cyclic sources
- var stackLength = stackA.length;
- while (stackLength--) {
- if ((found = stackA[stackLength] == source)) {
- value = stackB[stackLength];
- break;
- }
- }
- if (!found) {
- var isShallow;
- if (callback) {
- result = callback(value, source);
- if ((isShallow = typeof result != 'undefined')) {
- value = result;
- }
- }
- if (!isShallow) {
- value = isArr
- ? (isArray(value) ? value : [])
- : (isPlainObject(value) ? value : {});
- }
- // add `source` and associated `value` to the stack of traversed objects
- stackA.push(source);
- stackB.push(value);
- // recursively merge objects and arrays (susceptible to call stack limits)
- if (!isShallow) {
- baseMerge(value, source, callback, stackA, stackB);
- }
- }
- }
- else {
- if (callback) {
- result = callback(value, source);
- if (typeof result == 'undefined') {
- result = source;
- }
- }
- if (typeof result != 'undefined') {
- value = result;
- }
- }
- object[key] = value;
- });
- }
- /**
- * The base implementation of `_.random` without argument juggling or support
- * for returning floating-point numbers.
- *
- * @private
- * @param {number} min The minimum possible value.
- * @param {number} max The maximum possible value.
- * @returns {number} Returns a random number.
- */
- function baseRandom(min, max) {
- return min + floor(nativeRandom() * (max - min + 1));
- }
- /**
- * The base implementation of `_.uniq` without support for callback shorthands
- * or `thisArg` binding.
- *
- * @private
- * @param {Array} array The array to process.
- * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
- * @param {Function} [callback] The function called per iteration.
- * @returns {Array} Returns a duplicate-value-free array.
- */
- function baseUniq(array, isSorted, callback) {
- var index = -1,
- indexOf = getIndexOf(),
- length = array ? array.length : 0,
- result = [];
- var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf,
- seen = (callback || isLarge) ? getArray() : result;
- if (isLarge) {
- var cache = createCache(seen);
- indexOf = cacheIndexOf;
- seen = cache;
- }
- while (++index < length) {
- var value = array[index],
- computed = callback ? callback(value, index, array) : value;
- if (isSorted
- ? !index || seen[seen.length - 1] !== computed
- : indexOf(seen, computed) < 0
- ) {
- if (callback || isLarge) {
- seen.push(computed);
- }
- result.push(value);
- }
- }
- if (isLarge) {
- releaseArray(seen.array);
- releaseObject(seen);
- } else if (callback) {
- releaseArray(seen);
- }
- return result;
- }
- /**
- * Creates a function that aggregates a collection, creating an object composed
- * of keys generated from the results of running each element of the collection
- * through a callback. The given `setter` function sets the keys and values
- * of the composed object.
- *
- * @private
- * @param {Function} setter The setter function.
- * @returns {Function} Returns the new aggregator function.
- */
- function createAggregator(setter) {
- return function(collection, callback, thisArg) {
- var result = {};
- callback = lodash.createCallback(callback, thisArg, 3);
- var index = -1,
- length = collection ? collection.length : 0;
- if (typeof length == 'number') {
- while (++index < length) {
- var value = collection[index];
- setter(result, value, callback(value, index, collection), collection);
- }
- } else {
- forOwn(collection, function(value, key, collection) {
- setter(result, value, callback(value, key, collection), collection);
- });
- }
- return result;
- };
- }
- /**
- * Creates a function that, when called, either curries or invokes `func`
- * with an optional `this` binding and partially applied arguments.
- *
- * @private
- * @param {Function|string} func The function or method name to reference.
- * @param {number} bitmask The bitmask of method flags to compose.
- * The bitmask may be composed of the following flags:
- * 1 - `_.bind`
- * 2 - `_.bindKey`
- * 4 - `_.curry`
- * 8 - `_.curry` (bound)
- * 16 - `_.partial`
- * 32 - `_.partialRight`
- * @param {Array} [partialArgs] An array of arguments to prepend to those
- * provided to the new function.
- * @param {Array} [partialRightArgs] An array of arguments to append to those
- * provided to the new function.
- * @param {*} [thisArg] The `this` binding of `func`.
- * @param {number} [arity] The arity of `func`.
- * @returns {Function} Returns the new function.
- */
- function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) {
- var isBind = bitmask & 1,
- isBindKey = bitmask & 2,
- isCurry = bitmask & 4,
- isCurryBound = bitmask & 8,
- isPartial = bitmask & 16,
- isPartialRight = bitmask & 32;
- if (!isBindKey && !isFunction(func)) {
- throw new TypeError;
- }
- if (isPartial && !partialArgs.length) {
- bitmask &= ~16;
- isPartial = partialArgs = false;
- }
- if (isPartialRight && !partialRightArgs.length) {
- bitmask &= ~32;
- isPartialRight = partialRightArgs = false;
- }
- var bindData = func && func.__bindData__;
- if (bindData && bindData !== true) {
- // clone `bindData`
- bindData = slice(bindData);
- if (bindData[2]) {
- bindData[2] = slice(bindData[2]);
- }
- if (bindData[3]) {
- bindData[3] = slice(bindData[3]);
- }
- // set `thisBinding` is not previously bound
- if (isBind && !(bindData[1] & 1)) {
- bindData[4] = thisArg;
- }
- // set if previously bound but not currently (subsequent curried functions)
- if (!isBind && bindData[1] & 1) {
- bitmask |= 8;
- }
- // set curried arity if not yet set
- if (isCurry && !(bindData[1] & 4)) {
- bindData[5] = arity;
- }
- // append partial left arguments
- if (isPartial) {
- push.apply(bindData[2] || (bindData[2] = []), partialArgs);
- }
- // append partial right arguments
- if (isPartialRight) {
- unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs);
- }
- // merge flags
- bindData[1] |= bitmask;
- return createWrapper.apply(null, bindData);
- }
- // fast path for `_.bind`
- var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper;
- return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]);
- }
- /**
- * Used by `escape` to convert characters to HTML entities.
- *
- * @private
- * @param {string} match The matched character to escape.
- * @returns {string} Returns the escaped character.
- */
- function escapeHtmlChar(match) {
- return htmlEscapes[match];
- }
- /**
- * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
- * customized, this method returns the custom method, otherwise it returns
- * the `baseIndexOf` function.
- *
- * @private
- * @returns {Function} Returns the "indexOf" function.
- */
- function getIndexOf() {
- var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result;
- return result;
- }
- /**
- * Checks if `value` is a native function.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a native function, else `false`.
- */
- function isNative(value) {
- return typeof value == 'function' && reNative.test(value);
- }
- /**
- * Sets `this` binding data on a given function.
- *
- * @private
- * @param {Function} func The function to set data on.
- * @param {Array} value The data array to set.
- */
- var setBindData = !defineProperty ? noop : function(func, value) {
- descriptor.value = value;
- defineProperty(func, '__bindData__', descriptor);
- };
- /**
- * A fallback implementation of `isPlainObject` which checks if a given value
- * is an object created by the `Object` constructor, assuming objects created
- * by the `Object` constructor have no inherited enumerable properties and that
- * there are no `Object.prototype` extensions.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
- */
- function shimIsPlainObject(value) {
- var ctor,
- result;
- // avoid non Object objects, `arguments` objects, and DOM elements
- if (!(value && toString.call(value) == objectClass) ||
- (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor))) {
- return false;
- }
- // In most environments an object's own properties are iterated before
- // its inherited properties. If the last iterated property is an object's
- // own property then there are no inherited enumerable properties.
- forIn(value, function(value, key) {
- result = key;
- });
- return typeof result == 'undefined' || hasOwnProperty.call(value, result);
- }
- /**
- * Used by `unescape` to convert HTML entities to characters.
- *
- * @private
- * @param {string} match The matched character to unescape.
- * @returns {string} Returns the unescaped character.
- */
- function unescapeHtmlChar(match) {
- return htmlUnescapes[match];
- }
- /*--------------------------------------------------------------------------*/
- /**
- * Checks if `value` is an `arguments` object.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`.
- * @example
- *
- * (function() { return _.isArguments(arguments); })(1, 2, 3);
- * // => true
- *
- * _.isArguments([1, 2, 3]);
- * // => false
- */
- function isArguments(value) {
- return value && typeof value == 'object' && typeof value.length == 'number' &&
- toString.call(value) == argsClass || false;
- }
- /**
- * Checks if `value` is an array.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is an array, else `false`.
- * @example
- *
- * (function() { return _.isArray(arguments); })();
- * // => false
- *
- * _.isArray([1, 2, 3]);
- * // => true
- */
- var isArray = nativeIsArray || function(value) {
- return value && typeof value == 'object' && typeof value.length == 'number' &&
- toString.call(value) == arrayClass || false;
- };
- /**
- * A fallback implementation of `Object.keys` which produces an array of the
- * given object's own enumerable property names.
- *
- * @private
- * @type Function
- * @param {Object} object The object to inspect.
- * @returns {Array} Returns an array of property names.
- */
- var shimKeys = function(object) {
- var index, iterable = object, result = [];
- if (!iterable) return result;
- if (!(objectTypes[typeof object])) return result;
- for (index in iterable) {
- if (hasOwnProperty.call(iterable, index)) {
- result.push(index);
- }
- }
- return result
- };
- /**
- * Creates an array composed of the own enumerable property names of an object.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to inspect.
- * @returns {Array} Returns an array of property names.
- * @example
- *
- * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
- * // => ['one', 'two', 'three'] (property order is not guaranteed across environments)
- */
- var keys = !nativeKeys ? shimKeys : function(object) {
- if (!isObject(object)) {
- return [];
- }
- return nativeKeys(object);
- };
- /**
- * Used to convert characters to HTML entities:
- *
- * Though the `>` character is escaped for symmetry, characters like `>` and `/`
- * don't require escaping in HTML and have no special meaning unless they're part
- * of a tag or an unquoted attribute value.
- * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
- */
- var htmlEscapes = {
- '&': '&',
- '<': '<',
- '>': '>',
- '"': '"',
- "'": '''
- };
- /** Used to convert HTML entities to characters */
- var htmlUnescapes = invert(htmlEscapes);
- /** Used to match HTML entities and HTML characters */
- var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'),
- reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g');
- /*--------------------------------------------------------------------------*/
- /**
- * Assigns own enumerable properties of source object(s) to the destination
- * object. Subsequent sources will overwrite property assignments of previous
- * sources. If a callback is provided it will be executed to produce the
- * assigned values. The callback is bound to `thisArg` and invoked with two
- * arguments; (objectValue, sourceValue).
- *
- * @static
- * @memberOf _
- * @type Function
- * @alias extend
- * @category Objects
- * @param {Object} object The destination object.
- * @param {...Object} [source] The source objects.
- * @param {Function} [callback] The function to customize assigning values.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns the destination object.
- * @example
- *
- * _.assign({ 'name': 'fred' }, { 'employer': 'slate' });
- * // => { 'name': 'fred', 'employer': 'slate' }
- *
- * var defaults = _.partialRight(_.assign, function(a, b) {
- * return typeof a == 'undefined' ? b : a;
- * });
- *
- * var object = { 'name': 'barney' };
- * defaults(object, { 'name': 'fred', 'employer': 'slate' });
- * // => { 'name': 'barney', 'employer': 'slate' }
- */
- var assign = function(object, source, guard) {
- var index, iterable = object, result = iterable;
- if (!iterable) return result;
- var args = arguments,
- argsIndex = 0,
- argsLength = typeof guard == 'number' ? 2 : args.length;
- if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {
- var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);
- } else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {
- callback = args[--argsLength];
- }
- while (++argsIndex < argsLength) {
- iterable = args[argsIndex];
- if (iterable && objectTypes[typeof iterable]) {
- var ownIndex = -1,
- ownProps = objectTypes[typeof iterable] && keys(iterable),
- length = ownProps ? ownProps.length : 0;
- while (++ownIndex < length) {
- index = ownProps[ownIndex];
- result[index] = callback ? callback(result[index], iterable[index]) : iterable[index];
- }
- }
- }
- return result
- };
- /**
- * Creates a clone of `value`. If `isDeep` is `true` nested objects will also
- * be cloned, otherwise they will be assigned by reference. If a callback
- * is provided it will be executed to produce the cloned values. If the
- * callback returns `undefined` cloning will be handled by the method instead.
- * The callback is bound to `thisArg` and invoked with one argument; (value).
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to clone.
- * @param {boolean} [isDeep=false] Specify a deep clone.
- * @param {Function} [callback] The function to customize cloning values.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the cloned value.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * var shallow = _.clone(characters);
- * shallow[0] === characters[0];
- * // => true
- *
- * var deep = _.clone(characters, true);
- * deep[0] === characters[0];
- * // => false
- *
- * _.mixin({
- * 'clone': _.partialRight(_.clone, function(value) {
- * return _.isElement(value) ? value.cloneNode(false) : undefined;
- * })
- * });
- *
- * var clone = _.clone(document.body);
- * clone.childNodes.length;
- * // => 0
- */
- function clone(value, isDeep, callback, thisArg) {
- // allows working with "Collections" methods without using their `index`
- // and `collection` arguments for `isDeep` and `callback`
- if (typeof isDeep != 'boolean' && isDeep != null) {
- thisArg = callback;
- callback = isDeep;
- isDeep = false;
- }
- return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
- }
- /**
- * Creates a deep clone of `value`. If a callback is provided it will be
- * executed to produce the cloned values. If the callback returns `undefined`
- * cloning will be handled by the method instead. The callback is bound to
- * `thisArg` and invoked with one argument; (value).
- *
- * Note: This method is loosely based on the structured clone algorithm. Functions
- * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
- * objects created by constructors other than `Object` are cloned to plain `Object` objects.
- * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to deep clone.
- * @param {Function} [callback] The function to customize cloning values.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the deep cloned value.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * var deep = _.cloneDeep(characters);
- * deep[0] === characters[0];
- * // => false
- *
- * var view = {
- * 'label': 'docs',
- * 'node': element
- * };
- *
- * var clone = _.cloneDeep(view, function(value) {
- * return _.isElement(value) ? value.cloneNode(true) : undefined;
- * });
- *
- * clone.node == view.node;
- * // => false
- */
- function cloneDeep(value, callback, thisArg) {
- return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
- }
- /**
- * Creates an object that inherits from the given `prototype` object. If a
- * `properties` object is provided its own enumerable properties are assigned
- * to the created object.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} prototype The object to inherit from.
- * @param {Object} [properties] The properties to assign to the object.
- * @returns {Object} Returns the new object.
- * @example
- *
- * function Shape() {
- * this.x = 0;
- * this.y = 0;
- * }
- *
- * function Circle() {
- * Shape.call(this);
- * }
- *
- * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle });
- *
- * var circle = new Circle;
- * circle instanceof Circle;
- * // => true
- *
- * circle instanceof Shape;
- * // => true
- */
- function create(prototype, properties) {
- var result = baseCreate(prototype);
- return properties ? assign(result, properties) : result;
- }
- /**
- * Assigns own enumerable properties of source object(s) to the destination
- * object for all destination properties that resolve to `undefined`. Once a
- * property is set, additional defaults of the same property will be ignored.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Objects
- * @param {Object} object The destination object.
- * @param {...Object} [source] The source objects.
- * @param- {Object} [guard] Allows working with `_.reduce` without using its
- * `key` and `object` arguments as sources.
- * @returns {Object} Returns the destination object.
- * @example
- *
- * var object = { 'name': 'barney' };
- * _.defaults(object, { 'name': 'fred', 'employer': 'slate' });
- * // => { 'name': 'barney', 'employer': 'slate' }
- */
- var defaults = function(object, source, guard) {
- var index, iterable = object, result = iterable;
- if (!iterable) return result;
- var args = arguments,
- argsIndex = 0,
- argsLength = typeof guard == 'number' ? 2 : args.length;
- while (++argsIndex < argsLength) {
- iterable = args[argsIndex];
- if (iterable && objectTypes[typeof iterable]) {
- var ownIndex = -1,
- ownProps = objectTypes[typeof iterable] && keys(iterable),
- length = ownProps ? ownProps.length : 0;
- while (++ownIndex < length) {
- index = ownProps[ownIndex];
- if (typeof result[index] == 'undefined') result[index] = iterable[index];
- }
- }
- }
- return result
- };
- /**
- * This method is like `_.findIndex` except that it returns the key of the
- * first element that passes the callback check, instead of the element itself.
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to search.
- * @param {Function|Object|string} [callback=identity] The function called per
- * iteration. If a property name or object is provided it will be used to
- * create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {string|undefined} Returns the key of the found element, else `undefined`.
- * @example
- *
- * var characters = {
- * 'barney': { 'age': 36, 'blocked': false },
- * 'fred': { 'age': 40, 'blocked': true },
- * 'pebbles': { 'age': 1, 'blocked': false }
- * };
- *
- * _.findKey(characters, function(chr) {
- * return chr.age < 40;
- * });
- * // => 'barney' (property order is not guaranteed across environments)
- *
- * // using "_.where" callback shorthand
- * _.findKey(characters, { 'age': 1 });
- * // => 'pebbles'
- *
- * // using "_.pluck" callback shorthand
- * _.findKey(characters, 'blocked');
- * // => 'fred'
- */
- function findKey(object, callback, thisArg) {
- var result;
- callback = lodash.createCallback(callback, thisArg, 3);
- forOwn(object, function(value, key, object) {
- if (callback(value, key, object)) {
- result = key;
- return false;
- }
- });
- return result;
- }
- /**
- * This method is like `_.findKey` except that it iterates over elements
- * of a `collection` in the opposite order.
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to search.
- * @param {Function|Object|string} [callback=identity] The function called per
- * iteration. If a property name or object is provided it will be used to
- * create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {string|undefined} Returns the key of the found element, else `undefined`.
- * @example
- *
- * var characters = {
- * 'barney': { 'age': 36, 'blocked': true },
- * 'fred': { 'age': 40, 'blocked': false },
- * 'pebbles': { 'age': 1, 'blocked': true }
- * };
- *
- * _.findLastKey(characters, function(chr) {
- * return chr.age < 40;
- * });
- * // => returns `pebbles`, assuming `_.findKey` returns `barney`
- *
- * // using "_.where" callback shorthand
- * _.findLastKey(characters, { 'age': 40 });
- * // => 'fred'
- *
- * // using "_.pluck" callback shorthand
- * _.findLastKey(characters, 'blocked');
- * // => 'pebbles'
- */
- function findLastKey(object, callback, thisArg) {
- var result;
- callback = lodash.createCallback(callback, thisArg, 3);
- forOwnRight(object, function(value, key, object) {
- if (callback(value, key, object)) {
- result = key;
- return false;
- }
- });
- return result;
- }
- /**
- * Iterates over own and inherited enumerable properties of an object,
- * executing the callback for each property. The callback is bound to `thisArg`
- * and invoked with three arguments; (value, key, object). Callbacks may exit
- * iteration early by explicitly returning `false`.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Objects
- * @param {Object} object The object to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns `object`.
- * @example
- *
- * function Shape() {
- * this.x = 0;
- * this.y = 0;
- * }
- *
- * Shape.prototype.move = function(x, y) {
- * this.x += x;
- * this.y += y;
- * };
- *
- * _.forIn(new Shape, function(value, key) {
- * console.log(key);
- * });
- * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments)
- */
- var forIn = function(collection, callback, thisArg) {
- var index, iterable = collection, result = iterable;
- if (!iterable) return result;
- if (!objectTypes[typeof iterable]) return result;
- callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
- for (index in iterable) {
- if (callback(iterable[index], index, collection) === false) return result;
- }
- return result
- };
- /**
- * This method is like `_.forIn` except that it iterates over elements
- * of a `collection` in the opposite order.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns `object`.
- * @example
- *
- * function Shape() {
- * this.x = 0;
- * this.y = 0;
- * }
- *
- * Shape.prototype.move = function(x, y) {
- * this.x += x;
- * this.y += y;
- * };
- *
- * _.forInRight(new Shape, function(value, key) {
- * console.log(key);
- * });
- * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move'
- */
- function forInRight(object, callback, thisArg) {
- var pairs = [];
- forIn(object, function(value, key) {
- pairs.push(key, value);
- });
- var length = pairs.length;
- callback = baseCreateCallback(callback, thisArg, 3);
- while (length--) {
- if (callback(pairs[length--], pairs[length], object) === false) {
- break;
- }
- }
- return object;
- }
- /**
- * Iterates over own enumerable properties of an object, executing the callback
- * for each property. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, key, object). Callbacks may exit iteration early by
- * explicitly returning `false`.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Objects
- * @param {Object} object The object to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns `object`.
- * @example
- *
- * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
- * console.log(key);
- * });
- * // => logs '0', '1', and 'length' (property order is not guaranteed across environments)
- */
- var forOwn = function(collection, callback, thisArg) {
- var index, iterable = collection, result = iterable;
- if (!iterable) return result;
- if (!objectTypes[typeof iterable]) return result;
- callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
- var ownIndex = -1,
- ownProps = objectTypes[typeof iterable] && keys(iterable),
- length = ownProps ? ownProps.length : 0;
- while (++ownIndex < length) {
- index = ownProps[ownIndex];
- if (callback(iterable[index], index, collection) === false) return result;
- }
- return result
- };
- /**
- * This method is like `_.forOwn` except that it iterates over elements
- * of a `collection` in the opposite order.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns `object`.
- * @example
- *
- * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
- * console.log(key);
- * });
- * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length'
- */
- function forOwnRight(object, callback, thisArg) {
- var props = keys(object),
- length = props.length;
- callback = baseCreateCallback(callback, thisArg, 3);
- while (length--) {
- var key = props[length];
- if (callback(object[key], key, object) === false) {
- break;
- }
- }
- return object;
- }
- /**
- * Creates a sorted array of property names of all enumerable properties,
- * own and inherited, of `object` that have function values.
- *
- * @static
- * @memberOf _
- * @alias methods
- * @category Objects
- * @param {Object} object The object to inspect.
- * @returns {Array} Returns an array of property names that have function values.
- * @example
- *
- * _.functions(_);
- * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
- */
- function functions(object) {
- var result = [];
- forIn(object, function(value, key) {
- if (isFunction(value)) {
- result.push(key);
- }
- });
- return result.sort();
- }
- /**
- * Checks if the specified property name exists as a direct property of `object`,
- * instead of an inherited property.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to inspect.
- * @param {string} key The name of the property to check.
- * @returns {boolean} Returns `true` if key is a direct property, else `false`.
- * @example
- *
- * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
- * // => true
- */
- function has(object, key) {
- return object ? hasOwnProperty.call(object, key) : false;
- }
- /**
- * Creates an object composed of the inverted keys and values of the given object.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to invert.
- * @returns {Object} Returns the created inverted object.
- * @example
- *
- * _.invert({ 'first': 'fred', 'second': 'barney' });
- * // => { 'fred': 'first', 'barney': 'second' }
- */
- function invert(object) {
- var index = -1,
- props = keys(object),
- length = props.length,
- result = {};
- while (++index < length) {
- var key = props[index];
- result[object[key]] = key;
- }
- return result;
- }
- /**
- * Checks if `value` is a boolean value.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`.
- * @example
- *
- * _.isBoolean(null);
- * // => false
- */
- function isBoolean(value) {
- return value === true || value === false ||
- value && typeof value == 'object' && toString.call(value) == boolClass || false;
- }
- /**
- * Checks if `value` is a date.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a date, else `false`.
- * @example
- *
- * _.isDate(new Date);
- * // => true
- */
- function isDate(value) {
- return value && typeof value == 'object' && toString.call(value) == dateClass || false;
- }
- /**
- * Checks if `value` is a DOM element.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`.
- * @example
- *
- * _.isElement(document.body);
- * // => true
- */
- function isElement(value) {
- return value && value.nodeType === 1 || false;
- }
- /**
- * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
- * length of `0` and objects with no own enumerable properties are considered
- * "empty".
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Array|Object|string} value The value to inspect.
- * @returns {boolean} Returns `true` if the `value` is empty, else `false`.
- * @example
- *
- * _.isEmpty([1, 2, 3]);
- * // => false
- *
- * _.isEmpty({});
- * // => true
- *
- * _.isEmpty('');
- * // => true
- */
- function isEmpty(value) {
- var result = true;
- if (!value) {
- return result;
- }
- var className = toString.call(value),
- length = value.length;
- if ((className == arrayClass || className == stringClass || className == argsClass ) ||
- (className == objectClass && typeof length == 'number' && isFunction(value.splice))) {
- return !length;
- }
- forOwn(value, function() {
- return (result = false);
- });
- return result;
- }
- /**
- * Performs a deep comparison between two values to determine if they are
- * equivalent to each other. If a callback is provided it will be executed
- * to compare values. If the callback returns `undefined` comparisons will
- * be handled by the method instead. The callback is bound to `thisArg` and
- * invoked with two arguments; (a, b).
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} a The value to compare.
- * @param {*} b The other value to compare.
- * @param {Function} [callback] The function to customize comparing values.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
- * @example
- *
- * var object = { 'name': 'fred' };
- * var copy = { 'name': 'fred' };
- *
- * object == copy;
- * // => false
- *
- * _.isEqual(object, copy);
- * // => true
- *
- * var words = ['hello', 'goodbye'];
- * var otherWords = ['hi', 'goodbye'];
- *
- * _.isEqual(words, otherWords, function(a, b) {
- * var reGreet = /^(?:hello|hi)$/i,
- * aGreet = _.isString(a) && reGreet.test(a),
- * bGreet = _.isString(b) && reGreet.test(b);
- *
- * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
- * });
- * // => true
- */
- function isEqual(a, b, callback, thisArg) {
- return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2));
- }
- /**
- * Checks if `value` is, or can be coerced to, a finite number.
- *
- * Note: This is not the same as native `isFinite` which will return true for
- * booleans and empty strings. See http://es5.github.io/#x15.1.2.5.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is finite, else `false`.
- * @example
- *
- * _.isFinite(-101);
- * // => true
- *
- * _.isFinite('10');
- * // => true
- *
- * _.isFinite(true);
- * // => false
- *
- * _.isFinite('');
- * // => false
- *
- * _.isFinite(Infinity);
- * // => false
- */
- function isFinite(value) {
- return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
- }
- /**
- * Checks if `value` is a function.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a function, else `false`.
- * @example
- *
- * _.isFunction(_);
- * // => true
- */
- function isFunction(value) {
- return typeof value == 'function';
- }
- /**
- * Checks if `value` is the language type of Object.
- * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is an object, else `false`.
- * @example
- *
- * _.isObject({});
- * // => true
- *
- * _.isObject([1, 2, 3]);
- * // => true
- *
- * _.isObject(1);
- * // => false
- */
- function isObject(value) {
- // check if the value is the ECMAScript language type of Object
- // http://es5.github.io/#x8
- // and avoid a V8 bug
- // http://code.google.com/p/v8/issues/detail?id=2291
- return !!(value && objectTypes[typeof value]);
- }
- /**
- * Checks if `value` is `NaN`.
- *
- * Note: This is not the same as native `isNaN` which will return `true` for
- * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`.
- * @example
- *
- * _.isNaN(NaN);
- * // => true
- *
- * _.isNaN(new Number(NaN));
- * // => true
- *
- * isNaN(undefined);
- * // => true
- *
- * _.isNaN(undefined);
- * // => false
- */
- function isNaN(value) {
- // `NaN` as a primitive is the only value that is not equal to itself
- // (perform the [[Class]] check first to avoid errors with some host objects in IE)
- return isNumber(value) && value != +value;
- }
- /**
- * Checks if `value` is `null`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is `null`, else `false`.
- * @example
- *
- * _.isNull(null);
- * // => true
- *
- * _.isNull(undefined);
- * // => false
- */
- function isNull(value) {
- return value === null;
- }
- /**
- * Checks if `value` is a number.
- *
- * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a number, else `false`.
- * @example
- *
- * _.isNumber(8.4 * 5);
- * // => true
- */
- function isNumber(value) {
- return typeof value == 'number' ||
- value && typeof value == 'object' && toString.call(value) == numberClass || false;
- }
- /**
- * Checks if `value` is an object created by the `Object` constructor.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
- * @example
- *
- * function Shape() {
- * this.x = 0;
- * this.y = 0;
- * }
- *
- * _.isPlainObject(new Shape);
- * // => false
- *
- * _.isPlainObject([1, 2, 3]);
- * // => false
- *
- * _.isPlainObject({ 'x': 0, 'y': 0 });
- * // => true
- */
- var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) {
- if (!(value && toString.call(value) == objectClass)) {
- return false;
- }
- var valueOf = value.valueOf,
- objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
- return objProto
- ? (value == objProto || getPrototypeOf(value) == objProto)
- : shimIsPlainObject(value);
- };
- /**
- * Checks if `value` is a regular expression.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`.
- * @example
- *
- * _.isRegExp(/fred/);
- * // => true
- */
- function isRegExp(value) {
- return value && typeof value == 'object' && toString.call(value) == regexpClass || false;
- }
- /**
- * Checks if `value` is a string.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a string, else `false`.
- * @example
- *
- * _.isString('fred');
- * // => true
- */
- function isString(value) {
- return typeof value == 'string' ||
- value && typeof value == 'object' && toString.call(value) == stringClass || false;
- }
- /**
- * Checks if `value` is `undefined`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`.
- * @example
- *
- * _.isUndefined(void 0);
- * // => true
- */
- function isUndefined(value) {
- return typeof value == 'undefined';
- }
- /**
- * Creates an object with the same keys as `object` and values generated by
- * running each own enumerable property of `object` through the callback.
- * The callback is bound to `thisArg` and invoked with three arguments;
- * (value, key, object).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new object with values of the results of each `callback` execution.
- * @example
- *
- * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; });
- * // => { 'a': 3, 'b': 6, 'c': 9 }
- *
- * var characters = {
- * 'fred': { 'name': 'fred', 'age': 40 },
- * 'pebbles': { 'name': 'pebbles', 'age': 1 }
- * };
- *
- * // using "_.pluck" callback shorthand
- * _.mapValues(characters, 'age');
- * // => { 'fred': 40, 'pebbles': 1 }
- */
- function mapValues(object, callback, thisArg) {
- var result = {};
- callback = lodash.createCallback(callback, thisArg, 3);
- forOwn(object, function(value, key, object) {
- result[key] = callback(value, key, object);
- });
- return result;
- }
- /**
- * Recursively merges own enumerable properties of the source object(s), that
- * don't resolve to `undefined` into the destination object. Subsequent sources
- * will overwrite property assignments of previous sources. If a callback is
- * provided it will be executed to produce the merged values of the destination
- * and source properties. If the callback returns `undefined` merging will
- * be handled by the method instead. The callback is bound to `thisArg` and
- * invoked with two arguments; (objectValue, sourceValue).
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The destination object.
- * @param {...Object} [source] The source objects.
- * @param {Function} [callback] The function to customize merging properties.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns the destination object.
- * @example
- *
- * var names = {
- * 'characters': [
- * { 'name': 'barney' },
- * { 'name': 'fred' }
- * ]
- * };
- *
- * var ages = {
- * 'characters': [
- * { 'age': 36 },
- * { 'age': 40 }
- * ]
- * };
- *
- * _.merge(names, ages);
- * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] }
- *
- * var food = {
- * 'fruits': ['apple'],
- * 'vegetables': ['beet']
- * };
- *
- * var otherFood = {
- * 'fruits': ['banana'],
- * 'vegetables': ['carrot']
- * };
- *
- * _.merge(food, otherFood, function(a, b) {
- * return _.isArray(a) ? a.concat(b) : undefined;
- * });
- * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] }
- */
- function merge(object) {
- var args = arguments,
- length = 2;
- if (!isObject(object)) {
- return object;
- }
- // allows working with `_.reduce` and `_.reduceRight` without using
- // their `index` and `collection` arguments
- if (typeof args[2] != 'number') {
- length = args.length;
- }
- if (length > 3 && typeof args[length - 2] == 'function') {
- var callback = baseCreateCallback(args[--length - 1], args[length--], 2);
- } else if (length > 2 && typeof args[length - 1] == 'function') {
- callback = args[--length];
- }
- var sources = slice(arguments, 1, length),
- index = -1,
- stackA = getArray(),
- stackB = getArray();
- while (++index < length) {
- baseMerge(object, sources[index], callback, stackA, stackB);
- }
- releaseArray(stackA);
- releaseArray(stackB);
- return object;
- }
- /**
- * Creates a shallow clone of `object` excluding the specified properties.
- * Property names may be specified as individual arguments or as arrays of
- * property names. If a callback is provided it will be executed for each
- * property of `object` omitting the properties the callback returns truey
- * for. The callback is bound to `thisArg` and invoked with three arguments;
- * (value, key, object).
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The source object.
- * @param {Function|...string|string[]} [callback] The properties to omit or the
- * function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns an object without the omitted properties.
- * @example
- *
- * _.omit({ 'name': 'fred', 'age': 40 }, 'age');
- * // => { 'name': 'fred' }
- *
- * _.omit({ 'name': 'fred', 'age': 40 }, function(value) {
- * return typeof value == 'number';
- * });
- * // => { 'name': 'fred' }
- */
- function omit(object, callback, thisArg) {
- var result = {};
- if (typeof callback != 'function') {
- var props = [];
- forIn(object, function(value, key) {
- props.push(key);
- });
- props = baseDifference(props, baseFlatten(arguments, true, false, 1));
- var index = -1,
- length = props.length;
- while (++index < length) {
- var key = props[index];
- result[key] = object[key];
- }
- } else {
- callback = lodash.createCallback(callback, thisArg, 3);
- forIn(object, function(value, key, object) {
- if (!callback(value, key, object)) {
- result[key] = value;
- }
- });
- }
- return result;
- }
- /**
- * Creates a two dimensional array of an object's key-value pairs,
- * i.e. `[[key1, value1], [key2, value2]]`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to inspect.
- * @returns {Array} Returns new array of key-value pairs.
- * @example
- *
- * _.pairs({ 'barney': 36, 'fred': 40 });
- * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments)
- */
- function pairs(object) {
- var index = -1,
- props = keys(object),
- length = props.length,
- result = Array(length);
- while (++index < length) {
- var key = props[index];
- result[index] = [key, object[key]];
- }
- return result;
- }
- /**
- * Creates a shallow clone of `object` composed of the specified properties.
- * Property names may be specified as individual arguments or as arrays of
- * property names. If a callback is provided it will be executed for each
- * property of `object` picking the properties the callback returns truey
- * for. The callback is bound to `thisArg` and invoked with three arguments;
- * (value, key, object).
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The source object.
- * @param {Function|...string|string[]} [callback] The function called per
- * iteration or property names to pick, specified as individual property
- * names or arrays of property names.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns an object composed of the picked properties.
- * @example
- *
- * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name');
- * // => { 'name': 'fred' }
- *
- * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) {
- * return key.charAt(0) != '_';
- * });
- * // => { 'name': 'fred' }
- */
- function pick(object, callback, thisArg) {
- var result = {};
- if (typeof callback != 'function') {
- var index = -1,
- props = baseFlatten(arguments, true, false, 1),
- length = isObject(object) ? props.length : 0;
- while (++index < length) {
- var key = props[index];
- if (key in object) {
- result[key] = object[key];
- }
- }
- } else {
- callback = lodash.createCallback(callback, thisArg, 3);
- forIn(object, function(value, key, object) {
- if (callback(value, key, object)) {
- result[key] = value;
- }
- });
- }
- return result;
- }
- /**
- * An alternative to `_.reduce` this method transforms `object` to a new
- * `accumulator` object which is the result of running each of its own
- * enumerable properties through a callback, with each callback execution
- * potentially mutating the `accumulator` object. The callback is bound to
- * `thisArg` and invoked with four arguments; (accumulator, value, key, object).
- * Callbacks may exit iteration early by explicitly returning `false`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Array|Object} object The object to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [accumulator] The custom accumulator value.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the accumulated value.
- * @example
- *
- * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) {
- * num *= num;
- * if (num % 2) {
- * return result.push(num) < 3;
- * }
- * });
- * // => [1, 9, 25]
- *
- * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
- * result[key] = num * 3;
- * });
- * // => { 'a': 3, 'b': 6, 'c': 9 }
- */
- function transform(object, callback, accumulator, thisArg) {
- var isArr = isArray(object);
- if (accumulator == null) {
- if (isArr) {
- accumulator = [];
- } else {
- var ctor = object && object.constructor,
- proto = ctor && ctor.prototype;
- accumulator = baseCreate(proto);
- }
- }
- if (callback) {
- callback = lodash.createCallback(callback, thisArg, 4);
- (isArr ? forEach : forOwn)(object, function(value, index, object) {
- return callback(accumulator, value, index, object);
- });
- }
- return accumulator;
- }
- /**
- * Creates an array composed of the own enumerable property values of `object`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to inspect.
- * @returns {Array} Returns an array of property values.
- * @example
- *
- * _.values({ 'one': 1, 'two': 2, 'three': 3 });
- * // => [1, 2, 3] (property order is not guaranteed across environments)
- */
- function values(object) {
- var index = -1,
- props = keys(object),
- length = props.length,
- result = Array(length);
- while (++index < length) {
- result[index] = object[props[index]];
- }
- return result;
- }
- /*--------------------------------------------------------------------------*/
- /**
- * Creates an array of elements from the specified indexes, or keys, of the
- * `collection`. Indexes may be specified as individual arguments or as arrays
- * of indexes.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {...(number|number[]|string|string[])} [index] The indexes of `collection`
- * to retrieve, specified as individual indexes or arrays of indexes.
- * @returns {Array} Returns a new array of elements corresponding to the
- * provided indexes.
- * @example
- *
- * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]);
- * // => ['a', 'c', 'e']
- *
- * _.at(['fred', 'barney', 'pebbles'], 0, 2);
- * // => ['fred', 'pebbles']
- */
- function at(collection) {
- var args = arguments,
- index = -1,
- props = baseFlatten(args, true, false, 1),
- length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length,
- result = Array(length);
- while(++index < length) {
- result[index] = collection[props[index]];
- }
- return result;
- }
- /**
- * Checks if a given value is present in a collection using strict equality
- * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the
- * offset from the end of the collection.
- *
- * @static
- * @memberOf _
- * @alias include
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {*} target The value to check for.
- * @param {number} [fromIndex=0] The index to search from.
- * @returns {boolean} Returns `true` if the `target` element is found, else `false`.
- * @example
- *
- * _.contains([1, 2, 3], 1);
- * // => true
- *
- * _.contains([1, 2, 3], 1, 2);
- * // => false
- *
- * _.contains({ 'name': 'fred', 'age': 40 }, 'fred');
- * // => true
- *
- * _.contains('pebbles', 'eb');
- * // => true
- */
- function contains(collection, target, fromIndex) {
- var index = -1,
- indexOf = getIndexOf(),
- length = collection ? collection.length : 0,
- result = false;
- fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0;
- if (isArray(collection)) {
- result = indexOf(collection, target, fromIndex) > -1;
- } else if (typeof length == 'number') {
- result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1;
- } else {
- forOwn(collection, function(value) {
- if (++index >= fromIndex) {
- return !(result = value === target);
- }
- });
- }
- return result;
- }
- /**
- * Creates an object composed of keys generated from the results of running
- * each element of `collection` through the callback. The corresponding value
- * of each key is the number of times the key was returned by the callback.
- * The callback is bound to `thisArg` and invoked with three arguments;
- * (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns the composed aggregate object.
- * @example
- *
- * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); });
- * // => { '4': 1, '6': 2 }
- *
- * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
- * // => { '4': 1, '6': 2 }
- *
- * _.countBy(['one', 'two', 'three'], 'length');
- * // => { '3': 2, '5': 1 }
- */
- var countBy = createAggregator(function(result, value, key) {
- (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
- });
- /**
- * Checks if the given callback returns truey value for **all** elements of
- * a collection. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias all
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {boolean} Returns `true` if all elements passed the callback check,
- * else `false`.
- * @example
- *
- * _.every([true, 1, null, 'yes']);
- * // => false
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.every(characters, 'age');
- * // => true
- *
- * // using "_.where" callback shorthand
- * _.every(characters, { 'age': 36 });
- * // => false
- */
- function every(collection, callback, thisArg) {
- var result = true;
- callback = lodash.createCallback(callback, thisArg, 3);
- var index = -1,
- length = collection ? collection.length : 0;
- if (typeof length == 'number') {
- while (++index < length) {
- if (!(result = !!callback(collection[index], index, collection))) {
- break;
- }
- }
- } else {
- forOwn(collection, function(value, index, collection) {
- return (result = !!callback(value, index, collection));
- });
- }
- return result;
- }
- /**
- * Iterates over elements of a collection, returning an array of all elements
- * the callback returns truey for. The callback is bound to `thisArg` and
- * invoked with three arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias select
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new array of elements that passed the callback check.
- * @example
- *
- * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
- * // => [2, 4, 6]
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': false },
- * { 'name': 'fred', 'age': 40, 'blocked': true }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.filter(characters, 'blocked');
- * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
- *
- * // using "_.where" callback shorthand
- * _.filter(characters, { 'age': 36 });
- * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
- */
- function filter(collection, callback, thisArg) {
- var result = [];
- callback = lodash.createCallback(callback, thisArg, 3);
- var index = -1,
- length = collection ? collection.length : 0;
- if (typeof length == 'number') {
- while (++index < length) {
- var value = collection[index];
- if (callback(value, index, collection)) {
- result.push(value);
- }
- }
- } else {
- forOwn(collection, function(value, index, collection) {
- if (callback(value, index, collection)) {
- result.push(value);
- }
- });
- }
- return result;
- }
- /**
- * Iterates over elements of a collection, returning the first element that
- * the callback returns truey for. The callback is bound to `thisArg` and
- * invoked with three arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias detect, findWhere
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the found element, else `undefined`.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': false },
- * { 'name': 'fred', 'age': 40, 'blocked': true },
- * { 'name': 'pebbles', 'age': 1, 'blocked': false }
- * ];
- *
- * _.find(characters, function(chr) {
- * return chr.age < 40;
- * });
- * // => { 'name': 'barney', 'age': 36, 'blocked': false }
- *
- * // using "_.where" callback shorthand
- * _.find(characters, { 'age': 1 });
- * // => { 'name': 'pebbles', 'age': 1, 'blocked': false }
- *
- * // using "_.pluck" callback shorthand
- * _.find(characters, 'blocked');
- * // => { 'name': 'fred', 'age': 40, 'blocked': true }
- */
- function find(collection, callback, thisArg) {
- callback = lodash.createCallback(callback, thisArg, 3);
- var index = -1,
- length = collection ? collection.length : 0;
- if (typeof length == 'number') {
- while (++index < length) {
- var value = collection[index];
- if (callback(value, index, collection)) {
- return value;
- }
- }
- } else {
- var result;
- forOwn(collection, function(value, index, collection) {
- if (callback(value, index, collection)) {
- result = value;
- return false;
- }
- });
- return result;
- }
- }
- /**
- * This method is like `_.find` except that it iterates over elements
- * of a `collection` from right to left.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the found element, else `undefined`.
- * @example
- *
- * _.findLast([1, 2, 3, 4], function(num) {
- * return num % 2 == 1;
- * });
- * // => 3
- */
- function findLast(collection, callback, thisArg) {
- var result;
- callback = lodash.createCallback(callback, thisArg, 3);
- forEachRight(collection, function(value, index, collection) {
- if (callback(value, index, collection)) {
- result = value;
- return false;
- }
- });
- return result;
- }
- /**
- * Iterates over elements of a collection, executing the callback for each
- * element. The callback is bound to `thisArg` and invoked with three arguments;
- * (value, index|key, collection). Callbacks may exit iteration early by
- * explicitly returning `false`.
- *
- * Note: As with other "Collections" methods, objects with a `length` property
- * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
- * may be used for object iteration.
- *
- * @static
- * @memberOf _
- * @alias each
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array|Object|string} Returns `collection`.
- * @example
- *
- * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(',');
- * // => logs each number and returns '1,2,3'
- *
- * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); });
- * // => logs each number and returns the object (property order is not guaranteed across environments)
- */
- function forEach(collection, callback, thisArg) {
- var index = -1,
- length = collection ? collection.length : 0;
- callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
- if (typeof length == 'number') {
- while (++index < length) {
- if (callback(collection[index], index, collection) === false) {
- break;
- }
- }
- } else {
- forOwn(collection, callback);
- }
- return collection;
- }
- /**
- * This method is like `_.forEach` except that it iterates over elements
- * of a `collection` from right to left.
- *
- * @static
- * @memberOf _
- * @alias eachRight
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array|Object|string} Returns `collection`.
- * @example
- *
- * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(',');
- * // => logs each number from right to left and returns '3,2,1'
- */
- function forEachRight(collection, callback, thisArg) {
- var length = collection ? collection.length : 0;
- callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
- if (typeof length == 'number') {
- while (length--) {
- if (callback(collection[length], length, collection) === false) {
- break;
- }
- }
- } else {
- var props = keys(collection);
- length = props.length;
- forOwn(collection, function(value, key, collection) {
- key = props ? props[--length] : --length;
- return callback(collection[key], key, collection);
- });
- }
- return collection;
- }
- /**
- * Creates an object composed of keys generated from the results of running
- * each element of a collection through the callback. The corresponding value
- * of each key is an array of the elements responsible for generating the key.
- * The callback is bound to `thisArg` and invoked with three arguments;
- * (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns the composed aggregate object.
- * @example
- *
- * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); });
- * // => { '4': [4.2], '6': [6.1, 6.4] }
- *
- * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
- * // => { '4': [4.2], '6': [6.1, 6.4] }
- *
- * // using "_.pluck" callback shorthand
- * _.groupBy(['one', 'two', 'three'], 'length');
- * // => { '3': ['one', 'two'], '5': ['three'] }
- */
- var groupBy = createAggregator(function(result, value, key) {
- (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value);
- });
- /**
- * Creates an object composed of keys generated from the results of running
- * each element of the collection through the given callback. The corresponding
- * value of each key is the last element responsible for generating the key.
- * The callback is bound to `thisArg` and invoked with three arguments;
- * (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns the composed aggregate object.
- * @example
- *
- * var keys = [
- * { 'dir': 'left', 'code': 97 },
- * { 'dir': 'right', 'code': 100 }
- * ];
- *
- * _.indexBy(keys, 'dir');
- * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
- *
- * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); });
- * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
- *
- * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String);
- * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
- */
- var indexBy = createAggregator(function(result, value, key) {
- result[key] = value;
- });
- /**
- * Invokes the method named by `methodName` on each element in the `collection`
- * returning an array of the results of each invoked method. Additional arguments
- * will be provided to each invoked method. If `methodName` is a function it
- * will be invoked for, and `this` bound to, each element in the `collection`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|string} methodName The name of the method to invoke or
- * the function invoked per iteration.
- * @param {...*} [arg] Arguments to invoke the method with.
- * @returns {Array} Returns a new array of the results of each invoked method.
- * @example
- *
- * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
- * // => [[1, 5, 7], [1, 2, 3]]
- *
- * _.invoke([123, 456], String.prototype.split, '');
- * // => [['1', '2', '3'], ['4', '5', '6']]
- */
- function invoke(collection, methodName) {
- var args = slice(arguments, 2),
- index = -1,
- isFunc = typeof methodName == 'function',
- length = collection ? collection.length : 0,
- result = Array(typeof length == 'number' ? length : 0);
- forEach(collection, function(value) {
- result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args);
- });
- return result;
- }
- /**
- * Creates an array of values by running each element in the collection
- * through the callback. The callback is bound to `thisArg` and invoked with
- * three arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias collect
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new array of the results of each `callback` execution.
- * @example
- *
- * _.map([1, 2, 3], function(num) { return num * 3; });
- * // => [3, 6, 9]
- *
- * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
- * // => [3, 6, 9] (property order is not guaranteed across environments)
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.map(characters, 'name');
- * // => ['barney', 'fred']
- */
- function map(collection, callback, thisArg) {
- var index = -1,
- length = collection ? collection.length : 0;
- callback = lodash.createCallback(callback, thisArg, 3);
- if (typeof length == 'number') {
- var result = Array(length);
- while (++index < length) {
- result[index] = callback(collection[index], index, collection);
- }
- } else {
- result = [];
- forOwn(collection, function(value, key, collection) {
- result[++index] = callback(value, key, collection);
- });
- }
- return result;
- }
- /**
- * Retrieves the maximum value of a collection. If the collection is empty or
- * falsey `-Infinity` is returned. If a callback is provided it will be executed
- * for each value in the collection to generate the criterion by which the value
- * is ranked. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, index, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the maximum value.
- * @example
- *
- * _.max([4, 2, 8, 6]);
- * // => 8
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * _.max(characters, function(chr) { return chr.age; });
- * // => { 'name': 'fred', 'age': 40 };
- *
- * // using "_.pluck" callback shorthand
- * _.max(characters, 'age');
- * // => { 'name': 'fred', 'age': 40 };
- */
- function max(collection, callback, thisArg) {
- var computed = -Infinity,
- result = computed;
- // allows working with functions like `_.map` without using
- // their `index` argument as a callback
- if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
- callback = null;
- }
- if (callback == null && isArray(collection)) {
- var index = -1,
- length = collection.length;
- while (++index < length) {
- var value = collection[index];
- if (value > result) {
- result = value;
- }
- }
- } else {
- callback = (callback == null && isString(collection))
- ? charAtCallback
- : lodash.createCallback(callback, thisArg, 3);
- forEach(collection, function(value, index, collection) {
- var current = callback(value, index, collection);
- if (current > computed) {
- computed = current;
- result = value;
- }
- });
- }
- return result;
- }
- /**
- * Retrieves the minimum value of a collection. If the collection is empty or
- * falsey `Infinity` is returned. If a callback is provided it will be executed
- * for each value in the collection to generate the criterion by which the value
- * is ranked. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, index, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the minimum value.
- * @example
- *
- * _.min([4, 2, 8, 6]);
- * // => 2
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * _.min(characters, function(chr) { return chr.age; });
- * // => { 'name': 'barney', 'age': 36 };
- *
- * // using "_.pluck" callback shorthand
- * _.min(characters, 'age');
- * // => { 'name': 'barney', 'age': 36 };
- */
- function min(collection, callback, thisArg) {
- var computed = Infinity,
- result = computed;
- // allows working with functions like `_.map` without using
- // their `index` argument as a callback
- if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
- callback = null;
- }
- if (callback == null && isArray(collection)) {
- var index = -1,
- length = collection.length;
- while (++index < length) {
- var value = collection[index];
- if (value < result) {
- result = value;
- }
- }
- } else {
- callback = (callback == null && isString(collection))
- ? charAtCallback
- : lodash.createCallback(callback, thisArg, 3);
- forEach(collection, function(value, index, collection) {
- var current = callback(value, index, collection);
- if (current < computed) {
- computed = current;
- result = value;
- }
- });
- }
- return result;
- }
- /**
- * Retrieves the value of a specified property from all elements in the collection.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {string} property The name of the property to pluck.
- * @returns {Array} Returns a new array of property values.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * _.pluck(characters, 'name');
- * // => ['barney', 'fred']
- */
- var pluck = map;
- /**
- * Reduces a collection to a value which is the accumulated result of running
- * each element in the collection through the callback, where each successive
- * callback execution consumes the return value of the previous execution. If
- * `accumulator` is not provided the first element of the collection will be
- * used as the initial `accumulator` value. The callback is bound to `thisArg`
- * and invoked with four arguments; (accumulator, value, index|key, collection).
- *
- * @static
- * @memberOf _
- * @alias foldl, inject
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [accumulator] Initial value of the accumulator.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the accumulated value.
- * @example
- *
- * var sum = _.reduce([1, 2, 3], function(sum, num) {
- * return sum + num;
- * });
- * // => 6
- *
- * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
- * result[key] = num * 3;
- * return result;
- * }, {});
- * // => { 'a': 3, 'b': 6, 'c': 9 }
- */
- function reduce(collection, callback, accumulator, thisArg) {
- if (!collection) return accumulator;
- var noaccum = arguments.length < 3;
- callback = lodash.createCallback(callback, thisArg, 4);
- var index = -1,
- length = collection.length;
- if (typeof length == 'number') {
- if (noaccum) {
- accumulator = collection[++index];
- }
- while (++index < length) {
- accumulator = callback(accumulator, collection[index], index, collection);
- }
- } else {
- forOwn(collection, function(value, index, collection) {
- accumulator = noaccum
- ? (noaccum = false, value)
- : callback(accumulator, value, index, collection)
- });
- }
- return accumulator;
- }
- /**
- * This method is like `_.reduce` except that it iterates over elements
- * of a `collection` from right to left.
- *
- * @static
- * @memberOf _
- * @alias foldr
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [accumulator] Initial value of the accumulator.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the accumulated value.
- * @example
- *
- * var list = [[0, 1], [2, 3], [4, 5]];
- * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
- * // => [4, 5, 2, 3, 0, 1]
- */
- function reduceRight(collection, callback, accumulator, thisArg) {
- var noaccum = arguments.length < 3;
- callback = lodash.createCallback(callback, thisArg, 4);
- forEachRight(collection, function(value, index, collection) {
- accumulator = noaccum
- ? (noaccum = false, value)
- : callback(accumulator, value, index, collection);
- });
- return accumulator;
- }
- /**
- * The opposite of `_.filter` this method returns the elements of a
- * collection that the callback does **not** return truey for.
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new array of elements that failed the callback check.
- * @example
- *
- * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
- * // => [1, 3, 5]
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': false },
- * { 'name': 'fred', 'age': 40, 'blocked': true }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.reject(characters, 'blocked');
- * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
- *
- * // using "_.where" callback shorthand
- * _.reject(characters, { 'age': 36 });
- * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
- */
- function reject(collection, callback, thisArg) {
- callback = lodash.createCallback(callback, thisArg, 3);
- return filter(collection, function(value, index, collection) {
- return !callback(value, index, collection);
- });
- }
- /**
- * Retrieves a random element or `n` random elements from a collection.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to sample.
- * @param {number} [n] The number of elements to sample.
- * @param- {Object} [guard] Allows working with functions like `_.map`
- * without using their `index` arguments as `n`.
- * @returns {Array} Returns the random sample(s) of `collection`.
- * @example
- *
- * _.sample([1, 2, 3, 4]);
- * // => 2
- *
- * _.sample([1, 2, 3, 4], 2);
- * // => [3, 1]
- */
- function sample(collection, n, guard) {
- if (collection && typeof collection.length != 'number') {
- collection = values(collection);
- }
- if (n == null || guard) {
- return collection ? collection[baseRandom(0, collection.length - 1)] : undefined;
- }
- var result = shuffle(collection);
- result.length = nativeMin(nativeMax(0, n), result.length);
- return result;
- }
- /**
- * Creates an array of shuffled values, using a version of the Fisher-Yates
- * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to shuffle.
- * @returns {Array} Returns a new shuffled collection.
- * @example
- *
- * _.shuffle([1, 2, 3, 4, 5, 6]);
- * // => [4, 1, 6, 3, 5, 2]
- */
- function shuffle(collection) {
- var index = -1,
- length = collection ? collection.length : 0,
- result = Array(typeof length == 'number' ? length : 0);
- forEach(collection, function(value) {
- var rand = baseRandom(0, ++index);
- result[index] = result[rand];
- result[rand] = value;
- });
- return result;
- }
- /**
- * Gets the size of the `collection` by returning `collection.length` for arrays
- * and array-like objects or the number of own enumerable properties for objects.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to inspect.
- * @returns {number} Returns `collection.length` or number of own enumerable properties.
- * @example
- *
- * _.size([1, 2]);
- * // => 2
- *
- * _.size({ 'one': 1, 'two': 2, 'three': 3 });
- * // => 3
- *
- * _.size('pebbles');
- * // => 7
- */
- function size(collection) {
- var length = collection ? collection.length : 0;
- return typeof length == 'number' ? length : keys(collection).length;
- }
- /**
- * Checks if the callback returns a truey value for **any** element of a
- * collection. The function returns as soon as it finds a passing value and
- * does not iterate over the entire collection. The callback is bound to
- * `thisArg` and invoked with three arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias any
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {boolean} Returns `true` if any element passed the callback check,
- * else `false`.
- * @example
- *
- * _.some([null, 0, 'yes', false], Boolean);
- * // => true
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': false },
- * { 'name': 'fred', 'age': 40, 'blocked': true }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.some(characters, 'blocked');
- * // => true
- *
- * // using "_.where" callback shorthand
- * _.some(characters, { 'age': 1 });
- * // => false
- */
- function some(collection, callback, thisArg) {
- var result;
- callback = lodash.createCallback(callback, thisArg, 3);
- var index = -1,
- length = collection ? collection.length : 0;
- if (typeof length == 'number') {
- while (++index < length) {
- if ((result = callback(collection[index], index, collection))) {
- break;
- }
- }
- } else {
- forOwn(collection, function(value, index, collection) {
- return !(result = callback(value, index, collection));
- });
- }
- return !!result;
- }
- /**
- * Creates an array of elements, sorted in ascending order by the results of
- * running each element in a collection through the callback. This method
- * performs a stable sort, that is, it will preserve the original sort order
- * of equal elements. The callback is bound to `thisArg` and invoked with
- * three arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an array of property names is provided for `callback` the collection
- * will be sorted by each property value.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Array|Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new array of sorted elements.
- * @example
- *
- * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); });
- * // => [3, 1, 2]
- *
- * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math);
- * // => [3, 1, 2]
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 },
- * { 'name': 'barney', 'age': 26 },
- * { 'name': 'fred', 'age': 30 }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.map(_.sortBy(characters, 'age'), _.values);
- * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]]
- *
- * // sorting by multiple properties
- * _.map(_.sortBy(characters, ['name', 'age']), _.values);
- * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]]
- */
- function sortBy(collection, callback, thisArg) {
- var index = -1,
- isArr = isArray(callback),
- length = collection ? collection.length : 0,
- result = Array(typeof length == 'number' ? length : 0);
- if (!isArr) {
- callback = lodash.createCallback(callback, thisArg, 3);
- }
- forEach(collection, function(value, key, collection) {
- var object = result[++index] = getObject();
- if (isArr) {
- object.criteria = map(callback, function(key) { return value[key]; });
- } else {
- (object.criteria = getArray())[0] = callback(value, key, collection);
- }
- object.index = index;
- object.value = value;
- });
- length = result.length;
- result.sort(compareAscending);
- while (length--) {
- var object = result[length];
- result[length] = object.value;
- if (!isArr) {
- releaseArray(object.criteria);
- }
- releaseObject(object);
- }
- return result;
- }
- /**
- * Converts the `collection` to an array.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to convert.
- * @returns {Array} Returns the new converted array.
- * @example
- *
- * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
- * // => [2, 3, 4]
- */
- function toArray(collection) {
- if (collection && typeof collection.length == 'number') {
- return slice(collection);
- }
- return values(collection);
- }
- /**
- * Performs a deep comparison of each element in a `collection` to the given
- * `properties` object, returning an array of all elements that have equivalent
- * property values.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Object} props The object of property values to filter by.
- * @returns {Array} Returns a new array of elements that have the given properties.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] },
- * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }
- * ];
- *
- * _.where(characters, { 'age': 36 });
- * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }]
- *
- * _.where(characters, { 'pets': ['dino'] });
- * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }]
- */
- var where = filter;
- /*--------------------------------------------------------------------------*/
- /**
- * Creates an array with all falsey values removed. The values `false`, `null`,
- * `0`, `""`, `undefined`, and `NaN` are all falsey.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to compact.
- * @returns {Array} Returns a new array of filtered values.
- * @example
- *
- * _.compact([0, 1, false, 2, '', 3]);
- * // => [1, 2, 3]
- */
- function compact(array) {
- var index = -1,
- length = array ? array.length : 0,
- result = [];
- while (++index < length) {
- var value = array[index];
- if (value) {
- result.push(value);
- }
- }
- return result;
- }
- /**
- * Creates an array excluding all values of the provided arrays using strict
- * equality for comparisons, i.e. `===`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to process.
- * @param {...Array} [values] The arrays of values to exclude.
- * @returns {Array} Returns a new array of filtered values.
- * @example
- *
- * _.difference([1, 2, 3, 4, 5], [5, 2, 10]);
- * // => [1, 3, 4]
- */
- function difference(array) {
- return baseDifference(array, baseFlatten(arguments, true, true, 1));
- }
- /**
- * This method is like `_.find` except that it returns the index of the first
- * element that passes the callback check, instead of the element itself.
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to search.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {number} Returns the index of the found element, else `-1`.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': false },
- * { 'name': 'fred', 'age': 40, 'blocked': true },
- * { 'name': 'pebbles', 'age': 1, 'blocked': false }
- * ];
- *
- * _.findIndex(characters, function(chr) {
- * return chr.age < 20;
- * });
- * // => 2
- *
- * // using "_.where" callback shorthand
- * _.findIndex(characters, { 'age': 36 });
- * // => 0
- *
- * // using "_.pluck" callback shorthand
- * _.findIndex(characters, 'blocked');
- * // => 1
- */
- function findIndex(array, callback, thisArg) {
- var index = -1,
- length = array ? array.length : 0;
- callback = lodash.createCallback(callback, thisArg, 3);
- while (++index < length) {
- if (callback(array[index], index, array)) {
- return index;
- }
- }
- return -1;
- }
- /**
- * This method is like `_.findIndex` except that it iterates over elements
- * of a `collection` from right to left.
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to search.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {number} Returns the index of the found element, else `-1`.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': true },
- * { 'name': 'fred', 'age': 40, 'blocked': false },
- * { 'name': 'pebbles', 'age': 1, 'blocked': true }
- * ];
- *
- * _.findLastIndex(characters, function(chr) {
- * return chr.age > 30;
- * });
- * // => 1
- *
- * // using "_.where" callback shorthand
- * _.findLastIndex(characters, { 'age': 36 });
- * // => 0
- *
- * // using "_.pluck" callback shorthand
- * _.findLastIndex(characters, 'blocked');
- * // => 2
- */
- function findLastIndex(array, callback, thisArg) {
- var length = array ? array.length : 0;
- callback = lodash.createCallback(callback, thisArg, 3);
- while (length--) {
- if (callback(array[length], length, array)) {
- return length;
- }
- }
- return -1;
- }
- /**
- * Gets the first element or first `n` elements of an array. If a callback
- * is provided elements at the beginning of the array are returned as long
- * as the callback returns truey. The callback is bound to `thisArg` and
- * invoked with three arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias head, take
- * @category Arrays
- * @param {Array} array The array to query.
- * @param {Function|Object|number|string} [callback] The function called
- * per element or the number of elements to return. If a property name or
- * object is provided it will be used to create a "_.pluck" or "_.where"
- * style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the first element(s) of `array`.
- * @example
- *
- * _.first([1, 2, 3]);
- * // => 1
- *
- * _.first([1, 2, 3], 2);
- * // => [1, 2]
- *
- * _.first([1, 2, 3], function(num) {
- * return num < 3;
- * });
- * // => [1, 2]
- *
- * var characters = [
- * { 'name': 'barney', 'blocked': true, 'employer': 'slate' },
- * { 'name': 'fred', 'blocked': false, 'employer': 'slate' },
- * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.first(characters, 'blocked');
- * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }]
- *
- * // using "_.where" callback shorthand
- * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name');
- * // => ['barney', 'fred']
- */
- function first(array, callback, thisArg) {
- var n = 0,
- length = array ? array.length : 0;
- if (typeof callback != 'number' && callback != null) {
- var index = -1;
- callback = lodash.createCallback(callback, thisArg, 3);
- while (++index < length && callback(array[index], index, array)) {
- n++;
- }
- } else {
- n = callback;
- if (n == null || thisArg) {
- return array ? array[0] : undefined;
- }
- }
- return slice(array, 0, nativeMin(nativeMax(0, n), length));
- }
- /**
- * Flattens a nested array (the nesting can be to any depth). If `isShallow`
- * is truey, the array will only be flattened a single level. If a callback
- * is provided each element of the array is passed through the callback before
- * flattening. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to flatten.
- * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new flattened array.
- * @example
- *
- * _.flatten([1, [2], [3, [[4]]]]);
- * // => [1, 2, 3, 4];
- *
- * _.flatten([1, [2], [3, [[4]]]], true);
- * // => [1, 2, 3, [[4]]];
- *
- * var characters = [
- * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] },
- * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.flatten(characters, 'pets');
- * // => ['hoppy', 'baby puss', 'dino']
- */
- function flatten(array, isShallow, callback, thisArg) {
- // juggle arguments
- if (typeof isShallow != 'boolean' && isShallow != null) {
- thisArg = callback;
- callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow;
- isShallow = false;
- }
- if (callback != null) {
- array = map(array, callback, thisArg);
- }
- return baseFlatten(array, isShallow);
- }
- /**
- * Gets the index at which the first occurrence of `value` is found using
- * strict equality for comparisons, i.e. `===`. If the array is already sorted
- * providing `true` for `fromIndex` will run a faster binary search.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to search.
- * @param {*} value The value to search for.
- * @param {boolean|number} [fromIndex=0] The index to search from or `true`
- * to perform a binary search on a sorted array.
- * @returns {number} Returns the index of the matched value or `-1`.
- * @example
- *
- * _.indexOf([1, 2, 3, 1, 2, 3], 2);
- * // => 1
- *
- * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3);
- * // => 4
- *
- * _.indexOf([1, 1, 2, 2, 3, 3], 2, true);
- * // => 2
- */
- function indexOf(array, value, fromIndex) {
- if (typeof fromIndex == 'number') {
- var length = array ? array.length : 0;
- fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0);
- } else if (fromIndex) {
- var index = sortedIndex(array, value);
- return array[index] === value ? index : -1;
- }
- return baseIndexOf(array, value, fromIndex);
- }
- /**
- * Gets all but the last element or last `n` elements of an array. If a
- * callback is provided elements at the end of the array are excluded from
- * the result as long as the callback returns truey. The callback is bound
- * to `thisArg` and invoked with three arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to query.
- * @param {Function|Object|number|string} [callback=1] The function called
- * per element or the number of elements to exclude. If a property name or
- * object is provided it will be used to create a "_.pluck" or "_.where"
- * style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a slice of `array`.
- * @example
- *
- * _.initial([1, 2, 3]);
- * // => [1, 2]
- *
- * _.initial([1, 2, 3], 2);
- * // => [1]
- *
- * _.initial([1, 2, 3], function(num) {
- * return num > 1;
- * });
- * // => [1]
- *
- * var characters = [
- * { 'name': 'barney', 'blocked': false, 'employer': 'slate' },
- * { 'name': 'fred', 'blocked': true, 'employer': 'slate' },
- * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.initial(characters, 'blocked');
- * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }]
- *
- * // using "_.where" callback shorthand
- * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name');
- * // => ['barney', 'fred']
- */
- function initial(array, callback, thisArg) {
- var n = 0,
- length = array ? array.length : 0;
- if (typeof callback != 'number' && callback != null) {
- var index = length;
- callback = lodash.createCallback(callback, thisArg, 3);
- while (index-- && callback(array[index], index, array)) {
- n++;
- }
- } else {
- n = (callback == null || thisArg) ? 1 : callback || n;
- }
- return slice(array, 0, nativeMin(nativeMax(0, length - n), length));
- }
- /**
- * Creates an array of unique values present in all provided arrays using
- * strict equality for comparisons, i.e. `===`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {...Array} [array] The arrays to inspect.
- * @returns {Array} Returns an array of shared values.
- * @example
- *
- * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]);
- * // => [1, 2]
- */
- function intersection() {
- var args = [],
- argsIndex = -1,
- argsLength = arguments.length,
- caches = getArray(),
- indexOf = getIndexOf(),
- trustIndexOf = indexOf === baseIndexOf,
- seen = getArray();
- while (++argsIndex < argsLength) {
- var value = arguments[argsIndex];
- if (isArray(value) || isArguments(value)) {
- args.push(value);
- caches.push(trustIndexOf && value.length >= largeArraySize &&
- createCache(argsIndex ? args[argsIndex] : seen));
- }
- }
- var array = args[0],
- index = -1,
- length = array ? array.length : 0,
- result = [];
- outer:
- while (++index < length) {
- var cache = caches[0];
- value = array[index];
- if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) {
- argsIndex = argsLength;
- (cache || seen).push(value);
- while (--argsIndex) {
- cache = caches[argsIndex];
- if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) {
- continue outer;
- }
- }
- result.push(value);
- }
- }
- while (argsLength--) {
- cache = caches[argsLength];
- if (cache) {
- releaseObject(cache);
- }
- }
- releaseArray(caches);
- releaseArray(seen);
- return result;
- }
- /**
- * Gets the last element or last `n` elements of an array. If a callback is
- * provided elements at the end of the array are returned as long as the
- * callback returns truey. The callback is bound to `thisArg` and invoked
- * with three arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to query.
- * @param {Function|Object|number|string} [callback] The function called
- * per element or the number of elements to return. If a property name or
- * object is provided it will be used to create a "_.pluck" or "_.where"
- * style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the last element(s) of `array`.
- * @example
- *
- * _.last([1, 2, 3]);
- * // => 3
- *
- * _.last([1, 2, 3], 2);
- * // => [2, 3]
- *
- * _.last([1, 2, 3], function(num) {
- * return num > 1;
- * });
- * // => [2, 3]
- *
- * var characters = [
- * { 'name': 'barney', 'blocked': false, 'employer': 'slate' },
- * { 'name': 'fred', 'blocked': true, 'employer': 'slate' },
- * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.pluck(_.last(characters, 'blocked'), 'name');
- * // => ['fred', 'pebbles']
- *
- * // using "_.where" callback shorthand
- * _.last(characters, { 'employer': 'na' });
- * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
- */
- function last(array, callback, thisArg) {
- var n = 0,
- length = array ? array.length : 0;
- if (typeof callback != 'number' && callback != null) {
- var index = length;
- callback = lodash.createCallback(callback, thisArg, 3);
- while (index-- && callback(array[index], index, array)) {
- n++;
- }
- } else {
- n = callback;
- if (n == null || thisArg) {
- return array ? array[length - 1] : undefined;
- }
- }
- return slice(array, nativeMax(0, length - n));
- }
- /**
- * Gets the index at which the last occurrence of `value` is found using strict
- * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
- * as the offset from the end of the collection.
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to search.
- * @param {*} value The value to search for.
- * @param {number} [fromIndex=array.length-1] The index to search from.
- * @returns {number} Returns the index of the matched value or `-1`.
- * @example
- *
- * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
- * // => 4
- *
- * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3);
- * // => 1
- */
- function lastIndexOf(array, value, fromIndex) {
- var index = array ? array.length : 0;
- if (typeof fromIndex == 'number') {
- index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1;
- }
- while (index--) {
- if (array[index] === value) {
- return index;
- }
- }
- return -1;
- }
- /**
- * Removes all provided values from the given array using strict equality for
- * comparisons, i.e. `===`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to modify.
- * @param {...*} [value] The values to remove.
- * @returns {Array} Returns `array`.
- * @example
- *
- * var array = [1, 2, 3, 1, 2, 3];
- * _.pull(array, 2, 3);
- * console.log(array);
- * // => [1, 1]
- */
- function pull(array) {
- var args = arguments,
- argsIndex = 0,
- argsLength = args.length,
- length = array ? array.length : 0;
- while (++argsIndex < argsLength) {
- var index = -1,
- value = args[argsIndex];
- while (++index < length) {
- if (array[index] === value) {
- splice.call(array, index--, 1);
- length--;
- }
- }
- }
- return array;
- }
- /**
- * Creates an array of numbers (positive and/or negative) progressing from
- * `start` up to but not including `end`. If `start` is less than `stop` a
- * zero-length range is created unless a negative `step` is specified.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {number} [start=0] The start of the range.
- * @param {number} end The end of the range.
- * @param {number} [step=1] The value to increment or decrement by.
- * @returns {Array} Returns a new range array.
- * @example
- *
- * _.range(4);
- * // => [0, 1, 2, 3]
- *
- * _.range(1, 5);
- * // => [1, 2, 3, 4]
- *
- * _.range(0, 20, 5);
- * // => [0, 5, 10, 15]
- *
- * _.range(0, -4, -1);
- * // => [0, -1, -2, -3]
- *
- * _.range(1, 4, 0);
- * // => [1, 1, 1]
- *
- * _.range(0);
- * // => []
- */
- function range(start, end, step) {
- start = +start || 0;
- step = typeof step == 'number' ? step : (+step || 1);
- if (end == null) {
- end = start;
- start = 0;
- }
- // use `Array(length)` so engines like Chakra and V8 avoid slower modes
- // http://youtu.be/XAqIpGU8ZZk#t=17m25s
- var index = -1,
- length = nativeMax(0, ceil((end - start) / (step || 1))),
- result = Array(length);
- while (++index < length) {
- result[index] = start;
- start += step;
- }
- return result;
- }
- /**
- * Removes all elements from an array that the callback returns truey for
- * and returns an array of removed elements. The callback is bound to `thisArg`
- * and invoked with three arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to modify.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new array of removed elements.
- * @example
- *
- * var array = [1, 2, 3, 4, 5, 6];
- * var evens = _.remove(array, function(num) { return num % 2 == 0; });
- *
- * console.log(array);
- * // => [1, 3, 5]
- *
- * console.log(evens);
- * // => [2, 4, 6]
- */
- function remove(array, callback, thisArg) {
- var index = -1,
- length = array ? array.length : 0,
- result = [];
- callback = lodash.createCallback(callback, thisArg, 3);
- while (++index < length) {
- var value = array[index];
- if (callback(value, index, array)) {
- result.push(value);
- splice.call(array, index--, 1);
- length--;
- }
- }
- return result;
- }
- /**
- * The opposite of `_.initial` this method gets all but the first element or
- * first `n` elements of an array. If a callback function is provided elements
- * at the beginning of the array are excluded from the result as long as the
- * callback returns truey. The callback is bound to `thisArg` and invoked
- * with three arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias drop, tail
- * @category Arrays
- * @param {Array} array The array to query.
- * @param {Function|Object|number|string} [callback=1] The function called
- * per element or the number of elements to exclude. If a property name or
- * object is provided it will be used to create a "_.pluck" or "_.where"
- * style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a slice of `array`.
- * @example
- *
- * _.rest([1, 2, 3]);
- * // => [2, 3]
- *
- * _.rest([1, 2, 3], 2);
- * // => [3]
- *
- * _.rest([1, 2, 3], function(num) {
- * return num < 3;
- * });
- * // => [3]
- *
- * var characters = [
- * { 'name': 'barney', 'blocked': true, 'employer': 'slate' },
- * { 'name': 'fred', 'blocked': false, 'employer': 'slate' },
- * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.pluck(_.rest(characters, 'blocked'), 'name');
- * // => ['fred', 'pebbles']
- *
- * // using "_.where" callback shorthand
- * _.rest(characters, { 'employer': 'slate' });
- * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
- */
- function rest(array, callback, thisArg) {
- if (typeof callback != 'number' && callback != null) {
- var n = 0,
- index = -1,
- length = array ? array.length : 0;
- callback = lodash.createCallback(callback, thisArg, 3);
- while (++index < length && callback(array[index], index, array)) {
- n++;
- }
- } else {
- n = (callback == null || thisArg) ? 1 : nativeMax(0, callback);
- }
- return slice(array, n);
- }
- /**
- * Uses a binary search to determine the smallest index at which a value
- * should be inserted into a given sorted array in order to maintain the sort
- * order of the array. If a callback is provided it will be executed for
- * `value` and each element of `array` to compute their sort ranking. The
- * callback is bound to `thisArg` and invoked with one argument; (value).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to inspect.
- * @param {*} value The value to evaluate.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {number} Returns the index at which `value` should be inserted
- * into `array`.
- * @example
- *
- * _.sortedIndex([20, 30, 50], 40);
- * // => 2
- *
- * // using "_.pluck" callback shorthand
- * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
- * // => 2
- *
- * var dict = {
- * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 }
- * };
- *
- * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
- * return dict.wordToNumber[word];
- * });
- * // => 2
- *
- * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
- * return this.wordToNumber[word];
- * }, dict);
- * // => 2
- */
- function sortedIndex(array, value, callback, thisArg) {
- var low = 0,
- high = array ? array.length : low;
- // explicitly reference `identity` for better inlining in Firefox
- callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity;
- value = callback(value);
- while (low < high) {
- var mid = (low + high) >>> 1;
- (callback(array[mid]) < value)
- ? low = mid + 1
- : high = mid;
- }
- return low;
- }
- /**
- * Creates an array of unique values, in order, of the provided arrays using
- * strict equality for comparisons, i.e. `===`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {...Array} [array] The arrays to inspect.
- * @returns {Array} Returns an array of combined values.
- * @example
- *
- * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]);
- * // => [1, 2, 3, 5, 4]
- */
- function union() {
- return baseUniq(baseFlatten(arguments, true, true));
- }
- /**
- * Creates a duplicate-value-free version of an array using strict equality
- * for comparisons, i.e. `===`. If the array is sorted, providing
- * `true` for `isSorted` will use a faster algorithm. If a callback is provided
- * each element of `array` is passed through the callback before uniqueness
- * is computed. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias unique
- * @category Arrays
- * @param {Array} array The array to process.
- * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a duplicate-value-free array.
- * @example
- *
- * _.uniq([1, 2, 1, 3, 1]);
- * // => [1, 2, 3]
- *
- * _.uniq([1, 1, 2, 2, 3], true);
- * // => [1, 2, 3]
- *
- * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); });
- * // => ['A', 'b', 'C']
- *
- * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math);
- * // => [1, 2.5, 3]
- *
- * // using "_.pluck" callback shorthand
- * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
- * // => [{ 'x': 1 }, { 'x': 2 }]
- */
- function uniq(array, isSorted, callback, thisArg) {
- // juggle arguments
- if (typeof isSorted != 'boolean' && isSorted != null) {
- thisArg = callback;
- callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted;
- isSorted = false;
- }
- if (callback != null) {
- callback = lodash.createCallback(callback, thisArg, 3);
- }
- return baseUniq(array, isSorted, callback);
- }
- /**
- * Creates an array excluding all provided values using strict equality for
- * comparisons, i.e. `===`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to filter.
- * @param {...*} [value] The values to exclude.
- * @returns {Array} Returns a new array of filtered values.
- * @example
- *
- * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
- * // => [2, 3, 4]
- */
- function without(array) {
- return baseDifference(array, slice(arguments, 1));
- }
- /**
- * Creates an array that is the symmetric difference of the provided arrays.
- * See http://en.wikipedia.org/wiki/Symmetric_difference.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {...Array} [array] The arrays to inspect.
- * @returns {Array} Returns an array of values.
- * @example
- *
- * _.xor([1, 2, 3], [5, 2, 1, 4]);
- * // => [3, 5, 4]
- *
- * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]);
- * // => [1, 4, 5]
- */
- function xor() {
- var index = -1,
- length = arguments.length;
- while (++index < length) {
- var array = arguments[index];
- if (isArray(array) || isArguments(array)) {
- var result = result
- ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result)))
- : array;
- }
- }
- return result || [];
- }
- /**
- * Creates an array of grouped elements, the first of which contains the first
- * elements of the given arrays, the second of which contains the second
- * elements of the given arrays, and so on.
- *
- * @static
- * @memberOf _
- * @alias unzip
- * @category Arrays
- * @param {...Array} [array] Arrays to process.
- * @returns {Array} Returns a new array of grouped elements.
- * @example
- *
- * _.zip(['fred', 'barney'], [30, 40], [true, false]);
- * // => [['fred', 30, true], ['barney', 40, false]]
- */
- function zip() {
- var array = arguments.length > 1 ? arguments : arguments[0],
- index = -1,
- length = array ? max(pluck(array, 'length')) : 0,
- result = Array(length < 0 ? 0 : length);
- while (++index < length) {
- result[index] = pluck(array, index);
- }
- return result;
- }
- /**
- * Creates an object composed from arrays of `keys` and `values`. Provide
- * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`
- * or two arrays, one of `keys` and one of corresponding `values`.
- *
- * @static
- * @memberOf _
- * @alias object
- * @category Arrays
- * @param {Array} keys The array of keys.
- * @param {Array} [values=[]] The array of values.
- * @returns {Object} Returns an object composed of the given keys and
- * corresponding values.
- * @example
- *
- * _.zipObject(['fred', 'barney'], [30, 40]);
- * // => { 'fred': 30, 'barney': 40 }
- */
- function zipObject(keys, values) {
- var index = -1,
- length = keys ? keys.length : 0,
- result = {};
- if (!values && length && !isArray(keys[0])) {
- values = [];
- }
- while (++index < length) {
- var key = keys[index];
- if (values) {
- result[key] = values[index];
- } else if (key) {
- result[key[0]] = key[1];
- }
- }
- return result;
- }
- /*--------------------------------------------------------------------------*/
- /**
- * Creates a function that executes `func`, with the `this` binding and
- * arguments of the created function, only after being called `n` times.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {number} n The number of times the function must be called before
- * `func` is executed.
- * @param {Function} func The function to restrict.
- * @returns {Function} Returns the new restricted function.
- * @example
- *
- * var saves = ['profile', 'settings'];
- *
- * var done = _.after(saves.length, function() {
- * console.log('Done saving!');
- * });
- *
- * _.forEach(saves, function(type) {
- * asyncSave({ 'type': type, 'complete': done });
- * });
- * // => logs 'Done saving!', after all saves have completed
- */
- function after(n, func) {
- if (!isFunction(func)) {
- throw new TypeError;
- }
- return function() {
- if (--n < 1) {
- return func.apply(this, arguments);
- }
- };
- }
- /**
- * Creates a function that, when called, invokes `func` with the `this`
- * binding of `thisArg` and prepends any additional `bind` arguments to those
- * provided to the bound function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to bind.
- * @param {*} [thisArg] The `this` binding of `func`.
- * @param {...*} [arg] Arguments to be partially applied.
- * @returns {Function} Returns the new bound function.
- * @example
- *
- * var func = function(greeting) {
- * return greeting + ' ' + this.name;
- * };
- *
- * func = _.bind(func, { 'name': 'fred' }, 'hi');
- * func();
- * // => 'hi fred'
- */
- function bind(func, thisArg) {
- return arguments.length > 2
- ? createWrapper(func, 17, slice(arguments, 2), null, thisArg)
- : createWrapper(func, 1, null, null, thisArg);
- }
- /**
- * Binds methods of an object to the object itself, overwriting the existing
- * method. Method names may be specified as individual arguments or as arrays
- * of method names. If no method names are provided all the function properties
- * of `object` will be bound.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Object} object The object to bind and assign the bound methods to.
- * @param {...string} [methodName] The object method names to
- * bind, specified as individual method names or arrays of method names.
- * @returns {Object} Returns `object`.
- * @example
- *
- * var view = {
- * 'label': 'docs',
- * 'onClick': function() { console.log('clicked ' + this.label); }
- * };
- *
- * _.bindAll(view);
- * jQuery('#docs').on('click', view.onClick);
- * // => logs 'clicked docs', when the button is clicked
- */
- function bindAll(object) {
- var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object),
- index = -1,
- length = funcs.length;
- while (++index < length) {
- var key = funcs[index];
- object[key] = createWrapper(object[key], 1, null, null, object);
- }
- return object;
- }
- /**
- * Creates a function that, when called, invokes the method at `object[key]`
- * and prepends any additional `bindKey` arguments to those provided to the bound
- * function. This method differs from `_.bind` by allowing bound functions to
- * reference methods that will be redefined or don't yet exist.
- * See http://michaux.ca/articles/lazy-function-definition-pattern.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Object} object The object the method belongs to.
- * @param {string} key The key of the method.
- * @param {...*} [arg] Arguments to be partially applied.
- * @returns {Function} Returns the new bound function.
- * @example
- *
- * var object = {
- * 'name': 'fred',
- * 'greet': function(greeting) {
- * return greeting + ' ' + this.name;
- * }
- * };
- *
- * var func = _.bindKey(object, 'greet', 'hi');
- * func();
- * // => 'hi fred'
- *
- * object.greet = function(greeting) {
- * return greeting + 'ya ' + this.name + '!';
- * };
- *
- * func();
- * // => 'hiya fred!'
- */
- function bindKey(object, key) {
- return arguments.length > 2
- ? createWrapper(key, 19, slice(arguments, 2), null, object)
- : createWrapper(key, 3, null, null, object);
- }
- /**
- * Creates a function that is the composition of the provided functions,
- * where each function consumes the return value of the function that follows.
- * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`.
- * Each function is executed with the `this` binding of the composed function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {...Function} [func] Functions to compose.
- * @returns {Function} Returns the new composed function.
- * @example
- *
- * var realNameMap = {
- * 'pebbles': 'penelope'
- * };
- *
- * var format = function(name) {
- * name = realNameMap[name.toLowerCase()] || name;
- * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase();
- * };
- *
- * var greet = function(formatted) {
- * return 'Hiya ' + formatted + '!';
- * };
- *
- * var welcome = _.compose(greet, format);
- * welcome('pebbles');
- * // => 'Hiya Penelope!'
- */
- function compose() {
- var funcs = arguments,
- length = funcs.length;
- while (length--) {
- if (!isFunction(funcs[length])) {
- throw new TypeError;
- }
- }
- return function() {
- var args = arguments,
- length = funcs.length;
- while (length--) {
- args = [funcs[length].apply(this, args)];
- }
- return args[0];
- };
- }
- /**
- * Creates a function which accepts one or more arguments of `func` that when
- * invoked either executes `func` returning its result, if all `func` arguments
- * have been provided, or returns a function that accepts one or more of the
- * remaining `func` arguments, and so on. The arity of `func` can be specified
- * if `func.length` is not sufficient.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to curry.
- * @param {number} [arity=func.length] The arity of `func`.
- * @returns {Function} Returns the new curried function.
- * @example
- *
- * var curried = _.curry(function(a, b, c) {
- * console.log(a + b + c);
- * });
- *
- * curried(1)(2)(3);
- * // => 6
- *
- * curried(1, 2)(3);
- * // => 6
- *
- * curried(1, 2, 3);
- * // => 6
- */
- function curry(func, arity) {
- arity = typeof arity == 'number' ? arity : (+arity || func.length);
- return createWrapper(func, 4, null, null, null, arity);
- }
- /**
- * Creates a function that will delay the execution of `func` until after
- * `wait` milliseconds have elapsed since the last time it was invoked.
- * Provide an options object to indicate that `func` should be invoked on
- * the leading and/or trailing edge of the `wait` timeout. Subsequent calls
- * to the debounced function will return the result of the last `func` call.
- *
- * Note: If `leading` and `trailing` options are `true` `func` will be called
- * on the trailing edge of the timeout only if the the debounced function is
- * invoked more than once during the `wait` timeout.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to debounce.
- * @param {number} wait The number of milliseconds to delay.
- * @param {Object} [options] The options object.
- * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout.
- * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called.
- * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
- * @returns {Function} Returns the new debounced function.
- * @example
- *
- * // avoid costly calculations while the window size is in flux
- * var lazyLayout = _.debounce(calculateLayout, 150);
- * jQuery(window).on('resize', lazyLayout);
- *
- * // execute `sendMail` when the click event is fired, debouncing subsequent calls
- * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
- * 'leading': true,
- * 'trailing': false
- * });
- *
- * // ensure `batchLog` is executed once after 1 second of debounced calls
- * var source = new EventSource('/stream');
- * source.addEventListener('message', _.debounce(batchLog, 250, {
- * 'maxWait': 1000
- * }, false);
- */
- function debounce(func, wait, options) {
- var args,
- maxTimeoutId,
- result,
- stamp,
- thisArg,
- timeoutId,
- trailingCall,
- lastCalled = 0,
- maxWait = false,
- trailing = true;
- if (!isFunction(func)) {
- throw new TypeError;
- }
- wait = nativeMax(0, wait) || 0;
- if (options === true) {
- var leading = true;
- trailing = false;
- } else if (isObject(options)) {
- leading = options.leading;
- maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0);
- trailing = 'trailing' in options ? options.trailing : trailing;
- }
- var delayed = function() {
- var remaining = wait - (now() - stamp);
- if (remaining <= 0) {
- if (maxTimeoutId) {
- clearTimeout(maxTimeoutId);
- }
- var isCalled = trailingCall;
- maxTimeoutId = timeoutId = trailingCall = undefined;
- if (isCalled) {
- lastCalled = now();
- result = func.apply(thisArg, args);
- if (!timeoutId && !maxTimeoutId) {
- args = thisArg = null;
- }
- }
- } else {
- timeoutId = setTimeout(delayed, remaining);
- }
- };
- var maxDelayed = function() {
- if (timeoutId) {
- clearTimeout(timeoutId);
- }
- maxTimeoutId = timeoutId = trailingCall = undefined;
- if (trailing || (maxWait !== wait)) {
- lastCalled = now();
- result = func.apply(thisArg, args);
- if (!timeoutId && !maxTimeoutId) {
- args = thisArg = null;
- }
- }
- };
- return function() {
- args = arguments;
- stamp = now();
- thisArg = this;
- trailingCall = trailing && (timeoutId || !leading);
- if (maxWait === false) {
- var leadingCall = leading && !timeoutId;
- } else {
- if (!maxTimeoutId && !leading) {
- lastCalled = stamp;
- }
- var remaining = maxWait - (stamp - lastCalled),
- isCalled = remaining <= 0;
- if (isCalled) {
- if (maxTimeoutId) {
- maxTimeoutId = clearTimeout(maxTimeoutId);
- }
- lastCalled = stamp;
- result = func.apply(thisArg, args);
- }
- else if (!maxTimeoutId) {
- maxTimeoutId = setTimeout(maxDelayed, remaining);
- }
- }
- if (isCalled && timeoutId) {
- timeoutId = clearTimeout(timeoutId);
- }
- else if (!timeoutId && wait !== maxWait) {
- timeoutId = setTimeout(delayed, wait);
- }
- if (leadingCall) {
- isCalled = true;
- result = func.apply(thisArg, args);
- }
- if (isCalled && !timeoutId && !maxTimeoutId) {
- args = thisArg = null;
- }
- return result;
- };
- }
- /**
- * Defers executing the `func` function until the current call stack has cleared.
- * Additional arguments will be provided to `func` when it is invoked.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to defer.
- * @param {...*} [arg] Arguments to invoke the function with.
- * @returns {number} Returns the timer id.
- * @example
- *
- * _.defer(function(text) { console.log(text); }, 'deferred');
- * // logs 'deferred' after one or more milliseconds
- */
- function defer(func) {
- if (!isFunction(func)) {
- throw new TypeError;
- }
- var args = slice(arguments, 1);
- return setTimeout(function() { func.apply(undefined, args); }, 1);
- }
- /**
- * Executes the `func` function after `wait` milliseconds. Additional arguments
- * will be provided to `func` when it is invoked.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to delay.
- * @param {number} wait The number of milliseconds to delay execution.
- * @param {...*} [arg] Arguments to invoke the function with.
- * @returns {number} Returns the timer id.
- * @example
- *
- * _.delay(function(text) { console.log(text); }, 1000, 'later');
- * // => logs 'later' after one second
- */
- function delay(func, wait) {
- if (!isFunction(func)) {
- throw new TypeError;
- }
- var args = slice(arguments, 2);
- return setTimeout(function() { func.apply(undefined, args); }, wait);
- }
- /**
- * Creates a function that memoizes the result of `func`. If `resolver` is
- * provided it will be used to determine the cache key for storing the result
- * based on the arguments provided to the memoized function. By default, the
- * first argument provided to the memoized function is used as the cache key.
- * The `func` is executed with the `this` binding of the memoized function.
- * The result cache is exposed as the `cache` property on the memoized function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to have its output memoized.
- * @param {Function} [resolver] A function used to resolve the cache key.
- * @returns {Function} Returns the new memoizing function.
- * @example
- *
- * var fibonacci = _.memoize(function(n) {
- * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
- * });
- *
- * fibonacci(9)
- * // => 34
- *
- * var data = {
- * 'fred': { 'name': 'fred', 'age': 40 },
- * 'pebbles': { 'name': 'pebbles', 'age': 1 }
- * };
- *
- * // modifying the result cache
- * var get = _.memoize(function(name) { return data[name]; }, _.identity);
- * get('pebbles');
- * // => { 'name': 'pebbles', 'age': 1 }
- *
- * get.cache.pebbles.name = 'penelope';
- * get('pebbles');
- * // => { 'name': 'penelope', 'age': 1 }
- */
- function memoize(func, resolver) {
- if (!isFunction(func)) {
- throw new TypeError;
- }
- var memoized = function() {
- var cache = memoized.cache,
- key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0];
- return hasOwnProperty.call(cache, key)
- ? cache[key]
- : (cache[key] = func.apply(this, arguments));
- }
- memoized.cache = {};
- return memoized;
- }
- /**
- * Creates a function that is restricted to execute `func` once. Repeat calls to
- * the function will return the value of the first call. The `func` is executed
- * with the `this` binding of the created function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to restrict.
- * @returns {Function} Returns the new restricted function.
- * @example
- *
- * var initialize = _.once(createApplication);
- * initialize();
- * initialize();
- * // `initialize` executes `createApplication` once
- */
- function once(func) {
- var ran,
- result;
- if (!isFunction(func)) {
- throw new TypeError;
- }
- return function() {
- if (ran) {
- return result;
- }
- ran = true;
- result = func.apply(this, arguments);
- // clear the `func` variable so the function may be garbage collected
- func = null;
- return result;
- };
- }
- /**
- * Creates a function that, when called, invokes `func` with any additional
- * `partial` arguments prepended to those provided to the new function. This
- * method is similar to `_.bind` except it does **not** alter the `this` binding.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to partially apply arguments to.
- * @param {...*} [arg] Arguments to be partially applied.
- * @returns {Function} Returns the new partially applied function.
- * @example
- *
- * var greet = function(greeting, name) { return greeting + ' ' + name; };
- * var hi = _.partial(greet, 'hi');
- * hi('fred');
- * // => 'hi fred'
- */
- function partial(func) {
- return createWrapper(func, 16, slice(arguments, 1));
- }
- /**
- * This method is like `_.partial` except that `partial` arguments are
- * appended to those provided to the new function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to partially apply arguments to.
- * @param {...*} [arg] Arguments to be partially applied.
- * @returns {Function} Returns the new partially applied function.
- * @example
- *
- * var defaultsDeep = _.partialRight(_.merge, _.defaults);
- *
- * var options = {
- * 'variable': 'data',
- * 'imports': { 'jq': $ }
- * };
- *
- * defaultsDeep(options, _.templateSettings);
- *
- * options.variable
- * // => 'data'
- *
- * options.imports
- * // => { '_': _, 'jq': $ }
- */
- function partialRight(func) {
- return createWrapper(func, 32, null, slice(arguments, 1));
- }
- /**
- * Creates a function that, when executed, will only call the `func` function
- * at most once per every `wait` milliseconds. Provide an options object to
- * indicate that `func` should be invoked on the leading and/or trailing edge
- * of the `wait` timeout. Subsequent calls to the throttled function will
- * return the result of the last `func` call.
- *
- * Note: If `leading` and `trailing` options are `true` `func` will be called
- * on the trailing edge of the timeout only if the the throttled function is
- * invoked more than once during the `wait` timeout.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to throttle.
- * @param {number} wait The number of milliseconds to throttle executions to.
- * @param {Object} [options] The options object.
- * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout.
- * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
- * @returns {Function} Returns the new throttled function.
- * @example
- *
- * // avoid excessively updating the position while scrolling
- * var throttled = _.throttle(updatePosition, 100);
- * jQuery(window).on('scroll', throttled);
- *
- * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes
- * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
- * 'trailing': false
- * }));
- */
- function throttle(func, wait, options) {
- var leading = true,
- trailing = true;
- if (!isFunction(func)) {
- throw new TypeError;
- }
- if (options === false) {
- leading = false;
- } else if (isObject(options)) {
- leading = 'leading' in options ? options.leading : leading;
- trailing = 'trailing' in options ? options.trailing : trailing;
- }
- debounceOptions.leading = leading;
- debounceOptions.maxWait = wait;
- debounceOptions.trailing = trailing;
- return debounce(func, wait, debounceOptions);
- }
- /**
- * Creates a function that provides `value` to the wrapper function as its
- * first argument. Additional arguments provided to the function are appended
- * to those provided to the wrapper function. The wrapper is executed with
- * the `this` binding of the created function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {*} value The value to wrap.
- * @param {Function} wrapper The wrapper function.
- * @returns {Function} Returns the new function.
- * @example
- *
- * var p = _.wrap(_.escape, function(func, text) {
- * return '<p>' + func(text) + '</p>';
- * });
- *
- * p('Fred, Wilma, & Pebbles');
- * // => '<p>Fred, Wilma, & Pebbles</p>'
- */
- function wrap(value, wrapper) {
- return createWrapper(wrapper, 16, [value]);
- }
- /*--------------------------------------------------------------------------*/
- /**
- * Creates a function that returns `value`.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {*} value The value to return from the new function.
- * @returns {Function} Returns the new function.
- * @example
- *
- * var object = { 'name': 'fred' };
- * var getter = _.constant(object);
- * getter() === object;
- * // => true
- */
- function constant(value) {
- return function() {
- return value;
- };
- }
- /**
- * Produces a callback bound to an optional `thisArg`. If `func` is a property
- * name the created callback will return the property value for a given element.
- * If `func` is an object the created callback will return `true` for elements
- * that contain the equivalent object properties, otherwise it will return `false`.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {*} [func=identity] The value to convert to a callback.
- * @param {*} [thisArg] The `this` binding of the created callback.
- * @param {number} [argCount] The number of arguments the callback accepts.
- * @returns {Function} Returns a callback function.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * // wrap to create custom callback shorthands
- * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) {
- * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback);
- * return !match ? func(callback, thisArg) : function(object) {
- * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3];
- * };
- * });
- *
- * _.filter(characters, 'age__gt38');
- * // => [{ 'name': 'fred', 'age': 40 }]
- */
- function createCallback(func, thisArg, argCount) {
- var type = typeof func;
- if (func == null || type == 'function') {
- return baseCreateCallback(func, thisArg, argCount);
- }
- // handle "_.pluck" style callback shorthands
- if (type != 'object') {
- return property(func);
- }
- var props = keys(func),
- key = props[0],
- a = func[key];
- // handle "_.where" style callback shorthands
- if (props.length == 1 && a === a && !isObject(a)) {
- // fast path the common case of providing an object with a single
- // property containing a primitive value
- return function(object) {
- var b = object[key];
- return a === b && (a !== 0 || (1 / a == 1 / b));
- };
- }
- return function(object) {
- var length = props.length,
- result = false;
- while (length--) {
- if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) {
- break;
- }
- }
- return result;
- };
- }
- /**
- * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their
- * corresponding HTML entities.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {string} string The string to escape.
- * @returns {string} Returns the escaped string.
- * @example
- *
- * _.escape('Fred, Wilma, & Pebbles');
- * // => 'Fred, Wilma, & Pebbles'
- */
- function escape(string) {
- return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar);
- }
- /**
- * This method returns the first argument provided to it.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {*} value Any value.
- * @returns {*} Returns `value`.
- * @example
- *
- * var object = { 'name': 'fred' };
- * _.identity(object) === object;
- * // => true
- */
- function identity(value) {
- return value;
- }
- /**
- * Adds function properties of a source object to the destination object.
- * If `object` is a function methods will be added to its prototype as well.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {Function|Object} [object=lodash] object The destination object.
- * @param {Object} source The object of functions to add.
- * @param {Object} [options] The options object.
- * @param {boolean} [options.chain=true] Specify whether the functions added are chainable.
- * @example
- *
- * function capitalize(string) {
- * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
- * }
- *
- * _.mixin({ 'capitalize': capitalize });
- * _.capitalize('fred');
- * // => 'Fred'
- *
- * _('fred').capitalize().value();
- * // => 'Fred'
- *
- * _.mixin({ 'capitalize': capitalize }, { 'chain': false });
- * _('fred').capitalize();
- * // => 'Fred'
- */
- function mixin(object, source, options) {
- var chain = true,
- methodNames = source && functions(source);
- if (!source || (!options && !methodNames.length)) {
- if (options == null) {
- options = source;
- }
- ctor = lodashWrapper;
- source = object;
- object = lodash;
- methodNames = functions(source);
- }
- if (options === false) {
- chain = false;
- } else if (isObject(options) && 'chain' in options) {
- chain = options.chain;
- }
- var ctor = object,
- isFunc = isFunction(ctor);
- forEach(methodNames, function(methodName) {
- var func = object[methodName] = source[methodName];
- if (isFunc) {
- ctor.prototype[methodName] = function() {
- var chainAll = this.__chain__,
- value = this.__wrapped__,
- args = [value];
- push.apply(args, arguments);
- var result = func.apply(object, args);
- if (chain || chainAll) {
- if (value === result && isObject(result)) {
- return this;
- }
- result = new ctor(result);
- result.__chain__ = chainAll;
- }
- return result;
- };
- }
- });
- }
- /**
- * Reverts the '_' variable to its previous value and returns a reference to
- * the `lodash` function.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @returns {Function} Returns the `lodash` function.
- * @example
- *
- * var lodash = _.noConflict();
- */
- function noConflict() {
- context._ = oldDash;
- return this;
- }
- /**
- * A no-operation function.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @example
- *
- * var object = { 'name': 'fred' };
- * _.noop(object) === undefined;
- * // => true
- */
- function noop() {
- // no operation performed
- }
- /**
- * Gets the number of milliseconds that have elapsed since the Unix epoch
- * (1 January 1970 00:00:00 UTC).
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @example
- *
- * var stamp = _.now();
- * _.defer(function() { console.log(_.now() - stamp); });
- * // => logs the number of milliseconds it took for the deferred function to be called
- */
- var now = isNative(now = Date.now) && now || function() {
- return new Date().getTime();
- };
- /**
- * Converts the given value into an integer of the specified radix.
- * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the
- * `value` is a hexadecimal, in which case a `radix` of `16` is used.
- *
- * Note: This method avoids differences in native ES3 and ES5 `parseInt`
- * implementations. See http://es5.github.io/#E.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {string} value The value to parse.
- * @param {number} [radix] The radix used to interpret the value to parse.
- * @returns {number} Returns the new integer value.
- * @example
- *
- * _.parseInt('08');
- * // => 8
- */
- var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) {
- // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt`
- return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0);
- };
- /**
- * Creates a "_.pluck" style function, which returns the `key` value of a
- * given object.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {string} key The name of the property to retrieve.
- * @returns {Function} Returns the new function.
- * @example
- *
- * var characters = [
- * { 'name': 'fred', 'age': 40 },
- * { 'name': 'barney', 'age': 36 }
- * ];
- *
- * var getName = _.property('name');
- *
- * _.map(characters, getName);
- * // => ['barney', 'fred']
- *
- * _.sortBy(characters, getName);
- * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }]
- */
- function property(key) {
- return function(object) {
- return object[key];
- };
- }
- /**
- * Produces a random number between `min` and `max` (inclusive). If only one
- * argument is provided a number between `0` and the given number will be
- * returned. If `floating` is truey or either `min` or `max` are floats a
- * floating-point number will be returned instead of an integer.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {number} [min=0] The minimum possible value.
- * @param {number} [max=1] The maximum possible value.
- * @param {boolean} [floating=false] Specify returning a floating-point number.
- * @returns {number} Returns a random number.
- * @example
- *
- * _.random(0, 5);
- * // => an integer between 0 and 5
- *
- * _.random(5);
- * // => also an integer between 0 and 5
- *
- * _.random(5, true);
- * // => a floating-point number between 0 and 5
- *
- * _.random(1.2, 5.2);
- * // => a floating-point number between 1.2 and 5.2
- */
- function random(min, max, floating) {
- var noMin = min == null,
- noMax = max == null;
- if (floating == null) {
- if (typeof min == 'boolean' && noMax) {
- floating = min;
- min = 1;
- }
- else if (!noMax && typeof max == 'boolean') {
- floating = max;
- noMax = true;
- }
- }
- if (noMin && noMax) {
- max = 1;
- }
- min = +min || 0;
- if (noMax) {
- max = min;
- min = 0;
- } else {
- max = +max || 0;
- }
- if (floating || min % 1 || max % 1) {
- var rand = nativeRandom();
- return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max);
- }
- return baseRandom(min, max);
- }
- /**
- * Resolves the value of property `key` on `object`. If `key` is a function
- * it will be invoked with the `this` binding of `object` and its result returned,
- * else the property value is returned. If `object` is falsey then `undefined`
- * is returned.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {Object} object The object to inspect.
- * @param {string} key The name of the property to resolve.
- * @returns {*} Returns the resolved value.
- * @example
- *
- * var object = {
- * 'cheese': 'crumpets',
- * 'stuff': function() {
- * return 'nonsense';
- * }
- * };
- *
- * _.result(object, 'cheese');
- * // => 'crumpets'
- *
- * _.result(object, 'stuff');
- * // => 'nonsense'
- */
- function result(object, key) {
- if (object) {
- var value = object[key];
- return isFunction(value) ? object[key]() : value;
- }
- }
- /**
- * A micro-templating method that handles arbitrary delimiters, preserves
- * whitespace, and correctly escapes quotes within interpolated code.
- *
- * Note: In the development build, `_.template` utilizes sourceURLs for easier
- * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
- *
- * For more information on precompiling templates see:
- * http://lodash.com/custom-builds
- *
- * For more information on Chrome extension sandboxes see:
- * http://developer.chrome.com/stable/extensions/sandboxingEval.html
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {string} text The template text.
- * @param {Object} data The data object used to populate the text.
- * @param {Object} [options] The options object.
- * @param {RegExp} [options.escape] The "escape" delimiter.
- * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
- * @param {Object} [options.imports] An object to import into the template as local variables.
- * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
- * @param {string} [sourceURL] The sourceURL of the template's compiled source.
- * @param {string} [variable] The data object variable name.
- * @returns {Function|string} Returns a compiled function when no `data` object
- * is given, else it returns the interpolated text.
- * @example
- *
- * // using the "interpolate" delimiter to create a compiled template
- * var compiled = _.template('hello <%= name %>');
- * compiled({ 'name': 'fred' });
- * // => 'hello fred'
- *
- * // using the "escape" delimiter to escape HTML in data property values
- * _.template('<b><%- value %></b>', { 'value': '<script>' });
- * // => '<b><script></b>'
- *
- * // using the "evaluate" delimiter to generate HTML
- * var list = '<% _.forEach(people, function(name) { %><li><%- name %></li><% }); %>';
- * _.template(list, { 'people': ['fred', 'barney'] });
- * // => '<li>fred</li><li>barney</li>'
- *
- * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter
- * _.template('hello ${ name }', { 'name': 'pebbles' });
- * // => 'hello pebbles'
- *
- * // using the internal `print` function in "evaluate" delimiters
- * _.template('<% print("hello " + name); %>!', { 'name': 'barney' });
- * // => 'hello barney!'
- *
- * // using a custom template delimiters
- * _.templateSettings = {
- * 'interpolate': /{{([\s\S]+?)}}/g
- * };
- *
- * _.template('hello {{ name }}!', { 'name': 'mustache' });
- * // => 'hello mustache!'
- *
- * // using the `imports` option to import jQuery
- * var list = '<% jq.each(people, function(name) { %><li><%- name %></li><% }); %>';
- * _.template(list, { 'people': ['fred', 'barney'] }, { 'imports': { 'jq': jQuery } });
- * // => '<li>fred</li><li>barney</li>'
- *
- * // using the `sourceURL` option to specify a custom sourceURL for the template
- * var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' });
- * compiled(data);
- * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
- *
- * // using the `variable` option to ensure a with-statement isn't used in the compiled template
- * var compiled = _.template('hi <%= data.name %>!', null, { 'variable': 'data' });
- * compiled.source;
- * // => function(data) {
- * var __t, __p = '', __e = _.escape;
- * __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!';
- * return __p;
- * }
- *
- * // using the `source` property to inline compiled templates for meaningful
- * // line numbers in error messages and a stack trace
- * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
- * var JST = {\
- * "main": ' + _.template(mainText).source + '\
- * };\
- * ');
- */
- function template(text, data, options) {
- // based on John Resig's `tmpl` implementation
- // http://ejohn.org/blog/javascript-micro-templating/
- // and Laura Doktorova's doT.js
- // https://github.com/olado/doT
- var settings = lodash.templateSettings;
- text = String(text || '');
- // avoid missing dependencies when `iteratorTemplate` is not defined
- options = defaults({}, options, settings);
- var imports = defaults({}, options.imports, settings.imports),
- importsKeys = keys(imports),
- importsValues = values(imports);
- var isEvaluating,
- index = 0,
- interpolate = options.interpolate || reNoMatch,
- source = "__p += '";
- // compile the regexp to match each delimiter
- var reDelimiters = RegExp(
- (options.escape || reNoMatch).source + '|' +
- interpolate.source + '|' +
- (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
- (options.evaluate || reNoMatch).source + '|$'
- , 'g');
- text.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
- interpolateValue || (interpolateValue = esTemplateValue);
- // escape characters that cannot be included in string literals
- source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar);
- // replace delimiters with snippets
- if (escapeValue) {
- source += "' +\n__e(" + escapeValue + ") +\n'";
- }
- if (evaluateValue) {
- isEvaluating = true;
- source += "';\n" + evaluateValue + ";\n__p += '";
- }
- if (interpolateValue) {
- source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
- }
- index = offset + match.length;
- // the JS engine embedded in Adobe products requires returning the `match`
- // string in order to produce the correct `offset` value
- return match;
- });
- source += "';\n";
- // if `variable` is not specified, wrap a with-statement around the generated
- // code to add the data object to the top of the scope chain
- var variable = options.variable,
- hasVariable = variable;
- if (!hasVariable) {
- variable = 'obj';
- source = 'with (' + variable + ') {\n' + source + '\n}\n';
- }
- // cleanup code by stripping empty strings
- source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
- .replace(reEmptyStringMiddle, '$1')
- .replace(reEmptyStringTrailing, '$1;');
- // frame code as the function body
- source = 'function(' + variable + ') {\n' +
- (hasVariable ? '' : variable + ' || (' + variable + ' = {});\n') +
- "var __t, __p = '', __e = _.escape" +
- (isEvaluating
- ? ', __j = Array.prototype.join;\n' +
- "function print() { __p += __j.call(arguments, '') }\n"
- : ';\n'
- ) +
- source +
- 'return __p\n}';
- // Use a sourceURL for easier debugging.
- // http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
- var sourceURL = '\n/*\n//# sourceURL=' + (options.sourceURL || '/lodash/template/source[' + (templateCounter++) + ']') + '\n*/';
- try {
- var result = Function(importsKeys, 'return ' + source + sourceURL).apply(undefined, importsValues);
- } catch(e) {
- e.source = source;
- throw e;
- }
- if (data) {
- return result(data);
- }
- // provide the compiled function's source by its `toString` method, in
- // supported environments, or the `source` property as a convenience for
- // inlining compiled templates during the build process
- result.source = source;
- return result;
- }
- /**
- * Executes the callback `n` times, returning an array of the results
- * of each callback execution. The callback is bound to `thisArg` and invoked
- * with one argument; (index).
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {number} n The number of times to execute the callback.
- * @param {Function} callback The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns an array of the results of each `callback` execution.
- * @example
- *
- * var diceRolls = _.times(3, _.partial(_.random, 1, 6));
- * // => [3, 6, 4]
- *
- * _.times(3, function(n) { mage.castSpell(n); });
- * // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`, and `2` respectively
- *
- * _.times(3, function(n) { this.cast(n); }, mage);
- * // => also calls `mage.castSpell(n)` three times
- */
- function times(n, callback, thisArg) {
- n = (n = +n) > -1 ? n : 0;
- var index = -1,
- result = Array(n);
- callback = baseCreateCallback(callback, thisArg, 1);
- while (++index < n) {
- result[index] = callback(index);
- }
- return result;
- }
- /**
- * The inverse of `_.escape` this method converts the HTML entities
- * `&`, `<`, `>`, `"`, and `'` in `string` to their
- * corresponding characters.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {string} string The string to unescape.
- * @returns {string} Returns the unescaped string.
- * @example
- *
- * _.unescape('Fred, Barney & Pebbles');
- * // => 'Fred, Barney & Pebbles'
- */
- function unescape(string) {
- return string == null ? '' : String(string).replace(reEscapedHtml, unescapeHtmlChar);
- }
- /**
- * Generates a unique ID. If `prefix` is provided the ID will be appended to it.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {string} [prefix] The value to prefix the ID with.
- * @returns {string} Returns the unique ID.
- * @example
- *
- * _.uniqueId('contact_');
- * // => 'contact_104'
- *
- * _.uniqueId();
- * // => '105'
- */
- function uniqueId(prefix) {
- var id = ++idCounter;
- return String(prefix == null ? '' : prefix) + id;
- }
- /*--------------------------------------------------------------------------*/
- /**
- * Creates a `lodash` object that wraps the given value with explicit
- * method chaining enabled.
- *
- * @static
- * @memberOf _
- * @category Chaining
- * @param {*} value The value to wrap.
- * @returns {Object} Returns the wrapper object.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 },
- * { 'name': 'pebbles', 'age': 1 }
- * ];
- *
- * var youngest = _.chain(characters)
- * .sortBy('age')
- * .map(function(chr) { return chr.name + ' is ' + chr.age; })
- * .first()
- * .value();
- * // => 'pebbles is 1'
- */
- function chain(value) {
- value = new lodashWrapper(value);
- value.__chain__ = true;
- return value;
- }
- /**
- * Invokes `interceptor` with the `value` as the first argument and then
- * returns `value`. The purpose of this method is to "tap into" a method
- * chain in order to perform operations on intermediate results within
- * the chain.
- *
- * @static
- * @memberOf _
- * @category Chaining
- * @param {*} value The value to provide to `interceptor`.
- * @param {Function} interceptor The function to invoke.
- * @returns {*} Returns `value`.
- * @example
- *
- * _([1, 2, 3, 4])
- * .tap(function(array) { array.pop(); })
- * .reverse()
- * .value();
- * // => [3, 2, 1]
- */
- function tap(value, interceptor) {
- interceptor(value);
- return value;
- }
- /**
- * Enables explicit method chaining on the wrapper object.
- *
- * @name chain
- * @memberOf _
- * @category Chaining
- * @returns {*} Returns the wrapper object.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * // without explicit chaining
- * _(characters).first();
- * // => { 'name': 'barney', 'age': 36 }
- *
- * // with explicit chaining
- * _(characters).chain()
- * .first()
- * .pick('age')
- * .value();
- * // => { 'age': 36 }
- */
- function wrapperChain() {
- this.__chain__ = true;
- return this;
- }
- /**
- * Produces the `toString` result of the wrapped value.
- *
- * @name toString
- * @memberOf _
- * @category Chaining
- * @returns {string} Returns the string result.
- * @example
- *
- * _([1, 2, 3]).toString();
- * // => '1,2,3'
- */
- function wrapperToString() {
- return String(this.__wrapped__);
- }
- /**
- * Extracts the wrapped value.
- *
- * @name valueOf
- * @memberOf _
- * @alias value
- * @category Chaining
- * @returns {*} Returns the wrapped value.
- * @example
- *
- * _([1, 2, 3]).valueOf();
- * // => [1, 2, 3]
- */
- function wrapperValueOf() {
- return this.__wrapped__;
- }
- /*--------------------------------------------------------------------------*/
- // add functions that return wrapped values when chaining
- lodash.after = after;
- lodash.assign = assign;
- lodash.at = at;
- lodash.bind = bind;
- lodash.bindAll = bindAll;
- lodash.bindKey = bindKey;
- lodash.chain = chain;
- lodash.compact = compact;
- lodash.compose = compose;
- lodash.constant = constant;
- lodash.countBy = countBy;
- lodash.create = create;
- lodash.createCallback = createCallback;
- lodash.curry = curry;
- lodash.debounce = debounce;
- lodash.defaults = defaults;
- lodash.defer = defer;
- lodash.delay = delay;
- lodash.difference = difference;
- lodash.filter = filter;
- lodash.flatten = flatten;
- lodash.forEach = forEach;
- lodash.forEachRight = forEachRight;
- lodash.forIn = forIn;
- lodash.forInRight = forInRight;
- lodash.forOwn = forOwn;
- lodash.forOwnRight = forOwnRight;
- lodash.functions = functions;
- lodash.groupBy = groupBy;
- lodash.indexBy = indexBy;
- lodash.initial = initial;
- lodash.intersection = intersection;
- lodash.invert = invert;
- lodash.invoke = invoke;
- lodash.keys = keys;
- lodash.map = map;
- lodash.mapValues = mapValues;
- lodash.max = max;
- lodash.memoize = memoize;
- lodash.merge = merge;
- lodash.min = min;
- lodash.omit = omit;
- lodash.once = once;
- lodash.pairs = pairs;
- lodash.partial = partial;
- lodash.partialRight = partialRight;
- lodash.pick = pick;
- lodash.pluck = pluck;
- lodash.property = property;
- lodash.pull = pull;
- lodash.range = range;
- lodash.reject = reject;
- lodash.remove = remove;
- lodash.rest = rest;
- lodash.shuffle = shuffle;
- lodash.sortBy = sortBy;
- lodash.tap = tap;
- lodash.throttle = throttle;
- lodash.times = times;
- lodash.toArray = toArray;
- lodash.transform = transform;
- lodash.union = union;
- lodash.uniq = uniq;
- lodash.values = values;
- lodash.where = where;
- lodash.without = without;
- lodash.wrap = wrap;
- lodash.xor = xor;
- lodash.zip = zip;
- lodash.zipObject = zipObject;
- // add aliases
- lodash.collect = map;
- lodash.drop = rest;
- lodash.each = forEach;
- lodash.eachRight = forEachRight;
- lodash.extend = assign;
- lodash.methods = functions;
- lodash.object = zipObject;
- lodash.select = filter;
- lodash.tail = rest;
- lodash.unique = uniq;
- lodash.unzip = zip;
- // add functions to `lodash.prototype`
- mixin(lodash);
- /*--------------------------------------------------------------------------*/
- // add functions that return unwrapped values when chaining
- lodash.clone = clone;
- lodash.cloneDeep = cloneDeep;
- lodash.contains = contains;
- lodash.escape = escape;
- lodash.every = every;
- lodash.find = find;
- lodash.findIndex = findIndex;
- lodash.findKey = findKey;
- lodash.findLast = findLast;
- lodash.findLastIndex = findLastIndex;
- lodash.findLastKey = findLastKey;
- lodash.has = has;
- lodash.identity = identity;
- lodash.indexOf = indexOf;
- lodash.isArguments = isArguments;
- lodash.isArray = isArray;
- lodash.isBoolean = isBoolean;
- lodash.isDate = isDate;
- lodash.isElement = isElement;
- lodash.isEmpty = isEmpty;
- lodash.isEqual = isEqual;
- lodash.isFinite = isFinite;
- lodash.isFunction = isFunction;
- lodash.isNaN = isNaN;
- lodash.isNull = isNull;
- lodash.isNumber = isNumber;
- lodash.isObject = isObject;
- lodash.isPlainObject = isPlainObject;
- lodash.isRegExp = isRegExp;
- lodash.isString = isString;
- lodash.isUndefined = isUndefined;
- lodash.lastIndexOf = lastIndexOf;
- lodash.mixin = mixin;
- lodash.noConflict = noConflict;
- lodash.noop = noop;
- lodash.now = now;
- lodash.parseInt = parseInt;
- lodash.random = random;
- lodash.reduce = reduce;
- lodash.reduceRight = reduceRight;
- lodash.result = result;
- lodash.runInContext = runInContext;
- lodash.size = size;
- lodash.some = some;
- lodash.sortedIndex = sortedIndex;
- lodash.template = template;
- lodash.unescape = unescape;
- lodash.uniqueId = uniqueId;
- // add aliases
- lodash.all = every;
- lodash.any = some;
- lodash.detect = find;
- lodash.findWhere = find;
- lodash.foldl = reduce;
- lodash.foldr = reduceRight;
- lodash.include = contains;
- lodash.inject = reduce;
- mixin(function() {
- var source = {}
- forOwn(lodash, function(func, methodName) {
- if (!lodash.prototype[methodName]) {
- source[methodName] = func;
- }
- });
- return source;
- }(), false);
- /*--------------------------------------------------------------------------*/
- // add functions capable of returning wrapped and unwrapped values when chaining
- lodash.first = first;
- lodash.last = last;
- lodash.sample = sample;
- // add aliases
- lodash.take = first;
- lodash.head = first;
- forOwn(lodash, function(func, methodName) {
- var callbackable = methodName !== 'sample';
- if (!lodash.prototype[methodName]) {
- lodash.prototype[methodName]= function(n, guard) {
- var chainAll = this.__chain__,
- result = func(this.__wrapped__, n, guard);
- return !chainAll && (n == null || (guard && !(callbackable && typeof n == 'function')))
- ? result
- : new lodashWrapper(result, chainAll);
- };
- }
- });
- /*--------------------------------------------------------------------------*/
- /**
- * The semantic version number.
- *
- * @static
- * @memberOf _
- * @type string
- */
- lodash.VERSION = '2.4.1';
- // add "Chaining" functions to the wrapper
- lodash.prototype.chain = wrapperChain;
- lodash.prototype.toString = wrapperToString;
- lodash.prototype.value = wrapperValueOf;
- lodash.prototype.valueOf = wrapperValueOf;
- // add `Array` functions that return unwrapped values
- forEach(['join', 'pop', 'shift'], function(methodName) {
- var func = arrayRef[methodName];
- lodash.prototype[methodName] = function() {
- var chainAll = this.__chain__,
- result = func.apply(this.__wrapped__, arguments);
- return chainAll
- ? new lodashWrapper(result, chainAll)
- : result;
- };
- });
- // add `Array` functions that return the existing wrapped value
- forEach(['push', 'reverse', 'sort', 'unshift'], function(methodName) {
- var func = arrayRef[methodName];
- lodash.prototype[methodName] = function() {
- func.apply(this.__wrapped__, arguments);
- return this;
- };
- });
- // add `Array` functions that return new wrapped values
- forEach(['concat', 'slice', 'splice'], function(methodName) {
- var func = arrayRef[methodName];
- lodash.prototype[methodName] = function() {
- return new lodashWrapper(func.apply(this.__wrapped__, arguments), this.__chain__);
- };
- });
- return lodash;
- }
- /*--------------------------------------------------------------------------*/
- // expose Lo-Dash
- var _ = runInContext();
- // some AMD build optimizers like r.js check for condition patterns like the following:
- if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
- // Expose Lo-Dash to the global object even when an AMD loader is present in
- // case Lo-Dash is loaded with a RequireJS shim config.
- // See http://requirejs.org/docs/api.html#config-shim
- root._ = _;
- // define as an anonymous module so, through path mapping, it can be
- // referenced as the "underscore" module
- define(function() {
- return _;
- });
- }
- // check for `exports` after `define` in case a build optimizer adds an `exports` object
- else if (freeExports && freeModule) {
- // in Node.js or RingoJS
- if (moduleExports) {
- (freeModule.exports = _)._ = _;
- }
- // in Narwhal or Rhino -require
- else {
- freeExports._ = _;
- }
- }
- else {
- // in a browser or Rhino
- root._ = _;
- }
- }.call(this));
- },{}],32:[function(require,module,exports){
- // Underscore.string
- // (c) 2010 Esa-Matti Suuronen <esa-matti aet suuronen dot org>
- // Underscore.string is freely distributable under the terms of the MIT license.
- // Documentation: https://github.com/epeli/underscore.string
- // Some code is borrowed from MooTools and Alexandru Marasteanu.
- // Version '2.3.2'
- !function(root, String){
- 'use strict';
- // Defining helper functions.
- var nativeTrim = String.prototype.trim;
- var nativeTrimRight = String.prototype.trimRight;
- var nativeTrimLeft = String.prototype.trimLeft;
- var parseNumber = function(source) { return source * 1 || 0; };
- var strRepeat = function(str, qty){
- if (qty < 1) return '';
- var result = '';
- while (qty > 0) {
- if (qty & 1) result += str;
- qty >>= 1, str += str;
- }
- return result;
- };
- var slice = [].slice;
- var defaultToWhiteSpace = function(characters) {
- if (characters == null)
- return '\\s';
- else if (characters.source)
- return characters.source;
- else
- return '[' + _s.escapeRegExp(characters) + ']';
- };
- // Helper for toBoolean
- function boolMatch(s, matchers) {
- var i, matcher, down = s.toLowerCase();
- matchers = [].concat(matchers);
- for (i = 0; i < matchers.length; i += 1) {
- matcher = matchers[i];
- if (!matcher) continue;
- if (matcher.test && matcher.test(s)) return true;
- if (matcher.toLowerCase() === down) return true;
- }
- }
- var escapeChars = {
- lt: '<',
- gt: '>',
- quot: '"',
- amp: '&',
- apos: "'"
- };
- var reversedEscapeChars = {};
- for(var key in escapeChars) reversedEscapeChars[escapeChars[key]] = key;
- reversedEscapeChars["'"] = '#39';
- // sprintf() for JavaScript 0.7-beta1
- // http://www.diveintojavascript.com/projects/javascript-sprintf
- //
- // Copyright (c) Alexandru Marasteanu <alexaholic [at) gmail (dot] com>
- // All rights reserved.
- var sprintf = (function() {
- function get_type(variable) {
- return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase();
- }
- var str_repeat = strRepeat;
- var str_format = function() {
- if (!str_format.cache.hasOwnProperty(arguments[0])) {
- str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
- }
- return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
- };
- str_format.format = function(parse_tree, argv) {
- var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length;
- for (i = 0; i < tree_length; i++) {
- node_type = get_type(parse_tree[i]);
- if (node_type === 'string') {
- output.push(parse_tree[i]);
- }
- else if (node_type === 'array') {
- match = parse_tree[i]; // convenience purposes only
- if (match[2]) { // keyword argument
- arg = argv[cursor];
- for (k = 0; k < match[2].length; k++) {
- if (!arg.hasOwnProperty(match[2][k])) {
- throw new Error(sprintf('[_.sprintf] property "%s" does not exist', match[2][k]));
- }
- arg = arg[match[2][k]];
- }
- } else if (match[1]) { // positional argument (explicit)
- arg = argv[match[1]];
- }
- else { // positional argument (implicit)
- arg = argv[cursor++];
- }
- if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) {
- throw new Error(sprintf('[_.sprintf] expecting number but found %s', get_type(arg)));
- }
- switch (match[8]) {
- case 'b': arg = arg.toString(2); break;
- case 'c': arg = String.fromCharCode(arg); break;
- case 'd': arg = parseInt(arg, 10); break;
- case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break;
- case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break;
- case 'o': arg = arg.toString(8); break;
- case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break;
- case 'u': arg = Math.abs(arg); break;
- case 'x': arg = arg.toString(16); break;
- case 'X': arg = arg.toString(16).toUpperCase(); break;
- }
- arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg);
- pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' ';
- pad_length = match[6] - String(arg).length;
- pad = match[6] ? str_repeat(pad_character, pad_length) : '';
- output.push(match[5] ? arg + pad : pad + arg);
- }
- }
- return output.join('');
- };
- str_format.cache = {};
- str_format.parse = function(fmt) {
- var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
- while (_fmt) {
- if ((match = /^[^\x25]+/.exec(_fmt)) !== null) {
- parse_tree.push(match[0]);
- }
- else if ((match = /^\x25{2}/.exec(_fmt)) !== null) {
- parse_tree.push('%');
- }
- else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
- if (match[2]) {
- arg_names |= 1;
- var field_list = [], replacement_field = match[2], field_match = [];
- if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
- field_list.push(field_match[1]);
- while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
- if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
- field_list.push(field_match[1]);
- }
- else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
- field_list.push(field_match[1]);
- }
- else {
- throw new Error('[_.sprintf] huh?');
- }
- }
- }
- else {
- throw new Error('[_.sprintf] huh?');
- }
- match[2] = field_list;
- }
- else {
- arg_names |= 2;
- }
- if (arg_names === 3) {
- throw new Error('[_.sprintf] mixing positional and named placeholders is not (yet) supported');
- }
- parse_tree.push(match);
- }
- else {
- throw new Error('[_.sprintf] huh?');
- }
- _fmt = _fmt.substring(match[0].length);
- }
- return parse_tree;
- };
- return str_format;
- })();
- // Defining underscore.string
- var _s = {
- VERSION: '2.3.0',
- isBlank: function(str){
- if (str == null) str = '';
- return (/^\s*$/).test(str);
- },
- stripTags: function(str){
- if (str == null) return '';
- return String(str).replace(/<\/?[^>]+>/g, '');
- },
- capitalize : function(str){
- str = str == null ? '' : String(str);
- return str.charAt(0).toUpperCase() + str.slice(1);
- },
- chop: function(str, step){
- if (str == null) return [];
- str = String(str);
- step = ~~step;
- return step > 0 ? str.match(new RegExp('.{1,' + step + '}', 'g')) : [str];
- },
- clean: function(str){
- return _s.strip(str).replace(/\s+/g, ' ');
- },
- count: function(str, substr){
- if (str == null || substr == null) return 0;
- str = String(str);
- substr = String(substr);
- var count = 0,
- pos = 0,
- length = substr.length;
- while (true) {
- pos = str.indexOf(substr, pos);
- if (pos === -1) break;
- count++;
- pos += length;
- }
- return count;
- },
- chars: function(str) {
- if (str == null) return [];
- return String(str).split('');
- },
- swapCase: function(str) {
- if (str == null) return '';
- return String(str).replace(/\S/g, function(c){
- return c === c.toUpperCase() ? c.toLowerCase() : c.toUpperCase();
- });
- },
- escapeHTML: function(str) {
- if (str == null) return '';
- return String(str).replace(/[&<>"']/g, function(m){ return '&' + reversedEscapeChars[m] + ';'; });
- },
- unescapeHTML: function(str) {
- if (str == null) return '';
- return String(str).replace(/\&([^;]+);/g, function(entity, entityCode){
- var match;
- if (entityCode in escapeChars) {
- return escapeChars[entityCode];
- } else if (match = entityCode.match(/^#x([\da-fA-F]+)$/)) {
- return String.fromCharCode(parseInt(match[1], 16));
- } else if (match = entityCode.match(/^#(\d+)$/)) {
- return String.fromCharCode(~~match[1]);
- } else {
- return entity;
- }
- });
- },
- escapeRegExp: function(str){
- if (str == null) return '';
- return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
- },
- splice: function(str, i, howmany, substr){
- var arr = _s.chars(str);
- arr.splice(~~i, ~~howmany, substr);
- return arr.join('');
- },
- insert: function(str, i, substr){
- return _s.splice(str, i, 0, substr);
- },
- include: function(str, needle){
- if (needle === '') return true;
- if (str == null) return false;
- return String(str).indexOf(needle) !== -1;
- },
- join: function() {
- var args = slice.call(arguments),
- separator = args.shift();
- if (separator == null) separator = '';
- return args.join(separator);
- },
- lines: function(str) {
- if (str == null) return [];
- return String(str).split("\n");
- },
- reverse: function(str){
- return _s.chars(str).reverse().join('');
- },
- startsWith: function(str, starts){
- if (starts === '') return true;
- if (str == null || starts == null) return false;
- str = String(str); starts = String(starts);
- return str.length >= starts.length && str.slice(0, starts.length) === starts;
- },
- endsWith: function(str, ends){
- if (ends === '') return true;
- if (str == null || ends == null) return false;
- str = String(str); ends = String(ends);
- return str.length >= ends.length && str.slice(str.length - ends.length) === ends;
- },
- succ: function(str){
- if (str == null) return '';
- str = String(str);
- return str.slice(0, -1) + String.fromCharCode(str.charCodeAt(str.length-1) + 1);
- },
- titleize: function(str){
- if (str == null) return '';
- str = String(str).toLowerCase();
- return str.replace(/(?:^|\s|-)\S/g, function(c){ return c.toUpperCase(); });
- },
- camelize: function(str){
- return _s.trim(str).replace(/[-_\s]+(.)?/g, function(match, c){ return c ? c.toUpperCase() : ""; });
- },
- underscored: function(str){
- return _s.trim(str).replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/[-\s]+/g, '_').toLowerCase();
- },
- dasherize: function(str){
- return _s.trim(str).replace(/([A-Z])/g, '-$1').replace(/[-_\s]+/g, '-').toLowerCase();
- },
- classify: function(str){
- return _s.titleize(String(str).replace(/[\W_]/g, ' ')).replace(/\s/g, '');
- },
- humanize: function(str){
- return _s.capitalize(_s.underscored(str).replace(/_id$/,'').replace(/_/g, ' '));
- },
- trim: function(str, characters){
- if (str == null) return '';
- if (!characters && nativeTrim) return nativeTrim.call(str);
- characters = defaultToWhiteSpace(characters);
- return String(str).replace(new RegExp('\^' + characters + '+|' + characters + '+$', 'g'), '');
- },
- ltrim: function(str, characters){
- if (str == null) return '';
- if (!characters && nativeTrimLeft) return nativeTrimLeft.call(str);
- characters = defaultToWhiteSpace(characters);
- return String(str).replace(new RegExp('^' + characters + '+'), '');
- },
- rtrim: function(str, characters){
- if (str == null) return '';
- if (!characters && nativeTrimRight) return nativeTrimRight.call(str);
- characters = defaultToWhiteSpace(characters);
- return String(str).replace(new RegExp(characters + '+$'), '');
- },
- truncate: function(str, length, truncateStr){
- if (str == null) return '';
- str = String(str); truncateStr = truncateStr || '...';
- length = ~~length;
- return str.length > length ? str.slice(0, length) + truncateStr : str;
- },
- /**
- * _s.prune: a more elegant version of truncate
- * prune extra chars, never leaving a half-chopped word.
- * @author github.com/rwz
- */
- prune: function(str, length, pruneStr){
- if (str == null) return '';
- str = String(str); length = ~~length;
- pruneStr = pruneStr != null ? String(pruneStr) : '...';
- if (str.length <= length) return str;
- var tmpl = function(c){ return c.toUpperCase() !== c.toLowerCase() ? 'A' : ' '; },
- template = str.slice(0, length+1).replace(/.(?=\W*\w*$)/g, tmpl); // 'Hello, world' -> 'HellAA AAAAA'
- if (template.slice(template.length-2).match(/\w\w/))
- template = template.replace(/\s*\S+$/, '');
- else
- template = _s.rtrim(template.slice(0, template.length-1));
- return (template+pruneStr).length > str.length ? str : str.slice(0, template.length)+pruneStr;
- },
- words: function(str, delimiter) {
- if (_s.isBlank(str)) return [];
- return _s.trim(str, delimiter).split(delimiter || /\s+/);
- },
- pad: function(str, length, padStr, type) {
- str = str == null ? '' : String(str);
- length = ~~length;
- var padlen = 0;
- if (!padStr)
- padStr = ' ';
- else if (padStr.length > 1)
- padStr = padStr.charAt(0);
- switch(type) {
- case 'right':
- padlen = length - str.length;
- return str + strRepeat(padStr, padlen);
- case 'both':
- padlen = length - str.length;
- return strRepeat(padStr, Math.ceil(padlen/2)) + str
- + strRepeat(padStr, Math.floor(padlen/2));
- default: // 'left'
- padlen = length - str.length;
- return strRepeat(padStr, padlen) + str;
- }
- },
- lpad: function(str, length, padStr) {
- return _s.pad(str, length, padStr);
- },
- rpad: function(str, length, padStr) {
- return _s.pad(str, length, padStr, 'right');
- },
- lrpad: function(str, length, padStr) {
- return _s.pad(str, length, padStr, 'both');
- },
- sprintf: sprintf,
- vsprintf: function(fmt, argv){
- argv.unshift(fmt);
- return sprintf.apply(null, argv);
- },
- toNumber: function(str, decimals) {
- if (!str) return 0;
- str = _s.trim(str);
- if (!str.match(/^-?\d+(?:\.\d+)?$/)) return NaN;
- return parseNumber(parseNumber(str).toFixed(~~decimals));
- },
- numberFormat : function(number, dec, dsep, tsep) {
- if (isNaN(number) || number == null) return '';
- number = number.toFixed(~~dec);
- tsep = typeof tsep == 'string' ? tsep : ',';
- var parts = number.split('.'), fnums = parts[0],
- decimals = parts[1] ? (dsep || '.') + parts[1] : '';
- return fnums.replace(/(\d)(?=(?:\d{3})+$)/g, '$1' + tsep) + decimals;
- },
- strRight: function(str, sep){
- if (str == null) return '';
- str = String(str); sep = sep != null ? String(sep) : sep;
- var pos = !sep ? -1 : str.indexOf(sep);
- return ~pos ? str.slice(pos+sep.length, str.length) : str;
- },
- strRightBack: function(str, sep){
- if (str == null) return '';
- str = String(str); sep = sep != null ? String(sep) : sep;
- var pos = !sep ? -1 : str.lastIndexOf(sep);
- return ~pos ? str.slice(pos+sep.length, str.length) : str;
- },
- strLeft: function(str, sep){
- if (str == null) return '';
- str = String(str); sep = sep != null ? String(sep) : sep;
- var pos = !sep ? -1 : str.indexOf(sep);
- return ~pos ? str.slice(0, pos) : str;
- },
- strLeftBack: function(str, sep){
- if (str == null) return '';
- str += ''; sep = sep != null ? ''+sep : sep;
- var pos = str.lastIndexOf(sep);
- return ~pos ? str.slice(0, pos) : str;
- },
- toSentence: function(array, separator, lastSeparator, serial) {
- separator = separator || ', ';
- lastSeparator = lastSeparator || ' and ';
- var a = array.slice(), lastMember = a.pop();
- if (array.length > 2 && serial) lastSeparator = _s.rtrim(separator) + lastSeparator;
- return a.length ? a.join(separator) + lastSeparator + lastMember : lastMember;
- },
- toSentenceSerial: function() {
- var args = slice.call(arguments);
- args[3] = true;
- return _s.toSentence.apply(_s, args);
- },
- slugify: function(str) {
- if (str == null) return '';
- var from = "ąàáäâãåæăćęèéëêìíïîłńòóöôõøśșțùúüûñçżź",
- to = "aaaaaaaaaceeeeeiiiilnoooooosstuuuunczz",
- regex = new RegExp(defaultToWhiteSpace(from), 'g');
- str = String(str).toLowerCase().replace(regex, function(c){
- var index = from.indexOf(c);
- return to.charAt(index) || '-';
- });
- return _s.dasherize(str.replace(/[^\w\s-]/g, ''));
- },
- surround: function(str, wrapper) {
- return [wrapper, str, wrapper].join('');
- },
- quote: function(str, quoteChar) {
- return _s.surround(str, quoteChar || '"');
- },
- unquote: function(str, quoteChar) {
- quoteChar = quoteChar || '"';
- if (str[0] === quoteChar && str[str.length-1] === quoteChar)
- return str.slice(1,str.length-1);
- else return str;
- },
- exports: function() {
- var result = {};
- for (var prop in this) {
- if (!this.hasOwnProperty(prop) || prop.match(/^(?:include|contains|reverse)$/)) continue;
- result[prop] = this[prop];
- }
- return result;
- },
- repeat: function(str, qty, separator){
- if (str == null) return '';
- qty = ~~qty;
- // using faster implementation if separator is not needed;
- if (separator == null) return strRepeat(String(str), qty);
- // this one is about 300x slower in Google Chrome
- for (var repeat = []; qty > 0; repeat[--qty] = str) {}
- return repeat.join(separator);
- },
- naturalCmp: function(str1, str2){
- if (str1 == str2) return 0;
- if (!str1) return -1;
- if (!str2) return 1;
- var cmpRegex = /(\.\d+)|(\d+)|(\D+)/g,
- tokens1 = String(str1).toLowerCase().match(cmpRegex),
- tokens2 = String(str2).toLowerCase().match(cmpRegex),
- count = Math.min(tokens1.length, tokens2.length);
- for(var i = 0; i < count; i++) {
- var a = tokens1[i], b = tokens2[i];
- if (a !== b){
- var num1 = parseInt(a, 10);
- if (!isNaN(num1)){
- var num2 = parseInt(b, 10);
- if (!isNaN(num2) && num1 - num2)
- return num1 - num2;
- }
- return a < b ? -1 : 1;
- }
- }
- if (tokens1.length === tokens2.length)
- return tokens1.length - tokens2.length;
- return str1 < str2 ? -1 : 1;
- },
- levenshtein: function(str1, str2) {
- if (str1 == null && str2 == null) return 0;
- if (str1 == null) return String(str2).length;
- if (str2 == null) return String(str1).length;
- str1 = String(str1); str2 = String(str2);
- var current = [], prev, value;
- for (var i = 0; i <= str2.length; i++)
- for (var j = 0; j <= str1.length; j++) {
- if (i && j)
- if (str1.charAt(j - 1) === str2.charAt(i - 1))
- value = prev;
- else
- value = Math.min(current[j], current[j - 1], prev) + 1;
- else
- value = i + j;
- prev = current[j];
- current[j] = value;
- }
- return current.pop();
- },
- toBoolean: function(str, trueValues, falseValues) {
- if (typeof str === "number") str = "" + str;
- if (typeof str !== "string") return !!str;
- str = _s.trim(str);
- if (boolMatch(str, trueValues || ["true", "1"])) return true;
- if (boolMatch(str, falseValues || ["false", "0"])) return false;
- }
- };
- // Aliases
- _s.strip = _s.trim;
- _s.lstrip = _s.ltrim;
- _s.rstrip = _s.rtrim;
- _s.center = _s.lrpad;
- _s.rjust = _s.lpad;
- _s.ljust = _s.rpad;
- _s.contains = _s.include;
- _s.q = _s.quote;
- _s.toBool = _s.toBoolean;
- // Exporting
- // CommonJS module is defined
- if (typeof exports !== 'undefined') {
- if (typeof module !== 'undefined' && module.exports)
- module.exports = _s;
- exports._s = _s;
- }
- // Register as a named module with AMD.
- if (typeof define === 'function' && define.amd)
- define('underscore.string', [], function(){ return _s; });
- // Integrate with Underscore.js if defined
- // or create our own underscore object.
- root._ = root._ || {};
- root._.string = root._.str = _s;
- }(this, String);
- },{}]},{},[19])
- ;
- //# sourceMappingURL=framer.js.map
|