embed.js 543 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341
  1. (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
  2. (function (process){
  3. /**
  4. * Tween.js - Licensed under the MIT license
  5. * https://github.com/tweenjs/tween.js
  6. * ----------------------------------------------
  7. *
  8. * See https://github.com/tweenjs/tween.js/graphs/contributors for the full list of contributors.
  9. * Thank you all, you're awesome!
  10. */
  11. var TWEEN = TWEEN || (function () {
  12. var _tweens = [];
  13. return {
  14. getAll: function () {
  15. return _tweens;
  16. },
  17. removeAll: function () {
  18. _tweens = [];
  19. },
  20. add: function (tween) {
  21. _tweens.push(tween);
  22. },
  23. remove: function (tween) {
  24. var i = _tweens.indexOf(tween);
  25. if (i !== -1) {
  26. _tweens.splice(i, 1);
  27. }
  28. },
  29. update: function (time, preserve) {
  30. if (_tweens.length === 0) {
  31. return false;
  32. }
  33. var i = 0;
  34. time = time !== undefined ? time : TWEEN.now();
  35. while (i < _tweens.length) {
  36. if (_tweens[i].update(time) || preserve) {
  37. i++;
  38. } else {
  39. _tweens.splice(i, 1);
  40. }
  41. }
  42. return true;
  43. }
  44. };
  45. })();
  46. // Include a performance.now polyfill.
  47. // In node.js, use process.hrtime.
  48. if (typeof (window) === 'undefined' && typeof (process) !== 'undefined') {
  49. TWEEN.now = function () {
  50. var time = process.hrtime();
  51. // Convert [seconds, nanoseconds] to milliseconds.
  52. return time[0] * 1000 + time[1] / 1000000;
  53. };
  54. }
  55. // In a browser, use window.performance.now if it is available.
  56. else if (typeof (window) !== 'undefined' &&
  57. window.performance !== undefined &&
  58. window.performance.now !== undefined) {
  59. // This must be bound, because directly assigning this function
  60. // leads to an invocation exception in Chrome.
  61. TWEEN.now = window.performance.now.bind(window.performance);
  62. }
  63. // Use Date.now if it is available.
  64. else if (Date.now !== undefined) {
  65. TWEEN.now = Date.now;
  66. }
  67. // Otherwise, use 'new Date().getTime()'.
  68. else {
  69. TWEEN.now = function () {
  70. return new Date().getTime();
  71. };
  72. }
  73. TWEEN.Tween = function (object) {
  74. var _object = object;
  75. var _valuesStart = {};
  76. var _valuesEnd = {};
  77. var _valuesStartRepeat = {};
  78. var _duration = 1000;
  79. var _repeat = 0;
  80. var _repeatDelayTime;
  81. var _yoyo = false;
  82. var _isPlaying = false;
  83. var _reversed = false;
  84. var _delayTime = 0;
  85. var _startTime = null;
  86. var _easingFunction = TWEEN.Easing.Linear.None;
  87. var _interpolationFunction = TWEEN.Interpolation.Linear;
  88. var _chainedTweens = [];
  89. var _onStartCallback = null;
  90. var _onStartCallbackFired = false;
  91. var _onUpdateCallback = null;
  92. var _onCompleteCallback = null;
  93. var _onStopCallback = null;
  94. this.to = function (properties, duration) {
  95. _valuesEnd = properties;
  96. if (duration !== undefined) {
  97. _duration = duration;
  98. }
  99. return this;
  100. };
  101. this.start = function (time) {
  102. TWEEN.add(this);
  103. _isPlaying = true;
  104. _onStartCallbackFired = false;
  105. _startTime = time !== undefined ? time : TWEEN.now();
  106. _startTime += _delayTime;
  107. for (var property in _valuesEnd) {
  108. // Check if an Array was provided as property value
  109. if (_valuesEnd[property] instanceof Array) {
  110. if (_valuesEnd[property].length === 0) {
  111. continue;
  112. }
  113. // Create a local copy of the Array with the start value at the front
  114. _valuesEnd[property] = [_object[property]].concat(_valuesEnd[property]);
  115. }
  116. // If `to()` specifies a property that doesn't exist in the source object,
  117. // we should not set that property in the object
  118. if (_object[property] === undefined) {
  119. continue;
  120. }
  121. // Save the starting value.
  122. _valuesStart[property] = _object[property];
  123. if ((_valuesStart[property] instanceof Array) === false) {
  124. _valuesStart[property] *= 1.0; // Ensures we're using numbers, not strings
  125. }
  126. _valuesStartRepeat[property] = _valuesStart[property] || 0;
  127. }
  128. return this;
  129. };
  130. this.stop = function () {
  131. if (!_isPlaying) {
  132. return this;
  133. }
  134. TWEEN.remove(this);
  135. _isPlaying = false;
  136. if (_onStopCallback !== null) {
  137. _onStopCallback.call(_object, _object);
  138. }
  139. this.stopChainedTweens();
  140. return this;
  141. };
  142. this.end = function () {
  143. this.update(_startTime + _duration);
  144. return this;
  145. };
  146. this.stopChainedTweens = function () {
  147. for (var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++) {
  148. _chainedTweens[i].stop();
  149. }
  150. };
  151. this.delay = function (amount) {
  152. _delayTime = amount;
  153. return this;
  154. };
  155. this.repeat = function (times) {
  156. _repeat = times;
  157. return this;
  158. };
  159. this.repeatDelay = function (amount) {
  160. _repeatDelayTime = amount;
  161. return this;
  162. };
  163. this.yoyo = function (yoyo) {
  164. _yoyo = yoyo;
  165. return this;
  166. };
  167. this.easing = function (easing) {
  168. _easingFunction = easing;
  169. return this;
  170. };
  171. this.interpolation = function (interpolation) {
  172. _interpolationFunction = interpolation;
  173. return this;
  174. };
  175. this.chain = function () {
  176. _chainedTweens = arguments;
  177. return this;
  178. };
  179. this.onStart = function (callback) {
  180. _onStartCallback = callback;
  181. return this;
  182. };
  183. this.onUpdate = function (callback) {
  184. _onUpdateCallback = callback;
  185. return this;
  186. };
  187. this.onComplete = function (callback) {
  188. _onCompleteCallback = callback;
  189. return this;
  190. };
  191. this.onStop = function (callback) {
  192. _onStopCallback = callback;
  193. return this;
  194. };
  195. this.update = function (time) {
  196. var property;
  197. var elapsed;
  198. var value;
  199. if (time < _startTime) {
  200. return true;
  201. }
  202. if (_onStartCallbackFired === false) {
  203. if (_onStartCallback !== null) {
  204. _onStartCallback.call(_object, _object);
  205. }
  206. _onStartCallbackFired = true;
  207. }
  208. elapsed = (time - _startTime) / _duration;
  209. elapsed = elapsed > 1 ? 1 : elapsed;
  210. value = _easingFunction(elapsed);
  211. for (property in _valuesEnd) {
  212. // Don't update properties that do not exist in the source object
  213. if (_valuesStart[property] === undefined) {
  214. continue;
  215. }
  216. var start = _valuesStart[property] || 0;
  217. var end = _valuesEnd[property];
  218. if (end instanceof Array) {
  219. _object[property] = _interpolationFunction(end, value);
  220. } else {
  221. // Parses relative end values with start as base (e.g.: +10, -3)
  222. if (typeof (end) === 'string') {
  223. if (end.charAt(0) === '+' || end.charAt(0) === '-') {
  224. end = start + parseFloat(end);
  225. } else {
  226. end = parseFloat(end);
  227. }
  228. }
  229. // Protect against non numeric properties.
  230. if (typeof (end) === 'number') {
  231. _object[property] = start + (end - start) * value;
  232. }
  233. }
  234. }
  235. if (_onUpdateCallback !== null) {
  236. _onUpdateCallback.call(_object, value);
  237. }
  238. if (elapsed === 1) {
  239. if (_repeat > 0) {
  240. if (isFinite(_repeat)) {
  241. _repeat--;
  242. }
  243. // Reassign starting values, restart by making startTime = now
  244. for (property in _valuesStartRepeat) {
  245. if (typeof (_valuesEnd[property]) === 'string') {
  246. _valuesStartRepeat[property] = _valuesStartRepeat[property] + parseFloat(_valuesEnd[property]);
  247. }
  248. if (_yoyo) {
  249. var tmp = _valuesStartRepeat[property];
  250. _valuesStartRepeat[property] = _valuesEnd[property];
  251. _valuesEnd[property] = tmp;
  252. }
  253. _valuesStart[property] = _valuesStartRepeat[property];
  254. }
  255. if (_yoyo) {
  256. _reversed = !_reversed;
  257. }
  258. if (_repeatDelayTime !== undefined) {
  259. _startTime = time + _repeatDelayTime;
  260. } else {
  261. _startTime = time + _delayTime;
  262. }
  263. return true;
  264. } else {
  265. if (_onCompleteCallback !== null) {
  266. _onCompleteCallback.call(_object, _object);
  267. }
  268. for (var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++) {
  269. // Make the chained tweens start exactly at the time they should,
  270. // even if the `update()` method was called way past the duration of the tween
  271. _chainedTweens[i].start(_startTime + _duration);
  272. }
  273. return false;
  274. }
  275. }
  276. return true;
  277. };
  278. };
  279. TWEEN.Easing = {
  280. Linear: {
  281. None: function (k) {
  282. return k;
  283. }
  284. },
  285. Quadratic: {
  286. In: function (k) {
  287. return k * k;
  288. },
  289. Out: function (k) {
  290. return k * (2 - k);
  291. },
  292. InOut: function (k) {
  293. if ((k *= 2) < 1) {
  294. return 0.5 * k * k;
  295. }
  296. return - 0.5 * (--k * (k - 2) - 1);
  297. }
  298. },
  299. Cubic: {
  300. In: function (k) {
  301. return k * k * k;
  302. },
  303. Out: function (k) {
  304. return --k * k * k + 1;
  305. },
  306. InOut: function (k) {
  307. if ((k *= 2) < 1) {
  308. return 0.5 * k * k * k;
  309. }
  310. return 0.5 * ((k -= 2) * k * k + 2);
  311. }
  312. },
  313. Quartic: {
  314. In: function (k) {
  315. return k * k * k * k;
  316. },
  317. Out: function (k) {
  318. return 1 - (--k * k * k * k);
  319. },
  320. InOut: function (k) {
  321. if ((k *= 2) < 1) {
  322. return 0.5 * k * k * k * k;
  323. }
  324. return - 0.5 * ((k -= 2) * k * k * k - 2);
  325. }
  326. },
  327. Quintic: {
  328. In: function (k) {
  329. return k * k * k * k * k;
  330. },
  331. Out: function (k) {
  332. return --k * k * k * k * k + 1;
  333. },
  334. InOut: function (k) {
  335. if ((k *= 2) < 1) {
  336. return 0.5 * k * k * k * k * k;
  337. }
  338. return 0.5 * ((k -= 2) * k * k * k * k + 2);
  339. }
  340. },
  341. Sinusoidal: {
  342. In: function (k) {
  343. return 1 - Math.cos(k * Math.PI / 2);
  344. },
  345. Out: function (k) {
  346. return Math.sin(k * Math.PI / 2);
  347. },
  348. InOut: function (k) {
  349. return 0.5 * (1 - Math.cos(Math.PI * k));
  350. }
  351. },
  352. Exponential: {
  353. In: function (k) {
  354. return k === 0 ? 0 : Math.pow(1024, k - 1);
  355. },
  356. Out: function (k) {
  357. return k === 1 ? 1 : 1 - Math.pow(2, - 10 * k);
  358. },
  359. InOut: function (k) {
  360. if (k === 0) {
  361. return 0;
  362. }
  363. if (k === 1) {
  364. return 1;
  365. }
  366. if ((k *= 2) < 1) {
  367. return 0.5 * Math.pow(1024, k - 1);
  368. }
  369. return 0.5 * (- Math.pow(2, - 10 * (k - 1)) + 2);
  370. }
  371. },
  372. Circular: {
  373. In: function (k) {
  374. return 1 - Math.sqrt(1 - k * k);
  375. },
  376. Out: function (k) {
  377. return Math.sqrt(1 - (--k * k));
  378. },
  379. InOut: function (k) {
  380. if ((k *= 2) < 1) {
  381. return - 0.5 * (Math.sqrt(1 - k * k) - 1);
  382. }
  383. return 0.5 * (Math.sqrt(1 - (k -= 2) * k) + 1);
  384. }
  385. },
  386. Elastic: {
  387. In: function (k) {
  388. if (k === 0) {
  389. return 0;
  390. }
  391. if (k === 1) {
  392. return 1;
  393. }
  394. return -Math.pow(2, 10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI);
  395. },
  396. Out: function (k) {
  397. if (k === 0) {
  398. return 0;
  399. }
  400. if (k === 1) {
  401. return 1;
  402. }
  403. return Math.pow(2, -10 * k) * Math.sin((k - 0.1) * 5 * Math.PI) + 1;
  404. },
  405. InOut: function (k) {
  406. if (k === 0) {
  407. return 0;
  408. }
  409. if (k === 1) {
  410. return 1;
  411. }
  412. k *= 2;
  413. if (k < 1) {
  414. return -0.5 * Math.pow(2, 10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI);
  415. }
  416. return 0.5 * Math.pow(2, -10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI) + 1;
  417. }
  418. },
  419. Back: {
  420. In: function (k) {
  421. var s = 1.70158;
  422. return k * k * ((s + 1) * k - s);
  423. },
  424. Out: function (k) {
  425. var s = 1.70158;
  426. return --k * k * ((s + 1) * k + s) + 1;
  427. },
  428. InOut: function (k) {
  429. var s = 1.70158 * 1.525;
  430. if ((k *= 2) < 1) {
  431. return 0.5 * (k * k * ((s + 1) * k - s));
  432. }
  433. return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2);
  434. }
  435. },
  436. Bounce: {
  437. In: function (k) {
  438. return 1 - TWEEN.Easing.Bounce.Out(1 - k);
  439. },
  440. Out: function (k) {
  441. if (k < (1 / 2.75)) {
  442. return 7.5625 * k * k;
  443. } else if (k < (2 / 2.75)) {
  444. return 7.5625 * (k -= (1.5 / 2.75)) * k + 0.75;
  445. } else if (k < (2.5 / 2.75)) {
  446. return 7.5625 * (k -= (2.25 / 2.75)) * k + 0.9375;
  447. } else {
  448. return 7.5625 * (k -= (2.625 / 2.75)) * k + 0.984375;
  449. }
  450. },
  451. InOut: function (k) {
  452. if (k < 0.5) {
  453. return TWEEN.Easing.Bounce.In(k * 2) * 0.5;
  454. }
  455. return TWEEN.Easing.Bounce.Out(k * 2 - 1) * 0.5 + 0.5;
  456. }
  457. }
  458. };
  459. TWEEN.Interpolation = {
  460. Linear: function (v, k) {
  461. var m = v.length - 1;
  462. var f = m * k;
  463. var i = Math.floor(f);
  464. var fn = TWEEN.Interpolation.Utils.Linear;
  465. if (k < 0) {
  466. return fn(v[0], v[1], f);
  467. }
  468. if (k > 1) {
  469. return fn(v[m], v[m - 1], m - f);
  470. }
  471. return fn(v[i], v[i + 1 > m ? m : i + 1], f - i);
  472. },
  473. Bezier: function (v, k) {
  474. var b = 0;
  475. var n = v.length - 1;
  476. var pw = Math.pow;
  477. var bn = TWEEN.Interpolation.Utils.Bernstein;
  478. for (var i = 0; i <= n; i++) {
  479. b += pw(1 - k, n - i) * pw(k, i) * v[i] * bn(n, i);
  480. }
  481. return b;
  482. },
  483. CatmullRom: function (v, k) {
  484. var m = v.length - 1;
  485. var f = m * k;
  486. var i = Math.floor(f);
  487. var fn = TWEEN.Interpolation.Utils.CatmullRom;
  488. if (v[0] === v[m]) {
  489. if (k < 0) {
  490. i = Math.floor(f = m * (1 + k));
  491. }
  492. return fn(v[(i - 1 + m) % m], v[i], v[(i + 1) % m], v[(i + 2) % m], f - i);
  493. } else {
  494. if (k < 0) {
  495. return v[0] - (fn(v[0], v[0], v[1], v[1], -f) - v[0]);
  496. }
  497. if (k > 1) {
  498. return v[m] - (fn(v[m], v[m], v[m - 1], v[m - 1], f - m) - v[m]);
  499. }
  500. return fn(v[i ? i - 1 : 0], v[i], v[m < i + 1 ? m : i + 1], v[m < i + 2 ? m : i + 2], f - i);
  501. }
  502. },
  503. Utils: {
  504. Linear: function (p0, p1, t) {
  505. return (p1 - p0) * t + p0;
  506. },
  507. Bernstein: function (n, i) {
  508. var fc = TWEEN.Interpolation.Utils.Factorial;
  509. return fc(n) / fc(i) / fc(n - i);
  510. },
  511. Factorial: (function () {
  512. var a = [1];
  513. return function (n) {
  514. var s = 1;
  515. if (a[n]) {
  516. return a[n];
  517. }
  518. for (var i = n; i > 1; i--) {
  519. s *= i;
  520. }
  521. a[n] = s;
  522. return s;
  523. };
  524. })(),
  525. CatmullRom: function (p0, p1, p2, p3, t) {
  526. var v0 = (p2 - p0) * 0.5;
  527. var v1 = (p3 - p1) * 0.5;
  528. var t2 = t * t;
  529. var t3 = t * t2;
  530. return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (- 3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1;
  531. }
  532. }
  533. };
  534. // UMD (Universal Module Definition)
  535. (function (root) {
  536. if (typeof define === 'function' && define.amd) {
  537. // AMD
  538. define([], function () {
  539. return TWEEN;
  540. });
  541. } else if (typeof module !== 'undefined' && typeof exports === 'object') {
  542. // Node.js
  543. module.exports = TWEEN;
  544. } else if (root !== undefined) {
  545. // Global variable
  546. root.TWEEN = TWEEN;
  547. }
  548. })(this);
  549. }).call(this,_dereq_('_process'))
  550. },{"_process":4}],2:[function(_dereq_,module,exports){
  551. (function (process,global){
  552. /*!
  553. * @overview es6-promise - a tiny implementation of Promises/A+.
  554. * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)
  555. * @license Licensed under MIT license
  556. * See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE
  557. * @version 3.3.1
  558. */
  559. (function (global, factory) {
  560. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  561. typeof define === 'function' && define.amd ? define(factory) :
  562. (global.ES6Promise = factory());
  563. }(this, (function () { 'use strict';
  564. function objectOrFunction(x) {
  565. return typeof x === 'function' || typeof x === 'object' && x !== null;
  566. }
  567. function isFunction(x) {
  568. return typeof x === 'function';
  569. }
  570. var _isArray = undefined;
  571. if (!Array.isArray) {
  572. _isArray = function (x) {
  573. return Object.prototype.toString.call(x) === '[object Array]';
  574. };
  575. } else {
  576. _isArray = Array.isArray;
  577. }
  578. var isArray = _isArray;
  579. var len = 0;
  580. var vertxNext = undefined;
  581. var customSchedulerFn = undefined;
  582. var asap = function asap(callback, arg) {
  583. queue[len] = callback;
  584. queue[len + 1] = arg;
  585. len += 2;
  586. if (len === 2) {
  587. // If len is 2, that means that we need to schedule an async flush.
  588. // If additional callbacks are queued before the queue is flushed, they
  589. // will be processed by this flush that we are scheduling.
  590. if (customSchedulerFn) {
  591. customSchedulerFn(flush);
  592. } else {
  593. scheduleFlush();
  594. }
  595. }
  596. };
  597. function setScheduler(scheduleFn) {
  598. customSchedulerFn = scheduleFn;
  599. }
  600. function setAsap(asapFn) {
  601. asap = asapFn;
  602. }
  603. var browserWindow = typeof window !== 'undefined' ? window : undefined;
  604. var browserGlobal = browserWindow || {};
  605. var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
  606. var isNode = typeof self === 'undefined' && typeof process !== 'undefined' && ({}).toString.call(process) === '[object process]';
  607. // test for web worker but not in IE10
  608. var isWorker = typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined';
  609. // node
  610. function useNextTick() {
  611. // node version 0.10.x displays a deprecation warning when nextTick is used recursively
  612. // see https://github.com/cujojs/when/issues/410 for details
  613. return function () {
  614. return process.nextTick(flush);
  615. };
  616. }
  617. // vertx
  618. function useVertxTimer() {
  619. return function () {
  620. vertxNext(flush);
  621. };
  622. }
  623. function useMutationObserver() {
  624. var iterations = 0;
  625. var observer = new BrowserMutationObserver(flush);
  626. var node = document.createTextNode('');
  627. observer.observe(node, { characterData: true });
  628. return function () {
  629. node.data = iterations = ++iterations % 2;
  630. };
  631. }
  632. // web worker
  633. function useMessageChannel() {
  634. var channel = new MessageChannel();
  635. channel.port1.onmessage = flush;
  636. return function () {
  637. return channel.port2.postMessage(0);
  638. };
  639. }
  640. function useSetTimeout() {
  641. // Store setTimeout reference so es6-promise will be unaffected by
  642. // other code modifying setTimeout (like sinon.useFakeTimers())
  643. var globalSetTimeout = setTimeout;
  644. return function () {
  645. return globalSetTimeout(flush, 1);
  646. };
  647. }
  648. var queue = new Array(1000);
  649. function flush() {
  650. for (var i = 0; i < len; i += 2) {
  651. var callback = queue[i];
  652. var arg = queue[i + 1];
  653. callback(arg);
  654. queue[i] = undefined;
  655. queue[i + 1] = undefined;
  656. }
  657. len = 0;
  658. }
  659. function attemptVertx() {
  660. try {
  661. var r = _dereq_;
  662. var vertx = r('vertx');
  663. vertxNext = vertx.runOnLoop || vertx.runOnContext;
  664. return useVertxTimer();
  665. } catch (e) {
  666. return useSetTimeout();
  667. }
  668. }
  669. var scheduleFlush = undefined;
  670. // Decide what async method to use to triggering processing of queued callbacks:
  671. if (isNode) {
  672. scheduleFlush = useNextTick();
  673. } else if (BrowserMutationObserver) {
  674. scheduleFlush = useMutationObserver();
  675. } else if (isWorker) {
  676. scheduleFlush = useMessageChannel();
  677. } else if (browserWindow === undefined && typeof _dereq_ === 'function') {
  678. scheduleFlush = attemptVertx();
  679. } else {
  680. scheduleFlush = useSetTimeout();
  681. }
  682. function then(onFulfillment, onRejection) {
  683. var _arguments = arguments;
  684. var parent = this;
  685. var child = new this.constructor(noop);
  686. if (child[PROMISE_ID] === undefined) {
  687. makePromise(child);
  688. }
  689. var _state = parent._state;
  690. if (_state) {
  691. (function () {
  692. var callback = _arguments[_state - 1];
  693. asap(function () {
  694. return invokeCallback(_state, child, callback, parent._result);
  695. });
  696. })();
  697. } else {
  698. subscribe(parent, child, onFulfillment, onRejection);
  699. }
  700. return child;
  701. }
  702. /**
  703. `Promise.resolve` returns a promise that will become resolved with the
  704. passed `value`. It is shorthand for the following:
  705. ```javascript
  706. let promise = new Promise(function(resolve, reject){
  707. resolve(1);
  708. });
  709. promise.then(function(value){
  710. // value === 1
  711. });
  712. ```
  713. Instead of writing the above, your code now simply becomes the following:
  714. ```javascript
  715. let promise = Promise.resolve(1);
  716. promise.then(function(value){
  717. // value === 1
  718. });
  719. ```
  720. @method resolve
  721. @static
  722. @param {Any} value value that the returned promise will be resolved with
  723. Useful for tooling.
  724. @return {Promise} a promise that will become fulfilled with the given
  725. `value`
  726. */
  727. function resolve(object) {
  728. /*jshint validthis:true */
  729. var Constructor = this;
  730. if (object && typeof object === 'object' && object.constructor === Constructor) {
  731. return object;
  732. }
  733. var promise = new Constructor(noop);
  734. _resolve(promise, object);
  735. return promise;
  736. }
  737. var PROMISE_ID = Math.random().toString(36).substring(16);
  738. function noop() {}
  739. var PENDING = void 0;
  740. var FULFILLED = 1;
  741. var REJECTED = 2;
  742. var GET_THEN_ERROR = new ErrorObject();
  743. function selfFulfillment() {
  744. return new TypeError("You cannot resolve a promise with itself");
  745. }
  746. function cannotReturnOwn() {
  747. return new TypeError('A promises callback cannot return that same promise.');
  748. }
  749. function getThen(promise) {
  750. try {
  751. return promise.then;
  752. } catch (error) {
  753. GET_THEN_ERROR.error = error;
  754. return GET_THEN_ERROR;
  755. }
  756. }
  757. function tryThen(then, value, fulfillmentHandler, rejectionHandler) {
  758. try {
  759. then.call(value, fulfillmentHandler, rejectionHandler);
  760. } catch (e) {
  761. return e;
  762. }
  763. }
  764. function handleForeignThenable(promise, thenable, then) {
  765. asap(function (promise) {
  766. var sealed = false;
  767. var error = tryThen(then, thenable, function (value) {
  768. if (sealed) {
  769. return;
  770. }
  771. sealed = true;
  772. if (thenable !== value) {
  773. _resolve(promise, value);
  774. } else {
  775. fulfill(promise, value);
  776. }
  777. }, function (reason) {
  778. if (sealed) {
  779. return;
  780. }
  781. sealed = true;
  782. _reject(promise, reason);
  783. }, 'Settle: ' + (promise._label || ' unknown promise'));
  784. if (!sealed && error) {
  785. sealed = true;
  786. _reject(promise, error);
  787. }
  788. }, promise);
  789. }
  790. function handleOwnThenable(promise, thenable) {
  791. if (thenable._state === FULFILLED) {
  792. fulfill(promise, thenable._result);
  793. } else if (thenable._state === REJECTED) {
  794. _reject(promise, thenable._result);
  795. } else {
  796. subscribe(thenable, undefined, function (value) {
  797. return _resolve(promise, value);
  798. }, function (reason) {
  799. return _reject(promise, reason);
  800. });
  801. }
  802. }
  803. function handleMaybeThenable(promise, maybeThenable, then$$) {
  804. if (maybeThenable.constructor === promise.constructor && then$$ === then && maybeThenable.constructor.resolve === resolve) {
  805. handleOwnThenable(promise, maybeThenable);
  806. } else {
  807. if (then$$ === GET_THEN_ERROR) {
  808. _reject(promise, GET_THEN_ERROR.error);
  809. } else if (then$$ === undefined) {
  810. fulfill(promise, maybeThenable);
  811. } else if (isFunction(then$$)) {
  812. handleForeignThenable(promise, maybeThenable, then$$);
  813. } else {
  814. fulfill(promise, maybeThenable);
  815. }
  816. }
  817. }
  818. function _resolve(promise, value) {
  819. if (promise === value) {
  820. _reject(promise, selfFulfillment());
  821. } else if (objectOrFunction(value)) {
  822. handleMaybeThenable(promise, value, getThen(value));
  823. } else {
  824. fulfill(promise, value);
  825. }
  826. }
  827. function publishRejection(promise) {
  828. if (promise._onerror) {
  829. promise._onerror(promise._result);
  830. }
  831. publish(promise);
  832. }
  833. function fulfill(promise, value) {
  834. if (promise._state !== PENDING) {
  835. return;
  836. }
  837. promise._result = value;
  838. promise._state = FULFILLED;
  839. if (promise._subscribers.length !== 0) {
  840. asap(publish, promise);
  841. }
  842. }
  843. function _reject(promise, reason) {
  844. if (promise._state !== PENDING) {
  845. return;
  846. }
  847. promise._state = REJECTED;
  848. promise._result = reason;
  849. asap(publishRejection, promise);
  850. }
  851. function subscribe(parent, child, onFulfillment, onRejection) {
  852. var _subscribers = parent._subscribers;
  853. var length = _subscribers.length;
  854. parent._onerror = null;
  855. _subscribers[length] = child;
  856. _subscribers[length + FULFILLED] = onFulfillment;
  857. _subscribers[length + REJECTED] = onRejection;
  858. if (length === 0 && parent._state) {
  859. asap(publish, parent);
  860. }
  861. }
  862. function publish(promise) {
  863. var subscribers = promise._subscribers;
  864. var settled = promise._state;
  865. if (subscribers.length === 0) {
  866. return;
  867. }
  868. var child = undefined,
  869. callback = undefined,
  870. detail = promise._result;
  871. for (var i = 0; i < subscribers.length; i += 3) {
  872. child = subscribers[i];
  873. callback = subscribers[i + settled];
  874. if (child) {
  875. invokeCallback(settled, child, callback, detail);
  876. } else {
  877. callback(detail);
  878. }
  879. }
  880. promise._subscribers.length = 0;
  881. }
  882. function ErrorObject() {
  883. this.error = null;
  884. }
  885. var TRY_CATCH_ERROR = new ErrorObject();
  886. function tryCatch(callback, detail) {
  887. try {
  888. return callback(detail);
  889. } catch (e) {
  890. TRY_CATCH_ERROR.error = e;
  891. return TRY_CATCH_ERROR;
  892. }
  893. }
  894. function invokeCallback(settled, promise, callback, detail) {
  895. var hasCallback = isFunction(callback),
  896. value = undefined,
  897. error = undefined,
  898. succeeded = undefined,
  899. failed = undefined;
  900. if (hasCallback) {
  901. value = tryCatch(callback, detail);
  902. if (value === TRY_CATCH_ERROR) {
  903. failed = true;
  904. error = value.error;
  905. value = null;
  906. } else {
  907. succeeded = true;
  908. }
  909. if (promise === value) {
  910. _reject(promise, cannotReturnOwn());
  911. return;
  912. }
  913. } else {
  914. value = detail;
  915. succeeded = true;
  916. }
  917. if (promise._state !== PENDING) {
  918. // noop
  919. } else if (hasCallback && succeeded) {
  920. _resolve(promise, value);
  921. } else if (failed) {
  922. _reject(promise, error);
  923. } else if (settled === FULFILLED) {
  924. fulfill(promise, value);
  925. } else if (settled === REJECTED) {
  926. _reject(promise, value);
  927. }
  928. }
  929. function initializePromise(promise, resolver) {
  930. try {
  931. resolver(function resolvePromise(value) {
  932. _resolve(promise, value);
  933. }, function rejectPromise(reason) {
  934. _reject(promise, reason);
  935. });
  936. } catch (e) {
  937. _reject(promise, e);
  938. }
  939. }
  940. var id = 0;
  941. function nextId() {
  942. return id++;
  943. }
  944. function makePromise(promise) {
  945. promise[PROMISE_ID] = id++;
  946. promise._state = undefined;
  947. promise._result = undefined;
  948. promise._subscribers = [];
  949. }
  950. function Enumerator(Constructor, input) {
  951. this._instanceConstructor = Constructor;
  952. this.promise = new Constructor(noop);
  953. if (!this.promise[PROMISE_ID]) {
  954. makePromise(this.promise);
  955. }
  956. if (isArray(input)) {
  957. this._input = input;
  958. this.length = input.length;
  959. this._remaining = input.length;
  960. this._result = new Array(this.length);
  961. if (this.length === 0) {
  962. fulfill(this.promise, this._result);
  963. } else {
  964. this.length = this.length || 0;
  965. this._enumerate();
  966. if (this._remaining === 0) {
  967. fulfill(this.promise, this._result);
  968. }
  969. }
  970. } else {
  971. _reject(this.promise, validationError());
  972. }
  973. }
  974. function validationError() {
  975. return new Error('Array Methods must be provided an Array');
  976. };
  977. Enumerator.prototype._enumerate = function () {
  978. var length = this.length;
  979. var _input = this._input;
  980. for (var i = 0; this._state === PENDING && i < length; i++) {
  981. this._eachEntry(_input[i], i);
  982. }
  983. };
  984. Enumerator.prototype._eachEntry = function (entry, i) {
  985. var c = this._instanceConstructor;
  986. var resolve$$ = c.resolve;
  987. if (resolve$$ === resolve) {
  988. var _then = getThen(entry);
  989. if (_then === then && entry._state !== PENDING) {
  990. this._settledAt(entry._state, i, entry._result);
  991. } else if (typeof _then !== 'function') {
  992. this._remaining--;
  993. this._result[i] = entry;
  994. } else if (c === Promise) {
  995. var promise = new c(noop);
  996. handleMaybeThenable(promise, entry, _then);
  997. this._willSettleAt(promise, i);
  998. } else {
  999. this._willSettleAt(new c(function (resolve$$) {
  1000. return resolve$$(entry);
  1001. }), i);
  1002. }
  1003. } else {
  1004. this._willSettleAt(resolve$$(entry), i);
  1005. }
  1006. };
  1007. Enumerator.prototype._settledAt = function (state, i, value) {
  1008. var promise = this.promise;
  1009. if (promise._state === PENDING) {
  1010. this._remaining--;
  1011. if (state === REJECTED) {
  1012. _reject(promise, value);
  1013. } else {
  1014. this._result[i] = value;
  1015. }
  1016. }
  1017. if (this._remaining === 0) {
  1018. fulfill(promise, this._result);
  1019. }
  1020. };
  1021. Enumerator.prototype._willSettleAt = function (promise, i) {
  1022. var enumerator = this;
  1023. subscribe(promise, undefined, function (value) {
  1024. return enumerator._settledAt(FULFILLED, i, value);
  1025. }, function (reason) {
  1026. return enumerator._settledAt(REJECTED, i, reason);
  1027. });
  1028. };
  1029. /**
  1030. `Promise.all` accepts an array of promises, and returns a new promise which
  1031. is fulfilled with an array of fulfillment values for the passed promises, or
  1032. rejected with the reason of the first passed promise to be rejected. It casts all
  1033. elements of the passed iterable to promises as it runs this algorithm.
  1034. Example:
  1035. ```javascript
  1036. let promise1 = resolve(1);
  1037. let promise2 = resolve(2);
  1038. let promise3 = resolve(3);
  1039. let promises = [ promise1, promise2, promise3 ];
  1040. Promise.all(promises).then(function(array){
  1041. // The array here would be [ 1, 2, 3 ];
  1042. });
  1043. ```
  1044. If any of the `promises` given to `all` are rejected, the first promise
  1045. that is rejected will be given as an argument to the returned promises's
  1046. rejection handler. For example:
  1047. Example:
  1048. ```javascript
  1049. let promise1 = resolve(1);
  1050. let promise2 = reject(new Error("2"));
  1051. let promise3 = reject(new Error("3"));
  1052. let promises = [ promise1, promise2, promise3 ];
  1053. Promise.all(promises).then(function(array){
  1054. // Code here never runs because there are rejected promises!
  1055. }, function(error) {
  1056. // error.message === "2"
  1057. });
  1058. ```
  1059. @method all
  1060. @static
  1061. @param {Array} entries array of promises
  1062. @param {String} label optional string for labeling the promise.
  1063. Useful for tooling.
  1064. @return {Promise} promise that is fulfilled when all `promises` have been
  1065. fulfilled, or rejected if any of them become rejected.
  1066. @static
  1067. */
  1068. function all(entries) {
  1069. return new Enumerator(this, entries).promise;
  1070. }
  1071. /**
  1072. `Promise.race` returns a new promise which is settled in the same way as the
  1073. first passed promise to settle.
  1074. Example:
  1075. ```javascript
  1076. let promise1 = new Promise(function(resolve, reject){
  1077. setTimeout(function(){
  1078. resolve('promise 1');
  1079. }, 200);
  1080. });
  1081. let promise2 = new Promise(function(resolve, reject){
  1082. setTimeout(function(){
  1083. resolve('promise 2');
  1084. }, 100);
  1085. });
  1086. Promise.race([promise1, promise2]).then(function(result){
  1087. // result === 'promise 2' because it was resolved before promise1
  1088. // was resolved.
  1089. });
  1090. ```
  1091. `Promise.race` is deterministic in that only the state of the first
  1092. settled promise matters. For example, even if other promises given to the
  1093. `promises` array argument are resolved, but the first settled promise has
  1094. become rejected before the other promises became fulfilled, the returned
  1095. promise will become rejected:
  1096. ```javascript
  1097. let promise1 = new Promise(function(resolve, reject){
  1098. setTimeout(function(){
  1099. resolve('promise 1');
  1100. }, 200);
  1101. });
  1102. let promise2 = new Promise(function(resolve, reject){
  1103. setTimeout(function(){
  1104. reject(new Error('promise 2'));
  1105. }, 100);
  1106. });
  1107. Promise.race([promise1, promise2]).then(function(result){
  1108. // Code here never runs
  1109. }, function(reason){
  1110. // reason.message === 'promise 2' because promise 2 became rejected before
  1111. // promise 1 became fulfilled
  1112. });
  1113. ```
  1114. An example real-world use case is implementing timeouts:
  1115. ```javascript
  1116. Promise.race([ajax('foo.json'), timeout(5000)])
  1117. ```
  1118. @method race
  1119. @static
  1120. @param {Array} promises array of promises to observe
  1121. Useful for tooling.
  1122. @return {Promise} a promise which settles in the same way as the first passed
  1123. promise to settle.
  1124. */
  1125. function race(entries) {
  1126. /*jshint validthis:true */
  1127. var Constructor = this;
  1128. if (!isArray(entries)) {
  1129. return new Constructor(function (_, reject) {
  1130. return reject(new TypeError('You must pass an array to race.'));
  1131. });
  1132. } else {
  1133. return new Constructor(function (resolve, reject) {
  1134. var length = entries.length;
  1135. for (var i = 0; i < length; i++) {
  1136. Constructor.resolve(entries[i]).then(resolve, reject);
  1137. }
  1138. });
  1139. }
  1140. }
  1141. /**
  1142. `Promise.reject` returns a promise rejected with the passed `reason`.
  1143. It is shorthand for the following:
  1144. ```javascript
  1145. let promise = new Promise(function(resolve, reject){
  1146. reject(new Error('WHOOPS'));
  1147. });
  1148. promise.then(function(value){
  1149. // Code here doesn't run because the promise is rejected!
  1150. }, function(reason){
  1151. // reason.message === 'WHOOPS'
  1152. });
  1153. ```
  1154. Instead of writing the above, your code now simply becomes the following:
  1155. ```javascript
  1156. let promise = Promise.reject(new Error('WHOOPS'));
  1157. promise.then(function(value){
  1158. // Code here doesn't run because the promise is rejected!
  1159. }, function(reason){
  1160. // reason.message === 'WHOOPS'
  1161. });
  1162. ```
  1163. @method reject
  1164. @static
  1165. @param {Any} reason value that the returned promise will be rejected with.
  1166. Useful for tooling.
  1167. @return {Promise} a promise rejected with the given `reason`.
  1168. */
  1169. function reject(reason) {
  1170. /*jshint validthis:true */
  1171. var Constructor = this;
  1172. var promise = new Constructor(noop);
  1173. _reject(promise, reason);
  1174. return promise;
  1175. }
  1176. function needsResolver() {
  1177. throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
  1178. }
  1179. function needsNew() {
  1180. throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
  1181. }
  1182. /**
  1183. Promise objects represent the eventual result of an asynchronous operation. The
  1184. primary way of interacting with a promise is through its `then` method, which
  1185. registers callbacks to receive either a promise's eventual value or the reason
  1186. why the promise cannot be fulfilled.
  1187. Terminology
  1188. -----------
  1189. - `promise` is an object or function with a `then` method whose behavior conforms to this specification.
  1190. - `thenable` is an object or function that defines a `then` method.
  1191. - `value` is any legal JavaScript value (including undefined, a thenable, or a promise).
  1192. - `exception` is a value that is thrown using the throw statement.
  1193. - `reason` is a value that indicates why a promise was rejected.
  1194. - `settled` the final resting state of a promise, fulfilled or rejected.
  1195. A promise can be in one of three states: pending, fulfilled, or rejected.
  1196. Promises that are fulfilled have a fulfillment value and are in the fulfilled
  1197. state. Promises that are rejected have a rejection reason and are in the
  1198. rejected state. A fulfillment value is never a thenable.
  1199. Promises can also be said to *resolve* a value. If this value is also a
  1200. promise, then the original promise's settled state will match the value's
  1201. settled state. So a promise that *resolves* a promise that rejects will
  1202. itself reject, and a promise that *resolves* a promise that fulfills will
  1203. itself fulfill.
  1204. Basic Usage:
  1205. ------------
  1206. ```js
  1207. let promise = new Promise(function(resolve, reject) {
  1208. // on success
  1209. resolve(value);
  1210. // on failure
  1211. reject(reason);
  1212. });
  1213. promise.then(function(value) {
  1214. // on fulfillment
  1215. }, function(reason) {
  1216. // on rejection
  1217. });
  1218. ```
  1219. Advanced Usage:
  1220. ---------------
  1221. Promises shine when abstracting away asynchronous interactions such as
  1222. `XMLHttpRequest`s.
  1223. ```js
  1224. function getJSON(url) {
  1225. return new Promise(function(resolve, reject){
  1226. let xhr = new XMLHttpRequest();
  1227. xhr.open('GET', url);
  1228. xhr.onreadystatechange = handler;
  1229. xhr.responseType = 'json';
  1230. xhr.setRequestHeader('Accept', 'application/json');
  1231. xhr.send();
  1232. function handler() {
  1233. if (this.readyState === this.DONE) {
  1234. if (this.status === 200) {
  1235. resolve(this.response);
  1236. } else {
  1237. reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));
  1238. }
  1239. }
  1240. };
  1241. });
  1242. }
  1243. getJSON('/posts.json').then(function(json) {
  1244. // on fulfillment
  1245. }, function(reason) {
  1246. // on rejection
  1247. });
  1248. ```
  1249. Unlike callbacks, promises are great composable primitives.
  1250. ```js
  1251. Promise.all([
  1252. getJSON('/posts'),
  1253. getJSON('/comments')
  1254. ]).then(function(values){
  1255. values[0] // => postsJSON
  1256. values[1] // => commentsJSON
  1257. return values;
  1258. });
  1259. ```
  1260. @class Promise
  1261. @param {function} resolver
  1262. Useful for tooling.
  1263. @constructor
  1264. */
  1265. function Promise(resolver) {
  1266. this[PROMISE_ID] = nextId();
  1267. this._result = this._state = undefined;
  1268. this._subscribers = [];
  1269. if (noop !== resolver) {
  1270. typeof resolver !== 'function' && needsResolver();
  1271. this instanceof Promise ? initializePromise(this, resolver) : needsNew();
  1272. }
  1273. }
  1274. Promise.all = all;
  1275. Promise.race = race;
  1276. Promise.resolve = resolve;
  1277. Promise.reject = reject;
  1278. Promise._setScheduler = setScheduler;
  1279. Promise._setAsap = setAsap;
  1280. Promise._asap = asap;
  1281. Promise.prototype = {
  1282. constructor: Promise,
  1283. /**
  1284. The primary way of interacting with a promise is through its `then` method,
  1285. which registers callbacks to receive either a promise's eventual value or the
  1286. reason why the promise cannot be fulfilled.
  1287. ```js
  1288. findUser().then(function(user){
  1289. // user is available
  1290. }, function(reason){
  1291. // user is unavailable, and you are given the reason why
  1292. });
  1293. ```
  1294. Chaining
  1295. --------
  1296. The return value of `then` is itself a promise. This second, 'downstream'
  1297. promise is resolved with the return value of the first promise's fulfillment
  1298. or rejection handler, or rejected if the handler throws an exception.
  1299. ```js
  1300. findUser().then(function (user) {
  1301. return user.name;
  1302. }, function (reason) {
  1303. return 'default name';
  1304. }).then(function (userName) {
  1305. // If `findUser` fulfilled, `userName` will be the user's name, otherwise it
  1306. // will be `'default name'`
  1307. });
  1308. findUser().then(function (user) {
  1309. throw new Error('Found user, but still unhappy');
  1310. }, function (reason) {
  1311. throw new Error('`findUser` rejected and we're unhappy');
  1312. }).then(function (value) {
  1313. // never reached
  1314. }, function (reason) {
  1315. // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.
  1316. // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.
  1317. });
  1318. ```
  1319. If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.
  1320. ```js
  1321. findUser().then(function (user) {
  1322. throw new PedagogicalException('Upstream error');
  1323. }).then(function (value) {
  1324. // never reached
  1325. }).then(function (value) {
  1326. // never reached
  1327. }, function (reason) {
  1328. // The `PedgagocialException` is propagated all the way down to here
  1329. });
  1330. ```
  1331. Assimilation
  1332. ------------
  1333. Sometimes the value you want to propagate to a downstream promise can only be
  1334. retrieved asynchronously. This can be achieved by returning a promise in the
  1335. fulfillment or rejection handler. The downstream promise will then be pending
  1336. until the returned promise is settled. This is called *assimilation*.
  1337. ```js
  1338. findUser().then(function (user) {
  1339. return findCommentsByAuthor(user);
  1340. }).then(function (comments) {
  1341. // The user's comments are now available
  1342. });
  1343. ```
  1344. If the assimliated promise rejects, then the downstream promise will also reject.
  1345. ```js
  1346. findUser().then(function (user) {
  1347. return findCommentsByAuthor(user);
  1348. }).then(function (comments) {
  1349. // If `findCommentsByAuthor` fulfills, we'll have the value here
  1350. }, function (reason) {
  1351. // If `findCommentsByAuthor` rejects, we'll have the reason here
  1352. });
  1353. ```
  1354. Simple Example
  1355. --------------
  1356. Synchronous Example
  1357. ```javascript
  1358. let result;
  1359. try {
  1360. result = findResult();
  1361. // success
  1362. } catch(reason) {
  1363. // failure
  1364. }
  1365. ```
  1366. Errback Example
  1367. ```js
  1368. findResult(function(result, err){
  1369. if (err) {
  1370. // failure
  1371. } else {
  1372. // success
  1373. }
  1374. });
  1375. ```
  1376. Promise Example;
  1377. ```javascript
  1378. findResult().then(function(result){
  1379. // success
  1380. }, function(reason){
  1381. // failure
  1382. });
  1383. ```
  1384. Advanced Example
  1385. --------------
  1386. Synchronous Example
  1387. ```javascript
  1388. let author, books;
  1389. try {
  1390. author = findAuthor();
  1391. books = findBooksByAuthor(author);
  1392. // success
  1393. } catch(reason) {
  1394. // failure
  1395. }
  1396. ```
  1397. Errback Example
  1398. ```js
  1399. function foundBooks(books) {
  1400. }
  1401. function failure(reason) {
  1402. }
  1403. findAuthor(function(author, err){
  1404. if (err) {
  1405. failure(err);
  1406. // failure
  1407. } else {
  1408. try {
  1409. findBoooksByAuthor(author, function(books, err) {
  1410. if (err) {
  1411. failure(err);
  1412. } else {
  1413. try {
  1414. foundBooks(books);
  1415. } catch(reason) {
  1416. failure(reason);
  1417. }
  1418. }
  1419. });
  1420. } catch(error) {
  1421. failure(err);
  1422. }
  1423. // success
  1424. }
  1425. });
  1426. ```
  1427. Promise Example;
  1428. ```javascript
  1429. findAuthor().
  1430. then(findBooksByAuthor).
  1431. then(function(books){
  1432. // found books
  1433. }).catch(function(reason){
  1434. // something went wrong
  1435. });
  1436. ```
  1437. @method then
  1438. @param {Function} onFulfilled
  1439. @param {Function} onRejected
  1440. Useful for tooling.
  1441. @return {Promise}
  1442. */
  1443. then: then,
  1444. /**
  1445. `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
  1446. as the catch block of a try/catch statement.
  1447. ```js
  1448. function findAuthor(){
  1449. throw new Error('couldn't find that author');
  1450. }
  1451. // synchronous
  1452. try {
  1453. findAuthor();
  1454. } catch(reason) {
  1455. // something went wrong
  1456. }
  1457. // async with promises
  1458. findAuthor().catch(function(reason){
  1459. // something went wrong
  1460. });
  1461. ```
  1462. @method catch
  1463. @param {Function} onRejection
  1464. Useful for tooling.
  1465. @return {Promise}
  1466. */
  1467. 'catch': function _catch(onRejection) {
  1468. return this.then(null, onRejection);
  1469. }
  1470. };
  1471. function polyfill() {
  1472. var local = undefined;
  1473. if (typeof global !== 'undefined') {
  1474. local = global;
  1475. } else if (typeof self !== 'undefined') {
  1476. local = self;
  1477. } else {
  1478. try {
  1479. local = Function('return this')();
  1480. } catch (e) {
  1481. throw new Error('polyfill failed because global object is unavailable in this environment');
  1482. }
  1483. }
  1484. var P = local.Promise;
  1485. if (P) {
  1486. var promiseToString = null;
  1487. try {
  1488. promiseToString = Object.prototype.toString.call(P.resolve());
  1489. } catch (e) {
  1490. // silently ignored
  1491. }
  1492. if (promiseToString === '[object Promise]' && !P.cast) {
  1493. return;
  1494. }
  1495. }
  1496. local.Promise = Promise;
  1497. }
  1498. polyfill();
  1499. // Strange compat..
  1500. Promise.polyfill = polyfill;
  1501. Promise.Promise = Promise;
  1502. return Promise;
  1503. })));
  1504. }).call(this,_dereq_('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  1505. },{"_process":4}],3:[function(_dereq_,module,exports){
  1506. 'use strict';
  1507. var has = Object.prototype.hasOwnProperty;
  1508. //
  1509. // We store our EE objects in a plain object whose properties are event names.
  1510. // If `Object.create(null)` is not supported we prefix the event names with a
  1511. // `~` to make sure that the built-in object properties are not overridden or
  1512. // used as an attack vector.
  1513. // We also assume that `Object.create(null)` is available when the event name
  1514. // is an ES6 Symbol.
  1515. //
  1516. var prefix = typeof Object.create !== 'function' ? '~' : false;
  1517. /**
  1518. * Representation of a single EventEmitter function.
  1519. *
  1520. * @param {Function} fn Event handler to be called.
  1521. * @param {Mixed} context Context for function execution.
  1522. * @param {Boolean} [once=false] Only emit once
  1523. * @api private
  1524. */
  1525. function EE(fn, context, once) {
  1526. this.fn = fn;
  1527. this.context = context;
  1528. this.once = once || false;
  1529. }
  1530. /**
  1531. * Minimal EventEmitter interface that is molded against the Node.js
  1532. * EventEmitter interface.
  1533. *
  1534. * @constructor
  1535. * @api public
  1536. */
  1537. function EventEmitter() { /* Nothing to set */ }
  1538. /**
  1539. * Hold the assigned EventEmitters by name.
  1540. *
  1541. * @type {Object}
  1542. * @private
  1543. */
  1544. EventEmitter.prototype._events = undefined;
  1545. /**
  1546. * Return an array listing the events for which the emitter has registered
  1547. * listeners.
  1548. *
  1549. * @returns {Array}
  1550. * @api public
  1551. */
  1552. EventEmitter.prototype.eventNames = function eventNames() {
  1553. var events = this._events
  1554. , names = []
  1555. , name;
  1556. if (!events) return names;
  1557. for (name in events) {
  1558. if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
  1559. }
  1560. if (Object.getOwnPropertySymbols) {
  1561. return names.concat(Object.getOwnPropertySymbols(events));
  1562. }
  1563. return names;
  1564. };
  1565. /**
  1566. * Return a list of assigned event listeners.
  1567. *
  1568. * @param {String} event The events that should be listed.
  1569. * @param {Boolean} exists We only need to know if there are listeners.
  1570. * @returns {Array|Boolean}
  1571. * @api public
  1572. */
  1573. EventEmitter.prototype.listeners = function listeners(event, exists) {
  1574. var evt = prefix ? prefix + event : event
  1575. , available = this._events && this._events[evt];
  1576. if (exists) return !!available;
  1577. if (!available) return [];
  1578. if (available.fn) return [available.fn];
  1579. for (var i = 0, l = available.length, ee = new Array(l); i < l; i++) {
  1580. ee[i] = available[i].fn;
  1581. }
  1582. return ee;
  1583. };
  1584. /**
  1585. * Emit an event to all registered event listeners.
  1586. *
  1587. * @param {String} event The name of the event.
  1588. * @returns {Boolean} Indication if we've emitted an event.
  1589. * @api public
  1590. */
  1591. EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
  1592. var evt = prefix ? prefix + event : event;
  1593. if (!this._events || !this._events[evt]) return false;
  1594. var listeners = this._events[evt]
  1595. , len = arguments.length
  1596. , args
  1597. , i;
  1598. if ('function' === typeof listeners.fn) {
  1599. if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
  1600. switch (len) {
  1601. case 1: return listeners.fn.call(listeners.context), true;
  1602. case 2: return listeners.fn.call(listeners.context, a1), true;
  1603. case 3: return listeners.fn.call(listeners.context, a1, a2), true;
  1604. case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
  1605. case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
  1606. case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
  1607. }
  1608. for (i = 1, args = new Array(len -1); i < len; i++) {
  1609. args[i - 1] = arguments[i];
  1610. }
  1611. listeners.fn.apply(listeners.context, args);
  1612. } else {
  1613. var length = listeners.length
  1614. , j;
  1615. for (i = 0; i < length; i++) {
  1616. if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
  1617. switch (len) {
  1618. case 1: listeners[i].fn.call(listeners[i].context); break;
  1619. case 2: listeners[i].fn.call(listeners[i].context, a1); break;
  1620. case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
  1621. default:
  1622. if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
  1623. args[j - 1] = arguments[j];
  1624. }
  1625. listeners[i].fn.apply(listeners[i].context, args);
  1626. }
  1627. }
  1628. }
  1629. return true;
  1630. };
  1631. /**
  1632. * Register a new EventListener for the given event.
  1633. *
  1634. * @param {String} event Name of the event.
  1635. * @param {Function} fn Callback function.
  1636. * @param {Mixed} [context=this] The context of the function.
  1637. * @api public
  1638. */
  1639. EventEmitter.prototype.on = function on(event, fn, context) {
  1640. var listener = new EE(fn, context || this)
  1641. , evt = prefix ? prefix + event : event;
  1642. if (!this._events) this._events = prefix ? {} : Object.create(null);
  1643. if (!this._events[evt]) this._events[evt] = listener;
  1644. else {
  1645. if (!this._events[evt].fn) this._events[evt].push(listener);
  1646. else this._events[evt] = [
  1647. this._events[evt], listener
  1648. ];
  1649. }
  1650. return this;
  1651. };
  1652. /**
  1653. * Add an EventListener that's only called once.
  1654. *
  1655. * @param {String} event Name of the event.
  1656. * @param {Function} fn Callback function.
  1657. * @param {Mixed} [context=this] The context of the function.
  1658. * @api public
  1659. */
  1660. EventEmitter.prototype.once = function once(event, fn, context) {
  1661. var listener = new EE(fn, context || this, true)
  1662. , evt = prefix ? prefix + event : event;
  1663. if (!this._events) this._events = prefix ? {} : Object.create(null);
  1664. if (!this._events[evt]) this._events[evt] = listener;
  1665. else {
  1666. if (!this._events[evt].fn) this._events[evt].push(listener);
  1667. else this._events[evt] = [
  1668. this._events[evt], listener
  1669. ];
  1670. }
  1671. return this;
  1672. };
  1673. /**
  1674. * Remove event listeners.
  1675. *
  1676. * @param {String} event The event we want to remove.
  1677. * @param {Function} fn The listener that we need to find.
  1678. * @param {Mixed} context Only remove listeners matching this context.
  1679. * @param {Boolean} once Only remove once listeners.
  1680. * @api public
  1681. */
  1682. EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
  1683. var evt = prefix ? prefix + event : event;
  1684. if (!this._events || !this._events[evt]) return this;
  1685. var listeners = this._events[evt]
  1686. , events = [];
  1687. if (fn) {
  1688. if (listeners.fn) {
  1689. if (
  1690. listeners.fn !== fn
  1691. || (once && !listeners.once)
  1692. || (context && listeners.context !== context)
  1693. ) {
  1694. events.push(listeners);
  1695. }
  1696. } else {
  1697. for (var i = 0, length = listeners.length; i < length; i++) {
  1698. if (
  1699. listeners[i].fn !== fn
  1700. || (once && !listeners[i].once)
  1701. || (context && listeners[i].context !== context)
  1702. ) {
  1703. events.push(listeners[i]);
  1704. }
  1705. }
  1706. }
  1707. }
  1708. //
  1709. // Reset the array, or remove it completely if we have no more listeners.
  1710. //
  1711. if (events.length) {
  1712. this._events[evt] = events.length === 1 ? events[0] : events;
  1713. } else {
  1714. delete this._events[evt];
  1715. }
  1716. return this;
  1717. };
  1718. /**
  1719. * Remove all listeners or only the listeners for the specified event.
  1720. *
  1721. * @param {String} event The event want to remove all listeners for.
  1722. * @api public
  1723. */
  1724. EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
  1725. if (!this._events) return this;
  1726. if (event) delete this._events[prefix ? prefix + event : event];
  1727. else this._events = prefix ? {} : Object.create(null);
  1728. return this;
  1729. };
  1730. //
  1731. // Alias methods names because people roll like that.
  1732. //
  1733. EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
  1734. EventEmitter.prototype.addListener = EventEmitter.prototype.on;
  1735. //
  1736. // This function doesn't apply anymore.
  1737. //
  1738. EventEmitter.prototype.setMaxListeners = function setMaxListeners() {
  1739. return this;
  1740. };
  1741. //
  1742. // Expose the prefix.
  1743. //
  1744. EventEmitter.prefixed = prefix;
  1745. //
  1746. // Expose the module.
  1747. //
  1748. if ('undefined' !== typeof module) {
  1749. module.exports = EventEmitter;
  1750. }
  1751. },{}],4:[function(_dereq_,module,exports){
  1752. // shim for using process in browser
  1753. var process = module.exports = {};
  1754. // cached from whatever global is present so that test runners that stub it
  1755. // don't break things. But we need to wrap it in a try catch in case it is
  1756. // wrapped in strict mode code which doesn't define any globals. It's inside a
  1757. // function because try/catches deoptimize in certain engines.
  1758. var cachedSetTimeout;
  1759. var cachedClearTimeout;
  1760. function defaultSetTimout() {
  1761. throw new Error('setTimeout has not been defined');
  1762. }
  1763. function defaultClearTimeout () {
  1764. throw new Error('clearTimeout has not been defined');
  1765. }
  1766. (function () {
  1767. try {
  1768. if (typeof setTimeout === 'function') {
  1769. cachedSetTimeout = setTimeout;
  1770. } else {
  1771. cachedSetTimeout = defaultSetTimout;
  1772. }
  1773. } catch (e) {
  1774. cachedSetTimeout = defaultSetTimout;
  1775. }
  1776. try {
  1777. if (typeof clearTimeout === 'function') {
  1778. cachedClearTimeout = clearTimeout;
  1779. } else {
  1780. cachedClearTimeout = defaultClearTimeout;
  1781. }
  1782. } catch (e) {
  1783. cachedClearTimeout = defaultClearTimeout;
  1784. }
  1785. } ())
  1786. function runTimeout(fun) {
  1787. if (cachedSetTimeout === setTimeout) {
  1788. //normal enviroments in sane situations
  1789. return setTimeout(fun, 0);
  1790. }
  1791. // if setTimeout wasn't available but was latter defined
  1792. if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
  1793. cachedSetTimeout = setTimeout;
  1794. return setTimeout(fun, 0);
  1795. }
  1796. try {
  1797. // when when somebody has screwed with setTimeout but no I.E. maddness
  1798. return cachedSetTimeout(fun, 0);
  1799. } catch(e){
  1800. try {
  1801. // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
  1802. return cachedSetTimeout.call(null, fun, 0);
  1803. } catch(e){
  1804. // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
  1805. return cachedSetTimeout.call(this, fun, 0);
  1806. }
  1807. }
  1808. }
  1809. function runClearTimeout(marker) {
  1810. if (cachedClearTimeout === clearTimeout) {
  1811. //normal enviroments in sane situations
  1812. return clearTimeout(marker);
  1813. }
  1814. // if clearTimeout wasn't available but was latter defined
  1815. if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
  1816. cachedClearTimeout = clearTimeout;
  1817. return clearTimeout(marker);
  1818. }
  1819. try {
  1820. // when when somebody has screwed with setTimeout but no I.E. maddness
  1821. return cachedClearTimeout(marker);
  1822. } catch (e){
  1823. try {
  1824. // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
  1825. return cachedClearTimeout.call(null, marker);
  1826. } catch (e){
  1827. // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
  1828. // Some versions of I.E. have different rules for clearTimeout vs setTimeout
  1829. return cachedClearTimeout.call(this, marker);
  1830. }
  1831. }
  1832. }
  1833. var queue = [];
  1834. var draining = false;
  1835. var currentQueue;
  1836. var queueIndex = -1;
  1837. function cleanUpNextTick() {
  1838. if (!draining || !currentQueue) {
  1839. return;
  1840. }
  1841. draining = false;
  1842. if (currentQueue.length) {
  1843. queue = currentQueue.concat(queue);
  1844. } else {
  1845. queueIndex = -1;
  1846. }
  1847. if (queue.length) {
  1848. drainQueue();
  1849. }
  1850. }
  1851. function drainQueue() {
  1852. if (draining) {
  1853. return;
  1854. }
  1855. var timeout = runTimeout(cleanUpNextTick);
  1856. draining = true;
  1857. var len = queue.length;
  1858. while(len) {
  1859. currentQueue = queue;
  1860. queue = [];
  1861. while (++queueIndex < len) {
  1862. if (currentQueue) {
  1863. currentQueue[queueIndex].run();
  1864. }
  1865. }
  1866. queueIndex = -1;
  1867. len = queue.length;
  1868. }
  1869. currentQueue = null;
  1870. draining = false;
  1871. runClearTimeout(timeout);
  1872. }
  1873. process.nextTick = function (fun) {
  1874. var args = new Array(arguments.length - 1);
  1875. if (arguments.length > 1) {
  1876. for (var i = 1; i < arguments.length; i++) {
  1877. args[i - 1] = arguments[i];
  1878. }
  1879. }
  1880. queue.push(new Item(fun, args));
  1881. if (queue.length === 1 && !draining) {
  1882. runTimeout(drainQueue);
  1883. }
  1884. };
  1885. // v8 likes predictible objects
  1886. function Item(fun, array) {
  1887. this.fun = fun;
  1888. this.array = array;
  1889. }
  1890. Item.prototype.run = function () {
  1891. this.fun.apply(null, this.array);
  1892. };
  1893. process.title = 'browser';
  1894. process.browser = true;
  1895. process.env = {};
  1896. process.argv = [];
  1897. process.version = ''; // empty string to avoid regexp issues
  1898. process.versions = {};
  1899. function noop() {}
  1900. process.on = noop;
  1901. process.addListener = noop;
  1902. process.once = noop;
  1903. process.off = noop;
  1904. process.removeListener = noop;
  1905. process.removeAllListeners = noop;
  1906. process.emit = noop;
  1907. process.prependListener = noop;
  1908. process.prependOnceListener = noop;
  1909. process.listeners = function (name) { return [] }
  1910. process.binding = function (name) {
  1911. throw new Error('process.binding is not supported');
  1912. };
  1913. process.cwd = function () { return '/' };
  1914. process.chdir = function (dir) {
  1915. throw new Error('process.chdir is not supported');
  1916. };
  1917. process.umask = function() { return 0; };
  1918. },{}],5:[function(_dereq_,module,exports){
  1919. (function(){var g={};
  1920. (function(window){var k,aa=this;aa.we=!0;function n(a,b){var c=a.split("."),d=aa;c[0]in d||!d.execScript||d.execScript("var "+c[0]);for(var e;c.length&&(e=c.shift());)c.length||void 0===b?d[e]?d=d[e]:d=d[e]={}:d[e]=b}function ba(a){var b=p;function c(){}c.prototype=b.prototype;a.Be=b.prototype;a.prototype=new c;a.prototype.constructor=a;a.ye=function(a,c,f){return b.prototype[c].apply(a,Array.prototype.slice.call(arguments,2))}};/*
  1921. Copyright 2016 Google Inc.
  1922. Licensed under the Apache License, Version 2.0 (the "License");
  1923. you may not use this file except in compliance with the License.
  1924. You may obtain a copy of the License at
  1925. http://www.apache.org/licenses/LICENSE-2.0
  1926. Unless required by applicable law or agreed to in writing, software
  1927. distributed under the License is distributed on an "AS IS" BASIS,
  1928. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1929. See the License for the specific language governing permissions and
  1930. limitations under the License.
  1931. */
  1932. function ca(a){this.c=Math.exp(Math.log(.5)/a);this.b=this.a=0}function da(a,b,c){var d=Math.pow(a.c,b);c=c*(1-d)+d*a.a;isNaN(c)||(a.a=c,a.b+=b)}function ea(a){return a.a/(1-Math.pow(a.c,a.b))};function fa(){this.c=new ca(2);this.f=new ca(5);this.a=0;this.b=5E5}fa.prototype.setDefaultEstimate=function(a){this.b=a};fa.prototype.getBandwidthEstimate=function(){return 128E3>this.a?this.b:Math.min(ea(this.c),ea(this.f))};function ga(){};function t(a,b,c,d){this.severity=a;this.category=b;this.code=c;this.data=Array.prototype.slice.call(arguments,3)}n("shaka.util.Error",t);t.prototype.toString=function(){return"shaka.util.Error "+JSON.stringify(this,null," ")};t.Severity={RECOVERABLE:1,CRITICAL:2};t.Category={NETWORK:1,TEXT:2,MEDIA:3,MANIFEST:4,STREAMING:5,DRM:6,PLAYER:7,CAST:8,STORAGE:9};
  1933. t.Code={UNSUPPORTED_SCHEME:1E3,BAD_HTTP_STATUS:1001,HTTP_ERROR:1002,TIMEOUT:1003,MALFORMED_DATA_URI:1004,UNKNOWN_DATA_URI_ENCODING:1005,REQUEST_FILTER_ERROR:1006,RESPONSE_FILTER_ERROR:1007,INVALID_TEXT_HEADER:2E3,INVALID_TEXT_CUE:2001,UNABLE_TO_DETECT_ENCODING:2003,BAD_ENCODING:2004,INVALID_XML:2005,INVALID_MP4_TTML:2007,INVALID_MP4_VTT:2008,BUFFER_READ_OUT_OF_BOUNDS:3E3,JS_INTEGER_OVERFLOW:3001,EBML_OVERFLOW:3002,EBML_BAD_FLOATING_POINT_SIZE:3003,MP4_SIDX_WRONG_BOX_TYPE:3004,MP4_SIDX_INVALID_TIMESCALE:3005,
  1934. MP4_SIDX_TYPE_NOT_SUPPORTED:3006,WEBM_CUES_ELEMENT_MISSING:3007,WEBM_EBML_HEADER_ELEMENT_MISSING:3008,WEBM_SEGMENT_ELEMENT_MISSING:3009,WEBM_INFO_ELEMENT_MISSING:3010,WEBM_DURATION_ELEMENT_MISSING:3011,WEBM_CUE_TRACK_POSITIONS_ELEMENT_MISSING:3012,WEBM_CUE_TIME_ELEMENT_MISSING:3013,MEDIA_SOURCE_OPERATION_FAILED:3014,MEDIA_SOURCE_OPERATION_THREW:3015,VIDEO_ERROR:3016,QUOTA_EXCEEDED_ERROR:3017,UNABLE_TO_GUESS_MANIFEST_TYPE:4E3,DASH_INVALID_XML:4001,DASH_NO_SEGMENT_INFO:4002,DASH_EMPTY_ADAPTATION_SET:4003,
  1935. DASH_EMPTY_PERIOD:4004,DASH_WEBM_MISSING_INIT:4005,DASH_UNSUPPORTED_CONTAINER:4006,DASH_PSSH_BAD_ENCODING:4007,DASH_NO_COMMON_KEY_SYSTEM:4008,DASH_MULTIPLE_KEY_IDS_NOT_SUPPORTED:4009,DASH_CONFLICTING_KEY_IDS:4010,UNPLAYABLE_PERIOD:4011,RESTRICTIONS_CANNOT_BE_MET:4012,NO_PERIODS:4014,HLS_PLAYLIST_HEADER_MISSING:4015,INVALID_HLS_TAG:4016,HLS_INVALID_PLAYLIST_HIERARCHY:4017,DASH_DUPLICATE_REPRESENTATION_ID:4018,HLS_MULTIPLE_MEDIA_INIT_SECTIONS_FOUND:4020,HLS_COULD_NOT_GUESS_MIME_TYPE:4021,HLS_MASTER_PLAYLIST_NOT_PROVIDED:4022,
  1936. HLS_REQUIRED_ATTRIBUTE_MISSING:4023,HLS_REQUIRED_TAG_MISSING:4024,HLS_COULD_NOT_GUESS_CODECS:4025,HLS_KEYFORMATS_NOT_SUPPORTED:4026,INVALID_STREAMS_CHOSEN:5005,NO_RECOGNIZED_KEY_SYSTEMS:6E3,REQUESTED_KEY_SYSTEM_CONFIG_UNAVAILABLE:6001,FAILED_TO_CREATE_CDM:6002,FAILED_TO_ATTACH_TO_VIDEO:6003,INVALID_SERVER_CERTIFICATE:6004,FAILED_TO_CREATE_SESSION:6005,FAILED_TO_GENERATE_LICENSE_REQUEST:6006,LICENSE_REQUEST_FAILED:6007,LICENSE_RESPONSE_REJECTED:6008,ENCRYPTED_CONTENT_WITHOUT_DRM_INFO:6010,NO_LICENSE_SERVER_GIVEN:6012,
  1937. OFFLINE_SESSION_REMOVED:6013,EXPIRED:6014,LOAD_INTERRUPTED:7E3,CAST_API_UNAVAILABLE:8E3,NO_CAST_RECEIVERS:8001,ALREADY_CASTING:8002,UNEXPECTED_CAST_ERROR:8003,CAST_CANCELED_BY_USER:8004,CAST_CONNECTION_TIMED_OUT:8005,CAST_RECEIVER_APP_UNAVAILABLE:8006,STORAGE_NOT_SUPPORTED:9E3,INDEXED_DB_ERROR:9001,OPERATION_ABORTED:9002,REQUESTED_ITEM_NOT_FOUND:9003,MALFORMED_OFFLINE_URI:9004,CANNOT_STORE_LIVE_OFFLINE:9005,STORE_ALREADY_IN_PROGRESS:9006,NO_INIT_DATA_FOR_OFFLINE:9007,LOCAL_PLAYER_INSTANCE_REQUIRED:9008};var ha=/^(?:([^:/?#.]+):)?(?:\/\/(?:([^/?#]*)@)?([^/#?]*?)(?::([0-9]+))?(?=[/#?]|$))?([^?#]+)?(?:\?([^#]*))?(?:#(.*))?$/;function ia(a){var b;a instanceof ia?(ja(this,a.aa),this.Ba=a.Ba,this.ca=a.ca,ka(this,a.Ja),this.W=a.W,la(this,ma(a.a)),this.ta=a.ta):a&&(b=String(a).match(ha))?(ja(this,b[1]||"",!0),this.Ba=na(b[2]||""),this.ca=na(b[3]||"",!0),ka(this,b[4]),this.W=na(b[5]||"",!0),la(this,b[6]||"",!0),this.ta=na(b[7]||"")):this.a=new oa(null)}k=ia.prototype;k.aa="";k.Ba="";k.ca="";k.Ja=null;k.W="";k.ta="";
  1938. k.toString=function(){var a=[],b=this.aa;b&&a.push(qa(b,ra,!0),":");if(b=this.ca){a.push("//");var c=this.Ba;c&&a.push(qa(c,ra,!0),"@");a.push(encodeURIComponent(b).replace(/%25([0-9a-fA-F]{2})/g,"%$1"));b=this.Ja;null!=b&&a.push(":",String(b))}if(b=this.W)this.ca&&"/"!=b.charAt(0)&&a.push("/"),a.push(qa(b,"/"==b.charAt(0)?sa:ta,!0));(b=this.a.toString())&&a.push("?",b);(b=this.ta)&&a.push("#",qa(b,ua));return a.join("")};
  1939. k.resolve=function(a){var b=new ia(this);"data"===b.aa&&(b=new ia);var c=!!a.aa;c?ja(b,a.aa):c=!!a.Ba;c?b.Ba=a.Ba:c=!!a.ca;c?b.ca=a.ca:c=null!=a.Ja;var d=a.W;if(c)ka(b,a.Ja);else if(c=!!a.W){if("/"!=d.charAt(0))if(this.ca&&!this.W)d="/"+d;else{var e=b.W.lastIndexOf("/");-1!=e&&(d=b.W.substr(0,e+1)+d)}if(".."==d||"."==d)d="";else if(-1!=d.indexOf("./")||-1!=d.indexOf("/.")){for(var e=!d.lastIndexOf("/",0),d=d.split("/"),f=[],g=0;g<d.length;){var h=d[g++];"."==h?e&&g==d.length&&f.push(""):".."==h?((1<
  1940. f.length||1==f.length&&""!=f[0])&&f.pop(),e&&g==d.length&&f.push("")):(f.push(h),e=!0)}d=f.join("/")}}c?b.W=d:c=""!==a.a.toString();c?la(b,ma(a.a)):c=!!a.ta;c&&(b.ta=a.ta);return b};function ja(a,b,c){a.aa=c?na(b,!0):b;a.aa&&(a.aa=a.aa.replace(/:$/,""))}function ka(a,b){if(b){b=Number(b);if(isNaN(b)||0>b)throw Error("Bad port number "+b);a.Ja=b}else a.Ja=null}function la(a,b,c){b instanceof oa?a.a=b:(c||(b=qa(b,va)),a.a=new oa(b))}
  1941. function na(a,b){return a?b?decodeURI(a):decodeURIComponent(a):""}function qa(a,b,c){return"string"==typeof a?(a=encodeURI(a).replace(b,wa),c&&(a=a.replace(/%25([0-9a-fA-F]{2})/g,"%$1")),a):null}function wa(a){a=a.charCodeAt(0);return"%"+(a>>4&15).toString(16)+(a&15).toString(16)}var ra=/[#\/\?@]/g,ta=/[\#\?:]/g,sa=/[\#\?]/g,va=/[\#\?@]/g,ua=/#/g;function oa(a){this.b=a||null}oa.prototype.a=null;oa.prototype.c=null;
  1942. oa.prototype.toString=function(){if(this.b)return this.b;if(!this.a)return"";var a=[],b;for(b in this.a)for(var c=encodeURIComponent(b),d=this.a[b],e=0;e<d.length;e++){var f=c;""!==d[e]&&(f+="="+encodeURIComponent(d[e]));a.push(f)}return this.b=a.join("&")};function ma(a){var b=new oa;b.b=a.b;if(a.a){var c={},d;for(d in a.a)c[d]=a.a[d].concat();b.a=c;b.c=a.c}return b};function xa(a,b){return a.reduce(function(a,b,e){return b["catch"](a.bind(null,e))}.bind(null,b),Promise.reject())}function x(a,b){return a.concat(b)}function y(){}function ya(a){return null!=a}function za(a){return function(b){return b!=a}}function Aa(a,b,c){return c.indexOf(a)==b};function z(a,b){if(!b.length)return a;var c=b.map(function(a){return new ia(a)});return a.map(function(a){return new ia(a)}).map(function(a){return c.map(a.resolve.bind(a))}).reduce(x,[]).map(function(a){return a.toString()})}function Ba(a,b){return{keySystem:a,licenseServerUri:"",distinctiveIdentifierRequired:!1,persistentStateRequired:!1,audioRobustness:"",videoRobustness:"",serverCertificate:null,initData:b||[],keyIds:[]}};function Ca(a,b,c,d,e){var f=e in d,g;for(g in b){var h=e+"."+g,l=f?d[e]:c[g],m=!!{".abr.manager":!0}[h]||!!{serverCertificate:!0}[g];if(f||g in a)void 0===b[g]?void 0===l||f?delete a[g]:a[g]=l:m?a[g]=b[g]:"object"==typeof a[g]&&"object"==typeof b[g]?Ca(a[g],b[g],l,d,h):typeof b[g]==typeof l&&(a[g]=b[g])}}function Da(a){return JSON.parse(JSON.stringify(a))};function A(){var a,b,c=new Promise(function(c,e){a=c;b=e});c.resolve=a;c.reject=b;return c};function B(a){this.f=!1;this.a=[];this.b=[];this.c=[];this.h=a||null}n("shaka.net.NetworkingEngine",B);B.RequestType={MANIFEST:0,SEGMENT:1,LICENSE:2,APP:3};var Ea={};B.registerScheme=function(a,b){Ea[a]=b};B.unregisterScheme=function(a){delete Ea[a]};B.prototype.Ld=function(a){this.b.push(a)};B.prototype.registerRequestFilter=B.prototype.Ld;B.prototype.oe=function(a){var b=this.b;a=b.indexOf(a);0<=a&&b.splice(a,1)};B.prototype.unregisterRequestFilter=B.prototype.oe;
  1943. B.prototype.Ic=function(){this.b=[]};B.prototype.clearAllRequestFilters=B.prototype.Ic;B.prototype.Md=function(a){this.c.push(a)};B.prototype.registerResponseFilter=B.prototype.Md;B.prototype.pe=function(a){var b=this.c;a=b.indexOf(a);0<=a&&b.splice(a,1)};B.prototype.unregisterResponseFilter=B.prototype.pe;B.prototype.Jc=function(){this.c=[]};B.prototype.clearAllResponseFilters=B.prototype.Jc;function Fa(){return{maxAttempts:2,baseDelay:1E3,backoffFactor:2,fuzzFactor:.5,timeout:0}}
  1944. function C(a,b){return{uris:a,method:"GET",body:null,headers:{},allowCrossSiteCredentials:!1,retryParameters:b}}B.prototype.m=function(){this.f=!0;this.b=[];this.c=[];for(var a=[],b=0;b<this.a.length;++b)a.push(this.a[b]["catch"](y));return Promise.all(a)};B.prototype.destroy=B.prototype.m;
  1945. B.prototype.request=function(a,b){if(this.f)return Promise.reject();b.method=b.method||"GET";b.headers=b.headers||{};b.retryParameters=b.retryParameters?Da(b.retryParameters):Fa();b.uris=Da(b.uris);var c=Date.now(),d=Promise.resolve();this.b.forEach(function(c){d=d.then(c.bind(null,a,b))});d=d["catch"](function(a){throw new t(2,1,1006,a);});d=d.then(function(){for(var d=Date.now()-c,f=b.retryParameters||{},g=f.maxAttempts||1,h=f.backoffFactor||2,f=null==f.baseDelay?1E3:f.baseDelay,l=this.g(a,b,0,
  1946. d),m=1;m<g;m++)l=l["catch"](function(c,e,f){if(f&&1==f.severity){f=new A;var g=b.retryParameters||{};window.setTimeout(f.resolve,c*(1+(2*Math.random()-1)*(null==g.fuzzFactor?.5:g.fuzzFactor)));return f.then(this.g.bind(this,a,b,e,d))}throw f;}.bind(this,f,m%b.uris.length)),f*=h;return l}.bind(this));this.a.push(d);return d.then(function(b){0<=this.a.indexOf(d)&&this.a.splice(this.a.indexOf(d),1);this.h&&!b.fromCache&&1==a&&this.h(b.timeMs,b.data.byteLength);return b}.bind(this))["catch"](function(a){a&&
  1947. (a.severity=2);0<=this.a.indexOf(d)&&this.a.splice(this.a.indexOf(d),1);return Promise.reject(a)}.bind(this))};B.prototype.request=B.prototype.request;
  1948. B.prototype.g=function(a,b,c,d){if(this.f)return Promise.reject();var e=new ia(b.uris[c]),f=e.aa;f||(f=location.protocol,f=f.slice(0,-1),ja(e,f),b.uris[c]=e.toString());f=Ea[f];if(!f)return Promise.reject(new t(2,1,1E3,e));var g=Date.now();return f(b.uris[c],b,a).then(function(b){void 0==b.timeMs&&(b.timeMs=Date.now()-g);var c=Date.now(),e=Promise.resolve();this.c.forEach(function(c){e=e.then(function(){return Promise.resolve(c(a,b))}.bind(this))});e=e["catch"](function(a){var b=2;a instanceof t&&
  1949. (b=a.severity);throw new t(b,1,1007,a);});return e.then(function(){b.timeMs+=Date.now()-c;b.timeMs+=d;return b})}.bind(this))};function Ga(a,b){for(var c=[],d=0;d<a.length;++d){for(var e=!1,f=0;f<c.length&&!(e=b?b(a[d],c[f]):a[d]===c[f]);++f);e||c.push(a[d])}return c}function Ha(a,b,c){for(var d=0;d<a.length;++d)if(c(a[d],b))return d;return-1};function Ia(){this.a={}}Ia.prototype.push=function(a,b){this.a.hasOwnProperty(a)?this.a[a].push(b):this.a[a]=[b]};Ia.prototype.get=function(a){return(a=this.a[a])?a.slice():null};Ia.prototype.remove=function(a,b){var c=this.a[a];if(c)for(var d=0;d<c.length;++d)c[d]==b&&(c.splice(d,1),--d)};function D(){this.a=new Ia}D.prototype.m=function(){Ja(this);this.a=null;return Promise.resolve()};function E(a,b,c,d){a.a&&(b=new Ka(b,c,d),a.a.push(c,b))}function La(a,b,c,d){E(a,b,c,function(a){this.ha(b,c);d(a)}.bind(a))}D.prototype.ha=function(a,b){if(this.a)for(var c=this.a.get(b)||[],d=0;d<c.length;++d){var e=c[d];e.target==a&&(e.ha(),this.a.remove(b,e))}};function Ja(a){if(a.a){var b=a.a,c=[],d;for(d in b.a)c.push.apply(c,b.a[d]);for(b=0;b<c.length;++b)c[b].ha();a.a.a={}}}
  1950. function Ka(a,b,c){this.target=a;this.type=b;this.a=c;this.target.addEventListener(b,c,!1)}Ka.prototype.ha=function(){this.target.removeEventListener(this.type,this.a,!1);this.a=this.target=null};function Ma(a){return!a||!Object.keys(a).length}function Na(a){return Object.keys(a).map(function(b){return a[b]})}function Oa(a,b){return Object.keys(a).reduce(function(c,d){c[d]=b(a[d],d);return c},{})}function Pa(a,b){return Object.keys(a).every(function(c){return b(c,a[c])})}function Qa(a,b){Object.keys(a).forEach(function(c){b(c,a[c])})};function F(a){if(!a)return"";a=new Uint8Array(a);239==a[0]&&187==a[1]&&191==a[2]&&(a=a.subarray(3));a=escape(Ra(a));try{return decodeURIComponent(a)}catch(b){throw new t(2,2,2004);}}n("shaka.util.StringUtils.fromUTF8",F);
  1951. function Sa(a,b,c){if(!a)return"";if(!c&&a.byteLength%2)throw new t(2,2,2004);if(a instanceof ArrayBuffer)var d=a;else c=new Uint8Array(a.byteLength),c.set(new Uint8Array(a)),d=c.buffer;a=Math.floor(a.byteLength/2);c=new Uint16Array(a);d=new DataView(d);for(var e=0;e<a;e++)c[e]=d.getUint16(2*e,b);return Ra(c)}n("shaka.util.StringUtils.fromUTF16",Sa);
  1952. function Ta(a){var b=new Uint8Array(a);if(239==b[0]&&187==b[1]&&191==b[2])return F(b);if(254==b[0]&&255==b[1])return Sa(b.subarray(2),!1);if(255==b[0]&&254==b[1])return Sa(b.subarray(2),!0);var c=function(a,b){return a.byteLength<=b||32<=a[b]&&126>=a[b]}.bind(null,b);if(b[0]||b[2]){if(!b[1]&&!b[3])return Sa(a,!0);if(c(0)&&c(1)&&c(2)&&c(3))return F(a)}else return Sa(a,!1);throw new t(2,2,2003);}n("shaka.util.StringUtils.fromBytesAutoDetect",Ta);
  1953. function Ua(a){a=unescape(encodeURIComponent(a));for(var b=new Uint8Array(a.length),c=0;c<a.length;++c)b[c]=a.charCodeAt(c);return b.buffer}n("shaka.util.StringUtils.toUTF8",Ua);function Ra(a){for(var b="",c=0;c<a.length;c+=16E3)b+=String.fromCharCode.apply(null,a.subarray(c,c+16E3));return b};function Va(a){this.a=null;this.b=function(){this.a=null;a()}.bind(this)}Va.prototype.cancel=function(){null!=this.a&&(clearTimeout(this.a),this.a=null)};function Wa(a){a.cancel();a.a=setTimeout(a.b,500)};function Xa(a,b){var c=void 0==b?!0:b,d=window.btoa(String.fromCharCode.apply(null,a)).replace(/\+/g,"-").replace(/\//g,"_");return c?d:d.replace(/=*$/,"")}n("shaka.util.Uint8ArrayUtils.toBase64",Xa);function Ya(a){a=window.atob(a.replace(/-/g,"+").replace(/_/g,"/"));for(var b=new Uint8Array(a.length),c=0;c<a.length;++c)b[c]=a.charCodeAt(c);return b}n("shaka.util.Uint8ArrayUtils.fromBase64",Ya);
  1954. function Za(a){for(var b=new Uint8Array(a.length/2),c=0;c<a.length;c+=2)b[c/2]=window.parseInt(a.substr(c,2),16);return b}n("shaka.util.Uint8ArrayUtils.fromHex",Za);function $a(a){for(var b="",c=0;c<a.length;++c){var d=a[c].toString(16);1==d.length&&(d="0"+d);b+=d}return b}n("shaka.util.Uint8ArrayUtils.toHex",$a);function ab(a,b){if(!a&&!b)return!0;if(!a||!b||a.length!=b.length)return!1;for(var c=0;c<a.length;++c)if(a[c]!=b[c])return!1;return!0}n("shaka.util.Uint8ArrayUtils.equal",ab);
  1955. n("shaka.util.Uint8ArrayUtils.concat",function(a){for(var b=0,c=0;c<arguments.length;++c)b+=arguments[c].length;for(var b=new Uint8Array(b),d=0,c=0;c<arguments.length;++c)b.set(arguments[c],d),d+=arguments[c].length;return b});function bb(a,b,c,d){this.j=this.i=this.v=null;this.J=!1;this.b=null;this.f=new D;this.a=[];this.o=[];this.l=new A;this.ka=a;this.h=null;this.g=function(a){this.l.reject(a);b(a)}.bind(this);this.A={};this.Ca=c;this.la=d;this.B=new Va(this.Kd.bind(this));this.ja=this.c=!1;this.G=[];this.ia=!1;this.O=setInterval(this.Jd.bind(this),1E3);this.l["catch"](function(){})}k=bb.prototype;
  1956. k.m=function(){this.c=!0;var a=this.a.map(function(a){return(a.ba.close()||Promise.resolve())["catch"](y)});this.l.reject();this.f&&a.push(this.f.m());this.j&&a.push(this.j.setMediaKeys(null)["catch"](y));this.O&&(clearInterval(this.O),this.O=null);this.B&&this.B.cancel();this.f=this.j=this.i=this.v=this.b=this.B=null;this.a=[];this.o=[];this.la=this.g=this.h=this.ka=null;return Promise.all(a)};k.configure=function(a){this.h=a};
  1957. k.init=function(a,b){var c={},d=[];this.ja=b;this.o=a.offlineSessionIds;cb(this,a,b||0<a.offlineSessionIds.length,c,d);return d.length?db(this,c,d):(this.J=!0,Promise.resolve())};
  1958. function eb(a,b){if(!a.i)return La(a.f,b,"encrypted",function(){this.g(new t(2,6,6010))}.bind(a)),Promise.resolve();a.j=b;La(a.f,a.j,"play",a.qd.bind(a));var c=a.j.setMediaKeys(a.i),c=c["catch"](function(a){return Promise.reject(new t(2,6,6003,a.message))}),d=null;a.b.serverCertificate&&(d=a.i.setServerCertificate(a.b.serverCertificate).then(function(){})["catch"](function(a){return Promise.reject(new t(2,6,6004,a.message))}));return Promise.all([c,d]).then(function(){if(this.c)return Promise.reject();
  1959. fb(this);this.b.initData.length||this.o.length||E(this.f,this.j,"encrypted",this.fd.bind(this))}.bind(a))["catch"](function(a){return this.c?Promise.resolve():Promise.reject(a)}.bind(a))}function gb(a,b){return Promise.all(b.map(function(a){return hb(this,a).then(function(a){if(a){for(var b=new A,c=0;c<this.a.length;c++)if(this.a[c].ba==a){this.a[c].ib=b;break}return Promise.all([a.remove(),b])}}.bind(this))}.bind(a)))}
  1960. function fb(a){var b=a.b?a.b.initData:[];b.forEach(function(a){ib(this,a.initDataType,a.initData)}.bind(a));a.o.forEach(function(a){hb(this,a)}.bind(a));b.length||a.o.length||a.l.resolve();return a.l}k.keySystem=function(){return this.b?this.b.keySystem:""};function jb(a){return a.a.map(function(a){return a.ba.sessionId})}k.ab=function(){var a=this.a.map(function(a){a=a.ba.expiration;return isNaN(a)?Infinity:a});return Math.min.apply(Math,a)};
  1961. function cb(a,b,c,d,e){var f=kb(a);b.periods.forEach(function(a){a.variants.forEach(function(a){f&&(a.drmInfos=[f]);a.drmInfos.forEach(function(b){lb(this,b);window.cast&&window.cast.__platform__&&"com.microsoft.playready"==b.keySystem&&(b.keySystem="com.chromecast.playready");var f=d[b.keySystem];f||(f={audioCapabilities:[],videoCapabilities:[],distinctiveIdentifier:"optional",persistentState:c?"required":"optional",sessionTypes:[c?"persistent-license":"temporary"],label:b.keySystem,drmInfos:[]},
  1962. d[b.keySystem]=f,e.push(b.keySystem));f.drmInfos.push(b);b.distinctiveIdentifierRequired&&(f.distinctiveIdentifier="required");b.persistentStateRequired&&(f.persistentState="required");var g=[];a.video&&g.push(a.video);a.audio&&g.push(a.audio);g.forEach(function(a){var c="video"==a.type?f.videoCapabilities:f.audioCapabilities,d=("video"==a.type?b.videoRobustness:b.audioRobustness)||"",e=a.mimeType;a.codecs&&(e+='; codecs="'+a.codecs+'"');c.push({robustness:d,contentType:e})}.bind(this))}.bind(this))}.bind(this))}.bind(a))}
  1963. function db(a,b,c){if(1==c.length&&""==c[0])return Promise.reject(new t(2,6,6E3));var d=new A,e=d;[!0,!1].forEach(function(a){c.forEach(function(c){var d=b[c];d.drmInfos.some(function(a){return!!a.licenseServerUri})==a&&(d.audioCapabilities.length||delete d.audioCapabilities,d.videoCapabilities.length||delete d.videoCapabilities,e=e["catch"](function(){return this.c?Promise.reject():navigator.requestMediaKeySystemAccess(c,[d])}.bind(this)))}.bind(this))}.bind(a));e=e["catch"](function(){return Promise.reject(new t(2,
  1964. 6,6001))});e=e.then(function(a){if(this.c)return Promise.reject();var c=0<=navigator.userAgent.indexOf("Edge/"),d=a.getConfiguration();this.v=(d.audioCapabilities||[]).concat(d.videoCapabilities||[]).map(function(a){return a.contentType});c&&(this.v=null);c=b[a.keySystem];mb(this,a.keySystem,c,c.drmInfos);return this.b.licenseServerUri?a.createMediaKeys():Promise.reject(new t(2,6,6012))}.bind(a)).then(function(a){if(this.c)return Promise.reject();this.i=a;this.J=!0}.bind(a))["catch"](function(a){if(this.c)return Promise.resolve();
  1965. this.v=this.b=null;return a instanceof t?Promise.reject(a):Promise.reject(new t(2,6,6002,a.message))}.bind(a));d.reject();return e}
  1966. function lb(a,b){var c=b.keySystem;if(c){if(!b.licenseServerUri){var d=a.h.servers[c];d&&(b.licenseServerUri=d)}b.keyIds||(b.keyIds=[]);if(c=a.h.advanced[c])b.distinctiveIdentifierRequired||(b.distinctiveIdentifierRequired=c.distinctiveIdentifierRequired),b.persistentStateRequired||(b.persistentStateRequired=c.persistentStateRequired),b.videoRobustness||(b.videoRobustness=c.videoRobustness),b.audioRobustness||(b.audioRobustness=c.audioRobustness),b.serverCertificate||(b.serverCertificate=c.serverCertificate)}}
  1967. function kb(a){if(Ma(a.h.clearKeys))return null;var b=[],c=[],d;for(d in a.h.clearKeys){var e=a.h.clearKeys[d],f=Za(d),e=Za(e),f={kty:"oct",kid:Xa(f,!1),k:Xa(e,!1)};b.push(f);c.push(f.kid)}a=JSON.stringify({keys:b});c=JSON.stringify({kids:c});c=[{initData:new Uint8Array(Ua(c)),initDataType:"keyids"}];return{keySystem:"org.w3.clearkey",licenseServerUri:"data:application/json;base64,"+window.btoa(a),distinctiveIdentifierRequired:!1,persistentStateRequired:!1,audioRobustness:"",videoRobustness:"",serverCertificate:null,
  1968. initData:c,keyIds:[]}}function mb(a,b,c,d){var e=[],f=[],g=[],h=[];nb(d,e,f,g,h);a.b={keySystem:b,licenseServerUri:e[0],distinctiveIdentifierRequired:"required"==c.distinctiveIdentifier,persistentStateRequired:"required"==c.persistentState,audioRobustness:c.audioCapabilities?c.audioCapabilities[0].robustness:"",videoRobustness:c.videoCapabilities?c.videoCapabilities[0].robustness:"",serverCertificate:f[0],initData:g,keyIds:h}}
  1969. function nb(a,b,c,d,e){function f(a,b){return a.keyId&&a.keyId==b.keyId?!0:a.initDataType==b.initDataType&&ab(a.initData,b.initData)}a.forEach(function(a){-1==b.indexOf(a.licenseServerUri)&&b.push(a.licenseServerUri);a.serverCertificate&&-1==Ha(c,a.serverCertificate,ab)&&c.push(a.serverCertificate);a.initData&&a.initData.forEach(function(a){-1==Ha(d,a,f)&&d.push(a)});if(a.keyIds)for(var g=0;g<a.keyIds.length;++g)-1==e.indexOf(a.keyIds[g])&&e.push(a.keyIds[g])})}
  1970. k.fd=function(a){for(var b=new Uint8Array(a.initData),c=0;c<this.a.length;++c)if(ab(b,this.a[c].initData))return;ib(this,a.initDataType,b)};
  1971. function hb(a,b){try{var c=a.i.createSession("persistent-license")}catch(f){var d=new t(2,6,6005,f.message);a.g(d);return Promise.reject(d)}E(a.f,c,"message",a.kc.bind(a));E(a.f,c,"keystatuseschange",a.ec.bind(a));var e={initData:null,ba:c,loaded:!1,zb:Infinity,ib:null};a.a.push(e);return c.load(b).then(function(a){if(!this.c){if(a)return e.loaded=!0,this.a.every(function(a){return a.loaded})&&this.l.resolve(),c;this.a.splice(this.a.indexOf(e),1);this.g(new t(2,6,6013))}}.bind(a),function(a){this.c||
  1972. (this.a.splice(this.a.indexOf(e),1),this.g(new t(2,6,6005,a.message)))}.bind(a))}
  1973. function ib(a,b,c){try{var d=a.ja?a.i.createSession("persistent-license"):a.i.createSession()}catch(e){a.g(new t(2,6,6005,e.message));return}E(a.f,d,"message",a.kc.bind(a));E(a.f,d,"keystatuseschange",a.ec.bind(a));a.a.push({initData:c,ba:d,loaded:!1,zb:Infinity,ib:null});d.generateRequest(b,c.buffer)["catch"](function(a){if(!this.c){for(var b=0;b<this.a.length;++b)if(this.a[b].ba==d){this.a.splice(b,1);break}this.g(new t(2,6,6006,a.message))}}.bind(a))}
  1974. k.kc=function(a){this.h.delayLicenseRequestUntilPlayed&&this.j.paused&&!this.ia?this.G.push(a):ob(this,a)};
  1975. function ob(a,b){for(var c=b.target,d,e=0;e<a.a.length;e++)if(a.a[e].ba==c){d=a.a[e].ib;break}e=C([a.b.licenseServerUri],a.h.retryParameters);e.body=b.message;e.method="POST";"com.microsoft.playready"!=a.b.keySystem&&"com.chromecast.playready"!=a.b.keySystem||pb(e);a.ka.request(2,e).then(function(a){return this.c?Promise.reject():c.update(a.data).then(function(){d&&d.resolve()})}.bind(a),function(a){if(this.c)return Promise.resolve();a=new t(2,6,6007,a);this.g(a);d&&d.reject(a)}.bind(a))["catch"](function(a){if(this.c)return Promise.resolve();
  1976. a=new t(2,6,6008,a.message);this.g(a);d&&d.reject(a)}.bind(a))}function pb(a){var b=Sa(a.body,!0,!0);if(-1==b.indexOf("PlayReadyKeyMessage"))a.headers["Content-Type"]="text/xml; charset=utf-8";else{for(var b=(new DOMParser).parseFromString(b,"application/xml"),c=b.getElementsByTagName("HttpHeader"),d=0;d<c.length;++d)a.headers[c[d].querySelector("name").textContent]=c[d].querySelector("value").textContent;a.body=Ya(b.querySelector("Challenge").textContent).buffer}}
  1977. k.ec=function(a){a=a.target;var b;for(b=0;b<this.a.length&&this.a[b].ba!=a;++b);if(b!=this.a.length){var c=!1;a.keyStatuses.forEach(function(a,d){if("string"==typeof d){var e=d;d=a;a=e}if("com.microsoft.playready"==this.b.keySystem&&16==d.byteLength){var e=new DataView(d),f=e.getUint32(0,!0),l=e.getUint16(4,!0),m=e.getUint16(6,!0);e.setUint32(0,f,!1);e.setUint16(4,l,!1);e.setUint16(6,m,!1)}"com.microsoft.playready"==this.b.keySystem&&"status-pending"==a&&(a="usable");"status-pending"!=a&&(this.a[b].loaded=
  1978. !0,this.a.every(function(a){return a.loaded})&&this.l.resolve());"expired"==a&&(c=!0);e=$a(new Uint8Array(d));this.A[e]=a}.bind(this));var d=a.expiration-Date.now();(0>d||c&&1E3>d)&&!this.a[b].ib&&(this.a.splice(b,1),a.close());Wa(this.B)}};k.Kd=function(){function a(a,c){return"expired"==c}!Ma(this.A)&&Pa(this.A,a)&&this.g(new t(2,6,6014));this.Ca(this.A)};
  1979. function qb(){var a=[],b=[{contentType:'video/mp4; codecs="avc1.42E01E"'},{contentType:'video/webm; codecs="vp8"'}],c=[{videoCapabilities:b,persistentState:"required",sessionTypes:["persistent-license"]},{videoCapabilities:b}],d={};"org.w3.clearkey com.widevine.alpha com.microsoft.playready com.apple.fps.2_0 com.apple.fps.1_0 com.apple.fps com.adobe.primetime".split(" ").forEach(function(b){var e=navigator.requestMediaKeySystemAccess(b,c).then(function(a){var c=a.getConfiguration().sessionTypes;d[b]=
  1980. {persistentState:c?0<=c.indexOf("persistent-license"):!1};return a.createMediaKeys()})["catch"](function(){d[b]=null});a.push(e)});return Promise.all(a).then(function(){return d})}k.qd=function(){for(var a=0;a<this.G.length;a++)ob(this,this.G[a]);this.ia=!0;this.G=[]};function rb(a,b){var c=a.keySystem();return!b.drmInfos.length||b.drmInfos.some(function(a){return a.keySystem==c})}
  1981. function sb(a,b){if(!a.length)return b;if(!b.length)return a;for(var c=[],d=0;d<a.length;d++)for(var e=0;e<b.length;e++)if(a[d].keySystem==b[e].keySystem){var f=a[d],e=b[e],g=[],g=g.concat(f.initData||[]),g=g.concat(e.initData||[]),h=[],h=h.concat(f.keyIds),h=h.concat(e.keyIds);c.push({keySystem:f.keySystem,licenseServerUri:f.licenseServerUri||e.licenseServerUri,distinctiveIdentifierRequired:f.distinctiveIdentifierRequired||e.distinctiveIdentifierRequired,persistentStateRequired:f.persistentStateRequired||
  1982. e.persistentStateRequired,videoRobustness:f.videoRobustness||e.videoRobustness,audioRobustness:f.audioRobustness||e.audioRobustness,serverCertificate:f.serverCertificate||e.serverCertificate,initData:g,keyIds:h});break}return c}k.Jd=function(){this.a.forEach(function(a){var b=a.zb,c=a.ba.expiration;isNaN(c)&&(c=Infinity);c!=b&&(this.la(a.ba.sessionId,c),a.zb=c)}.bind(this))};function tb(a){this.f=null;this.c=a;this.h=0;this.g=Infinity;this.a=this.b=null}var ub={};function vb(a,b){ub[a]=b.length?wb.bind(null,b):b}n("shaka.media.TextEngine.registerParser",vb);n("shaka.media.TextEngine.unregisterParser",function(a){delete ub[a]});function xb(a,b,c){return a>=b?null:new VTTCue(a,b,c)}n("shaka.media.TextEngine.makeCue",xb);tb.prototype.m=function(){this.c&&yb(this,function(){return!0});this.c=this.f=null;return Promise.resolve()};
  1983. function zb(a,b,c,d){return Promise.resolve().then(function(){if(this.c)if(null==c||null==d)this.f.parseInit(b);else{for(var a=this.f.parseMedia(b,{periodStart:this.h,segmentStart:c,segmentEnd:d}),f=0;f<a.length&&!(a[f].startTime>=this.g);++f)this.c.addCue(a[f]);null==this.b&&(this.b=c);this.a=Math.min(d,this.g)}}.bind(a))}
  1984. tb.prototype.remove=function(a,b){return Promise.resolve().then(function(){this.c&&(yb(this,function(c){return c.startTime>=b||c.endTime<=a?!1:!0}),null==this.b||b<=this.b||a>=this.a||(a<=this.b&&b>=this.a?this.b=this.a=null:a<=this.b&&b<this.a?this.b=b:a>this.b&&b>=this.a&&(this.a=a)))}.bind(this))};function yb(a,b){for(var c=a.c.cues,d=[],e=0;e<c.length;++e)b(c[e])&&d.push(c[e]);for(e=0;e<d.length;++e)a.c.removeCue(d[e])}function wb(a){this.Na=a}
  1985. wb.prototype.parseInit=function(a){this.Na(a,0,null,null)};wb.prototype.parseMedia=function(a,b){return this.Na(a,b.periodStart,b.segmentStart,b.segmentEnd)};function Ab(a){return!a||1==a.length&&1E-6>a.end(0)-a.start(0)?null:a.length?a.end(a.length-1):null}function Bb(a,b){return!a||!a.length||1==a.length&&1E-6>a.end(0)-a.start(0)?!1:b>=a.start(0)&&b<=a.end(a.length-1)}function Cb(a,b){if(!a||!a.length||1==a.length&&1E-6>a.end(0)-a.start(0))return 0;for(var c=0,d=a.length-1;0<=d&&a.end(d)>b;--d)c+=a.end(d)-Math.max(a.start(d),b);return c};function Db(a,b,c){this.f=a;this.N=b;this.i=c;this.c={};this.a=null;this.b={};this.g=new D;this.h=!1}
  1986. function Eb(){var a={};'video/mp4; codecs="avc1.42E01E",video/mp4; codecs="avc3.42E01E",video/mp4; codecs="hvc1.1.6.L93.90",audio/mp4; codecs="mp4a.40.2",audio/mp4; codecs="ac-3",audio/mp4; codecs="ec-3",video/webm; codecs="vp8",video/webm; codecs="vp9",video/webm; codecs="av1",audio/webm; codecs="vorbis",audio/webm; codecs="opus",video/mp2t; codecs="avc1.42E01E",video/mp2t; codecs="avc3.42E01E",video/mp2t; codecs="hvc1.1.6.L93.90",video/mp2t; codecs="mp4a.40.2",video/mp2t; codecs="ac-3",video/mp2t; codecs="ec-3",video/mp2t; codecs="mp4a.40.2",text/vtt,application/mp4; codecs="wvtt",application/ttml+xml,application/mp4; codecs="stpp"'.split(",").forEach(function(b){a[b]=!!ub[b]||
  1987. MediaSource.isTypeSupported(b);var c=b.split(";")[0];a[c]=a[c]||a[b]});return a}k=Db.prototype;k.m=function(){this.h=!0;var a=[],b;for(b in this.b){var c=this.b[b],d=c[0];this.b[b]=c.slice(0,1);d&&a.push(d.p["catch"](y));for(d=1;d<c.length;++d)c[d].p["catch"](y),c[d].p.reject()}this.a&&a.push(this.a.m());return Promise.all(a).then(function(){this.g.m();this.a=this.i=this.N=this.f=this.g=null;this.c={};this.b={}}.bind(this))};
  1988. k.init=function(a){for(var b in a){var c=a[b];"text"==b?Fb(this,c):(c=this.N.addSourceBuffer(c),E(this.g,c,"error",this.je.bind(this,b)),E(this.g,c,"updateend",this.Ia.bind(this,b)),this.c[b]=c,this.b[b]=[])}};function Fb(a,b){a.a||(a.a=new tb(a.i));a.a.f=new ub[b]}function Gb(a,b){if("text"==b)var c=a.a.b;else c=Ib(a,b),c=!c||1==c.length&&1E-6>c.end(0)-c.start(0)?null:1==c.length&&0>c.start(0)?0:c.length?c.start(0):null;return c}function Ib(a,b){try{return a.c[b].buffered}catch(c){return null}}
  1989. function Jb(a,b,c,d,e){return"text"==b?zb(a.a,c,d,e):Kb(a,b,a.ie.bind(a,b,c))}k.remove=function(a,b,c){return"text"==a?this.a.remove(b,c):Kb(this,a,this.qc.bind(this,a,b,c))};function Lb(a,b){return"text"==b?a.a.remove(0,Infinity):Kb(a,b,a.qc.bind(a,b,0,a.N.duration))}function Mb(a,b,c,d){if("text"==b)return a.a.h=c,null!=d&&(a.a.g=d),Promise.resolve();null==d&&(d=Infinity);return Promise.all([Kb(a,b,a.Ec.bind(a,b)),Kb(a,b,a.Zd.bind(a,b,c)),Kb(a,b,a.Xd.bind(a,b,d))])}
  1990. k.endOfStream=function(a){return Nb(this,function(){a?this.N.endOfStream(a):this.N.endOfStream()}.bind(this))};k.pa=function(a){return Nb(this,function(){this.N.duration=a}.bind(this))};k.Y=function(){return this.N.duration};k.ie=function(a,b){this.c[a].appendBuffer(b)};k.qc=function(a,b,c){c<=b?this.Ia(a):this.c[a].remove(b,c)};k.Ec=function(a){var b=this.c[a].appendWindowEnd;this.c[a].abort();this.c[a].appendWindowEnd=b;this.Ia(a)};k.Oc=function(a){this.f.currentTime-=.001;this.Ia(a)};
  1991. k.Zd=function(a,b){this.c[a].timestampOffset=b;this.Ia(a)};k.Xd=function(a,b){this.c[a].appendWindowEnd=b+.04;this.Ia(a)};k.je=function(a){this.b[a][0].p.reject(new t(2,3,3014,this.f.error?this.f.error.code:0))};k.Ia=function(a){var b=this.b[a][0];b&&(b.p.resolve(),Ob(this,a))};
  1992. function Kb(a,b,c){if(a.h)return Promise.reject();c={start:c,p:new A};a.b[b].push(c);if(1==a.b[b].length)try{c.start()}catch(d){"QuotaExceededError"==d.name?c.p.reject(new t(2,3,3017,b)):c.p.reject(new t(2,3,3015,d)),Ob(a,b)}return c.p}
  1993. function Nb(a,b){if(a.h)return Promise.reject();var c=[],d;for(d in a.c){var e=new A,f={start:function(a){a.resolve()}.bind(null,e),p:e};a.b[d].push(f);c.push(e);1==a.b[d].length&&f.start()}return Promise.all(c).then(function(){var a;try{b()}catch(l){var c=Promise.reject(new t(2,3,3015,l))}for(a in this.c)Ob(this,a);return c}.bind(a),function(){return Promise.reject()}.bind(a))}function Ob(a,b){a.b[b].shift();var c=a.b[b][0];if(c)try{c.start()}catch(d){c.p.reject(new t(2,3,3015,d)),Ob(a,b)}};function Pb(a,b,c){return c==b||a>=Qb&&c==b.split("-")[0]||a>=Rb&&c.split("-")[0]==b.split("-")[0]?!0:!1}var Qb=1,Rb=2;function Sb(a){a=a.toLowerCase().split("-");var b=Tb[a[0]];b&&(a[0]=b);return a.join("-")}
  1994. var Tb={aar:"aa",abk:"ab",afr:"af",aka:"ak",alb:"sq",amh:"am",ara:"ar",arg:"an",arm:"hy",asm:"as",ava:"av",ave:"ae",aym:"ay",aze:"az",bak:"ba",bam:"bm",baq:"eu",bel:"be",ben:"bn",bih:"bh",bis:"bi",bod:"bo",bos:"bs",bre:"br",bul:"bg",bur:"my",cat:"ca",ces:"cs",cha:"ch",che:"ce",chi:"zh",chu:"cu",chv:"cv",cor:"kw",cos:"co",cre:"cr",cym:"cy",cze:"cs",dan:"da",deu:"de",div:"dv",dut:"nl",dzo:"dz",ell:"el",eng:"en",epo:"eo",est:"et",eus:"eu",ewe:"ee",fao:"fo",fas:"fa",fij:"fj",fin:"fi",fra:"fr",fre:"fr",
  1995. fry:"fy",ful:"ff",geo:"ka",ger:"de",gla:"gd",gle:"ga",glg:"gl",glv:"gv",gre:"el",grn:"gn",guj:"gu",hat:"ht",hau:"ha",heb:"he",her:"hz",hin:"hi",hmo:"ho",hrv:"hr",hun:"hu",hye:"hy",ibo:"ig",ice:"is",ido:"io",iii:"ii",iku:"iu",ile:"ie",ina:"ia",ind:"id",ipk:"ik",isl:"is",ita:"it",jav:"jv",jpn:"ja",kal:"kl",kan:"kn",kas:"ks",kat:"ka",kau:"kr",kaz:"kk",khm:"km",kik:"ki",kin:"rw",kir:"ky",kom:"kv",kon:"kg",kor:"ko",kua:"kj",kur:"ku",lao:"lo",lat:"la",lav:"lv",lim:"li",lin:"ln",lit:"lt",ltz:"lb",lub:"lu",
  1996. lug:"lg",mac:"mk",mah:"mh",mal:"ml",mao:"mi",mar:"mr",may:"ms",mkd:"mk",mlg:"mg",mlt:"mt",mon:"mn",mri:"mi",msa:"ms",mya:"my",nau:"na",nav:"nv",nbl:"nr",nde:"nd",ndo:"ng",nep:"ne",nld:"nl",nno:"nn",nob:"nb",nor:"no",nya:"ny",oci:"oc",oji:"oj",ori:"or",orm:"om",oss:"os",pan:"pa",per:"fa",pli:"pi",pol:"pl",por:"pt",pus:"ps",que:"qu",roh:"rm",ron:"ro",rum:"ro",run:"rn",rus:"ru",sag:"sg",san:"sa",sin:"si",slk:"sk",slo:"sk",slv:"sl",sme:"se",smo:"sm",sna:"sn",snd:"sd",som:"so",sot:"st",spa:"es",sqi:"sq",
  1997. srd:"sc",srp:"sr",ssw:"ss",sun:"su",swa:"sw",swe:"sv",tah:"ty",tam:"ta",tat:"tt",tel:"te",tgk:"tg",tgl:"tl",tha:"th",tib:"bo",tir:"ti",ton:"to",tsn:"tn",tso:"ts",tuk:"tk",tur:"tr",twi:"tw",uig:"ug",ukr:"uk",urd:"ur",uzb:"uz",ven:"ve",vie:"vi",vol:"vo",wel:"cy",wln:"wa",wol:"wo",xho:"xh",yid:"yi",yor:"yo",zha:"za",zho:"zh",zul:"zu"};function Ub(a,b,c){var d=a.video;return d&&(d.width<b.minWidth||d.width>b.maxWidth||d.width>c.width||d.height<b.minHeight||d.height>b.maxHeight||d.height>c.height||d.width*d.height<b.minPixels||d.width*d.height>b.maxPixels)||a.bandwidth<b.minBandwidth||a.bandwidth>b.maxBandwidth?!1:!0}function Vb(a,b,c){var d=!1;a.variants.forEach(function(a){var e=a.allowedByApplication;a.allowedByApplication=Ub(a,b,c);e!=a.allowedByApplication&&(d=!0)});return d}
  1998. function Wb(a,b,c){var d=b.video,e=b.audio;for(b=0;b<c.variants.length;++b){var f=c.variants[b],g=a,h=e,l=d;(g&&g.J&&!rb(g,f)?0:Xb(f.audio,g,h)&&Xb(f.video,g,l))||(c.variants.splice(b,1),--b)}for(b=0;b<c.textStreams.length;++b)a=c.textStreams[b],ub[Yb(a.mimeType,a.codecs)]||(c.textStreams.splice(b,1),--b)}
  1999. function Xb(a,b,c){if(!a)return!0;var d=null;b&&b.J&&(d=b.v);b=Yb(a.mimeType,a.codecs);return!ub[b]&&!MediaSource.isTypeSupported(b)||d&&a.encrypted&&0>d.indexOf(b)||c&&(a.mimeType!=c.mimeType||a.codecs.split(".")[0]!=c.codecs.split(".")[0])?!1:!0}
  2000. function Zb(a,b,c){var d=null;return $b(a.variants).map(function(a){var e;a.video&&a.audio?e=c==a.video.id&&b==a.audio.id:e=a.video&&c==a.video.id||a.audio&&b==a.audio.id;var g="";a.video&&(g+=a.video.codecs);a.audio&&(""!=g&&(g+=", "),g+=a.audio.codecs,d=a.audio.label);var h=a.audio?a.audio.codecs:null,l=a.video?a.video.codecs:null,m=null;a.video?m=a.video.mimeType:a.audio&&(m=a.audio.mimeType);var q=null;a.audio?q=a.audio.kind:a.video&&(q=a.video.kind);var r=Ga((a.audio?a.audio.roles:[]).concat(a.video?
  2001. a.video.roles:[]));return{id:a.id,active:e,type:"variant",bandwidth:a.bandwidth,language:a.language,label:d,kind:q||null,width:a.video?a.video.width:null,height:a.video?a.video.height:null,frameRate:a.video?a.video.frameRate:void 0,mimeType:m,codecs:g,audioCodec:h,videoCodec:l,primary:a.primary,roles:r,videoId:a.video?a.video.id:null,audioId:a.audio?a.audio.id:null}})}
  2002. function ac(a,b){return a.textStreams.map(function(a){return{id:a.id,active:b==a.id,type:"text",language:a.language,label:a.label,kind:a.kind,mimeType:a.mimeType,codecs:a.codecs||null,audioCodec:null,videoCodec:null,primary:a.primary,roles:a.roles}})}function bc(a,b){for(var c=0;c<a.variants.length;c++)if(a.variants[c].id==b.id)return a.variants[c];return null}function cc(a,b){for(var c=0;c<a.textStreams.length;c++)if(a.textStreams[c].id==b.id)return a.textStreams[c];return null}
  2003. function $b(a){return a.filter(function(a){return a.allowedByApplication&&a.allowedByKeySystem})}
  2004. function dc(a,b,c,d){var e=$b(a.variants),f=e.filter(function(a){return a.language==e[0].language});a=e.filter(function(a){return a.primary});a.length&&(f=a);if(b){var g=Sb(b);[Rb,Qb,0].forEach(function(a){var b=!1;e.forEach(function(d){g=Sb(g);var e=Sb(d.language);Pb(a,g,e)&&(b?f.push(d):(f=[d],b=!0),c&&(c.audio=!0))})})}var h=d||"";return h&&(b=f.filter(function(a){return a.audio&&-1<a.audio.roles.indexOf(h)||a.video&&-1<a.video.roles.indexOf(h)}),b.length)?b:f}
  2005. function ec(a,b,c,d){var e=a.textStreams,f=e;a=e.filter(function(a){return a.primary});a.length&&(f=a);if(b){var g=Sb(b);[Rb,Qb,0].forEach(function(a){var b=!1;e.forEach(function(d){var e=Sb(d.language);Pb(a,g,e)&&(b?f.push(d):(f=[d],b=!0),c&&(c.text=!0))})})}var h=d||"";return h&&(b=f.filter(function(a){return a&&-1<a.roles.indexOf(h)}),b.length)?b:f}function fc(a,b,c){for(var d=0;d<c.length;d++)if(c[d].audio==a&&c[d].video==b)return c[d];return null}
  2006. function gc(a,b,c){function d(a,b){return null==a?null==b:b.id==a}for(var e=0;e<c.length;e++)if(d(a,c[e].audio)&&d(b,c[e].video))return c[e];return null}function Yb(a,b){var c=a;b&&(c+='; codecs="'+b+'"');return c}function hc(a,b){for(var c=a.periods.length-1;0<c;--c)if(b>=a.periods[c].startTime)return c;return 0}
  2007. function ic(a,b){for(var c=0;c<a.periods.length;++c){var d=a.periods[c];if("text"==b.type)for(var e=0;e<d.textStreams.length;++e){if(d.textStreams[e]==b)return c}else for(e=0;e<d.variants.length;++e){var f=d.variants[e];if(f.audio==b||f.video==b||f.video&&f.video.trickModeVideo==b)return c}}return-1};function H(){this.f=null;this.b=!1;this.a=new fa;this.h=[];this.g=[];this.j=!1;this.c=null;this.i={minWidth:0,maxWidth:Infinity,minHeight:0,maxHeight:Infinity,minPixels:0,maxPixels:Infinity,minBandwidth:0,maxBandwidth:Infinity}}n("shaka.abr.SimpleAbrManager",H);H.prototype.stop=function(){this.f=null;this.b=!1;this.h=[];this.g=[];this.c=null};H.prototype.stop=H.prototype.stop;H.prototype.init=function(a){this.f=a};H.prototype.init=H.prototype.init;
  2008. H.prototype.chooseStreams=function(a){var b={};if(-1<a.indexOf("audio")||-1<a.indexOf("video")){var c=this.h;var d=jc(this.i,c);var e=this.a.getBandwidthEstimate();if(c.length&&!d.length)throw new t(2,4,4012);for(var c=d[0],f=0;f<d.length;++f){var g=d[f],h=(d[f+1]||{bandwidth:Infinity}).bandwidth/.85;e>=g.bandwidth/.95&&e<=h&&(c=g)}(d=c)&&d.video&&(b.video=d.video);d&&d.audio&&(b.audio=d.audio)}-1<a.indexOf("text")&&(b.text=this.g[0]);this.c=Date.now();return b};H.prototype.chooseStreams=H.prototype.chooseStreams;
  2009. H.prototype.enable=function(){this.b=!0};H.prototype.enable=H.prototype.enable;H.prototype.disable=function(){this.b=!1};H.prototype.disable=H.prototype.disable;H.prototype.segmentDownloaded=function(a,b){var c=this.a;if(!(16E3>b)){var d=8E3*b/a,e=a/1E3;c.a+=b;da(c.c,e,d);da(c.f,e,d)}if(null!=this.c&&this.b)a:{if(!this.j){if(!(128E3<=this.a.a))break a;this.j=!0}else if(8E3>Date.now()-this.c)break a;c=this.chooseStreams(["audio","video"]);this.a.getBandwidthEstimate();this.f(c)}};
  2010. H.prototype.segmentDownloaded=H.prototype.segmentDownloaded;H.prototype.getBandwidthEstimate=function(){return this.a.getBandwidthEstimate()};H.prototype.getBandwidthEstimate=H.prototype.getBandwidthEstimate;H.prototype.setDefaultEstimate=function(a){this.a.setDefaultEstimate(a)};H.prototype.setDefaultEstimate=H.prototype.setDefaultEstimate;H.prototype.setRestrictions=function(a){this.i=a};H.prototype.setRestrictions=H.prototype.setRestrictions;H.prototype.setVariants=function(a){this.h=a};
  2011. H.prototype.setVariants=H.prototype.setVariants;H.prototype.setTextStreams=function(a){this.g=a};H.prototype.setTextStreams=H.prototype.setTextStreams;function jc(a,b){return b.filter(function(b){return Ub(b,a,{width:Infinity,height:Infinity})}).sort(function(a,b){return a.bandwidth-b.bandwidth})};function I(a,b){var c=b||{},d;for(d in c)this[d]=c[d];this.defaultPrevented=this.cancelable=this.bubbles=!1;this.timeStamp=window.performance&&window.performance.now?window.performance.now():Date.now();this.type=a;this.isTrusted=!1;this.target=this.currentTarget=null;this.a=!1}I.prototype.preventDefault=function(){this.cancelable&&(this.defaultPrevented=!0)};I.prototype.stopImmediatePropagation=function(){this.a=!0};I.prototype.stopPropagation=function(){};var kc="ended play playing pause pausing ratechange seeked seeking timeupdate volumechange".split(" "),lc="buffered currentTime duration ended loop muted paused playbackRate seeking videoHeight videoWidth volume".split(" "),mc=["loop","playbackRate"],nc=["pause","play"],oc="adaptation buffering emsg error loading unloading texttrackvisibility timelineregionadded timelineregionenter timelineregionexit trackschanged".split(" "),pc="drmInfo getAudioLanguages getConfiguration getExpiration getManifestUri getPlaybackRate getPlayheadTimeAsDate getTextLanguages getTextTracks getTracks getStats getVariantTracks isBuffering isInProgress isLive isTextTrackVisible keySystem seekRange".split(" "),
  2012. qc=[["getConfiguration","configure"]],rc=[["isTextTrackVisible","setTextTrackVisibility"]],sc="addTextTrack cancelTrickPlay configure resetConfiguration selectAudioLanguage selectTextLanguage selectTextTrack selectTrack selectVariantTrack setTextTrackVisibility trickPlay".split(" "),uc=["load","unload"];
  2013. function vc(a){return JSON.stringify(a,function(a,c){if("manager"!=a&&"function"!=typeof c){if(c instanceof Event||c instanceof I){var b={},e;for(e in c){var f=c[e];f&&"object"==typeof f||e in Event||(b[e]=f)}return b}if(c instanceof TimeRanges)for(b={__type__:"TimeRanges",length:c.length,start:[],end:[]},e=0;e<c.length;++e)b.start.push(c.start(e)),b.end.push(c.end(e));else b="number"==typeof c?isNaN(c)?"NaN":isFinite(c)?c:0>c?"-Infinity":"Infinity":c;return b}})}
  2014. function wc(a){return JSON.parse(a,function(a,c){return"NaN"==c?NaN:"-Infinity"==c?-Infinity:"Infinity"==c?Infinity:c&&"object"==typeof c&&"TimeRanges"==c.__type__?xc(c):c})}function xc(a){return{length:a.length,start:function(b){return a.start[b]},end:function(b){return a.end[b]}}};function yc(a,b,c,d,e){this.J=a;this.l=b;this.B=c;this.G=d;this.v=e;this.c=this.j=this.h=!1;this.A="";this.a=this.i=null;this.b={video:{},player:{}};this.o=0;this.f={};this.g=null}k=yc.prototype;k.m=function(){zc(this);this.a&&(this.a.leave(function(){},function(){}),this.a=null);this.G=this.B=this.l=null;this.c=this.j=this.h=!1;this.g=this.f=this.b=this.i=null;return Promise.resolve()};k.V=function(){return this.c};k.Fb=function(){return this.A};
  2015. k.init=function(){if(window.chrome&&chrome.cast&&chrome.cast.isAvailable){delete window.__onGCastApiAvailable;this.h=!0;this.l();var a=new chrome.cast.SessionRequest(this.J),a=new chrome.cast.ApiConfig(a,this.gd.bind(this),this.sd.bind(this),"origin_scoped");chrome.cast.initialize(a,function(){},function(){})}else window.__onGCastApiAvailable=function(a){a&&this.init()}.bind(this)};k.Ib=function(a){this.i=a;this.c&&Ac(this,{type:"appData",appData:this.i})};
  2016. k.cast=function(a){if(!this.h)return Promise.reject(new t(1,8,8E3));if(!this.j)return Promise.reject(new t(1,8,8001));if(this.c)return Promise.reject(new t(1,8,8002));this.g=new A;chrome.cast.requestSession(this.Bb.bind(this,a),this.cc.bind(this));return this.g};k.$a=function(){this.c&&(zc(this),this.a&&(this.a.stop(function(){},function(){}),this.a=null))};
  2017. k.get=function(a,b){if("video"==a){if(0<=nc.indexOf(b))return this.pc.bind(this,a,b)}else if("player"==a){if(0<=sc.indexOf(b))return this.pc.bind(this,a,b);if(0<=uc.indexOf(b))return this.Od.bind(this,a,b);if(0<=pc.indexOf(b))return this.lc.bind(this,a,b)}return this.lc(a,b)};k.set=function(a,b,c){this.b[a][b]=c;Ac(this,{type:"set",targetName:a,property:b,value:c})};
  2018. k.Bb=function(a,b){this.a=b;this.a.addUpdateListener(this.dc.bind(this));this.a.addMessageListener("urn:x-cast:com.google.shaka.v2",this.md.bind(this));this.dc();Ac(this,{type:"init",initState:a,appData:this.i});this.g.resolve()};k.cc=function(a){var b=8003;switch(a.code){case "cancel":b=8004;break;case "timeout":b=8005;break;case "receiver_unavailable":b=8006}this.g.reject(new t(2,8,b,a))};k.lc=function(a,b){return this.b[a][b]};
  2019. k.pc=function(a,b){Ac(this,{type:"call",targetName:a,methodName:b,args:Array.prototype.slice.call(arguments,2)})};k.Od=function(a,b){var c=Array.prototype.slice.call(arguments,2),d=new A,e=this.o.toString();this.o++;this.f[e]=d;Ac(this,{type:"asyncCall",targetName:a,methodName:b,args:c,id:e});return d};k.gd=function(a){var b=this.v();this.g=new A;this.Bb(b,a)};k.sd=function(a){this.j="available"==a;this.l()};
  2020. k.dc=function(){var a=this.a?"connected"==this.a.status:!1;if(this.c&&!a){this.G();for(var b in this.b)this.b[b]={};zc(this)}this.A=(this.c=a)?this.a.receiver.friendlyName:"";this.l()};function zc(a){for(var b in a.f){var c=a.f[b];delete a.f[b];c.reject(new t(1,7,7E3))}}
  2021. k.md=function(a,b){var c=wc(b);switch(c.type){case "event":var d=c.targetName,e=c.event;this.B(d,new I(e.type,e));break;case "update":e=c.update;for(d in e){var c=this.b[d]||{};for(f in e[d])c[f]=e[d][f]}break;case "asyncComplete":d=c.id;var f=c.error;c=this.f[d];delete this.f[d];if(c)if(f){d=new t(f.severity,f.category,f.code);for(e in f)d[e]=f[e];c.reject(d)}else c.resolve()}};function Ac(a,b){var c=vc(b);a.a.sendMessage("urn:x-cast:com.google.shaka.v2",c,function(){},ga)};function p(){this.nb=new Ia;this.Ta=this}p.prototype.addEventListener=function(a,b){this.nb.push(a,b)};p.prototype.removeEventListener=function(a,b){this.nb.remove(a,b)};p.prototype.dispatchEvent=function(a){for(var b=this.nb.get(a.type)||[],c=0;c<b.length;++c){a.target=this.Ta;a.currentTarget=this.Ta;var d=b[c];try{d.handleEvent?d.handleEvent(a):d.call(this,a)}catch(e){}if(a.a)break}return a.defaultPrevented};function J(a,b,c){p.call(this);this.c=a;this.b=b;this.h=this.f=this.g=this.i=this.j=null;this.a=new yc(c,this.ee.bind(this),this.fe.bind(this),this.ge.bind(this),this.Vb.bind(this));Bc(this)}ba(J);n("shaka.cast.CastProxy",J);J.prototype.m=function(a){a&&this.a&&this.a.$a();a=[this.h?this.h.m():null,this.b?this.b.m():null,this.a?this.a.m():null];this.a=this.h=this.i=this.j=this.b=this.c=null;return Promise.all(a)};J.prototype.destroy=J.prototype.m;J.prototype.Zc=function(){return this.j};
  2022. J.prototype.getVideo=J.prototype.Zc;J.prototype.Tc=function(){return this.i};J.prototype.getPlayer=J.prototype.Tc;J.prototype.Fc=function(){return this.a?this.a.h&&this.a.j:!1};J.prototype.canCast=J.prototype.Fc;J.prototype.V=function(){return this.a?this.a.V():!1};J.prototype.isCasting=J.prototype.V;J.prototype.Fb=function(){return this.a?this.a.Fb():""};J.prototype.receiverName=J.prototype.Fb;J.prototype.cast=function(){var a=this.Vb();return this.a.cast(a).then(function(){return this.b.hb()}.bind(this))};
  2023. J.prototype.cast=J.prototype.cast;J.prototype.Ib=function(a){this.a.Ib(a)};J.prototype.setAppData=J.prototype.Ib;J.prototype.me=function(){var a=this.a;if(a.c){var b=a.v();chrome.cast.requestSession(a.Bb.bind(a,b),a.cc.bind(a))}};J.prototype.suggestDisconnect=J.prototype.me;J.prototype.$a=function(){this.a.$a()};J.prototype.forceDisconnect=J.prototype.$a;
  2024. function Bc(a){a.a.init();a.h=new D;kc.forEach(function(a){E(this.h,this.c,a,this.te.bind(this))}.bind(a));oc.forEach(function(a){E(this.h,this.b,a,this.Id.bind(this))}.bind(a));a.j={};for(var b in a.c)Object.defineProperty(a.j,b,{configurable:!1,enumerable:!0,get:a.se.bind(a,b),set:a.ue.bind(a,b)});a.i={};for(b in a.b)Object.defineProperty(a.i,b,{configurable:!1,enumerable:!0,get:a.Hd.bind(a,b)});a.g=new p;a.g.Ta=a.j;a.f=new p;a.f.Ta=a.i}k=J.prototype;
  2025. k.Vb=function(){var a={video:{},player:{},playerAfterLoad:{},manifest:this.b.Ya,startTime:null};this.c.pause();mc.forEach(function(b){a.video[b]=this.c[b]}.bind(this));this.c.ended||(a.startTime=this.c.currentTime);qc.forEach(function(b){var c=b[1];b=this.b[b[0]]();a.player[c]=b}.bind(this));rc.forEach(function(b){var c=b[1];b=this.b[b[0]]();a.playerAfterLoad[c]=b}.bind(this));return a};k.ee=function(){this.dispatchEvent(new I("caststatuschanged"))};
  2026. k.ge=function(){qc.forEach(function(a){var b=a[1];a=this.a.get("player",a[0])();this.b[b](a)}.bind(this));var a=this.a.get("player","getManifestUri")(),b=this.a.get("video","ended"),c=Promise.resolve(),d=this.c.autoplay,e=null;b||(e=this.a.get("video","currentTime"));a&&(this.c.autoplay=!1,c=this.b.load(a,e),c["catch"](function(a){this.b.dispatchEvent(new I("error",{detail:a}))}.bind(this)));var f={};mc.forEach(function(a){f[a]=this.a.get("video",a)}.bind(this));c.then(function(){mc.forEach(function(a){this.c[a]=
  2027. f[a]}.bind(this));rc.forEach(function(a){var b=a[1];a=this.a.get("player",a[0])();this.b[b](a)}.bind(this));this.c.autoplay=d;a&&this.c.play()}.bind(this))};
  2028. k.se=function(a){if("addEventListener"==a)return this.g.addEventListener.bind(this.g);if("removeEventListener"==a)return this.g.removeEventListener.bind(this.g);if(this.a.V()&&!Object.keys(this.a.b.video).length){var b=this.c[a];if("function"!=typeof b)return b}return this.a.V()?this.a.get("video",a):(b=this.c[a],"function"==typeof b&&(b=b.bind(this.c)),b)};k.ue=function(a,b){this.a.V()?this.a.set("video",a,b):this.c[a]=b};k.te=function(a){this.a.V()||this.g.dispatchEvent(new I(a.type,a))};
  2029. k.Hd=function(a){return"addEventListener"==a?this.f.addEventListener.bind(this.f):"removeEventListener"==a?this.f.removeEventListener.bind(this.f):"getNetworkingEngine"==a?this.b.Wb.bind(this.b):this.a.V()&&!Object.keys(this.a.b.video).length&&0<=pc.indexOf(a)||!this.a.V()?(a=this.b[a],a.bind(this.b)):this.a.get("player",a)};k.Id=function(a){this.a.V()||this.f.dispatchEvent(a)};k.fe=function(a,b){this.a.V()&&("video"==a?this.g.dispatchEvent(b):"player"==a&&this.f.dispatchEvent(b))};function K(a,b,c,d){p.call(this);this.a=a;this.b=b;this.j={video:a,player:b};this.l=c||function(){};this.o=d||function(a){return a};this.i=!1;this.f=!0;this.h=this.g=this.c=null;Cc(this)}ba(K);n("shaka.cast.CastReceiver",K);K.prototype.isConnected=function(){return this.i};K.prototype.isConnected=K.prototype.isConnected;K.prototype.ad=function(){return this.f};K.prototype.isIdle=K.prototype.ad;
  2030. K.prototype.m=function(){var a=this.b?this.b.m():Promise.resolve();null!=this.h&&window.clearTimeout(this.h);this.l=this.j=this.b=this.a=null;this.i=!1;this.f=!0;this.h=this.g=this.c=null;return a.then(function(){cast.receiver.CastReceiverManager.getInstance().stop()})};K.prototype.destroy=K.prototype.m;
  2031. function Cc(a){var b=cast.receiver.CastReceiverManager.getInstance();b.onSenderConnected=a.jc.bind(a);b.onSenderDisconnected=a.jc.bind(a);b.onSystemVolumeChanged=a.Mc.bind(a);a.g=b.getCastMessageBus("urn:x-cast:com.google.cast.media");a.g.onMessage=a.hd.bind(a);a.c=b.getCastMessageBus("urn:x-cast:com.google.shaka.v2");a.c.onMessage=a.vd.bind(a);b.start();kc.forEach(function(a){this.a.addEventListener(a,this.mc.bind(this,"video"))}.bind(a));oc.forEach(function(a){this.b.addEventListener(a,this.mc.bind(this,
  2032. "player"))}.bind(a));cast.__platform__&&cast.__platform__.canDisplayType('video/mp4; codecs="avc1.640028"; width=3840; height=2160')?a.b.Jb(3840,2160):a.b.Jb(1920,1080);a.b.addEventListener("loading",function(){this.f=!1;Dc(this)}.bind(a));a.a.addEventListener("playing",function(){this.f=!1;Dc(this)}.bind(a));a.a.addEventListener("pause",function(){Dc(this)}.bind(a));a.b.addEventListener("unloading",function(){this.f=!0;Dc(this)}.bind(a));a.a.addEventListener("ended",function(){window.setTimeout(function(){this.a&&
  2033. this.a.ended&&(this.f=!0,Dc(this))}.bind(this),5E3)}.bind(a))}k=K.prototype;k.jc=function(){this.i=!!cast.receiver.CastReceiverManager.getInstance().getSenders().length;Dc(this)};function Dc(a){Promise.resolve().then(function(){this.dispatchEvent(new I("caststatuschanged"));L(this,0)}.bind(a))}
  2034. function Ec(a,b,c){for(var d in b.player)a.b[d](b.player[d]);a.l(c);c=Promise.resolve();var e=a.a.autoplay;b.manifest&&(a.a.autoplay=!1,c=a.b.load(b.manifest,b.startTime),c["catch"](function(a){this.b.dispatchEvent(new I("error",{detail:a}))}.bind(a)));c.then(function(){var a;for(a in b.video){var c=b.video[a];this.a[a]=c}for(a in b.playerAfterLoad)c=b.playerAfterLoad[a],this.b[a](c);this.a.autoplay=e;b.manifest&&(this.a.play(),L(this,0))}.bind(a))}
  2035. k.mc=function(a,b){this.Cb();Fc(this,{type:"event",targetName:a,event:b},this.c)};k.Cb=function(){null!=this.h&&window.clearTimeout(this.h);this.h=window.setTimeout(this.Cb.bind(this),500);var a={video:{},player:{}};lc.forEach(function(b){a.video[b]=this.a[b]}.bind(this));pc.forEach(function(b){a.player[b]=this.b[b]()}.bind(this));var b=cast.receiver.CastReceiverManager.getInstance().getSystemVolume();b&&(a.video.volume=b.level,a.video.muted=b.muted);Fc(this,{type:"update",update:a},this.c)};
  2036. k.Mc=function(){var a=cast.receiver.CastReceiverManager.getInstance().getSystemVolume();a&&Fc(this,{type:"update",update:{video:{volume:a.level,muted:a.muted}}},this.c);Fc(this,{type:"event",targetName:"video",event:{type:"volumechange"}},this.c)};
  2037. k.vd=function(a){var b=wc(a.data);switch(b.type){case "init":Ec(this,b.initState,b.appData);this.Cb();break;case "appData":this.l(b.appData);break;case "set":var c=b.targetName,d=b.property,e=b.value;if("video"==c)if(b=cast.receiver.CastReceiverManager.getInstance(),"volume"==d){b.setSystemVolumeLevel(e);break}else if("muted"==d){b.setSystemVolumeMuted(e);break}this.j[c][d]=e;break;case "call":c=b.targetName;d=b.methodName;e=b.args;c=this.j[c];c[d].apply(c,e);break;case "asyncCall":c=b.targetName,
  2038. d=b.methodName,e=b.args,b=b.id,a=a.senderId,c=this.j[c],c[d].apply(c,e).then(this.vc.bind(this,a,b,null),this.vc.bind(this,a,b))}};
  2039. k.hd=function(a){var b=wc(a.data);switch(b.type){case "PLAY":this.a.play();L(this,0);break;case "PAUSE":this.a.pause();L(this,0);break;case "SEEK":a=b.currentTime;var c=b.resumeState;null!=a&&(this.a.currentTime=Number(a));c&&"PLAYBACK_START"==c?(this.a.play(),L(this,0)):c&&"PLAYBACK_PAUSE"==c&&(this.a.pause(),L(this,0));break;case "STOP":this.b.hb().then(function(){L(this,0)}.bind(this));break;case "GET_STATUS":L(this,Number(b.requestId));break;case "VOLUME":c=b.volume;a=c.level;var c=c.muted,d=
  2040. this.a.volume,e=this.a.muted;null!=a&&(this.a.volume=Number(a));null!=c&&(this.a.muted=c);d==this.a.volume&&e==this.a.muted||L(this,0);break;case "LOAD":c=b.media.contentId;a=b.currentTime;var f=this.o(c);this.a.autoplay=!0;this.b.load(f,a).then(function(){L(this,0,{contentId:f,streamType:this.b.$()?"LIVE":"BUFFERED",contentType:""})}.bind(this))["catch"](function(a){var c="LOAD_FAILED";7==a.category&&7E3==a.code&&(c="LOAD_CANCELLED");Fc(this,{requestId:Number(b.requestId),type:c},this.g)}.bind(this));
  2041. break;default:Fc(this,{requestId:Number(b.requestId),type:"INVALID_REQUEST",reason:"INVALID_COMMAND"},this.g)}};k.vc=function(a,b,c){Fc(this,{type:"asyncComplete",id:b,error:c},this.c,a)};function Fc(a,b,c,d){a.i&&(a=vc(b),d?c.getCastChannel(d).send(a):c.broadcast(a))}
  2042. function L(a,b,c){var d=Gc,d={mediaSessionId:0,playbackRate:a.a.playbackRate,playerState:a.f?d.IDLE:a.b.ka?d.Ac:a.a.paused?d.Bc:d.Cc,currentTime:a.a.currentTime,supportedMediaCommands:15,volume:{level:a.a.volume,muted:a.a.muted}};c&&(d.media=c);Fc(a,{requestId:b,type:"MEDIA_STATUS",status:[d]},a.g)}var Gc={IDLE:"IDLE",Cc:"PLAYING",Ac:"BUFFERING",Bc:"PAUSED"};function Hc(a,b){var c=M(a,b);return 1!=c.length?null:c[0]}function M(a,b){return Array.prototype.filter.call(a.childNodes,function(a){return a.tagName==b})}function Ic(a){var b=a.firstChild;return b&&b.nodeType==Node.TEXT_NODE?a.textContent.trim():null}function N(a,b,c,d){var e=null;a=a.getAttribute(b);null!=a&&(e=c(a));return null==e?void 0!=d?d:null:e}function Jc(a){if(!a)return null;a=Date.parse(a);return isNaN(a)?null:Math.floor(a/1E3)}
  2043. function Kc(a){if(!a)return null;a=/^P(?:([0-9]*)Y)?(?:([0-9]*)M)?(?:([0-9]*)D)?(?:T(?:([0-9]*)H)?(?:([0-9]*)M)?(?:([0-9.]*)S)?)?$/.exec(a);if(!a)return null;a=31536E3*Number(a[1]||null)+2592E3*Number(a[2]||null)+86400*Number(a[3]||null)+3600*Number(a[4]||null)+60*Number(a[5]||null)+Number(a[6]||null);return isFinite(a)?a:null}function Lc(a){var b=/([0-9]+)-([0-9]+)/.exec(a);if(!b)return null;a=Number(b[1]);if(!isFinite(a))return null;b=Number(b[2]);return isFinite(b)?{start:a,end:b}:null}
  2044. function Mc(a){a=Number(a);return a%1?null:a}function Nc(a){a=Number(a);return!(a%1)&&0<a?a:null}function Oc(a){a=Number(a);return!(a%1)&&0<=a?a:null}function Pc(a){var b;a=(b=a.match(/^(\d+)\/(\d+)$/))?Number(b[1]/b[2]):Number(a);return isNaN(a)?null:a};var Qc={"urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b":"org.w3.clearkey","urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed":"com.widevine.alpha","urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95":"com.microsoft.playready","urn:uuid:f239e769-efa3-4850-9c16-a903c6932efb":"com.adobe.primetime"};
  2045. function Rc(a,b,c){a=Sc(a);var d=null,e=null,f=[],g=[],h=a.map(function(a){return a.keyId}).filter(ya);if(0<h.length&&(e=h[0],h.some(za(e))))throw new t(2,4,4010);c||(g=a.filter(function(a){return"urn:mpeg:dash:mp4protection:2011"==a.sc?(d=a.init||d,!1):!0}),0<g.length&&(f=Tc(d,b,g),f.length||(f=[Ba("",d)])));0<a.length&&(c||!g.length)&&(f=Na(Qc).map(function(a){return Ba(a,d)}));e&&f.forEach(function(a){a.initData.forEach(function(a){a.keyId=e})});return{Sb:e,ze:d,drmInfos:f,Ub:!0}}
  2046. function Uc(a,b,c,d){var e=Rc(a,b,d);if(c.Ub){a=1==c.drmInfos.length&&!c.drmInfos[0].keySystem;b=!e.drmInfos.length;if(!c.drmInfos.length||a&&!b)c.drmInfos=e.drmInfos;c.Ub=!1}else if(0<e.drmInfos.length&&(c.drmInfos=c.drmInfos.filter(function(a){return e.drmInfos.some(function(b){return b.keySystem==a.keySystem})}),!c.drmInfos.length))throw new t(2,4,4008);return e.Sb||c.Sb}function Tc(a,b,c){return c.map(function(c){var d=Qc[c.sc];return d?[Ba(d,c.init||a)]:b(c.node)||[]}).reduce(x,[])}
  2047. function Sc(a){return a.map(function(a){var b=a.getAttribute("schemeIdUri"),d=a.getAttribute("cenc:default_KID"),e=M(a,"cenc:pssh").map(Ic);if(!b)return null;b=b.toLowerCase();if(d&&(d=d.replace(/-/g,"").toLowerCase(),0<=d.indexOf(" ")))throw new t(2,4,4009);var f=[];try{f=e.map(function(a){return{initDataType:"cenc",initData:Ya(a),keyId:null}})}catch(g){throw new t(2,4,4007);}return{node:a,sc:b,keyId:d,init:0<f.length?f:null}}).filter(ya)};function Vc(a,b,c,d,e){null!=e&&(e=Math.round(e));var f={RepresentationID:b,Number:c,Bandwidth:d,Time:e};return a.replace(/\$(RepresentationID|Number|Bandwidth|Time)?(?:%0([0-9]+)d)?\$/g,function(a,b,c){if("$$"==a)return"$";var d=f[b];if(null==d)return a;"RepresentationID"==b&&c&&(c=void 0);a=d.toString();c=window.parseInt(c,10)||1;return Array(Math.max(0,c-a.length)+1).join("0")+a})}
  2048. function Wc(a,b){var c=Xc(a,b,"timescale"),d=1;c&&(d=Nc(c)||1);c=Xc(a,b,"duration");(c=Nc(c||""))&&(c/=d);var e=Xc(a,b,"startNumber"),f=Xc(a,b,"presentationTimeOffset"),g=Oc(e||"");if(null==e||null==g)g=1;var h=Yc(a,b,"SegmentTimeline"),e=null;if(h){for(var e=d,l=Number(f),m=a.R.duration||Infinity,h=M(h,"S"),q=[],r=0,v=0;v<h.length;++v){var u=h[v],w=N(u,"t",Oc),G=N(u,"d",Oc),u=N(u,"r",Mc);null!=w&&(w-=l);if(!G)break;w=null!=w?w:r;u=u||0;if(0>u)if(v+1<h.length){u=N(h[v+1],"t",Oc);if(null==u)break;
  2049. else if(w>=u)break;u=Math.ceil((u-w)/G)-1}else{if(Infinity==m)break;else if(w/e>=m)break;u=Math.ceil((m*e-w)/G)-1}0<q.length&&w!=r&&(q[q.length-1].end=w/e);for(var pa=0;pa<=u;++pa)r=w+G,q.push({start:w/e,end:r/e,qe:w}),w=r}e=q}return{timescale:d,P:c,za:g,presentationTimeOffset:Number(f)/d||0,Pb:Number(f),F:e}}function Xc(a,b,c){return[b(a.w),b(a.S),b(a.T)].filter(ya).map(function(a){return a.getAttribute(c)}).reduce(function(a,b){return a||b})}
  2050. function Yc(a,b,c){return[b(a.w),b(a.S),b(a.T)].filter(ya).map(function(a){return Hc(a,c)}).reduce(function(a,b){return a||b})};function Zc(a,b,c){this.a=a;this.X=b;this.M=c}n("shaka.media.InitSegmentReference",Zc);function O(a,b,c,d,e,f){this.position=a;this.startTime=b;this.endTime=c;this.a=d;this.X=e;this.M=f}n("shaka.media.SegmentReference",O);function P(a,b){this.H=a;this.a=b==$c;this.u=0}n("shaka.util.DataViewReader",P);var $c=1;P.Endianness={ve:0,xe:$c};P.prototype.Z=function(){return this.u<this.H.byteLength};P.prototype.hasMoreData=P.prototype.Z;P.prototype.Vc=function(){return this.u};P.prototype.getPosition=P.prototype.Vc;P.prototype.Qc=function(){return this.H.byteLength};P.prototype.getLength=P.prototype.Qc;P.prototype.Eb=function(){try{var a=this.H.getUint8(this.u)}catch(b){ad()}this.u+=1;return a};P.prototype.readUint8=P.prototype.Eb;
  2051. P.prototype.oc=function(){try{var a=this.H.getUint16(this.u,this.a)}catch(b){ad()}this.u+=2;return a};P.prototype.readUint16=P.prototype.oc;P.prototype.D=function(){try{var a=this.H.getUint32(this.u,this.a)}catch(b){ad()}this.u+=4;return a};P.prototype.readUint32=P.prototype.D;P.prototype.nc=function(){try{var a=this.H.getInt32(this.u,this.a)}catch(b){ad()}this.u+=4;return a};P.prototype.readInt32=P.prototype.nc;
  2052. P.prototype.Pa=function(){try{if(this.a){var a=this.H.getUint32(this.u,!0);var b=this.H.getUint32(this.u+4,!0)}else b=this.H.getUint32(this.u,!1),a=this.H.getUint32(this.u+4,!1)}catch(c){ad()}if(2097151<b)throw new t(2,3,3001);this.u+=8;return b*Math.pow(2,32)+a};P.prototype.readUint64=P.prototype.Pa;P.prototype.Ka=function(a){this.u+a>this.H.byteLength&&ad();var b=this.H.buffer.slice(this.u,this.u+a);this.u+=a;return new Uint8Array(b)};P.prototype.readBytes=P.prototype.Ka;
  2053. P.prototype.I=function(a){this.u+a>this.H.byteLength&&ad();this.u+=a};P.prototype.skip=P.prototype.I;P.prototype.Db=function(){for(var a=this.u;this.Z()&&this.H.getUint8(this.u);)this.u+=1;a=this.H.buffer.slice(a,this.u);this.u+=1;return F(a)};P.prototype.readTerminatedString=P.prototype.Db;function ad(){throw new t(2,3,3E3);};function Q(){this.b=[];this.a=[]}n("shaka.util.Mp4Parser",Q);Q.prototype.C=function(a,b){var c=bd(a);this.b[c]=0;this.a[c]=b;return this};Q.prototype.box=Q.prototype.C;Q.prototype.da=function(a,b){var c=bd(a);this.b[c]=1;this.a[c]=b;return this};Q.prototype.fullBox=Q.prototype.da;Q.prototype.parse=function(a){for(a=new P(new DataView(a),0);a.Z();)this.eb(0,a)};Q.prototype.parse=Q.prototype.parse;
  2054. Q.prototype.eb=function(a,b){var c=b.u,d=b.D(),e=b.D();switch(d){case 0:d=b.H.byteLength-c;break;case 1:d=b.Pa()}var f=this.a[e];if(f){var g=null,h=null;1==this.b[e]&&(h=b.D(),g=h>>>24,h&=16777215);e=c+d-b.u;e=0<e?b.Ka(e).buffer:new ArrayBuffer(0);e=new P(new DataView(e),0);f({Na:this,version:g,Nc:h,s:e,size:d,start:c+a})}else b.I(c+d-b.u)};Q.prototype.parseNext=Q.prototype.eb;function R(a){for(;a.s.Z();)a.Na.eb(a.start,a.s)}Q.children=R;
  2055. function cd(a){for(var b=a.s.D();0<b;--b)a.Na.eb(a.start,a.s)}Q.sampleDescription=cd;function dd(a){return function(b){a(b.s.Ka(b.s.H.byteLength-b.s.u))}}Q.allData=dd;function bd(a){for(var b=0,c=0;c<a.length;c++)b=b<<8|a.charCodeAt(c);return b};function ed(a,b,c,d){var e,f=(new Q).da("sidx",function(a){e=fd(b,d,c,a)});a&&f.parse(a);if(e)return e;throw new t(2,3,3004);}
  2056. function fd(a,b,c,d){var e=[];d.s.I(4);var f=d.s.D();if(!f)throw new t(2,3,3005);if(d.version){var g=d.s.Pa();var h=d.s.Pa()}else g=d.s.D(),h=d.s.D();d.s.I(2);var l=d.s.oc();b=g-b;a=a+d.size+h;for(h=0;h<l;h++){var m=d.s.D();g=(m&2147483648)>>>31;var m=m&2147483647,q=d.s.D();d.s.I(4);if(1==g)throw new t(2,3,3006);e.push(new O(e.length,b/f,(b+q)/f,function(){return c},a,a+m-1));b+=q;a+=m}return e};function S(a){this.a=a}n("shaka.media.SegmentIndex",S);S.prototype.m=function(){this.a=null;return Promise.resolve()};S.prototype.destroy=S.prototype.m;S.prototype.find=function(a){for(var b=this.a.length-1;0<=b;--b){var c=this.a[b];if(a>=c.startTime&&a<c.endTime)return c.position}return this.a.length&&a<this.a[0].startTime?this.a[0].position:null};S.prototype.find=S.prototype.find;S.prototype.get=function(a){if(!this.a.length)return null;a-=this.a[0].position;return 0>a||a>=this.a.length?null:this.a[a]};
  2057. S.prototype.get=S.prototype.get;S.prototype.xb=function(a){for(var b,c,d=[],e=c=0;c<this.a.length&&e<a.length;){var f=this.a[c];b=a[e];f.startTime<b.startTime?(d.push(f),c++):(f.startTime>b.startTime||(.1<Math.abs(f.endTime-b.endTime)?d.push(b):d.push(f),c++),e++)}for(;c<this.a.length;)d.push(this.a[c++]);if(d.length)for(c=d[d.length-1].position+1;e<a.length;)b=a[e++],b=new O(c++,b.startTime,b.endTime,b.a,b.X,b.M),d.push(b);else d=a;this.a=d};S.prototype.merge=S.prototype.xb;
  2058. S.prototype.qb=function(a){for(var b=0;b<this.a.length&&!(this.a[b].endTime>a);++b);this.a.splice(0,b)};S.prototype.evict=S.prototype.qb;function gd(a,b){if(a.a.length){var c=a.a[a.a.length-1];c.startTime>b||(a.a[a.a.length-1]=new O(c.position,c.startTime,b,c.a,c.X,c.M))}};function hd(a){this.b=a;this.a=new P(a,0);id||(id=[new Uint8Array([255]),new Uint8Array([127,255]),new Uint8Array([63,255,255]),new Uint8Array([31,255,255,255]),new Uint8Array([15,255,255,255,255]),new Uint8Array([7,255,255,255,255,255]),new Uint8Array([3,255,255,255,255,255,255]),new Uint8Array([1,255,255,255,255,255,255,255])])}var id;hd.prototype.Z=function(){return this.a.Z()};
  2059. function jd(a){var b=kd(a);if(7<b.length)throw new t(2,3,3002);for(var c=0,d=0;d<b.length;d++)c=256*c+b[d];b=c;c=kd(a);a:{for(d=0;d<id.length;d++)if(ab(c,id[d])){d=!0;break a}d=!1}if(d)c=a.b.byteLength-a.a.u;else{if(8==c.length&&c[1]&224)throw new t(2,3,3001);for(var d=c[0]&(1<<8-c.length)-1,e=1;e<c.length;e++)d=256*d+c[e];c=d}c=a.a.u+c<=a.b.byteLength?c:a.b.byteLength-a.a.u;d=new DataView(a.b.buffer,a.b.byteOffset+a.a.u,c);a.a.I(c);return new ld(b,d)}
  2060. function kd(a){var b=a.a.Eb(),c;for(c=1;8>=c&&!(b&1<<8-c);c++);if(8<c)throw new t(2,3,3002);var d=new Uint8Array(c);d[0]=b;for(b=1;b<c;b++)d[b]=a.a.Eb();return d}function ld(a,b){this.id=a;this.a=b}function md(a){if(8<a.a.byteLength)throw new t(2,3,3002);if(8==a.a.byteLength&&a.a.getUint8(0)&224)throw new t(2,3,3001);for(var b=0,c=0;c<a.a.byteLength;c++)var d=a.a.getUint8(c),b=256*b+d;return b};function nd(){}
  2061. nd.prototype.parse=function(a,b,c,d){var e;b=new hd(new DataView(b));if(440786851!=jd(b).id)throw new t(2,3,3008);var f=jd(b);if(408125543!=f.id)throw new t(2,3,3009);b=f.a.byteOffset;f=new hd(f.a);for(e=null;f.Z();){var g=jd(f);if(357149030==g.id){e=g;break}}if(!e)throw new t(2,3,3010);f=new hd(e.a);e=1E6;for(g=null;f.Z();){var h=jd(f);if(2807729==h.id)e=md(h);else if(17545==h.id)if(g=h,4==g.a.byteLength)g=g.a.getFloat32(0);else if(8==g.a.byteLength)g=g.a.getFloat64(0);else throw new t(2,3,3003);
  2062. }if(null==g)throw new t(2,3,3011);f=e/1E9;e=g*f;a=jd(new hd(new DataView(a)));if(475249515!=a.id)throw new t(2,3,3007);return od(a,b,f,e,c,d)};function od(a,b,c,d,e,f){function g(){return e}var h=[];a=new hd(a.a);for(var l=-1,m=-1;a.Z();){var q=jd(a);if(187==q.id){var r=pd(q);r&&(q=c*(r.re-f),r=b+r.Nd,0<=l&&h.push(new O(h.length,l,q,g,m,r-1)),l=q,m=r)}}0<=l&&h.push(new O(h.length,l,d,g,m,null));return h}
  2063. function pd(a){var b=new hd(a.a);a=jd(b);if(179!=a.id)throw new t(2,3,3013);a=md(a);b=jd(b);if(183!=b.id)throw new t(2,3,3012);for(var b=new hd(b.a),c=0;b.Z();){var d=jd(b);if(241==d.id){c=md(d);break}}return{re:a,Nd:c}};function qd(a,b){var c=Yc(a,b,"Initialization");if(!c)return null;var d=a.w.U,e=c.getAttribute("sourceURL");e&&(d=z(a.w.U,[e]));var e=0,f=null;if(c=N(c,"range",Lc))e=c.start,f=c.end;return new Zc(function(){return d},e,f)}
  2064. function rd(a,b){var c=Xc(a,sd,"presentationTimeOffset"),d=qd(a,sd);var e=Number(c);var f=a.w.contentType,g=a.w.mimeType.split("/")[1];if("text"!=f&&"mp4"!=g&&"webm"!=g)throw new t(2,4,4006);if("webm"==g&&!d)throw new t(2,4,4005);var f=Yc(a,sd,"RepresentationIndex"),h=Xc(a,sd,"indexRange"),l=a.w.U,h=Lc(h||"");if(f){var m=f.getAttribute("sourceURL");m&&(l=z(a.w.U,[m]));h=N(f,"range",Lc,h)}if(!h)throw new t(2,4,4002);e=td(a,b,d,l,h.start,h.end,g,e);return{createSegmentIndex:e.createSegmentIndex,findSegmentPosition:e.findSegmentPosition,
  2065. getSegmentReference:e.getSegmentReference,initSegmentReference:d,presentationTimeOffset:Number(c)||0}}
  2066. function td(a,b,c,d,e,f,g,h){var l=a.presentationTimeline,m=!a.Da||!a.R.ub,q=a.R.duration,r=b,v=null;return{createSegmentIndex:function(){var a=[r(d,e,f),"webm"==g?r(c.a(),c.X,c.M):null];r=null;return Promise.all(a).then(function(a){var b=a[0];a=a[1]||null;b="mp4"==g?ed(b,e,d,h):(new nd).parse(b,a,d,h);l.Ha(0,b);v=new S(b);m&&gd(v,q)})},findSegmentPosition:function(a){return v.find(a)},getSegmentReference:function(a){return v.get(a)}}}function sd(a){return a.Qa};function ud(a,b){var c=qd(a,vd);var d=wd(a);var e=Wc(a,vd),f=e.za;f||(f=1);var g=0;e.P?g=e.P*(f-1):e.F&&0<e.F.length&&(g=e.F[0].start);d={P:e.P,startTime:g,za:f,presentationTimeOffset:e.presentationTimeOffset,F:e.F,Ga:d};if(!d.P&&!d.F&&1<d.Ga.length)throw new t(2,4,4002);if(!d.P&&!a.R.duration&&!d.F&&1==d.Ga.length)throw new t(2,4,4002);if(d.F&&!d.F.length)throw new t(2,4,4002);f=e=null;a.T.id&&a.w.id&&(f=a.T.id+","+a.w.id,e=b[f]);g=xd(a.R.duration,d.za,a.w.U,d);e?(e.xb(g),e.qb(a.presentationTimeline.ma()-
  2067. a.R.start)):(a.presentationTimeline.Ha(0,g),e=new S(g),f&&a.Da&&(b[f]=e));a.Da&&a.R.ub||gd(e,a.R.duration);return{createSegmentIndex:Promise.resolve.bind(Promise),findSegmentPosition:e.find.bind(e),getSegmentReference:e.get.bind(e),initSegmentReference:c,presentationTimeOffset:d.presentationTimeOffset}}function vd(a){return a.oa}
  2068. function xd(a,b,c,d){var e=d.Ga.length;d.F&&d.F.length!=d.Ga.length&&(e=Math.min(d.F.length,d.Ga.length));for(var f=[],g=d.startTime,h=0;h<e;h++){var l=d.Ga[h],m=z(c,[l.cd]);var q=null!=d.P?g+d.P:d.F?d.F[h].end:g+a;f.push(new O(h+b,g,q,function(a){return a}.bind(null,m),l.start,l.end));g=q}return f}
  2069. function wd(a){return[a.w.oa,a.S.oa,a.T.oa].filter(ya).map(function(a){return M(a,"SegmentURL")}).reduce(function(a,c){return 0<a.length?a:c}).map(function(b){b.getAttribute("indexRange")&&!a.$b&&(a.$b=!0);var c=b.getAttribute("media");b=N(b,"mediaRange",Lc,{start:0,end:null});return{cd:c,start:b.start,end:b.end}})};function yd(a,b,c,d){var e=zd(a);var f=Wc(a,Ad);var g=Xc(a,Ad,"media"),h=Xc(a,Ad,"index");f={P:f.P,timescale:f.timescale,za:f.za,presentationTimeOffset:f.presentationTimeOffset,Pb:f.Pb,F:f.F,wb:g,Ma:h};g=0+(f.Ma?1:0);g+=f.F?1:0;g+=f.P?1:0;if(!g)throw new t(2,4,4002);1!=g&&(f.Ma&&(f.F=null),f.P=null);if(!f.Ma&&!f.wb)throw new t(2,4,4002);if(f.Ma){c=a.w.mimeType.split("/")[1];if("mp4"!=c&&"webm"!=c)throw new t(2,4,4006);if("webm"==c&&!e)throw new t(2,4,4005);d=Vc(f.Ma,a.w.id,null,a.bandwidth||null,
  2070. null);d=z(a.w.U,[d]);a=td(a,b,e,d,0,null,c,f.presentationTimeOffset)}else f.P?(d||a.presentationTimeline.yb(f.P),a=Bd(a,f)):(d=b=null,a.T.id&&a.w.id&&(d=a.T.id+","+a.w.id,b=c[d]),g=Cd(a,f),b?(b.xb(g),b.qb(a.presentationTimeline.ma()-a.R.start)):(a.presentationTimeline.Ha(0,g),b=new S(g),d&&a.Da&&(c[d]=b)),a.Da&&a.R.ub||gd(b,a.R.duration),a={createSegmentIndex:Promise.resolve.bind(Promise),findSegmentPosition:b.find.bind(b),getSegmentReference:b.get.bind(b)});return{createSegmentIndex:a.createSegmentIndex,
  2071. findSegmentPosition:a.findSegmentPosition,getSegmentReference:a.getSegmentReference,initSegmentReference:e,presentationTimeOffset:f.presentationTimeOffset}}function Ad(a){return a.Ra}
  2072. function Bd(a,b){var c=a.R.duration,d=b.P,e=b.za,f=b.timescale,g=b.wb,h=a.bandwidth||null,l=a.w.id,m=a.w.U;return{createSegmentIndex:Promise.resolve.bind(Promise),findSegmentPosition:function(a){return 0>a||c&&a>=c?null:Math.floor(a/d)},getSegmentReference:function(a){var b=a*d;return 0>b||c&&b>=c?null:new O(a,b,b+d,function(){var c=Vc(g,l,a+e,h,b*f);return z(m,[c])},0,null)}}}
  2073. function Cd(a,b){for(var c=[],d=0;d<b.F.length;d++){var e=d+b.za;c.push(new O(e,b.F[d].start,b.F[d].end,function(a,b,c,d,e,q){a=Vc(a,b,e,c,q);return z(d,[a]).map(function(a){return a.toString()})}.bind(null,b.wb,a.w.id,a.bandwidth||null,a.w.U,e,b.F[d].qe+b.Pb),0,null))}return c}function zd(a){var b=Xc(a,Ad,"initialization");if(!b)return null;var c=a.w.id,d=a.bandwidth||null,e=a.w.U;return new Zc(function(){var a=Vc(b,c,null,d,null);return z(e,[a])},0,null)};var Dd={},Ed={};n("shaka.media.ManifestParser.registerParserByExtension",function(a,b){Ed[a]=b});n("shaka.media.ManifestParser.registerParserByMime",function(a,b){Dd[a]=b});function Fd(){var a={},b;for(b in Dd)a[b]=!0;for(b in Ed)a[b]=!0;["application/dash+xml","application/x-mpegurl","application/vnd.apple.mpegurl","application/vnd.ms-sstr+xml"].forEach(function(b){a[b]=!!Dd[b]});["mpd","m3u8","ism"].forEach(function(b){a[b]=!!Ed[b]});return a}
  2074. function Gd(a,b,c,d){var e=d;e||(d=(new ia(a)).W.split("/").pop().split("."),1<d.length&&(d=d.pop().toLowerCase(),e=Ed[d]));if(e)return Promise.resolve(e);c=C([a],c);c.method="HEAD";return b.request(0,c).then(function(b){(b=b.headers["content-type"])&&(b=b.toLowerCase());return(e=Dd[b])?e:Promise.reject(new t(2,4,4E3,a))},function(a){a.severity=2;return Promise.reject(a)})};function T(a,b){this.f=a;this.i=b;this.c=this.a=Infinity;this.b=1;this.h=0;this.g=!0}n("shaka.media.PresentationTimeline",T);T.prototype.Y=function(){return this.a};T.prototype.getDuration=T.prototype.Y;T.prototype.pa=function(a){this.a=a};T.prototype.setDuration=T.prototype.pa;T.prototype.Wc=function(){return this.f};T.prototype.getPresentationStartTime=T.prototype.Wc;T.prototype.wc=function(a){this.h=a};T.prototype.setClockOffset=T.prototype.wc;T.prototype.yc=function(a){this.g=a};
  2075. T.prototype.setStatic=T.prototype.yc;T.prototype.Xc=function(){return this.c};T.prototype.getSegmentAvailabilityDuration=T.prototype.Xc;T.prototype.xc=function(a){this.c=a};T.prototype.setSegmentAvailabilityDuration=T.prototype.xc;T.prototype.Ha=function(a,b){b.length&&(this.b=b.reduce(function(a,b){return Math.max(a,b.endTime-b.startTime)},this.b))};T.prototype.notifySegments=T.prototype.Ha;T.prototype.yb=function(a){this.b=Math.max(this.b,a)};T.prototype.notifyMaxSegmentDuration=T.prototype.yb;
  2076. T.prototype.$=function(){return Infinity==this.a&&!this.g};T.prototype.isLive=T.prototype.$;T.prototype.va=function(){return Infinity!=this.a&&!this.g};T.prototype.isInProgress=T.prototype.va;T.prototype.ma=function(){return this.Ea(0)};T.prototype.getSegmentAvailabilityStart=T.prototype.ma;T.prototype.Ea=function(a){if(Infinity==this.c)return 0;var b=this.ua();return Math.max(0,Math.min(b-this.c+a,b))};T.prototype.getSafeAvailabilityStart=T.prototype.Ea;
  2077. T.prototype.ua=function(){return this.$()||this.va()?Math.min(Math.max(0,(Date.now()+this.h)/1E3-this.b-this.f),this.a):this.a};T.prototype.getSegmentAvailabilityEnd=T.prototype.ua;T.prototype.bb=function(){return Math.max(0,this.ua()-(this.$()||this.va()?this.i:0))};T.prototype.getSeekRangeEnd=T.prototype.bb;function Hd(){this.a=this.b=null;this.g=[];this.c=null;this.i=[];this.h=1;this.j={};this.l=0;this.f=null}n("shaka.dash.DashParser",Hd);k=Hd.prototype;k.configure=function(a){this.b=a};k.start=function(a,b){this.g=[a];this.a=b;return Id(this).then(function(){this.a&&Jd(this,0);return this.c}.bind(this))};k.stop=function(){this.b=this.a=null;this.g=[];this.c=null;this.i=[];this.j={};null!=this.f&&(window.clearTimeout(this.f),this.f=null);return Promise.resolve()};k.update=function(){Id(this)["catch"](function(a){if(this.a)this.a.onError(a)}.bind(this))};
  2078. k.onExpirationUpdated=function(){};function Id(a){return a.a.networkingEngine.request(0,C(a.g,a.b.retryParameters)).then(function(a){if(this.a)return Kd(this,a.data,a.uri)}.bind(a))}
  2079. function Kd(a,b,c){var d=F(b),e=new DOMParser,f=null;b=null;try{f=e.parseFromString(d,"text/xml")}catch(v){}f&&"MPD"==f.documentElement.tagName&&(b=f.documentElement);b&&0<b.getElementsByTagName("parsererror").length&&(b=null);if(!b)throw new t(2,4,4001);c=[c];d=M(b,"Location").map(Ic).filter(ya);0<d.length&&(c=a.g=d);d=M(b,"BaseURL").map(Ic);c=z(c,d);var g=N(b,"minBufferTime",Kc);a.l=N(b,"minimumUpdatePeriod",Kc,-1);var h=N(b,"availabilityStartTime",Jc),d=N(b,"timeShiftBufferDepth",Kc),l=N(b,"suggestedPresentationDelay",
  2080. Kc),e=N(b,"maxSegmentDuration",Kc),f=b.getAttribute("type")||"static";if(a.c)var m=a.c.presentationTimeline;else{var q=Math.max(10,1.5*g);m=new T(h,null!=l?l:q)}var h=Ld(a,{Da:"static"!=f,presentationTimeline:m,T:null,R:null,S:null,w:null,bandwidth:void 0,$b:!1},c,b),l=h.duration,r=h.periods;m.yc("static"==f);m.pa(l||Infinity);m.xc(null!=d?d:Infinity);m.yb(e||1);if(a.c)return Promise.resolve();b=M(b,"UTCTiming");return Md(a,c,b,m.$()).then(function(a){this.a&&(m.wc(a),this.c={presentationTimeline:m,
  2081. periods:r,offlineSessionIds:[],minBufferTime:g||0})}.bind(a))}
  2082. function Ld(a,b,c,d){var e=N(d,"mediaPresentationDuration",Kc),f=[],g=0;d=M(d,"Period");for(var h=0;h<d.length;h++){var l=d[h],g=N(l,"start",Kc,g),m=N(l,"duration",Kc),q=null;if(h!=d.length-1){var r=N(d[h+1],"start",Kc);null!=r&&(q=r-g)}else null!=e&&(q=e-g);null==q&&(q=m);l=Nd(a,b,c,{start:g,duration:q,node:l,ub:null==q||h==d.length-1});f.push(l);m=b.T.id;a.i.every(za(m))&&(a.a.filterPeriod(l),a.i.push(m),a.c&&a.c.periods.push(l));if(null==q){g=null;break}g+=q}return null!=e?{periods:f,duration:e}:
  2083. {periods:f,duration:g}}
  2084. function Nd(a,b,c,d){b.T=Od(d.node,null,c);b.R=d;b.T.id||(b.T.id="__shaka_period_"+d.start);M(d.node,"EventStream").forEach(a.Fd.bind(a,d.start,d.duration));c=M(d.node,"AdaptationSet").map(a.Dd.bind(a,b)).filter(ya);var e=c.map(function(a){return a.Pd}).reduce(x,[]),f=e.filter(Aa);if(b.Da&&e.length!=f.length)throw new t(2,4,4018);var g=c.filter(function(a){return!a.Ob});c.filter(function(a){return a.Ob}).forEach(function(a){var b=a.streams[0],c=a.Ob;g.forEach(function(a){a.id==c&&a.streams.forEach(function(a){a.trickModeVideo=
  2085. b})})});e=Pd(g,"video");f=Pd(g,"audio");if(!e.length&&!f.length)throw new t(2,4,4004);f.length||(f=[null]);e.length||(e=[null]);b=[];for(c=0;c<f.length;c++)for(var h=0;h<e.length;h++)Qd(a,f[c],e[h],b);a=Pd(g,"text");e=[];for(c=0;c<a.length;c++)e.push.apply(e,a[c].streams);return{startTime:d.start,textStreams:e,variants:b}}function Pd(a,b){return a.filter(function(a){return a.contentType==b})}
  2086. function Qd(a,b,c,d){if(b||c)if(b&&c){var e=b.drmInfos;var f=c.drmInfos;if(e.length&&f.length?0<sb(e,f).length:1)for(var g=sb(b.drmInfos,c.drmInfos),e=0;e<b.streams.length;e++)for(var h=0;h<c.streams.length;h++)f=c.streams[h].bandwidth+b.streams[e].bandwidth,f={id:a.h++,language:b.language,primary:b.vb||c.vb,audio:b.streams[e],video:c.streams[h],bandwidth:f,drmInfos:g,allowedByApplication:!0,allowedByKeySystem:!0},d.push(f)}else for(g=b||c,e=0;e<g.streams.length;e++)f=g.streams[e].bandwidth,f={id:a.h++,
  2087. language:g.language||"und",primary:g.vb,audio:b?g.streams[e]:null,video:c?g.streams[e]:null,bandwidth:f,drmInfos:g.drmInfos,allowedByApplication:!0,allowedByKeySystem:!0},d.push(f)}
  2088. k.Dd=function(a,b){a.S=Od(b,a.T,null);var c=!1,d=M(b,"Role"),e=d.map(function(a){return a.getAttribute("value")}).filter(ya),f=void 0;"text"==a.S.contentType&&(f="subtitle");for(var g=0;g<d.length;g++){var h=d[g].getAttribute("schemeIdUri");if(null==h||"urn:mpeg:dash:role:2011"==h)switch(h=d[g].getAttribute("value"),h){case "main":c=!0;break;case "caption":case "subtitle":f=h}}var l=null,m=!1;M(b,"EssentialProperty").forEach(function(a){"http://dashif.org/guidelines/trickmode"==a.getAttribute("schemeIdUri")?
  2089. l=a.getAttribute("value"):m=!0});if(m)return null;var d=M(b,"ContentProtection"),q=Rc(d,this.b.dash.customScheme,this.b.dash.ignoreDrmInfo),d=Sb(b.getAttribute("lang")||"und"),h=b.getAttribute("label"),g=M(b,"Representation"),e=g.map(this.Gd.bind(this,a,q,f,d,h,c,e)).filter(function(a){return!!a});if(!e.length)throw new t(2,4,4003);a.S.contentType&&"application"!=a.S.contentType||(a.S.contentType=Rd(e[0].mimeType,e[0].codecs),e.forEach(function(b){b.type=a.S.contentType}));e.forEach(function(a){q.drmInfos.forEach(function(b){a.keyId&&
  2090. b.keyIds.push(a.keyId)})});f=g.map(function(a){return a.getAttribute("id")}).filter(ya);return{id:a.S.id||"__fake__"+this.h++,contentType:a.S.contentType,language:d,vb:c,streams:e,drmInfos:q.drmInfos,Ob:l,Pd:f}};
  2091. k.Gd=function(a,b,c,d,e,f,g,h){a.w=Od(h,a.S,null);if(!Sd(a.w))return null;a.bandwidth=N(h,"bandwidth",Nc)||void 0;var l=this.Qd.bind(this);if(a.w.Qa)l=rd(a,l);else if(a.w.oa)l=ud(a,this.j);else if(a.w.Ra)l=yd(a,l,this.j,!!this.c);else{var m=a.w.U,q=a.R.duration||0;l={createSegmentIndex:Promise.resolve.bind(Promise),findSegmentPosition:function(a){return 0<=a&&a<q?1:null},getSegmentReference:function(a){return 1!=a?null:new O(1,0,q,function(){return m},0,null)},initSegmentReference:null,presentationTimeOffset:0}}h=
  2092. M(h,"ContentProtection");h=Uc(h,this.b.dash.customScheme,b,this.b.dash.ignoreDrmInfo);return{id:this.h++,createSegmentIndex:l.createSegmentIndex,findSegmentPosition:l.findSegmentPosition,getSegmentReference:l.getSegmentReference,initSegmentReference:l.initSegmentReference,presentationTimeOffset:l.presentationTimeOffset,mimeType:a.w.mimeType,codecs:a.w.codecs,frameRate:a.w.frameRate,bandwidth:a.bandwidth,width:a.w.width,height:a.w.height,kind:c,encrypted:0<b.drmInfos.length,keyId:h,language:d,label:e,
  2093. type:a.S.contentType,primary:f,trickModeVideo:null,containsEmsgBoxes:a.w.containsEmsgBoxes,roles:g}};k.he=function(){this.f=null;var a=Date.now();Id(this).then(function(){this.a&&Jd(this,(Date.now()-a)/1E3)}.bind(this))["catch"](function(a){this.a&&(a.severity=1,this.a.onError(a),Jd(this,0))}.bind(this))};function Jd(a,b){0>a.l||(a.f=window.setTimeout(a.he.bind(a),1E3*Math.max(Math.max(3,a.l)-b,0)))}
  2094. function Od(a,b,c){b=b||{contentType:"",mimeType:"",codecs:"",containsEmsgBoxes:!1,frameRate:void 0};c=c||b.U;var d=M(a,"BaseURL").map(Ic),e=a.getAttribute("contentType")||b.contentType,f=a.getAttribute("mimeType")||b.mimeType,g=a.getAttribute("codecs")||b.codecs,h=N(a,"frameRate",Pc)||b.frameRate,l=!!M(a,"InbandEventStream").length;e||(e=Rd(f,g));return{U:z(c,d),Qa:Hc(a,"SegmentBase")||b.Qa,oa:Hc(a,"SegmentList")||b.oa,Ra:Hc(a,"SegmentTemplate")||b.Ra,width:N(a,"width",Oc)||b.width,height:N(a,"height",
  2095. Oc)||b.height,contentType:e,mimeType:f,codecs:g,frameRate:h,containsEmsgBoxes:l||b.containsEmsgBoxes,id:a.getAttribute("id")}}function Sd(a){var b=0+(a.Qa?1:0);b+=a.oa?1:0;b+=a.Ra?1:0;if(!b)return"text"==a.contentType||"application"==a.contentType?!0:!1;1!=b&&(a.Qa&&(a.oa=null),a.Ra=null);return!0}
  2096. function Td(a,b,c,d){b=z(b,[c]);b=C(b,a.b.retryParameters);b.method=d;return a.a.networkingEngine.request(0,b).then(function(a){if("HEAD"==d){if(!a.headers||!a.headers.date)return 0;a=a.headers.date}else a=F(a.data);a=Date.parse(a);return isNaN(a)?0:a-Date.now()})}
  2097. function Md(a,b,c,d){c=c.map(function(a){return{scheme:a.getAttribute("schemeIdUri"),value:a.getAttribute("value")}});var e=a.b.dash.clockSyncUri;d&&!c.length&&e&&c.push({scheme:"urn:mpeg:dash:utc:http-head:2014",value:e});return xa(c,function(a){var c=a.value;switch(a.scheme){case "urn:mpeg:dash:utc:http-head:2014":case "urn:mpeg:dash:utc:http-head:2012":return Td(this,b,c,"HEAD");case "urn:mpeg:dash:utc:http-xsdate:2014":case "urn:mpeg:dash:utc:http-iso:2014":case "urn:mpeg:dash:utc:http-xsdate:2012":case "urn:mpeg:dash:utc:http-iso:2012":return Td(this,
  2098. b,c,"GET");case "urn:mpeg:dash:utc:direct:2014":case "urn:mpeg:dash:utc:direct:2012":return a=Date.parse(c),isNaN(a)?0:a-Date.now();case "urn:mpeg:dash:utc:http-ntp:2014":case "urn:mpeg:dash:utc:ntp:2014":case "urn:mpeg:dash:utc:sntp:2014":return Promise.reject();default:return Promise.reject()}}.bind(a))["catch"](function(){return 0})}
  2099. k.Fd=function(a,b,c){var d=c.getAttribute("schemeIdUri")||"",e=c.getAttribute("value")||"",f=N(c,"timescale",Oc)||1;M(c,"Event").forEach(function(c){var g=N(c,"presentationTime",Oc)||0,l=N(c,"duration",Oc)||0,g=g/f+a,l=g+l/f;null!=b&&(g=Math.min(g,a+b),l=Math.min(l,a+b));c={schemeIdUri:d,value:e,startTime:g,endTime:l,id:c.getAttribute("id")||"",eventElement:c};this.a.onTimelineRegionAdded(c)}.bind(this))};
  2100. k.Qd=function(a,b,c){a=C(a,this.b.retryParameters);null!=b&&(a.headers.Range="bytes="+b+"-"+(null!=c?c:""));return this.a.networkingEngine.request(1,a).then(function(a){return a.data})};function Rd(a,b){return ub[Yb(a,b)]?"text":a.split("/")[0]}Ed.mpd=Hd;Dd["application/dash+xml"]=Hd;function Ud(a,b,c,d){this.uri=a;this.type=b;this.ga=c;this.segments=d||null}function Vd(a,b,c,d){this.id=a;this.name=b;this.a=c;this.value=d||null}Vd.prototype.toString=function(){function a(a){return a.name+'="'+a.value+'"'}return this.value?"#"+this.name+":"+this.value:0<this.a.length?"#"+this.name+":"+this.a.map(a).join(","):"#"+this.name};function Wd(a,b){this.name=a;this.value=b}Vd.prototype.getAttribute=function(a){var b=this.a.filter(function(b){return b.name==a});return b.length?b[0]:null};
  2101. function Xd(a,b,c){c=c||null;return(a=a.getAttribute(b))?a.value:c}function Yd(a,b){this.ga=b;this.uri=a};function Zd(a,b){return a.filter(function(a){return a.name==b})}function $d(a,b){var c=Zd(a,b);return c.length?c[0]:null}function ae(a,b,c){return a.filter(function(a){var d=a.getAttribute("TYPE");a=a.getAttribute("GROUP-ID");return d.value==b&&a.value==c})};function be(a){this.b=a;this.a=0}function ce(a,b){b.lastIndex=a.a;var c=(c=b.exec(a.b))?{position:c.index,length:c[0].length,Sd:c}:null;if(a.a==a.b.length||!c||c.position!=a.a)return null;a.a+=c.length;return c.Sd}function de(a){return a.a==a.b.length?null:(a=ce(a,/[^ \t\n]*/gm))?a[0]:null};function ee(){this.a=0}
  2102. function fe(a,b,c){b=F(b);b=b.replace(/\r\n|\r(?=[^\n]|$)/gm,"\n").trim();var d=b.split(/\n+/m);if(!/^#EXTM3U($|[ \t\n])/m.test(d[0]))throw new t(2,4,4015);b=0;for(var e=[],f=1;f<d.length;)if(/^#(?!EXT)/m.test(d[f]))f+=1;else{var g=d[f];g=ge(a.a++,g);if(0<=he.indexOf(g.name))b=1;else if(0<=ie.indexOf(g.name)){if(1!=b)throw new t(2,4,4017);d=d.splice(f,d.length-f);a=je(a,d);return new Ud(c,b,e,a)}e.push(g);f+=1;"EXT-X-STREAM-INF"==g.name&&(g.a.push(new Wd("URI",d[f])),f+=1)}return new Ud(c,b,e)}
  2103. function je(a,b){var c=[],d=[];b.forEach(function(a){/^(#EXT)/.test(a)?(a=ge(this.a++,a),d.push(a)):/^#(?!EXT)/m.test(a)||(c.push(new Yd(a.trim(),d)),d=[])}.bind(a));return c}function ge(a,b){var c=b.match(/^#(EXT[^:]*)(?::(.*))?$/);if(!c)throw new t(2,4,4016);var d=c[1],e=c[2],c=[];if(e&&0<=e.indexOf("="))for(var e=new be(e),f,g=/([^=]+)=(?:"([^"]*)"|([^",]*))(?:,|$)/g;f=ce(e,g);)c.push(new Wd(f[1],f[2]||f[3]));else if(e)return new Vd(a,d,c,e);return new Vd(a,d,c)}
  2104. var he="EXT-X-TARGETDURATION EXT-X-MEDIA-SEQUENCE EXT-X-DISCONTINUITY-SEQUENCE EXT-X-PLAYLIST-TYPE EXT-X-MAP EXT-X-I-FRAMES-ONLY".split(" "),ie="EXTINF EXT-X-BYTERANGE EXT-X-DISCONTINUITY EXT-X-PROGRAM-DATE-TIME EXT-X-KEY EXT-X-DATERANGE".split(" ");function ke(a){return new Promise(function(b){var c=ke.parse(a);b({uri:a,data:c.data,headers:{"content-type":c.contentType}})})}n("shaka.net.DataUriPlugin",ke);
  2105. ke.parse=function(a){var b=a.split(":");if(2>b.length||"data"!=b[0])throw new t(2,1,1004,a);b=b.slice(1).join(":").split(",");if(2>b.length)throw new t(2,1,1004,a);var c=b[0],b=window.decodeURIComponent(b.slice(1).join(",")),c=c.split(";"),d=null;1<c.length&&(d=c[1]);if("base64"==d)a=Ya(b).buffer;else{if(d)throw new t(2,1,1005,a);a=Ua(b)}return{data:a,contentType:c[0]}};Ea.data=ke;function le(){this.b=this.c=null;this.i=1;this.g={};this.f={};this.a=null;this.j="";this.h=new ee}n("shaka.hls.HlsParser",le);k=le.prototype;k.configure=function(a){this.b=a};k.start=function(a,b){this.c=b;this.j=a;return this.c.networkingEngine.request(0,C([a],this.b.retryParameters)).then(function(b){return ne(this,b.data,a)}.bind(this))};k.stop=function(){this.b=this.c=null;this.g={};return Promise.resolve()};k.update=function(){};k.onExpirationUpdated=function(){};
  2106. function ne(a,b,c){b=fe(a.h,b,c);if(0!=b.type)throw new t(2,4,4022);a.a=new T(null,0);return oe(a,b).then(function(a){this.c.filterPeriod(a);return{presentationTimeline:this.a,periods:[a],offlineSessionIds:[],minBufferTime:0}}.bind(a))}
  2107. function oe(a,b){var c=Zd(b.ga,"EXT-X-STREAM-INF").map(function(a){return pe(this,a,b)}.bind(a)),d=Zd(b.ga,"EXT-X-MEDIA").filter(function(a){return"SUBTITLES"==U(a,"TYPE")}.bind(a)).map(function(a){return qe(this,a,b)}.bind(a));return Promise.all(c).then(function(a){return Promise.all(d).then(function(b){var c=a.reduce(x,[]);re(this,c);return{startTime:0,variants:c,textStreams:b}}.bind(this))}.bind(a))}
  2108. function pe(a,b,c){var d=Number(U(b,"BANDWIDTH")),e=Xd(b,"CODECS","avc1.42E01E,mp4a.40.2").split(","),f=b.getAttribute("RESOLUTION"),g=null,h=null,l=Xd(b,"FRAME-RATE");if(f)var m=f.value.split("x"),g=m[0],h=m[1];var q=se(a,c);c=Zd(c.ga,"EXT-X-MEDIA");var r=Xd(b,"AUDIO"),v=Xd(b,"VIDEO");r?c=ae(c,"AUDIO",r):v&&(c=ae(c,"VIDEO",v));c=c.map(function(a){return te(this,a,e,q)}.bind(a));var u=[],w=[];return Promise.all(c).then(function(a){r?u=a:v&&(w=a);if(u.length||w.length)var c=u.length?"video":"audio";
  2109. else 1==e.length?c=f||l?"video":"audio":(c="video",e=[e.join(",")]);a=e;var d=U(b,"URI");return ue(this,d,a,c,q,"und",!1,null)}.bind(a)).then(function(a){"audio"==a.stream.type?u=[a]:w=[a];return ve(this,u,w,d,g,h,l)}.bind(a))}
  2110. function ve(a,b,c,d,e,f,g){c.forEach(function(a){if(a=a.stream)a.width=Number(e)||void 0,a.height=Number(f)||void 0,a.frameRate=Number(g)||void 0}.bind(a));b.length||(b=[null]);c.length||(c=[null]);for(var h=[],l=0;l<b.length;l++)for(var m=0;m<c.length;m++){var q=b[l]?b[l].stream:null,r=c[m]?c[m].stream:null,v=b[l]?b[l].drmInfos:null,u=c[m]?c[m].drmInfos:null;if(q&&r)if(v.length&&u.length?0<sb(v,u).length:1)var w=sb(v,u);else continue;else q?w=v:r&&(w=u);h.push(xe(a,q,r,d,w))}return h}
  2111. function xe(a,b,c,d,e){return{id:a.i++,language:b?b.language:"und",primary:!!b&&b.primary||!!c&&c.primary,audio:b,video:c,bandwidth:d,drmInfos:e,allowedByApplication:!0,allowedByKeySystem:!0}}function qe(a,b,c){U(b,"TYPE");c=se(a,c);return te(a,b,[],c).then(function(a){return a.stream})}
  2112. function te(a,b,c,d){if(a.g[b.id])return Promise.resolve().then(function(){return this.g[b.id]}.bind(a));var e=U(b,"TYPE").toLowerCase();"subtitles"==e&&(e="text");var f=Sb(Xd(b,"LANGUAGE","und")),g=Xd(b,"NAME"),h=b.getAttribute("DEFAULT"),l=b.getAttribute("AUTOSELECT"),m=U(b,"URI");return ue(a,m,c,e,d,f,!!h||!!l,g).then(function(a){return this.g[b.id]=a}.bind(a))}
  2113. function ue(a,b,c,d,e,f,g,h){b=z([a.j],[b])[0];return a.c.networkingEngine.request(0,C([b],a.b.retryParameters)).then(function(a){a=fe(this.h,a.data,a.uri);if(1!=a.type)throw new t(2,4,4017);e=se(this,a)||e;var b=null;"text"!=d&&(b=ye(a));var l=$d(a.ga,"EXT-X-MEDIA-SEQUENCE"),l=ze(this,a,l?Number(l.value):0);this.a.Ha(0,l);var r=l[l.length-1].endTime-l[0].startTime,v=this.a.Y();(Infinity==v||v<r)&&this.a.pa(r);var u=Ae(d,c),w=void 0;"text"==d&&(w="subtitle");var G=new S(l),pa=[];a.segments.forEach(function(a){a=
  2114. Zd(a.ga,"EXT-X-KEY");pa.push.apply(pa,a)});var Hb=!1,tc=[],me=null;pa.forEach(function(a){if("NONE"!=U(a,"METHOD")){Hb=!0;var b=U(a,"KEYFORMAT");if(a=(b=Be[b])?b(a):null)a.keyIds.length&&(me=a.keyIds[0]),tc.push(a)}});if(Hb&&!tc.length)throw new t(2,4,4026);return Ce(this,d,l[0].a()[0]).then(function(a){a={id:this.i++,createSegmentIndex:Promise.resolve.bind(Promise),findSegmentPosition:G.find.bind(G),getSegmentReference:G.get.bind(G),initSegmentReference:b,presentationTimeOffset:e||0,mimeType:a,codecs:u,
  2115. kind:w,encrypted:Hb,keyId:me,language:f,label:h||null,type:d,primary:g,trickModeVideo:null,containsEmsgBoxes:!1,frameRate:void 0,width:void 0,height:void 0,bandwidth:void 0,roles:[]};this.f[a.id]=G;return{stream:a,Ae:G,drmInfos:tc}}.bind(this))}.bind(a))}
  2116. function ye(a){var b=Zd(a.ga,"EXT-X-MAP");if(!b.length)return null;if(1<b.length)throw new t(2,4,4020);var b=b[0],c=U(b,"URI"),d=z([a.uri],[c])[0];a=0;c=null;if(b=Xd(b,"BYTERANGE"))a=b.split("@"),b=Number(a[0]),a=Number(a[1]),c=a+b-1;return new Zc(function(){return[d]},a,c)}
  2117. function ze(a,b,c){var d=b.segments,e=[];d.forEach(function(a){var f=a.ga,h=z([b.uri],[a.uri])[0],l=De(f).value.split(","),l=Number(l[0]),m;(a=d.indexOf(a))?m=e[a-1].endTime:m=0;var l=m+l,q=0,r=null;if(f=$d(f,"EXT-X-BYTERANGE"))f=f.value.split("@"),r=Number(f[0]),f[1]?q=Number(f[1]):q=e[a-1].M,r=q+r-1,a==d.length-1&&(r=null);e.push(new O(c+a,m,l,function(){return[h]},q,r))}.bind(a));return e}
  2118. function re(a,b){b.forEach(function(a){var b=this.a.Y(),c=a.video;a=a.audio;c&&this.f[c.id]&&gd(this.f[c.id],b);a&&this.f[a.id]&&gd(this.f[a.id],b)}.bind(a))}function Ae(a,b){if(1==b.length)return b[0];if("text"==a)return"";var c=Ee;"audio"==a&&(c=Fe);for(var d=0;d<c.length;d++)for(var e=0;e<b.length;e++)if(c[d].test(b[e].trim()))return b[e].trim();throw new t(2,4,4025,b);}
  2119. function Ce(a,b,c){var d=c.split("."),e=d[d.length-1];if("text"==b)return Promise.resolve("text/vtt");d=Ge;"video"==b&&(d=He);if(b=d[e])return Promise.resolve(b);c=C([c],a.b.retryParameters);c.method="HEAD";return a.c.networkingEngine.request(1,c).then(function(a){a=a.headers["content-type"];if(!a)throw new t(2,4,4021,e);return a})}function se(a,b){var c=$d(b.ga,"EXT-X-START");return c?Number(U(c,"TIME-OFFSET")):a.b.hls.defaultTimeOffset}
  2120. function U(a,b){var c=a.getAttribute(b);if(!c)throw new t(2,4,4023,b);return c.value}function De(a){a=$d(a,"EXTINF");if(!a)throw new t(2,4,4024,"EXTINF");return a}
  2121. var Ee=[/^(avc)/,/^(hvc)/,/^(vp[8-9])$/,/^(av1)$/,/^(mp4v)/],Fe=[/^(vorbis)/,/^(opus)/,/^(mp4a)/,/^(ac-3)$/,/^(ec-3)$/],Ge={mp4:"audio/mp4",m4s:"audio/mp4",m4i:"audio/mp4",m4a:"audio/mp4",ts:"video/mp2t"},He={mp4:"video/mp4",m4s:"video/mp4",m4i:"video/mp4",m4v:"video/mp4",ts:"video/mp2t"},Be={"urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed":function(a){if("SAMPLE-AES-CENC"!=U(a,"METHOD"))return null;var b=U(a,"URI"),b=ke.parse(b),b=new Uint8Array(b.data),b=Ba("com.widevine.alpha",[{initDataType:"cenc",
  2122. initData:b}]);if(a=Xd(a,"KEYID"))b.keyIds=[a.substr(2).toLowerCase()];return b}};Ed.m3u8=le;Dd["application/x-mpegurl"]=le;Dd["application/vnd.apple.mpegurl"]=le;function Ie(){}Ie.prototype.parseInit=function(){};
  2123. Ie.prototype.parseMedia=function(a,b){var c=F(a),d=[],e=new DOMParser,f=null;try{f=e.parseFromString(c,"text/xml")}catch(Hb){throw new t(2,2,2005);}if(f){var g=f.getElementsByTagName("tt")[0];if(g){e=g.getAttribute("ttp:frameRate");f=g.getAttribute("ttp:subFrameRate");var h=g.getAttribute("ttp:frameRateMultiplier");var l=g.getAttribute("ttp:tickRate");c=g.getAttribute("xml:space")||"default"}else throw new t(2,2,2005);if("default"!=c&&"preserve"!=c)throw new t(2,2,2005);c="default"==c;e=new Je(e,
  2124. f,h,l);f=Ke(g.getElementsByTagName("styling")[0]);h=Ke(g.getElementsByTagName("layout")[0]);g=Ke(g.getElementsByTagName("body")[0]);for(l=0;l<g.length;l++){var m=g[l],q=b.periodStart,r=e;var v=f;var u=h,w=c;if(m.hasAttribute("begin")||m.hasAttribute("end")||!/^\s*$/.test(m.textContent)){Le(m,w);var w=Me(m.getAttribute("begin"),r),G=Me(m.getAttribute("end"),r),r=Me(m.getAttribute("dur"),r),pa=m.textContent;null==G&&null!=r&&(G=w+r);if(null==w||null==G)throw new t(2,2,2001);if(q=xb(w+q,G+q,pa)){w=Ne(m,
  2125. "region",u);u=q;if(G=Oe(m,w,v,"tts:extent"))if(r=Pe.exec(G))u.size=Number(r[1]);r=Oe(m,w,v,"tts:writingMode");G=!0;"tb"==r||"tblr"==r?u.vertical="lr":"tbrl"==r?u.vertical="rl":G=!1;if(r=Oe(m,w,v,"tts:origin"))if(r=Pe.exec(r))G?(u.position=Number(r[2]),u.line=Number(r[1])):(u.position=Number(r[1]),u.line=Number(r[2])),u.snapToLines=!1;if(v=Oe(m,w,v,"tts:textAlign"))u.align=v,"center"==v&&("center"!=u.align&&(u.align="middle"),u.position="auto"),u.positionAlign=Qe[v],u.lineAlign=Re[v];v=q}else v=null}else v=
  2126. null;v&&d.push(v)}}return d};var Se=/^(\d{2,}):(\d{2}):(\d{2}):(\d{2})\.?(\d+)?$/,Te=/^(?:(\d{2,}):)?(\d{2}):(\d{2})$/,Ue=/^(?:(\d{2,}):)?(\d{2}):(\d{2}\.\d{2,})$/,Ve=/^(\d*\.?\d*)f$/,We=/^(\d*\.?\d*)t$/,Xe=/^(?:(\d*\.?\d*)h)?(?:(\d*\.?\d*)m)?(?:(\d*\.?\d*)s)?(?:(\d*\.?\d*)ms)?$/,Pe=/^(\d{1,2}|100)% (\d{1,2}|100)%$/,Re={left:"start",center:"center",right:"end",start:"start",end:"end"},Qe={left:"line-left",center:"center",right:"line-right"};
  2127. function Ke(a){var b=[];if(!a)return b;for(var c=a.childNodes,d=0;d<c.length;d++){var e="span"==c[d].nodeName&&"p"==a.nodeName;c[d].nodeType!=Node.ELEMENT_NODE||"br"==c[d].nodeName||e||(e=Ke(c[d]),b=b.concat(e))}b.length||b.push(a);return b}function Le(a,b){for(var c=a.childNodes,d=0;d<c.length;d++)if("br"==c[d].nodeName&&0<d)c[d-1].textContent+="\n";else if(0<c[d].childNodes.length)Le(c[d],b);else if(b){var e=c[d].textContent.trim(),e=e.replace(/\s+/g," ");c[d].textContent=e}}
  2128. function Oe(a,b,c,d){for(var e=Ke(b),f=0;f<e.length;f++){var g=e[f].getAttribute(d);if(g)return g}e=Ne;return(a=e(b,"style",c)||e(a,"style",c))?a.getAttribute(d):null}function Ne(a,b,c){if(!a||1>c.length)return null;var d=null,e=a;for(a=null;e&&!(a=e.getAttribute(b))&&(e=e.parentNode,e instanceof Element););if(b=a)for(a=0;a<c.length;a++)if(c[a].getAttribute("xml:id")==b){d=c[a];break}return d}
  2129. function Me(a,b){var c=null;if(Se.test(a))var c=Se.exec(a),d=Number(c[1]),e=Number(c[2]),f=Number(c[3]),g=Number(c[4]),g=g+(Number(c[5])||0)/b.b,f=f+g/b.frameRate,c=f+60*e+3600*d;else Te.test(a)?c=Ye(Te,a):Ue.test(a)?c=Ye(Ue,a):Ve.test(a)?(c=Ve.exec(a),c=Number(c[1])/b.frameRate):We.test(a)?(c=We.exec(a),c=Number(c[1])/b.a):Xe.test(a)&&(c=Ye(Xe,a));return c}
  2130. function Ye(a,b){var c=a.exec(b);return c&&""!=c[0]?(Number(c[4])||0)/1E3+(Number(c[3])||0)+60*(Number(c[2])||0)+3600*(Number(c[1])||0):null}function Je(a,b,c,d){this.frameRate=Number(a)||30;this.b=Number(b)||1;this.a=Number(d);this.a||(this.a=a?this.frameRate*this.b:1);c&&(a=/^(\d+) (\d+)$/g.exec(c))&&(this.frameRate*=a[1]/a[2])}vb("application/ttml+xml",Ie);function Ze(){this.a=new Ie}Ze.prototype.parseInit=function(a){var b=!1;(new Q).C("moov",R).C("trak",R).C("mdia",R).C("minf",R).C("stbl",R).da("stsd",cd).C("stpp",function(){b=!0}).parse(a);if(!b)throw new t(2,2,2007);};Ze.prototype.parseMedia=function(a,b){var c=!1,d=[];(new Q).C("mdat",dd(function(a){c=!0;d=this.a.parseMedia(a.buffer,b)}.bind(this))).parse(a);if(!c)throw new t(2,2,2007);return d};vb('application/mp4; codecs="stpp"',Ze);function $e(){}$e.prototype.parseInit=function(){};
  2131. $e.prototype.parseMedia=function(a,b){var c=F(a),c=c.replace(/\r\n|\r(?=[^\n]|$)/gm,"\n"),c=c.split(/\n{2,}/m);if(!/^WEBVTT($|[ \t\n])/m.test(c[0]))throw new t(2,2,2E3);var d=b.segmentStart;if(0<=c[0].indexOf("X-TIMESTAMP-MAP")){var e=c[0].match(/LOCAL:((?:(\d{1,}):)?(\d{2}):(\d{2})\.(\d{3}))/m),f=c[0].match(/MPEGTS:(\d+)/m);e&&f&&(d=af(new be(e[1])),d=b.periodStart+(Number(f[1])/9E4-d))}f=[];for(e=1;e<c.length;e++){var g=c[e].split("\n"),h=d;if(1==g.length&&!g[0]||/^NOTE($|[ \t])/.test(g[0]))var l=
  2132. null;else{l=null;0>g[0].indexOf("--\x3e")&&(l=g[0],g.splice(0,1));var m=new be(g[0]),q=af(m),r=ce(m,/[ \t]+--\x3e[ \t]+/g),v=af(m);if(null==q||!r||null==v)throw new t(2,2,2001);if(g=xb(q+h,v+h,g.slice(1).join("\n").trim())){ce(m,/[ \t]+/gm);for(h=de(m);h;)bf(g,h),ce(m,/[ \t]+/gm),h=de(m);null!=l&&(g.id=l);l=g}else l=null}l&&f.push(l)}return f};
  2133. function bf(a,b){var c;if(c=/^align:(start|middle|center|end|left|right)$/.exec(b))a.align=c[1],"center"==c[1]&&"center"!=a.align&&(a.position="auto",a.align="middle");else if(c=/^vertical:(lr|rl)$/.exec(b))a.vertical=c[1];else if(c=/^size:(\d{1,2}|100)%$/.exec(b))a.size=Number(c[1]);else if(c=/^position:(\d{1,2}|100)%(?:,(line-left|line-right|center|start|end))?$/.exec(b))a.position=Number(c[1]),c[2]&&(a.positionAlign=c[2]);else if(c=/^line:(\d{1,2}|100)%(?:,(start|end|center))?$/.exec(b))a.snapToLines=
  2134. !1,a.line=Number(c[1]),c[2]&&(a.lineAlign=c[2]);else if(c=/^line:(-?\d+)(?:,(start|end|center))?$/.exec(b))a.snapToLines=!0,a.line=Number(c[1]),c[2]&&(a.lineAlign=c[2])}function af(a){a=ce(a,/(?:(\d{1,}):)?(\d{2}):(\d{2})\.(\d{3})/g);if(!a)return null;var b=Number(a[2]),c=Number(a[3]);return 59<b||59<c?null:Number(a[4])/1E3+c+60*b+3600*(Number(a[1])||0)}vb("text/vtt",$e);vb('text/vtt; codecs="vtt"',$e);function cf(){this.a=null}cf.prototype.parseInit=function(a){var b=!1;(new Q).C("moov",R).C("trak",R).C("mdia",R).da("mdhd",function(a){0==a.version?(a.s.I(4),a.s.I(4),this.a=a.s.D(),a.s.I(4)):(a.s.I(8),a.s.I(8),this.a=a.s.D(),a.s.I(8));a.s.I(4)}.bind(this)).C("minf",R).C("stbl",R).da("stsd",cd).C("wvtt",function(){b=!0}).parse(a);if(!this.a)throw new t(2,2,2008);if(!b)throw new t(2,2,2008);};
  2135. cf.prototype.parseMedia=function(a,b){var c=0,d=[],e=[],f=[],g=!1,h=!1,l=!1;(new Q).C("moof",R).C("traf",R).da("tfdt",function(a){g=!0;c=a.version?a.s.Pa():a.s.D()}).da("trun",function(a){h=!0;var b=a.version,c=a.Nc;a=a.s;var e=a.D();c&1&&a.I(4);c&4&&a.I(4);for(var f=[],g=0;g<e;g++){var l={duration:null,Nb:null};c&256&&(l.duration=a.D());c&512&&a.I(4);c&1024&&a.I(4);c&2048&&(l.Nb=b?a.nc():a.D());f.push(l)}d=f}).C("vtte",function(){e.push(null)}).C("vttc",dd(function(a){e.push(a.buffer)})).C("mdat",
  2136. function(a){l=!0;R(a)}).parse(a);if(!l&&!g&&!h)throw new t(2,2,2008);for(var m=c,q=0;q<d.length;q++){var r=d[q],v=e[q];if(r.duration){var u=r.Nb?c+r.Nb:m,m=u+r.duration;v&&f.push(df(v,b.periodStart+u/this.a,b.periodStart+m/this.a))}}return f};function df(a,b,c){var d,e,f;(new Q).C("payl",dd(function(a){d=F(a)})).C("iden",dd(function(a){e=F(a)})).C("sttg",dd(function(a){f=F(a)})).parse(a);return d?ef(d,e,f,b,c):null}
  2137. function ef(a,b,c,d,e){(a=xb(d,e,a))&&b&&(a.id=b);if(a&&c)for(b=new be(c),c=de(b);c;)bf(a,c),ce(b,/[ \t]+/gm),c=de(b);return a}vb('application/mp4; codecs="wvtt"',cf);function ff(a,b,c,d,e,f){this.a=a;this.c=b;this.l=c;this.A=d;this.J=e;this.G=f;this.b=new D;this.h=!1;this.g=1;this.j=this.f=null;this.B=a.readyState;this.i=!1;this.O=this.v=-1;this.o=!1;0<a.readyState?this.fc():La(this.b,a,"loadedmetadata",this.fc.bind(this));b=this.hc.bind(this);E(this.b,a,"ratechange",this.rd.bind(this));E(this.b,a,"waiting",b);this.j=setInterval(b,250)}k=ff.prototype;
  2138. k.m=function(){var a=this.b.m();this.b=null;null!=this.f&&(window.clearInterval(this.f),this.f=null);null!=this.j&&(window.clearInterval(this.j),this.j=null);this.G=this.J=this.l=this.c=this.a=null;return a};function gf(a,b){0<a.a.readyState?a.a.currentTime=hf(a,b):a.A=b}function jf(a){return 0<a.a.readyState?hf(a,a.a.currentTime):kf(a)}function kf(a){if(a.A)return hf(a,a.A);a=a.c.presentationTimeline;return Infinity>a.Y()?a.ma():a.bb()}k.rb=function(){return this.g};
  2139. function lf(a,b){null!=a.f&&(window.clearInterval(a.f),a.f=null);a.g=b;a.a.playbackRate=a.h||0>b?0:b;!a.h&&0>b&&(a.f=window.setInterval(function(){this.a.currentTime+=b/4}.bind(a),250))}k.Ab=function(){this.o=!0;this.hc()};k.rd=function(){this.a.playbackRate!=(this.h||0>this.g?0:this.g)&&lf(this,this.a.playbackRate)};
  2140. k.fc=function(){var a=kf(this);.001>Math.abs(this.a.currentTime-a)?(E(this.b,this.a,"seeking",this.ic.bind(this)),E(this.b,this.a,"playing",this.gc.bind(this))):(La(this.b,this.a,"seeking",this.td.bind(this)),this.a.currentTime=a)};k.td=function(){E(this.b,this.a,"seeking",this.ic.bind(this));E(this.b,this.a,"playing",this.gc.bind(this))};
  2141. k.hc=function(){if(this.a.readyState){this.a.readyState!=this.B&&(this.i=!1,this.B=this.a.readyState);var a=this.l.smallGapLimit,b=this.a.currentTime,c=this.a.buffered;a:{if(c&&c.length&&!(1==c.length&&1E-6>c.end(0)-c.start(0))){var d=.1;/(Edge|Trident)\//.test(navigator.userAgent)&&(d=.5);for(var e=0;e<c.length;e++)if(c.start(e)>b&&(!e||c.end(e-1)-b<=d)){d=e;break a}}d=null}if(null==d){if(3>this.a.readyState&&0<this.a.playbackRate)if(this.O!=b)this.O=b,this.v=Date.now();else if(this.v<Date.now()-
  2142. 1E3)for(this.v=Date.now()+5E3,d=0;d<c.length;d++)if(b>=c.start(d)&&b<c.end(d)-.5){this.a.currentTime=this.a.currentTime;break}}else if(d||this.o)if(e=c.start(d),!(e>=this.c.presentationTimeline.bb())){var f=e-b,a=f<=a,g=!1;a||this.i||(this.i=!0,f=new I("largegap",{currentTime:b,gapSize:f}),f.cancelable=!0,this.G(f),this.l.jumpLargeGaps&&!f.defaultPrevented&&(g=!0));if(a||g)d&&c.end(d-1),mf(this,b,e)}}};
  2143. k.ic=function(){this.o=!1;var a=this.a.currentTime,b=nf(this,a);.001<Math.abs(b-a)?mf(this,a,b):(this.i=!1,this.J())};k.gc=function(){var a=this.a.currentTime,b=nf(this,a);.001<Math.abs(b-a)&&mf(this,a,b)};function nf(a,b){var c=Bb.bind(null,a.a.buffered),d=1*Math.max(a.c.minBufferTime||0,a.l.rebufferingGoal),e=a.c.presentationTimeline,f=e.ua(),g=e.Ea(d),h=e.Ea(5),d=e.Ea(d+5);return b>f?f:b<e.Ea(0)?c(h)?h:d:b>=g||c(b)?b:d}
  2144. function mf(a,b,c){a.a.currentTime=c;var d=0,e=function(){!this.a||10<=d++||this.a.currentTime!=b||(this.a.currentTime=c,setTimeout(e,100))}.bind(a);setTimeout(e,100)}function hf(a,b){var c=a.c.presentationTimeline.ma();if(b<c)return c;c=a.c.presentationTimeline.ua();return b>c?c:b};function of(a,b,c,d,e,f){this.a=a;this.g=b;this.A=c;this.l=d;this.h=e;this.B=f;this.c=[];this.j=new D;this.b=!1;this.i=-1;this.f=null;pf(this)}of.prototype.m=function(){var a=this.j?this.j.m():Promise.resolve();this.j=null;qf(this);this.B=this.h=this.l=this.A=this.g=this.a=null;this.c=[];return a};
  2145. of.prototype.v=function(a){if(!this.c.some(function(b){return b.info.schemeIdUri==a.schemeIdUri&&b.info.startTime==a.startTime&&b.info.endTime==a.endTime})){var b={info:a,status:1};this.c.push(b);var c=new I("timelineregionadded",{detail:rf(a)});this.h(c);this.o(!0,b)}};function rf(a){var b=Da(a);b.eventElement=a.eventElement;return b}
  2146. of.prototype.o=function(a,b){var c=b.info.startTime>this.a.currentTime?1:b.info.endTime<this.a.currentTime?3:2,d=2==b.status,e=2==c;if(c!=b.status){if(!a||d||e)d||this.h(new I("timelineregionenter",{detail:rf(b.info)})),e||this.h(new I("timelineregionexit",{detail:rf(b.info)}));b.status=c}};function pf(a){qf(a);a.f=window.setTimeout(a.G.bind(a),250)}function qf(a){a.f&&(window.clearTimeout(a.f),a.f=null)}
  2147. of.prototype.G=function(){this.f=null;pf(this);var a=hc(this.g,this.a.currentTime);a!=this.i&&(-1!=this.i&&this.B(),this.i=a);var a=Cb(this.a.buffered,this.a.currentTime),b=Ab(this.a.buffered)>=this.g.presentationTimeline.ua()-.1||this.a.ended;if(this.b){var c=1*Math.max(this.g.minBufferTime||0,this.A.rebufferingGoal);(b||a>=c)&&0!=this.b&&(this.b=!1,this.l(!1))}else!b&&.5>a&&1!=this.b&&(this.b=!0,this.l(!0));this.c.forEach(this.o.bind(this,!1))};function sf(a,b){this.a=b;this.b=a;this.g=null;this.i=1;this.o=Promise.resolve();this.h=[];this.j={};this.c={};this.f=this.l=this.v=!1}k=sf.prototype;k.m=function(){for(var a in this.c)tf(this.c[a]);this.g=this.c=this.j=this.h=this.o=this.b=this.a=null;this.f=!0;return Promise.resolve()};k.configure=function(a){this.g=a};k.init=function(){var a=this.a.bc(this.b.periods[hc(this.b,jf(this.a.Oa))]);return Ma(a)?Promise.reject(new t(2,5,5005)):uf(this,a).then(function(){this.a&&this.a.jd&&this.a.jd()}.bind(this))};
  2148. function V(a){return a.b.periods[hc(a.b,jf(a.a.Oa))]}function vf(a){return Oa(a.c,function(a){return a.na||a.stream})}function wf(a,b){var c={};c.text=b;return uf(a,c)}function xf(a,b){var c=a.c.video;if(c){var d=c.stream;if(d)if(b){var e=d.trickModeVideo;if(e){var f=c.na;f||(yf(a,"video",e,!1),c.na=d)}}else if(f=c.na)c.na=null,yf(a,"video",f,!0)}}
  2149. function yf(a,b,c,d){var e=a.c[b];if(!e&&"text"==b&&a.g.ignoreTextStreamFailures)wf(a,c);else if(e){var f=ic(a.b,c);d&&f!=e.wa?zf(a):(e.na&&(c.trickModeVideo?(e.na=c,c=c.trickModeVideo):e.na=null),"text"==b&&Fb(a.a.K,Yb(c.mimeType,c.codecs)),(b=a.h[f])&&b.La&&(b=a.j[c.id])&&b.La&&e.stream!=c&&(e.stream=c,e.cb=!0,d&&(e.sa?e.kb=!0:e.xa?(e.ra=!0,e.kb=!0):(tf(e),Af(a,e,!0)))))}}
  2150. function Bf(a){var b=jf(a.a.Oa);Object.keys(a.c).every(function(a){var c=this.a.K;"text"==a?(a=c.a,a=b>=a.b&&b<a.a):(a=Ib(c,a),a=Bb(a,b));return a}.bind(a))||zf(a)}function zf(a){for(var b in a.c){var c=a.c[b];c.sa||c.ra||(c.xa?c.ra=!0:null==Gb(a.a.K,b)?null==c.qa&&Cf(a,c,0):(tf(c),Af(a,c,!1)))}}
  2151. function uf(a,b,c){var d=hc(a.b,jf(a.a.Oa)),e=Oa(b,function(a){return Yb(a.mimeType,a.codecs)});a.a.K.init(e);Df(a);e=Na(b);return Ef(a,e).then(function(){if(!this.f)for(var a in b){var e=b[a];this.c[a]||(this.c[a]={stream:e,type:a,Fa:null,ea:null,na:null,cb:!0,wa:d,endOfStream:!1,xa:!1,qa:null,ra:!1,kb:!1,sa:!1,Gb:!1,tb:!1,rc:c||0},Cf(this,this.c[a],0))}}.bind(a))}
  2152. function Ff(a,b){var c=a.h[b];if(c)return c.L;c={L:new A,La:!1};a.h[b]=c;var d=a.b.periods[b].variants.map(function(a){var b=[];a.audio&&b.push(a.audio);a.video&&b.push(a.video);a.video&&a.video.trickModeVideo&&b.push(a.video.trickModeVideo);return b}).reduce(x,[]).filter(Aa);d.push.apply(d,a.b.periods[b].textStreams);a.o=a.o.then(function(){if(!this.f)return Ef(this,d)}.bind(a)).then(function(){this.f||(this.h[b].L.resolve(),this.h[b].La=!0)}.bind(a))["catch"](function(a){this.f||(this.h[b].L.reject(),
  2153. delete this.h[b],this.a.onError(a))}.bind(a));return c.L}
  2154. function Ef(a,b){b.map(function(a){return a.id}).filter(Aa);for(var c=[],d=0;d<b.length;++d){var e=b[d];var f=a.j[e.id];f?c.push(f.L):(a.j[e.id]={L:new A,La:!1},c.push(e.createSegmentIndex()))}return Promise.all(c).then(function(){if(!this.f)for(var a=0;a<b.length;++a){var c=this.j[b[a].id];c.La||(c.L.resolve(),c.La=!0)}}.bind(a))["catch"](function(a){if(!this.f)return this.j[e.id].L.reject(),delete this.j[e.id],Promise.reject(a)}.bind(a))}
  2155. function Df(a){var b=a.b.presentationTimeline.Y();Infinity>b?a.a.K.pa(b):a.a.K.pa(Math.pow(2,32))}k.ke=function(a){if(!this.f&&!a.xa&&null!=a.qa&&!a.sa)if(a.qa=null,a.ra)Af(this,a,a.kb);else{try{var b=Gf(this,a);null!=b&&(Cf(this,a,b),a.tb=!1)}catch(c){this.a.onError(c);return}b=Na(this.c);Hf(this,a);b.every(function(a){return a.endOfStream})&&this.a.K.endOfStream().then(function(){this.b.presentationTimeline.pa(this.a.K.Y())}.bind(this))}};
  2156. function Gf(a,b){var c=jf(a.a.Oa),d=b.Fa&&b.ea?a.b.periods[ic(a.b,b.Fa)].startTime+b.ea.endTime:Math.max(c,b.rc);b.rc=0;var e=ic(a.b,b.stream),f=hc(a.b,d);var g=a.a.K;var h=b.type;"text"==h?(g=g.a,g=null==g.a||g.a<c?0:g.a-Math.max(c,g.b)):(g=Ib(g,h),g=Cb(g,c));h=Math.max(a.i*Math.max(a.b.minBufferTime||0,a.g.rebufferingGoal),a.i*a.g.bufferingGoal);if(d>=a.b.presentationTimeline.Y())return b.endOfStream=!0,null;b.endOfStream=!1;b.wa=f;if(f!=e)return null;if(g>=h)return.5;d=a.a.K;f=b.type;d="text"==
  2157. f?d.a.a:Ab(Ib(d,f));b.ea&&b.stream==b.Fa?(f=b.ea.position+1,d=If(a,b,e,f)):(f=b.ea?b.stream.findSegmentPosition(Math.max(0,a.b.periods[ic(a.b,b.Fa)].startTime+b.ea.endTime-a.b.periods[e].startTime)):b.stream.findSegmentPosition(Math.max(0,(d||c)-a.b.periods[e].startTime)),null==f?d=null:(g=null,null==d&&(g=If(a,b,e,Math.max(0,f-1))),d=g||If(a,b,e,f)));if(!d)return 1;Jf(a,b,c,e,d);return null}
  2158. function If(a,b,c,d){c=a.b.periods[c];b=b.stream.getSegmentReference(d);if(!b)return null;a=a.b.presentationTimeline;d=a.ua();return c.startTime+b.endTime<a.ma()||c.startTime+b.startTime>d?null:b}
  2159. function Jf(a,b,c,d,e){var f=a.b.periods[d],g=b.stream,h=a.b.periods[d+1],l=null,l=h?h.startTime:a.b.presentationTimeline.Y();d=Kf(a,b,d,l);b.xa=!0;b.cb=!1;h=Lf(a,e);Promise.all([d,h]).then(function(a){if(!this.f&&!this.l)return Mf(this,b,c,f,g,e,a[1])}.bind(a)).then(function(){this.f||this.l||(b.xa=!1,b.Gb=!1,b.ra||this.a.Ab(),Cf(this,b,0),Nf(this,g))}.bind(a))["catch"](function(a){this.f||this.l||(b.xa=!1,this.b.presentationTimeline.$()&&this.g.infiniteRetriesForLiveStreams&&(1001==a.code||1002==
  2160. a.code||1003==a.code)?"text"==b.type&&this.g.ignoreTextStreamFailures&&1001==a.code?delete this.c.text:(a.severity=1,this.a.onError(a),Cf(this,b,4)):3017==a.code?Of(this,b,a):"text"==b.type&&this.g.ignoreTextStreamFailures?delete this.c.text:(b.tb=!0,a.severity=2,this.a.onError(a)))}.bind(a))}function Of(a,b,c){if(!Na(a.c).some(function(a){return a!=b&&a.Gb})){var d=Math.round(100*a.i);if(20<d)a.i-=.2;else if(4<d)a.i-=.04;else{b.tb=!0;a.l=!0;a.a.onError(c);return}b.Gb=!0}Cf(a,b,4)}
  2161. function Kf(a,b,c,d){if(!b.cb)return Promise.resolve();c=Mb(a.a.K,b.type,a.b.periods[c].startTime-b.stream.presentationTimeOffset,d);if(!b.stream.initSegmentReference)return c;a=Lf(a,b.stream.initSegmentReference).then(function(a){if(!this.f)return Jb(this.a.K,b.type,a,null,null)}.bind(a))["catch"](function(a){b.cb=!0;return Promise.reject(a)});return Promise.all([c,a])}
  2162. function Mf(a,b,c,d,e,f,g){e.containsEmsgBoxes&&(new Q).da("emsg",a.Ed.bind(a,d,f)).parse(g);return Pf(a,b,c).then(function(){if(!this.f)return Jb(this.a.K,b.type,g,f.startTime+d.startTime,f.endTime+d.startTime)}.bind(a)).then(function(){if(!this.f)return b.Fa=e,b.ea=f,Promise.resolve()}.bind(a))}
  2163. k.Ed=function(a,b,c){var d=c.s.Db(),e=c.s.Db(),f=c.s.D(),g=c.s.D(),h=c.s.D(),l=c.s.D();c=c.s.Ka(c.s.H.byteLength-c.s.u);a=a.startTime+b.startTime+g/f;if("urn:mpeg:dash:event:2012"==d)this.a.kd();else this.a.onEvent(new I("emsg",{detail:{startTime:a,endTime:a+h/f,schemeIdUri:d,value:e,timescale:f,presentationTimeDelta:g,eventDuration:h,id:l,messageData:c}}))};
  2164. function Pf(a,b,c){var d=Gb(a.a.K,b.type);if(null==d)return Promise.resolve();c=c-d-a.g.bufferBehind;return 0>=c?Promise.resolve():a.a.K.remove(b.type,d,d+c).then(function(){}.bind(a))}function Nf(a,b){if(!a.v&&(a.v=Na(a.c).every(function(a){return"text"==a.type?!0:!a.ra&&!a.sa&&a.ea}),a.v)){var c=ic(a.b,b);a.h[c]||Ff(a,c).then(function(){this.a.ac()}.bind(a))["catch"](y);for(c=0;c<a.b.periods.length;++c)Ff(a,c)["catch"](y);a.a.wd&&a.a.wd()}}
  2165. function Hf(a,b){if(b.wa!=ic(a.b,b.stream)){var c=b.wa,d=Na(a.c);d.every(function(a){return a.wa==c})&&d.every(Qf)&&Ff(a,c).then(function(){if(!this.f&&d.every(function(a){var b=ic(this.b,a.stream);return Qf(a)&&a.wa==c&&b!=c}.bind(this))){var a=this.b.periods[c],b=this.a.bc(a),g;for(g in this.c)if(!b[g]&&"text"!=g){this.a.onError(new t(2,5,5005));return}for(g in b)if(!this.c[g])if("text"==g)uf(this,{text:b.text},a.startTime),delete b[g];else{this.a.onError(new t(2,5,5005));return}for(g in this.c)(a=
  2166. b[g])?(yf(this,g,a,!1),Cf(this,this.c[g],0)):delete this.c[g];this.a.ac()}}.bind(a))["catch"](y)}}function Qf(a){return!a.xa&&null==a.qa&&!a.ra&&!a.sa}function Lf(a,b){var c=C(b.a(),a.g.retryParameters);if(b.X||null!=b.M){var d="bytes="+b.X+"-";null!=b.M&&(d+=b.M);c.headers.Range=d}return a.a.dd.request(1,c).then(function(a){return a.data})}
  2167. function Af(a,b,c){b.ra=!1;b.kb=!1;b.sa=!0;Lb(a.a.K,b.type).then(function(){if(!this.f&&c){var a=this.a.K,e=b.type;return"text"==e?Promise.resolve():Kb(a,e,a.Oc.bind(a,e))}}.bind(a)).then(function(){this.f||(b.Fa=null,b.ea=null,b.sa=!1,b.endOfStream=!1,Cf(this,b,0))}.bind(a))}function Cf(a,b,c){b.qa=window.setTimeout(a.ke.bind(a,b),1E3*c)}function tf(a){null!=a.qa&&(window.clearTimeout(a.qa),a.qa=null)};function Rf(a,b){return new Promise(function(c,d){var e=new XMLHttpRequest;e.open(b.method,a,!0);e.responseType="arraybuffer";e.timeout=b.retryParameters.timeout;e.withCredentials=b.allowCrossSiteCredentials;e.onload=function(b){b=b.target;var e=b.getAllResponseHeaders().split("\r\n").reduce(function(a,b){var c=b.split(": ");a[c[0].toLowerCase()]=c.slice(1).join(": ");return a},{});if(200<=b.status&&299>=b.status&&202!=b.status)b.responseURL&&(a=b.responseURL),c({uri:a,data:b.response,headers:e,fromCache:!!e["x-shaka-from-cache"]});
  2168. else{var f=null;try{f=Ta(b.response)}catch(m){}d(new t(401==b.status||403==b.status?2:1,1,1001,a,b.status,f,e))}};e.onerror=function(){d(new t(1,1,1002,a))};e.ontimeout=function(){d(new t(1,1,1003,a))};for(var f in b.headers)e.setRequestHeader(f,b.headers[f]);e.send(b.body)})}n("shaka.net.HttpPlugin",Rf);Ea.http=Rf;Ea.https=Rf;function Sf(){this.a=null;this.b=[];this.c={}}k=Sf.prototype;k.init=function(a,b){return Tf(this,a,b).then(function(){var b=Object.keys(a);return Promise.all(b.map(function(a){return Uf(this,a).then(function(b){this.c[a]=b}.bind(this))}.bind(this)))}.bind(this))};k.m=function(){return Promise.all(this.b.map(function(a){try{a.transaction.abort()}catch(b){}return a.L["catch"](y)})).then(function(){this.a&&(this.a.close(),this.a=null)}.bind(this))};
  2169. k.get=function(a,b){var c;return Vf(this,a,"readonly",function(a){c=a.get(b)}).then(function(){return c.result})};k.forEach=function(a,b){return Vf(this,a,"readonly",function(a){a.openCursor().onsuccess=function(a){if(a=a.target.result)b(a.value),a["continue"]()}})};function Wf(a,b,c){return Vf(a,b,"readwrite",function(a){a.put(c)})}k.remove=function(a,b){return Vf(this,a,"readwrite",function(a){a["delete"](b)})};
  2170. function Xf(a,b,c){return Vf(a,"segment","readwrite",function(a){for(var d=0;d<b.length;d++)a["delete"](b[d]).onsuccess=c||function(){}})}function Uf(a,b){var c=0;return Vf(a,b,"readonly",function(a){a.openCursor(null,"prev").onsuccess=function(a){(a=a.target.result)&&(c=a.key+1)}}).then(function(){return c})}
  2171. function Vf(a,b,c,d){var e={transaction:a.a.transaction([b],c),L:new A};e.transaction.oncomplete=function(){this.b.splice(this.b.indexOf(e),1);e.L.resolve()}.bind(a);e.transaction.onabort=function(a){this.b.splice(this.b.indexOf(e),1);Yf(e.transaction,e.L,a)}.bind(a);e.transaction.onerror=function(a){a.preventDefault()}.bind(a);b=e.transaction.objectStore(b);d(b);a.b.push(e);return e.L}
  2172. function Tf(a,b,c){var d=window.indexedDB.open("shaka_offline_db",1),e=!1,f=new A;d.onupgradeneeded=function(a){e=!0;a=a.target.result;for(var c in b)a.createObjectStore(c,{keyPath:b[c]})};d.onsuccess=function(a){c&&!e?(a.target.result.close(),setTimeout(function(){Tf(this,b,c-1).then(f.resolve,f.reject)}.bind(this),1E3)):(this.a=a.target.result,f.resolve())}.bind(a);d.onerror=Yf.bind(null,d,f);return f}
  2173. function Yf(a,b,c){a.error?b.reject(new t(2,9,9001,a.error)):b.reject(new t(2,9,9002));c.preventDefault()};var Zf={manifest:"key",segment:"key"};function $f(a){var b=ag(a.periods[0],[],new T(null,0)),c=Zb(b,null,null),b=ac(b,null);c.push.apply(c,b);return{offlineUri:"offline:"+a.key,originalManifestUri:a.originalManifestUri,duration:a.duration,size:a.size,expiration:void 0==a.expiration?Infinity:a.expiration,tracks:c,appMetadata:a.appMetadata}}
  2174. function ag(a,b,c){var d=a.streams.filter(function(a){return"text"==a.contentType}),e=a.streams.filter(function(a){return"audio"==a.contentType}),f=a.streams.filter(function(a){return"video"==a.contentType});b=bg(e,f,b);d=d.map(cg);a.streams.forEach(function(a){a=dg(a);c.Ha(0,a)});return{startTime:a.startTime,variants:b,textStreams:d}}function dg(a){return a.segments.map(function(a,c){return new O(c,a.startTime,a.endTime,function(){return[a.uri]},0,null)})}
  2175. function bg(a,b,c){var d=[];if(!a.length&&!b.length)return d;a.length?b.length||(b=[null]):a=[null];for(var e=0,f=0;f<a.length;f++)for(var g=0;g<b.length;g++)if(eg(a[f],b[g])){var h=a[f];var l=b[g],m=c;h={id:e++,language:h?h.language:"",primary:!!h&&h.primary||!!l&&l.primary,audio:cg(h),video:cg(l),bandwidth:0,drmInfos:m,allowedByApplication:!0,allowedByKeySystem:!0};d.push(h)}return d}
  2176. function eg(a,b){if(!(a&&b&&a.variantIds&&b.variantIds))return!0;for(var c=0;c<a.variantIds.length;c++)if(b.variantIds.some(function(b){return b==a.variantIds[c]}))return!0;return!1}
  2177. function cg(a){if(!a)return null;var b=dg(a),b=new S(b);return{id:a.id,createSegmentIndex:Promise.resolve.bind(Promise),findSegmentPosition:b.find.bind(b),getSegmentReference:b.get.bind(b),initSegmentReference:a.initSegmentUri?new Zc(function(){return[a.initSegmentUri]},0,null):null,presentationTimeOffset:a.presentationTimeOffset,mimeType:a.mimeType,codecs:a.codecs,width:a.width||void 0,height:a.height||void 0,frameRate:a.frameRate||void 0,kind:a.kind,encrypted:a.encrypted,keyId:a.keyId,language:a.language,
  2178. label:a.label||null,type:a.contentType,primary:a.primary,trickModeVideo:null,containsEmsgBoxes:!1,roles:[]}}function fg(){return window.indexedDB?new Sf:null};function gg(a,b,c,d){this.b={};this.l=[];this.o=d;this.j=a;this.v=b;this.A=c;this.i=this.a=null;this.f=this.g=this.h=this.c=0}gg.prototype.m=function(){var a=this.j,b=this.l,c=this.i||Promise.resolve(),c=c.then(function(){return Xf(a,b)});this.b={};this.l=[];this.i=this.a=this.A=this.v=this.j=this.o=null;return c};function hg(a,b,c,d,e){a.b[b]=a.b[b]||[];a.b[b].push({uris:c.a(),X:c.X,M:c.M,Rb:d,Hb:e})}
  2179. function ig(a,b){a.c=0;a.h=0;a.g=0;a.f=0;Na(a.b).forEach(function(a){a.forEach(function(a){null!=a.M?this.c+=a.M-a.X+1:this.g+=a.Rb}.bind(this))}.bind(a));a.a=b;a.a.size=a.c;var c=Na(a.b).map(function(a){var b=0,c=function(){if(!this.o)return Promise.reject(new t(2,9,9002));if(b>=a.length)return Promise.resolve();var d=a[b++];return jg(this,d).then(c)}.bind(this);return c()}.bind(a));a.b={};a.i=Promise.all(c).then(function(){return Wf(this.j,"manifest",b)}.bind(a)).then(function(){this.l=[]}.bind(a));
  2180. return a.i}
  2181. function jg(a,b){var c=C(b.uris,a.A);if(b.X||null!=b.M)c.headers.Range="bytes="+b.X+"-"+(null==b.M?"":b.M);var d;return a.v.request(1,c).then(function(a){if(!this.a)return Promise.reject(new t(2,9,9002));d=a.data.byteLength;this.l.push(b.Hb.key);b.Hb.data=a.data;return Wf(this.j,"segment",b.Hb)}.bind(a)).then(function(){if(!this.a)return Promise.reject(new t(2,9,9002));null==b.M?(this.a.size+=d,this.f+=b.Rb):this.h+=d;var a=(this.h+this.f)/(this.c+this.g),c=$f(this.a);this.o.progressCallback(c,a)}.bind(a))}
  2182. ;function kg(){this.a=-1}k=kg.prototype;k.configure=function(){};k.start=function(a){var b=/^offline:([0-9]+)$/.exec(a);if(!b)return Promise.reject(new t(2,1,9004,a));var c=Number(b[1]),d=fg();this.a=c;return d?d.init(Zf).then(function(){return d.get("manifest",c)}).then(function(a){if(!a)throw new t(2,9,9003,c);return lg(a)}).then(function(a){return d.m().then(function(){return a})},function(a){return d.m().then(function(){throw a;})}):Promise.reject(new t(2,9,9E3))};k.stop=function(){return Promise.resolve()};
  2183. k.update=function(){};k.onExpirationUpdated=function(a,b){var c=fg();c.init(Zf).then(function(){return c.get("manifest",this.a)}.bind(this)).then(function(d){if(d&&!(0>d.sessionIds.indexOf(a))&&(void 0==d.expiration||d.expiration>b))return d.expiration=b,Wf(c,"manifest",d)})["catch"](function(){}).then(function(){return c.m()})};
  2184. function lg(a){var b=new T(null,0);b.pa(a.duration);var c=a.drmInfo?[a.drmInfo]:[];return{presentationTimeline:b,minBufferTime:10,offlineSessionIds:a.sessionIds,periods:a.periods.map(function(a){return ag(a,c,b)})}}Dd["application/x-offline-manifest"]=kg;function mg(a){if(/^offline:([0-9]+)$/.exec(a)){var b={uri:a,data:new ArrayBuffer(0),headers:{"content-type":"application/x-offline-manifest"}};return Promise.resolve(b)}if(b=/^offline:[0-9]+\/[0-9]+\/([0-9]+)$/.exec(a)){var c=Number(b[1]),d=fg();return d?d.init(Zf).then(function(){return d.get("segment",c)}).then(function(b){return d.m().then(function(){if(!b)throw new t(2,9,9003,c);return{uri:a,data:b.data,headers:{}}})}):Promise.reject(new t(2,9,9E3))}return Promise.reject(new t(2,1,9004,a))}
  2185. n("shaka.offline.OfflineScheme",mg);Ea.offline=mg;function ng(){this.a=Promise.resolve();this.b=this.c=this.f=!1;this.i=new Promise(function(a){this.g=a}.bind(this))}ng.prototype.then=function(a){this.a=this.a.then(a).then(function(a){return this.b?(this.g(),Promise.reject(this.h)):Promise.resolve(a)}.bind(this));return this};function og(a){a.f||(a.a=a.a.then(function(a){this.c=!0;return Promise.resolve(a)}.bind(a),function(a){this.c=!0;return this.b?(this.g(),Promise.reject(this.h)):Promise.reject(a)}.bind(a)));a.f=!0;return a.a}
  2186. ng.prototype.cancel=function(a){if(this.c)return Promise.resolve();this.b=!0;this.h=a;return this.i};function W(a,b){p.call(this);this.O=!1;this.f=a;this.A=null;this.l=new D;this.Qb=new H;this.Ya=this.c=this.h=this.a=this.v=this.g=this.Wa=this.ja=this.N=this.j=this.o=null;this.Dc=1E9;this.Va=[];this.ka=!1;this.Za=!0;this.la=this.J=null;this.G={};this.Xa=[];this.B={};this.b=pg(this);this.ob={width:Infinity,height:Infinity};this.i=qg();this.Ua=0;this.ia=this.b.preferredAudioLanguage;this.Ca=this.b.preferredTextLanguage;this.lb=this.mb="";b&&b(this);this.o=new B(this.de.bind(this));this.Wa=rg(this);
  2187. for(var c=0;c<this.f.textTracks.length;++c){var d=this.f.textTracks[c];d.mode="disabled";"Shaka Player TextTrack"==d.label&&(this.A=d)}this.A||(this.A=this.f.addTextTrack("subtitles","Shaka Player TextTrack"));this.A.mode="hidden";E(this.l,this.f,"error",this.yd.bind(this))}ba(W);n("shaka.Player",W);
  2188. W.prototype.m=function(){this.O=!0;var a=Promise.resolve();this.J&&(a=this.J.cancel(new t(2,7,7E3)));return a.then(function(){var a=Promise.all([this.la,sg(this),this.l?this.l.m():null,this.o?this.o.m():null]);this.b=this.o=this.Qb=this.l=this.A=this.f=null;return a}.bind(this))};W.prototype.destroy=W.prototype.m;W.version="v2.1.4";var tg={};W.registerSupportPlugin=function(a,b){tg[a]=b};
  2189. W.isBrowserSupported=function(){return!!window.Promise&&!!window.Uint8Array&&!!Array.prototype.forEach&&!!window.MediaSource&&!!window.MediaSource.isTypeSupported&&!!window.MediaKeys&&!!window.navigator&&!!window.navigator.requestMediaKeySystemAccess&&!!window.MediaKeySystemAccess&&!!window.MediaKeySystemAccess.prototype.getConfiguration};W.probeSupport=function(){return qb().then(function(a){var b=Fd(),c=Eb();a={manifest:b,media:c,drm:a};for(var d in tg)a[d]=tg[d]();return a})};
  2190. W.prototype.load=function(a,b,c){var d=this.hb(),e=new ng;this.J=e;this.dispatchEvent(new I("loading"));var f=Date.now();return og(e.then(function(){return d}).then(function(){this.i=qg();E(this.l,this.f,"playing",this.Sa.bind(this));E(this.l,this.f,"pause",this.Sa.bind(this));E(this.l,this.f,"ended",this.Sa.bind(this));return Gd(a,this.o,this.b.manifest.retryParameters,c)}.bind(this)).then(function(b){this.h=new b;this.h.configure(this.b.manifest);b={networkingEngine:this.o,filterPeriod:this.fb.bind(this),
  2191. onTimelineRegionAdded:this.xd.bind(this),onEvent:this.gb.bind(this),onError:this.ya.bind(this)};return 2<this.h.start.length?this.h.start(a,this.o,b.filterPeriod,b.onError,b.onEvent):this.h.start(a,b)}.bind(this)).then(function(b){if(0==b.periods.length)throw new t(2,4,4014);this.c=b;this.Ya=a;this.j=new bb(this.o,this.ya.bind(this),this.be.bind(this),this.ae.bind(this));this.j.configure(this.b.drm);return this.j.init(b,!1)}.bind(this)).then(function(){this.c.periods.forEach(this.fb.bind(this));this.Ua=
  2192. Date.now()/1E3;this.ia=this.b.preferredAudioLanguage;this.Ca=this.b.preferredTextLanguage;return Promise.all([eb(this.j,this.f),this.Wa])}.bind(this)).then(function(){this.b.abr.manager.init(this.Lb.bind(this));this.g=new ff(this.f,this.c,this.b.streaming,b||null,this.ce.bind(this),this.gb.bind(this));this.v=new of(this.f,this.c,this.b.streaming,this.zc.bind(this),this.gb.bind(this),this.$d.bind(this));this.ja=new Db(this.f,this.N,this.A);this.a=new sf(this.c,{Oa:this.g,K:this.ja,dd:this.o,bc:this.ed.bind(this),
  2193. ac:this.Gc.bind(this),onError:this.ya.bind(this),onEvent:this.gb.bind(this),kd:this.ld.bind(this),Ab:this.ud.bind(this)});this.a.configure(this.b.streaming);ug(this);return this.a.init()}.bind(this)).then(function(){if(this.b.streaming.startAtSegmentBoundary){var a=vg(this,jf(this.g));gf(this.g,a)}this.c.periods.forEach(this.fb.bind(this));wg(this);xg(this);var a=V(this.a),b=dc(a,this.ia);this.b.abr.manager.setVariants(b);a.variants.some(function(a){return a.primary});this.Xa.forEach(this.v.v.bind(this.v));
  2194. this.Xa=[];La(this.l,this.f,"loadeddata",function(){this.i.loadLatency=(Date.now()-f)/1E3}.bind(this));this.J=null}.bind(this)))["catch"](function(a){this.J==e&&(this.J=null,this.dispatchEvent(new I("unloading")));return Promise.reject(a)}.bind(this))};W.prototype.load=W.prototype.load;
  2195. function ug(a){function b(a){return(a.video?a.video.codecs.split(".")[0]:"")+"-"+(a.audio?a.audio.codecs.split(".")[0]:"")}var c={};a.c.periods.forEach(function(a){a.variants.forEach(function(a){var d=b(a);d in c||(c[d]=[]);c[d].push(a)})});var d=null,e=Infinity;Qa(c,function(a,b){var c=0,f=0;b.forEach(function(a){c+=a.bandwidth;++f});var g=c/f;g<e&&(d=a,e=g)});a.c.periods.forEach(function(a){a.variants=a.variants.filter(function(a){return b(a)==d?!0:!1})})}
  2196. function rg(a){a.N=new MediaSource;var b=new A;E(a.l,a.N,"sourceopen",b.resolve);a.f.src=window.URL.createObjectURL(a.N);return b}W.prototype.configure=function(a){a.abr&&a.abr.manager&&a.abr.manager!=this.b.abr.manager&&(this.b.abr.manager.stop(),a.abr.manager.init(this.Lb.bind(this)));Ca(this.b,a,pg(this),yg(),"");zg(this)};W.prototype.configure=W.prototype.configure;
  2197. function zg(a){a.h&&a.h.configure(a.b.manifest);a.j&&a.j.configure(a.b.drm);if(a.a){a.a.configure(a.b.streaming);try{a.c.periods.forEach(a.fb.bind(a))}catch(b){a.ya(b)}Ag(a,V(a.a))}a.b.abr.enabled&&!a.Za?a.b.abr.manager.enable():a.b.abr.manager.disable();a.b.abr.manager.setDefaultEstimate(a.b.abr.defaultBandwidthEstimate);a.b.abr.manager.setRestrictions(a.b.abr.restrictions)}W.prototype.getConfiguration=function(){var a=pg(this);Ca(a,this.b,pg(this),yg(),"");return a};
  2198. W.prototype.getConfiguration=W.prototype.getConfiguration;W.prototype.Rd=function(){var a=pg(this);a.abr&&a.abr.manager&&a.abr.manager!=this.b.abr.manager&&(this.b.abr.manager.stop(),a.abr.manager.init(this.Lb.bind(this)));this.b=pg(this);zg(this)};W.prototype.resetConfiguration=W.prototype.Rd;W.prototype.Sc=function(){return this.f};W.prototype.getMediaElement=W.prototype.Sc;W.prototype.Wb=function(){return this.o};W.prototype.getNetworkingEngine=W.prototype.Wb;W.prototype.Rc=function(){return this.Ya};
  2199. W.prototype.getManifestUri=W.prototype.Rc;W.prototype.$=function(){return this.c?this.c.presentationTimeline.$():!1};W.prototype.isLive=W.prototype.$;W.prototype.va=function(){return this.c?this.c.presentationTimeline.va():!1};W.prototype.isInProgress=W.prototype.va;W.prototype.Td=function(){var a=0,b=0;this.c&&(b=this.c.presentationTimeline,a=b.ma(),b=b.bb());return{start:a,end:b}};W.prototype.seekRange=W.prototype.Td;W.prototype.keySystem=function(){return this.j?this.j.keySystem():""};
  2200. W.prototype.keySystem=W.prototype.keySystem;W.prototype.drmInfo=function(){return this.j?this.j.b:null};W.prototype.drmInfo=W.prototype.drmInfo;W.prototype.ab=function(){return this.j?this.j.ab():Infinity};W.prototype.getExpiration=W.prototype.ab;W.prototype.$c=function(){return this.ka};W.prototype.isBuffering=W.prototype.$c;
  2201. W.prototype.hb=function(){if(this.O)return Promise.resolve();this.dispatchEvent(new I("unloading"));var a=Promise.resolve();this.J&&(a=this.J.cancel(new t(2,7,7E3)));return a.then(function(){this.la||(this.la=Bg(this).then(function(){this.la=null}.bind(this)));return this.la}.bind(this))};W.prototype.unload=W.prototype.hb;W.prototype.rb=function(){return this.g?this.g.rb():0};W.prototype.getPlaybackRate=W.prototype.rb;W.prototype.ne=function(a){this.g&&lf(this.g,a);this.a&&xf(this.a,1!=a)};
  2202. W.prototype.trickPlay=W.prototype.ne;W.prototype.Hc=function(){this.g&&lf(this.g,1);this.a&&xf(this.a,!1)};W.prototype.cancelTrickPlay=W.prototype.Hc;W.prototype.getTracks=function(){return this.Yb().concat(this.Xb())};W.prototype.getTracks=W.prototype.getTracks;W.prototype.Wd=function(a,b){"text"==a.type?this.tc(a):(this.configure({abr:{enabled:!1}}),this.uc(a,b))};W.prototype.selectTrack=W.prototype.Wd;
  2203. W.prototype.Yb=function(){if(!this.c)return[];var a=hc(this.c,jf(this.g)),b=this.B[a]||{};return Zb(this.c.periods[a],b.audio,b.video)};W.prototype.getVariantTracks=W.prototype.Yb;W.prototype.Xb=function(){if(!this.c)return[];var a=hc(this.c,jf(this.g));return ac(this.c.periods[a],(this.B[a]||{}).text).filter(function(a){return 0>this.Va.indexOf(a.id)}.bind(this))};W.prototype.getTextTracks=W.prototype.Xb;
  2204. W.prototype.tc=function(a){if(this.a&&(a=cc(V(this.a),a))){Cg(this,a,!1);var b={};b.text=a;Dg(this,b,!0)}};W.prototype.selectTextTrack=W.prototype.tc;
  2205. W.prototype.uc=function(a,b){if(this.a){var c={},d=bc(V(this.a),a),e=vf(this.a);if(d){if(!d.allowedByApplication||!d.allowedByKeySystem)return;d.audio&&(Eg(this,d.audio),d.audio!=e.audio&&(c.audio=d.audio));d.video&&(Eg(this,d.video),d.video!=e.video&&(c.video=d.video))}Na(c).forEach(function(a){Cg(this,a,!1)}.bind(this));(d=e.text)&&(c.text=d);Dg(this,c,b)}};W.prototype.selectVariantTrack=W.prototype.uc;
  2206. W.prototype.Pc=function(){return this.a?$b(V(this.a).variants).map(function(a){return a.language}).filter(Aa):[]};W.prototype.getAudioLanguages=W.prototype.Pc;W.prototype.Yc=function(){return this.a?V(this.a).textStreams.map(function(a){return a.language}).filter(Aa):[]};W.prototype.getTextLanguages=W.prototype.Yc;W.prototype.Ud=function(a,b){if(this.a){var c=V(this.a);this.ia=a;this.mb=b||"";Ag(this,c)}};W.prototype.selectAudioLanguage=W.prototype.Ud;
  2207. W.prototype.Vd=function(a,b){if(this.a){var c=V(this.a);this.Ca=a;this.lb=b||"";Ag(this,c)}};W.prototype.selectTextLanguage=W.prototype.Vd;W.prototype.bd=function(){return"showing"==this.A.mode};W.prototype.isTextTrackVisible=W.prototype.bd;W.prototype.Yd=function(a){this.A.mode=a?"showing":"hidden";Fg(this)};W.prototype.setTextTrackVisibility=W.prototype.Yd;W.prototype.Uc=function(){return this.c?new Date(1E3*this.c.presentationTimeline.f+1E3*this.f.currentTime):null};
  2208. W.prototype.getPlayheadTimeAsDate=W.prototype.Uc;
  2209. W.prototype.getStats=function(){Gg(this);this.Sa();var a=null,b=null,c=this.f&&this.f.getVideoPlaybackQuality?this.f.getVideoPlaybackQuality():{};this.g&&this.c&&(a=hc(this.c,jf(this.g)),b=this.B[a],b=gc(b.audio,b.video,this.c.periods[a].variants),a=b.video||{});a||(a={});b||(b={});return{width:a.width||0,height:a.height||0,streamBandwidth:b.bandwidth||0,decodedFrames:Number(c.totalVideoFrames),droppedFrames:Number(c.droppedVideoFrames),estimatedBandwidth:this.b.abr.manager.getBandwidthEstimate(),loadLatency:this.i.loadLatency,
  2210. playTime:this.i.playTime,bufferingTime:this.i.bufferingTime,switchHistory:Da(this.i.switchHistory),stateHistory:Da(this.i.stateHistory)}};W.prototype.getStats=W.prototype.getStats;
  2211. W.prototype.addTextTrack=function(a,b,c,d,e,f){if(!this.a)return Promise.reject();for(var g=V(this.a),h,l=0;l<this.c.periods.length;l++)if(this.c.periods[l]==g){if(l==this.c.periods.length-1){if(h=this.c.presentationTimeline.Y()-g.startTime,Infinity==h)return Promise.reject()}else h=this.c.periods[l+1].startTime-g.startTime;break}var m={id:this.Dc++,createSegmentIndex:Promise.resolve.bind(Promise),findSegmentPosition:function(){return 1},getSegmentReference:function(b){return 1!=b?null:new O(1,0,
  2212. h,function(){return[a]},0,null)},initSegmentReference:null,presentationTimeOffset:0,mimeType:d,codecs:e||"",kind:c,encrypted:!1,keyId:null,language:b,label:f||null,type:"text",primary:!1,trickModeVideo:null,containsEmsgBoxes:!1,roles:[]};this.Va.push(m.id);g.textStreams.push(m);return wf(this.a,m).then(function(){if(!this.O){var a=this.c.periods.indexOf(g),d=vf(this.a);d.text&&(this.B[a].text=d.text.id);this.Va.splice(this.Va.indexOf(m.id),1);Ag(this,g);wg(this);return{id:m.id,active:!1,type:"text",
  2213. bandwidth:0,language:b,label:f||null,kind:c,width:null,height:null}}}.bind(this))};W.prototype.addTextTrack=W.prototype.addTextTrack;W.prototype.Jb=function(a,b){this.ob.width=a;this.ob.height=b};W.prototype.setMaxHardwareResolution=W.prototype.Jb;function Cg(a,b,c){a.i.switchHistory.push({timestamp:Date.now()/1E3,id:b.id,type:b.type,fromAdaptation:c});Eg(a,b)}function Eg(a,b){var c=ic(a.c,b);a.B[c]||(a.B[c]={});a.B[c][b.type]=b.id}
  2214. function sg(a){a.l&&(a.l.ha(a.N,"sourceopen"),a.l.ha(a.f,"loadeddata"),a.l.ha(a.f,"playing"),a.l.ha(a.f,"pause"),a.l.ha(a.f,"ended"));a.f&&(a.f.removeAttribute("src"),a.f.load());var b=Promise.all([a.b?a.b.abr.manager.stop():null,a.j?a.j.m():null,a.ja?a.ja.m():null,a.g?a.g.m():null,a.v?a.v.m():null,a.a?a.a.m():null,a.h?a.h.stop():null]);a.j=null;a.ja=null;a.g=null;a.v=null;a.a=null;a.h=null;a.c=null;a.Ya=null;a.Wa=null;a.N=null;a.Xa=[];a.B={};a.G={};a.i=qg();return b}
  2215. function Bg(a){return a.h?sg(a).then(function(){this.O||(this.zc(!1),this.Wa=rg(this))}.bind(a)):Promise.resolve()}function yg(){return{".drm.servers":"",".drm.clearKeys":"",".drm.advanced":{distinctiveIdentifierRequired:!1,persistentStateRequired:!1,videoRobustness:"",audioRobustness:"",serverCertificate:null}}}
  2216. function pg(a){return{drm:{retryParameters:Fa(),servers:{},clearKeys:{},advanced:{},delayLicenseRequestUntilPlayed:!1},manifest:{retryParameters:Fa(),dash:{customScheme:function(a){if(a)return null},clockSyncUri:"",ignoreDrmInfo:!1},hls:{defaultTimeOffset:0}},streaming:{retryParameters:Fa(),infiniteRetriesForLiveStreams:!0,rebufferingGoal:2,bufferingGoal:10,bufferBehind:30,ignoreTextStreamFailures:!1,startAtSegmentBoundary:!1,smallGapLimit:.5,jumpLargeGaps:!1},abr:{manager:a.Qb,enabled:!0,defaultBandwidthEstimate:5E5,
  2217. restrictions:{minWidth:0,maxWidth:Infinity,minHeight:0,maxHeight:Infinity,minPixels:0,maxPixels:Infinity,minBandwidth:0,maxBandwidth:Infinity}},preferredAudioLanguage:"",preferredTextLanguage:"",restrictions:{minWidth:0,maxWidth:Infinity,minHeight:0,maxHeight:Infinity,minPixels:0,maxPixels:Infinity,minBandwidth:0,maxBandwidth:Infinity}}}
  2218. function qg(){return{width:NaN,height:NaN,streamBandwidth:NaN,decodedFrames:NaN,droppedFrames:NaN,estimatedBandwidth:NaN,loadLatency:NaN,playTime:0,bufferingTime:0,switchHistory:[],stateHistory:[]}}k=W.prototype;k.fb=function(a){var b=this.a?vf(this.a):{};Wb(this.j,b,a);b=0<$b(a.variants).length;Vb(a,this.b.restrictions,this.ob)&&this.a&&V(this.a)==a&&wg(this);a=1>$b(a.variants).length;if(!b)throw new t(2,4,4011);if(a)throw new t(2,4,4012);};
  2219. function Dg(a,b,c){for(var d in b){var e=b[d],f=c||!1;"text"==d&&(f=!0);a.Za?a.G[d]={stream:e,Kc:f}:yf(a.a,d,e,f)}}function Gg(a){if(a.c){var b=Date.now()/1E3;a.ka?a.i.bufferingTime+=b-a.Ua:a.i.playTime+=b-a.Ua;a.Ua=b}}
  2220. function vg(a,b){function c(a,b){if(!a)return null;var c=a.findSegmentPosition(b-e.startTime);return null==c?null:(c=a.getSegmentReference(c))?c.startTime+e.startTime:null}var d=vf(a.a),e=V(a.a),f=c(d.video,b),d=c(d.audio,b);return null!=f&&null!=d?Math.max(f,d):null!=f?f:null!=d?d:b}k.de=function(a,b){this.b.abr.manager.segmentDownloaded(a,b)};k.zc=function(a){Gg(this);this.ka=a;this.Sa();if(this.g){var b=this.g;a!=b.h&&(b.h=a,lf(b,b.g))}this.dispatchEvent(new I("buffering",{buffering:a}))};
  2221. k.$d=function(){wg(this)};k.Sa=function(){if(!this.O){var a=this.ka?"buffering":this.f.ended?"ended":this.f.paused?"paused":"playing";var b=Date.now()/1E3;if(this.i.stateHistory.length){var c=this.i.stateHistory[this.i.stateHistory.length-1];c.duration=b-c.timestamp;if(a==c.state)return}this.i.stateHistory.push({timestamp:b,state:a,duration:0})}};k.ce=function(){if(this.v){var a=this.v;a.c.forEach(a.o.bind(a,!0))}this.a&&Bf(this.a)};
  2222. function Hg(a,b,c,d,e){if(!c||1>c.length)return a.ya(new t(2,4,4012)),{};a.b.abr.manager.setVariants(c);a.b.abr.manager.setTextStreams(d);var f=[];e&&(f=["video","audio"],b.textStreams.length&&f.push("text"));e=vf(a.a);var g=a.a;var h=g.c.video||g.c.audio;g=h?g.b.periods[h.wa]:null;if(b=fc(e.audio,e.video,g?g.variants:b.variants)){b.allowedByApplication&&b.allowedByKeySystem||(f.push("audio"),f.push("video"));for(var l in e)b=e[l],"audio"==b.type&&b.language!=c[0].language?f.push(l):"text"==b.type&&
  2223. 0<d.length&&b.language!=d[0].language&&f.push(l)}f=f.filter(Aa);if(0<f.length){c={};try{c=a.b.abr.manager.chooseStreams(f)}catch(m){a.ya(m)}return c}return{}}function Ag(a,b){var c={audio:!1,text:!1},d=dc(b,a.ia,c,a.mb),e=ec(b,a.Ca,c,a.lb),d=Hg(a,b,d,e),f;for(f in d)Cg(a,d[f],!0);Dg(a,d,!0);xg(a);d.text&&d.audio&&c.text&&d.text.language!=d.audio.language&&(a.A.mode="showing",Fg(a))}
  2224. k.ed=function(a){this.Za=!0;this.b.abr.manager.disable();var b=dc(a,this.ia,void 0,this.mb),c=ec(a,this.Ca,void 0,this.lb);a=Hg(this,a,b,c,!0);for(var d in this.G)a[d]=this.G[d].stream;this.G={};for(d in a)Cg(this,a[d],!0);return a};k.Gc=function(){this.Za=!1;this.b.abr.enabled&&this.b.abr.manager.enable();for(var a in this.G){var b=this.G[a];yf(this.a,a,b.stream,b.Kc)}this.G={}};k.ld=function(){this.h&&this.h.update&&this.h.update()};k.ud=function(){this.g&&this.g.Ab()};
  2225. k.Lb=function(a,b){var c=vf(this.a),d;for(d in a){var e=a[d];c[d]!=e?Cg(this,e,!0):delete a[d]}if(!Ma(a)&&this.a){for(d in a)yf(this.a,d,a[d],b||!1);xg(this)}};function xg(a){Promise.resolve().then(function(){this.O||this.dispatchEvent(new I("adaptation"))}.bind(a))}function wg(a){Promise.resolve().then(function(){this.O||this.dispatchEvent(new I("trackschanged"))}.bind(a))}function Fg(a){a.dispatchEvent(new I("texttrackvisibility"))}k.ya=function(a){this.O||this.dispatchEvent(new I("error",{detail:a}))};
  2226. k.xd=function(a){this.v?this.v.v(a):this.Xa.push(a)};k.gb=function(a){this.dispatchEvent(a)};k.yd=function(){if(this.f.error){var a=this.f.error.code;if(1!=a){var b=this.f.error.msExtendedCode;b&&(0>b&&(b+=Math.pow(2,32)),b=b.toString(16));this.ya(new t(2,3,3016,a,b))}}};
  2227. k.be=function(a){var b=["output-restricted","internal-error"],c=V(this.a),d=!1;c.variants.forEach(function(c){var e=[];c.audio&&e.push(c.audio);c.video&&e.push(c.video);e.forEach(function(e){var f=c.allowedByKeySystem;e.keyId&&(e=a[e.keyId],c.allowedByKeySystem=!!e&&0>b.indexOf(e));f!=c.allowedByKeySystem&&(d=!0)})});var e=vf(this.a);(e=fc(e.audio,e.video,c.variants))&&!e.allowedByKeySystem&&Ag(this,c);d&&wg(this)};
  2228. k.ae=function(a,b){if(this.h&&this.h.onExpirationUpdated)this.h.onExpirationUpdated(a,b);this.dispatchEvent(new I("expirationupdated"))};function X(a){if(!a||a.constructor!=W)throw new t(2,9,9008);this.a=fg();this.f=a;this.i=Ig(this);this.b=null;this.v=!1;this.j=null;this.g=-1;this.l=0;this.c=null;this.h=new gg(this.a,a.o,a.getConfiguration().streaming.retryParameters,this.i)}n("shaka.offline.Storage",X);function Jg(){return!!window.indexedDB}X.support=Jg;X.prototype.m=function(){var a=this.a,b=this.h?this.h.m()["catch"](function(){}).then(function(){if(a)return a.m()}):Promise.resolve();this.i=this.f=this.h=this.a=null;return b};
  2229. X.prototype.destroy=X.prototype.m;X.prototype.configure=function(a){Ca(this.i,a,Ig(this),{},"")};X.prototype.configure=X.prototype.configure;
  2230. X.prototype.le=function(a,b,c){function d(a){f=a}if(this.v)return Promise.reject(new t(2,9,9006));this.v=!0;var e,f=null;return Kg(this).then(function(){Y(this);return Lg(this,a,d,c)}.bind(this)).then(function(c){Y(this);this.c=c.manifest;this.b=c.Lc;if(this.c.presentationTimeline.$()||this.c.presentationTimeline.va())throw new t(2,9,9005,a);this.c.periods.forEach(this.o.bind(this));this.g=this.a.c.manifest++;this.l=0;c=this.c.periods.map(this.B.bind(this));var d=this.b.b,f=jb(this.b);if(d){if(!f.length)throw new t(2,
  2231. 9,9007,a);d.initData=[]}e={key:this.g,originalManifestUri:a,duration:this.l,size:0,expiration:this.b.ab(),periods:c,sessionIds:f,drmInfo:d,appMetadata:b};return ig(this.h,e)}.bind(this)).then(function(){Y(this);if(f)throw f;return Mg(this)}.bind(this)).then(function(){return $f(e)}.bind(this))["catch"](function(a){return Mg(this)["catch"](y).then(function(){throw a;})}.bind(this))};X.prototype.store=X.prototype.le;
  2232. X.prototype.remove=function(a){function b(a){6013!=a.code&&(e=a)}var c=a.offlineUri,d=/^offline:([0-9]+)$/.exec(c);if(!d)return Promise.reject(new t(2,9,9004,c));var e=null,f,g,h=Number(d[1]);return Kg(this).then(function(){Y(this);return this.a.get("manifest",h)}.bind(this)).then(function(a){Y(this);if(!a)throw new t(2,9,9003,c);f=a;a=lg(f);g=new bb(this.f.o,b,function(){},function(){});g.configure(this.f.getConfiguration().drm);return g.init(a,!0)}.bind(this)).then(function(){return gb(g,f.sessionIds)}.bind(this)).then(function(){return g.m()}.bind(this)).then(function(){Y(this);
  2233. if(e)throw e;var b=f.periods.map(function(a){return a.streams.map(function(a){var b=a.segments.map(function(a){a=/^offline:[0-9]+\/[0-9]+\/([0-9]+)$/.exec(a.uri);return Number(a[1])});a.initSegmentUri&&(a=/^offline:[0-9]+\/[0-9]+\/([0-9]+)$/.exec(a.initSegmentUri),b.push(Number(a[1])));return b}).reduce(x,[])}).reduce(x,[]),c=0,d=b.length,g=this.i.progressCallback;return Xf(this.a,b,function(){c++;g(a,c/d)})}.bind(this)).then(function(){Y(this);this.i.progressCallback(a,1);return this.a.remove("manifest",
  2234. h)}.bind(this))};X.prototype.remove=X.prototype.remove;X.prototype.list=function(){var a=[];return Kg(this).then(function(){Y(this);return this.a.forEach("manifest",function(b){a.push($f(b))})}.bind(this)).then(function(){return a})};X.prototype.list=X.prototype.list;
  2235. function Lg(a,b,c,d){function e(){}var f=a.f.o,g=a.f.getConfiguration(),h,l,m;return Gd(b,f,g.manifest.retryParameters,d).then(function(a){Y(this);m=new a;m.configure(g.manifest);return m.start(b,{networkingEngine:f,filterPeriod:this.o.bind(this),onTimelineRegionAdded:function(){},onEvent:function(){},onError:c})}.bind(a)).then(function(a){Y(this);h=a;l=new bb(f,c,e,function(){});l.configure(g.drm);return l.init(h,!0)}.bind(a)).then(function(){Y(this);return Ng(h)}.bind(a)).then(function(){Y(this);
  2236. return fb(l)}.bind(a)).then(function(){Y(this);return m.stop()}.bind(a)).then(function(){Y(this);return{manifest:h,Lc:l}}.bind(a))["catch"](function(a){if(m)return m.stop().then(function(){throw a;});throw a;})}
  2237. X.prototype.A=function(a){for(var b=[],c=Sb(this.f.getConfiguration().preferredAudioLanguage),d=[0,Qb,Rb],e=a.filter(function(a){return"variant"==a.type}),d=d.map(function(a){return e.filter(function(b){b=Sb(b.language);return Pb(a,c,b)})}),f,g=0;g<d.length;g++)if(d[g].length){f=d[g];break}f||(d=e.filter(function(a){return a.primary}),d.length&&(f=d));f||(f=e,e.map(function(a){return a.language}).filter(Aa));var h=f.filter(function(a){return a.height&&480>=a.height});h.length&&(h.sort(function(a,
  2238. b){return b.height-a.height}),f=h.filter(function(a){return a.height==h[0].height}));f.sort(function(a,b){return a.bandwidth-b.bandwidth});f.length&&b.push(f[Math.floor(f.length/2)]);b.push.apply(b,a.filter(function(a){return"text"==a.type}));return b};function Ig(a){return{trackSelectionCallback:a.A.bind(a),progressCallback:function(a,c){if(a||c)return null}}}function Kg(a){return a.a?a.a.a?Promise.resolve():a.a.init(Zf):Promise.reject(new t(2,9,9E3))}
  2239. X.prototype.o=function(a){var b={};if(this.j){var c=this.j.filter(function(a){return"variant"==a.type}),d=null;c.length&&(d=bc(a,c[0]));d&&(d.video&&(b.video=d.video),d.audio&&(b.audio=d.audio))}Wb(this.b,b,a);Vb(a,this.f.getConfiguration().restrictions,{width:Infinity,height:Infinity})};function Mg(a){var b=a.b?a.b.m():Promise.resolve();a.b=null;a.c=null;a.v=!1;a.j=null;a.g=-1;return b}
  2240. function Ng(a){var b=a.periods.map(function(a){return a.variants}).reduce(x,[]).map(function(a){var b=[];a.audio&&b.push(a.audio);a.video&&b.push(a.video);return b}).reduce(x,[]).filter(Aa);a=a.periods.map(function(a){return a.textStreams}).reduce(x,[]);b.push.apply(b,a);return Promise.all(b.map(function(a){return a.createSegmentIndex()}))}
  2241. X.prototype.B=function(a){var b,c,d=Zb(a,null,null),e=ac(a,null),d=this.i.trackSelectionCallback(d.concat(e));this.j||(this.j=d,this.c.periods.forEach(this.o.bind(this)));for(e=d.length-1;0<e;--e){var f=!1;for(c=e-1;0<=c;--c)if(d[e].type==d[c].type&&d[e].kind==d[c].kind&&d[e].language==d[c].language){f=!0;break}if(f)break}f=[];for(e=0;e<d.length;e++)(b=bc(a,d[e]))?(b.audio&&((c=f.filter(function(a){return a.id==b.audio.id})[0])?c.variantIds.push(b.id):(c=b.video?b.bandwidth/2:b.bandwidth,f.push(Og(this,
  2242. a,b.audio,c,b.id)))),b.video&&((c=f.filter(function(a){return a.id==b.video.id})[0])?c.variantIds.push(b.id):(c=b.audio?b.bandwidth/2:b.bandwidth,f.push(Og(this,a,b.video,c,b.id))))):f.push(Og(this,a,cc(a,d[e]),0));return{startTime:a.startTime,streams:f}};
  2243. function Og(a,b,c,d,e){var f=[],g=a.c.presentationTimeline.ma();var h=g;for(var l=c.findSegmentPosition(g),m=null!=l?c.getSegmentReference(l):null;m;)h=a.a.c.segment++,hg(a.h,c.type,m,(m.endTime-m.startTime)*d/8,{key:h,data:null,manifestKey:a.g,streamNumber:c.id,segmentNumber:h}),f.push({startTime:m.startTime,endTime:m.endTime,uri:"offline:"+a.g+"/"+c.id+"/"+h}),h=m.endTime+b.startTime,m=c.getSegmentReference(++l);a.l=Math.max(a.l,h-g);b=null;c.initSegmentReference&&(h=a.a.c.segment++,b="offline:"+
  2244. a.g+"/"+c.id+"/"+h,hg(a.h,c.contentType,c.initSegmentReference,0,{key:h,data:null,manifestKey:a.g,streamNumber:c.id,segmentNumber:-1}));a=[];null!=e&&a.push(e);return{id:c.id,primary:c.primary,presentationTimeOffset:c.presentationTimeOffset||0,contentType:c.type,mimeType:c.mimeType,codecs:c.codecs,frameRate:c.frameRate,kind:c.kind,language:c.language,label:c.label,width:c.width||null,height:c.height||null,initSegmentUri:b,encrypted:c.encrypted,keyId:c.keyId,segments:f,variantIds:a}}
  2245. function Y(a){if(!a.f)throw new t(2,9,9002);}tg.offline=Jg;n("shaka.polyfill.installAll",function(){for(var a=0;a<Pg.length;++a)Pg[a]()});var Pg=[];function Qg(a){Pg.push(a)}n("shaka.polyfill.register",Qg);function Rg(a){var b=a.type.replace(/^(webkit|moz|MS)/,"").toLowerCase();if("function"===typeof Event)var c=new Event(b,a);else c=document.createEvent("Event"),c.initEvent(b,a.bubbles,a.cancelable);a.target.dispatchEvent(c)}
  2246. Qg(function(){if(window.Document){var a=Element.prototype;a.requestFullscreen=a.requestFullscreen||a.mozRequestFullScreen||a.msRequestFullscreen||a.webkitRequestFullscreen;a=Document.prototype;a.exitFullscreen=a.exitFullscreen||a.mozCancelFullScreen||a.msExitFullscreen||a.webkitExitFullscreen;"fullscreenElement"in document||(Object.defineProperty(document,"fullscreenElement",{get:function(){return document.mozFullScreenElement||document.msFullscreenElement||document.webkitFullscreenElement}}),Object.defineProperty(document,
  2247. "fullscreenEnabled",{get:function(){return document.mozFullScreenEnabled||document.msFullscreenEnabled||document.webkitFullscreenEnabled}}));document.addEventListener("webkitfullscreenchange",Rg);document.addEventListener("webkitfullscreenerror",Rg);document.addEventListener("mozfullscreenchange",Rg);document.addEventListener("mozfullscreenerror",Rg);document.addEventListener("MSFullscreenChange",Rg);document.addEventListener("MSFullscreenError",Rg)}});Qg(function(){var a=navigator.userAgent;a&&0<=a.indexOf("CrKey")&&delete window.indexedDB});Qg(function(){if(4503599627370497!=Math.round(4503599627370497)){var a=Math.round;Math.round=function(b){var c=b;4503599627370496>=b&&(c=a(b));return c}}});function Sg(a){this.f=[];this.b=[];this.a=[];(new Q).da("pssh",this.c.bind(this)).parse(a.buffer)}Sg.prototype.c=function(a){if(!(1<a.version)){var b=$a(a.s.Ka(16)),c=[];if(0<a.version)for(var d=a.s.D(),e=0;e<d;++e){var f=$a(a.s.Ka(16));c.push(f)}d=a.s.D();a.s.I(d);this.b.push.apply(this.b,c);this.f.push(b);this.a.push({start:a.start,end:a.start+a.size-1})}};function Tg(a,b){try{var c=new Ug(a,b);return Promise.resolve(c)}catch(d){return Promise.reject(d)}}
  2248. function Ug(a,b){this.keySystem=a;for(var c=!1,d=0;d<b.length;++d){var e=b[d];var f={audioCapabilities:[],videoCapabilities:[],persistentState:"optional",distinctiveIdentifier:"optional",initDataTypes:e.initDataTypes,sessionTypes:["temporary"],label:e.label},g=!1;if(e.audioCapabilities)for(var h=0;h<e.audioCapabilities.length;++h){var l=e.audioCapabilities[h];if(l.contentType){g=!0;var m=l.contentType.split(";")[0];MSMediaKeys.isTypeSupported(this.keySystem,m)&&(f.audioCapabilities.push(l),c=!0)}}if(e.videoCapabilities)for(h=
  2249. 0;h<e.videoCapabilities.length;++h)l=e.videoCapabilities[h],l.contentType&&(g=!0,m=l.contentType.split(";")[0],MSMediaKeys.isTypeSupported(this.keySystem,m)&&(f.videoCapabilities.push(l),c=!0));g||(c=MSMediaKeys.isTypeSupported(this.keySystem,"video/mp4"));"required"==e.persistentState&&(f.persistentState="required",f.sessionTypes=["persistent-license"]);if(c){this.a=f;return}}e=Error("Unsupported keySystem");e.name="NotSupportedError";e.code=DOMException.NOT_SUPPORTED_ERR;throw e;}
  2250. Ug.prototype.createMediaKeys=function(){var a=new Vg(this.keySystem);return Promise.resolve(a)};Ug.prototype.getConfiguration=function(){return this.a};function Wg(a){var b=this.mediaKeys;b&&b!=a&&Xg(b,null);delete this.mediaKeys;return(this.mediaKeys=a)?Xg(a,this):Promise.resolve()}function Vg(a){this.a=new MSMediaKeys(a);this.b=new D}Vg.prototype.createSession=function(a){if("temporary"!=(a||"temporary"))throw new TypeError("Session type "+a+" is unsupported on this platform.");return new Yg(this.a)};
  2251. Vg.prototype.setServerCertificate=function(){return Promise.resolve(!1)};function Xg(a,b){function c(){b.msSetMediaKeys(d.a);b.removeEventListener("loadedmetadata",c)}Ja(a.b);if(!b)return Promise.resolve();E(a.b,b,"msneedkey",Zg);var d=a;try{return 1<=b.readyState?b.msSetMediaKeys(a.a):b.addEventListener("loadedmetadata",c),Promise.resolve()}catch(e){return Promise.reject(e)}}
  2252. function Yg(a){p.call(this);this.c=null;this.g=a;this.b=this.a=null;this.f=new D;this.sessionId="";this.expiration=NaN;this.closed=new A;this.keyStatuses=new $g}ba(Yg);k=Yg.prototype;k.generateRequest=function(a,b){this.a=new A;try{this.c=this.g.createSession("video/mp4",new Uint8Array(b),null),E(this.f,this.c,"mskeymessage",this.pd.bind(this)),E(this.f,this.c,"mskeyadded",this.nd.bind(this)),E(this.f,this.c,"mskeyerror",this.od.bind(this)),ah(this,"status-pending")}catch(c){this.a.reject(c)}return this.a};
  2253. k.load=function(){return Promise.reject(Error("MediaKeySession.load not yet supported"))};k.update=function(a){this.b=new A;try{this.c.update(new Uint8Array(a))}catch(b){this.b.reject(b)}return this.b};k.close=function(){try{this.c.close(),this.closed.resolve(),Ja(this.f)}catch(a){this.closed.reject(a)}return this.closed};k.remove=function(){return Promise.reject(Error("MediaKeySession.remove is only applicable for persistent licenses, which are not supported on this platform"))};
  2254. function Zg(a){var b=document.createEvent("CustomEvent");b.initCustomEvent("encrypted",!1,!1,null);b.initDataType="cenc";var c=a.initData;if(c){var d=new Sg(c);if(1>=d.a.length)a=c;else{var e=[];for(a=0;a<d.a.length;a++)e.push(c.subarray(d.a[a].start,d.a[a].end+1));c=Ga(e,bh);for(a=d=0;a<c.length;a++)d+=c[a].length;d=new Uint8Array(d);for(a=e=0;a<c.length;a++)d.set(c[a],e),e+=c[a].length;a=d}}else a=c;b.initData=a;this.dispatchEvent(b)}function bh(a,b){return ab(a,b)}
  2255. k.pd=function(a){this.a&&(this.a.resolve(),this.a=null);this.dispatchEvent(new I("message",{messageType:void 0==this.keyStatuses.sb()?"licenserequest":"licenserenewal",message:a.message.buffer}))};k.nd=function(){this.a?(ah(this,"usable"),this.a.resolve(),this.a=null):this.b&&(ah(this,"usable"),this.b.resolve(),this.b=null)};
  2256. k.od=function(){var a=Error("EME PatchedMediaKeysMs key error");a.errorCode=this.c.error;if(this.a)this.a.reject(a),this.a=null;else if(this.b)this.b.reject(a),this.b=null;else switch(this.c.error.code){case MSMediaKeyError.MS_MEDIA_KEYERR_OUTPUT:case MSMediaKeyError.MS_MEDIA_KEYERR_HARDWARECHANGE:ah(this,"output-not-allowed");default:ah(this,"internal-error")}};function ah(a,b){a.keyStatuses.Kb(b);a.dispatchEvent(new I("keystatuseschange"))}function $g(){this.size=0;this.a=void 0}var ch;k=$g.prototype;
  2257. k.Kb=function(a){this.size=void 0==a?0:1;this.a=a};k.sb=function(){return this.a};k.forEach=function(a){this.a&&a(this.a,ch)};k.get=function(a){if(this.has(a))return this.a};k.has=function(a){var b=ch;return this.a&&ab(new Uint8Array(a),new Uint8Array(b))?!0:!1};k.entries=function(){};k.keys=function(){};k.values=function(){};function dh(){return Promise.reject(Error("The key system specified is not supported."))}function eh(a){return a?Promise.reject(Error("MediaKeys not supported.")):Promise.resolve()}function fh(){throw new TypeError("Illegal constructor.");}fh.prototype.createSession=function(){};fh.prototype.setServerCertificate=function(){};function gh(){throw new TypeError("Illegal constructor.");}gh.prototype.getConfiguration=function(){};gh.prototype.createMediaKeys=function(){};var hh="";function ih(a){hh=a;jh=(new Uint8Array([0])).buffer;navigator.requestMediaKeySystemAccess=kh;delete HTMLMediaElement.prototype.mediaKeys;HTMLMediaElement.prototype.mediaKeys=null;HTMLMediaElement.prototype.setMediaKeys=lh;window.MediaKeys=mh;window.MediaKeySystemAccess=nh}function oh(a){var b=hh;return b?b+a.charAt(0).toUpperCase()+a.slice(1):a}function kh(a,b){try{var c=new nh(a,b);return Promise.resolve(c)}catch(d){return Promise.reject(d)}}
  2258. function lh(a){var b=this.mediaKeys;b&&b!=a&&ph(b,null);delete this.mediaKeys;(this.mediaKeys=a)&&ph(a,this);return Promise.resolve()}
  2259. function nh(a,b){this.a=this.keySystem=a;var c=!0;"org.w3.clearkey"==a&&(this.a="webkit-org.w3.clearkey",c=!1);var d=!1;var e=document.getElementsByTagName("video");var f=e.length?e[0]:document.createElement("video");for(var g=0;g<b.length;++g){e=b[g];var h={audioCapabilities:[],videoCapabilities:[],persistentState:"optional",distinctiveIdentifier:"optional",initDataTypes:e.initDataTypes,sessionTypes:["temporary"],label:e.label},l=!1;if(e.audioCapabilities)for(var m=0;m<e.audioCapabilities.length;++m){var q=
  2260. e.audioCapabilities[m];if(q.contentType){var l=!0,r=q.contentType.split(";")[0];f.canPlayType(r,this.a)&&(h.audioCapabilities.push(q),d=!0)}}if(e.videoCapabilities)for(m=0;m<e.videoCapabilities.length;++m)q=e.videoCapabilities[m],q.contentType&&(l=!0,f.canPlayType(q.contentType,this.a)&&(h.videoCapabilities.push(q),d=!0));l||(d=f.canPlayType("video/mp4",this.a)||f.canPlayType("video/webm",this.a));"required"==e.persistentState&&(c?(h.persistentState="required",h.sessionTypes=["persistent-license"]):
  2261. d=!1);if(d){this.b=h;return}}c="Unsupported keySystem";if("org.w3.clearkey"==a||"com.widevine.alpha"==a)c="None of the requested configurations were supported.";c=Error(c);c.name="NotSupportedError";c.code=DOMException.NOT_SUPPORTED_ERR;throw c;}nh.prototype.createMediaKeys=function(){var a=new mh(this.a);return Promise.resolve(a)};nh.prototype.getConfiguration=function(){return this.b};function mh(a){this.g=a;this.b=null;this.a=new D;this.c=[];this.f={}}
  2262. function ph(a,b){a.b=b;Ja(a.a);var c=hh;b&&(E(a.a,b,c+"needkey",a.Cd.bind(a)),E(a.a,b,c+"keymessage",a.Bd.bind(a)),E(a.a,b,c+"keyadded",a.zd.bind(a)),E(a.a,b,c+"keyerror",a.Ad.bind(a)))}k=mh.prototype;k.createSession=function(a){var b=a||"temporary";if("temporary"!=b&&"persistent-license"!=b)throw new TypeError("Session type "+a+" is unsupported on this platform.");a=this.b||document.createElement("video");a.src||(a.src="about:blank");b=new qh(a,this.g,b);this.c.push(b);return b};
  2263. k.setServerCertificate=function(){return Promise.resolve(!1)};k.Cd=function(a){var b=document.createEvent("CustomEvent");b.initCustomEvent("encrypted",!1,!1,null);b.initDataType="webm";b.initData=a.initData;this.b.dispatchEvent(b)};k.Bd=function(a){var b=rh(this,a.sessionId);b&&(a=new I("message",{messageType:void 0==b.keyStatuses.sb()?"licenserequest":"licenserenewal",message:a.message}),b.b&&(b.b.resolve(),b.b=null),b.dispatchEvent(a))};
  2264. k.zd=function(a){if(a=rh(this,a.sessionId))sh(a,"usable"),a.a&&a.a.resolve(),a.a=null};
  2265. k.Ad=function(a){var b=rh(this,a.sessionId);if(b){var c=Error("EME v0.1b key error");c.errorCode=a.errorCode;c.errorCode.systemCode=a.systemCode;!a.sessionId&&b.b?(c.method="generateRequest",45==a.systemCode&&(c.message="Unsupported session type."),b.b.reject(c),b.b=null):a.sessionId&&b.a?(c.method="update",b.a.reject(c),b.a=null):(c=a.systemCode,a.errorCode.code==MediaKeyError.MEDIA_KEYERR_OUTPUT?sh(b,"output-restricted"):1==c?sh(b,"expired"):sh(b,"internal-error"))}};
  2266. function rh(a,b){var c=a.f[b];return c?c:(c=a.c.shift())?(c.sessionId=b,a.f[b]=c):null}function qh(a,b,c){p.call(this);this.f=a;this.h=!1;this.a=this.b=null;this.c=b;this.g=c;this.sessionId="";this.expiration=NaN;this.closed=new A;this.keyStatuses=new th}ba(qh);
  2267. function uh(a,b,c){if(a.h)return Promise.reject(Error("The session is already initialized."));a.h=!0;try{if("persistent-license"==a.g)if(c)var d=new Uint8Array(Ua("LOAD_SESSION|"+c));else{var e=Ua("PERSISTENT|"),f=new Uint8Array(e.byteLength+b.byteLength);f.set(new Uint8Array(e),0);f.set(new Uint8Array(b),e.byteLength);d=f}else d=new Uint8Array(b)}catch(h){return Promise.reject(h)}a.b=new A;var g=oh("generateKeyRequest");try{a.f[g](a.c,d)}catch(h){if("InvalidStateError"!=h.name)return a.b=null,Promise.reject(h);
  2268. setTimeout(function(){try{this.f[g](this.c,d)}catch(l){this.b.reject(l),this.b=null}}.bind(a),10)}return a.b}k=qh.prototype;
  2269. k.Mb=function(a,b){if(this.a)this.a.then(this.Mb.bind(this,a,b))["catch"](this.Mb.bind(this,a,b));else{this.a=a;if("webkit-org.w3.clearkey"==this.c){var c=F(b);var d=JSON.parse(c);"oct"!=d.keys[0].kty&&(this.a.reject(Error("Response is not a valid JSON Web Key Set.")),this.a=null);c=Ya(d.keys[0].k);d=Ya(d.keys[0].kid)}else c=new Uint8Array(b),d=null;var e=oh("addKey");try{this.f[e](this.c,c,d,this.sessionId)}catch(f){this.a.reject(f),this.a=null}}};
  2270. function sh(a,b){a.keyStatuses.Kb(b);a.dispatchEvent(new I("keystatuseschange"))}k.generateRequest=function(a,b){return uh(this,b,null)};k.load=function(a){return"persistent-license"==this.g?uh(this,null,a):Promise.reject(Error("Not a persistent session."))};k.update=function(a){var b=new A;this.Mb(b,a);return b};
  2271. k.close=function(){if("persistent-license"!=this.g){if(!this.sessionId)return this.closed.reject(Error("The session is not callable.")),this.closed;var a=oh("cancelKeyRequest");try{this.f[a](this.c,this.sessionId)}catch(b){}}this.closed.resolve();return this.closed};k.remove=function(){return"persistent-license"!=this.g?Promise.reject(Error("Not a persistent session.")):this.close()};function th(){this.size=0;this.a=void 0}var jh;k=th.prototype;k.Kb=function(a){this.size=void 0==a?0:1;this.a=a};
  2272. k.sb=function(){return this.a};k.forEach=function(a){this.a&&a(this.a,jh)};k.get=function(a){if(this.has(a))return this.a};k.has=function(a){var b=jh;return this.a&&ab(new Uint8Array(a),new Uint8Array(b))?!0:!1};k.entries=function(){};k.keys=function(){};k.values=function(){};Qg(function(){!window.HTMLVideoElement||navigator.requestMediaKeySystemAccess&&MediaKeySystemAccess.prototype.getConfiguration||(HTMLMediaElement.prototype.webkitGenerateKeyRequest?ih("webkit"):HTMLMediaElement.prototype.generateKeyRequest?ih(""):window.MSMediaKeys?(ch=(new Uint8Array([0])).buffer,delete HTMLMediaElement.prototype.mediaKeys,HTMLMediaElement.prototype.mediaKeys=null,HTMLMediaElement.prototype.setMediaKeys=Wg,window.MediaKeys=Vg,window.MediaKeySystemAccess=Ug,navigator.requestMediaKeySystemAccess=
  2273. Tg):(navigator.requestMediaKeySystemAccess=dh,delete HTMLMediaElement.prototype.mediaKeys,HTMLMediaElement.prototype.mediaKeys=null,HTMLMediaElement.prototype.setMediaKeys=eh,window.MediaKeys=fh,window.MediaKeySystemAccess=gh))});function vh(){var a=MediaSource.prototype.addSourceBuffer;MediaSource.prototype.addSourceBuffer=function(){var b=a.apply(this,arguments);b.abort=function(){};return b}}
  2274. function wh(){var a=MediaSource.prototype.endOfStream;MediaSource.prototype.endOfStream=function(){for(var b,d=0,e=0;e<this.sourceBuffers.length;++e)b=this.sourceBuffers[e],b=b.buffered.end(b.buffered.length-1),d=Math.max(d,b);if(!isNaN(this.duration)&&d<this.duration)for(this.Zb=!0,e=0;e<this.sourceBuffers.length;++e)b=this.sourceBuffers[e],b.Tb=!1;return a.apply(this,arguments)};var b=MediaSource.prototype.addSourceBuffer;MediaSource.prototype.addSourceBuffer=function(){var a=b.apply(this,arguments);
  2275. a.N=this;a.addEventListener("updateend",xh,!1);this.a||(this.addEventListener("sourceclose",yh,!1),this.a=!0);return a}}function xh(a){var b=a.target,c=b.N;if(c.Zb){a.preventDefault();a.stopPropagation();a.stopImmediatePropagation();b.Tb=!0;for(a=0;a<c.sourceBuffers.length;++a)if(0==c.sourceBuffers[a].Tb)return;c.Zb=!1}}function yh(a){a=a.target;for(var b=0;b<a.sourceBuffers.length;++b)a.sourceBuffers[b].removeEventListener("updateend",xh,!1);a.removeEventListener("sourceclose",yh,!1)}
  2276. Qg(function(){if(window.MediaSource){var a=navigator.vendor,b=navigator.appVersion;!a||!b||0>a.indexOf("Apple")||(0<=b.indexOf("Version/8")?window.MediaSource=null:0<=b.indexOf("Version/9")?vh():0<=b.indexOf("Version/10")&&(vh(),wh()))}});function Z(a){this.c=[];this.b=[];this.Aa=zh;if(a)try{a(this.fa.bind(this),this.a.bind(this))}catch(b){this.a(b)}}var zh=0;function Ah(a){var b=new Z;b.fa(void 0);return b.then(function(){return a})}function Bh(a){var b=new Z;b.a(a);return b}function Ch(a){function b(a,b,c){a.Aa==zh&&(e[b]=c,d++,d==e.length&&a.fa(e))}var c=new Z;if(!a.length)return c.fa([]),c;for(var d=0,e=Array(a.length),f=c.a.bind(c),g=0;g<a.length;++g)a[g]&&a[g].then?a[g].then(b.bind(null,c,g),f):b(c,g,a[g]);return c}
  2277. function Dh(a){for(var b=new Z,c=b.fa.bind(b),d=b.a.bind(b),e=0;e<a.length;++e)a[e]&&a[e].then?a[e].then(c,d):c(a[e]);return b}Z.prototype.then=function(a,b){var c=new Z;switch(this.Aa){case 1:Eh(this,c,a);break;case 2:Eh(this,c,b);break;case zh:this.c.push({L:c,pb:a}),this.b.push({L:c,pb:b})}return c};Z.prototype["catch"]=function(a){return this.then(void 0,a)};
  2278. Z.prototype.fa=function(a){if(this.Aa==zh){this.jb=a;this.Aa=1;for(a=0;a<this.c.length;++a)Eh(this,this.c[a].L,this.c[a].pb);this.c=[];this.b=[]}};Z.prototype.a=function(a){if(this.Aa==zh){this.jb=a;this.Aa=2;for(a=0;a<this.b.length;++a)Eh(this,this.b[a].L,this.b[a].pb);this.c=[];this.b=[]}};
  2279. function Eh(a,b,c){Fh.push(function(){if(c&&"function"==typeof c){try{var a=c(this.jb)}catch(f){b.a(f);return}try{var e=a&&a.then}catch(f){b.a(f);return}a instanceof Z?a==b?b.a(new TypeError("Chaining cycle detected")):a.then(b.fa.bind(b),b.a.bind(b)):e?Gh(a,e,b):b.fa(a)}else 1==this.Aa?b.fa(this.jb):b.a(this.jb)}.bind(a));null==Hh&&(Hh=Ih(Jh))}
  2280. function Gh(a,b,c){try{var d=!1;b.call(a,function(a){if(!d){d=!0;try{var b=a&&a.then}catch(g){c.a(g);return}b?Gh(a,b,c):c.fa(a)}},c.a.bind(c))}catch(e){c.a(e)}}function Jh(){for(;Fh.length;){null!=Hh&&(Kh(Hh),Hh=null);var a=Fh;Fh=[];for(var b=0;b<a.length;++b)a[b]()}}function Ih(){return 0}function Kh(){}var Hh=null,Fh=[];
  2281. Qg(function(a){window.setImmediate?(Ih=function(a){return window.setImmediate(a)},Kh=function(a){return window.clearImmediate(a)}):(Ih=function(a){return window.setTimeout(a,0)},Kh=function(a){return window.clearTimeout(a)});if(!window.Promise||a)window.Promise=Z,window.Promise.resolve=Ah,window.Promise.reject=Bh,window.Promise.all=Ch,window.Promise.race=Dh,window.Promise.prototype.then=Z.prototype.then,window.Promise.prototype["catch"]=Z.prototype["catch"]});Qg(function(){if(window.HTMLMediaElement){var a=HTMLMediaElement.prototype.play;HTMLMediaElement.prototype.play=function(){var b=a.apply(this,arguments);b&&b["catch"](function(){});return b}}});function Lh(){return{droppedVideoFrames:this.webkitDroppedFrameCount,totalVideoFrames:this.webkitDecodedFrameCount,corruptedVideoFrames:0,creationTime:NaN,totalFrameDelay:0}}Qg(function(){if(window.HTMLVideoElement){var a=HTMLVideoElement.prototype;!a.getVideoPlaybackQuality&&"webkitDroppedFrameCount"in a&&(a.getVideoPlaybackQuality=Lh)}});function Mh(a,b,c){return new window.TextTrackCue(a,b,c)}function Nh(a,b,c){return new window.TextTrackCue(a+"-"+b+"-"+c,a,b,c)}Qg(function(){if(!window.VTTCue&&window.TextTrackCue){var a=TextTrackCue.length;if(3==a)window.VTTCue=Mh;else if(6==a)window.VTTCue=Nh;else{try{var b=!!Mh(1,2,"")}catch(c){b=!1}b&&(window.VTTCue=Mh)}}});}.call(g,this));
  2282. if (typeof(module)!="undefined"&&module.exports)module.exports=g.shaka;
  2283. else if (typeof(define)!="undefined" && define.amd)define(function(){return g.shaka});
  2284. else this.shaka=g.shaka;
  2285. })();
  2286. },{}],6:[function(_dereq_,module,exports){
  2287. // stats.js - http://github.com/mrdoob/stats.js
  2288. var Stats=function(){var l=Date.now(),m=l,g=0,n=Infinity,o=0,h=0,p=Infinity,q=0,r=0,s=0,f=document.createElement("div");f.id="stats";f.addEventListener("mousedown",function(b){b.preventDefault();t(++s%2)},!1);f.style.cssText="width:80px;opacity:0.9;cursor:pointer";var a=document.createElement("div");a.id="fps";a.style.cssText="padding:0 0 3px 3px;text-align:left;background-color:#002";f.appendChild(a);var i=document.createElement("div");i.id="fpsText";i.style.cssText="color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px";
  2289. i.innerHTML="FPS";a.appendChild(i);var c=document.createElement("div");c.id="fpsGraph";c.style.cssText="position:relative;width:74px;height:30px;background-color:#0ff";for(a.appendChild(c);74>c.children.length;){var j=document.createElement("span");j.style.cssText="width:1px;height:30px;float:left;background-color:#113";c.appendChild(j)}var d=document.createElement("div");d.id="ms";d.style.cssText="padding:0 0 3px 3px;text-align:left;background-color:#020;display:none";f.appendChild(d);var k=document.createElement("div");
  2290. k.id="msText";k.style.cssText="color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px";k.innerHTML="MS";d.appendChild(k);var e=document.createElement("div");e.id="msGraph";e.style.cssText="position:relative;width:74px;height:30px;background-color:#0f0";for(d.appendChild(e);74>e.children.length;)j=document.createElement("span"),j.style.cssText="width:1px;height:30px;float:left;background-color:#131",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display=
  2291. "block";d.style.display="none";break;case 1:a.style.display="none",d.style.display="block"}};return{REVISION:12,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+" MS ("+n+"-"+o+")";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+"px";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+" FPS ("+p+"-"+q+")",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height=
  2292. a+"px",m=b,r=0);return b},update:function(){l=this.end()}}};"object"===typeof module&&(module.exports=Stats);
  2293. },{}],7:[function(_dereq_,module,exports){
  2294. (function (global){
  2295. (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.WebVRManager = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof _dereq_=="function"&&_dereq_;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 _dereq_=="function"&&_dereq_;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
  2296. /*
  2297. * Copyright 2015 Google Inc. All Rights Reserved.
  2298. * Licensed under the Apache License, Version 2.0 (the "License");
  2299. * you may not use this file except in compliance with the License.
  2300. * You may obtain a copy of the License at
  2301. *
  2302. * http://www.apache.org/licenses/LICENSE-2.0
  2303. *
  2304. * Unless required by applicable law or agreed to in writing, software
  2305. * distributed under the License is distributed on an "AS IS" BASIS,
  2306. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  2307. * See the License for the specific language governing permissions and
  2308. * limitations under the License.
  2309. */
  2310. var Emitter = _dereq_('./emitter.js');
  2311. var Modes = _dereq_('./modes.js');
  2312. var Util = _dereq_('./util.js');
  2313. /**
  2314. * Everything having to do with the WebVR button.
  2315. * Emits a 'click' event when it's clicked.
  2316. */
  2317. function ButtonManager(opt_root) {
  2318. var root = opt_root || document.body;
  2319. this.loadIcons_();
  2320. // Make the fullscreen button.
  2321. var fsButton = this.createButton();
  2322. fsButton.src = this.ICONS.fullscreen;
  2323. fsButton.title = 'Fullscreen mode';
  2324. var s = fsButton.style;
  2325. s.bottom = '40px';
  2326. s.right = 0;
  2327. fsButton.addEventListener('click', this.createClickHandler_('fs'));
  2328. root.appendChild(fsButton);
  2329. this.fsButton = fsButton;
  2330. // Make the VR button.
  2331. var vrButton = this.createButton();
  2332. vrButton.src = this.ICONS.cardboard;
  2333. vrButton.title = 'Virtual reality mode';
  2334. var s = vrButton.style;
  2335. s.bottom = '40px';
  2336. s.right = '48px';
  2337. vrButton.addEventListener('click', this.createClickHandler_('vr'));
  2338. root.appendChild(vrButton);
  2339. this.vrButton = vrButton;
  2340. this.isVisible = true;
  2341. }
  2342. ButtonManager.prototype = new Emitter();
  2343. ButtonManager.prototype.createButton = function() {
  2344. var button = document.createElement('img');
  2345. button.className = 'webvr-button';
  2346. var s = button.style;
  2347. s.position = 'absolute';
  2348. s.width = '24px'
  2349. s.height = '24px';
  2350. s.backgroundSize = 'cover';
  2351. s.backgroundColor = 'transparent';
  2352. s.border = 0;
  2353. s.userSelect = 'none';
  2354. s.webkitUserSelect = 'none';
  2355. s.MozUserSelect = 'none';
  2356. s.cursor = 'pointer';
  2357. s.padding = '12px';
  2358. s.zIndex = 1;
  2359. s.display = 'none';
  2360. s.boxSizing = 'content-box';
  2361. // Prevent button from being selected and dragged.
  2362. button.draggable = false;
  2363. button.addEventListener('dragstart', function(e) {
  2364. e.preventDefault();
  2365. });
  2366. // Style it on hover.
  2367. button.addEventListener('mouseenter', function(e) {
  2368. s.filter = s.webkitFilter = 'drop-shadow(0 0 5px rgba(255,255,255,1))';
  2369. });
  2370. button.addEventListener('mouseleave', function(e) {
  2371. s.filter = s.webkitFilter = '';
  2372. });
  2373. return button;
  2374. };
  2375. ButtonManager.prototype.setMode = function(mode, isVRCompatible) {
  2376. isVRCompatible = isVRCompatible || WebVRConfig.FORCE_ENABLE_VR;
  2377. if (!this.isVisible) {
  2378. return;
  2379. }
  2380. switch (mode) {
  2381. case Modes.NORMAL:
  2382. this.fsButton.style.display = 'none';
  2383. this.fsButton.src = this.ICONS.fullscreen;
  2384. this.vrButton.style.display = (isVRCompatible ? 'block' : 'none');
  2385. break;
  2386. case Modes.MAGIC_WINDOW:
  2387. this.fsButton.style.display = 'block';
  2388. this.fsButton.src = this.ICONS.exitFullscreen;
  2389. this.vrButton.style.display = 'none';
  2390. break;
  2391. case Modes.VR:
  2392. this.fsButton.style.display = 'none';
  2393. this.vrButton.style.display = 'none';
  2394. break;
  2395. }
  2396. // Hack for Safari Mac/iOS to force relayout (svg-specific issue)
  2397. // http://goo.gl/hjgR6r
  2398. var oldValue = this.fsButton.style.display;
  2399. this.fsButton.style.display = 'inline-block';
  2400. this.fsButton.offsetHeight;
  2401. this.fsButton.style.display = oldValue;
  2402. };
  2403. ButtonManager.prototype.setVisibility = function(isVisible) {
  2404. this.isVisible = isVisible;
  2405. this.fsButton.style.display = isVisible ? 'block' : 'none';
  2406. this.vrButton.style.display = isVisible ? 'block' : 'none';
  2407. };
  2408. ButtonManager.prototype.createClickHandler_ = function(eventName) {
  2409. return function(e) {
  2410. e.stopPropagation();
  2411. e.preventDefault();
  2412. this.emit(eventName);
  2413. }.bind(this);
  2414. };
  2415. ButtonManager.prototype.loadIcons_ = function() {
  2416. // Preload some hard-coded SVG.
  2417. this.ICONS = {};
  2418. this.ICONS.cardboard = Util.base64('image/svg+xml', 'PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNHB4IiBoZWlnaHQ9IjI0cHgiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI0ZGRkZGRiI+CiAgICA8cGF0aCBkPSJNMjAuNzQgNkgzLjIxQzIuNTUgNiAyIDYuNTcgMiA3LjI4djEwLjQ0YzAgLjcuNTUgMS4yOCAxLjIzIDEuMjhoNC43OWMuNTIgMCAuOTYtLjMzIDEuMTQtLjc5bDEuNC0zLjQ4Yy4yMy0uNTkuNzktMS4wMSAxLjQ0LTEuMDFzMS4yMS40MiAxLjQ1IDEuMDFsMS4zOSAzLjQ4Yy4xOS40Ni42My43OSAxLjExLjc5aDQuNzljLjcxIDAgMS4yNi0uNTcgMS4yNi0xLjI4VjcuMjhjMC0uNy0uNTUtMS4yOC0xLjI2LTEuMjh6TTcuNSAxNC42MmMtMS4xNyAwLTIuMTMtLjk1LTIuMTMtMi4xMiAwLTEuMTcuOTYtMi4xMyAyLjEzLTIuMTMgMS4xOCAwIDIuMTIuOTYgMi4xMiAyLjEzcy0uOTUgMi4xMi0yLjEyIDIuMTJ6bTkgMGMtMS4xNyAwLTIuMTMtLjk1LTIuMTMtMi4xMiAwLTEuMTcuOTYtMi4xMyAyLjEzLTIuMTNzMi4xMi45NiAyLjEyIDIuMTMtLjk1IDIuMTItMi4xMiAyLjEyeiIvPgogICAgPHBhdGggZmlsbD0ibm9uZSIgZD0iTTAgMGgyNHYyNEgwVjB6Ii8+Cjwvc3ZnPgo=');
  2419. this.ICONS.fullscreen = Util.base64('image/svg+xml', 'PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNHB4IiBoZWlnaHQ9IjI0cHgiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI0ZGRkZGRiI+CiAgICA8cGF0aCBkPSJNMCAwaDI0djI0SDB6IiBmaWxsPSJub25lIi8+CiAgICA8cGF0aCBkPSJNNyAxNEg1djVoNXYtMkg3di0zem0tMi00aDJWN2gzVjVINXY1em0xMiA3aC0zdjJoNXYtNWgtMnYzek0xNCA1djJoM3YzaDJWNWgtNXoiLz4KPC9zdmc+Cg==');
  2420. this.ICONS.exitFullscreen = Util.base64('image/svg+xml', 'PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNHB4IiBoZWlnaHQ9IjI0cHgiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI0ZGRkZGRiI+CiAgICA8cGF0aCBkPSJNMCAwaDI0djI0SDB6IiBmaWxsPSJub25lIi8+CiAgICA8cGF0aCBkPSJNNSAxNmgzdjNoMnYtNUg1djJ6bTMtOEg1djJoNVY1SDh2M3ptNiAxMWgydi0zaDN2LTJoLTV2NXptMi0xMVY1aC0ydjVoNVY4aC0zeiIvPgo8L3N2Zz4K');
  2421. this.ICONS.settings = Util.base64('image/svg+xml', 'PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNHB4IiBoZWlnaHQ9IjI0cHgiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI0ZGRkZGRiI+CiAgICA8cGF0aCBkPSJNMCAwaDI0djI0SDB6IiBmaWxsPSJub25lIi8+CiAgICA8cGF0aCBkPSJNMTkuNDMgMTIuOThjLjA0LS4zMi4wNy0uNjQuMDctLjk4cy0uMDMtLjY2LS4wNy0uOThsMi4xMS0xLjY1Yy4xOS0uMTUuMjQtLjQyLjEyLS42NGwtMi0zLjQ2Yy0uMTItLjIyLS4zOS0uMy0uNjEtLjIybC0yLjQ5IDFjLS41Mi0uNC0xLjA4LS43My0xLjY5LS45OGwtLjM4LTIuNjVDMTQuNDYgMi4xOCAxNC4yNSAyIDE0IDJoLTRjLS4yNSAwLS40Ni4xOC0uNDkuNDJsLS4zOCAyLjY1Yy0uNjEuMjUtMS4xNy41OS0xLjY5Ljk4bC0yLjQ5LTFjLS4yMy0uMDktLjQ5IDAtLjYxLjIybC0yIDMuNDZjLS4xMy4yMi0uMDcuNDkuMTIuNjRsMi4xMSAxLjY1Yy0uMDQuMzItLjA3LjY1LS4wNy45OHMuMDMuNjYuMDcuOThsLTIuMTEgMS42NWMtLjE5LjE1LS4yNC40Mi0uMTIuNjRsMiAzLjQ2Yy4xMi4yMi4zOS4zLjYxLjIybDIuNDktMWMuNTIuNCAxLjA4LjczIDEuNjkuOThsLjM4IDIuNjVjLjAzLjI0LjI0LjQyLjQ5LjQyaDRjLjI1IDAgLjQ2LS4xOC40OS0uNDJsLjM4LTIuNjVjLjYxLS4yNSAxLjE3LS41OSAxLjY5LS45OGwyLjQ5IDFjLjIzLjA5LjQ5IDAgLjYxLS4yMmwyLTMuNDZjLjEyLS4yMi4wNy0uNDktLjEyLS42NGwtMi4xMS0xLjY1ek0xMiAxNS41Yy0xLjkzIDAtMy41LTEuNTctMy41LTMuNXMxLjU3LTMuNSAzLjUtMy41IDMuNSAxLjU3IDMuNSAzLjUtMS41NyAzLjUtMy41IDMuNXoiLz4KPC9zdmc+Cg==');
  2422. };
  2423. module.exports = ButtonManager;
  2424. },{"./emitter.js":2,"./modes.js":3,"./util.js":4}],2:[function(_dereq_,module,exports){
  2425. /*
  2426. * Copyright 2015 Google Inc. All Rights Reserved.
  2427. * Licensed under the Apache License, Version 2.0 (the "License");
  2428. * you may not use this file except in compliance with the License.
  2429. * You may obtain a copy of the License at
  2430. *
  2431. * http://www.apache.org/licenses/LICENSE-2.0
  2432. *
  2433. * Unless required by applicable law or agreed to in writing, software
  2434. * distributed under the License is distributed on an "AS IS" BASIS,
  2435. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  2436. * See the License for the specific language governing permissions and
  2437. * limitations under the License.
  2438. */
  2439. function Emitter() {
  2440. this.callbacks = {};
  2441. }
  2442. Emitter.prototype.emit = function(eventName) {
  2443. var callbacks = this.callbacks[eventName];
  2444. if (!callbacks) {
  2445. //console.log('No valid callback specified.');
  2446. return;
  2447. }
  2448. var args = [].slice.call(arguments);
  2449. // Eliminate the first param (the callback).
  2450. args.shift();
  2451. for (var i = 0; i < callbacks.length; i++) {
  2452. callbacks[i].apply(this, args);
  2453. }
  2454. };
  2455. Emitter.prototype.on = function(eventName, callback) {
  2456. if (eventName in this.callbacks) {
  2457. this.callbacks[eventName].push(callback);
  2458. } else {
  2459. this.callbacks[eventName] = [callback];
  2460. }
  2461. };
  2462. module.exports = Emitter;
  2463. },{}],3:[function(_dereq_,module,exports){
  2464. /*
  2465. * Copyright 2015 Google Inc. All Rights Reserved.
  2466. * Licensed under the Apache License, Version 2.0 (the "License");
  2467. * you may not use this file except in compliance with the License.
  2468. * You may obtain a copy of the License at
  2469. *
  2470. * http://www.apache.org/licenses/LICENSE-2.0
  2471. *
  2472. * Unless required by applicable law or agreed to in writing, software
  2473. * distributed under the License is distributed on an "AS IS" BASIS,
  2474. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  2475. * See the License for the specific language governing permissions and
  2476. * limitations under the License.
  2477. */
  2478. var Modes = {
  2479. UNKNOWN: 0,
  2480. // Not fullscreen, just tracking.
  2481. NORMAL: 1,
  2482. // Magic window immersive mode.
  2483. MAGIC_WINDOW: 2,
  2484. // Full screen split screen VR mode.
  2485. VR: 3,
  2486. };
  2487. module.exports = Modes;
  2488. },{}],4:[function(_dereq_,module,exports){
  2489. /*
  2490. * Copyright 2015 Google Inc. All Rights Reserved.
  2491. * Licensed under the Apache License, Version 2.0 (the "License");
  2492. * you may not use this file except in compliance with the License.
  2493. * You may obtain a copy of the License at
  2494. *
  2495. * http://www.apache.org/licenses/LICENSE-2.0
  2496. *
  2497. * Unless required by applicable law or agreed to in writing, software
  2498. * distributed under the License is distributed on an "AS IS" BASIS,
  2499. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  2500. * See the License for the specific language governing permissions and
  2501. * limitations under the License.
  2502. */
  2503. var Util = {};
  2504. Util.base64 = function(mimeType, base64) {
  2505. return 'data:' + mimeType + ';base64,' + base64;
  2506. };
  2507. Util.isMobile = function() {
  2508. var check = false;
  2509. (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))check = true})(navigator.userAgent||navigator.vendor||window.opera);
  2510. return check;
  2511. };
  2512. Util.isFirefox = function() {
  2513. return /firefox/i.test(navigator.userAgent);
  2514. };
  2515. Util.isIOS = function() {
  2516. return /(iPad|iPhone|iPod)/g.test(navigator.userAgent);
  2517. };
  2518. Util.isIFrame = function() {
  2519. try {
  2520. return window.self !== window.top;
  2521. } catch (e) {
  2522. return true;
  2523. }
  2524. };
  2525. Util.appendQueryParameter = function(url, key, value) {
  2526. // Determine delimiter based on if the URL already GET parameters in it.
  2527. var delimiter = (url.indexOf('?') < 0 ? '?' : '&');
  2528. url += delimiter + key + '=' + value;
  2529. return url;
  2530. };
  2531. // From http://goo.gl/4WX3tg
  2532. Util.getQueryParameter = function(name) {
  2533. var name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
  2534. var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
  2535. results = regex.exec(location.search);
  2536. return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
  2537. };
  2538. Util.isLandscapeMode = function() {
  2539. return (window.orientation == 90 || window.orientation == -90);
  2540. };
  2541. Util.getScreenWidth = function() {
  2542. return Math.max(window.screen.width, window.screen.height) *
  2543. window.devicePixelRatio;
  2544. };
  2545. Util.getScreenHeight = function() {
  2546. return Math.min(window.screen.width, window.screen.height) *
  2547. window.devicePixelRatio;
  2548. };
  2549. module.exports = Util;
  2550. },{}],5:[function(_dereq_,module,exports){
  2551. /*
  2552. * Copyright 2015 Google Inc. All Rights Reserved.
  2553. * Licensed under the Apache License, Version 2.0 (the "License");
  2554. * you may not use this file except in compliance with the License.
  2555. * You may obtain a copy of the License at
  2556. *
  2557. * http://www.apache.org/licenses/LICENSE-2.0
  2558. *
  2559. * Unless required by applicable law or agreed to in writing, software
  2560. * distributed under the License is distributed on an "AS IS" BASIS,
  2561. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  2562. * See the License for the specific language governing permissions and
  2563. * limitations under the License.
  2564. */
  2565. var ButtonManager = _dereq_('./button-manager.js');
  2566. var Emitter = _dereq_('./emitter.js');
  2567. var Modes = _dereq_('./modes.js');
  2568. var Util = _dereq_('./util.js');
  2569. /**
  2570. * Helper for getting in and out of VR mode.
  2571. */
  2572. function WebVRManager(renderer, effect, params) {
  2573. this.params = params || {};
  2574. this.mode = Modes.UNKNOWN;
  2575. // Set option to hide the button.
  2576. this.hideButton = this.params.hideButton || false;
  2577. // Whether or not the FOV should be distorted or un-distorted. By default, it
  2578. // should be distorted, but in the case of vertex shader based distortion,
  2579. // ensure that we use undistorted parameters.
  2580. this.predistorted = !!this.params.predistorted;
  2581. // Save the THREE.js renderer and effect for later.
  2582. this.renderer = renderer;
  2583. this.effect = effect;
  2584. var polyfillWrapper = document.querySelector('.webvr-polyfill-fullscreen-wrapper');
  2585. this.button = new ButtonManager(polyfillWrapper);
  2586. this.isFullscreenDisabled = !!Util.getQueryParameter('no_fullscreen');
  2587. this.startMode = Modes.NORMAL;
  2588. var startModeParam = parseInt(Util.getQueryParameter('start_mode'));
  2589. if (!isNaN(startModeParam)) {
  2590. this.startMode = startModeParam;
  2591. }
  2592. if (this.hideButton) {
  2593. this.button.setVisibility(false);
  2594. }
  2595. // Check if the browser is compatible with WebVR.
  2596. this.getDeviceByType_(VRDisplay).then(function(hmd) {
  2597. this.hmd = hmd;
  2598. // Only enable VR mode if there's a VR device attached or we are running the
  2599. // polyfill on mobile.
  2600. if (!this.isVRCompatibleOverride) {
  2601. this.isVRCompatible = !hmd.isPolyfilled || Util.isMobile();
  2602. }
  2603. switch (this.startMode) {
  2604. case Modes.MAGIC_WINDOW:
  2605. this.setMode_(Modes.MAGIC_WINDOW);
  2606. break;
  2607. case Modes.VR:
  2608. this.enterVRMode_();
  2609. this.setMode_(Modes.VR);
  2610. break;
  2611. default:
  2612. this.setMode_(Modes.NORMAL);
  2613. }
  2614. this.emit('initialized');
  2615. }.bind(this));
  2616. // Hook up button listeners.
  2617. this.button.on('fs', this.onFSClick_.bind(this));
  2618. this.button.on('vr', this.onVRClick_.bind(this));
  2619. // Bind to fullscreen events.
  2620. document.addEventListener('webkitfullscreenchange',
  2621. this.onFullscreenChange_.bind(this));
  2622. document.addEventListener('mozfullscreenchange',
  2623. this.onFullscreenChange_.bind(this));
  2624. document.addEventListener('msfullscreenchange',
  2625. this.onFullscreenChange_.bind(this));
  2626. // Bind to VR* specific events.
  2627. window.addEventListener('vrdisplaypresentchange',
  2628. this.onVRDisplayPresentChange_.bind(this));
  2629. window.addEventListener('vrdisplaydeviceparamschange',
  2630. this.onVRDisplayDeviceParamsChange_.bind(this));
  2631. }
  2632. WebVRManager.prototype = new Emitter();
  2633. // Expose these values externally.
  2634. WebVRManager.Modes = Modes;
  2635. WebVRManager.prototype.render = function(scene, camera, timestamp) {
  2636. // Scene may be an array of two scenes, one for each eye.
  2637. if (scene instanceof Array) {
  2638. this.effect.render(scene[0], camera);
  2639. } else {
  2640. this.effect.render(scene, camera);
  2641. }
  2642. };
  2643. WebVRManager.prototype.setVRCompatibleOverride = function(isVRCompatible) {
  2644. this.isVRCompatible = isVRCompatible;
  2645. this.isVRCompatibleOverride = true;
  2646. // Don't actually change modes, just update the buttons.
  2647. this.button.setMode(this.mode, this.isVRCompatible);
  2648. };
  2649. WebVRManager.prototype.setFullscreenCallback = function(callback) {
  2650. this.fullscreenCallback = callback;
  2651. };
  2652. WebVRManager.prototype.setVRCallback = function(callback) {
  2653. this.vrCallback = callback;
  2654. };
  2655. WebVRManager.prototype.setExitFullscreenCallback = function(callback) {
  2656. this.exitFullscreenCallback = callback;
  2657. }
  2658. /**
  2659. * Promise returns true if there is at least one HMD device available.
  2660. */
  2661. WebVRManager.prototype.getDeviceByType_ = function(type) {
  2662. return new Promise(function(resolve, reject) {
  2663. navigator.getVRDisplays().then(function(displays) {
  2664. // Promise succeeds, but check if there are any displays actually.
  2665. for (var i = 0; i < displays.length; i++) {
  2666. if (displays[i] instanceof type) {
  2667. resolve(displays[i]);
  2668. break;
  2669. }
  2670. }
  2671. resolve(null);
  2672. }, function() {
  2673. // No displays are found.
  2674. resolve(null);
  2675. });
  2676. });
  2677. };
  2678. /**
  2679. * Helper for entering VR mode.
  2680. */
  2681. WebVRManager.prototype.enterVRMode_ = function() {
  2682. this.hmd.requestPresent([{
  2683. source: this.renderer.domElement,
  2684. predistorted: this.predistorted
  2685. }]);
  2686. };
  2687. WebVRManager.prototype.setMode_ = function(mode) {
  2688. var oldMode = this.mode;
  2689. if (mode == this.mode) {
  2690. console.warn('Not changing modes, already in %s', mode);
  2691. return;
  2692. }
  2693. // console.log('Mode change: %s => %s', this.mode, mode);
  2694. this.mode = mode;
  2695. this.button.setMode(mode, this.isVRCompatible);
  2696. // Emit an event indicating the mode changed.
  2697. this.emit('modechange', mode, oldMode);
  2698. };
  2699. /**
  2700. * Main button was clicked.
  2701. */
  2702. WebVRManager.prototype.onFSClick_ = function() {
  2703. switch (this.mode) {
  2704. case Modes.NORMAL:
  2705. // TODO: Remove this hack if/when iOS gets real fullscreen mode.
  2706. // If this is an iframe on iOS, break out and open in no_fullscreen mode.
  2707. if (Util.isIOS() && Util.isIFrame()) {
  2708. if (this.fullscreenCallback) {
  2709. this.fullscreenCallback();
  2710. } else {
  2711. var url = window.location.href;
  2712. url = Util.appendQueryParameter(url, 'no_fullscreen', 'true');
  2713. url = Util.appendQueryParameter(url, 'start_mode', Modes.MAGIC_WINDOW);
  2714. top.location.href = url;
  2715. return;
  2716. }
  2717. }
  2718. this.setMode_(Modes.MAGIC_WINDOW);
  2719. this.requestFullscreen_();
  2720. break;
  2721. case Modes.MAGIC_WINDOW:
  2722. if (this.isFullscreenDisabled) {
  2723. window.history.back();
  2724. return;
  2725. }
  2726. if (this.exitFullscreenCallback) {
  2727. this.exitFullscreenCallback();
  2728. }
  2729. this.setMode_(Modes.NORMAL);
  2730. this.exitFullscreen_();
  2731. break;
  2732. }
  2733. };
  2734. /**
  2735. * The VR button was clicked.
  2736. */
  2737. WebVRManager.prototype.onVRClick_ = function() {
  2738. // TODO: Remove this hack when iOS has fullscreen mode.
  2739. // If this is an iframe on iOS, break out and open in no_fullscreen mode.
  2740. if (this.mode == Modes.NORMAL && Util.isIOS() && Util.isIFrame()) {
  2741. if (this.vrCallback) {
  2742. this.vrCallback();
  2743. } else {
  2744. var url = window.location.href;
  2745. url = Util.appendQueryParameter(url, 'no_fullscreen', 'true');
  2746. url = Util.appendQueryParameter(url, 'start_mode', Modes.VR);
  2747. top.location.href = url;
  2748. return;
  2749. }
  2750. }
  2751. this.enterVRMode_();
  2752. };
  2753. WebVRManager.prototype.requestFullscreen_ = function() {
  2754. var canvas = document.body;
  2755. //var canvas = this.renderer.domElement;
  2756. if (canvas.requestFullscreen) {
  2757. canvas.requestFullscreen();
  2758. } else if (canvas.mozRequestFullScreen) {
  2759. canvas.mozRequestFullScreen();
  2760. } else if (canvas.webkitRequestFullscreen) {
  2761. canvas.webkitRequestFullscreen();
  2762. } else if (canvas.msRequestFullscreen) {
  2763. canvas.msRequestFullscreen();
  2764. }
  2765. };
  2766. WebVRManager.prototype.exitFullscreen_ = function() {
  2767. if (document.exitFullscreen) {
  2768. document.exitFullscreen();
  2769. } else if (document.mozCancelFullScreen) {
  2770. document.mozCancelFullScreen();
  2771. } else if (document.webkitExitFullscreen) {
  2772. document.webkitExitFullscreen();
  2773. } else if (document.msExitFullscreen) {
  2774. document.msExitFullscreen();
  2775. }
  2776. };
  2777. WebVRManager.prototype.onVRDisplayPresentChange_ = function(e) {
  2778. console.log('onVRDisplayPresentChange_', e);
  2779. if (this.hmd.isPresenting) {
  2780. this.setMode_(Modes.VR);
  2781. } else {
  2782. this.setMode_(Modes.NORMAL);
  2783. }
  2784. };
  2785. WebVRManager.prototype.onVRDisplayDeviceParamsChange_ = function(e) {
  2786. console.log('onVRDisplayDeviceParamsChange_', e);
  2787. };
  2788. WebVRManager.prototype.onFullscreenChange_ = function(e) {
  2789. // If we leave full-screen, go back to normal mode.
  2790. if (document.webkitFullscreenElement === null ||
  2791. document.mozFullScreenElement === null) {
  2792. this.setMode_(Modes.NORMAL);
  2793. }
  2794. };
  2795. module.exports = WebVRManager;
  2796. },{"./button-manager.js":1,"./emitter.js":2,"./modes.js":3,"./util.js":4}]},{},[5])(5)
  2797. });
  2798. }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  2799. },{}],8:[function(_dereq_,module,exports){
  2800. module.exports={
  2801. "_args": [
  2802. [
  2803. "webvr-polyfill@^0.9.38",
  2804. "/Users/lincolnfrog/daydream/vrview"
  2805. ]
  2806. ],
  2807. "_from": "webvr-polyfill@>=0.9.38 <0.10.0",
  2808. "_id": "webvr-polyfill@0.9.40",
  2809. "_inCache": true,
  2810. "_installable": true,
  2811. "_location": "/webvr-polyfill",
  2812. "_nodeVersion": "8.6.0",
  2813. "_npmOperationalInternal": {
  2814. "host": "s3://npm-registry-packages",
  2815. "tmp": "tmp/webvr-polyfill-0.9.40.tgz_1507657755590_0.00047161197289824486"
  2816. },
  2817. "_npmUser": {
  2818. "email": "jsantell@gmail.com",
  2819. "name": "jsantell"
  2820. },
  2821. "_npmVersion": "5.3.0",
  2822. "_phantomChildren": {},
  2823. "_requested": {
  2824. "name": "webvr-polyfill",
  2825. "raw": "webvr-polyfill@^0.9.38",
  2826. "rawSpec": "^0.9.38",
  2827. "scope": null,
  2828. "spec": ">=0.9.38 <0.10.0",
  2829. "type": "range"
  2830. },
  2831. "_requiredBy": [
  2832. "/",
  2833. "/webvr-boilerplate"
  2834. ],
  2835. "_resolved": "https://registry.npmjs.org/webvr-polyfill/-/webvr-polyfill-0.9.40.tgz",
  2836. "_shasum": "2cfa0ec0e0cc6ba7238c73a09cba4952fff59a63",
  2837. "_shrinkwrap": null,
  2838. "_spec": "webvr-polyfill@^0.9.38",
  2839. "_where": "/Users/lincolnfrog/daydream/vrview",
  2840. "authors": [
  2841. "Boris Smus <boris@smus.com>",
  2842. "Brandon Jones <tojiro@gmail.com>",
  2843. "Jordan Santell <jordan@jsantell.com>"
  2844. ],
  2845. "bugs": {
  2846. "url": "https://github.com/googlevr/webvr-polyfill/issues"
  2847. },
  2848. "dependencies": {},
  2849. "description": "Use WebVR today, on mobile or desktop, without requiring a special browser build.",
  2850. "devDependencies": {
  2851. "chai": "^3.5.0",
  2852. "jsdom": "^9.12.0",
  2853. "mocha": "^3.2.0",
  2854. "semver": "^5.3.0",
  2855. "webpack": "^2.6.1",
  2856. "webpack-dev-server": "2.7.1"
  2857. },
  2858. "directories": {},
  2859. "dist": {
  2860. "integrity": "sha512-m7jhJHjFcUYPyPSNeGmly7a2h/cP7bARz0OZMoUn5SueVXEKeZ4P7bzbAUDBDvvqCsa5gHgM3PFIhYe13bqaWw==",
  2861. "shasum": "2cfa0ec0e0cc6ba7238c73a09cba4952fff59a63",
  2862. "tarball": "https://registry.npmjs.org/webvr-polyfill/-/webvr-polyfill-0.9.40.tgz"
  2863. },
  2864. "gitHead": "45828ffdb8c3e0f9bb90296d6039d3cc7909ba8e",
  2865. "homepage": "https://github.com/googlevr/webvr-polyfill",
  2866. "keywords": [
  2867. "vr",
  2868. "webvr"
  2869. ],
  2870. "license": "Apache-2.0",
  2871. "main": "src/node-entry",
  2872. "maintainers": [
  2873. {
  2874. "email": "jsantell@gmail.com",
  2875. "name": "jsantell"
  2876. },
  2877. {
  2878. "email": "tojiro@gmail.com",
  2879. "name": "toji"
  2880. },
  2881. {
  2882. "email": "boris@smus.com",
  2883. "name": "smus"
  2884. }
  2885. ],
  2886. "name": "webvr-polyfill",
  2887. "optionalDependencies": {},
  2888. "readme": "ERROR: No README data found!",
  2889. "repository": {
  2890. "type": "git",
  2891. "url": "git+https://github.com/googlevr/webvr-polyfill.git"
  2892. },
  2893. "scripts": {
  2894. "build": "webpack",
  2895. "start": "npm run watch",
  2896. "test": "mocha",
  2897. "watch": "webpack-dev-server"
  2898. },
  2899. "version": "0.9.40"
  2900. }
  2901. },{}],9:[function(_dereq_,module,exports){
  2902. /*
  2903. * Copyright 2015 Google Inc. All Rights Reserved.
  2904. * Licensed under the Apache License, Version 2.0 (the "License");
  2905. * you may not use this file except in compliance with the License.
  2906. * You may obtain a copy of the License at
  2907. *
  2908. * http://www.apache.org/licenses/LICENSE-2.0
  2909. *
  2910. * Unless required by applicable law or agreed to in writing, software
  2911. * distributed under the License is distributed on an "AS IS" BASIS,
  2912. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  2913. * See the License for the specific language governing permissions and
  2914. * limitations under the License.
  2915. */
  2916. var Util = _dereq_('./util.js');
  2917. var WakeLock = _dereq_('./wakelock.js');
  2918. // Start at a higher number to reduce chance of conflict.
  2919. var nextDisplayId = 1000;
  2920. var hasShowDeprecationWarning = false;
  2921. var defaultLeftBounds = [0, 0, 0.5, 1];
  2922. var defaultRightBounds = [0.5, 0, 0.5, 1];
  2923. /**
  2924. * The base class for all VR frame data.
  2925. */
  2926. function VRFrameData() {
  2927. this.leftProjectionMatrix = new Float32Array(16);
  2928. this.leftViewMatrix = new Float32Array(16);
  2929. this.rightProjectionMatrix = new Float32Array(16);
  2930. this.rightViewMatrix = new Float32Array(16);
  2931. this.pose = null;
  2932. };
  2933. /**
  2934. * The base class for all VR displays.
  2935. */
  2936. function VRDisplay() {
  2937. this.isPolyfilled = true;
  2938. this.displayId = nextDisplayId++;
  2939. this.displayName = 'webvr-polyfill displayName';
  2940. this.depthNear = 0.01;
  2941. this.depthFar = 10000.0;
  2942. this.isConnected = true;
  2943. this.isPresenting = false;
  2944. this.capabilities = {
  2945. hasPosition: false,
  2946. hasOrientation: false,
  2947. hasExternalDisplay: false,
  2948. canPresent: false,
  2949. maxLayers: 1
  2950. };
  2951. this.stageParameters = null;
  2952. // "Private" members.
  2953. this.waitingForPresent_ = false;
  2954. this.layer_ = null;
  2955. this.fullscreenElement_ = null;
  2956. this.fullscreenWrapper_ = null;
  2957. this.fullscreenElementCachedStyle_ = null;
  2958. this.fullscreenEventTarget_ = null;
  2959. this.fullscreenChangeHandler_ = null;
  2960. this.fullscreenErrorHandler_ = null;
  2961. this.wakelock_ = new WakeLock();
  2962. }
  2963. VRDisplay.prototype.getFrameData = function(frameData) {
  2964. // TODO: Technically this should retain it's value for the duration of a frame
  2965. // but I doubt that's practical to do in javascript.
  2966. return Util.frameDataFromPose(frameData, this.getPose(), this);
  2967. };
  2968. VRDisplay.prototype.getPose = function() {
  2969. // TODO: Technically this should retain it's value for the duration of a frame
  2970. // but I doubt that's practical to do in javascript.
  2971. return this.getImmediatePose();
  2972. };
  2973. VRDisplay.prototype.requestAnimationFrame = function(callback) {
  2974. return window.requestAnimationFrame(callback);
  2975. };
  2976. VRDisplay.prototype.cancelAnimationFrame = function(id) {
  2977. return window.cancelAnimationFrame(id);
  2978. };
  2979. VRDisplay.prototype.wrapForFullscreen = function(element) {
  2980. // Don't wrap in iOS.
  2981. if (Util.isIOS()) {
  2982. return element;
  2983. }
  2984. if (!this.fullscreenWrapper_) {
  2985. this.fullscreenWrapper_ = document.createElement('div');
  2986. var cssProperties = [
  2987. 'height: ' + Math.min(screen.height, screen.width) + 'px !important',
  2988. 'top: 0 !important',
  2989. 'left: 0 !important',
  2990. 'right: 0 !important',
  2991. 'border: 0',
  2992. 'margin: 0',
  2993. 'padding: 0',
  2994. 'z-index: 999999 !important',
  2995. 'position: fixed',
  2996. ];
  2997. this.fullscreenWrapper_.setAttribute('style', cssProperties.join('; ') + ';');
  2998. this.fullscreenWrapper_.classList.add('webvr-polyfill-fullscreen-wrapper');
  2999. }
  3000. if (this.fullscreenElement_ == element) {
  3001. return this.fullscreenWrapper_;
  3002. }
  3003. // Remove any previously applied wrappers
  3004. this.removeFullscreenWrapper();
  3005. this.fullscreenElement_ = element;
  3006. var parent = this.fullscreenElement_.parentElement;
  3007. parent.insertBefore(this.fullscreenWrapper_, this.fullscreenElement_);
  3008. parent.removeChild(this.fullscreenElement_);
  3009. this.fullscreenWrapper_.insertBefore(this.fullscreenElement_, this.fullscreenWrapper_.firstChild);
  3010. this.fullscreenElementCachedStyle_ = this.fullscreenElement_.getAttribute('style');
  3011. var self = this;
  3012. function applyFullscreenElementStyle() {
  3013. if (!self.fullscreenElement_) {
  3014. return;
  3015. }
  3016. var cssProperties = [
  3017. 'position: absolute',
  3018. 'top: 0',
  3019. 'left: 0',
  3020. 'width: ' + Math.max(screen.width, screen.height) + 'px',
  3021. 'height: ' + Math.min(screen.height, screen.width) + 'px',
  3022. 'border: 0',
  3023. 'margin: 0',
  3024. 'padding: 0',
  3025. ];
  3026. self.fullscreenElement_.setAttribute('style', cssProperties.join('; ') + ';');
  3027. }
  3028. applyFullscreenElementStyle();
  3029. return this.fullscreenWrapper_;
  3030. };
  3031. VRDisplay.prototype.removeFullscreenWrapper = function() {
  3032. if (!this.fullscreenElement_) {
  3033. return;
  3034. }
  3035. var element = this.fullscreenElement_;
  3036. if (this.fullscreenElementCachedStyle_) {
  3037. element.setAttribute('style', this.fullscreenElementCachedStyle_);
  3038. } else {
  3039. element.removeAttribute('style');
  3040. }
  3041. this.fullscreenElement_ = null;
  3042. this.fullscreenElementCachedStyle_ = null;
  3043. var parent = this.fullscreenWrapper_.parentElement;
  3044. this.fullscreenWrapper_.removeChild(element);
  3045. parent.insertBefore(element, this.fullscreenWrapper_);
  3046. parent.removeChild(this.fullscreenWrapper_);
  3047. return element;
  3048. };
  3049. VRDisplay.prototype.requestPresent = function(layers) {
  3050. var wasPresenting = this.isPresenting;
  3051. var self = this;
  3052. if (!(layers instanceof Array)) {
  3053. if (!hasShowDeprecationWarning) {
  3054. console.warn("Using a deprecated form of requestPresent. Should pass in an array of VRLayers.");
  3055. hasShowDeprecationWarning = true;
  3056. }
  3057. layers = [layers];
  3058. }
  3059. return new Promise(function(resolve, reject) {
  3060. if (!self.capabilities.canPresent) {
  3061. reject(new Error('VRDisplay is not capable of presenting.'));
  3062. return;
  3063. }
  3064. if (layers.length == 0 || layers.length > self.capabilities.maxLayers) {
  3065. reject(new Error('Invalid number of layers.'));
  3066. return;
  3067. }
  3068. var incomingLayer = layers[0];
  3069. if (!incomingLayer.source) {
  3070. /*
  3071. todo: figure out the correct behavior if the source is not provided.
  3072. see https://github.com/w3c/webvr/issues/58
  3073. */
  3074. resolve();
  3075. return;
  3076. }
  3077. var leftBounds = incomingLayer.leftBounds || defaultLeftBounds;
  3078. var rightBounds = incomingLayer.rightBounds || defaultRightBounds;
  3079. if (wasPresenting) {
  3080. // Already presenting, just changing configuration
  3081. var layer = self.layer_;
  3082. if (layer.source !== incomingLayer.source) {
  3083. layer.source = incomingLayer.source;
  3084. }
  3085. for (var i = 0; i < 4; i++) {
  3086. layer.leftBounds[i] = leftBounds[i];
  3087. layer.rightBounds[i] = rightBounds[i];
  3088. }
  3089. resolve();
  3090. return;
  3091. }
  3092. // Was not already presenting.
  3093. self.layer_ = {
  3094. predistorted: incomingLayer.predistorted,
  3095. source: incomingLayer.source,
  3096. leftBounds: leftBounds.slice(0),
  3097. rightBounds: rightBounds.slice(0)
  3098. };
  3099. self.waitingForPresent_ = false;
  3100. if (self.layer_ && self.layer_.source) {
  3101. var fullscreenElement = self.wrapForFullscreen(self.layer_.source);
  3102. var onFullscreenChange = function() {
  3103. var actualFullscreenElement = Util.getFullscreenElement();
  3104. self.isPresenting = (fullscreenElement === actualFullscreenElement);
  3105. if (self.isPresenting) {
  3106. if (screen.orientation && screen.orientation.lock) {
  3107. screen.orientation.lock('landscape-primary').catch(function(error){
  3108. console.error('screen.orientation.lock() failed due to', error.message)
  3109. });
  3110. }
  3111. self.waitingForPresent_ = false;
  3112. self.beginPresent_();
  3113. resolve();
  3114. } else {
  3115. if (screen.orientation && screen.orientation.unlock) {
  3116. screen.orientation.unlock();
  3117. }
  3118. self.removeFullscreenWrapper();
  3119. self.wakelock_.release();
  3120. self.endPresent_();
  3121. self.removeFullscreenListeners_();
  3122. }
  3123. self.fireVRDisplayPresentChange_();
  3124. }
  3125. var onFullscreenError = function() {
  3126. if (!self.waitingForPresent_) {
  3127. return;
  3128. }
  3129. self.removeFullscreenWrapper();
  3130. self.removeFullscreenListeners_();
  3131. self.wakelock_.release();
  3132. self.waitingForPresent_ = false;
  3133. self.isPresenting = false;
  3134. reject(new Error('Unable to present.'));
  3135. }
  3136. self.addFullscreenListeners_(fullscreenElement,
  3137. onFullscreenChange, onFullscreenError);
  3138. if (Util.requestFullscreen(fullscreenElement)) {
  3139. self.wakelock_.request();
  3140. self.waitingForPresent_ = true;
  3141. } else if (Util.isIOS() || Util.isWebViewAndroid()) {
  3142. // *sigh* Just fake it.
  3143. self.wakelock_.request();
  3144. self.isPresenting = true;
  3145. self.beginPresent_();
  3146. self.fireVRDisplayPresentChange_();
  3147. resolve();
  3148. }
  3149. }
  3150. if (!self.waitingForPresent_ && !Util.isIOS()) {
  3151. Util.exitFullscreen();
  3152. reject(new Error('Unable to present.'));
  3153. }
  3154. });
  3155. };
  3156. VRDisplay.prototype.exitPresent = function() {
  3157. var wasPresenting = this.isPresenting;
  3158. var self = this;
  3159. this.isPresenting = false;
  3160. this.layer_ = null;
  3161. this.wakelock_.release();
  3162. return new Promise(function(resolve, reject) {
  3163. if (wasPresenting) {
  3164. if (!Util.exitFullscreen() && Util.isIOS()) {
  3165. self.endPresent_();
  3166. self.fireVRDisplayPresentChange_();
  3167. }
  3168. if (Util.isWebViewAndroid()) {
  3169. self.removeFullscreenWrapper();
  3170. self.removeFullscreenListeners_();
  3171. self.endPresent_();
  3172. self.fireVRDisplayPresentChange_();
  3173. }
  3174. resolve();
  3175. } else {
  3176. reject(new Error('Was not presenting to VRDisplay.'));
  3177. }
  3178. });
  3179. };
  3180. VRDisplay.prototype.getLayers = function() {
  3181. if (this.layer_) {
  3182. return [this.layer_];
  3183. }
  3184. return [];
  3185. };
  3186. VRDisplay.prototype.fireVRDisplayPresentChange_ = function() {
  3187. // Important: unfortunately we cannot have full spec compliance here.
  3188. // CustomEvent custom fields all go under e.detail (so the VRDisplay ends up
  3189. // being e.detail.display, instead of e.display as per WebVR spec).
  3190. var event = new CustomEvent('vrdisplaypresentchange', {detail: {display: this}});
  3191. window.dispatchEvent(event);
  3192. };
  3193. VRDisplay.prototype.fireVRDisplayConnect_ = function() {
  3194. // Important: unfortunately we cannot have full spec compliance here.
  3195. // CustomEvent custom fields all go under e.detail (so the VRDisplay ends up
  3196. // being e.detail.display, instead of e.display as per WebVR spec).
  3197. var event = new CustomEvent('vrdisplayconnect', {detail: {display: this}});
  3198. window.dispatchEvent(event);
  3199. };
  3200. VRDisplay.prototype.addFullscreenListeners_ = function(element, changeHandler, errorHandler) {
  3201. this.removeFullscreenListeners_();
  3202. this.fullscreenEventTarget_ = element;
  3203. this.fullscreenChangeHandler_ = changeHandler;
  3204. this.fullscreenErrorHandler_ = errorHandler;
  3205. if (changeHandler) {
  3206. if (document.fullscreenEnabled) {
  3207. element.addEventListener('fullscreenchange', changeHandler, false);
  3208. } else if (document.webkitFullscreenEnabled) {
  3209. element.addEventListener('webkitfullscreenchange', changeHandler, false);
  3210. } else if (document.mozFullScreenEnabled) {
  3211. document.addEventListener('mozfullscreenchange', changeHandler, false);
  3212. } else if (document.msFullscreenEnabled) {
  3213. element.addEventListener('msfullscreenchange', changeHandler, false);
  3214. }
  3215. }
  3216. if (errorHandler) {
  3217. if (document.fullscreenEnabled) {
  3218. element.addEventListener('fullscreenerror', errorHandler, false);
  3219. } else if (document.webkitFullscreenEnabled) {
  3220. element.addEventListener('webkitfullscreenerror', errorHandler, false);
  3221. } else if (document.mozFullScreenEnabled) {
  3222. document.addEventListener('mozfullscreenerror', errorHandler, false);
  3223. } else if (document.msFullscreenEnabled) {
  3224. element.addEventListener('msfullscreenerror', errorHandler, false);
  3225. }
  3226. }
  3227. };
  3228. VRDisplay.prototype.removeFullscreenListeners_ = function() {
  3229. if (!this.fullscreenEventTarget_)
  3230. return;
  3231. var element = this.fullscreenEventTarget_;
  3232. if (this.fullscreenChangeHandler_) {
  3233. var changeHandler = this.fullscreenChangeHandler_;
  3234. element.removeEventListener('fullscreenchange', changeHandler, false);
  3235. element.removeEventListener('webkitfullscreenchange', changeHandler, false);
  3236. document.removeEventListener('mozfullscreenchange', changeHandler, false);
  3237. element.removeEventListener('msfullscreenchange', changeHandler, false);
  3238. }
  3239. if (this.fullscreenErrorHandler_) {
  3240. var errorHandler = this.fullscreenErrorHandler_;
  3241. element.removeEventListener('fullscreenerror', errorHandler, false);
  3242. element.removeEventListener('webkitfullscreenerror', errorHandler, false);
  3243. document.removeEventListener('mozfullscreenerror', errorHandler, false);
  3244. element.removeEventListener('msfullscreenerror', errorHandler, false);
  3245. }
  3246. this.fullscreenEventTarget_ = null;
  3247. this.fullscreenChangeHandler_ = null;
  3248. this.fullscreenErrorHandler_ = null;
  3249. };
  3250. VRDisplay.prototype.beginPresent_ = function() {
  3251. // Override to add custom behavior when presentation begins.
  3252. };
  3253. VRDisplay.prototype.endPresent_ = function() {
  3254. // Override to add custom behavior when presentation ends.
  3255. };
  3256. VRDisplay.prototype.submitFrame = function(pose) {
  3257. // Override to add custom behavior for frame submission.
  3258. };
  3259. VRDisplay.prototype.getEyeParameters = function(whichEye) {
  3260. // Override to return accurate eye parameters if canPresent is true.
  3261. return null;
  3262. };
  3263. /*
  3264. * Deprecated classes
  3265. */
  3266. /**
  3267. * The base class for all VR devices. (Deprecated)
  3268. */
  3269. function VRDevice() {
  3270. this.isPolyfilled = true;
  3271. this.hardwareUnitId = 'webvr-polyfill hardwareUnitId';
  3272. this.deviceId = 'webvr-polyfill deviceId';
  3273. this.deviceName = 'webvr-polyfill deviceName';
  3274. }
  3275. /**
  3276. * The base class for all VR HMD devices. (Deprecated)
  3277. */
  3278. function HMDVRDevice() {
  3279. }
  3280. HMDVRDevice.prototype = new VRDevice();
  3281. /**
  3282. * The base class for all VR position sensor devices. (Deprecated)
  3283. */
  3284. function PositionSensorVRDevice() {
  3285. }
  3286. PositionSensorVRDevice.prototype = new VRDevice();
  3287. module.exports.VRFrameData = VRFrameData;
  3288. module.exports.VRDisplay = VRDisplay;
  3289. module.exports.VRDevice = VRDevice;
  3290. module.exports.HMDVRDevice = HMDVRDevice;
  3291. module.exports.PositionSensorVRDevice = PositionSensorVRDevice;
  3292. },{"./util.js":29,"./wakelock.js":31}],10:[function(_dereq_,module,exports){
  3293. /*
  3294. * Copyright 2016 Google Inc. All Rights Reserved.
  3295. * Licensed under the Apache License, Version 2.0 (the "License");
  3296. * you may not use this file except in compliance with the License.
  3297. * You may obtain a copy of the License at
  3298. *
  3299. * http://www.apache.org/licenses/LICENSE-2.0
  3300. *
  3301. * Unless required by applicable law or agreed to in writing, software
  3302. * distributed under the License is distributed on an "AS IS" BASIS,
  3303. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  3304. * See the License for the specific language governing permissions and
  3305. * limitations under the License.
  3306. */
  3307. var CardboardUI = _dereq_('./cardboard-ui.js');
  3308. var Util = _dereq_('./util.js');
  3309. var WGLUPreserveGLState = _dereq_('./deps/wglu-preserve-state.js');
  3310. var distortionVS = [
  3311. 'attribute vec2 position;',
  3312. 'attribute vec3 texCoord;',
  3313. 'varying vec2 vTexCoord;',
  3314. 'uniform vec4 viewportOffsetScale[2];',
  3315. 'void main() {',
  3316. ' vec4 viewport = viewportOffsetScale[int(texCoord.z)];',
  3317. ' vTexCoord = (texCoord.xy * viewport.zw) + viewport.xy;',
  3318. ' gl_Position = vec4( position, 1.0, 1.0 );',
  3319. '}',
  3320. ].join('\n');
  3321. var distortionFS = [
  3322. 'precision mediump float;',
  3323. 'uniform sampler2D diffuse;',
  3324. 'varying vec2 vTexCoord;',
  3325. 'void main() {',
  3326. ' gl_FragColor = texture2D(diffuse, vTexCoord);',
  3327. '}',
  3328. ].join('\n');
  3329. /**
  3330. * A mesh-based distorter.
  3331. */
  3332. function CardboardDistorter(gl) {
  3333. this.gl = gl;
  3334. this.ctxAttribs = gl.getContextAttributes();
  3335. this.meshWidth = 20;
  3336. this.meshHeight = 20;
  3337. this.bufferScale = window.WebVRConfig.BUFFER_SCALE;
  3338. this.bufferWidth = gl.drawingBufferWidth;
  3339. this.bufferHeight = gl.drawingBufferHeight;
  3340. // Patching support
  3341. this.realBindFramebuffer = gl.bindFramebuffer;
  3342. this.realEnable = gl.enable;
  3343. this.realDisable = gl.disable;
  3344. this.realColorMask = gl.colorMask;
  3345. this.realClearColor = gl.clearColor;
  3346. this.realViewport = gl.viewport;
  3347. if (!Util.isIOS()) {
  3348. this.realCanvasWidth = Object.getOwnPropertyDescriptor(gl.canvas.__proto__, 'width');
  3349. this.realCanvasHeight = Object.getOwnPropertyDescriptor(gl.canvas.__proto__, 'height');
  3350. }
  3351. this.isPatched = false;
  3352. // State tracking
  3353. this.lastBoundFramebuffer = null;
  3354. this.cullFace = false;
  3355. this.depthTest = false;
  3356. this.blend = false;
  3357. this.scissorTest = false;
  3358. this.stencilTest = false;
  3359. this.viewport = [0, 0, 0, 0];
  3360. this.colorMask = [true, true, true, true];
  3361. this.clearColor = [0, 0, 0, 0];
  3362. this.attribs = {
  3363. position: 0,
  3364. texCoord: 1
  3365. };
  3366. this.program = Util.linkProgram(gl, distortionVS, distortionFS, this.attribs);
  3367. this.uniforms = Util.getProgramUniforms(gl, this.program);
  3368. this.viewportOffsetScale = new Float32Array(8);
  3369. this.setTextureBounds();
  3370. this.vertexBuffer = gl.createBuffer();
  3371. this.indexBuffer = gl.createBuffer();
  3372. this.indexCount = 0;
  3373. this.renderTarget = gl.createTexture();
  3374. this.framebuffer = gl.createFramebuffer();
  3375. this.depthStencilBuffer = null;
  3376. this.depthBuffer = null;
  3377. this.stencilBuffer = null;
  3378. if (this.ctxAttribs.depth && this.ctxAttribs.stencil) {
  3379. this.depthStencilBuffer = gl.createRenderbuffer();
  3380. } else if (this.ctxAttribs.depth) {
  3381. this.depthBuffer = gl.createRenderbuffer();
  3382. } else if (this.ctxAttribs.stencil) {
  3383. this.stencilBuffer = gl.createRenderbuffer();
  3384. }
  3385. this.patch();
  3386. this.onResize();
  3387. if (!window.WebVRConfig.CARDBOARD_UI_DISABLED) {
  3388. this.cardboardUI = new CardboardUI(gl);
  3389. }
  3390. };
  3391. /**
  3392. * Tears down all the resources created by the distorter and removes any
  3393. * patches.
  3394. */
  3395. CardboardDistorter.prototype.destroy = function() {
  3396. var gl = this.gl;
  3397. this.unpatch();
  3398. gl.deleteProgram(this.program);
  3399. gl.deleteBuffer(this.vertexBuffer);
  3400. gl.deleteBuffer(this.indexBuffer);
  3401. gl.deleteTexture(this.renderTarget);
  3402. gl.deleteFramebuffer(this.framebuffer);
  3403. if (this.depthStencilBuffer) {
  3404. gl.deleteRenderbuffer(this.depthStencilBuffer);
  3405. }
  3406. if (this.depthBuffer) {
  3407. gl.deleteRenderbuffer(this.depthBuffer);
  3408. }
  3409. if (this.stencilBuffer) {
  3410. gl.deleteRenderbuffer(this.stencilBuffer);
  3411. }
  3412. if (this.cardboardUI) {
  3413. this.cardboardUI.destroy();
  3414. }
  3415. };
  3416. /**
  3417. * Resizes the backbuffer to match the canvas width and height.
  3418. */
  3419. CardboardDistorter.prototype.onResize = function() {
  3420. var gl = this.gl;
  3421. var self = this;
  3422. var glState = [
  3423. gl.RENDERBUFFER_BINDING,
  3424. gl.TEXTURE_BINDING_2D, gl.TEXTURE0
  3425. ];
  3426. WGLUPreserveGLState(gl, glState, function(gl) {
  3427. // Bind real backbuffer and clear it once. We don't need to clear it again
  3428. // after that because we're overwriting the same area every frame.
  3429. self.realBindFramebuffer.call(gl, gl.FRAMEBUFFER, null);
  3430. // Put things in a good state
  3431. if (self.scissorTest) { self.realDisable.call(gl, gl.SCISSOR_TEST); }
  3432. self.realColorMask.call(gl, true, true, true, true);
  3433. self.realViewport.call(gl, 0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
  3434. self.realClearColor.call(gl, 0, 0, 0, 1);
  3435. gl.clear(gl.COLOR_BUFFER_BIT);
  3436. // Now bind and resize the fake backbuffer
  3437. self.realBindFramebuffer.call(gl, gl.FRAMEBUFFER, self.framebuffer);
  3438. gl.bindTexture(gl.TEXTURE_2D, self.renderTarget);
  3439. gl.texImage2D(gl.TEXTURE_2D, 0, self.ctxAttribs.alpha ? gl.RGBA : gl.RGB,
  3440. self.bufferWidth, self.bufferHeight, 0,
  3441. self.ctxAttribs.alpha ? gl.RGBA : gl.RGB, gl.UNSIGNED_BYTE, null);
  3442. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  3443. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  3444. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  3445. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  3446. gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, self.renderTarget, 0);
  3447. if (self.ctxAttribs.depth && self.ctxAttribs.stencil) {
  3448. gl.bindRenderbuffer(gl.RENDERBUFFER, self.depthStencilBuffer);
  3449. gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL,
  3450. self.bufferWidth, self.bufferHeight);
  3451. gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT,
  3452. gl.RENDERBUFFER, self.depthStencilBuffer);
  3453. } else if (self.ctxAttribs.depth) {
  3454. gl.bindRenderbuffer(gl.RENDERBUFFER, self.depthBuffer);
  3455. gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16,
  3456. self.bufferWidth, self.bufferHeight);
  3457. gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT,
  3458. gl.RENDERBUFFER, self.depthBuffer);
  3459. } else if (self.ctxAttribs.stencil) {
  3460. gl.bindRenderbuffer(gl.RENDERBUFFER, self.stencilBuffer);
  3461. gl.renderbufferStorage(gl.RENDERBUFFER, gl.STENCIL_INDEX8,
  3462. self.bufferWidth, self.bufferHeight);
  3463. gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT,
  3464. gl.RENDERBUFFER, self.stencilBuffer);
  3465. }
  3466. if (!gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE) {
  3467. console.error('Framebuffer incomplete!');
  3468. }
  3469. self.realBindFramebuffer.call(gl, gl.FRAMEBUFFER, self.lastBoundFramebuffer);
  3470. if (self.scissorTest) { self.realEnable.call(gl, gl.SCISSOR_TEST); }
  3471. self.realColorMask.apply(gl, self.colorMask);
  3472. self.realViewport.apply(gl, self.viewport);
  3473. self.realClearColor.apply(gl, self.clearColor);
  3474. });
  3475. if (this.cardboardUI) {
  3476. this.cardboardUI.onResize();
  3477. }
  3478. };
  3479. CardboardDistorter.prototype.patch = function() {
  3480. if (this.isPatched) {
  3481. return;
  3482. }
  3483. var self = this;
  3484. var canvas = this.gl.canvas;
  3485. var gl = this.gl;
  3486. if (!Util.isIOS()) {
  3487. canvas.width = Util.getScreenWidth() * this.bufferScale;
  3488. canvas.height = Util.getScreenHeight() * this.bufferScale;
  3489. Object.defineProperty(canvas, 'width', {
  3490. configurable: true,
  3491. enumerable: true,
  3492. get: function() {
  3493. return self.bufferWidth;
  3494. },
  3495. set: function(value) {
  3496. self.bufferWidth = value;
  3497. self.realCanvasWidth.set.call(canvas, value);
  3498. self.onResize();
  3499. }
  3500. });
  3501. Object.defineProperty(canvas, 'height', {
  3502. configurable: true,
  3503. enumerable: true,
  3504. get: function() {
  3505. return self.bufferHeight;
  3506. },
  3507. set: function(value) {
  3508. self.bufferHeight = value;
  3509. self.realCanvasHeight.set.call(canvas, value);
  3510. self.onResize();
  3511. }
  3512. });
  3513. }
  3514. this.lastBoundFramebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING);
  3515. if (this.lastBoundFramebuffer == null) {
  3516. this.lastBoundFramebuffer = this.framebuffer;
  3517. this.gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
  3518. }
  3519. this.gl.bindFramebuffer = function(target, framebuffer) {
  3520. self.lastBoundFramebuffer = framebuffer ? framebuffer : self.framebuffer;
  3521. // Silently make calls to bind the default framebuffer bind ours instead.
  3522. self.realBindFramebuffer.call(gl, target, self.lastBoundFramebuffer);
  3523. };
  3524. this.cullFace = gl.getParameter(gl.CULL_FACE);
  3525. this.depthTest = gl.getParameter(gl.DEPTH_TEST);
  3526. this.blend = gl.getParameter(gl.BLEND);
  3527. this.scissorTest = gl.getParameter(gl.SCISSOR_TEST);
  3528. this.stencilTest = gl.getParameter(gl.STENCIL_TEST);
  3529. gl.enable = function(pname) {
  3530. switch (pname) {
  3531. case gl.CULL_FACE: self.cullFace = true; break;
  3532. case gl.DEPTH_TEST: self.depthTest = true; break;
  3533. case gl.BLEND: self.blend = true; break;
  3534. case gl.SCISSOR_TEST: self.scissorTest = true; break;
  3535. case gl.STENCIL_TEST: self.stencilTest = true; break;
  3536. }
  3537. self.realEnable.call(gl, pname);
  3538. };
  3539. gl.disable = function(pname) {
  3540. switch (pname) {
  3541. case gl.CULL_FACE: self.cullFace = false; break;
  3542. case gl.DEPTH_TEST: self.depthTest = false; break;
  3543. case gl.BLEND: self.blend = false; break;
  3544. case gl.SCISSOR_TEST: self.scissorTest = false; break;
  3545. case gl.STENCIL_TEST: self.stencilTest = false; break;
  3546. }
  3547. self.realDisable.call(gl, pname);
  3548. };
  3549. this.colorMask = gl.getParameter(gl.COLOR_WRITEMASK);
  3550. gl.colorMask = function(r, g, b, a) {
  3551. self.colorMask[0] = r;
  3552. self.colorMask[1] = g;
  3553. self.colorMask[2] = b;
  3554. self.colorMask[3] = a;
  3555. self.realColorMask.call(gl, r, g, b, a);
  3556. };
  3557. this.clearColor = gl.getParameter(gl.COLOR_CLEAR_VALUE);
  3558. gl.clearColor = function(r, g, b, a) {
  3559. self.clearColor[0] = r;
  3560. self.clearColor[1] = g;
  3561. self.clearColor[2] = b;
  3562. self.clearColor[3] = a;
  3563. self.realClearColor.call(gl, r, g, b, a);
  3564. };
  3565. this.viewport = gl.getParameter(gl.VIEWPORT);
  3566. gl.viewport = function(x, y, w, h) {
  3567. self.viewport[0] = x;
  3568. self.viewport[1] = y;
  3569. self.viewport[2] = w;
  3570. self.viewport[3] = h;
  3571. self.realViewport.call(gl, x, y, w, h);
  3572. };
  3573. this.isPatched = true;
  3574. Util.safariCssSizeWorkaround(canvas);
  3575. };
  3576. CardboardDistorter.prototype.unpatch = function() {
  3577. if (!this.isPatched) {
  3578. return;
  3579. }
  3580. var gl = this.gl;
  3581. var canvas = this.gl.canvas;
  3582. if (!Util.isIOS()) {
  3583. Object.defineProperty(canvas, 'width', this.realCanvasWidth);
  3584. Object.defineProperty(canvas, 'height', this.realCanvasHeight);
  3585. }
  3586. canvas.width = this.bufferWidth;
  3587. canvas.height = this.bufferHeight;
  3588. gl.bindFramebuffer = this.realBindFramebuffer;
  3589. gl.enable = this.realEnable;
  3590. gl.disable = this.realDisable;
  3591. gl.colorMask = this.realColorMask;
  3592. gl.clearColor = this.realClearColor;
  3593. gl.viewport = this.realViewport;
  3594. // Check to see if our fake backbuffer is bound and bind the real backbuffer
  3595. // if that's the case.
  3596. if (this.lastBoundFramebuffer == this.framebuffer) {
  3597. gl.bindFramebuffer(gl.FRAMEBUFFER, null);
  3598. }
  3599. this.isPatched = false;
  3600. setTimeout(function() {
  3601. Util.safariCssSizeWorkaround(canvas);
  3602. }, 1);
  3603. };
  3604. CardboardDistorter.prototype.setTextureBounds = function(leftBounds, rightBounds) {
  3605. if (!leftBounds) {
  3606. leftBounds = [0, 0, 0.5, 1];
  3607. }
  3608. if (!rightBounds) {
  3609. rightBounds = [0.5, 0, 0.5, 1];
  3610. }
  3611. // Left eye
  3612. this.viewportOffsetScale[0] = leftBounds[0]; // X
  3613. this.viewportOffsetScale[1] = leftBounds[1]; // Y
  3614. this.viewportOffsetScale[2] = leftBounds[2]; // Width
  3615. this.viewportOffsetScale[3] = leftBounds[3]; // Height
  3616. // Right eye
  3617. this.viewportOffsetScale[4] = rightBounds[0]; // X
  3618. this.viewportOffsetScale[5] = rightBounds[1]; // Y
  3619. this.viewportOffsetScale[6] = rightBounds[2]; // Width
  3620. this.viewportOffsetScale[7] = rightBounds[3]; // Height
  3621. };
  3622. /**
  3623. * Performs distortion pass on the injected backbuffer, rendering it to the real
  3624. * backbuffer.
  3625. */
  3626. CardboardDistorter.prototype.submitFrame = function() {
  3627. var gl = this.gl;
  3628. var self = this;
  3629. var glState = [];
  3630. if (!window.WebVRConfig.DIRTY_SUBMIT_FRAME_BINDINGS) {
  3631. glState.push(
  3632. gl.CURRENT_PROGRAM,
  3633. gl.ARRAY_BUFFER_BINDING,
  3634. gl.ELEMENT_ARRAY_BUFFER_BINDING,
  3635. gl.TEXTURE_BINDING_2D, gl.TEXTURE0
  3636. );
  3637. }
  3638. WGLUPreserveGLState(gl, glState, function(gl) {
  3639. // Bind the real default framebuffer
  3640. self.realBindFramebuffer.call(gl, gl.FRAMEBUFFER, null);
  3641. // Make sure the GL state is in a good place
  3642. if (self.cullFace) { self.realDisable.call(gl, gl.CULL_FACE); }
  3643. if (self.depthTest) { self.realDisable.call(gl, gl.DEPTH_TEST); }
  3644. if (self.blend) { self.realDisable.call(gl, gl.BLEND); }
  3645. if (self.scissorTest) { self.realDisable.call(gl, gl.SCISSOR_TEST); }
  3646. if (self.stencilTest) { self.realDisable.call(gl, gl.STENCIL_TEST); }
  3647. self.realColorMask.call(gl, true, true, true, true);
  3648. self.realViewport.call(gl, 0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
  3649. // If the backbuffer has an alpha channel clear every frame so the page
  3650. // doesn't show through.
  3651. if (self.ctxAttribs.alpha || Util.isIOS()) {
  3652. self.realClearColor.call(gl, 0, 0, 0, 1);
  3653. gl.clear(gl.COLOR_BUFFER_BIT);
  3654. }
  3655. // Bind distortion program and mesh
  3656. gl.useProgram(self.program);
  3657. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.indexBuffer);
  3658. gl.bindBuffer(gl.ARRAY_BUFFER, self.vertexBuffer);
  3659. gl.enableVertexAttribArray(self.attribs.position);
  3660. gl.enableVertexAttribArray(self.attribs.texCoord);
  3661. gl.vertexAttribPointer(self.attribs.position, 2, gl.FLOAT, false, 20, 0);
  3662. gl.vertexAttribPointer(self.attribs.texCoord, 3, gl.FLOAT, false, 20, 8);
  3663. gl.activeTexture(gl.TEXTURE0);
  3664. gl.uniform1i(self.uniforms.diffuse, 0);
  3665. gl.bindTexture(gl.TEXTURE_2D, self.renderTarget);
  3666. gl.uniform4fv(self.uniforms.viewportOffsetScale, self.viewportOffsetScale);
  3667. // Draws both eyes
  3668. gl.drawElements(gl.TRIANGLES, self.indexCount, gl.UNSIGNED_SHORT, 0);
  3669. if (self.cardboardUI) {
  3670. self.cardboardUI.renderNoState();
  3671. }
  3672. // Bind the fake default framebuffer again
  3673. self.realBindFramebuffer.call(self.gl, gl.FRAMEBUFFER, self.framebuffer);
  3674. // If preserveDrawingBuffer == false clear the framebuffer
  3675. if (!self.ctxAttribs.preserveDrawingBuffer) {
  3676. self.realClearColor.call(gl, 0, 0, 0, 0);
  3677. gl.clear(gl.COLOR_BUFFER_BIT);
  3678. }
  3679. if (!window.WebVRConfig.DIRTY_SUBMIT_FRAME_BINDINGS) {
  3680. self.realBindFramebuffer.call(gl, gl.FRAMEBUFFER, self.lastBoundFramebuffer);
  3681. }
  3682. // Restore state
  3683. if (self.cullFace) { self.realEnable.call(gl, gl.CULL_FACE); }
  3684. if (self.depthTest) { self.realEnable.call(gl, gl.DEPTH_TEST); }
  3685. if (self.blend) { self.realEnable.call(gl, gl.BLEND); }
  3686. if (self.scissorTest) { self.realEnable.call(gl, gl.SCISSOR_TEST); }
  3687. if (self.stencilTest) { self.realEnable.call(gl, gl.STENCIL_TEST); }
  3688. self.realColorMask.apply(gl, self.colorMask);
  3689. self.realViewport.apply(gl, self.viewport);
  3690. if (self.ctxAttribs.alpha || !self.ctxAttribs.preserveDrawingBuffer) {
  3691. self.realClearColor.apply(gl, self.clearColor);
  3692. }
  3693. });
  3694. // Workaround for the fact that Safari doesn't allow us to patch the canvas
  3695. // width and height correctly. After each submit frame check to see what the
  3696. // real backbuffer size has been set to and resize the fake backbuffer size
  3697. // to match.
  3698. if (Util.isIOS()) {
  3699. var canvas = gl.canvas;
  3700. if (canvas.width != self.bufferWidth || canvas.height != self.bufferHeight) {
  3701. self.bufferWidth = canvas.width;
  3702. self.bufferHeight = canvas.height;
  3703. self.onResize();
  3704. }
  3705. }
  3706. };
  3707. /**
  3708. * Call when the deviceInfo has changed. At this point we need
  3709. * to re-calculate the distortion mesh.
  3710. */
  3711. CardboardDistorter.prototype.updateDeviceInfo = function(deviceInfo) {
  3712. var gl = this.gl;
  3713. var self = this;
  3714. var glState = [gl.ARRAY_BUFFER_BINDING, gl.ELEMENT_ARRAY_BUFFER_BINDING];
  3715. WGLUPreserveGLState(gl, glState, function(gl) {
  3716. var vertices = self.computeMeshVertices_(self.meshWidth, self.meshHeight, deviceInfo);
  3717. gl.bindBuffer(gl.ARRAY_BUFFER, self.vertexBuffer);
  3718. gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
  3719. // Indices don't change based on device parameters, so only compute once.
  3720. if (!self.indexCount) {
  3721. var indices = self.computeMeshIndices_(self.meshWidth, self.meshHeight);
  3722. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.indexBuffer);
  3723. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
  3724. self.indexCount = indices.length;
  3725. }
  3726. });
  3727. };
  3728. /**
  3729. * Build the distortion mesh vertices.
  3730. * Based on code from the Unity cardboard plugin.
  3731. */
  3732. CardboardDistorter.prototype.computeMeshVertices_ = function(width, height, deviceInfo) {
  3733. var vertices = new Float32Array(2 * width * height * 5);
  3734. var lensFrustum = deviceInfo.getLeftEyeVisibleTanAngles();
  3735. var noLensFrustum = deviceInfo.getLeftEyeNoLensTanAngles();
  3736. var viewport = deviceInfo.getLeftEyeVisibleScreenRect(noLensFrustum);
  3737. var vidx = 0;
  3738. var iidx = 0;
  3739. for (var e = 0; e < 2; e++) {
  3740. for (var j = 0; j < height; j++) {
  3741. for (var i = 0; i < width; i++, vidx++) {
  3742. var u = i / (width - 1);
  3743. var v = j / (height - 1);
  3744. // Grid points regularly spaced in StreoScreen, and barrel distorted in
  3745. // the mesh.
  3746. var s = u;
  3747. var t = v;
  3748. var x = Util.lerp(lensFrustum[0], lensFrustum[2], u);
  3749. var y = Util.lerp(lensFrustum[3], lensFrustum[1], v);
  3750. var d = Math.sqrt(x * x + y * y);
  3751. var r = deviceInfo.distortion.distortInverse(d);
  3752. var p = x * r / d;
  3753. var q = y * r / d;
  3754. u = (p - noLensFrustum[0]) / (noLensFrustum[2] - noLensFrustum[0]);
  3755. v = (q - noLensFrustum[3]) / (noLensFrustum[1] - noLensFrustum[3]);
  3756. // Convert u,v to mesh screen coordinates.
  3757. var aspect = deviceInfo.device.widthMeters / deviceInfo.device.heightMeters;
  3758. // FIXME: The original Unity plugin multiplied U by the aspect ratio
  3759. // and didn't multiply either value by 2, but that seems to get it
  3760. // really close to correct looking for me. I hate this kind of "Don't
  3761. // know why it works" code though, and wold love a more logical
  3762. // explanation of what needs to happen here.
  3763. u = (viewport.x + u * viewport.width - 0.5) * 2.0; //* aspect;
  3764. v = (viewport.y + v * viewport.height - 0.5) * 2.0;
  3765. vertices[(vidx * 5) + 0] = u; // position.x
  3766. vertices[(vidx * 5) + 1] = v; // position.y
  3767. vertices[(vidx * 5) + 2] = s; // texCoord.x
  3768. vertices[(vidx * 5) + 3] = t; // texCoord.y
  3769. vertices[(vidx * 5) + 4] = e; // texCoord.z (viewport index)
  3770. }
  3771. }
  3772. var w = lensFrustum[2] - lensFrustum[0];
  3773. lensFrustum[0] = -(w + lensFrustum[0]);
  3774. lensFrustum[2] = w - lensFrustum[2];
  3775. w = noLensFrustum[2] - noLensFrustum[0];
  3776. noLensFrustum[0] = -(w + noLensFrustum[0]);
  3777. noLensFrustum[2] = w - noLensFrustum[2];
  3778. viewport.x = 1 - (viewport.x + viewport.width);
  3779. }
  3780. return vertices;
  3781. }
  3782. /**
  3783. * Build the distortion mesh indices.
  3784. * Based on code from the Unity cardboard plugin.
  3785. */
  3786. CardboardDistorter.prototype.computeMeshIndices_ = function(width, height) {
  3787. var indices = new Uint16Array(2 * (width - 1) * (height - 1) * 6);
  3788. var halfwidth = width / 2;
  3789. var halfheight = height / 2;
  3790. var vidx = 0;
  3791. var iidx = 0;
  3792. for (var e = 0; e < 2; e++) {
  3793. for (var j = 0; j < height; j++) {
  3794. for (var i = 0; i < width; i++, vidx++) {
  3795. if (i == 0 || j == 0)
  3796. continue;
  3797. // Build a quad. Lower right and upper left quadrants have quads with
  3798. // the triangle diagonal flipped to get the vignette to interpolate
  3799. // correctly.
  3800. if ((i <= halfwidth) == (j <= halfheight)) {
  3801. // Quad diagonal lower left to upper right.
  3802. indices[iidx++] = vidx;
  3803. indices[iidx++] = vidx - width - 1;
  3804. indices[iidx++] = vidx - width;
  3805. indices[iidx++] = vidx - width - 1;
  3806. indices[iidx++] = vidx;
  3807. indices[iidx++] = vidx - 1;
  3808. } else {
  3809. // Quad diagonal upper left to lower right.
  3810. indices[iidx++] = vidx - 1;
  3811. indices[iidx++] = vidx - width;
  3812. indices[iidx++] = vidx;
  3813. indices[iidx++] = vidx - width;
  3814. indices[iidx++] = vidx - 1;
  3815. indices[iidx++] = vidx - width - 1;
  3816. }
  3817. }
  3818. }
  3819. }
  3820. return indices;
  3821. };
  3822. CardboardDistorter.prototype.getOwnPropertyDescriptor_ = function(proto, attrName) {
  3823. var descriptor = Object.getOwnPropertyDescriptor(proto, attrName);
  3824. // In some cases (ahem... Safari), the descriptor returns undefined get and
  3825. // set fields. In this case, we need to create a synthetic property
  3826. // descriptor. This works around some of the issues in
  3827. // https://github.com/borismus/webvr-polyfill/issues/46
  3828. if (descriptor.get === undefined || descriptor.set === undefined) {
  3829. descriptor.configurable = true;
  3830. descriptor.enumerable = true;
  3831. descriptor.get = function() {
  3832. return this.getAttribute(attrName);
  3833. };
  3834. descriptor.set = function(val) {
  3835. this.setAttribute(attrName, val);
  3836. };
  3837. }
  3838. return descriptor;
  3839. };
  3840. module.exports = CardboardDistorter;
  3841. },{"./cardboard-ui.js":11,"./deps/wglu-preserve-state.js":13,"./util.js":29}],11:[function(_dereq_,module,exports){
  3842. /*
  3843. * Copyright 2016 Google Inc. All Rights Reserved.
  3844. * Licensed under the Apache License, Version 2.0 (the "License");
  3845. * you may not use this file except in compliance with the License.
  3846. * You may obtain a copy of the License at
  3847. *
  3848. * http://www.apache.org/licenses/LICENSE-2.0
  3849. *
  3850. * Unless required by applicable law or agreed to in writing, software
  3851. * distributed under the License is distributed on an "AS IS" BASIS,
  3852. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  3853. * See the License for the specific language governing permissions and
  3854. * limitations under the License.
  3855. */
  3856. var Util = _dereq_('./util.js');
  3857. var WGLUPreserveGLState = _dereq_('./deps/wglu-preserve-state.js');
  3858. var uiVS = [
  3859. 'attribute vec2 position;',
  3860. 'uniform mat4 projectionMat;',
  3861. 'void main() {',
  3862. ' gl_Position = projectionMat * vec4( position, -1.0, 1.0 );',
  3863. '}',
  3864. ].join('\n');
  3865. var uiFS = [
  3866. 'precision mediump float;',
  3867. 'uniform vec4 color;',
  3868. 'void main() {',
  3869. ' gl_FragColor = color;',
  3870. '}',
  3871. ].join('\n');
  3872. var DEG2RAD = Math.PI/180.0;
  3873. // The gear has 6 identical sections, each spanning 60 degrees.
  3874. var kAnglePerGearSection = 60;
  3875. // Half-angle of the span of the outer rim.
  3876. var kOuterRimEndAngle = 12;
  3877. // Angle between the middle of the outer rim and the start of the inner rim.
  3878. var kInnerRimBeginAngle = 20;
  3879. // Distance from center to outer rim, normalized so that the entire model
  3880. // fits in a [-1, 1] x [-1, 1] square.
  3881. var kOuterRadius = 1;
  3882. // Distance from center to depressed rim, in model units.
  3883. var kMiddleRadius = 0.75;
  3884. // Radius of the inner hollow circle, in model units.
  3885. var kInnerRadius = 0.3125;
  3886. // Center line thickness in DP.
  3887. var kCenterLineThicknessDp = 4;
  3888. // Button width in DP.
  3889. var kButtonWidthDp = 28;
  3890. // Factor to scale the touch area that responds to the touch.
  3891. var kTouchSlopFactor = 1.5;
  3892. var Angles = [
  3893. 0, kOuterRimEndAngle, kInnerRimBeginAngle,
  3894. kAnglePerGearSection - kInnerRimBeginAngle,
  3895. kAnglePerGearSection - kOuterRimEndAngle
  3896. ];
  3897. /**
  3898. * Renders the alignment line and "options" gear. It is assumed that the canvas
  3899. * this is rendered into covers the entire screen (or close to it.)
  3900. */
  3901. function CardboardUI(gl) {
  3902. this.gl = gl;
  3903. this.attribs = {
  3904. position: 0
  3905. };
  3906. this.program = Util.linkProgram(gl, uiVS, uiFS, this.attribs);
  3907. this.uniforms = Util.getProgramUniforms(gl, this.program);
  3908. this.vertexBuffer = gl.createBuffer();
  3909. this.gearOffset = 0;
  3910. this.gearVertexCount = 0;
  3911. this.arrowOffset = 0;
  3912. this.arrowVertexCount = 0;
  3913. this.projMat = new Float32Array(16);
  3914. this.listener = null;
  3915. this.onResize();
  3916. };
  3917. /**
  3918. * Tears down all the resources created by the UI renderer.
  3919. */
  3920. CardboardUI.prototype.destroy = function() {
  3921. var gl = this.gl;
  3922. if (this.listener) {
  3923. gl.canvas.removeEventListener('click', this.listener, false);
  3924. }
  3925. gl.deleteProgram(this.program);
  3926. gl.deleteBuffer(this.vertexBuffer);
  3927. };
  3928. /**
  3929. * Adds a listener to clicks on the gear and back icons
  3930. */
  3931. CardboardUI.prototype.listen = function(optionsCallback, backCallback) {
  3932. var canvas = this.gl.canvas;
  3933. this.listener = function(event) {
  3934. var midline = canvas.clientWidth / 2;
  3935. var buttonSize = kButtonWidthDp * kTouchSlopFactor;
  3936. // Check to see if the user clicked on (or around) the gear icon
  3937. if (event.clientX > midline - buttonSize &&
  3938. event.clientX < midline + buttonSize &&
  3939. event.clientY > canvas.clientHeight - buttonSize) {
  3940. optionsCallback(event);
  3941. }
  3942. // Check to see if the user clicked on (or around) the back icon
  3943. else if (event.clientX < buttonSize && event.clientY < buttonSize) {
  3944. backCallback(event);
  3945. }
  3946. };
  3947. canvas.addEventListener('click', this.listener, false);
  3948. };
  3949. /**
  3950. * Builds the UI mesh.
  3951. */
  3952. CardboardUI.prototype.onResize = function() {
  3953. var gl = this.gl;
  3954. var self = this;
  3955. var glState = [
  3956. gl.ARRAY_BUFFER_BINDING
  3957. ];
  3958. WGLUPreserveGLState(gl, glState, function(gl) {
  3959. var vertices = [];
  3960. var midline = gl.drawingBufferWidth / 2;
  3961. // The gl buffer size will likely be smaller than the physical pixel count.
  3962. // So we need to scale the dps down based on the actual buffer size vs physical pixel count.
  3963. // This will properly size the ui elements no matter what the gl buffer resolution is
  3964. var physicalPixels = Math.max(screen.width, screen.height) * window.devicePixelRatio;
  3965. var scalingRatio = gl.drawingBufferWidth / physicalPixels;
  3966. var dps = scalingRatio * window.devicePixelRatio;
  3967. var lineWidth = kCenterLineThicknessDp * dps / 2;
  3968. var buttonSize = kButtonWidthDp * kTouchSlopFactor * dps;
  3969. var buttonScale = kButtonWidthDp * dps / 2;
  3970. var buttonBorder = ((kButtonWidthDp * kTouchSlopFactor) - kButtonWidthDp) * dps;
  3971. // Build centerline
  3972. vertices.push(midline - lineWidth, buttonSize);
  3973. vertices.push(midline - lineWidth, gl.drawingBufferHeight);
  3974. vertices.push(midline + lineWidth, buttonSize);
  3975. vertices.push(midline + lineWidth, gl.drawingBufferHeight);
  3976. // Build gear
  3977. self.gearOffset = (vertices.length / 2);
  3978. function addGearSegment(theta, r) {
  3979. var angle = (90 - theta) * DEG2RAD;
  3980. var x = Math.cos(angle);
  3981. var y = Math.sin(angle);
  3982. vertices.push(kInnerRadius * x * buttonScale + midline, kInnerRadius * y * buttonScale + buttonScale);
  3983. vertices.push(r * x * buttonScale + midline, r * y * buttonScale + buttonScale);
  3984. }
  3985. for (var i = 0; i <= 6; i++) {
  3986. var segmentTheta = i * kAnglePerGearSection;
  3987. addGearSegment(segmentTheta, kOuterRadius);
  3988. addGearSegment(segmentTheta + kOuterRimEndAngle, kOuterRadius);
  3989. addGearSegment(segmentTheta + kInnerRimBeginAngle, kMiddleRadius);
  3990. addGearSegment(segmentTheta + (kAnglePerGearSection - kInnerRimBeginAngle), kMiddleRadius);
  3991. addGearSegment(segmentTheta + (kAnglePerGearSection - kOuterRimEndAngle), kOuterRadius);
  3992. }
  3993. self.gearVertexCount = (vertices.length / 2) - self.gearOffset;
  3994. // Build back arrow
  3995. self.arrowOffset = (vertices.length / 2);
  3996. function addArrowVertex(x, y) {
  3997. vertices.push(buttonBorder + x, gl.drawingBufferHeight - buttonBorder - y);
  3998. }
  3999. var angledLineWidth = lineWidth / Math.sin(45 * DEG2RAD);
  4000. addArrowVertex(0, buttonScale);
  4001. addArrowVertex(buttonScale, 0);
  4002. addArrowVertex(buttonScale + angledLineWidth, angledLineWidth);
  4003. addArrowVertex(angledLineWidth, buttonScale + angledLineWidth);
  4004. addArrowVertex(angledLineWidth, buttonScale - angledLineWidth);
  4005. addArrowVertex(0, buttonScale);
  4006. addArrowVertex(buttonScale, buttonScale * 2);
  4007. addArrowVertex(buttonScale + angledLineWidth, (buttonScale * 2) - angledLineWidth);
  4008. addArrowVertex(angledLineWidth, buttonScale - angledLineWidth);
  4009. addArrowVertex(0, buttonScale);
  4010. addArrowVertex(angledLineWidth, buttonScale - lineWidth);
  4011. addArrowVertex(kButtonWidthDp * dps, buttonScale - lineWidth);
  4012. addArrowVertex(angledLineWidth, buttonScale + lineWidth);
  4013. addArrowVertex(kButtonWidthDp * dps, buttonScale + lineWidth);
  4014. self.arrowVertexCount = (vertices.length / 2) - self.arrowOffset;
  4015. // Buffer data
  4016. gl.bindBuffer(gl.ARRAY_BUFFER, self.vertexBuffer);
  4017. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
  4018. });
  4019. };
  4020. /**
  4021. * Performs distortion pass on the injected backbuffer, rendering it to the real
  4022. * backbuffer.
  4023. */
  4024. CardboardUI.prototype.render = function() {
  4025. var gl = this.gl;
  4026. var self = this;
  4027. var glState = [
  4028. gl.CULL_FACE,
  4029. gl.DEPTH_TEST,
  4030. gl.BLEND,
  4031. gl.SCISSOR_TEST,
  4032. gl.STENCIL_TEST,
  4033. gl.COLOR_WRITEMASK,
  4034. gl.VIEWPORT,
  4035. gl.CURRENT_PROGRAM,
  4036. gl.ARRAY_BUFFER_BINDING
  4037. ];
  4038. WGLUPreserveGLState(gl, glState, function(gl) {
  4039. // Make sure the GL state is in a good place
  4040. gl.disable(gl.CULL_FACE);
  4041. gl.disable(gl.DEPTH_TEST);
  4042. gl.disable(gl.BLEND);
  4043. gl.disable(gl.SCISSOR_TEST);
  4044. gl.disable(gl.STENCIL_TEST);
  4045. gl.colorMask(true, true, true, true);
  4046. gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
  4047. self.renderNoState();
  4048. });
  4049. };
  4050. CardboardUI.prototype.renderNoState = function() {
  4051. var gl = this.gl;
  4052. // Bind distortion program and mesh
  4053. gl.useProgram(this.program);
  4054. gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
  4055. gl.enableVertexAttribArray(this.attribs.position);
  4056. gl.vertexAttribPointer(this.attribs.position, 2, gl.FLOAT, false, 8, 0);
  4057. gl.uniform4f(this.uniforms.color, 1.0, 1.0, 1.0, 1.0);
  4058. Util.orthoMatrix(this.projMat, 0, gl.drawingBufferWidth, 0, gl.drawingBufferHeight, 0.1, 1024.0);
  4059. gl.uniformMatrix4fv(this.uniforms.projectionMat, false, this.projMat);
  4060. // Draws UI element
  4061. gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  4062. gl.drawArrays(gl.TRIANGLE_STRIP, this.gearOffset, this.gearVertexCount);
  4063. gl.drawArrays(gl.TRIANGLE_STRIP, this.arrowOffset, this.arrowVertexCount);
  4064. };
  4065. module.exports = CardboardUI;
  4066. },{"./deps/wglu-preserve-state.js":13,"./util.js":29}],12:[function(_dereq_,module,exports){
  4067. /*
  4068. * Copyright 2016 Google Inc. All Rights Reserved.
  4069. * Licensed under the Apache License, Version 2.0 (the "License");
  4070. * you may not use this file except in compliance with the License.
  4071. * You may obtain a copy of the License at
  4072. *
  4073. * http://www.apache.org/licenses/LICENSE-2.0
  4074. *
  4075. * Unless required by applicable law or agreed to in writing, software
  4076. * distributed under the License is distributed on an "AS IS" BASIS,
  4077. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  4078. * See the License for the specific language governing permissions and
  4079. * limitations under the License.
  4080. */
  4081. var CardboardDistorter = _dereq_('./cardboard-distorter.js');
  4082. var CardboardUI = _dereq_('./cardboard-ui.js');
  4083. var DeviceInfo = _dereq_('./device-info.js');
  4084. var Dpdb = _dereq_('./dpdb/dpdb.js');
  4085. var FusionPoseSensor = _dereq_('./sensor-fusion/fusion-pose-sensor.js');
  4086. var RotateInstructions = _dereq_('./rotate-instructions.js');
  4087. var ViewerSelector = _dereq_('./viewer-selector.js');
  4088. var VRDisplay = _dereq_('./base.js').VRDisplay;
  4089. var Util = _dereq_('./util.js');
  4090. var Eye = {
  4091. LEFT: 'left',
  4092. RIGHT: 'right'
  4093. };
  4094. /**
  4095. * VRDisplay based on mobile device parameters and DeviceMotion APIs.
  4096. */
  4097. function CardboardVRDisplay() {
  4098. this.displayName = 'Cardboard VRDisplay (webvr-polyfill)';
  4099. this.capabilities.hasOrientation = true;
  4100. this.capabilities.canPresent = true;
  4101. // "Private" members.
  4102. this.bufferScale_ = window.WebVRConfig.BUFFER_SCALE;
  4103. this.poseSensor_ = new FusionPoseSensor();
  4104. this.distorter_ = null;
  4105. this.cardboardUI_ = null;
  4106. this.dpdb_ = new Dpdb(true, this.onDeviceParamsUpdated_.bind(this));
  4107. this.deviceInfo_ = new DeviceInfo(this.dpdb_.getDeviceParams());
  4108. this.viewerSelector_ = new ViewerSelector();
  4109. this.viewerSelector_.onChange(this.onViewerChanged_.bind(this));
  4110. // Set the correct initial viewer.
  4111. this.deviceInfo_.setViewer(this.viewerSelector_.getCurrentViewer());
  4112. if (!window.WebVRConfig.ROTATE_INSTRUCTIONS_DISABLED) {
  4113. this.rotateInstructions_ = new RotateInstructions();
  4114. }
  4115. if (Util.isIOS()) {
  4116. // Listen for resize events to workaround this awful Safari bug.
  4117. window.addEventListener('resize', this.onResize_.bind(this));
  4118. }
  4119. }
  4120. CardboardVRDisplay.prototype = new VRDisplay();
  4121. CardboardVRDisplay.prototype.getImmediatePose = function() {
  4122. return {
  4123. position: this.poseSensor_.getPosition(),
  4124. orientation: this.poseSensor_.getOrientation(),
  4125. linearVelocity: null,
  4126. linearAcceleration: null,
  4127. angularVelocity: null,
  4128. angularAcceleration: null
  4129. };
  4130. };
  4131. CardboardVRDisplay.prototype.resetPose = function() {
  4132. this.poseSensor_.resetPose();
  4133. };
  4134. CardboardVRDisplay.prototype.getEyeParameters = function(whichEye) {
  4135. var offset = [this.deviceInfo_.viewer.interLensDistance * 0.5, 0.0, 0.0];
  4136. var fieldOfView;
  4137. // TODO: FoV can be a little expensive to compute. Cache when device params change.
  4138. if (whichEye == Eye.LEFT) {
  4139. offset[0] *= -1.0;
  4140. fieldOfView = this.deviceInfo_.getFieldOfViewLeftEye();
  4141. } else if (whichEye == Eye.RIGHT) {
  4142. fieldOfView = this.deviceInfo_.getFieldOfViewRightEye();
  4143. } else {
  4144. console.error('Invalid eye provided: %s', whichEye);
  4145. return null;
  4146. }
  4147. return {
  4148. fieldOfView: fieldOfView,
  4149. offset: offset,
  4150. // TODO: Should be able to provide better values than these.
  4151. renderWidth: this.deviceInfo_.device.width * 0.5 * this.bufferScale_,
  4152. renderHeight: this.deviceInfo_.device.height * this.bufferScale_,
  4153. };
  4154. };
  4155. CardboardVRDisplay.prototype.onDeviceParamsUpdated_ = function(newParams) {
  4156. if (Util.isDebug()) {
  4157. console.log('DPDB reported that device params were updated.');
  4158. }
  4159. this.deviceInfo_.updateDeviceParams(newParams);
  4160. if (this.distorter_) {
  4161. this.distorter_.updateDeviceInfo(this.deviceInfo_);
  4162. }
  4163. };
  4164. CardboardVRDisplay.prototype.updateBounds_ = function () {
  4165. if (this.layer_ && this.distorter_ && (this.layer_.leftBounds || this.layer_.rightBounds)) {
  4166. this.distorter_.setTextureBounds(this.layer_.leftBounds, this.layer_.rightBounds);
  4167. }
  4168. };
  4169. CardboardVRDisplay.prototype.beginPresent_ = function() {
  4170. var gl = this.layer_.source.getContext('webgl');
  4171. if (!gl)
  4172. gl = this.layer_.source.getContext('experimental-webgl');
  4173. if (!gl)
  4174. gl = this.layer_.source.getContext('webgl2');
  4175. if (!gl)
  4176. return; // Can't do distortion without a WebGL context.
  4177. // Provides a way to opt out of distortion
  4178. if (this.layer_.predistorted) {
  4179. if (!window.WebVRConfig.CARDBOARD_UI_DISABLED) {
  4180. gl.canvas.width = Util.getScreenWidth() * this.bufferScale_;
  4181. gl.canvas.height = Util.getScreenHeight() * this.bufferScale_;
  4182. this.cardboardUI_ = new CardboardUI(gl);
  4183. }
  4184. } else {
  4185. // Create a new distorter for the target context
  4186. this.distorter_ = new CardboardDistorter(gl);
  4187. this.distorter_.updateDeviceInfo(this.deviceInfo_);
  4188. this.cardboardUI_ = this.distorter_.cardboardUI;
  4189. }
  4190. if (this.cardboardUI_) {
  4191. this.cardboardUI_.listen(function(e) {
  4192. // Options clicked.
  4193. this.viewerSelector_.show(this.layer_.source.parentElement);
  4194. e.stopPropagation();
  4195. e.preventDefault();
  4196. }.bind(this), function(e) {
  4197. // Back clicked.
  4198. this.exitPresent();
  4199. e.stopPropagation();
  4200. e.preventDefault();
  4201. }.bind(this));
  4202. }
  4203. if (this.rotateInstructions_) {
  4204. if (Util.isLandscapeMode() && Util.isMobile()) {
  4205. // In landscape mode, temporarily show the "put into Cardboard"
  4206. // interstitial. Otherwise, do the default thing.
  4207. this.rotateInstructions_.showTemporarily(3000, this.layer_.source.parentElement);
  4208. } else {
  4209. this.rotateInstructions_.update();
  4210. }
  4211. }
  4212. // Listen for orientation change events in order to show interstitial.
  4213. this.orientationHandler = this.onOrientationChange_.bind(this);
  4214. window.addEventListener('orientationchange', this.orientationHandler);
  4215. // Listen for present display change events in order to update distorter dimensions
  4216. this.vrdisplaypresentchangeHandler = this.updateBounds_.bind(this);
  4217. window.addEventListener('vrdisplaypresentchange', this.vrdisplaypresentchangeHandler);
  4218. // Fire this event initially, to give geometry-distortion clients the chance
  4219. // to do something custom.
  4220. this.fireVRDisplayDeviceParamsChange_();
  4221. };
  4222. CardboardVRDisplay.prototype.endPresent_ = function() {
  4223. if (this.distorter_) {
  4224. this.distorter_.destroy();
  4225. this.distorter_ = null;
  4226. }
  4227. if (this.cardboardUI_) {
  4228. this.cardboardUI_.destroy();
  4229. this.cardboardUI_ = null;
  4230. }
  4231. if (this.rotateInstructions_) {
  4232. this.rotateInstructions_.hide();
  4233. }
  4234. this.viewerSelector_.hide();
  4235. window.removeEventListener('orientationchange', this.orientationHandler);
  4236. window.removeEventListener('vrdisplaypresentchange', this.vrdisplaypresentchangeHandler);
  4237. };
  4238. CardboardVRDisplay.prototype.submitFrame = function(pose) {
  4239. if (this.distorter_) {
  4240. this.updateBounds_();
  4241. this.distorter_.submitFrame();
  4242. } else if (this.cardboardUI_ && this.layer_) {
  4243. // Hack for predistorted: true.
  4244. var canvas = this.layer_.source.getContext('webgl').canvas;
  4245. if (canvas.width != this.lastWidth || canvas.height != this.lastHeight) {
  4246. this.cardboardUI_.onResize();
  4247. }
  4248. this.lastWidth = canvas.width;
  4249. this.lastHeight = canvas.height;
  4250. // Render the Cardboard UI.
  4251. this.cardboardUI_.render();
  4252. }
  4253. };
  4254. CardboardVRDisplay.prototype.onOrientationChange_ = function(e) {
  4255. // Hide the viewer selector.
  4256. this.viewerSelector_.hide();
  4257. // Update the rotate instructions.
  4258. if (this.rotateInstructions_) {
  4259. this.rotateInstructions_.update();
  4260. }
  4261. this.onResize_();
  4262. };
  4263. CardboardVRDisplay.prototype.onResize_ = function(e) {
  4264. if (this.layer_) {
  4265. var gl = this.layer_.source.getContext('webgl');
  4266. // Size the CSS canvas.
  4267. // Added padding on right and bottom because iPhone 5 will not
  4268. // hide the URL bar unless content is bigger than the screen.
  4269. // This will not be visible as long as the container element (e.g. body)
  4270. // is set to 'overflow: hidden'.
  4271. // Additionally, 'box-sizing: content-box' ensures renderWidth = width + padding.
  4272. // This is required when 'box-sizing: border-box' is used elsewhere in the page.
  4273. var cssProperties = [
  4274. 'position: absolute',
  4275. 'top: 0',
  4276. 'left: 0',
  4277. // Use vw/vh to handle implicitly devicePixelRatio; issue #282
  4278. 'width: 100vw',
  4279. 'height: 100vh',
  4280. 'border: 0',
  4281. 'margin: 0',
  4282. // Set no padding in the case where you don't have control over
  4283. // the content injection, like in Unity WebGL; issue #282
  4284. 'padding: 0px',
  4285. 'box-sizing: content-box',
  4286. ];
  4287. gl.canvas.setAttribute('style', cssProperties.join('; ') + ';');
  4288. Util.safariCssSizeWorkaround(gl.canvas);
  4289. }
  4290. };
  4291. CardboardVRDisplay.prototype.onViewerChanged_ = function(viewer) {
  4292. this.deviceInfo_.setViewer(viewer);
  4293. if (this.distorter_) {
  4294. // Update the distortion appropriately.
  4295. this.distorter_.updateDeviceInfo(this.deviceInfo_);
  4296. }
  4297. // Fire a new event containing viewer and device parameters for clients that
  4298. // want to implement their own geometry-based distortion.
  4299. this.fireVRDisplayDeviceParamsChange_();
  4300. };
  4301. CardboardVRDisplay.prototype.fireVRDisplayDeviceParamsChange_ = function() {
  4302. var event = new CustomEvent('vrdisplaydeviceparamschange', {
  4303. detail: {
  4304. vrdisplay: this,
  4305. deviceInfo: this.deviceInfo_,
  4306. }
  4307. });
  4308. window.dispatchEvent(event);
  4309. };
  4310. module.exports = CardboardVRDisplay;
  4311. },{"./base.js":9,"./cardboard-distorter.js":10,"./cardboard-ui.js":11,"./device-info.js":14,"./dpdb/dpdb.js":18,"./rotate-instructions.js":23,"./sensor-fusion/fusion-pose-sensor.js":25,"./util.js":29,"./viewer-selector.js":30}],13:[function(_dereq_,module,exports){
  4312. /**
  4313. * Copyright (c) 2016, Brandon Jones.
  4314. * https://github.com/toji/webgl-utils/blob/master/src/wglu-preserve-state.js
  4315. * LICENSE: https://github.com/toji/webgl-utils/blob/master/LICENSE.md
  4316. */
  4317. function WGLUPreserveGLState(gl, bindings, callback) {
  4318. if (!bindings) {
  4319. callback(gl);
  4320. return;
  4321. }
  4322. var boundValues = [];
  4323. var activeTexture = null;
  4324. for (var i = 0; i < bindings.length; ++i) {
  4325. var binding = bindings[i];
  4326. switch (binding) {
  4327. case gl.TEXTURE_BINDING_2D:
  4328. case gl.TEXTURE_BINDING_CUBE_MAP:
  4329. var textureUnit = bindings[++i];
  4330. if (textureUnit < gl.TEXTURE0 || textureUnit > gl.TEXTURE31) {
  4331. console.error("TEXTURE_BINDING_2D or TEXTURE_BINDING_CUBE_MAP must be followed by a valid texture unit");
  4332. boundValues.push(null, null);
  4333. break;
  4334. }
  4335. if (!activeTexture) {
  4336. activeTexture = gl.getParameter(gl.ACTIVE_TEXTURE);
  4337. }
  4338. gl.activeTexture(textureUnit);
  4339. boundValues.push(gl.getParameter(binding), null);
  4340. break;
  4341. case gl.ACTIVE_TEXTURE:
  4342. activeTexture = gl.getParameter(gl.ACTIVE_TEXTURE);
  4343. boundValues.push(null);
  4344. break;
  4345. default:
  4346. boundValues.push(gl.getParameter(binding));
  4347. break;
  4348. }
  4349. }
  4350. callback(gl);
  4351. for (var i = 0; i < bindings.length; ++i) {
  4352. var binding = bindings[i];
  4353. var boundValue = boundValues[i];
  4354. switch (binding) {
  4355. case gl.ACTIVE_TEXTURE:
  4356. break; // Ignore this binding, since we special-case it to happen last.
  4357. case gl.ARRAY_BUFFER_BINDING:
  4358. gl.bindBuffer(gl.ARRAY_BUFFER, boundValue);
  4359. break;
  4360. case gl.COLOR_CLEAR_VALUE:
  4361. gl.clearColor(boundValue[0], boundValue[1], boundValue[2], boundValue[3]);
  4362. break;
  4363. case gl.COLOR_WRITEMASK:
  4364. gl.colorMask(boundValue[0], boundValue[1], boundValue[2], boundValue[3]);
  4365. break;
  4366. case gl.CURRENT_PROGRAM:
  4367. gl.useProgram(boundValue);
  4368. break;
  4369. case gl.ELEMENT_ARRAY_BUFFER_BINDING:
  4370. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, boundValue);
  4371. break;
  4372. case gl.FRAMEBUFFER_BINDING:
  4373. gl.bindFramebuffer(gl.FRAMEBUFFER, boundValue);
  4374. break;
  4375. case gl.RENDERBUFFER_BINDING:
  4376. gl.bindRenderbuffer(gl.RENDERBUFFER, boundValue);
  4377. break;
  4378. case gl.TEXTURE_BINDING_2D:
  4379. var textureUnit = bindings[++i];
  4380. if (textureUnit < gl.TEXTURE0 || textureUnit > gl.TEXTURE31)
  4381. break;
  4382. gl.activeTexture(textureUnit);
  4383. gl.bindTexture(gl.TEXTURE_2D, boundValue);
  4384. break;
  4385. case gl.TEXTURE_BINDING_CUBE_MAP:
  4386. var textureUnit = bindings[++i];
  4387. if (textureUnit < gl.TEXTURE0 || textureUnit > gl.TEXTURE31)
  4388. break;
  4389. gl.activeTexture(textureUnit);
  4390. gl.bindTexture(gl.TEXTURE_CUBE_MAP, boundValue);
  4391. break;
  4392. case gl.VIEWPORT:
  4393. gl.viewport(boundValue[0], boundValue[1], boundValue[2], boundValue[3]);
  4394. break;
  4395. case gl.BLEND:
  4396. case gl.CULL_FACE:
  4397. case gl.DEPTH_TEST:
  4398. case gl.SCISSOR_TEST:
  4399. case gl.STENCIL_TEST:
  4400. if (boundValue) {
  4401. gl.enable(binding);
  4402. } else {
  4403. gl.disable(binding);
  4404. }
  4405. break;
  4406. default:
  4407. console.log("No GL restore behavior for 0x" + binding.toString(16));
  4408. break;
  4409. }
  4410. if (activeTexture) {
  4411. gl.activeTexture(activeTexture);
  4412. }
  4413. }
  4414. }
  4415. module.exports = WGLUPreserveGLState;
  4416. },{}],14:[function(_dereq_,module,exports){
  4417. /*
  4418. * Copyright 2015 Google Inc. All Rights Reserved.
  4419. * Licensed under the Apache License, Version 2.0 (the "License");
  4420. * you may not use this file except in compliance with the License.
  4421. * You may obtain a copy of the License at
  4422. *
  4423. * http://www.apache.org/licenses/LICENSE-2.0
  4424. *
  4425. * Unless required by applicable law or agreed to in writing, software
  4426. * distributed under the License is distributed on an "AS IS" BASIS,
  4427. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  4428. * See the License for the specific language governing permissions and
  4429. * limitations under the License.
  4430. */
  4431. var Distortion = _dereq_('./distortion/distortion.js');
  4432. var MathUtil = _dereq_('./math-util.js');
  4433. var Util = _dereq_('./util.js');
  4434. function Device(params) {
  4435. this.width = params.width || Util.getScreenWidth();
  4436. this.height = params.height || Util.getScreenHeight();
  4437. this.widthMeters = params.widthMeters;
  4438. this.heightMeters = params.heightMeters;
  4439. this.bevelMeters = params.bevelMeters;
  4440. }
  4441. // Fallback Android device (based on Nexus 5 measurements) for use when
  4442. // we can't recognize an Android device.
  4443. var DEFAULT_ANDROID = new Device({
  4444. widthMeters: 0.110,
  4445. heightMeters: 0.062,
  4446. bevelMeters: 0.004
  4447. });
  4448. // Fallback iOS device (based on iPhone6) for use when
  4449. // we can't recognize an Android device.
  4450. var DEFAULT_IOS = new Device({
  4451. widthMeters: 0.1038,
  4452. heightMeters: 0.0584,
  4453. bevelMeters: 0.004
  4454. });
  4455. var Viewers = {
  4456. CardboardV1: new CardboardViewer({
  4457. id: 'CardboardV1',
  4458. label: 'Cardboard I/O 2014',
  4459. fov: 40,
  4460. interLensDistance: 0.060,
  4461. baselineLensDistance: 0.035,
  4462. screenLensDistance: 0.042,
  4463. distortionCoefficients: [0.441, 0.156],
  4464. inverseCoefficients: [-0.4410035, 0.42756155, -0.4804439, 0.5460139,
  4465. -0.58821183, 0.5733938, -0.48303202, 0.33299083, -0.17573841,
  4466. 0.0651772, -0.01488963, 0.001559834]
  4467. }),
  4468. CardboardV2: new CardboardViewer({
  4469. id: 'CardboardV2',
  4470. label: 'Cardboard I/O 2015',
  4471. fov: 60,
  4472. interLensDistance: 0.064,
  4473. baselineLensDistance: 0.035,
  4474. screenLensDistance: 0.039,
  4475. distortionCoefficients: [0.34, 0.55],
  4476. inverseCoefficients: [-0.33836704, -0.18162185, 0.862655, -1.2462051,
  4477. 1.0560602, -0.58208317, 0.21609078, -0.05444823, 0.009177956,
  4478. -9.904169E-4, 6.183535E-5, -1.6981803E-6]
  4479. })
  4480. };
  4481. var DEFAULT_LEFT_CENTER = {x: 0.5, y: 0.5};
  4482. var DEFAULT_RIGHT_CENTER = {x: 0.5, y: 0.5};
  4483. /**
  4484. * Manages information about the device and the viewer.
  4485. *
  4486. * deviceParams indicates the parameters of the device to use (generally
  4487. * obtained from dpdb.getDeviceParams()). Can be null to mean no device
  4488. * params were found.
  4489. */
  4490. function DeviceInfo(deviceParams) {
  4491. this.viewer = Viewers.CardboardV2;
  4492. this.updateDeviceParams(deviceParams);
  4493. this.distortion = new Distortion(this.viewer.distortionCoefficients);
  4494. }
  4495. DeviceInfo.prototype.updateDeviceParams = function(deviceParams) {
  4496. this.device = this.determineDevice_(deviceParams) || this.device;
  4497. };
  4498. DeviceInfo.prototype.getDevice = function() {
  4499. return this.device;
  4500. };
  4501. DeviceInfo.prototype.setViewer = function(viewer) {
  4502. this.viewer = viewer;
  4503. this.distortion = new Distortion(this.viewer.distortionCoefficients);
  4504. };
  4505. DeviceInfo.prototype.determineDevice_ = function(deviceParams) {
  4506. if (!deviceParams) {
  4507. // No parameters, so use a default.
  4508. if (Util.isIOS()) {
  4509. console.warn('Using fallback iOS device measurements.');
  4510. return DEFAULT_IOS;
  4511. } else {
  4512. console.warn('Using fallback Android device measurements.');
  4513. return DEFAULT_ANDROID;
  4514. }
  4515. }
  4516. // Compute device screen dimensions based on deviceParams.
  4517. var METERS_PER_INCH = 0.0254;
  4518. var metersPerPixelX = METERS_PER_INCH / deviceParams.xdpi;
  4519. var metersPerPixelY = METERS_PER_INCH / deviceParams.ydpi;
  4520. var width = Util.getScreenWidth();
  4521. var height = Util.getScreenHeight();
  4522. return new Device({
  4523. widthMeters: metersPerPixelX * width,
  4524. heightMeters: metersPerPixelY * height,
  4525. bevelMeters: deviceParams.bevelMm * 0.001,
  4526. });
  4527. };
  4528. /**
  4529. * Calculates field of view for the left eye.
  4530. */
  4531. DeviceInfo.prototype.getDistortedFieldOfViewLeftEye = function() {
  4532. var viewer = this.viewer;
  4533. var device = this.device;
  4534. var distortion = this.distortion;
  4535. // Device.height and device.width for device in portrait mode, so transpose.
  4536. var eyeToScreenDistance = viewer.screenLensDistance;
  4537. var outerDist = (device.widthMeters - viewer.interLensDistance) / 2;
  4538. var innerDist = viewer.interLensDistance / 2;
  4539. var bottomDist = viewer.baselineLensDistance - device.bevelMeters;
  4540. var topDist = device.heightMeters - bottomDist;
  4541. var outerAngle = MathUtil.radToDeg * Math.atan(
  4542. distortion.distort(outerDist / eyeToScreenDistance));
  4543. var innerAngle = MathUtil.radToDeg * Math.atan(
  4544. distortion.distort(innerDist / eyeToScreenDistance));
  4545. var bottomAngle = MathUtil.radToDeg * Math.atan(
  4546. distortion.distort(bottomDist / eyeToScreenDistance));
  4547. var topAngle = MathUtil.radToDeg * Math.atan(
  4548. distortion.distort(topDist / eyeToScreenDistance));
  4549. return {
  4550. leftDegrees: Math.min(outerAngle, viewer.fov),
  4551. rightDegrees: Math.min(innerAngle, viewer.fov),
  4552. downDegrees: Math.min(bottomAngle, viewer.fov),
  4553. upDegrees: Math.min(topAngle, viewer.fov)
  4554. };
  4555. };
  4556. /**
  4557. * Calculates the tan-angles from the maximum FOV for the left eye for the
  4558. * current device and screen parameters.
  4559. */
  4560. DeviceInfo.prototype.getLeftEyeVisibleTanAngles = function() {
  4561. var viewer = this.viewer;
  4562. var device = this.device;
  4563. var distortion = this.distortion;
  4564. // Tan-angles from the max FOV.
  4565. var fovLeft = Math.tan(-MathUtil.degToRad * viewer.fov);
  4566. var fovTop = Math.tan(MathUtil.degToRad * viewer.fov);
  4567. var fovRight = Math.tan(MathUtil.degToRad * viewer.fov);
  4568. var fovBottom = Math.tan(-MathUtil.degToRad * viewer.fov);
  4569. // Viewport size.
  4570. var halfWidth = device.widthMeters / 4;
  4571. var halfHeight = device.heightMeters / 2;
  4572. // Viewport center, measured from left lens position.
  4573. var verticalLensOffset = (viewer.baselineLensDistance - device.bevelMeters - halfHeight);
  4574. var centerX = viewer.interLensDistance / 2 - halfWidth;
  4575. var centerY = -verticalLensOffset;
  4576. var centerZ = viewer.screenLensDistance;
  4577. // Tan-angles of the viewport edges, as seen through the lens.
  4578. var screenLeft = distortion.distort((centerX - halfWidth) / centerZ);
  4579. var screenTop = distortion.distort((centerY + halfHeight) / centerZ);
  4580. var screenRight = distortion.distort((centerX + halfWidth) / centerZ);
  4581. var screenBottom = distortion.distort((centerY - halfHeight) / centerZ);
  4582. // Compare the two sets of tan-angles and take the value closer to zero on each side.
  4583. var result = new Float32Array(4);
  4584. result[0] = Math.max(fovLeft, screenLeft);
  4585. result[1] = Math.min(fovTop, screenTop);
  4586. result[2] = Math.min(fovRight, screenRight);
  4587. result[3] = Math.max(fovBottom, screenBottom);
  4588. return result;
  4589. };
  4590. /**
  4591. * Calculates the tan-angles from the maximum FOV for the left eye for the
  4592. * current device and screen parameters, assuming no lenses.
  4593. */
  4594. DeviceInfo.prototype.getLeftEyeNoLensTanAngles = function() {
  4595. var viewer = this.viewer;
  4596. var device = this.device;
  4597. var distortion = this.distortion;
  4598. var result = new Float32Array(4);
  4599. // Tan-angles from the max FOV.
  4600. var fovLeft = distortion.distortInverse(Math.tan(-MathUtil.degToRad * viewer.fov));
  4601. var fovTop = distortion.distortInverse(Math.tan(MathUtil.degToRad * viewer.fov));
  4602. var fovRight = distortion.distortInverse(Math.tan(MathUtil.degToRad * viewer.fov));
  4603. var fovBottom = distortion.distortInverse(Math.tan(-MathUtil.degToRad * viewer.fov));
  4604. // Viewport size.
  4605. var halfWidth = device.widthMeters / 4;
  4606. var halfHeight = device.heightMeters / 2;
  4607. // Viewport center, measured from left lens position.
  4608. var verticalLensOffset = (viewer.baselineLensDistance - device.bevelMeters - halfHeight);
  4609. var centerX = viewer.interLensDistance / 2 - halfWidth;
  4610. var centerY = -verticalLensOffset;
  4611. var centerZ = viewer.screenLensDistance;
  4612. // Tan-angles of the viewport edges, as seen through the lens.
  4613. var screenLeft = (centerX - halfWidth) / centerZ;
  4614. var screenTop = (centerY + halfHeight) / centerZ;
  4615. var screenRight = (centerX + halfWidth) / centerZ;
  4616. var screenBottom = (centerY - halfHeight) / centerZ;
  4617. // Compare the two sets of tan-angles and take the value closer to zero on each side.
  4618. result[0] = Math.max(fovLeft, screenLeft);
  4619. result[1] = Math.min(fovTop, screenTop);
  4620. result[2] = Math.min(fovRight, screenRight);
  4621. result[3] = Math.max(fovBottom, screenBottom);
  4622. return result;
  4623. };
  4624. /**
  4625. * Calculates the screen rectangle visible from the left eye for the
  4626. * current device and screen parameters.
  4627. */
  4628. DeviceInfo.prototype.getLeftEyeVisibleScreenRect = function(undistortedFrustum) {
  4629. var viewer = this.viewer;
  4630. var device = this.device;
  4631. var dist = viewer.screenLensDistance;
  4632. var eyeX = (device.widthMeters - viewer.interLensDistance) / 2;
  4633. var eyeY = viewer.baselineLensDistance - device.bevelMeters;
  4634. var left = (undistortedFrustum[0] * dist + eyeX) / device.widthMeters;
  4635. var top = (undistortedFrustum[1] * dist + eyeY) / device.heightMeters;
  4636. var right = (undistortedFrustum[2] * dist + eyeX) / device.widthMeters;
  4637. var bottom = (undistortedFrustum[3] * dist + eyeY) / device.heightMeters;
  4638. return {
  4639. x: left,
  4640. y: bottom,
  4641. width: right - left,
  4642. height: top - bottom
  4643. };
  4644. };
  4645. DeviceInfo.prototype.getFieldOfViewLeftEye = function(opt_isUndistorted) {
  4646. return opt_isUndistorted ? this.getUndistortedFieldOfViewLeftEye() :
  4647. this.getDistortedFieldOfViewLeftEye();
  4648. };
  4649. DeviceInfo.prototype.getFieldOfViewRightEye = function(opt_isUndistorted) {
  4650. var fov = this.getFieldOfViewLeftEye(opt_isUndistorted);
  4651. return {
  4652. leftDegrees: fov.rightDegrees,
  4653. rightDegrees: fov.leftDegrees,
  4654. upDegrees: fov.upDegrees,
  4655. downDegrees: fov.downDegrees
  4656. };
  4657. };
  4658. /**
  4659. * Calculates undistorted field of view for the left eye.
  4660. */
  4661. DeviceInfo.prototype.getUndistortedFieldOfViewLeftEye = function() {
  4662. var p = this.getUndistortedParams_();
  4663. return {
  4664. leftDegrees: MathUtil.radToDeg * Math.atan(p.outerDist),
  4665. rightDegrees: MathUtil.radToDeg * Math.atan(p.innerDist),
  4666. downDegrees: MathUtil.radToDeg * Math.atan(p.bottomDist),
  4667. upDegrees: MathUtil.radToDeg * Math.atan(p.topDist)
  4668. };
  4669. };
  4670. DeviceInfo.prototype.getUndistortedViewportLeftEye = function() {
  4671. var p = this.getUndistortedParams_();
  4672. var viewer = this.viewer;
  4673. var device = this.device;
  4674. // Distances stored in local variables are in tan-angle units unless otherwise
  4675. // noted.
  4676. var eyeToScreenDistance = viewer.screenLensDistance;
  4677. var screenWidth = device.widthMeters / eyeToScreenDistance;
  4678. var screenHeight = device.heightMeters / eyeToScreenDistance;
  4679. var xPxPerTanAngle = device.width / screenWidth;
  4680. var yPxPerTanAngle = device.height / screenHeight;
  4681. var x = Math.round((p.eyePosX - p.outerDist) * xPxPerTanAngle);
  4682. var y = Math.round((p.eyePosY - p.bottomDist) * yPxPerTanAngle);
  4683. return {
  4684. x: x,
  4685. y: y,
  4686. width: Math.round((p.eyePosX + p.innerDist) * xPxPerTanAngle) - x,
  4687. height: Math.round((p.eyePosY + p.topDist) * yPxPerTanAngle) - y
  4688. };
  4689. };
  4690. DeviceInfo.prototype.getUndistortedParams_ = function() {
  4691. var viewer = this.viewer;
  4692. var device = this.device;
  4693. var distortion = this.distortion;
  4694. // Most of these variables in tan-angle units.
  4695. var eyeToScreenDistance = viewer.screenLensDistance;
  4696. var halfLensDistance = viewer.interLensDistance / 2 / eyeToScreenDistance;
  4697. var screenWidth = device.widthMeters / eyeToScreenDistance;
  4698. var screenHeight = device.heightMeters / eyeToScreenDistance;
  4699. var eyePosX = screenWidth / 2 - halfLensDistance;
  4700. var eyePosY = (viewer.baselineLensDistance - device.bevelMeters) / eyeToScreenDistance;
  4701. var maxFov = viewer.fov;
  4702. var viewerMax = distortion.distortInverse(Math.tan(MathUtil.degToRad * maxFov));
  4703. var outerDist = Math.min(eyePosX, viewerMax);
  4704. var innerDist = Math.min(halfLensDistance, viewerMax);
  4705. var bottomDist = Math.min(eyePosY, viewerMax);
  4706. var topDist = Math.min(screenHeight - eyePosY, viewerMax);
  4707. return {
  4708. outerDist: outerDist,
  4709. innerDist: innerDist,
  4710. topDist: topDist,
  4711. bottomDist: bottomDist,
  4712. eyePosX: eyePosX,
  4713. eyePosY: eyePosY
  4714. };
  4715. };
  4716. function CardboardViewer(params) {
  4717. // A machine readable ID.
  4718. this.id = params.id;
  4719. // A human readable label.
  4720. this.label = params.label;
  4721. // Field of view in degrees (per side).
  4722. this.fov = params.fov;
  4723. // Distance between lens centers in meters.
  4724. this.interLensDistance = params.interLensDistance;
  4725. // Distance between viewer baseline and lens center in meters.
  4726. this.baselineLensDistance = params.baselineLensDistance;
  4727. // Screen-to-lens distance in meters.
  4728. this.screenLensDistance = params.screenLensDistance;
  4729. // Distortion coefficients.
  4730. this.distortionCoefficients = params.distortionCoefficients;
  4731. // Inverse distortion coefficients.
  4732. // TODO: Calculate these from distortionCoefficients in the future.
  4733. this.inverseCoefficients = params.inverseCoefficients;
  4734. }
  4735. // Export viewer information.
  4736. DeviceInfo.Viewers = Viewers;
  4737. module.exports = DeviceInfo;
  4738. },{"./distortion/distortion.js":16,"./math-util.js":20,"./util.js":29}],15:[function(_dereq_,module,exports){
  4739. /*
  4740. * Copyright 2016 Google Inc. All Rights Reserved.
  4741. * Licensed under the Apache License, Version 2.0 (the "License");
  4742. * you may not use this file except in compliance with the License.
  4743. * You may obtain a copy of the License at
  4744. *
  4745. * http://www.apache.org/licenses/LICENSE-2.0
  4746. *
  4747. * Unless required by applicable law or agreed to in writing, software
  4748. * distributed under the License is distributed on an "AS IS" BASIS,
  4749. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  4750. * See the License for the specific language governing permissions and
  4751. * limitations under the License.
  4752. */
  4753. var VRDisplay = _dereq_('./base.js').VRDisplay;
  4754. var HMDVRDevice = _dereq_('./base.js').HMDVRDevice;
  4755. var PositionSensorVRDevice = _dereq_('./base.js').PositionSensorVRDevice;
  4756. /**
  4757. * Wraps a VRDisplay and exposes it as a HMDVRDevice
  4758. */
  4759. function VRDisplayHMDDevice(display) {
  4760. this.display = display;
  4761. this.hardwareUnitId = display.displayId;
  4762. this.deviceId = 'webvr-polyfill:HMD:' + display.displayId;
  4763. this.deviceName = display.displayName + ' (HMD)';
  4764. }
  4765. VRDisplayHMDDevice.prototype = new HMDVRDevice();
  4766. VRDisplayHMDDevice.prototype.getEyeParameters = function(whichEye) {
  4767. var eyeParameters = this.display.getEyeParameters(whichEye);
  4768. return {
  4769. currentFieldOfView: eyeParameters.fieldOfView,
  4770. maximumFieldOfView: eyeParameters.fieldOfView,
  4771. minimumFieldOfView: eyeParameters.fieldOfView,
  4772. recommendedFieldOfView: eyeParameters.fieldOfView,
  4773. eyeTranslation: { x: eyeParameters.offset[0], y: eyeParameters.offset[1], z: eyeParameters.offset[2] },
  4774. renderRect: {
  4775. x: (whichEye == 'right') ? eyeParameters.renderWidth : 0,
  4776. y: 0,
  4777. width: eyeParameters.renderWidth,
  4778. height: eyeParameters.renderHeight
  4779. }
  4780. };
  4781. };
  4782. VRDisplayHMDDevice.prototype.setFieldOfView =
  4783. function(opt_fovLeft, opt_fovRight, opt_zNear, opt_zFar) {
  4784. // Not supported. getEyeParameters reports that the min, max, and recommended
  4785. // FoV is all the same, so no adjustment can be made.
  4786. };
  4787. // TODO: Need to hook requestFullscreen to see if a wrapped VRDisplay was passed
  4788. // in as an option. If so we should prevent the default fullscreen behavior and
  4789. // call VRDisplay.requestPresent instead.
  4790. /**
  4791. * Wraps a VRDisplay and exposes it as a PositionSensorVRDevice
  4792. */
  4793. function VRDisplayPositionSensorDevice(display) {
  4794. this.display = display;
  4795. this.hardwareUnitId = display.displayId;
  4796. this.deviceId = 'webvr-polyfill:PositionSensor: ' + display.displayId;
  4797. this.deviceName = display.displayName + ' (PositionSensor)';
  4798. }
  4799. VRDisplayPositionSensorDevice.prototype = new PositionSensorVRDevice();
  4800. VRDisplayPositionSensorDevice.prototype.getState = function() {
  4801. var pose = this.display.getPose();
  4802. return {
  4803. position: pose.position ? { x: pose.position[0], y: pose.position[1], z: pose.position[2] } : null,
  4804. orientation: pose.orientation ? { x: pose.orientation[0], y: pose.orientation[1], z: pose.orientation[2], w: pose.orientation[3] } : null,
  4805. linearVelocity: null,
  4806. linearAcceleration: null,
  4807. angularVelocity: null,
  4808. angularAcceleration: null
  4809. };
  4810. };
  4811. VRDisplayPositionSensorDevice.prototype.resetState = function() {
  4812. return this.positionDevice.resetPose();
  4813. };
  4814. module.exports.VRDisplayHMDDevice = VRDisplayHMDDevice;
  4815. module.exports.VRDisplayPositionSensorDevice = VRDisplayPositionSensorDevice;
  4816. },{"./base.js":9}],16:[function(_dereq_,module,exports){
  4817. /**
  4818. * TODO(smus): Implement coefficient inversion.
  4819. */
  4820. function Distortion(coefficients) {
  4821. this.coefficients = coefficients;
  4822. }
  4823. /**
  4824. * Calculates the inverse distortion for a radius.
  4825. * </p><p>
  4826. * Allows to compute the original undistorted radius from a distorted one.
  4827. * See also getApproximateInverseDistortion() for a faster but potentially
  4828. * less accurate method.
  4829. *
  4830. * @param {Number} radius Distorted radius from the lens center in tan-angle units.
  4831. * @return {Number} The undistorted radius in tan-angle units.
  4832. */
  4833. Distortion.prototype.distortInverse = function(radius) {
  4834. // Secant method.
  4835. var r0 = 0;
  4836. var r1 = 1;
  4837. var dr0 = radius - this.distort(r0);
  4838. while (Math.abs(r1 - r0) > 0.0001 /** 0.1mm */) {
  4839. var dr1 = radius - this.distort(r1);
  4840. var r2 = r1 - dr1 * ((r1 - r0) / (dr1 - dr0));
  4841. r0 = r1;
  4842. r1 = r2;
  4843. dr0 = dr1;
  4844. }
  4845. return r1;
  4846. };
  4847. /**
  4848. * Distorts a radius by its distortion factor from the center of the lenses.
  4849. *
  4850. * @param {Number} radius Radius from the lens center in tan-angle units.
  4851. * @return {Number} The distorted radius in tan-angle units.
  4852. */
  4853. Distortion.prototype.distort = function(radius) {
  4854. var r2 = radius * radius;
  4855. var ret = 0;
  4856. for (var i = 0; i < this.coefficients.length; i++) {
  4857. ret = r2 * (ret + this.coefficients[i]);
  4858. }
  4859. return (ret + 1) * radius;
  4860. };
  4861. module.exports = Distortion;
  4862. },{}],17:[function(_dereq_,module,exports){
  4863. module.exports={
  4864. "format": 1,
  4865. "last_updated": "2017-08-27T14:39:31Z",
  4866. "devices": [
  4867. {
  4868. "type": "android",
  4869. "rules": [
  4870. {
  4871. "mdmh": "asus/*/Nexus 7/*"
  4872. },
  4873. {
  4874. "ua": "Nexus 7"
  4875. }
  4876. ],
  4877. "dpi": [
  4878. 320.8,
  4879. 323
  4880. ],
  4881. "bw": 3,
  4882. "ac": 500
  4883. },
  4884. {
  4885. "type": "android",
  4886. "rules": [
  4887. {
  4888. "mdmh": "asus/*/ASUS_Z00AD/*"
  4889. },
  4890. {
  4891. "ua": "ASUS_Z00AD"
  4892. }
  4893. ],
  4894. "dpi": [
  4895. 403,
  4896. 404.6
  4897. ],
  4898. "bw": 3,
  4899. "ac": 1000
  4900. },
  4901. {
  4902. "type": "android",
  4903. "rules": [
  4904. {
  4905. "mdmh": "Google/*/Pixel XL/*"
  4906. },
  4907. {
  4908. "ua": "Pixel XL"
  4909. }
  4910. ],
  4911. "dpi": [
  4912. 537.9,
  4913. 533
  4914. ],
  4915. "bw": 3,
  4916. "ac": 1000
  4917. },
  4918. {
  4919. "type": "android",
  4920. "rules": [
  4921. {
  4922. "mdmh": "Google/*/Pixel/*"
  4923. },
  4924. {
  4925. "ua": "Pixel"
  4926. }
  4927. ],
  4928. "dpi": [
  4929. 432.6,
  4930. 436.7
  4931. ],
  4932. "bw": 3,
  4933. "ac": 1000
  4934. },
  4935. {
  4936. "type": "android",
  4937. "rules": [
  4938. {
  4939. "mdmh": "HTC/*/HTC6435LVW/*"
  4940. },
  4941. {
  4942. "ua": "HTC6435LVW"
  4943. }
  4944. ],
  4945. "dpi": [
  4946. 449.7,
  4947. 443.3
  4948. ],
  4949. "bw": 3,
  4950. "ac": 1000
  4951. },
  4952. {
  4953. "type": "android",
  4954. "rules": [
  4955. {
  4956. "mdmh": "HTC/*/HTC One XL/*"
  4957. },
  4958. {
  4959. "ua": "HTC One XL"
  4960. }
  4961. ],
  4962. "dpi": [
  4963. 315.3,
  4964. 314.6
  4965. ],
  4966. "bw": 3,
  4967. "ac": 1000
  4968. },
  4969. {
  4970. "type": "android",
  4971. "rules": [
  4972. {
  4973. "mdmh": "htc/*/Nexus 9/*"
  4974. },
  4975. {
  4976. "ua": "Nexus 9"
  4977. }
  4978. ],
  4979. "dpi": 289,
  4980. "bw": 3,
  4981. "ac": 500
  4982. },
  4983. {
  4984. "type": "android",
  4985. "rules": [
  4986. {
  4987. "mdmh": "HTC/*/HTC One M9/*"
  4988. },
  4989. {
  4990. "ua": "HTC One M9"
  4991. }
  4992. ],
  4993. "dpi": [
  4994. 442.5,
  4995. 443.3
  4996. ],
  4997. "bw": 3,
  4998. "ac": 500
  4999. },
  5000. {
  5001. "type": "android",
  5002. "rules": [
  5003. {
  5004. "mdmh": "HTC/*/HTC One_M8/*"
  5005. },
  5006. {
  5007. "ua": "HTC One_M8"
  5008. }
  5009. ],
  5010. "dpi": [
  5011. 449.7,
  5012. 447.4
  5013. ],
  5014. "bw": 3,
  5015. "ac": 500
  5016. },
  5017. {
  5018. "type": "android",
  5019. "rules": [
  5020. {
  5021. "mdmh": "HTC/*/HTC One/*"
  5022. },
  5023. {
  5024. "ua": "HTC One"
  5025. }
  5026. ],
  5027. "dpi": 472.8,
  5028. "bw": 3,
  5029. "ac": 1000
  5030. },
  5031. {
  5032. "type": "android",
  5033. "rules": [
  5034. {
  5035. "mdmh": "Huawei/*/Nexus 6P/*"
  5036. },
  5037. {
  5038. "ua": "Nexus 6P"
  5039. }
  5040. ],
  5041. "dpi": [
  5042. 515.1,
  5043. 518
  5044. ],
  5045. "bw": 3,
  5046. "ac": 1000
  5047. },
  5048. {
  5049. "type": "android",
  5050. "rules": [
  5051. {
  5052. "mdmh": "LENOVO/*/Lenovo PB2-690Y/*"
  5053. },
  5054. {
  5055. "ua": "Lenovo PB2-690Y"
  5056. }
  5057. ],
  5058. "dpi": [
  5059. 457.2,
  5060. 454.713
  5061. ],
  5062. "bw": 3,
  5063. "ac": 500
  5064. },
  5065. {
  5066. "type": "android",
  5067. "rules": [
  5068. {
  5069. "mdmh": "LGE/*/Nexus 5X/*"
  5070. },
  5071. {
  5072. "ua": "Nexus 5X"
  5073. }
  5074. ],
  5075. "dpi": [
  5076. 422,
  5077. 419.9
  5078. ],
  5079. "bw": 3,
  5080. "ac": 1000
  5081. },
  5082. {
  5083. "type": "android",
  5084. "rules": [
  5085. {
  5086. "mdmh": "LGE/*/LGMS345/*"
  5087. },
  5088. {
  5089. "ua": "LGMS345"
  5090. }
  5091. ],
  5092. "dpi": [
  5093. 221.7,
  5094. 219.1
  5095. ],
  5096. "bw": 3,
  5097. "ac": 500
  5098. },
  5099. {
  5100. "type": "android",
  5101. "rules": [
  5102. {
  5103. "mdmh": "LGE/*/LG-D800/*"
  5104. },
  5105. {
  5106. "ua": "LG-D800"
  5107. }
  5108. ],
  5109. "dpi": [
  5110. 422,
  5111. 424.1
  5112. ],
  5113. "bw": 3,
  5114. "ac": 500
  5115. },
  5116. {
  5117. "type": "android",
  5118. "rules": [
  5119. {
  5120. "mdmh": "LGE/*/LG-D850/*"
  5121. },
  5122. {
  5123. "ua": "LG-D850"
  5124. }
  5125. ],
  5126. "dpi": [
  5127. 537.9,
  5128. 541.9
  5129. ],
  5130. "bw": 3,
  5131. "ac": 500
  5132. },
  5133. {
  5134. "type": "android",
  5135. "rules": [
  5136. {
  5137. "mdmh": "LGE/*/VS985 4G/*"
  5138. },
  5139. {
  5140. "ua": "VS985 4G"
  5141. }
  5142. ],
  5143. "dpi": [
  5144. 537.9,
  5145. 535.6
  5146. ],
  5147. "bw": 3,
  5148. "ac": 1000
  5149. },
  5150. {
  5151. "type": "android",
  5152. "rules": [
  5153. {
  5154. "mdmh": "LGE/*/Nexus 5/*"
  5155. },
  5156. {
  5157. "ua": "Nexus 5 B"
  5158. }
  5159. ],
  5160. "dpi": [
  5161. 442.4,
  5162. 444.8
  5163. ],
  5164. "bw": 3,
  5165. "ac": 1000
  5166. },
  5167. {
  5168. "type": "android",
  5169. "rules": [
  5170. {
  5171. "mdmh": "LGE/*/Nexus 4/*"
  5172. },
  5173. {
  5174. "ua": "Nexus 4"
  5175. }
  5176. ],
  5177. "dpi": [
  5178. 319.8,
  5179. 318.4
  5180. ],
  5181. "bw": 3,
  5182. "ac": 1000
  5183. },
  5184. {
  5185. "type": "android",
  5186. "rules": [
  5187. {
  5188. "mdmh": "LGE/*/LG-P769/*"
  5189. },
  5190. {
  5191. "ua": "LG-P769"
  5192. }
  5193. ],
  5194. "dpi": [
  5195. 240.6,
  5196. 247.5
  5197. ],
  5198. "bw": 3,
  5199. "ac": 1000
  5200. },
  5201. {
  5202. "type": "android",
  5203. "rules": [
  5204. {
  5205. "mdmh": "LGE/*/LGMS323/*"
  5206. },
  5207. {
  5208. "ua": "LGMS323"
  5209. }
  5210. ],
  5211. "dpi": [
  5212. 206.6,
  5213. 204.6
  5214. ],
  5215. "bw": 3,
  5216. "ac": 1000
  5217. },
  5218. {
  5219. "type": "android",
  5220. "rules": [
  5221. {
  5222. "mdmh": "LGE/*/LGLS996/*"
  5223. },
  5224. {
  5225. "ua": "LGLS996"
  5226. }
  5227. ],
  5228. "dpi": [
  5229. 403.4,
  5230. 401.5
  5231. ],
  5232. "bw": 3,
  5233. "ac": 1000
  5234. },
  5235. {
  5236. "type": "android",
  5237. "rules": [
  5238. {
  5239. "mdmh": "Micromax/*/4560MMX/*"
  5240. },
  5241. {
  5242. "ua": "4560MMX"
  5243. }
  5244. ],
  5245. "dpi": [
  5246. 240,
  5247. 219.4
  5248. ],
  5249. "bw": 3,
  5250. "ac": 1000
  5251. },
  5252. {
  5253. "type": "android",
  5254. "rules": [
  5255. {
  5256. "mdmh": "Micromax/*/A250/*"
  5257. },
  5258. {
  5259. "ua": "Micromax A250"
  5260. }
  5261. ],
  5262. "dpi": [
  5263. 480,
  5264. 446.4
  5265. ],
  5266. "bw": 3,
  5267. "ac": 1000
  5268. },
  5269. {
  5270. "type": "android",
  5271. "rules": [
  5272. {
  5273. "mdmh": "Micromax/*/Micromax AQ4501/*"
  5274. },
  5275. {
  5276. "ua": "Micromax AQ4501"
  5277. }
  5278. ],
  5279. "dpi": 240,
  5280. "bw": 3,
  5281. "ac": 500
  5282. },
  5283. {
  5284. "type": "android",
  5285. "rules": [
  5286. {
  5287. "mdmh": "motorola/*/DROID RAZR/*"
  5288. },
  5289. {
  5290. "ua": "DROID RAZR"
  5291. }
  5292. ],
  5293. "dpi": [
  5294. 368.1,
  5295. 256.7
  5296. ],
  5297. "bw": 3,
  5298. "ac": 1000
  5299. },
  5300. {
  5301. "type": "android",
  5302. "rules": [
  5303. {
  5304. "mdmh": "motorola/*/XT830C/*"
  5305. },
  5306. {
  5307. "ua": "XT830C"
  5308. }
  5309. ],
  5310. "dpi": [
  5311. 254,
  5312. 255.9
  5313. ],
  5314. "bw": 3,
  5315. "ac": 1000
  5316. },
  5317. {
  5318. "type": "android",
  5319. "rules": [
  5320. {
  5321. "mdmh": "motorola/*/XT1021/*"
  5322. },
  5323. {
  5324. "ua": "XT1021"
  5325. }
  5326. ],
  5327. "dpi": [
  5328. 254,
  5329. 256.7
  5330. ],
  5331. "bw": 3,
  5332. "ac": 500
  5333. },
  5334. {
  5335. "type": "android",
  5336. "rules": [
  5337. {
  5338. "mdmh": "motorola/*/XT1023/*"
  5339. },
  5340. {
  5341. "ua": "XT1023"
  5342. }
  5343. ],
  5344. "dpi": [
  5345. 254,
  5346. 256.7
  5347. ],
  5348. "bw": 3,
  5349. "ac": 500
  5350. },
  5351. {
  5352. "type": "android",
  5353. "rules": [
  5354. {
  5355. "mdmh": "motorola/*/XT1028/*"
  5356. },
  5357. {
  5358. "ua": "XT1028"
  5359. }
  5360. ],
  5361. "dpi": [
  5362. 326.6,
  5363. 327.6
  5364. ],
  5365. "bw": 3,
  5366. "ac": 1000
  5367. },
  5368. {
  5369. "type": "android",
  5370. "rules": [
  5371. {
  5372. "mdmh": "motorola/*/XT1034/*"
  5373. },
  5374. {
  5375. "ua": "XT1034"
  5376. }
  5377. ],
  5378. "dpi": [
  5379. 326.6,
  5380. 328.4
  5381. ],
  5382. "bw": 3,
  5383. "ac": 500
  5384. },
  5385. {
  5386. "type": "android",
  5387. "rules": [
  5388. {
  5389. "mdmh": "motorola/*/XT1053/*"
  5390. },
  5391. {
  5392. "ua": "XT1053"
  5393. }
  5394. ],
  5395. "dpi": [
  5396. 315.3,
  5397. 316.1
  5398. ],
  5399. "bw": 3,
  5400. "ac": 1000
  5401. },
  5402. {
  5403. "type": "android",
  5404. "rules": [
  5405. {
  5406. "mdmh": "motorola/*/XT1562/*"
  5407. },
  5408. {
  5409. "ua": "XT1562"
  5410. }
  5411. ],
  5412. "dpi": [
  5413. 403.4,
  5414. 402.7
  5415. ],
  5416. "bw": 3,
  5417. "ac": 1000
  5418. },
  5419. {
  5420. "type": "android",
  5421. "rules": [
  5422. {
  5423. "mdmh": "motorola/*/Nexus 6/*"
  5424. },
  5425. {
  5426. "ua": "Nexus 6 B"
  5427. }
  5428. ],
  5429. "dpi": [
  5430. 494.3,
  5431. 489.7
  5432. ],
  5433. "bw": 3,
  5434. "ac": 1000
  5435. },
  5436. {
  5437. "type": "android",
  5438. "rules": [
  5439. {
  5440. "mdmh": "motorola/*/XT1063/*"
  5441. },
  5442. {
  5443. "ua": "XT1063"
  5444. }
  5445. ],
  5446. "dpi": [
  5447. 295,
  5448. 296.6
  5449. ],
  5450. "bw": 3,
  5451. "ac": 1000
  5452. },
  5453. {
  5454. "type": "android",
  5455. "rules": [
  5456. {
  5457. "mdmh": "motorola/*/XT1064/*"
  5458. },
  5459. {
  5460. "ua": "XT1064"
  5461. }
  5462. ],
  5463. "dpi": [
  5464. 295,
  5465. 295.6
  5466. ],
  5467. "bw": 3,
  5468. "ac": 500
  5469. },
  5470. {
  5471. "type": "android",
  5472. "rules": [
  5473. {
  5474. "mdmh": "motorola/*/XT1092/*"
  5475. },
  5476. {
  5477. "ua": "XT1092"
  5478. }
  5479. ],
  5480. "dpi": [
  5481. 422,
  5482. 424.1
  5483. ],
  5484. "bw": 3,
  5485. "ac": 500
  5486. },
  5487. {
  5488. "type": "android",
  5489. "rules": [
  5490. {
  5491. "mdmh": "motorola/*/XT1095/*"
  5492. },
  5493. {
  5494. "ua": "XT1095"
  5495. }
  5496. ],
  5497. "dpi": [
  5498. 422,
  5499. 423.4
  5500. ],
  5501. "bw": 3,
  5502. "ac": 1000
  5503. },
  5504. {
  5505. "type": "android",
  5506. "rules": [
  5507. {
  5508. "mdmh": "motorola/*/G4/*"
  5509. },
  5510. {
  5511. "ua": "Moto G (4)"
  5512. }
  5513. ],
  5514. "dpi": 401,
  5515. "bw": 4,
  5516. "ac": 1000
  5517. },
  5518. {
  5519. "type": "android",
  5520. "rules": [
  5521. {
  5522. "mdmh": "OnePlus/*/A0001/*"
  5523. },
  5524. {
  5525. "ua": "A0001"
  5526. }
  5527. ],
  5528. "dpi": [
  5529. 403.4,
  5530. 401
  5531. ],
  5532. "bw": 3,
  5533. "ac": 1000
  5534. },
  5535. {
  5536. "type": "android",
  5537. "rules": [
  5538. {
  5539. "mdmh": "OnePlus/*/ONE E1005/*"
  5540. },
  5541. {
  5542. "ua": "ONE E1005"
  5543. }
  5544. ],
  5545. "dpi": [
  5546. 442.4,
  5547. 441.4
  5548. ],
  5549. "bw": 3,
  5550. "ac": 1000
  5551. },
  5552. {
  5553. "type": "android",
  5554. "rules": [
  5555. {
  5556. "mdmh": "OnePlus/*/ONE A2005/*"
  5557. },
  5558. {
  5559. "ua": "ONE A2005"
  5560. }
  5561. ],
  5562. "dpi": [
  5563. 391.9,
  5564. 405.4
  5565. ],
  5566. "bw": 3,
  5567. "ac": 1000
  5568. },
  5569. {
  5570. "type": "android",
  5571. "rules": [
  5572. {
  5573. "mdmh": "OPPO/*/X909/*"
  5574. },
  5575. {
  5576. "ua": "X909"
  5577. }
  5578. ],
  5579. "dpi": [
  5580. 442.4,
  5581. 444.1
  5582. ],
  5583. "bw": 3,
  5584. "ac": 1000
  5585. },
  5586. {
  5587. "type": "android",
  5588. "rules": [
  5589. {
  5590. "mdmh": "samsung/*/GT-I9082/*"
  5591. },
  5592. {
  5593. "ua": "GT-I9082"
  5594. }
  5595. ],
  5596. "dpi": [
  5597. 184.7,
  5598. 185.4
  5599. ],
  5600. "bw": 3,
  5601. "ac": 1000
  5602. },
  5603. {
  5604. "type": "android",
  5605. "rules": [
  5606. {
  5607. "mdmh": "samsung/*/SM-G360P/*"
  5608. },
  5609. {
  5610. "ua": "SM-G360P"
  5611. }
  5612. ],
  5613. "dpi": [
  5614. 196.7,
  5615. 205.4
  5616. ],
  5617. "bw": 3,
  5618. "ac": 1000
  5619. },
  5620. {
  5621. "type": "android",
  5622. "rules": [
  5623. {
  5624. "mdmh": "samsung/*/Nexus S/*"
  5625. },
  5626. {
  5627. "ua": "Nexus S"
  5628. }
  5629. ],
  5630. "dpi": [
  5631. 234.5,
  5632. 229.8
  5633. ],
  5634. "bw": 3,
  5635. "ac": 1000
  5636. },
  5637. {
  5638. "type": "android",
  5639. "rules": [
  5640. {
  5641. "mdmh": "samsung/*/GT-I9300/*"
  5642. },
  5643. {
  5644. "ua": "GT-I9300"
  5645. }
  5646. ],
  5647. "dpi": [
  5648. 304.8,
  5649. 303.9
  5650. ],
  5651. "bw": 5,
  5652. "ac": 500
  5653. },
  5654. {
  5655. "type": "android",
  5656. "rules": [
  5657. {
  5658. "mdmh": "samsung/*/SM-T230NU/*"
  5659. },
  5660. {
  5661. "ua": "SM-T230NU"
  5662. }
  5663. ],
  5664. "dpi": 216,
  5665. "bw": 3,
  5666. "ac": 500
  5667. },
  5668. {
  5669. "type": "android",
  5670. "rules": [
  5671. {
  5672. "mdmh": "samsung/*/SGH-T399/*"
  5673. },
  5674. {
  5675. "ua": "SGH-T399"
  5676. }
  5677. ],
  5678. "dpi": [
  5679. 217.7,
  5680. 231.4
  5681. ],
  5682. "bw": 3,
  5683. "ac": 1000
  5684. },
  5685. {
  5686. "type": "android",
  5687. "rules": [
  5688. {
  5689. "mdmh": "samsung/*/SGH-M919/*"
  5690. },
  5691. {
  5692. "ua": "SGH-M919"
  5693. }
  5694. ],
  5695. "dpi": [
  5696. 440.8,
  5697. 437.7
  5698. ],
  5699. "bw": 3,
  5700. "ac": 1000
  5701. },
  5702. {
  5703. "type": "android",
  5704. "rules": [
  5705. {
  5706. "mdmh": "samsung/*/SM-N9005/*"
  5707. },
  5708. {
  5709. "ua": "SM-N9005"
  5710. }
  5711. ],
  5712. "dpi": [
  5713. 386.4,
  5714. 387
  5715. ],
  5716. "bw": 3,
  5717. "ac": 500
  5718. },
  5719. {
  5720. "type": "android",
  5721. "rules": [
  5722. {
  5723. "mdmh": "samsung/*/SAMSUNG-SM-N900A/*"
  5724. },
  5725. {
  5726. "ua": "SAMSUNG-SM-N900A"
  5727. }
  5728. ],
  5729. "dpi": [
  5730. 386.4,
  5731. 387.7
  5732. ],
  5733. "bw": 3,
  5734. "ac": 1000
  5735. },
  5736. {
  5737. "type": "android",
  5738. "rules": [
  5739. {
  5740. "mdmh": "samsung/*/GT-I9500/*"
  5741. },
  5742. {
  5743. "ua": "GT-I9500"
  5744. }
  5745. ],
  5746. "dpi": [
  5747. 442.5,
  5748. 443.3
  5749. ],
  5750. "bw": 3,
  5751. "ac": 500
  5752. },
  5753. {
  5754. "type": "android",
  5755. "rules": [
  5756. {
  5757. "mdmh": "samsung/*/GT-I9505/*"
  5758. },
  5759. {
  5760. "ua": "GT-I9505"
  5761. }
  5762. ],
  5763. "dpi": 439.4,
  5764. "bw": 4,
  5765. "ac": 1000
  5766. },
  5767. {
  5768. "type": "android",
  5769. "rules": [
  5770. {
  5771. "mdmh": "samsung/*/SM-G900F/*"
  5772. },
  5773. {
  5774. "ua": "SM-G900F"
  5775. }
  5776. ],
  5777. "dpi": [
  5778. 415.6,
  5779. 431.6
  5780. ],
  5781. "bw": 5,
  5782. "ac": 1000
  5783. },
  5784. {
  5785. "type": "android",
  5786. "rules": [
  5787. {
  5788. "mdmh": "samsung/*/SM-G900M/*"
  5789. },
  5790. {
  5791. "ua": "SM-G900M"
  5792. }
  5793. ],
  5794. "dpi": [
  5795. 415.6,
  5796. 431.6
  5797. ],
  5798. "bw": 5,
  5799. "ac": 1000
  5800. },
  5801. {
  5802. "type": "android",
  5803. "rules": [
  5804. {
  5805. "mdmh": "samsung/*/SM-G800F/*"
  5806. },
  5807. {
  5808. "ua": "SM-G800F"
  5809. }
  5810. ],
  5811. "dpi": 326.8,
  5812. "bw": 3,
  5813. "ac": 1000
  5814. },
  5815. {
  5816. "type": "android",
  5817. "rules": [
  5818. {
  5819. "mdmh": "samsung/*/SM-G906S/*"
  5820. },
  5821. {
  5822. "ua": "SM-G906S"
  5823. }
  5824. ],
  5825. "dpi": [
  5826. 562.7,
  5827. 572.4
  5828. ],
  5829. "bw": 3,
  5830. "ac": 1000
  5831. },
  5832. {
  5833. "type": "android",
  5834. "rules": [
  5835. {
  5836. "mdmh": "samsung/*/GT-I9300/*"
  5837. },
  5838. {
  5839. "ua": "GT-I9300"
  5840. }
  5841. ],
  5842. "dpi": [
  5843. 306.7,
  5844. 304.8
  5845. ],
  5846. "bw": 5,
  5847. "ac": 1000
  5848. },
  5849. {
  5850. "type": "android",
  5851. "rules": [
  5852. {
  5853. "mdmh": "samsung/*/SM-T535/*"
  5854. },
  5855. {
  5856. "ua": "SM-T535"
  5857. }
  5858. ],
  5859. "dpi": [
  5860. 142.6,
  5861. 136.4
  5862. ],
  5863. "bw": 3,
  5864. "ac": 500
  5865. },
  5866. {
  5867. "type": "android",
  5868. "rules": [
  5869. {
  5870. "mdmh": "samsung/*/SM-N920C/*"
  5871. },
  5872. {
  5873. "ua": "SM-N920C"
  5874. }
  5875. ],
  5876. "dpi": [
  5877. 515.1,
  5878. 518.4
  5879. ],
  5880. "bw": 3,
  5881. "ac": 1000
  5882. },
  5883. {
  5884. "type": "android",
  5885. "rules": [
  5886. {
  5887. "mdmh": "samsung/*/SM-N920W8/*"
  5888. },
  5889. {
  5890. "ua": "SM-N920W8"
  5891. }
  5892. ],
  5893. "dpi": [
  5894. 515.1,
  5895. 518.4
  5896. ],
  5897. "bw": 3,
  5898. "ac": 1000
  5899. },
  5900. {
  5901. "type": "android",
  5902. "rules": [
  5903. {
  5904. "mdmh": "samsung/*/GT-I9300I/*"
  5905. },
  5906. {
  5907. "ua": "GT-I9300I"
  5908. }
  5909. ],
  5910. "dpi": [
  5911. 304.8,
  5912. 305.8
  5913. ],
  5914. "bw": 3,
  5915. "ac": 1000
  5916. },
  5917. {
  5918. "type": "android",
  5919. "rules": [
  5920. {
  5921. "mdmh": "samsung/*/GT-I9195/*"
  5922. },
  5923. {
  5924. "ua": "GT-I9195"
  5925. }
  5926. ],
  5927. "dpi": [
  5928. 249.4,
  5929. 256.7
  5930. ],
  5931. "bw": 3,
  5932. "ac": 500
  5933. },
  5934. {
  5935. "type": "android",
  5936. "rules": [
  5937. {
  5938. "mdmh": "samsung/*/SPH-L520/*"
  5939. },
  5940. {
  5941. "ua": "SPH-L520"
  5942. }
  5943. ],
  5944. "dpi": [
  5945. 249.4,
  5946. 255.9
  5947. ],
  5948. "bw": 3,
  5949. "ac": 1000
  5950. },
  5951. {
  5952. "type": "android",
  5953. "rules": [
  5954. {
  5955. "mdmh": "samsung/*/SAMSUNG-SGH-I717/*"
  5956. },
  5957. {
  5958. "ua": "SAMSUNG-SGH-I717"
  5959. }
  5960. ],
  5961. "dpi": 285.8,
  5962. "bw": 3,
  5963. "ac": 1000
  5964. },
  5965. {
  5966. "type": "android",
  5967. "rules": [
  5968. {
  5969. "mdmh": "samsung/*/SPH-D710/*"
  5970. },
  5971. {
  5972. "ua": "SPH-D710"
  5973. }
  5974. ],
  5975. "dpi": [
  5976. 217.7,
  5977. 204.2
  5978. ],
  5979. "bw": 3,
  5980. "ac": 1000
  5981. },
  5982. {
  5983. "type": "android",
  5984. "rules": [
  5985. {
  5986. "mdmh": "samsung/*/GT-N7100/*"
  5987. },
  5988. {
  5989. "ua": "GT-N7100"
  5990. }
  5991. ],
  5992. "dpi": 265.1,
  5993. "bw": 3,
  5994. "ac": 1000
  5995. },
  5996. {
  5997. "type": "android",
  5998. "rules": [
  5999. {
  6000. "mdmh": "samsung/*/SCH-I605/*"
  6001. },
  6002. {
  6003. "ua": "SCH-I605"
  6004. }
  6005. ],
  6006. "dpi": 265.1,
  6007. "bw": 3,
  6008. "ac": 1000
  6009. },
  6010. {
  6011. "type": "android",
  6012. "rules": [
  6013. {
  6014. "mdmh": "samsung/*/Galaxy Nexus/*"
  6015. },
  6016. {
  6017. "ua": "Galaxy Nexus"
  6018. }
  6019. ],
  6020. "dpi": [
  6021. 315.3,
  6022. 314.2
  6023. ],
  6024. "bw": 3,
  6025. "ac": 1000
  6026. },
  6027. {
  6028. "type": "android",
  6029. "rules": [
  6030. {
  6031. "mdmh": "samsung/*/SM-N910H/*"
  6032. },
  6033. {
  6034. "ua": "SM-N910H"
  6035. }
  6036. ],
  6037. "dpi": [
  6038. 515.1,
  6039. 518
  6040. ],
  6041. "bw": 3,
  6042. "ac": 1000
  6043. },
  6044. {
  6045. "type": "android",
  6046. "rules": [
  6047. {
  6048. "mdmh": "samsung/*/SM-N910C/*"
  6049. },
  6050. {
  6051. "ua": "SM-N910C"
  6052. }
  6053. ],
  6054. "dpi": [
  6055. 515.2,
  6056. 520.2
  6057. ],
  6058. "bw": 3,
  6059. "ac": 500
  6060. },
  6061. {
  6062. "type": "android",
  6063. "rules": [
  6064. {
  6065. "mdmh": "samsung/*/SM-G130M/*"
  6066. },
  6067. {
  6068. "ua": "SM-G130M"
  6069. }
  6070. ],
  6071. "dpi": [
  6072. 165.9,
  6073. 164.8
  6074. ],
  6075. "bw": 3,
  6076. "ac": 500
  6077. },
  6078. {
  6079. "type": "android",
  6080. "rules": [
  6081. {
  6082. "mdmh": "samsung/*/SM-G928I/*"
  6083. },
  6084. {
  6085. "ua": "SM-G928I"
  6086. }
  6087. ],
  6088. "dpi": [
  6089. 515.1,
  6090. 518.4
  6091. ],
  6092. "bw": 3,
  6093. "ac": 1000
  6094. },
  6095. {
  6096. "type": "android",
  6097. "rules": [
  6098. {
  6099. "mdmh": "samsung/*/SM-G920F/*"
  6100. },
  6101. {
  6102. "ua": "SM-G920F"
  6103. }
  6104. ],
  6105. "dpi": 580.6,
  6106. "bw": 3,
  6107. "ac": 500
  6108. },
  6109. {
  6110. "type": "android",
  6111. "rules": [
  6112. {
  6113. "mdmh": "samsung/*/SM-G920P/*"
  6114. },
  6115. {
  6116. "ua": "SM-G920P"
  6117. }
  6118. ],
  6119. "dpi": [
  6120. 522.5,
  6121. 577
  6122. ],
  6123. "bw": 3,
  6124. "ac": 1000
  6125. },
  6126. {
  6127. "type": "android",
  6128. "rules": [
  6129. {
  6130. "mdmh": "samsung/*/SM-G925F/*"
  6131. },
  6132. {
  6133. "ua": "SM-G925F"
  6134. }
  6135. ],
  6136. "dpi": 580.6,
  6137. "bw": 3,
  6138. "ac": 500
  6139. },
  6140. {
  6141. "type": "android",
  6142. "rules": [
  6143. {
  6144. "mdmh": "samsung/*/SM-G925V/*"
  6145. },
  6146. {
  6147. "ua": "SM-G925V"
  6148. }
  6149. ],
  6150. "dpi": [
  6151. 522.5,
  6152. 576.6
  6153. ],
  6154. "bw": 3,
  6155. "ac": 1000
  6156. },
  6157. {
  6158. "type": "android",
  6159. "rules": [
  6160. {
  6161. "mdmh": "samsung/*/SM-G930F/*"
  6162. },
  6163. {
  6164. "ua": "SM-G930F"
  6165. }
  6166. ],
  6167. "dpi": 576.6,
  6168. "bw": 3,
  6169. "ac": 1000
  6170. },
  6171. {
  6172. "type": "android",
  6173. "rules": [
  6174. {
  6175. "mdmh": "samsung/*/SM-G935F/*"
  6176. },
  6177. {
  6178. "ua": "SM-G935F"
  6179. }
  6180. ],
  6181. "dpi": 533,
  6182. "bw": 3,
  6183. "ac": 500
  6184. },
  6185. {
  6186. "type": "android",
  6187. "rules": [
  6188. {
  6189. "mdmh": "samsung/*/SM-G950F/*"
  6190. },
  6191. {
  6192. "ua": "SM-G950F"
  6193. }
  6194. ],
  6195. "dpi": [
  6196. 562.707,
  6197. 565.293
  6198. ],
  6199. "bw": 3,
  6200. "ac": 500
  6201. },
  6202. {
  6203. "type": "android",
  6204. "rules": [
  6205. {
  6206. "mdmh": "samsung/*/SM-G955U/*"
  6207. },
  6208. {
  6209. "ua": "SM-G955U"
  6210. }
  6211. ],
  6212. "dpi": [
  6213. 522.514,
  6214. 525.762
  6215. ],
  6216. "bw": 3,
  6217. "ac": 500
  6218. },
  6219. {
  6220. "type": "android",
  6221. "rules": [
  6222. {
  6223. "mdmh": "Sony/*/C6903/*"
  6224. },
  6225. {
  6226. "ua": "C6903"
  6227. }
  6228. ],
  6229. "dpi": [
  6230. 442.5,
  6231. 443.3
  6232. ],
  6233. "bw": 3,
  6234. "ac": 500
  6235. },
  6236. {
  6237. "type": "android",
  6238. "rules": [
  6239. {
  6240. "mdmh": "Sony/*/D6653/*"
  6241. },
  6242. {
  6243. "ua": "D6653"
  6244. }
  6245. ],
  6246. "dpi": [
  6247. 428.6,
  6248. 427.6
  6249. ],
  6250. "bw": 3,
  6251. "ac": 1000
  6252. },
  6253. {
  6254. "type": "android",
  6255. "rules": [
  6256. {
  6257. "mdmh": "Sony/*/E6653/*"
  6258. },
  6259. {
  6260. "ua": "E6653"
  6261. }
  6262. ],
  6263. "dpi": [
  6264. 428.6,
  6265. 425.7
  6266. ],
  6267. "bw": 3,
  6268. "ac": 1000
  6269. },
  6270. {
  6271. "type": "android",
  6272. "rules": [
  6273. {
  6274. "mdmh": "Sony/*/E6853/*"
  6275. },
  6276. {
  6277. "ua": "E6853"
  6278. }
  6279. ],
  6280. "dpi": [
  6281. 403.4,
  6282. 401.9
  6283. ],
  6284. "bw": 3,
  6285. "ac": 1000
  6286. },
  6287. {
  6288. "type": "android",
  6289. "rules": [
  6290. {
  6291. "mdmh": "Sony/*/SGP321/*"
  6292. },
  6293. {
  6294. "ua": "SGP321"
  6295. }
  6296. ],
  6297. "dpi": [
  6298. 224.7,
  6299. 224.1
  6300. ],
  6301. "bw": 3,
  6302. "ac": 500
  6303. },
  6304. {
  6305. "type": "android",
  6306. "rules": [
  6307. {
  6308. "mdmh": "TCT/*/ALCATEL ONE TOUCH Fierce/*"
  6309. },
  6310. {
  6311. "ua": "ALCATEL ONE TOUCH Fierce"
  6312. }
  6313. ],
  6314. "dpi": [
  6315. 240,
  6316. 247.5
  6317. ],
  6318. "bw": 3,
  6319. "ac": 1000
  6320. },
  6321. {
  6322. "type": "android",
  6323. "rules": [
  6324. {
  6325. "mdmh": "THL/*/thl 5000/*"
  6326. },
  6327. {
  6328. "ua": "thl 5000"
  6329. }
  6330. ],
  6331. "dpi": [
  6332. 480,
  6333. 443.3
  6334. ],
  6335. "bw": 3,
  6336. "ac": 1000
  6337. },
  6338. {
  6339. "type": "android",
  6340. "rules": [
  6341. {
  6342. "mdmh": "ZTE/*/ZTE Blade L2/*"
  6343. },
  6344. {
  6345. "ua": "ZTE Blade L2"
  6346. }
  6347. ],
  6348. "dpi": 240,
  6349. "bw": 3,
  6350. "ac": 500
  6351. },
  6352. {
  6353. "type": "ios",
  6354. "rules": [
  6355. {
  6356. "res": [
  6357. 640,
  6358. 960
  6359. ]
  6360. }
  6361. ],
  6362. "dpi": [
  6363. 325.1,
  6364. 328.4
  6365. ],
  6366. "bw": 4,
  6367. "ac": 1000
  6368. },
  6369. {
  6370. "type": "ios",
  6371. "rules": [
  6372. {
  6373. "res": [
  6374. 640,
  6375. 1136
  6376. ]
  6377. }
  6378. ],
  6379. "dpi": [
  6380. 317.1,
  6381. 320.2
  6382. ],
  6383. "bw": 3,
  6384. "ac": 1000
  6385. },
  6386. {
  6387. "type": "ios",
  6388. "rules": [
  6389. {
  6390. "res": [
  6391. 750,
  6392. 1334
  6393. ]
  6394. }
  6395. ],
  6396. "dpi": 326.4,
  6397. "bw": 4,
  6398. "ac": 1000
  6399. },
  6400. {
  6401. "type": "ios",
  6402. "rules": [
  6403. {
  6404. "res": [
  6405. 1242,
  6406. 2208
  6407. ]
  6408. }
  6409. ],
  6410. "dpi": [
  6411. 453.6,
  6412. 458.4
  6413. ],
  6414. "bw": 4,
  6415. "ac": 1000
  6416. },
  6417. {
  6418. "type": "ios",
  6419. "rules": [
  6420. {
  6421. "res": [
  6422. 1125,
  6423. 2001
  6424. ]
  6425. }
  6426. ],
  6427. "dpi": [
  6428. 410.9,
  6429. 415.4
  6430. ],
  6431. "bw": 4,
  6432. "ac": 1000
  6433. }
  6434. ]
  6435. }
  6436. },{}],18:[function(_dereq_,module,exports){
  6437. /*
  6438. * Copyright 2015 Google Inc. All Rights Reserved.
  6439. * Licensed under the Apache License, Version 2.0 (the "License");
  6440. * you may not use this file except in compliance with the License.
  6441. * You may obtain a copy of the License at
  6442. *
  6443. * http://www.apache.org/licenses/LICENSE-2.0
  6444. *
  6445. * Unless required by applicable law or agreed to in writing, software
  6446. * distributed under the License is distributed on an "AS IS" BASIS,
  6447. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  6448. * See the License for the specific language governing permissions and
  6449. * limitations under the License.
  6450. */
  6451. // Offline cache of the DPDB, to be used until we load the online one (and
  6452. // as a fallback in case we can't load the online one).
  6453. var DPDB_CACHE = _dereq_('./dpdb.json');
  6454. var Util = _dereq_('../util.js');
  6455. // Online DPDB URL.
  6456. var ONLINE_DPDB_URL =
  6457. 'https://dpdb.webvr.rocks/dpdb.json';
  6458. /**
  6459. * Calculates device parameters based on the DPDB (Device Parameter Database).
  6460. * Initially, uses the cached DPDB values.
  6461. *
  6462. * If fetchOnline == true, then this object tries to fetch the online version
  6463. * of the DPDB and updates the device info if a better match is found.
  6464. * Calls the onDeviceParamsUpdated callback when there is an update to the
  6465. * device information.
  6466. */
  6467. function Dpdb(fetchOnline, onDeviceParamsUpdated) {
  6468. // Start with the offline DPDB cache while we are loading the real one.
  6469. this.dpdb = DPDB_CACHE;
  6470. // Calculate device params based on the offline version of the DPDB.
  6471. this.recalculateDeviceParams_();
  6472. // XHR to fetch online DPDB file, if requested.
  6473. if (fetchOnline) {
  6474. // Set the callback.
  6475. this.onDeviceParamsUpdated = onDeviceParamsUpdated;
  6476. var xhr = new XMLHttpRequest();
  6477. var obj = this;
  6478. xhr.open('GET', ONLINE_DPDB_URL, true);
  6479. xhr.addEventListener('load', function() {
  6480. obj.loading = false;
  6481. if (xhr.status >= 200 && xhr.status <= 299) {
  6482. // Success.
  6483. obj.dpdb = JSON.parse(xhr.response);
  6484. obj.recalculateDeviceParams_();
  6485. } else {
  6486. // Error loading the DPDB.
  6487. console.error('Error loading online DPDB!');
  6488. }
  6489. });
  6490. xhr.send();
  6491. }
  6492. }
  6493. // Returns the current device parameters.
  6494. Dpdb.prototype.getDeviceParams = function() {
  6495. return this.deviceParams;
  6496. };
  6497. // Recalculates this device's parameters based on the DPDB.
  6498. Dpdb.prototype.recalculateDeviceParams_ = function() {
  6499. var newDeviceParams = this.calcDeviceParams_();
  6500. if (newDeviceParams) {
  6501. this.deviceParams = newDeviceParams;
  6502. // Invoke callback, if it is set.
  6503. if (this.onDeviceParamsUpdated) {
  6504. this.onDeviceParamsUpdated(this.deviceParams);
  6505. }
  6506. } else {
  6507. console.error('Failed to recalculate device parameters.');
  6508. }
  6509. };
  6510. // Returns a DeviceParams object that represents the best guess as to this
  6511. // device's parameters. Can return null if the device does not match any
  6512. // known devices.
  6513. Dpdb.prototype.calcDeviceParams_ = function() {
  6514. var db = this.dpdb; // shorthand
  6515. if (!db) {
  6516. console.error('DPDB not available.');
  6517. return null;
  6518. }
  6519. if (db.format != 1) {
  6520. console.error('DPDB has unexpected format version.');
  6521. return null;
  6522. }
  6523. if (!db.devices || !db.devices.length) {
  6524. console.error('DPDB does not have a devices section.');
  6525. return null;
  6526. }
  6527. // Get the actual user agent and screen dimensions in pixels.
  6528. var userAgent = navigator.userAgent || navigator.vendor || window.opera;
  6529. var width = Util.getScreenWidth();
  6530. var height = Util.getScreenHeight();
  6531. if (!db.devices) {
  6532. console.error('DPDB has no devices section.');
  6533. return null;
  6534. }
  6535. for (var i = 0; i < db.devices.length; i++) {
  6536. var device = db.devices[i];
  6537. if (!device.rules) {
  6538. console.warn('Device[' + i + '] has no rules section.');
  6539. continue;
  6540. }
  6541. if (device.type != 'ios' && device.type != 'android') {
  6542. console.warn('Device[' + i + '] has invalid type.');
  6543. continue;
  6544. }
  6545. // See if this device is of the appropriate type.
  6546. if (Util.isIOS() != (device.type == 'ios')) continue;
  6547. // See if this device matches any of the rules:
  6548. var matched = false;
  6549. for (var j = 0; j < device.rules.length; j++) {
  6550. var rule = device.rules[j];
  6551. if (this.matchRule_(rule, userAgent, width, height)) {
  6552. matched = true;
  6553. break;
  6554. }
  6555. }
  6556. if (!matched) continue;
  6557. // device.dpi might be an array of [ xdpi, ydpi] or just a scalar.
  6558. var xdpi = device.dpi[0] || device.dpi;
  6559. var ydpi = device.dpi[1] || device.dpi;
  6560. return new DeviceParams({ xdpi: xdpi, ydpi: ydpi, bevelMm: device.bw });
  6561. }
  6562. console.warn('No DPDB device match.');
  6563. return null;
  6564. };
  6565. Dpdb.prototype.matchRule_ = function(rule, ua, screenWidth, screenHeight) {
  6566. // We can only match 'ua' and 'res' rules, not other types like 'mdmh'
  6567. // (which are meant for native platforms).
  6568. if (!rule.ua && !rule.res) return false;
  6569. // If our user agent string doesn't contain the indicated user agent string,
  6570. // the match fails.
  6571. if (rule.ua && ua.indexOf(rule.ua) < 0) return false;
  6572. // If the rule specifies screen dimensions that don't correspond to ours,
  6573. // the match fails.
  6574. if (rule.res) {
  6575. if (!rule.res[0] || !rule.res[1]) return false;
  6576. var resX = rule.res[0];
  6577. var resY = rule.res[1];
  6578. // Compare min and max so as to make the order not matter, i.e., it should
  6579. // be true that 640x480 == 480x640.
  6580. if (Math.min(screenWidth, screenHeight) != Math.min(resX, resY) ||
  6581. (Math.max(screenWidth, screenHeight) != Math.max(resX, resY))) {
  6582. return false;
  6583. }
  6584. }
  6585. return true;
  6586. }
  6587. function DeviceParams(params) {
  6588. this.xdpi = params.xdpi;
  6589. this.ydpi = params.ydpi;
  6590. this.bevelMm = params.bevelMm;
  6591. }
  6592. module.exports = Dpdb;
  6593. },{"../util.js":29,"./dpdb.json":17}],19:[function(_dereq_,module,exports){
  6594. /*
  6595. * Copyright 2015 Google Inc. All Rights Reserved.
  6596. * Licensed under the Apache License, Version 2.0 (the "License");
  6597. * you may not use this file except in compliance with the License.
  6598. * You may obtain a copy of the License at
  6599. *
  6600. * http://www.apache.org/licenses/LICENSE-2.0
  6601. *
  6602. * Unless required by applicable law or agreed to in writing, software
  6603. * distributed under the License is distributed on an "AS IS" BASIS,
  6604. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  6605. * See the License for the specific language governing permissions and
  6606. * limitations under the License.
  6607. */
  6608. var Util = _dereq_('./util.js');
  6609. var WebVRPolyfill = _dereq_('./webvr-polyfill.js').WebVRPolyfill;
  6610. // Initialize a WebVRConfig just in case.
  6611. window.WebVRConfig = Util.extend({
  6612. // Forces availability of VR mode, even for non-mobile devices.
  6613. FORCE_ENABLE_VR: false,
  6614. // Complementary filter coefficient. 0 for accelerometer, 1 for gyro.
  6615. K_FILTER: 0.98,
  6616. // How far into the future to predict during fast motion (in seconds).
  6617. PREDICTION_TIME_S: 0.040,
  6618. // Flag to enable touch panner. In case you have your own touch controls.
  6619. TOUCH_PANNER_DISABLED: true,
  6620. // Flag to disabled the UI in VR Mode.
  6621. CARDBOARD_UI_DISABLED: false, // Default: false
  6622. // Flag to disable the instructions to rotate your device.
  6623. ROTATE_INSTRUCTIONS_DISABLED: false, // Default: false.
  6624. // Enable yaw panning only, disabling roll and pitch. This can be useful
  6625. // for panoramas with nothing interesting above or below.
  6626. YAW_ONLY: false,
  6627. // To disable keyboard and mouse controls, if you want to use your own
  6628. // implementation.
  6629. MOUSE_KEYBOARD_CONTROLS_DISABLED: false,
  6630. // Prevent the polyfill from initializing immediately. Requires the app
  6631. // to call InitializeWebVRPolyfill() before it can be used.
  6632. DEFER_INITIALIZATION: false,
  6633. // Enable the deprecated version of the API (navigator.getVRDevices).
  6634. ENABLE_DEPRECATED_API: false,
  6635. // Scales the recommended buffer size reported by WebVR, which can improve
  6636. // performance.
  6637. // UPDATE(2016-05-03): Setting this to 0.5 by default since 1.0 does not
  6638. // perform well on many mobile devices.
  6639. BUFFER_SCALE: 0.5,
  6640. // Allow VRDisplay.submitFrame to change gl bindings, which is more
  6641. // efficient if the application code will re-bind its resources on the
  6642. // next frame anyway. This has been seen to cause rendering glitches with
  6643. // THREE.js.
  6644. // Dirty bindings include: gl.FRAMEBUFFER_BINDING, gl.CURRENT_PROGRAM,
  6645. // gl.ARRAY_BUFFER_BINDING, gl.ELEMENT_ARRAY_BUFFER_BINDING,
  6646. // and gl.TEXTURE_BINDING_2D for texture unit 0.
  6647. DIRTY_SUBMIT_FRAME_BINDINGS: false,
  6648. // When set to true, this will cause a polyfilled VRDisplay to always be
  6649. // appended to the list returned by navigator.getVRDisplays(), even if that
  6650. // list includes a native VRDisplay.
  6651. ALWAYS_APPEND_POLYFILL_DISPLAY: false,
  6652. // There are versions of Chrome (M58-M60?) where the native WebVR API exists,
  6653. // and instead of returning 0 VR displays when none are detected,
  6654. // `navigator.getVRDisplays()`'s promise never resolves. This results
  6655. // in the polyfill hanging and not being able to provide fallback
  6656. // displays, so set a timeout in milliseconds to stop waiting for a response
  6657. // and just use polyfilled displays.
  6658. // https://bugs.chromium.org/p/chromium/issues/detail?id=727969
  6659. GET_VR_DISPLAYS_TIMEOUT: 1000,
  6660. }, window.WebVRConfig);
  6661. if (!window.WebVRConfig.DEFER_INITIALIZATION) {
  6662. new WebVRPolyfill();
  6663. } else {
  6664. window.InitializeWebVRPolyfill = function() {
  6665. new WebVRPolyfill();
  6666. }
  6667. }
  6668. window.WebVRPolyfill = WebVRPolyfill;
  6669. },{"./util.js":29,"./webvr-polyfill.js":32}],20:[function(_dereq_,module,exports){
  6670. /*
  6671. * Copyright 2016 Google Inc. All Rights Reserved.
  6672. * Licensed under the Apache License, Version 2.0 (the "License");
  6673. * you may not use this file except in compliance with the License.
  6674. * You may obtain a copy of the License at
  6675. *
  6676. * http://www.apache.org/licenses/LICENSE-2.0
  6677. *
  6678. * Unless required by applicable law or agreed to in writing, software
  6679. * distributed under the License is distributed on an "AS IS" BASIS,
  6680. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  6681. * See the License for the specific language governing permissions and
  6682. * limitations under the License.
  6683. */
  6684. var MathUtil = window.MathUtil || {};
  6685. MathUtil.degToRad = Math.PI / 180;
  6686. MathUtil.radToDeg = 180 / Math.PI;
  6687. // Some minimal math functionality borrowed from THREE.Math and stripped down
  6688. // for the purposes of this library.
  6689. MathUtil.Vector2 = function ( x, y ) {
  6690. this.x = x || 0;
  6691. this.y = y || 0;
  6692. };
  6693. MathUtil.Vector2.prototype = {
  6694. constructor: MathUtil.Vector2,
  6695. set: function ( x, y ) {
  6696. this.x = x;
  6697. this.y = y;
  6698. return this;
  6699. },
  6700. copy: function ( v ) {
  6701. this.x = v.x;
  6702. this.y = v.y;
  6703. return this;
  6704. },
  6705. subVectors: function ( a, b ) {
  6706. this.x = a.x - b.x;
  6707. this.y = a.y - b.y;
  6708. return this;
  6709. },
  6710. };
  6711. MathUtil.Vector3 = function ( x, y, z ) {
  6712. this.x = x || 0;
  6713. this.y = y || 0;
  6714. this.z = z || 0;
  6715. };
  6716. MathUtil.Vector3.prototype = {
  6717. constructor: MathUtil.Vector3,
  6718. set: function ( x, y, z ) {
  6719. this.x = x;
  6720. this.y = y;
  6721. this.z = z;
  6722. return this;
  6723. },
  6724. copy: function ( v ) {
  6725. this.x = v.x;
  6726. this.y = v.y;
  6727. this.z = v.z;
  6728. return this;
  6729. },
  6730. length: function () {
  6731. return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );
  6732. },
  6733. normalize: function () {
  6734. var scalar = this.length();
  6735. if ( scalar !== 0 ) {
  6736. var invScalar = 1 / scalar;
  6737. this.multiplyScalar(invScalar);
  6738. } else {
  6739. this.x = 0;
  6740. this.y = 0;
  6741. this.z = 0;
  6742. }
  6743. return this;
  6744. },
  6745. multiplyScalar: function ( scalar ) {
  6746. this.x *= scalar;
  6747. this.y *= scalar;
  6748. this.z *= scalar;
  6749. },
  6750. applyQuaternion: function ( q ) {
  6751. var x = this.x;
  6752. var y = this.y;
  6753. var z = this.z;
  6754. var qx = q.x;
  6755. var qy = q.y;
  6756. var qz = q.z;
  6757. var qw = q.w;
  6758. // calculate quat * vector
  6759. var ix = qw * x + qy * z - qz * y;
  6760. var iy = qw * y + qz * x - qx * z;
  6761. var iz = qw * z + qx * y - qy * x;
  6762. var iw = - qx * x - qy * y - qz * z;
  6763. // calculate result * inverse quat
  6764. this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;
  6765. this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;
  6766. this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;
  6767. return this;
  6768. },
  6769. dot: function ( v ) {
  6770. return this.x * v.x + this.y * v.y + this.z * v.z;
  6771. },
  6772. crossVectors: function ( a, b ) {
  6773. var ax = a.x, ay = a.y, az = a.z;
  6774. var bx = b.x, by = b.y, bz = b.z;
  6775. this.x = ay * bz - az * by;
  6776. this.y = az * bx - ax * bz;
  6777. this.z = ax * by - ay * bx;
  6778. return this;
  6779. },
  6780. };
  6781. MathUtil.Quaternion = function ( x, y, z, w ) {
  6782. this.x = x || 0;
  6783. this.y = y || 0;
  6784. this.z = z || 0;
  6785. this.w = ( w !== undefined ) ? w : 1;
  6786. };
  6787. MathUtil.Quaternion.prototype = {
  6788. constructor: MathUtil.Quaternion,
  6789. set: function ( x, y, z, w ) {
  6790. this.x = x;
  6791. this.y = y;
  6792. this.z = z;
  6793. this.w = w;
  6794. return this;
  6795. },
  6796. copy: function ( quaternion ) {
  6797. this.x = quaternion.x;
  6798. this.y = quaternion.y;
  6799. this.z = quaternion.z;
  6800. this.w = quaternion.w;
  6801. return this;
  6802. },
  6803. setFromEulerXYZ: function( x, y, z ) {
  6804. var c1 = Math.cos( x / 2 );
  6805. var c2 = Math.cos( y / 2 );
  6806. var c3 = Math.cos( z / 2 );
  6807. var s1 = Math.sin( x / 2 );
  6808. var s2 = Math.sin( y / 2 );
  6809. var s3 = Math.sin( z / 2 );
  6810. this.x = s1 * c2 * c3 + c1 * s2 * s3;
  6811. this.y = c1 * s2 * c3 - s1 * c2 * s3;
  6812. this.z = c1 * c2 * s3 + s1 * s2 * c3;
  6813. this.w = c1 * c2 * c3 - s1 * s2 * s3;
  6814. return this;
  6815. },
  6816. setFromEulerYXZ: function( x, y, z ) {
  6817. var c1 = Math.cos( x / 2 );
  6818. var c2 = Math.cos( y / 2 );
  6819. var c3 = Math.cos( z / 2 );
  6820. var s1 = Math.sin( x / 2 );
  6821. var s2 = Math.sin( y / 2 );
  6822. var s3 = Math.sin( z / 2 );
  6823. this.x = s1 * c2 * c3 + c1 * s2 * s3;
  6824. this.y = c1 * s2 * c3 - s1 * c2 * s3;
  6825. this.z = c1 * c2 * s3 - s1 * s2 * c3;
  6826. this.w = c1 * c2 * c3 + s1 * s2 * s3;
  6827. return this;
  6828. },
  6829. setFromAxisAngle: function ( axis, angle ) {
  6830. // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm
  6831. // assumes axis is normalized
  6832. var halfAngle = angle / 2, s = Math.sin( halfAngle );
  6833. this.x = axis.x * s;
  6834. this.y = axis.y * s;
  6835. this.z = axis.z * s;
  6836. this.w = Math.cos( halfAngle );
  6837. return this;
  6838. },
  6839. multiply: function ( q ) {
  6840. return this.multiplyQuaternions( this, q );
  6841. },
  6842. multiplyQuaternions: function ( a, b ) {
  6843. // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm
  6844. var qax = a.x, qay = a.y, qaz = a.z, qaw = a.w;
  6845. var qbx = b.x, qby = b.y, qbz = b.z, qbw = b.w;
  6846. this.x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;
  6847. this.y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;
  6848. this.z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;
  6849. this.w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;
  6850. return this;
  6851. },
  6852. inverse: function () {
  6853. this.x *= -1;
  6854. this.y *= -1;
  6855. this.z *= -1;
  6856. this.normalize();
  6857. return this;
  6858. },
  6859. normalize: function () {
  6860. var l = Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );
  6861. if ( l === 0 ) {
  6862. this.x = 0;
  6863. this.y = 0;
  6864. this.z = 0;
  6865. this.w = 1;
  6866. } else {
  6867. l = 1 / l;
  6868. this.x = this.x * l;
  6869. this.y = this.y * l;
  6870. this.z = this.z * l;
  6871. this.w = this.w * l;
  6872. }
  6873. return this;
  6874. },
  6875. slerp: function ( qb, t ) {
  6876. if ( t === 0 ) return this;
  6877. if ( t === 1 ) return this.copy( qb );
  6878. var x = this.x, y = this.y, z = this.z, w = this.w;
  6879. // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/
  6880. var cosHalfTheta = w * qb.w + x * qb.x + y * qb.y + z * qb.z;
  6881. if ( cosHalfTheta < 0 ) {
  6882. this.w = - qb.w;
  6883. this.x = - qb.x;
  6884. this.y = - qb.y;
  6885. this.z = - qb.z;
  6886. cosHalfTheta = - cosHalfTheta;
  6887. } else {
  6888. this.copy( qb );
  6889. }
  6890. if ( cosHalfTheta >= 1.0 ) {
  6891. this.w = w;
  6892. this.x = x;
  6893. this.y = y;
  6894. this.z = z;
  6895. return this;
  6896. }
  6897. var halfTheta = Math.acos( cosHalfTheta );
  6898. var sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );
  6899. if ( Math.abs( sinHalfTheta ) < 0.001 ) {
  6900. this.w = 0.5 * ( w + this.w );
  6901. this.x = 0.5 * ( x + this.x );
  6902. this.y = 0.5 * ( y + this.y );
  6903. this.z = 0.5 * ( z + this.z );
  6904. return this;
  6905. }
  6906. var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,
  6907. ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;
  6908. this.w = ( w * ratioA + this.w * ratioB );
  6909. this.x = ( x * ratioA + this.x * ratioB );
  6910. this.y = ( y * ratioA + this.y * ratioB );
  6911. this.z = ( z * ratioA + this.z * ratioB );
  6912. return this;
  6913. },
  6914. setFromUnitVectors: function () {
  6915. // http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final
  6916. // assumes direction vectors vFrom and vTo are normalized
  6917. var v1, r;
  6918. var EPS = 0.000001;
  6919. return function ( vFrom, vTo ) {
  6920. if ( v1 === undefined ) v1 = new MathUtil.Vector3();
  6921. r = vFrom.dot( vTo ) + 1;
  6922. if ( r < EPS ) {
  6923. r = 0;
  6924. if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {
  6925. v1.set( - vFrom.y, vFrom.x, 0 );
  6926. } else {
  6927. v1.set( 0, - vFrom.z, vFrom.y );
  6928. }
  6929. } else {
  6930. v1.crossVectors( vFrom, vTo );
  6931. }
  6932. this.x = v1.x;
  6933. this.y = v1.y;
  6934. this.z = v1.z;
  6935. this.w = r;
  6936. this.normalize();
  6937. return this;
  6938. }
  6939. }(),
  6940. };
  6941. module.exports = MathUtil;
  6942. },{}],21:[function(_dereq_,module,exports){
  6943. /*
  6944. * Copyright 2016 Google Inc. All Rights Reserved.
  6945. * Licensed under the Apache License, Version 2.0 (the "License");
  6946. * you may not use this file except in compliance with the License.
  6947. * You may obtain a copy of the License at
  6948. *
  6949. * http://www.apache.org/licenses/LICENSE-2.0
  6950. *
  6951. * Unless required by applicable law or agreed to in writing, software
  6952. * distributed under the License is distributed on an "AS IS" BASIS,
  6953. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  6954. * See the License for the specific language governing permissions and
  6955. * limitations under the License.
  6956. */
  6957. var VRDisplay = _dereq_('./base.js').VRDisplay;
  6958. var MathUtil = _dereq_('./math-util.js');
  6959. var Util = _dereq_('./util.js');
  6960. // How much to rotate per key stroke.
  6961. var KEY_SPEED = 0.15;
  6962. var KEY_ANIMATION_DURATION = 80;
  6963. // How much to rotate for mouse events.
  6964. var MOUSE_SPEED_X = 0.5;
  6965. var MOUSE_SPEED_Y = 0.3;
  6966. /**
  6967. * VRDisplay based on mouse and keyboard input. Designed for desktops/laptops
  6968. * where orientation events aren't supported. Cannot present.
  6969. */
  6970. function MouseKeyboardVRDisplay() {
  6971. this.displayName = 'Mouse and Keyboard VRDisplay (webvr-polyfill)';
  6972. this.capabilities.hasOrientation = true;
  6973. // Attach to mouse and keyboard events.
  6974. window.addEventListener('keydown', this.onKeyDown_.bind(this));
  6975. window.addEventListener('mousemove', this.onMouseMove_.bind(this));
  6976. window.addEventListener('mousedown', this.onMouseDown_.bind(this));
  6977. window.addEventListener('mouseup', this.onMouseUp_.bind(this));
  6978. // "Private" members.
  6979. this.phi_ = 0;
  6980. this.theta_ = 0;
  6981. // Variables for keyboard-based rotation animation.
  6982. this.targetAngle_ = null;
  6983. this.angleAnimation_ = null;
  6984. // State variables for calculations.
  6985. this.orientation_ = new MathUtil.Quaternion();
  6986. // Variables for mouse-based rotation.
  6987. this.rotateStart_ = new MathUtil.Vector2();
  6988. this.rotateEnd_ = new MathUtil.Vector2();
  6989. this.rotateDelta_ = new MathUtil.Vector2();
  6990. this.isDragging_ = false;
  6991. this.orientationOut_ = new Float32Array(4);
  6992. }
  6993. MouseKeyboardVRDisplay.prototype = new VRDisplay();
  6994. MouseKeyboardVRDisplay.prototype.getImmediatePose = function() {
  6995. this.orientation_.setFromEulerYXZ(this.phi_, this.theta_, 0);
  6996. this.orientationOut_[0] = this.orientation_.x;
  6997. this.orientationOut_[1] = this.orientation_.y;
  6998. this.orientationOut_[2] = this.orientation_.z;
  6999. this.orientationOut_[3] = this.orientation_.w;
  7000. return {
  7001. position: null,
  7002. orientation: this.orientationOut_,
  7003. linearVelocity: null,
  7004. linearAcceleration: null,
  7005. angularVelocity: null,
  7006. angularAcceleration: null
  7007. };
  7008. };
  7009. MouseKeyboardVRDisplay.prototype.onKeyDown_ = function(e) {
  7010. // Track WASD and arrow keys.
  7011. if (e.keyCode == 38) { // Up key.
  7012. this.animatePhi_(this.phi_ + KEY_SPEED);
  7013. } else if (e.keyCode == 39) { // Right key.
  7014. this.animateTheta_(this.theta_ - KEY_SPEED);
  7015. } else if (e.keyCode == 40) { // Down key.
  7016. this.animatePhi_(this.phi_ - KEY_SPEED);
  7017. } else if (e.keyCode == 37) { // Left key.
  7018. this.animateTheta_(this.theta_ + KEY_SPEED);
  7019. }
  7020. };
  7021. MouseKeyboardVRDisplay.prototype.animateTheta_ = function(targetAngle) {
  7022. this.animateKeyTransitions_('theta_', targetAngle);
  7023. };
  7024. MouseKeyboardVRDisplay.prototype.animatePhi_ = function(targetAngle) {
  7025. // Prevent looking too far up or down.
  7026. targetAngle = Util.clamp(targetAngle, -Math.PI/2, Math.PI/2);
  7027. this.animateKeyTransitions_('phi_', targetAngle);
  7028. };
  7029. /**
  7030. * Start an animation to transition an angle from one value to another.
  7031. */
  7032. MouseKeyboardVRDisplay.prototype.animateKeyTransitions_ = function(angleName, targetAngle) {
  7033. // If an animation is currently running, cancel it.
  7034. if (this.angleAnimation_) {
  7035. cancelAnimationFrame(this.angleAnimation_);
  7036. }
  7037. var startAngle = this[angleName];
  7038. var startTime = new Date();
  7039. // Set up an interval timer to perform the animation.
  7040. this.angleAnimation_ = requestAnimationFrame(function animate() {
  7041. // Once we're finished the animation, we're done.
  7042. var elapsed = new Date() - startTime;
  7043. if (elapsed >= KEY_ANIMATION_DURATION) {
  7044. this[angleName] = targetAngle;
  7045. cancelAnimationFrame(this.angleAnimation_);
  7046. return;
  7047. }
  7048. // loop with requestAnimationFrame
  7049. this.angleAnimation_ = requestAnimationFrame(animate.bind(this))
  7050. // Linearly interpolate the angle some amount.
  7051. var percent = elapsed / KEY_ANIMATION_DURATION;
  7052. this[angleName] = startAngle + (targetAngle - startAngle) * percent;
  7053. }.bind(this));
  7054. };
  7055. MouseKeyboardVRDisplay.prototype.onMouseDown_ = function(e) {
  7056. this.rotateStart_.set(e.clientX, e.clientY);
  7057. this.isDragging_ = true;
  7058. };
  7059. // Very similar to https://gist.github.com/mrflix/8351020
  7060. MouseKeyboardVRDisplay.prototype.onMouseMove_ = function(e) {
  7061. if (!this.isDragging_ && !this.isPointerLocked_()) {
  7062. return;
  7063. }
  7064. // Support pointer lock API.
  7065. if (this.isPointerLocked_()) {
  7066. var movementX = e.movementX || e.mozMovementX || 0;
  7067. var movementY = e.movementY || e.mozMovementY || 0;
  7068. this.rotateEnd_.set(this.rotateStart_.x - movementX, this.rotateStart_.y - movementY);
  7069. } else {
  7070. this.rotateEnd_.set(e.clientX, e.clientY);
  7071. }
  7072. // Calculate how much we moved in mouse space.
  7073. this.rotateDelta_.subVectors(this.rotateEnd_, this.rotateStart_);
  7074. this.rotateStart_.copy(this.rotateEnd_);
  7075. // Keep track of the cumulative euler angles.
  7076. this.phi_ += 2 * Math.PI * this.rotateDelta_.y / screen.height * MOUSE_SPEED_Y;
  7077. this.theta_ += 2 * Math.PI * this.rotateDelta_.x / screen.width * MOUSE_SPEED_X;
  7078. // Prevent looking too far up or down.
  7079. this.phi_ = Util.clamp(this.phi_, -Math.PI/2, Math.PI/2);
  7080. };
  7081. MouseKeyboardVRDisplay.prototype.onMouseUp_ = function(e) {
  7082. this.isDragging_ = false;
  7083. };
  7084. MouseKeyboardVRDisplay.prototype.isPointerLocked_ = function() {
  7085. var el = document.pointerLockElement || document.mozPointerLockElement ||
  7086. document.webkitPointerLockElement;
  7087. return el !== undefined;
  7088. };
  7089. MouseKeyboardVRDisplay.prototype.resetPose = function() {
  7090. this.phi_ = 0;
  7091. this.theta_ = 0;
  7092. };
  7093. module.exports = MouseKeyboardVRDisplay;
  7094. },{"./base.js":9,"./math-util.js":20,"./util.js":29}],22:[function(_dereq_,module,exports){
  7095. (function (global){
  7096. // This is the entry point if requiring/importing via node, or
  7097. // a build tool that uses package.json entry (like browserify, webpack).
  7098. // If running in node with a window mock available, globalize its members
  7099. // if needed. Otherwise, just continue to `./main`
  7100. if (typeof global !== 'undefined' && global.window) {
  7101. global.document = global.window.document;
  7102. global.navigator = global.window.navigator;
  7103. }
  7104. _dereq_('./main');
  7105. }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  7106. },{"./main":19}],23:[function(_dereq_,module,exports){
  7107. /*
  7108. * Copyright 2015 Google Inc. All Rights Reserved.
  7109. * Licensed under the Apache License, Version 2.0 (the "License");
  7110. * you may not use this file except in compliance with the License.
  7111. * You may obtain a copy of the License at
  7112. *
  7113. * http://www.apache.org/licenses/LICENSE-2.0
  7114. *
  7115. * Unless required by applicable law or agreed to in writing, software
  7116. * distributed under the License is distributed on an "AS IS" BASIS,
  7117. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  7118. * See the License for the specific language governing permissions and
  7119. * limitations under the License.
  7120. */
  7121. var Util = _dereq_('./util.js');
  7122. function RotateInstructions() {
  7123. this.loadIcon_();
  7124. var overlay = document.createElement('div');
  7125. var s = overlay.style;
  7126. s.position = 'fixed';
  7127. s.top = 0;
  7128. s.right = 0;
  7129. s.bottom = 0;
  7130. s.left = 0;
  7131. s.backgroundColor = 'gray';
  7132. s.fontFamily = 'sans-serif';
  7133. // Force this to be above the fullscreen canvas, which is at zIndex: 999999.
  7134. s.zIndex = 1000000;
  7135. var img = document.createElement('img');
  7136. img.src = this.icon;
  7137. var s = img.style;
  7138. s.marginLeft = '25%';
  7139. s.marginTop = '25%';
  7140. s.width = '50%';
  7141. overlay.appendChild(img);
  7142. var text = document.createElement('div');
  7143. var s = text.style;
  7144. s.textAlign = 'center';
  7145. s.fontSize = '16px';
  7146. s.lineHeight = '24px';
  7147. s.margin = '24px 25%';
  7148. s.width = '50%';
  7149. text.innerHTML = 'Place your phone into your Cardboard viewer.';
  7150. overlay.appendChild(text);
  7151. var snackbar = document.createElement('div');
  7152. var s = snackbar.style;
  7153. s.backgroundColor = '#CFD8DC';
  7154. s.position = 'fixed';
  7155. s.bottom = 0;
  7156. s.width = '100%';
  7157. s.height = '48px';
  7158. s.padding = '14px 24px';
  7159. s.boxSizing = 'border-box';
  7160. s.color = '#656A6B';
  7161. overlay.appendChild(snackbar);
  7162. var snackbarText = document.createElement('div');
  7163. snackbarText.style.float = 'left';
  7164. snackbarText.innerHTML = 'No Cardboard viewer?';
  7165. var snackbarButton = document.createElement('a');
  7166. snackbarButton.href = 'https://www.google.com/get/cardboard/get-cardboard/';
  7167. snackbarButton.innerHTML = 'get one';
  7168. snackbarButton.target = '_blank';
  7169. var s = snackbarButton.style;
  7170. s.float = 'right';
  7171. s.fontWeight = 600;
  7172. s.textTransform = 'uppercase';
  7173. s.borderLeft = '1px solid gray';
  7174. s.paddingLeft = '24px';
  7175. s.textDecoration = 'none';
  7176. s.color = '#656A6B';
  7177. snackbar.appendChild(snackbarText);
  7178. snackbar.appendChild(snackbarButton);
  7179. this.overlay = overlay;
  7180. this.text = text;
  7181. this.hide();
  7182. }
  7183. RotateInstructions.prototype.show = function(parent) {
  7184. if (!parent && !this.overlay.parentElement) {
  7185. document.body.appendChild(this.overlay);
  7186. } else if (parent) {
  7187. if (this.overlay.parentElement && this.overlay.parentElement != parent)
  7188. this.overlay.parentElement.removeChild(this.overlay);
  7189. parent.appendChild(this.overlay);
  7190. }
  7191. this.overlay.style.display = 'block';
  7192. var img = this.overlay.querySelector('img');
  7193. var s = img.style;
  7194. if (Util.isLandscapeMode()) {
  7195. s.width = '20%';
  7196. s.marginLeft = '40%';
  7197. s.marginTop = '3%';
  7198. } else {
  7199. s.width = '50%';
  7200. s.marginLeft = '25%';
  7201. s.marginTop = '25%';
  7202. }
  7203. };
  7204. RotateInstructions.prototype.hide = function() {
  7205. this.overlay.style.display = 'none';
  7206. };
  7207. RotateInstructions.prototype.showTemporarily = function(ms, parent) {
  7208. this.show(parent);
  7209. this.timer = setTimeout(this.hide.bind(this), ms);
  7210. };
  7211. RotateInstructions.prototype.disableShowTemporarily = function() {
  7212. clearTimeout(this.timer);
  7213. };
  7214. RotateInstructions.prototype.update = function() {
  7215. this.disableShowTemporarily();
  7216. // In portrait VR mode, tell the user to rotate to landscape. Otherwise, hide
  7217. // the instructions.
  7218. if (!Util.isLandscapeMode() && Util.isMobile()) {
  7219. this.show();
  7220. } else {
  7221. this.hide();
  7222. }
  7223. };
  7224. RotateInstructions.prototype.loadIcon_ = function() {
  7225. // Encoded asset_src/rotate-instructions.svg
  7226. this.icon = Util.base64('image/svg+xml', 'PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+Cjxzdmcgd2lkdGg9IjE5OHB4IiBoZWlnaHQ9IjI0MHB4IiB2aWV3Qm94PSIwIDAgMTk4IDI0MCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWxuczpza2V0Y2g9Imh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaC9ucyI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDMuMy4zICgxMjA4MSkgLSBodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2ggLS0+CiAgICA8dGl0bGU+dHJhbnNpdGlvbjwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxkZWZzPjwvZGVmcz4KICAgIDxnIGlkPSJQYWdlLTEiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHNrZXRjaDp0eXBlPSJNU1BhZ2UiPgogICAgICAgIDxnIGlkPSJ0cmFuc2l0aW9uIiBza2V0Y2g6dHlwZT0iTVNBcnRib2FyZEdyb3VwIj4KICAgICAgICAgICAgPGcgaWQ9IkltcG9ydGVkLUxheWVycy1Db3B5LTQtKy1JbXBvcnRlZC1MYXllcnMtQ29weS0rLUltcG9ydGVkLUxheWVycy1Db3B5LTItQ29weSIgc2tldGNoOnR5cGU9Ik1TTGF5ZXJHcm91cCI+CiAgICAgICAgICAgICAgICA8ZyBpZD0iSW1wb3J0ZWQtTGF5ZXJzLUNvcHktNCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMC4wMDAwMDAsIDEwNy4wMDAwMDApIiBza2V0Y2g6dHlwZT0iTVNTaGFwZUdyb3VwIj4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTQ5LjYyNSwyLjUyNyBDMTQ5LjYyNSwyLjUyNyAxNTUuODA1LDYuMDk2IDE1Ni4zNjIsNi40MTggTDE1Ni4zNjIsNy4zMDQgQzE1Ni4zNjIsNy40ODEgMTU2LjM3NSw3LjY2NCAxNTYuNCw3Ljg1MyBDMTU2LjQxLDcuOTM0IDE1Ni40Miw4LjAxNSAxNTYuNDI3LDguMDk1IEMxNTYuNTY3LDkuNTEgMTU3LjQwMSwxMS4wOTMgMTU4LjUzMiwxMi4wOTQgTDE2NC4yNTIsMTcuMTU2IEwxNjQuMzMzLDE3LjA2NiBDMTY0LjMzMywxNy4wNjYgMTY4LjcxNSwxNC41MzYgMTY5LjU2OCwxNC4wNDIgQzE3MS4wMjUsMTQuODgzIDE5NS41MzgsMjkuMDM1IDE5NS41MzgsMjkuMDM1IEwxOTUuNTM4LDgzLjAzNiBDMTk1LjUzOCw4My44MDcgMTk1LjE1Miw4NC4yNTMgMTk0LjU5LDg0LjI1MyBDMTk0LjM1Nyw4NC4yNTMgMTk0LjA5NSw4NC4xNzcgMTkzLjgxOCw4NC4wMTcgTDE2OS44NTEsNzAuMTc5IEwxNjkuODM3LDcwLjIwMyBMMTQyLjUxNSw4NS45NzggTDE0MS42NjUsODQuNjU1IEMxMzYuOTM0LDgzLjEyNiAxMzEuOTE3LDgxLjkxNSAxMjYuNzE0LDgxLjA0NSBDMTI2LjcwOSw4MS4wNiAxMjYuNzA3LDgxLjA2OSAxMjYuNzA3LDgxLjA2OSBMMTIxLjY0LDk4LjAzIEwxMTMuNzQ5LDEwMi41ODYgTDExMy43MTIsMTAyLjUyMyBMMTEzLjcxMiwxMzAuMTEzIEMxMTMuNzEyLDEzMC44ODUgMTEzLjMyNiwxMzEuMzMgMTEyLjc2NCwxMzEuMzMgQzExMi41MzIsMTMxLjMzIDExMi4yNjksMTMxLjI1NCAxMTEuOTkyLDEzMS4wOTQgTDY5LjUxOSwxMDYuNTcyIEM2OC41NjksMTA2LjAyMyA2Ny43OTksMTA0LjY5NSA2Ny43OTksMTAzLjYwNSBMNjcuNzk5LDEwMi41NyBMNjcuNzc4LDEwMi42MTcgQzY3LjI3LDEwMi4zOTMgNjYuNjQ4LDEwMi4yNDkgNjUuOTYyLDEwMi4yMTggQzY1Ljg3NSwxMDIuMjE0IDY1Ljc4OCwxMDIuMjEyIDY1LjcwMSwxMDIuMjEyIEM2NS42MDYsMTAyLjIxMiA2NS41MTEsMTAyLjIxNSA2NS40MTYsMTAyLjIxOSBDNjUuMTk1LDEwMi4yMjkgNjQuOTc0LDEwMi4yMzUgNjQuNzU0LDEwMi4yMzUgQzY0LjMzMSwxMDIuMjM1IDYzLjkxMSwxMDIuMjE2IDYzLjQ5OCwxMDIuMTc4IEM2MS44NDMsMTAyLjAyNSA2MC4yOTgsMTAxLjU3OCA1OS4wOTQsMTAwLjg4MiBMMTIuNTE4LDczLjk5MiBMMTIuNTIzLDc0LjAwNCBMMi4yNDUsNTUuMjU0IEMxLjI0NCw1My40MjcgMi4wMDQsNTEuMDM4IDMuOTQzLDQ5LjkxOCBMNTkuOTU0LDE3LjU3MyBDNjAuNjI2LDE3LjE4NSA2MS4zNSwxNy4wMDEgNjIuMDUzLDE3LjAwMSBDNjMuMzc5LDE3LjAwMSA2NC42MjUsMTcuNjYgNjUuMjgsMTguODU0IEw2NS4yODUsMTguODUxIEw2NS41MTIsMTkuMjY0IEw2NS41MDYsMTkuMjY4IEM2NS45MDksMjAuMDAzIDY2LjQwNSwyMC42OCA2Ni45ODMsMjEuMjg2IEw2Ny4yNiwyMS41NTYgQzY5LjE3NCwyMy40MDYgNzEuNzI4LDI0LjM1NyA3NC4zNzMsMjQuMzU3IEM3Ni4zMjIsMjQuMzU3IDc4LjMyMSwyMy44NCA4MC4xNDgsMjIuNzg1IEM4MC4xNjEsMjIuNzg1IDg3LjQ2NywxOC41NjYgODcuNDY3LDE4LjU2NiBDODguMTM5LDE4LjE3OCA4OC44NjMsMTcuOTk0IDg5LjU2NiwxNy45OTQgQzkwLjg5MiwxNy45OTQgOTIuMTM4LDE4LjY1MiA5Mi43OTIsMTkuODQ3IEw5Ni4wNDIsMjUuNzc1IEw5Ni4wNjQsMjUuNzU3IEwxMDIuODQ5LDI5LjY3NCBMMTAyLjc0NCwyOS40OTIgTDE0OS42MjUsMi41MjcgTTE0OS42MjUsMC44OTIgQzE0OS4zNDMsMC44OTIgMTQ5LjA2MiwwLjk2NSAxNDguODEsMS4xMSBMMTAyLjY0MSwyNy42NjYgTDk3LjIzMSwyNC41NDIgTDk0LjIyNiwxOS4wNjEgQzkzLjMxMywxNy4zOTQgOTEuNTI3LDE2LjM1OSA4OS41NjYsMTYuMzU4IEM4OC41NTUsMTYuMzU4IDg3LjU0NiwxNi42MzIgODYuNjQ5LDE3LjE1IEM4My44NzgsMTguNzUgNzkuNjg3LDIxLjE2OSA3OS4zNzQsMjEuMzQ1IEM3OS4zNTksMjEuMzUzIDc5LjM0NSwyMS4zNjEgNzkuMzMsMjEuMzY5IEM3Ny43OTgsMjIuMjU0IDc2LjA4NCwyMi43MjIgNzQuMzczLDIyLjcyMiBDNzIuMDgxLDIyLjcyMiA2OS45NTksMjEuODkgNjguMzk3LDIwLjM4IEw2OC4xNDUsMjAuMTM1IEM2Ny43MDYsMTkuNjcyIDY3LjMyMywxOS4xNTYgNjcuMDA2LDE4LjYwMSBDNjYuOTg4LDE4LjU1OSA2Ni45NjgsMTguNTE5IDY2Ljk0NiwxOC40NzkgTDY2LjcxOSwxOC4wNjUgQzY2LjY5LDE4LjAxMiA2Ni42NTgsMTcuOTYgNjYuNjI0LDE3LjkxMSBDNjUuNjg2LDE2LjMzNyA2My45NTEsMTUuMzY2IDYyLjA1MywxNS4zNjYgQzYxLjA0MiwxNS4zNjYgNjAuMDMzLDE1LjY0IDU5LjEzNiwxNi4xNTggTDMuMTI1LDQ4LjUwMiBDMC40MjYsNTAuMDYxIC0wLjYxMyw1My40NDIgMC44MTEsNTYuMDQgTDExLjA4OSw3NC43OSBDMTEuMjY2LDc1LjExMyAxMS41MzcsNzUuMzUzIDExLjg1LDc1LjQ5NCBMNTguMjc2LDEwMi4yOTggQzU5LjY3OSwxMDMuMTA4IDYxLjQzMywxMDMuNjMgNjMuMzQ4LDEwMy44MDYgQzYzLjgxMiwxMDMuODQ4IDY0LjI4NSwxMDMuODcgNjQuNzU0LDEwMy44NyBDNjUsMTAzLjg3IDY1LjI0OSwxMDMuODY0IDY1LjQ5NCwxMDMuODUyIEM2NS41NjMsMTAzLjg0OSA2NS42MzIsMTAzLjg0NyA2NS43MDEsMTAzLjg0NyBDNjUuNzY0LDEwMy44NDcgNjUuODI4LDEwMy44NDkgNjUuODksMTAzLjg1MiBDNjUuOTg2LDEwMy44NTYgNjYuMDgsMTAzLjg2MyA2Ni4xNzMsMTAzLjg3NCBDNjYuMjgyLDEwNS40NjcgNjcuMzMyLDEwNy4xOTcgNjguNzAyLDEwNy45ODggTDExMS4xNzQsMTMyLjUxIEMxMTEuNjk4LDEzMi44MTIgMTEyLjIzMiwxMzIuOTY1IDExMi43NjQsMTMyLjk2NSBDMTE0LjI2MSwxMzIuOTY1IDExNS4zNDcsMTMxLjc2NSAxMTUuMzQ3LDEzMC4xMTMgTDExNS4zNDcsMTAzLjU1MSBMMTIyLjQ1OCw5OS40NDYgQzEyMi44MTksOTkuMjM3IDEyMy4wODcsOTguODk4IDEyMy4yMDcsOTguNDk4IEwxMjcuODY1LDgyLjkwNSBDMTMyLjI3OSw4My43MDIgMTM2LjU1Nyw4NC43NTMgMTQwLjYwNyw4Ni4wMzMgTDE0MS4xNCw4Ni44NjIgQzE0MS40NTEsODcuMzQ2IDE0MS45NzcsODcuNjEzIDE0Mi41MTYsODcuNjEzIEMxNDIuNzk0LDg3LjYxMyAxNDMuMDc2LDg3LjU0MiAxNDMuMzMzLDg3LjM5MyBMMTY5Ljg2NSw3Mi4wNzYgTDE5Myw4NS40MzMgQzE5My41MjMsODUuNzM1IDE5NC4wNTgsODUuODg4IDE5NC41OSw4NS44ODggQzE5Ni4wODcsODUuODg4IDE5Ny4xNzMsODQuNjg5IDE5Ny4xNzMsODMuMDM2IEwxOTcuMTczLDI5LjAzNSBDMTk3LjE3MywyOC40NTEgMTk2Ljg2MSwyNy45MTEgMTk2LjM1NSwyNy42MTkgQzE5Ni4zNTUsMjcuNjE5IDE3MS44NDMsMTMuNDY3IDE3MC4zODUsMTIuNjI2IEMxNzAuMTMyLDEyLjQ4IDE2OS44NSwxMi40MDcgMTY5LjU2OCwxMi40MDcgQzE2OS4yODUsMTIuNDA3IDE2OS4wMDIsMTIuNDgxIDE2OC43NDksMTIuNjI3IEMxNjguMTQzLDEyLjk3OCAxNjUuNzU2LDE0LjM1NyAxNjQuNDI0LDE1LjEyNSBMMTU5LjYxNSwxMC44NyBDMTU4Ljc5NiwxMC4xNDUgMTU4LjE1NCw4LjkzNyAxNTguMDU0LDcuOTM0IEMxNTguMDQ1LDcuODM3IDE1OC4wMzQsNy43MzkgMTU4LjAyMSw3LjY0IEMxNTguMDA1LDcuNTIzIDE1Ny45OTgsNy40MSAxNTcuOTk4LDcuMzA0IEwxNTcuOTk4LDYuNDE4IEMxNTcuOTk4LDUuODM0IDE1Ny42ODYsNS4yOTUgMTU3LjE4MSw1LjAwMiBDMTU2LjYyNCw0LjY4IDE1MC40NDIsMS4xMTEgMTUwLjQ0MiwxLjExMSBDMTUwLjE4OSwwLjk2NSAxNDkuOTA3LDAuODkyIDE0OS42MjUsMC44OTIiIGlkPSJGaWxsLTEiIGZpbGw9IiM0NTVBNjQiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNOTYuMDI3LDI1LjYzNiBMMTQyLjYwMyw1Mi41MjcgQzE0My44MDcsNTMuMjIyIDE0NC41ODIsNTQuMTE0IDE0NC44NDUsNTUuMDY4IEwxNDQuODM1LDU1LjA3NSBMNjMuNDYxLDEwMi4wNTcgTDYzLjQ2LDEwMi4wNTcgQzYxLjgwNiwxMDEuOTA1IDYwLjI2MSwxMDEuNDU3IDU5LjA1NywxMDAuNzYyIEwxMi40ODEsNzMuODcxIEw5Ni4wMjcsMjUuNjM2IiBpZD0iRmlsbC0yIiBmaWxsPSIjRkFGQUZBIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTYzLjQ2MSwxMDIuMTc0IEM2My40NTMsMTAyLjE3NCA2My40NDYsMTAyLjE3NCA2My40MzksMTAyLjE3MiBDNjEuNzQ2LDEwMi4wMTYgNjAuMjExLDEwMS41NjMgNTguOTk4LDEwMC44NjMgTDEyLjQyMiw3My45NzMgQzEyLjM4Niw3My45NTIgMTIuMzY0LDczLjkxNCAxMi4zNjQsNzMuODcxIEMxMi4zNjQsNzMuODMgMTIuMzg2LDczLjc5MSAxMi40MjIsNzMuNzcgTDk1Ljk2OCwyNS41MzUgQzk2LjAwNCwyNS41MTQgOTYuMDQ5LDI1LjUxNCA5Ni4wODUsMjUuNTM1IEwxNDIuNjYxLDUyLjQyNiBDMTQzLjg4OCw1My4xMzQgMTQ0LjY4Miw1NC4wMzggMTQ0Ljk1Nyw1NS4wMzcgQzE0NC45Nyw1NS4wODMgMTQ0Ljk1Myw1NS4xMzMgMTQ0LjkxNSw1NS4xNjEgQzE0NC45MTEsNTUuMTY1IDE0NC44OTgsNTUuMTc0IDE0NC44OTQsNTUuMTc3IEw2My41MTksMTAyLjE1OCBDNjMuNTAxLDEwMi4xNjkgNjMuNDgxLDEwMi4xNzQgNjMuNDYxLDEwMi4xNzQgTDYzLjQ2MSwxMDIuMTc0IFogTTEyLjcxNCw3My44NzEgTDU5LjExNSwxMDAuNjYxIEM2MC4yOTMsMTAxLjM0MSA2MS43ODYsMTAxLjc4MiA2My40MzUsMTAxLjkzNyBMMTQ0LjcwNyw1NS4wMTUgQzE0NC40MjgsNTQuMTA4IDE0My42ODIsNTMuMjg1IDE0Mi41NDQsNTIuNjI4IEw5Ni4wMjcsMjUuNzcxIEwxMi43MTQsNzMuODcxIEwxMi43MTQsNzMuODcxIFoiIGlkPSJGaWxsLTMiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTQ4LjMyNyw1OC40NzEgQzE0OC4xNDUsNTguNDggMTQ3Ljk2Miw1OC40OCAxNDcuNzgxLDU4LjQ3MiBDMTQ1Ljg4Nyw1OC4zODkgMTQ0LjQ3OSw1Ny40MzQgMTQ0LjYzNiw1Ni4zNCBDMTQ0LjY4OSw1NS45NjcgMTQ0LjY2NCw1NS41OTcgMTQ0LjU2NCw1NS4yMzUgTDYzLjQ2MSwxMDIuMDU3IEM2NC4wODksMTAyLjExNSA2NC43MzMsMTAyLjEzIDY1LjM3OSwxMDIuMDk5IEM2NS41NjEsMTAyLjA5IDY1Ljc0MywxMDIuMDkgNjUuOTI1LDEwMi4wOTggQzY3LjgxOSwxMDIuMTgxIDY5LjIyNywxMDMuMTM2IDY5LjA3LDEwNC4yMyBMMTQ4LjMyNyw1OC40NzEiIGlkPSJGaWxsLTQiIGZpbGw9IiNGRkZGRkYiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNNjkuMDcsMTA0LjM0NyBDNjkuMDQ4LDEwNC4zNDcgNjkuMDI1LDEwNC4zNCA2OS4wMDUsMTA0LjMyNyBDNjguOTY4LDEwNC4zMDEgNjguOTQ4LDEwNC4yNTcgNjguOTU1LDEwNC4yMTMgQzY5LDEwMy44OTYgNjguODk4LDEwMy41NzYgNjguNjU4LDEwMy4yODggQzY4LjE1MywxMDIuNjc4IDY3LjEwMywxMDIuMjY2IDY1LjkyLDEwMi4yMTQgQzY1Ljc0MiwxMDIuMjA2IDY1LjU2MywxMDIuMjA3IDY1LjM4NSwxMDIuMjE1IEM2NC43NDIsMTAyLjI0NiA2NC4wODcsMTAyLjIzMiA2My40NSwxMDIuMTc0IEM2My4zOTksMTAyLjE2OSA2My4zNTgsMTAyLjEzMiA2My4zNDcsMTAyLjA4MiBDNjMuMzM2LDEwMi4wMzMgNjMuMzU4LDEwMS45ODEgNjMuNDAyLDEwMS45NTYgTDE0NC41MDYsNTUuMTM0IEMxNDQuNTM3LDU1LjExNiAxNDQuNTc1LDU1LjExMyAxNDQuNjA5LDU1LjEyNyBDMTQ0LjY0Miw1NS4xNDEgMTQ0LjY2OCw1NS4xNyAxNDQuNjc3LDU1LjIwNCBDMTQ0Ljc4MSw1NS41ODUgMTQ0LjgwNiw1NS45NzIgMTQ0Ljc1MSw1Ni4zNTcgQzE0NC43MDYsNTYuNjczIDE0NC44MDgsNTYuOTk0IDE0NS4wNDcsNTcuMjgyIEMxNDUuNTUzLDU3Ljg5MiAxNDYuNjAyLDU4LjMwMyAxNDcuNzg2LDU4LjM1NSBDMTQ3Ljk2NCw1OC4zNjMgMTQ4LjE0Myw1OC4zNjMgMTQ4LjMyMSw1OC4zNTQgQzE0OC4zNzcsNTguMzUyIDE0OC40MjQsNTguMzg3IDE0OC40MzksNTguNDM4IEMxNDguNDU0LDU4LjQ5IDE0OC40MzIsNTguNTQ1IDE0OC4zODUsNTguNTcyIEw2OS4xMjksMTA0LjMzMSBDNjkuMTExLDEwNC4zNDIgNjkuMDksMTA0LjM0NyA2OS4wNywxMDQuMzQ3IEw2OS4wNywxMDQuMzQ3IFogTTY1LjY2NSwxMDEuOTc1IEM2NS43NTQsMTAxLjk3NSA2NS44NDIsMTAxLjk3NyA2NS45MywxMDEuOTgxIEM2Ny4xOTYsMTAyLjAzNyA2OC4yODMsMTAyLjQ2OSA2OC44MzgsMTAzLjEzOSBDNjkuMDY1LDEwMy40MTMgNjkuMTg4LDEwMy43MTQgNjkuMTk4LDEwNC4wMjEgTDE0Ny44ODMsNTguNTkyIEMxNDcuODQ3LDU4LjU5MiAxNDcuODExLDU4LjU5MSAxNDcuNzc2LDU4LjU4OSBDMTQ2LjUwOSw1OC41MzMgMTQ1LjQyMiw1OC4xIDE0NC44NjcsNTcuNDMxIEMxNDQuNTg1LDU3LjA5MSAxNDQuNDY1LDU2LjcwNyAxNDQuNTIsNTYuMzI0IEMxNDQuNTYzLDU2LjAyMSAxNDQuNTUyLDU1LjcxNiAxNDQuNDg4LDU1LjQxNCBMNjMuODQ2LDEwMS45NyBDNjQuMzUzLDEwMi4wMDIgNjQuODY3LDEwMi4wMDYgNjUuMzc0LDEwMS45ODIgQzY1LjQ3MSwxMDEuOTc3IDY1LjU2OCwxMDEuOTc1IDY1LjY2NSwxMDEuOTc1IEw2NS42NjUsMTAxLjk3NSBaIiBpZD0iRmlsbC01IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTIuMjA4LDU1LjEzNCBDMS4yMDcsNTMuMzA3IDEuOTY3LDUwLjkxNyAzLjkwNiw0OS43OTcgTDU5LjkxNywxNy40NTMgQzYxLjg1NiwxNi4zMzMgNjQuMjQxLDE2LjkwNyA2NS4yNDMsMTguNzM0IEw2NS40NzUsMTkuMTQ0IEM2NS44NzIsMTkuODgyIDY2LjM2OCwyMC41NiA2Ni45NDUsMjEuMTY1IEw2Ny4yMjMsMjEuNDM1IEM3MC41NDgsMjQuNjQ5IDc1LjgwNiwyNS4xNTEgODAuMTExLDIyLjY2NSBMODcuNDMsMTguNDQ1IEM4OS4zNywxNy4zMjYgOTEuNzU0LDE3Ljg5OSA5Mi43NTUsMTkuNzI3IEw5Ni4wMDUsMjUuNjU1IEwxMi40ODYsNzMuODg0IEwyLjIwOCw1NS4xMzQgWiIgaWQ9IkZpbGwtNiIgZmlsbD0iI0ZBRkFGQSI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xMi40ODYsNzQuMDAxIEMxMi40NzYsNzQuMDAxIDEyLjQ2NSw3My45OTkgMTIuNDU1LDczLjk5NiBDMTIuNDI0LDczLjk4OCAxMi4zOTksNzMuOTY3IDEyLjM4NCw3My45NCBMMi4xMDYsNTUuMTkgQzEuMDc1LDUzLjMxIDEuODU3LDUwLjg0NSAzLjg0OCw0OS42OTYgTDU5Ljg1OCwxNy4zNTIgQzYwLjUyNSwxNi45NjcgNjEuMjcxLDE2Ljc2NCA2Mi4wMTYsMTYuNzY0IEM2My40MzEsMTYuNzY0IDY0LjY2NiwxNy40NjYgNjUuMzI3LDE4LjY0NiBDNjUuMzM3LDE4LjY1NCA2NS4zNDUsMTguNjYzIDY1LjM1MSwxOC42NzQgTDY1LjU3OCwxOS4wODggQzY1LjU4NCwxOS4xIDY1LjU4OSwxOS4xMTIgNjUuNTkxLDE5LjEyNiBDNjUuOTg1LDE5LjgzOCA2Ni40NjksMjAuNDk3IDY3LjAzLDIxLjA4NSBMNjcuMzA1LDIxLjM1MSBDNjkuMTUxLDIzLjEzNyA3MS42NDksMjQuMTIgNzQuMzM2LDI0LjEyIEM3Ni4zMTMsMjQuMTIgNzguMjksMjMuNTgyIDgwLjA1MywyMi41NjMgQzgwLjA2NCwyMi41NTcgODAuMDc2LDIyLjU1MyA4MC4wODgsMjIuNTUgTDg3LjM3MiwxOC4zNDQgQzg4LjAzOCwxNy45NTkgODguNzg0LDE3Ljc1NiA4OS41MjksMTcuNzU2IEM5MC45NTYsMTcuNzU2IDkyLjIwMSwxOC40NzIgOTIuODU4LDE5LjY3IEw5Ni4xMDcsMjUuNTk5IEM5Ni4xMzgsMjUuNjU0IDk2LjExOCwyNS43MjQgOTYuMDYzLDI1Ljc1NiBMMTIuNTQ1LDczLjk4NSBDMTIuNTI2LDczLjk5NiAxMi41MDYsNzQuMDAxIDEyLjQ4Niw3NC4wMDEgTDEyLjQ4Niw3NC4wMDEgWiBNNjIuMDE2LDE2Ljk5NyBDNjEuMzEyLDE2Ljk5NyA2MC42MDYsMTcuMTkgNTkuOTc1LDE3LjU1NCBMMy45NjUsNDkuODk5IEMyLjA4Myw1MC45ODUgMS4zNDEsNTMuMzA4IDIuMzEsNTUuMDc4IEwxMi41MzEsNzMuNzIzIEw5NS44NDgsMjUuNjExIEw5Mi42NTMsMTkuNzgyIEM5Mi4wMzgsMTguNjYgOTAuODcsMTcuOTkgODkuNTI5LDE3Ljk5IEM4OC44MjUsMTcuOTkgODguMTE5LDE4LjE4MiA4Ny40ODksMTguNTQ3IEw4MC4xNzIsMjIuNzcyIEM4MC4xNjEsMjIuNzc4IDgwLjE0OSwyMi43ODIgODAuMTM3LDIyLjc4NSBDNzguMzQ2LDIzLjgxMSA3Ni4zNDEsMjQuMzU0IDc0LjMzNiwyNC4zNTQgQzcxLjU4OCwyNC4zNTQgNjkuMDMzLDIzLjM0NyA2Ny4xNDIsMjEuNTE5IEw2Ni44NjQsMjEuMjQ5IEM2Ni4yNzcsMjAuNjM0IDY1Ljc3NCwxOS45NDcgNjUuMzY3LDE5LjIwMyBDNjUuMzYsMTkuMTkyIDY1LjM1NiwxOS4xNzkgNjUuMzU0LDE5LjE2NiBMNjUuMTYzLDE4LjgxOSBDNjUuMTU0LDE4LjgxMSA2NS4xNDYsMTguODAxIDY1LjE0LDE4Ljc5IEM2NC41MjUsMTcuNjY3IDYzLjM1NywxNi45OTcgNjIuMDE2LDE2Ljk5NyBMNjIuMDE2LDE2Ljk5NyBaIiBpZD0iRmlsbC03IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTQyLjQzNCw0OC44MDggTDQyLjQzNCw0OC44MDggQzM5LjkyNCw0OC44MDcgMzcuNzM3LDQ3LjU1IDM2LjU4Miw0NS40NDMgQzM0Ljc3MSw0Mi4xMzkgMzYuMTQ0LDM3LjgwOSAzOS42NDEsMzUuNzg5IEw1MS45MzIsMjguNjkxIEM1My4xMDMsMjguMDE1IDU0LjQxMywyNy42NTggNTUuNzIxLDI3LjY1OCBDNTguMjMxLDI3LjY1OCA2MC40MTgsMjguOTE2IDYxLjU3MywzMS4wMjMgQzYzLjM4NCwzNC4zMjcgNjIuMDEyLDM4LjY1NyA1OC41MTQsNDAuNjc3IEw0Ni4yMjMsNDcuNzc1IEM0NS4wNTMsNDguNDUgNDMuNzQyLDQ4LjgwOCA0Mi40MzQsNDguODA4IEw0Mi40MzQsNDguODA4IFogTTU1LjcyMSwyOC4xMjUgQzU0LjQ5NSwyOC4xMjUgNTMuMjY1LDI4LjQ2MSA1Mi4xNjYsMjkuMDk2IEwzOS44NzUsMzYuMTk0IEMzNi41OTYsMzguMDg3IDM1LjMwMiw0Mi4xMzYgMzYuOTkyLDQ1LjIxOCBDMzguMDYzLDQ3LjE3MyA0MC4wOTgsNDguMzQgNDIuNDM0LDQ4LjM0IEM0My42NjEsNDguMzQgNDQuODksNDguMDA1IDQ1Ljk5LDQ3LjM3IEw1OC4yODEsNDAuMjcyIEM2MS41NiwzOC4zNzkgNjIuODUzLDM0LjMzIDYxLjE2NCwzMS4yNDggQzYwLjA5MiwyOS4yOTMgNTguMDU4LDI4LjEyNSA1NS43MjEsMjguMTI1IEw1NS43MjEsMjguMTI1IFoiIGlkPSJGaWxsLTgiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTQ5LjU4OCwyLjQwNyBDMTQ5LjU4OCwyLjQwNyAxNTUuNzY4LDUuOTc1IDE1Ni4zMjUsNi4yOTcgTDE1Ni4zMjUsNy4xODQgQzE1Ni4zMjUsNy4zNiAxNTYuMzM4LDcuNTQ0IDE1Ni4zNjIsNy43MzMgQzE1Ni4zNzMsNy44MTQgMTU2LjM4Miw3Ljg5NCAxNTYuMzksNy45NzUgQzE1Ni41Myw5LjM5IDE1Ny4zNjMsMTAuOTczIDE1OC40OTUsMTEuOTc0IEwxNjUuODkxLDE4LjUxOSBDMTY2LjA2OCwxOC42NzUgMTY2LjI0OSwxOC44MTQgMTY2LjQzMiwxOC45MzQgQzE2OC4wMTEsMTkuOTc0IDE2OS4zODIsMTkuNCAxNjkuNDk0LDE3LjY1MiBDMTY5LjU0MywxNi44NjggMTY5LjU1MSwxNi4wNTcgMTY5LjUxNywxNS4yMjMgTDE2OS41MTQsMTUuMDYzIEwxNjkuNTE0LDEzLjkxMiBDMTcwLjc4LDE0LjY0MiAxOTUuNTAxLDI4LjkxNSAxOTUuNTAxLDI4LjkxNSBMMTk1LjUwMSw4Mi45MTUgQzE5NS41MDEsODQuMDA1IDE5NC43MzEsODQuNDQ1IDE5My43ODEsODMuODk3IEwxNTEuMzA4LDU5LjM3NCBDMTUwLjM1OCw1OC44MjYgMTQ5LjU4OCw1Ny40OTcgMTQ5LjU4OCw1Ni40MDggTDE0OS41ODgsMjIuMzc1IiBpZD0iRmlsbC05IiBmaWxsPSIjRkFGQUZBIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE5NC41NTMsODQuMjUgQzE5NC4yOTYsODQuMjUgMTk0LjAxMyw4NC4xNjUgMTkzLjcyMiw4My45OTcgTDE1MS4yNSw1OS40NzYgQzE1MC4yNjksNTguOTA5IDE0OS40NzEsNTcuNTMzIDE0OS40NzEsNTYuNDA4IEwxNDkuNDcxLDIyLjM3NSBMMTQ5LjcwNSwyMi4zNzUgTDE0OS43MDUsNTYuNDA4IEMxNDkuNzA1LDU3LjQ1OSAxNTAuNDUsNTguNzQ0IDE1MS4zNjYsNTkuMjc0IEwxOTMuODM5LDgzLjc5NSBDMTk0LjI2Myw4NC4wNCAxOTQuNjU1LDg0LjA4MyAxOTQuOTQyLDgzLjkxNyBDMTk1LjIyNyw4My43NTMgMTk1LjM4NCw4My4zOTcgMTk1LjM4NCw4Mi45MTUgTDE5NS4zODQsMjguOTgyIEMxOTQuMTAyLDI4LjI0MiAxNzIuMTA0LDE1LjU0MiAxNjkuNjMxLDE0LjExNCBMMTY5LjYzNCwxNS4yMiBDMTY5LjY2OCwxNi4wNTIgMTY5LjY2LDE2Ljg3NCAxNjkuNjEsMTcuNjU5IEMxNjkuNTU2LDE4LjUwMyAxNjkuMjE0LDE5LjEyMyAxNjguNjQ3LDE5LjQwNSBDMTY4LjAyOCwxOS43MTQgMTY3LjE5NywxOS41NzggMTY2LjM2NywxOS4wMzIgQzE2Ni4xODEsMTguOTA5IDE2NS45OTUsMTguNzY2IDE2NS44MTQsMTguNjA2IEwxNTguNDE3LDEyLjA2MiBDMTU3LjI1OSwxMS4wMzYgMTU2LjQxOCw5LjQzNyAxNTYuMjc0LDcuOTg2IEMxNTYuMjY2LDcuOTA3IDE1Ni4yNTcsNy44MjcgMTU2LjI0Nyw3Ljc0OCBDMTU2LjIyMSw3LjU1NSAxNTYuMjA5LDcuMzY1IDE1Ni4yMDksNy4xODQgTDE1Ni4yMDksNi4zNjQgQzE1NS4zNzUsNS44ODMgMTQ5LjUyOSwyLjUwOCAxNDkuNTI5LDIuNTA4IEwxNDkuNjQ2LDIuMzA2IEMxNDkuNjQ2LDIuMzA2IDE1NS44MjcsNS44NzQgMTU2LjM4NCw2LjE5NiBMMTU2LjQ0Miw2LjIzIEwxNTYuNDQyLDcuMTg0IEMxNTYuNDQyLDcuMzU1IDE1Ni40NTQsNy41MzUgMTU2LjQ3OCw3LjcxNyBDMTU2LjQ4OSw3LjggMTU2LjQ5OSw3Ljg4MiAxNTYuNTA3LDcuOTYzIEMxNTYuNjQ1LDkuMzU4IDE1Ny40NTUsMTAuODk4IDE1OC41NzIsMTEuODg2IEwxNjUuOTY5LDE4LjQzMSBDMTY2LjE0MiwxOC41ODQgMTY2LjMxOSwxOC43MiAxNjYuNDk2LDE4LjgzNyBDMTY3LjI1NCwxOS4zMzYgMTY4LDE5LjQ2NyAxNjguNTQzLDE5LjE5NiBDMTY5LjAzMywxOC45NTMgMTY5LjMyOSwxOC40MDEgMTY5LjM3NywxNy42NDUgQzE2OS40MjcsMTYuODY3IDE2OS40MzQsMTYuMDU0IDE2OS40MDEsMTUuMjI4IEwxNjkuMzk3LDE1LjA2NSBMMTY5LjM5NywxMy43MSBMMTY5LjU3MiwxMy44MSBDMTcwLjgzOSwxNC41NDEgMTk1LjU1OSwyOC44MTQgMTk1LjU1OSwyOC44MTQgTDE5NS42MTgsMjguODQ3IEwxOTUuNjE4LDgyLjkxNSBDMTk1LjYxOCw4My40ODQgMTk1LjQyLDgzLjkxMSAxOTUuMDU5LDg0LjExOSBDMTk0LjkwOCw4NC4yMDYgMTk0LjczNyw4NC4yNSAxOTQuNTUzLDg0LjI1IiBpZD0iRmlsbC0xMCIgZmlsbD0iIzYwN0Q4QiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xNDUuNjg1LDU2LjE2MSBMMTY5LjgsNzAuMDgzIEwxNDMuODIyLDg1LjA4MSBMMTQyLjM2LDg0Ljc3NCBDMTM1LjgyNiw4Mi42MDQgMTI4LjczMiw4MS4wNDYgMTIxLjM0MSw4MC4xNTggQzExNi45NzYsNzkuNjM0IDExMi42NzgsODEuMjU0IDExMS43NDMsODMuNzc4IEMxMTEuNTA2LDg0LjQxNCAxMTEuNTAzLDg1LjA3MSAxMTEuNzMyLDg1LjcwNiBDMTEzLjI3LDg5Ljk3MyAxMTUuOTY4LDk0LjA2OSAxMTkuNzI3LDk3Ljg0MSBMMTIwLjI1OSw5OC42ODYgQzEyMC4yNiw5OC42ODUgOTQuMjgyLDExMy42ODMgOTQuMjgyLDExMy42ODMgTDcwLjE2Nyw5OS43NjEgTDE0NS42ODUsNTYuMTYxIiBpZD0iRmlsbC0xMSIgZmlsbD0iI0ZGRkZGRiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik05NC4yODIsMTEzLjgxOCBMOTQuMjIzLDExMy43ODUgTDY5LjkzMyw5OS43NjEgTDcwLjEwOCw5OS42NiBMMTQ1LjY4NSw1Ni4wMjYgTDE0NS43NDMsNTYuMDU5IEwxNzAuMDMzLDcwLjA4MyBMMTQzLjg0Miw4NS4yMDUgTDE0My43OTcsODUuMTk1IEMxNDMuNzcyLDg1LjE5IDE0Mi4zMzYsODQuODg4IDE0Mi4zMzYsODQuODg4IEMxMzUuNzg3LDgyLjcxNCAxMjguNzIzLDgxLjE2MyAxMjEuMzI3LDgwLjI3NCBDMTIwLjc4OCw4MC4yMDkgMTIwLjIzNiw4MC4xNzcgMTE5LjY4OSw4MC4xNzcgQzExNS45MzEsODAuMTc3IDExMi42MzUsODEuNzA4IDExMS44NTIsODMuODE5IEMxMTEuNjI0LDg0LjQzMiAxMTEuNjIxLDg1LjA1MyAxMTEuODQyLDg1LjY2NyBDMTEzLjM3Nyw4OS45MjUgMTE2LjA1OCw5My45OTMgMTE5LjgxLDk3Ljc1OCBMMTE5LjgyNiw5Ny43NzkgTDEyMC4zNTIsOTguNjE0IEMxMjAuMzU0LDk4LjYxNyAxMjAuMzU2LDk4LjYyIDEyMC4zNTgsOTguNjI0IEwxMjAuNDIyLDk4LjcyNiBMMTIwLjMxNyw5OC43ODcgQzEyMC4yNjQsOTguODE4IDk0LjU5OSwxMTMuNjM1IDk0LjM0LDExMy43ODUgTDk0LjI4MiwxMTMuODE4IEw5NC4yODIsMTEzLjgxOCBaIE03MC40MDEsOTkuNzYxIEw5NC4yODIsMTEzLjU0OSBMMTE5LjA4NCw5OS4yMjkgQzExOS42Myw5OC45MTQgMTE5LjkzLDk4Ljc0IDEyMC4xMDEsOTguNjU0IEwxMTkuNjM1LDk3LjkxNCBDMTE1Ljg2NCw5NC4xMjcgMTEzLjE2OCw5MC4wMzMgMTExLjYyMiw4NS43NDYgQzExMS4zODIsODUuMDc5IDExMS4zODYsODQuNDA0IDExMS42MzMsODMuNzM4IEMxMTIuNDQ4LDgxLjUzOSAxMTUuODM2LDc5Ljk0MyAxMTkuNjg5LDc5Ljk0MyBDMTIwLjI0Niw3OS45NDMgMTIwLjgwNiw3OS45NzYgMTIxLjM1NSw4MC4wNDIgQzEyOC43NjcsODAuOTMzIDEzNS44NDYsODIuNDg3IDE0Mi4zOTYsODQuNjYzIEMxNDMuMjMyLDg0LjgzOCAxNDMuNjExLDg0LjkxNyAxNDMuNzg2LDg0Ljk2NyBMMTY5LjU2Niw3MC4wODMgTDE0NS42ODUsNTYuMjk1IEw3MC40MDEsOTkuNzYxIEw3MC40MDEsOTkuNzYxIFoiIGlkPSJGaWxsLTEyIiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE2Ny4yMywxOC45NzkgTDE2Ny4yMyw2OS44NSBMMTM5LjkwOSw4NS42MjMgTDEzMy40NDgsNzEuNDU2IEMxMzIuNTM4LDY5LjQ2IDEzMC4wMiw2OS43MTggMTI3LjgyNCw3Mi4wMyBDMTI2Ljc2OSw3My4xNCAxMjUuOTMxLDc0LjU4NSAxMjUuNDk0LDc2LjA0OCBMMTE5LjAzNCw5Ny42NzYgTDkxLjcxMiwxMTMuNDUgTDkxLjcxMiw2Mi41NzkgTDE2Ny4yMywxOC45NzkiIGlkPSJGaWxsLTEzIiBmaWxsPSIjRkZGRkZGIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTkxLjcxMiwxMTMuNTY3IEM5MS42OTIsMTEzLjU2NyA5MS42NzIsMTEzLjU2MSA5MS42NTMsMTEzLjU1MSBDOTEuNjE4LDExMy41MyA5MS41OTUsMTEzLjQ5MiA5MS41OTUsMTEzLjQ1IEw5MS41OTUsNjIuNTc5IEM5MS41OTUsNjIuNTM3IDkxLjYxOCw2Mi40OTkgOTEuNjUzLDYyLjQ3OCBMMTY3LjE3MiwxOC44NzggQzE2Ny4yMDgsMTguODU3IDE2Ny4yNTIsMTguODU3IDE2Ny4yODgsMTguODc4IEMxNjcuMzI0LDE4Ljg5OSAxNjcuMzQ3LDE4LjkzNyAxNjcuMzQ3LDE4Ljk3OSBMMTY3LjM0Nyw2OS44NSBDMTY3LjM0Nyw2OS44OTEgMTY3LjMyNCw2OS45MyAxNjcuMjg4LDY5Ljk1IEwxMzkuOTY3LDg1LjcyNSBDMTM5LjkzOSw4NS43NDEgMTM5LjkwNSw4NS43NDUgMTM5Ljg3Myw4NS43MzUgQzEzOS44NDIsODUuNzI1IDEzOS44MTYsODUuNzAyIDEzOS44MDIsODUuNjcyIEwxMzMuMzQyLDcxLjUwNCBDMTMyLjk2Nyw3MC42ODIgMTMyLjI4LDcwLjIyOSAxMzEuNDA4LDcwLjIyOSBDMTMwLjMxOSw3MC4yMjkgMTI5LjA0NCw3MC45MTUgMTI3LjkwOCw3Mi4xMSBDMTI2Ljg3NCw3My4yIDEyNi4wMzQsNzQuNjQ3IDEyNS42MDYsNzYuMDgyIEwxMTkuMTQ2LDk3LjcwOSBDMTE5LjEzNyw5Ny43MzggMTE5LjExOCw5Ny43NjIgMTE5LjA5Miw5Ny43NzcgTDkxLjc3LDExMy41NTEgQzkxLjc1MiwxMTMuNTYxIDkxLjczMiwxMTMuNTY3IDkxLjcxMiwxMTMuNTY3IEw5MS43MTIsMTEzLjU2NyBaIE05MS44MjksNjIuNjQ3IEw5MS44MjksMTEzLjI0OCBMMTE4LjkzNSw5Ny41OTggTDEyNS4zODIsNzYuMDE1IEMxMjUuODI3LDc0LjUyNSAxMjYuNjY0LDczLjA4MSAxMjcuNzM5LDcxLjk1IEMxMjguOTE5LDcwLjcwOCAxMzAuMjU2LDY5Ljk5NiAxMzEuNDA4LDY5Ljk5NiBDMTMyLjM3Nyw2OS45OTYgMTMzLjEzOSw3MC40OTcgMTMzLjU1NCw3MS40MDcgTDEzOS45NjEsODUuNDU4IEwxNjcuMTEzLDY5Ljc4MiBMMTY3LjExMywxOS4xODEgTDkxLjgyOSw2Mi42NDcgTDkxLjgyOSw2Mi42NDcgWiIgaWQ9IkZpbGwtMTQiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTY4LjU0MywxOS4yMTMgTDE2OC41NDMsNzAuMDgzIEwxNDEuMjIxLDg1Ljg1NyBMMTM0Ljc2MSw3MS42ODkgQzEzMy44NTEsNjkuNjk0IDEzMS4zMzMsNjkuOTUxIDEyOS4xMzcsNzIuMjYzIEMxMjguMDgyLDczLjM3NCAxMjcuMjQ0LDc0LjgxOSAxMjYuODA3LDc2LjI4MiBMMTIwLjM0Niw5Ny45MDkgTDkzLjAyNSwxMTMuNjgzIEw5My4wMjUsNjIuODEzIEwxNjguNTQzLDE5LjIxMyIgaWQ9IkZpbGwtMTUiIGZpbGw9IiNGRkZGRkYiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNOTMuMDI1LDExMy44IEM5My4wMDUsMTEzLjggOTIuOTg0LDExMy43OTUgOTIuOTY2LDExMy43ODUgQzkyLjkzMSwxMTMuNzY0IDkyLjkwOCwxMTMuNzI1IDkyLjkwOCwxMTMuNjg0IEw5Mi45MDgsNjIuODEzIEM5Mi45MDgsNjIuNzcxIDkyLjkzMSw2Mi43MzMgOTIuOTY2LDYyLjcxMiBMMTY4LjQ4NCwxOS4xMTIgQzE2OC41MiwxOS4wOSAxNjguNTY1LDE5LjA5IDE2OC42MDEsMTkuMTEyIEMxNjguNjM3LDE5LjEzMiAxNjguNjYsMTkuMTcxIDE2OC42NiwxOS4yMTIgTDE2OC42Niw3MC4wODMgQzE2OC42Niw3MC4xMjUgMTY4LjYzNyw3MC4xNjQgMTY4LjYwMSw3MC4xODQgTDE0MS4yOCw4NS45NTggQzE0MS4yNTEsODUuOTc1IDE0MS4yMTcsODUuOTc5IDE0MS4xODYsODUuOTY4IEMxNDEuMTU0LDg1Ljk1OCAxNDEuMTI5LDg1LjkzNiAxNDEuMTE1LDg1LjkwNiBMMTM0LjY1NSw3MS43MzggQzEzNC4yOCw3MC45MTUgMTMzLjU5Myw3MC40NjMgMTMyLjcyLDcwLjQ2MyBDMTMxLjYzMiw3MC40NjMgMTMwLjM1Nyw3MS4xNDggMTI5LjIyMSw3Mi4zNDQgQzEyOC4xODYsNzMuNDMzIDEyNy4zNDcsNzQuODgxIDEyNi45MTksNzYuMzE1IEwxMjAuNDU4LDk3Ljk0MyBDMTIwLjQ1LDk3Ljk3MiAxMjAuNDMxLDk3Ljk5NiAxMjAuNDA1LDk4LjAxIEw5My4wODMsMTEzLjc4NSBDOTMuMDY1LDExMy43OTUgOTMuMDQ1LDExMy44IDkzLjAyNSwxMTMuOCBMOTMuMDI1LDExMy44IFogTTkzLjE0Miw2Mi44ODEgTDkzLjE0MiwxMTMuNDgxIEwxMjAuMjQ4LDk3LjgzMiBMMTI2LjY5NSw3Ni4yNDggQzEyNy4xNCw3NC43NTggMTI3Ljk3Nyw3My4zMTUgMTI5LjA1Miw3Mi4xODMgQzEzMC4yMzEsNzAuOTQyIDEzMS41NjgsNzAuMjI5IDEzMi43Miw3MC4yMjkgQzEzMy42ODksNzAuMjI5IDEzNC40NTIsNzAuNzMxIDEzNC44NjcsNzEuNjQxIEwxNDEuMjc0LDg1LjY5MiBMMTY4LjQyNiw3MC4wMTYgTDE2OC40MjYsMTkuNDE1IEw5My4xNDIsNjIuODgxIEw5My4xNDIsNjIuODgxIFoiIGlkPSJGaWxsLTE2IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE2OS44LDcwLjA4MyBMMTQyLjQ3OCw4NS44NTcgTDEzNi4wMTgsNzEuNjg5IEMxMzUuMTA4LDY5LjY5NCAxMzIuNTksNjkuOTUxIDEzMC4zOTMsNzIuMjYzIEMxMjkuMzM5LDczLjM3NCAxMjguNSw3NC44MTkgMTI4LjA2NCw3Ni4yODIgTDEyMS42MDMsOTcuOTA5IEw5NC4yODIsMTEzLjY4MyBMOTQuMjgyLDYyLjgxMyBMMTY5LjgsMTkuMjEzIEwxNjkuOCw3MC4wODMgWiIgaWQ9IkZpbGwtMTciIGZpbGw9IiNGQUZBRkEiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNOTQuMjgyLDExMy45MTcgQzk0LjI0MSwxMTMuOTE3IDk0LjIwMSwxMTMuOTA3IDk0LjE2NSwxMTMuODg2IEM5NC4wOTMsMTEzLjg0NSA5NC4wNDgsMTEzLjc2NyA5NC4wNDgsMTEzLjY4NCBMOTQuMDQ4LDYyLjgxMyBDOTQuMDQ4LDYyLjczIDk0LjA5Myw2Mi42NTIgOTQuMTY1LDYyLjYxMSBMMTY5LjY4MywxOS4wMSBDMTY5Ljc1NSwxOC45NjkgMTY5Ljg0NCwxOC45NjkgMTY5LjkxNywxOS4wMSBDMTY5Ljk4OSwxOS4wNTIgMTcwLjAzMywxOS4xMjkgMTcwLjAzMywxOS4yMTIgTDE3MC4wMzMsNzAuMDgzIEMxNzAuMDMzLDcwLjE2NiAxNjkuOTg5LDcwLjI0NCAxNjkuOTE3LDcwLjI4NSBMMTQyLjU5NSw4Ni4wNiBDMTQyLjUzOCw4Ni4wOTIgMTQyLjQ2OSw4Ni4xIDE0Mi40MDcsODYuMDggQzE0Mi4zNDQsODYuMDYgMTQyLjI5Myw4Ni4wMTQgMTQyLjI2Niw4NS45NTQgTDEzNS44MDUsNzEuNzg2IEMxMzUuNDQ1LDcwLjk5NyAxMzQuODEzLDcwLjU4IDEzMy45NzcsNzAuNTggQzEzMi45MjEsNzAuNTggMTMxLjY3Niw3MS4yNTIgMTMwLjU2Miw3Mi40MjQgQzEyOS41NCw3My41MDEgMTI4LjcxMSw3NC45MzEgMTI4LjI4Nyw3Ni4zNDggTDEyMS44MjcsOTcuOTc2IEMxMjEuODEsOTguMDM0IDEyMS43NzEsOTguMDgyIDEyMS43Miw5OC4xMTIgTDk0LjM5OCwxMTMuODg2IEM5NC4zNjIsMTEzLjkwNyA5NC4zMjIsMTEzLjkxNyA5NC4yODIsMTEzLjkxNyBMOTQuMjgyLDExMy45MTcgWiBNOTQuNTE1LDYyLjk0OCBMOTQuNTE1LDExMy4yNzkgTDEyMS40MDYsOTcuNzU0IEwxMjcuODQsNzYuMjE1IEMxMjguMjksNzQuNzA4IDEyOS4xMzcsNzMuMjQ3IDEzMC4yMjQsNzIuMTAzIEMxMzEuNDI1LDcwLjgzOCAxMzIuNzkzLDcwLjExMiAxMzMuOTc3LDcwLjExMiBDMTM0Ljk5NSw3MC4xMTIgMTM1Ljc5NSw3MC42MzggMTM2LjIzLDcxLjU5MiBMMTQyLjU4NCw4NS41MjYgTDE2OS41NjYsNjkuOTQ4IEwxNjkuNTY2LDE5LjYxNyBMOTQuNTE1LDYyLjk0OCBMOTQuNTE1LDYyLjk0OCBaIiBpZD0iRmlsbC0xOCIgZmlsbD0iIzYwN0Q4QiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xMDkuODk0LDkyLjk0MyBMMTA5Ljg5NCw5Mi45NDMgQzEwOC4xMiw5Mi45NDMgMTA2LjY1Myw5Mi4yMTggMTA1LjY1LDkwLjgyMyBDMTA1LjU4Myw5MC43MzEgMTA1LjU5Myw5MC42MSAxMDUuNjczLDkwLjUyOSBDMTA1Ljc1Myw5MC40NDggMTA1Ljg4LDkwLjQ0IDEwNS45NzQsOTAuNTA2IEMxMDYuNzU0LDkxLjA1MyAxMDcuNjc5LDkxLjMzMyAxMDguNzI0LDkxLjMzMyBDMTEwLjA0Nyw5MS4zMzMgMTExLjQ3OCw5MC44OTQgMTEyLjk4LDkwLjAyNyBDMTE4LjI5MSw4Ni45NiAxMjIuNjExLDc5LjUwOSAxMjIuNjExLDczLjQxNiBDMTIyLjYxMSw3MS40ODkgMTIyLjE2OSw2OS44NTYgMTIxLjMzMyw2OC42OTIgQzEyMS4yNjYsNjguNiAxMjEuMjc2LDY4LjQ3MyAxMjEuMzU2LDY4LjM5MiBDMTIxLjQzNiw2OC4zMTEgMTIxLjU2Myw2OC4yOTkgMTIxLjY1Niw2OC4zNjUgQzEyMy4zMjcsNjkuNTM3IDEyNC4yNDcsNzEuNzQ2IDEyNC4yNDcsNzQuNTg0IEMxMjQuMjQ3LDgwLjgyNiAxMTkuODIxLDg4LjQ0NyAxMTQuMzgyLDkxLjU4NyBDMTEyLjgwOCw5Mi40OTUgMTExLjI5OCw5Mi45NDMgMTA5Ljg5NCw5Mi45NDMgTDEwOS44OTQsOTIuOTQzIFogTTEwNi45MjUsOTEuNDAxIEMxMDcuNzM4LDkyLjA1MiAxMDguNzQ1LDkyLjI3OCAxMDkuODkzLDkyLjI3OCBMMTA5Ljg5NCw5Mi4yNzggQzExMS4yMTUsOTIuMjc4IDExMi42NDcsOTEuOTUxIDExNC4xNDgsOTEuMDg0IEMxMTkuNDU5LDg4LjAxNyAxMjMuNzgsODAuNjIxIDEyMy43OCw3NC41MjggQzEyMy43OCw3Mi41NDkgMTIzLjMxNyw3MC45MjkgMTIyLjQ1NCw2OS43NjcgQzEyMi44NjUsNzAuODAyIDEyMy4wNzksNzIuMDQyIDEyMy4wNzksNzMuNDAyIEMxMjMuMDc5LDc5LjY0NSAxMTguNjUzLDg3LjI4NSAxMTMuMjE0LDkwLjQyNSBDMTExLjY0LDkxLjMzNCAxMTAuMTMsOTEuNzQyIDEwOC43MjQsOTEuNzQyIEMxMDguMDgzLDkxLjc0MiAxMDcuNDgxLDkxLjU5MyAxMDYuOTI1LDkxLjQwMSBMMTA2LjkyNSw5MS40MDEgWiIgaWQ9IkZpbGwtMTkiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTEzLjA5Nyw5MC4yMyBDMTE4LjQ4MSw4Ny4xMjIgMTIyLjg0NSw3OS41OTQgMTIyLjg0NSw3My40MTYgQzEyMi44NDUsNzEuMzY1IDEyMi4zNjIsNjkuNzI0IDEyMS41MjIsNjguNTU2IEMxMTkuNzM4LDY3LjMwNCAxMTcuMTQ4LDY3LjM2MiAxMTQuMjY1LDY5LjAyNiBDMTA4Ljg4MSw3Mi4xMzQgMTA0LjUxNyw3OS42NjIgMTA0LjUxNyw4NS44NCBDMTA0LjUxNyw4Ny44OTEgMTA1LDg5LjUzMiAxMDUuODQsOTAuNyBDMTA3LjYyNCw5MS45NTIgMTEwLjIxNCw5MS44OTQgMTEzLjA5Nyw5MC4yMyIgaWQ9IkZpbGwtMjAiIGZpbGw9IiNGQUZBRkEiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTA4LjcyNCw5MS42MTQgTDEwOC43MjQsOTEuNjE0IEMxMDcuNTgyLDkxLjYxNCAxMDYuNTY2LDkxLjQwMSAxMDUuNzA1LDkwLjc5NyBDMTA1LjY4NCw5MC43ODMgMTA1LjY2NSw5MC44MTEgMTA1LjY1LDkwLjc5IEMxMDQuNzU2LDg5LjU0NiAxMDQuMjgzLDg3Ljg0MiAxMDQuMjgzLDg1LjgxNyBDMTA0LjI4Myw3OS41NzUgMTA4LjcwOSw3MS45NTMgMTE0LjE0OCw2OC44MTIgQzExNS43MjIsNjcuOTA0IDExNy4yMzIsNjcuNDQ5IDExOC42MzgsNjcuNDQ5IEMxMTkuNzgsNjcuNDQ5IDEyMC43OTYsNjcuNzU4IDEyMS42NTYsNjguMzYyIEMxMjEuNjc4LDY4LjM3NyAxMjEuNjk3LDY4LjM5NyAxMjEuNzEyLDY4LjQxOCBDMTIyLjYwNiw2OS42NjIgMTIzLjA3OSw3MS4zOSAxMjMuMDc5LDczLjQxNSBDMTIzLjA3OSw3OS42NTggMTE4LjY1Myw4Ny4xOTggMTEzLjIxNCw5MC4zMzggQzExMS42NCw5MS4yNDcgMTEwLjEzLDkxLjYxNCAxMDguNzI0LDkxLjYxNCBMMTA4LjcyNCw5MS42MTQgWiBNMTA2LjAwNiw5MC41MDUgQzEwNi43OCw5MS4wMzcgMTA3LjY5NCw5MS4yODEgMTA4LjcyNCw5MS4yODEgQzExMC4wNDcsOTEuMjgxIDExMS40NzgsOTAuODY4IDExMi45OCw5MC4wMDEgQzExOC4yOTEsODYuOTM1IDEyMi42MTEsNzkuNDk2IDEyMi42MTEsNzMuNDAzIEMxMjIuNjExLDcxLjQ5NCAxMjIuMTc3LDY5Ljg4IDEyMS4zNTYsNjguNzE4IEMxMjAuNTgyLDY4LjE4NSAxMTkuNjY4LDY3LjkxOSAxMTguNjM4LDY3LjkxOSBDMTE3LjMxNSw2Ny45MTkgMTE1Ljg4Myw2OC4zNiAxMTQuMzgyLDY5LjIyNyBDMTA5LjA3MSw3Mi4yOTMgMTA0Ljc1MSw3OS43MzMgMTA0Ljc1MSw4NS44MjYgQzEwNC43NTEsODcuNzM1IDEwNS4xODUsODkuMzQzIDEwNi4wMDYsOTAuNTA1IEwxMDYuMDA2LDkwLjUwNSBaIiBpZD0iRmlsbC0yMSIgZmlsbD0iIzYwN0Q4QiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xNDkuMzE4LDcuMjYyIEwxMzkuMzM0LDE2LjE0IEwxNTUuMjI3LDI3LjE3MSBMMTYwLjgxNiwyMS4wNTkgTDE0OS4zMTgsNy4yNjIiIGlkPSJGaWxsLTIyIiBmaWxsPSIjRkFGQUZBIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE2OS42NzYsMTMuODQgTDE1OS45MjgsMTkuNDY3IEMxNTYuMjg2LDIxLjU3IDE1MC40LDIxLjU4IDE0Ni43ODEsMTkuNDkxIEMxNDMuMTYxLDE3LjQwMiAxNDMuMTgsMTQuMDAzIDE0Ni44MjIsMTEuOSBMMTU2LjMxNyw2LjI5MiBMMTQ5LjU4OCwyLjQwNyBMNjcuNzUyLDQ5LjQ3OCBMMTEzLjY3NSw3NS45OTIgTDExNi43NTYsNzQuMjEzIEMxMTcuMzg3LDczLjg0OCAxMTcuNjI1LDczLjMxNSAxMTcuMzc0LDcyLjgyMyBDMTE1LjAxNyw2OC4xOTEgMTE0Ljc4MSw2My4yNzcgMTE2LjY5MSw1OC41NjEgQzEyMi4zMjksNDQuNjQxIDE0MS4yLDMzLjc0NiAxNjUuMzA5LDMwLjQ5MSBDMTczLjQ3OCwyOS4zODggMTgxLjk4OSwyOS41MjQgMTkwLjAxMywzMC44ODUgQzE5MC44NjUsMzEuMDMgMTkxLjc4OSwzMC44OTMgMTkyLjQyLDMwLjUyOCBMMTk1LjUwMSwyOC43NSBMMTY5LjY3NiwxMy44NCIgaWQ9IkZpbGwtMjMiIGZpbGw9IiNGQUZBRkEiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTEzLjY3NSw3Ni40NTkgQzExMy41OTQsNzYuNDU5IDExMy41MTQsNzYuNDM4IDExMy40NDIsNzYuMzk3IEw2Ny41MTgsNDkuODgyIEM2Ny4zNzQsNDkuNzk5IDY3LjI4NCw0OS42NDUgNjcuMjg1LDQ5LjQ3OCBDNjcuMjg1LDQ5LjMxMSA2Ny4zNzQsNDkuMTU3IDY3LjUxOSw0OS4wNzMgTDE0OS4zNTUsMi4wMDIgQzE0OS40OTksMS45MTkgMTQ5LjY3NywxLjkxOSAxNDkuODIxLDIuMDAyIEwxNTYuNTUsNS44ODcgQzE1Ni43NzQsNi4wMTcgMTU2Ljg1LDYuMzAyIDE1Ni43MjIsNi41MjYgQzE1Ni41OTIsNi43NDkgMTU2LjMwNyw2LjgyNiAxNTYuMDgzLDYuNjk2IEwxNDkuNTg3LDIuOTQ2IEw2OC42ODcsNDkuNDc5IEwxMTMuNjc1LDc1LjQ1MiBMMTE2LjUyMyw3My44MDggQzExNi43MTUsNzMuNjk3IDExNy4xNDMsNzMuMzk5IDExNi45NTgsNzMuMDM1IEMxMTQuNTQyLDY4LjI4NyAxMTQuMyw2My4yMjEgMTE2LjI1OCw1OC4zODUgQzExOS4wNjQsNTEuNDU4IDEyNS4xNDMsNDUuMTQzIDEzMy44NCw0MC4xMjIgQzE0Mi40OTcsMzUuMTI0IDE1My4zNTgsMzEuNjMzIDE2NS4yNDcsMzAuMDI4IEMxNzMuNDQ1LDI4LjkyMSAxODIuMDM3LDI5LjA1OCAxOTAuMDkxLDMwLjQyNSBDMTkwLjgzLDMwLjU1IDE5MS42NTIsMzAuNDMyIDE5Mi4xODYsMzAuMTI0IEwxOTQuNTY3LDI4Ljc1IEwxNjkuNDQyLDE0LjI0NCBDMTY5LjIxOSwxNC4xMTUgMTY5LjE0MiwxMy44MjkgMTY5LjI3MSwxMy42MDYgQzE2OS40LDEzLjM4MiAxNjkuNjg1LDEzLjMwNiAxNjkuOTA5LDEzLjQzNSBMMTk1LjczNCwyOC4zNDUgQzE5NS44NzksMjguNDI4IDE5NS45NjgsMjguNTgzIDE5NS45NjgsMjguNzUgQzE5NS45NjgsMjguOTE2IDE5NS44NzksMjkuMDcxIDE5NS43MzQsMjkuMTU0IEwxOTIuNjUzLDMwLjkzMyBDMTkxLjkzMiwzMS4zNSAxOTAuODksMzEuNTA4IDE4OS45MzUsMzEuMzQ2IEMxODEuOTcyLDI5Ljk5NSAxNzMuNDc4LDI5Ljg2IDE2NS4zNzIsMzAuOTU0IEMxNTMuNjAyLDMyLjU0MyAxNDIuODYsMzUuOTkzIDEzNC4zMDcsNDAuOTMxIEMxMjUuNzkzLDQ1Ljg0NyAxMTkuODUxLDUyLjAwNCAxMTcuMTI0LDU4LjczNiBDMTE1LjI3LDYzLjMxNCAxMTUuNTAxLDY4LjExMiAxMTcuNzksNzIuNjExIEMxMTguMTYsNzMuMzM2IDExNy44NDUsNzQuMTI0IDExNi45OSw3NC42MTcgTDExMy45MDksNzYuMzk3IEMxMTMuODM2LDc2LjQzOCAxMTMuNzU2LDc2LjQ1OSAxMTMuNjc1LDc2LjQ1OSIgaWQ9IkZpbGwtMjQiIGZpbGw9IiM0NTVBNjQiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTUzLjMxNiwyMS4yNzkgQzE1MC45MDMsMjEuMjc5IDE0OC40OTUsMjAuNzUxIDE0Ni42NjQsMTkuNjkzIEMxNDQuODQ2LDE4LjY0NCAxNDMuODQ0LDE3LjIzMiAxNDMuODQ0LDE1LjcxOCBDMTQzLjg0NCwxNC4xOTEgMTQ0Ljg2LDEyLjc2MyAxNDYuNzA1LDExLjY5OCBMMTU2LjE5OCw2LjA5MSBDMTU2LjMwOSw2LjAyNSAxNTYuNDUyLDYuMDYyIDE1Ni41MTgsNi4xNzMgQzE1Ni41ODMsNi4yODQgMTU2LjU0Nyw2LjQyNyAxNTYuNDM2LDYuNDkzIEwxNDYuOTQsMTIuMTAyIEMxNDUuMjQ0LDEzLjA4MSAxNDQuMzEyLDE0LjM2NSAxNDQuMzEyLDE1LjcxOCBDMTQ0LjMxMiwxNy4wNTggMTQ1LjIzLDE4LjMyNiAxNDYuODk3LDE5LjI4OSBDMTUwLjQ0NiwyMS4zMzggMTU2LjI0LDIxLjMyNyAxNTkuODExLDE5LjI2NSBMMTY5LjU1OSwxMy42MzcgQzE2OS42NywxMy41NzMgMTY5LjgxMywxMy42MTEgMTY5Ljg3OCwxMy43MjMgQzE2OS45NDMsMTMuODM0IDE2OS45MDQsMTMuOTc3IDE2OS43OTMsMTQuMDQyIEwxNjAuMDQ1LDE5LjY3IEMxNTguMTg3LDIwLjc0MiAxNTUuNzQ5LDIxLjI3OSAxNTMuMzE2LDIxLjI3OSIgaWQ9IkZpbGwtMjUiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTEzLjY3NSw3NS45OTIgTDY3Ljc2Miw0OS40ODQiIGlkPSJGaWxsLTI2IiBmaWxsPSIjNDU1QTY0Ij48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTExMy42NzUsNzYuMzQyIEMxMTMuNjE1LDc2LjM0MiAxMTMuNTU1LDc2LjMyNyAxMTMuNSw3Ni4yOTUgTDY3LjU4Nyw0OS43ODcgQzY3LjQxOSw0OS42OSA2Ny4zNjIsNDkuNDc2IDY3LjQ1OSw0OS4zMDkgQzY3LjU1Niw0OS4xNDEgNjcuNzcsNDkuMDgzIDY3LjkzNyw0OS4xOCBMMTEzLjg1LDc1LjY4OCBDMTE0LjAxOCw3NS43ODUgMTE0LjA3NSw3NiAxMTMuOTc4LDc2LjE2NyBDMTEzLjkxNCw3Ni4yNzkgMTEzLjc5Niw3Ni4zNDIgMTEzLjY3NSw3Ni4zNDIiIGlkPSJGaWxsLTI3IiBmaWxsPSIjNDU1QTY0Ij48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTY3Ljc2Miw0OS40ODQgTDY3Ljc2MiwxMDMuNDg1IEM2Ny43NjIsMTA0LjU3NSA2OC41MzIsMTA1LjkwMyA2OS40ODIsMTA2LjQ1MiBMMTExLjk1NSwxMzAuOTczIEMxMTIuOTA1LDEzMS41MjIgMTEzLjY3NSwxMzEuMDgzIDExMy42NzUsMTI5Ljk5MyBMMTEzLjY3NSw3NS45OTIiIGlkPSJGaWxsLTI4IiBmaWxsPSIjRkFGQUZBIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTExMi43MjcsMTMxLjU2MSBDMTEyLjQzLDEzMS41NjEgMTEyLjEwNywxMzEuNDY2IDExMS43OCwxMzEuMjc2IEw2OS4zMDcsMTA2Ljc1NSBDNjguMjQ0LDEwNi4xNDIgNjcuNDEyLDEwNC43MDUgNjcuNDEyLDEwMy40ODUgTDY3LjQxMiw0OS40ODQgQzY3LjQxMiw0OS4yOSA2Ny41NjksNDkuMTM0IDY3Ljc2Miw0OS4xMzQgQzY3Ljk1Niw0OS4xMzQgNjguMTEzLDQ5LjI5IDY4LjExMyw0OS40ODQgTDY4LjExMywxMDMuNDg1IEM2OC4xMTMsMTA0LjQ0NSA2OC44MiwxMDUuNjY1IDY5LjY1NywxMDYuMTQ4IEwxMTIuMTMsMTMwLjY3IEMxMTIuNDc0LDEzMC44NjggMTEyLjc5MSwxMzAuOTEzIDExMywxMzAuNzkyIEMxMTMuMjA2LDEzMC42NzMgMTEzLjMyNSwxMzAuMzgxIDExMy4zMjUsMTI5Ljk5MyBMMTEzLjMyNSw3NS45OTIgQzExMy4zMjUsNzUuNzk4IDExMy40ODIsNzUuNjQxIDExMy42NzUsNzUuNjQxIEMxMTMuODY5LDc1LjY0MSAxMTQuMDI1LDc1Ljc5OCAxMTQuMDI1LDc1Ljk5MiBMMTE0LjAyNSwxMjkuOTkzIEMxMTQuMDI1LDEzMC42NDggMTEzLjc4NiwxMzEuMTQ3IDExMy4zNSwxMzEuMzk5IEMxMTMuMTYyLDEzMS41MDcgMTEyLjk1MiwxMzEuNTYxIDExMi43MjcsMTMxLjU2MSIgaWQ9IkZpbGwtMjkiIGZpbGw9IiM0NTVBNjQiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTEyLjg2LDQwLjUxMiBDMTEyLjg2LDQwLjUxMiAxMTIuODYsNDAuNTEyIDExMi44NTksNDAuNTEyIEMxMTAuNTQxLDQwLjUxMiAxMDguMzYsMzkuOTkgMTA2LjcxNywzOS4wNDEgQzEwNS4wMTIsMzguMDU3IDEwNC4wNzQsMzYuNzI2IDEwNC4wNzQsMzUuMjkyIEMxMDQuMDc0LDMzLjg0NyAxMDUuMDI2LDMyLjUwMSAxMDYuNzU0LDMxLjUwNCBMMTE4Ljc5NSwyNC41NTEgQzEyMC40NjMsMjMuNTg5IDEyMi42NjksMjMuMDU4IDEyNS4wMDcsMjMuMDU4IEMxMjcuMzI1LDIzLjA1OCAxMjkuNTA2LDIzLjU4MSAxMzEuMTUsMjQuNTMgQzEzMi44NTQsMjUuNTE0IDEzMy43OTMsMjYuODQ1IDEzMy43OTMsMjguMjc4IEMxMzMuNzkzLDI5LjcyNCAxMzIuODQxLDMxLjA2OSAxMzEuMTEzLDMyLjA2NyBMMTE5LjA3MSwzOS4wMTkgQzExNy40MDMsMzkuOTgyIDExNS4xOTcsNDAuNTEyIDExMi44Niw0MC41MTIgTDExMi44Niw0MC41MTIgWiBNMTI1LjAwNywyMy43NTkgQzEyMi43OSwyMy43NTkgMTIwLjcwOSwyNC4yNTYgMTE5LjE0NiwyNS4xNTggTDEwNy4xMDQsMzIuMTEgQzEwNS42MDIsMzIuOTc4IDEwNC43NzQsMzQuMTA4IDEwNC43NzQsMzUuMjkyIEMxMDQuNzc0LDM2LjQ2NSAxMDUuNTg5LDM3LjU4MSAxMDcuMDY3LDM4LjQzNCBDMTA4LjYwNSwzOS4zMjMgMTEwLjY2MywzOS44MTIgMTEyLjg1OSwzOS44MTIgTDExMi44NiwzOS44MTIgQzExNS4wNzYsMzkuODEyIDExNy4xNTgsMzkuMzE1IDExOC43MjEsMzguNDEzIEwxMzAuNzYyLDMxLjQ2IEMxMzIuMjY0LDMwLjU5MyAxMzMuMDkyLDI5LjQ2MyAxMzMuMDkyLDI4LjI3OCBDMTMzLjA5MiwyNy4xMDYgMTMyLjI3OCwyNS45OSAxMzAuOCwyNS4xMzYgQzEyOS4yNjEsMjQuMjQ4IDEyNy4yMDQsMjMuNzU5IDEyNS4wMDcsMjMuNzU5IEwxMjUuMDA3LDIzLjc1OSBaIiBpZD0iRmlsbC0zMCIgZmlsbD0iIzYwN0Q4QiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xNjUuNjMsMTYuMjE5IEwxNTkuODk2LDE5LjUzIEMxNTYuNzI5LDIxLjM1OCAxNTEuNjEsMjEuMzY3IDE0OC40NjMsMTkuNTUgQzE0NS4zMTYsMTcuNzMzIDE0NS4zMzIsMTQuNzc4IDE0OC40OTksMTIuOTQ5IEwxNTQuMjMzLDkuNjM5IEwxNjUuNjMsMTYuMjE5IiBpZD0iRmlsbC0zMSIgZmlsbD0iI0ZBRkFGQSI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xNTQuMjMzLDEwLjQ0OCBMMTY0LjIyOCwxNi4yMTkgTDE1OS41NDYsMTguOTIzIEMxNTguMTEyLDE5Ljc1IDE1Ni4xOTQsMjAuMjA2IDE1NC4xNDcsMjAuMjA2IEMxNTIuMTE4LDIwLjIwNiAxNTAuMjI0LDE5Ljc1NyAxNDguODE0LDE4Ljk0MyBDMTQ3LjUyNCwxOC4xOTkgMTQ2LjgxNCwxNy4yNDkgMTQ2LjgxNCwxNi4yNjkgQzE0Ni44MTQsMTUuMjc4IDE0Ny41MzcsMTQuMzE0IDE0OC44NSwxMy41NTYgTDE1NC4yMzMsMTAuNDQ4IE0xNTQuMjMzLDkuNjM5IEwxNDguNDk5LDEyLjk0OSBDMTQ1LjMzMiwxNC43NzggMTQ1LjMxNiwxNy43MzMgMTQ4LjQ2MywxOS41NSBDMTUwLjAzMSwyMC40NTUgMTUyLjA4NiwyMC45MDcgMTU0LjE0NywyMC45MDcgQzE1Ni4yMjQsMjAuOTA3IDE1OC4zMDYsMjAuNDQ3IDE1OS44OTYsMTkuNTMgTDE2NS42MywxNi4yMTkgTDE1NC4yMzMsOS42MzkiIGlkPSJGaWxsLTMyIiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE0NS40NDUsNzIuNjY3IEwxNDUuNDQ1LDcyLjY2NyBDMTQzLjY3Miw3Mi42NjcgMTQyLjIwNCw3MS44MTcgMTQxLjIwMiw3MC40MjIgQzE0MS4xMzUsNzAuMzMgMTQxLjE0NSw3MC4xNDcgMTQxLjIyNSw3MC4wNjYgQzE0MS4zMDUsNjkuOTg1IDE0MS40MzIsNjkuOTQ2IDE0MS41MjUsNzAuMDExIEMxNDIuMzA2LDcwLjU1OSAxNDMuMjMxLDcwLjgyMyAxNDQuMjc2LDcwLjgyMiBDMTQ1LjU5OCw3MC44MjIgMTQ3LjAzLDcwLjM3NiAxNDguNTMyLDY5LjUwOSBDMTUzLjg0Miw2Ni40NDMgMTU4LjE2Myw1OC45ODcgMTU4LjE2Myw1Mi44OTQgQzE1OC4xNjMsNTAuOTY3IDE1Ny43MjEsNDkuMzMyIDE1Ni44ODQsNDguMTY4IEMxNTYuODE4LDQ4LjA3NiAxNTYuODI4LDQ3Ljk0OCAxNTYuOTA4LDQ3Ljg2NyBDMTU2Ljk4OCw0Ny43ODYgMTU3LjExNCw0Ny43NzQgMTU3LjIwOCw0Ny44NCBDMTU4Ljg3OCw0OS4wMTIgMTU5Ljc5OCw1MS4yMiAxNTkuNzk4LDU0LjA1OSBDMTU5Ljc5OCw2MC4zMDEgMTU1LjM3Myw2OC4wNDYgMTQ5LjkzMyw3MS4xODYgQzE0OC4zNiw3Mi4wOTQgMTQ2Ljg1LDcyLjY2NyAxNDUuNDQ1LDcyLjY2NyBMMTQ1LjQ0NSw3Mi42NjcgWiBNMTQyLjQ3Niw3MSBDMTQzLjI5LDcxLjY1MSAxNDQuMjk2LDcyLjAwMiAxNDUuNDQ1LDcyLjAwMiBDMTQ2Ljc2Nyw3Mi4wMDIgMTQ4LjE5OCw3MS41NSAxNDkuNyw3MC42ODIgQzE1NS4wMSw2Ny42MTcgMTU5LjMzMSw2MC4xNTkgMTU5LjMzMSw1NC4wNjUgQzE1OS4zMzEsNTIuMDg1IDE1OC44NjgsNTAuNDM1IDE1OC4wMDYsNDkuMjcyIEMxNTguNDE3LDUwLjMwNyAxNTguNjMsNTEuNTMyIDE1OC42Myw1Mi44OTIgQzE1OC42Myw1OS4xMzQgMTU0LjIwNSw2Ni43NjcgMTQ4Ljc2NSw2OS45MDcgQzE0Ny4xOTIsNzAuODE2IDE0NS42ODEsNzEuMjgzIDE0NC4yNzYsNzEuMjgzIEMxNDMuNjM0LDcxLjI4MyAxNDMuMDMzLDcxLjE5MiAxNDIuNDc2LDcxIEwxNDIuNDc2LDcxIFoiIGlkPSJGaWxsLTMzIiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE0OC42NDgsNjkuNzA0IEMxNTQuMDMyLDY2LjU5NiAxNTguMzk2LDU5LjA2OCAxNTguMzk2LDUyLjg5MSBDMTU4LjM5Niw1MC44MzkgMTU3LjkxMyw0OS4xOTggMTU3LjA3NCw0OC4wMyBDMTU1LjI4OSw0Ni43NzggMTUyLjY5OSw0Ni44MzYgMTQ5LjgxNiw0OC41MDEgQzE0NC40MzMsNTEuNjA5IDE0MC4wNjgsNTkuMTM3IDE0MC4wNjgsNjUuMzE0IEMxNDAuMDY4LDY3LjM2NSAxNDAuNTUyLDY5LjAwNiAxNDEuMzkxLDcwLjE3NCBDMTQzLjE3Niw3MS40MjcgMTQ1Ljc2NSw3MS4zNjkgMTQ4LjY0OCw2OS43MDQiIGlkPSJGaWxsLTM0IiBmaWxsPSIjRkFGQUZBIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE0NC4yNzYsNzEuMjc2IEwxNDQuMjc2LDcxLjI3NiBDMTQzLjEzMyw3MS4yNzYgMTQyLjExOCw3MC45NjkgMTQxLjI1Nyw3MC4zNjUgQzE0MS4yMzYsNzAuMzUxIDE0MS4yMTcsNzAuMzMyIDE0MS4yMDIsNzAuMzExIEMxNDAuMzA3LDY5LjA2NyAxMzkuODM1LDY3LjMzOSAxMzkuODM1LDY1LjMxNCBDMTM5LjgzNSw1OS4wNzMgMTQ0LjI2LDUxLjQzOSAxNDkuNyw0OC4yOTggQzE1MS4yNzMsNDcuMzkgMTUyLjc4NCw0Ni45MjkgMTU0LjE4OSw0Ni45MjkgQzE1NS4zMzIsNDYuOTI5IDE1Ni4zNDcsNDcuMjM2IDE1Ny4yMDgsNDcuODM5IEMxNTcuMjI5LDQ3Ljg1NCAxNTcuMjQ4LDQ3Ljg3MyAxNTcuMjYzLDQ3Ljg5NCBDMTU4LjE1Nyw0OS4xMzggMTU4LjYzLDUwLjg2NSAxNTguNjMsNTIuODkxIEMxNTguNjMsNTkuMTMyIDE1NC4yMDUsNjYuNzY2IDE0OC43NjUsNjkuOTA3IEMxNDcuMTkyLDcwLjgxNSAxNDUuNjgxLDcxLjI3NiAxNDQuMjc2LDcxLjI3NiBMMTQ0LjI3Niw3MS4yNzYgWiBNMTQxLjU1OCw3MC4xMDQgQzE0Mi4zMzEsNzAuNjM3IDE0My4yNDUsNzEuMDA1IDE0NC4yNzYsNzEuMDA1IEMxNDUuNTk4LDcxLjAwNSAxNDcuMDMsNzAuNDY3IDE0OC41MzIsNjkuNiBDMTUzLjg0Miw2Ni41MzQgMTU4LjE2Myw1OS4wMzMgMTU4LjE2Myw1Mi45MzkgQzE1OC4xNjMsNTEuMDMxIDE1Ny43MjksNDkuMzg1IDE1Ni45MDcsNDguMjIzIEMxNTYuMTMzLDQ3LjY5MSAxNTUuMjE5LDQ3LjQwOSAxNTQuMTg5LDQ3LjQwOSBDMTUyLjg2Nyw0Ny40MDkgMTUxLjQzNSw0Ny44NDIgMTQ5LjkzMyw0OC43MDkgQzE0NC42MjMsNTEuNzc1IDE0MC4zMDIsNTkuMjczIDE0MC4zMDIsNjUuMzY2IEMxNDAuMzAyLDY3LjI3NiAxNDAuNzM2LDY4Ljk0MiAxNDEuNTU4LDcwLjEwNCBMMTQxLjU1OCw3MC4xMDQgWiIgaWQ9IkZpbGwtMzUiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTUwLjcyLDY1LjM2MSBMMTUwLjM1Nyw2NS4wNjYgQzE1MS4xNDcsNjQuMDkyIDE1MS44NjksNjMuMDQgMTUyLjUwNSw2MS45MzggQzE1My4zMTMsNjAuNTM5IDE1My45NzgsNTkuMDY3IDE1NC40ODIsNTcuNTYzIEwxNTQuOTI1LDU3LjcxMiBDMTU0LjQxMiw1OS4yNDUgMTUzLjczMyw2MC43NDUgMTUyLjkxLDYyLjE3MiBDMTUyLjI2Miw2My4yOTUgMTUxLjUyNSw2NC4zNjggMTUwLjcyLDY1LjM2MSIgaWQ9IkZpbGwtMzYiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTE1LjkxNyw4NC41MTQgTDExNS41NTQsODQuMjIgQzExNi4zNDQsODMuMjQ1IDExNy4wNjYsODIuMTk0IDExNy43MDIsODEuMDkyIEMxMTguNTEsNzkuNjkyIDExOS4xNzUsNzguMjIgMTE5LjY3OCw3Ni43MTcgTDEyMC4xMjEsNzYuODY1IEMxMTkuNjA4LDc4LjM5OCAxMTguOTMsNzkuODk5IDExOC4xMDYsODEuMzI2IEMxMTcuNDU4LDgyLjQ0OCAxMTYuNzIyLDgzLjUyMSAxMTUuOTE3LDg0LjUxNCIgaWQ9IkZpbGwtMzciIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTE0LDEzMC40NzYgTDExNCwxMzAuMDA4IEwxMTQsNzYuMDUyIEwxMTQsNzUuNTg0IEwxMTQsNzYuMDUyIEwxMTQsMTMwLjAwOCBMMTE0LDEzMC40NzYiIGlkPSJGaWxsLTM4IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICA8L2c+CiAgICAgICAgICAgICAgICA8ZyBpZD0iSW1wb3J0ZWQtTGF5ZXJzLUNvcHkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDYyLjAwMDAwMCwgMC4wMDAwMDApIiBza2V0Y2g6dHlwZT0iTVNTaGFwZUdyb3VwIj4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTkuODIyLDM3LjQ3NCBDMTkuODM5LDM3LjMzOSAxOS43NDcsMzcuMTk0IDE5LjU1NSwzNy4wODIgQzE5LjIyOCwzNi44OTQgMTguNzI5LDM2Ljg3MiAxOC40NDYsMzcuMDM3IEwxMi40MzQsNDAuNTA4IEMxMi4zMDMsNDAuNTg0IDEyLjI0LDQwLjY4NiAxMi4yNDMsNDAuNzkzIEMxMi4yNDUsNDAuOTI1IDEyLjI0NSw0MS4yNTQgMTIuMjQ1LDQxLjM3MSBMMTIuMjQ1LDQxLjQxNCBMMTIuMjM4LDQxLjU0MiBDOC4xNDgsNDMuODg3IDUuNjQ3LDQ1LjMyMSA1LjY0Nyw0NS4zMjEgQzUuNjQ2LDQ1LjMyMSAzLjU3LDQ2LjM2NyAyLjg2LDUwLjUxMyBDMi44Niw1MC41MTMgMS45NDgsNTcuNDc0IDEuOTYyLDcwLjI1OCBDMS45NzcsODIuODI4IDIuNTY4LDg3LjMyOCAzLjEyOSw5MS42MDkgQzMuMzQ5LDkzLjI5MyA2LjEzLDkzLjczNCA2LjEzLDkzLjczNCBDNi40NjEsOTMuNzc0IDYuODI4LDkzLjcwNyA3LjIxLDkzLjQ4NiBMODIuNDgzLDQ5LjkzNSBDODQuMjkxLDQ4Ljg2NiA4NS4xNSw0Ni4yMTYgODUuNTM5LDQzLjY1MSBDODYuNzUyLDM1LjY2MSA4Ny4yMTQsMTAuNjczIDg1LjI2NCwzLjc3MyBDODUuMDY4LDMuMDggODQuNzU0LDIuNjkgODQuMzk2LDIuNDkxIEw4Mi4zMSwxLjcwMSBDODEuNTgzLDEuNzI5IDgwLjg5NCwyLjE2OCA4MC43NzYsMi4yMzYgQzgwLjYzNiwyLjMxNyA0MS44MDcsMjQuNTg1IDIwLjAzMiwzNy4wNzIgTDE5LjgyMiwzNy40NzQiIGlkPSJGaWxsLTEiIGZpbGw9IiNGRkZGRkYiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNODIuMzExLDEuNzAxIEw4NC4zOTYsMi40OTEgQzg0Ljc1NCwyLjY5IDg1LjA2OCwzLjA4IDg1LjI2NCwzLjc3MyBDODcuMjEzLDEwLjY3MyA4Ni43NTEsMzUuNjYgODUuNTM5LDQzLjY1MSBDODUuMTQ5LDQ2LjIxNiA4NC4yOSw0OC44NjYgODIuNDgzLDQ5LjkzNSBMNy4yMSw5My40ODYgQzYuODk3LDkzLjY2NyA2LjU5NSw5My43NDQgNi4zMTQsOTMuNzQ0IEw2LjEzMSw5My43MzMgQzYuMTMxLDkzLjczNCAzLjM0OSw5My4yOTMgMy4xMjgsOTEuNjA5IEMyLjU2OCw4Ny4zMjcgMS45NzcsODIuODI4IDEuOTYzLDcwLjI1OCBDMS45NDgsNTcuNDc0IDIuODYsNTAuNTEzIDIuODYsNTAuNTEzIEMzLjU3LDQ2LjM2NyA1LjY0Nyw0NS4zMjEgNS42NDcsNDUuMzIxIEM1LjY0Nyw0NS4zMjEgOC4xNDgsNDMuODg3IDEyLjIzOCw0MS41NDIgTDEyLjI0NSw0MS40MTQgTDEyLjI0NSw0MS4zNzEgQzEyLjI0NSw0MS4yNTQgMTIuMjQ1LDQwLjkyNSAxMi4yNDMsNDAuNzkzIEMxMi4yNCw0MC42ODYgMTIuMzAyLDQwLjU4MyAxMi40MzQsNDAuNTA4IEwxOC40NDYsMzcuMDM2IEMxOC41NzQsMzYuOTYyIDE4Ljc0NiwzNi45MjYgMTguOTI3LDM2LjkyNiBDMTkuMTQ1LDM2LjkyNiAxOS4zNzYsMzYuOTc5IDE5LjU1NCwzNy4wODIgQzE5Ljc0NywzNy4xOTQgMTkuODM5LDM3LjM0IDE5LjgyMiwzNy40NzQgTDIwLjAzMywzNy4wNzIgQzQxLjgwNiwyNC41ODUgODAuNjM2LDIuMzE4IDgwLjc3NywyLjIzNiBDODAuODk0LDIuMTY4IDgxLjU4MywxLjcyOSA4Mi4zMTEsMS43MDEgTTgyLjMxMSwwLjcwNCBMODIuMjcyLDAuNzA1IEM4MS42NTQsMC43MjggODAuOTg5LDAuOTQ5IDgwLjI5OCwxLjM2MSBMODAuMjc3LDEuMzczIEM4MC4xMjksMS40NTggNTkuNzY4LDEzLjEzNSAxOS43NTgsMzYuMDc5IEMxOS41LDM1Ljk4MSAxOS4yMTQsMzUuOTI5IDE4LjkyNywzNS45MjkgQzE4LjU2MiwzNS45MjkgMTguMjIzLDM2LjAxMyAxNy45NDcsMzYuMTczIEwxMS45MzUsMzkuNjQ0IEMxMS40OTMsMzkuODk5IDExLjIzNiw0MC4zMzQgMTEuMjQ2LDQwLjgxIEwxMS4yNDcsNDAuOTYgTDUuMTY3LDQ0LjQ0NyBDNC43OTQsNDQuNjQ2IDIuNjI1LDQ1Ljk3OCAxLjg3Nyw1MC4zNDUgTDEuODcxLDUwLjM4NCBDMS44NjIsNTAuNDU0IDAuOTUxLDU3LjU1NyAwLjk2NSw3MC4yNTkgQzAuOTc5LDgyLjg3OSAxLjU2OCw4Ny4zNzUgMi4xMzcsOTEuNzI0IEwyLjEzOSw5MS43MzkgQzIuNDQ3LDk0LjA5NCA1LjYxNCw5NC42NjIgNS45NzUsOTQuNzE5IEw2LjAwOSw5NC43MjMgQzYuMTEsOTQuNzM2IDYuMjEzLDk0Ljc0MiA2LjMxNCw5NC43NDIgQzYuNzksOTQuNzQyIDcuMjYsOTQuNjEgNy43MSw5NC4zNSBMODIuOTgzLDUwLjc5OCBDODQuNzk0LDQ5LjcyNyA4NS45ODIsNDcuMzc1IDg2LjUyNSw0My44MDEgQzg3LjcxMSwzNS45ODcgODguMjU5LDEwLjcwNSA4Ni4yMjQsMy41MDIgQzg1Ljk3MSwyLjYwOSA4NS41MiwxLjk3NSA4NC44ODEsMS42MiBMODQuNzQ5LDEuNTU4IEw4Mi42NjQsMC43NjkgQzgyLjU1MSwwLjcyNSA4Mi40MzEsMC43MDQgODIuMzExLDAuNzA0IiBpZD0iRmlsbC0yIiBmaWxsPSIjNDU1QTY0Ij48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTY2LjI2NywxMS41NjUgTDY3Ljc2MiwxMS45OTkgTDExLjQyMyw0NC4zMjUiIGlkPSJGaWxsLTMiIGZpbGw9IiNGRkZGRkYiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTIuMjAyLDkwLjU0NSBDMTIuMDI5LDkwLjU0NSAxMS44NjIsOTAuNDU1IDExLjc2OSw5MC4yOTUgQzExLjYzMiw5MC4wNTcgMTEuNzEzLDg5Ljc1MiAxMS45NTIsODkuNjE0IEwzMC4zODksNzguOTY5IEMzMC42MjgsNzguODMxIDMwLjkzMyw3OC45MTMgMzEuMDcxLDc5LjE1MiBDMzEuMjA4LDc5LjM5IDMxLjEyNyw3OS42OTYgMzAuODg4LDc5LjgzMyBMMTIuNDUxLDkwLjQ3OCBMMTIuMjAyLDkwLjU0NSIgaWQ9IkZpbGwtNCIgZmlsbD0iIzYwN0Q4QiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xMy43NjQsNDIuNjU0IEwxMy42NTYsNDIuNTkyIEwxMy43MDIsNDIuNDIxIEwxOC44MzcsMzkuNDU3IEwxOS4wMDcsMzkuNTAyIEwxOC45NjIsMzkuNjczIEwxMy44MjcsNDIuNjM3IEwxMy43NjQsNDIuNjU0IiBpZD0iRmlsbC01IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTguNTIsOTAuMzc1IEw4LjUyLDQ2LjQyMSBMOC41ODMsNDYuMzg1IEw3NS44NCw3LjU1NCBMNzUuODQsNTEuNTA4IEw3NS43NzgsNTEuNTQ0IEw4LjUyLDkwLjM3NSBMOC41Miw5MC4zNzUgWiBNOC43Nyw0Ni41NjQgTDguNzcsODkuOTQ0IEw3NS41OTEsNTEuMzY1IEw3NS41OTEsNy45ODUgTDguNzcsNDYuNTY0IEw4Ljc3LDQ2LjU2NCBaIiBpZD0iRmlsbC02IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTI0Ljk4Niw4My4xODIgQzI0Ljc1Niw4My4zMzEgMjQuMzc0LDgzLjU2NiAyNC4xMzcsODMuNzA1IEwxMi42MzIsOTAuNDA2IEMxMi4zOTUsOTAuNTQ1IDEyLjQyNiw5MC42NTggMTIuNyw5MC42NTggTDEzLjI2NSw5MC42NTggQzEzLjU0LDkwLjY1OCAxMy45NTgsOTAuNTQ1IDE0LjE5NSw5MC40MDYgTDI1LjcsODMuNzA1IEMyNS45MzcsODMuNTY2IDI2LjEyOCw4My40NTIgMjYuMTI1LDgzLjQ0OSBDMjYuMTIyLDgzLjQ0NyAyNi4xMTksODMuMjIgMjYuMTE5LDgyLjk0NiBDMjYuMTE5LDgyLjY3MiAyNS45MzEsODIuNTY5IDI1LjcwMSw4Mi43MTkgTDI0Ljk4Niw4My4xODIiIGlkPSJGaWxsLTciIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTMuMjY2LDkwLjc4MiBMMTIuNyw5MC43ODIgQzEyLjUsOTAuNzgyIDEyLjM4NCw5MC43MjYgMTIuMzU0LDkwLjYxNiBDMTIuMzI0LDkwLjUwNiAxMi4zOTcsOTAuMzk5IDEyLjU2OSw5MC4yOTkgTDI0LjA3NCw4My41OTcgQzI0LjMxLDgzLjQ1OSAyNC42ODksODMuMjI2IDI0LjkxOCw4My4wNzggTDI1LjYzMyw4Mi42MTQgQzI1LjcyMyw4Mi41NTUgMjUuODEzLDgyLjUyNSAyNS44OTksODIuNTI1IEMyNi4wNzEsODIuNTI1IDI2LjI0NCw4Mi42NTUgMjYuMjQ0LDgyLjk0NiBDMjYuMjQ0LDgzLjE2IDI2LjI0NSw4My4zMDkgMjYuMjQ3LDgzLjM4MyBMMjYuMjUzLDgzLjM4NyBMMjYuMjQ5LDgzLjQ1NiBDMjYuMjQ2LDgzLjUzMSAyNi4yNDYsODMuNTMxIDI1Ljc2Myw4My44MTIgTDE0LjI1OCw5MC41MTQgQzE0LDkwLjY2NSAxMy41NjQsOTAuNzgyIDEzLjI2Niw5MC43ODIgTDEzLjI2Niw5MC43ODIgWiBNMTIuNjY2LDkwLjUzMiBMMTIuNyw5MC41MzMgTDEzLjI2Niw5MC41MzMgQzEzLjUxOCw5MC41MzMgMTMuOTE1LDkwLjQyNSAxNC4xMzIsOTAuMjk5IEwyNS42MzcsODMuNTk3IEMyNS44MDUsODMuNDk5IDI1LjkzMSw4My40MjQgMjUuOTk4LDgzLjM4MyBDMjUuOTk0LDgzLjI5OSAyNS45OTQsODMuMTY1IDI1Ljk5NCw4Mi45NDYgTDI1Ljg5OSw4Mi43NzUgTDI1Ljc2OCw4Mi44MjQgTDI1LjA1NCw4My4yODcgQzI0LjgyMiw4My40MzcgMjQuNDM4LDgzLjY3MyAyNC4yLDgzLjgxMiBMMTIuNjk1LDkwLjUxNCBMMTIuNjY2LDkwLjUzMiBMMTIuNjY2LDkwLjUzMiBaIiBpZD0iRmlsbC04IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTEzLjI2Niw4OS44NzEgTDEyLjcsODkuODcxIEMxMi41LDg5Ljg3MSAxMi4zODQsODkuODE1IDEyLjM1NCw4OS43MDUgQzEyLjMyNCw4OS41OTUgMTIuMzk3LDg5LjQ4OCAxMi41NjksODkuMzg4IEwyNC4wNzQsODIuNjg2IEMyNC4zMzIsODIuNTM1IDI0Ljc2OCw4Mi40MTggMjUuMDY3LDgyLjQxOCBMMjUuNjMyLDgyLjQxOCBDMjUuODMyLDgyLjQxOCAyNS45NDgsODIuNDc0IDI1Ljk3OCw4Mi41ODQgQzI2LjAwOCw4Mi42OTQgMjUuOTM1LDgyLjgwMSAyNS43NjMsODIuOTAxIEwxNC4yNTgsODkuNjAzIEMxNCw4OS43NTQgMTMuNTY0LDg5Ljg3MSAxMy4yNjYsODkuODcxIEwxMy4yNjYsODkuODcxIFogTTEyLjY2Niw4OS42MjEgTDEyLjcsODkuNjIyIEwxMy4yNjYsODkuNjIyIEMxMy41MTgsODkuNjIyIDEzLjkxNSw4OS41MTUgMTQuMTMyLDg5LjM4OCBMMjUuNjM3LDgyLjY4NiBMMjUuNjY3LDgyLjY2OCBMMjUuNjMyLDgyLjY2NyBMMjUuMDY3LDgyLjY2NyBDMjQuODE1LDgyLjY2NyAyNC40MTgsODIuNzc1IDI0LjIsODIuOTAxIEwxMi42OTUsODkuNjAzIEwxMi42NjYsODkuNjIxIEwxMi42NjYsODkuNjIxIFoiIGlkPSJGaWxsLTkiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTIuMzcsOTAuODAxIEwxMi4zNyw4OS41NTQgTDEyLjM3LDkwLjgwMSIgaWQ9IkZpbGwtMTAiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNNi4xMyw5My45MDEgQzUuMzc5LDkzLjgwOCA0LjgxNiw5My4xNjQgNC42OTEsOTIuNTI1IEMzLjg2LDg4LjI4NyAzLjU0LDgzLjc0MyAzLjUyNiw3MS4xNzMgQzMuNTExLDU4LjM4OSA0LjQyMyw1MS40MjggNC40MjMsNTEuNDI4IEM1LjEzNCw0Ny4yODIgNy4yMSw0Ni4yMzYgNy4yMSw0Ni4yMzYgQzcuMjEsNDYuMjM2IDgxLjY2NywzLjI1IDgyLjA2OSwzLjAxNyBDODIuMjkyLDIuODg4IDg0LjU1NiwxLjQzMyA4NS4yNjQsMy45NCBDODcuMjE0LDEwLjg0IDg2Ljc1MiwzNS44MjcgODUuNTM5LDQzLjgxOCBDODUuMTUsNDYuMzgzIDg0LjI5MSw0OS4wMzMgODIuNDgzLDUwLjEwMSBMNy4yMSw5My42NTMgQzYuODI4LDkzLjg3NCA2LjQ2MSw5My45NDEgNi4xMyw5My45MDEgQzYuMTMsOTMuOTAxIDMuMzQ5LDkzLjQ2IDMuMTI5LDkxLjc3NiBDMi41NjgsODcuNDk1IDEuOTc3LDgyLjk5NSAxLjk2Miw3MC40MjUgQzEuOTQ4LDU3LjY0MSAyLjg2LDUwLjY4IDIuODYsNTAuNjggQzMuNTcsNDYuNTM0IDUuNjQ3LDQ1LjQ4OSA1LjY0Nyw0NS40ODkgQzUuNjQ2LDQ1LjQ4OSA4LjA2NSw0NC4wOTIgMTIuMjQ1LDQxLjY3OSBMMTMuMTE2LDQxLjU2IEwxOS43MTUsMzcuNzMgTDE5Ljc2MSwzNy4yNjkgTDYuMTMsOTMuOTAxIiBpZD0iRmlsbC0xMSIgZmlsbD0iI0ZBRkFGQSI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik02LjMxNyw5NC4xNjEgTDYuMTAyLDk0LjE0OCBMNi4xMDEsOTQuMTQ4IEw1Ljg1Nyw5NC4xMDEgQzUuMTM4LDkzLjk0NSAzLjA4NSw5My4zNjUgMi44ODEsOTEuODA5IEMyLjMxMyw4Ny40NjkgMS43MjcsODIuOTk2IDEuNzEzLDcwLjQyNSBDMS42OTksNTcuNzcxIDIuNjA0LDUwLjcxOCAyLjYxMyw1MC42NDggQzMuMzM4LDQ2LjQxNyA1LjQ0NSw0NS4zMSA1LjUzNSw0NS4yNjYgTDEyLjE2Myw0MS40MzkgTDEzLjAzMyw0MS4zMiBMMTkuNDc5LDM3LjU3OCBMMTkuNTEzLDM3LjI0NCBDMTkuNTI2LDM3LjEwNyAxOS42NDcsMzcuMDA4IDE5Ljc4NiwzNy4wMjEgQzE5LjkyMiwzNy4wMzQgMjAuMDIzLDM3LjE1NiAyMC4wMDksMzcuMjkzIEwxOS45NSwzNy44ODIgTDEzLjE5OCw0MS44MDEgTDEyLjMyOCw0MS45MTkgTDUuNzcyLDQ1LjcwNCBDNS43NDEsNDUuNzIgMy43ODIsNDYuNzcyIDMuMTA2LDUwLjcyMiBDMy4wOTksNTAuNzgyIDIuMTk4LDU3LjgwOCAyLjIxMiw3MC40MjQgQzIuMjI2LDgyLjk2MyAyLjgwOSw4Ny40MiAzLjM3Myw5MS43MjkgQzMuNDY0LDkyLjQyIDQuMDYyLDkyLjg4MyA0LjY4Miw5My4xODEgQzQuNTY2LDkyLjk4NCA0LjQ4Niw5Mi43NzYgNC40NDYsOTIuNTcyIEMzLjY2NSw4OC41ODggMy4yOTEsODQuMzcgMy4yNzYsNzEuMTczIEMzLjI2Miw1OC41MiA0LjE2Nyw1MS40NjYgNC4xNzYsNTEuMzk2IEM0LjkwMSw0Ny4xNjUgNy4wMDgsNDYuMDU5IDcuMDk4LDQ2LjAxNCBDNy4wOTQsNDYuMDE1IDgxLjU0MiwzLjAzNCA4MS45NDQsMi44MDIgTDgxLjk3MiwyLjc4NSBDODIuODc2LDIuMjQ3IDgzLjY5MiwyLjA5NyA4NC4zMzIsMi4zNTIgQzg0Ljg4NywyLjU3MyA4NS4yODEsMy4wODUgODUuNTA0LDMuODcyIEM4Ny41MTgsMTEgODYuOTY0LDM2LjA5MSA4NS43ODUsNDMuODU1IEM4NS4yNzgsNDcuMTk2IDg0LjIxLDQ5LjM3IDgyLjYxLDUwLjMxNyBMNy4zMzUsOTMuODY5IEM2Ljk5OSw5NC4wNjMgNi42NTgsOTQuMTYxIDYuMzE3LDk0LjE2MSBMNi4zMTcsOTQuMTYxIFogTTYuMTcsOTMuNjU0IEM2LjQ2Myw5My42OSA2Ljc3NCw5My42MTcgNy4wODUsOTMuNDM3IEw4Mi4zNTgsNDkuODg2IEM4NC4xODEsNDguODA4IDg0Ljk2LDQ1Ljk3MSA4NS4yOTIsNDMuNzggQzg2LjQ2NiwzNi4wNDkgODcuMDIzLDExLjA4NSA4NS4wMjQsNC4wMDggQzg0Ljg0NiwzLjM3NyA4NC41NTEsMi45NzYgODQuMTQ4LDIuODE2IEM4My42NjQsMi42MjMgODIuOTgyLDIuNzY0IDgyLjIyNywzLjIxMyBMODIuMTkzLDMuMjM0IEM4MS43OTEsMy40NjYgNy4zMzUsNDYuNDUyIDcuMzM1LDQ2LjQ1MiBDNy4zMDQsNDYuNDY5IDUuMzQ2LDQ3LjUyMSA0LjY2OSw1MS40NzEgQzQuNjYyLDUxLjUzIDMuNzYxLDU4LjU1NiAzLjc3NSw3MS4xNzMgQzMuNzksODQuMzI4IDQuMTYxLDg4LjUyNCA0LjkzNiw5Mi40NzYgQzUuMDI2LDkyLjkzNyA1LjQxMiw5My40NTkgNS45NzMsOTMuNjE1IEM2LjA4Nyw5My42NCA2LjE1OCw5My42NTIgNi4xNjksOTMuNjU0IEw2LjE3LDkzLjY1NCBMNi4xNyw5My42NTQgWiIgaWQ9IkZpbGwtMTIiIGZpbGw9IiM0NTVBNjQiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNNy4zMTcsNjguOTgyIEM3LjgwNiw2OC43MDEgOC4yMDIsNjguOTI2IDguMjAyLDY5LjQ4NyBDOC4yMDIsNzAuMDQ3IDcuODA2LDcwLjczIDcuMzE3LDcxLjAxMiBDNi44MjksNzEuMjk0IDYuNDMzLDcxLjA2OSA2LjQzMyw3MC41MDggQzYuNDMzLDY5Ljk0OCA2LjgyOSw2OS4yNjUgNy4zMTcsNjguOTgyIiBpZD0iRmlsbC0xMyIgZmlsbD0iI0ZGRkZGRiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik02LjkyLDcxLjEzMyBDNi42MzEsNzEuMTMzIDYuNDMzLDcwLjkwNSA2LjQzMyw3MC41MDggQzYuNDMzLDY5Ljk0OCA2LjgyOSw2OS4yNjUgNy4zMTcsNjguOTgyIEM3LjQ2LDY4LjkgNy41OTUsNjguODYxIDcuNzE0LDY4Ljg2MSBDOC4wMDMsNjguODYxIDguMjAyLDY5LjA5IDguMjAyLDY5LjQ4NyBDOC4yMDIsNzAuMDQ3IDcuODA2LDcwLjczIDcuMzE3LDcxLjAxMiBDNy4xNzQsNzEuMDk0IDcuMDM5LDcxLjEzMyA2LjkyLDcxLjEzMyBNNy43MTQsNjguNjc0IEM3LjU1Nyw2OC42NzQgNy4zOTIsNjguNzIzIDcuMjI0LDY4LjgyMSBDNi42NzYsNjkuMTM4IDYuMjQ2LDY5Ljg3OSA2LjI0Niw3MC41MDggQzYuMjQ2LDcwLjk5NCA2LjUxNyw3MS4zMiA2LjkyLDcxLjMyIEM3LjA3OCw3MS4zMiA3LjI0Myw3MS4yNzEgNy40MTEsNzEuMTc0IEM3Ljk1OSw3MC44NTcgOC4zODksNzAuMTE3IDguMzg5LDY5LjQ4NyBDOC4zODksNjkuMDAxIDguMTE3LDY4LjY3NCA3LjcxNCw2OC42NzQiIGlkPSJGaWxsLTE0IiBmaWxsPSIjODA5N0EyIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTYuOTIsNzAuOTQ3IEM2LjY0OSw3MC45NDcgNi42MjEsNzAuNjQgNi42MjEsNzAuNTA4IEM2LjYyMSw3MC4wMTcgNi45ODIsNjkuMzkyIDcuNDExLDY5LjE0NSBDNy41MjEsNjkuMDgyIDcuNjI1LDY5LjA0OSA3LjcxNCw2OS4wNDkgQzcuOTg2LDY5LjA0OSA4LjAxNSw2OS4zNTUgOC4wMTUsNjkuNDg3IEM4LjAxNSw2OS45NzggNy42NTIsNzAuNjAzIDcuMjI0LDcwLjg1MSBDNy4xMTUsNzAuOTE0IDcuMDEsNzAuOTQ3IDYuOTIsNzAuOTQ3IE03LjcxNCw2OC44NjEgQzcuNTk1LDY4Ljg2MSA3LjQ2LDY4LjkgNy4zMTcsNjguOTgyIEM2LjgyOSw2OS4yNjUgNi40MzMsNjkuOTQ4IDYuNDMzLDcwLjUwOCBDNi40MzMsNzAuOTA1IDYuNjMxLDcxLjEzMyA2LjkyLDcxLjEzMyBDNy4wMzksNzEuMTMzIDcuMTc0LDcxLjA5NCA3LjMxNyw3MS4wMTIgQzcuODA2LDcwLjczIDguMjAyLDcwLjA0NyA4LjIwMiw2OS40ODcgQzguMjAyLDY5LjA5IDguMDAzLDY4Ljg2MSA3LjcxNCw2OC44NjEiIGlkPSJGaWxsLTE1IiBmaWxsPSIjODA5N0EyIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTcuNDQ0LDg1LjM1IEM3LjcwOCw4NS4xOTggNy45MjEsODUuMzE5IDcuOTIxLDg1LjYyMiBDNy45MjEsODUuOTI1IDcuNzA4LDg2LjI5MiA3LjQ0NCw4Ni40NDQgQzcuMTgxLDg2LjU5NyA2Ljk2Nyw4Ni40NzUgNi45NjcsODYuMTczIEM2Ljk2Nyw4NS44NzEgNy4xODEsODUuNTAyIDcuNDQ0LDg1LjM1IiBpZD0iRmlsbC0xNiIgZmlsbD0iI0ZGRkZGRiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik03LjIzLDg2LjUxIEM3LjA3NCw4Ni41MSA2Ljk2Nyw4Ni4zODcgNi45NjcsODYuMTczIEM2Ljk2Nyw4NS44NzEgNy4xODEsODUuNTAyIDcuNDQ0LDg1LjM1IEM3LjUyMSw4NS4zMDUgNy41OTQsODUuMjg0IDcuNjU4LDg1LjI4NCBDNy44MTQsODUuMjg0IDcuOTIxLDg1LjQwOCA3LjkyMSw4NS42MjIgQzcuOTIxLDg1LjkyNSA3LjcwOCw4Ni4yOTIgNy40NDQsODYuNDQ0IEM3LjM2Nyw4Ni40ODkgNy4yOTQsODYuNTEgNy4yMyw4Ni41MSBNNy42NTgsODUuMDk4IEM3LjU1OCw4NS4wOTggNy40NTUsODUuMTI3IDcuMzUxLDg1LjE4OCBDNy4wMzEsODUuMzczIDYuNzgxLDg1LjgwNiA2Ljc4MSw4Ni4xNzMgQzYuNzgxLDg2LjQ4MiA2Ljk2Niw4Ni42OTcgNy4yMyw4Ni42OTcgQzcuMzMsODYuNjk3IDcuNDMzLDg2LjY2NiA3LjUzOCw4Ni42MDcgQzcuODU4LDg2LjQyMiA4LjEwOCw4NS45ODkgOC4xMDgsODUuNjIyIEM4LjEwOCw4NS4zMTMgNy45MjMsODUuMDk4IDcuNjU4LDg1LjA5OCIgaWQ9IkZpbGwtMTciIGZpbGw9IiM4MDk3QTIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNNy4yMyw4Ni4zMjIgTDcuMTU0LDg2LjE3MyBDNy4xNTQsODUuOTM4IDcuMzMzLDg1LjYyOSA3LjUzOCw4NS41MTIgTDcuNjU4LDg1LjQ3MSBMNy43MzQsODUuNjIyIEM3LjczNCw4NS44NTYgNy41NTUsODYuMTY0IDcuMzUxLDg2LjI4MiBMNy4yMyw4Ni4zMjIgTTcuNjU4LDg1LjI4NCBDNy41OTQsODUuMjg0IDcuNTIxLDg1LjMwNSA3LjQ0NCw4NS4zNSBDNy4xODEsODUuNTAyIDYuOTY3LDg1Ljg3MSA2Ljk2Nyw4Ni4xNzMgQzYuOTY3LDg2LjM4NyA3LjA3NCw4Ni41MSA3LjIzLDg2LjUxIEM3LjI5NCw4Ni41MSA3LjM2Nyw4Ni40ODkgNy40NDQsODYuNDQ0IEM3LjcwOCw4Ni4yOTIgNy45MjEsODUuOTI1IDcuOTIxLDg1LjYyMiBDNy45MjEsODUuNDA4IDcuODE0LDg1LjI4NCA3LjY1OCw4NS4yODQiIGlkPSJGaWxsLTE4IiBmaWxsPSIjODA5N0EyIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTc3LjI3OCw3Ljc2OSBMNzcuMjc4LDUxLjQzNiBMMTAuMjA4LDkwLjE2IEwxMC4yMDgsNDYuNDkzIEw3Ny4yNzgsNy43NjkiIGlkPSJGaWxsLTE5IiBmaWxsPSIjNDU1QTY0Ij48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTEwLjA4Myw5MC4zNzUgTDEwLjA4Myw0Ni40MjEgTDEwLjE0Niw0Ni4zODUgTDc3LjQwMyw3LjU1NCBMNzcuNDAzLDUxLjUwOCBMNzcuMzQxLDUxLjU0NCBMMTAuMDgzLDkwLjM3NSBMMTAuMDgzLDkwLjM3NSBaIE0xMC4zMzMsNDYuNTY0IEwxMC4zMzMsODkuOTQ0IEw3Ny4xNTQsNTEuMzY1IEw3Ny4xNTQsNy45ODUgTDEwLjMzMyw0Ni41NjQgTDEwLjMzMyw0Ni41NjQgWiIgaWQ9IkZpbGwtMjAiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xMjUuNzM3LDg4LjY0NyBMMTE4LjA5OCw5MS45ODEgTDExOC4wOTgsODQgTDEwNi42MzksODguNzEzIEwxMDYuNjM5LDk2Ljk4MiBMOTksMTAwLjMxNSBMMTEyLjM2OSwxMDMuOTYxIEwxMjUuNzM3LDg4LjY0NyIgaWQ9IkltcG9ydGVkLUxheWVycy1Db3B5LTIiIGZpbGw9IiM0NTVBNjQiIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiPjwvcGF0aD4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+');
  7227. };
  7228. module.exports = RotateInstructions;
  7229. },{"./util.js":29}],24:[function(_dereq_,module,exports){
  7230. /*
  7231. * Copyright 2015 Google Inc. All Rights Reserved.
  7232. * Licensed under the Apache License, Version 2.0 (the "License");
  7233. * you may not use this file except in compliance with the License.
  7234. * You may obtain a copy of the License at
  7235. *
  7236. * http://www.apache.org/licenses/LICENSE-2.0
  7237. *
  7238. * Unless required by applicable law or agreed to in writing, software
  7239. * distributed under the License is distributed on an "AS IS" BASIS,
  7240. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  7241. * See the License for the specific language governing permissions and
  7242. * limitations under the License.
  7243. */
  7244. var SensorSample = _dereq_('./sensor-sample.js');
  7245. var MathUtil = _dereq_('../math-util.js');
  7246. var Util = _dereq_('../util.js');
  7247. /**
  7248. * An implementation of a simple complementary filter, which fuses gyroscope and
  7249. * accelerometer data from the 'devicemotion' event.
  7250. *
  7251. * Accelerometer data is very noisy, but stable over the long term.
  7252. * Gyroscope data is smooth, but tends to drift over the long term.
  7253. *
  7254. * This fusion is relatively simple:
  7255. * 1. Get orientation estimates from accelerometer by applying a low-pass filter
  7256. * on that data.
  7257. * 2. Get orientation estimates from gyroscope by integrating over time.
  7258. * 3. Combine the two estimates, weighing (1) in the long term, but (2) for the
  7259. * short term.
  7260. */
  7261. function ComplementaryFilter(kFilter) {
  7262. this.kFilter = kFilter;
  7263. // Raw sensor measurements.
  7264. this.currentAccelMeasurement = new SensorSample();
  7265. this.currentGyroMeasurement = new SensorSample();
  7266. this.previousGyroMeasurement = new SensorSample();
  7267. // Set default look direction to be in the correct direction.
  7268. if (Util.isIOS()) {
  7269. this.filterQ = new MathUtil.Quaternion(-1, 0, 0, 1);
  7270. } else {
  7271. this.filterQ = new MathUtil.Quaternion(1, 0, 0, 1);
  7272. }
  7273. this.previousFilterQ = new MathUtil.Quaternion();
  7274. this.previousFilterQ.copy(this.filterQ);
  7275. // Orientation based on the accelerometer.
  7276. this.accelQ = new MathUtil.Quaternion();
  7277. // Whether or not the orientation has been initialized.
  7278. this.isOrientationInitialized = false;
  7279. // Running estimate of gravity based on the current orientation.
  7280. this.estimatedGravity = new MathUtil.Vector3();
  7281. // Measured gravity based on accelerometer.
  7282. this.measuredGravity = new MathUtil.Vector3();
  7283. // Debug only quaternion of gyro-based orientation.
  7284. this.gyroIntegralQ = new MathUtil.Quaternion();
  7285. }
  7286. ComplementaryFilter.prototype.addAccelMeasurement = function(vector, timestampS) {
  7287. this.currentAccelMeasurement.set(vector, timestampS);
  7288. };
  7289. ComplementaryFilter.prototype.addGyroMeasurement = function(vector, timestampS) {
  7290. this.currentGyroMeasurement.set(vector, timestampS);
  7291. var deltaT = timestampS - this.previousGyroMeasurement.timestampS;
  7292. if (Util.isTimestampDeltaValid(deltaT)) {
  7293. this.run_();
  7294. }
  7295. this.previousGyroMeasurement.copy(this.currentGyroMeasurement);
  7296. };
  7297. ComplementaryFilter.prototype.run_ = function() {
  7298. if (!this.isOrientationInitialized) {
  7299. this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample);
  7300. this.previousFilterQ.copy(this.accelQ);
  7301. this.isOrientationInitialized = true;
  7302. return;
  7303. }
  7304. var deltaT = this.currentGyroMeasurement.timestampS -
  7305. this.previousGyroMeasurement.timestampS;
  7306. // Convert gyro rotation vector to a quaternion delta.
  7307. var gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT);
  7308. this.gyroIntegralQ.multiply(gyroDeltaQ);
  7309. // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel.
  7310. this.filterQ.copy(this.previousFilterQ);
  7311. this.filterQ.multiply(gyroDeltaQ);
  7312. // Calculate the delta between the current estimated gravity and the real
  7313. // gravity vector from accelerometer.
  7314. var invFilterQ = new MathUtil.Quaternion();
  7315. invFilterQ.copy(this.filterQ);
  7316. invFilterQ.inverse();
  7317. this.estimatedGravity.set(0, 0, -1);
  7318. this.estimatedGravity.applyQuaternion(invFilterQ);
  7319. this.estimatedGravity.normalize();
  7320. this.measuredGravity.copy(this.currentAccelMeasurement.sample);
  7321. this.measuredGravity.normalize();
  7322. // Compare estimated gravity with measured gravity, get the delta quaternion
  7323. // between the two.
  7324. var deltaQ = new MathUtil.Quaternion();
  7325. deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity);
  7326. deltaQ.inverse();
  7327. if (Util.isDebug()) {
  7328. console.log('Delta: %d deg, G_est: (%s, %s, %s), G_meas: (%s, %s, %s)',
  7329. MathUtil.radToDeg * Util.getQuaternionAngle(deltaQ),
  7330. (this.estimatedGravity.x).toFixed(1),
  7331. (this.estimatedGravity.y).toFixed(1),
  7332. (this.estimatedGravity.z).toFixed(1),
  7333. (this.measuredGravity.x).toFixed(1),
  7334. (this.measuredGravity.y).toFixed(1),
  7335. (this.measuredGravity.z).toFixed(1));
  7336. }
  7337. // Calculate the SLERP target: current orientation plus the measured-estimated
  7338. // quaternion delta.
  7339. var targetQ = new MathUtil.Quaternion();
  7340. targetQ.copy(this.filterQ);
  7341. targetQ.multiply(deltaQ);
  7342. // SLERP factor: 0 is pure gyro, 1 is pure accel.
  7343. this.filterQ.slerp(targetQ, 1 - this.kFilter);
  7344. this.previousFilterQ.copy(this.filterQ);
  7345. };
  7346. ComplementaryFilter.prototype.getOrientation = function() {
  7347. return this.filterQ;
  7348. };
  7349. ComplementaryFilter.prototype.accelToQuaternion_ = function(accel) {
  7350. var normAccel = new MathUtil.Vector3();
  7351. normAccel.copy(accel);
  7352. normAccel.normalize();
  7353. var quat = new MathUtil.Quaternion();
  7354. quat.setFromUnitVectors(new MathUtil.Vector3(0, 0, -1), normAccel);
  7355. quat.inverse();
  7356. return quat;
  7357. };
  7358. ComplementaryFilter.prototype.gyroToQuaternionDelta_ = function(gyro, dt) {
  7359. // Extract axis and angle from the gyroscope data.
  7360. var quat = new MathUtil.Quaternion();
  7361. var axis = new MathUtil.Vector3();
  7362. axis.copy(gyro);
  7363. axis.normalize();
  7364. quat.setFromAxisAngle(axis, gyro.length() * dt);
  7365. return quat;
  7366. };
  7367. module.exports = ComplementaryFilter;
  7368. },{"../math-util.js":20,"../util.js":29,"./sensor-sample.js":27}],25:[function(_dereq_,module,exports){
  7369. /*
  7370. * Copyright 2015 Google Inc. All Rights Reserved.
  7371. * Licensed under the Apache License, Version 2.0 (the "License");
  7372. * you may not use this file except in compliance with the License.
  7373. * You may obtain a copy of the License at
  7374. *
  7375. * http://www.apache.org/licenses/LICENSE-2.0
  7376. *
  7377. * Unless required by applicable law or agreed to in writing, software
  7378. * distributed under the License is distributed on an "AS IS" BASIS,
  7379. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  7380. * See the License for the specific language governing permissions and
  7381. * limitations under the License.
  7382. */
  7383. var ComplementaryFilter = _dereq_('./complementary-filter.js');
  7384. var PosePredictor = _dereq_('./pose-predictor.js');
  7385. var TouchPanner = _dereq_('../touch-panner.js');
  7386. var MathUtil = _dereq_('../math-util.js');
  7387. var Util = _dereq_('../util.js');
  7388. /**
  7389. * The pose sensor, implemented using DeviceMotion APIs.
  7390. */
  7391. function FusionPoseSensor() {
  7392. this.deviceId = 'webvr-polyfill:fused';
  7393. this.deviceName = 'VR Position Device (webvr-polyfill:fused)';
  7394. this.accelerometer = new MathUtil.Vector3();
  7395. this.gyroscope = new MathUtil.Vector3();
  7396. this.start();
  7397. this.filter = new ComplementaryFilter(window.WebVRConfig.K_FILTER);
  7398. this.posePredictor = new PosePredictor(window.WebVRConfig.PREDICTION_TIME_S);
  7399. this.touchPanner = new TouchPanner();
  7400. this.filterToWorldQ = new MathUtil.Quaternion();
  7401. // Set the filter to world transform, depending on OS.
  7402. if (Util.isIOS()) {
  7403. this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), Math.PI / 2);
  7404. } else {
  7405. this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), -Math.PI / 2);
  7406. }
  7407. this.inverseWorldToScreenQ = new MathUtil.Quaternion();
  7408. this.worldToScreenQ = new MathUtil.Quaternion();
  7409. this.originalPoseAdjustQ = new MathUtil.Quaternion();
  7410. this.originalPoseAdjustQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1),
  7411. -window.orientation * Math.PI / 180);
  7412. this.setScreenTransform_();
  7413. // Adjust this filter for being in landscape mode.
  7414. if (Util.isLandscapeMode()) {
  7415. this.filterToWorldQ.multiply(this.inverseWorldToScreenQ);
  7416. }
  7417. // Keep track of a reset transform for resetSensor.
  7418. this.resetQ = new MathUtil.Quaternion();
  7419. this.isFirefoxAndroid = Util.isFirefoxAndroid();
  7420. this.isIOS = Util.isIOS();
  7421. this.orientationOut_ = new Float32Array(4);
  7422. }
  7423. FusionPoseSensor.prototype.getPosition = function() {
  7424. // This PoseSensor doesn't support position
  7425. return null;
  7426. };
  7427. FusionPoseSensor.prototype.getOrientation = function() {
  7428. // Convert from filter space to the the same system used by the
  7429. // deviceorientation event.
  7430. var orientation = this.filter.getOrientation();
  7431. // Predict orientation.
  7432. this.predictedQ = this.posePredictor.getPrediction(orientation, this.gyroscope, this.previousTimestampS);
  7433. // Convert to THREE coordinate system: -Z forward, Y up, X right.
  7434. var out = new MathUtil.Quaternion();
  7435. out.copy(this.filterToWorldQ);
  7436. out.multiply(this.resetQ);
  7437. if (!window.WebVRConfig.TOUCH_PANNER_DISABLED) {
  7438. out.multiply(this.touchPanner.getOrientation());
  7439. }
  7440. out.multiply(this.predictedQ);
  7441. out.multiply(this.worldToScreenQ);
  7442. // Handle the yaw-only case.
  7443. if (window.WebVRConfig.YAW_ONLY) {
  7444. // Make a quaternion that only turns around the Y-axis.
  7445. out.x = 0;
  7446. out.z = 0;
  7447. out.normalize();
  7448. }
  7449. this.orientationOut_[0] = out.x;
  7450. this.orientationOut_[1] = out.y;
  7451. this.orientationOut_[2] = out.z;
  7452. this.orientationOut_[3] = out.w;
  7453. return this.orientationOut_;
  7454. };
  7455. FusionPoseSensor.prototype.resetPose = function() {
  7456. // Reduce to inverted yaw-only.
  7457. this.resetQ.copy(this.filter.getOrientation());
  7458. this.resetQ.x = 0;
  7459. this.resetQ.y = 0;
  7460. this.resetQ.z *= -1;
  7461. this.resetQ.normalize();
  7462. // Take into account extra transformations in landscape mode.
  7463. if (Util.isLandscapeMode()) {
  7464. this.resetQ.multiply(this.inverseWorldToScreenQ);
  7465. }
  7466. // Take into account original pose.
  7467. this.resetQ.multiply(this.originalPoseAdjustQ);
  7468. if (!window.WebVRConfig.TOUCH_PANNER_DISABLED) {
  7469. this.touchPanner.resetSensor();
  7470. }
  7471. };
  7472. FusionPoseSensor.prototype.onDeviceMotion_ = function(deviceMotion) {
  7473. this.updateDeviceMotion_(deviceMotion);
  7474. };
  7475. FusionPoseSensor.prototype.updateDeviceMotion_ = function(deviceMotion) {
  7476. var accGravity = deviceMotion.accelerationIncludingGravity;
  7477. var rotRate = deviceMotion.rotationRate;
  7478. var timestampS = deviceMotion.timeStamp / 1000;
  7479. var deltaS = timestampS - this.previousTimestampS;
  7480. if (deltaS <= Util.MIN_TIMESTEP || deltaS > Util.MAX_TIMESTEP) {
  7481. console.warn('Invalid timestamps detected. Time step between successive ' +
  7482. 'gyroscope sensor samples is very small or not monotonic');
  7483. this.previousTimestampS = timestampS;
  7484. return;
  7485. }
  7486. this.accelerometer.set(-accGravity.x, -accGravity.y, -accGravity.z);
  7487. if (Util.isR7()) {
  7488. this.gyroscope.set(-rotRate.beta, rotRate.alpha, rotRate.gamma);
  7489. } else {
  7490. this.gyroscope.set(rotRate.alpha, rotRate.beta, rotRate.gamma);
  7491. }
  7492. // With iOS and Firefox Android, rotationRate is reported in degrees,
  7493. // so we first convert to radians.
  7494. if (this.isIOS || this.isFirefoxAndroid) {
  7495. this.gyroscope.multiplyScalar(Math.PI / 180);
  7496. }
  7497. this.filter.addAccelMeasurement(this.accelerometer, timestampS);
  7498. this.filter.addGyroMeasurement(this.gyroscope, timestampS);
  7499. this.previousTimestampS = timestampS;
  7500. };
  7501. FusionPoseSensor.prototype.onOrientationChange_ = function(screenOrientation) {
  7502. this.setScreenTransform_();
  7503. };
  7504. /**
  7505. * This is only needed if we are in an cross origin iframe on iOS to work around
  7506. * this issue: https://bugs.webkit.org/show_bug.cgi?id=152299.
  7507. */
  7508. FusionPoseSensor.prototype.onMessage_ = function(event) {
  7509. var message = event.data;
  7510. // If there's no message type, ignore it.
  7511. if (!message || !message.type) {
  7512. return;
  7513. }
  7514. // Ignore all messages that aren't devicemotion.
  7515. var type = message.type.toLowerCase();
  7516. if (type !== 'devicemotion') {
  7517. return;
  7518. }
  7519. // Update device motion.
  7520. this.updateDeviceMotion_(message.deviceMotionEvent);
  7521. };
  7522. FusionPoseSensor.prototype.setScreenTransform_ = function() {
  7523. this.worldToScreenQ.set(0, 0, 0, 1);
  7524. switch (window.orientation) {
  7525. case 0:
  7526. break;
  7527. case 90:
  7528. this.worldToScreenQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1), -Math.PI / 2);
  7529. break;
  7530. case -90:
  7531. this.worldToScreenQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1), Math.PI / 2);
  7532. break;
  7533. case 180:
  7534. // TODO.
  7535. break;
  7536. }
  7537. this.inverseWorldToScreenQ.copy(this.worldToScreenQ);
  7538. this.inverseWorldToScreenQ.inverse();
  7539. };
  7540. FusionPoseSensor.prototype.start = function() {
  7541. this.onDeviceMotionCallback_ = this.onDeviceMotion_.bind(this);
  7542. this.onOrientationChangeCallback_ = this.onOrientationChange_.bind(this);
  7543. this.onMessageCallback_ = this.onMessage_.bind(this);
  7544. // Only listen for postMessages if we're in an iOS and embedded inside a cross
  7545. // domain IFrame. In this case, the polyfill can still work if the containing
  7546. // page sends synthetic devicemotion events. For an example of this, see
  7547. // iframe-message-sender.js in VR View: https://goo.gl/XDtvFZ
  7548. if (Util.isIOS() && Util.isInsideCrossDomainIFrame()) {
  7549. window.addEventListener('message', this.onMessageCallback_);
  7550. }
  7551. window.addEventListener('orientationchange', this.onOrientationChangeCallback_);
  7552. window.addEventListener('devicemotion', this.onDeviceMotionCallback_);
  7553. };
  7554. FusionPoseSensor.prototype.stop = function() {
  7555. window.removeEventListener('devicemotion', this.onDeviceMotionCallback_);
  7556. window.removeEventListener('orientationchange', this.onOrientationChangeCallback_);
  7557. window.removeEventListener('message', this.onMessageCallback_);
  7558. };
  7559. module.exports = FusionPoseSensor;
  7560. },{"../math-util.js":20,"../touch-panner.js":28,"../util.js":29,"./complementary-filter.js":24,"./pose-predictor.js":26}],26:[function(_dereq_,module,exports){
  7561. /*
  7562. * Copyright 2015 Google Inc. All Rights Reserved.
  7563. * Licensed under the Apache License, Version 2.0 (the "License");
  7564. * you may not use this file except in compliance with the License.
  7565. * You may obtain a copy of the License at
  7566. *
  7567. * http://www.apache.org/licenses/LICENSE-2.0
  7568. *
  7569. * Unless required by applicable law or agreed to in writing, software
  7570. * distributed under the License is distributed on an "AS IS" BASIS,
  7571. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  7572. * See the License for the specific language governing permissions and
  7573. * limitations under the License.
  7574. */
  7575. var MathUtil = _dereq_('../math-util');
  7576. var Util = _dereq_('../util');
  7577. /**
  7578. * Given an orientation and the gyroscope data, predicts the future orientation
  7579. * of the head. This makes rendering appear faster.
  7580. *
  7581. * Also see: http://msl.cs.uiuc.edu/~lavalle/papers/LavYerKatAnt14.pdf
  7582. *
  7583. * @param {Number} predictionTimeS time from head movement to the appearance of
  7584. * the corresponding image.
  7585. */
  7586. function PosePredictor(predictionTimeS) {
  7587. this.predictionTimeS = predictionTimeS;
  7588. // The quaternion corresponding to the previous state.
  7589. this.previousQ = new MathUtil.Quaternion();
  7590. // Previous time a prediction occurred.
  7591. this.previousTimestampS = null;
  7592. // The delta quaternion that adjusts the current pose.
  7593. this.deltaQ = new MathUtil.Quaternion();
  7594. // The output quaternion.
  7595. this.outQ = new MathUtil.Quaternion();
  7596. }
  7597. PosePredictor.prototype.getPrediction = function(currentQ, gyro, timestampS) {
  7598. if (!this.previousTimestampS) {
  7599. this.previousQ.copy(currentQ);
  7600. this.previousTimestampS = timestampS;
  7601. return currentQ;
  7602. }
  7603. // Calculate axis and angle based on gyroscope rotation rate data.
  7604. var axis = new MathUtil.Vector3();
  7605. axis.copy(gyro);
  7606. axis.normalize();
  7607. var angularSpeed = gyro.length();
  7608. // If we're rotating slowly, don't do prediction.
  7609. if (angularSpeed < MathUtil.degToRad * 20) {
  7610. if (Util.isDebug()) {
  7611. console.log('Moving slowly, at %s deg/s: no prediction',
  7612. (MathUtil.radToDeg * angularSpeed).toFixed(1));
  7613. }
  7614. this.outQ.copy(currentQ);
  7615. this.previousQ.copy(currentQ);
  7616. return this.outQ;
  7617. }
  7618. // Get the predicted angle based on the time delta and latency.
  7619. var deltaT = timestampS - this.previousTimestampS;
  7620. var predictAngle = angularSpeed * this.predictionTimeS;
  7621. this.deltaQ.setFromAxisAngle(axis, predictAngle);
  7622. this.outQ.copy(this.previousQ);
  7623. this.outQ.multiply(this.deltaQ);
  7624. this.previousQ.copy(currentQ);
  7625. this.previousTimestampS = timestampS;
  7626. return this.outQ;
  7627. };
  7628. module.exports = PosePredictor;
  7629. },{"../math-util":20,"../util":29}],27:[function(_dereq_,module,exports){
  7630. function SensorSample(sample, timestampS) {
  7631. this.set(sample, timestampS);
  7632. };
  7633. SensorSample.prototype.set = function(sample, timestampS) {
  7634. this.sample = sample;
  7635. this.timestampS = timestampS;
  7636. };
  7637. SensorSample.prototype.copy = function(sensorSample) {
  7638. this.set(sensorSample.sample, sensorSample.timestampS);
  7639. };
  7640. module.exports = SensorSample;
  7641. },{}],28:[function(_dereq_,module,exports){
  7642. /*
  7643. * Copyright 2015 Google Inc. All Rights Reserved.
  7644. * Licensed under the Apache License, Version 2.0 (the "License");
  7645. * you may not use this file except in compliance with the License.
  7646. * You may obtain a copy of the License at
  7647. *
  7648. * http://www.apache.org/licenses/LICENSE-2.0
  7649. *
  7650. * Unless required by applicable law or agreed to in writing, software
  7651. * distributed under the License is distributed on an "AS IS" BASIS,
  7652. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  7653. * See the License for the specific language governing permissions and
  7654. * limitations under the License.
  7655. */
  7656. var MathUtil = _dereq_('./math-util.js');
  7657. var Util = _dereq_('./util.js');
  7658. var ROTATE_SPEED = 0.5;
  7659. /**
  7660. * Provides a quaternion responsible for pre-panning the scene before further
  7661. * transformations due to device sensors.
  7662. */
  7663. function TouchPanner() {
  7664. window.addEventListener('touchstart', this.onTouchStart_.bind(this));
  7665. window.addEventListener('touchmove', this.onTouchMove_.bind(this));
  7666. window.addEventListener('touchend', this.onTouchEnd_.bind(this));
  7667. this.isTouching = false;
  7668. this.rotateStart = new MathUtil.Vector2();
  7669. this.rotateEnd = new MathUtil.Vector2();
  7670. this.rotateDelta = new MathUtil.Vector2();
  7671. this.theta = 0;
  7672. this.orientation = new MathUtil.Quaternion();
  7673. }
  7674. TouchPanner.prototype.getOrientation = function() {
  7675. this.orientation.setFromEulerXYZ(0, 0, this.theta);
  7676. return this.orientation;
  7677. };
  7678. TouchPanner.prototype.resetSensor = function() {
  7679. this.theta = 0;
  7680. };
  7681. TouchPanner.prototype.onTouchStart_ = function(e) {
  7682. // Only respond if there is exactly one touch.
  7683. // Note that the Daydream controller passes in a `touchstart` event with
  7684. // no `touches` property, so we must check for that case too.
  7685. if (!e.touches || e.touches.length != 1) {
  7686. return;
  7687. }
  7688. this.rotateStart.set(e.touches[0].pageX, e.touches[0].pageY);
  7689. this.isTouching = true;
  7690. };
  7691. TouchPanner.prototype.onTouchMove_ = function(e) {
  7692. if (!this.isTouching) {
  7693. return;
  7694. }
  7695. this.rotateEnd.set(e.touches[0].pageX, e.touches[0].pageY);
  7696. this.rotateDelta.subVectors(this.rotateEnd, this.rotateStart);
  7697. this.rotateStart.copy(this.rotateEnd);
  7698. // On iOS, direction is inverted.
  7699. if (Util.isIOS()) {
  7700. this.rotateDelta.x *= -1;
  7701. }
  7702. var element = document.body;
  7703. this.theta += 2 * Math.PI * this.rotateDelta.x / element.clientWidth * ROTATE_SPEED;
  7704. };
  7705. TouchPanner.prototype.onTouchEnd_ = function(e) {
  7706. this.isTouching = false;
  7707. };
  7708. module.exports = TouchPanner;
  7709. },{"./math-util.js":20,"./util.js":29}],29:[function(_dereq_,module,exports){
  7710. /*
  7711. * Copyright 2015 Google Inc. All Rights Reserved.
  7712. * Licensed under the Apache License, Version 2.0 (the "License");
  7713. * you may not use this file except in compliance with the License.
  7714. * You may obtain a copy of the License at
  7715. *
  7716. * http://www.apache.org/licenses/LICENSE-2.0
  7717. *
  7718. * Unless required by applicable law or agreed to in writing, software
  7719. * distributed under the License is distributed on an "AS IS" BASIS,
  7720. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  7721. * See the License for the specific language governing permissions and
  7722. * limitations under the License.
  7723. */
  7724. var Util = window.Util || {};
  7725. Util.MIN_TIMESTEP = 0.001;
  7726. Util.MAX_TIMESTEP = 1;
  7727. Util.base64 = function(mimeType, base64) {
  7728. return 'data:' + mimeType + ';base64,' + base64;
  7729. };
  7730. Util.clamp = function(value, min, max) {
  7731. return Math.min(Math.max(min, value), max);
  7732. };
  7733. Util.lerp = function(a, b, t) {
  7734. return a + ((b - a) * t);
  7735. };
  7736. /**
  7737. * Light polyfill for `Promise.race`. Returns
  7738. * a promise that resolves when the first promise
  7739. * provided resolves.
  7740. *
  7741. * @param {Array<Promise>} promises
  7742. */
  7743. Util.race = function(promises) {
  7744. if (Promise.race) {
  7745. return Promise.race(promises);
  7746. }
  7747. return new Promise(function (resolve, reject) {
  7748. for (var i = 0; i < promises.length; i++) {
  7749. promises[i].then(resolve, reject);
  7750. }
  7751. });
  7752. };
  7753. Util.isIOS = (function() {
  7754. var isIOS = /iPad|iPhone|iPod/.test(navigator.platform);
  7755. return function() {
  7756. return isIOS;
  7757. };
  7758. })();
  7759. Util.isWebViewAndroid = (function() {
  7760. var isWebViewAndroid = navigator.userAgent.indexOf('Version') !== -1 &&
  7761. navigator.userAgent.indexOf('Android') !== -1 &&
  7762. navigator.userAgent.indexOf('Chrome') !== -1;
  7763. return function() {
  7764. return isWebViewAndroid;
  7765. };
  7766. })();
  7767. Util.isSafari = (function() {
  7768. var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
  7769. return function() {
  7770. return isSafari;
  7771. };
  7772. })();
  7773. Util.isFirefoxAndroid = (function() {
  7774. var isFirefoxAndroid = navigator.userAgent.indexOf('Firefox') !== -1 &&
  7775. navigator.userAgent.indexOf('Android') !== -1;
  7776. return function() {
  7777. return isFirefoxAndroid;
  7778. };
  7779. })();
  7780. Util.isR7 = (function() {
  7781. var isR7 = navigator.userAgent.indexOf('R7 Build') !== -1;
  7782. return function() {
  7783. return isR7;
  7784. };
  7785. })();
  7786. Util.isLandscapeMode = function() {
  7787. var rtn = (window.orientation == 90 || window.orientation == -90);
  7788. return Util.isR7() ? !rtn : rtn;
  7789. };
  7790. // Helper method to validate the time steps of sensor timestamps.
  7791. Util.isTimestampDeltaValid = function(timestampDeltaS) {
  7792. if (isNaN(timestampDeltaS)) {
  7793. return false;
  7794. }
  7795. if (timestampDeltaS <= Util.MIN_TIMESTEP) {
  7796. return false;
  7797. }
  7798. if (timestampDeltaS > Util.MAX_TIMESTEP) {
  7799. return false;
  7800. }
  7801. return true;
  7802. };
  7803. Util.getScreenWidth = function() {
  7804. return Math.max(window.screen.width, window.screen.height) *
  7805. window.devicePixelRatio;
  7806. };
  7807. Util.getScreenHeight = function() {
  7808. return Math.min(window.screen.width, window.screen.height) *
  7809. window.devicePixelRatio;
  7810. };
  7811. Util.requestFullscreen = function(element) {
  7812. if (Util.isWebViewAndroid()) {
  7813. return false;
  7814. }
  7815. if (element.requestFullscreen) {
  7816. element.requestFullscreen();
  7817. } else if (element.webkitRequestFullscreen) {
  7818. element.webkitRequestFullscreen();
  7819. } else if (element.mozRequestFullScreen) {
  7820. element.mozRequestFullScreen();
  7821. } else if (element.msRequestFullscreen) {
  7822. element.msRequestFullscreen();
  7823. } else {
  7824. return false;
  7825. }
  7826. return true;
  7827. };
  7828. Util.exitFullscreen = function() {
  7829. if (document.exitFullscreen) {
  7830. document.exitFullscreen();
  7831. } else if (document.webkitExitFullscreen) {
  7832. document.webkitExitFullscreen();
  7833. } else if (document.mozCancelFullScreen) {
  7834. document.mozCancelFullScreen();
  7835. } else if (document.msExitFullscreen) {
  7836. document.msExitFullscreen();
  7837. } else {
  7838. return false;
  7839. }
  7840. return true;
  7841. };
  7842. Util.getFullscreenElement = function() {
  7843. return document.fullscreenElement ||
  7844. document.webkitFullscreenElement ||
  7845. document.mozFullScreenElement ||
  7846. document.msFullscreenElement;
  7847. };
  7848. Util.linkProgram = function(gl, vertexSource, fragmentSource, attribLocationMap) {
  7849. // No error checking for brevity.
  7850. var vertexShader = gl.createShader(gl.VERTEX_SHADER);
  7851. gl.shaderSource(vertexShader, vertexSource);
  7852. gl.compileShader(vertexShader);
  7853. var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
  7854. gl.shaderSource(fragmentShader, fragmentSource);
  7855. gl.compileShader(fragmentShader);
  7856. var program = gl.createProgram();
  7857. gl.attachShader(program, vertexShader);
  7858. gl.attachShader(program, fragmentShader);
  7859. for (var attribName in attribLocationMap)
  7860. gl.bindAttribLocation(program, attribLocationMap[attribName], attribName);
  7861. gl.linkProgram(program);
  7862. gl.deleteShader(vertexShader);
  7863. gl.deleteShader(fragmentShader);
  7864. return program;
  7865. };
  7866. Util.getProgramUniforms = function(gl, program) {
  7867. var uniforms = {};
  7868. var uniformCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
  7869. var uniformName = '';
  7870. for (var i = 0; i < uniformCount; i++) {
  7871. var uniformInfo = gl.getActiveUniform(program, i);
  7872. uniformName = uniformInfo.name.replace('[0]', '');
  7873. uniforms[uniformName] = gl.getUniformLocation(program, uniformName);
  7874. }
  7875. return uniforms;
  7876. };
  7877. Util.orthoMatrix = function (out, left, right, bottom, top, near, far) {
  7878. var lr = 1 / (left - right),
  7879. bt = 1 / (bottom - top),
  7880. nf = 1 / (near - far);
  7881. out[0] = -2 * lr;
  7882. out[1] = 0;
  7883. out[2] = 0;
  7884. out[3] = 0;
  7885. out[4] = 0;
  7886. out[5] = -2 * bt;
  7887. out[6] = 0;
  7888. out[7] = 0;
  7889. out[8] = 0;
  7890. out[9] = 0;
  7891. out[10] = 2 * nf;
  7892. out[11] = 0;
  7893. out[12] = (left + right) * lr;
  7894. out[13] = (top + bottom) * bt;
  7895. out[14] = (far + near) * nf;
  7896. out[15] = 1;
  7897. return out;
  7898. };
  7899. Util.copyArray = function (source, dest) {
  7900. for (var i = 0, n = source.length; i < n; i++) {
  7901. dest[i] = source[i];
  7902. }
  7903. };
  7904. Util.isMobile = function() {
  7905. var check = false;
  7906. (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))check = true})(navigator.userAgent||navigator.vendor||window.opera);
  7907. return check;
  7908. };
  7909. Util.extend = function(dest, src) {
  7910. for (var key in src) {
  7911. if (src.hasOwnProperty(key)) {
  7912. dest[key] = src[key];
  7913. }
  7914. }
  7915. return dest;
  7916. }
  7917. Util.safariCssSizeWorkaround = function(canvas) {
  7918. // TODO(smus): Remove this workaround when Safari for iOS is fixed.
  7919. // iOS only workaround (for https://bugs.webkit.org/show_bug.cgi?id=152556).
  7920. //
  7921. // "To the last I grapple with thee;
  7922. // from hell's heart I stab at thee;
  7923. // for hate's sake I spit my last breath at thee."
  7924. // -- Moby Dick, by Herman Melville
  7925. if (Util.isIOS()) {
  7926. var width = canvas.style.width;
  7927. var height = canvas.style.height;
  7928. canvas.style.width = (parseInt(width) + 1) + 'px';
  7929. canvas.style.height = (parseInt(height)) + 'px';
  7930. setTimeout(function() {
  7931. canvas.style.width = width;
  7932. canvas.style.height = height;
  7933. }, 100);
  7934. }
  7935. // Debug only.
  7936. window.Util = Util;
  7937. window.canvas = canvas;
  7938. };
  7939. Util.isDebug = function() {
  7940. return Util.getQueryParameter('debug');
  7941. };
  7942. Util.getQueryParameter = function(name) {
  7943. var name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
  7944. var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
  7945. results = regex.exec(location.search);
  7946. return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
  7947. };
  7948. Util.frameDataFromPose = (function() {
  7949. var piOver180 = Math.PI / 180.0;
  7950. var rad45 = Math.PI * 0.25;
  7951. // Borrowed from glMatrix.
  7952. function mat4_perspectiveFromFieldOfView(out, fov, near, far) {
  7953. var upTan = Math.tan(fov ? (fov.upDegrees * piOver180) : rad45),
  7954. downTan = Math.tan(fov ? (fov.downDegrees * piOver180) : rad45),
  7955. leftTan = Math.tan(fov ? (fov.leftDegrees * piOver180) : rad45),
  7956. rightTan = Math.tan(fov ? (fov.rightDegrees * piOver180) : rad45),
  7957. xScale = 2.0 / (leftTan + rightTan),
  7958. yScale = 2.0 / (upTan + downTan);
  7959. out[0] = xScale;
  7960. out[1] = 0.0;
  7961. out[2] = 0.0;
  7962. out[3] = 0.0;
  7963. out[4] = 0.0;
  7964. out[5] = yScale;
  7965. out[6] = 0.0;
  7966. out[7] = 0.0;
  7967. out[8] = -((leftTan - rightTan) * xScale * 0.5);
  7968. out[9] = ((upTan - downTan) * yScale * 0.5);
  7969. out[10] = far / (near - far);
  7970. out[11] = -1.0;
  7971. out[12] = 0.0;
  7972. out[13] = 0.0;
  7973. out[14] = (far * near) / (near - far);
  7974. out[15] = 0.0;
  7975. return out;
  7976. }
  7977. function mat4_fromRotationTranslation(out, q, v) {
  7978. // Quaternion math
  7979. var x = q[0], y = q[1], z = q[2], w = q[3],
  7980. x2 = x + x,
  7981. y2 = y + y,
  7982. z2 = z + z,
  7983. xx = x * x2,
  7984. xy = x * y2,
  7985. xz = x * z2,
  7986. yy = y * y2,
  7987. yz = y * z2,
  7988. zz = z * z2,
  7989. wx = w * x2,
  7990. wy = w * y2,
  7991. wz = w * z2;
  7992. out[0] = 1 - (yy + zz);
  7993. out[1] = xy + wz;
  7994. out[2] = xz - wy;
  7995. out[3] = 0;
  7996. out[4] = xy - wz;
  7997. out[5] = 1 - (xx + zz);
  7998. out[6] = yz + wx;
  7999. out[7] = 0;
  8000. out[8] = xz + wy;
  8001. out[9] = yz - wx;
  8002. out[10] = 1 - (xx + yy);
  8003. out[11] = 0;
  8004. out[12] = v[0];
  8005. out[13] = v[1];
  8006. out[14] = v[2];
  8007. out[15] = 1;
  8008. return out;
  8009. };
  8010. function mat4_translate(out, a, v) {
  8011. var x = v[0], y = v[1], z = v[2],
  8012. a00, a01, a02, a03,
  8013. a10, a11, a12, a13,
  8014. a20, a21, a22, a23;
  8015. if (a === out) {
  8016. out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];
  8017. out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];
  8018. out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];
  8019. out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];
  8020. } else {
  8021. a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];
  8022. a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];
  8023. a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];
  8024. out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03;
  8025. out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13;
  8026. out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23;
  8027. out[12] = a00 * x + a10 * y + a20 * z + a[12];
  8028. out[13] = a01 * x + a11 * y + a21 * z + a[13];
  8029. out[14] = a02 * x + a12 * y + a22 * z + a[14];
  8030. out[15] = a03 * x + a13 * y + a23 * z + a[15];
  8031. }
  8032. return out;
  8033. };
  8034. function mat4_invert(out, a) {
  8035. var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
  8036. a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
  8037. a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
  8038. a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15],
  8039. b00 = a00 * a11 - a01 * a10,
  8040. b01 = a00 * a12 - a02 * a10,
  8041. b02 = a00 * a13 - a03 * a10,
  8042. b03 = a01 * a12 - a02 * a11,
  8043. b04 = a01 * a13 - a03 * a11,
  8044. b05 = a02 * a13 - a03 * a12,
  8045. b06 = a20 * a31 - a21 * a30,
  8046. b07 = a20 * a32 - a22 * a30,
  8047. b08 = a20 * a33 - a23 * a30,
  8048. b09 = a21 * a32 - a22 * a31,
  8049. b10 = a21 * a33 - a23 * a31,
  8050. b11 = a22 * a33 - a23 * a32,
  8051. // Calculate the determinant
  8052. det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
  8053. if (!det) {
  8054. return null;
  8055. }
  8056. det = 1.0 / det;
  8057. out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
  8058. out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
  8059. out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
  8060. out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;
  8061. out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
  8062. out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
  8063. out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
  8064. out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;
  8065. out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
  8066. out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
  8067. out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
  8068. out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;
  8069. out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;
  8070. out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;
  8071. out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;
  8072. out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;
  8073. return out;
  8074. };
  8075. var defaultOrientation = new Float32Array([0, 0, 0, 1]);
  8076. var defaultPosition = new Float32Array([0, 0, 0]);
  8077. function updateEyeMatrices(projection, view, pose, parameters, vrDisplay) {
  8078. mat4_perspectiveFromFieldOfView(projection, parameters ? parameters.fieldOfView : null, vrDisplay.depthNear, vrDisplay.depthFar);
  8079. var orientation = pose.orientation || defaultOrientation;
  8080. var position = pose.position || defaultPosition;
  8081. mat4_fromRotationTranslation(view, orientation, position);
  8082. if (parameters)
  8083. mat4_translate(view, view, parameters.offset);
  8084. mat4_invert(view, view);
  8085. }
  8086. return function(frameData, pose, vrDisplay) {
  8087. if (!frameData || !pose)
  8088. return false;
  8089. frameData.pose = pose;
  8090. frameData.timestamp = pose.timestamp;
  8091. updateEyeMatrices(
  8092. frameData.leftProjectionMatrix, frameData.leftViewMatrix,
  8093. pose, vrDisplay.getEyeParameters("left"), vrDisplay);
  8094. updateEyeMatrices(
  8095. frameData.rightProjectionMatrix, frameData.rightViewMatrix,
  8096. pose, vrDisplay.getEyeParameters("right"), vrDisplay);
  8097. return true;
  8098. };
  8099. })();
  8100. Util.isInsideCrossDomainIFrame = function() {
  8101. var isFramed = (window.self !== window.top);
  8102. var refDomain = Util.getDomainFromUrl(document.referrer);
  8103. var thisDomain = Util.getDomainFromUrl(window.location.href);
  8104. return isFramed && (refDomain !== thisDomain);
  8105. };
  8106. // From http://stackoverflow.com/a/23945027.
  8107. Util.getDomainFromUrl = function(url) {
  8108. var domain;
  8109. // Find & remove protocol (http, ftp, etc.) and get domain.
  8110. if (url.indexOf("://") > -1) {
  8111. domain = url.split('/')[2];
  8112. }
  8113. else {
  8114. domain = url.split('/')[0];
  8115. }
  8116. //find & remove port number
  8117. domain = domain.split(':')[0];
  8118. return domain;
  8119. }
  8120. module.exports = Util;
  8121. },{}],30:[function(_dereq_,module,exports){
  8122. /*
  8123. * Copyright 2015 Google Inc. All Rights Reserved.
  8124. * Licensed under the Apache License, Version 2.0 (the "License");
  8125. * you may not use this file except in compliance with the License.
  8126. * You may obtain a copy of the License at
  8127. *
  8128. * http://www.apache.org/licenses/LICENSE-2.0
  8129. *
  8130. * Unless required by applicable law or agreed to in writing, software
  8131. * distributed under the License is distributed on an "AS IS" BASIS,
  8132. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  8133. * See the License for the specific language governing permissions and
  8134. * limitations under the License.
  8135. */
  8136. var DeviceInfo = _dereq_('./device-info.js');
  8137. var Util = _dereq_('./util.js');
  8138. var DEFAULT_VIEWER = 'CardboardV1';
  8139. var VIEWER_KEY = 'WEBVR_CARDBOARD_VIEWER';
  8140. var CLASS_NAME = 'webvr-polyfill-viewer-selector';
  8141. /**
  8142. * Creates a viewer selector with the options specified. Supports being shown
  8143. * and hidden. Generates events when viewer parameters change. Also supports
  8144. * saving the currently selected index in localStorage.
  8145. */
  8146. function ViewerSelector() {
  8147. // Try to load the selected key from local storage.
  8148. try {
  8149. this.selectedKey = localStorage.getItem(VIEWER_KEY);
  8150. } catch (error) {
  8151. console.error('Failed to load viewer profile: %s', error);
  8152. }
  8153. //If none exists, or if localstorage is unavailable, use the default key.
  8154. if (!this.selectedKey) {
  8155. this.selectedKey = DEFAULT_VIEWER;
  8156. }
  8157. this.dialog = this.createDialog_(DeviceInfo.Viewers);
  8158. this.root = null;
  8159. this.onChangeCallbacks_ = [];
  8160. }
  8161. ViewerSelector.prototype.show = function(root) {
  8162. this.root = root;
  8163. root.appendChild(this.dialog);
  8164. // Ensure the currently selected item is checked.
  8165. var selected = this.dialog.querySelector('#' + this.selectedKey);
  8166. selected.checked = true;
  8167. // Show the UI.
  8168. this.dialog.style.display = 'block';
  8169. };
  8170. ViewerSelector.prototype.hide = function() {
  8171. if (this.root && this.root.contains(this.dialog)) {
  8172. this.root.removeChild(this.dialog);
  8173. }
  8174. this.dialog.style.display = 'none';
  8175. };
  8176. ViewerSelector.prototype.getCurrentViewer = function() {
  8177. return DeviceInfo.Viewers[this.selectedKey];
  8178. };
  8179. ViewerSelector.prototype.getSelectedKey_ = function() {
  8180. var input = this.dialog.querySelector('input[name=field]:checked');
  8181. if (input) {
  8182. return input.id;
  8183. }
  8184. return null;
  8185. };
  8186. ViewerSelector.prototype.onChange = function(cb) {
  8187. this.onChangeCallbacks_.push(cb);
  8188. };
  8189. ViewerSelector.prototype.fireOnChange_ = function(viewer) {
  8190. for (var i = 0; i < this.onChangeCallbacks_.length; i++) {
  8191. this.onChangeCallbacks_[i](viewer);
  8192. }
  8193. };
  8194. ViewerSelector.prototype.onSave_ = function() {
  8195. this.selectedKey = this.getSelectedKey_();
  8196. if (!this.selectedKey || !DeviceInfo.Viewers[this.selectedKey]) {
  8197. console.error('ViewerSelector.onSave_: this should never happen!');
  8198. return;
  8199. }
  8200. this.fireOnChange_(DeviceInfo.Viewers[this.selectedKey]);
  8201. // Attempt to save the viewer profile, but fails in private mode.
  8202. try {
  8203. localStorage.setItem(VIEWER_KEY, this.selectedKey);
  8204. } catch(error) {
  8205. console.error('Failed to save viewer profile: %s', error);
  8206. }
  8207. this.hide();
  8208. };
  8209. /**
  8210. * Creates the dialog.
  8211. */
  8212. ViewerSelector.prototype.createDialog_ = function(options) {
  8213. var container = document.createElement('div');
  8214. container.classList.add(CLASS_NAME);
  8215. container.style.display = 'none';
  8216. // Create an overlay that dims the background, and which goes away when you
  8217. // tap it.
  8218. var overlay = document.createElement('div');
  8219. var s = overlay.style;
  8220. s.position = 'fixed';
  8221. s.left = 0;
  8222. s.top = 0;
  8223. s.width = '100%';
  8224. s.height = '100%';
  8225. s.background = 'rgba(0, 0, 0, 0.3)';
  8226. overlay.addEventListener('click', this.hide.bind(this));
  8227. var width = 280;
  8228. var dialog = document.createElement('div');
  8229. var s = dialog.style;
  8230. s.boxSizing = 'border-box';
  8231. s.position = 'fixed';
  8232. s.top = '24px';
  8233. s.left = '50%';
  8234. s.marginLeft = (-width/2) + 'px';
  8235. s.width = width + 'px';
  8236. s.padding = '24px';
  8237. s.overflow = 'hidden';
  8238. s.background = '#fafafa';
  8239. s.fontFamily = "'Roboto', sans-serif";
  8240. s.boxShadow = '0px 5px 20px #666';
  8241. dialog.appendChild(this.createH1_('Select your viewer'));
  8242. for (var id in options) {
  8243. dialog.appendChild(this.createChoice_(id, options[id].label));
  8244. }
  8245. dialog.appendChild(this.createButton_('Save', this.onSave_.bind(this)));
  8246. container.appendChild(overlay);
  8247. container.appendChild(dialog);
  8248. return container;
  8249. };
  8250. ViewerSelector.prototype.createH1_ = function(name) {
  8251. var h1 = document.createElement('h1');
  8252. var s = h1.style;
  8253. s.color = 'black';
  8254. s.fontSize = '20px';
  8255. s.fontWeight = 'bold';
  8256. s.marginTop = 0;
  8257. s.marginBottom = '24px';
  8258. h1.innerHTML = name;
  8259. return h1;
  8260. };
  8261. ViewerSelector.prototype.createChoice_ = function(id, name) {
  8262. /*
  8263. <div class="choice">
  8264. <input id="v1" type="radio" name="field" value="v1">
  8265. <label for="v1">Cardboard V1</label>
  8266. </div>
  8267. */
  8268. var div = document.createElement('div');
  8269. div.style.marginTop = '8px';
  8270. div.style.color = 'black';
  8271. var input = document.createElement('input');
  8272. input.style.fontSize = '30px';
  8273. input.setAttribute('id', id);
  8274. input.setAttribute('type', 'radio');
  8275. input.setAttribute('value', id);
  8276. input.setAttribute('name', 'field');
  8277. var label = document.createElement('label');
  8278. label.style.marginLeft = '4px';
  8279. label.setAttribute('for', id);
  8280. label.innerHTML = name;
  8281. div.appendChild(input);
  8282. div.appendChild(label);
  8283. return div;
  8284. };
  8285. ViewerSelector.prototype.createButton_ = function(label, onclick) {
  8286. var button = document.createElement('button');
  8287. button.innerHTML = label;
  8288. var s = button.style;
  8289. s.float = 'right';
  8290. s.textTransform = 'uppercase';
  8291. s.color = '#1094f7';
  8292. s.fontSize = '14px';
  8293. s.letterSpacing = 0;
  8294. s.border = 0;
  8295. s.background = 'none';
  8296. s.marginTop = '16px';
  8297. button.addEventListener('click', onclick);
  8298. return button;
  8299. };
  8300. module.exports = ViewerSelector;
  8301. },{"./device-info.js":14,"./util.js":29}],31:[function(_dereq_,module,exports){
  8302. /*
  8303. * Copyright 2015 Google Inc. All Rights Reserved.
  8304. * Licensed under the Apache License, Version 2.0 (the "License");
  8305. * you may not use this file except in compliance with the License.
  8306. * You may obtain a copy of the License at
  8307. *
  8308. * http://www.apache.org/licenses/LICENSE-2.0
  8309. *
  8310. * Unless required by applicable law or agreed to in writing, software
  8311. * distributed under the License is distributed on an "AS IS" BASIS,
  8312. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  8313. * See the License for the specific language governing permissions and
  8314. * limitations under the License.
  8315. */
  8316. var Util = _dereq_('./util.js');
  8317. /**
  8318. * Android and iOS compatible wakelock implementation.
  8319. *
  8320. * Refactored thanks to dkovalev@.
  8321. */
  8322. function AndroidWakeLock() {
  8323. var video = document.createElement('video');
  8324. video.setAttribute('loop', '');
  8325. function addSourceToVideo(element, type, dataURI) {
  8326. var source = document.createElement('source');
  8327. source.src = dataURI;
  8328. source.type = 'video/' + type;
  8329. element.appendChild(source);
  8330. }
  8331. addSourceToVideo(video,'webm', Util.base64('video/webm', 'GkXfo0AgQoaBAUL3gQFC8oEEQvOBCEKCQAR3ZWJtQoeBAkKFgQIYU4BnQI0VSalmQCgq17FAAw9CQE2AQAZ3aGFtbXlXQUAGd2hhbW15RIlACECPQAAAAAAAFlSua0AxrkAu14EBY8WBAZyBACK1nEADdW5khkAFVl9WUDglhohAA1ZQOIOBAeBABrCBCLqBCB9DtnVAIueBAKNAHIEAAIAwAQCdASoIAAgAAUAmJaQAA3AA/vz0AAA='));
  8332. addSourceToVideo(video, 'mp4', Util.base64('video/mp4', 'AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAAG21kYXQAAAGzABAHAAABthADAowdbb9/AAAC6W1vb3YAAABsbXZoZAAAAAB8JbCAfCWwgAAAA+gAAAAAAAEAAAEAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAIVdHJhawAAAFx0a2hkAAAAD3wlsIB8JbCAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAQAAAAAAIAAAACAAAAAABsW1kaWEAAAAgbWRoZAAAAAB8JbCAfCWwgAAAA+gAAAAAVcQAAAAAAC1oZGxyAAAAAAAAAAB2aWRlAAAAAAAAAAAAAAAAVmlkZW9IYW5kbGVyAAAAAVxtaW5mAAAAFHZtaGQAAAABAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAAEcc3RibAAAALhzdHNkAAAAAAAAAAEAAACobXA0dgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAIAAgASAAAAEgAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABj//wAAAFJlc2RzAAAAAANEAAEABDwgEQAAAAADDUAAAAAABS0AAAGwAQAAAbWJEwAAAQAAAAEgAMSNiB9FAEQBFGMAAAGyTGF2YzUyLjg3LjQGAQIAAAAYc3R0cwAAAAAAAAABAAAAAQAAAAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAEAAAABAAAAFHN0c3oAAAAAAAAAEwAAAAEAAAAUc3RjbwAAAAAAAAABAAAALAAAAGB1ZHRhAAAAWG1ldGEAAAAAAAAAIWhkbHIAAAAAAAAAAG1kaXJhcHBsAAAAAAAAAAAAAAAAK2lsc3QAAAAjqXRvbwAAABtkYXRhAAAAAQAAAABMYXZmNTIuNzguMw=='));
  8333. this.request = function() {
  8334. if (video.paused) {
  8335. video.play();
  8336. }
  8337. };
  8338. this.release = function() {
  8339. video.pause();
  8340. };
  8341. }
  8342. function iOSWakeLock() {
  8343. var timer = null;
  8344. this.request = function() {
  8345. if (!timer) {
  8346. timer = setInterval(function() {
  8347. window.location = window.location;
  8348. setTimeout(window.stop, 0);
  8349. }, 30000);
  8350. }
  8351. }
  8352. this.release = function() {
  8353. if (timer) {
  8354. clearInterval(timer);
  8355. timer = null;
  8356. }
  8357. }
  8358. }
  8359. function getWakeLock() {
  8360. var userAgent = navigator.userAgent || navigator.vendor || window.opera;
  8361. if (userAgent.match(/iPhone/i) || userAgent.match(/iPod/i)) {
  8362. return iOSWakeLock;
  8363. } else {
  8364. return AndroidWakeLock;
  8365. }
  8366. }
  8367. module.exports = getWakeLock();
  8368. },{"./util.js":29}],32:[function(_dereq_,module,exports){
  8369. /*
  8370. * Copyright 2015 Google Inc. All Rights Reserved.
  8371. * Licensed under the Apache License, Version 2.0 (the "License");
  8372. * you may not use this file except in compliance with the License.
  8373. * You may obtain a copy of the License at
  8374. *
  8375. * http://www.apache.org/licenses/LICENSE-2.0
  8376. *
  8377. * Unless required by applicable law or agreed to in writing, software
  8378. * distributed under the License is distributed on an "AS IS" BASIS,
  8379. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  8380. * See the License for the specific language governing permissions and
  8381. * limitations under the License.
  8382. */
  8383. var Util = _dereq_('./util.js');
  8384. var CardboardVRDisplay = _dereq_('./cardboard-vr-display.js');
  8385. var MouseKeyboardVRDisplay = _dereq_('./mouse-keyboard-vr-display.js');
  8386. // Uncomment to add positional tracking via webcam.
  8387. //var WebcamPositionSensorVRDevice = require('./webcam-position-sensor-vr-device.js');
  8388. var VRDisplay = _dereq_('./base.js').VRDisplay;
  8389. var VRFrameData = _dereq_('./base.js').VRFrameData;
  8390. var HMDVRDevice = _dereq_('./base.js').HMDVRDevice;
  8391. var PositionSensorVRDevice = _dereq_('./base.js').PositionSensorVRDevice;
  8392. var VRDisplayHMDDevice = _dereq_('./display-wrappers.js').VRDisplayHMDDevice;
  8393. var VRDisplayPositionSensorDevice = _dereq_('./display-wrappers.js').VRDisplayPositionSensorDevice;
  8394. var version = _dereq_('../package.json').version;
  8395. function WebVRPolyfill() {
  8396. this.displays = [];
  8397. this.devices = []; // For deprecated objects
  8398. this.devicesPopulated = false;
  8399. this.nativeWebVRAvailable = this.isWebVRAvailable();
  8400. this.nativeLegacyWebVRAvailable = this.isDeprecatedWebVRAvailable();
  8401. this.nativeGetVRDisplaysFunc = this.nativeWebVRAvailable ?
  8402. navigator.getVRDisplays :
  8403. null;
  8404. if (!this.nativeLegacyWebVRAvailable && !this.nativeWebVRAvailable) {
  8405. this.enablePolyfill();
  8406. if (window.WebVRConfig.ENABLE_DEPRECATED_API) {
  8407. this.enableDeprecatedPolyfill();
  8408. }
  8409. }
  8410. // Put a shim in place to update the API to 1.1 if needed.
  8411. InstallWebVRSpecShim();
  8412. }
  8413. WebVRPolyfill.prototype.isWebVRAvailable = function() {
  8414. return ('getVRDisplays' in navigator);
  8415. };
  8416. WebVRPolyfill.prototype.isDeprecatedWebVRAvailable = function() {
  8417. return ('getVRDevices' in navigator) || ('mozGetVRDevices' in navigator);
  8418. };
  8419. WebVRPolyfill.prototype.connectDisplay = function(vrDisplay) {
  8420. vrDisplay.fireVRDisplayConnect_();
  8421. this.displays.push(vrDisplay);
  8422. };
  8423. WebVRPolyfill.prototype.populateDevices = function() {
  8424. if (this.devicesPopulated) {
  8425. return;
  8426. }
  8427. // Initialize our virtual VR devices.
  8428. var vrDisplay = null;
  8429. // Add a Cardboard VRDisplay on compatible mobile devices
  8430. if (this.isCardboardCompatible()) {
  8431. vrDisplay = new CardboardVRDisplay();
  8432. this.connectDisplay(vrDisplay);
  8433. // For backwards compatibility
  8434. if (window.WebVRConfig.ENABLE_DEPRECATED_API) {
  8435. this.devices.push(new VRDisplayHMDDevice(vrDisplay));
  8436. this.devices.push(new VRDisplayPositionSensorDevice(vrDisplay));
  8437. }
  8438. }
  8439. // Add a Mouse and Keyboard driven VRDisplay for desktops/laptops
  8440. if (!this.isMobile() && !window.WebVRConfig.MOUSE_KEYBOARD_CONTROLS_DISABLED) {
  8441. vrDisplay = new MouseKeyboardVRDisplay();
  8442. this.connectDisplay(vrDisplay);
  8443. // For backwards compatibility
  8444. if (window.WebVRConfig.ENABLE_DEPRECATED_API) {
  8445. this.devices.push(new VRDisplayHMDDevice(vrDisplay));
  8446. this.devices.push(new VRDisplayPositionSensorDevice(vrDisplay));
  8447. }
  8448. }
  8449. // Uncomment to add positional tracking via webcam.
  8450. //if (!this.isMobile() && window.WebVRConfig.ENABLE_DEPRECATED_API) {
  8451. // positionDevice = new WebcamPositionSensorVRDevice();
  8452. // this.devices.push(positionDevice);
  8453. //}
  8454. this.devicesPopulated = true;
  8455. };
  8456. WebVRPolyfill.prototype.enablePolyfill = function() {
  8457. // Provide navigator.getVRDisplays.
  8458. navigator.getVRDisplays = this.getVRDisplays.bind(this);
  8459. // Polyfill native VRDisplay.getFrameData
  8460. if (this.nativeWebVRAvailable && window.VRFrameData) {
  8461. var NativeVRFrameData = window.VRFrameData;
  8462. var nativeFrameData = new window.VRFrameData();
  8463. var nativeGetFrameData = window.VRDisplay.prototype.getFrameData;
  8464. window.VRFrameData = VRFrameData;
  8465. window.VRDisplay.prototype.getFrameData = function(frameData) {
  8466. if (frameData instanceof NativeVRFrameData) {
  8467. nativeGetFrameData.call(this, frameData);
  8468. return;
  8469. }
  8470. /*
  8471. Copy frame data from the native object into the polyfilled object.
  8472. */
  8473. nativeGetFrameData.call(this, nativeFrameData);
  8474. frameData.pose = nativeFrameData.pose;
  8475. Util.copyArray(nativeFrameData.leftProjectionMatrix, frameData.leftProjectionMatrix);
  8476. Util.copyArray(nativeFrameData.rightProjectionMatrix, frameData.rightProjectionMatrix);
  8477. Util.copyArray(nativeFrameData.leftViewMatrix, frameData.leftViewMatrix);
  8478. Util.copyArray(nativeFrameData.rightViewMatrix, frameData.rightViewMatrix);
  8479. //todo: copy
  8480. };
  8481. }
  8482. // Provide the `VRDisplay` object.
  8483. window.VRDisplay = VRDisplay;
  8484. // Provide the `navigator.vrEnabled` property.
  8485. if (navigator && typeof navigator.vrEnabled === 'undefined') {
  8486. var self = this;
  8487. Object.defineProperty(navigator, 'vrEnabled', {
  8488. get: function () {
  8489. return self.isCardboardCompatible() &&
  8490. (self.isFullScreenAvailable() || Util.isIOS());
  8491. }
  8492. });
  8493. }
  8494. if (!('VRFrameData' in window)) {
  8495. // Provide the VRFrameData object.
  8496. window.VRFrameData = VRFrameData;
  8497. }
  8498. };
  8499. WebVRPolyfill.prototype.enableDeprecatedPolyfill = function() {
  8500. // Provide navigator.getVRDevices.
  8501. navigator.getVRDevices = this.getVRDevices.bind(this);
  8502. // Provide the CardboardHMDVRDevice and PositionSensorVRDevice objects.
  8503. window.HMDVRDevice = HMDVRDevice;
  8504. window.PositionSensorVRDevice = PositionSensorVRDevice;
  8505. };
  8506. WebVRPolyfill.prototype.getVRDisplays = function() {
  8507. this.populateDevices();
  8508. var polyfillDisplays = this.displays;
  8509. if (!this.nativeWebVRAvailable) {
  8510. return Promise.resolve(polyfillDisplays);
  8511. }
  8512. // Set up a race condition if this browser has a bug where
  8513. // `navigator.getVRDisplays()` never resolves.
  8514. var timeoutId;
  8515. var vrDisplaysNative = this.nativeGetVRDisplaysFunc.call(navigator);
  8516. var timeoutPromise = new Promise(function(resolve) {
  8517. timeoutId = setTimeout(function() {
  8518. console.warn('Native WebVR implementation detected, but `getVRDisplays()` failed to resolve. Falling back to polyfill.');
  8519. resolve([]);
  8520. }, window.WebVRConfig.GET_VR_DISPLAYS_TIMEOUT);
  8521. });
  8522. return Util.race([
  8523. vrDisplaysNative,
  8524. timeoutPromise
  8525. ]).then(function(nativeDisplays) {
  8526. clearTimeout(timeoutId);
  8527. if (window.WebVRConfig.ALWAYS_APPEND_POLYFILL_DISPLAY) {
  8528. return nativeDisplays.concat(polyfillDisplays);
  8529. } else {
  8530. return nativeDisplays.length > 0 ? nativeDisplays : polyfillDisplays;
  8531. }
  8532. });
  8533. };
  8534. WebVRPolyfill.prototype.getVRDevices = function() {
  8535. console.warn('getVRDevices is deprecated. Please update your code to use getVRDisplays instead.');
  8536. var self = this;
  8537. return new Promise(function(resolve, reject) {
  8538. try {
  8539. if (!self.devicesPopulated) {
  8540. if (self.nativeWebVRAvailable) {
  8541. return navigator.getVRDisplays(function(displays) {
  8542. for (var i = 0; i < displays.length; ++i) {
  8543. self.devices.push(new VRDisplayHMDDevice(displays[i]));
  8544. self.devices.push(new VRDisplayPositionSensorDevice(displays[i]));
  8545. }
  8546. self.devicesPopulated = true;
  8547. resolve(self.devices);
  8548. }, reject);
  8549. }
  8550. if (self.nativeLegacyWebVRAvailable) {
  8551. return (navigator.getVRDDevices || navigator.mozGetVRDevices)(function(devices) {
  8552. for (var i = 0; i < devices.length; ++i) {
  8553. if (devices[i] instanceof HMDVRDevice) {
  8554. self.devices.push(devices[i]);
  8555. }
  8556. if (devices[i] instanceof PositionSensorVRDevice) {
  8557. self.devices.push(devices[i]);
  8558. }
  8559. }
  8560. self.devicesPopulated = true;
  8561. resolve(self.devices);
  8562. }, reject);
  8563. }
  8564. }
  8565. self.populateDevices();
  8566. resolve(self.devices);
  8567. } catch (e) {
  8568. reject(e);
  8569. }
  8570. });
  8571. };
  8572. WebVRPolyfill.prototype.NativeVRFrameData = window.VRFrameData;
  8573. /**
  8574. * Determine if a device is mobile.
  8575. */
  8576. WebVRPolyfill.prototype.isMobile = function() {
  8577. return /Android/i.test(navigator.userAgent) ||
  8578. /iPhone|iPad|iPod/i.test(navigator.userAgent);
  8579. };
  8580. WebVRPolyfill.prototype.isCardboardCompatible = function() {
  8581. // For now, support all iOS and Android devices.
  8582. // Also enable the WebVRConfig.FORCE_VR flag for debugging.
  8583. return this.isMobile() || window.WebVRConfig.FORCE_ENABLE_VR;
  8584. };
  8585. WebVRPolyfill.prototype.isFullScreenAvailable = function() {
  8586. return (document.fullscreenEnabled ||
  8587. document.mozFullScreenEnabled ||
  8588. document.webkitFullscreenEnabled ||
  8589. false);
  8590. };
  8591. // Installs a shim that updates a WebVR 1.0 spec implementation to WebVR 1.1
  8592. function InstallWebVRSpecShim() {
  8593. if ('VRDisplay' in window && !('VRFrameData' in window)) {
  8594. // Provide the VRFrameData object.
  8595. window.VRFrameData = VRFrameData;
  8596. // A lot of Chrome builds don't have depthNear and depthFar, even
  8597. // though they're in the WebVR 1.0 spec. Patch them in if they're not present.
  8598. if(!('depthNear' in window.VRDisplay.prototype)) {
  8599. window.VRDisplay.prototype.depthNear = 0.01;
  8600. }
  8601. if(!('depthFar' in window.VRDisplay.prototype)) {
  8602. window.VRDisplay.prototype.depthFar = 10000.0;
  8603. }
  8604. window.VRDisplay.prototype.getFrameData = function(frameData) {
  8605. return Util.frameDataFromPose(frameData, this.getPose(), this);
  8606. }
  8607. }
  8608. };
  8609. WebVRPolyfill.InstallWebVRSpecShim = InstallWebVRSpecShim;
  8610. WebVRPolyfill.version = version;
  8611. module.exports.WebVRPolyfill = WebVRPolyfill;
  8612. },{"../package.json":8,"./base.js":9,"./cardboard-vr-display.js":12,"./display-wrappers.js":15,"./mouse-keyboard-vr-display.js":21,"./util.js":29}],33:[function(_dereq_,module,exports){
  8613. /*
  8614. * Copyright 2016 Google Inc. All Rights Reserved.
  8615. * Licensed under the Apache License, Version 2.0 (the "License");
  8616. * you may not use this file except in compliance with the License.
  8617. * You may obtain a copy of the License at
  8618. *
  8619. * http://www.apache.org/licenses/LICENSE-2.0
  8620. *
  8621. * Unless required by applicable law or agreed to in writing, software
  8622. * distributed under the License is distributed on an "AS IS" BASIS,
  8623. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  8624. * See the License for the specific language governing permissions and
  8625. * limitations under the License.
  8626. */
  8627. var EventEmitter = _dereq_('eventemitter3');
  8628. var shaka = _dereq_('shaka-player');
  8629. var Types = _dereq_('../video-type');
  8630. var Util = _dereq_('../util');
  8631. var DEFAULT_BITS_PER_SECOND = 1000000;
  8632. /**
  8633. * Supports regular video URLs (eg. mp4), as well as adaptive manifests like
  8634. * DASH (.mpd) and soon HLS (.m3u8).
  8635. *
  8636. * Events:
  8637. * load(video): When the video is loaded.
  8638. * error(message): If an error occurs.
  8639. *
  8640. * To play/pause/seek/etc, please use the underlying video element.
  8641. */
  8642. function AdaptivePlayer(params) {
  8643. this.video = document.createElement('video');
  8644. // Loop by default.
  8645. if (params.loop === true) {
  8646. this.video.setAttribute('loop', true);
  8647. }
  8648. if (params.volume !== undefined) {
  8649. // XXX: .setAttribute('volume', params.volume) doesn't work for some reason.
  8650. this.video.volume = params.volume;
  8651. }
  8652. // Not muted by default.
  8653. if (params.muted === true) {
  8654. this.video.muted = params.muted;
  8655. }
  8656. // For FF, make sure we enable preload.
  8657. this.video.setAttribute('preload', 'auto');
  8658. // Enable inline video playback in iOS 10+.
  8659. this.video.setAttribute('playsinline', true);
  8660. this.video.setAttribute('crossorigin', 'anonymous');
  8661. }
  8662. AdaptivePlayer.prototype = new EventEmitter();
  8663. AdaptivePlayer.prototype.load = function(url) {
  8664. var self = this;
  8665. // TODO(smus): Investigate whether or not differentiation is best done by
  8666. // mimeType after all. Cursory research suggests that adaptive streaming
  8667. // manifest mime types aren't properly supported.
  8668. //
  8669. // For now, make determination based on extension.
  8670. var extension = Util.getExtension(url);
  8671. switch (extension) {
  8672. case 'm3u8': // HLS
  8673. this.type = Types.HLS;
  8674. if (Util.isSafari()) {
  8675. this.loadVideo_(url).then(function() {
  8676. self.emit('load', self.video, self.type);
  8677. }).catch(this.onError_.bind(this));
  8678. } else {
  8679. self.onError_('HLS is only supported on Safari.');
  8680. }
  8681. break;
  8682. case 'mpd': // MPEG-DASH
  8683. this.type = Types.DASH;
  8684. this.loadShakaVideo_(url).then(function() {
  8685. console.log('The video has now been loaded!');
  8686. self.emit('load', self.video, self.type);
  8687. }).catch(this.onError_.bind(this));
  8688. break;
  8689. default: // A regular video, not an adaptive manifest.
  8690. this.type = Types.VIDEO;
  8691. this.loadVideo_(url).then(function() {
  8692. self.emit('load', self.video, self.type);
  8693. }).catch(this.onError_.bind(this));
  8694. break;
  8695. }
  8696. };
  8697. AdaptivePlayer.prototype.destroy = function() {
  8698. this.video.pause();
  8699. this.video.src = '';
  8700. this.video = null;
  8701. };
  8702. /*** PRIVATE API ***/
  8703. AdaptivePlayer.prototype.onError_ = function(e) {
  8704. console.error(e);
  8705. this.emit('error', e);
  8706. };
  8707. AdaptivePlayer.prototype.loadVideo_ = function(url) {
  8708. var self = this, video = self.video;
  8709. return new Promise(function(resolve, reject) {
  8710. video.src = url;
  8711. video.addEventListener('canplaythrough', resolve);
  8712. video.addEventListener('loadedmetadata', function() {
  8713. self.emit('timeupdate', {
  8714. currentTime: video.currentTime,
  8715. duration: video.duration
  8716. });
  8717. });
  8718. video.addEventListener('error', reject);
  8719. video.load();
  8720. });
  8721. };
  8722. AdaptivePlayer.prototype.initShaka_ = function() {
  8723. this.player = new shaka.Player(this.video);
  8724. this.player.configure({
  8725. abr: { defaultBandwidthEstimate: DEFAULT_BITS_PER_SECOND }
  8726. });
  8727. // Listen for error events.
  8728. this.player.addEventListener('error', this.onError_);
  8729. };
  8730. AdaptivePlayer.prototype.loadShakaVideo_ = function(url) {
  8731. // Install built-in polyfills to patch browser incompatibilities.
  8732. shaka.polyfill.installAll();
  8733. if (!shaka.Player.isBrowserSupported()) {
  8734. console.error('Shaka is not supported on this browser.');
  8735. return;
  8736. }
  8737. this.initShaka_();
  8738. return this.player.load(url);
  8739. };
  8740. module.exports = AdaptivePlayer;
  8741. },{"../util":45,"../video-type":46,"eventemitter3":3,"shaka-player":5}],34:[function(_dereq_,module,exports){
  8742. /*
  8743. * Copyright 2016 Google Inc. All Rights Reserved.
  8744. * Licensed under the Apache License, Version 2.0 (the "License");
  8745. * you may not use this file except in compliance with the License.
  8746. * You may obtain a copy of the License at
  8747. *
  8748. * http://www.apache.org/licenses/LICENSE-2.0
  8749. *
  8750. * Unless required by applicable law or agreed to in writing, software
  8751. * distributed under the License is distributed on an "AS IS" BASIS,
  8752. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  8753. * See the License for the specific language governing permissions and
  8754. * limitations under the License.
  8755. */
  8756. var Eyes = {
  8757. LEFT: 1,
  8758. RIGHT: 2
  8759. };
  8760. module.exports = Eyes;
  8761. },{}],35:[function(_dereq_,module,exports){
  8762. /*
  8763. * Copyright 2016 Google Inc. All Rights Reserved.
  8764. * Licensed under the Apache License, Version 2.0 (the "License");
  8765. * you may not use this file except in compliance with the License.
  8766. * You may obtain a copy of the License at
  8767. *
  8768. * http://www.apache.org/licenses/LICENSE-2.0
  8769. *
  8770. * Unless required by applicable law or agreed to in writing, software
  8771. * distributed under the License is distributed on an "AS IS" BASIS,
  8772. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  8773. * See the License for the specific language governing permissions and
  8774. * limitations under the License.
  8775. */
  8776. var EventEmitter = _dereq_('eventemitter3');
  8777. var TWEEN = _dereq_('@tweenjs/tween.js');
  8778. var Util = _dereq_('../util');
  8779. // Constants for the focus/blur animation.
  8780. var NORMAL_SCALE = new THREE.Vector3(1, 1, 1);
  8781. var FOCUS_SCALE = new THREE.Vector3(1.2, 1.2, 1.2);
  8782. var FOCUS_DURATION = 200;
  8783. // Constants for the active/inactive animation.
  8784. var INACTIVE_COLOR = new THREE.Color(1, 1, 1);
  8785. var ACTIVE_COLOR = new THREE.Color(0.8, 0, 0);
  8786. var ACTIVE_DURATION = 100;
  8787. // Constants for opacity.
  8788. var MAX_INNER_OPACITY = 0.8;
  8789. var MAX_OUTER_OPACITY = 0.5;
  8790. var FADE_START_ANGLE_DEG = 35;
  8791. var FADE_END_ANGLE_DEG = 60;
  8792. /**
  8793. * Responsible for rectangular hot spots that the user can interact with.
  8794. *
  8795. * Specific duties:
  8796. * Adding and removing hotspots.
  8797. * Rendering the hotspots (debug mode only).
  8798. * Notifying when hotspots are interacted with.
  8799. *
  8800. * Emits the following events:
  8801. * click (id): a hotspot is clicked.
  8802. * focus (id): a hotspot is focused.
  8803. * blur (id): a hotspot is no longer hovered over.
  8804. */
  8805. function HotspotRenderer(worldRenderer) {
  8806. this.worldRenderer = worldRenderer;
  8807. this.scene = worldRenderer.scene;
  8808. // Note: this event must be added to document.body and not to window for it to
  8809. // work inside iOS iframes.
  8810. var body = document.body;
  8811. // Bind events for hotspot interaction.
  8812. if (!Util.isMobile()) {
  8813. // Only enable mouse events on desktop.
  8814. body.addEventListener('mousedown', this.onMouseDown_.bind(this), false);
  8815. body.addEventListener('mousemove', this.onMouseMove_.bind(this), false);
  8816. body.addEventListener('mouseup', this.onMouseUp_.bind(this), false);
  8817. }
  8818. body.addEventListener('touchstart', this.onTouchStart_.bind(this), false);
  8819. body.addEventListener('touchend', this.onTouchEnd_.bind(this), false);
  8820. // Add a placeholder for hotspots.
  8821. this.hotspotRoot = new THREE.Object3D();
  8822. // Align the center with the center of the camera too.
  8823. this.hotspotRoot.rotation.y = Math.PI / 2;
  8824. this.scene.add(this.hotspotRoot);
  8825. // All hotspot IDs.
  8826. this.hotspots = {};
  8827. // Currently selected hotspots.
  8828. this.selectedHotspots = {};
  8829. // Hotspots that the last touchstart / mousedown event happened for.
  8830. this.downHotspots = {};
  8831. // For raycasting. Initialize mouse to be off screen initially.
  8832. this.pointer = new THREE.Vector2(1, 1);
  8833. this.raycaster = new THREE.Raycaster();
  8834. }
  8835. HotspotRenderer.prototype = new EventEmitter();
  8836. /**
  8837. * @param pitch {Number} The latitude of center, specified in degrees, between
  8838. * -90 and 90, with 0 at the horizon.
  8839. * @param yaw {Number} The longitude of center, specified in degrees, between
  8840. * -180 and 180, with 0 at the image center.
  8841. * @param radius {Number} The radius of the hotspot, specified in meters.
  8842. * @param distance {Number} The distance of the hotspot from camera, specified
  8843. * in meters.
  8844. * @param hotspotId {String} The ID of the hotspot.
  8845. */
  8846. HotspotRenderer.prototype.add = function(pitch, yaw, radius, distance, id) {
  8847. // If a hotspot already exists with this ID, stop.
  8848. if (this.hotspots[id]) {
  8849. // TODO: Proper error reporting.
  8850. console.error('Attempt to add hotspot with existing id %s.', id);
  8851. return;
  8852. }
  8853. var hotspot = this.createHotspot_(radius, distance);
  8854. hotspot.name = id;
  8855. // Position the hotspot based on the pitch and yaw specified.
  8856. var quat = new THREE.Quaternion();
  8857. quat.setFromEuler(new THREE.Euler(THREE.Math.degToRad(pitch), THREE.Math.degToRad(yaw), 0, 'ZYX'));
  8858. hotspot.position.applyQuaternion(quat);
  8859. hotspot.lookAt(new THREE.Vector3());
  8860. this.hotspotRoot.add(hotspot);
  8861. this.hotspots[id] = hotspot;
  8862. }
  8863. /**
  8864. * Removes a hotspot based on the ID.
  8865. *
  8866. * @param ID {String} Identifier of the hotspot to be removed.
  8867. */
  8868. HotspotRenderer.prototype.remove = function(id) {
  8869. // If there's no hotspot with this ID, fail.
  8870. if (!this.hotspots[id]) {
  8871. // TODO: Proper error reporting.
  8872. console.error('Attempt to remove non-existing hotspot with id %s.', id);
  8873. return;
  8874. }
  8875. // Remove the mesh from the scene.
  8876. this.hotspotRoot.remove(this.hotspots[id]);
  8877. // If this hotspot was selected, make sure it gets unselected.
  8878. delete this.selectedHotspots[id];
  8879. delete this.downHotspots[id];
  8880. delete this.hotspots[id];
  8881. this.emit('blur', id);
  8882. };
  8883. /**
  8884. * Clears all hotspots from the pano. Often called when changing panos.
  8885. */
  8886. HotspotRenderer.prototype.clearAll = function() {
  8887. for (var id in this.hotspots) {
  8888. this.remove(id);
  8889. }
  8890. };
  8891. HotspotRenderer.prototype.getCount = function() {
  8892. var count = 0;
  8893. for (var id in this.hotspots) {
  8894. count += 1;
  8895. }
  8896. return count;
  8897. };
  8898. HotspotRenderer.prototype.update = function(camera) {
  8899. if (this.worldRenderer.isVRMode()) {
  8900. this.pointer.set(0, 0);
  8901. }
  8902. // Update the picking ray with the camera and mouse position.
  8903. this.raycaster.setFromCamera(this.pointer, camera);
  8904. // Fade hotspots out if they are really far from center to avoid overly
  8905. // distorted visuals.
  8906. this.fadeOffCenterHotspots_(camera);
  8907. var hotspots = this.hotspotRoot.children;
  8908. // Go through all hotspots to see if they are currently selected.
  8909. for (var i = 0; i < hotspots.length; i++) {
  8910. var hotspot = hotspots[i];
  8911. //hotspot.lookAt(camera.position);
  8912. var id = hotspot.name;
  8913. // Check if hotspot is intersected with the picking ray.
  8914. var intersects = this.raycaster.intersectObjects(hotspot.children);
  8915. var isIntersected = (intersects.length > 0);
  8916. // If newly selected, emit a focus event.
  8917. if (isIntersected && !this.selectedHotspots[id]) {
  8918. this.emit('focus', id);
  8919. this.focus_(id);
  8920. }
  8921. // If no longer selected, emit a blur event.
  8922. if (!isIntersected && this.selectedHotspots[id]) {
  8923. this.emit('blur', id);
  8924. this.blur_(id);
  8925. }
  8926. // Update the set of selected hotspots.
  8927. if (isIntersected) {
  8928. this.selectedHotspots[id] = true;
  8929. } else {
  8930. delete this.selectedHotspots[id];
  8931. }
  8932. }
  8933. };
  8934. /**
  8935. * Toggle whether or not hotspots are visible.
  8936. */
  8937. HotspotRenderer.prototype.setVisibility = function(isVisible) {
  8938. this.hotspotRoot.visible = isVisible;
  8939. };
  8940. HotspotRenderer.prototype.onTouchStart_ = function(e) {
  8941. // In VR mode, don't touch the pointer position.
  8942. if (!this.worldRenderer.isVRMode()) {
  8943. this.updateTouch_(e);
  8944. }
  8945. // Force a camera update to see if any hotspots were selected.
  8946. this.update(this.worldRenderer.camera);
  8947. this.downHotspots = {};
  8948. for (var id in this.selectedHotspots) {
  8949. this.downHotspots[id] = true;
  8950. this.down_(id);
  8951. }
  8952. return false;
  8953. };
  8954. HotspotRenderer.prototype.onTouchEnd_ = function(e) {
  8955. // If no hotspots are pressed, emit an empty click event.
  8956. if (Util.isEmptyObject(this.downHotspots)) {
  8957. this.emit('click');
  8958. return;
  8959. }
  8960. // Only emit a click if the finger was down on the same hotspot before.
  8961. for (var id in this.downHotspots) {
  8962. this.emit('click', id);
  8963. this.up_(id);
  8964. e.preventDefault();
  8965. }
  8966. };
  8967. HotspotRenderer.prototype.updateTouch_ = function(e) {
  8968. var size = this.getSize_();
  8969. var touch = e.touches[0];
  8970. this.pointer.x = (touch.clientX / size.width) * 2 - 1;
  8971. this.pointer.y = - (touch.clientY / size.height) * 2 + 1;
  8972. };
  8973. HotspotRenderer.prototype.onMouseDown_ = function(e) {
  8974. this.updateMouse_(e);
  8975. this.downHotspots = {};
  8976. for (var id in this.selectedHotspots) {
  8977. this.downHotspots[id] = true;
  8978. this.down_(id);
  8979. }
  8980. };
  8981. HotspotRenderer.prototype.onMouseMove_ = function(e) {
  8982. this.updateMouse_(e);
  8983. };
  8984. HotspotRenderer.prototype.onMouseUp_ = function(e) {
  8985. this.updateMouse_(e);
  8986. // If no hotspots are pressed, emit an empty click event.
  8987. if (Util.isEmptyObject(this.downHotspots)) {
  8988. this.emit('click');
  8989. return;
  8990. }
  8991. // Only emit a click if the mouse was down on the same hotspot before.
  8992. for (var id in this.selectedHotspots) {
  8993. if (id in this.downHotspots) {
  8994. this.emit('click', id);
  8995. this.up_(id);
  8996. }
  8997. }
  8998. };
  8999. HotspotRenderer.prototype.updateMouse_ = function(e) {
  9000. var size = this.getSize_();
  9001. this.pointer.x = (e.clientX / size.width) * 2 - 1;
  9002. this.pointer.y = - (e.clientY / size.height) * 2 + 1;
  9003. };
  9004. HotspotRenderer.prototype.getSize_ = function() {
  9005. var canvas = this.worldRenderer.renderer.domElement;
  9006. return this.worldRenderer.renderer.getSize();
  9007. };
  9008. HotspotRenderer.prototype.createHotspot_ = function(radius, distance) {
  9009. var innerGeometry = new THREE.CircleGeometry(radius, 32);
  9010. var innerMaterial = new THREE.MeshBasicMaterial({
  9011. color: 0xffffff, side: THREE.DoubleSide, transparent: true,
  9012. opacity: MAX_INNER_OPACITY, depthTest: false
  9013. });
  9014. var inner = new THREE.Mesh(innerGeometry, innerMaterial);
  9015. inner.name = 'inner';
  9016. var outerMaterial = new THREE.MeshBasicMaterial({
  9017. color: 0xffffff, side: THREE.DoubleSide, transparent: true,
  9018. opacity: MAX_OUTER_OPACITY, depthTest: false
  9019. });
  9020. var outerGeometry = new THREE.RingGeometry(radius * 0.85, radius, 32);
  9021. var outer = new THREE.Mesh(outerGeometry, outerMaterial);
  9022. outer.name = 'outer';
  9023. // Position at the extreme end of the sphere.
  9024. var hotspot = new THREE.Object3D();
  9025. hotspot.position.z = -distance;
  9026. hotspot.scale.copy(NORMAL_SCALE);
  9027. hotspot.add(inner);
  9028. hotspot.add(outer);
  9029. return hotspot;
  9030. };
  9031. /**
  9032. * Large aspect ratios tend to cause visually jarring distortions on the sides.
  9033. * Here we fade hotspots out to avoid them.
  9034. */
  9035. HotspotRenderer.prototype.fadeOffCenterHotspots_ = function(camera) {
  9036. var lookAt = new THREE.Vector3(1, 0, 0);
  9037. lookAt.applyQuaternion(camera.quaternion);
  9038. // Take into account the camera parent too.
  9039. lookAt.applyQuaternion(camera.parent.quaternion);
  9040. // Go through each hotspot. Calculate how far off center it is.
  9041. for (var id in this.hotspots) {
  9042. var hotspot = this.hotspots[id];
  9043. var angle = hotspot.position.angleTo(lookAt);
  9044. var angleDeg = THREE.Math.radToDeg(angle);
  9045. var isVisible = angleDeg < 45;
  9046. var opacity;
  9047. if (angleDeg < FADE_START_ANGLE_DEG) {
  9048. opacity = 1;
  9049. } else if (angleDeg > FADE_END_ANGLE_DEG) {
  9050. opacity = 0;
  9051. } else {
  9052. // We are in the case START < angle < END. Linearly interpolate.
  9053. var range = FADE_END_ANGLE_DEG - FADE_START_ANGLE_DEG;
  9054. var value = FADE_END_ANGLE_DEG - angleDeg;
  9055. opacity = value / range;
  9056. }
  9057. // Opacity a function of angle. If angle is large, opacity is zero. At some
  9058. // point, ramp opacity down.
  9059. this.setOpacity_(id, opacity);
  9060. }
  9061. };
  9062. HotspotRenderer.prototype.focus_ = function(id) {
  9063. var hotspot = this.hotspots[id];
  9064. // Tween scale of hotspot.
  9065. this.tween = new TWEEN.Tween(hotspot.scale).to(FOCUS_SCALE, FOCUS_DURATION)
  9066. .easing(TWEEN.Easing.Quadratic.InOut)
  9067. .start();
  9068. if (this.worldRenderer.isVRMode()) {
  9069. this.timeForHospotClick = setTimeout(function () {
  9070. this.emit('click', id);
  9071. }, 1200 )
  9072. }
  9073. };
  9074. HotspotRenderer.prototype.blur_ = function(id) {
  9075. var hotspot = this.hotspots[id];
  9076. this.tween = new TWEEN.Tween(hotspot.scale).to(NORMAL_SCALE, FOCUS_DURATION)
  9077. .easing(TWEEN.Easing.Quadratic.InOut)
  9078. .start();
  9079. if (this.timeForHospotClick) {
  9080. clearTimeout( this.timeForHospotClick );
  9081. }
  9082. };
  9083. HotspotRenderer.prototype.down_ = function(id) {
  9084. // Become active.
  9085. var hotspot = this.hotspots[id];
  9086. var outer = hotspot.getObjectByName('inner');
  9087. this.tween = new TWEEN.Tween(outer.material.color).to(ACTIVE_COLOR, ACTIVE_DURATION)
  9088. .start();
  9089. };
  9090. HotspotRenderer.prototype.up_ = function(id) {
  9091. // Become inactive.
  9092. var hotspot = this.hotspots[id];
  9093. var outer = hotspot.getObjectByName('inner');
  9094. this.tween = new TWEEN.Tween(outer.material.color).to(INACTIVE_COLOR, ACTIVE_DURATION)
  9095. .start();
  9096. };
  9097. HotspotRenderer.prototype.setOpacity_ = function(id, opacity) {
  9098. var hotspot = this.hotspots[id];
  9099. var outer = hotspot.getObjectByName('outer');
  9100. var inner = hotspot.getObjectByName('inner');
  9101. outer.material.opacity = opacity * MAX_OUTER_OPACITY;
  9102. inner.material.opacity = opacity * MAX_INNER_OPACITY;
  9103. };
  9104. module.exports = HotspotRenderer;
  9105. },{"../util":45,"@tweenjs/tween.js":1,"eventemitter3":3}],36:[function(_dereq_,module,exports){
  9106. /*
  9107. * Copyright 2016 Google Inc. All Rights Reserved.
  9108. * Licensed under the Apache License, Version 2.0 (the "License");
  9109. * you may not use this file except in compliance with the License.
  9110. * You may obtain a copy of the License at
  9111. *
  9112. * http://www.apache.org/licenses/LICENSE-2.0
  9113. *
  9114. * Unless required by applicable law or agreed to in writing, software
  9115. * distributed under the License is distributed on an "AS IS" BASIS,
  9116. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9117. * See the License for the specific language governing permissions and
  9118. * limitations under the License.
  9119. */
  9120. var EventEmitter = _dereq_('eventemitter3');
  9121. var Message = _dereq_('../message');
  9122. var Util = _dereq_('../util');
  9123. /**
  9124. * Sits in an embedded iframe, receiving messages from a containing
  9125. * iFrame. This facilitates an API which provides the following features:
  9126. *
  9127. * Playing and pausing content.
  9128. * Adding hotspots.
  9129. * Sending messages back to the containing iframe when hotspot is clicked
  9130. * Sending analytics events to containing iframe.
  9131. *
  9132. * Note: this script used to also respond to synthetic devicemotion events, but
  9133. * no longer does so. This is because as of iOS 9.2, Safari disallows listening
  9134. * for devicemotion events within cross-device iframes. To work around this, the
  9135. * webvr-polyfill responds to the postMessage event containing devicemotion
  9136. * information (sent by the iframe-message-sender in the VR View API).
  9137. */
  9138. function IFrameMessageReceiver() {
  9139. window.addEventListener('message', this.onMessage_.bind(this), false);
  9140. }
  9141. IFrameMessageReceiver.prototype = new EventEmitter();
  9142. IFrameMessageReceiver.prototype.onMessage_ = function(event) {
  9143. if (Util.isDebug()) {
  9144. console.log('onMessage_', event);
  9145. }
  9146. var message = event.data;
  9147. var type = message.type.toLowerCase();
  9148. var data = message.data;
  9149. switch (type) {
  9150. case Message.SET_CONTENT:
  9151. case Message.SET_VOLUME:
  9152. case Message.MUTED:
  9153. case Message.ADD_HOTSPOT:
  9154. case Message.PLAY:
  9155. case Message.PAUSE:
  9156. case Message.SET_CURRENT_TIME:
  9157. case Message.GET_POSITION:
  9158. case Message.SET_FULLSCREEN:
  9159. this.emit(type, data);
  9160. break;
  9161. default:
  9162. if (Util.isDebug()) {
  9163. console.warn('Got unknown message of type %s from %s', message.type, message.origin);
  9164. }
  9165. }
  9166. };
  9167. module.exports = IFrameMessageReceiver;
  9168. },{"../message":44,"../util":45,"eventemitter3":3}],37:[function(_dereq_,module,exports){
  9169. /*
  9170. * Copyright 2016 Google Inc. All Rights Reserved.
  9171. * Licensed under the Apache License, Version 2.0 (the "License");
  9172. * you may not use this file except in compliance with the License.
  9173. * You may obtain a copy of the License at
  9174. *
  9175. * http://www.apache.org/licenses/LICENSE-2.0
  9176. *
  9177. * Unless required by applicable law or agreed to in writing, software
  9178. * distributed under the License is distributed on an "AS IS" BASIS,
  9179. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9180. * See the License for the specific language governing permissions and
  9181. * limitations under the License.
  9182. */
  9183. /**
  9184. * Shows a 2D loading indicator while various pieces of EmbedVR load.
  9185. */
  9186. function LoadingIndicator() {
  9187. this.el = this.build_();
  9188. document.body.appendChild(this.el);
  9189. this.show();
  9190. }
  9191. LoadingIndicator.prototype.build_ = function() {
  9192. var overlay = document.createElement('div');
  9193. var s = overlay.style;
  9194. s.position = 'fixed';
  9195. s.top = 0;
  9196. s.left = 0;
  9197. s.width = '100%';
  9198. s.height = '100%';
  9199. s.background = '#eee';
  9200. var img = document.createElement('img');
  9201. img.src = 'images/loading.gif';
  9202. var s = img.style;
  9203. s.position = 'absolute';
  9204. s.top = '50%';
  9205. s.left = '50%';
  9206. s.transform = 'translate(-50%, -50%)';
  9207. overlay.appendChild(img);
  9208. return overlay;
  9209. };
  9210. LoadingIndicator.prototype.hide = function() {
  9211. this.el.style.display = 'none';
  9212. };
  9213. LoadingIndicator.prototype.show = function() {
  9214. this.el.style.display = 'block';
  9215. };
  9216. module.exports = LoadingIndicator;
  9217. },{}],38:[function(_dereq_,module,exports){
  9218. /*
  9219. * Copyright 2016 Google Inc. All Rights Reserved.
  9220. * Licensed under the Apache License, Version 2.0 (the "License");
  9221. * you may not use this file except in compliance with the License.
  9222. * You may obtain a copy of the License at
  9223. *
  9224. * http://www.apache.org/licenses/LICENSE-2.0
  9225. *
  9226. * Unless required by applicable law or agreed to in writing, software
  9227. * distributed under the License is distributed on an "AS IS" BASIS,
  9228. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9229. * See the License for the specific language governing permissions and
  9230. * limitations under the License.
  9231. */
  9232. // Initialize the loading indicator as quickly as possible to give the user
  9233. // immediate feedback.
  9234. var LoadingIndicator = _dereq_('./loading-indicator');
  9235. var loadIndicator = new LoadingIndicator();
  9236. var ES6Promise = _dereq_('es6-promise');
  9237. // Polyfill ES6 promises for IE.
  9238. ES6Promise.polyfill();
  9239. var IFrameMessageReceiver = _dereq_('./iframe-message-receiver');
  9240. var Message = _dereq_('../message');
  9241. var SceneInfo = _dereq_('./scene-info');
  9242. var Stats = _dereq_('../../node_modules/stats-js/build/stats.min');
  9243. var Util = _dereq_('../util');
  9244. var WebVRPolyfill = _dereq_('webvr-polyfill');
  9245. var WorldRenderer = _dereq_('./world-renderer');
  9246. var receiver = new IFrameMessageReceiver();
  9247. receiver.on(Message.PLAY, onPlayRequest);
  9248. receiver.on(Message.PAUSE, onPauseRequest);
  9249. receiver.on(Message.ADD_HOTSPOT, onAddHotspot);
  9250. receiver.on(Message.SET_CONTENT, onSetContent);
  9251. receiver.on(Message.SET_VOLUME, onSetVolume);
  9252. receiver.on(Message.MUTED, onMuted);
  9253. receiver.on(Message.SET_CURRENT_TIME, onUpdateCurrentTime);
  9254. receiver.on(Message.GET_POSITION, onGetPosition);
  9255. receiver.on(Message.SET_FULLSCREEN, onSetFullscreen);
  9256. window.addEventListener('load', onLoad);
  9257. var stats = new Stats();
  9258. var scene = SceneInfo.loadFromGetParams();
  9259. var worldRenderer = new WorldRenderer(scene);
  9260. worldRenderer.on('error', onRenderError);
  9261. worldRenderer.on('load', onRenderLoad);
  9262. worldRenderer.on('modechange', onModeChange);
  9263. worldRenderer.on('ended', onEnded);
  9264. worldRenderer.on('play', onPlay);
  9265. worldRenderer.hotspotRenderer.on('click', onHotspotClick);
  9266. window.worldRenderer = worldRenderer;
  9267. var isReadySent = false;
  9268. var volume = 0;
  9269. function onLoad() {
  9270. if (!Util.isWebGLEnabled()) {
  9271. showError('WebGL not supported.');
  9272. return;
  9273. }
  9274. // Load the scene.
  9275. worldRenderer.setScene(scene);
  9276. if (scene.isDebug) {
  9277. // Show stats.
  9278. showStats();
  9279. }
  9280. if (scene.isYawOnly) {
  9281. WebVRConfig = window.WebVRConfig || {};
  9282. WebVRConfig.YAW_ONLY = true;
  9283. }
  9284. requestAnimationFrame(loop);
  9285. }
  9286. function onVideoTap() {
  9287. worldRenderer.videoProxy.play();
  9288. hidePlayButton();
  9289. // Prevent multiple play() calls on the video element.
  9290. document.body.removeEventListener('touchend', onVideoTap);
  9291. }
  9292. function onRenderLoad(event) {
  9293. if (event.videoElement) {
  9294. var scene = SceneInfo.loadFromGetParams();
  9295. // On mobile, tell the user they need to tap to start. Otherwise, autoplay.
  9296. if (Util.isMobile()) {
  9297. // Tell user to tap to start.
  9298. showPlayButton();
  9299. document.body.addEventListener('touchend', onVideoTap);
  9300. } else {
  9301. event.videoElement.play();
  9302. }
  9303. // Attach to pause and play events, to notify the API.
  9304. event.videoElement.addEventListener('pause', onPause);
  9305. event.videoElement.addEventListener('play', onPlay);
  9306. event.videoElement.addEventListener('timeupdate', onGetCurrentTime);
  9307. event.videoElement.addEventListener('ended', onEnded);
  9308. }
  9309. // Hide loading indicator.
  9310. loadIndicator.hide();
  9311. // Autopan only on desktop, for photos only, and only if autopan is enabled.
  9312. if (!Util.isMobile() && !worldRenderer.sceneInfo.video && !worldRenderer.sceneInfo.isAutopanOff) {
  9313. worldRenderer.autopan();
  9314. }
  9315. // Notify the API that we are ready, but only do this once.
  9316. if (!isReadySent) {
  9317. if (event.videoElement) {
  9318. Util.sendParentMessage({
  9319. type: 'ready',
  9320. data: {
  9321. duration: event.videoElement.duration
  9322. }
  9323. });
  9324. } else {
  9325. Util.sendParentMessage({
  9326. type: 'ready'
  9327. });
  9328. }
  9329. isReadySent = true;
  9330. }
  9331. }
  9332. function onPlayRequest() {
  9333. if (!worldRenderer.videoProxy) {
  9334. onApiError('Attempt to pause, but no video found.');
  9335. return;
  9336. }
  9337. worldRenderer.videoProxy.play();
  9338. }
  9339. function onPauseRequest() {
  9340. if (!worldRenderer.videoProxy) {
  9341. onApiError('Attempt to pause, but no video found.');
  9342. return;
  9343. }
  9344. worldRenderer.videoProxy.pause();
  9345. }
  9346. function onAddHotspot(e) {
  9347. if (Util.isDebug()) {
  9348. console.log('onAddHotspot', e);
  9349. }
  9350. // TODO: Implement some validation?
  9351. var pitch = parseFloat(e.pitch);
  9352. var yaw = parseFloat(e.yaw);
  9353. var radius = parseFloat(e.radius);
  9354. var distance = parseFloat(e.distance);
  9355. var id = e.id;
  9356. worldRenderer.hotspotRenderer.add(pitch, yaw, radius, distance, id);
  9357. }
  9358. function onSetContent(e) {
  9359. if (Util.isDebug()) {
  9360. console.log('onSetContent', e);
  9361. }
  9362. // Remove all of the hotspots.
  9363. worldRenderer.hotspotRenderer.clearAll();
  9364. // Fade to black.
  9365. worldRenderer.sphereRenderer.setOpacity(0, 500).then(function() {
  9366. // Then load the new scene.
  9367. var scene = SceneInfo.loadFromAPIParams(e.contentInfo);
  9368. worldRenderer.destroy();
  9369. // Update the URL to reflect the new scene. This is important particularily
  9370. // on iOS where we use a fake fullscreen mode.
  9371. var url = scene.getCurrentUrl();
  9372. //console.log('Updating url to be %s', url);
  9373. window.history.pushState(null, 'VR View', url);
  9374. // And set the new scene.
  9375. return worldRenderer.setScene(scene);
  9376. }).then(function() {
  9377. // Then fade the scene back in.
  9378. worldRenderer.sphereRenderer.setOpacity(1, 500);
  9379. });
  9380. }
  9381. function onSetVolume(e) {
  9382. // Only work for video. If there's no video, send back an error.
  9383. if (!worldRenderer.videoProxy) {
  9384. onApiError('Attempt to set volume, but no video found.');
  9385. return;
  9386. }
  9387. worldRenderer.videoProxy.setVolume(e.volumeLevel);
  9388. volume = e.volumeLevel;
  9389. Util.sendParentMessage({
  9390. type: 'volumechange',
  9391. data: e.volumeLevel
  9392. });
  9393. }
  9394. function onMuted(e) {
  9395. // Only work for video. If there's no video, send back an error.
  9396. if (!worldRenderer.videoProxy) {
  9397. onApiError('Attempt to mute, but no video found.');
  9398. return;
  9399. }
  9400. worldRenderer.videoProxy.mute(e.muteState);
  9401. Util.sendParentMessage({
  9402. type: 'muted',
  9403. data: e.muteState
  9404. });
  9405. }
  9406. function onUpdateCurrentTime(time) {
  9407. if (!worldRenderer.videoProxy) {
  9408. onApiError('Attempt to pause, but no video found.');
  9409. return;
  9410. }
  9411. worldRenderer.videoProxy.setCurrentTime(time);
  9412. onGetCurrentTime();
  9413. }
  9414. function onGetCurrentTime() {
  9415. var time = worldRenderer.videoProxy.getCurrentTime();
  9416. Util.sendParentMessage({
  9417. type: 'timeupdate',
  9418. data: time
  9419. });
  9420. }
  9421. function onSetFullscreen() {
  9422. if (!worldRenderer.videoProxy) {
  9423. onApiError('Attempt to set fullscreen, but no video found.');
  9424. return;
  9425. }
  9426. worldRenderer.manager.onFSClick_();
  9427. }
  9428. function onApiError(message) {
  9429. console.error(message);
  9430. Util.sendParentMessage({
  9431. type: 'error',
  9432. data: {message: message}
  9433. });
  9434. }
  9435. function onModeChange(mode) {
  9436. Util.sendParentMessage({
  9437. type: 'modechange',
  9438. data: {mode: mode}
  9439. });
  9440. }
  9441. function onHotspotClick(id) {
  9442. Util.sendParentMessage({
  9443. type: 'click',
  9444. data: {id: id}
  9445. });
  9446. }
  9447. function onPlay() {
  9448. Util.sendParentMessage({
  9449. type: 'paused',
  9450. data: false
  9451. });
  9452. }
  9453. function onPause() {
  9454. Util.sendParentMessage({
  9455. type: 'paused',
  9456. data: true
  9457. });
  9458. }
  9459. function onEnded() {
  9460. Util.sendParentMessage({
  9461. type: 'ended',
  9462. data: true
  9463. });
  9464. }
  9465. function onSceneError(message) {
  9466. showError('Loader: ' + message);
  9467. }
  9468. function onRenderError(message) {
  9469. showError('Render: ' + message);
  9470. }
  9471. function showError(message) {
  9472. // Hide loading indicator.
  9473. loadIndicator.hide();
  9474. // Sanitize `message` as it could contain user supplied
  9475. // values. Re-add the space character as to not modify the
  9476. // error messages used throughout the codebase.
  9477. message = encodeURI(message).replace(/%20/g, ' ');
  9478. var error = document.querySelector('#error');
  9479. error.classList.add('visible');
  9480. error.querySelector('.message').innerHTML = message;
  9481. error.querySelector('.title').innerHTML = 'Error';
  9482. }
  9483. function hideError() {
  9484. var error = document.querySelector('#error');
  9485. error.classList.remove('visible');
  9486. }
  9487. function showPlayButton() {
  9488. var playButton = document.querySelector('#play-overlay');
  9489. playButton.classList.add('visible');
  9490. }
  9491. function hidePlayButton() {
  9492. var playButton = document.querySelector('#play-overlay');
  9493. playButton.classList.remove('visible');
  9494. }
  9495. function showStats() {
  9496. stats.setMode(0); // 0: fps, 1: ms
  9497. // Align bottom-left.
  9498. stats.domElement.style.position = 'absolute';
  9499. stats.domElement.style.left = '0px';
  9500. stats.domElement.style.bottom = '0px';
  9501. document.body.appendChild(stats.domElement);
  9502. }
  9503. function loop(time) {
  9504. // Use the VRDisplay RAF if it is present.
  9505. if (worldRenderer.vrDisplay) {
  9506. worldRenderer.vrDisplay.requestAnimationFrame(loop);
  9507. } else {
  9508. requestAnimationFrame(loop);
  9509. }
  9510. stats.begin();
  9511. // Update the video if needed.
  9512. if (worldRenderer.videoProxy) {
  9513. worldRenderer.videoProxy.update(time);
  9514. }
  9515. worldRenderer.render(time);
  9516. worldRenderer.submitFrame();
  9517. stats.end();
  9518. }
  9519. function onGetPosition() {
  9520. Util.sendParentMessage({
  9521. type: 'getposition',
  9522. data: {
  9523. Yaw: worldRenderer.camera.rotation.y * 180 / Math.PI,
  9524. Pitch: worldRenderer.camera.rotation.x * 180 / Math.PI
  9525. }
  9526. });
  9527. }
  9528. },{"../../node_modules/stats-js/build/stats.min":6,"../message":44,"../util":45,"./iframe-message-receiver":36,"./loading-indicator":37,"./scene-info":40,"./world-renderer":43,"es6-promise":2,"webvr-polyfill":22}],39:[function(_dereq_,module,exports){
  9529. /*
  9530. * Copyright 2016 Google Inc. All Rights Reserved.
  9531. * Licensed under the Apache License, Version 2.0 (the "License");
  9532. * you may not use this file except in compliance with the License.
  9533. * You may obtain a copy of the License at
  9534. *
  9535. * http://www.apache.org/licenses/LICENSE-2.0
  9536. *
  9537. * Unless required by applicable law or agreed to in writing, software
  9538. * distributed under the License is distributed on an "AS IS" BASIS,
  9539. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9540. * See the License for the specific language governing permissions and
  9541. * limitations under the License.
  9542. */
  9543. function ReticleRenderer(camera) {
  9544. this.camera = camera;
  9545. this.reticle = this.createReticle_();
  9546. // In front of the hotspot itself, which is at r=0.99.
  9547. this.reticle.position.z = -0.97;
  9548. camera.add(this.reticle);
  9549. this.setVisibility(false);
  9550. }
  9551. ReticleRenderer.prototype.setVisibility = function(isVisible) {
  9552. // TODO: Tween the transition.
  9553. this.reticle.visible = isVisible;
  9554. };
  9555. ReticleRenderer.prototype.createReticle_ = function() {
  9556. // Make a torus.
  9557. var geometry = new THREE.TorusGeometry(0.02, 0.005, 10, 20);
  9558. var material = new THREE.MeshBasicMaterial({color: 0x000000});
  9559. var torus = new THREE.Mesh(geometry, material);
  9560. return torus;
  9561. };
  9562. module.exports = ReticleRenderer;
  9563. },{}],40:[function(_dereq_,module,exports){
  9564. /*
  9565. * Copyright 2016 Google Inc. All Rights Reserved.
  9566. * Licensed under the Apache License, Version 2.0 (the "License");
  9567. * you may not use this file except in compliance with the License.
  9568. * You may obtain a copy of the License at
  9569. *
  9570. * http://www.apache.org/licenses/LICENSE-2.0
  9571. *
  9572. * Unless required by applicable law or agreed to in writing, software
  9573. * distributed under the License is distributed on an "AS IS" BASIS,
  9574. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9575. * See the License for the specific language governing permissions and
  9576. * limitations under the License.
  9577. */
  9578. var Util = _dereq_('../util');
  9579. var CAMEL_TO_UNDERSCORE = {
  9580. video: 'video',
  9581. image: 'image',
  9582. preview: 'preview',
  9583. loop: 'loop',
  9584. volume: 'volume',
  9585. muted: 'muted',
  9586. isStereo: 'is_stereo',
  9587. defaultYaw: 'default_yaw',
  9588. isYawOnly: 'is_yaw_only',
  9589. isDebug: 'is_debug',
  9590. isVROff: 'is_vr_off',
  9591. isAutopanOff: 'is_autopan_off',
  9592. hideFullscreenButton: 'hide_fullscreen_button'
  9593. };
  9594. /**
  9595. * Contains all information about a given scene.
  9596. */
  9597. function SceneInfo(opt_params) {
  9598. var params = opt_params || {};
  9599. params.player = {
  9600. loop: opt_params.loop,
  9601. volume: opt_params.volume,
  9602. muted: opt_params.muted
  9603. };
  9604. this.image = params.image !== undefined ? encodeURI(params.image) : undefined;
  9605. this.preview = params.preview !== undefined ? encodeURI(params.preview) : undefined;
  9606. this.video = params.video !== undefined ? encodeURI(params.video) : undefined;
  9607. this.defaultYaw = THREE.Math.degToRad(params.defaultYaw || 0);
  9608. this.isStereo = Util.parseBoolean(params.isStereo);
  9609. this.isYawOnly = Util.parseBoolean(params.isYawOnly);
  9610. this.isDebug = Util.parseBoolean(params.isDebug);
  9611. this.isVROff = Util.parseBoolean(params.isVROff);
  9612. this.isAutopanOff = Util.parseBoolean(params.isAutopanOff);
  9613. this.loop = Util.parseBoolean(params.player.loop);
  9614. this.volume = parseFloat(
  9615. params.player.volume ? params.player.volume : '1');
  9616. this.muted = Util.parseBoolean(params.player.muted);
  9617. this.hideFullscreenButton = Util.parseBoolean(params.hideFullscreenButton);
  9618. }
  9619. SceneInfo.loadFromGetParams = function() {
  9620. var params = {};
  9621. for (var camelCase in CAMEL_TO_UNDERSCORE) {
  9622. var underscore = CAMEL_TO_UNDERSCORE[camelCase];
  9623. params[camelCase] = Util.getQueryParameter(underscore)
  9624. || ((window.WebVRConfig && window.WebVRConfig.PLAYER) ? window.WebVRConfig.PLAYER[underscore] : "");
  9625. }
  9626. var scene = new SceneInfo(params);
  9627. if (!scene.isValid()) {
  9628. console.warn('Invalid scene: %s', scene.errorMessage);
  9629. }
  9630. return scene;
  9631. };
  9632. SceneInfo.loadFromAPIParams = function(underscoreParams) {
  9633. var params = {};
  9634. for (var camelCase in CAMEL_TO_UNDERSCORE) {
  9635. var underscore = CAMEL_TO_UNDERSCORE[camelCase];
  9636. if (underscoreParams[underscore]) {
  9637. params[camelCase] = underscoreParams[underscore];
  9638. }
  9639. }
  9640. var scene = new SceneInfo(params);
  9641. if (!scene.isValid()) {
  9642. console.warn('Invalid scene: %s', scene.errorMessage);
  9643. }
  9644. return scene;
  9645. };
  9646. SceneInfo.prototype.isValid = function() {
  9647. // Either it's an image or a video.
  9648. if (!this.image && !this.video) {
  9649. this.errorMessage = 'Either image or video URL must be specified.';
  9650. return false;
  9651. }
  9652. if (this.image && !this.isValidImage_(this.image)) {
  9653. this.errorMessage = 'Invalid image URL: ' + this.image;
  9654. return false;
  9655. }
  9656. this.errorMessage = null;
  9657. return true;
  9658. };
  9659. /**
  9660. * Generates a URL to reflect this scene.
  9661. */
  9662. SceneInfo.prototype.getCurrentUrl = function() {
  9663. var url = location.protocol + '//' + location.host + location.pathname + '?';
  9664. for (var camelCase in CAMEL_TO_UNDERSCORE) {
  9665. var underscore = CAMEL_TO_UNDERSCORE[camelCase];
  9666. var value = this[camelCase];
  9667. if (value !== undefined) {
  9668. url += underscore + '=' + value + '&';
  9669. }
  9670. }
  9671. // Chop off the trailing ampersand.
  9672. return url.substring(0, url.length - 1);
  9673. };
  9674. SceneInfo.prototype.isValidImage_ = function(imageUrl) {
  9675. return true;
  9676. };
  9677. module.exports = SceneInfo;
  9678. },{"../util":45}],41:[function(_dereq_,module,exports){
  9679. /*
  9680. * Copyright 2016 Google Inc. All Rights Reserved.
  9681. * Licensed under the Apache License, Version 2.0 (the "License");
  9682. * you may not use this file except in compliance with the License.
  9683. * You may obtain a copy of the License at
  9684. *
  9685. * http://www.apache.org/licenses/LICENSE-2.0
  9686. *
  9687. * Unless required by applicable law or agreed to in writing, software
  9688. * distributed under the License is distributed on an "AS IS" BASIS,
  9689. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9690. * See the License for the specific language governing permissions and
  9691. * limitations under the License.
  9692. */
  9693. var Eyes = _dereq_('./eyes');
  9694. var TWEEN = _dereq_('@tweenjs/tween.js');
  9695. var Util = _dereq_('../util');
  9696. var VideoType = _dereq_('../video-type');
  9697. function SphereRenderer(scene) {
  9698. this.scene = scene;
  9699. // Create a transparent mask.
  9700. this.createOpacityMask_();
  9701. }
  9702. /**
  9703. * Sets the photosphere based on the image in the source. Supports stereo and
  9704. * mono photospheres.
  9705. *
  9706. * @return {Promise}
  9707. */
  9708. SphereRenderer.prototype.setPhotosphere = function(src, opt_params) {
  9709. return new Promise(function(resolve, reject) {
  9710. this.resolve = resolve;
  9711. this.reject = reject;
  9712. var params = opt_params || {};
  9713. this.isStereo = !!params.isStereo;
  9714. this.src = src;
  9715. // Load texture.
  9716. var loader = new THREE.TextureLoader();
  9717. loader.crossOrigin = 'anonymous';
  9718. loader.load(src, this.onTextureLoaded_.bind(this), undefined,
  9719. this.onTextureError_.bind(this));
  9720. }.bind(this));
  9721. };
  9722. /**
  9723. * @return {Promise} Yeah.
  9724. */
  9725. SphereRenderer.prototype.set360Video = function (videoElement, videoType, opt_params) {
  9726. return new Promise(function(resolve, reject) {
  9727. this.resolve = resolve;
  9728. this.reject = reject;
  9729. var params = opt_params || {};
  9730. this.isStereo = !!params.isStereo;
  9731. // Load the video texture.
  9732. var videoTexture = new THREE.VideoTexture(videoElement);
  9733. videoTexture.minFilter = THREE.LinearFilter;
  9734. videoTexture.magFilter = THREE.LinearFilter;
  9735. videoTexture.generateMipmaps = false;
  9736. if (Util.isSafari() && videoType === VideoType.HLS) {
  9737. // fix black screen issue on safari
  9738. videoTexture.format = THREE.RGBAFormat;
  9739. videoTexture.flipY = false;
  9740. } else {
  9741. videoTexture.format = THREE.RGBFormat;
  9742. }
  9743. videoTexture.needsUpdate = true;
  9744. this.onTextureLoaded_(videoTexture);
  9745. }.bind(this));
  9746. };
  9747. /**
  9748. * Set the opacity of the panorama.
  9749. *
  9750. * @param {Number} opacity How opaque we want the panorama to be. 0 means black,
  9751. * 1 means full color.
  9752. * @param {Number} duration Number of milliseconds the transition should take.
  9753. *
  9754. * @return {Promise} When the opacity change is complete.
  9755. */
  9756. SphereRenderer.prototype.setOpacity = function(opacity, duration) {
  9757. var scene = this.scene;
  9758. // If we want the opacity
  9759. var overlayOpacity = 1 - opacity;
  9760. return new Promise(function(resolve, reject) {
  9761. var mask = scene.getObjectByName('opacityMask');
  9762. var tween = new TWEEN.Tween({opacity: mask.material.opacity})
  9763. .to({opacity: overlayOpacity}, duration)
  9764. .easing(TWEEN.Easing.Quadratic.InOut);
  9765. tween.onUpdate(function(e) {
  9766. mask.material.opacity = this.opacity;
  9767. });
  9768. tween.onComplete(resolve).start();
  9769. });
  9770. };
  9771. SphereRenderer.prototype.onTextureLoaded_ = function(texture) {
  9772. var sphereLeft;
  9773. var sphereRight;
  9774. if (this.isStereo) {
  9775. sphereLeft = this.createPhotosphere_(texture, {offsetY: 0.5, scaleY: 0.5});
  9776. sphereRight = this.createPhotosphere_(texture, {offsetY: 0, scaleY: 0.5});
  9777. } else {
  9778. sphereLeft = this.createPhotosphere_(texture);
  9779. sphereRight = this.createPhotosphere_(texture);
  9780. }
  9781. // Display in left and right eye respectively.
  9782. sphereLeft.layers.set(Eyes.LEFT);
  9783. sphereLeft.eye = Eyes.LEFT;
  9784. sphereLeft.name = 'eyeLeft';
  9785. sphereRight.layers.set(Eyes.RIGHT);
  9786. sphereRight.eye = Eyes.RIGHT;
  9787. sphereRight.name = 'eyeRight';
  9788. this.scene.getObjectByName('photo').children = [sphereLeft, sphereRight];
  9789. this.resolve();
  9790. };
  9791. SphereRenderer.prototype.onTextureError_ = function(error) {
  9792. this.reject('Unable to load texture from "' + this.src + '"');
  9793. };
  9794. SphereRenderer.prototype.createPhotosphere_ = function(texture, opt_params) {
  9795. var p = opt_params || {};
  9796. p.scaleX = p.scaleX || 1;
  9797. p.scaleY = p.scaleY || 1;
  9798. p.offsetX = p.offsetX || 0;
  9799. p.offsetY = p.offsetY || 0;
  9800. p.phiStart = p.phiStart || 0;
  9801. p.phiLength = p.phiLength || Math.PI * 2;
  9802. p.thetaStart = p.thetaStart || 0;
  9803. p.thetaLength = p.thetaLength || Math.PI;
  9804. var geometry = new THREE.SphereGeometry(1, 48, 48,
  9805. p.phiStart, p.phiLength, p.thetaStart, p.thetaLength);
  9806. geometry.applyMatrix(new THREE.Matrix4().makeScale(-1, 1, 1));
  9807. var uvs = geometry.faceVertexUvs[0];
  9808. for (var i = 0; i < uvs.length; i ++) {
  9809. for (var j = 0; j < 3; j ++) {
  9810. uvs[i][j].x *= p.scaleX;
  9811. uvs[i][j].x += p.offsetX;
  9812. uvs[i][j].y *= p.scaleY;
  9813. uvs[i][j].y += p.offsetY;
  9814. }
  9815. }
  9816. var material;
  9817. if (texture.format === THREE.RGBAFormat && texture.flipY === false) {
  9818. material = new THREE.ShaderMaterial({
  9819. uniforms: {
  9820. texture: { value: texture }
  9821. },
  9822. vertexShader: [
  9823. "varying vec2 vUV;",
  9824. "void main() {",
  9825. " vUV = vec2( uv.x, 1.0 - uv.y );",
  9826. " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
  9827. "}"
  9828. ].join("\n"),
  9829. fragmentShader: [
  9830. "uniform sampler2D texture;",
  9831. "varying vec2 vUV;",
  9832. "void main() {",
  9833. " gl_FragColor = texture2D( texture, vUV )" + (Util.isIOS() ? ".bgra" : "") + ";",
  9834. "}"
  9835. ].join("\n")
  9836. });
  9837. } else {
  9838. material = new THREE.MeshBasicMaterial({ map: texture });
  9839. }
  9840. var out = new THREE.Mesh(geometry, material);
  9841. //out.visible = false;
  9842. out.renderOrder = -1;
  9843. return out;
  9844. };
  9845. SphereRenderer.prototype.createOpacityMask_ = function() {
  9846. var geometry = new THREE.SphereGeometry(0.49, 48, 48);
  9847. var material = new THREE.MeshBasicMaterial({
  9848. color: 0x000000, side: THREE.DoubleSide, opacity: 0, transparent: true});
  9849. var opacityMask = new THREE.Mesh(geometry, material);
  9850. opacityMask.name = 'opacityMask';
  9851. opacityMask.renderOrder = 1;
  9852. this.scene.add(opacityMask);
  9853. return opacityMask;
  9854. };
  9855. module.exports = SphereRenderer;
  9856. },{"../util":45,"../video-type":46,"./eyes":34,"@tweenjs/tween.js":1}],42:[function(_dereq_,module,exports){
  9857. /*
  9858. * Copyright 2016 Google Inc. All Rights Reserved.
  9859. * Licensed under the Apache License, Version 2.0 (the "License");
  9860. * you may not use this file except in compliance with the License.
  9861. * You may obtain a copy of the License at
  9862. *
  9863. * http://www.apache.org/licenses/LICENSE-2.0
  9864. *
  9865. * Unless required by applicable law or agreed to in writing, software
  9866. * distributed under the License is distributed on an "AS IS" BASIS,
  9867. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9868. * See the License for the specific language governing permissions and
  9869. * limitations under the License.
  9870. */
  9871. var Util = _dereq_('../util');
  9872. /**
  9873. * A proxy class for working around the fact that as soon as a video is play()ed
  9874. * on iOS, Safari auto-fullscreens the video.
  9875. *
  9876. * TODO(smus): The entire raison d'etre for this class is to work around this
  9877. * issue. Once Safari implements some way to suppress this fullscreen player, we
  9878. * can remove this code.
  9879. */
  9880. function VideoProxy(videoElement) {
  9881. this.videoElement = videoElement;
  9882. // True if we're currently manually advancing the playhead (only on iOS).
  9883. this.isFakePlayback = false;
  9884. // When the video started playing.
  9885. this.startTime = null;
  9886. }
  9887. VideoProxy.prototype.play = function() {
  9888. if (Util.isIOS9OrLess()) {
  9889. this.startTime = performance.now();
  9890. this.isFakePlayback = true;
  9891. // Make an audio element to playback just the audio part.
  9892. this.audioElement = new Audio();
  9893. this.audioElement.src = this.videoElement.src;
  9894. this.audioElement.play();
  9895. } else {
  9896. this.videoElement.play().then(function(e) {
  9897. console.log('Playing video.', e);
  9898. });
  9899. }
  9900. };
  9901. VideoProxy.prototype.pause = function() {
  9902. if (Util.isIOS9OrLess() && this.isFakePlayback) {
  9903. this.isFakePlayback = true;
  9904. this.audioElement.pause();
  9905. } else {
  9906. this.videoElement.pause();
  9907. }
  9908. };
  9909. VideoProxy.prototype.setVolume = function(volumeLevel) {
  9910. if (this.videoElement) {
  9911. // On iOS 10, the VideoElement.volume property is read-only. So we special
  9912. // case muting and unmuting.
  9913. if (Util.isIOS()) {
  9914. this.videoElement.muted = (volumeLevel === 0);
  9915. } else {
  9916. this.videoElement.volume = volumeLevel;
  9917. }
  9918. }
  9919. if (this.audioElement) {
  9920. this.audioElement.volume = volumeLevel;
  9921. }
  9922. };
  9923. /**
  9924. * Set the attribute mute of the elements according with the muteState param.
  9925. *
  9926. * @param bool muteState
  9927. */
  9928. VideoProxy.prototype.mute = function(muteState) {
  9929. if (this.videoElement) {
  9930. this.videoElement.muted = muteState;
  9931. }
  9932. if (this.audioElement) {
  9933. this.audioElement.muted = muteState;
  9934. }
  9935. };
  9936. VideoProxy.prototype.getCurrentTime = function() {
  9937. return Util.isIOS9OrLess() ? this.audioElement.currentTime : this.videoElement.currentTime;
  9938. };
  9939. /**
  9940. *
  9941. * @param {Object} time
  9942. */
  9943. VideoProxy.prototype.setCurrentTime = function(time) {
  9944. if (this.videoElement) {
  9945. this.videoElement.currentTime = time.currentTime;
  9946. }
  9947. if (this.audioElement) {
  9948. this.audioElement.currentTime = time.currentTime;
  9949. }
  9950. };
  9951. /**
  9952. * Called on RAF to progress playback.
  9953. */
  9954. VideoProxy.prototype.update = function() {
  9955. // Fakes playback for iOS only.
  9956. if (!this.isFakePlayback) {
  9957. return;
  9958. }
  9959. var duration = this.videoElement.duration;
  9960. var now = performance.now();
  9961. var delta = now - this.startTime;
  9962. var deltaS = delta / 1000;
  9963. this.videoElement.currentTime = deltaS;
  9964. // Loop through the video
  9965. if (deltaS > duration) {
  9966. this.startTime = now;
  9967. this.videoElement.currentTime = 0;
  9968. // Also restart the audio.
  9969. this.audioElement.currentTime = 0;
  9970. }
  9971. };
  9972. module.exports = VideoProxy;
  9973. },{"../util":45}],43:[function(_dereq_,module,exports){
  9974. /*
  9975. * Copyright 2016 Google Inc. All Rights Reserved.
  9976. * Licensed under the Apache License, Version 2.0 (the "License");
  9977. * you may not use this file except in compliance with the License.
  9978. * You may obtain a copy of the License at
  9979. *
  9980. * http://www.apache.org/licenses/LICENSE-2.0
  9981. *
  9982. * Unless required by applicable law or agreed to in writing, software
  9983. * distributed under the License is distributed on an "AS IS" BASIS,
  9984. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9985. * See the License for the specific language governing permissions and
  9986. * limitations under the License.
  9987. */
  9988. var AdaptivePlayer = _dereq_('./adaptive-player');
  9989. var EventEmitter = _dereq_('eventemitter3');
  9990. var Eyes = _dereq_('./eyes');
  9991. var HotspotRenderer = _dereq_('./hotspot-renderer');
  9992. var ReticleRenderer = _dereq_('./reticle-renderer');
  9993. var SphereRenderer = _dereq_('./sphere-renderer');
  9994. var TWEEN = _dereq_('@tweenjs/tween.js');
  9995. var Util = _dereq_('../util');
  9996. var VideoProxy = _dereq_('./video-proxy');
  9997. var WebVRManager = _dereq_('webvr-boilerplate');
  9998. var AUTOPAN_DURATION = 3000;
  9999. var AUTOPAN_ANGLE = 0.4;
  10000. /**
  10001. * The main WebGL rendering entry point. Manages the scene, camera, VR-related
  10002. * rendering updates. Interacts with the WebVRManager.
  10003. *
  10004. * Coordinates the other renderers: SphereRenderer, HotspotRenderer,
  10005. * ReticleRenderer.
  10006. *
  10007. * Also manages the AdaptivePlayer and VideoProxy.
  10008. *
  10009. * Emits the following events:
  10010. * load: when the scene is loaded.
  10011. * error: if there is an error loading the scene.
  10012. * modechange(Boolean isVR): if the mode (eg. VR, fullscreen, etc) changes.
  10013. */
  10014. function WorldRenderer(params) {
  10015. this.init_(params.hideFullscreenButton);
  10016. this.sphereRenderer = new SphereRenderer(this.scene);
  10017. this.hotspotRenderer = new HotspotRenderer(this);
  10018. this.hotspotRenderer.on('focus', this.onHotspotFocus_.bind(this));
  10019. this.hotspotRenderer.on('blur', this.onHotspotBlur_.bind(this));
  10020. this.reticleRenderer = new ReticleRenderer(this.camera);
  10021. // Get the VR Display as soon as we initialize.
  10022. navigator.getVRDisplays().then(function(displays) {
  10023. if (displays.length > 0) {
  10024. this.vrDisplay = displays[0];
  10025. }
  10026. }.bind(this));
  10027. }
  10028. WorldRenderer.prototype = new EventEmitter();
  10029. WorldRenderer.prototype.render = function(time) {
  10030. this.controls.update();
  10031. TWEEN.update(time);
  10032. this.effect.render(this.scene, this.camera);
  10033. this.hotspotRenderer.update(this.camera);
  10034. };
  10035. /**
  10036. * @return {Promise} When the scene is fully loaded.
  10037. */
  10038. WorldRenderer.prototype.setScene = function(scene) {
  10039. var self = this;
  10040. var promise = new Promise(function(resolve, reject) {
  10041. self.sceneResolve = resolve;
  10042. self.sceneReject = reject;
  10043. });
  10044. if (!scene || !scene.isValid()) {
  10045. this.didLoadFail_(scene.errorMessage);
  10046. return;
  10047. }
  10048. var params = {
  10049. isStereo: scene.isStereo,
  10050. loop: scene.loop,
  10051. volume: scene.volume,
  10052. muted: scene.muted
  10053. };
  10054. this.setDefaultYaw_(scene.defaultYaw || 0);
  10055. // Disable VR mode if explicitly disabled, or if we're loading a video on iOS
  10056. // 9 or earlier.
  10057. if (scene.isVROff || (scene.video && Util.isIOS9OrLess())) {
  10058. this.manager.setVRCompatibleOverride(false);
  10059. }
  10060. // Set various callback overrides in iOS.
  10061. if (Util.isIOS()) {
  10062. this.manager.setFullscreenCallback(function() {
  10063. Util.sendParentMessage({type: 'enter-fullscreen'});
  10064. });
  10065. this.manager.setExitFullscreenCallback(function() {
  10066. Util.sendParentMessage({type: 'exit-fullscreen'});
  10067. });
  10068. this.manager.setVRCallback(function() {
  10069. Util.sendParentMessage({type: 'enter-vr'});
  10070. });
  10071. }
  10072. // If we're dealing with an image, and not a video.
  10073. if (scene.image && !scene.video) {
  10074. if (scene.preview) {
  10075. // First load the preview.
  10076. this.sphereRenderer.setPhotosphere(scene.preview, params).then(function() {
  10077. // As soon as something is loaded, emit the load event to hide the
  10078. // loading progress bar.
  10079. self.didLoad_();
  10080. // Then load the full resolution image.
  10081. self.sphereRenderer.setPhotosphere(scene.image, params);
  10082. }).catch(self.didLoadFail_.bind(self));
  10083. } else {
  10084. // No preview -- go straight to rendering the full image.
  10085. this.sphereRenderer.setPhotosphere(scene.image, params).then(function() {
  10086. self.didLoad_();
  10087. }).catch(self.didLoadFail_.bind(self));
  10088. }
  10089. } else if (scene.video) {
  10090. if (Util.isIE11()) {
  10091. // On IE 11, if an 'image' param is provided, load it instead of showing
  10092. // an error.
  10093. //
  10094. // TODO(smus): Once video textures are supported, remove this fallback.
  10095. if (scene.image) {
  10096. this.sphereRenderer.setPhotosphere(scene.image, params).then(function() {
  10097. self.didLoad_();
  10098. }).catch(self.didLoadFail_.bind(self));
  10099. } else {
  10100. this.didLoadFail_('Video is not supported on IE11.');
  10101. }
  10102. } else {
  10103. this.player = new AdaptivePlayer(params);
  10104. this.player.on('load', function(videoElement, videoType) {
  10105. self.sphereRenderer.set360Video(videoElement, videoType, params).then(function() {
  10106. self.didLoad_({videoElement: videoElement});
  10107. }).catch(self.didLoadFail_.bind(self));
  10108. });
  10109. this.player.on('error', function(error) {
  10110. self.didLoadFail_('Video load error: ' + error);
  10111. });
  10112. this.player.load(scene.video);
  10113. this.videoProxy = new VideoProxy(this.player.video);
  10114. }
  10115. }
  10116. this.sceneInfo = scene;
  10117. if (Util.isDebug()) {
  10118. console.log('Loaded scene', scene);
  10119. }
  10120. return promise;
  10121. };
  10122. WorldRenderer.prototype.isVRMode = function() {
  10123. return !!this.vrDisplay && this.vrDisplay.isPresenting;
  10124. };
  10125. WorldRenderer.prototype.submitFrame = function() {
  10126. if (this.isVRMode()) {
  10127. this.vrDisplay.submitFrame();
  10128. }
  10129. };
  10130. WorldRenderer.prototype.disposeEye_ = function(eye) {
  10131. if (eye) {
  10132. if (eye.material.map) {
  10133. eye.material.map.dispose();
  10134. }
  10135. eye.material.dispose();
  10136. eye.geometry.dispose();
  10137. }
  10138. };
  10139. WorldRenderer.prototype.dispose = function() {
  10140. var eyeLeft = this.scene.getObjectByName('eyeLeft');
  10141. this.disposeEye_(eyeLeft);
  10142. var eyeRight = this.scene.getObjectByName('eyeRight');
  10143. this.disposeEye_(eyeRight);
  10144. };
  10145. WorldRenderer.prototype.destroy = function() {
  10146. if (this.player) {
  10147. this.player.removeAllListeners();
  10148. this.player.destroy();
  10149. this.player = null;
  10150. }
  10151. var photo = this.scene.getObjectByName('photo');
  10152. var eyeLeft = this.scene.getObjectByName('eyeLeft');
  10153. var eyeRight = this.scene.getObjectByName('eyeRight');
  10154. if (eyeLeft) {
  10155. this.disposeEye_(eyeLeft);
  10156. photo.remove(eyeLeft);
  10157. this.scene.remove(eyeLeft);
  10158. }
  10159. if (eyeRight) {
  10160. this.disposeEye_(eyeRight);
  10161. photo.remove(eyeRight);
  10162. this.scene.remove(eyeRight);
  10163. }
  10164. };
  10165. WorldRenderer.prototype.didLoad_ = function(opt_event) {
  10166. var event = opt_event || {};
  10167. this.emit('load', event);
  10168. if (this.sceneResolve) {
  10169. this.sceneResolve();
  10170. }
  10171. };
  10172. WorldRenderer.prototype.didLoadFail_ = function(message) {
  10173. this.emit('error', message);
  10174. if (this.sceneReject) {
  10175. this.sceneReject(message);
  10176. }
  10177. };
  10178. /**
  10179. * Sets the default yaw.
  10180. * @param {Number} angleRad The yaw in radians.
  10181. */
  10182. WorldRenderer.prototype.setDefaultYaw_ = function(angleRad) {
  10183. // Rotate the camera parent to take into account the scene's rotation.
  10184. // By default, it should be at the center of the image.
  10185. var display = this.controls.getVRDisplay();
  10186. // For desktop, we subtract the current display Y axis
  10187. var theta = display.theta_ || 0;
  10188. // For devices with orientation we make the current view center
  10189. if (display.poseSensor_) {
  10190. display.poseSensor_.resetPose();
  10191. }
  10192. this.camera.parent.rotation.y = (Math.PI / 2.0) + angleRad - theta;
  10193. };
  10194. /**
  10195. * Do the initial camera tween to rotate the camera, giving an indication that
  10196. * there is live content there (on desktop only).
  10197. */
  10198. WorldRenderer.prototype.autopan = function(duration) {
  10199. var targetY = this.camera.parent.rotation.y - AUTOPAN_ANGLE;
  10200. var tween = new TWEEN.Tween(this.camera.parent.rotation)
  10201. .to({y: targetY}, AUTOPAN_DURATION)
  10202. .easing(TWEEN.Easing.Quadratic.Out)
  10203. .start();
  10204. };
  10205. WorldRenderer.prototype.init_ = function(hideFullscreenButton) {
  10206. var container = document.querySelector('body');
  10207. var aspect = window.innerWidth / window.innerHeight;
  10208. var camera = new THREE.PerspectiveCamera(75, aspect, 0.1, 100);
  10209. camera.layers.enable(1);
  10210. var cameraDummy = new THREE.Object3D();
  10211. cameraDummy.add(camera);
  10212. // Antialiasing disabled to improve performance.
  10213. var renderer = new THREE.WebGLRenderer({antialias: false});
  10214. renderer.setClearColor(0x000000, 0);
  10215. renderer.setSize(window.innerWidth, window.innerHeight);
  10216. renderer.setPixelRatio(window.devicePixelRatio);
  10217. container.appendChild(renderer.domElement);
  10218. var controls = new THREE.VRControls(camera);
  10219. var effect = new THREE.VREffect(renderer);
  10220. // Disable eye separation.
  10221. effect.scale = 0;
  10222. effect.setSize(window.innerWidth, window.innerHeight);
  10223. // Present submission of frames automatically. This is done manually in
  10224. // submitFrame().
  10225. effect.autoSubmitFrame = false;
  10226. this.camera = camera;
  10227. this.renderer = renderer;
  10228. this.effect = effect;
  10229. this.controls = controls;
  10230. this.manager = new WebVRManager(renderer, effect, {predistorted: false, hideButton: hideFullscreenButton});
  10231. this.scene = this.createScene_();
  10232. this.scene.add(this.camera.parent);
  10233. // Watch the resize event.
  10234. window.addEventListener('resize', this.onResize_.bind(this));
  10235. // Prevent context menu.
  10236. window.addEventListener('contextmenu', this.onContextMenu_.bind(this));
  10237. window.addEventListener('vrdisplaypresentchange',
  10238. this.onVRDisplayPresentChange_.bind(this));
  10239. };
  10240. WorldRenderer.prototype.onResize_ = function() {
  10241. this.effect.setSize(window.innerWidth, window.innerHeight);
  10242. this.camera.aspect = window.innerWidth / window.innerHeight;
  10243. this.camera.updateProjectionMatrix();
  10244. };
  10245. WorldRenderer.prototype.onVRDisplayPresentChange_ = function(e) {
  10246. if (Util.isDebug()) {
  10247. console.log('onVRDisplayPresentChange_');
  10248. }
  10249. var isVR = this.isVRMode();
  10250. // If the mode changed to VR and there is at least one hotspot, show reticle.
  10251. var isReticleVisible = isVR && this.hotspotRenderer.getCount() > 0;
  10252. this.reticleRenderer.setVisibility(isReticleVisible);
  10253. // Resize the renderer for good measure.
  10254. this.onResize_();
  10255. // Analytics.
  10256. if (window.analytics) {
  10257. analytics.logModeChanged(isVR);
  10258. }
  10259. // When exiting VR mode from iOS, make sure we emit back an exit-fullscreen event.
  10260. if (!isVR && Util.isIOS()) {
  10261. Util.sendParentMessage({type: 'exit-fullscreen'});
  10262. }
  10263. // Emit a mode change event back to any listeners.
  10264. this.emit('modechange', isVR);
  10265. };
  10266. WorldRenderer.prototype.createScene_ = function(opt_params) {
  10267. var scene = new THREE.Scene();
  10268. // Add a group for the photosphere.
  10269. var photoGroup = new THREE.Object3D();
  10270. photoGroup.name = 'photo';
  10271. scene.add(photoGroup);
  10272. return scene;
  10273. };
  10274. WorldRenderer.prototype.onHotspotFocus_ = function(id) {
  10275. // Set the default cursor to be a pointer.
  10276. this.setCursor_('pointer');
  10277. };
  10278. WorldRenderer.prototype.onHotspotBlur_ = function(id) {
  10279. // Reset the default cursor to be the default one.
  10280. this.setCursor_('');
  10281. };
  10282. WorldRenderer.prototype.setCursor_ = function(cursor) {
  10283. this.renderer.domElement.style.cursor = cursor;
  10284. };
  10285. WorldRenderer.prototype.onContextMenu_ = function(e) {
  10286. e.preventDefault();
  10287. e.stopPropagation();
  10288. return false;
  10289. };
  10290. module.exports = WorldRenderer;
  10291. },{"../util":45,"./adaptive-player":33,"./eyes":34,"./hotspot-renderer":35,"./reticle-renderer":39,"./sphere-renderer":41,"./video-proxy":42,"@tweenjs/tween.js":1,"eventemitter3":3,"webvr-boilerplate":7}],44:[function(_dereq_,module,exports){
  10292. /*
  10293. * Copyright 2016 Google Inc. All Rights Reserved.
  10294. * Licensed under the Apache License, Version 2.0 (the "License");
  10295. * you may not use this file except in compliance with the License.
  10296. * You may obtain a copy of the License at
  10297. *
  10298. * http://www.apache.org/licenses/LICENSE-2.0
  10299. *
  10300. * Unless required by applicable law or agreed to in writing, software
  10301. * distributed under the License is distributed on an "AS IS" BASIS,
  10302. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10303. * See the License for the specific language governing permissions and
  10304. * limitations under the License.
  10305. */
  10306. /**
  10307. * Messages from the API to the embed.
  10308. */
  10309. var Message = {
  10310. PLAY: 'play',
  10311. PAUSE: 'pause',
  10312. TIMEUPDATE: 'timeupdate',
  10313. ADD_HOTSPOT: 'addhotspot',
  10314. SET_CONTENT: 'setimage',
  10315. SET_VOLUME: 'setvolume',
  10316. MUTED: 'muted',
  10317. SET_CURRENT_TIME: 'setcurrenttime',
  10318. DEVICE_MOTION: 'devicemotion',
  10319. GET_POSITION: 'getposition',
  10320. SET_FULLSCREEN: 'setfullscreen',
  10321. };
  10322. module.exports = Message;
  10323. },{}],45:[function(_dereq_,module,exports){
  10324. /*
  10325. * Copyright 2016 Google Inc. All Rights Reserved.
  10326. * Licensed under the Apache License, Version 2.0 (the "License");
  10327. * you may not use this file except in compliance with the License.
  10328. * You may obtain a copy of the License at
  10329. *
  10330. * http://www.apache.org/licenses/LICENSE-2.0
  10331. *
  10332. * Unless required by applicable law or agreed to in writing, software
  10333. * distributed under the License is distributed on an "AS IS" BASIS,
  10334. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10335. * See the License for the specific language governing permissions and
  10336. * limitations under the License.
  10337. */
  10338. var Util = window.Util || {};
  10339. Util.isDataURI = function(src) {
  10340. return src && src.indexOf('data:') == 0;
  10341. };
  10342. Util.generateUUID = function() {
  10343. function s4() {
  10344. return Math.floor((1 + Math.random()) * 0x10000)
  10345. .toString(16)
  10346. .substring(1);
  10347. }
  10348. return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
  10349. s4() + '-' + s4() + s4() + s4();
  10350. };
  10351. Util.isMobile = function() {
  10352. var check = false;
  10353. (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))check = true})(navigator.userAgent||navigator.vendor||window.opera);
  10354. return check;
  10355. };
  10356. Util.isIOS = function() {
  10357. return /(iPad|iPhone|iPod)/g.test(navigator.userAgent);
  10358. };
  10359. Util.isSafari = function() {
  10360. return /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
  10361. };
  10362. Util.cloneObject = function(obj) {
  10363. var out = {};
  10364. for (key in obj) {
  10365. out[key] = obj[key];
  10366. }
  10367. return out;
  10368. };
  10369. Util.hashCode = function(s) {
  10370. return s.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0);
  10371. };
  10372. Util.loadTrackSrc = function(context, src, callback, opt_progressCallback) {
  10373. var request = new XMLHttpRequest();
  10374. request.open('GET', src, true);
  10375. request.responseType = 'arraybuffer';
  10376. // Decode asynchronously.
  10377. request.onload = function() {
  10378. context.decodeAudioData(request.response, function(buffer) {
  10379. callback(buffer);
  10380. }, function(e) {
  10381. console.error(e);
  10382. });
  10383. };
  10384. if (opt_progressCallback) {
  10385. request.onprogress = function(e) {
  10386. var percent = e.loaded / e.total;
  10387. opt_progressCallback(percent);
  10388. };
  10389. }
  10390. request.send();
  10391. };
  10392. Util.isPow2 = function(n) {
  10393. return (n & (n - 1)) == 0;
  10394. };
  10395. Util.capitalize = function(s) {
  10396. return s.charAt(0).toUpperCase() + s.slice(1);
  10397. };
  10398. Util.isIFrame = function() {
  10399. try {
  10400. return window.self !== window.top;
  10401. } catch (e) {
  10402. return true;
  10403. }
  10404. };
  10405. // From http://goo.gl/4WX3tg
  10406. Util.getQueryParameter = function(name) {
  10407. name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
  10408. var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
  10409. results = regex.exec(location.search);
  10410. return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
  10411. };
  10412. // From http://stackoverflow.com/questions/11871077/proper-way-to-detect-webgl-support.
  10413. Util.isWebGLEnabled = function() {
  10414. var canvas = document.createElement('canvas');
  10415. try { gl = canvas.getContext("webgl"); }
  10416. catch (x) { gl = null; }
  10417. if (gl == null) {
  10418. try { gl = canvas.getContext("experimental-webgl"); experimental = true; }
  10419. catch (x) { gl = null; }
  10420. }
  10421. return !!gl;
  10422. };
  10423. Util.clone = function(obj) {
  10424. return JSON.parse(JSON.stringify(obj));
  10425. };
  10426. // From http://stackoverflow.com/questions/10140604/fastest-hypotenuse-in-javascript
  10427. Util.hypot = Math.hypot || function(x, y) {
  10428. return Math.sqrt(x*x + y*y);
  10429. };
  10430. // From http://stackoverflow.com/a/17447718/693934
  10431. Util.isIE11 = function() {
  10432. return navigator.userAgent.match(/Trident/);
  10433. };
  10434. Util.getRectCenter = function(rect) {
  10435. return new THREE.Vector2(rect.x + rect.width/2, rect.y + rect.height/2);
  10436. };
  10437. Util.getScreenWidth = function() {
  10438. return Math.max(window.screen.width, window.screen.height) *
  10439. window.devicePixelRatio;
  10440. };
  10441. Util.getScreenHeight = function() {
  10442. return Math.min(window.screen.width, window.screen.height) *
  10443. window.devicePixelRatio;
  10444. };
  10445. Util.isIOS9OrLess = function() {
  10446. if (!Util.isIOS()) {
  10447. return false;
  10448. }
  10449. var re = /(iPhone|iPad|iPod) OS ([\d_]+)/;
  10450. var iOSVersion = navigator.userAgent.match(re);
  10451. if (!iOSVersion) {
  10452. return false;
  10453. }
  10454. // Get the last group.
  10455. var versionString = iOSVersion[iOSVersion.length - 1];
  10456. var majorVersion = parseFloat(versionString);
  10457. return majorVersion <= 9;
  10458. };
  10459. Util.getExtension = function(url) {
  10460. return url.split('.').pop().split('?')[0];
  10461. };
  10462. Util.createGetParams = function(params) {
  10463. var out = '?';
  10464. for (var k in params) {
  10465. var paramString = k + '=' + params[k] + '&';
  10466. out += paramString;
  10467. }
  10468. // Remove the trailing ampersand.
  10469. out.substring(0, params.length - 2);
  10470. return out;
  10471. };
  10472. Util.sendParentMessage = function(message) {
  10473. if (window.parent) {
  10474. parent.postMessage(message, '*');
  10475. }
  10476. };
  10477. Util.parseBoolean = function(value) {
  10478. if (value == 'false' || value == 0) {
  10479. return false;
  10480. } else if (value == 'true' || value == 1) {
  10481. return true;
  10482. } else {
  10483. return !!value;
  10484. }
  10485. };
  10486. /**
  10487. * @param base {String} An absolute directory root.
  10488. * @param relative {String} A relative path.
  10489. *
  10490. * @returns {String} An absolute path corresponding to the rootPath.
  10491. *
  10492. * From http://stackoverflow.com/a/14780463/693934.
  10493. */
  10494. Util.relativeToAbsolutePath = function(base, relative) {
  10495. var stack = base.split('/');
  10496. var parts = relative.split('/');
  10497. for (var i = 0; i < parts.length; i++) {
  10498. if (parts[i] == '.') {
  10499. continue;
  10500. }
  10501. if (parts[i] == '..') {
  10502. stack.pop();
  10503. } else {
  10504. stack.push(parts[i]);
  10505. }
  10506. }
  10507. return stack.join('/');
  10508. };
  10509. /**
  10510. * @return {Boolean} True iff the specified path is an absolute path.
  10511. */
  10512. Util.isPathAbsolute = function(path) {
  10513. return ! /^(?:\/|[a-z]+:\/\/)/.test(path);
  10514. }
  10515. Util.isEmptyObject = function(obj) {
  10516. return Object.getOwnPropertyNames(obj).length == 0;
  10517. };
  10518. Util.isDebug = function() {
  10519. return Util.parseBoolean(Util.getQueryParameter('debug'));
  10520. };
  10521. Util.getCurrentScript = function() {
  10522. // Note: in IE11, document.currentScript doesn't work, so we fall back to this
  10523. // hack, taken from https://goo.gl/TpExuH.
  10524. if (!document.currentScript) {
  10525. console.warn('This browser does not support document.currentScript. Trying fallback.');
  10526. }
  10527. return document.currentScript || document.scripts[document.scripts.length - 1];
  10528. }
  10529. module.exports = Util;
  10530. },{}],46:[function(_dereq_,module,exports){
  10531. /*
  10532. * Copyright 2016 Google Inc. All Rights Reserved.
  10533. * Licensed under the Apache License, Version 2.0 (the "License");
  10534. * you may not use this file except in compliance with the License.
  10535. * You may obtain a copy of the License at
  10536. *
  10537. * http://www.apache.org/licenses/LICENSE-2.0
  10538. *
  10539. * Unless required by applicable law or agreed to in writing, software
  10540. * distributed under the License is distributed on an "AS IS" BASIS,
  10541. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10542. * See the License for the specific language governing permissions and
  10543. * limitations under the License.
  10544. */
  10545. /**
  10546. * Video Types
  10547. */
  10548. var VideoTypes = {
  10549. HLS: 1,
  10550. DASH: 2,
  10551. VIDEO: 3
  10552. };
  10553. module.exports = VideoTypes;
  10554. },{}]},{},[38]);