flowplayer.js 294 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015
  1. /*!
  2. Flowplayer v6.0.5 (Wednesday, 13. January 2016 09:17AM) | flowplayer.org/license
  3. */
  4. /*! (C) WebReflection Mit Style License */
  5. (function(e){function g(e,t,n,r){for(var i,s=n.slice(),o=w(t,e),u=0,a=s.length;u<a;u++){handler=s[u],typeof handler=="object"&&typeof handler.handleEvent=="function"?handler.handleEvent(o):handler.call(e,o);if(o.stoppedImmediatePropagation)break}return i=!o.stoppedPropagation,r&&i&&e.parentNode?e.parentNode.dispatchEvent(o):!o.defaultPrevented}function y(e,t){return{configurable:!0,get:e,set:t}}function b(e,t,n){var r=f(t||e,n);u(e,"textContent",y(function(){return r.get.call(this)},function(e){r.set.call(this,e)}))}function w(e,t){return e.currentTarget=t,e.eventPhase=e.target===e.currentTarget?2:3,e}function E(e,t){var n=e.length;while(n--&&e[n]!==t);return n}function S(){if(this.tagName==="BR")return"\n";var e=this.firstChild,t=[];while(e)e.nodeType!==8&&e.nodeType!==7&&t.push(e.textContent),e=e.nextSibling;return t.join("")}function x(e){return e.nodeType!==9&&document.documentElement.contains(e)}function T(e){!n&&d.test(document.readyState)&&(n=!n,document.detachEvent(r,T),e=document.createEvent("Event"),e.initEvent(i,!0,!0),document.dispatchEvent(e))}function N(e){var t;while(t=this.lastChild)this.removeChild(t);e!=null&&this.appendChild(document.createTextNode(e))}function C(t,n){return n||(n=e.event),n.target||(n.target=n.srcElement||n.fromElement||document),n.timeStamp||(n.timeStamp=(new Date).getTime()),n}if(document.createEvent)return;var t=!0,n=!1,r="onreadystatechange",i="DOMContentLoaded",s="__IE8__"+Math.random(),o=e.Object,u=o.defineProperty||function(e,t,n){e[t]=n.value},a=o.defineProperties||function(t,n){for(var r in n)if(l.call(n,r))try{u(t,r,n[r])}catch(i){e.console&&console.log(r+" failed on object:",t,i.message)}},f=o.getOwnPropertyDescriptor,l=o.prototype.hasOwnProperty,c=e.Element.prototype,h=e.Text.prototype,p=/^[a-z]+$/,d=/loaded|complete/,v={},m=document.createElement("div");b(e.HTMLCommentElement.prototype,c,"nodeValue"),b(e.HTMLScriptElement.prototype,null,"text"),b(h,null,"nodeValue"),b(e.HTMLTitleElement.prototype,null,"text"),u(e.HTMLStyleElement.prototype,"textContent",function(e){return y(function(){return e.get.call(this.styleSheet)},function(t){e.set.call(this.styleSheet,t)})}(f(e.CSSStyleSheet.prototype,"cssText"))),a(c,{textContent:{get:S,set:N},firstElementChild:{get:function(){for(var e=this.childNodes||[],t=0,n=e.length;t<n;t++)if(e[t].nodeType==1)return e[t]}},lastElementChild:{get:function(){for(var e=this.childNodes||[],t=e.length;t--;)if(e[t].nodeType==1)return e[t]}},previousElementSibling:{get:function(){var e=this.previousSibling;while(e&&e.nodeType!=1)e=e.previousSibling;return e}},nextElementSibling:{get:function(){var e=this.nextSibling;while(e&&e.nodeType!=1)e=e.nextSibling;return e}},childElementCount:{get:function(){for(var e=0,t=this.childNodes||[],n=t.length;n--;e+=t[n].nodeType==1);return e}},addEventListener:{value:function(e,t,n){var r=this,i="on"+e,o=r[s]||u(r,s,{value:{}})[s],a=o[i]||(o[i]={}),f=a.h||(a.h=[]),c;if(!l.call(a,"w")){a.w=function(e){return e[s]||g(r,C(r,e),f,!1)};if(!l.call(v,i))if(p.test(e))try{c=document.createEventObject(),c[s]=!0,r.nodeType!=9&&r.parentNode==null&&m.appendChild(r),r.fireEvent(i,c),v[i]=!0}catch(c){v[i]=!1;while(m.hasChildNodes())m.removeChild(m.firstChild)}else v[i]=!1;(a.n=v[i])&&r.attachEvent(i,a.w)}E(f,t)<0&&f[n?"unshift":"push"](t)}},dispatchEvent:{value:function(e){var t=this,n="on"+e.type,r=t[s],i=r&&r[n],o=!!i,u;return e.target||(e.target=t),o?i.n?t.fireEvent(n,e):g(t,e,i.h,!0):(u=t.parentNode)?u.dispatchEvent(e):!0,!e.defaultPrevented}},removeEventListener:{value:function(e,t,n){var r=this,i="on"+e,o=r[s],u=o&&o[i],a=u&&u.h,f=a?E(a,t):-1;-1<f&&a.splice(f,1)}}}),a(h,{addEventListener:{value:c.addEventListener},dispatchEvent:{value:c.dispatchEvent},removeEventListener:{value:c.removeEventListener}}),a(e.XMLHttpRequest.prototype,{addEventListener:{value:function(e,t,n){var r=this,i="on"+e,o=r[s]||u(r,s,{value:{}})[s],a=o[i]||(o[i]={}),f=a.h||(a.h=[]);E(f,t)<0&&(r[i]||(r[i]=function(){var t=document.createEvent("Event");t.initEvent(e,!0,!0),r.dispatchEvent(t)}),f[n?"unshift":"push"](t))}},dispatchEvent:{value:function(e){var t=this,n="on"+e.type,r=t[s],i=r&&r[n],o=!!i;return o&&(i.n?t.fireEvent(n,e):g(t,e,i.h,!0))}},removeEventListener:{value:c.removeEventListener}}),a(e.Event.prototype,{bubbles:{value:!0,writable:!0},cancelable:{value:!0,writable:!0},preventDefault:{value:function(){this.cancelable&&(this.defaultPrevented=!0,this.returnValue=!1)}},stopPropagation:{value:function(){this.stoppedPropagation=!0,this.cancelBubble=!0}},stopImmediatePropagation:{value:function(){this.stoppedImmediatePropagation=!0,this.stopPropagation()}},initEvent:{value:function(e,t,n){this.type=e,this.bubbles=!!t,this.cancelable=!!n,this.bubbles||this.stopPropagation()}}}),a(e.HTMLDocument.prototype,{textContent:{get:function(){return this.nodeType===11?S.call(this):null},set:function(e){this.nodeType===11&&N.call(this,e)}},addEventListener:{value:function(n,s,o){var u=this;c.addEventListener.call(u,n,s,o),t&&n===i&&!d.test(u.readyState)&&(t=!1,u.attachEvent(r,T),e==top&&function a(e){try{u.documentElement.doScroll("left"),T()}catch(t){setTimeout(a,50)}}())}},dispatchEvent:{value:c.dispatchEvent},removeEventListener:{value:c.removeEventListener},createEvent:{value:function(e){var t;if(e!=="Event")throw new Error("unsupported "+e);return t=document.createEventObject(),t.timeStamp=(new Date).getTime(),t}}}),a(e.Window.prototype,{getComputedStyle:{value:function(){function i(e){this._=e}function s(){}var e=/^(?:[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|))(?!px)[a-z%]+$/,t=/^(top|right|bottom|left)$/,n=/\-([a-z])/g,r=function(e,t){return t.toUpperCase()};return i.prototype.getPropertyValue=function(i){var s=this._,o=s.style,u=s.currentStyle,a=s.runtimeStyle,f,l,c;return i=(i==="float"?"style-float":i).replace(n,r),f=u?u[i]:o[i],e.test(f)&&!t.test(i)&&(l=o.left,c=a&&a.left,c&&(a.left=u.left),o.left=i==="fontSize"?"1em":f,f=o.pixelLeft+"px",o.left=l,c&&(a.left=c)),f==null?f:f+""||"auto"},s.prototype.getPropertyValue=function(){return null},function(e,t){return t?new s(e):new i(e)}}()},addEventListener:{value:function(t,n,r){var i=e,o="on"+t,u;i[o]||(i[o]=function(e){return g(i,C(i,e),u,!1)}),u=i[o][s]||(i[o][s]=[]),E(u,n)<0&&u[r?"unshift":"push"](n)}},dispatchEvent:{value:function(t){var n=e["on"+t.type];return n?n.call(e,t)!==!1&&!t.defaultPrevented:!0}},removeEventListener:{value:function(t,n,r){var i="on"+t,u=(e[i]||o)[s],a=u?E(u,n):-1;-1<a&&u.splice(a,1)}}})})(this);
  6. !function (e) { if ("object" == typeof exports && "undefined" != typeof module) module.exports = e(); else if ("function" == typeof define && define.amd) define([], e); else { var f; "undefined" != typeof window ? f = window : "undefined" != typeof global ? f = global : "undefined" != typeof self && (f = self), f.flowplayer = e() } } (function () {
  7. var define, module, exports; return (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { var a = typeof require == "function" && require; if (!u && a) return a(o, !0); if (i) return i(o, !0); var f = new Error("Cannot find module '" + o + "'"); throw f.code = "MODULE_NOT_FOUND", f } var l = n[o] = { exports: {} }; t[o][0].call(l.exports, function (e) { var n = t[o][1][e]; return s(n ? n : e) }, l, l.exports, e, t, n, r) } return n[o].exports } var i = typeof require == "function" && require; for (var o = 0; o < r.length; o++) s(r[o]); return s })({ 1: [function (_dereq_, module, exports) {
  8. 'use strict';
  9. var common = module.exports = {},
  10. ClassList = _dereq_('class-list'),
  11. $ = window.jQuery,
  12. punycode = _dereq_('punycode'),
  13. computedStyle = _dereq_('computed-style');
  14. common.noop = function () { };
  15. common.identity = function (i) { return i; };
  16. common.removeNode = function (el) {
  17. if (!el || !el.parentNode) return;
  18. el.parentNode.removeChild(el);
  19. };
  20. common.find = function (query, ctx) {
  21. if ($) return $(query, ctx).toArray();
  22. ctx = ctx || document;
  23. return Array.prototype.map.call(ctx.querySelectorAll(query), function (el) { return el; });
  24. };
  25. common.text = function (el, txt) {
  26. el[('innerText' in el) ? 'innerText' : 'textContent'] = txt;
  27. };
  28. common.findDirect = function (query, ctx) {
  29. return common.find(query, ctx).filter(function (node) {
  30. return node.parentNode === ctx;
  31. });
  32. };
  33. common.hasClass = function (el, kls) {
  34. return ClassList(el).contains(kls);
  35. };
  36. common.isSameDomain = function (url) {
  37. var w = window.location,
  38. a = common.createElement('a', { href: url });
  39. return w.hostname === a.hostname &&
  40. w.protocol === a.protocol &&
  41. w.port === a.port;
  42. };
  43. common.css = function (el, property, value) {
  44. if (typeof property === 'object') {
  45. return Object.keys(property).forEach(function (key) {
  46. common.css(el, key, property[key]);
  47. });
  48. }
  49. if (typeof value !== 'undefined') {
  50. if (value === '') return el ? el.style.removeProperty(property) : undefined;
  51. return el ? el.style.setProperty(property, value) : undefined;
  52. }
  53. return el ? computedStyle(el, property) : undefined;
  54. };
  55. common.createElement = function (tag, attributes, innerHTML) {
  56. try {
  57. var el = document.createElement(tag);
  58. for (var key in attributes) {
  59. if (!attributes.hasOwnProperty(key)) continue;
  60. if (key === 'css') {
  61. common.css(el, attributes[key]);
  62. } else {
  63. common.attr(el, key, attributes[key]);
  64. }
  65. }
  66. el.innerHTML = innerHTML || '';
  67. return el;
  68. } catch (e) {
  69. if (!$) throw e;
  70. return $('<' + tag + '>' + innerHTML + '</' + tag + '>').attr(attributes)[0];
  71. }
  72. };
  73. common.toggleClass = function (el, cls, flag) {
  74. if (!el) return;
  75. var classes = ClassList(el);
  76. if (typeof flag === 'undefined') classes.toggle(cls);
  77. else if (flag) classes.add(cls);
  78. else if (!flag) classes.remove(cls);
  79. };
  80. common.addClass = function (el, cls) {
  81. return common.toggleClass(el, cls, true);
  82. };
  83. common.removeClass = function (el, cls) {
  84. return common.toggleClass(el, cls, false);
  85. };
  86. common.append = function (par, child) {
  87. par.appendChild(child);
  88. return par;
  89. };
  90. common.appendTo = function (child, par) {
  91. common.append(par, child);
  92. return child;
  93. };
  94. common.prepend = function (par, child) {
  95. par.insertBefore(child, par.firstChild);
  96. };
  97. // Inserts `el` after `child` that is child of `par`
  98. common.insertAfter = function (par, child, el) {
  99. if (child == common.lastChild(par)) par.appendChild(el);
  100. var childIndex = Array.prototype.indexOf.call(par.children, child);
  101. par.insertBefore(el, par.children[childIndex + 1]);
  102. };
  103. common.html = function (elms, val) {
  104. elms = elms.length ? elms : [elms];
  105. elms.forEach(function (elm) {
  106. elm.innerHTML = val;
  107. });
  108. };
  109. common.attr = function (el, key, val) {
  110. if (key === 'class') key = 'className';
  111. if (common.hasOwnOrPrototypeProperty(el, key)) {
  112. try {
  113. el[key] = val;
  114. } catch (e) { // Most likely IE not letting set property
  115. if ($) {
  116. $(el).attr(key, val);
  117. } else {
  118. throw e;
  119. }
  120. }
  121. } else {
  122. if (val === false) {
  123. el.removeAttribute(key);
  124. } else {
  125. el.setAttribute(key, val);
  126. }
  127. }
  128. return el;
  129. };
  130. common.prop = function (el, key, val) {
  131. if (typeof val === 'undefined') {
  132. return el && el[key];
  133. }
  134. el[key] = val;
  135. };
  136. common.offset = function (el) {
  137. var ret = el.getBoundingClientRect();
  138. if (el.offsetWidth / el.offsetHeight > el.clientWidth / el.clientHeight) { // https://github.com/flowplayer/flowplayer/issues/757
  139. ret = {
  140. left: ret.left * 100,
  141. right: ret.right * 100,
  142. top: ret.top * 100,
  143. bottom: ret.bottom * 100,
  144. width: ret.width * 100,
  145. height: ret.height * 100
  146. };
  147. }
  148. return ret;
  149. };
  150. common.width = function (el, val) {
  151. /*jshint -W093 */
  152. if (val) return el.style.width = ('' + val).replace(/px$/, '') + 'px';
  153. var ret = common.offset(el).width;
  154. return typeof ret === 'undefined' ? el.offsetWidth : ret;
  155. };
  156. common.height = function (el, val) {
  157. /*jshint -W093 */
  158. if (val) return el.style.height = ('' + val).replace(/px$/, '') + 'px';
  159. var ret = common.offset(el).height;
  160. return typeof ret === 'undefined' ? el.offsetHeight : ret;
  161. };
  162. common.lastChild = function (el) {
  163. return el.children[el.children.length - 1];
  164. };
  165. common.hasParent = function (el, parentSelector) {
  166. var parent = el.parentElement;
  167. while (parent) {
  168. if (common.matches(parent, parentSelector)) return true;
  169. parent = parent.parentElement;
  170. }
  171. return false;
  172. };
  173. common.createAbsoluteUrl = function (url) {
  174. return common.createElement('a', { href: url }).href; // This won't work on IE7
  175. };
  176. common.xhrGet = function (url, successCb, errorCb) {
  177. var xhr = new XMLHttpRequest();
  178. xhr.onreadystatechange = function () {
  179. if (this.readyState !== 4) return;
  180. if (this.status >= 400) return errorCb();
  181. successCb(this.responseText);
  182. };
  183. xhr.open('get', url, true);
  184. xhr.send();
  185. };
  186. common.pick = function (obj, props) {
  187. var ret = {};
  188. props.forEach(function (prop) {
  189. if (obj.hasOwnProperty(prop)) ret[prop] = obj[prop];
  190. });
  191. return ret;
  192. };
  193. common.hostname = function (host) {
  194. return punycode.toUnicode(host || window.location.hostname);
  195. };
  196. //Hacks
  197. common.browser = {
  198. webkit: 'WebkitAppearance' in document.documentElement.style
  199. };
  200. common.getPrototype = function (el) {
  201. /* jshint proto:true */
  202. if (!Object.getPrototypeOf) return el.__proto__;
  203. return Object.getPrototypeOf(el);
  204. };
  205. common.hasOwnOrPrototypeProperty = function (obj, prop) {
  206. var o = obj;
  207. while (o) {
  208. if (Object.prototype.hasOwnProperty.call(o, prop)) return true;
  209. o = common.getPrototype(o);
  210. }
  211. return false;
  212. };
  213. // Polyfill for Element.matches
  214. // adapted from https://developer.mozilla.org/en/docs/Web/API/Element/matches
  215. common.matches = function (elem, selector) {
  216. var proto = Element.prototype,
  217. fn = proto.matches ||
  218. proto.matchesSelector ||
  219. proto.mozMatchesSelector ||
  220. proto.msMatchesSelector ||
  221. proto.oMatchesSelector ||
  222. proto.webkitMatchesSelector ||
  223. function (selector) {
  224. var element = this,
  225. matches = (element.document || element.ownerDocument).querySelectorAll(selector),
  226. i = 0;
  227. while (matches[i] && matches[i] !== element) {
  228. i++;
  229. }
  230. return matches[i] ? true : false;
  231. };
  232. return fn.call(elem, selector);
  233. };
  234. // Polyfill for CSSStyleDeclaration
  235. // from https://github.com/shawnbot/aight
  236. (function (CSSSDProto) {
  237. function getAttribute(property) {
  238. return property.replace(/-[a-z]/g, function (bit) {
  239. return bit[1].toUpperCase();
  240. });
  241. }
  242. // patch CSSStyleDeclaration.prototype using IE8's methods
  243. if (typeof CSSSDProto.setAttribute !== "undefined") {
  244. CSSSDProto.setProperty = function (property, value) {
  245. return this.setAttribute(getAttribute(property), String(value) /*, important */);
  246. };
  247. CSSSDProto.getPropertyValue = function (property) {
  248. return this.getAttribute(getAttribute(property)) || null;
  249. };
  250. CSSSDProto.removeProperty = function (property) {
  251. var value = this.getPropertyValue(property);
  252. this.removeAttribute(getAttribute(property));
  253. return value;
  254. };
  255. }
  256. })(window.CSSStyleDeclaration.prototype);
  257. }, { "class-list": 22, "computed-style": 24, "punycode": 21}], 2: [function (_dereq_, module, exports) {
  258. 'use strict';
  259. var common = _dereq_('../common');
  260. // movie required in opts
  261. module.exports = function embed(swf, flashvars, wmode, bgColor) {
  262. wmode = wmode || "opaque";
  263. var id = "obj" + ("" + Math.random()).slice(2, 15),
  264. tag = '<object class="fp-engine" id="' + id + '" name="' + id + '" ',
  265. msie = navigator.userAgent.indexOf('MSIE') > -1;
  266. tag += msie ? 'classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000">' :
  267. ' data="' + swf + '" type="application/x-shockwave-flash">';
  268. var opts = {
  269. width: "100%",
  270. height: "100%",
  271. allowscriptaccess: "always",
  272. wmode: wmode,
  273. quality: "high",
  274. flashvars: "",
  275. // https://github.com/flowplayer/flowplayer/issues/13#issuecomment-9369919
  276. movie: swf + (msie ? "?" + id : ""),
  277. name: id
  278. };
  279. if (wmode !== 'transparent') opts.bgcolor = bgColor || '#333333';
  280. // flashvars
  281. Object.keys(flashvars).forEach(function (key) {
  282. opts.flashvars += key + "=" + flashvars[key] + "&";
  283. });
  284. // parameters
  285. Object.keys(opts).forEach(function (key) {
  286. tag += '<param name="' + key + '" value="' + opts[key] + '"/>';
  287. });
  288. tag += "</object>";
  289. var el = common.createElement('div', {}, tag);
  290. return common.find('object', el);
  291. };
  292. // Flash is buggy allover
  293. if (window.attachEvent) {
  294. window.attachEvent("onbeforeunload", function () {
  295. window.__flash_savedUnloadHandler = window.__flash_unloadHandler = function () { };
  296. });
  297. }
  298. }, { "../common": 1}], 3: [function (_dereq_, module, exports) {
  299. 'use strict';
  300. var flowplayer = _dereq_('../flowplayer'),
  301. common = _dereq_('../common'),
  302. embed = _dereq_('./embed'),
  303. extend = _dereq_('extend-object'),
  304. bean = _dereq_('bean'),
  305. engineImpl;
  306. engineImpl = function flashEngine(player, root) {
  307. var conf = player.conf,
  308. video = player.video,
  309. loadVideo,
  310. callbackId,
  311. objectTag,
  312. api;
  313. var win = window;
  314. var engine = {
  315. engineName: engineImpl.engineName,
  316. pick: function (sources) {
  317. var source = extend({}, (function () {
  318. if (flowplayer.support.flashVideo) {
  319. var selectedSource;
  320. for (var i = 0, source; i < sources.length; i++) {
  321. source = sources[i];
  322. if (/mp4|flv|flash/i.test(source.type)) selectedSource = source;
  323. if (player.conf.swfHls && /mpegurl/i.test(source.type)) selectedSource = source;
  324. if (selectedSource && !/mp4/i.test(selectedSource.type)) return selectedSource;
  325. // Did not find any source or source was video/mp4, let's try find more
  326. }
  327. return selectedSource; // Accept the fact we don't have anything or just an MP4
  328. }
  329. })());
  330. if (!source) return;
  331. if (source.src && !isAbsolute(source.src) && !player.conf.rtmp && !source.rtmp) source.src = common.createAbsoluteUrl(source.src);
  332. return source;
  333. },
  334. load: function (video) {
  335. loadVideo = video;
  336. function escapeURL(url) {
  337. return url.replace(/&amp;/g, '%26').replace(/&/g, '%26').replace(/=/g, '%3D');
  338. }
  339. var html5Tag = common.findDirect('video', root)[0] || common.find('.fp-player > video', root)[0],
  340. url = video.src,
  341. is_absolute = isAbsolute(url);
  342. var removeTag = function () {
  343. common.removeNode(html5Tag);
  344. };
  345. var hasSupportedSource = function (sources) {
  346. return sources.some(function (src) {
  347. return !!html5Tag.canPlayType(src.type);
  348. });
  349. };
  350. if (flowplayer.support.video &&
  351. common.prop(html5Tag, 'autoplay') &&
  352. hasSupportedSource(video.sources)) bean.one(html5Tag, 'timeupdate', removeTag);
  353. else removeTag();
  354. // convert to absolute
  355. var rtmp = video.rtmp || conf.rtmp;
  356. if (!is_absolute && !rtmp) url = common.createAbsoluteUrl(url);
  357. if (api && isHLS(video) && api.data !== conf.swfHls) engine.unload();
  358. if (api) {
  359. ['live', 'preload', 'loop'].forEach(function (prop) {
  360. if (!video.hasOwnProperty(prop)) return;
  361. api.__set(prop, video[prop]);
  362. });
  363. Object.keys(video.flashls || {}).forEach(function (key) {
  364. api.__set('hls_' + key, video.flashls[key]);
  365. });
  366. var providerChangeNeeded = false;
  367. if (!is_absolute && rtmp) api.__set('rtmp', rtmp.url || rtmp);
  368. else {
  369. var oldRtmp = api.__get('rtmp');
  370. providerChangeNeeded = !!oldRtmp;
  371. api.__set('rtmp', null);
  372. }
  373. api.__play(url, providerChangeNeeded || video.rtmp && video.rtmp !== conf.rtmp);
  374. } else {
  375. callbackId = "fpCallback" + ("" + Math.random()).slice(3, 15);
  376. url = escapeURL(url);
  377. var opts = {
  378. hostname: conf.embedded ? common.hostname(conf.hostname) : common.hostname(location.hostname),
  379. url: url,
  380. callback: callbackId
  381. };
  382. if (root.getAttribute('data-origin')) {
  383. opts.origin = root.getAttribute('data-origin');
  384. }
  385. // optional conf
  386. ['proxy', 'key', 'autoplay', 'preload', 'subscribe', 'live', 'loop', 'debug', 'splash', 'poster', 'rtmpt'].forEach(function (key) {
  387. if (conf.hasOwnProperty(key)) opts[key] = conf[key];
  388. if (video.hasOwnProperty(key)) opts[key] = video[key];
  389. if ((conf.rtmp || {}).hasOwnProperty(key)) opts[key] = (conf.rtmp || {})[key];
  390. if ((video.rtmp || {}).hasOwnProperty(key)) opts[key] = (video.rtmp || {})[key];
  391. });
  392. if (conf.rtmp) opts.rtmp = conf.rtmp.url || conf.rtmp;
  393. if (video.rtmp) opts.rtmp = video.rtmp.url || video.rtmp;
  394. Object.keys(video.flashls || {}).forEach(function (key) {
  395. var val = video.flashls[key];
  396. opts['hls_' + key] = val;
  397. });
  398. // bufferTime might be 0
  399. if (conf.bufferTime !== undefined) opts.bufferTime = conf.bufferTime;
  400. if (is_absolute) delete opts.rtmp;
  401. // issues #376
  402. if (opts.rtmp) {
  403. opts.rtmp = escapeURL(opts.rtmp);
  404. }
  405. // issues #733, 906
  406. var bgColor = conf.bgcolor || common.css(root, 'background-color') || '', bg;
  407. if (bgColor.indexOf('rgb') === 0) {
  408. bg = toHex(bgColor);
  409. } else if (bgColor.indexOf('#') === 0) {
  410. bg = toLongHex(bgColor);
  411. }
  412. // issues #387
  413. opts.initialVolume = player.volumeLevel;
  414. var swfUrl = isHLS(video) ? conf.swfHls : conf.swf;
  415. api = embed(swfUrl, opts, conf.wmode, bg)[0];
  416. var container = common.find('.fp-player', root)[0];
  417. common.prepend(container, api);
  418. // throw error if no loading occurs
  419. setTimeout(function () {
  420. try {
  421. if (!api.PercentLoaded()) {
  422. return player.trigger("error", [player, { code: 7, url: conf.swf}]);
  423. }
  424. } catch (e) { }
  425. }, 5000);
  426. // detect disabled flash
  427. setTimeout(function () {
  428. if (typeof api.PercentLoaded === 'undefined') {
  429. player.trigger('flashdisabled', [player]);
  430. }
  431. }, 1000);
  432. player.off('resume.flashhack').on('resume.flashhack', function () {
  433. var timer = setTimeout(function () {
  434. if (player.playing) {
  435. player.trigger('flashdisabled', [player]);
  436. }
  437. }, 1000);
  438. player.one('progress', function () {
  439. clearTimeout(timer);
  440. });
  441. });
  442. api.pollInterval = setInterval(function () {
  443. if (!api) return;
  444. var status = api.__status ? api.__status() : null;
  445. if (!status) return;
  446. if (player.playing && status.time && status.time !== player.video.time) player.trigger("progress", [player, status.time]);
  447. video.buffer = status.buffer / video.bytes * video.duration;
  448. player.trigger("buffer", [player, video.buffer]);
  449. if (!video.buffered && status.time > 0) {
  450. video.buffered = true;
  451. player.trigger("buffered", [player]);
  452. }
  453. }, 250);
  454. // listen
  455. window[callbackId] = function (type, arg) {
  456. var video = loadVideo;
  457. if (conf.debug) {
  458. if (type.indexOf('debug') === 0 && arg && arg.length) {
  459. console.log.apply(console, ['-- ' + type].concat(arg));
  460. }
  461. else console.log("--", type, arg);
  462. }
  463. var event = {
  464. type: type
  465. };
  466. switch (type) {
  467. // RTMP sends a lot of finish events in vain
  468. // case "finish": if (conf.rtmp) return;
  469. case "ready": arg = extend(video, arg); break;
  470. case "click": event.flash = true; break;
  471. case "keydown": event.which = arg; break;
  472. case "seek": video.time = arg; break;
  473. case "status":
  474. player.trigger("progress", [player, arg.time]);
  475. if (arg.buffer < video.bytes && !video.buffered) {
  476. video.buffer = arg.buffer / video.bytes * video.duration;
  477. player.trigger("buffer", video.buffer);
  478. } else if (!video.buffered) {
  479. video.buffered = true;
  480. player.trigger("buffered");
  481. }
  482. break;
  483. }
  484. if (type === 'click' || type === 'keydown') {
  485. event.target = root;
  486. bean.fire(root, type, [event]);
  487. }
  488. else if (type != 'buffered' && type !== 'unload') {
  489. // add some delay so that player is truly ready after an event
  490. setTimeout(function () { player.trigger(event, [player, arg]); }, 1);
  491. } else if (type === 'unload') {
  492. player.trigger(event, [player, arg]);
  493. }
  494. };
  495. }
  496. },
  497. // not supported yet
  498. speed: common.noop,
  499. unload: function () {
  500. if (api && api.__unload) api.__unload();
  501. try {
  502. if (callbackId && window[callbackId]) delete window[callbackId];
  503. } catch (e) { }
  504. common.find("object", root).forEach(common.removeNode);
  505. api = 0;
  506. player.off('.flashengine');
  507. clearInterval(api.pollInterval);
  508. }
  509. };
  510. ['pause', 'resume', 'seek', 'volume'].forEach(function (name) {
  511. engine[name] = function (arg) {
  512. try {
  513. if (player.ready) {
  514. if (arg === undefined) {
  515. api["__" + name]();
  516. } else {
  517. api["__" + name](arg);
  518. }
  519. }
  520. } catch (e) {
  521. if (typeof api["__" + name] === 'undefined') { //flash lost it's methods
  522. return player.trigger('flashdisabled', [player]);
  523. }
  524. throw e;
  525. }
  526. };
  527. });
  528. function toHex(bg) {
  529. function hex(x) {
  530. return ("0" + parseInt(x).toString(16)).slice(-2);
  531. }
  532. bg = bg.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
  533. if (!bg) return;
  534. return '#' + hex(bg[1]) + hex(bg[2]) + hex(bg[3]);
  535. }
  536. function toLongHex(bg) {
  537. if (bg.length === 7) return bg;
  538. var a = bg.split('').slice(1);
  539. return '#' + a.map(function (i) {
  540. return i + i;
  541. }).join('');
  542. }
  543. function isHLS(video) {
  544. return /application\/x-mpegurl/i.test(video.type);
  545. }
  546. return engine;
  547. };
  548. engineImpl.engineName = 'flash';
  549. engineImpl.canPlay = function (type, conf) {
  550. return flowplayer.support.flashVideo && /video\/(mp4|flash|flv)/i.test(type) || flowplayer.support.flashVideo && conf.swfHls && /mpegurl/i.test(type);
  551. };
  552. flowplayer.engines.push(engineImpl);
  553. function isAbsolute(url) {
  554. return /^https?:/.test(url);
  555. }
  556. }, { "../common": 1, "../flowplayer": 18, "./embed": 2, "bean": 20, "extend-object": 26}], 4: [function (_dereq_, module, exports) {
  557. 'use strict';
  558. var flowplayer = _dereq_('../flowplayer'),
  559. bean = _dereq_('bean'),
  560. ClassList = _dereq_('class-list'),
  561. extend = _dereq_('extend-object'),
  562. common = _dereq_('../common');
  563. var VIDEO = document.createElement('video');
  564. // HTML5 --> Flowplayer event
  565. var EVENTS = {
  566. // fired
  567. ended: 'finish',
  568. pause: 'pause',
  569. play: 'resume',
  570. progress: 'buffer',
  571. timeupdate: 'progress',
  572. volumechange: 'volume',
  573. ratechange: 'speed',
  574. //seeking: 'beforeseek',
  575. seeked: 'seek',
  576. // abort: 'resume',
  577. // not fired
  578. loadeddata: 'ready',
  579. // loadedmetadata: 0,
  580. // canplay: 0,
  581. // error events
  582. // load: 0,
  583. // emptied: 0,
  584. // empty: 0,
  585. error: 'error',
  586. dataunavailable: 'error',
  587. webkitendfullscreen: !flowplayer.support.inlineVideo && 'unload'
  588. };
  589. function round(val, per) {
  590. per = per || 100;
  591. return Math.round(val * per) / per;
  592. }
  593. function getType(type) {
  594. return /mpegurl/i.test(type) ? "application/x-mpegurl" : type;
  595. }
  596. function canPlay(type) {
  597. if (!/^(video|application)/i.test(type))
  598. type = getType(type);
  599. return !!VIDEO.canPlayType(type).replace("no", '');
  600. }
  601. function findFromSourcesByType(sources, type) {
  602. var arr = sources.filter(function (s) {
  603. return s.type === type;
  604. });
  605. return arr.length ? arr[0] : null;
  606. }
  607. var videoTagCache;
  608. var createVideoTag = function (video, autoplay, preload, useCache) {
  609. if (typeof autoplay === 'undefined') autoplay = true;
  610. if (typeof preload === 'undefined') preload = 'none';
  611. if (typeof useCache === 'undefined') useCache = true;
  612. if (useCache && videoTagCache) {
  613. videoTagCache.type = getType(video.type);
  614. videoTagCache.src = video.src;
  615. common.find('track', videoTagCache).forEach(common.removeNode);
  616. videoTagCache.removeAttribute('crossorigin');
  617. return videoTagCache;
  618. }
  619. var el = document.createElement('video');
  620. el.src = video.src;
  621. el.type = getType(video.type);
  622. el.className = 'fp-engine';
  623. el.autoplay = autoplay ? 'autoplay' : false;
  624. el.preload = preload;
  625. el.setAttribute('x-webkit-airplay', 'allow');
  626. if (useCache) videoTagCache = el;
  627. return el;
  628. };
  629. var engine;
  630. engine = function (player, root) {
  631. var api = common.findDirect('video', root)[0] || common.find('.fp-player > video', root)[0],
  632. support = flowplayer.support,
  633. track = common.find("track", api)[0],
  634. conf = player.conf,
  635. self,
  636. timer,
  637. volumeLevel;
  638. /*jshint -W093 */
  639. return self = {
  640. engineName: engine.engineName,
  641. pick: function (sources) {
  642. var source = (function () {
  643. if (support.video) {
  644. if (conf.videoTypePreference) {
  645. var mp4source = findFromSourcesByType(sources, conf.videoTypePreference);
  646. if (mp4source) return mp4source;
  647. }
  648. for (var i = 0, source; i < sources.length; i++) {
  649. if (canPlay(sources[i].type)) return sources[i];
  650. }
  651. }
  652. })();
  653. if (!source) return;
  654. if (typeof source.src === 'string') source.src = common.createAbsoluteUrl(source.src);
  655. return source;
  656. },
  657. load: function (video) {
  658. var created = false, container = common.find('.fp-player', root)[0], reload = false;
  659. if (conf.splash && !api) {
  660. api = createVideoTag(video);
  661. common.prepend(container, api);
  662. created = true;
  663. } else if (!api) {
  664. api = createVideoTag(video, !!video.autoplay || !!conf.autoplay, conf.clip.preload || 'metadata', false);
  665. common.prepend(container, api);
  666. created = true;
  667. } else {
  668. ClassList(api).add('fp-engine');
  669. common.find('source,track', api).forEach(common.removeNode);
  670. if (!player.conf.nativesubtitles) common.attr(api, 'crossorigin', false);
  671. reload = api.src === video.src;
  672. }
  673. if (!support.inlineVideo) {
  674. common.css(api, {
  675. position: 'absolute',
  676. top: '-9999em'
  677. });
  678. }
  679. //TODO subtitles support
  680. // IE does not fire delegated timeupdate events
  681. bean.off(api, 'timeupdate', common.noop);
  682. bean.on(api, 'timeupdate', common.noop);
  683. common.prop(api, 'loop', !!(video.loop || conf.loop));
  684. if (typeof volumeLevel !== 'undefined') {
  685. api.volume = volumeLevel;
  686. }
  687. if (player.video.src && video.src != player.video.src || video.index) common.attr(api, 'autoplay', 'autoplay');
  688. api.src = video.src;
  689. api.type = video.type;
  690. self._listeners = listen(api, common.find("source", api).concat(api), video);
  691. // iPad (+others?) demands load()
  692. if (conf.clip.preload != 'none' && video.type != "mpegurl" || !support.zeropreload || !support.dataload) api.load();
  693. if (created || reload) api.load();
  694. if (api.paused && (video.autoplay || conf.autoplay)) api.play();
  695. },
  696. pause: function () {
  697. api.pause();
  698. },
  699. resume: function () {
  700. api.play();
  701. },
  702. speed: function (val) {
  703. api.playbackRate = val;
  704. },
  705. seek: function (time) {
  706. try {
  707. var pausedState = player.paused;
  708. api.currentTime = time;
  709. if (pausedState) api.pause();
  710. } catch (ignored) { }
  711. },
  712. volume: function (level) {
  713. volumeLevel = level;
  714. if (api) {
  715. api.volume = level;
  716. }
  717. },
  718. unload: function () {
  719. common.find('video.fp-engine', root).forEach(common.removeNode);
  720. if (!support.cachedVideoTag) videoTagCache = null;
  721. timer = clearInterval(timer);
  722. var instanceId = root.getAttribute('data-flowplayer-instance-id');
  723. delete api.listeners[instanceId];
  724. api = 0;
  725. if (self._listeners) Object.keys(self._listeners).forEach(function (typ) {
  726. self._listeners[typ].forEach(function (l) {
  727. root.removeEventListener(typ, l, true);
  728. });
  729. });
  730. }
  731. };
  732. function listen(api, sources, video) {
  733. // listen only once
  734. var instanceId = root.getAttribute('data-flowplayer-instance-id');
  735. if (api.listeners && api.listeners.hasOwnProperty(instanceId)) {
  736. api.listeners[instanceId] = video;
  737. return;
  738. }
  739. (api.listeners || (api.listeners = {}))[instanceId] = video;
  740. bean.on(sources, 'error', function (e) {
  741. try {
  742. if (canPlay(e.target.getAttribute('type'))) {
  743. player.trigger("error", [player, { code: 4, video: extend(video, { src: api.src, url: api.src })}]);
  744. }
  745. } catch (er) {
  746. // Most likely: https://bugzilla.mozilla.org/show_bug.cgi?id=208427
  747. }
  748. });
  749. player.on('shutdown', function () {
  750. bean.off(sources);
  751. });
  752. var eventListeners = {};
  753. Object.keys(EVENTS).forEach(function (type) {
  754. var flow = EVENTS[type];
  755. if (!flow) return;
  756. var l = function (e) {
  757. video = api.listeners[instanceId];
  758. if (!e.target || !ClassList(e.target).contains('fp-engine')) return;
  759. if (conf.debug && !/progress/.test(flow)) console.log(type, "->", flow, e);
  760. // no events if player not ready
  761. if (!player.ready && !/ready|error/.test(flow) || !flow || !common.find('video', root).length) { return; }
  762. var arg, vtype;
  763. if (flow === 'unload') { //Call player unload
  764. player.unload();
  765. return;
  766. }
  767. var triggerEvent = function () {
  768. player.trigger(flow, [player, arg]);
  769. };
  770. switch (flow) {
  771. case "ready":
  772. arg = extend(video, {
  773. duration: api.duration,
  774. width: api.videoWidth,
  775. height: api.videoHeight,
  776. url: api.currentSrc,
  777. src: api.currentSrc
  778. });
  779. try {
  780. arg.seekable = !player.live && /mpegurl/i.test(video ? (video.type || '') : '') && api.duration || api.seekable && api.seekable.end(null);
  781. } catch (ignored) { }
  782. // buffer
  783. timer = timer || setInterval(function () {
  784. try {
  785. arg.buffer = api.buffered.end(null);
  786. } catch (ignored) { }
  787. if (arg.buffer) {
  788. if (round(arg.buffer, 1000) < round(arg.duration, 1000) && !arg.buffered) {
  789. player.trigger("buffer", e);
  790. } else if (!arg.buffered) {
  791. arg.buffered = true;
  792. player.trigger("buffer", e).trigger("buffered", e);
  793. clearInterval(timer);
  794. timer = 0;
  795. }
  796. }
  797. }, 250);
  798. if (!player.live && !arg.duration && !support.hlsDuration && type === "loadeddata") {
  799. var durationChanged = function () {
  800. arg.duration = api.duration;
  801. try {
  802. arg.seekable = api.seekable && api.seekable.end(null);
  803. } catch (ignored) { }
  804. triggerEvent();
  805. api.removeEventListener('durationchange', durationChanged);
  806. ClassList(root).remove('is-live');
  807. };
  808. api.addEventListener('durationchange', durationChanged);
  809. // Ugly hack to handle broken Android devices
  810. var timeUpdated = function () {
  811. if (!player.ready && !api.duration) { // No duration even though the video already plays
  812. arg.duration = 0;
  813. ClassList(root).add('is-live'); // Make UI believe it's live
  814. triggerEvent();
  815. }
  816. api.removeEventListener('timeupdate', timeUpdated);
  817. };
  818. api.addEventListener('timeupdate', timeUpdated);
  819. return;
  820. }
  821. break;
  822. case "progress": case "seek":
  823. var dur = player.video.duration;
  824. if (api.currentTime > 0 || player.live) {
  825. arg = Math.max(api.currentTime, 0);
  826. } else if (flow == 'progress') {
  827. return;
  828. }
  829. break;
  830. case "speed":
  831. arg = round(api.playbackRate);
  832. break;
  833. case "volume":
  834. arg = round(api.volume);
  835. break;
  836. case "error":
  837. try {
  838. arg = (e.srcElement || e.originalTarget).error;
  839. arg.video = extend(video, { src: api.src, url: api.src });
  840. } catch (er) {
  841. // Most likely https://bugzilla.mozilla.org/show_bug.cgi?id=208427
  842. return;
  843. }
  844. }
  845. triggerEvent();
  846. };
  847. root.addEventListener(type, l, true);
  848. if (!eventListeners[type]) eventListeners[type] = [];
  849. eventListeners[type].push(l);
  850. });
  851. return eventListeners;
  852. }
  853. };
  854. engine.canPlay = function (type) {
  855. return flowplayer.support.video && canPlay(type);
  856. };
  857. engine.engineName = 'html5';
  858. flowplayer.engines.push(engine);
  859. }, { "../common": 1, "../flowplayer": 18, "bean": 20, "class-list": 22, "extend-object": 26}], 5: [function (_dereq_, module, exports) {
  860. 'use strict';
  861. /* global _gat */
  862. var flowplayer = _dereq_('../flowplayer'),
  863. TYPE_RE = _dereq_('./resolve').TYPE_RE,
  864. scriptjs = _dereq_('scriptjs'),
  865. bean = _dereq_('bean');
  866. flowplayer(function (player, root) {
  867. var id = player.conf.analytics, time = 0, last = 0, timer;
  868. if (id) {
  869. // load Analytics script if needed
  870. if (typeof _gat == 'undefined') scriptjs("//google-analytics.com/ga.js");
  871. var getTracker = function () {
  872. var tracker = _gat._getTracker(id);
  873. tracker._setAllowLinker(true);
  874. return tracker;
  875. };
  876. var track = function track(e, api, video) {
  877. video = video || player.video;
  878. if (time && typeof _gat != 'undefined') {
  879. var tracker = getTracker();
  880. // http://code.google.com/apis/analytics/docs/tracking/eventTrackerGuide.html
  881. tracker._trackEvent(
  882. "Video / Seconds played",
  883. player.engine.engineName + "/" + video.type,
  884. video.title || root.getAttribute("title") || video.src.split("/").slice(-1)[0].replace(TYPE_RE, ''),
  885. Math.round(time / 1000)
  886. );
  887. time = 0;
  888. if (timer) {
  889. clearTimeout(timer);
  890. timer = null;
  891. }
  892. }
  893. };
  894. player.bind("load unload", track).bind("progress", function () {
  895. if (!player.seeking) {
  896. time += last ? (+new Date() - last) : 0;
  897. last = +new Date();
  898. }
  899. if (!timer) {
  900. timer = setTimeout(function () {
  901. timer = null;
  902. var tracker = getTracker();
  903. tracker._trackEvent('Flowplayer heartbeat', 'Heartbeat', '', 0, true);
  904. }, 10 * 60 * 1000); // heartbeat every 10 minutes
  905. }
  906. }).bind("pause", function () {
  907. last = 0;
  908. });
  909. player.bind('shutdown', function () {
  910. bean.off(window, 'unload', track);
  911. });
  912. bean.on(window, 'unload', track);
  913. }
  914. });
  915. }, { "../flowplayer": 18, "./resolve": 13, "bean": 20, "scriptjs": 29}], 6: [function (_dereq_, module, exports) {
  916. 'use strict';
  917. var flowplayer = _dereq_('../flowplayer'),
  918. ClassList = _dereq_('class-list'),
  919. common = _dereq_('../common'),
  920. bean = _dereq_('bean');
  921. flowplayer(function (player, root) {
  922. var CUE_RE = / ?cue\d+ ?/;
  923. var lastTime = 0, cuepointsDisabled = false;
  924. function setClass(index) {
  925. root.className = root.className.replace(CUE_RE, " ");
  926. if (index >= 0) ClassList(root).add('cue' + index);
  927. }
  928. var segments = {}, lastFiredSegment = -0.125;
  929. var fire = function (cue) {
  930. var idx = player.cuepoints.indexOf(cue);
  931. if (!isNaN(cue)) cue = { time: cue };
  932. cue.index = idx;
  933. setClass(idx);
  934. player.trigger('cuepoint', [player, cue]);
  935. };
  936. player.on("progress", function (e, api, time) {
  937. if (cuepointsDisabled) return;
  938. var segment = segmentForCue(time);
  939. while (lastFiredSegment < segment) {
  940. lastFiredSegment += 0.125;
  941. if (!segments[lastFiredSegment]) continue;
  942. segments[lastFiredSegment].forEach(fire);
  943. }
  944. }).on("unload", setClass)
  945. .on('beforeseek', function (ev) {
  946. setTimeout(function () {
  947. if (!ev.defaultPrevented) cuepointsDisabled = true;
  948. });
  949. }).on("seek", function (ev, api, time) {
  950. setClass();
  951. lastFiredSegment = segmentForCue(time || 0) - 0.125;
  952. cuepointsDisabled = false;
  953. if (!time && segments[0]) segments[0].forEach(fire);
  954. }).on('ready', function (e, api, video) {
  955. lastFiredSegment = -0.125;
  956. var cues = video.cuepoints || player.conf.cuepoints || [];
  957. player.setCuepoints(cues);
  958. }).on('finish', function () {
  959. lastFiredSegment = -0.125;
  960. });
  961. if (player.conf.generate_cuepoints) {
  962. player.bind("load", function () {
  963. // clean up cuepoint elements of previous playlist items
  964. common.find('.fp-cuepoint', root).forEach(common.removeNode);
  965. });
  966. }
  967. /**
  968. * API
  969. */
  970. player.setCuepoints = function (cues) {
  971. player.cuepoints = [];
  972. segments = {};
  973. cues.forEach(player.addCuepoint);
  974. return player;
  975. };
  976. player.addCuepoint = function (cue) {
  977. if (!player.cuepoints) player.cuepoints = [];
  978. var segment = segmentForCue(cue);
  979. if (!segments[segment]) segments[segment] = [];
  980. segments[segment].push(cue);
  981. player.cuepoints.push(cue);
  982. if (player.conf.generate_cuepoints && cue.visible !== false) {
  983. var duration = player.video.duration,
  984. timeline = common.find('.fp-timeline', root)[0];
  985. common.css(timeline, "overflow", "visible");
  986. var time = cue.time || cue;
  987. if (time < 0) time = duration + time;
  988. var el = common.createElement('a', { className: 'fp-cuepoint fp-cuepoint' + (player.cuepoints.length - 1) });
  989. common.css(el, "left", (time / duration * 100) + "%");
  990. timeline.appendChild(el);
  991. bean.on(el, 'mousedown', function (e) {
  992. e.preventDefault();
  993. e.stopPropagation();
  994. player.seek(time);
  995. });
  996. }
  997. return player;
  998. };
  999. player.removeCuepoint = function (cue) {
  1000. var idx = player.cuepoints.indexOf(cue),
  1001. segment = segmentForCue(cue);
  1002. if (idx === -1) return;
  1003. player.cuepoints = player.cuepoints.slice(0, idx).concat(player.cuepoints.slice(idx + 1));
  1004. var sIdx = segments[segment].indexOf(cue);
  1005. if (sIdx === -1) return;
  1006. segments[segment] = segments[segment].slice(0, sIdx).concat(segments[segment].slice(sIdx + 1));
  1007. return player;
  1008. };
  1009. function segmentForCue(cue) {
  1010. var time = cue && !isNaN(cue.time) ? cue.time : cue;
  1011. if (time < 0) time = player.video.duration + time;
  1012. return Math.round(time / 0.125) * 0.125;
  1013. }
  1014. });
  1015. }, { "../common": 1, "../flowplayer": 18, "bean": 20, "class-list": 22}], 7: [function (_dereq_, module, exports) {
  1016. 'use strict';
  1017. var flowplayer = _dereq_('../flowplayer'),
  1018. bean = _dereq_('bean'),
  1019. common = _dereq_('../common'),
  1020. isObject = _dereq_('is-object'),
  1021. extend = _dereq_('extend-object'),
  1022. ClassList = _dereq_('class-list');
  1023. flowplayer(function (player, root) {
  1024. // no embedding
  1025. if (player.conf.embed === false) return;
  1026. var conf = player.conf,
  1027. ui = common.find('.fp-ui', root)[0],
  1028. trigger = common.createElement('a', { "class": "fp-embed", title: 'Copy to your site' }),
  1029. target = common.createElement('div', { 'class': 'fp-embed-code' }, '<label>Paste this HTML code on your site to embed.</label><textarea></textarea>'),
  1030. area = common.find("textarea", target)[0];
  1031. ui.appendChild(trigger);
  1032. ui.appendChild(target);
  1033. player.embedCode = function () {
  1034. var embedConf = player.conf.embed || {},
  1035. video = player.video;
  1036. if (embedConf.iframe) {
  1037. var src = player.conf.embed.iframe,
  1038. width = embedConf.width || video.width || common.width(root),
  1039. height = embedConf.height || video.height || common.height(root);
  1040. return '<iframe src="' + player.conf.embed.iframe + '" allowfullscreen style="width:' + width + ';height:' + height + ';border:none;"></iframe>';
  1041. }
  1042. var props = ['ratio', 'rtmp', 'live', 'bufferTime', 'origin', 'analytics', 'key', 'subscribe', 'swf', 'swfHls', 'embed', 'adaptiveRatio', 'logo'];
  1043. if (embedConf.playlist) props.push('playlist');
  1044. var c = common.pick(player.conf, props);
  1045. if (c.logo) c.logo = common.createElement('img', { src: c.logo }).src;
  1046. if (!embedConf.playlist || !player.conf.playlist.length) c.clip = extend({}, player.conf.clip, common.pick(player.video, ['sources']));
  1047. var script = "var w=window,d=document,e;w._fpes||(w._fpes=[],w.addEventListener(\"load\",function(){var s=d.createElement(\"script\");s.src=\"//embed.flowplayer.org/6.0.5/embed.min.js\",d.body.appendChild(s)})),e=[].slice.call(d.getElementsByTagName(\"script\"),-1)[0].parentNode,w._fpes.push({e:e,l:\"$library\",c:$conf});\n".replace('$conf', JSON.stringify(c)).replace('$library', embedConf.library || '');
  1048. return '<a href="$href">Watch video!\n<script>$script</script></a>'.replace('$href', player.conf.origin || window.location.href).replace('$script', script);
  1049. };
  1050. fptip(root, ".fp-embed", "is-embedding");
  1051. bean.on(root, 'click', '.fp-embed-code textarea', function () {
  1052. area.select();
  1053. });
  1054. bean.on(root, 'click', '.fp-embed', function () {
  1055. area.textContent = player.embedCode().replace(/(\r\n|\n|\r)/gm, "");
  1056. area.focus();
  1057. area.select();
  1058. });
  1059. });
  1060. var fptip = function (root, trigger, active) {
  1061. function close() {
  1062. rootClasses.remove(active);
  1063. bean.off(document, '.st');
  1064. }
  1065. var rootClasses = ClassList(root);
  1066. bean.on(root, 'click', trigger || 'a', function (e) {
  1067. e.preventDefault();
  1068. rootClasses.toggle(active);
  1069. if (rootClasses.contains(active)) {
  1070. bean.on(document, 'keydown.st', function (e) {
  1071. if (e.which == 27) close();
  1072. });
  1073. bean.on(document, 'click.st', function (e) {
  1074. if (!common.hasParent(e.target, '.' + active)) close();
  1075. });
  1076. }
  1077. });
  1078. };
  1079. }, { "../common": 1, "../flowplayer": 18, "bean": 20, "class-list": 22, "extend-object": 26, "is-object": 28}], 8: [function (_dereq_, module, exports) {
  1080. 'use strict';
  1081. /* global jQuery */
  1082. /**
  1083. * Mimimal jQuery-like event emitter implementation
  1084. */
  1085. module.exports = function (obj, elem) {
  1086. if (!elem) elem = document.createElement('div'); //In this case we always want to trigger (Custom)Events on dom element
  1087. var handlers = {}, eventArguments = {};
  1088. var listenEvent = function (type, hndlr, disposable) {
  1089. var actualEvent = type.split('.')[0]; //Strip namespace
  1090. var internalHandler = function (ev) {
  1091. if (disposable) {
  1092. elem.removeEventListener(actualEvent, internalHandler);
  1093. handlers[type].splice(handlers[type].indexOf(internalHandler), 1);
  1094. }
  1095. var args = [ev].concat(eventArguments[ev.timeStamp + ev.type] || []);
  1096. if (hndlr) hndlr.apply(undefined, args);
  1097. };
  1098. elem.addEventListener(actualEvent, internalHandler);
  1099. //Store handlers for unbinding
  1100. if (!handlers[type]) handlers[type] = [];
  1101. handlers[type].push(internalHandler);
  1102. };
  1103. obj.on = obj.bind = function (typ, hndlr) {
  1104. var types = typ.split(' ');
  1105. types.forEach(function (type) {
  1106. listenEvent(type, hndlr);
  1107. });
  1108. return obj; //for chaining
  1109. };
  1110. obj.one = function (typ, hndlr) {
  1111. var types = typ.split(' ');
  1112. types.forEach(function (type) {
  1113. listenEvent(type, hndlr, true);
  1114. });
  1115. return obj;
  1116. };
  1117. // Function to check if all items in toBeContained array are in the containing array
  1118. var containsAll = function (containing, toBeContained) {
  1119. return toBeContained.filter(function (i) {
  1120. return containing.indexOf(i) === -1;
  1121. }).length === 0;
  1122. };
  1123. obj.off = obj.unbind = function (typ) {
  1124. var types = typ.split(' ');
  1125. types.forEach(function (type) {
  1126. var typeNameSpaces = type.split('.').slice(1),
  1127. actualType = type.split('.')[0];
  1128. Object.keys(handlers).filter(function (t) {
  1129. var handlerNamespaces = t.split('.').slice(1);
  1130. return (!actualType || t.indexOf(actualType) === 0) && containsAll(handlerNamespaces, typeNameSpaces);
  1131. }).forEach(function (t) {
  1132. var registererHandlers = handlers[t],
  1133. actualEvent = t.split('.')[0];
  1134. registererHandlers.forEach(function (hndlr) {
  1135. elem.removeEventListener(actualEvent, hndlr);
  1136. registererHandlers.splice(registererHandlers.indexOf(hndlr), 1);
  1137. });
  1138. });
  1139. });
  1140. return obj;
  1141. };
  1142. obj.trigger = function (typ, args, returnEvent) {
  1143. if (!typ) return;
  1144. args = (args || []).length ? args || [] : [args];
  1145. var event = document.createEvent('Event'), typStr;
  1146. typStr = typ.type || typ;
  1147. event.initEvent(typStr, false, true);
  1148. if (Object.defineProperty) event.preventDefault = function () {
  1149. Object.defineProperty(this, 'defaultPrevented', { get: function () { return true; } });
  1150. };
  1151. eventArguments[event.timeStamp + event.type] = args;
  1152. elem.dispatchEvent(event);
  1153. return returnEvent ? event : obj;
  1154. };
  1155. };
  1156. module.exports.EVENTS = [
  1157. 'beforeseek',
  1158. 'disable',
  1159. 'error',
  1160. 'finish',
  1161. 'fullscreen',
  1162. 'fullscreen-exit',
  1163. 'load',
  1164. 'mute',
  1165. 'pause',
  1166. 'progress',
  1167. 'ready',
  1168. 'resume',
  1169. 'seek',
  1170. 'speed',
  1171. 'stop',
  1172. 'unload',
  1173. 'volume',
  1174. 'boot',
  1175. 'shutdown'
  1176. ];
  1177. }, {}], 9: [function (_dereq_, module, exports) {
  1178. 'use strict';
  1179. var flowplayer = _dereq_('../flowplayer'),
  1180. bean = _dereq_('bean'),
  1181. ClassList = _dereq_('class-list'),
  1182. extend = _dereq_('extend-object'),
  1183. common = _dereq_('../common'),
  1184. VENDOR = flowplayer.support.browser.mozilla ? "moz" : "webkit",
  1185. FS_ENTER = "fullscreen",
  1186. FS_EXIT = "fullscreen-exit",
  1187. FULL_PLAYER,
  1188. FS_SUPPORT = flowplayer.support.fullscreen,
  1189. FS_NATIVE_SUPPORT = typeof document.exitFullscreen == 'function',
  1190. ua = navigator.userAgent.toLowerCase(),
  1191. IS_SAFARI = /(safari)[ \/]([\w.]+)/.exec(ua) && !/(chrome)[ \/]([\w.]+)/.exec(ua);
  1192. // esc button
  1193. bean.on(document, "fullscreenchange.ffscr webkitfullscreenchange.ffscr mozfullscreenchange.ffscr MSFullscreenChange.ffscr", function (e) {
  1194. var el = document.webkitCurrentFullScreenElement || document.mozFullScreenElement || document.fullscreenElement || document.msFullscreenElement || e.target;
  1195. if (!FULL_PLAYER && (!el.parentNode || !el.parentNode.getAttribute('data-flowplayer-instance-id'))) return;
  1196. var player = FULL_PLAYER || flowplayer(el.parentNode);
  1197. if (el && !FULL_PLAYER) {
  1198. FULL_PLAYER = player.trigger(FS_ENTER, [el]);
  1199. } else {
  1200. FULL_PLAYER.trigger(FS_EXIT, [FULL_PLAYER]);
  1201. FULL_PLAYER = null;
  1202. }
  1203. });
  1204. flowplayer(function (player, root) {
  1205. var wrapper = common.createElement('div', { className: 'fp-player' });
  1206. Array.prototype.map.call(root.children, common.identity).forEach(function (el) {
  1207. if (common.matches(el, '.fp-ratio,script')) return;
  1208. wrapper.appendChild(el);
  1209. });
  1210. root.appendChild(wrapper);
  1211. if (!player.conf.fullscreen) return;
  1212. var win = window,
  1213. scrollY,
  1214. scrollX,
  1215. rootClasses = ClassList(root);
  1216. player.isFullscreen = false;
  1217. player.fullscreen = function (flag) {
  1218. if (player.disabled) return;
  1219. if (flag === undefined) flag = !player.isFullscreen;
  1220. if (flag) {
  1221. scrollY = win.scrollY;
  1222. scrollX = win.scrollX;
  1223. }
  1224. if (FS_SUPPORT) {
  1225. if (flag) {
  1226. ['requestFullScreen', 'webkitRequestFullScreen', 'mozRequestFullScreen', 'msRequestFullscreen'].forEach(function (fName) {
  1227. if (typeof wrapper[fName] === 'function') {
  1228. wrapper[fName](Element.ALLOW_KEYBOARD_INPUT);
  1229. if (IS_SAFARI && !document.webkitCurrentFullScreenElement && !document.mozFullScreenElement) { // Element.ALLOW_KEYBOARD_INPUT not allowed
  1230. wrapper[fName]();
  1231. }
  1232. return false;
  1233. }
  1234. });
  1235. } else {
  1236. ['exitFullscreen', 'webkitCancelFullScreen', 'mozCancelFullScreen', 'msExitFullscreen'].forEach(function (fName) {
  1237. if (typeof document[fName] === 'function') {
  1238. document[fName]();
  1239. return false;
  1240. }
  1241. });
  1242. }
  1243. } else {
  1244. player.trigger(flag ? FS_ENTER : FS_EXIT, [player]);
  1245. }
  1246. return player;
  1247. };
  1248. var lastClick;
  1249. player.on("mousedown.fs", function () {
  1250. if (+new Date() - lastClick < 150 && player.ready) player.fullscreen();
  1251. lastClick = +new Date();
  1252. });
  1253. player.on(FS_ENTER, function (e) {
  1254. rootClasses.add("is-fullscreen");
  1255. if (!FS_SUPPORT) common.css(root, 'position', 'fixed');
  1256. player.isFullscreen = true;
  1257. }).on(FS_EXIT, function (e) {
  1258. var oldOpacity;
  1259. if (!FS_SUPPORT && player.engine === "html5") {
  1260. oldOpacity = root.css('opacity') || '';
  1261. common.css(root, 'opacity', 0);
  1262. }
  1263. if (!FS_SUPPORT) common.css(root, 'position', '');
  1264. rootClasses.remove("is-fullscreen");
  1265. if (!FS_SUPPORT && player.engine === "html5") setTimeout(function () { root.css('opacity', oldOpacity); });
  1266. player.isFullscreen = false;
  1267. win.scrollTo(scrollX, scrollY);
  1268. }).on('unload', function () {
  1269. if (player.isFullscreen) player.fullscreen();
  1270. });
  1271. player.on('shutdown', function () {
  1272. FULL_PLAYER = null;
  1273. });
  1274. });
  1275. }, { "../common": 1, "../flowplayer": 18, "bean": 20, "class-list": 22, "extend-object": 26}], 10: [function (_dereq_, module, exports) {
  1276. 'use strict';
  1277. var flowplayer = _dereq_('../flowplayer'),
  1278. bean = _dereq_('bean'),
  1279. focused,
  1280. focusedRoot,
  1281. IS_HELP = "is-help",
  1282. common = _dereq_('../common'),
  1283. ClassList = _dereq_('class-list');
  1284. // keyboard. single global listener
  1285. bean.on(document, "keydown.fp", function (e) {
  1286. var el = focused,
  1287. metaKeyPressed = e.ctrlKey || e.metaKey || e.altKey,
  1288. key = e.which,
  1289. conf = el && el.conf,
  1290. focusedRootClasses = focusedRoot && ClassList(focusedRoot);
  1291. if (!el || !conf.keyboard || el.disabled) return;
  1292. // help dialog (shift key not truly required)
  1293. if ([63, 187, 191].indexOf(key) != -1) {
  1294. focusedRootClasses.toggle(IS_HELP);
  1295. return false;
  1296. }
  1297. // close help / unload
  1298. if (key == 27 && focusedRootClasses.contains(IS_HELP)) {
  1299. focusedRootClasses.toggle(IS_HELP);
  1300. return false;
  1301. }
  1302. if (!metaKeyPressed && el.ready) {
  1303. e.preventDefault();
  1304. // slow motion / fast forward
  1305. if (e.shiftKey) {
  1306. if (key == 39) el.speed(true);
  1307. else if (key == 37) el.speed(false);
  1308. return;
  1309. }
  1310. // 1, 2, 3, 4 ..
  1311. if (key < 58 && key > 47) return el.seekTo(key - 48);
  1312. switch (key) {
  1313. case 38: case 75: el.volume(el.volumeLevel + 0.15); break; // volume up
  1314. case 40: case 74: el.volume(el.volumeLevel - 0.15); break; // volume down
  1315. case 39: case 76: el.seeking = true; el.seek(true); break; // forward
  1316. case 37: case 72: el.seeking = true; el.seek(false); break; // backward
  1317. case 190: el.seekTo(); break; // to last seek position
  1318. case 32: el.toggle(); break; // spacebar
  1319. case 70: if (conf.fullscreen) el.fullscreen(); break; // toggle fullscreen
  1320. case 77: el.mute(); break; // mute
  1321. case 81: el.unload(); break; // unload/stop
  1322. }
  1323. }
  1324. });
  1325. flowplayer(function (api, root) {
  1326. // no keyboard configured
  1327. if (!api.conf.keyboard) return;
  1328. // hover
  1329. bean.on(root, "mouseenter mouseleave", function (e) {
  1330. focused = !api.disabled && e.type == 'mouseover' ? api : 0;
  1331. if (focused) focusedRoot = root;
  1332. });
  1333. var speedhelp = flowplayer.support.video && api.conf.engine !== "flash" &&
  1334. !!document.createElement('video').playbackRate ?
  1335. '<p><em>shift</em> + <em>&#8592;</em><em>&#8594;</em>slower / faster</p>' : '';
  1336. // TODO: add to player-layout.html
  1337. root.appendChild(common.createElement('div', { className: 'fp-help' }, '\
  1338. <a class="fp-close"></a>\
  1339. <div class="fp-help-section fp-help-basics">\
  1340. <p><em>space</em>play / pause</p>\
  1341. <p><em>q</em>unload | stop</p>\
  1342. <p><em>f</em>fullscreen</p>' + speedhelp + '\
  1343. </div>\
  1344. <div class="fp-help-section">\
  1345. <p><em>&#8593;</em><em>&#8595;</em>volume</p>\
  1346. <p><em>m</em>mute</p>\
  1347. </div>\
  1348. <div class="fp-help-section">\
  1349. <p><em>&#8592;</em><em>&#8594;</em>seek</p>\
  1350. <p><em>&nbsp;. </em>seek to previous\
  1351. </p><p><em>1</em><em>2</em>&hellip; <em>6</em> seek to 10%, 20% &hellip; 60% </p>\
  1352. </div>\
  1353. '));
  1354. if (api.conf.tooltip) {
  1355. var ui = common.find('.fp-ui', root)[0];
  1356. ui.setAttribute('title', 'Hit ? for help');
  1357. bean.one(root, "mouseout.tip", '.fp-ui', function () {
  1358. ui.removeAttribute('title');
  1359. });
  1360. }
  1361. bean.on(root, 'click', '.fp-close', function () {
  1362. ClassList(root).toggle(IS_HELP);
  1363. });
  1364. api.bind('shutdown', function () {
  1365. if (focusedRoot == root) focusedRoot = null;
  1366. });
  1367. });
  1368. }, { "../common": 1, "../flowplayer": 18, "bean": 20, "class-list": 22}], 11: [function (_dereq_, module, exports) {
  1369. 'use strict';
  1370. var flowplayer = _dereq_('../flowplayer'),
  1371. isIeMobile = /IEMobile/.test(window.navigator.userAgent),
  1372. ClassList = _dereq_('class-list'),
  1373. common = _dereq_('../common'),
  1374. bean = _dereq_('bean'),
  1375. format = _dereq_('./ui').format,
  1376. UA = window.navigator.userAgent;
  1377. if (flowplayer.support.touch || isIeMobile) {
  1378. flowplayer(function (player, root) {
  1379. var isAndroid = /Android/.test(UA) && !/Firefox/.test(UA) && !/Opera/.test(UA),
  1380. isSilk = /Silk/.test(UA),
  1381. androidVer = isAndroid ? parseFloat(/Android\ (\d\.\d)/.exec(UA)[1], 10) : 0,
  1382. rootClasses = ClassList(root);
  1383. // custom load for android
  1384. if (isAndroid && !isIeMobile) {
  1385. if (!/Chrome/.test(UA) && androidVer < 4) {
  1386. var originalLoad = player.load;
  1387. player.load = function (video, callback) {
  1388. var ret = originalLoad.apply(player, arguments);
  1389. player.trigger('ready', [player, player.video]);
  1390. return ret;
  1391. };
  1392. }
  1393. var timer, currentTime = 0;
  1394. var resumeTimer = function (api) {
  1395. timer = setInterval(function () {
  1396. api.video.time = ++currentTime;
  1397. api.trigger('progress', [api, currentTime]);
  1398. }, 1000);
  1399. };
  1400. player.bind('ready pause unload', function () {
  1401. if (timer) {
  1402. clearInterval(timer);
  1403. timer = null;
  1404. }
  1405. });
  1406. player.bind('ready', function () {
  1407. currentTime = 0;
  1408. });
  1409. player.bind('resume', function (ev, api) {
  1410. if (!api.live) return;
  1411. if (currentTime) { return resumeTimer(api); }
  1412. player.one('progress', function (ev, api, t) {
  1413. if (t === 0) { // https://github.com/flowplayer/flowplayer/issues/727
  1414. resumeTimer(api);
  1415. }
  1416. });
  1417. });
  1418. }
  1419. // hide volume
  1420. if (!flowplayer.support.volume) {
  1421. rootClasses.add("no-volume");
  1422. rootClasses.add("no-mute");
  1423. }
  1424. rootClasses.add("is-touch");
  1425. if (player.sliders && player.sliders.timeline) player.sliders.timeline.disableAnimation();
  1426. if (!flowplayer.support.inlineVideo || player.conf.native_fullscreen) player.conf.nativesubtitles = true;
  1427. // fake mouseover effect with click
  1428. var hasMoved = false;
  1429. bean.on(root, 'touchmove', function () {
  1430. hasMoved = true;
  1431. });
  1432. bean.on(root, 'touchend click', function (e) {
  1433. if (hasMoved) { //not intentional, most likely scrolling
  1434. hasMoved = false;
  1435. return;
  1436. }
  1437. if (player.playing && !rootClasses.contains("is-mouseover")) {
  1438. rootClasses.add("is-mouseover");
  1439. rootClasses.remove("is-mouseout");
  1440. e.preventDefault();
  1441. e.stopPropagation();
  1442. return;
  1443. }
  1444. if (!player.playing && !player.splash && rootClasses.contains('is-mouseout') && !rootClasses.contains('is-mouseover')) {
  1445. setTimeout(function () {
  1446. if (!player.playing && !player.splash) {
  1447. player.resume();
  1448. }
  1449. }, 400);
  1450. }
  1451. });
  1452. // native fullscreen
  1453. if (player.conf.native_fullscreen && typeof document.createElement('video').webkitEnterFullScreen === 'function') {
  1454. player.fullscreen = function () {
  1455. var video = common.find('video.fp-engine', root)[0];
  1456. video.webkitEnterFullScreen();
  1457. bean.one(video, 'webkitendfullscreen', function () {
  1458. common.prop(video, 'controls', true);
  1459. common.prop(video, 'controls', false);
  1460. });
  1461. };
  1462. }
  1463. // Android browser gives video.duration == 1 until second 'timeupdate' event
  1464. if (isAndroid || isSilk) player.bind("ready", function () {
  1465. var video = common.find('video.fp-engine', root)[0];
  1466. bean.one(video, 'canplay', function () {
  1467. video.play();
  1468. });
  1469. video.play();
  1470. player.bind("progress.dur", function () {
  1471. var duration = video.duration;
  1472. if (duration !== 1) {
  1473. player.video.duration = duration;
  1474. common.find(".fp-duration", root)[0].innerHTML = format(duration);
  1475. player.unbind("progress.dur");
  1476. }
  1477. });
  1478. });
  1479. });
  1480. }
  1481. }, { "../common": 1, "../flowplayer": 18, "./ui": 17, "bean": 20, "class-list": 22}], 12: [function (_dereq_, module, exports) {
  1482. 'use strict';
  1483. var flowplayer = _dereq_('../flowplayer'),
  1484. extend = _dereq_('extend-object'),
  1485. bean = _dereq_('bean'),
  1486. ClassList = _dereq_('class-list'),
  1487. common = _dereq_('../common'),
  1488. Resolve = _dereq_('./resolve'),
  1489. resolver = new Resolve(),
  1490. $ = window.jQuery,
  1491. externalRe = /^#/;
  1492. flowplayer(function (player, root) {
  1493. var conf = extend({ active: 'is-active', advance: true, query: ".fp-playlist a" }, player.conf),
  1494. klass = conf.active, rootClasses = ClassList(root);
  1495. // getters
  1496. function els() {
  1497. return common.find(conf.query, queryRoot());
  1498. }
  1499. function queryRoot() {
  1500. if (externalRe.test(conf.query)) return;
  1501. return root;
  1502. }
  1503. function active() {
  1504. return common.find(conf.query + "." + klass, queryRoot());
  1505. }
  1506. player.play = function (i) {
  1507. if (i === undefined) return player.resume();
  1508. if (typeof i === 'number' && !player.conf.playlist[i]) return player;
  1509. else if (typeof i != 'number') return player.load.apply(null, arguments);
  1510. var arg = extend({ index: i }, player.conf.playlist[i]);
  1511. if (i === player.video.index) return player.load(arg, function () { player.resume(); });
  1512. player.off('resume.fromfirst'); // Don't start from beginning if clip explicitely chosen
  1513. player.load(arg, function () {
  1514. player.video.index = i;
  1515. });
  1516. return player;
  1517. };
  1518. player.next = function (e) {
  1519. if (e) e.preventDefault();
  1520. var current = player.video.index;
  1521. if (current != -1) {
  1522. current = current === player.conf.playlist.length - 1 ? 0 : current + 1;
  1523. player.play(current);
  1524. }
  1525. return player;
  1526. };
  1527. player.prev = function (e) {
  1528. if (e) e.preventDefault();
  1529. var current = player.video.index;
  1530. if (current != -1) {
  1531. current = current === 0 ? player.conf.playlist.length - 1 : current - 1;
  1532. player.play(current);
  1533. }
  1534. return player;
  1535. };
  1536. player.setPlaylist = function (items) {
  1537. player.conf.playlist = items;
  1538. delete player.video.index;
  1539. generatePlaylist();
  1540. return player;
  1541. };
  1542. player.addPlaylistItem = function (item) {
  1543. return player.setPlaylist(player.conf.playlist.concat([item]));
  1544. };
  1545. player.removePlaylistItem = function (idx) {
  1546. var pl = player.conf.playlist;
  1547. return player.setPlaylist(pl.slice(0, idx).concat(pl.slice(idx + 1)));
  1548. };
  1549. bean.on(root, 'click', '.fp-next', player.next);
  1550. bean.on(root, 'click', '.fp-prev', player.prev);
  1551. if (conf.advance) {
  1552. player.off("finish.pl").on("finish.pl", function (e, player) {
  1553. // clip looping
  1554. if (player.video.loop) return player.seek(0, function () { player.resume(); });
  1555. // next clip is found or loop
  1556. var next = player.video.index >= 0 ? player.video.index + 1 : undefined;
  1557. if (next < player.conf.playlist.length || conf.loop) {
  1558. next = next === player.conf.playlist.length ? 0 : next;
  1559. rootClasses.remove('is-finished');
  1560. setTimeout(function () { // Let other finish callbacks fire first
  1561. player.play(next);
  1562. });
  1563. // stop to last clip, play button starts from 1:st clip
  1564. } else {
  1565. // If we have multiple items in playlist, start from first
  1566. if (player.conf.playlist.length > 1) player.one("resume.fromfirst", function () {
  1567. player.play(0);
  1568. return false;
  1569. });
  1570. }
  1571. });
  1572. }
  1573. function generatePlaylist() {
  1574. var plEl = common.find('.fp-playlist', root)[0];
  1575. if (!plEl) {
  1576. plEl = common.createElement('div', { className: 'fp-playlist' });
  1577. var cntrls = common.find('.fp-next,.fp-prev', root);
  1578. if (!cntrls.length) common.insertAfter(root, common.find('video', root)[0], plEl);
  1579. else cntrls[0].parentElement.insertBefore(plEl, cntrls[0]);
  1580. }
  1581. plEl.innerHTML = '';
  1582. if (player.conf.playlist[0].length) { // FP5 style playlist
  1583. player.conf.playlist = player.conf.playlist.map(function (itm) {
  1584. if (typeof itm === 'string') {
  1585. var type = itm.split(Resolve.TYPE_RE)[1];
  1586. return {
  1587. sources: [{
  1588. type: type.toLowerCase() === 'm3u8' ? 'application/x-mpegurl' : 'video/' + type,
  1589. src: itm
  1590. }]
  1591. };
  1592. }
  1593. return {
  1594. sources: itm.map(function (src) {
  1595. var s = {};
  1596. Object.keys(src).forEach(function (k) {
  1597. s.type = /mpegurl/i.test(k) ? 'application/x-mpegurl' : 'video/' + k;
  1598. s.src = src[k];
  1599. });
  1600. return s;
  1601. })
  1602. };
  1603. });
  1604. }
  1605. player.conf.playlist.forEach(function (item, i) {
  1606. var href = item.sources[0].src;
  1607. plEl.appendChild(common.createElement('a', {
  1608. href: href,
  1609. 'data-index': i
  1610. }));
  1611. });
  1612. }
  1613. var playlistInitialized = false;
  1614. if (player.conf.playlist.length) { // playlist configured by javascript, generate playlist
  1615. playlistInitialized = true;
  1616. generatePlaylist();
  1617. if (!player.conf.clip || !player.conf.clip.sources.length) {
  1618. player.conf.clip = player.conf.playlist[player.conf.startIndex || 0];
  1619. }
  1620. }
  1621. if (els().length && !playlistInitialized) { //generate playlist from existing elements
  1622. player.conf.playlist = [];
  1623. delete player.conf.startIndex;
  1624. els().forEach(function (el) {
  1625. var src = el.href;
  1626. el.setAttribute('data-index', player.conf.playlist.length);
  1627. var itm = resolver.resolve(src, player.conf.clip.sources);
  1628. if ($) {
  1629. extend(itm, $(el).data());
  1630. }
  1631. player.conf.playlist.push(itm);
  1632. });
  1633. }
  1634. /* click -> play */
  1635. bean.on(externalRe.test(conf.query) ? document : root, "click", conf.query, function (e) {
  1636. e.preventDefault();
  1637. var el = e.currentTarget;
  1638. var toPlay = Number(el.getAttribute('data-index'));
  1639. if (toPlay != -1) {
  1640. player.play(toPlay);
  1641. }
  1642. });
  1643. // highlight
  1644. function videoIndex(video) {
  1645. if (typeof video.index !== 'undefined') return video.index;
  1646. if (typeof player.video.index !== 'undefined') return player.video.index;
  1647. return player.conf.startIndex || 0;
  1648. }
  1649. player.on("load", function (e, api, video) {
  1650. if (!player.conf.playlist.length) return;
  1651. var prev = active()[0],
  1652. prevIndex = prev && prev.getAttribute('data-index'),
  1653. index = video.index = videoIndex(video),
  1654. el = common.find(conf.query + '[data-index="' + index + '"]', queryRoot())[0],
  1655. is_last = index == player.conf.playlist.length - 1;
  1656. if (prev) ClassList(prev).remove(klass);
  1657. if (el) ClassList(el).add(klass);
  1658. // index
  1659. rootClasses.remove("video" + prevIndex);
  1660. rootClasses.add("video" + index);
  1661. common.toggleClass(root, "last-video", is_last);
  1662. // video properties
  1663. video.index = api.video.index = index;
  1664. video.is_last = api.video.is_last = is_last;
  1665. // without namespace callback called only once. unknown rason.
  1666. }).on("unload.pl", function () {
  1667. if (!player.conf.playlist.length) return;
  1668. active().forEach(function (el) {
  1669. ClassList(el).toggle(klass);
  1670. });
  1671. player.conf.playlist.forEach(function (itm, i) {
  1672. rootClasses.remove('video' + i);
  1673. });
  1674. });
  1675. if (player.conf.playlist.length) {
  1676. // disable single clip looping
  1677. player.conf.loop = false;
  1678. }
  1679. });
  1680. }, { "../common": 1, "../flowplayer": 18, "./resolve": 13, "bean": 20, "class-list": 22, "extend-object": 26}], 13: [function (_dereq_, module, exports) {
  1681. 'use strict';
  1682. var TYPE_RE = /\.(\w{3,4})(\?.*)?$/i,
  1683. extend = _dereq_('extend-object');
  1684. function parseSource(el) {
  1685. var src = el.attr("src"),
  1686. type = el.attr("type") || "",
  1687. suffix = src.split(TYPE_RE)[1];
  1688. type = type.toLowerCase();
  1689. return extend(el.data(), { src: src, suffix: suffix || type, type: type || suffix });
  1690. }
  1691. function getType(typ) {
  1692. if (/mpegurl/i.test(typ)) return 'application/x-mpegurl';
  1693. return 'video/' + typ;
  1694. }
  1695. /* Resolves video object from initial configuration and from load() method */
  1696. module.exports = function URLResolver() {
  1697. var self = this;
  1698. self.sourcesFromVideoTag = function (videoTag, $) {
  1699. /* global $ */
  1700. var sources = [];
  1701. // initial sources
  1702. $("source", videoTag).each(function () {
  1703. sources.push(parseSource($(this)));
  1704. });
  1705. if (!sources.length && videoTag.length) sources.push(parseSource(videoTag));
  1706. return sources;
  1707. };
  1708. self.resolve = function (video, sources) {
  1709. if (!video) return { sources: sources };
  1710. if (typeof video == 'string') {
  1711. video = { src: video, sources: [] };
  1712. video.sources = (sources || []).map(function (source) {
  1713. var suffix = source.src.split(TYPE_RE)[1];
  1714. return { type: source.type, src: video.src.replace(TYPE_RE, '.' + suffix + "$2") };
  1715. });
  1716. }
  1717. if (video instanceof Array) {
  1718. video = {
  1719. sources: video.map(function (src) {
  1720. if (src.type && src.src) return src;
  1721. return Object.keys(src).reduce(function (m, typ) {
  1722. return extend(m, {
  1723. type: getType(typ),
  1724. src: src[typ]
  1725. });
  1726. }, {});
  1727. })
  1728. };
  1729. }
  1730. return video;
  1731. };
  1732. };
  1733. module.exports.TYPE_RE = TYPE_RE;
  1734. }, { "extend-object": 26}], 14: [function (_dereq_, module, exports) {
  1735. 'use strict';
  1736. // skip IE policies
  1737. // document.ondragstart = function () { return false; };
  1738. //
  1739. var ClassList = _dereq_('class-list'),
  1740. bean = _dereq_('bean'),
  1741. common = _dereq_('../common');
  1742. // execute function every <delay> ms
  1743. var throttle = function (fn, delay) {
  1744. var locked;
  1745. return function () {
  1746. if (!locked) {
  1747. fn.apply(this, arguments);
  1748. locked = 1;
  1749. setTimeout(function () { locked = 0; }, delay);
  1750. }
  1751. };
  1752. };
  1753. var slider = function (root, rtl) {
  1754. var IS_IPAD = /iPad/.test(navigator.userAgent) && !/CriOS/.test(navigator.userAgent);
  1755. var progress = common.lastChild(root),
  1756. rootClasses = ClassList(root),
  1757. progressClasses = ClassList(progress),
  1758. disabled,
  1759. offset,
  1760. width,
  1761. height,
  1762. vertical,
  1763. size,
  1764. maxValue,
  1765. max,
  1766. skipAnimation = false,
  1767. /* private */
  1768. calc = function () {
  1769. offset = common.offset(root);
  1770. width = common.width(root);
  1771. height = common.height(root);
  1772. /* exit from fullscreen can mess this up.*/
  1773. // vertical = height > width;
  1774. size = vertical ? height : width;
  1775. max = toDelta(maxValue);
  1776. },
  1777. fire = function (value) {
  1778. if (!disabled && value != api.value && (!maxValue || value < maxValue)) {
  1779. bean.fire(root, 'slide', [value]);
  1780. api.value = value;
  1781. }
  1782. },
  1783. mousemove = function (e) {
  1784. var pageX = e.pageX || e.clientX;
  1785. if (!pageX && e.originalEvent && e.originalEvent.touches && e.originalEvent.touches.length) {
  1786. pageX = e.originalEvent.touches[0].pageX;
  1787. }
  1788. var delta = vertical ? e.pageY - offset.top : pageX - offset.left;
  1789. delta = Math.max(0, Math.min(max || size, delta));
  1790. var value = delta / size;
  1791. if (vertical) value = 1 - value;
  1792. if (rtl) value = 1 - value;
  1793. return move(value, 0, true);
  1794. },
  1795. move = function (value, speed) {
  1796. if (speed === undefined) { speed = 0; }
  1797. if (value > 1) value = 1;
  1798. var to = (Math.round(value * 1000) / 10) + "%";
  1799. if (!maxValue || value <= maxValue) {
  1800. progressClasses.remove('animated');
  1801. if (skipAnimation) {
  1802. progressClasses.remove('animated');
  1803. } else {
  1804. progressClasses.add('animated');
  1805. common.css(progress, 'transition-duration', (speed || 0) + 'ms');
  1806. }
  1807. common.css(progress, 'width', to);
  1808. }
  1809. return value;
  1810. },
  1811. toDelta = function (value) {
  1812. return Math.max(0, Math.min(size, vertical ? (1 - value) * height : value * width));
  1813. },
  1814. /* public */
  1815. api = {
  1816. max: function (value) {
  1817. maxValue = value;
  1818. },
  1819. disable: function (flag) {
  1820. disabled = flag;
  1821. },
  1822. slide: function (value, speed, fireEvent) {
  1823. calc();
  1824. if (fireEvent) fire(value);
  1825. move(value, speed);
  1826. },
  1827. // Should animation be handled via css
  1828. disableAnimation: function (value, alsoCssAnimations) {
  1829. skipAnimation = value !== false;
  1830. common.toggleClass(root, 'no-animation', !!alsoCssAnimations);
  1831. }
  1832. };
  1833. calc();
  1834. // bound dragging into document
  1835. bean.on(root, 'mousedown.sld touchstart', function (e) {
  1836. e.preventDefault();
  1837. if (!disabled) {
  1838. // begin --> recalculate. allows dynamic resizing of the slider
  1839. var delayedFire = throttle(fire, 100);
  1840. calc();
  1841. api.dragging = true;
  1842. rootClasses.add('is-dragging');
  1843. fire(mousemove(e));
  1844. bean.on(document, 'mousemove.sld touchmove.sld', function (e) {
  1845. e.preventDefault();
  1846. delayedFire(mousemove(e));
  1847. });
  1848. bean.one(document, 'mouseup touchend', function () {
  1849. api.dragging = false;
  1850. rootClasses.remove('is-dragging');
  1851. bean.off(document, 'mousemove.sld touchmove.sld');
  1852. });
  1853. }
  1854. });
  1855. return api;
  1856. };
  1857. module.exports = slider;
  1858. }, { "../common": 1, "bean": 20, "class-list": 22}], 15: [function (_dereq_, module, exports) {
  1859. 'use strict';
  1860. var flowplayer = _dereq_('../flowplayer'),
  1861. common = _dereq_('../common'),
  1862. bean = _dereq_('bean'),
  1863. ClassList = _dereq_('class-list');
  1864. flowplayer.defaults.subtitleParser = function (txt) {
  1865. var TIMECODE_RE = /^(([0-9]{2}:){1,2}[0-9]{2}[,.][0-9]{3}) --\> (([0-9]{2}:){1,2}[0-9]{2}[,.][0-9]{3})(.*)/;
  1866. function seconds(timecode) {
  1867. var els = timecode.split(':');
  1868. if (els.length == 2) els.unshift(0);
  1869. return els[0] * 60 * 60 + els[1] * 60 + parseFloat(els[2].replace(',', '.'));
  1870. }
  1871. var entries = [];
  1872. for (var i = 0, lines = txt.split("\n"), len = lines.length, entry = {}, title, timecode, text, cue; i < len; i++) {
  1873. timecode = TIMECODE_RE.exec(lines[i]);
  1874. if (timecode) {
  1875. // title
  1876. title = lines[i - 1];
  1877. // text
  1878. text = "<p>" + lines[++i] + "</p><br/>";
  1879. while (typeof lines[++i] === 'string' && lines[i].trim() && i < lines.length) text += "<p>" + lines[i] + "</p><br/>";
  1880. // entry
  1881. entry = {
  1882. title: title,
  1883. startTime: seconds(timecode[1]),
  1884. endTime: seconds(timecode[3]),
  1885. text: text
  1886. };
  1887. entries.push(entry);
  1888. }
  1889. }
  1890. return entries;
  1891. };
  1892. flowplayer(function (p, root) {
  1893. var wrapClasses, currentPoint, wrap,
  1894. rootClasses = ClassList(root),
  1895. subtitleControl;
  1896. var createSubtitleControl = function () {
  1897. subtitleControl = common.createElement('a', { className: 'fp-menu' });
  1898. var menu = common.createElement('ul', { className: 'fp-dropdown fp-dropup' });
  1899. menu.appendChild(common.createElement('li', { 'data-subtitle-index': -1 }, 'No subtitles'));
  1900. (p.video.subtitles || []).forEach(function (st, i) {
  1901. var srcLang = st.srclang || 'en',
  1902. label = st.label || 'Default (' + srcLang + ')';
  1903. var item = common.createElement('li', { 'data-subtitle-index': i }, label);
  1904. menu.appendChild(item);
  1905. });
  1906. subtitleControl.appendChild(menu);
  1907. common.find('.fp-controls', root)[0].appendChild(subtitleControl);
  1908. return subtitleControl;
  1909. };
  1910. bean.on(root, 'click', '.fp-menu', function (ev) {
  1911. ClassList(subtitleControl).toggle('dropdown-open');
  1912. });
  1913. bean.on(root, 'click', '.fp-menu li[data-subtitle-index]', function (ev) {
  1914. var idx = ev.target.getAttribute('data-subtitle-index');
  1915. if (idx === '-1') return p.disableSubtitles();
  1916. p.loadSubtitles(idx);
  1917. });
  1918. var createUIElements = function () {
  1919. var playerEl = common.find('.fp-player', root)[0];
  1920. wrap = common.find('.fp-subtitle', root)[0];
  1921. wrap = wrap || common.appendTo(common.createElement('div', { 'class': 'fp-subtitle' }), playerEl);
  1922. Array.prototype.forEach.call(wrap.children, common.removeNode);
  1923. wrapClasses = ClassList(wrap);
  1924. common.find('.fp-menu', root).forEach(common.removeNode);
  1925. createSubtitleControl();
  1926. };
  1927. p.on('ready', function (ev, player, video) {
  1928. var conf = player.conf;
  1929. if (flowplayer.support.subtitles && conf.nativesubtitles && player.engine.engineName == 'html5') {
  1930. var setMode = function (mode) {
  1931. var tracks = common.find('video', root)[0].textTracks;
  1932. if (!tracks.length) return;
  1933. tracks[0].mode = mode;
  1934. };
  1935. if (!video.subtitles || !video.subtitles.length) return;
  1936. var videoTag = common.find('video.fp-engine', root)[0];
  1937. if (video.subtitles.some(function (st) { return !common.isSameDomain(st.src); })) common.attr(videoTag, 'crossorigin', 'anonymous');
  1938. videoTag.textTracks.addEventListener('addtrack', function () {
  1939. setMode('disabled');
  1940. setMode('showing');
  1941. });
  1942. video.subtitles.forEach(function (st) {
  1943. videoTag.appendChild(common.createElement('track', {
  1944. kind: 'subtitles',
  1945. srclang: st.srclang || 'en',
  1946. label: st.label || 'en',
  1947. src: st.src,
  1948. 'default': st['default']
  1949. }));
  1950. });
  1951. return;
  1952. }
  1953. player.subtitles = [];
  1954. createUIElements();
  1955. rootClasses.remove('has-menu');
  1956. p.disableSubtitles();
  1957. if (!video.subtitles || !video.subtitles.length) return;
  1958. rootClasses.add('has-menu');
  1959. var defaultSubtitle = video.subtitles.filter(function (one) {
  1960. return one['default'];
  1961. })[0];
  1962. if (defaultSubtitle) player.loadSubtitles(video.subtitles.indexOf(defaultSubtitle));
  1963. });
  1964. p.bind("cuepoint", function (e, api, cue) {
  1965. if (cue.subtitle) {
  1966. currentPoint = cue.index;
  1967. common.html(wrap, cue.subtitle.text);
  1968. wrapClasses.add('fp-active');
  1969. } else if (cue.subtitleEnd) {
  1970. wrapClasses.remove('fp-active');
  1971. currentPoint = cue.index;
  1972. }
  1973. });
  1974. p.bind("seek", function (e, api, time) {
  1975. // Clear future subtitles if seeking backwards
  1976. if (currentPoint && p.cuepoints[currentPoint] && p.cuepoints[currentPoint].time > time) {
  1977. wrapClasses.remove('fp-active');
  1978. currentPoint = null;
  1979. }
  1980. (p.cuepoints || []).forEach(function (cue) {
  1981. var entry = cue.subtitle;
  1982. //Trigger cuepoint if start time before seek position and end time nonexistent or in the future
  1983. if (entry && currentPoint != cue.index) {
  1984. if (time >= cue.time && (!entry.endTime || time <= entry.endTime)) p.trigger("cuepoint", [p, cue]);
  1985. } // Also handle cuepoints that act as the removal trigger
  1986. else if (cue.subtitleEnd && time >= cue.time && cue.index == currentPoint + 1) p.trigger("cuepoint", [p, cue]);
  1987. });
  1988. });
  1989. var setActiveSubtitleClass = function (idx) {
  1990. common.toggleClass(common.find('li.active', root)[0], 'active');
  1991. common.toggleClass(common.find('li[data-subtitle-index="' + idx + '"]', root)[0], 'active');
  1992. };
  1993. p.disableSubtitles = function () {
  1994. p.subtitles = [];
  1995. (p.cuepoints || []).forEach(function (c) {
  1996. if (c.subtitle || c.subtitleEnd) p.removeCuepoint(c);
  1997. });
  1998. if (wrap) Array.prototype.forEach.call(wrap.children, common.removeNode);
  1999. setActiveSubtitleClass(-1);
  2000. return p;
  2001. };
  2002. p.loadSubtitles = function (i) {
  2003. //First remove possible old subtitles
  2004. p.disableSubtitles();
  2005. var st = p.video.subtitles[i];
  2006. var url = st.src;
  2007. if (!url) return;
  2008. setActiveSubtitleClass(i);
  2009. common.xhrGet(url, function (txt) {
  2010. var entries = p.conf.subtitleParser(txt);
  2011. entries.forEach(function (entry) {
  2012. var cue = { time: entry.startTime, subtitle: entry, visible: false };
  2013. p.subtitles.push(entry);
  2014. p.addCuepoint(cue);
  2015. p.addCuepoint({ time: entry.endTime, subtitleEnd: entry.title, visible: false });
  2016. // initial cuepoint
  2017. if (entry.startTime === 0 && !p.video.time) {
  2018. p.trigger("cuepoint", [p, cue]);
  2019. }
  2020. });
  2021. }, function () {
  2022. p.trigger("error", { code: 8, url: url });
  2023. return false;
  2024. });
  2025. return p;
  2026. };
  2027. });
  2028. }, { "../common": 1, "../flowplayer": 18, "bean": 20, "class-list": 22}], 16: [function (_dereq_, module, exports) {
  2029. 'use strict';
  2030. /* global ActiveXObject */
  2031. var flowplayer = _dereq_('../flowplayer'),
  2032. extend = _dereq_('extend-object');
  2033. (function () {
  2034. var parseIpadVersion = function (UA) {
  2035. var e = /Version\/(\d\.\d)/.exec(UA);
  2036. if (e && e.length > 1) {
  2037. return parseFloat(e[1], 10);
  2038. }
  2039. return 0;
  2040. };
  2041. var createVideoTag = function () {
  2042. var videoTag = document.createElement('video');
  2043. try {
  2044. videoTag.loop = true;
  2045. videoTag.autoplay = true;
  2046. videoTag.preload = true;
  2047. } catch (e) { }
  2048. return videoTag;
  2049. };
  2050. var b = {},
  2051. ua = navigator.userAgent.toLowerCase(),
  2052. match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
  2053. /(safari)[ \/]([\w.]+)/.exec(ua) ||
  2054. /(webkit)[ \/]([\w.]+)/.exec(ua) ||
  2055. /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
  2056. /(msie) ([\w.]+)/.exec(ua) ||
  2057. ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || [];
  2058. if (match[1]) {
  2059. b[match[1]] = true;
  2060. b.version = match[2] || "0";
  2061. }
  2062. var video = createVideoTag(),
  2063. UA = navigator.userAgent,
  2064. IS_IE = b.msie || /Trident\/7/.test(UA),
  2065. IS_IPAD = /iPad|MeeGo/.test(UA) && !/CriOS/.test(UA),
  2066. IS_IPAD_CHROME = /iPad/.test(UA) && /CriOS/.test(UA),
  2067. IS_IPHONE = /iP(hone|od)/i.test(UA) && !/iPad/.test(UA) && !/IEMobile/i.test(UA),
  2068. IS_ANDROID = /Android/.test(UA) && !/Firefox/.test(UA),
  2069. IS_ANDROID_FIREFOX = /Android/.test(UA) && /Firefox/.test(UA),
  2070. IS_SILK = /Silk/.test(UA),
  2071. IS_WP = /IEMobile/.test(UA),
  2072. WP_VER = IS_WP ? parseFloat(/Windows\ Phone\ (\d+\.\d+)/.exec(UA)[1], 10) : 0,
  2073. IE_MOBILE_VER = IS_WP ? parseFloat(/IEMobile\/(\d+\.\d+)/.exec(UA)[1], 10) : 0,
  2074. IPAD_VER = IS_IPAD ? parseIpadVersion(UA) : 0,
  2075. ANDROID_VER = IS_ANDROID ? parseFloat(/Android\ (\d\.\d)/.exec(UA)[1], 10) : 0,
  2076. s = extend(flowplayer.support, {
  2077. browser: b,
  2078. subtitles: !!video.addTextTrack,
  2079. fullscreen: typeof document.webkitCancelFullScreen == 'function' && !/Mac OS X 10_5.+Version\/5\.0\.\d Safari/.test(UA) ||
  2080. document.mozFullScreenEnabled ||
  2081. typeof document.exitFullscreen == 'function' ||
  2082. typeof document.msExitFullscreen == 'function',
  2083. inlineBlock: !(IS_IE && b.version < 8),
  2084. touch: ('ontouchstart' in window),
  2085. dataload: !IS_IPAD && !IS_IPHONE && !IS_WP,
  2086. zeropreload: !IS_IE && !IS_ANDROID, // IE supports only preload=metadata
  2087. volume: !IS_IPAD && !IS_ANDROID && !IS_IPHONE && !IS_SILK && !IS_IPAD_CHROME,
  2088. cachedVideoTag: !IS_IPAD && !IS_IPHONE && !IS_IPAD_CHROME && !IS_WP,
  2089. firstframe: !IS_IPHONE && !IS_IPAD && !IS_ANDROID && !IS_SILK && !IS_IPAD_CHROME && !IS_WP && !IS_ANDROID_FIREFOX,
  2090. inlineVideo: !IS_IPHONE && (!IS_WP || (WP_VER >= 8.1 && IE_MOBILE_VER >= 11)) && (!IS_ANDROID || ANDROID_VER >= 3),
  2091. hlsDuration: !IS_ANDROID && (!b.safari || IS_IPAD || IS_IPHONE || IS_IPAD_CHROME),
  2092. seekable: !IS_IPAD && !IS_IPAD_CHROME
  2093. });
  2094. // flashVideo
  2095. try {
  2096. var plugin = navigator.plugins["Shockwave Flash"],
  2097. ver = IS_IE ? new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable('$version') : plugin.description;
  2098. if (!IS_IE && !plugin[0].enabledPlugin) s.flashVideo = false;
  2099. else {
  2100. ver = ver.split(/\D+/);
  2101. if (ver.length && !ver[0]) ver = ver.slice(1);
  2102. s.flashVideo = ver[0] > 9 || ver[0] == 9 && ver[3] >= 115;
  2103. }
  2104. //s.flashVideo = false;
  2105. } catch (ignored) { }
  2106. try {
  2107. s.video = !!video.canPlayType;
  2108. if (s.video) video.canPlayType('video/mp4');
  2109. } catch (e) {
  2110. s.video = false;
  2111. }
  2112. // animation
  2113. s.animation = (function () {
  2114. var vendors = ['', 'Webkit', 'Moz', 'O', 'ms', 'Khtml'], el = document.createElement('p');
  2115. for (var i = 0; i < vendors.length; i++) {
  2116. if (typeof el.style[vendors[i] + 'AnimationName'] !== 'undefined') return true;
  2117. }
  2118. })();
  2119. })();
  2120. }, { "../flowplayer": 18, "extend-object": 26}], 17: [function (_dereq_, module, exports) {
  2121. 'use strict';
  2122. var flowplayer = _dereq_('../flowplayer'),
  2123. common = _dereq_('../common'),
  2124. ClassList = _dereq_('class-list'),
  2125. bean = _dereq_('bean'),
  2126. slider = _dereq_('./slider');
  2127. function zeropad(val) {
  2128. val = parseInt(val, 10);
  2129. return val >= 10 ? val : "0" + val;
  2130. }
  2131. // display seconds in hh:mm:ss format
  2132. function format(sec) {
  2133. sec = sec || 0;
  2134. var h = Math.floor(sec / 3600),
  2135. min = Math.floor(sec / 60);
  2136. sec = sec - (min * 60);
  2137. if (h >= 1) {
  2138. min -= h * 60;
  2139. return h + ":" + zeropad(min) + ":" + zeropad(sec);
  2140. }
  2141. return zeropad(min) + ":" + zeropad(sec);
  2142. }
  2143. flowplayer(function (api, root) {
  2144. var conf = api.conf,
  2145. support = flowplayer.support,
  2146. hovertimer,
  2147. rootClasses = ClassList(root);
  2148. common.find('.fp-ratio,.fp-ui', root).forEach(common.removeNode);
  2149. rootClasses.add('flowplayer');
  2150. root.appendChild(common.createElement('div', { className: 'fp-ratio' }));
  2151. var ui = common.createElement('div', { className: 'fp-ui' }, '\
  2152. <div class="waiting"><em></em><em></em><em></em></div>\
  2153. <a class="fullscreen"></a>\
  2154. <a class="unload"></a>\
  2155. <p class="speed"></p>\
  2156. <div class="controls">\
  2157. <a class="play"></a>\
  2158. <div class="timeline">\
  2159. <div class="buffer"></div>\
  2160. <div class="progress"></div>\
  2161. </div>\
  2162. <div class="timeline-tooltip fp-tooltip"></div>\
  2163. <div class="volume">\
  2164. <a class="mute"></a>\
  2165. <div class="volumeslider">\
  2166. <div class="volumelevel"></div>\
  2167. </div>\
  2168. </div>\
  2169. </div>\
  2170. <div class="time">\
  2171. <em class="elapsed">00:00</em>\
  2172. <em class="remaining"></em>\
  2173. <em class="duration">00:00</em>\
  2174. </div>\
  2175. <div class="message"><h2></h2><p></p></div>'.replace(/class="/g, 'class="fp-'));
  2176. root.appendChild(ui);
  2177. function find(klass) {
  2178. return common.find(".fp-" + klass, root)[0];
  2179. }
  2180. // widgets
  2181. var progress = find("progress"),
  2182. buffer = find("buffer"),
  2183. elapsed = find("elapsed"),
  2184. remaining = find("remaining"),
  2185. waiting = find("waiting"),
  2186. ratio = find("ratio"),
  2187. speed = find("speed"),
  2188. speedClasses = ClassList(speed),
  2189. durationEl = find("duration"),
  2190. controls = find('controls'),
  2191. timelineTooltip = find('timeline-tooltip'),
  2192. origRatio = common.css(ratio, 'padding-top'),
  2193. // sliders
  2194. timeline = find("timeline"),
  2195. timelineApi = slider(timeline, api.rtl),
  2196. volume = find("volume"),
  2197. fullscreen = find("fullscreen"),
  2198. volumeSlider = find("volumeslider"),
  2199. volumeApi = slider(volumeSlider, api.rtl),
  2200. noToggle = rootClasses.contains('fixed-controls') || rootClasses.contains('no-toggle');
  2201. timelineApi.disableAnimation(rootClasses.contains('is-touch'));
  2202. api.sliders = api.sliders || {};
  2203. api.sliders.timeline = timelineApi;
  2204. api.sliders.volume = volumeApi;
  2205. // aspect ratio
  2206. function setRatio(val) {
  2207. common.css(ratio, 'padding-top', val * 100 + "%");
  2208. if (!support.inlineBlock) common.height(common.find('object', root)[0], common.height(root));
  2209. }
  2210. function hover(flag) {
  2211. if (flag) {
  2212. rootClasses.add('is-mouseover');
  2213. rootClasses.remove('is-mouseout');
  2214. } else {
  2215. rootClasses.add('is-mouseout');
  2216. rootClasses.remove('is-mouseover');
  2217. }
  2218. }
  2219. // loading...
  2220. if (!support.animation) common.html(waiting, "<p>loading &hellip;</p>");
  2221. if (conf.ratio) setRatio(conf.ratio);
  2222. // no fullscreen in IFRAME
  2223. try {
  2224. if (!conf.fullscreen) common.removeNode(fullscreen);
  2225. } catch (e) {
  2226. common.removeNode(fullscreen);
  2227. }
  2228. api.on("ready", function (ev, api, video) {
  2229. var duration = api.video.duration;
  2230. timelineApi.disable(api.disabled || !duration);
  2231. if (conf.adaptiveRatio && !isNaN(video.height / video.width)) setRatio(video.height / video.width, true);
  2232. // initial time & volume
  2233. common.html([durationEl, remaining], format(duration));
  2234. // do we need additional space for showing hour
  2235. common.toggleClass(root, 'is-long', duration >= 3600);
  2236. volumeApi.slide(api.volumeLevel);
  2237. if (api.engine.engineName === 'flash') timelineApi.disableAnimation(true, true);
  2238. else timelineApi.disableAnimation(false);
  2239. common.find('.fp-title', ui).forEach(common.removeNode);
  2240. if (video.title) {
  2241. common.prepend(ui, common.createElement('div', {
  2242. className: 'fp-title'
  2243. }, video.title));
  2244. }
  2245. }).on("unload", function () {
  2246. if (!origRatio && !conf.splash) common.css(ratio, "paddingTop", "");
  2247. timelineApi.slide(0);
  2248. // buffer
  2249. }).on("buffer", function () {
  2250. var video = api.video,
  2251. max = video.buffer / video.duration;
  2252. if (!video.seekable && support.seekable) timelineApi.max(max);
  2253. if (max < 1) common.css(buffer, "width", (max * 100) + "%");
  2254. else common.css(buffer, 'width', '100%');
  2255. }).on("speed", function (e, api, val) {
  2256. common.text(speed, val + "x");
  2257. speedClasses.add('fp-hilite');
  2258. setTimeout(function () { speedClasses.remove('fp-hilite'); }, 1000);
  2259. }).on("buffered", function () {
  2260. common.css(buffer, 'width', '100%');
  2261. timelineApi.max(1);
  2262. // progress
  2263. }).on("progress", function () {
  2264. var time = api.video.time,
  2265. duration = api.video.duration;
  2266. if (!timelineApi.dragging) {
  2267. timelineApi.slide(time / duration, api.seeking ? 0 : 250);
  2268. }
  2269. common.html(elapsed, format(time));
  2270. common.html(remaining, '-' + format(duration - time));
  2271. }).on("finish resume seek", function (e) {
  2272. common.toggleClass(root, "is-finished", e.type == "finish");
  2273. }).on("stop", function () {
  2274. common.html(elapsed, format(0));
  2275. timelineApi.slide(0, 100);
  2276. }).on("finish", function () {
  2277. common.html(elapsed, format(api.video.duration));
  2278. timelineApi.slide(1, 100);
  2279. rootClasses.remove('is-seeking');
  2280. // misc
  2281. }).on("beforeseek", function () {
  2282. //TODO FIXME
  2283. //progress.stop();
  2284. }).on("volume", function () {
  2285. volumeApi.slide(api.volumeLevel);
  2286. }).on("disable", function () {
  2287. var flag = api.disabled;
  2288. timelineApi.disable(flag);
  2289. volumeApi.disable(flag);
  2290. common.toggleClass(root, 'is-disabled', api.disabled);
  2291. }).on("mute", function (e, api, flag) {
  2292. common.toggleClass(root, 'is-muted', flag);
  2293. }).on("error", function (e, api, error) {
  2294. common.removeClass(root, 'is-loading');
  2295. common.removeClass(root, 'is-seeking');
  2296. common.addClass(root, 'is-error');
  2297. if (error) {
  2298. error.message = conf.errors[error.code];
  2299. api.error = true;
  2300. var el = common.find('.fp-message', root)[0],
  2301. video = error.video || api.video;
  2302. common.find('h2', el)[0].innerHTML = (api.engine && api.engine.engineName || 'html5') + ": " + error.message;
  2303. common.find('p', el)[0].innerHTML = error.url || video.url || video.src || conf.errorUrls[error.code];
  2304. api.off("mouseenter click");
  2305. rootClasses.remove('is-mouseover');
  2306. }
  2307. // hover
  2308. });
  2309. //Interaction events
  2310. bean.on(root, "mouseenter mouseleave", function (e) {
  2311. if (noToggle) return;
  2312. var is_over = e.type == "mouseover",
  2313. lastMove;
  2314. // is-mouseover/out
  2315. hover(is_over);
  2316. if (is_over) {
  2317. var reg = function () {
  2318. hover(true);
  2319. lastMove = new Date();
  2320. };
  2321. api.on("pause.x volume.x", reg);
  2322. bean.on(root, 'mousemove.x', reg);
  2323. hovertimer = setInterval(function () {
  2324. if (new Date() - lastMove > conf.mouseoutTimeout) {
  2325. hover(false);
  2326. lastMove = new Date();
  2327. }
  2328. }, 100);
  2329. } else {
  2330. bean.off(root, 'mousemove.x');
  2331. api.off("pause.x volume.x");
  2332. clearInterval(hovertimer);
  2333. }
  2334. // allow dragging over the player edge
  2335. });
  2336. bean.on(root, "mouseleave", function () {
  2337. if (timelineApi.dragging || volumeApi.dragging) {
  2338. rootClasses.add('is-mouseover');
  2339. rootClasses.remove('is-mouseout');
  2340. }
  2341. // click
  2342. });
  2343. bean.on(root, "click.player", function (e) {
  2344. if (api.disabled) return;
  2345. var kls = ClassList(e.target);
  2346. if (kls.contains('fp-ui') || kls.contains('fp-engine') || e.flash) {
  2347. if (e.preventDefault) e.preventDefault();
  2348. return api.toggle();
  2349. }
  2350. });
  2351. bean.on(root, 'mousemove', '.fp-timeline', function (ev) {
  2352. var x = ev.pageX || ev.clientX,
  2353. delta = x - common.offset(timeline).left,
  2354. percentage = delta / common.width(timeline),
  2355. seconds = percentage * api.video.duration;
  2356. if (percentage < 0) return;
  2357. common.html(timelineTooltip, format(seconds));
  2358. common.css(timelineTooltip, 'left', (x - common.offset(controls).left - common.width(timelineTooltip) / 2) + 'px');
  2359. });
  2360. bean.on(root, 'contextmenu', function (ev) {
  2361. var o = common.offset(common.find('.fp-player', root)[0]),
  2362. w = window,
  2363. left = ev.clientX - (o.left + w.scrollX),
  2364. t = ev.clientY - (o.top + w.scrollY);
  2365. if (rootClasses.contains('is-flash-disabled')) return;
  2366. var menu = common.find('.fp-context-menu', root)[0];
  2367. if (!menu) return;
  2368. ev.preventDefault();
  2369. common.css(menu,
  2370. { left: left + 'px',
  2371. top: t + 'px',
  2372. display: 'block'
  2373. });
  2374. bean.on(root, 'click', '.fp-context-menu', function (ev) {
  2375. ev.stopPropagation();
  2376. });
  2377. bean.on(document, 'click.outsidemenu', function (ev) {
  2378. common.css(menu, 'display', 'none');
  2379. bean.off(document, 'click.outsidemenu');
  2380. });
  2381. });
  2382. api.on('flashdisabled', function () {
  2383. rootClasses.add('is-flash-disabled');
  2384. api.one('ready progress', function () {
  2385. rootClasses.remove('is-flash-disabled');
  2386. common.find('.fp-flash-disabled', root).forEach(common.removeNode);
  2387. });
  2388. root.appendChild(common.createElement('div', { className: "fp-flash-disabled" }, 'Adobe Flash is disabled for this page, click player area to enable'));
  2389. });
  2390. // poster -> background image
  2391. if (conf.poster) common.css(root, 'background-image', "url(" + conf.poster + ")");
  2392. var bc = common.css(root, 'background-color'),
  2393. has_bg = common.css(root, 'background-image') != "none" || bc && bc != "rgba(0, 0, 0, 0)" && bc != "transparent";
  2394. // is-poster class
  2395. if (has_bg && !conf.splash) {
  2396. if (!conf.poster) conf.poster = true;
  2397. api.on("ready stop", function () {
  2398. rootClasses.add("is-poster");
  2399. api.poster = true;
  2400. api.one("progress", function () {
  2401. rootClasses.remove("is-poster");
  2402. api.poster = false;
  2403. });
  2404. });
  2405. }
  2406. if (typeof conf.splash === 'string') {
  2407. common.css(root, 'background-image', "url('" + conf.splash + "')");
  2408. }
  2409. // default background color if not present
  2410. if (!has_bg && api.forcedSplash) {
  2411. common.css(root, "background-color", "#555");
  2412. }
  2413. bean.on(root, 'click', '.fp-toggle, .fp-play', function () {
  2414. if (api.disabled) return;
  2415. api.toggle();
  2416. });
  2417. /* controlbar elements */
  2418. bean.on(root, 'click', '.fp-mute', function () { api.mute(); });
  2419. bean.on(root, 'click', '.fp-fullscreen', function () { api.fullscreen(); });
  2420. bean.on(root, 'click', '.fp-unload', function () { api.unload(); });
  2421. bean.on(timeline, 'slide', function (val) {
  2422. api.seeking = true;
  2423. api.seek(val * api.video.duration);
  2424. });
  2425. bean.on(volumeSlider, 'slide', function (val) {
  2426. api.volume(val);
  2427. });
  2428. // times
  2429. var time = find('time');
  2430. bean.on(root, 'click', '.fp-time', function () {
  2431. ClassList(time).toggle('is-inverted');
  2432. });
  2433. hover(noToggle);
  2434. api.on('shutdown', function () {
  2435. bean.off(timeline);
  2436. bean.off(volumeSlider);
  2437. });
  2438. });
  2439. module.exports.format = format;
  2440. }, { "../common": 1, "../flowplayer": 18, "./slider": 14, "bean": 20, "class-list": 22}], 18: [function (_dereq_, module, exports) {
  2441. 'use strict';
  2442. var extend = _dereq_('extend-object'),
  2443. isFunction = _dereq_('is-function'),
  2444. ClassList = _dereq_('class-list'),
  2445. bean = _dereq_('bean'),
  2446. common = _dereq_('./common'),
  2447. events = _dereq_('./ext/events');
  2448. var instances = [],
  2449. extensions = [],
  2450. UA = window.navigator.userAgent;
  2451. var oldHandler = window.onbeforeunload;
  2452. window.onbeforeunload = function (ev) {
  2453. instances.forEach(function (api) {
  2454. if (api.conf.splash) {
  2455. api.unload();
  2456. } else {
  2457. api.bind("error", function () {
  2458. common.find('.flowplayer.is-error .fp-message').forEach(common.removeNode);
  2459. });
  2460. }
  2461. });
  2462. if (oldHandler) return oldHandler(ev);
  2463. };
  2464. var supportLocalStorage = false;
  2465. try {
  2466. if (typeof window.localStorage == "object") {
  2467. window.localStorage.flowplayerTestStorage = "test";
  2468. supportLocalStorage = true;
  2469. }
  2470. } catch (ignored) { }
  2471. var isSafari = /Safari/.exec(navigator.userAgent) && !/Chrome/.exec(navigator.userAgent),
  2472. m = /(\d+\.\d+) Safari/.exec(navigator.userAgent),
  2473. safariVersion = m ? Number(m[1]) : 100;
  2474. /* flowplayer() */
  2475. var flowplayer = module.exports = function (fn, opts, callback) {
  2476. if (isFunction(fn)) return extensions.push(fn);
  2477. if (typeof fn == 'number' || typeof fn === 'undefined') return instances[fn || 0];
  2478. if (fn.nodeType) { // Is an element
  2479. if (fn.getAttribute('data-flowplayer-instance-id') !== null) { // Already flowplayer instance
  2480. return instances[fn.getAttribute('data-flowplayer-instance-id')];
  2481. }
  2482. if (!opts) return; // Can't initialize without data
  2483. return initializePlayer(fn, opts, callback);
  2484. }
  2485. if (fn.jquery) return flowplayer(fn[0], opts, callback);
  2486. if (typeof fn === 'string') {
  2487. var el = common.find(fn)[0];
  2488. return el && flowplayer(el, opts, callback);
  2489. }
  2490. };
  2491. extend(flowplayer, {
  2492. version: '6.0.5',
  2493. engines: [],
  2494. conf: {},
  2495. set: function (key, value) {
  2496. if (typeof key === 'string') flowplayer.conf[key] = value;
  2497. else extend(flowplayer.conf, key);
  2498. },
  2499. support: {},
  2500. defaults: {
  2501. debug: supportLocalStorage ? !!localStorage.flowplayerDebug : false,
  2502. // true = forced playback
  2503. disabled: false,
  2504. fullscreen: window == window.top,
  2505. // keyboard shortcuts
  2506. keyboard: true,
  2507. // default aspect ratio
  2508. ratio: 9 / 16,
  2509. adaptiveRatio: false,
  2510. rtmp: 0,
  2511. proxy: 'best',
  2512. splash: false,
  2513. live: false,
  2514. swf: "/Scripts/flowplayer-6.0.5/flowplayer.swf",
  2515. swfHls: "/Scripts/flowplayer-6.0.5/flowplayerhls.swf",
  2516. speeds: [0.25, 0.5, 1, 1.5, 2],
  2517. tooltip: true,
  2518. mouseoutTimeout: 5000,
  2519. // initial volume level
  2520. volume: !supportLocalStorage ? 1 : localStorage.muted == "true" ? 0 : !isNaN(localStorage.volume) ? localStorage.volume || 1 : 1,
  2521. // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#error-codes
  2522. errors: [
  2523. // video exceptions
  2524. '',
  2525. 'Video loading aborted',
  2526. 'Network error',
  2527. 'Video not properly encoded',
  2528. 'Video file not found',
  2529. // player exceptions
  2530. 'Unsupported video',
  2531. 'Skin not found',
  2532. 'SWF file not found',
  2533. 'Subtitles not found',
  2534. 'Invalid RTMP URL',
  2535. 'Unsupported video format. Try installing Adobe Flash.'
  2536. ],
  2537. errorUrls: ['', '', '', '', '', '', '', '', '', '',
  2538. 'http://get.adobe.com/flashplayer/'
  2539. ],
  2540. playlist: [],
  2541. hlsFix: isSafari && safariVersion < 8
  2542. },
  2543. // Expose utilities for plugins
  2544. bean: bean,
  2545. common: common,
  2546. extend: extend
  2547. });
  2548. // keep track of players
  2549. var playerCount = 0;
  2550. var URLResolver = _dereq_('./ext/resolve');
  2551. if (typeof window.jQuery !== 'undefined') {
  2552. var $ = window.jQuery;
  2553. // auto-install (any video tag with parent .flowplayer)
  2554. $(function () {
  2555. if (typeof $.fn.flowplayer == 'function') {
  2556. $('.flowplayer:has(video,script[type="application/json"])').flowplayer();
  2557. }
  2558. });
  2559. // jQuery plugin
  2560. var videoTagConfig = function (videoTag) {
  2561. if (!videoTag.length) return {};
  2562. var clip = videoTag.data() || {}, conf = {};
  2563. $.each(['autoplay', 'loop', 'preload', 'poster'], function (i, key) {
  2564. var val = videoTag.attr(key);
  2565. if (val !== undefined && ['autoplay', 'poster'].indexOf(key) !== -1) conf[key] = val ? val : true;
  2566. else if (val !== undefined) clip[key] = val ? val : true;
  2567. });
  2568. clip.subtitles = videoTag.find('track').map(function () {
  2569. var tr = $(this);
  2570. return {
  2571. src: tr.attr('src'),
  2572. kind: tr.attr('kind'),
  2573. label: tr.attr('label'),
  2574. srclang: tr.attr('srclang'),
  2575. 'default': tr.prop('default')
  2576. };
  2577. }).get();
  2578. clip.sources = (new URLResolver()).sourcesFromVideoTag(videoTag, $);
  2579. return extend(conf, { clip: clip });
  2580. };
  2581. $.fn.flowplayer = function (opts, callback) {
  2582. return this.each(function () {
  2583. if (typeof opts == 'string') opts = { swf: opts };
  2584. if (isFunction(opts)) { callback = opts; opts = {}; }
  2585. var root = $(this),
  2586. scriptConf = root.find('script[type="application/json"]'),
  2587. confObject = scriptConf.length ? JSON.parse(scriptConf.text()) : videoTagConfig(root.find('video')),
  2588. conf = $.extend({}, opts || {}, confObject, root.data());
  2589. var api = initializePlayer(this, conf, callback);
  2590. events.EVENTS.forEach(function (evName) {
  2591. api.on(evName + '.jquery', function (ev) {
  2592. root.trigger.call(root, ev.type, ev.detail && ev.detail.args);
  2593. });
  2594. });
  2595. root.data('flowplayer', api);
  2596. });
  2597. };
  2598. }
  2599. function initializePlayer(element, opts, callback) {
  2600. if (opts && opts.embed) opts.embed = extend({}, flowplayer.defaults.embed, opts.embed);
  2601. var root = element,
  2602. rootClasses = ClassList(root),
  2603. conf = extend({}, flowplayer.defaults, flowplayer.conf, opts),
  2604. storage = {},
  2605. lastSeekPosition,
  2606. engine,
  2607. url,
  2608. urlResolver = new URLResolver();
  2609. rootClasses.add('is-loading');
  2610. try {
  2611. storage = supportLocalStorage ? window.localStorage : storage;
  2612. } catch (e) { }
  2613. var isRTL = (root.currentStyle && root.currentStyle.direction === 'rtl') ||
  2614. (window.getComputedStyle && window.getComputedStyle(root, null) !== null && window.getComputedStyle(root, null).getPropertyValue('direction') === 'rtl');
  2615. if (isRTL) rootClasses.add('is-rtl');
  2616. /*** API ***/
  2617. var api = {
  2618. // properties
  2619. conf: conf,
  2620. currentSpeed: 1,
  2621. volumeLevel: conf.muted ? 0 : typeof conf.volume === "undefined" ? storage.volume * 1 : conf.volume,
  2622. video: {},
  2623. // states
  2624. disabled: false,
  2625. finished: false,
  2626. loading: false,
  2627. muted: storage.muted == "true" || conf.muted,
  2628. paused: false,
  2629. playing: false,
  2630. ready: false,
  2631. splash: false,
  2632. rtl: isRTL,
  2633. // methods
  2634. load: function (video, callback) {
  2635. if (api.error || api.loading) return;
  2636. api.video = {};
  2637. api.finished = false;
  2638. video = video || conf.clip;
  2639. // resolve URL
  2640. video = extend({}, urlResolver.resolve(video, conf.clip.sources));
  2641. if (api.playing || api.engine) video.autoplay = true;
  2642. var engineImpl = selectEngine(video);
  2643. if (!engineImpl) return api.trigger("error", [api, { code: flowplayer.support.flashVideo ? 5 : 10}]);
  2644. if (!engineImpl.engineName) throw new Error('engineName property of factory should be exposed');
  2645. if (!api.engine || engineImpl.engineName !== api.engine.engineName) {
  2646. api.ready = false;
  2647. if (api.engine) {
  2648. api.engine.unload();
  2649. api.conf.autoplay = true;
  2650. }
  2651. engine = api.engine = engineImpl(api, root);
  2652. api.one('ready', function () {
  2653. engine.volume(api.volumeLevel);
  2654. });
  2655. }
  2656. extend(video, engine.pick(video.sources.filter(function (source) { // Filter out sources explicitely configured for some other engine
  2657. if (!source.engine) return true;
  2658. return source.engine === engine.engineName;
  2659. })));
  2660. if (video.src) {
  2661. var e = api.trigger('load', [api, video, engine], true);
  2662. if (!e.defaultPrevented) {
  2663. engine.load(video);
  2664. // callback
  2665. if (isFunction(video)) callback = video;
  2666. if (callback) api.one("ready", callback);
  2667. } else {
  2668. api.loading = false;
  2669. }
  2670. }
  2671. return api;
  2672. },
  2673. pause: function (fn) {
  2674. if (api.ready && !api.seeking && !api.loading) {
  2675. engine.pause();
  2676. api.one("pause", fn);
  2677. }
  2678. return api;
  2679. },
  2680. resume: function () {
  2681. if (api.ready && api.paused) {
  2682. engine.resume();
  2683. // Firefox (+others?) does not fire "resume" after finish
  2684. if (api.finished) {
  2685. api.trigger("resume", [api]);
  2686. api.finished = false;
  2687. }
  2688. }
  2689. return api;
  2690. },
  2691. toggle: function () {
  2692. return api.ready ? api.paused ? api.resume() : api.pause() : api.load();
  2693. },
  2694. /*
  2695. seek(1.4) -> 1.4s time
  2696. seek(true) -> 10% forward
  2697. seek(false) -> 10% backward
  2698. */
  2699. seek: function (time, callback) {
  2700. if (api.ready && !api.live) {
  2701. if (typeof time == "boolean") {
  2702. var delta = api.video.duration * 0.1;
  2703. time = api.video.time + (time ? delta : -delta);
  2704. }
  2705. time = lastSeekPosition = Math.min(Math.max(time, 0), api.video.duration - 0.1).toFixed(1);
  2706. var ev = api.trigger('beforeseek', [api, time], true);
  2707. if (!ev.defaultPrevented) {
  2708. engine.seek(time);
  2709. if (isFunction(callback)) api.one("seek", callback);
  2710. } else {
  2711. api.seeking = false;
  2712. common.toggleClass(root, 'is-seeking', api.seeking); // remove loading indicator
  2713. }
  2714. }
  2715. return api;
  2716. },
  2717. /*
  2718. seekTo(1) -> 10%
  2719. seekTo(2) -> 20%
  2720. seekTo(3) -> 30%
  2721. ...
  2722. seekTo() -> last position
  2723. */
  2724. seekTo: function (position, fn) {
  2725. var time = position === undefined ? lastSeekPosition : api.video.duration * 0.1 * position;
  2726. return api.seek(time, fn);
  2727. },
  2728. mute: function (flag, skipStore) {
  2729. if (flag === undefined) flag = !api.muted;
  2730. if (!skipStore) {
  2731. storage.muted = api.muted = flag;
  2732. storage.volume = !isNaN(storage.volume) ? storage.volume : conf.volume; // make sure storage has volume
  2733. }
  2734. api.volume(flag ? 0 : storage.volume, true);
  2735. api.trigger("mute", [api, flag]);
  2736. return api;
  2737. },
  2738. volume: function (level, skipStore) {
  2739. if (api.ready) {
  2740. level = Math.min(Math.max(level, 0), 1);
  2741. if (!skipStore) storage.volume = level;
  2742. engine.volume(level);
  2743. }
  2744. return api;
  2745. },
  2746. speed: function (val, callback) {
  2747. if (api.ready) {
  2748. // increase / decrease
  2749. if (typeof val == "boolean") {
  2750. val = conf.speeds[conf.speeds.indexOf(api.currentSpeed) + (val ? 1 : -1)] || api.currentSpeed;
  2751. }
  2752. engine.speed(val);
  2753. if (callback) root.one("speed", callback);
  2754. }
  2755. return api;
  2756. },
  2757. stop: function () {
  2758. if (api.ready) {
  2759. api.pause();
  2760. api.seek(0, function () {
  2761. api.trigger("stop", [api]);
  2762. });
  2763. }
  2764. return api;
  2765. },
  2766. unload: function () {
  2767. if (!rootClasses.contains("is-embedding")) {
  2768. if (conf.splash) {
  2769. api.trigger("unload", [api]);
  2770. if (engine) {
  2771. engine.unload();
  2772. api.engine = engine = 0;
  2773. }
  2774. } else {
  2775. api.stop();
  2776. }
  2777. }
  2778. return api;
  2779. },
  2780. shutdown: function () {
  2781. api.unload();
  2782. api.trigger('shutdown', [api]);
  2783. bean.off(root);
  2784. delete instances[root.getAttribute('data-flowplayer-instance-id')];
  2785. root.removeAttribute('data-flowplayer-instance-id');
  2786. },
  2787. disable: function (flag) {
  2788. if (flag === undefined) flag = !api.disabled;
  2789. if (flag != api.disabled) {
  2790. api.disabled = flag;
  2791. api.trigger("disable", flag);
  2792. }
  2793. return api;
  2794. }
  2795. };
  2796. api.conf = extend(api.conf, conf);
  2797. /* event binding / unbinding */
  2798. events(api);
  2799. var selectEngine = function (clip) {
  2800. var engine;
  2801. var engines = flowplayer.engines;
  2802. if (conf.engine) {
  2803. var eng = engines.filter(function (e) { return e.engineName === conf.engine; })[0];
  2804. if (eng && clip.sources.some(function (source) {
  2805. if (source.engine && source.engine !== eng.engineName) return false;
  2806. return eng.canPlay(source.type, api.conf);
  2807. })) return eng;
  2808. }
  2809. if (conf.enginePreference) engines = flowplayer.engines.filter(function (one) { return conf.enginePreference.indexOf(one.engineName) > -1; }).sort(function (a, b) {
  2810. return conf.enginePreference.indexOf(a.engineName) - conf.enginePreference.indexOf(b.engineName);
  2811. });
  2812. clip.sources.some(function (source) {
  2813. var eng = engines.filter(function (engine) {
  2814. if (source.engine && source.engine !== engine.engineName) return false;
  2815. return engine.canPlay(source.type, api.conf);
  2816. }).shift();
  2817. if (eng) engine = eng;
  2818. return !!eng;
  2819. });
  2820. return engine;
  2821. };
  2822. /*** Behaviour ***/
  2823. if (!root.getAttribute('data-flowplayer-instance-id')) { // Only bind once
  2824. root.setAttribute('data-flowplayer-instance-id', playerCount++);
  2825. api.on('boot', function () {
  2826. // splash
  2827. if (conf.splash || rootClasses.contains("is-splash") || !flowplayer.support.firstframe) {
  2828. api.forcedSplash = !conf.splash && !rootClasses.contains("is-splash");
  2829. api.splash = conf.autoplay = true;
  2830. if (!conf.splash) conf.splash = true;
  2831. rootClasses.add("is-splash");
  2832. }
  2833. if (conf.splash) common.find('video', root).forEach(common.removeNode);
  2834. if (conf.live || rootClasses.contains('is-live')) {
  2835. api.live = conf.live = true;
  2836. rootClasses.add('is-live');
  2837. }
  2838. // extensions
  2839. extensions.forEach(function (e) {
  2840. e(api, root);
  2841. });
  2842. // instances
  2843. instances.push(api);
  2844. // start
  2845. if (conf.splash) api.unload(); else api.load();
  2846. // disabled
  2847. if (conf.disabled) api.disable();
  2848. // initial callback
  2849. api.one("ready", callback);
  2850. }).on("load", function (e, api, video) {
  2851. // unload others
  2852. if (conf.splash) {
  2853. common.find('.flowplayer.is-ready,.flowplayer.is-loading').forEach(function (el) {
  2854. var playerId = el.getAttribute('data-flowplayer-instance-id');
  2855. if (playerId === root.getAttribute('data-flowplayer-instance-id')) return;
  2856. var a = instances[Number(playerId)];
  2857. if (a && a.conf.splash) a.unload();
  2858. });
  2859. }
  2860. // loading
  2861. rootClasses.add("is-loading");
  2862. api.loading = true;
  2863. if (typeof video.live !== 'undefined') {
  2864. common.toggleClass(root, 'is-live', video.live);
  2865. api.live = video.live;
  2866. }
  2867. }).on("ready", function (e, api, video) {
  2868. video.time = 0;
  2869. api.video = video;
  2870. rootClasses.remove("is-loading");
  2871. api.loading = false;
  2872. // saved state
  2873. if (api.muted) api.mute(true, true);
  2874. else api.volume(api.volumeLevel);
  2875. // see https://github.com/flowplayer/flowplayer/issues/479
  2876. var hlsFix = api.conf.hlsFix && /mpegurl/i.exec(video.type);
  2877. common.toggleClass(root, 'hls-fix', !!hlsFix);
  2878. }).on("unload", function (e) {
  2879. rootClasses.remove("is-loading");
  2880. api.loading = false;
  2881. }).on("ready unload", function (e) {
  2882. var is_ready = e.type == "ready";
  2883. common.toggleClass(root, 'is-splash', !is_ready);
  2884. common.toggleClass(root, 'is-ready', is_ready);
  2885. api.ready = is_ready;
  2886. api.splash = !is_ready;
  2887. }).on("progress", function (e, api, time) {
  2888. api.video.time = time;
  2889. }).on("speed", function (e, api, val) {
  2890. api.currentSpeed = val;
  2891. }).on("volume", function (e, api, level) {
  2892. api.volumeLevel = Math.round(level * 100) / 100;
  2893. if (!api.muted) storage.volume = level;
  2894. else if (level) api.mute(false);
  2895. }).on("beforeseek seek", function (e) {
  2896. api.seeking = e.type == "beforeseek";
  2897. common.toggleClass(root, 'is-seeking', api.seeking);
  2898. }).on("ready pause resume unload finish stop", function (e, _api, video) {
  2899. // PAUSED: pause / finish
  2900. api.paused = /pause|finish|unload|stop/.test(e.type);
  2901. api.paused = api.paused || e.type === 'ready' && !conf.autoplay && !api.playing;
  2902. // the opposite
  2903. api.playing = !api.paused;
  2904. // CSS classes
  2905. common.toggleClass(root, 'is-paused', api.paused);
  2906. common.toggleClass(root, 'is-playing', api.playing);
  2907. // sanity check
  2908. if (!api.load.ed) api.pause();
  2909. }).on("finish", function (e) {
  2910. api.finished = true;
  2911. }).on("error", function () {
  2912. });
  2913. }
  2914. // boot
  2915. api.trigger('boot', [api, root]);
  2916. return api;
  2917. }
  2918. }, { "./common": 1, "./ext/events": 8, "./ext/resolve": 13, "bean": 20, "class-list": 22, "extend-object": 26, "is-function": 27}], 19: [function (_dereq_, module, exports) {
  2919. //Flowplayer with extensions
  2920. _dereq_('es5-shim');
  2921. var flowplayer = module.exports = _dereq_('./flowplayer');
  2922. //
  2923. //Support needed before engines
  2924. _dereq_('./ext/support');
  2925. //Engines
  2926. _dereq_('./engine/embed');
  2927. _dereq_('./engine/html5');
  2928. _dereq_('./engine/flash');
  2929. //Extensions
  2930. //require('./ext/slider'); //TODO enable
  2931. _dereq_('./ext/ui');
  2932. _dereq_('./ext/keyboard');
  2933. _dereq_('./ext/playlist');
  2934. _dereq_('./ext/cuepoint');
  2935. _dereq_('./ext/subtitle');
  2936. _dereq_('./ext/analytics');
  2937. _dereq_('./ext/embed');
  2938. //Have to add fullscreen last
  2939. _dereq_('./ext/fullscreen');
  2940. _dereq_('./ext/mobile');
  2941. flowplayer(function (e, o) { function a(e) { var o = document.createElement("a"); return o.href = e, t.hostname(o.hostname) } var n = function (e, o) { var a = e.className.split(" "); -1 === a.indexOf(o) && (e.className += " " + o) }, r = function (e) { return "none" !== window.getComputedStyle(e).display }, l = e.conf, t = flowplayer.common, i = t.createElement, d = l.swf.indexOf("flowplayer.org") && l.e && o.getAttribute("data-origin"), p = d ? a(d) : t.hostname(), s = (document, l.key); "file:" == location.protocol && (p = "localhost"), e.load.ed = 1, l.hostname = p, l.origin = d || location.href, d && n(o, "is-embedded"), "string" == typeof s && (s = s.split(/,\s*/)); var f = function (e, a) { var n = i("a", { href: a, className: "fp-brand" }); n.innerHTML = e, t.find(".fp-controls", o)[0].appendChild(n) }; if (s && "function" == typeof key_check && key_check(s, p)) { if (l.logo) { var c = t.find(".fp-player", o)[0], h = i("a", { className: "fp-logo" }); d && (h.href = d), l.embed && l.embed.popup && (h.target = "_blank"); var y = i("img", { src: l.logo }); h.appendChild(y), (c || o).appendChild(h) } l.brand && d || l.brand && l.brand.showOnOrigin ? f(l.brand.text || l.brand, d || location.href) : t.addClass(o, "no-brand") } else { f("flowplayer", "http://flowplayer.org"); var h = i("a", { href: "http://flowplayer.org" }); o.appendChild(h); var u = i("div", { className: "fp-context-menu" }, '<ul><li class="copyright">&copy; 2015</li><li><a href="http://flowplayer.org">About Flowplayer</a></li><li><a href="http://flowplayer.org/license">GPL based license</a></li></ul>'), g = window.location.href.indexOf("localhost"), c = t.find(".fp-player", o)[0]; 7 !== g && (c || o).appendChild(u), e.on("pause resume finish unload ready", function (e, a) { t.removeClass(o, "no-brand"); var n = -1; if (a.video.src) for (var l = [["org", "flowplayer", "drive"], ["org", "flowplayer", "my"], ["org", "flowplayer", "cdn"]], i = 0; i < l.length && (n = a.video.src.indexOf("://" + l[i].reverse().join(".")), -1 === n); i++); if ((4 === n || 5 === n) && t.addClass(o, "no-brand"), /pause|resume/.test(e.type) && "flash" != a.engine.engineName && 4 != n && 5 != n) { var d = { display: "block", position: "absolute", left: "16px", bottom: "46px", zIndex: 99999, width: "100px", height: "20px", backgroundImage: "url(" + [".png", "logo", "/", ".net", ".cloudfront", "d32wqyuo10o653", "//"].reverse().join("") + ")" }; for (var p in d) d.hasOwnProperty(p) && (h.style[p] = d[p]); a.load.ed = r(h) && (7 === g || u.parentNode == o || u.parentNode == c) && !t.hasClass(o, "no-brand"), a.load.ed || a.pause() } else h.style.display = "none" }) } });
  2942. }, { "./engine/embed": 2, "./engine/flash": 3, "./engine/html5": 4, "./ext/analytics": 5, "./ext/cuepoint": 6, "./ext/embed": 7, "./ext/fullscreen": 9, "./ext/keyboard": 10, "./ext/mobile": 11, "./ext/playlist": 12, "./ext/subtitle": 15, "./ext/support": 16, "./ext/ui": 17, "./flowplayer": 18, "es5-shim": 25}], 20: [function (_dereq_, module, exports) {
  2943. /*!
  2944. * Bean - copyright (c) Jacob Thornton 2011-2012
  2945. * https://github.com/fat/bean
  2946. * MIT license
  2947. */
  2948. (function (name, context, definition) {
  2949. if (typeof module != 'undefined' && module.exports) module.exports = definition()
  2950. else if (typeof define == 'function' && define.amd) define(definition)
  2951. else context[name] = definition()
  2952. })('bean', this, function (name, context) {
  2953. name = name || 'bean'
  2954. context = context || this
  2955. var win = window
  2956. , old = context[name]
  2957. , namespaceRegex = /[^\.]*(?=\..*)\.|.*/
  2958. , nameRegex = /\..*/
  2959. , addEvent = 'addEventListener'
  2960. , removeEvent = 'removeEventListener'
  2961. , doc = document || {}
  2962. , root = doc.documentElement || {}
  2963. , W3C_MODEL = root[addEvent]
  2964. , eventSupport = W3C_MODEL ? addEvent : 'attachEvent'
  2965. , ONE = {} // singleton for quick matching making add() do one()
  2966. , slice = Array.prototype.slice
  2967. , str2arr = function (s, d) { return s.split(d || ' ') }
  2968. , isString = function (o) { return typeof o == 'string' }
  2969. , isFunction = function (o) { return typeof o == 'function' }
  2970. // events that we consider to be 'native', anything not in this list will
  2971. // be treated as a custom event
  2972. , standardNativeEvents =
  2973. 'click dblclick mouseup mousedown contextmenu ' + // mouse buttons
  2974. 'mousewheel mousemultiwheel DOMMouseScroll ' + // mouse wheel
  2975. 'mouseover mouseout mousemove selectstart selectend ' + // mouse movement
  2976. 'keydown keypress keyup ' + // keyboard
  2977. 'orientationchange ' + // mobile
  2978. 'focus blur change reset select submit ' + // form elements
  2979. 'load unload beforeunload resize move DOMContentLoaded ' + // window
  2980. 'readystatechange message ' + // window
  2981. 'error abort scroll ' // misc
  2982. // element.fireEvent('onXYZ'... is not forgiving if we try to fire an event
  2983. // that doesn't actually exist, so make sure we only do these on newer browsers
  2984. , w3cNativeEvents =
  2985. 'show ' + // mouse buttons
  2986. 'input invalid ' + // form elements
  2987. 'touchstart touchmove touchend touchcancel ' + // touch
  2988. 'gesturestart gesturechange gestureend ' + // gesture
  2989. 'textinput ' + // TextEvent
  2990. 'readystatechange pageshow pagehide popstate ' + // window
  2991. 'hashchange offline online ' + // window
  2992. 'afterprint beforeprint ' + // printing
  2993. 'dragstart dragenter dragover dragleave drag drop dragend ' + // dnd
  2994. 'loadstart progress suspend emptied stalled loadmetadata ' + // media
  2995. 'loadeddata canplay canplaythrough playing waiting seeking ' + // media
  2996. 'seeked ended durationchange timeupdate play pause ratechange ' + // media
  2997. 'volumechange cuechange ' + // media
  2998. 'checking noupdate downloading cached updateready obsolete ' // appcache
  2999. // convert to a hash for quick lookups
  3000. , nativeEvents = (function (hash, events, i) {
  3001. for (i = 0; i < events.length; i++) events[i] && (hash[events[i]] = 1)
  3002. return hash
  3003. } ({}, str2arr(standardNativeEvents + (W3C_MODEL ? w3cNativeEvents : ''))))
  3004. // custom events are events that we *fake*, they are not provided natively but
  3005. // we can use native events to generate them
  3006. , customEvents = (function () {
  3007. var isAncestor = 'compareDocumentPosition' in root
  3008. ? function (element, container) {
  3009. return container.compareDocumentPosition && (container.compareDocumentPosition(element) & 16) === 16
  3010. }
  3011. : 'contains' in root
  3012. ? function (element, container) {
  3013. container = container.nodeType === 9 || container === window ? root : container
  3014. return container !== element && container.contains(element)
  3015. }
  3016. : function (element, container) {
  3017. while (element = element.parentNode) if (element === container) return 1
  3018. return 0
  3019. }
  3020. , check = function (event) {
  3021. var related = event.relatedTarget
  3022. return !related
  3023. ? related == null
  3024. : (related !== this && related.prefix !== 'xul' && !/document/.test(this.toString())
  3025. && !isAncestor(related, this))
  3026. }
  3027. return {
  3028. mouseenter: { base: 'mouseover', condition: check }
  3029. , mouseleave: { base: 'mouseout', condition: check }
  3030. , mousewheel: { base: /Firefox/.test(navigator.userAgent) ? 'DOMMouseScroll' : 'mousewheel' }
  3031. }
  3032. } ())
  3033. // we provide a consistent Event object across browsers by taking the actual DOM
  3034. // event object and generating a new one from its properties.
  3035. , Event = (function () {
  3036. // a whitelist of properties (for different event types) tells us what to check for and copy
  3037. var commonProps = str2arr('altKey attrChange attrName bubbles cancelable ctrlKey currentTarget ' +
  3038. 'detail eventPhase getModifierState isTrusted metaKey relatedNode relatedTarget shiftKey ' +
  3039. 'srcElement target timeStamp type view which propertyName')
  3040. , mouseProps = commonProps.concat(str2arr('button buttons clientX clientY dataTransfer ' +
  3041. 'fromElement offsetX offsetY pageX pageY screenX screenY toElement'))
  3042. , mouseWheelProps = mouseProps.concat(str2arr('wheelDelta wheelDeltaX wheelDeltaY wheelDeltaZ ' +
  3043. 'axis')) // 'axis' is FF specific
  3044. , keyProps = commonProps.concat(str2arr('char charCode key keyCode keyIdentifier ' +
  3045. 'keyLocation location'))
  3046. , textProps = commonProps.concat(str2arr('data'))
  3047. , touchProps = commonProps.concat(str2arr('touches targetTouches changedTouches scale rotation'))
  3048. , messageProps = commonProps.concat(str2arr('data origin source'))
  3049. , stateProps = commonProps.concat(str2arr('state'))
  3050. , overOutRegex = /over|out/
  3051. // some event types need special handling and some need special properties, do that all here
  3052. , typeFixers = [
  3053. { // key events
  3054. reg: /key/i
  3055. , fix: function (event, newEvent) {
  3056. newEvent.keyCode = event.keyCode || event.which
  3057. return keyProps
  3058. }
  3059. }
  3060. , { // mouse events
  3061. reg: /click|mouse(?!(.*wheel|scroll))|menu|drag|drop/i
  3062. , fix: function (event, newEvent, type) {
  3063. newEvent.rightClick = event.which === 3 || event.button === 2
  3064. newEvent.pos = { x: 0, y: 0 }
  3065. if (event.pageX || event.pageY) {
  3066. newEvent.clientX = event.pageX
  3067. newEvent.clientY = event.pageY
  3068. } else if (event.clientX || event.clientY) {
  3069. newEvent.clientX = event.clientX + doc.body.scrollLeft + root.scrollLeft
  3070. newEvent.clientY = event.clientY + doc.body.scrollTop + root.scrollTop
  3071. }
  3072. if (overOutRegex.test(type)) {
  3073. newEvent.relatedTarget = event.relatedTarget
  3074. || event[(type == 'mouseover' ? 'from' : 'to') + 'Element']
  3075. }
  3076. return mouseProps
  3077. }
  3078. }
  3079. , { // mouse wheel events
  3080. reg: /mouse.*(wheel|scroll)/i
  3081. , fix: function () { return mouseWheelProps }
  3082. }
  3083. , { // TextEvent
  3084. reg: /^text/i
  3085. , fix: function () { return textProps }
  3086. }
  3087. , { // touch and gesture events
  3088. reg: /^touch|^gesture/i
  3089. , fix: function () { return touchProps }
  3090. }
  3091. , { // message events
  3092. reg: /^message$/i
  3093. , fix: function () { return messageProps }
  3094. }
  3095. , { // popstate events
  3096. reg: /^popstate$/i
  3097. , fix: function () { return stateProps }
  3098. }
  3099. , { // everything else
  3100. reg: /.*/
  3101. , fix: function () { return commonProps }
  3102. }
  3103. ]
  3104. , typeFixerMap = {} // used to map event types to fixer functions (above), a basic cache mechanism
  3105. , Event = function (event, element, isNative) {
  3106. if (!arguments.length) return
  3107. event = event || ((element.ownerDocument || element.document || element).parentWindow || win).event
  3108. this.originalEvent = event
  3109. this.isNative = isNative
  3110. this.isBean = true
  3111. if (!event) return
  3112. var type = event.type
  3113. , target = event.target || event.srcElement
  3114. , i, l, p, props, fixer
  3115. this.target = target && target.nodeType === 3 ? target.parentNode : target
  3116. if (isNative) { // we only need basic augmentation on custom events, the rest expensive & pointless
  3117. fixer = typeFixerMap[type]
  3118. if (!fixer) { // haven't encountered this event type before, map a fixer function for it
  3119. for (i = 0, l = typeFixers.length; i < l; i++) {
  3120. if (typeFixers[i].reg.test(type)) { // guaranteed to match at least one, last is .*
  3121. typeFixerMap[type] = fixer = typeFixers[i].fix
  3122. break
  3123. }
  3124. }
  3125. }
  3126. props = fixer(event, this, type)
  3127. for (i = props.length; i--; ) {
  3128. if (!((p = props[i]) in this) && p in event) this[p] = event[p]
  3129. }
  3130. }
  3131. }
  3132. // preventDefault() and stopPropagation() are a consistent interface to those functions
  3133. // on the DOM, stop() is an alias for both of them together
  3134. Event.prototype.preventDefault = function () {
  3135. if (this.originalEvent.preventDefault) this.originalEvent.preventDefault()
  3136. else this.originalEvent.returnValue = false
  3137. }
  3138. Event.prototype.stopPropagation = function () {
  3139. if (this.originalEvent.stopPropagation) this.originalEvent.stopPropagation()
  3140. else this.originalEvent.cancelBubble = true
  3141. }
  3142. Event.prototype.stop = function () {
  3143. this.preventDefault()
  3144. this.stopPropagation()
  3145. this.stopped = true
  3146. }
  3147. // stopImmediatePropagation() has to be handled internally because we manage the event list for
  3148. // each element
  3149. // note that originalElement may be a Bean#Event object in some situations
  3150. Event.prototype.stopImmediatePropagation = function () {
  3151. if (this.originalEvent.stopImmediatePropagation) this.originalEvent.stopImmediatePropagation()
  3152. this.isImmediatePropagationStopped = function () { return true }
  3153. }
  3154. Event.prototype.isImmediatePropagationStopped = function () {
  3155. return this.originalEvent.isImmediatePropagationStopped && this.originalEvent.isImmediatePropagationStopped()
  3156. }
  3157. Event.prototype.clone = function (currentTarget) {
  3158. //TODO: this is ripe for optimisation, new events are *expensive*
  3159. // improving this will speed up delegated events
  3160. var ne = new Event(this, this.element, this.isNative)
  3161. ne.currentTarget = currentTarget
  3162. return ne
  3163. }
  3164. return Event
  3165. } ())
  3166. // if we're in old IE we can't do onpropertychange on doc or win so we use doc.documentElement for both
  3167. , targetElement = function (element, isNative) {
  3168. return !W3C_MODEL && !isNative && (element === doc || element === win) ? root : element
  3169. }
  3170. /**
  3171. * Bean maintains an internal registry for event listeners. We don't touch elements, objects
  3172. * or functions to identify them, instead we store everything in the registry.
  3173. * Each event listener has a RegEntry object, we have one 'registry' for the whole instance.
  3174. */
  3175. , RegEntry = (function () {
  3176. // each handler is wrapped so we can handle delegation and custom events
  3177. var wrappedHandler = function (element, fn, condition, args) {
  3178. var call = function (event, eargs) {
  3179. return fn.apply(element, args ? slice.call(eargs, event ? 0 : 1).concat(args) : eargs)
  3180. }
  3181. , findTarget = function (event, eventElement) {
  3182. return fn.__beanDel ? fn.__beanDel.ft(event.target, element) : eventElement
  3183. }
  3184. , handler = condition
  3185. ? function (event) {
  3186. var target = findTarget(event, this) // deleated event
  3187. if (condition.apply(target, arguments)) {
  3188. if (event) event.currentTarget = target
  3189. return call(event, arguments)
  3190. }
  3191. }
  3192. : function (event) {
  3193. if (fn.__beanDel) event = event.clone(findTarget(event)) // delegated event, fix the fix
  3194. return call(event, arguments)
  3195. }
  3196. handler.__beanDel = fn.__beanDel
  3197. return handler
  3198. }
  3199. , RegEntry = function (element, type, handler, original, namespaces, args, root) {
  3200. var customType = customEvents[type]
  3201. , isNative
  3202. if (type == 'unload') {
  3203. // self clean-up
  3204. handler = once(removeListener, element, type, handler, original)
  3205. }
  3206. if (customType) {
  3207. if (customType.condition) {
  3208. handler = wrappedHandler(element, handler, customType.condition, args)
  3209. }
  3210. type = customType.base || type
  3211. }
  3212. this.isNative = isNative = nativeEvents[type] && !!element[eventSupport]
  3213. this.customType = !W3C_MODEL && !isNative && type
  3214. this.element = element
  3215. this.type = type
  3216. this.original = original
  3217. this.namespaces = namespaces
  3218. this.eventType = W3C_MODEL || isNative ? type : 'propertychange'
  3219. this.target = targetElement(element, isNative)
  3220. this[eventSupport] = !!this.target[eventSupport]
  3221. this.root = root
  3222. this.handler = wrappedHandler(element, handler, null, args)
  3223. }
  3224. // given a list of namespaces, is our entry in any of them?
  3225. RegEntry.prototype.inNamespaces = function (checkNamespaces) {
  3226. var i, j, c = 0
  3227. if (!checkNamespaces) return true
  3228. if (!this.namespaces) return false
  3229. for (i = checkNamespaces.length; i--; ) {
  3230. for (j = this.namespaces.length; j--; ) {
  3231. if (checkNamespaces[i] == this.namespaces[j]) c++
  3232. }
  3233. }
  3234. return checkNamespaces.length === c
  3235. }
  3236. // match by element, original fn (opt), handler fn (opt)
  3237. RegEntry.prototype.matches = function (checkElement, checkOriginal, checkHandler) {
  3238. return this.element === checkElement &&
  3239. (!checkOriginal || this.original === checkOriginal) &&
  3240. (!checkHandler || this.handler === checkHandler)
  3241. }
  3242. return RegEntry
  3243. } ())
  3244. , registry = (function () {
  3245. // our map stores arrays by event type, just because it's better than storing
  3246. // everything in a single array.
  3247. // uses '$' as a prefix for the keys for safety and 'r' as a special prefix for
  3248. // rootListeners so we can look them up fast
  3249. var map = {}
  3250. // generic functional search of our registry for matching listeners,
  3251. // `fn` returns false to break out of the loop
  3252. , forAll = function (element, type, original, handler, root, fn) {
  3253. var pfx = root ? 'r' : '$'
  3254. if (!type || type == '*') {
  3255. // search the whole registry
  3256. for (var t in map) {
  3257. if (t.charAt(0) == pfx) {
  3258. forAll(element, t.substr(1), original, handler, root, fn)
  3259. }
  3260. }
  3261. } else {
  3262. var i = 0, l, list = map[pfx + type], all = element == '*'
  3263. if (!list) return
  3264. for (l = list.length; i < l; i++) {
  3265. if ((all || list[i].matches(element, original, handler)) && !fn(list[i], list, i, type)) return
  3266. }
  3267. }
  3268. }
  3269. , has = function (element, type, original, root) {
  3270. // we're not using forAll here simply because it's a bit slower and this
  3271. // needs to be fast
  3272. var i, list = map[(root ? 'r' : '$') + type]
  3273. if (list) {
  3274. for (i = list.length; i--; ) {
  3275. if (!list[i].root && list[i].matches(element, original, null)) return true
  3276. }
  3277. }
  3278. return false
  3279. }
  3280. , get = function (element, type, original, root) {
  3281. var entries = []
  3282. forAll(element, type, original, null, root, function (entry) {
  3283. return entries.push(entry)
  3284. })
  3285. return entries
  3286. }
  3287. , put = function (entry) {
  3288. var has = !entry.root && !this.has(entry.element, entry.type, null, false)
  3289. , key = (entry.root ? 'r' : '$') + entry.type
  3290. ; (map[key] || (map[key] = [])).push(entry)
  3291. return has
  3292. }
  3293. , del = function (entry) {
  3294. forAll(entry.element, entry.type, null, entry.handler, entry.root, function (entry, list, i) {
  3295. list.splice(i, 1)
  3296. entry.removed = true
  3297. if (list.length === 0) delete map[(entry.root ? 'r' : '$') + entry.type]
  3298. return false
  3299. })
  3300. }
  3301. // dump all entries, used for onunload
  3302. , entries = function () {
  3303. var t, entries = []
  3304. for (t in map) {
  3305. if (t.charAt(0) == '$') entries = entries.concat(map[t])
  3306. }
  3307. return entries
  3308. }
  3309. return { has: has, get: get, put: put, del: del, entries: entries }
  3310. } ())
  3311. // we need a selector engine for delegated events, use querySelectorAll if it exists
  3312. // but for older browsers we need Qwery, Sizzle or similar
  3313. , selectorEngine
  3314. , setSelectorEngine = function (e) {
  3315. if (!arguments.length) {
  3316. selectorEngine = doc.querySelectorAll
  3317. ? function (s, r) {
  3318. return r.querySelectorAll(s)
  3319. }
  3320. : function () {
  3321. throw new Error('Bean: No selector engine installed') // eeek
  3322. }
  3323. } else {
  3324. selectorEngine = e
  3325. }
  3326. }
  3327. // we attach this listener to each DOM event that we need to listen to, only once
  3328. // per event type per DOM element
  3329. , rootListener = function (event, type) {
  3330. if (!W3C_MODEL && type && event && event.propertyName != '_on' + type) return
  3331. var listeners = registry.get(this, type || event.type, null, false)
  3332. , l = listeners.length
  3333. , i = 0
  3334. event = new Event(event, this, true)
  3335. if (type) event.type = type
  3336. // iterate through all handlers registered for this type, calling them unless they have
  3337. // been removed by a previous handler or stopImmediatePropagation() has been called
  3338. for (; i < l && !event.isImmediatePropagationStopped(); i++) {
  3339. if (!listeners[i].removed) listeners[i].handler.call(this, event)
  3340. }
  3341. }
  3342. // add and remove listeners to DOM elements
  3343. , listener = W3C_MODEL
  3344. ? function (element, type, add) {
  3345. // new browsers
  3346. element[add ? addEvent : removeEvent](type, rootListener, false)
  3347. }
  3348. : function (element, type, add, custom) {
  3349. // IE8 and below, use attachEvent/detachEvent and we have to piggy-back propertychange events
  3350. // to simulate event bubbling etc.
  3351. var entry
  3352. if (add) {
  3353. registry.put(entry = new RegEntry(
  3354. element
  3355. , custom || type
  3356. , function (event) { // handler
  3357. rootListener.call(element, event, custom)
  3358. }
  3359. , rootListener
  3360. , null
  3361. , null
  3362. , true // is root
  3363. ))
  3364. if (custom && element['_on' + custom] == null) element['_on' + custom] = 0
  3365. entry.target.attachEvent('on' + entry.eventType, entry.handler)
  3366. } else {
  3367. entry = registry.get(element, custom || type, rootListener, true)[0]
  3368. if (entry) {
  3369. entry.target.detachEvent('on' + entry.eventType, entry.handler)
  3370. registry.del(entry)
  3371. }
  3372. }
  3373. }
  3374. , once = function (rm, element, type, fn, originalFn) {
  3375. // wrap the handler in a handler that does a remove as well
  3376. return function () {
  3377. fn.apply(this, arguments)
  3378. rm(element, type, originalFn)
  3379. }
  3380. }
  3381. , removeListener = function (element, orgType, handler, namespaces) {
  3382. var type = orgType && orgType.replace(nameRegex, '')
  3383. , handlers = registry.get(element, type, null, false)
  3384. , removed = {}
  3385. , i, l
  3386. for (i = 0, l = handlers.length; i < l; i++) {
  3387. if ((!handler || handlers[i].original === handler) && handlers[i].inNamespaces(namespaces)) {
  3388. // TODO: this is problematic, we have a registry.get() and registry.del() that
  3389. // both do registry searches so we waste cycles doing this. Needs to be rolled into
  3390. // a single registry.forAll(fn) that removes while finding, but the catch is that
  3391. // we'll be splicing the arrays that we're iterating over. Needs extra tests to
  3392. // make sure we don't screw it up. @rvagg
  3393. registry.del(handlers[i])
  3394. if (!removed[handlers[i].eventType] && handlers[i][eventSupport])
  3395. removed[handlers[i].eventType] = { t: handlers[i].eventType, c: handlers[i].type }
  3396. }
  3397. }
  3398. // check each type/element for removed listeners and remove the rootListener where it's no longer needed
  3399. for (i in removed) {
  3400. if (!registry.has(element, removed[i].t, null, false)) {
  3401. // last listener of this type, remove the rootListener
  3402. listener(element, removed[i].t, false, removed[i].c)
  3403. }
  3404. }
  3405. }
  3406. // set up a delegate helper using the given selector, wrap the handler function
  3407. , delegate = function (selector, fn) {
  3408. //TODO: findTarget (therefore $) is called twice, once for match and once for
  3409. // setting e.currentTarget, fix this so it's only needed once
  3410. var findTarget = function (target, root) {
  3411. var i, array = isString(selector) ? selectorEngine(selector, root) : selector
  3412. for (; target && target !== root; target = target.parentNode) {
  3413. for (i = array.length; i--; ) {
  3414. if (array[i] === target) return target
  3415. }
  3416. }
  3417. }
  3418. , handler = function (e) {
  3419. var match = findTarget(e.target, this)
  3420. if (match) fn.apply(match, arguments)
  3421. }
  3422. // __beanDel isn't pleasant but it's a private function, not exposed outside of Bean
  3423. handler.__beanDel = {
  3424. ft: findTarget // attach it here for customEvents to use too
  3425. , selector: selector
  3426. }
  3427. return handler
  3428. }
  3429. , fireListener = W3C_MODEL ? function (isNative, type, element) {
  3430. // modern browsers, do a proper dispatchEvent()
  3431. var evt = doc.createEvent(isNative ? 'HTMLEvents' : 'UIEvents')
  3432. evt[isNative ? 'initEvent' : 'initUIEvent'](type, true, true, win, 1)
  3433. element.dispatchEvent(evt)
  3434. } : function (isNative, type, element) {
  3435. // old browser use onpropertychange, just increment a custom property to trigger the event
  3436. element = targetElement(element, isNative)
  3437. isNative ? element.fireEvent('on' + type, doc.createEventObject()) : element['_on' + type]++
  3438. }
  3439. /**
  3440. * Public API: off(), on(), add(), (remove()), one(), fire(), clone()
  3441. */
  3442. /**
  3443. * off(element[, eventType(s)[, handler ]])
  3444. */
  3445. , off = function (element, typeSpec, fn) {
  3446. var isTypeStr = isString(typeSpec)
  3447. , k, type, namespaces, i
  3448. if (isTypeStr && typeSpec.indexOf(' ') > 0) {
  3449. // off(el, 't1 t2 t3', fn) or off(el, 't1 t2 t3')
  3450. typeSpec = str2arr(typeSpec)
  3451. for (i = typeSpec.length; i--; )
  3452. off(element, typeSpec[i], fn)
  3453. return element
  3454. }
  3455. type = isTypeStr && typeSpec.replace(nameRegex, '')
  3456. if (type && customEvents[type]) type = customEvents[type].base
  3457. if (!typeSpec || isTypeStr) {
  3458. // off(el) or off(el, t1.ns) or off(el, .ns) or off(el, .ns1.ns2.ns3)
  3459. if (namespaces = isTypeStr && typeSpec.replace(namespaceRegex, '')) namespaces = str2arr(namespaces, '.')
  3460. removeListener(element, type, fn, namespaces)
  3461. } else if (isFunction(typeSpec)) {
  3462. // off(el, fn)
  3463. removeListener(element, null, typeSpec)
  3464. } else {
  3465. // off(el, { t1: fn1, t2, fn2 })
  3466. for (k in typeSpec) {
  3467. if (typeSpec.hasOwnProperty(k)) off(element, k, typeSpec[k])
  3468. }
  3469. }
  3470. return element
  3471. }
  3472. /**
  3473. * on(element, eventType(s)[, selector], handler[, args ])
  3474. */
  3475. , on = function (element, events, selector, fn) {
  3476. var originalFn, type, types, i, args, entry, first
  3477. //TODO: the undefined check means you can't pass an 'args' argument, fix this perhaps?
  3478. if (selector === undefined && typeof events == 'object') {
  3479. //TODO: this can't handle delegated events
  3480. for (type in events) {
  3481. if (events.hasOwnProperty(type)) {
  3482. on.call(this, element, type, events[type])
  3483. }
  3484. }
  3485. return
  3486. }
  3487. if (!isFunction(selector)) {
  3488. // delegated event
  3489. originalFn = fn
  3490. args = slice.call(arguments, 4)
  3491. fn = delegate(selector, originalFn, selectorEngine)
  3492. } else {
  3493. args = slice.call(arguments, 3)
  3494. fn = originalFn = selector
  3495. }
  3496. types = str2arr(events)
  3497. // special case for one(), wrap in a self-removing handler
  3498. if (this === ONE) {
  3499. fn = once(off, element, events, fn, originalFn)
  3500. }
  3501. for (i = types.length; i--; ) {
  3502. // add new handler to the registry and check if it's the first for this element/type
  3503. first = registry.put(entry = new RegEntry(
  3504. element
  3505. , types[i].replace(nameRegex, '') // event type
  3506. , fn
  3507. , originalFn
  3508. , str2arr(types[i].replace(namespaceRegex, ''), '.') // namespaces
  3509. , args
  3510. , false // not root
  3511. ))
  3512. if (entry[eventSupport] && first) {
  3513. // first event of this type on this element, add root listener
  3514. listener(element, entry.eventType, true, entry.customType)
  3515. }
  3516. }
  3517. return element
  3518. }
  3519. /**
  3520. * add(element[, selector], eventType(s), handler[, args ])
  3521. *
  3522. * Deprecated: kept (for now) for backward-compatibility
  3523. */
  3524. , add = function (element, events, fn, delfn) {
  3525. return on.apply(
  3526. null
  3527. , !isString(fn)
  3528. ? slice.call(arguments)
  3529. : [element, fn, events, delfn].concat(arguments.length > 3 ? slice.call(arguments, 5) : [])
  3530. )
  3531. }
  3532. /**
  3533. * one(element, eventType(s)[, selector], handler[, args ])
  3534. */
  3535. , one = function () {
  3536. return on.apply(ONE, arguments)
  3537. }
  3538. /**
  3539. * fire(element, eventType(s)[, args ])
  3540. *
  3541. * The optional 'args' argument must be an array, if no 'args' argument is provided
  3542. * then we can use the browser's DOM event system, otherwise we trigger handlers manually
  3543. */
  3544. , fire = function (element, type, args) {
  3545. var types = str2arr(type)
  3546. , i, j, l, names, handlers
  3547. for (i = types.length; i--; ) {
  3548. type = types[i].replace(nameRegex, '')
  3549. if (names = types[i].replace(namespaceRegex, '')) names = str2arr(names, '.')
  3550. if (!names && !args && element[eventSupport]) {
  3551. fireListener(nativeEvents[type], type, element)
  3552. } else {
  3553. // non-native event, either because of a namespace, arguments or a non DOM element
  3554. // iterate over all listeners and manually 'fire'
  3555. handlers = registry.get(element, type, null, false)
  3556. args = [false].concat(args)
  3557. for (j = 0, l = handlers.length; j < l; j++) {
  3558. if (handlers[j].inNamespaces(names)) {
  3559. handlers[j].handler.apply(element, args)
  3560. }
  3561. }
  3562. }
  3563. }
  3564. return element
  3565. }
  3566. /**
  3567. * clone(dstElement, srcElement[, eventType ])
  3568. *
  3569. * TODO: perhaps for consistency we should allow the same flexibility in type specifiers?
  3570. */
  3571. , clone = function (element, from, type) {
  3572. var handlers = registry.get(from, type, null, false)
  3573. , l = handlers.length
  3574. , i = 0
  3575. , args, beanDel
  3576. for (; i < l; i++) {
  3577. if (handlers[i].original) {
  3578. args = [element, handlers[i].type]
  3579. if (beanDel = handlers[i].handler.__beanDel) args.push(beanDel.selector)
  3580. args.push(handlers[i].original)
  3581. on.apply(null, args)
  3582. }
  3583. }
  3584. return element
  3585. }
  3586. , bean = {
  3587. 'on': on
  3588. , 'add': add
  3589. , 'one': one
  3590. , 'off': off
  3591. , 'remove': off
  3592. , 'clone': clone
  3593. , 'fire': fire
  3594. , 'Event': Event
  3595. , 'setSelectorEngine': setSelectorEngine
  3596. , 'noConflict': function () {
  3597. context[name] = old
  3598. return this
  3599. }
  3600. }
  3601. // for IE, clean up on unload to avoid leaks
  3602. if (win.attachEvent) {
  3603. var cleanup = function () {
  3604. var i, entries = registry.entries()
  3605. for (i in entries) {
  3606. if (entries[i].type && entries[i].type !== 'unload') off(entries[i].element, entries[i].type)
  3607. }
  3608. win.detachEvent('onunload', cleanup)
  3609. win.CollectGarbage && win.CollectGarbage()
  3610. }
  3611. win.attachEvent('onunload', cleanup)
  3612. }
  3613. // initialize selector engine to internal default (qSA or throw Error)
  3614. setSelectorEngine()
  3615. return bean
  3616. });
  3617. }, {}], 21: [function (_dereq_, module, exports) {
  3618. (function (global) {
  3619. /*! http://mths.be/punycode v1.2.4 by @mathias */
  3620. ; (function (root) {
  3621. /** Detect free variables */
  3622. var freeExports = typeof exports == 'object' && exports;
  3623. var freeModule = typeof module == 'object' && module &&
  3624. module.exports == freeExports && module;
  3625. var freeGlobal = typeof global == 'object' && global;
  3626. if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
  3627. root = freeGlobal;
  3628. }
  3629. /**
  3630. * The `punycode` object.
  3631. * @name punycode
  3632. * @type Object
  3633. */
  3634. var punycode,
  3635. /** Highest positive signed 32-bit float value */
  3636. maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1
  3637. /** Bootstring parameters */
  3638. base = 36,
  3639. tMin = 1,
  3640. tMax = 26,
  3641. skew = 38,
  3642. damp = 700,
  3643. initialBias = 72,
  3644. initialN = 128, // 0x80
  3645. delimiter = '-', // '\x2D'
  3646. /** Regular expressions */
  3647. regexPunycode = /^xn--/,
  3648. regexNonASCII = /[^ -~]/, // unprintable ASCII chars + non-ASCII chars
  3649. regexSeparators = /\x2E|\u3002|\uFF0E|\uFF61/g, // RFC 3490 separators
  3650. /** Error messages */
  3651. errors = {
  3652. 'overflow': 'Overflow: input needs wider integers to process',
  3653. 'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
  3654. 'invalid-input': 'Invalid input'
  3655. },
  3656. /** Convenience shortcuts */
  3657. baseMinusTMin = base - tMin,
  3658. floor = Math.floor,
  3659. stringFromCharCode = String.fromCharCode,
  3660. /** Temporary variable */
  3661. key;
  3662. /*--------------------------------------------------------------------------*/
  3663. /**
  3664. * A generic error utility function.
  3665. * @private
  3666. * @param {String} type The error type.
  3667. * @returns {Error} Throws a `RangeError` with the applicable error message.
  3668. */
  3669. function error(type) {
  3670. throw RangeError(errors[type]);
  3671. }
  3672. /**
  3673. * A generic `Array#map` utility function.
  3674. * @private
  3675. * @param {Array} array The array to iterate over.
  3676. * @param {Function} callback The function that gets called for every array
  3677. * item.
  3678. * @returns {Array} A new array of values returned by the callback function.
  3679. */
  3680. function map(array, fn) {
  3681. var length = array.length;
  3682. while (length--) {
  3683. array[length] = fn(array[length]);
  3684. }
  3685. return array;
  3686. }
  3687. /**
  3688. * A simple `Array#map`-like wrapper to work with domain name strings.
  3689. * @private
  3690. * @param {String} domain The domain name.
  3691. * @param {Function} callback The function that gets called for every
  3692. * character.
  3693. * @returns {Array} A new string of characters returned by the callback
  3694. * function.
  3695. */
  3696. function mapDomain(string, fn) {
  3697. return map(string.split(regexSeparators), fn).join('.');
  3698. }
  3699. /**
  3700. * Creates an array containing the numeric code points of each Unicode
  3701. * character in the string. While JavaScript uses UCS-2 internally,
  3702. * this function will convert a pair of surrogate halves (each of which
  3703. * UCS-2 exposes as separate characters) into a single code point,
  3704. * matching UTF-16.
  3705. * @see `punycode.ucs2.encode`
  3706. * @see <http://mathiasbynens.be/notes/javascript-encoding>
  3707. * @memberOf punycode.ucs2
  3708. * @name decode
  3709. * @param {String} string The Unicode input string (UCS-2).
  3710. * @returns {Array} The new array of code points.
  3711. */
  3712. function ucs2decode(string) {
  3713. var output = [],
  3714. counter = 0,
  3715. length = string.length,
  3716. value,
  3717. extra;
  3718. while (counter < length) {
  3719. value = string.charCodeAt(counter++);
  3720. if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
  3721. // high surrogate, and there is a next character
  3722. extra = string.charCodeAt(counter++);
  3723. if ((extra & 0xFC00) == 0xDC00) { // low surrogate
  3724. output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
  3725. } else {
  3726. // unmatched surrogate; only append this code unit, in case the next
  3727. // code unit is the high surrogate of a surrogate pair
  3728. output.push(value);
  3729. counter--;
  3730. }
  3731. } else {
  3732. output.push(value);
  3733. }
  3734. }
  3735. return output;
  3736. }
  3737. /**
  3738. * Creates a string based on an array of numeric code points.
  3739. * @see `punycode.ucs2.decode`
  3740. * @memberOf punycode.ucs2
  3741. * @name encode
  3742. * @param {Array} codePoints The array of numeric code points.
  3743. * @returns {String} The new Unicode string (UCS-2).
  3744. */
  3745. function ucs2encode(array) {
  3746. return map(array, function (value) {
  3747. var output = '';
  3748. if (value > 0xFFFF) {
  3749. value -= 0x10000;
  3750. output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
  3751. value = 0xDC00 | value & 0x3FF;
  3752. }
  3753. output += stringFromCharCode(value);
  3754. return output;
  3755. }).join('');
  3756. }
  3757. /**
  3758. * Converts a basic code point into a digit/integer.
  3759. * @see `digitToBasic()`
  3760. * @private
  3761. * @param {Number} codePoint The basic numeric code point value.
  3762. * @returns {Number} The numeric value of a basic code point (for use in
  3763. * representing integers) in the range `0` to `base - 1`, or `base` if
  3764. * the code point does not represent a value.
  3765. */
  3766. function basicToDigit(codePoint) {
  3767. if (codePoint - 48 < 10) {
  3768. return codePoint - 22;
  3769. }
  3770. if (codePoint - 65 < 26) {
  3771. return codePoint - 65;
  3772. }
  3773. if (codePoint - 97 < 26) {
  3774. return codePoint - 97;
  3775. }
  3776. return base;
  3777. }
  3778. /**
  3779. * Converts a digit/integer into a basic code point.
  3780. * @see `basicToDigit()`
  3781. * @private
  3782. * @param {Number} digit The numeric value of a basic code point.
  3783. * @returns {Number} The basic code point whose value (when used for
  3784. * representing integers) is `digit`, which needs to be in the range
  3785. * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
  3786. * used; else, the lowercase form is used. The behavior is undefined
  3787. * if `flag` is non-zero and `digit` has no uppercase form.
  3788. */
  3789. function digitToBasic(digit, flag) {
  3790. // 0..25 map to ASCII a..z or A..Z
  3791. // 26..35 map to ASCII 0..9
  3792. return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
  3793. }
  3794. /**
  3795. * Bias adaptation function as per section 3.4 of RFC 3492.
  3796. * http://tools.ietf.org/html/rfc3492#section-3.4
  3797. * @private
  3798. */
  3799. function adapt(delta, numPoints, firstTime) {
  3800. var k = 0;
  3801. delta = firstTime ? floor(delta / damp) : delta >> 1;
  3802. delta += floor(delta / numPoints);
  3803. for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
  3804. delta = floor(delta / baseMinusTMin);
  3805. }
  3806. return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
  3807. }
  3808. /**
  3809. * Converts a Punycode string of ASCII-only symbols to a string of Unicode
  3810. * symbols.
  3811. * @memberOf punycode
  3812. * @param {String} input The Punycode string of ASCII-only symbols.
  3813. * @returns {String} The resulting string of Unicode symbols.
  3814. */
  3815. function decode(input) {
  3816. // Don't use UCS-2
  3817. var output = [],
  3818. inputLength = input.length,
  3819. out,
  3820. i = 0,
  3821. n = initialN,
  3822. bias = initialBias,
  3823. basic,
  3824. j,
  3825. index,
  3826. oldi,
  3827. w,
  3828. k,
  3829. digit,
  3830. t,
  3831. /** Cached calculation results */
  3832. baseMinusT;
  3833. // Handle the basic code points: let `basic` be the number of input code
  3834. // points before the last delimiter, or `0` if there is none, then copy
  3835. // the first basic code points to the output.
  3836. basic = input.lastIndexOf(delimiter);
  3837. if (basic < 0) {
  3838. basic = 0;
  3839. }
  3840. for (j = 0; j < basic; ++j) {
  3841. // if it's not a basic code point
  3842. if (input.charCodeAt(j) >= 0x80) {
  3843. error('not-basic');
  3844. }
  3845. output.push(input.charCodeAt(j));
  3846. }
  3847. // Main decoding loop: start just after the last delimiter if any basic code
  3848. // points were copied; start at the beginning otherwise.
  3849. for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {
  3850. // `index` is the index of the next character to be consumed.
  3851. // Decode a generalized variable-length integer into `delta`,
  3852. // which gets added to `i`. The overflow checking is easier
  3853. // if we increase `i` as we go, then subtract off its starting
  3854. // value at the end to obtain `delta`.
  3855. for (oldi = i, w = 1, k = base; /* no condition */; k += base) {
  3856. if (index >= inputLength) {
  3857. error('invalid-input');
  3858. }
  3859. digit = basicToDigit(input.charCodeAt(index++));
  3860. if (digit >= base || digit > floor((maxInt - i) / w)) {
  3861. error('overflow');
  3862. }
  3863. i += digit * w;
  3864. t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
  3865. if (digit < t) {
  3866. break;
  3867. }
  3868. baseMinusT = base - t;
  3869. if (w > floor(maxInt / baseMinusT)) {
  3870. error('overflow');
  3871. }
  3872. w *= baseMinusT;
  3873. }
  3874. out = output.length + 1;
  3875. bias = adapt(i - oldi, out, oldi == 0);
  3876. // `i` was supposed to wrap around from `out` to `0`,
  3877. // incrementing `n` each time, so we'll fix that now:
  3878. if (floor(i / out) > maxInt - n) {
  3879. error('overflow');
  3880. }
  3881. n += floor(i / out);
  3882. i %= out;
  3883. // Insert `n` at position `i` of the output
  3884. output.splice(i++, 0, n);
  3885. }
  3886. return ucs2encode(output);
  3887. }
  3888. /**
  3889. * Converts a string of Unicode symbols to a Punycode string of ASCII-only
  3890. * symbols.
  3891. * @memberOf punycode
  3892. * @param {String} input The string of Unicode symbols.
  3893. * @returns {String} The resulting Punycode string of ASCII-only symbols.
  3894. */
  3895. function encode(input) {
  3896. var n,
  3897. delta,
  3898. handledCPCount,
  3899. basicLength,
  3900. bias,
  3901. j,
  3902. m,
  3903. q,
  3904. k,
  3905. t,
  3906. currentValue,
  3907. output = [],
  3908. /** `inputLength` will hold the number of code points in `input`. */
  3909. inputLength,
  3910. /** Cached calculation results */
  3911. handledCPCountPlusOne,
  3912. baseMinusT,
  3913. qMinusT;
  3914. // Convert the input in UCS-2 to Unicode
  3915. input = ucs2decode(input);
  3916. // Cache the length
  3917. inputLength = input.length;
  3918. // Initialize the state
  3919. n = initialN;
  3920. delta = 0;
  3921. bias = initialBias;
  3922. // Handle the basic code points
  3923. for (j = 0; j < inputLength; ++j) {
  3924. currentValue = input[j];
  3925. if (currentValue < 0x80) {
  3926. output.push(stringFromCharCode(currentValue));
  3927. }
  3928. }
  3929. handledCPCount = basicLength = output.length;
  3930. // `handledCPCount` is the number of code points that have been handled;
  3931. // `basicLength` is the number of basic code points.
  3932. // Finish the basic string - if it is not empty - with a delimiter
  3933. if (basicLength) {
  3934. output.push(delimiter);
  3935. }
  3936. // Main encoding loop:
  3937. while (handledCPCount < inputLength) {
  3938. // All non-basic code points < n have been handled already. Find the next
  3939. // larger one:
  3940. for (m = maxInt, j = 0; j < inputLength; ++j) {
  3941. currentValue = input[j];
  3942. if (currentValue >= n && currentValue < m) {
  3943. m = currentValue;
  3944. }
  3945. }
  3946. // Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,
  3947. // but guard against overflow
  3948. handledCPCountPlusOne = handledCPCount + 1;
  3949. if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
  3950. error('overflow');
  3951. }
  3952. delta += (m - n) * handledCPCountPlusOne;
  3953. n = m;
  3954. for (j = 0; j < inputLength; ++j) {
  3955. currentValue = input[j];
  3956. if (currentValue < n && ++delta > maxInt) {
  3957. error('overflow');
  3958. }
  3959. if (currentValue == n) {
  3960. // Represent delta as a generalized variable-length integer
  3961. for (q = delta, k = base; /* no condition */; k += base) {
  3962. t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
  3963. if (q < t) {
  3964. break;
  3965. }
  3966. qMinusT = q - t;
  3967. baseMinusT = base - t;
  3968. output.push(
  3969. stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
  3970. );
  3971. q = floor(qMinusT / baseMinusT);
  3972. }
  3973. output.push(stringFromCharCode(digitToBasic(q, 0)));
  3974. bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
  3975. delta = 0;
  3976. ++handledCPCount;
  3977. }
  3978. }
  3979. ++delta;
  3980. ++n;
  3981. }
  3982. return output.join('');
  3983. }
  3984. /**
  3985. * Converts a Punycode string representing a domain name to Unicode. Only the
  3986. * Punycoded parts of the domain name will be converted, i.e. it doesn't
  3987. * matter if you call it on a string that has already been converted to
  3988. * Unicode.
  3989. * @memberOf punycode
  3990. * @param {String} domain The Punycode domain name to convert to Unicode.
  3991. * @returns {String} The Unicode representation of the given Punycode
  3992. * string.
  3993. */
  3994. function toUnicode(domain) {
  3995. return mapDomain(domain, function (string) {
  3996. return regexPunycode.test(string)
  3997. ? decode(string.slice(4).toLowerCase())
  3998. : string;
  3999. });
  4000. }
  4001. /**
  4002. * Converts a Unicode string representing a domain name to Punycode. Only the
  4003. * non-ASCII parts of the domain name will be converted, i.e. it doesn't
  4004. * matter if you call it with a domain that's already in ASCII.
  4005. * @memberOf punycode
  4006. * @param {String} domain The domain name to convert, as a Unicode string.
  4007. * @returns {String} The Punycode representation of the given domain name.
  4008. */
  4009. function toASCII(domain) {
  4010. return mapDomain(domain, function (string) {
  4011. return regexNonASCII.test(string)
  4012. ? 'xn--' + encode(string)
  4013. : string;
  4014. });
  4015. }
  4016. /*--------------------------------------------------------------------------*/
  4017. /** Define the public API */
  4018. punycode = {
  4019. /**
  4020. * A string representing the current Punycode.js version number.
  4021. * @memberOf punycode
  4022. * @type String
  4023. */
  4024. 'version': '1.2.4',
  4025. /**
  4026. * An object of methods to convert from JavaScript's internal character
  4027. * representation (UCS-2) to Unicode code points, and back.
  4028. * @see <http://mathiasbynens.be/notes/javascript-encoding>
  4029. * @memberOf punycode
  4030. * @type Object
  4031. */
  4032. 'ucs2': {
  4033. 'decode': ucs2decode,
  4034. 'encode': ucs2encode
  4035. },
  4036. 'decode': decode,
  4037. 'encode': encode,
  4038. 'toASCII': toASCII,
  4039. 'toUnicode': toUnicode
  4040. };
  4041. /** Expose `punycode` */
  4042. // Some AMD build optimizers, like r.js, check for specific condition patterns
  4043. // like the following:
  4044. if (
  4045. typeof define == 'function' &&
  4046. typeof define.amd == 'object' &&
  4047. define.amd
  4048. ) {
  4049. define('punycode', function () {
  4050. return punycode;
  4051. });
  4052. } else if (freeExports && !freeExports.nodeType) {
  4053. if (freeModule) { // in Node.js or RingoJS v0.8.0+
  4054. freeModule.exports = punycode;
  4055. } else { // in Narwhal or RingoJS v0.7.0-
  4056. for (key in punycode) {
  4057. punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
  4058. }
  4059. }
  4060. } else { // in Rhino or a web browser
  4061. root.punycode = punycode;
  4062. }
  4063. } (this));
  4064. }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  4065. }, {}], 22: [function (_dereq_, module, exports) {
  4066. // contains, add, remove, toggle
  4067. var indexof = _dereq_('indexof')
  4068. module.exports = ClassList
  4069. function ClassList(elem) {
  4070. var cl = elem.classList
  4071. if (cl) {
  4072. return cl
  4073. }
  4074. var classList = {
  4075. add: add
  4076. , remove: remove
  4077. , contains: contains
  4078. , toggle: toggle
  4079. , toString: $toString
  4080. , length: 0
  4081. , item: item
  4082. }
  4083. return classList
  4084. function add(token) {
  4085. var list = getTokens()
  4086. if (indexof(list, token) > -1) {
  4087. return
  4088. }
  4089. list.push(token)
  4090. setTokens(list)
  4091. }
  4092. function remove(token) {
  4093. var list = getTokens()
  4094. , index = indexof(list, token)
  4095. if (index === -1) {
  4096. return
  4097. }
  4098. list.splice(index, 1)
  4099. setTokens(list)
  4100. }
  4101. function contains(token) {
  4102. return indexof(getTokens(), token) > -1
  4103. }
  4104. function toggle(token) {
  4105. if (contains(token)) {
  4106. remove(token)
  4107. return false
  4108. } else {
  4109. add(token)
  4110. return true
  4111. }
  4112. }
  4113. function $toString() {
  4114. return elem.className
  4115. }
  4116. function item(index) {
  4117. var tokens = getTokens()
  4118. return tokens[index] || null
  4119. }
  4120. function getTokens() {
  4121. var className = elem.className
  4122. return filter(className.split(" "), isTruthy)
  4123. }
  4124. function setTokens(list) {
  4125. var length = list.length
  4126. elem.className = list.join(" ")
  4127. classList.length = length
  4128. for (var i = 0; i < list.length; i++) {
  4129. classList[i] = list[i]
  4130. }
  4131. delete list[length]
  4132. }
  4133. }
  4134. function filter(arr, fn) {
  4135. var ret = []
  4136. for (var i = 0; i < arr.length; i++) {
  4137. if (fn(arr[i])) ret.push(arr[i])
  4138. }
  4139. return ret
  4140. }
  4141. function isTruthy(value) {
  4142. return !!value
  4143. }
  4144. }, { "indexof": 23}], 23: [function (_dereq_, module, exports) {
  4145. var indexOf = [].indexOf;
  4146. module.exports = function (arr, obj) {
  4147. if (indexOf) return arr.indexOf(obj);
  4148. for (var i = 0; i < arr.length; ++i) {
  4149. if (arr[i] === obj) return i;
  4150. }
  4151. return -1;
  4152. };
  4153. }, {}], 24: [function (_dereq_, module, exports) {
  4154. // DEV: We don't use var but favor parameters since these play nicer with minification
  4155. function computedStyle(el, prop, getComputedStyle, style) {
  4156. getComputedStyle = window.getComputedStyle;
  4157. style =
  4158. // If we have getComputedStyle
  4159. getComputedStyle ?
  4160. // Query it
  4161. // TODO: From CSS-Query notes, we might need (node, null) for FF
  4162. getComputedStyle(el) :
  4163. // Otherwise, we are in IE and use currentStyle
  4164. el.currentStyle;
  4165. if (style) {
  4166. return style
  4167. [
  4168. // Switch to camelCase for CSSOM
  4169. // DEV: Grabbed from jQuery
  4170. // https://github.com/jquery/jquery/blob/1.9-stable/src/css.js#L191-L194
  4171. // https://github.com/jquery/jquery/blob/1.9-stable/src/core.js#L593-L597
  4172. prop.replace(/-(\w)/gi, function (word, letter) {
  4173. return letter.toUpperCase();
  4174. })
  4175. ];
  4176. }
  4177. }
  4178. module.exports = computedStyle;
  4179. }, {}], 25: [function (_dereq_, module, exports) {
  4180. /*!
  4181. * https://github.com/es-shims/es5-shim
  4182. * @license es5-shim Copyright 2009-2015 by contributors, MIT License
  4183. * see https://github.com/es-shims/es5-shim/blob/master/LICENSE
  4184. */
  4185. // vim: ts=4 sts=4 sw=4 expandtab
  4186. // Add semicolon to prevent IIFE from being passed as argument to concatenated code.
  4187. ;
  4188. // UMD (Universal Module Definition)
  4189. // see https://github.com/umdjs/umd/blob/master/templates/returnExports.js
  4190. (function (root, factory) {
  4191. 'use strict';
  4192. /* global define, exports, module */
  4193. if (typeof define === 'function' && define.amd) {
  4194. // AMD. Register as an anonymous module.
  4195. define(factory);
  4196. } else if (typeof exports === 'object') {
  4197. // Node. Does not work with strict CommonJS, but
  4198. // only CommonJS-like enviroments that support module.exports,
  4199. // like Node.
  4200. module.exports = factory();
  4201. } else {
  4202. // Browser globals (root is window)
  4203. root.returnExports = factory();
  4204. }
  4205. } (this, function () {
  4206. /**
  4207. * Brings an environment as close to ECMAScript 5 compliance
  4208. * as is possible with the facilities of erstwhile engines.
  4209. *
  4210. * Annotated ES5: http://es5.github.com/ (specific links below)
  4211. * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
  4212. * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/
  4213. */
  4214. // Shortcut to an often accessed properties, in order to avoid multiple
  4215. // dereference that costs universally. This also holds a reference to known-good
  4216. // functions.
  4217. var $Array = Array;
  4218. var ArrayPrototype = $Array.prototype;
  4219. var $Object = Object;
  4220. var ObjectPrototype = $Object.prototype;
  4221. var FunctionPrototype = Function.prototype;
  4222. var $String = String;
  4223. var StringPrototype = $String.prototype;
  4224. var $Number = Number;
  4225. var NumberPrototype = $Number.prototype;
  4226. var array_slice = ArrayPrototype.slice;
  4227. var array_splice = ArrayPrototype.splice;
  4228. var array_push = ArrayPrototype.push;
  4229. var array_unshift = ArrayPrototype.unshift;
  4230. var array_concat = ArrayPrototype.concat;
  4231. var call = FunctionPrototype.call;
  4232. var apply = FunctionPrototype.apply;
  4233. var max = Math.max;
  4234. var min = Math.min;
  4235. // Having a toString local variable name breaks in Opera so use to_string.
  4236. var to_string = ObjectPrototype.toString;
  4237. var hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';
  4238. var isCallable; /* inlined from https://npmjs.com/is-callable */var fnToStr = Function.prototype.toString, tryFunctionObject = function tryFunctionObject(value) { try { fnToStr.call(value); return true; } catch (e) { return false; } }, fnClass = '[object Function]', genClass = '[object GeneratorFunction]'; isCallable = function isCallable(value) { if (typeof value !== 'function') { return false; } if (hasToStringTag) { return tryFunctionObject(value); } var strClass = to_string.call(value); return strClass === fnClass || strClass === genClass; };
  4239. var isRegex; /* inlined from https://npmjs.com/is-regex */var regexExec = RegExp.prototype.exec, tryRegexExec = function tryRegexExec(value) { try { regexExec.call(value); return true; } catch (e) { return false; } }, regexClass = '[object RegExp]'; isRegex = function isRegex(value) { if (typeof value !== 'object') { return false; } return hasToStringTag ? tryRegexExec(value) : to_string.call(value) === regexClass; };
  4240. var isString; /* inlined from https://npmjs.com/is-string */var strValue = String.prototype.valueOf, tryStringObject = function tryStringObject(value) { try { strValue.call(value); return true; } catch (e) { return false; } }, stringClass = '[object String]'; isString = function isString(value) { if (typeof value === 'string') { return true; } if (typeof value !== 'object') { return false; } return hasToStringTag ? tryStringObject(value) : to_string.call(value) === stringClass; };
  4241. /* inlined from http://npmjs.com/define-properties */
  4242. var supportsDescriptors = $Object.defineProperty && (function () {
  4243. try {
  4244. var obj = {};
  4245. $Object.defineProperty(obj, 'x', { enumerable: false, value: obj });
  4246. for (var _ in obj) { return false; }
  4247. return obj.x === obj;
  4248. } catch (e) { /* this is ES3 */
  4249. return false;
  4250. }
  4251. } ());
  4252. var defineProperties = (function (has) {
  4253. // Define configurable, writable, and non-enumerable props
  4254. // if they don't exist.
  4255. var defineProperty;
  4256. if (supportsDescriptors) {
  4257. defineProperty = function (object, name, method, forceAssign) {
  4258. if (!forceAssign && (name in object)) { return; }
  4259. $Object.defineProperty(object, name, {
  4260. configurable: true,
  4261. enumerable: false,
  4262. writable: true,
  4263. value: method
  4264. });
  4265. };
  4266. } else {
  4267. defineProperty = function (object, name, method, forceAssign) {
  4268. if (!forceAssign && (name in object)) { return; }
  4269. object[name] = method;
  4270. };
  4271. }
  4272. return function defineProperties(object, map, forceAssign) {
  4273. for (var name in map) {
  4274. if (has.call(map, name)) {
  4275. defineProperty(object, name, map[name], forceAssign);
  4276. }
  4277. }
  4278. };
  4279. } (ObjectPrototype.hasOwnProperty));
  4280. //
  4281. // Util
  4282. // ======
  4283. //
  4284. /* replaceable with https://npmjs.com/package/es-abstract /helpers/isPrimitive */
  4285. var isPrimitive = function isPrimitive(input) {
  4286. var type = typeof input;
  4287. return input === null || (type !== 'object' && type !== 'function');
  4288. };
  4289. var isActualNaN = $Number.isNaN || function (x) { return x !== x; };
  4290. var ES = {
  4291. // ES5 9.4
  4292. // http://es5.github.com/#x9.4
  4293. // http://jsperf.com/to-integer
  4294. /* replaceable with https://npmjs.com/package/es-abstract ES5.ToInteger */
  4295. ToInteger: function ToInteger(num) {
  4296. var n = +num;
  4297. if (isActualNaN(n)) {
  4298. n = 0;
  4299. } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
  4300. n = (n > 0 || -1) * Math.floor(Math.abs(n));
  4301. }
  4302. return n;
  4303. },
  4304. /* replaceable with https://npmjs.com/package/es-abstract ES5.ToPrimitive */
  4305. ToPrimitive: function ToPrimitive(input) {
  4306. var val, valueOf, toStr;
  4307. if (isPrimitive(input)) {
  4308. return input;
  4309. }
  4310. valueOf = input.valueOf;
  4311. if (isCallable(valueOf)) {
  4312. val = valueOf.call(input);
  4313. if (isPrimitive(val)) {
  4314. return val;
  4315. }
  4316. }
  4317. toStr = input.toString;
  4318. if (isCallable(toStr)) {
  4319. val = toStr.call(input);
  4320. if (isPrimitive(val)) {
  4321. return val;
  4322. }
  4323. }
  4324. throw new TypeError();
  4325. },
  4326. // ES5 9.9
  4327. // http://es5.github.com/#x9.9
  4328. /* replaceable with https://npmjs.com/package/es-abstract ES5.ToObject */
  4329. ToObject: function (o) {
  4330. if (o == null) { // this matches both null and undefined
  4331. throw new TypeError("can't convert " + o + ' to object');
  4332. }
  4333. return $Object(o);
  4334. },
  4335. /* replaceable with https://npmjs.com/package/es-abstract ES5.ToUint32 */
  4336. ToUint32: function ToUint32(x) {
  4337. return x >>> 0;
  4338. }
  4339. };
  4340. //
  4341. // Function
  4342. // ========
  4343. //
  4344. // ES-5 15.3.4.5
  4345. // http://es5.github.com/#x15.3.4.5
  4346. var Empty = function Empty() { };
  4347. defineProperties(FunctionPrototype, {
  4348. bind: function bind(that) { // .length is 1
  4349. // 1. Let Target be the this value.
  4350. var target = this;
  4351. // 2. If IsCallable(Target) is false, throw a TypeError exception.
  4352. if (!isCallable(target)) {
  4353. throw new TypeError('Function.prototype.bind called on incompatible ' + target);
  4354. }
  4355. // 3. Let A be a new (possibly empty) internal list of all of the
  4356. // argument values provided after thisArg (arg1, arg2 etc), in order.
  4357. // XXX slicedArgs will stand in for "A" if used
  4358. var args = array_slice.call(arguments, 1); // for normal call
  4359. // 4. Let F be a new native ECMAScript object.
  4360. // 11. Set the [[Prototype]] internal property of F to the standard
  4361. // built-in Function prototype object as specified in 15.3.3.1.
  4362. // 12. Set the [[Call]] internal property of F as described in
  4363. // 15.3.4.5.1.
  4364. // 13. Set the [[Construct]] internal property of F as described in
  4365. // 15.3.4.5.2.
  4366. // 14. Set the [[HasInstance]] internal property of F as described in
  4367. // 15.3.4.5.3.
  4368. var bound;
  4369. var binder = function () {
  4370. if (this instanceof bound) {
  4371. // 15.3.4.5.2 [[Construct]]
  4372. // When the [[Construct]] internal method of a function object,
  4373. // F that was created using the bind function is called with a
  4374. // list of arguments ExtraArgs, the following steps are taken:
  4375. // 1. Let target be the value of F's [[TargetFunction]]
  4376. // internal property.
  4377. // 2. If target has no [[Construct]] internal method, a
  4378. // TypeError exception is thrown.
  4379. // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
  4380. // property.
  4381. // 4. Let args be a new list containing the same values as the
  4382. // list boundArgs in the same order followed by the same
  4383. // values as the list ExtraArgs in the same order.
  4384. // 5. Return the result of calling the [[Construct]] internal
  4385. // method of target providing args as the arguments.
  4386. var result = target.apply(
  4387. this,
  4388. array_concat.call(args, array_slice.call(arguments))
  4389. );
  4390. if ($Object(result) === result) {
  4391. return result;
  4392. }
  4393. return this;
  4394. } else {
  4395. // 15.3.4.5.1 [[Call]]
  4396. // When the [[Call]] internal method of a function object, F,
  4397. // which was created using the bind function is called with a
  4398. // this value and a list of arguments ExtraArgs, the following
  4399. // steps are taken:
  4400. // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
  4401. // property.
  4402. // 2. Let boundThis be the value of F's [[BoundThis]] internal
  4403. // property.
  4404. // 3. Let target be the value of F's [[TargetFunction]] internal
  4405. // property.
  4406. // 4. Let args be a new list containing the same values as the
  4407. // list boundArgs in the same order followed by the same
  4408. // values as the list ExtraArgs in the same order.
  4409. // 5. Return the result of calling the [[Call]] internal method
  4410. // of target providing boundThis as the this value and
  4411. // providing args as the arguments.
  4412. // equiv: target.call(this, ...boundArgs, ...args)
  4413. return target.apply(
  4414. that,
  4415. array_concat.call(args, array_slice.call(arguments))
  4416. );
  4417. }
  4418. };
  4419. // 15. If the [[Class]] internal property of Target is "Function", then
  4420. // a. Let L be the length property of Target minus the length of A.
  4421. // b. Set the length own property of F to either 0 or L, whichever is
  4422. // larger.
  4423. // 16. Else set the length own property of F to 0.
  4424. var boundLength = max(0, target.length - args.length);
  4425. // 17. Set the attributes of the length own property of F to the values
  4426. // specified in 15.3.5.1.
  4427. var boundArgs = [];
  4428. for (var i = 0; i < boundLength; i++) {
  4429. array_push.call(boundArgs, '$' + i);
  4430. }
  4431. // XXX Build a dynamic function with desired amount of arguments is the only
  4432. // way to set the length property of a function.
  4433. // In environments where Content Security Policies enabled (Chrome extensions,
  4434. // for ex.) all use of eval or Function costructor throws an exception.
  4435. // However in all of these environments Function.prototype.bind exists
  4436. // and so this code will never be executed.
  4437. bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this, arguments); }')(binder);
  4438. if (target.prototype) {
  4439. Empty.prototype = target.prototype;
  4440. bound.prototype = new Empty();
  4441. // Clean up dangling references.
  4442. Empty.prototype = null;
  4443. }
  4444. // TODO
  4445. // 18. Set the [[Extensible]] internal property of F to true.
  4446. // TODO
  4447. // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
  4448. // 20. Call the [[DefineOwnProperty]] internal method of F with
  4449. // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
  4450. // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
  4451. // false.
  4452. // 21. Call the [[DefineOwnProperty]] internal method of F with
  4453. // arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
  4454. // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
  4455. // and false.
  4456. // TODO
  4457. // NOTE Function objects created using Function.prototype.bind do not
  4458. // have a prototype property or the [[Code]], [[FormalParameters]], and
  4459. // [[Scope]] internal properties.
  4460. // XXX can't delete prototype in pure-js.
  4461. // 22. Return F.
  4462. return bound;
  4463. }
  4464. });
  4465. // _Please note: Shortcuts are defined after `Function.prototype.bind` as we
  4466. // use it in defining shortcuts.
  4467. var owns = call.bind(ObjectPrototype.hasOwnProperty);
  4468. var toStr = call.bind(ObjectPrototype.toString);
  4469. var arraySlice = call.bind(array_slice);
  4470. var arraySliceApply = apply.bind(array_slice);
  4471. var strSlice = call.bind(StringPrototype.slice);
  4472. var strSplit = call.bind(StringPrototype.split);
  4473. var strIndexOf = call.bind(StringPrototype.indexOf);
  4474. var push = call.bind(array_push);
  4475. var isEnum = call.bind(ObjectPrototype.propertyIsEnumerable);
  4476. var arraySort = call.bind(ArrayPrototype.sort);
  4477. //
  4478. // Array
  4479. // =====
  4480. //
  4481. var isArray = $Array.isArray || function isArray(obj) {
  4482. return toStr(obj) === '[object Array]';
  4483. };
  4484. // ES5 15.4.4.12
  4485. // http://es5.github.com/#x15.4.4.13
  4486. // Return len+argCount.
  4487. // [bugfix, ielt8]
  4488. // IE < 8 bug: [].unshift(0) === undefined but should be "1"
  4489. var hasUnshiftReturnValueBug = [].unshift(0) !== 1;
  4490. defineProperties(ArrayPrototype, {
  4491. unshift: function () {
  4492. array_unshift.apply(this, arguments);
  4493. return this.length;
  4494. }
  4495. }, hasUnshiftReturnValueBug);
  4496. // ES5 15.4.3.2
  4497. // http://es5.github.com/#x15.4.3.2
  4498. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
  4499. defineProperties($Array, { isArray: isArray });
  4500. // The IsCallable() check in the Array functions
  4501. // has been replaced with a strict check on the
  4502. // internal class of the object to trap cases where
  4503. // the provided function was actually a regular
  4504. // expression literal, which in V8 and
  4505. // JavaScriptCore is a typeof "function". Only in
  4506. // V8 are regular expression literals permitted as
  4507. // reduce parameters, so it is desirable in the
  4508. // general case for the shim to match the more
  4509. // strict and common behavior of rejecting regular
  4510. // expressions.
  4511. // ES5 15.4.4.18
  4512. // http://es5.github.com/#x15.4.4.18
  4513. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach
  4514. // Check failure of by-index access of string characters (IE < 9)
  4515. // and failure of `0 in boxedString` (Rhino)
  4516. var boxedString = $Object('a');
  4517. var splitString = boxedString[0] !== 'a' || !(0 in boxedString);
  4518. var properlyBoxesContext = function properlyBoxed(method) {
  4519. // Check node 0.6.21 bug where third parameter is not boxed
  4520. var properlyBoxesNonStrict = true;
  4521. var properlyBoxesStrict = true;
  4522. if (method) {
  4523. method.call('foo', function (_, __, context) {
  4524. if (typeof context !== 'object') { properlyBoxesNonStrict = false; }
  4525. });
  4526. method.call([1], function () {
  4527. 'use strict';
  4528. properlyBoxesStrict = typeof this === 'string';
  4529. }, 'x');
  4530. }
  4531. return !!method && properlyBoxesNonStrict && properlyBoxesStrict;
  4532. };
  4533. defineProperties(ArrayPrototype, {
  4534. forEach: function forEach(callbackfn/*, thisArg*/) {
  4535. var object = ES.ToObject(this);
  4536. var self = splitString && isString(this) ? strSplit(this, '') : object;
  4537. var i = -1;
  4538. var length = ES.ToUint32(self.length);
  4539. var T;
  4540. if (arguments.length > 1) {
  4541. T = arguments[1];
  4542. }
  4543. // If no callback function or if callback is not a callable function
  4544. if (!isCallable(callbackfn)) {
  4545. throw new TypeError('Array.prototype.forEach callback must be a function');
  4546. }
  4547. while (++i < length) {
  4548. if (i in self) {
  4549. // Invoke the callback function with call, passing arguments:
  4550. // context, property value, property key, thisArg object
  4551. if (typeof T === 'undefined') {
  4552. callbackfn(self[i], i, object);
  4553. } else {
  4554. callbackfn.call(T, self[i], i, object);
  4555. }
  4556. }
  4557. }
  4558. }
  4559. }, !properlyBoxesContext(ArrayPrototype.forEach));
  4560. // ES5 15.4.4.19
  4561. // http://es5.github.com/#x15.4.4.19
  4562. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
  4563. defineProperties(ArrayPrototype, {
  4564. map: function map(callbackfn/*, thisArg*/) {
  4565. var object = ES.ToObject(this);
  4566. var self = splitString && isString(this) ? strSplit(this, '') : object;
  4567. var length = ES.ToUint32(self.length);
  4568. var result = $Array(length);
  4569. var T;
  4570. if (arguments.length > 1) {
  4571. T = arguments[1];
  4572. }
  4573. // If no callback function or if callback is not a callable function
  4574. if (!isCallable(callbackfn)) {
  4575. throw new TypeError('Array.prototype.map callback must be a function');
  4576. }
  4577. for (var i = 0; i < length; i++) {
  4578. if (i in self) {
  4579. if (typeof T === 'undefined') {
  4580. result[i] = callbackfn(self[i], i, object);
  4581. } else {
  4582. result[i] = callbackfn.call(T, self[i], i, object);
  4583. }
  4584. }
  4585. }
  4586. return result;
  4587. }
  4588. }, !properlyBoxesContext(ArrayPrototype.map));
  4589. // ES5 15.4.4.20
  4590. // http://es5.github.com/#x15.4.4.20
  4591. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
  4592. defineProperties(ArrayPrototype, {
  4593. filter: function filter(callbackfn/*, thisArg*/) {
  4594. var object = ES.ToObject(this);
  4595. var self = splitString && isString(this) ? strSplit(this, '') : object;
  4596. var length = ES.ToUint32(self.length);
  4597. var result = [];
  4598. var value;
  4599. var T;
  4600. if (arguments.length > 1) {
  4601. T = arguments[1];
  4602. }
  4603. // If no callback function or if callback is not a callable function
  4604. if (!isCallable(callbackfn)) {
  4605. throw new TypeError('Array.prototype.filter callback must be a function');
  4606. }
  4607. for (var i = 0; i < length; i++) {
  4608. if (i in self) {
  4609. value = self[i];
  4610. if (typeof T === 'undefined' ? callbackfn(value, i, object) : callbackfn.call(T, value, i, object)) {
  4611. push(result, value);
  4612. }
  4613. }
  4614. }
  4615. return result;
  4616. }
  4617. }, !properlyBoxesContext(ArrayPrototype.filter));
  4618. // ES5 15.4.4.16
  4619. // http://es5.github.com/#x15.4.4.16
  4620. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
  4621. defineProperties(ArrayPrototype, {
  4622. every: function every(callbackfn/*, thisArg*/) {
  4623. var object = ES.ToObject(this);
  4624. var self = splitString && isString(this) ? strSplit(this, '') : object;
  4625. var length = ES.ToUint32(self.length);
  4626. var T;
  4627. if (arguments.length > 1) {
  4628. T = arguments[1];
  4629. }
  4630. // If no callback function or if callback is not a callable function
  4631. if (!isCallable(callbackfn)) {
  4632. throw new TypeError('Array.prototype.every callback must be a function');
  4633. }
  4634. for (var i = 0; i < length; i++) {
  4635. if (i in self && !(typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
  4636. return false;
  4637. }
  4638. }
  4639. return true;
  4640. }
  4641. }, !properlyBoxesContext(ArrayPrototype.every));
  4642. // ES5 15.4.4.17
  4643. // http://es5.github.com/#x15.4.4.17
  4644. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
  4645. defineProperties(ArrayPrototype, {
  4646. some: function some(callbackfn/*, thisArg */) {
  4647. var object = ES.ToObject(this);
  4648. var self = splitString && isString(this) ? strSplit(this, '') : object;
  4649. var length = ES.ToUint32(self.length);
  4650. var T;
  4651. if (arguments.length > 1) {
  4652. T = arguments[1];
  4653. }
  4654. // If no callback function or if callback is not a callable function
  4655. if (!isCallable(callbackfn)) {
  4656. throw new TypeError('Array.prototype.some callback must be a function');
  4657. }
  4658. for (var i = 0; i < length; i++) {
  4659. if (i in self && (typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
  4660. return true;
  4661. }
  4662. }
  4663. return false;
  4664. }
  4665. }, !properlyBoxesContext(ArrayPrototype.some));
  4666. // ES5 15.4.4.21
  4667. // http://es5.github.com/#x15.4.4.21
  4668. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
  4669. var reduceCoercesToObject = false;
  4670. if (ArrayPrototype.reduce) {
  4671. reduceCoercesToObject = typeof ArrayPrototype.reduce.call('es5', function (_, __, ___, list) { return list; }) === 'object';
  4672. }
  4673. defineProperties(ArrayPrototype, {
  4674. reduce: function reduce(callbackfn/*, initialValue*/) {
  4675. var object = ES.ToObject(this);
  4676. var self = splitString && isString(this) ? strSplit(this, '') : object;
  4677. var length = ES.ToUint32(self.length);
  4678. // If no callback function or if callback is not a callable function
  4679. if (!isCallable(callbackfn)) {
  4680. throw new TypeError('Array.prototype.reduce callback must be a function');
  4681. }
  4682. // no value to return if no initial value and an empty array
  4683. if (length === 0 && arguments.length === 1) {
  4684. throw new TypeError('reduce of empty array with no initial value');
  4685. }
  4686. var i = 0;
  4687. var result;
  4688. if (arguments.length >= 2) {
  4689. result = arguments[1];
  4690. } else {
  4691. do {
  4692. if (i in self) {
  4693. result = self[i++];
  4694. break;
  4695. }
  4696. // if array contains no values, no initial value to return
  4697. if (++i >= length) {
  4698. throw new TypeError('reduce of empty array with no initial value');
  4699. }
  4700. } while (true);
  4701. }
  4702. for (; i < length; i++) {
  4703. if (i in self) {
  4704. result = callbackfn(result, self[i], i, object);
  4705. }
  4706. }
  4707. return result;
  4708. }
  4709. }, !reduceCoercesToObject);
  4710. // ES5 15.4.4.22
  4711. // http://es5.github.com/#x15.4.4.22
  4712. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
  4713. var reduceRightCoercesToObject = false;
  4714. if (ArrayPrototype.reduceRight) {
  4715. reduceRightCoercesToObject = typeof ArrayPrototype.reduceRight.call('es5', function (_, __, ___, list) { return list; }) === 'object';
  4716. }
  4717. defineProperties(ArrayPrototype, {
  4718. reduceRight: function reduceRight(callbackfn/*, initial*/) {
  4719. var object = ES.ToObject(this);
  4720. var self = splitString && isString(this) ? strSplit(this, '') : object;
  4721. var length = ES.ToUint32(self.length);
  4722. // If no callback function or if callback is not a callable function
  4723. if (!isCallable(callbackfn)) {
  4724. throw new TypeError('Array.prototype.reduceRight callback must be a function');
  4725. }
  4726. // no value to return if no initial value, empty array
  4727. if (length === 0 && arguments.length === 1) {
  4728. throw new TypeError('reduceRight of empty array with no initial value');
  4729. }
  4730. var result;
  4731. var i = length - 1;
  4732. if (arguments.length >= 2) {
  4733. result = arguments[1];
  4734. } else {
  4735. do {
  4736. if (i in self) {
  4737. result = self[i--];
  4738. break;
  4739. }
  4740. // if array contains no values, no initial value to return
  4741. if (--i < 0) {
  4742. throw new TypeError('reduceRight of empty array with no initial value');
  4743. }
  4744. } while (true);
  4745. }
  4746. if (i < 0) {
  4747. return result;
  4748. }
  4749. do {
  4750. if (i in self) {
  4751. result = callbackfn(result, self[i], i, object);
  4752. }
  4753. } while (i--);
  4754. return result;
  4755. }
  4756. }, !reduceRightCoercesToObject);
  4757. // ES5 15.4.4.14
  4758. // http://es5.github.com/#x15.4.4.14
  4759. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
  4760. var hasFirefox2IndexOfBug = ArrayPrototype.indexOf && [0, 1].indexOf(1, 2) !== -1;
  4761. defineProperties(ArrayPrototype, {
  4762. indexOf: function indexOf(searchElement/*, fromIndex */) {
  4763. var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);
  4764. var length = ES.ToUint32(self.length);
  4765. if (length === 0) {
  4766. return -1;
  4767. }
  4768. var i = 0;
  4769. if (arguments.length > 1) {
  4770. i = ES.ToInteger(arguments[1]);
  4771. }
  4772. // handle negative indices
  4773. i = i >= 0 ? i : max(0, length + i);
  4774. for (; i < length; i++) {
  4775. if (i in self && self[i] === searchElement) {
  4776. return i;
  4777. }
  4778. }
  4779. return -1;
  4780. }
  4781. }, hasFirefox2IndexOfBug);
  4782. // ES5 15.4.4.15
  4783. // http://es5.github.com/#x15.4.4.15
  4784. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
  4785. var hasFirefox2LastIndexOfBug = ArrayPrototype.lastIndexOf && [0, 1].lastIndexOf(0, -3) !== -1;
  4786. defineProperties(ArrayPrototype, {
  4787. lastIndexOf: function lastIndexOf(searchElement/*, fromIndex */) {
  4788. var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);
  4789. var length = ES.ToUint32(self.length);
  4790. if (length === 0) {
  4791. return -1;
  4792. }
  4793. var i = length - 1;
  4794. if (arguments.length > 1) {
  4795. i = min(i, ES.ToInteger(arguments[1]));
  4796. }
  4797. // handle negative indices
  4798. i = i >= 0 ? i : length - Math.abs(i);
  4799. for (; i >= 0; i--) {
  4800. if (i in self && searchElement === self[i]) {
  4801. return i;
  4802. }
  4803. }
  4804. return -1;
  4805. }
  4806. }, hasFirefox2LastIndexOfBug);
  4807. // ES5 15.4.4.12
  4808. // http://es5.github.com/#x15.4.4.12
  4809. var spliceNoopReturnsEmptyArray = (function () {
  4810. var a = [1, 2];
  4811. var result = a.splice();
  4812. return a.length === 2 && isArray(result) && result.length === 0;
  4813. } ());
  4814. defineProperties(ArrayPrototype, {
  4815. // Safari 5.0 bug where .splice() returns undefined
  4816. splice: function splice(start, deleteCount) {
  4817. if (arguments.length === 0) {
  4818. return [];
  4819. } else {
  4820. return array_splice.apply(this, arguments);
  4821. }
  4822. }
  4823. }, !spliceNoopReturnsEmptyArray);
  4824. var spliceWorksWithEmptyObject = (function () {
  4825. var obj = {};
  4826. ArrayPrototype.splice.call(obj, 0, 0, 1);
  4827. return obj.length === 1;
  4828. } ());
  4829. defineProperties(ArrayPrototype, {
  4830. splice: function splice(start, deleteCount) {
  4831. if (arguments.length === 0) { return []; }
  4832. var args = arguments;
  4833. this.length = max(ES.ToInteger(this.length), 0);
  4834. if (arguments.length > 0 && typeof deleteCount !== 'number') {
  4835. args = arraySlice(arguments);
  4836. if (args.length < 2) {
  4837. push(args, this.length - start);
  4838. } else {
  4839. args[1] = ES.ToInteger(deleteCount);
  4840. }
  4841. }
  4842. return array_splice.apply(this, args);
  4843. }
  4844. }, !spliceWorksWithEmptyObject);
  4845. var spliceWorksWithLargeSparseArrays = (function () {
  4846. // Per https://github.com/es-shims/es5-shim/issues/295
  4847. // Safari 7/8 breaks with sparse arrays of size 1e5 or greater
  4848. var arr = new $Array(1e5);
  4849. // note: the index MUST be 8 or larger or the test will false pass
  4850. arr[8] = 'x';
  4851. arr.splice(1, 1);
  4852. // note: this test must be defined *after* the indexOf shim
  4853. // per https://github.com/es-shims/es5-shim/issues/313
  4854. return arr.indexOf('x') === 7;
  4855. } ());
  4856. var spliceWorksWithSmallSparseArrays = (function () {
  4857. // Per https://github.com/es-shims/es5-shim/issues/295
  4858. // Opera 12.15 breaks on this, no idea why.
  4859. var n = 256;
  4860. var arr = [];
  4861. arr[n] = 'a';
  4862. arr.splice(n + 1, 0, 'b');
  4863. return arr[n] === 'a';
  4864. } ());
  4865. defineProperties(ArrayPrototype, {
  4866. splice: function splice(start, deleteCount) {
  4867. var O = ES.ToObject(this);
  4868. var A = [];
  4869. var len = ES.ToUint32(O.length);
  4870. var relativeStart = ES.ToInteger(start);
  4871. var actualStart = relativeStart < 0 ? max((len + relativeStart), 0) : min(relativeStart, len);
  4872. var actualDeleteCount = min(max(ES.ToInteger(deleteCount), 0), len - actualStart);
  4873. var k = 0;
  4874. var from;
  4875. while (k < actualDeleteCount) {
  4876. from = $String(actualStart + k);
  4877. if (owns(O, from)) {
  4878. A[k] = O[from];
  4879. }
  4880. k += 1;
  4881. }
  4882. var items = arraySlice(arguments, 2);
  4883. var itemCount = items.length;
  4884. var to;
  4885. if (itemCount < actualDeleteCount) {
  4886. k = actualStart;
  4887. while (k < (len - actualDeleteCount)) {
  4888. from = $String(k + actualDeleteCount);
  4889. to = $String(k + itemCount);
  4890. if (owns(O, from)) {
  4891. O[to] = O[from];
  4892. } else {
  4893. delete O[to];
  4894. }
  4895. k += 1;
  4896. }
  4897. k = len;
  4898. while (k > (len - actualDeleteCount + itemCount)) {
  4899. delete O[k - 1];
  4900. k -= 1;
  4901. }
  4902. } else if (itemCount > actualDeleteCount) {
  4903. k = len - actualDeleteCount;
  4904. while (k > actualStart) {
  4905. from = $String(k + actualDeleteCount - 1);
  4906. to = $String(k + itemCount - 1);
  4907. if (owns(O, from)) {
  4908. O[to] = O[from];
  4909. } else {
  4910. delete O[to];
  4911. }
  4912. k -= 1;
  4913. }
  4914. }
  4915. k = actualStart;
  4916. for (var i = 0; i < items.length; ++i) {
  4917. O[k] = items[i];
  4918. k += 1;
  4919. }
  4920. O.length = len - actualDeleteCount + itemCount;
  4921. return A;
  4922. }
  4923. }, !spliceWorksWithLargeSparseArrays || !spliceWorksWithSmallSparseArrays);
  4924. var originalJoin = ArrayPrototype.join;
  4925. var hasStringJoinBug;
  4926. try {
  4927. hasStringJoinBug = Array.prototype.join.call('123', ',') !== '1,2,3';
  4928. } catch (e) {
  4929. hasStringJoinBug = true;
  4930. }
  4931. if (hasStringJoinBug) {
  4932. defineProperties(ArrayPrototype, {
  4933. join: function join(separator) {
  4934. var sep = typeof separator === 'undefined' ? ',' : separator;
  4935. return originalJoin.call(isString(this) ? strSplit(this, '') : this, sep);
  4936. }
  4937. }, hasStringJoinBug);
  4938. }
  4939. var hasJoinUndefinedBug = [1, 2].join(undefined) !== '1,2';
  4940. if (hasJoinUndefinedBug) {
  4941. defineProperties(ArrayPrototype, {
  4942. join: function join(separator) {
  4943. var sep = typeof separator === 'undefined' ? ',' : separator;
  4944. return originalJoin.call(this, sep);
  4945. }
  4946. }, hasJoinUndefinedBug);
  4947. }
  4948. var pushShim = function push(item) {
  4949. var O = ES.ToObject(this);
  4950. var n = ES.ToUint32(O.length);
  4951. var i = 0;
  4952. while (i < arguments.length) {
  4953. O[n + i] = arguments[i];
  4954. i += 1;
  4955. }
  4956. O.length = n + i;
  4957. return n + i;
  4958. };
  4959. var pushIsNotGeneric = (function () {
  4960. var obj = {};
  4961. var result = Array.prototype.push.call(obj, undefined);
  4962. return result !== 1 || obj.length !== 1 || typeof obj[0] !== 'undefined' || !owns(obj, 0);
  4963. } ());
  4964. defineProperties(ArrayPrototype, {
  4965. push: function push(item) {
  4966. if (isArray(this)) {
  4967. return array_push.apply(this, arguments);
  4968. }
  4969. return pushShim.apply(this, arguments);
  4970. }
  4971. }, pushIsNotGeneric);
  4972. // This fixes a very weird bug in Opera 10.6 when pushing `undefined
  4973. var pushUndefinedIsWeird = (function () {
  4974. var arr = [];
  4975. var result = arr.push(undefined);
  4976. return result !== 1 || arr.length !== 1 || typeof arr[0] !== 'undefined' || !owns(arr, 0);
  4977. } ());
  4978. defineProperties(ArrayPrototype, { push: pushShim }, pushUndefinedIsWeird);
  4979. // ES5 15.2.3.14
  4980. // http://es5.github.io/#x15.4.4.10
  4981. // Fix boxed string bug
  4982. defineProperties(ArrayPrototype, {
  4983. slice: function (start, end) {
  4984. var arr = isString(this) ? strSplit(this, '') : this;
  4985. return arraySliceApply(arr, arguments);
  4986. }
  4987. }, splitString);
  4988. var sortIgnoresNonFunctions = (function () {
  4989. try {
  4990. [1, 2].sort(null);
  4991. [1, 2].sort({});
  4992. return true;
  4993. } catch (e) { /**/ }
  4994. return false;
  4995. } ());
  4996. var sortThrowsOnRegex = (function () {
  4997. // this is a problem in Firefox 4, in which `typeof /a/ === 'function'`
  4998. try {
  4999. [1, 2].sort(/a/);
  5000. return false;
  5001. } catch (e) { /**/ }
  5002. return true;
  5003. } ());
  5004. var sortIgnoresUndefined = (function () {
  5005. // applies in IE 8, for one.
  5006. try {
  5007. [1, 2].sort(undefined);
  5008. return true;
  5009. } catch (e) { /**/ }
  5010. return false;
  5011. } ());
  5012. defineProperties(ArrayPrototype, {
  5013. sort: function sort(compareFn) {
  5014. if (typeof compareFn === 'undefined') {
  5015. return arraySort(this);
  5016. }
  5017. if (!isCallable(compareFn)) {
  5018. throw new TypeError('Array.prototype.sort callback must be a function');
  5019. }
  5020. return arraySort(this, compareFn);
  5021. }
  5022. }, sortIgnoresNonFunctions || !sortIgnoresUndefined || !sortThrowsOnRegex);
  5023. //
  5024. // Object
  5025. // ======
  5026. //
  5027. // ES5 15.2.3.14
  5028. // http://es5.github.com/#x15.2.3.14
  5029. // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
  5030. var hasDontEnumBug = !({ 'toString': null }).propertyIsEnumerable('toString');
  5031. var hasProtoEnumBug = function () { } .propertyIsEnumerable('prototype');
  5032. var hasStringEnumBug = !owns('x', '0');
  5033. var equalsConstructorPrototype = function (o) {
  5034. var ctor = o.constructor;
  5035. return ctor && ctor.prototype === o;
  5036. };
  5037. var blacklistedKeys = {
  5038. $window: true,
  5039. $console: true,
  5040. $parent: true,
  5041. $self: true,
  5042. $frame: true,
  5043. $frames: true,
  5044. $frameElement: true,
  5045. $webkitIndexedDB: true,
  5046. $webkitStorageInfo: true,
  5047. $external: true
  5048. };
  5049. var hasAutomationEqualityBug = (function () {
  5050. /* globals window */
  5051. if (typeof window === 'undefined') { return false; }
  5052. for (var k in window) {
  5053. try {
  5054. if (!blacklistedKeys['$' + k] && owns(window, k) && window[k] !== null && typeof window[k] === 'object') {
  5055. equalsConstructorPrototype(window[k]);
  5056. }
  5057. } catch (e) {
  5058. return true;
  5059. }
  5060. }
  5061. return false;
  5062. } ());
  5063. var equalsConstructorPrototypeIfNotBuggy = function (object) {
  5064. if (typeof window === 'undefined' || !hasAutomationEqualityBug) { return equalsConstructorPrototype(object); }
  5065. try {
  5066. return equalsConstructorPrototype(object);
  5067. } catch (e) {
  5068. return false;
  5069. }
  5070. };
  5071. var dontEnums = [
  5072. 'toString',
  5073. 'toLocaleString',
  5074. 'valueOf',
  5075. 'hasOwnProperty',
  5076. 'isPrototypeOf',
  5077. 'propertyIsEnumerable',
  5078. 'constructor'
  5079. ];
  5080. var dontEnumsLength = dontEnums.length;
  5081. // taken directly from https://github.com/ljharb/is-arguments/blob/master/index.js
  5082. // can be replaced with require('is-arguments') if we ever use a build process instead
  5083. var isStandardArguments = function isArguments(value) {
  5084. return toStr(value) === '[object Arguments]';
  5085. };
  5086. var isLegacyArguments = function isArguments(value) {
  5087. return value !== null &&
  5088. typeof value === 'object' &&
  5089. typeof value.length === 'number' &&
  5090. value.length >= 0 &&
  5091. !isArray(value) &&
  5092. isCallable(value.callee);
  5093. };
  5094. var isArguments = isStandardArguments(arguments) ? isStandardArguments : isLegacyArguments;
  5095. defineProperties($Object, {
  5096. keys: function keys(object) {
  5097. var isFn = isCallable(object);
  5098. var isArgs = isArguments(object);
  5099. var isObject = object !== null && typeof object === 'object';
  5100. var isStr = isObject && isString(object);
  5101. if (!isObject && !isFn && !isArgs) {
  5102. throw new TypeError('Object.keys called on a non-object');
  5103. }
  5104. var theKeys = [];
  5105. var skipProto = hasProtoEnumBug && isFn;
  5106. if ((isStr && hasStringEnumBug) || isArgs) {
  5107. for (var i = 0; i < object.length; ++i) {
  5108. push(theKeys, $String(i));
  5109. }
  5110. }
  5111. if (!isArgs) {
  5112. for (var name in object) {
  5113. if (!(skipProto && name === 'prototype') && owns(object, name)) {
  5114. push(theKeys, $String(name));
  5115. }
  5116. }
  5117. }
  5118. if (hasDontEnumBug) {
  5119. var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);
  5120. for (var j = 0; j < dontEnumsLength; j++) {
  5121. var dontEnum = dontEnums[j];
  5122. if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) {
  5123. push(theKeys, dontEnum);
  5124. }
  5125. }
  5126. }
  5127. return theKeys;
  5128. }
  5129. });
  5130. var keysWorksWithArguments = $Object.keys && (function () {
  5131. // Safari 5.0 bug
  5132. return $Object.keys(arguments).length === 2;
  5133. } (1, 2));
  5134. var keysHasArgumentsLengthBug = $Object.keys && (function () {
  5135. var argKeys = $Object.keys(arguments);
  5136. return arguments.length !== 1 || argKeys.length !== 1 || argKeys[0] !== 1;
  5137. } (1));
  5138. var originalKeys = $Object.keys;
  5139. defineProperties($Object, {
  5140. keys: function keys(object) {
  5141. if (isArguments(object)) {
  5142. return originalKeys(arraySlice(object));
  5143. } else {
  5144. return originalKeys(object);
  5145. }
  5146. }
  5147. }, !keysWorksWithArguments || keysHasArgumentsLengthBug);
  5148. //
  5149. // Date
  5150. // ====
  5151. //
  5152. // ES5 15.9.5.43
  5153. // http://es5.github.com/#x15.9.5.43
  5154. // This function returns a String value represent the instance in time
  5155. // represented by this Date object. The format of the String is the Date Time
  5156. // string format defined in 15.9.1.15. All fields are present in the String.
  5157. // The time zone is always UTC, denoted by the suffix Z. If the time value of
  5158. // this object is not a finite Number a RangeError exception is thrown.
  5159. var negativeDate = -62198755200000;
  5160. var negativeYearString = '-000001';
  5161. var hasNegativeDateBug = Date.prototype.toISOString && new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1;
  5162. var hasSafari51DateBug = Date.prototype.toISOString && new Date(-1).toISOString() !== '1969-12-31T23:59:59.999Z';
  5163. defineProperties(Date.prototype, {
  5164. toISOString: function toISOString() {
  5165. var result, length, value, year, month;
  5166. if (!isFinite(this)) {
  5167. throw new RangeError('Date.prototype.toISOString called on non-finite value.');
  5168. }
  5169. year = this.getUTCFullYear();
  5170. month = this.getUTCMonth();
  5171. // see https://github.com/es-shims/es5-shim/issues/111
  5172. year += Math.floor(month / 12);
  5173. month = (month % 12 + 12) % 12;
  5174. // the date time string format is specified in 15.9.1.15.
  5175. result = [month + 1, this.getUTCDate(), this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()];
  5176. year = (
  5177. (year < 0 ? '-' : (year > 9999 ? '+' : '')) +
  5178. strSlice('00000' + Math.abs(year), (0 <= year && year <= 9999) ? -4 : -6)
  5179. );
  5180. length = result.length;
  5181. while (length--) {
  5182. value = result[length];
  5183. // pad months, days, hours, minutes, and seconds to have two
  5184. // digits.
  5185. if (value < 10) {
  5186. result[length] = '0' + value;
  5187. }
  5188. }
  5189. // pad milliseconds to have three digits.
  5190. return (
  5191. year + '-' + arraySlice(result, 0, 2).join('-') +
  5192. 'T' + arraySlice(result, 2).join(':') + '.' +
  5193. strSlice('000' + this.getUTCMilliseconds(), -3) + 'Z'
  5194. );
  5195. }
  5196. }, hasNegativeDateBug || hasSafari51DateBug);
  5197. // ES5 15.9.5.44
  5198. // http://es5.github.com/#x15.9.5.44
  5199. // This function provides a String representation of a Date object for use by
  5200. // JSON.stringify (15.12.3).
  5201. var dateToJSONIsSupported = (function () {
  5202. try {
  5203. return Date.prototype.toJSON &&
  5204. new Date(NaN).toJSON() === null &&
  5205. new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 &&
  5206. Date.prototype.toJSON.call({ // generic
  5207. toISOString: function () { return true; }
  5208. });
  5209. } catch (e) {
  5210. return false;
  5211. }
  5212. } ());
  5213. if (!dateToJSONIsSupported) {
  5214. Date.prototype.toJSON = function toJSON(key) {
  5215. // When the toJSON method is called with argument key, the following
  5216. // steps are taken:
  5217. // 1. Let O be the result of calling ToObject, giving it the this
  5218. // value as its argument.
  5219. // 2. Let tv be ES.ToPrimitive(O, hint Number).
  5220. var O = $Object(this);
  5221. var tv = ES.ToPrimitive(O);
  5222. // 3. If tv is a Number and is not finite, return null.
  5223. if (typeof tv === 'number' && !isFinite(tv)) {
  5224. return null;
  5225. }
  5226. // 4. Let toISO be the result of calling the [[Get]] internal method of
  5227. // O with argument "toISOString".
  5228. var toISO = O.toISOString;
  5229. // 5. If IsCallable(toISO) is false, throw a TypeError exception.
  5230. if (!isCallable(toISO)) {
  5231. throw new TypeError('toISOString property is not callable');
  5232. }
  5233. // 6. Return the result of calling the [[Call]] internal method of
  5234. // toISO with O as the this value and an empty argument list.
  5235. return toISO.call(O);
  5236. // NOTE 1 The argument is ignored.
  5237. // NOTE 2 The toJSON function is intentionally generic; it does not
  5238. // require that its this value be a Date object. Therefore, it can be
  5239. // transferred to other kinds of objects for use as a method. However,
  5240. // it does require that any such object have a toISOString method. An
  5241. // object is free to use the argument key to filter its
  5242. // stringification.
  5243. };
  5244. }
  5245. // ES5 15.9.4.2
  5246. // http://es5.github.com/#x15.9.4.2
  5247. // based on work shared by Daniel Friesen (dantman)
  5248. // http://gist.github.com/303249
  5249. var supportsExtendedYears = Date.parse('+033658-09-27T01:46:40.000Z') === 1e15;
  5250. var acceptsInvalidDates = !isNaN(Date.parse('2012-04-04T24:00:00.500Z')) || !isNaN(Date.parse('2012-11-31T23:59:59.000Z')) || !isNaN(Date.parse('2012-12-31T23:59:60.000Z'));
  5251. var doesNotParseY2KNewYear = isNaN(Date.parse('2000-01-01T00:00:00.000Z'));
  5252. if (doesNotParseY2KNewYear || acceptsInvalidDates || !supportsExtendedYears) {
  5253. // XXX global assignment won't work in embeddings that use
  5254. // an alternate object for the context.
  5255. /* global Date: true */
  5256. /* eslint-disable no-undef */
  5257. var maxSafeUnsigned32Bit = Math.pow(2, 31) - 1;
  5258. var hasSafariSignedIntBug = isActualNaN(new Date(1970, 0, 1, 0, 0, 0, maxSafeUnsigned32Bit + 1).getTime());
  5259. Date = (function (NativeDate) {
  5260. /* eslint-enable no-undef */
  5261. // Date.length === 7
  5262. var DateShim = function Date(Y, M, D, h, m, s, ms) {
  5263. var length = arguments.length;
  5264. var date;
  5265. if (this instanceof NativeDate) {
  5266. var seconds = s;
  5267. var millis = ms;
  5268. if (hasSafariSignedIntBug && length >= 7 && ms > maxSafeUnsigned32Bit) {
  5269. // work around a Safari 8/9 bug where it treats the seconds as signed
  5270. var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit;
  5271. var sToShift = Math.floor(msToShift / 1e3);
  5272. seconds += sToShift;
  5273. millis -= sToShift * 1e3;
  5274. }
  5275. date = length === 1 && $String(Y) === Y ? // isString(Y)
  5276. // We explicitly pass it through parse:
  5277. new NativeDate(DateShim.parse(Y)) :
  5278. // We have to manually make calls depending on argument
  5279. // length here
  5280. length >= 7 ? new NativeDate(Y, M, D, h, m, seconds, millis) :
  5281. length >= 6 ? new NativeDate(Y, M, D, h, m, seconds) :
  5282. length >= 5 ? new NativeDate(Y, M, D, h, m) :
  5283. length >= 4 ? new NativeDate(Y, M, D, h) :
  5284. length >= 3 ? new NativeDate(Y, M, D) :
  5285. length >= 2 ? new NativeDate(Y, M) :
  5286. length >= 1 ? new NativeDate(Y) :
  5287. new NativeDate();
  5288. } else {
  5289. date = NativeDate.apply(this, arguments);
  5290. }
  5291. if (!isPrimitive(date)) {
  5292. // Prevent mixups with unfixed Date object
  5293. defineProperties(date, { constructor: DateShim }, true);
  5294. }
  5295. return date;
  5296. };
  5297. // 15.9.1.15 Date Time String Format.
  5298. var isoDateExpression = new RegExp('^' +
  5299. '(\\d{4}|[+-]\\d{6})' + // four-digit year capture or sign +
  5300. // 6-digit extended year
  5301. '(?:-(\\d{2})' + // optional month capture
  5302. '(?:-(\\d{2})' + // optional day capture
  5303. '(?:' + // capture hours:minutes:seconds.milliseconds
  5304. 'T(\\d{2})' + // hours capture
  5305. ':(\\d{2})' + // minutes capture
  5306. '(?:' + // optional :seconds.milliseconds
  5307. ':(\\d{2})' + // seconds capture
  5308. '(?:(\\.\\d{1,}))?' + // milliseconds capture
  5309. ')?' +
  5310. '(' + // capture UTC offset component
  5311. 'Z|' + // UTC capture
  5312. '(?:' + // offset specifier +/-hours:minutes
  5313. '([-+])' + // sign capture
  5314. '(\\d{2})' + // hours offset capture
  5315. ':(\\d{2})' + // minutes offset capture
  5316. ')' +
  5317. ')?)?)?)?' +
  5318. '$');
  5319. var months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365];
  5320. var dayFromMonth = function dayFromMonth(year, month) {
  5321. var t = month > 1 ? 1 : 0;
  5322. return (
  5323. months[month] +
  5324. Math.floor((year - 1969 + t) / 4) -
  5325. Math.floor((year - 1901 + t) / 100) +
  5326. Math.floor((year - 1601 + t) / 400) +
  5327. 365 * (year - 1970)
  5328. );
  5329. };
  5330. var toUTC = function toUTC(t) {
  5331. var s = 0;
  5332. var ms = t;
  5333. if (hasSafariSignedIntBug && ms > maxSafeUnsigned32Bit) {
  5334. // work around a Safari 8/9 bug where it treats the seconds as signed
  5335. var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit;
  5336. var sToShift = Math.floor(msToShift / 1e3);
  5337. s += sToShift;
  5338. ms -= sToShift * 1e3;
  5339. }
  5340. return $Number(new NativeDate(1970, 0, 1, 0, 0, s, ms));
  5341. };
  5342. // Copy any custom methods a 3rd party library may have added
  5343. for (var key in NativeDate) {
  5344. if (owns(NativeDate, key)) {
  5345. DateShim[key] = NativeDate[key];
  5346. }
  5347. }
  5348. // Copy "native" methods explicitly; they may be non-enumerable
  5349. defineProperties(DateShim, {
  5350. now: NativeDate.now,
  5351. UTC: NativeDate.UTC
  5352. }, true);
  5353. DateShim.prototype = NativeDate.prototype;
  5354. defineProperties(DateShim.prototype, {
  5355. constructor: DateShim
  5356. }, true);
  5357. // Upgrade Date.parse to handle simplified ISO 8601 strings
  5358. var parseShim = function parse(string) {
  5359. var match = isoDateExpression.exec(string);
  5360. if (match) {
  5361. // parse months, days, hours, minutes, seconds, and milliseconds
  5362. // provide default values if necessary
  5363. // parse the UTC offset component
  5364. var year = $Number(match[1]),
  5365. month = $Number(match[2] || 1) - 1,
  5366. day = $Number(match[3] || 1) - 1,
  5367. hour = $Number(match[4] || 0),
  5368. minute = $Number(match[5] || 0),
  5369. second = $Number(match[6] || 0),
  5370. millisecond = Math.floor($Number(match[7] || 0) * 1000),
  5371. // When time zone is missed, local offset should be used
  5372. // (ES 5.1 bug)
  5373. // see https://bugs.ecmascript.org/show_bug.cgi?id=112
  5374. isLocalTime = Boolean(match[4] && !match[8]),
  5375. signOffset = match[9] === '-' ? 1 : -1,
  5376. hourOffset = $Number(match[10] || 0),
  5377. minuteOffset = $Number(match[11] || 0),
  5378. result;
  5379. var hasMinutesOrSecondsOrMilliseconds = minute > 0 || second > 0 || millisecond > 0;
  5380. if (
  5381. hour < (hasMinutesOrSecondsOrMilliseconds ? 24 : 25) &&
  5382. minute < 60 && second < 60 && millisecond < 1000 &&
  5383. month > -1 && month < 12 && hourOffset < 24 &&
  5384. minuteOffset < 60 && // detect invalid offsets
  5385. day > -1 &&
  5386. day < (dayFromMonth(year, month + 1) - dayFromMonth(year, month))
  5387. ) {
  5388. result = (
  5389. (dayFromMonth(year, month) + day) * 24 +
  5390. hour +
  5391. hourOffset * signOffset
  5392. ) * 60;
  5393. result = (
  5394. (result + minute + minuteOffset * signOffset) * 60 +
  5395. second
  5396. ) * 1000 + millisecond;
  5397. if (isLocalTime) {
  5398. result = toUTC(result);
  5399. }
  5400. if (-8.64e15 <= result && result <= 8.64e15) {
  5401. return result;
  5402. }
  5403. }
  5404. return NaN;
  5405. }
  5406. return NativeDate.parse.apply(this, arguments);
  5407. };
  5408. defineProperties(DateShim, { parse: parseShim });
  5409. return DateShim;
  5410. } (Date));
  5411. /* global Date: false */
  5412. }
  5413. // ES5 15.9.4.4
  5414. // http://es5.github.com/#x15.9.4.4
  5415. if (!Date.now) {
  5416. Date.now = function now() {
  5417. return new Date().getTime();
  5418. };
  5419. }
  5420. //
  5421. // Number
  5422. // ======
  5423. //
  5424. // ES5.1 15.7.4.5
  5425. // http://es5.github.com/#x15.7.4.5
  5426. var hasToFixedBugs = NumberPrototype.toFixed && (
  5427. (0.00008).toFixed(3) !== '0.000' ||
  5428. (0.9).toFixed(0) !== '1' ||
  5429. (1.255).toFixed(2) !== '1.25' ||
  5430. (1000000000000000128).toFixed(0) !== '1000000000000000128'
  5431. );
  5432. var toFixedHelpers = {
  5433. base: 1e7,
  5434. size: 6,
  5435. data: [0, 0, 0, 0, 0, 0],
  5436. multiply: function multiply(n, c) {
  5437. var i = -1;
  5438. var c2 = c;
  5439. while (++i < toFixedHelpers.size) {
  5440. c2 += n * toFixedHelpers.data[i];
  5441. toFixedHelpers.data[i] = c2 % toFixedHelpers.base;
  5442. c2 = Math.floor(c2 / toFixedHelpers.base);
  5443. }
  5444. },
  5445. divide: function divide(n) {
  5446. var i = toFixedHelpers.size, c = 0;
  5447. while (--i >= 0) {
  5448. c += toFixedHelpers.data[i];
  5449. toFixedHelpers.data[i] = Math.floor(c / n);
  5450. c = (c % n) * toFixedHelpers.base;
  5451. }
  5452. },
  5453. numToString: function numToString() {
  5454. var i = toFixedHelpers.size;
  5455. var s = '';
  5456. while (--i >= 0) {
  5457. if (s !== '' || i === 0 || toFixedHelpers.data[i] !== 0) {
  5458. var t = $String(toFixedHelpers.data[i]);
  5459. if (s === '') {
  5460. s = t;
  5461. } else {
  5462. s += strSlice('0000000', 0, 7 - t.length) + t;
  5463. }
  5464. }
  5465. }
  5466. return s;
  5467. },
  5468. pow: function pow(x, n, acc) {
  5469. return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc)));
  5470. },
  5471. log: function log(x) {
  5472. var n = 0;
  5473. var x2 = x;
  5474. while (x2 >= 4096) {
  5475. n += 12;
  5476. x2 /= 4096;
  5477. }
  5478. while (x2 >= 2) {
  5479. n += 1;
  5480. x2 /= 2;
  5481. }
  5482. return n;
  5483. }
  5484. };
  5485. var toFixedShim = function toFixed(fractionDigits) {
  5486. var f, x, s, m, e, z, j, k;
  5487. // Test for NaN and round fractionDigits down
  5488. f = $Number(fractionDigits);
  5489. f = isActualNaN(f) ? 0 : Math.floor(f);
  5490. if (f < 0 || f > 20) {
  5491. throw new RangeError('Number.toFixed called with invalid number of decimals');
  5492. }
  5493. x = $Number(this);
  5494. if (isActualNaN(x)) {
  5495. return 'NaN';
  5496. }
  5497. // If it is too big or small, return the string value of the number
  5498. if (x <= -1e21 || x >= 1e21) {
  5499. return $String(x);
  5500. }
  5501. s = '';
  5502. if (x < 0) {
  5503. s = '-';
  5504. x = -x;
  5505. }
  5506. m = '0';
  5507. if (x > 1e-21) {
  5508. // 1e-21 < x < 1e21
  5509. // -70 < log2(x) < 70
  5510. e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69;
  5511. z = (e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1));
  5512. z *= 0x10000000000000; // Math.pow(2, 52);
  5513. e = 52 - e;
  5514. // -18 < e < 122
  5515. // x = z / 2 ^ e
  5516. if (e > 0) {
  5517. toFixedHelpers.multiply(0, z);
  5518. j = f;
  5519. while (j >= 7) {
  5520. toFixedHelpers.multiply(1e7, 0);
  5521. j -= 7;
  5522. }
  5523. toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0);
  5524. j = e - 1;
  5525. while (j >= 23) {
  5526. toFixedHelpers.divide(1 << 23);
  5527. j -= 23;
  5528. }
  5529. toFixedHelpers.divide(1 << j);
  5530. toFixedHelpers.multiply(1, 1);
  5531. toFixedHelpers.divide(2);
  5532. m = toFixedHelpers.numToString();
  5533. } else {
  5534. toFixedHelpers.multiply(0, z);
  5535. toFixedHelpers.multiply(1 << (-e), 0);
  5536. m = toFixedHelpers.numToString() + strSlice('0.00000000000000000000', 2, 2 + f);
  5537. }
  5538. }
  5539. if (f > 0) {
  5540. k = m.length;
  5541. if (k <= f) {
  5542. m = s + strSlice('0.0000000000000000000', 0, f - k + 2) + m;
  5543. } else {
  5544. m = s + strSlice(m, 0, k - f) + '.' + strSlice(m, k - f);
  5545. }
  5546. } else {
  5547. m = s + m;
  5548. }
  5549. return m;
  5550. };
  5551. defineProperties(NumberPrototype, { toFixed: toFixedShim }, hasToFixedBugs);
  5552. var hasToPrecisionUndefinedBug = (function () {
  5553. try {
  5554. return 1.0.toPrecision(undefined) === '1';
  5555. } catch (e) {
  5556. return true;
  5557. }
  5558. } ());
  5559. var originalToPrecision = NumberPrototype.toPrecision;
  5560. defineProperties(NumberPrototype, {
  5561. toPrecision: function toPrecision(precision) {
  5562. return typeof precision === 'undefined' ? originalToPrecision.call(this) : originalToPrecision.call(this, precision);
  5563. }
  5564. }, hasToPrecisionUndefinedBug);
  5565. //
  5566. // String
  5567. // ======
  5568. //
  5569. // ES5 15.5.4.14
  5570. // http://es5.github.com/#x15.5.4.14
  5571. // [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers]
  5572. // Many browsers do not split properly with regular expressions or they
  5573. // do not perform the split correctly under obscure conditions.
  5574. // See http://blog.stevenlevithan.com/archives/cross-browser-split
  5575. // I've tested in many browsers and this seems to cover the deviant ones:
  5576. // 'ab'.split(/(?:ab)*/) should be ["", ""], not [""]
  5577. // '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""]
  5578. // 'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not
  5579. // [undefined, "t", undefined, "e", ...]
  5580. // ''.split(/.?/) should be [], not [""]
  5581. // '.'.split(/()()/) should be ["."], not ["", "", "."]
  5582. if (
  5583. 'ab'.split(/(?:ab)*/).length !== 2 ||
  5584. '.'.split(/(.?)(.?)/).length !== 4 ||
  5585. 'tesst'.split(/(s)*/)[1] === 't' ||
  5586. 'test'.split(/(?:)/, -1).length !== 4 ||
  5587. ''.split(/.?/).length ||
  5588. '.'.split(/()()/).length > 1
  5589. ) {
  5590. (function () {
  5591. var compliantExecNpcg = typeof (/()??/).exec('')[1] === 'undefined'; // NPCG: nonparticipating capturing group
  5592. var maxSafe32BitInt = Math.pow(2, 32) - 1;
  5593. StringPrototype.split = function (separator, limit) {
  5594. var string = String(this);
  5595. if (typeof separator === 'undefined' && limit === 0) {
  5596. return [];
  5597. }
  5598. // If `separator` is not a regex, use native split
  5599. if (!isRegex(separator)) {
  5600. return strSplit(this, separator, limit);
  5601. }
  5602. var output = [];
  5603. var flags = (separator.ignoreCase ? 'i' : '') +
  5604. (separator.multiline ? 'm' : '') +
  5605. (separator.unicode ? 'u' : '') + // in ES6
  5606. (separator.sticky ? 'y' : ''), // Firefox 3+ and ES6
  5607. lastLastIndex = 0,
  5608. // Make `global` and avoid `lastIndex` issues by working with a copy
  5609. separator2, match, lastIndex, lastLength;
  5610. var separatorCopy = new RegExp(separator.source, flags + 'g');
  5611. if (!compliantExecNpcg) {
  5612. // Doesn't need flags gy, but they don't hurt
  5613. separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags);
  5614. }
  5615. /* Values for `limit`, per the spec:
  5616. * If undefined: 4294967295 // maxSafe32BitInt
  5617. * If 0, Infinity, or NaN: 0
  5618. * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
  5619. * If negative number: 4294967296 - Math.floor(Math.abs(limit))
  5620. * If other: Type-convert, then use the above rules
  5621. */
  5622. var splitLimit = typeof limit === 'undefined' ? maxSafe32BitInt : ES.ToUint32(limit);
  5623. match = separatorCopy.exec(string);
  5624. while (match) {
  5625. // `separatorCopy.lastIndex` is not reliable cross-browser
  5626. lastIndex = match.index + match[0].length;
  5627. if (lastIndex > lastLastIndex) {
  5628. push(output, strSlice(string, lastLastIndex, match.index));
  5629. // Fix browsers whose `exec` methods don't consistently return `undefined` for
  5630. // nonparticipating capturing groups
  5631. if (!compliantExecNpcg && match.length > 1) {
  5632. /* eslint-disable no-loop-func */
  5633. match[0].replace(separator2, function () {
  5634. for (var i = 1; i < arguments.length - 2; i++) {
  5635. if (typeof arguments[i] === 'undefined') {
  5636. match[i] = void 0;
  5637. }
  5638. }
  5639. });
  5640. /* eslint-enable no-loop-func */
  5641. }
  5642. if (match.length > 1 && match.index < string.length) {
  5643. array_push.apply(output, arraySlice(match, 1));
  5644. }
  5645. lastLength = match[0].length;
  5646. lastLastIndex = lastIndex;
  5647. if (output.length >= splitLimit) {
  5648. break;
  5649. }
  5650. }
  5651. if (separatorCopy.lastIndex === match.index) {
  5652. separatorCopy.lastIndex++; // Avoid an infinite loop
  5653. }
  5654. match = separatorCopy.exec(string);
  5655. }
  5656. if (lastLastIndex === string.length) {
  5657. if (lastLength || !separatorCopy.test('')) {
  5658. push(output, '');
  5659. }
  5660. } else {
  5661. push(output, strSlice(string, lastLastIndex));
  5662. }
  5663. return output.length > splitLimit ? strSlice(output, 0, splitLimit) : output;
  5664. };
  5665. } ());
  5666. // [bugfix, chrome]
  5667. // If separator is undefined, then the result array contains just one String,
  5668. // which is the this value (converted to a String). If limit is not undefined,
  5669. // then the output array is truncated so that it contains no more than limit
  5670. // elements.
  5671. // "0".split(undefined, 0) -> []
  5672. } else if ('0'.split(void 0, 0).length) {
  5673. StringPrototype.split = function split(separator, limit) {
  5674. if (typeof separator === 'undefined' && limit === 0) { return []; }
  5675. return strSplit(this, separator, limit);
  5676. };
  5677. }
  5678. var str_replace = StringPrototype.replace;
  5679. var replaceReportsGroupsCorrectly = (function () {
  5680. var groups = [];
  5681. 'x'.replace(/x(.)?/g, function (match, group) {
  5682. push(groups, group);
  5683. });
  5684. return groups.length === 1 && typeof groups[0] === 'undefined';
  5685. } ());
  5686. if (!replaceReportsGroupsCorrectly) {
  5687. StringPrototype.replace = function replace(searchValue, replaceValue) {
  5688. var isFn = isCallable(replaceValue);
  5689. var hasCapturingGroups = isRegex(searchValue) && (/\)[*?]/).test(searchValue.source);
  5690. if (!isFn || !hasCapturingGroups) {
  5691. return str_replace.call(this, searchValue, replaceValue);
  5692. } else {
  5693. var wrappedReplaceValue = function (match) {
  5694. var length = arguments.length;
  5695. var originalLastIndex = searchValue.lastIndex;
  5696. searchValue.lastIndex = 0;
  5697. var args = searchValue.exec(match) || [];
  5698. searchValue.lastIndex = originalLastIndex;
  5699. push(args, arguments[length - 2], arguments[length - 1]);
  5700. return replaceValue.apply(this, args);
  5701. };
  5702. return str_replace.call(this, searchValue, wrappedReplaceValue);
  5703. }
  5704. };
  5705. }
  5706. // ECMA-262, 3rd B.2.3
  5707. // Not an ECMAScript standard, although ECMAScript 3rd Edition has a
  5708. // non-normative section suggesting uniform semantics and it should be
  5709. // normalized across all browsers
  5710. // [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE
  5711. var string_substr = StringPrototype.substr;
  5712. var hasNegativeSubstrBug = ''.substr && '0b'.substr(-1) !== 'b';
  5713. defineProperties(StringPrototype, {
  5714. substr: function substr(start, length) {
  5715. var normalizedStart = start;
  5716. if (start < 0) {
  5717. normalizedStart = max(this.length + start, 0);
  5718. }
  5719. return string_substr.call(this, normalizedStart, length);
  5720. }
  5721. }, hasNegativeSubstrBug);
  5722. // ES5 15.5.4.20
  5723. // whitespace from: http://es5.github.io/#x15.5.4.20
  5724. var ws = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' +
  5725. '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028' +
  5726. '\u2029\uFEFF';
  5727. var zeroWidth = '\u200b';
  5728. var wsRegexChars = '[' + ws + ']';
  5729. var trimBeginRegexp = new RegExp('^' + wsRegexChars + wsRegexChars + '*');
  5730. var trimEndRegexp = new RegExp(wsRegexChars + wsRegexChars + '*$');
  5731. var hasTrimWhitespaceBug = StringPrototype.trim && (ws.trim() || !zeroWidth.trim());
  5732. defineProperties(StringPrototype, {
  5733. // http://blog.stevenlevithan.com/archives/faster-trim-javascript
  5734. // http://perfectionkills.com/whitespace-deviations/
  5735. trim: function trim() {
  5736. if (typeof this === 'undefined' || this === null) {
  5737. throw new TypeError("can't convert " + this + ' to object');
  5738. }
  5739. return $String(this).replace(trimBeginRegexp, '').replace(trimEndRegexp, '');
  5740. }
  5741. }, hasTrimWhitespaceBug);
  5742. var hasLastIndexBug = StringPrototype.lastIndexOf && 'abcあい'.lastIndexOf('あい', 2) !== -1;
  5743. defineProperties(StringPrototype, {
  5744. lastIndexOf: function lastIndexOf(searchString) {
  5745. if (typeof this === 'undefined' || this === null) {
  5746. throw new TypeError("can't convert " + this + ' to object');
  5747. }
  5748. var S = $String(this);
  5749. var searchStr = $String(searchString);
  5750. var numPos = arguments.length > 1 ? $Number(arguments[1]) : NaN;
  5751. var pos = isActualNaN(numPos) ? Infinity : ES.ToInteger(numPos);
  5752. var start = min(max(pos, 0), S.length);
  5753. var searchLen = searchStr.length;
  5754. var k = start + searchLen;
  5755. while (k > 0) {
  5756. k = max(0, k - searchLen);
  5757. var index = strIndexOf(strSlice(S, k, start + searchLen), searchStr);
  5758. if (index !== -1) {
  5759. return k + index;
  5760. }
  5761. }
  5762. return -1;
  5763. }
  5764. }, hasLastIndexBug);
  5765. var originalLastIndexOf = StringPrototype.lastIndexOf;
  5766. defineProperties(StringPrototype, {
  5767. lastIndexOf: function lastIndexOf(searchString) {
  5768. return originalLastIndexOf.apply(this, arguments);
  5769. }
  5770. }, StringPrototype.lastIndexOf.length !== 1);
  5771. // ES-5 15.1.2.2
  5772. /* eslint-disable radix */
  5773. if (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) {
  5774. /* eslint-enable radix */
  5775. /* global parseInt: true */
  5776. parseInt = (function (origParseInt) {
  5777. var hexRegex = /^[\-+]?0[xX]/;
  5778. return function parseInt(str, radix) {
  5779. var string = $String(str).trim();
  5780. var defaultedRadix = $Number(radix) || (hexRegex.test(string) ? 16 : 10);
  5781. return origParseInt(string, defaultedRadix);
  5782. };
  5783. } (parseInt));
  5784. }
  5785. if (String(new RangeError('test')) !== 'RangeError: test') {
  5786. var errorToStringShim = function toString() {
  5787. if (typeof this === 'undefined' || this === null) {
  5788. throw new TypeError("can't convert " + this + ' to object');
  5789. }
  5790. var name = this.name;
  5791. if (typeof name === 'undefined') {
  5792. name = 'Error';
  5793. } else if (typeof name !== 'string') {
  5794. name = $String(name);
  5795. }
  5796. var msg = this.message;
  5797. if (typeof msg === 'undefined') {
  5798. msg = '';
  5799. } else if (typeof msg !== 'string') {
  5800. msg = $String(msg);
  5801. }
  5802. if (!name) {
  5803. return msg;
  5804. }
  5805. if (!msg) {
  5806. return name;
  5807. }
  5808. return name + ': ' + msg;
  5809. };
  5810. // can't use defineProperties here because of toString enumeration issue in IE <= 8
  5811. Error.prototype.toString = errorToStringShim;
  5812. }
  5813. if (supportsDescriptors) {
  5814. var ensureNonEnumerable = function (obj, prop) {
  5815. if (isEnum(obj, prop)) {
  5816. var desc = Object.getOwnPropertyDescriptor(obj, prop);
  5817. desc.enumerable = false;
  5818. Object.defineProperty(obj, prop, desc);
  5819. }
  5820. };
  5821. ensureNonEnumerable(Error.prototype, 'message');
  5822. if (Error.prototype.message !== '') {
  5823. Error.prototype.message = '';
  5824. }
  5825. ensureNonEnumerable(Error.prototype, 'name');
  5826. }
  5827. if (String(/a/mig) !== '/a/gim') {
  5828. var regexToString = function toString() {
  5829. var str = '/' + this.source + '/';
  5830. if (this.global) {
  5831. str += 'g';
  5832. }
  5833. if (this.ignoreCase) {
  5834. str += 'i';
  5835. }
  5836. if (this.multiline) {
  5837. str += 'm';
  5838. }
  5839. return str;
  5840. };
  5841. // can't use defineProperties here because of toString enumeration issue in IE <= 8
  5842. RegExp.prototype.toString = regexToString;
  5843. }
  5844. }));
  5845. }, {}], 26: [function (_dereq_, module, exports) {
  5846. var arr = [];
  5847. var each = arr.forEach;
  5848. var slice = arr.slice;
  5849. module.exports = function (obj) {
  5850. each.call(slice.call(arguments, 1), function (source) {
  5851. if (source) {
  5852. for (var prop in source) {
  5853. obj[prop] = source[prop];
  5854. }
  5855. }
  5856. });
  5857. return obj;
  5858. };
  5859. }, {}], 27: [function (_dereq_, module, exports) {
  5860. module.exports = isFunction
  5861. var toString = Object.prototype.toString
  5862. function isFunction(fn) {
  5863. var string = toString.call(fn)
  5864. return string === '[object Function]' ||
  5865. (typeof fn === 'function' && string !== '[object RegExp]') ||
  5866. (typeof window !== 'undefined' &&
  5867. // IE8 and below
  5868. (fn === window.setTimeout ||
  5869. fn === window.alert ||
  5870. fn === window.confirm ||
  5871. fn === window.prompt))
  5872. };
  5873. }, {}], 28: [function (_dereq_, module, exports) {
  5874. "use strict";
  5875. module.exports = function isObject(x) {
  5876. return typeof x === "object" && x !== null;
  5877. };
  5878. }, {}], 29: [function (_dereq_, module, exports) {
  5879. /*!
  5880. * $script.js JS loader & dependency manager
  5881. * https://github.com/ded/script.js
  5882. * (c) Dustin Diaz 2014 | License MIT
  5883. */
  5884. (function (name, definition) {
  5885. if (typeof module != 'undefined' && module.exports) module.exports = definition()
  5886. else if (typeof define == 'function' && define.amd) define(definition)
  5887. else this[name] = definition()
  5888. })('$script', function () {
  5889. var doc = document
  5890. , head = doc.getElementsByTagName('head')[0]
  5891. , s = 'string'
  5892. , f = false
  5893. , push = 'push'
  5894. , readyState = 'readyState'
  5895. , onreadystatechange = 'onreadystatechange'
  5896. , list = {}
  5897. , ids = {}
  5898. , delay = {}
  5899. , scripts = {}
  5900. , scriptpath
  5901. , urlArgs
  5902. function every(ar, fn) {
  5903. for (var i = 0, j = ar.length; i < j; ++i) if (!fn(ar[i])) return f
  5904. return 1
  5905. }
  5906. function each(ar, fn) {
  5907. every(ar, function (el) {
  5908. return !fn(el)
  5909. })
  5910. }
  5911. function $script(paths, idOrDone, optDone) {
  5912. paths = paths[push] ? paths : [paths]
  5913. var idOrDoneIsDone = idOrDone && idOrDone.call
  5914. , done = idOrDoneIsDone ? idOrDone : optDone
  5915. , id = idOrDoneIsDone ? paths.join('') : idOrDone
  5916. , queue = paths.length
  5917. function loopFn(item) {
  5918. return item.call ? item() : list[item]
  5919. }
  5920. function callback() {
  5921. if (! --queue) {
  5922. list[id] = 1
  5923. done && done()
  5924. for (var dset in delay) {
  5925. every(dset.split('|'), loopFn) && !each(delay[dset], loopFn) && (delay[dset] = [])
  5926. }
  5927. }
  5928. }
  5929. setTimeout(function () {
  5930. each(paths, function loading(path, force) {
  5931. if (path === null) return callback()
  5932. if (!force && !/^https?:\/\//.test(path) && scriptpath) {
  5933. path = (path.indexOf('.js') === -1) ? scriptpath + path + '.js' : scriptpath + path;
  5934. }
  5935. if (scripts[path]) {
  5936. if (id) ids[id] = 1
  5937. return (scripts[path] == 2) ? callback() : setTimeout(function () { loading(path, true) }, 0)
  5938. }
  5939. scripts[path] = 1
  5940. if (id) ids[id] = 1
  5941. create(path, callback)
  5942. })
  5943. }, 0)
  5944. return $script
  5945. }
  5946. function create(path, fn) {
  5947. var el = doc.createElement('script'), loaded
  5948. el.onload = el.onerror = el[onreadystatechange] = function () {
  5949. if ((el[readyState] && !(/^c|loade/.test(el[readyState]))) || loaded) return;
  5950. el.onload = el[onreadystatechange] = null
  5951. loaded = 1
  5952. scripts[path] = 2
  5953. fn()
  5954. }
  5955. el.async = 1
  5956. el.src = urlArgs ? path + (path.indexOf('?') === -1 ? '?' : '&') + urlArgs : path;
  5957. head.insertBefore(el, head.lastChild)
  5958. }
  5959. $script.get = create
  5960. $script.order = function (scripts, id, done) {
  5961. (function callback(s) {
  5962. s = scripts.shift()
  5963. !scripts.length ? $script(s, id, done) : $script(s, callback)
  5964. } ())
  5965. }
  5966. $script.path = function (p) {
  5967. scriptpath = p
  5968. }
  5969. $script.urlArgs = function (str) {
  5970. urlArgs = str;
  5971. }
  5972. $script.ready = function (deps, ready, req) {
  5973. deps = deps[push] ? deps : [deps]
  5974. var missing = [];
  5975. !each(deps, function (dep) {
  5976. list[dep] || missing[push](dep);
  5977. }) && every(deps, function (dep) { return list[dep] }) ?
  5978. ready() : !function (key) {
  5979. delay[key] = delay[key] || []
  5980. delay[key][push](ready)
  5981. req && req(missing)
  5982. } (deps.join('|'))
  5983. return $script
  5984. }
  5985. $script.done = function (idOrDone) {
  5986. $script([null], idOrDone)
  5987. }
  5988. return $script
  5989. });
  5990. }, {}]
  5991. }, {}, [19])(19)
  5992. });