flat-ui.js 446 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728
  1. /*!
  2. * Flat UI Free v2.2.2 (http://designmodo.github.io/Flat-UI/)
  3. * Copyright 2013-2014 Designmodo, Inc.
  4. */
  5. /*!
  6. * jQuery UI Core 1.10.4
  7. * http://jqueryui.com
  8. *
  9. * Copyright 2014 jQuery Foundation and other contributors
  10. * Released under the MIT license.
  11. * http://jquery.org/license
  12. *
  13. * http://api.jqueryui.com/category/ui-core/
  14. */
  15. (function( $, undefined ) {
  16. var uuid = 0,
  17. runiqueId = /^ui-id-\d+$/;
  18. // $.ui might exist from components with no dependencies, e.g., $.ui.position
  19. $.ui = $.ui || {};
  20. $.extend( $.ui, {
  21. version: "1.10.4",
  22. keyCode: {
  23. BACKSPACE: 8,
  24. COMMA: 188,
  25. DELETE: 46,
  26. DOWN: 40,
  27. END: 35,
  28. ENTER: 13,
  29. ESCAPE: 27,
  30. HOME: 36,
  31. LEFT: 37,
  32. NUMPAD_ADD: 107,
  33. NUMPAD_DECIMAL: 110,
  34. NUMPAD_DIVIDE: 111,
  35. NUMPAD_ENTER: 108,
  36. NUMPAD_MULTIPLY: 106,
  37. NUMPAD_SUBTRACT: 109,
  38. PAGE_DOWN: 34,
  39. PAGE_UP: 33,
  40. PERIOD: 190,
  41. RIGHT: 39,
  42. SPACE: 32,
  43. TAB: 9,
  44. UP: 38
  45. }
  46. });
  47. // plugins
  48. $.fn.extend({
  49. focus: (function( orig ) {
  50. return function( delay, fn ) {
  51. return typeof delay === "number" ?
  52. this.each(function() {
  53. var elem = this;
  54. setTimeout(function() {
  55. $( elem ).focus();
  56. if ( fn ) {
  57. fn.call( elem );
  58. }
  59. }, delay );
  60. }) :
  61. orig.apply( this, arguments );
  62. };
  63. })( $.fn.focus ),
  64. scrollParent: function() {
  65. var scrollParent;
  66. if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
  67. scrollParent = this.parents().filter(function() {
  68. return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
  69. }).eq(0);
  70. } else {
  71. scrollParent = this.parents().filter(function() {
  72. return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
  73. }).eq(0);
  74. }
  75. return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
  76. },
  77. zIndex: function( zIndex ) {
  78. if ( zIndex !== undefined ) {
  79. return this.css( "zIndex", zIndex );
  80. }
  81. if ( this.length ) {
  82. var elem = $( this[ 0 ] ), position, value;
  83. while ( elem.length && elem[ 0 ] !== document ) {
  84. // Ignore z-index if position is set to a value where z-index is ignored by the browser
  85. // This makes behavior of this function consistent across browsers
  86. // WebKit always returns auto if the element is positioned
  87. position = elem.css( "position" );
  88. if ( position === "absolute" || position === "relative" || position === "fixed" ) {
  89. // IE returns 0 when zIndex is not specified
  90. // other browsers return a string
  91. // we ignore the case of nested elements with an explicit value of 0
  92. // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
  93. value = parseInt( elem.css( "zIndex" ), 10 );
  94. if ( !isNaN( value ) && value !== 0 ) {
  95. return value;
  96. }
  97. }
  98. elem = elem.parent();
  99. }
  100. }
  101. return 0;
  102. },
  103. uniqueId: function() {
  104. return this.each(function() {
  105. if ( !this.id ) {
  106. this.id = "ui-id-" + (++uuid);
  107. }
  108. });
  109. },
  110. removeUniqueId: function() {
  111. return this.each(function() {
  112. if ( runiqueId.test( this.id ) ) {
  113. $( this ).removeAttr( "id" );
  114. }
  115. });
  116. }
  117. });
  118. // selectors
  119. function focusable( element, isTabIndexNotNaN ) {
  120. var map, mapName, img,
  121. nodeName = element.nodeName.toLowerCase();
  122. if ( "area" === nodeName ) {
  123. map = element.parentNode;
  124. mapName = map.name;
  125. if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
  126. return false;
  127. }
  128. img = $( "img[usemap=#" + mapName + "]" )[0];
  129. return !!img && visible( img );
  130. }
  131. return ( /input|select|textarea|button|object/.test( nodeName ) ?
  132. !element.disabled :
  133. "a" === nodeName ?
  134. element.href || isTabIndexNotNaN :
  135. isTabIndexNotNaN) &&
  136. // the element and all of its ancestors must be visible
  137. visible( element );
  138. }
  139. function visible( element ) {
  140. return $.expr.filters.visible( element ) &&
  141. !$( element ).parents().addBack().filter(function() {
  142. return $.css( this, "visibility" ) === "hidden";
  143. }).length;
  144. }
  145. $.extend( $.expr[ ":" ], {
  146. data: $.expr.createPseudo ?
  147. $.expr.createPseudo(function( dataName ) {
  148. return function( elem ) {
  149. return !!$.data( elem, dataName );
  150. };
  151. }) :
  152. // support: jQuery <1.8
  153. function( elem, i, match ) {
  154. return !!$.data( elem, match[ 3 ] );
  155. },
  156. focusable: function( element ) {
  157. return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
  158. },
  159. tabbable: function( element ) {
  160. var tabIndex = $.attr( element, "tabindex" ),
  161. isTabIndexNaN = isNaN( tabIndex );
  162. return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
  163. }
  164. });
  165. // support: jQuery <1.8
  166. if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
  167. $.each( [ "Width", "Height" ], function( i, name ) {
  168. var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
  169. type = name.toLowerCase(),
  170. orig = {
  171. innerWidth: $.fn.innerWidth,
  172. innerHeight: $.fn.innerHeight,
  173. outerWidth: $.fn.outerWidth,
  174. outerHeight: $.fn.outerHeight
  175. };
  176. function reduce( elem, size, border, margin ) {
  177. $.each( side, function() {
  178. size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
  179. if ( border ) {
  180. size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
  181. }
  182. if ( margin ) {
  183. size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
  184. }
  185. });
  186. return size;
  187. }
  188. $.fn[ "inner" + name ] = function( size ) {
  189. if ( size === undefined ) {
  190. return orig[ "inner" + name ].call( this );
  191. }
  192. return this.each(function() {
  193. $( this ).css( type, reduce( this, size ) + "px" );
  194. });
  195. };
  196. $.fn[ "outer" + name] = function( size, margin ) {
  197. if ( typeof size !== "number" ) {
  198. return orig[ "outer" + name ].call( this, size );
  199. }
  200. return this.each(function() {
  201. $( this).css( type, reduce( this, size, true, margin ) + "px" );
  202. });
  203. };
  204. });
  205. }
  206. // support: jQuery <1.8
  207. if ( !$.fn.addBack ) {
  208. $.fn.addBack = function( selector ) {
  209. return this.add( selector == null ?
  210. this.prevObject : this.prevObject.filter( selector )
  211. );
  212. };
  213. }
  214. // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
  215. if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
  216. $.fn.removeData = (function( removeData ) {
  217. return function( key ) {
  218. if ( arguments.length ) {
  219. return removeData.call( this, $.camelCase( key ) );
  220. } else {
  221. return removeData.call( this );
  222. }
  223. };
  224. })( $.fn.removeData );
  225. }
  226. // deprecated
  227. $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
  228. $.support.selectstart = "onselectstart" in document.createElement( "div" );
  229. $.fn.extend({
  230. disableSelection: function() {
  231. return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
  232. ".ui-disableSelection", function( event ) {
  233. event.preventDefault();
  234. });
  235. },
  236. enableSelection: function() {
  237. return this.unbind( ".ui-disableSelection" );
  238. }
  239. });
  240. $.extend( $.ui, {
  241. // $.ui.plugin is deprecated. Use $.widget() extensions instead.
  242. plugin: {
  243. add: function( module, option, set ) {
  244. var i,
  245. proto = $.ui[ module ].prototype;
  246. for ( i in set ) {
  247. proto.plugins[ i ] = proto.plugins[ i ] || [];
  248. proto.plugins[ i ].push( [ option, set[ i ] ] );
  249. }
  250. },
  251. call: function( instance, name, args ) {
  252. var i,
  253. set = instance.plugins[ name ];
  254. if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
  255. return;
  256. }
  257. for ( i = 0; i < set.length; i++ ) {
  258. if ( instance.options[ set[ i ][ 0 ] ] ) {
  259. set[ i ][ 1 ].apply( instance.element, args );
  260. }
  261. }
  262. }
  263. },
  264. // only used by resizable
  265. hasScroll: function( el, a ) {
  266. //If overflow is hidden, the element might have extra content, but the user wants to hide it
  267. if ( $( el ).css( "overflow" ) === "hidden") {
  268. return false;
  269. }
  270. var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
  271. has = false;
  272. if ( el[ scroll ] > 0 ) {
  273. return true;
  274. }
  275. // TODO: determine which cases actually cause this to happen
  276. // if the element doesn't have the scroll set, see if it's possible to
  277. // set the scroll
  278. el[ scroll ] = 1;
  279. has = ( el[ scroll ] > 0 );
  280. el[ scroll ] = 0;
  281. return has;
  282. }
  283. });
  284. })( jQuery );
  285. /*!
  286. * jQuery UI Widget 1.10.4
  287. * http://jqueryui.com
  288. *
  289. * Copyright 2014 jQuery Foundation and other contributors
  290. * Released under the MIT license.
  291. * http://jquery.org/license
  292. *
  293. * http://api.jqueryui.com/jQuery.widget/
  294. */
  295. (function( $, undefined ) {
  296. var uuid = 0,
  297. slice = Array.prototype.slice,
  298. _cleanData = $.cleanData;
  299. $.cleanData = function( elems ) {
  300. for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
  301. try {
  302. $( elem ).triggerHandler( "remove" );
  303. // http://bugs.jquery.com/ticket/8235
  304. } catch( e ) {}
  305. }
  306. _cleanData( elems );
  307. };
  308. $.widget = function( name, base, prototype ) {
  309. var fullName, existingConstructor, constructor, basePrototype,
  310. // proxiedPrototype allows the provided prototype to remain unmodified
  311. // so that it can be used as a mixin for multiple widgets (#8876)
  312. proxiedPrototype = {},
  313. namespace = name.split( "." )[ 0 ];
  314. name = name.split( "." )[ 1 ];
  315. fullName = namespace + "-" + name;
  316. if ( !prototype ) {
  317. prototype = base;
  318. base = $.Widget;
  319. }
  320. // create selector for plugin
  321. $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
  322. return !!$.data( elem, fullName );
  323. };
  324. $[ namespace ] = $[ namespace ] || {};
  325. existingConstructor = $[ namespace ][ name ];
  326. constructor = $[ namespace ][ name ] = function( options, element ) {
  327. // allow instantiation without "new" keyword
  328. if ( !this._createWidget ) {
  329. return new constructor( options, element );
  330. }
  331. // allow instantiation without initializing for simple inheritance
  332. // must use "new" keyword (the code above always passes args)
  333. if ( arguments.length ) {
  334. this._createWidget( options, element );
  335. }
  336. };
  337. // extend with the existing constructor to carry over any static properties
  338. $.extend( constructor, existingConstructor, {
  339. version: prototype.version,
  340. // copy the object used to create the prototype in case we need to
  341. // redefine the widget later
  342. _proto: $.extend( {}, prototype ),
  343. // track widgets that inherit from this widget in case this widget is
  344. // redefined after a widget inherits from it
  345. _childConstructors: []
  346. });
  347. basePrototype = new base();
  348. // we need to make the options hash a property directly on the new instance
  349. // otherwise we'll modify the options hash on the prototype that we're
  350. // inheriting from
  351. basePrototype.options = $.widget.extend( {}, basePrototype.options );
  352. $.each( prototype, function( prop, value ) {
  353. if ( !$.isFunction( value ) ) {
  354. proxiedPrototype[ prop ] = value;
  355. return;
  356. }
  357. proxiedPrototype[ prop ] = (function() {
  358. var _super = function() {
  359. return base.prototype[ prop ].apply( this, arguments );
  360. },
  361. _superApply = function( args ) {
  362. return base.prototype[ prop ].apply( this, args );
  363. };
  364. return function() {
  365. var __super = this._super,
  366. __superApply = this._superApply,
  367. returnValue;
  368. this._super = _super;
  369. this._superApply = _superApply;
  370. returnValue = value.apply( this, arguments );
  371. this._super = __super;
  372. this._superApply = __superApply;
  373. return returnValue;
  374. };
  375. })();
  376. });
  377. constructor.prototype = $.widget.extend( basePrototype, {
  378. // TODO: remove support for widgetEventPrefix
  379. // always use the name + a colon as the prefix, e.g., draggable:start
  380. // don't prefix for widgets that aren't DOM-based
  381. widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
  382. }, proxiedPrototype, {
  383. constructor: constructor,
  384. namespace: namespace,
  385. widgetName: name,
  386. widgetFullName: fullName
  387. });
  388. // If this widget is being redefined then we need to find all widgets that
  389. // are inheriting from it and redefine all of them so that they inherit from
  390. // the new version of this widget. We're essentially trying to replace one
  391. // level in the prototype chain.
  392. if ( existingConstructor ) {
  393. $.each( existingConstructor._childConstructors, function( i, child ) {
  394. var childPrototype = child.prototype;
  395. // redefine the child widget using the same prototype that was
  396. // originally used, but inherit from the new version of the base
  397. $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
  398. });
  399. // remove the list of existing child constructors from the old constructor
  400. // so the old child constructors can be garbage collected
  401. delete existingConstructor._childConstructors;
  402. } else {
  403. base._childConstructors.push( constructor );
  404. }
  405. $.widget.bridge( name, constructor );
  406. };
  407. $.widget.extend = function( target ) {
  408. var input = slice.call( arguments, 1 ),
  409. inputIndex = 0,
  410. inputLength = input.length,
  411. key,
  412. value;
  413. for ( ; inputIndex < inputLength; inputIndex++ ) {
  414. for ( key in input[ inputIndex ] ) {
  415. value = input[ inputIndex ][ key ];
  416. if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
  417. // Clone objects
  418. if ( $.isPlainObject( value ) ) {
  419. target[ key ] = $.isPlainObject( target[ key ] ) ?
  420. $.widget.extend( {}, target[ key ], value ) :
  421. // Don't extend strings, arrays, etc. with objects
  422. $.widget.extend( {}, value );
  423. // Copy everything else by reference
  424. } else {
  425. target[ key ] = value;
  426. }
  427. }
  428. }
  429. }
  430. return target;
  431. };
  432. $.widget.bridge = function( name, object ) {
  433. var fullName = object.prototype.widgetFullName || name;
  434. $.fn[ name ] = function( options ) {
  435. var isMethodCall = typeof options === "string",
  436. args = slice.call( arguments, 1 ),
  437. returnValue = this;
  438. // allow multiple hashes to be passed on init
  439. options = !isMethodCall && args.length ?
  440. $.widget.extend.apply( null, [ options ].concat(args) ) :
  441. options;
  442. if ( isMethodCall ) {
  443. this.each(function() {
  444. var methodValue,
  445. instance = $.data( this, fullName );
  446. if ( !instance ) {
  447. return $.error( "cannot call methods on " + name + " prior to initialization; " +
  448. "attempted to call method '" + options + "'" );
  449. }
  450. if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
  451. return $.error( "no such method '" + options + "' for " + name + " widget instance" );
  452. }
  453. methodValue = instance[ options ].apply( instance, args );
  454. if ( methodValue !== instance && methodValue !== undefined ) {
  455. returnValue = methodValue && methodValue.jquery ?
  456. returnValue.pushStack( methodValue.get() ) :
  457. methodValue;
  458. return false;
  459. }
  460. });
  461. } else {
  462. this.each(function() {
  463. var instance = $.data( this, fullName );
  464. if ( instance ) {
  465. instance.option( options || {} )._init();
  466. } else {
  467. $.data( this, fullName, new object( options, this ) );
  468. }
  469. });
  470. }
  471. return returnValue;
  472. };
  473. };
  474. $.Widget = function( /* options, element */ ) {};
  475. $.Widget._childConstructors = [];
  476. $.Widget.prototype = {
  477. widgetName: "widget",
  478. widgetEventPrefix: "",
  479. defaultElement: "<div>",
  480. options: {
  481. disabled: false,
  482. // callbacks
  483. create: null
  484. },
  485. _createWidget: function( options, element ) {
  486. element = $( element || this.defaultElement || this )[ 0 ];
  487. this.element = $( element );
  488. this.uuid = uuid++;
  489. this.eventNamespace = "." + this.widgetName + this.uuid;
  490. this.options = $.widget.extend( {},
  491. this.options,
  492. this._getCreateOptions(),
  493. options );
  494. this.bindings = $();
  495. this.hoverable = $();
  496. this.focusable = $();
  497. if ( element !== this ) {
  498. $.data( element, this.widgetFullName, this );
  499. this._on( true, this.element, {
  500. remove: function( event ) {
  501. if ( event.target === element ) {
  502. this.destroy();
  503. }
  504. }
  505. });
  506. this.document = $( element.style ?
  507. // element within the document
  508. element.ownerDocument :
  509. // element is window or document
  510. element.document || element );
  511. this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
  512. }
  513. this._create();
  514. this._trigger( "create", null, this._getCreateEventData() );
  515. this._init();
  516. },
  517. _getCreateOptions: $.noop,
  518. _getCreateEventData: $.noop,
  519. _create: $.noop,
  520. _init: $.noop,
  521. destroy: function() {
  522. this._destroy();
  523. // we can probably remove the unbind calls in 2.0
  524. // all event bindings should go through this._on()
  525. this.element
  526. .unbind( this.eventNamespace )
  527. // 1.9 BC for #7810
  528. // TODO remove dual storage
  529. .removeData( this.widgetName )
  530. .removeData( this.widgetFullName )
  531. // support: jquery <1.6.3
  532. // http://bugs.jquery.com/ticket/9413
  533. .removeData( $.camelCase( this.widgetFullName ) );
  534. this.widget()
  535. .unbind( this.eventNamespace )
  536. .removeAttr( "aria-disabled" )
  537. .removeClass(
  538. this.widgetFullName + "-disabled " +
  539. "ui-state-disabled" );
  540. // clean up events and states
  541. this.bindings.unbind( this.eventNamespace );
  542. this.hoverable.removeClass( "ui-state-hover" );
  543. this.focusable.removeClass( "ui-state-focus" );
  544. },
  545. _destroy: $.noop,
  546. widget: function() {
  547. return this.element;
  548. },
  549. option: function( key, value ) {
  550. var options = key,
  551. parts,
  552. curOption,
  553. i;
  554. if ( arguments.length === 0 ) {
  555. // don't return a reference to the internal hash
  556. return $.widget.extend( {}, this.options );
  557. }
  558. if ( typeof key === "string" ) {
  559. // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
  560. options = {};
  561. parts = key.split( "." );
  562. key = parts.shift();
  563. if ( parts.length ) {
  564. curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
  565. for ( i = 0; i < parts.length - 1; i++ ) {
  566. curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
  567. curOption = curOption[ parts[ i ] ];
  568. }
  569. key = parts.pop();
  570. if ( arguments.length === 1 ) {
  571. return curOption[ key ] === undefined ? null : curOption[ key ];
  572. }
  573. curOption[ key ] = value;
  574. } else {
  575. if ( arguments.length === 1 ) {
  576. return this.options[ key ] === undefined ? null : this.options[ key ];
  577. }
  578. options[ key ] = value;
  579. }
  580. }
  581. this._setOptions( options );
  582. return this;
  583. },
  584. _setOptions: function( options ) {
  585. var key;
  586. for ( key in options ) {
  587. this._setOption( key, options[ key ] );
  588. }
  589. return this;
  590. },
  591. _setOption: function( key, value ) {
  592. this.options[ key ] = value;
  593. if ( key === "disabled" ) {
  594. this.widget()
  595. .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
  596. .attr( "aria-disabled", value );
  597. this.hoverable.removeClass( "ui-state-hover" );
  598. this.focusable.removeClass( "ui-state-focus" );
  599. }
  600. return this;
  601. },
  602. enable: function() {
  603. return this._setOption( "disabled", false );
  604. },
  605. disable: function() {
  606. return this._setOption( "disabled", true );
  607. },
  608. _on: function( suppressDisabledCheck, element, handlers ) {
  609. var delegateElement,
  610. instance = this;
  611. // no suppressDisabledCheck flag, shuffle arguments
  612. if ( typeof suppressDisabledCheck !== "boolean" ) {
  613. handlers = element;
  614. element = suppressDisabledCheck;
  615. suppressDisabledCheck = false;
  616. }
  617. // no element argument, shuffle and use this.element
  618. if ( !handlers ) {
  619. handlers = element;
  620. element = this.element;
  621. delegateElement = this.widget();
  622. } else {
  623. // accept selectors, DOM elements
  624. element = delegateElement = $( element );
  625. this.bindings = this.bindings.add( element );
  626. }
  627. $.each( handlers, function( event, handler ) {
  628. function handlerProxy() {
  629. // allow widgets to customize the disabled handling
  630. // - disabled as an array instead of boolean
  631. // - disabled class as method for disabling individual parts
  632. if ( !suppressDisabledCheck &&
  633. ( instance.options.disabled === true ||
  634. $( this ).hasClass( "ui-state-disabled" ) ) ) {
  635. return;
  636. }
  637. return ( typeof handler === "string" ? instance[ handler ] : handler )
  638. .apply( instance, arguments );
  639. }
  640. // copy the guid so direct unbinding works
  641. if ( typeof handler !== "string" ) {
  642. handlerProxy.guid = handler.guid =
  643. handler.guid || handlerProxy.guid || $.guid++;
  644. }
  645. var match = event.match( /^(\w+)\s*(.*)$/ ),
  646. eventName = match[1] + instance.eventNamespace,
  647. selector = match[2];
  648. if ( selector ) {
  649. delegateElement.delegate( selector, eventName, handlerProxy );
  650. } else {
  651. element.bind( eventName, handlerProxy );
  652. }
  653. });
  654. },
  655. _off: function( element, eventName ) {
  656. eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
  657. element.unbind( eventName ).undelegate( eventName );
  658. },
  659. _delay: function( handler, delay ) {
  660. function handlerProxy() {
  661. return ( typeof handler === "string" ? instance[ handler ] : handler )
  662. .apply( instance, arguments );
  663. }
  664. var instance = this;
  665. return setTimeout( handlerProxy, delay || 0 );
  666. },
  667. _hoverable: function( element ) {
  668. this.hoverable = this.hoverable.add( element );
  669. this._on( element, {
  670. mouseenter: function( event ) {
  671. $( event.currentTarget ).addClass( "ui-state-hover" );
  672. },
  673. mouseleave: function( event ) {
  674. $( event.currentTarget ).removeClass( "ui-state-hover" );
  675. }
  676. });
  677. },
  678. _focusable: function( element ) {
  679. this.focusable = this.focusable.add( element );
  680. this._on( element, {
  681. focusin: function( event ) {
  682. $( event.currentTarget ).addClass( "ui-state-focus" );
  683. },
  684. focusout: function( event ) {
  685. $( event.currentTarget ).removeClass( "ui-state-focus" );
  686. }
  687. });
  688. },
  689. _trigger: function( type, event, data ) {
  690. var prop, orig,
  691. callback = this.options[ type ];
  692. data = data || {};
  693. event = $.Event( event );
  694. event.type = ( type === this.widgetEventPrefix ?
  695. type :
  696. this.widgetEventPrefix + type ).toLowerCase();
  697. // the original event may come from any element
  698. // so we need to reset the target on the new event
  699. event.target = this.element[ 0 ];
  700. // copy original event properties over to the new event
  701. orig = event.originalEvent;
  702. if ( orig ) {
  703. for ( prop in orig ) {
  704. if ( !( prop in event ) ) {
  705. event[ prop ] = orig[ prop ];
  706. }
  707. }
  708. }
  709. this.element.trigger( event, data );
  710. return !( $.isFunction( callback ) &&
  711. callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
  712. event.isDefaultPrevented() );
  713. }
  714. };
  715. $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
  716. $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
  717. if ( typeof options === "string" ) {
  718. options = { effect: options };
  719. }
  720. var hasOptions,
  721. effectName = !options ?
  722. method :
  723. options === true || typeof options === "number" ?
  724. defaultEffect :
  725. options.effect || defaultEffect;
  726. options = options || {};
  727. if ( typeof options === "number" ) {
  728. options = { duration: options };
  729. }
  730. hasOptions = !$.isEmptyObject( options );
  731. options.complete = callback;
  732. if ( options.delay ) {
  733. element.delay( options.delay );
  734. }
  735. if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
  736. element[ method ]( options );
  737. } else if ( effectName !== method && element[ effectName ] ) {
  738. element[ effectName ]( options.duration, options.easing, callback );
  739. } else {
  740. element.queue(function( next ) {
  741. $( this )[ method ]();
  742. if ( callback ) {
  743. callback.call( element[ 0 ] );
  744. }
  745. next();
  746. });
  747. }
  748. };
  749. });
  750. })( jQuery );
  751. /*!
  752. * jQuery UI Mouse 1.10.4
  753. * http://jqueryui.com
  754. *
  755. * Copyright 2014 jQuery Foundation and other contributors
  756. * Released under the MIT license.
  757. * http://jquery.org/license
  758. *
  759. * http://api.jqueryui.com/mouse/
  760. *
  761. * Depends:
  762. * jquery.ui.widget.js
  763. */
  764. (function( $, undefined ) {
  765. var mouseHandled = false;
  766. $( document ).mouseup( function() {
  767. mouseHandled = false;
  768. });
  769. $.widget("ui.mouse", {
  770. version: "1.10.4",
  771. options: {
  772. cancel: "input,textarea,button,select,option",
  773. distance: 1,
  774. delay: 0
  775. },
  776. _mouseInit: function() {
  777. var that = this;
  778. this.element
  779. .bind("mousedown."+this.widgetName, function(event) {
  780. return that._mouseDown(event);
  781. })
  782. .bind("click."+this.widgetName, function(event) {
  783. if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
  784. $.removeData(event.target, that.widgetName + ".preventClickEvent");
  785. event.stopImmediatePropagation();
  786. return false;
  787. }
  788. });
  789. this.started = false;
  790. },
  791. // TODO: make sure destroying one instance of mouse doesn't mess with
  792. // other instances of mouse
  793. _mouseDestroy: function() {
  794. this.element.unbind("."+this.widgetName);
  795. if ( this._mouseMoveDelegate ) {
  796. $(document)
  797. .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
  798. .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
  799. }
  800. },
  801. _mouseDown: function(event) {
  802. // don't let more than one widget handle mouseStart
  803. if( mouseHandled ) { return; }
  804. // we may have missed mouseup (out of window)
  805. (this._mouseStarted && this._mouseUp(event));
  806. this._mouseDownEvent = event;
  807. var that = this,
  808. btnIsLeft = (event.which === 1),
  809. // event.target.nodeName works around a bug in IE 8 with
  810. // disabled inputs (#7620)
  811. elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
  812. if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
  813. return true;
  814. }
  815. this.mouseDelayMet = !this.options.delay;
  816. if (!this.mouseDelayMet) {
  817. this._mouseDelayTimer = setTimeout(function() {
  818. that.mouseDelayMet = true;
  819. }, this.options.delay);
  820. }
  821. if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
  822. this._mouseStarted = (this._mouseStart(event) !== false);
  823. if (!this._mouseStarted) {
  824. event.preventDefault();
  825. return true;
  826. }
  827. }
  828. // Click event may never have fired (Gecko & Opera)
  829. if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
  830. $.removeData(event.target, this.widgetName + ".preventClickEvent");
  831. }
  832. // these delegates are required to keep context
  833. this._mouseMoveDelegate = function(event) {
  834. return that._mouseMove(event);
  835. };
  836. this._mouseUpDelegate = function(event) {
  837. return that._mouseUp(event);
  838. };
  839. $(document)
  840. .bind("mousemove."+this.widgetName, this._mouseMoveDelegate)
  841. .bind("mouseup."+this.widgetName, this._mouseUpDelegate);
  842. event.preventDefault();
  843. mouseHandled = true;
  844. return true;
  845. },
  846. _mouseMove: function(event) {
  847. // IE mouseup check - mouseup happened when mouse was out of window
  848. if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
  849. return this._mouseUp(event);
  850. }
  851. if (this._mouseStarted) {
  852. this._mouseDrag(event);
  853. return event.preventDefault();
  854. }
  855. if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
  856. this._mouseStarted =
  857. (this._mouseStart(this._mouseDownEvent, event) !== false);
  858. (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
  859. }
  860. return !this._mouseStarted;
  861. },
  862. _mouseUp: function(event) {
  863. $(document)
  864. .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
  865. .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
  866. if (this._mouseStarted) {
  867. this._mouseStarted = false;
  868. if (event.target === this._mouseDownEvent.target) {
  869. $.data(event.target, this.widgetName + ".preventClickEvent", true);
  870. }
  871. this._mouseStop(event);
  872. }
  873. return false;
  874. },
  875. _mouseDistanceMet: function(event) {
  876. return (Math.max(
  877. Math.abs(this._mouseDownEvent.pageX - event.pageX),
  878. Math.abs(this._mouseDownEvent.pageY - event.pageY)
  879. ) >= this.options.distance
  880. );
  881. },
  882. _mouseDelayMet: function(/* event */) {
  883. return this.mouseDelayMet;
  884. },
  885. // These are placeholder methods, to be overriden by extending plugin
  886. _mouseStart: function(/* event */) {},
  887. _mouseDrag: function(/* event */) {},
  888. _mouseStop: function(/* event */) {},
  889. _mouseCapture: function(/* event */) { return true; }
  890. });
  891. })(jQuery);
  892. /*!
  893. * jQuery UI Position 1.10.4
  894. * http://jqueryui.com
  895. *
  896. * Copyright 2014 jQuery Foundation and other contributors
  897. * Released under the MIT license.
  898. * http://jquery.org/license
  899. *
  900. * http://api.jqueryui.com/position/
  901. */
  902. (function( $, undefined ) {
  903. $.ui = $.ui || {};
  904. var cachedScrollbarWidth,
  905. max = Math.max,
  906. abs = Math.abs,
  907. round = Math.round,
  908. rhorizontal = /left|center|right/,
  909. rvertical = /top|center|bottom/,
  910. roffset = /[\+\-]\d+(\.[\d]+)?%?/,
  911. rposition = /^\w+/,
  912. rpercent = /%$/,
  913. _position = $.fn.position;
  914. function getOffsets( offsets, width, height ) {
  915. return [
  916. parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
  917. parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
  918. ];
  919. }
  920. function parseCss( element, property ) {
  921. return parseInt( $.css( element, property ), 10 ) || 0;
  922. }
  923. function getDimensions( elem ) {
  924. var raw = elem[0];
  925. if ( raw.nodeType === 9 ) {
  926. return {
  927. width: elem.width(),
  928. height: elem.height(),
  929. offset: { top: 0, left: 0 }
  930. };
  931. }
  932. if ( $.isWindow( raw ) ) {
  933. return {
  934. width: elem.width(),
  935. height: elem.height(),
  936. offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
  937. };
  938. }
  939. if ( raw.preventDefault ) {
  940. return {
  941. width: 0,
  942. height: 0,
  943. offset: { top: raw.pageY, left: raw.pageX }
  944. };
  945. }
  946. return {
  947. width: elem.outerWidth(),
  948. height: elem.outerHeight(),
  949. offset: elem.offset()
  950. };
  951. }
  952. $.position = {
  953. scrollbarWidth: function() {
  954. if ( cachedScrollbarWidth !== undefined ) {
  955. return cachedScrollbarWidth;
  956. }
  957. var w1, w2,
  958. div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
  959. innerDiv = div.children()[0];
  960. $( "body" ).append( div );
  961. w1 = innerDiv.offsetWidth;
  962. div.css( "overflow", "scroll" );
  963. w2 = innerDiv.offsetWidth;
  964. if ( w1 === w2 ) {
  965. w2 = div[0].clientWidth;
  966. }
  967. div.remove();
  968. return (cachedScrollbarWidth = w1 - w2);
  969. },
  970. getScrollInfo: function( within ) {
  971. var overflowX = within.isWindow || within.isDocument ? "" :
  972. within.element.css( "overflow-x" ),
  973. overflowY = within.isWindow || within.isDocument ? "" :
  974. within.element.css( "overflow-y" ),
  975. hasOverflowX = overflowX === "scroll" ||
  976. ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
  977. hasOverflowY = overflowY === "scroll" ||
  978. ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
  979. return {
  980. width: hasOverflowY ? $.position.scrollbarWidth() : 0,
  981. height: hasOverflowX ? $.position.scrollbarWidth() : 0
  982. };
  983. },
  984. getWithinInfo: function( element ) {
  985. var withinElement = $( element || window ),
  986. isWindow = $.isWindow( withinElement[0] ),
  987. isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
  988. return {
  989. element: withinElement,
  990. isWindow: isWindow,
  991. isDocument: isDocument,
  992. offset: withinElement.offset() || { left: 0, top: 0 },
  993. scrollLeft: withinElement.scrollLeft(),
  994. scrollTop: withinElement.scrollTop(),
  995. width: isWindow ? withinElement.width() : withinElement.outerWidth(),
  996. height: isWindow ? withinElement.height() : withinElement.outerHeight()
  997. };
  998. }
  999. };
  1000. $.fn.position = function( options ) {
  1001. if ( !options || !options.of ) {
  1002. return _position.apply( this, arguments );
  1003. }
  1004. // make a copy, we don't want to modify arguments
  1005. options = $.extend( {}, options );
  1006. var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
  1007. target = $( options.of ),
  1008. within = $.position.getWithinInfo( options.within ),
  1009. scrollInfo = $.position.getScrollInfo( within ),
  1010. collision = ( options.collision || "flip" ).split( " " ),
  1011. offsets = {};
  1012. dimensions = getDimensions( target );
  1013. if ( target[0].preventDefault ) {
  1014. // force left top to allow flipping
  1015. options.at = "left top";
  1016. }
  1017. targetWidth = dimensions.width;
  1018. targetHeight = dimensions.height;
  1019. targetOffset = dimensions.offset;
  1020. // clone to reuse original targetOffset later
  1021. basePosition = $.extend( {}, targetOffset );
  1022. // force my and at to have valid horizontal and vertical positions
  1023. // if a value is missing or invalid, it will be converted to center
  1024. $.each( [ "my", "at" ], function() {
  1025. var pos = ( options[ this ] || "" ).split( " " ),
  1026. horizontalOffset,
  1027. verticalOffset;
  1028. if ( pos.length === 1) {
  1029. pos = rhorizontal.test( pos[ 0 ] ) ?
  1030. pos.concat( [ "center" ] ) :
  1031. rvertical.test( pos[ 0 ] ) ?
  1032. [ "center" ].concat( pos ) :
  1033. [ "center", "center" ];
  1034. }
  1035. pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
  1036. pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
  1037. // calculate offsets
  1038. horizontalOffset = roffset.exec( pos[ 0 ] );
  1039. verticalOffset = roffset.exec( pos[ 1 ] );
  1040. offsets[ this ] = [
  1041. horizontalOffset ? horizontalOffset[ 0 ] : 0,
  1042. verticalOffset ? verticalOffset[ 0 ] : 0
  1043. ];
  1044. // reduce to just the positions without the offsets
  1045. options[ this ] = [
  1046. rposition.exec( pos[ 0 ] )[ 0 ],
  1047. rposition.exec( pos[ 1 ] )[ 0 ]
  1048. ];
  1049. });
  1050. // normalize collision option
  1051. if ( collision.length === 1 ) {
  1052. collision[ 1 ] = collision[ 0 ];
  1053. }
  1054. if ( options.at[ 0 ] === "right" ) {
  1055. basePosition.left += targetWidth;
  1056. } else if ( options.at[ 0 ] === "center" ) {
  1057. basePosition.left += targetWidth / 2;
  1058. }
  1059. if ( options.at[ 1 ] === "bottom" ) {
  1060. basePosition.top += targetHeight;
  1061. } else if ( options.at[ 1 ] === "center" ) {
  1062. basePosition.top += targetHeight / 2;
  1063. }
  1064. atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
  1065. basePosition.left += atOffset[ 0 ];
  1066. basePosition.top += atOffset[ 1 ];
  1067. return this.each(function() {
  1068. var collisionPosition, using,
  1069. elem = $( this ),
  1070. elemWidth = elem.outerWidth(),
  1071. elemHeight = elem.outerHeight(),
  1072. marginLeft = parseCss( this, "marginLeft" ),
  1073. marginTop = parseCss( this, "marginTop" ),
  1074. collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
  1075. collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
  1076. position = $.extend( {}, basePosition ),
  1077. myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
  1078. if ( options.my[ 0 ] === "right" ) {
  1079. position.left -= elemWidth;
  1080. } else if ( options.my[ 0 ] === "center" ) {
  1081. position.left -= elemWidth / 2;
  1082. }
  1083. if ( options.my[ 1 ] === "bottom" ) {
  1084. position.top -= elemHeight;
  1085. } else if ( options.my[ 1 ] === "center" ) {
  1086. position.top -= elemHeight / 2;
  1087. }
  1088. position.left += myOffset[ 0 ];
  1089. position.top += myOffset[ 1 ];
  1090. // if the browser doesn't support fractions, then round for consistent results
  1091. if ( !$.support.offsetFractions ) {
  1092. position.left = round( position.left );
  1093. position.top = round( position.top );
  1094. }
  1095. collisionPosition = {
  1096. marginLeft: marginLeft,
  1097. marginTop: marginTop
  1098. };
  1099. $.each( [ "left", "top" ], function( i, dir ) {
  1100. if ( $.ui.position[ collision[ i ] ] ) {
  1101. $.ui.position[ collision[ i ] ][ dir ]( position, {
  1102. targetWidth: targetWidth,
  1103. targetHeight: targetHeight,
  1104. elemWidth: elemWidth,
  1105. elemHeight: elemHeight,
  1106. collisionPosition: collisionPosition,
  1107. collisionWidth: collisionWidth,
  1108. collisionHeight: collisionHeight,
  1109. offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
  1110. my: options.my,
  1111. at: options.at,
  1112. within: within,
  1113. elem : elem
  1114. });
  1115. }
  1116. });
  1117. if ( options.using ) {
  1118. // adds feedback as second argument to using callback, if present
  1119. using = function( props ) {
  1120. var left = targetOffset.left - position.left,
  1121. right = left + targetWidth - elemWidth,
  1122. top = targetOffset.top - position.top,
  1123. bottom = top + targetHeight - elemHeight,
  1124. feedback = {
  1125. target: {
  1126. element: target,
  1127. left: targetOffset.left,
  1128. top: targetOffset.top,
  1129. width: targetWidth,
  1130. height: targetHeight
  1131. },
  1132. element: {
  1133. element: elem,
  1134. left: position.left,
  1135. top: position.top,
  1136. width: elemWidth,
  1137. height: elemHeight
  1138. },
  1139. horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
  1140. vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
  1141. };
  1142. if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
  1143. feedback.horizontal = "center";
  1144. }
  1145. if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
  1146. feedback.vertical = "middle";
  1147. }
  1148. if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
  1149. feedback.important = "horizontal";
  1150. } else {
  1151. feedback.important = "vertical";
  1152. }
  1153. options.using.call( this, props, feedback );
  1154. };
  1155. }
  1156. elem.offset( $.extend( position, { using: using } ) );
  1157. });
  1158. };
  1159. $.ui.position = {
  1160. fit: {
  1161. left: function( position, data ) {
  1162. var within = data.within,
  1163. withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
  1164. outerWidth = within.width,
  1165. collisionPosLeft = position.left - data.collisionPosition.marginLeft,
  1166. overLeft = withinOffset - collisionPosLeft,
  1167. overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
  1168. newOverRight;
  1169. // element is wider than within
  1170. if ( data.collisionWidth > outerWidth ) {
  1171. // element is initially over the left side of within
  1172. if ( overLeft > 0 && overRight <= 0 ) {
  1173. newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
  1174. position.left += overLeft - newOverRight;
  1175. // element is initially over right side of within
  1176. } else if ( overRight > 0 && overLeft <= 0 ) {
  1177. position.left = withinOffset;
  1178. // element is initially over both left and right sides of within
  1179. } else {
  1180. if ( overLeft > overRight ) {
  1181. position.left = withinOffset + outerWidth - data.collisionWidth;
  1182. } else {
  1183. position.left = withinOffset;
  1184. }
  1185. }
  1186. // too far left -> align with left edge
  1187. } else if ( overLeft > 0 ) {
  1188. position.left += overLeft;
  1189. // too far right -> align with right edge
  1190. } else if ( overRight > 0 ) {
  1191. position.left -= overRight;
  1192. // adjust based on position and margin
  1193. } else {
  1194. position.left = max( position.left - collisionPosLeft, position.left );
  1195. }
  1196. },
  1197. top: function( position, data ) {
  1198. var within = data.within,
  1199. withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
  1200. outerHeight = data.within.height,
  1201. collisionPosTop = position.top - data.collisionPosition.marginTop,
  1202. overTop = withinOffset - collisionPosTop,
  1203. overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
  1204. newOverBottom;
  1205. // element is taller than within
  1206. if ( data.collisionHeight > outerHeight ) {
  1207. // element is initially over the top of within
  1208. if ( overTop > 0 && overBottom <= 0 ) {
  1209. newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
  1210. position.top += overTop - newOverBottom;
  1211. // element is initially over bottom of within
  1212. } else if ( overBottom > 0 && overTop <= 0 ) {
  1213. position.top = withinOffset;
  1214. // element is initially over both top and bottom of within
  1215. } else {
  1216. if ( overTop > overBottom ) {
  1217. position.top = withinOffset + outerHeight - data.collisionHeight;
  1218. } else {
  1219. position.top = withinOffset;
  1220. }
  1221. }
  1222. // too far up -> align with top
  1223. } else if ( overTop > 0 ) {
  1224. position.top += overTop;
  1225. // too far down -> align with bottom edge
  1226. } else if ( overBottom > 0 ) {
  1227. position.top -= overBottom;
  1228. // adjust based on position and margin
  1229. } else {
  1230. position.top = max( position.top - collisionPosTop, position.top );
  1231. }
  1232. }
  1233. },
  1234. flip: {
  1235. left: function( position, data ) {
  1236. var within = data.within,
  1237. withinOffset = within.offset.left + within.scrollLeft,
  1238. outerWidth = within.width,
  1239. offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
  1240. collisionPosLeft = position.left - data.collisionPosition.marginLeft,
  1241. overLeft = collisionPosLeft - offsetLeft,
  1242. overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
  1243. myOffset = data.my[ 0 ] === "left" ?
  1244. -data.elemWidth :
  1245. data.my[ 0 ] === "right" ?
  1246. data.elemWidth :
  1247. 0,
  1248. atOffset = data.at[ 0 ] === "left" ?
  1249. data.targetWidth :
  1250. data.at[ 0 ] === "right" ?
  1251. -data.targetWidth :
  1252. 0,
  1253. offset = -2 * data.offset[ 0 ],
  1254. newOverRight,
  1255. newOverLeft;
  1256. if ( overLeft < 0 ) {
  1257. newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
  1258. if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
  1259. position.left += myOffset + atOffset + offset;
  1260. }
  1261. }
  1262. else if ( overRight > 0 ) {
  1263. newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
  1264. if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
  1265. position.left += myOffset + atOffset + offset;
  1266. }
  1267. }
  1268. },
  1269. top: function( position, data ) {
  1270. var within = data.within,
  1271. withinOffset = within.offset.top + within.scrollTop,
  1272. outerHeight = within.height,
  1273. offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
  1274. collisionPosTop = position.top - data.collisionPosition.marginTop,
  1275. overTop = collisionPosTop - offsetTop,
  1276. overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
  1277. top = data.my[ 1 ] === "top",
  1278. myOffset = top ?
  1279. -data.elemHeight :
  1280. data.my[ 1 ] === "bottom" ?
  1281. data.elemHeight :
  1282. 0,
  1283. atOffset = data.at[ 1 ] === "top" ?
  1284. data.targetHeight :
  1285. data.at[ 1 ] === "bottom" ?
  1286. -data.targetHeight :
  1287. 0,
  1288. offset = -2 * data.offset[ 1 ],
  1289. newOverTop,
  1290. newOverBottom;
  1291. if ( overTop < 0 ) {
  1292. newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
  1293. if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
  1294. position.top += myOffset + atOffset + offset;
  1295. }
  1296. }
  1297. else if ( overBottom > 0 ) {
  1298. newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
  1299. if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
  1300. position.top += myOffset + atOffset + offset;
  1301. }
  1302. }
  1303. }
  1304. },
  1305. flipfit: {
  1306. left: function() {
  1307. $.ui.position.flip.left.apply( this, arguments );
  1308. $.ui.position.fit.left.apply( this, arguments );
  1309. },
  1310. top: function() {
  1311. $.ui.position.flip.top.apply( this, arguments );
  1312. $.ui.position.fit.top.apply( this, arguments );
  1313. }
  1314. }
  1315. };
  1316. // fraction support test
  1317. (function () {
  1318. var testElement, testElementParent, testElementStyle, offsetLeft, i,
  1319. body = document.getElementsByTagName( "body" )[ 0 ],
  1320. div = document.createElement( "div" );
  1321. //Create a "fake body" for testing based on method used in jQuery.support
  1322. testElement = document.createElement( body ? "div" : "body" );
  1323. testElementStyle = {
  1324. visibility: "hidden",
  1325. width: 0,
  1326. height: 0,
  1327. border: 0,
  1328. margin: 0,
  1329. background: "none"
  1330. };
  1331. if ( body ) {
  1332. $.extend( testElementStyle, {
  1333. position: "absolute",
  1334. left: "-1000px",
  1335. top: "-1000px"
  1336. });
  1337. }
  1338. for ( i in testElementStyle ) {
  1339. testElement.style[ i ] = testElementStyle[ i ];
  1340. }
  1341. testElement.appendChild( div );
  1342. testElementParent = body || document.documentElement;
  1343. testElementParent.insertBefore( testElement, testElementParent.firstChild );
  1344. div.style.cssText = "position: absolute; left: 10.7432222px;";
  1345. offsetLeft = $( div ).offset().left;
  1346. $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
  1347. testElement.innerHTML = "";
  1348. testElementParent.removeChild( testElement );
  1349. })();
  1350. }( jQuery ) );
  1351. /*!
  1352. * jQuery UI Button 1.10.4
  1353. * http://jqueryui.com
  1354. *
  1355. * Copyright 2014 jQuery Foundation and other contributors
  1356. * Released under the MIT license.
  1357. * http://jquery.org/license
  1358. *
  1359. * http://api.jqueryui.com/button/
  1360. *
  1361. * Depends:
  1362. * jquery.ui.core.js
  1363. * jquery.ui.widget.js
  1364. */
  1365. (function( $, undefined ) {
  1366. var lastActive,
  1367. baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
  1368. typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
  1369. formResetHandler = function() {
  1370. var form = $( this );
  1371. setTimeout(function() {
  1372. form.find( ":ui-button" ).button( "refresh" );
  1373. }, 1 );
  1374. },
  1375. radioGroup = function( radio ) {
  1376. var name = radio.name,
  1377. form = radio.form,
  1378. radios = $( [] );
  1379. if ( name ) {
  1380. name = name.replace( /'/g, "\\'" );
  1381. if ( form ) {
  1382. radios = $( form ).find( "[name='" + name + "']" );
  1383. } else {
  1384. radios = $( "[name='" + name + "']", radio.ownerDocument )
  1385. .filter(function() {
  1386. return !this.form;
  1387. });
  1388. }
  1389. }
  1390. return radios;
  1391. };
  1392. $.widget( "ui.button", {
  1393. version: "1.10.4",
  1394. defaultElement: "<button>",
  1395. options: {
  1396. disabled: null,
  1397. text: true,
  1398. label: null,
  1399. icons: {
  1400. primary: null,
  1401. secondary: null
  1402. }
  1403. },
  1404. _create: function() {
  1405. this.element.closest( "form" )
  1406. .unbind( "reset" + this.eventNamespace )
  1407. .bind( "reset" + this.eventNamespace, formResetHandler );
  1408. if ( typeof this.options.disabled !== "boolean" ) {
  1409. this.options.disabled = !!this.element.prop( "disabled" );
  1410. } else {
  1411. this.element.prop( "disabled", this.options.disabled );
  1412. }
  1413. this._determineButtonType();
  1414. this.hasTitle = !!this.buttonElement.attr( "title" );
  1415. var that = this,
  1416. options = this.options,
  1417. toggleButton = this.type === "checkbox" || this.type === "radio",
  1418. activeClass = !toggleButton ? "ui-state-active" : "";
  1419. if ( options.label === null ) {
  1420. options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
  1421. }
  1422. this._hoverable( this.buttonElement );
  1423. this.buttonElement
  1424. .addClass( baseClasses )
  1425. .attr( "role", "button" )
  1426. .bind( "mouseenter" + this.eventNamespace, function() {
  1427. if ( options.disabled ) {
  1428. return;
  1429. }
  1430. if ( this === lastActive ) {
  1431. $( this ).addClass( "ui-state-active" );
  1432. }
  1433. })
  1434. .bind( "mouseleave" + this.eventNamespace, function() {
  1435. if ( options.disabled ) {
  1436. return;
  1437. }
  1438. $( this ).removeClass( activeClass );
  1439. })
  1440. .bind( "click" + this.eventNamespace, function( event ) {
  1441. if ( options.disabled ) {
  1442. event.preventDefault();
  1443. event.stopImmediatePropagation();
  1444. }
  1445. });
  1446. // Can't use _focusable() because the element that receives focus
  1447. // and the element that gets the ui-state-focus class are different
  1448. this._on({
  1449. focus: function() {
  1450. this.buttonElement.addClass( "ui-state-focus" );
  1451. },
  1452. blur: function() {
  1453. this.buttonElement.removeClass( "ui-state-focus" );
  1454. }
  1455. });
  1456. if ( toggleButton ) {
  1457. this.element.bind( "change" + this.eventNamespace, function() {
  1458. that.refresh();
  1459. });
  1460. }
  1461. if ( this.type === "checkbox" ) {
  1462. this.buttonElement.bind( "click" + this.eventNamespace, function() {
  1463. if ( options.disabled ) {
  1464. return false;
  1465. }
  1466. });
  1467. } else if ( this.type === "radio" ) {
  1468. this.buttonElement.bind( "click" + this.eventNamespace, function() {
  1469. if ( options.disabled ) {
  1470. return false;
  1471. }
  1472. $( this ).addClass( "ui-state-active" );
  1473. that.buttonElement.attr( "aria-pressed", "true" );
  1474. var radio = that.element[ 0 ];
  1475. radioGroup( radio )
  1476. .not( radio )
  1477. .map(function() {
  1478. return $( this ).button( "widget" )[ 0 ];
  1479. })
  1480. .removeClass( "ui-state-active" )
  1481. .attr( "aria-pressed", "false" );
  1482. });
  1483. } else {
  1484. this.buttonElement
  1485. .bind( "mousedown" + this.eventNamespace, function() {
  1486. if ( options.disabled ) {
  1487. return false;
  1488. }
  1489. $( this ).addClass( "ui-state-active" );
  1490. lastActive = this;
  1491. that.document.one( "mouseup", function() {
  1492. lastActive = null;
  1493. });
  1494. })
  1495. .bind( "mouseup" + this.eventNamespace, function() {
  1496. if ( options.disabled ) {
  1497. return false;
  1498. }
  1499. $( this ).removeClass( "ui-state-active" );
  1500. })
  1501. .bind( "keydown" + this.eventNamespace, function(event) {
  1502. if ( options.disabled ) {
  1503. return false;
  1504. }
  1505. if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
  1506. $( this ).addClass( "ui-state-active" );
  1507. }
  1508. })
  1509. // see #8559, we bind to blur here in case the button element loses
  1510. // focus between keydown and keyup, it would be left in an "active" state
  1511. .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
  1512. $( this ).removeClass( "ui-state-active" );
  1513. });
  1514. if ( this.buttonElement.is("a") ) {
  1515. this.buttonElement.keyup(function(event) {
  1516. if ( event.keyCode === $.ui.keyCode.SPACE ) {
  1517. // TODO pass through original event correctly (just as 2nd argument doesn't work)
  1518. $( this ).click();
  1519. }
  1520. });
  1521. }
  1522. }
  1523. // TODO: pull out $.Widget's handling for the disabled option into
  1524. // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
  1525. // be overridden by individual plugins
  1526. this._setOption( "disabled", options.disabled );
  1527. this._resetButton();
  1528. },
  1529. _determineButtonType: function() {
  1530. var ancestor, labelSelector, checked;
  1531. if ( this.element.is("[type=checkbox]") ) {
  1532. this.type = "checkbox";
  1533. } else if ( this.element.is("[type=radio]") ) {
  1534. this.type = "radio";
  1535. } else if ( this.element.is("input") ) {
  1536. this.type = "input";
  1537. } else {
  1538. this.type = "button";
  1539. }
  1540. if ( this.type === "checkbox" || this.type === "radio" ) {
  1541. // we don't search against the document in case the element
  1542. // is disconnected from the DOM
  1543. ancestor = this.element.parents().last();
  1544. labelSelector = "label[for='" + this.element.attr("id") + "']";
  1545. this.buttonElement = ancestor.find( labelSelector );
  1546. if ( !this.buttonElement.length ) {
  1547. ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
  1548. this.buttonElement = ancestor.filter( labelSelector );
  1549. if ( !this.buttonElement.length ) {
  1550. this.buttonElement = ancestor.find( labelSelector );
  1551. }
  1552. }
  1553. this.element.addClass( "ui-helper-hidden-accessible" );
  1554. checked = this.element.is( ":checked" );
  1555. if ( checked ) {
  1556. this.buttonElement.addClass( "ui-state-active" );
  1557. }
  1558. this.buttonElement.prop( "aria-pressed", checked );
  1559. } else {
  1560. this.buttonElement = this.element;
  1561. }
  1562. },
  1563. widget: function() {
  1564. return this.buttonElement;
  1565. },
  1566. _destroy: function() {
  1567. this.element
  1568. .removeClass( "ui-helper-hidden-accessible" );
  1569. this.buttonElement
  1570. .removeClass( baseClasses + " ui-state-active " + typeClasses )
  1571. .removeAttr( "role" )
  1572. .removeAttr( "aria-pressed" )
  1573. .html( this.buttonElement.find(".ui-button-text").html() );
  1574. if ( !this.hasTitle ) {
  1575. this.buttonElement.removeAttr( "title" );
  1576. }
  1577. },
  1578. _setOption: function( key, value ) {
  1579. this._super( key, value );
  1580. if ( key === "disabled" ) {
  1581. this.element.prop( "disabled", !!value );
  1582. if ( value ) {
  1583. this.buttonElement.removeClass( "ui-state-focus" );
  1584. }
  1585. return;
  1586. }
  1587. this._resetButton();
  1588. },
  1589. refresh: function() {
  1590. //See #8237 & #8828
  1591. var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
  1592. if ( isDisabled !== this.options.disabled ) {
  1593. this._setOption( "disabled", isDisabled );
  1594. }
  1595. if ( this.type === "radio" ) {
  1596. radioGroup( this.element[0] ).each(function() {
  1597. if ( $( this ).is( ":checked" ) ) {
  1598. $( this ).button( "widget" )
  1599. .addClass( "ui-state-active" )
  1600. .attr( "aria-pressed", "true" );
  1601. } else {
  1602. $( this ).button( "widget" )
  1603. .removeClass( "ui-state-active" )
  1604. .attr( "aria-pressed", "false" );
  1605. }
  1606. });
  1607. } else if ( this.type === "checkbox" ) {
  1608. if ( this.element.is( ":checked" ) ) {
  1609. this.buttonElement
  1610. .addClass( "ui-state-active" )
  1611. .attr( "aria-pressed", "true" );
  1612. } else {
  1613. this.buttonElement
  1614. .removeClass( "ui-state-active" )
  1615. .attr( "aria-pressed", "false" );
  1616. }
  1617. }
  1618. },
  1619. _resetButton: function() {
  1620. if ( this.type === "input" ) {
  1621. if ( this.options.label ) {
  1622. this.element.val( this.options.label );
  1623. }
  1624. return;
  1625. }
  1626. var buttonElement = this.buttonElement.removeClass( typeClasses ),
  1627. buttonText = $( "<span></span>", this.document[0] )
  1628. .addClass( "ui-button-text" )
  1629. .html( this.options.label )
  1630. .appendTo( buttonElement.empty() )
  1631. .text(),
  1632. icons = this.options.icons,
  1633. multipleIcons = icons.primary && icons.secondary,
  1634. buttonClasses = [];
  1635. if ( icons.primary || icons.secondary ) {
  1636. if ( this.options.text ) {
  1637. buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
  1638. }
  1639. if ( icons.primary ) {
  1640. buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
  1641. }
  1642. if ( icons.secondary ) {
  1643. buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
  1644. }
  1645. if ( !this.options.text ) {
  1646. buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
  1647. if ( !this.hasTitle ) {
  1648. buttonElement.attr( "title", $.trim( buttonText ) );
  1649. }
  1650. }
  1651. } else {
  1652. buttonClasses.push( "ui-button-text-only" );
  1653. }
  1654. buttonElement.addClass( buttonClasses.join( " " ) );
  1655. }
  1656. });
  1657. $.widget( "ui.buttonset", {
  1658. version: "1.10.4",
  1659. options: {
  1660. items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
  1661. },
  1662. _create: function() {
  1663. this.element.addClass( "ui-buttonset" );
  1664. },
  1665. _init: function() {
  1666. this.refresh();
  1667. },
  1668. _setOption: function( key, value ) {
  1669. if ( key === "disabled" ) {
  1670. this.buttons.button( "option", key, value );
  1671. }
  1672. this._super( key, value );
  1673. },
  1674. refresh: function() {
  1675. var rtl = this.element.css( "direction" ) === "rtl";
  1676. this.buttons = this.element.find( this.options.items )
  1677. .filter( ":ui-button" )
  1678. .button( "refresh" )
  1679. .end()
  1680. .not( ":ui-button" )
  1681. .button()
  1682. .end()
  1683. .map(function() {
  1684. return $( this ).button( "widget" )[ 0 ];
  1685. })
  1686. .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
  1687. .filter( ":first" )
  1688. .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
  1689. .end()
  1690. .filter( ":last" )
  1691. .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
  1692. .end()
  1693. .end();
  1694. },
  1695. _destroy: function() {
  1696. this.element.removeClass( "ui-buttonset" );
  1697. this.buttons
  1698. .map(function() {
  1699. return $( this ).button( "widget" )[ 0 ];
  1700. })
  1701. .removeClass( "ui-corner-left ui-corner-right" )
  1702. .end()
  1703. .button( "destroy" );
  1704. }
  1705. });
  1706. }( jQuery ) );
  1707. /*!
  1708. * jQuery UI Slider 1.10.4
  1709. * http://jqueryui.com
  1710. *
  1711. * Copyright 2014 jQuery Foundation and other contributors
  1712. * Released under the MIT license.
  1713. * http://jquery.org/license
  1714. *
  1715. * http://api.jqueryui.com/slider/
  1716. *
  1717. * Depends:
  1718. * jquery.ui.core.js
  1719. * jquery.ui.mouse.js
  1720. * jquery.ui.widget.js
  1721. */
  1722. (function( $, undefined ) {
  1723. // number of pages in a slider
  1724. // (how many times can you page up/down to go through the whole range)
  1725. var numPages = 5;
  1726. $.widget( "ui.slider", $.ui.mouse, {
  1727. version: "1.10.4",
  1728. widgetEventPrefix: "slide",
  1729. options: {
  1730. animate: false,
  1731. distance: 0,
  1732. max: 100,
  1733. min: 0,
  1734. orientation: "horizontal",
  1735. range: false,
  1736. step: 1,
  1737. value: 0,
  1738. values: null,
  1739. // callbacks
  1740. change: null,
  1741. slide: null,
  1742. start: null,
  1743. stop: null
  1744. },
  1745. _create: function() {
  1746. this._keySliding = false;
  1747. this._mouseSliding = false;
  1748. this._animateOff = true;
  1749. this._handleIndex = null;
  1750. this._detectOrientation();
  1751. this._mouseInit();
  1752. this.element
  1753. .addClass( "ui-slider" +
  1754. " ui-slider-" + this.orientation +
  1755. " ui-widget" +
  1756. " ui-widget-content" +
  1757. " ui-corner-all");
  1758. this._refresh();
  1759. this._setOption( "disabled", this.options.disabled );
  1760. this._animateOff = false;
  1761. },
  1762. _refresh: function() {
  1763. this._createRange();
  1764. this._createHandles();
  1765. this._setupEvents();
  1766. this._refreshValue();
  1767. },
  1768. _createHandles: function() {
  1769. var i, handleCount,
  1770. options = this.options,
  1771. existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
  1772. handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
  1773. handles = [];
  1774. handleCount = ( options.values && options.values.length ) || 1;
  1775. if ( existingHandles.length > handleCount ) {
  1776. existingHandles.slice( handleCount ).remove();
  1777. existingHandles = existingHandles.slice( 0, handleCount );
  1778. }
  1779. for ( i = existingHandles.length; i < handleCount; i++ ) {
  1780. handles.push( handle );
  1781. }
  1782. this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
  1783. this.handle = this.handles.eq( 0 );
  1784. this.handles.each(function( i ) {
  1785. $( this ).data( "ui-slider-handle-index", i );
  1786. });
  1787. },
  1788. _createRange: function() {
  1789. var options = this.options,
  1790. classes = "";
  1791. if ( options.range ) {
  1792. if ( options.range === true ) {
  1793. if ( !options.values ) {
  1794. options.values = [ this._valueMin(), this._valueMin() ];
  1795. } else if ( options.values.length && options.values.length !== 2 ) {
  1796. options.values = [ options.values[0], options.values[0] ];
  1797. } else if ( $.isArray( options.values ) ) {
  1798. options.values = options.values.slice(0);
  1799. }
  1800. }
  1801. if ( !this.range || !this.range.length ) {
  1802. this.range = $( "<div></div>" )
  1803. .appendTo( this.element );
  1804. classes = "ui-slider-range" +
  1805. // note: this isn't the most fittingly semantic framework class for this element,
  1806. // but worked best visually with a variety of themes
  1807. " ui-widget-header ui-corner-all";
  1808. } else {
  1809. this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
  1810. // Handle range switching from true to min/max
  1811. .css({
  1812. "left": "",
  1813. "bottom": ""
  1814. });
  1815. }
  1816. this.range.addClass( classes +
  1817. ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
  1818. } else {
  1819. if ( this.range ) {
  1820. this.range.remove();
  1821. }
  1822. this.range = null;
  1823. }
  1824. },
  1825. _setupEvents: function() {
  1826. var elements = this.handles.add( this.range ).filter( "a" );
  1827. this._off( elements );
  1828. this._on( elements, this._handleEvents );
  1829. this._hoverable( elements );
  1830. this._focusable( elements );
  1831. },
  1832. _destroy: function() {
  1833. this.handles.remove();
  1834. if ( this.range ) {
  1835. this.range.remove();
  1836. }
  1837. this.element
  1838. .removeClass( "ui-slider" +
  1839. " ui-slider-horizontal" +
  1840. " ui-slider-vertical" +
  1841. " ui-widget" +
  1842. " ui-widget-content" +
  1843. " ui-corner-all" );
  1844. this._mouseDestroy();
  1845. },
  1846. _mouseCapture: function( event ) {
  1847. var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
  1848. that = this,
  1849. o = this.options;
  1850. if ( o.disabled ) {
  1851. return false;
  1852. }
  1853. this.elementSize = {
  1854. width: this.element.outerWidth(),
  1855. height: this.element.outerHeight()
  1856. };
  1857. this.elementOffset = this.element.offset();
  1858. position = { x: event.pageX, y: event.pageY };
  1859. normValue = this._normValueFromMouse( position );
  1860. distance = this._valueMax() - this._valueMin() + 1;
  1861. this.handles.each(function( i ) {
  1862. var thisDistance = Math.abs( normValue - that.values(i) );
  1863. if (( distance > thisDistance ) ||
  1864. ( distance === thisDistance &&
  1865. (i === that._lastChangedValue || that.values(i) === o.min ))) {
  1866. distance = thisDistance;
  1867. closestHandle = $( this );
  1868. index = i;
  1869. }
  1870. });
  1871. allowed = this._start( event, index );
  1872. if ( allowed === false ) {
  1873. return false;
  1874. }
  1875. this._mouseSliding = true;
  1876. this._handleIndex = index;
  1877. closestHandle
  1878. .addClass( "ui-state-active" )
  1879. .focus();
  1880. offset = closestHandle.offset();
  1881. mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
  1882. this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
  1883. left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
  1884. top: event.pageY - offset.top -
  1885. ( closestHandle.height() / 2 ) -
  1886. ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
  1887. ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
  1888. ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
  1889. };
  1890. if ( !this.handles.hasClass( "ui-state-hover" ) ) {
  1891. this._slide( event, index, normValue );
  1892. }
  1893. this._animateOff = true;
  1894. return true;
  1895. },
  1896. _mouseStart: function() {
  1897. return true;
  1898. },
  1899. _mouseDrag: function( event ) {
  1900. var position = { x: event.pageX, y: event.pageY },
  1901. normValue = this._normValueFromMouse( position );
  1902. this._slide( event, this._handleIndex, normValue );
  1903. return false;
  1904. },
  1905. _mouseStop: function( event ) {
  1906. this.handles.removeClass( "ui-state-active" );
  1907. this._mouseSliding = false;
  1908. this._stop( event, this._handleIndex );
  1909. this._change( event, this._handleIndex );
  1910. this._handleIndex = null;
  1911. this._clickOffset = null;
  1912. this._animateOff = false;
  1913. return false;
  1914. },
  1915. _detectOrientation: function() {
  1916. this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
  1917. },
  1918. _normValueFromMouse: function( position ) {
  1919. var pixelTotal,
  1920. pixelMouse,
  1921. percentMouse,
  1922. valueTotal,
  1923. valueMouse;
  1924. if ( this.orientation === "horizontal" ) {
  1925. pixelTotal = this.elementSize.width;
  1926. pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
  1927. } else {
  1928. pixelTotal = this.elementSize.height;
  1929. pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
  1930. }
  1931. percentMouse = ( pixelMouse / pixelTotal );
  1932. if ( percentMouse > 1 ) {
  1933. percentMouse = 1;
  1934. }
  1935. if ( percentMouse < 0 ) {
  1936. percentMouse = 0;
  1937. }
  1938. if ( this.orientation === "vertical" ) {
  1939. percentMouse = 1 - percentMouse;
  1940. }
  1941. valueTotal = this._valueMax() - this._valueMin();
  1942. valueMouse = this._valueMin() + percentMouse * valueTotal;
  1943. return this._trimAlignValue( valueMouse );
  1944. },
  1945. _start: function( event, index ) {
  1946. var uiHash = {
  1947. handle: this.handles[ index ],
  1948. value: this.value()
  1949. };
  1950. if ( this.options.values && this.options.values.length ) {
  1951. uiHash.value = this.values( index );
  1952. uiHash.values = this.values();
  1953. }
  1954. return this._trigger( "start", event, uiHash );
  1955. },
  1956. _slide: function( event, index, newVal ) {
  1957. var otherVal,
  1958. newValues,
  1959. allowed;
  1960. if ( this.options.values && this.options.values.length ) {
  1961. otherVal = this.values( index ? 0 : 1 );
  1962. if ( ( this.options.values.length === 2 && this.options.range === true ) &&
  1963. ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
  1964. ) {
  1965. newVal = otherVal;
  1966. }
  1967. if ( newVal !== this.values( index ) ) {
  1968. newValues = this.values();
  1969. newValues[ index ] = newVal;
  1970. // A slide can be canceled by returning false from the slide callback
  1971. allowed = this._trigger( "slide", event, {
  1972. handle: this.handles[ index ],
  1973. value: newVal,
  1974. values: newValues
  1975. } );
  1976. otherVal = this.values( index ? 0 : 1 );
  1977. if ( allowed !== false ) {
  1978. this.values( index, newVal );
  1979. }
  1980. }
  1981. } else {
  1982. if ( newVal !== this.value() ) {
  1983. // A slide can be canceled by returning false from the slide callback
  1984. allowed = this._trigger( "slide", event, {
  1985. handle: this.handles[ index ],
  1986. value: newVal
  1987. } );
  1988. if ( allowed !== false ) {
  1989. this.value( newVal );
  1990. }
  1991. }
  1992. }
  1993. },
  1994. _stop: function( event, index ) {
  1995. var uiHash = {
  1996. handle: this.handles[ index ],
  1997. value: this.value()
  1998. };
  1999. if ( this.options.values && this.options.values.length ) {
  2000. uiHash.value = this.values( index );
  2001. uiHash.values = this.values();
  2002. }
  2003. this._trigger( "stop", event, uiHash );
  2004. },
  2005. _change: function( event, index ) {
  2006. if ( !this._keySliding && !this._mouseSliding ) {
  2007. var uiHash = {
  2008. handle: this.handles[ index ],
  2009. value: this.value()
  2010. };
  2011. if ( this.options.values && this.options.values.length ) {
  2012. uiHash.value = this.values( index );
  2013. uiHash.values = this.values();
  2014. }
  2015. //store the last changed value index for reference when handles overlap
  2016. this._lastChangedValue = index;
  2017. this._trigger( "change", event, uiHash );
  2018. }
  2019. },
  2020. value: function( newValue ) {
  2021. if ( arguments.length ) {
  2022. this.options.value = this._trimAlignValue( newValue );
  2023. this._refreshValue();
  2024. this._change( null, 0 );
  2025. return;
  2026. }
  2027. return this._value();
  2028. },
  2029. values: function( index, newValue ) {
  2030. var vals,
  2031. newValues,
  2032. i;
  2033. if ( arguments.length > 1 ) {
  2034. this.options.values[ index ] = this._trimAlignValue( newValue );
  2035. this._refreshValue();
  2036. this._change( null, index );
  2037. return;
  2038. }
  2039. if ( arguments.length ) {
  2040. if ( $.isArray( arguments[ 0 ] ) ) {
  2041. vals = this.options.values;
  2042. newValues = arguments[ 0 ];
  2043. for ( i = 0; i < vals.length; i += 1 ) {
  2044. vals[ i ] = this._trimAlignValue( newValues[ i ] );
  2045. this._change( null, i );
  2046. }
  2047. this._refreshValue();
  2048. } else {
  2049. if ( this.options.values && this.options.values.length ) {
  2050. return this._values( index );
  2051. } else {
  2052. return this.value();
  2053. }
  2054. }
  2055. } else {
  2056. return this._values();
  2057. }
  2058. },
  2059. _setOption: function( key, value ) {
  2060. var i,
  2061. valsLength = 0;
  2062. if ( key === "range" && this.options.range === true ) {
  2063. if ( value === "min" ) {
  2064. this.options.value = this._values( 0 );
  2065. this.options.values = null;
  2066. } else if ( value === "max" ) {
  2067. this.options.value = this._values( this.options.values.length-1 );
  2068. this.options.values = null;
  2069. }
  2070. }
  2071. if ( $.isArray( this.options.values ) ) {
  2072. valsLength = this.options.values.length;
  2073. }
  2074. $.Widget.prototype._setOption.apply( this, arguments );
  2075. switch ( key ) {
  2076. case "orientation":
  2077. this._detectOrientation();
  2078. this.element
  2079. .removeClass( "ui-slider-horizontal ui-slider-vertical" )
  2080. .addClass( "ui-slider-" + this.orientation );
  2081. this._refreshValue();
  2082. break;
  2083. case "value":
  2084. this._animateOff = true;
  2085. this._refreshValue();
  2086. this._change( null, 0 );
  2087. this._animateOff = false;
  2088. break;
  2089. case "values":
  2090. this._animateOff = true;
  2091. this._refreshValue();
  2092. for ( i = 0; i < valsLength; i += 1 ) {
  2093. this._change( null, i );
  2094. }
  2095. this._animateOff = false;
  2096. break;
  2097. case "min":
  2098. case "max":
  2099. this._animateOff = true;
  2100. this._refreshValue();
  2101. this._animateOff = false;
  2102. break;
  2103. case "range":
  2104. this._animateOff = true;
  2105. this._refresh();
  2106. this._animateOff = false;
  2107. break;
  2108. }
  2109. },
  2110. //internal value getter
  2111. // _value() returns value trimmed by min and max, aligned by step
  2112. _value: function() {
  2113. var val = this.options.value;
  2114. val = this._trimAlignValue( val );
  2115. return val;
  2116. },
  2117. //internal values getter
  2118. // _values() returns array of values trimmed by min and max, aligned by step
  2119. // _values( index ) returns single value trimmed by min and max, aligned by step
  2120. _values: function( index ) {
  2121. var val,
  2122. vals,
  2123. i;
  2124. if ( arguments.length ) {
  2125. val = this.options.values[ index ];
  2126. val = this._trimAlignValue( val );
  2127. return val;
  2128. } else if ( this.options.values && this.options.values.length ) {
  2129. // .slice() creates a copy of the array
  2130. // this copy gets trimmed by min and max and then returned
  2131. vals = this.options.values.slice();
  2132. for ( i = 0; i < vals.length; i+= 1) {
  2133. vals[ i ] = this._trimAlignValue( vals[ i ] );
  2134. }
  2135. return vals;
  2136. } else {
  2137. return [];
  2138. }
  2139. },
  2140. // returns the step-aligned value that val is closest to, between (inclusive) min and max
  2141. _trimAlignValue: function( val ) {
  2142. if ( val <= this._valueMin() ) {
  2143. return this._valueMin();
  2144. }
  2145. if ( val >= this._valueMax() ) {
  2146. return this._valueMax();
  2147. }
  2148. var step = ( this.options.step > 0 ) ? this.options.step : 1,
  2149. valModStep = (val - this._valueMin()) % step,
  2150. alignValue = val - valModStep;
  2151. if ( Math.abs(valModStep) * 2 >= step ) {
  2152. alignValue += ( valModStep > 0 ) ? step : ( -step );
  2153. }
  2154. // Since JavaScript has problems with large floats, round
  2155. // the final value to 5 digits after the decimal point (see #4124)
  2156. return parseFloat( alignValue.toFixed(5) );
  2157. },
  2158. _valueMin: function() {
  2159. return this.options.min;
  2160. },
  2161. _valueMax: function() {
  2162. return this.options.max;
  2163. },
  2164. _refreshValue: function() {
  2165. var lastValPercent, valPercent, value, valueMin, valueMax,
  2166. oRange = this.options.range,
  2167. o = this.options,
  2168. that = this,
  2169. animate = ( !this._animateOff ) ? o.animate : false,
  2170. _set = {};
  2171. if ( this.options.values && this.options.values.length ) {
  2172. this.handles.each(function( i ) {
  2173. valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
  2174. _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
  2175. $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
  2176. if ( that.options.range === true ) {
  2177. if ( that.orientation === "horizontal" ) {
  2178. if ( i === 0 ) {
  2179. that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
  2180. }
  2181. if ( i === 1 ) {
  2182. that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
  2183. }
  2184. } else {
  2185. if ( i === 0 ) {
  2186. that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
  2187. }
  2188. if ( i === 1 ) {
  2189. that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
  2190. }
  2191. }
  2192. }
  2193. lastValPercent = valPercent;
  2194. });
  2195. } else {
  2196. value = this.value();
  2197. valueMin = this._valueMin();
  2198. valueMax = this._valueMax();
  2199. valPercent = ( valueMax !== valueMin ) ?
  2200. ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
  2201. 0;
  2202. _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
  2203. this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
  2204. if ( oRange === "min" && this.orientation === "horizontal" ) {
  2205. this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
  2206. }
  2207. if ( oRange === "max" && this.orientation === "horizontal" ) {
  2208. this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
  2209. }
  2210. if ( oRange === "min" && this.orientation === "vertical" ) {
  2211. this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
  2212. }
  2213. if ( oRange === "max" && this.orientation === "vertical" ) {
  2214. this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
  2215. }
  2216. }
  2217. },
  2218. _handleEvents: {
  2219. keydown: function( event ) {
  2220. var allowed, curVal, newVal, step,
  2221. index = $( event.target ).data( "ui-slider-handle-index" );
  2222. switch ( event.keyCode ) {
  2223. case $.ui.keyCode.HOME:
  2224. case $.ui.keyCode.END:
  2225. case $.ui.keyCode.PAGE_UP:
  2226. case $.ui.keyCode.PAGE_DOWN:
  2227. case $.ui.keyCode.UP:
  2228. case $.ui.keyCode.RIGHT:
  2229. case $.ui.keyCode.DOWN:
  2230. case $.ui.keyCode.LEFT:
  2231. event.preventDefault();
  2232. if ( !this._keySliding ) {
  2233. this._keySliding = true;
  2234. $( event.target ).addClass( "ui-state-active" );
  2235. allowed = this._start( event, index );
  2236. if ( allowed === false ) {
  2237. return;
  2238. }
  2239. }
  2240. break;
  2241. }
  2242. step = this.options.step;
  2243. if ( this.options.values && this.options.values.length ) {
  2244. curVal = newVal = this.values( index );
  2245. } else {
  2246. curVal = newVal = this.value();
  2247. }
  2248. switch ( event.keyCode ) {
  2249. case $.ui.keyCode.HOME:
  2250. newVal = this._valueMin();
  2251. break;
  2252. case $.ui.keyCode.END:
  2253. newVal = this._valueMax();
  2254. break;
  2255. case $.ui.keyCode.PAGE_UP:
  2256. newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );
  2257. break;
  2258. case $.ui.keyCode.PAGE_DOWN:
  2259. newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );
  2260. break;
  2261. case $.ui.keyCode.UP:
  2262. case $.ui.keyCode.RIGHT:
  2263. if ( curVal === this._valueMax() ) {
  2264. return;
  2265. }
  2266. newVal = this._trimAlignValue( curVal + step );
  2267. break;
  2268. case $.ui.keyCode.DOWN:
  2269. case $.ui.keyCode.LEFT:
  2270. if ( curVal === this._valueMin() ) {
  2271. return;
  2272. }
  2273. newVal = this._trimAlignValue( curVal - step );
  2274. break;
  2275. }
  2276. this._slide( event, index, newVal );
  2277. },
  2278. click: function( event ) {
  2279. event.preventDefault();
  2280. },
  2281. keyup: function( event ) {
  2282. var index = $( event.target ).data( "ui-slider-handle-index" );
  2283. if ( this._keySliding ) {
  2284. this._keySliding = false;
  2285. this._stop( event, index );
  2286. this._change( event, index );
  2287. $( event.target ).removeClass( "ui-state-active" );
  2288. }
  2289. }
  2290. }
  2291. });
  2292. }(jQuery));
  2293. /*!
  2294. * jQuery UI Effects 1.10.4
  2295. * http://jqueryui.com
  2296. *
  2297. * Copyright 2014 jQuery Foundation and other contributors
  2298. * Released under the MIT license.
  2299. * http://jquery.org/license
  2300. *
  2301. * http://api.jqueryui.com/category/effects-core/
  2302. */
  2303. (function($, undefined) {
  2304. var dataSpace = "ui-effects-";
  2305. $.effects = {
  2306. effect: {}
  2307. };
  2308. /*!
  2309. * jQuery Color Animations v2.1.2
  2310. * https://github.com/jquery/jquery-color
  2311. *
  2312. * Copyright 2013 jQuery Foundation and other contributors
  2313. * Released under the MIT license.
  2314. * http://jquery.org/license
  2315. *
  2316. * Date: Wed Jan 16 08:47:09 2013 -0600
  2317. */
  2318. (function( jQuery, undefined ) {
  2319. var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
  2320. // plusequals test for += 100 -= 100
  2321. rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
  2322. // a set of RE's that can match strings and generate color tuples.
  2323. stringParsers = [{
  2324. re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
  2325. parse: function( execResult ) {
  2326. return [
  2327. execResult[ 1 ],
  2328. execResult[ 2 ],
  2329. execResult[ 3 ],
  2330. execResult[ 4 ]
  2331. ];
  2332. }
  2333. }, {
  2334. re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
  2335. parse: function( execResult ) {
  2336. return [
  2337. execResult[ 1 ] * 2.55,
  2338. execResult[ 2 ] * 2.55,
  2339. execResult[ 3 ] * 2.55,
  2340. execResult[ 4 ]
  2341. ];
  2342. }
  2343. }, {
  2344. // this regex ignores A-F because it's compared against an already lowercased string
  2345. re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
  2346. parse: function( execResult ) {
  2347. return [
  2348. parseInt( execResult[ 1 ], 16 ),
  2349. parseInt( execResult[ 2 ], 16 ),
  2350. parseInt( execResult[ 3 ], 16 )
  2351. ];
  2352. }
  2353. }, {
  2354. // this regex ignores A-F because it's compared against an already lowercased string
  2355. re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
  2356. parse: function( execResult ) {
  2357. return [
  2358. parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
  2359. parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
  2360. parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
  2361. ];
  2362. }
  2363. }, {
  2364. re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
  2365. space: "hsla",
  2366. parse: function( execResult ) {
  2367. return [
  2368. execResult[ 1 ],
  2369. execResult[ 2 ] / 100,
  2370. execResult[ 3 ] / 100,
  2371. execResult[ 4 ]
  2372. ];
  2373. }
  2374. }],
  2375. // jQuery.Color( )
  2376. color = jQuery.Color = function( color, green, blue, alpha ) {
  2377. return new jQuery.Color.fn.parse( color, green, blue, alpha );
  2378. },
  2379. spaces = {
  2380. rgba: {
  2381. props: {
  2382. red: {
  2383. idx: 0,
  2384. type: "byte"
  2385. },
  2386. green: {
  2387. idx: 1,
  2388. type: "byte"
  2389. },
  2390. blue: {
  2391. idx: 2,
  2392. type: "byte"
  2393. }
  2394. }
  2395. },
  2396. hsla: {
  2397. props: {
  2398. hue: {
  2399. idx: 0,
  2400. type: "degrees"
  2401. },
  2402. saturation: {
  2403. idx: 1,
  2404. type: "percent"
  2405. },
  2406. lightness: {
  2407. idx: 2,
  2408. type: "percent"
  2409. }
  2410. }
  2411. }
  2412. },
  2413. propTypes = {
  2414. "byte": {
  2415. floor: true,
  2416. max: 255
  2417. },
  2418. "percent": {
  2419. max: 1
  2420. },
  2421. "degrees": {
  2422. mod: 360,
  2423. floor: true
  2424. }
  2425. },
  2426. support = color.support = {},
  2427. // element for support tests
  2428. supportElem = jQuery( "<p>" )[ 0 ],
  2429. // colors = jQuery.Color.names
  2430. colors,
  2431. // local aliases of functions called often
  2432. each = jQuery.each;
  2433. // determine rgba support immediately
  2434. supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
  2435. support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
  2436. // define cache name and alpha properties
  2437. // for rgba and hsla spaces
  2438. each( spaces, function( spaceName, space ) {
  2439. space.cache = "_" + spaceName;
  2440. space.props.alpha = {
  2441. idx: 3,
  2442. type: "percent",
  2443. def: 1
  2444. };
  2445. });
  2446. function clamp( value, prop, allowEmpty ) {
  2447. var type = propTypes[ prop.type ] || {};
  2448. if ( value == null ) {
  2449. return (allowEmpty || !prop.def) ? null : prop.def;
  2450. }
  2451. // ~~ is an short way of doing floor for positive numbers
  2452. value = type.floor ? ~~value : parseFloat( value );
  2453. // IE will pass in empty strings as value for alpha,
  2454. // which will hit this case
  2455. if ( isNaN( value ) ) {
  2456. return prop.def;
  2457. }
  2458. if ( type.mod ) {
  2459. // we add mod before modding to make sure that negatives values
  2460. // get converted properly: -10 -> 350
  2461. return (value + type.mod) % type.mod;
  2462. }
  2463. // for now all property types without mod have min and max
  2464. return 0 > value ? 0 : type.max < value ? type.max : value;
  2465. }
  2466. function stringParse( string ) {
  2467. var inst = color(),
  2468. rgba = inst._rgba = [];
  2469. string = string.toLowerCase();
  2470. each( stringParsers, function( i, parser ) {
  2471. var parsed,
  2472. match = parser.re.exec( string ),
  2473. values = match && parser.parse( match ),
  2474. spaceName = parser.space || "rgba";
  2475. if ( values ) {
  2476. parsed = inst[ spaceName ]( values );
  2477. // if this was an rgba parse the assignment might happen twice
  2478. // oh well....
  2479. inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
  2480. rgba = inst._rgba = parsed._rgba;
  2481. // exit each( stringParsers ) here because we matched
  2482. return false;
  2483. }
  2484. });
  2485. // Found a stringParser that handled it
  2486. if ( rgba.length ) {
  2487. // if this came from a parsed string, force "transparent" when alpha is 0
  2488. // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
  2489. if ( rgba.join() === "0,0,0,0" ) {
  2490. jQuery.extend( rgba, colors.transparent );
  2491. }
  2492. return inst;
  2493. }
  2494. // named colors
  2495. return colors[ string ];
  2496. }
  2497. color.fn = jQuery.extend( color.prototype, {
  2498. parse: function( red, green, blue, alpha ) {
  2499. if ( red === undefined ) {
  2500. this._rgba = [ null, null, null, null ];
  2501. return this;
  2502. }
  2503. if ( red.jquery || red.nodeType ) {
  2504. red = jQuery( red ).css( green );
  2505. green = undefined;
  2506. }
  2507. var inst = this,
  2508. type = jQuery.type( red ),
  2509. rgba = this._rgba = [];
  2510. // more than 1 argument specified - assume ( red, green, blue, alpha )
  2511. if ( green !== undefined ) {
  2512. red = [ red, green, blue, alpha ];
  2513. type = "array";
  2514. }
  2515. if ( type === "string" ) {
  2516. return this.parse( stringParse( red ) || colors._default );
  2517. }
  2518. if ( type === "array" ) {
  2519. each( spaces.rgba.props, function( key, prop ) {
  2520. rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
  2521. });
  2522. return this;
  2523. }
  2524. if ( type === "object" ) {
  2525. if ( red instanceof color ) {
  2526. each( spaces, function( spaceName, space ) {
  2527. if ( red[ space.cache ] ) {
  2528. inst[ space.cache ] = red[ space.cache ].slice();
  2529. }
  2530. });
  2531. } else {
  2532. each( spaces, function( spaceName, space ) {
  2533. var cache = space.cache;
  2534. each( space.props, function( key, prop ) {
  2535. // if the cache doesn't exist, and we know how to convert
  2536. if ( !inst[ cache ] && space.to ) {
  2537. // if the value was null, we don't need to copy it
  2538. // if the key was alpha, we don't need to copy it either
  2539. if ( key === "alpha" || red[ key ] == null ) {
  2540. return;
  2541. }
  2542. inst[ cache ] = space.to( inst._rgba );
  2543. }
  2544. // this is the only case where we allow nulls for ALL properties.
  2545. // call clamp with alwaysAllowEmpty
  2546. inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
  2547. });
  2548. // everything defined but alpha?
  2549. if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
  2550. // use the default of 1
  2551. inst[ cache ][ 3 ] = 1;
  2552. if ( space.from ) {
  2553. inst._rgba = space.from( inst[ cache ] );
  2554. }
  2555. }
  2556. });
  2557. }
  2558. return this;
  2559. }
  2560. },
  2561. is: function( compare ) {
  2562. var is = color( compare ),
  2563. same = true,
  2564. inst = this;
  2565. each( spaces, function( _, space ) {
  2566. var localCache,
  2567. isCache = is[ space.cache ];
  2568. if (isCache) {
  2569. localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
  2570. each( space.props, function( _, prop ) {
  2571. if ( isCache[ prop.idx ] != null ) {
  2572. same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
  2573. return same;
  2574. }
  2575. });
  2576. }
  2577. return same;
  2578. });
  2579. return same;
  2580. },
  2581. _space: function() {
  2582. var used = [],
  2583. inst = this;
  2584. each( spaces, function( spaceName, space ) {
  2585. if ( inst[ space.cache ] ) {
  2586. used.push( spaceName );
  2587. }
  2588. });
  2589. return used.pop();
  2590. },
  2591. transition: function( other, distance ) {
  2592. var end = color( other ),
  2593. spaceName = end._space(),
  2594. space = spaces[ spaceName ],
  2595. startColor = this.alpha() === 0 ? color( "transparent" ) : this,
  2596. start = startColor[ space.cache ] || space.to( startColor._rgba ),
  2597. result = start.slice();
  2598. end = end[ space.cache ];
  2599. each( space.props, function( key, prop ) {
  2600. var index = prop.idx,
  2601. startValue = start[ index ],
  2602. endValue = end[ index ],
  2603. type = propTypes[ prop.type ] || {};
  2604. // if null, don't override start value
  2605. if ( endValue === null ) {
  2606. return;
  2607. }
  2608. // if null - use end
  2609. if ( startValue === null ) {
  2610. result[ index ] = endValue;
  2611. } else {
  2612. if ( type.mod ) {
  2613. if ( endValue - startValue > type.mod / 2 ) {
  2614. startValue += type.mod;
  2615. } else if ( startValue - endValue > type.mod / 2 ) {
  2616. startValue -= type.mod;
  2617. }
  2618. }
  2619. result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
  2620. }
  2621. });
  2622. return this[ spaceName ]( result );
  2623. },
  2624. blend: function( opaque ) {
  2625. // if we are already opaque - return ourself
  2626. if ( this._rgba[ 3 ] === 1 ) {
  2627. return this;
  2628. }
  2629. var rgb = this._rgba.slice(),
  2630. a = rgb.pop(),
  2631. blend = color( opaque )._rgba;
  2632. return color( jQuery.map( rgb, function( v, i ) {
  2633. return ( 1 - a ) * blend[ i ] + a * v;
  2634. }));
  2635. },
  2636. toRgbaString: function() {
  2637. var prefix = "rgba(",
  2638. rgba = jQuery.map( this._rgba, function( v, i ) {
  2639. return v == null ? ( i > 2 ? 1 : 0 ) : v;
  2640. });
  2641. if ( rgba[ 3 ] === 1 ) {
  2642. rgba.pop();
  2643. prefix = "rgb(";
  2644. }
  2645. return prefix + rgba.join() + ")";
  2646. },
  2647. toHslaString: function() {
  2648. var prefix = "hsla(",
  2649. hsla = jQuery.map( this.hsla(), function( v, i ) {
  2650. if ( v == null ) {
  2651. v = i > 2 ? 1 : 0;
  2652. }
  2653. // catch 1 and 2
  2654. if ( i && i < 3 ) {
  2655. v = Math.round( v * 100 ) + "%";
  2656. }
  2657. return v;
  2658. });
  2659. if ( hsla[ 3 ] === 1 ) {
  2660. hsla.pop();
  2661. prefix = "hsl(";
  2662. }
  2663. return prefix + hsla.join() + ")";
  2664. },
  2665. toHexString: function( includeAlpha ) {
  2666. var rgba = this._rgba.slice(),
  2667. alpha = rgba.pop();
  2668. if ( includeAlpha ) {
  2669. rgba.push( ~~( alpha * 255 ) );
  2670. }
  2671. return "#" + jQuery.map( rgba, function( v ) {
  2672. // default to 0 when nulls exist
  2673. v = ( v || 0 ).toString( 16 );
  2674. return v.length === 1 ? "0" + v : v;
  2675. }).join("");
  2676. },
  2677. toString: function() {
  2678. return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
  2679. }
  2680. });
  2681. color.fn.parse.prototype = color.fn;
  2682. // hsla conversions adapted from:
  2683. // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
  2684. function hue2rgb( p, q, h ) {
  2685. h = ( h + 1 ) % 1;
  2686. if ( h * 6 < 1 ) {
  2687. return p + (q - p) * h * 6;
  2688. }
  2689. if ( h * 2 < 1) {
  2690. return q;
  2691. }
  2692. if ( h * 3 < 2 ) {
  2693. return p + (q - p) * ((2/3) - h) * 6;
  2694. }
  2695. return p;
  2696. }
  2697. spaces.hsla.to = function ( rgba ) {
  2698. if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
  2699. return [ null, null, null, rgba[ 3 ] ];
  2700. }
  2701. var r = rgba[ 0 ] / 255,
  2702. g = rgba[ 1 ] / 255,
  2703. b = rgba[ 2 ] / 255,
  2704. a = rgba[ 3 ],
  2705. max = Math.max( r, g, b ),
  2706. min = Math.min( r, g, b ),
  2707. diff = max - min,
  2708. add = max + min,
  2709. l = add * 0.5,
  2710. h, s;
  2711. if ( min === max ) {
  2712. h = 0;
  2713. } else if ( r === max ) {
  2714. h = ( 60 * ( g - b ) / diff ) + 360;
  2715. } else if ( g === max ) {
  2716. h = ( 60 * ( b - r ) / diff ) + 120;
  2717. } else {
  2718. h = ( 60 * ( r - g ) / diff ) + 240;
  2719. }
  2720. // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
  2721. // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
  2722. if ( diff === 0 ) {
  2723. s = 0;
  2724. } else if ( l <= 0.5 ) {
  2725. s = diff / add;
  2726. } else {
  2727. s = diff / ( 2 - add );
  2728. }
  2729. return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
  2730. };
  2731. spaces.hsla.from = function ( hsla ) {
  2732. if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
  2733. return [ null, null, null, hsla[ 3 ] ];
  2734. }
  2735. var h = hsla[ 0 ] / 360,
  2736. s = hsla[ 1 ],
  2737. l = hsla[ 2 ],
  2738. a = hsla[ 3 ],
  2739. q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
  2740. p = 2 * l - q;
  2741. return [
  2742. Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
  2743. Math.round( hue2rgb( p, q, h ) * 255 ),
  2744. Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
  2745. a
  2746. ];
  2747. };
  2748. each( spaces, function( spaceName, space ) {
  2749. var props = space.props,
  2750. cache = space.cache,
  2751. to = space.to,
  2752. from = space.from;
  2753. // makes rgba() and hsla()
  2754. color.fn[ spaceName ] = function( value ) {
  2755. // generate a cache for this space if it doesn't exist
  2756. if ( to && !this[ cache ] ) {
  2757. this[ cache ] = to( this._rgba );
  2758. }
  2759. if ( value === undefined ) {
  2760. return this[ cache ].slice();
  2761. }
  2762. var ret,
  2763. type = jQuery.type( value ),
  2764. arr = ( type === "array" || type === "object" ) ? value : arguments,
  2765. local = this[ cache ].slice();
  2766. each( props, function( key, prop ) {
  2767. var val = arr[ type === "object" ? key : prop.idx ];
  2768. if ( val == null ) {
  2769. val = local[ prop.idx ];
  2770. }
  2771. local[ prop.idx ] = clamp( val, prop );
  2772. });
  2773. if ( from ) {
  2774. ret = color( from( local ) );
  2775. ret[ cache ] = local;
  2776. return ret;
  2777. } else {
  2778. return color( local );
  2779. }
  2780. };
  2781. // makes red() green() blue() alpha() hue() saturation() lightness()
  2782. each( props, function( key, prop ) {
  2783. // alpha is included in more than one space
  2784. if ( color.fn[ key ] ) {
  2785. return;
  2786. }
  2787. color.fn[ key ] = function( value ) {
  2788. var vtype = jQuery.type( value ),
  2789. fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
  2790. local = this[ fn ](),
  2791. cur = local[ prop.idx ],
  2792. match;
  2793. if ( vtype === "undefined" ) {
  2794. return cur;
  2795. }
  2796. if ( vtype === "function" ) {
  2797. value = value.call( this, cur );
  2798. vtype = jQuery.type( value );
  2799. }
  2800. if ( value == null && prop.empty ) {
  2801. return this;
  2802. }
  2803. if ( vtype === "string" ) {
  2804. match = rplusequals.exec( value );
  2805. if ( match ) {
  2806. value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
  2807. }
  2808. }
  2809. local[ prop.idx ] = value;
  2810. return this[ fn ]( local );
  2811. };
  2812. });
  2813. });
  2814. // add cssHook and .fx.step function for each named hook.
  2815. // accept a space separated string of properties
  2816. color.hook = function( hook ) {
  2817. var hooks = hook.split( " " );
  2818. each( hooks, function( i, hook ) {
  2819. jQuery.cssHooks[ hook ] = {
  2820. set: function( elem, value ) {
  2821. var parsed, curElem,
  2822. backgroundColor = "";
  2823. if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
  2824. value = color( parsed || value );
  2825. if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
  2826. curElem = hook === "backgroundColor" ? elem.parentNode : elem;
  2827. while (
  2828. (backgroundColor === "" || backgroundColor === "transparent") &&
  2829. curElem && curElem.style
  2830. ) {
  2831. try {
  2832. backgroundColor = jQuery.css( curElem, "backgroundColor" );
  2833. curElem = curElem.parentNode;
  2834. } catch ( e ) {
  2835. }
  2836. }
  2837. value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
  2838. backgroundColor :
  2839. "_default" );
  2840. }
  2841. value = value.toRgbaString();
  2842. }
  2843. try {
  2844. elem.style[ hook ] = value;
  2845. } catch( e ) {
  2846. // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
  2847. }
  2848. }
  2849. };
  2850. jQuery.fx.step[ hook ] = function( fx ) {
  2851. if ( !fx.colorInit ) {
  2852. fx.start = color( fx.elem, hook );
  2853. fx.end = color( fx.end );
  2854. fx.colorInit = true;
  2855. }
  2856. jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
  2857. };
  2858. });
  2859. };
  2860. color.hook( stepHooks );
  2861. jQuery.cssHooks.borderColor = {
  2862. expand: function( value ) {
  2863. var expanded = {};
  2864. each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
  2865. expanded[ "border" + part + "Color" ] = value;
  2866. });
  2867. return expanded;
  2868. }
  2869. };
  2870. // Basic color names only.
  2871. // Usage of any of the other color names requires adding yourself or including
  2872. // jquery.color.svg-names.js.
  2873. colors = jQuery.Color.names = {
  2874. // 4.1. Basic color keywords
  2875. aqua: "#00ffff",
  2876. black: "#000000",
  2877. blue: "#0000ff",
  2878. fuchsia: "#ff00ff",
  2879. gray: "#808080",
  2880. green: "#008000",
  2881. lime: "#00ff00",
  2882. maroon: "#800000",
  2883. navy: "#000080",
  2884. olive: "#808000",
  2885. purple: "#800080",
  2886. red: "#ff0000",
  2887. silver: "#c0c0c0",
  2888. teal: "#008080",
  2889. white: "#ffffff",
  2890. yellow: "#ffff00",
  2891. // 4.2.3. "transparent" color keyword
  2892. transparent: [ null, null, null, 0 ],
  2893. _default: "#ffffff"
  2894. };
  2895. })( jQuery );
  2896. /******************************************************************************/
  2897. /****************************** CLASS ANIMATIONS ******************************/
  2898. /******************************************************************************/
  2899. (function() {
  2900. var classAnimationActions = [ "add", "remove", "toggle" ],
  2901. shorthandStyles = {
  2902. border: 1,
  2903. borderBottom: 1,
  2904. borderColor: 1,
  2905. borderLeft: 1,
  2906. borderRight: 1,
  2907. borderTop: 1,
  2908. borderWidth: 1,
  2909. margin: 1,
  2910. padding: 1
  2911. };
  2912. $.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
  2913. $.fx.step[ prop ] = function( fx ) {
  2914. if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
  2915. jQuery.style( fx.elem, prop, fx.end );
  2916. fx.setAttr = true;
  2917. }
  2918. };
  2919. });
  2920. function getElementStyles( elem ) {
  2921. var key, len,
  2922. style = elem.ownerDocument.defaultView ?
  2923. elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
  2924. elem.currentStyle,
  2925. styles = {};
  2926. if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
  2927. len = style.length;
  2928. while ( len-- ) {
  2929. key = style[ len ];
  2930. if ( typeof style[ key ] === "string" ) {
  2931. styles[ $.camelCase( key ) ] = style[ key ];
  2932. }
  2933. }
  2934. // support: Opera, IE <9
  2935. } else {
  2936. for ( key in style ) {
  2937. if ( typeof style[ key ] === "string" ) {
  2938. styles[ key ] = style[ key ];
  2939. }
  2940. }
  2941. }
  2942. return styles;
  2943. }
  2944. function styleDifference( oldStyle, newStyle ) {
  2945. var diff = {},
  2946. name, value;
  2947. for ( name in newStyle ) {
  2948. value = newStyle[ name ];
  2949. if ( oldStyle[ name ] !== value ) {
  2950. if ( !shorthandStyles[ name ] ) {
  2951. if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
  2952. diff[ name ] = value;
  2953. }
  2954. }
  2955. }
  2956. }
  2957. return diff;
  2958. }
  2959. // support: jQuery <1.8
  2960. if ( !$.fn.addBack ) {
  2961. $.fn.addBack = function( selector ) {
  2962. return this.add( selector == null ?
  2963. this.prevObject : this.prevObject.filter( selector )
  2964. );
  2965. };
  2966. }
  2967. $.effects.animateClass = function( value, duration, easing, callback ) {
  2968. var o = $.speed( duration, easing, callback );
  2969. return this.queue( function() {
  2970. var animated = $( this ),
  2971. baseClass = animated.attr( "class" ) || "",
  2972. applyClassChange,
  2973. allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
  2974. // map the animated objects to store the original styles.
  2975. allAnimations = allAnimations.map(function() {
  2976. var el = $( this );
  2977. return {
  2978. el: el,
  2979. start: getElementStyles( this )
  2980. };
  2981. });
  2982. // apply class change
  2983. applyClassChange = function() {
  2984. $.each( classAnimationActions, function(i, action) {
  2985. if ( value[ action ] ) {
  2986. animated[ action + "Class" ]( value[ action ] );
  2987. }
  2988. });
  2989. };
  2990. applyClassChange();
  2991. // map all animated objects again - calculate new styles and diff
  2992. allAnimations = allAnimations.map(function() {
  2993. this.end = getElementStyles( this.el[ 0 ] );
  2994. this.diff = styleDifference( this.start, this.end );
  2995. return this;
  2996. });
  2997. // apply original class
  2998. animated.attr( "class", baseClass );
  2999. // map all animated objects again - this time collecting a promise
  3000. allAnimations = allAnimations.map(function() {
  3001. var styleInfo = this,
  3002. dfd = $.Deferred(),
  3003. opts = $.extend({}, o, {
  3004. queue: false,
  3005. complete: function() {
  3006. dfd.resolve( styleInfo );
  3007. }
  3008. });
  3009. this.el.animate( this.diff, opts );
  3010. return dfd.promise();
  3011. });
  3012. // once all animations have completed:
  3013. $.when.apply( $, allAnimations.get() ).done(function() {
  3014. // set the final class
  3015. applyClassChange();
  3016. // for each animated element,
  3017. // clear all css properties that were animated
  3018. $.each( arguments, function() {
  3019. var el = this.el;
  3020. $.each( this.diff, function(key) {
  3021. el.css( key, "" );
  3022. });
  3023. });
  3024. // this is guarnteed to be there if you use jQuery.speed()
  3025. // it also handles dequeuing the next anim...
  3026. o.complete.call( animated[ 0 ] );
  3027. });
  3028. });
  3029. };
  3030. $.fn.extend({
  3031. addClass: (function( orig ) {
  3032. return function( classNames, speed, easing, callback ) {
  3033. return speed ?
  3034. $.effects.animateClass.call( this,
  3035. { add: classNames }, speed, easing, callback ) :
  3036. orig.apply( this, arguments );
  3037. };
  3038. })( $.fn.addClass ),
  3039. removeClass: (function( orig ) {
  3040. return function( classNames, speed, easing, callback ) {
  3041. return arguments.length > 1 ?
  3042. $.effects.animateClass.call( this,
  3043. { remove: classNames }, speed, easing, callback ) :
  3044. orig.apply( this, arguments );
  3045. };
  3046. })( $.fn.removeClass ),
  3047. toggleClass: (function( orig ) {
  3048. return function( classNames, force, speed, easing, callback ) {
  3049. if ( typeof force === "boolean" || force === undefined ) {
  3050. if ( !speed ) {
  3051. // without speed parameter
  3052. return orig.apply( this, arguments );
  3053. } else {
  3054. return $.effects.animateClass.call( this,
  3055. (force ? { add: classNames } : { remove: classNames }),
  3056. speed, easing, callback );
  3057. }
  3058. } else {
  3059. // without force parameter
  3060. return $.effects.animateClass.call( this,
  3061. { toggle: classNames }, force, speed, easing );
  3062. }
  3063. };
  3064. })( $.fn.toggleClass ),
  3065. switchClass: function( remove, add, speed, easing, callback) {
  3066. return $.effects.animateClass.call( this, {
  3067. add: add,
  3068. remove: remove
  3069. }, speed, easing, callback );
  3070. }
  3071. });
  3072. })();
  3073. /******************************************************************************/
  3074. /*********************************** EFFECTS **********************************/
  3075. /******************************************************************************/
  3076. (function() {
  3077. $.extend( $.effects, {
  3078. version: "1.10.4",
  3079. // Saves a set of properties in a data storage
  3080. save: function( element, set ) {
  3081. for( var i=0; i < set.length; i++ ) {
  3082. if ( set[ i ] !== null ) {
  3083. element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
  3084. }
  3085. }
  3086. },
  3087. // Restores a set of previously saved properties from a data storage
  3088. restore: function( element, set ) {
  3089. var val, i;
  3090. for( i=0; i < set.length; i++ ) {
  3091. if ( set[ i ] !== null ) {
  3092. val = element.data( dataSpace + set[ i ] );
  3093. // support: jQuery 1.6.2
  3094. // http://bugs.jquery.com/ticket/9917
  3095. // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
  3096. // We can't differentiate between "" and 0 here, so we just assume
  3097. // empty string since it's likely to be a more common value...
  3098. if ( val === undefined ) {
  3099. val = "";
  3100. }
  3101. element.css( set[ i ], val );
  3102. }
  3103. }
  3104. },
  3105. setMode: function( el, mode ) {
  3106. if (mode === "toggle") {
  3107. mode = el.is( ":hidden" ) ? "show" : "hide";
  3108. }
  3109. return mode;
  3110. },
  3111. // Translates a [top,left] array into a baseline value
  3112. // this should be a little more flexible in the future to handle a string & hash
  3113. getBaseline: function( origin, original ) {
  3114. var y, x;
  3115. switch ( origin[ 0 ] ) {
  3116. case "top": y = 0; break;
  3117. case "middle": y = 0.5; break;
  3118. case "bottom": y = 1; break;
  3119. default: y = origin[ 0 ] / original.height;
  3120. }
  3121. switch ( origin[ 1 ] ) {
  3122. case "left": x = 0; break;
  3123. case "center": x = 0.5; break;
  3124. case "right": x = 1; break;
  3125. default: x = origin[ 1 ] / original.width;
  3126. }
  3127. return {
  3128. x: x,
  3129. y: y
  3130. };
  3131. },
  3132. // Wraps the element around a wrapper that copies position properties
  3133. createWrapper: function( element ) {
  3134. // if the element is already wrapped, return it
  3135. if ( element.parent().is( ".ui-effects-wrapper" )) {
  3136. return element.parent();
  3137. }
  3138. // wrap the element
  3139. var props = {
  3140. width: element.outerWidth(true),
  3141. height: element.outerHeight(true),
  3142. "float": element.css( "float" )
  3143. },
  3144. wrapper = $( "<div></div>" )
  3145. .addClass( "ui-effects-wrapper" )
  3146. .css({
  3147. fontSize: "100%",
  3148. background: "transparent",
  3149. border: "none",
  3150. margin: 0,
  3151. padding: 0
  3152. }),
  3153. // Store the size in case width/height are defined in % - Fixes #5245
  3154. size = {
  3155. width: element.width(),
  3156. height: element.height()
  3157. },
  3158. active = document.activeElement;
  3159. // support: Firefox
  3160. // Firefox incorrectly exposes anonymous content
  3161. // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
  3162. try {
  3163. active.id;
  3164. } catch( e ) {
  3165. active = document.body;
  3166. }
  3167. element.wrap( wrapper );
  3168. // Fixes #7595 - Elements lose focus when wrapped.
  3169. if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
  3170. $( active ).focus();
  3171. }
  3172. wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
  3173. // transfer positioning properties to the wrapper
  3174. if ( element.css( "position" ) === "static" ) {
  3175. wrapper.css({ position: "relative" });
  3176. element.css({ position: "relative" });
  3177. } else {
  3178. $.extend( props, {
  3179. position: element.css( "position" ),
  3180. zIndex: element.css( "z-index" )
  3181. });
  3182. $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
  3183. props[ pos ] = element.css( pos );
  3184. if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
  3185. props[ pos ] = "auto";
  3186. }
  3187. });
  3188. element.css({
  3189. position: "relative",
  3190. top: 0,
  3191. left: 0,
  3192. right: "auto",
  3193. bottom: "auto"
  3194. });
  3195. }
  3196. element.css(size);
  3197. return wrapper.css( props ).show();
  3198. },
  3199. removeWrapper: function( element ) {
  3200. var active = document.activeElement;
  3201. if ( element.parent().is( ".ui-effects-wrapper" ) ) {
  3202. element.parent().replaceWith( element );
  3203. // Fixes #7595 - Elements lose focus when wrapped.
  3204. if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
  3205. $( active ).focus();
  3206. }
  3207. }
  3208. return element;
  3209. },
  3210. setTransition: function( element, list, factor, value ) {
  3211. value = value || {};
  3212. $.each( list, function( i, x ) {
  3213. var unit = element.cssUnit( x );
  3214. if ( unit[ 0 ] > 0 ) {
  3215. value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
  3216. }
  3217. });
  3218. return value;
  3219. }
  3220. });
  3221. // return an effect options object for the given parameters:
  3222. function _normalizeArguments( effect, options, speed, callback ) {
  3223. // allow passing all options as the first parameter
  3224. if ( $.isPlainObject( effect ) ) {
  3225. options = effect;
  3226. effect = effect.effect;
  3227. }
  3228. // convert to an object
  3229. effect = { effect: effect };
  3230. // catch (effect, null, ...)
  3231. if ( options == null ) {
  3232. options = {};
  3233. }
  3234. // catch (effect, callback)
  3235. if ( $.isFunction( options ) ) {
  3236. callback = options;
  3237. speed = null;
  3238. options = {};
  3239. }
  3240. // catch (effect, speed, ?)
  3241. if ( typeof options === "number" || $.fx.speeds[ options ] ) {
  3242. callback = speed;
  3243. speed = options;
  3244. options = {};
  3245. }
  3246. // catch (effect, options, callback)
  3247. if ( $.isFunction( speed ) ) {
  3248. callback = speed;
  3249. speed = null;
  3250. }
  3251. // add options to effect
  3252. if ( options ) {
  3253. $.extend( effect, options );
  3254. }
  3255. speed = speed || options.duration;
  3256. effect.duration = $.fx.off ? 0 :
  3257. typeof speed === "number" ? speed :
  3258. speed in $.fx.speeds ? $.fx.speeds[ speed ] :
  3259. $.fx.speeds._default;
  3260. effect.complete = callback || options.complete;
  3261. return effect;
  3262. }
  3263. function standardAnimationOption( option ) {
  3264. // Valid standard speeds (nothing, number, named speed)
  3265. if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
  3266. return true;
  3267. }
  3268. // Invalid strings - treat as "normal" speed
  3269. if ( typeof option === "string" && !$.effects.effect[ option ] ) {
  3270. return true;
  3271. }
  3272. // Complete callback
  3273. if ( $.isFunction( option ) ) {
  3274. return true;
  3275. }
  3276. // Options hash (but not naming an effect)
  3277. if ( typeof option === "object" && !option.effect ) {
  3278. return true;
  3279. }
  3280. // Didn't match any standard API
  3281. return false;
  3282. }
  3283. $.fn.extend({
  3284. effect: function( /* effect, options, speed, callback */ ) {
  3285. var args = _normalizeArguments.apply( this, arguments ),
  3286. mode = args.mode,
  3287. queue = args.queue,
  3288. effectMethod = $.effects.effect[ args.effect ];
  3289. if ( $.fx.off || !effectMethod ) {
  3290. // delegate to the original method (e.g., .show()) if possible
  3291. if ( mode ) {
  3292. return this[ mode ]( args.duration, args.complete );
  3293. } else {
  3294. return this.each( function() {
  3295. if ( args.complete ) {
  3296. args.complete.call( this );
  3297. }
  3298. });
  3299. }
  3300. }
  3301. function run( next ) {
  3302. var elem = $( this ),
  3303. complete = args.complete,
  3304. mode = args.mode;
  3305. function done() {
  3306. if ( $.isFunction( complete ) ) {
  3307. complete.call( elem[0] );
  3308. }
  3309. if ( $.isFunction( next ) ) {
  3310. next();
  3311. }
  3312. }
  3313. // If the element already has the correct final state, delegate to
  3314. // the core methods so the internal tracking of "olddisplay" works.
  3315. if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
  3316. elem[ mode ]();
  3317. done();
  3318. } else {
  3319. effectMethod.call( elem[0], args, done );
  3320. }
  3321. }
  3322. return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
  3323. },
  3324. show: (function( orig ) {
  3325. return function( option ) {
  3326. if ( standardAnimationOption( option ) ) {
  3327. return orig.apply( this, arguments );
  3328. } else {
  3329. var args = _normalizeArguments.apply( this, arguments );
  3330. args.mode = "show";
  3331. return this.effect.call( this, args );
  3332. }
  3333. };
  3334. })( $.fn.show ),
  3335. hide: (function( orig ) {
  3336. return function( option ) {
  3337. if ( standardAnimationOption( option ) ) {
  3338. return orig.apply( this, arguments );
  3339. } else {
  3340. var args = _normalizeArguments.apply( this, arguments );
  3341. args.mode = "hide";
  3342. return this.effect.call( this, args );
  3343. }
  3344. };
  3345. })( $.fn.hide ),
  3346. toggle: (function( orig ) {
  3347. return function( option ) {
  3348. if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
  3349. return orig.apply( this, arguments );
  3350. } else {
  3351. var args = _normalizeArguments.apply( this, arguments );
  3352. args.mode = "toggle";
  3353. return this.effect.call( this, args );
  3354. }
  3355. };
  3356. })( $.fn.toggle ),
  3357. // helper functions
  3358. cssUnit: function(key) {
  3359. var style = this.css( key ),
  3360. val = [];
  3361. $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
  3362. if ( style.indexOf( unit ) > 0 ) {
  3363. val = [ parseFloat( style ), unit ];
  3364. }
  3365. });
  3366. return val;
  3367. }
  3368. });
  3369. })();
  3370. /******************************************************************************/
  3371. /*********************************** EASING ***********************************/
  3372. /******************************************************************************/
  3373. (function() {
  3374. // based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
  3375. var baseEasings = {};
  3376. $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
  3377. baseEasings[ name ] = function( p ) {
  3378. return Math.pow( p, i + 2 );
  3379. };
  3380. });
  3381. $.extend( baseEasings, {
  3382. Sine: function ( p ) {
  3383. return 1 - Math.cos( p * Math.PI / 2 );
  3384. },
  3385. Circ: function ( p ) {
  3386. return 1 - Math.sqrt( 1 - p * p );
  3387. },
  3388. Elastic: function( p ) {
  3389. return p === 0 || p === 1 ? p :
  3390. -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
  3391. },
  3392. Back: function( p ) {
  3393. return p * p * ( 3 * p - 2 );
  3394. },
  3395. Bounce: function ( p ) {
  3396. var pow2,
  3397. bounce = 4;
  3398. while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
  3399. return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
  3400. }
  3401. });
  3402. $.each( baseEasings, function( name, easeIn ) {
  3403. $.easing[ "easeIn" + name ] = easeIn;
  3404. $.easing[ "easeOut" + name ] = function( p ) {
  3405. return 1 - easeIn( 1 - p );
  3406. };
  3407. $.easing[ "easeInOut" + name ] = function( p ) {
  3408. return p < 0.5 ?
  3409. easeIn( p * 2 ) / 2 :
  3410. 1 - easeIn( p * -2 + 2 ) / 2;
  3411. };
  3412. });
  3413. })();
  3414. })(jQuery);
  3415. /*!
  3416. * jQuery UI Touch Punch 0.2.2
  3417. *
  3418. * Copyright 2011, Dave Furfero
  3419. * Dual licensed under the MIT or GPL Version 2 licenses.
  3420. *
  3421. * Depends:
  3422. * jquery.ui.widget.js
  3423. * jquery.ui.mouse.js
  3424. */
  3425. (function ($) {
  3426. // Detect touch support
  3427. $.support.touch = 'ontouchend' in document;
  3428. // Ignore browsers without touch support
  3429. if (!$.support.touch) {
  3430. return;
  3431. }
  3432. var mouseProto = $.ui.mouse.prototype,
  3433. _mouseInit = mouseProto._mouseInit,
  3434. touchHandled;
  3435. /**
  3436. * Simulate a mouse event based on a corresponding touch event
  3437. * @param {Object} event A touch event
  3438. * @param {String} simulatedType The corresponding mouse event
  3439. */
  3440. function simulateMouseEvent (event, simulatedType) {
  3441. // Ignore multi-touch events
  3442. if (event.originalEvent.touches.length > 1) {
  3443. return;
  3444. }
  3445. event.preventDefault();
  3446. var touch = event.originalEvent.changedTouches[0],
  3447. simulatedEvent = document.createEvent('MouseEvents');
  3448. // Initialize the simulated mouse event using the touch event's coordinates
  3449. simulatedEvent.initMouseEvent(
  3450. simulatedType, // type
  3451. true, // bubbles
  3452. true, // cancelable
  3453. window, // view
  3454. 1, // detail
  3455. touch.screenX, // screenX
  3456. touch.screenY, // screenY
  3457. touch.clientX, // clientX
  3458. touch.clientY, // clientY
  3459. false, // ctrlKey
  3460. false, // altKey
  3461. false, // shiftKey
  3462. false, // metaKey
  3463. 0, // button
  3464. null // relatedTarget
  3465. );
  3466. // Dispatch the simulated event to the target element
  3467. event.target.dispatchEvent(simulatedEvent);
  3468. }
  3469. /**
  3470. * Handle the jQuery UI widget's touchstart events
  3471. * @param {Object} event The widget element's touchstart event
  3472. */
  3473. mouseProto._touchStart = function (event) {
  3474. var self = this;
  3475. // Ignore the event if another widget is already being handled
  3476. if (touchHandled || !self._mouseCapture(event.originalEvent.changedTouches[0])) {
  3477. return;
  3478. }
  3479. // Set the flag to prevent other widgets from inheriting the touch event
  3480. touchHandled = true;
  3481. // Track movement to determine if interaction was a click
  3482. self._touchMoved = false;
  3483. // Simulate the mouseover event
  3484. simulateMouseEvent(event, 'mouseover');
  3485. // Simulate the mousemove event
  3486. simulateMouseEvent(event, 'mousemove');
  3487. // Simulate the mousedown event
  3488. simulateMouseEvent(event, 'mousedown');
  3489. };
  3490. /**
  3491. * Handle the jQuery UI widget's touchmove events
  3492. * @param {Object} event The document's touchmove event
  3493. */
  3494. mouseProto._touchMove = function (event) {
  3495. // Ignore event if not handled
  3496. if (!touchHandled) {
  3497. return;
  3498. }
  3499. // Interaction was not a click
  3500. this._touchMoved = true;
  3501. // Simulate the mousemove event
  3502. simulateMouseEvent(event, 'mousemove');
  3503. };
  3504. /**
  3505. * Handle the jQuery UI widget's touchend events
  3506. * @param {Object} event The document's touchend event
  3507. */
  3508. mouseProto._touchEnd = function (event) {
  3509. // Ignore event if not handled
  3510. if (!touchHandled) {
  3511. return;
  3512. }
  3513. // Simulate the mouseup event
  3514. simulateMouseEvent(event, 'mouseup');
  3515. // Simulate the mouseout event
  3516. simulateMouseEvent(event, 'mouseout');
  3517. // If the touch interaction did not move, it should trigger a click
  3518. if (!this._touchMoved) {
  3519. // Simulate the click event
  3520. simulateMouseEvent(event, 'click');
  3521. }
  3522. // Unset the flag to allow other widgets to inherit the touch event
  3523. touchHandled = false;
  3524. };
  3525. /**
  3526. * A duck punch of the $.ui.mouse _mouseInit method to support touch events.
  3527. * This method extends the widget with bound touch event handlers that
  3528. * translate touch events to mouse events and pass them to the widget's
  3529. * original mouse event handling methods.
  3530. */
  3531. mouseProto._mouseInit = function () {
  3532. var self = this;
  3533. // Delegate the touch handlers to the widget's element
  3534. self.element
  3535. .bind('touchstart', $.proxy(self, '_touchStart'))
  3536. .bind('touchmove', $.proxy(self, '_touchMove'))
  3537. .bind('touchend', $.proxy(self, '_touchEnd'));
  3538. // Call the original $.ui.mouse init method
  3539. _mouseInit.call(self);
  3540. };
  3541. })(jQuery);
  3542. /*!
  3543. * Bootstrap v3.2.0 (http://getbootstrap.com)
  3544. * Copyright 2011-2014 Twitter, Inc.
  3545. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  3546. */
  3547. if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript requires jQuery') }
  3548. /* ========================================================================
  3549. * Bootstrap: transition.js v3.2.0
  3550. * http://getbootstrap.com/javascript/#transitions
  3551. * ========================================================================
  3552. * Copyright 2011-2014 Twitter, Inc.
  3553. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  3554. * ======================================================================== */
  3555. +function ($) {
  3556. 'use strict';
  3557. // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
  3558. // ============================================================
  3559. function transitionEnd() {
  3560. var el = document.createElement('bootstrap')
  3561. var transEndEventNames = {
  3562. WebkitTransition : 'webkitTransitionEnd',
  3563. MozTransition : 'transitionend',
  3564. OTransition : 'oTransitionEnd otransitionend',
  3565. transition : 'transitionend'
  3566. }
  3567. for (var name in transEndEventNames) {
  3568. if (el.style[name] !== undefined) {
  3569. return { end: transEndEventNames[name] }
  3570. }
  3571. }
  3572. return false // explicit for ie8 ( ._.)
  3573. }
  3574. // http://blog.alexmaccaw.com/css-transitions
  3575. $.fn.emulateTransitionEnd = function (duration) {
  3576. var called = false
  3577. var $el = this
  3578. $(this).one('bsTransitionEnd', function () { called = true })
  3579. var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
  3580. setTimeout(callback, duration)
  3581. return this
  3582. }
  3583. $(function () {
  3584. $.support.transition = transitionEnd()
  3585. if (!$.support.transition) return
  3586. $.event.special.bsTransitionEnd = {
  3587. bindType: $.support.transition.end,
  3588. delegateType: $.support.transition.end,
  3589. handle: function (e) {
  3590. if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
  3591. }
  3592. }
  3593. })
  3594. }(jQuery);
  3595. /* ========================================================================
  3596. * Bootstrap: alert.js v3.2.0
  3597. * http://getbootstrap.com/javascript/#alerts
  3598. * ========================================================================
  3599. * Copyright 2011-2014 Twitter, Inc.
  3600. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  3601. * ======================================================================== */
  3602. +function ($) {
  3603. 'use strict';
  3604. // ALERT CLASS DEFINITION
  3605. // ======================
  3606. var dismiss = '[data-dismiss="alert"]'
  3607. var Alert = function (el) {
  3608. $(el).on('click', dismiss, this.close)
  3609. }
  3610. Alert.VERSION = '3.2.0'
  3611. Alert.prototype.close = function (e) {
  3612. var $this = $(this)
  3613. var selector = $this.attr('data-target')
  3614. if (!selector) {
  3615. selector = $this.attr('href')
  3616. selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
  3617. }
  3618. var $parent = $(selector)
  3619. if (e) e.preventDefault()
  3620. if (!$parent.length) {
  3621. $parent = $this.hasClass('alert') ? $this : $this.parent()
  3622. }
  3623. $parent.trigger(e = $.Event('close.bs.alert'))
  3624. if (e.isDefaultPrevented()) return
  3625. $parent.removeClass('in')
  3626. function removeElement() {
  3627. // detach from parent, fire event then clean up data
  3628. $parent.detach().trigger('closed.bs.alert').remove()
  3629. }
  3630. $.support.transition && $parent.hasClass('fade') ?
  3631. $parent
  3632. .one('bsTransitionEnd', removeElement)
  3633. .emulateTransitionEnd(150) :
  3634. removeElement()
  3635. }
  3636. // ALERT PLUGIN DEFINITION
  3637. // =======================
  3638. function Plugin(option) {
  3639. return this.each(function () {
  3640. var $this = $(this)
  3641. var data = $this.data('bs.alert')
  3642. if (!data) $this.data('bs.alert', (data = new Alert(this)))
  3643. if (typeof option == 'string') data[option].call($this)
  3644. })
  3645. }
  3646. var old = $.fn.alert
  3647. $.fn.alert = Plugin
  3648. $.fn.alert.Constructor = Alert
  3649. // ALERT NO CONFLICT
  3650. // =================
  3651. $.fn.alert.noConflict = function () {
  3652. $.fn.alert = old
  3653. return this
  3654. }
  3655. // ALERT DATA-API
  3656. // ==============
  3657. $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
  3658. }(jQuery);
  3659. /* ========================================================================
  3660. * Bootstrap: button.js v3.2.0
  3661. * http://getbootstrap.com/javascript/#buttons
  3662. * ========================================================================
  3663. * Copyright 2011-2014 Twitter, Inc.
  3664. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  3665. * ======================================================================== */
  3666. +function ($) {
  3667. 'use strict';
  3668. // BUTTON PUBLIC CLASS DEFINITION
  3669. // ==============================
  3670. var Button = function (element, options) {
  3671. this.$element = $(element)
  3672. this.options = $.extend({}, Button.DEFAULTS, options)
  3673. this.isLoading = false
  3674. }
  3675. Button.VERSION = '3.2.0'
  3676. Button.DEFAULTS = {
  3677. loadingText: 'loading...'
  3678. }
  3679. Button.prototype.setState = function (state) {
  3680. var d = 'disabled'
  3681. var $el = this.$element
  3682. var val = $el.is('input') ? 'val' : 'html'
  3683. var data = $el.data()
  3684. state = state + 'Text'
  3685. if (data.resetText == null) $el.data('resetText', $el[val]())
  3686. $el[val](data[state] == null ? this.options[state] : data[state])
  3687. // push to event loop to allow forms to submit
  3688. setTimeout($.proxy(function () {
  3689. if (state == 'loadingText') {
  3690. this.isLoading = true
  3691. $el.addClass(d).attr(d, d)
  3692. } else if (this.isLoading) {
  3693. this.isLoading = false
  3694. $el.removeClass(d).removeAttr(d)
  3695. }
  3696. }, this), 0)
  3697. }
  3698. Button.prototype.toggle = function () {
  3699. var changed = true
  3700. var $parent = this.$element.closest('[data-toggle="buttons"]')
  3701. if ($parent.length) {
  3702. var $input = this.$element.find('input')
  3703. if ($input.prop('type') == 'radio') {
  3704. if ($input.prop('checked') && this.$element.hasClass('active')) changed = false
  3705. else $parent.find('.active').removeClass('active')
  3706. }
  3707. if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')
  3708. }
  3709. if (changed) this.$element.toggleClass('active')
  3710. }
  3711. // BUTTON PLUGIN DEFINITION
  3712. // ========================
  3713. function Plugin(option) {
  3714. return this.each(function () {
  3715. var $this = $(this)
  3716. var data = $this.data('bs.button')
  3717. var options = typeof option == 'object' && option
  3718. if (!data) $this.data('bs.button', (data = new Button(this, options)))
  3719. if (option == 'toggle') data.toggle()
  3720. else if (option) data.setState(option)
  3721. })
  3722. }
  3723. var old = $.fn.button
  3724. $.fn.button = Plugin
  3725. $.fn.button.Constructor = Button
  3726. // BUTTON NO CONFLICT
  3727. // ==================
  3728. $.fn.button.noConflict = function () {
  3729. $.fn.button = old
  3730. return this
  3731. }
  3732. // BUTTON DATA-API
  3733. // ===============
  3734. $(document).on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
  3735. var $btn = $(e.target)
  3736. if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
  3737. Plugin.call($btn, 'toggle')
  3738. e.preventDefault()
  3739. })
  3740. }(jQuery);
  3741. /* ========================================================================
  3742. * Bootstrap: carousel.js v3.2.0
  3743. * http://getbootstrap.com/javascript/#carousel
  3744. * ========================================================================
  3745. * Copyright 2011-2014 Twitter, Inc.
  3746. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  3747. * ======================================================================== */
  3748. +function ($) {
  3749. 'use strict';
  3750. // CAROUSEL CLASS DEFINITION
  3751. // =========================
  3752. var Carousel = function (element, options) {
  3753. this.$element = $(element).on('keydown.bs.carousel', $.proxy(this.keydown, this))
  3754. this.$indicators = this.$element.find('.carousel-indicators')
  3755. this.options = options
  3756. this.paused =
  3757. this.sliding =
  3758. this.interval =
  3759. this.$active =
  3760. this.$items = null
  3761. this.options.pause == 'hover' && this.$element
  3762. .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
  3763. .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
  3764. }
  3765. Carousel.VERSION = '3.2.0'
  3766. Carousel.DEFAULTS = {
  3767. interval: 5000,
  3768. pause: 'hover',
  3769. wrap: true
  3770. }
  3771. Carousel.prototype.keydown = function (e) {
  3772. switch (e.which) {
  3773. case 37: this.prev(); break
  3774. case 39: this.next(); break
  3775. default: return
  3776. }
  3777. e.preventDefault()
  3778. }
  3779. Carousel.prototype.cycle = function (e) {
  3780. e || (this.paused = false)
  3781. this.interval && clearInterval(this.interval)
  3782. this.options.interval
  3783. && !this.paused
  3784. && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
  3785. return this
  3786. }
  3787. Carousel.prototype.getItemIndex = function (item) {
  3788. this.$items = item.parent().children('.item')
  3789. return this.$items.index(item || this.$active)
  3790. }
  3791. Carousel.prototype.to = function (pos) {
  3792. var that = this
  3793. var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
  3794. if (pos > (this.$items.length - 1) || pos < 0) return
  3795. if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
  3796. if (activeIndex == pos) return this.pause().cycle()
  3797. return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))
  3798. }
  3799. Carousel.prototype.pause = function (e) {
  3800. e || (this.paused = true)
  3801. if (this.$element.find('.next, .prev').length && $.support.transition) {
  3802. this.$element.trigger($.support.transition.end)
  3803. this.cycle(true)
  3804. }
  3805. this.interval = clearInterval(this.interval)
  3806. return this
  3807. }
  3808. Carousel.prototype.next = function () {
  3809. if (this.sliding) return
  3810. return this.slide('next')
  3811. }
  3812. Carousel.prototype.prev = function () {
  3813. if (this.sliding) return
  3814. return this.slide('prev')
  3815. }
  3816. Carousel.prototype.slide = function (type, next) {
  3817. var $active = this.$element.find('.item.active')
  3818. var $next = next || $active[type]()
  3819. var isCycling = this.interval
  3820. var direction = type == 'next' ? 'left' : 'right'
  3821. var fallback = type == 'next' ? 'first' : 'last'
  3822. var that = this
  3823. if (!$next.length) {
  3824. if (!this.options.wrap) return
  3825. $next = this.$element.find('.item')[fallback]()
  3826. }
  3827. if ($next.hasClass('active')) return (this.sliding = false)
  3828. var relatedTarget = $next[0]
  3829. var slideEvent = $.Event('slide.bs.carousel', {
  3830. relatedTarget: relatedTarget,
  3831. direction: direction
  3832. })
  3833. this.$element.trigger(slideEvent)
  3834. if (slideEvent.isDefaultPrevented()) return
  3835. this.sliding = true
  3836. isCycling && this.pause()
  3837. if (this.$indicators.length) {
  3838. this.$indicators.find('.active').removeClass('active')
  3839. var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
  3840. $nextIndicator && $nextIndicator.addClass('active')
  3841. }
  3842. var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
  3843. if ($.support.transition && this.$element.hasClass('slide')) {
  3844. $next.addClass(type)
  3845. $next[0].offsetWidth // force reflow
  3846. $active.addClass(direction)
  3847. $next.addClass(direction)
  3848. $active
  3849. .one('bsTransitionEnd', function () {
  3850. $next.removeClass([type, direction].join(' ')).addClass('active')
  3851. $active.removeClass(['active', direction].join(' '))
  3852. that.sliding = false
  3853. setTimeout(function () {
  3854. that.$element.trigger(slidEvent)
  3855. }, 0)
  3856. })
  3857. .emulateTransitionEnd($active.css('transition-duration').slice(0, -1) * 1000)
  3858. } else {
  3859. $active.removeClass('active')
  3860. $next.addClass('active')
  3861. this.sliding = false
  3862. this.$element.trigger(slidEvent)
  3863. }
  3864. isCycling && this.cycle()
  3865. return this
  3866. }
  3867. // CAROUSEL PLUGIN DEFINITION
  3868. // ==========================
  3869. function Plugin(option) {
  3870. return this.each(function () {
  3871. var $this = $(this)
  3872. var data = $this.data('bs.carousel')
  3873. var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
  3874. var action = typeof option == 'string' ? option : options.slide
  3875. if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
  3876. if (typeof option == 'number') data.to(option)
  3877. else if (action) data[action]()
  3878. else if (options.interval) data.pause().cycle()
  3879. })
  3880. }
  3881. var old = $.fn.carousel
  3882. $.fn.carousel = Plugin
  3883. $.fn.carousel.Constructor = Carousel
  3884. // CAROUSEL NO CONFLICT
  3885. // ====================
  3886. $.fn.carousel.noConflict = function () {
  3887. $.fn.carousel = old
  3888. return this
  3889. }
  3890. // CAROUSEL DATA-API
  3891. // =================
  3892. $(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {
  3893. var href
  3894. var $this = $(this)
  3895. var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
  3896. if (!$target.hasClass('carousel')) return
  3897. var options = $.extend({}, $target.data(), $this.data())
  3898. var slideIndex = $this.attr('data-slide-to')
  3899. if (slideIndex) options.interval = false
  3900. Plugin.call($target, options)
  3901. if (slideIndex) {
  3902. $target.data('bs.carousel').to(slideIndex)
  3903. }
  3904. e.preventDefault()
  3905. })
  3906. $(window).on('load', function () {
  3907. $('[data-ride="carousel"]').each(function () {
  3908. var $carousel = $(this)
  3909. Plugin.call($carousel, $carousel.data())
  3910. })
  3911. })
  3912. }(jQuery);
  3913. /* ========================================================================
  3914. * Bootstrap: collapse.js v3.2.0
  3915. * http://getbootstrap.com/javascript/#collapse
  3916. * ========================================================================
  3917. * Copyright 2011-2014 Twitter, Inc.
  3918. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  3919. * ======================================================================== */
  3920. +function ($) {
  3921. 'use strict';
  3922. // COLLAPSE PUBLIC CLASS DEFINITION
  3923. // ================================
  3924. var Collapse = function (element, options) {
  3925. this.$element = $(element)
  3926. this.options = $.extend({}, Collapse.DEFAULTS, options)
  3927. this.transitioning = null
  3928. if (this.options.parent) this.$parent = $(this.options.parent)
  3929. if (this.options.toggle) this.toggle()
  3930. }
  3931. Collapse.VERSION = '3.2.0'
  3932. Collapse.DEFAULTS = {
  3933. toggle: true
  3934. }
  3935. Collapse.prototype.dimension = function () {
  3936. var hasWidth = this.$element.hasClass('width')
  3937. return hasWidth ? 'width' : 'height'
  3938. }
  3939. Collapse.prototype.show = function () {
  3940. if (this.transitioning || this.$element.hasClass('in')) return
  3941. var startEvent = $.Event('show.bs.collapse')
  3942. this.$element.trigger(startEvent)
  3943. if (startEvent.isDefaultPrevented()) return
  3944. var actives = this.$parent && this.$parent.find('> .panel > .in')
  3945. if (actives && actives.length) {
  3946. var hasData = actives.data('bs.collapse')
  3947. if (hasData && hasData.transitioning) return
  3948. Plugin.call(actives, 'hide')
  3949. hasData || actives.data('bs.collapse', null)
  3950. }
  3951. var dimension = this.dimension()
  3952. this.$element
  3953. .removeClass('collapse')
  3954. .addClass('collapsing')[dimension](0)
  3955. this.transitioning = 1
  3956. var complete = function () {
  3957. this.$element
  3958. .removeClass('collapsing')
  3959. .addClass('collapse in')[dimension]('')
  3960. this.transitioning = 0
  3961. this.$element
  3962. .trigger('shown.bs.collapse')
  3963. }
  3964. if (!$.support.transition) return complete.call(this)
  3965. var scrollSize = $.camelCase(['scroll', dimension].join('-'))
  3966. this.$element
  3967. .one('bsTransitionEnd', $.proxy(complete, this))
  3968. .emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize])
  3969. }
  3970. Collapse.prototype.hide = function () {
  3971. if (this.transitioning || !this.$element.hasClass('in')) return
  3972. var startEvent = $.Event('hide.bs.collapse')
  3973. this.$element.trigger(startEvent)
  3974. if (startEvent.isDefaultPrevented()) return
  3975. var dimension = this.dimension()
  3976. this.$element[dimension](this.$element[dimension]())[0].offsetHeight
  3977. this.$element
  3978. .addClass('collapsing')
  3979. .removeClass('collapse')
  3980. .removeClass('in')
  3981. this.transitioning = 1
  3982. var complete = function () {
  3983. this.transitioning = 0
  3984. this.$element
  3985. .trigger('hidden.bs.collapse')
  3986. .removeClass('collapsing')
  3987. .addClass('collapse')
  3988. }
  3989. if (!$.support.transition) return complete.call(this)
  3990. this.$element
  3991. [dimension](0)
  3992. .one('bsTransitionEnd', $.proxy(complete, this))
  3993. .emulateTransitionEnd(350)
  3994. }
  3995. Collapse.prototype.toggle = function () {
  3996. this[this.$element.hasClass('in') ? 'hide' : 'show']()
  3997. }
  3998. // COLLAPSE PLUGIN DEFINITION
  3999. // ==========================
  4000. function Plugin(option) {
  4001. return this.each(function () {
  4002. var $this = $(this)
  4003. var data = $this.data('bs.collapse')
  4004. var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
  4005. if (!data && options.toggle && option == 'show') option = !option
  4006. if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
  4007. if (typeof option == 'string') data[option]()
  4008. })
  4009. }
  4010. var old = $.fn.collapse
  4011. $.fn.collapse = Plugin
  4012. $.fn.collapse.Constructor = Collapse
  4013. // COLLAPSE NO CONFLICT
  4014. // ====================
  4015. $.fn.collapse.noConflict = function () {
  4016. $.fn.collapse = old
  4017. return this
  4018. }
  4019. // COLLAPSE DATA-API
  4020. // =================
  4021. $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
  4022. var href
  4023. var $this = $(this)
  4024. var target = $this.attr('data-target')
  4025. || e.preventDefault()
  4026. || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
  4027. var $target = $(target)
  4028. var data = $target.data('bs.collapse')
  4029. var option = data ? 'toggle' : $this.data()
  4030. var parent = $this.attr('data-parent')
  4031. var $parent = parent && $(parent)
  4032. if (!data || !data.transitioning) {
  4033. if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed')
  4034. $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
  4035. }
  4036. Plugin.call($target, option)
  4037. })
  4038. }(jQuery);
  4039. /* ========================================================================
  4040. * Bootstrap: dropdown.js v3.2.0
  4041. * http://getbootstrap.com/javascript/#dropdowns
  4042. * ========================================================================
  4043. * Copyright 2011-2014 Twitter, Inc.
  4044. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  4045. * ======================================================================== */
  4046. +function ($) {
  4047. 'use strict';
  4048. // DROPDOWN CLASS DEFINITION
  4049. // =========================
  4050. var backdrop = '.dropdown-backdrop'
  4051. var toggle = '[data-toggle="dropdown"]'
  4052. var Dropdown = function (element) {
  4053. $(element).on('click.bs.dropdown', this.toggle)
  4054. }
  4055. Dropdown.VERSION = '3.2.0'
  4056. Dropdown.prototype.toggle = function (e) {
  4057. var $this = $(this)
  4058. if ($this.is('.disabled, :disabled')) return
  4059. var $parent = getParent($this)
  4060. var isActive = $parent.hasClass('open')
  4061. clearMenus()
  4062. if (!isActive) {
  4063. if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
  4064. // if mobile we use a backdrop because click events don't delegate
  4065. $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
  4066. }
  4067. var relatedTarget = { relatedTarget: this }
  4068. $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
  4069. if (e.isDefaultPrevented()) return
  4070. $this.trigger('focus')
  4071. $parent
  4072. .toggleClass('open')
  4073. .trigger('shown.bs.dropdown', relatedTarget)
  4074. }
  4075. return false
  4076. }
  4077. Dropdown.prototype.keydown = function (e) {
  4078. if (!/(38|40|27)/.test(e.keyCode)) return
  4079. var $this = $(this)
  4080. e.preventDefault()
  4081. e.stopPropagation()
  4082. if ($this.is('.disabled, :disabled')) return
  4083. var $parent = getParent($this)
  4084. var isActive = $parent.hasClass('open')
  4085. if (!isActive || (isActive && e.keyCode == 27)) {
  4086. if (e.which == 27) $parent.find(toggle).trigger('focus')
  4087. return $this.trigger('click')
  4088. }
  4089. var desc = ' li:not(.divider):visible a'
  4090. var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc)
  4091. if (!$items.length) return
  4092. var index = $items.index($items.filter(':focus'))
  4093. if (e.keyCode == 38 && index > 0) index-- // up
  4094. if (e.keyCode == 40 && index < $items.length - 1) index++ // down
  4095. if (!~index) index = 0
  4096. $items.eq(index).trigger('focus')
  4097. }
  4098. function clearMenus(e) {
  4099. if (e && e.which === 3) return
  4100. $(backdrop).remove()
  4101. $(toggle).each(function () {
  4102. var $parent = getParent($(this))
  4103. var relatedTarget = { relatedTarget: this }
  4104. if (!$parent.hasClass('open')) return
  4105. $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
  4106. if (e.isDefaultPrevented()) return
  4107. $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
  4108. })
  4109. }
  4110. function getParent($this) {
  4111. var selector = $this.attr('data-target')
  4112. if (!selector) {
  4113. selector = $this.attr('href')
  4114. selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
  4115. }
  4116. var $parent = selector && $(selector)
  4117. return $parent && $parent.length ? $parent : $this.parent()
  4118. }
  4119. // DROPDOWN PLUGIN DEFINITION
  4120. // ==========================
  4121. function Plugin(option) {
  4122. return this.each(function () {
  4123. var $this = $(this)
  4124. var data = $this.data('bs.dropdown')
  4125. if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
  4126. if (typeof option == 'string') data[option].call($this)
  4127. })
  4128. }
  4129. var old = $.fn.dropdown
  4130. $.fn.dropdown = Plugin
  4131. $.fn.dropdown.Constructor = Dropdown
  4132. // DROPDOWN NO CONFLICT
  4133. // ====================
  4134. $.fn.dropdown.noConflict = function () {
  4135. $.fn.dropdown = old
  4136. return this
  4137. }
  4138. // APPLY TO STANDARD DROPDOWN ELEMENTS
  4139. // ===================================
  4140. $(document)
  4141. .on('click.bs.dropdown.data-api', clearMenus)
  4142. .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
  4143. .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
  4144. .on('keydown.bs.dropdown.data-api', toggle + ', [role="menu"], [role="listbox"]', Dropdown.prototype.keydown)
  4145. }(jQuery);
  4146. /* ========================================================================
  4147. * Bootstrap: modal.js v3.2.0
  4148. * http://getbootstrap.com/javascript/#modals
  4149. * ========================================================================
  4150. * Copyright 2011-2014 Twitter, Inc.
  4151. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  4152. * ======================================================================== */
  4153. +function ($) {
  4154. 'use strict';
  4155. // MODAL CLASS DEFINITION
  4156. // ======================
  4157. var Modal = function (element, options) {
  4158. this.options = options
  4159. this.$body = $(document.body)
  4160. this.$element = $(element)
  4161. this.$backdrop =
  4162. this.isShown = null
  4163. this.scrollbarWidth = 0
  4164. if (this.options.remote) {
  4165. this.$element
  4166. .find('.modal-content')
  4167. .load(this.options.remote, $.proxy(function () {
  4168. this.$element.trigger('loaded.bs.modal')
  4169. }, this))
  4170. }
  4171. }
  4172. Modal.VERSION = '3.2.0'
  4173. Modal.DEFAULTS = {
  4174. backdrop: true,
  4175. keyboard: true,
  4176. show: true
  4177. }
  4178. Modal.prototype.toggle = function (_relatedTarget) {
  4179. return this.isShown ? this.hide() : this.show(_relatedTarget)
  4180. }
  4181. Modal.prototype.show = function (_relatedTarget) {
  4182. var that = this
  4183. var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
  4184. this.$element.trigger(e)
  4185. if (this.isShown || e.isDefaultPrevented()) return
  4186. this.isShown = true
  4187. this.checkScrollbar()
  4188. this.$body.addClass('modal-open')
  4189. this.setScrollbar()
  4190. this.escape()
  4191. this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
  4192. this.backdrop(function () {
  4193. var transition = $.support.transition && that.$element.hasClass('fade')
  4194. if (!that.$element.parent().length) {
  4195. that.$element.appendTo(that.$body) // don't move modals dom position
  4196. }
  4197. that.$element
  4198. .show()
  4199. .scrollTop(0)
  4200. if (transition) {
  4201. that.$element[0].offsetWidth // force reflow
  4202. }
  4203. that.$element
  4204. .addClass('in')
  4205. .attr('aria-hidden', false)
  4206. that.enforceFocus()
  4207. var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
  4208. transition ?
  4209. that.$element.find('.modal-dialog') // wait for modal to slide in
  4210. .one('bsTransitionEnd', function () {
  4211. that.$element.trigger('focus').trigger(e)
  4212. })
  4213. .emulateTransitionEnd(300) :
  4214. that.$element.trigger('focus').trigger(e)
  4215. })
  4216. }
  4217. Modal.prototype.hide = function (e) {
  4218. if (e) e.preventDefault()
  4219. e = $.Event('hide.bs.modal')
  4220. this.$element.trigger(e)
  4221. if (!this.isShown || e.isDefaultPrevented()) return
  4222. this.isShown = false
  4223. this.$body.removeClass('modal-open')
  4224. this.resetScrollbar()
  4225. this.escape()
  4226. $(document).off('focusin.bs.modal')
  4227. this.$element
  4228. .removeClass('in')
  4229. .attr('aria-hidden', true)
  4230. .off('click.dismiss.bs.modal')
  4231. $.support.transition && this.$element.hasClass('fade') ?
  4232. this.$element
  4233. .one('bsTransitionEnd', $.proxy(this.hideModal, this))
  4234. .emulateTransitionEnd(300) :
  4235. this.hideModal()
  4236. }
  4237. Modal.prototype.enforceFocus = function () {
  4238. $(document)
  4239. .off('focusin.bs.modal') // guard against infinite focus loop
  4240. .on('focusin.bs.modal', $.proxy(function (e) {
  4241. if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
  4242. this.$element.trigger('focus')
  4243. }
  4244. }, this))
  4245. }
  4246. Modal.prototype.escape = function () {
  4247. if (this.isShown && this.options.keyboard) {
  4248. this.$element.on('keyup.dismiss.bs.modal', $.proxy(function (e) {
  4249. e.which == 27 && this.hide()
  4250. }, this))
  4251. } else if (!this.isShown) {
  4252. this.$element.off('keyup.dismiss.bs.modal')
  4253. }
  4254. }
  4255. Modal.prototype.hideModal = function () {
  4256. var that = this
  4257. this.$element.hide()
  4258. this.backdrop(function () {
  4259. that.$element.trigger('hidden.bs.modal')
  4260. })
  4261. }
  4262. Modal.prototype.removeBackdrop = function () {
  4263. this.$backdrop && this.$backdrop.remove()
  4264. this.$backdrop = null
  4265. }
  4266. Modal.prototype.backdrop = function (callback) {
  4267. var that = this
  4268. var animate = this.$element.hasClass('fade') ? 'fade' : ''
  4269. if (this.isShown && this.options.backdrop) {
  4270. var doAnimate = $.support.transition && animate
  4271. this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
  4272. .appendTo(this.$body)
  4273. this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
  4274. if (e.target !== e.currentTarget) return
  4275. this.options.backdrop == 'static'
  4276. ? this.$element[0].focus.call(this.$element[0])
  4277. : this.hide.call(this)
  4278. }, this))
  4279. if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
  4280. this.$backdrop.addClass('in')
  4281. if (!callback) return
  4282. doAnimate ?
  4283. this.$backdrop
  4284. .one('bsTransitionEnd', callback)
  4285. .emulateTransitionEnd(150) :
  4286. callback()
  4287. } else if (!this.isShown && this.$backdrop) {
  4288. this.$backdrop.removeClass('in')
  4289. var callbackRemove = function () {
  4290. that.removeBackdrop()
  4291. callback && callback()
  4292. }
  4293. $.support.transition && this.$element.hasClass('fade') ?
  4294. this.$backdrop
  4295. .one('bsTransitionEnd', callbackRemove)
  4296. .emulateTransitionEnd(150) :
  4297. callbackRemove()
  4298. } else if (callback) {
  4299. callback()
  4300. }
  4301. }
  4302. Modal.prototype.checkScrollbar = function () {
  4303. if (document.body.clientWidth >= window.innerWidth) return
  4304. this.scrollbarWidth = this.scrollbarWidth || this.measureScrollbar()
  4305. }
  4306. Modal.prototype.setScrollbar = function () {
  4307. var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
  4308. if (this.scrollbarWidth) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
  4309. }
  4310. Modal.prototype.resetScrollbar = function () {
  4311. this.$body.css('padding-right', '')
  4312. }
  4313. Modal.prototype.measureScrollbar = function () { // thx walsh
  4314. var scrollDiv = document.createElement('div')
  4315. scrollDiv.className = 'modal-scrollbar-measure'
  4316. this.$body.append(scrollDiv)
  4317. var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
  4318. this.$body[0].removeChild(scrollDiv)
  4319. return scrollbarWidth
  4320. }
  4321. // MODAL PLUGIN DEFINITION
  4322. // =======================
  4323. function Plugin(option, _relatedTarget) {
  4324. return this.each(function () {
  4325. var $this = $(this)
  4326. var data = $this.data('bs.modal')
  4327. var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
  4328. if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
  4329. if (typeof option == 'string') data[option](_relatedTarget)
  4330. else if (options.show) data.show(_relatedTarget)
  4331. })
  4332. }
  4333. var old = $.fn.modal
  4334. $.fn.modal = Plugin
  4335. $.fn.modal.Constructor = Modal
  4336. // MODAL NO CONFLICT
  4337. // =================
  4338. $.fn.modal.noConflict = function () {
  4339. $.fn.modal = old
  4340. return this
  4341. }
  4342. // MODAL DATA-API
  4343. // ==============
  4344. $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
  4345. var $this = $(this)
  4346. var href = $this.attr('href')
  4347. var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
  4348. var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
  4349. if ($this.is('a')) e.preventDefault()
  4350. $target.one('show.bs.modal', function (showEvent) {
  4351. if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
  4352. $target.one('hidden.bs.modal', function () {
  4353. $this.is(':visible') && $this.trigger('focus')
  4354. })
  4355. })
  4356. Plugin.call($target, option, this)
  4357. })
  4358. }(jQuery);
  4359. /* ========================================================================
  4360. * Bootstrap: tooltip.js v3.2.0
  4361. * http://getbootstrap.com/javascript/#tooltip
  4362. * Inspired by the original jQuery.tipsy by Jason Frame
  4363. * ========================================================================
  4364. * Copyright 2011-2014 Twitter, Inc.
  4365. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  4366. * ======================================================================== */
  4367. +function ($) {
  4368. 'use strict';
  4369. // TOOLTIP PUBLIC CLASS DEFINITION
  4370. // ===============================
  4371. var Tooltip = function (element, options) {
  4372. this.type =
  4373. this.options =
  4374. this.enabled =
  4375. this.timeout =
  4376. this.hoverState =
  4377. this.$element = null
  4378. this.init('tooltip', element, options)
  4379. }
  4380. Tooltip.VERSION = '3.2.0'
  4381. Tooltip.DEFAULTS = {
  4382. animation: true,
  4383. placement: 'top',
  4384. selector: false,
  4385. template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
  4386. trigger: 'hover focus',
  4387. title: '',
  4388. delay: 0,
  4389. html: false,
  4390. container: false,
  4391. viewport: {
  4392. selector: 'body',
  4393. padding: 0
  4394. }
  4395. }
  4396. Tooltip.prototype.init = function (type, element, options) {
  4397. this.enabled = true
  4398. this.type = type
  4399. this.$element = $(element)
  4400. this.options = this.getOptions(options)
  4401. this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)
  4402. var triggers = this.options.trigger.split(' ')
  4403. for (var i = triggers.length; i--;) {
  4404. var trigger = triggers[i]
  4405. if (trigger == 'click') {
  4406. this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
  4407. } else if (trigger != 'manual') {
  4408. var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'
  4409. var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
  4410. this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
  4411. this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
  4412. }
  4413. }
  4414. this.options.selector ?
  4415. (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
  4416. this.fixTitle()
  4417. }
  4418. Tooltip.prototype.getDefaults = function () {
  4419. return Tooltip.DEFAULTS
  4420. }
  4421. Tooltip.prototype.getOptions = function (options) {
  4422. options = $.extend({}, this.getDefaults(), this.$element.data(), options)
  4423. if (options.delay && typeof options.delay == 'number') {
  4424. options.delay = {
  4425. show: options.delay,
  4426. hide: options.delay
  4427. }
  4428. }
  4429. return options
  4430. }
  4431. Tooltip.prototype.getDelegateOptions = function () {
  4432. var options = {}
  4433. var defaults = this.getDefaults()
  4434. this._options && $.each(this._options, function (key, value) {
  4435. if (defaults[key] != value) options[key] = value
  4436. })
  4437. return options
  4438. }
  4439. Tooltip.prototype.enter = function (obj) {
  4440. var self = obj instanceof this.constructor ?
  4441. obj : $(obj.currentTarget).data('bs.' + this.type)
  4442. if (!self) {
  4443. self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
  4444. $(obj.currentTarget).data('bs.' + this.type, self)
  4445. }
  4446. clearTimeout(self.timeout)
  4447. self.hoverState = 'in'
  4448. if (!self.options.delay || !self.options.delay.show) return self.show()
  4449. self.timeout = setTimeout(function () {
  4450. if (self.hoverState == 'in') self.show()
  4451. }, self.options.delay.show)
  4452. }
  4453. Tooltip.prototype.leave = function (obj) {
  4454. var self = obj instanceof this.constructor ?
  4455. obj : $(obj.currentTarget).data('bs.' + this.type)
  4456. if (!self) {
  4457. self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
  4458. $(obj.currentTarget).data('bs.' + this.type, self)
  4459. }
  4460. clearTimeout(self.timeout)
  4461. self.hoverState = 'out'
  4462. if (!self.options.delay || !self.options.delay.hide) return self.hide()
  4463. self.timeout = setTimeout(function () {
  4464. if (self.hoverState == 'out') self.hide()
  4465. }, self.options.delay.hide)
  4466. }
  4467. Tooltip.prototype.show = function () {
  4468. var e = $.Event('show.bs.' + this.type)
  4469. if (this.hasContent() && this.enabled) {
  4470. this.$element.trigger(e)
  4471. var inDom = $.contains(document.documentElement, this.$element[0])
  4472. if (e.isDefaultPrevented() || !inDom) return
  4473. var that = this
  4474. var $tip = this.tip()
  4475. var tipId = this.getUID(this.type)
  4476. this.setContent()
  4477. $tip.attr('id', tipId)
  4478. this.$element.attr('aria-describedby', tipId)
  4479. if (this.options.animation) $tip.addClass('fade')
  4480. var placement = typeof this.options.placement == 'function' ?
  4481. this.options.placement.call(this, $tip[0], this.$element[0]) :
  4482. this.options.placement
  4483. var autoToken = /\s?auto?\s?/i
  4484. var autoPlace = autoToken.test(placement)
  4485. if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
  4486. $tip
  4487. .detach()
  4488. .css({ top: 0, left: 0, display: 'block' })
  4489. .addClass(placement)
  4490. .data('bs.' + this.type, this)
  4491. this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
  4492. var pos = this.getPosition()
  4493. var actualWidth = $tip[0].offsetWidth
  4494. var actualHeight = $tip[0].offsetHeight
  4495. if (autoPlace) {
  4496. var orgPlacement = placement
  4497. var $parent = this.$element.parent()
  4498. var parentDim = this.getPosition($parent)
  4499. placement = placement == 'bottom' && pos.top + pos.height + actualHeight - parentDim.scroll > parentDim.height ? 'top' :
  4500. placement == 'top' && pos.top - parentDim.scroll - actualHeight < 0 ? 'bottom' :
  4501. placement == 'right' && pos.right + actualWidth > parentDim.width ? 'left' :
  4502. placement == 'left' && pos.left - actualWidth < parentDim.left ? 'right' :
  4503. placement
  4504. $tip
  4505. .removeClass(orgPlacement)
  4506. .addClass(placement)
  4507. }
  4508. var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
  4509. this.applyPlacement(calculatedOffset, placement)
  4510. var complete = function () {
  4511. that.$element.trigger('shown.bs.' + that.type)
  4512. that.hoverState = null
  4513. }
  4514. $.support.transition && this.$tip.hasClass('fade') ?
  4515. $tip
  4516. .one('bsTransitionEnd', complete)
  4517. .emulateTransitionEnd(150) :
  4518. complete()
  4519. }
  4520. }
  4521. Tooltip.prototype.applyPlacement = function (offset, placement) {
  4522. var $tip = this.tip()
  4523. var width = $tip[0].offsetWidth
  4524. var height = $tip[0].offsetHeight
  4525. // manually read margins because getBoundingClientRect includes difference
  4526. var marginTop = parseInt($tip.css('margin-top'), 10)
  4527. var marginLeft = parseInt($tip.css('margin-left'), 10)
  4528. // we must check for NaN for ie 8/9
  4529. if (isNaN(marginTop)) marginTop = 0
  4530. if (isNaN(marginLeft)) marginLeft = 0
  4531. offset.top = offset.top + marginTop
  4532. offset.left = offset.left + marginLeft
  4533. // $.fn.offset doesn't round pixel values
  4534. // so we use setOffset directly with our own function B-0
  4535. $.offset.setOffset($tip[0], $.extend({
  4536. using: function (props) {
  4537. $tip.css({
  4538. top: Math.round(props.top),
  4539. left: Math.round(props.left)
  4540. })
  4541. }
  4542. }, offset), 0)
  4543. $tip.addClass('in')
  4544. // check to see if placing tip in new offset caused the tip to resize itself
  4545. var actualWidth = $tip[0].offsetWidth
  4546. var actualHeight = $tip[0].offsetHeight
  4547. if (placement == 'top' && actualHeight != height) {
  4548. offset.top = offset.top + height - actualHeight
  4549. }
  4550. var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
  4551. if (delta.left) offset.left += delta.left
  4552. else offset.top += delta.top
  4553. var arrowDelta = delta.left ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
  4554. var arrowPosition = delta.left ? 'left' : 'top'
  4555. var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight'
  4556. $tip.offset(offset)
  4557. this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition)
  4558. }
  4559. Tooltip.prototype.replaceArrow = function (delta, dimension, position) {
  4560. this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + '%') : '')
  4561. }
  4562. Tooltip.prototype.setContent = function () {
  4563. var $tip = this.tip()
  4564. var title = this.getTitle()
  4565. $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
  4566. $tip.removeClass('fade in top bottom left right')
  4567. }
  4568. Tooltip.prototype.hide = function () {
  4569. var that = this
  4570. var $tip = this.tip()
  4571. var e = $.Event('hide.bs.' + this.type)
  4572. this.$element.removeAttr('aria-describedby')
  4573. function complete() {
  4574. if (that.hoverState != 'in') $tip.detach()
  4575. that.$element.trigger('hidden.bs.' + that.type)
  4576. }
  4577. this.$element.trigger(e)
  4578. if (e.isDefaultPrevented()) return
  4579. $tip.removeClass('in')
  4580. $.support.transition && this.$tip.hasClass('fade') ?
  4581. $tip
  4582. .one('bsTransitionEnd', complete)
  4583. .emulateTransitionEnd(150) :
  4584. complete()
  4585. this.hoverState = null
  4586. return this
  4587. }
  4588. Tooltip.prototype.fixTitle = function () {
  4589. var $e = this.$element
  4590. if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') {
  4591. $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
  4592. }
  4593. }
  4594. Tooltip.prototype.hasContent = function () {
  4595. return this.getTitle()
  4596. }
  4597. Tooltip.prototype.getPosition = function ($element) {
  4598. $element = $element || this.$element
  4599. var el = $element[0]
  4600. var isBody = el.tagName == 'BODY'
  4601. return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : null, {
  4602. scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop(),
  4603. width: isBody ? $(window).width() : $element.outerWidth(),
  4604. height: isBody ? $(window).height() : $element.outerHeight()
  4605. }, isBody ? { top: 0, left: 0 } : $element.offset())
  4606. }
  4607. Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
  4608. return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
  4609. placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
  4610. placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
  4611. /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
  4612. }
  4613. Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
  4614. var delta = { top: 0, left: 0 }
  4615. if (!this.$viewport) return delta
  4616. var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
  4617. var viewportDimensions = this.getPosition(this.$viewport)
  4618. if (/right|left/.test(placement)) {
  4619. var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll
  4620. var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
  4621. if (topEdgeOffset < viewportDimensions.top) { // top overflow
  4622. delta.top = viewportDimensions.top - topEdgeOffset
  4623. } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
  4624. delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
  4625. }
  4626. } else {
  4627. var leftEdgeOffset = pos.left - viewportPadding
  4628. var rightEdgeOffset = pos.left + viewportPadding + actualWidth
  4629. if (leftEdgeOffset < viewportDimensions.left) { // left overflow
  4630. delta.left = viewportDimensions.left - leftEdgeOffset
  4631. } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow
  4632. delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
  4633. }
  4634. }
  4635. return delta
  4636. }
  4637. Tooltip.prototype.getTitle = function () {
  4638. var title
  4639. var $e = this.$element
  4640. var o = this.options
  4641. title = $e.attr('data-original-title')
  4642. || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
  4643. return title
  4644. }
  4645. Tooltip.prototype.getUID = function (prefix) {
  4646. do prefix += ~~(Math.random() * 1000000)
  4647. while (document.getElementById(prefix))
  4648. return prefix
  4649. }
  4650. Tooltip.prototype.tip = function () {
  4651. return (this.$tip = this.$tip || $(this.options.template))
  4652. }
  4653. Tooltip.prototype.arrow = function () {
  4654. return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
  4655. }
  4656. Tooltip.prototype.validate = function () {
  4657. if (!this.$element[0].parentNode) {
  4658. this.hide()
  4659. this.$element = null
  4660. this.options = null
  4661. }
  4662. }
  4663. Tooltip.prototype.enable = function () {
  4664. this.enabled = true
  4665. }
  4666. Tooltip.prototype.disable = function () {
  4667. this.enabled = false
  4668. }
  4669. Tooltip.prototype.toggleEnabled = function () {
  4670. this.enabled = !this.enabled
  4671. }
  4672. Tooltip.prototype.toggle = function (e) {
  4673. var self = this
  4674. if (e) {
  4675. self = $(e.currentTarget).data('bs.' + this.type)
  4676. if (!self) {
  4677. self = new this.constructor(e.currentTarget, this.getDelegateOptions())
  4678. $(e.currentTarget).data('bs.' + this.type, self)
  4679. }
  4680. }
  4681. self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
  4682. }
  4683. Tooltip.prototype.destroy = function () {
  4684. clearTimeout(this.timeout)
  4685. this.hide().$element.off('.' + this.type).removeData('bs.' + this.type)
  4686. }
  4687. // TOOLTIP PLUGIN DEFINITION
  4688. // =========================
  4689. function Plugin(option) {
  4690. return this.each(function () {
  4691. var $this = $(this)
  4692. var data = $this.data('bs.tooltip')
  4693. var options = typeof option == 'object' && option
  4694. if (!data && option == 'destroy') return
  4695. if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
  4696. if (typeof option == 'string') data[option]()
  4697. })
  4698. }
  4699. var old = $.fn.tooltip
  4700. $.fn.tooltip = Plugin
  4701. $.fn.tooltip.Constructor = Tooltip
  4702. // TOOLTIP NO CONFLICT
  4703. // ===================
  4704. $.fn.tooltip.noConflict = function () {
  4705. $.fn.tooltip = old
  4706. return this
  4707. }
  4708. }(jQuery);
  4709. /* ========================================================================
  4710. * Bootstrap: popover.js v3.2.0
  4711. * http://getbootstrap.com/javascript/#popovers
  4712. * ========================================================================
  4713. * Copyright 2011-2014 Twitter, Inc.
  4714. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  4715. * ======================================================================== */
  4716. +function ($) {
  4717. 'use strict';
  4718. // POPOVER PUBLIC CLASS DEFINITION
  4719. // ===============================
  4720. var Popover = function (element, options) {
  4721. this.init('popover', element, options)
  4722. }
  4723. if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
  4724. Popover.VERSION = '3.2.0'
  4725. Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
  4726. placement: 'right',
  4727. trigger: 'click',
  4728. content: '',
  4729. template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
  4730. })
  4731. // NOTE: POPOVER EXTENDS tooltip.js
  4732. // ================================
  4733. Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
  4734. Popover.prototype.constructor = Popover
  4735. Popover.prototype.getDefaults = function () {
  4736. return Popover.DEFAULTS
  4737. }
  4738. Popover.prototype.setContent = function () {
  4739. var $tip = this.tip()
  4740. var title = this.getTitle()
  4741. var content = this.getContent()
  4742. $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
  4743. $tip.find('.popover-content').empty()[ // we use append for html objects to maintain js events
  4744. this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
  4745. ](content)
  4746. $tip.removeClass('fade top bottom left right in')
  4747. // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
  4748. // this manually by checking the contents.
  4749. if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
  4750. }
  4751. Popover.prototype.hasContent = function () {
  4752. return this.getTitle() || this.getContent()
  4753. }
  4754. Popover.prototype.getContent = function () {
  4755. var $e = this.$element
  4756. var o = this.options
  4757. return $e.attr('data-content')
  4758. || (typeof o.content == 'function' ?
  4759. o.content.call($e[0]) :
  4760. o.content)
  4761. }
  4762. Popover.prototype.arrow = function () {
  4763. return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
  4764. }
  4765. Popover.prototype.tip = function () {
  4766. if (!this.$tip) this.$tip = $(this.options.template)
  4767. return this.$tip
  4768. }
  4769. // POPOVER PLUGIN DEFINITION
  4770. // =========================
  4771. function Plugin(option) {
  4772. return this.each(function () {
  4773. var $this = $(this)
  4774. var data = $this.data('bs.popover')
  4775. var options = typeof option == 'object' && option
  4776. if (!data && option == 'destroy') return
  4777. if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
  4778. if (typeof option == 'string') data[option]()
  4779. })
  4780. }
  4781. var old = $.fn.popover
  4782. $.fn.popover = Plugin
  4783. $.fn.popover.Constructor = Popover
  4784. // POPOVER NO CONFLICT
  4785. // ===================
  4786. $.fn.popover.noConflict = function () {
  4787. $.fn.popover = old
  4788. return this
  4789. }
  4790. }(jQuery);
  4791. /* ========================================================================
  4792. * Bootstrap: scrollspy.js v3.2.0
  4793. * http://getbootstrap.com/javascript/#scrollspy
  4794. * ========================================================================
  4795. * Copyright 2011-2014 Twitter, Inc.
  4796. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  4797. * ======================================================================== */
  4798. +function ($) {
  4799. 'use strict';
  4800. // SCROLLSPY CLASS DEFINITION
  4801. // ==========================
  4802. function ScrollSpy(element, options) {
  4803. var process = $.proxy(this.process, this)
  4804. this.$body = $('body')
  4805. this.$scrollElement = $(element).is('body') ? $(window) : $(element)
  4806. this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
  4807. this.selector = (this.options.target || '') + ' .nav li > a'
  4808. this.offsets = []
  4809. this.targets = []
  4810. this.activeTarget = null
  4811. this.scrollHeight = 0
  4812. this.$scrollElement.on('scroll.bs.scrollspy', process)
  4813. this.refresh()
  4814. this.process()
  4815. }
  4816. ScrollSpy.VERSION = '3.2.0'
  4817. ScrollSpy.DEFAULTS = {
  4818. offset: 10
  4819. }
  4820. ScrollSpy.prototype.getScrollHeight = function () {
  4821. return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
  4822. }
  4823. ScrollSpy.prototype.refresh = function () {
  4824. var offsetMethod = 'offset'
  4825. var offsetBase = 0
  4826. if (!$.isWindow(this.$scrollElement[0])) {
  4827. offsetMethod = 'position'
  4828. offsetBase = this.$scrollElement.scrollTop()
  4829. }
  4830. this.offsets = []
  4831. this.targets = []
  4832. this.scrollHeight = this.getScrollHeight()
  4833. var self = this
  4834. this.$body
  4835. .find(this.selector)
  4836. .map(function () {
  4837. var $el = $(this)
  4838. var href = $el.data('target') || $el.attr('href')
  4839. var $href = /^#./.test(href) && $(href)
  4840. return ($href
  4841. && $href.length
  4842. && $href.is(':visible')
  4843. && [[$href[offsetMethod]().top + offsetBase, href]]) || null
  4844. })
  4845. .sort(function (a, b) { return a[0] - b[0] })
  4846. .each(function () {
  4847. self.offsets.push(this[0])
  4848. self.targets.push(this[1])
  4849. })
  4850. }
  4851. ScrollSpy.prototype.process = function () {
  4852. var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
  4853. var scrollHeight = this.getScrollHeight()
  4854. var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()
  4855. var offsets = this.offsets
  4856. var targets = this.targets
  4857. var activeTarget = this.activeTarget
  4858. var i
  4859. if (this.scrollHeight != scrollHeight) {
  4860. this.refresh()
  4861. }
  4862. if (scrollTop >= maxScroll) {
  4863. return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
  4864. }
  4865. if (activeTarget && scrollTop <= offsets[0]) {
  4866. return activeTarget != (i = targets[0]) && this.activate(i)
  4867. }
  4868. for (i = offsets.length; i--;) {
  4869. activeTarget != targets[i]
  4870. && scrollTop >= offsets[i]
  4871. && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
  4872. && this.activate(targets[i])
  4873. }
  4874. }
  4875. ScrollSpy.prototype.activate = function (target) {
  4876. this.activeTarget = target
  4877. $(this.selector)
  4878. .parentsUntil(this.options.target, '.active')
  4879. .removeClass('active')
  4880. var selector = this.selector +
  4881. '[data-target="' + target + '"],' +
  4882. this.selector + '[href="' + target + '"]'
  4883. var active = $(selector)
  4884. .parents('li')
  4885. .addClass('active')
  4886. if (active.parent('.dropdown-menu').length) {
  4887. active = active
  4888. .closest('li.dropdown')
  4889. .addClass('active')
  4890. }
  4891. active.trigger('activate.bs.scrollspy')
  4892. }
  4893. // SCROLLSPY PLUGIN DEFINITION
  4894. // ===========================
  4895. function Plugin(option) {
  4896. return this.each(function () {
  4897. var $this = $(this)
  4898. var data = $this.data('bs.scrollspy')
  4899. var options = typeof option == 'object' && option
  4900. if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
  4901. if (typeof option == 'string') data[option]()
  4902. })
  4903. }
  4904. var old = $.fn.scrollspy
  4905. $.fn.scrollspy = Plugin
  4906. $.fn.scrollspy.Constructor = ScrollSpy
  4907. // SCROLLSPY NO CONFLICT
  4908. // =====================
  4909. $.fn.scrollspy.noConflict = function () {
  4910. $.fn.scrollspy = old
  4911. return this
  4912. }
  4913. // SCROLLSPY DATA-API
  4914. // ==================
  4915. $(window).on('load.bs.scrollspy.data-api', function () {
  4916. $('[data-spy="scroll"]').each(function () {
  4917. var $spy = $(this)
  4918. Plugin.call($spy, $spy.data())
  4919. })
  4920. })
  4921. }(jQuery);
  4922. /* ========================================================================
  4923. * Bootstrap: tab.js v3.2.0
  4924. * http://getbootstrap.com/javascript/#tabs
  4925. * ========================================================================
  4926. * Copyright 2011-2014 Twitter, Inc.
  4927. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  4928. * ======================================================================== */
  4929. +function ($) {
  4930. 'use strict';
  4931. // TAB CLASS DEFINITION
  4932. // ====================
  4933. var Tab = function (element) {
  4934. this.element = $(element)
  4935. }
  4936. Tab.VERSION = '3.2.0'
  4937. Tab.prototype.show = function () {
  4938. var $this = this.element
  4939. var $ul = $this.closest('ul:not(.dropdown-menu)')
  4940. var selector = $this.data('target')
  4941. if (!selector) {
  4942. selector = $this.attr('href')
  4943. selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
  4944. }
  4945. if ($this.parent('li').hasClass('active')) return
  4946. var previous = $ul.find('.active:last a')[0]
  4947. var e = $.Event('show.bs.tab', {
  4948. relatedTarget: previous
  4949. })
  4950. $this.trigger(e)
  4951. if (e.isDefaultPrevented()) return
  4952. var $target = $(selector)
  4953. this.activate($this.closest('li'), $ul)
  4954. this.activate($target, $target.parent(), function () {
  4955. $this.trigger({
  4956. type: 'shown.bs.tab',
  4957. relatedTarget: previous
  4958. })
  4959. })
  4960. }
  4961. Tab.prototype.activate = function (element, container, callback) {
  4962. var $active = container.find('> .active')
  4963. var transition = callback
  4964. && $.support.transition
  4965. && $active.hasClass('fade')
  4966. function next() {
  4967. $active
  4968. .removeClass('active')
  4969. .find('> .dropdown-menu > .active')
  4970. .removeClass('active')
  4971. element.addClass('active')
  4972. if (transition) {
  4973. element[0].offsetWidth // reflow for transition
  4974. element.addClass('in')
  4975. } else {
  4976. element.removeClass('fade')
  4977. }
  4978. if (element.parent('.dropdown-menu')) {
  4979. element.closest('li.dropdown').addClass('active')
  4980. }
  4981. callback && callback()
  4982. }
  4983. transition ?
  4984. $active
  4985. .one('bsTransitionEnd', next)
  4986. .emulateTransitionEnd(150) :
  4987. next()
  4988. $active.removeClass('in')
  4989. }
  4990. // TAB PLUGIN DEFINITION
  4991. // =====================
  4992. function Plugin(option) {
  4993. return this.each(function () {
  4994. var $this = $(this)
  4995. var data = $this.data('bs.tab')
  4996. if (!data) $this.data('bs.tab', (data = new Tab(this)))
  4997. if (typeof option == 'string') data[option]()
  4998. })
  4999. }
  5000. var old = $.fn.tab
  5001. $.fn.tab = Plugin
  5002. $.fn.tab.Constructor = Tab
  5003. // TAB NO CONFLICT
  5004. // ===============
  5005. $.fn.tab.noConflict = function () {
  5006. $.fn.tab = old
  5007. return this
  5008. }
  5009. // TAB DATA-API
  5010. // ============
  5011. $(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
  5012. e.preventDefault()
  5013. Plugin.call($(this), 'show')
  5014. })
  5015. }(jQuery);
  5016. /* ========================================================================
  5017. * Bootstrap: affix.js v3.2.0
  5018. * http://getbootstrap.com/javascript/#affix
  5019. * ========================================================================
  5020. * Copyright 2011-2014 Twitter, Inc.
  5021. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  5022. * ======================================================================== */
  5023. +function ($) {
  5024. 'use strict';
  5025. // AFFIX CLASS DEFINITION
  5026. // ======================
  5027. var Affix = function (element, options) {
  5028. this.options = $.extend({}, Affix.DEFAULTS, options)
  5029. this.$target = $(this.options.target)
  5030. .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
  5031. .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
  5032. this.$element = $(element)
  5033. this.affixed =
  5034. this.unpin =
  5035. this.pinnedOffset = null
  5036. this.checkPosition()
  5037. }
  5038. Affix.VERSION = '3.2.0'
  5039. Affix.RESET = 'affix affix-top affix-bottom'
  5040. Affix.DEFAULTS = {
  5041. offset: 0,
  5042. target: window
  5043. }
  5044. Affix.prototype.getPinnedOffset = function () {
  5045. if (this.pinnedOffset) return this.pinnedOffset
  5046. this.$element.removeClass(Affix.RESET).addClass('affix')
  5047. var scrollTop = this.$target.scrollTop()
  5048. var position = this.$element.offset()
  5049. return (this.pinnedOffset = position.top - scrollTop)
  5050. }
  5051. Affix.prototype.checkPositionWithEventLoop = function () {
  5052. setTimeout($.proxy(this.checkPosition, this), 1)
  5053. }
  5054. Affix.prototype.checkPosition = function () {
  5055. if (!this.$element.is(':visible')) return
  5056. var scrollHeight = $(document).height()
  5057. var scrollTop = this.$target.scrollTop()
  5058. var position = this.$element.offset()
  5059. var offset = this.options.offset
  5060. var offsetTop = offset.top
  5061. var offsetBottom = offset.bottom
  5062. if (typeof offset != 'object') offsetBottom = offsetTop = offset
  5063. if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
  5064. if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
  5065. var affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ? false :
  5066. offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 'bottom' :
  5067. offsetTop != null && (scrollTop <= offsetTop) ? 'top' : false
  5068. if (this.affixed === affix) return
  5069. if (this.unpin != null) this.$element.css('top', '')
  5070. var affixType = 'affix' + (affix ? '-' + affix : '')
  5071. var e = $.Event(affixType + '.bs.affix')
  5072. this.$element.trigger(e)
  5073. if (e.isDefaultPrevented()) return
  5074. this.affixed = affix
  5075. this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
  5076. this.$element
  5077. .removeClass(Affix.RESET)
  5078. .addClass(affixType)
  5079. .trigger($.Event(affixType.replace('affix', 'affixed')))
  5080. if (affix == 'bottom') {
  5081. this.$element.offset({
  5082. top: scrollHeight - this.$element.height() - offsetBottom
  5083. })
  5084. }
  5085. }
  5086. // AFFIX PLUGIN DEFINITION
  5087. // =======================
  5088. function Plugin(option) {
  5089. return this.each(function () {
  5090. var $this = $(this)
  5091. var data = $this.data('bs.affix')
  5092. var options = typeof option == 'object' && option
  5093. if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
  5094. if (typeof option == 'string') data[option]()
  5095. })
  5096. }
  5097. var old = $.fn.affix
  5098. $.fn.affix = Plugin
  5099. $.fn.affix.Constructor = Affix
  5100. // AFFIX NO CONFLICT
  5101. // =================
  5102. $.fn.affix.noConflict = function () {
  5103. $.fn.affix = old
  5104. return this
  5105. }
  5106. // AFFIX DATA-API
  5107. // ==============
  5108. $(window).on('load', function () {
  5109. $('[data-spy="affix"]').each(function () {
  5110. var $spy = $(this)
  5111. var data = $spy.data()
  5112. data.offset = data.offset || {}
  5113. if (data.offsetBottom) data.offset.bottom = data.offsetBottom
  5114. if (data.offsetTop) data.offset.top = data.offsetTop
  5115. Plugin.call($spy, data)
  5116. })
  5117. })
  5118. }(jQuery);
  5119. /* ========================================================================
  5120. * bootstrap-switch - v3.0.2
  5121. * http://www.bootstrap-switch.org
  5122. * ========================================================================
  5123. * Copyright 2012-2013 Mattia Larentis
  5124. *
  5125. * ========================================================================
  5126. * Licensed under the Apache License, Version 2.0 (the "License");
  5127. * you may not use this file except in compliance with the License.
  5128. * You may obtain a copy of the License at
  5129. *
  5130. * http://www.apache.org/licenses/LICENSE-2.0
  5131. *
  5132. * Unless required by applicable law or agreed to in writing, software
  5133. * distributed under the License is distributed on an "AS IS" BASIS,
  5134. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  5135. * See the License for the specific language governing permissions and
  5136. * limitations under the License.
  5137. * ========================================================================
  5138. */
  5139. (function() {
  5140. var __slice = [].slice;
  5141. (function($, window) {
  5142. "use strict";
  5143. var BootstrapSwitch;
  5144. BootstrapSwitch = (function() {
  5145. function BootstrapSwitch(element, options) {
  5146. if (options == null) {
  5147. options = {};
  5148. }
  5149. this.$element = $(element);
  5150. this.options = $.extend({}, $.fn.bootstrapSwitch.defaults, {
  5151. state: this.$element.is(":checked"),
  5152. size: this.$element.data("size"),
  5153. animate: this.$element.data("animate"),
  5154. disabled: this.$element.is(":disabled"),
  5155. readonly: this.$element.is("[readonly]"),
  5156. indeterminate: this.$element.data("indeterminate"),
  5157. onColor: this.$element.data("on-color"),
  5158. offColor: this.$element.data("off-color"),
  5159. onText: this.$element.data("on-text"),
  5160. offText: this.$element.data("off-text"),
  5161. labelText: this.$element.data("label-text"),
  5162. baseClass: this.$element.data("base-class"),
  5163. wrapperClass: this.$element.data("wrapper-class"),
  5164. radioAllOff: this.$element.data("radio-all-off")
  5165. }, options);
  5166. this.$wrapper = $("<div>", {
  5167. "class": (function(_this) {
  5168. return function() {
  5169. var classes;
  5170. classes = ["" + _this.options.baseClass].concat(_this._getClasses(_this.options.wrapperClass));
  5171. classes.push(_this.options.state ? "" + _this.options.baseClass + "-on" : "" + _this.options.baseClass + "-off");
  5172. if (_this.options.size != null) {
  5173. classes.push("" + _this.options.baseClass + "-" + _this.options.size);
  5174. }
  5175. if (_this.options.animate) {
  5176. classes.push("" + _this.options.baseClass + "-animate");
  5177. }
  5178. if (_this.options.disabled) {
  5179. classes.push("" + _this.options.baseClass + "-disabled");
  5180. }
  5181. if (_this.options.readonly) {
  5182. classes.push("" + _this.options.baseClass + "-readonly");
  5183. }
  5184. if (_this.options.indeterminate) {
  5185. classes.push("" + _this.options.baseClass + "-indeterminate");
  5186. }
  5187. if (_this.$element.attr("id")) {
  5188. classes.push("" + _this.options.baseClass + "-id-" + (_this.$element.attr("id")));
  5189. }
  5190. return classes.join(" ");
  5191. };
  5192. })(this)()
  5193. });
  5194. this.$container = $("<div>", {
  5195. "class": "" + this.options.baseClass + "-container"
  5196. });
  5197. this.$on = $("<span>", {
  5198. html: this.options.onText,
  5199. "class": "" + this.options.baseClass + "-handle-on " + this.options.baseClass + "-" + this.options.onColor
  5200. });
  5201. this.$off = $("<span>", {
  5202. html: this.options.offText,
  5203. "class": "" + this.options.baseClass + "-handle-off " + this.options.baseClass + "-" + this.options.offColor
  5204. });
  5205. this.$label = $("<label>", {
  5206. html: this.options.labelText,
  5207. "class": "" + this.options.baseClass + "-label"
  5208. });
  5209. if (this.options.indeterminate) {
  5210. this.$element.prop("indeterminate", true);
  5211. }
  5212. this.$element.on("init.bootstrapSwitch", (function(_this) {
  5213. return function() {
  5214. return _this.options.onInit.apply(element, arguments);
  5215. };
  5216. })(this));
  5217. this.$element.on("switchChange.bootstrapSwitch", (function(_this) {
  5218. return function() {
  5219. return _this.options.onSwitchChange.apply(element, arguments);
  5220. };
  5221. })(this));
  5222. this.$container = this.$element.wrap(this.$container).parent();
  5223. this.$wrapper = this.$container.wrap(this.$wrapper).parent();
  5224. this.$element.before(this.$on).before(this.$label).before(this.$off).trigger("init.bootstrapSwitch");
  5225. this._elementHandlers();
  5226. this._handleHandlers();
  5227. this._labelHandlers();
  5228. this._formHandler();
  5229. }
  5230. BootstrapSwitch.prototype._constructor = BootstrapSwitch;
  5231. BootstrapSwitch.prototype.state = function(value, skip) {
  5232. if (typeof value === "undefined") {
  5233. return this.options.state;
  5234. }
  5235. if (this.options.disabled || this.options.readonly || this.options.indeterminate) {
  5236. return this.$element;
  5237. }
  5238. if (this.options.state && !this.options.radioAllOff && this.$element.is(':radio')) {
  5239. return this.$element;
  5240. }
  5241. value = !!value;
  5242. this.$element.prop("checked", value).trigger("change.bootstrapSwitch", skip);
  5243. return this.$element;
  5244. };
  5245. BootstrapSwitch.prototype.toggleState = function(skip) {
  5246. if (this.options.disabled || this.options.readonly || this.options.indeterminate) {
  5247. return this.$element;
  5248. }
  5249. return this.$element.prop("checked", !this.options.state).trigger("change.bootstrapSwitch", skip);
  5250. };
  5251. BootstrapSwitch.prototype.size = function(value) {
  5252. if (typeof value === "undefined") {
  5253. return this.options.size;
  5254. }
  5255. if (this.options.size != null) {
  5256. this.$wrapper.removeClass("" + this.options.baseClass + "-" + this.options.size);
  5257. }
  5258. if (value) {
  5259. this.$wrapper.addClass("" + this.options.baseClass + "-" + value);
  5260. }
  5261. this.options.size = value;
  5262. return this.$element;
  5263. };
  5264. BootstrapSwitch.prototype.animate = function(value) {
  5265. if (typeof value === "undefined") {
  5266. return this.options.animate;
  5267. }
  5268. value = !!value;
  5269. this.$wrapper[value ? "addClass" : "removeClass"]("" + this.options.baseClass + "-animate");
  5270. this.options.animate = value;
  5271. return this.$element;
  5272. };
  5273. BootstrapSwitch.prototype.disabled = function(value) {
  5274. if (typeof value === "undefined") {
  5275. return this.options.disabled;
  5276. }
  5277. value = !!value;
  5278. this.$wrapper[value ? "addClass" : "removeClass"]("" + this.options.baseClass + "-disabled");
  5279. this.$element.prop("disabled", value);
  5280. this.options.disabled = value;
  5281. return this.$element;
  5282. };
  5283. BootstrapSwitch.prototype.toggleDisabled = function() {
  5284. this.$element.prop("disabled", !this.options.disabled);
  5285. this.$wrapper.toggleClass("" + this.options.baseClass + "-disabled");
  5286. this.options.disabled = !this.options.disabled;
  5287. return this.$element;
  5288. };
  5289. BootstrapSwitch.prototype.readonly = function(value) {
  5290. if (typeof value === "undefined") {
  5291. return this.options.readonly;
  5292. }
  5293. value = !!value;
  5294. this.$wrapper[value ? "addClass" : "removeClass"]("" + this.options.baseClass + "-readonly");
  5295. this.$element.prop("readonly", value);
  5296. this.options.readonly = value;
  5297. return this.$element;
  5298. };
  5299. BootstrapSwitch.prototype.toggleReadonly = function() {
  5300. this.$element.prop("readonly", !this.options.readonly);
  5301. this.$wrapper.toggleClass("" + this.options.baseClass + "-readonly");
  5302. this.options.readonly = !this.options.readonly;
  5303. return this.$element;
  5304. };
  5305. BootstrapSwitch.prototype.indeterminate = function(value) {
  5306. if (typeof value === "undefined") {
  5307. return this.options.indeterminate;
  5308. }
  5309. value = !!value;
  5310. this.$wrapper[value ? "addClass" : "removeClass"]("" + this.options.baseClass + "-indeterminate");
  5311. this.$element.prop("indeterminate", value);
  5312. this.options.indeterminate = value;
  5313. return this.$element;
  5314. };
  5315. BootstrapSwitch.prototype.toggleIndeterminate = function() {
  5316. this.$element.prop("indeterminate", !this.options.indeterminate);
  5317. this.$wrapper.toggleClass("" + this.options.baseClass + "-indeterminate");
  5318. this.options.indeterminate = !this.options.indeterminate;
  5319. return this.$element;
  5320. };
  5321. BootstrapSwitch.prototype.onColor = function(value) {
  5322. var color;
  5323. color = this.options.onColor;
  5324. if (typeof value === "undefined") {
  5325. return color;
  5326. }
  5327. if (color != null) {
  5328. this.$on.removeClass("" + this.options.baseClass + "-" + color);
  5329. }
  5330. this.$on.addClass("" + this.options.baseClass + "-" + value);
  5331. this.options.onColor = value;
  5332. return this.$element;
  5333. };
  5334. BootstrapSwitch.prototype.offColor = function(value) {
  5335. var color;
  5336. color = this.options.offColor;
  5337. if (typeof value === "undefined") {
  5338. return color;
  5339. }
  5340. if (color != null) {
  5341. this.$off.removeClass("" + this.options.baseClass + "-" + color);
  5342. }
  5343. this.$off.addClass("" + this.options.baseClass + "-" + value);
  5344. this.options.offColor = value;
  5345. return this.$element;
  5346. };
  5347. BootstrapSwitch.prototype.onText = function(value) {
  5348. if (typeof value === "undefined") {
  5349. return this.options.onText;
  5350. }
  5351. this.$on.html(value);
  5352. this.options.onText = value;
  5353. return this.$element;
  5354. };
  5355. BootstrapSwitch.prototype.offText = function(value) {
  5356. if (typeof value === "undefined") {
  5357. return this.options.offText;
  5358. }
  5359. this.$off.html(value);
  5360. this.options.offText = value;
  5361. return this.$element;
  5362. };
  5363. BootstrapSwitch.prototype.labelText = function(value) {
  5364. if (typeof value === "undefined") {
  5365. return this.options.labelText;
  5366. }
  5367. this.$label.html(value);
  5368. this.options.labelText = value;
  5369. return this.$element;
  5370. };
  5371. BootstrapSwitch.prototype.baseClass = function(value) {
  5372. return this.options.baseClass;
  5373. };
  5374. BootstrapSwitch.prototype.wrapperClass = function(value) {
  5375. if (typeof value === "undefined") {
  5376. return this.options.wrapperClass;
  5377. }
  5378. if (!value) {
  5379. value = $.fn.bootstrapSwitch.defaults.wrapperClass;
  5380. }
  5381. this.$wrapper.removeClass(this._getClasses(this.options.wrapperClass).join(" "));
  5382. this.$wrapper.addClass(this._getClasses(value).join(" "));
  5383. this.options.wrapperClass = value;
  5384. return this.$element;
  5385. };
  5386. BootstrapSwitch.prototype.radioAllOff = function(value) {
  5387. if (typeof value === "undefined") {
  5388. return this.options.radioAllOff;
  5389. }
  5390. this.options.radioAllOff = value;
  5391. return this.$element;
  5392. };
  5393. BootstrapSwitch.prototype.onInit = function(value) {
  5394. if (typeof value === "undefined") {
  5395. return this.options.onInit;
  5396. }
  5397. if (!value) {
  5398. value = $.fn.bootstrapSwitch.defaults.onInit;
  5399. }
  5400. this.options.onInit = value;
  5401. return this.$element;
  5402. };
  5403. BootstrapSwitch.prototype.onSwitchChange = function(value) {
  5404. if (typeof value === "undefined") {
  5405. return this.options.onSwitchChange;
  5406. }
  5407. if (!value) {
  5408. value = $.fn.bootstrapSwitch.defaults.onSwitchChange;
  5409. }
  5410. this.options.onSwitchChange = value;
  5411. return this.$element;
  5412. };
  5413. BootstrapSwitch.prototype.destroy = function() {
  5414. var $form;
  5415. $form = this.$element.closest("form");
  5416. if ($form.length) {
  5417. $form.off("reset.bootstrapSwitch").removeData("bootstrap-switch");
  5418. }
  5419. this.$container.children().not(this.$element).remove();
  5420. this.$element.unwrap().unwrap().off(".bootstrapSwitch").removeData("bootstrap-switch");
  5421. return this.$element;
  5422. };
  5423. BootstrapSwitch.prototype._elementHandlers = function() {
  5424. return this.$element.on({
  5425. "change.bootstrapSwitch": (function(_this) {
  5426. return function(e, skip) {
  5427. var checked;
  5428. e.preventDefault();
  5429. e.stopImmediatePropagation();
  5430. checked = _this.$element.is(":checked");
  5431. if (checked === _this.options.state) {
  5432. return;
  5433. }
  5434. _this.options.state = checked;
  5435. _this.$wrapper.removeClass(checked ? "" + _this.options.baseClass + "-off" : "" + _this.options.baseClass + "-on").addClass(checked ? "" + _this.options.baseClass + "-on" : "" + _this.options.baseClass + "-off");
  5436. if (!skip) {
  5437. if (_this.$element.is(":radio")) {
  5438. $("[name='" + (_this.$element.attr('name')) + "']").not(_this.$element).prop("checked", false).trigger("change.bootstrapSwitch", true);
  5439. }
  5440. return _this.$element.trigger("switchChange.bootstrapSwitch", [checked]);
  5441. }
  5442. };
  5443. })(this),
  5444. "focus.bootstrapSwitch": (function(_this) {
  5445. return function(e) {
  5446. e.preventDefault();
  5447. return _this.$wrapper.addClass("" + _this.options.baseClass + "-focused");
  5448. };
  5449. })(this),
  5450. "blur.bootstrapSwitch": (function(_this) {
  5451. return function(e) {
  5452. e.preventDefault();
  5453. return _this.$wrapper.removeClass("" + _this.options.baseClass + "-focused");
  5454. };
  5455. })(this),
  5456. "keydown.bootstrapSwitch": (function(_this) {
  5457. return function(e) {
  5458. if (!e.which || _this.options.disabled || _this.options.readonly || _this.options.indeterminate) {
  5459. return;
  5460. }
  5461. switch (e.which) {
  5462. case 37:
  5463. e.preventDefault();
  5464. e.stopImmediatePropagation();
  5465. return _this.state(false);
  5466. case 39:
  5467. e.preventDefault();
  5468. e.stopImmediatePropagation();
  5469. return _this.state(true);
  5470. }
  5471. };
  5472. })(this)
  5473. });
  5474. };
  5475. BootstrapSwitch.prototype._handleHandlers = function() {
  5476. this.$on.on("click.bootstrapSwitch", (function(_this) {
  5477. return function(e) {
  5478. _this.state(false);
  5479. return _this.$element.trigger("focus.bootstrapSwitch");
  5480. };
  5481. })(this));
  5482. return this.$off.on("click.bootstrapSwitch", (function(_this) {
  5483. return function(e) {
  5484. _this.state(true);
  5485. return _this.$element.trigger("focus.bootstrapSwitch");
  5486. };
  5487. })(this));
  5488. };
  5489. BootstrapSwitch.prototype._labelHandlers = function() {
  5490. return this.$label.on({
  5491. "mousemove.bootstrapSwitch touchmove.bootstrapSwitch": (function(_this) {
  5492. return function(e) {
  5493. var left, pageX, percent, right;
  5494. if (!_this.isLabelDragging) {
  5495. return;
  5496. }
  5497. e.preventDefault();
  5498. _this.isLabelDragged = true;
  5499. pageX = e.pageX || e.originalEvent.touches[0].pageX;
  5500. percent = ((pageX - _this.$wrapper.offset().left) / _this.$wrapper.width()) * 100;
  5501. left = 25;
  5502. right = 75;
  5503. if (_this.options.animate) {
  5504. _this.$wrapper.removeClass("" + _this.options.baseClass + "-animate");
  5505. }
  5506. if (percent < left) {
  5507. percent = left;
  5508. } else if (percent > right) {
  5509. percent = right;
  5510. }
  5511. _this.$container.css("margin-left", "" + (percent - right) + "%");
  5512. return _this.$element.trigger("focus.bootstrapSwitch");
  5513. };
  5514. })(this),
  5515. "mousedown.bootstrapSwitch touchstart.bootstrapSwitch": (function(_this) {
  5516. return function(e) {
  5517. if (_this.isLabelDragging || _this.options.disabled || _this.options.readonly || _this.options.indeterminate) {
  5518. return;
  5519. }
  5520. e.preventDefault();
  5521. _this.isLabelDragging = true;
  5522. return _this.$element.trigger("focus.bootstrapSwitch");
  5523. };
  5524. })(this),
  5525. "mouseup.bootstrapSwitch touchend.bootstrapSwitch": (function(_this) {
  5526. return function(e) {
  5527. if (!_this.isLabelDragging) {
  5528. return;
  5529. }
  5530. e.preventDefault();
  5531. if (_this.isLabelDragged) {
  5532. _this.isLabelDragged = false;
  5533. _this.state(parseInt(_this.$container.css("margin-left"), 10) > -(_this.$container.width() / 6));
  5534. if (_this.options.animate) {
  5535. _this.$wrapper.addClass("" + _this.options.baseClass + "-animate");
  5536. }
  5537. _this.$container.css("margin-left", "");
  5538. } else {
  5539. _this.state(!_this.options.state);
  5540. }
  5541. return _this.isLabelDragging = false;
  5542. };
  5543. })(this),
  5544. "mouseleave.bootstrapSwitch": (function(_this) {
  5545. return function(e) {
  5546. return _this.$label.trigger("mouseup.bootstrapSwitch");
  5547. };
  5548. })(this)
  5549. });
  5550. };
  5551. BootstrapSwitch.prototype._formHandler = function() {
  5552. var $form;
  5553. $form = this.$element.closest("form");
  5554. if ($form.data("bootstrap-switch")) {
  5555. return;
  5556. }
  5557. return $form.on("reset.bootstrapSwitch", function() {
  5558. return window.setTimeout(function() {
  5559. return $form.find("input").filter(function() {
  5560. return $(this).data("bootstrap-switch");
  5561. }).each(function() {
  5562. return $(this).bootstrapSwitch("state", this.checked);
  5563. });
  5564. }, 1);
  5565. }).data("bootstrap-switch", true);
  5566. };
  5567. BootstrapSwitch.prototype._getClasses = function(classes) {
  5568. var c, cls, _i, _len;
  5569. if (!$.isArray(classes)) {
  5570. return ["" + this.options.baseClass + "-" + classes];
  5571. }
  5572. cls = [];
  5573. for (_i = 0, _len = classes.length; _i < _len; _i++) {
  5574. c = classes[_i];
  5575. cls.push("" + this.options.baseClass + "-" + c);
  5576. }
  5577. return cls;
  5578. };
  5579. return BootstrapSwitch;
  5580. })();
  5581. $.fn.bootstrapSwitch = function() {
  5582. var args, option, ret;
  5583. option = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
  5584. ret = this;
  5585. this.each(function() {
  5586. var $this, data;
  5587. $this = $(this);
  5588. data = $this.data("bootstrap-switch");
  5589. if (!data) {
  5590. $this.data("bootstrap-switch", data = new BootstrapSwitch(this, option));
  5591. }
  5592. if (typeof option === "string") {
  5593. return ret = data[option].apply(data, args);
  5594. }
  5595. });
  5596. return ret;
  5597. };
  5598. $.fn.bootstrapSwitch.Constructor = BootstrapSwitch;
  5599. return $.fn.bootstrapSwitch.defaults = {
  5600. state: true,
  5601. size: null,
  5602. animate: true,
  5603. disabled: false,
  5604. readonly: false,
  5605. indeterminate: false,
  5606. onColor: "primary",
  5607. offColor: "default",
  5608. onText: "ON",
  5609. offText: "OFF",
  5610. labelText: "&nbsp;",
  5611. baseClass: "bootstrap-switch",
  5612. wrapperClass: "wrapper",
  5613. radioAllOff: false,
  5614. onInit: function() {},
  5615. onSwitchChange: function() {}
  5616. };
  5617. })(window.jQuery, window);
  5618. }).call(this);
  5619. (function ($) {
  5620. "use strict";
  5621. var defaultOptions = {
  5622. tagClass: function(item) {
  5623. return 'label label-info';
  5624. },
  5625. itemValue: function(item) {
  5626. return item ? item.toString() : item;
  5627. },
  5628. itemText: function(item) {
  5629. return this.itemValue(item);
  5630. },
  5631. freeInput: true,
  5632. addOnBlur: true,
  5633. maxTags: undefined,
  5634. maxChars: undefined,
  5635. confirmKeys: [13, 44],
  5636. onTagExists: function(item, $tag) {
  5637. $tag.hide().fadeIn();
  5638. },
  5639. trimValue: false,
  5640. allowDuplicates: false
  5641. };
  5642. /**
  5643. * Constructor function
  5644. */
  5645. function TagsInput(element, options) {
  5646. this.itemsArray = [];
  5647. this.$element = $(element);
  5648. this.$element.hide();
  5649. this.isSelect = (element.tagName === 'SELECT');
  5650. this.multiple = (this.isSelect && element.hasAttribute('multiple'));
  5651. this.objectItems = options && options.itemValue;
  5652. this.placeholderText = element.hasAttribute('placeholder') ? this.$element.attr('placeholder') : '';
  5653. this.inputSize = Math.max(1, this.placeholderText.length);
  5654. this.$container = $('<div class="bootstrap-tagsinput"></div>');
  5655. this.$input = $('<input type="text" placeholder="' + this.placeholderText + '"/>').appendTo(this.$container);
  5656. this.$element.after(this.$container);
  5657. var inputWidth = (this.inputSize < 3 ? 3 : this.inputSize) + "em";
  5658. this.$input.get(0).style.cssText = "width: " + inputWidth + " !important;";
  5659. this.build(options);
  5660. }
  5661. TagsInput.prototype = {
  5662. constructor: TagsInput,
  5663. /**
  5664. * Adds the given item as a new tag. Pass true to dontPushVal to prevent
  5665. * updating the elements val()
  5666. */
  5667. add: function(item, dontPushVal) {
  5668. var self = this;
  5669. if (self.options.maxTags && self.itemsArray.length >= self.options.maxTags)
  5670. return;
  5671. // Ignore falsey values, except false
  5672. if (item !== false && !item)
  5673. return;
  5674. // Trim value
  5675. if (typeof item === "string" && self.options.trimValue) {
  5676. item = $.trim(item);
  5677. }
  5678. // Throw an error when trying to add an object while the itemValue option was not set
  5679. if (typeof item === "object" && !self.objectItems)
  5680. throw("Can't add objects when itemValue option is not set");
  5681. // Ignore strings only containg whitespace
  5682. if (item.toString().match(/^\s*$/))
  5683. return;
  5684. // If SELECT but not multiple, remove current tag
  5685. if (self.isSelect && !self.multiple && self.itemsArray.length > 0)
  5686. self.remove(self.itemsArray[0]);
  5687. if (typeof item === "string" && this.$element[0].tagName === 'INPUT') {
  5688. var items = item.split(',');
  5689. if (items.length > 1) {
  5690. for (var i = 0; i < items.length; i++) {
  5691. this.add(items[i], true);
  5692. }
  5693. if (!dontPushVal)
  5694. self.pushVal();
  5695. return;
  5696. }
  5697. }
  5698. var itemValue = self.options.itemValue(item),
  5699. itemText = self.options.itemText(item),
  5700. tagClass = self.options.tagClass(item);
  5701. // Ignore items allready added
  5702. var existing = $.grep(self.itemsArray, function(item) { return self.options.itemValue(item) === itemValue; } )[0];
  5703. if (existing && !self.options.allowDuplicates) {
  5704. // Invoke onTagExists
  5705. if (self.options.onTagExists) {
  5706. var $existingTag = $(".tag", self.$container).filter(function() { return $(this).data("item") === existing; });
  5707. self.options.onTagExists(item, $existingTag);
  5708. }
  5709. return;
  5710. }
  5711. // if length greater than limit
  5712. if (self.items().toString().length + item.length + 1 > self.options.maxInputLength)
  5713. return;
  5714. // raise beforeItemAdd arg
  5715. var beforeItemAddEvent = $.Event('beforeItemAdd', { item: item, cancel: false });
  5716. self.$element.trigger(beforeItemAddEvent);
  5717. if (beforeItemAddEvent.cancel)
  5718. return;
  5719. // register item in internal array and map
  5720. self.itemsArray.push(item);
  5721. // add a tag element
  5722. var $tag = $('<span class="tag ' + htmlEncode(tagClass) + '">' + htmlEncode(itemText) + '<span data-role="remove"></span></span>');
  5723. $tag.data('item', item);
  5724. self.findInputWrapper().before($tag);
  5725. $tag.after(' ');
  5726. // add <option /> if item represents a value not present in one of the <select />'s options
  5727. if (self.isSelect && !$('option[value="' + encodeURIComponent(itemValue) + '"]',self.$element)[0]) {
  5728. var $option = $('<option selected>' + htmlEncode(itemText) + '</option>');
  5729. $option.data('item', item);
  5730. $option.attr('value', itemValue);
  5731. self.$element.append($option);
  5732. }
  5733. if (!dontPushVal)
  5734. self.pushVal();
  5735. // Add class when reached maxTags
  5736. if (self.options.maxTags === self.itemsArray.length || self.items().toString().length === self.options.maxInputLength)
  5737. self.$container.addClass('bootstrap-tagsinput-max');
  5738. self.$element.trigger($.Event('itemAdded', { item: item }));
  5739. },
  5740. /**
  5741. * Removes the given item. Pass true to dontPushVal to prevent updating the
  5742. * elements val()
  5743. */
  5744. remove: function(item, dontPushVal) {
  5745. var self = this;
  5746. if (self.objectItems) {
  5747. if (typeof item === "object")
  5748. item = $.grep(self.itemsArray, function(other) { return self.options.itemValue(other) == self.options.itemValue(item); } );
  5749. else
  5750. item = $.grep(self.itemsArray, function(other) { return self.options.itemValue(other) == item; } );
  5751. item = item[item.length-1];
  5752. }
  5753. if (item) {
  5754. var beforeItemRemoveEvent = $.Event('beforeItemRemove', { item: item, cancel: false });
  5755. self.$element.trigger(beforeItemRemoveEvent);
  5756. if (beforeItemRemoveEvent.cancel)
  5757. return;
  5758. $('.tag', self.$container).filter(function() { return $(this).data('item') === item; }).remove();
  5759. $('option', self.$element).filter(function() { return $(this).data('item') === item; }).remove();
  5760. if($.inArray(item, self.itemsArray) !== -1)
  5761. self.itemsArray.splice($.inArray(item, self.itemsArray), 1);
  5762. }
  5763. if (!dontPushVal)
  5764. self.pushVal();
  5765. // Remove class when reached maxTags
  5766. if (self.options.maxTags > self.itemsArray.length)
  5767. self.$container.removeClass('bootstrap-tagsinput-max');
  5768. self.$element.trigger($.Event('itemRemoved', { item: item }));
  5769. },
  5770. /**
  5771. * Removes all items
  5772. */
  5773. removeAll: function() {
  5774. var self = this;
  5775. $('.tag', self.$container).remove();
  5776. $('option', self.$element).remove();
  5777. while(self.itemsArray.length > 0)
  5778. self.itemsArray.pop();
  5779. self.pushVal();
  5780. },
  5781. /**
  5782. * Refreshes the tags so they match the text/value of their corresponding
  5783. * item.
  5784. */
  5785. refresh: function() {
  5786. var self = this;
  5787. $('.tag', self.$container).each(function() {
  5788. var $tag = $(this),
  5789. item = $tag.data('item'),
  5790. itemValue = self.options.itemValue(item),
  5791. itemText = self.options.itemText(item),
  5792. tagClass = self.options.tagClass(item);
  5793. // Update tag's class and inner text
  5794. $tag.attr('class', null);
  5795. $tag.addClass('tag ' + htmlEncode(tagClass));
  5796. $tag.contents().filter(function() {
  5797. return this.nodeType == 3;
  5798. })[0].nodeValue = htmlEncode(itemText);
  5799. if (self.isSelect) {
  5800. var option = $('option', self.$element).filter(function() { return $(this).data('item') === item; });
  5801. option.attr('value', itemValue);
  5802. }
  5803. });
  5804. },
  5805. /**
  5806. * Returns the items added as tags
  5807. */
  5808. items: function() {
  5809. return this.itemsArray;
  5810. },
  5811. /**
  5812. * Assembly value by retrieving the value of each item, and set it on the
  5813. * element.
  5814. */
  5815. pushVal: function() {
  5816. var self = this,
  5817. val = $.map(self.items(), function(item) {
  5818. return self.options.itemValue(item).toString();
  5819. });
  5820. self.$element.val(val, true).trigger('change');
  5821. },
  5822. /**
  5823. * Initializes the tags input behaviour on the element
  5824. */
  5825. build: function(options) {
  5826. var self = this;
  5827. self.options = $.extend({}, defaultOptions, options);
  5828. // When itemValue is set, freeInput should always be false
  5829. if (self.objectItems)
  5830. self.options.freeInput = false;
  5831. makeOptionItemFunction(self.options, 'itemValue');
  5832. makeOptionItemFunction(self.options, 'itemText');
  5833. makeOptionFunction(self.options, 'tagClass');
  5834. // Typeahead Bootstrap version 2.3.2
  5835. if (self.options.typeahead) {
  5836. var typeahead = self.options.typeahead || {};
  5837. makeOptionFunction(typeahead, 'source');
  5838. self.$input.typeahead($.extend({}, typeahead, {
  5839. source: function (query, process) {
  5840. function processItems(items) {
  5841. var texts = [];
  5842. for (var i = 0; i < items.length; i++) {
  5843. var text = self.options.itemText(items[i]);
  5844. map[text] = items[i];
  5845. texts.push(text);
  5846. }
  5847. process(texts);
  5848. }
  5849. this.map = {};
  5850. var map = this.map,
  5851. data = typeahead.source(query);
  5852. if ($.isFunction(data.success)) {
  5853. // support for Angular callbacks
  5854. data.success(processItems);
  5855. } else if ($.isFunction(data.then)) {
  5856. // support for Angular promises
  5857. data.then(processItems);
  5858. } else {
  5859. // support for functions and jquery promises
  5860. $.when(data)
  5861. .then(processItems);
  5862. }
  5863. },
  5864. updater: function (text) {
  5865. self.add(this.map[text]);
  5866. },
  5867. matcher: function (text) {
  5868. return (text.toLowerCase().indexOf(this.query.trim().toLowerCase()) !== -1);
  5869. },
  5870. sorter: function (texts) {
  5871. return texts.sort();
  5872. },
  5873. highlighter: function (text) {
  5874. var regex = new RegExp( '(' + this.query + ')', 'gi' );
  5875. return text.replace( regex, "<strong>$1</strong>" );
  5876. }
  5877. }));
  5878. }
  5879. // typeahead.js
  5880. if (self.options.typeaheadjs) {
  5881. var typeaheadjs = self.options.typeaheadjs || {};
  5882. self.$input.typeahead(null, typeaheadjs).on('typeahead:selected', $.proxy(function (obj, datum) {
  5883. if (typeaheadjs.valueKey)
  5884. self.add(datum[typeaheadjs.valueKey]);
  5885. else
  5886. self.add(datum);
  5887. self.$input.typeahead('val', '');
  5888. }, self));
  5889. }
  5890. self.$container.on('click', $.proxy(function(event) {
  5891. if (! self.$element.attr('disabled')) {
  5892. self.$input.removeAttr('disabled');
  5893. }
  5894. self.$input.focus();
  5895. }, self));
  5896. if (self.options.addOnBlur && self.options.freeInput) {
  5897. self.$input.on('focusout', $.proxy(function(event) {
  5898. // HACK: only process on focusout when no typeahead opened, to
  5899. // avoid adding the typeahead text as tag
  5900. if ($('.typeahead, .twitter-typeahead', self.$container).length === 0) {
  5901. self.add(self.$input.val());
  5902. self.$input.val('');
  5903. }
  5904. }, self));
  5905. }
  5906. self.$container.on('keydown', 'input', $.proxy(function(event) {
  5907. var $input = $(event.target),
  5908. $inputWrapper = self.findInputWrapper();
  5909. if (self.$element.attr('disabled')) {
  5910. self.$input.attr('disabled', 'disabled');
  5911. return;
  5912. }
  5913. switch (event.which) {
  5914. // BACKSPACE
  5915. case 8:
  5916. if (doGetCaretPosition($input[0]) === 0) {
  5917. var prev = $inputWrapper.prev();
  5918. if (prev) {
  5919. self.remove(prev.data('item'));
  5920. }
  5921. }
  5922. break;
  5923. // DELETE
  5924. case 46:
  5925. if (doGetCaretPosition($input[0]) === 0) {
  5926. var next = $inputWrapper.next();
  5927. if (next) {
  5928. self.remove(next.data('item'));
  5929. }
  5930. }
  5931. break;
  5932. // LEFT ARROW
  5933. case 37:
  5934. // Try to move the input before the previous tag
  5935. var $prevTag = $inputWrapper.prev();
  5936. if ($input.val().length === 0 && $prevTag[0]) {
  5937. $prevTag.before($inputWrapper);
  5938. $input.focus();
  5939. }
  5940. break;
  5941. // RIGHT ARROW
  5942. case 39:
  5943. // Try to move the input after the next tag
  5944. var $nextTag = $inputWrapper.next();
  5945. if ($input.val().length === 0 && $nextTag[0]) {
  5946. $nextTag.after($inputWrapper);
  5947. $input.focus();
  5948. }
  5949. break;
  5950. default:
  5951. // ignore
  5952. }
  5953. // Reset internal input's size
  5954. var textLength = $input.val().length,
  5955. wordSpace = Math.ceil(textLength / 5),
  5956. size = textLength + wordSpace + 1;
  5957. $input.attr('size', Math.max(this.inputSize, $input.val().length));
  5958. }, self));
  5959. self.$container.on('keypress', 'input', $.proxy(function(event) {
  5960. var $input = $(event.target);
  5961. if (self.$element.attr('disabled')) {
  5962. self.$input.attr('disabled', 'disabled');
  5963. return;
  5964. }
  5965. var text = $input.val(),
  5966. maxLengthReached = self.options.maxChars && text.length >= self.options.maxChars;
  5967. if (self.options.freeInput && (keyCombinationInList(event, self.options.confirmKeys) || maxLengthReached)) {
  5968. self.add(maxLengthReached ? text.substr(0, self.options.maxChars) : text);
  5969. $input.val('');
  5970. event.preventDefault();
  5971. }
  5972. // Reset internal input's size
  5973. var textLength = $input.val().length,
  5974. wordSpace = Math.ceil(textLength / 5),
  5975. size = textLength + wordSpace + 1;
  5976. $input.attr('size', Math.max(this.inputSize, $input.val().length));
  5977. }, self));
  5978. // Remove icon clicked
  5979. self.$container.on('click', '[data-role=remove]', $.proxy(function(event) {
  5980. if (self.$element.attr('disabled')) {
  5981. return;
  5982. }
  5983. self.remove($(event.target).closest('.tag').data('item'));
  5984. }, self));
  5985. // Only add existing value as tags when using strings as tags
  5986. if (self.options.itemValue === defaultOptions.itemValue) {
  5987. if (self.$element[0].tagName === 'INPUT') {
  5988. self.add(self.$element.val());
  5989. } else {
  5990. $('option', self.$element).each(function() {
  5991. self.add($(this).attr('value'), true);
  5992. });
  5993. }
  5994. }
  5995. },
  5996. /**
  5997. * Removes all tagsinput behaviour and unregsiter all event handlers
  5998. */
  5999. destroy: function() {
  6000. var self = this;
  6001. // Unbind events
  6002. self.$container.off('keypress', 'input');
  6003. self.$container.off('click', '[role=remove]');
  6004. self.$container.remove();
  6005. self.$element.removeData('tagsinput');
  6006. self.$element.show();
  6007. },
  6008. /**
  6009. * Sets focus on the tagsinput
  6010. */
  6011. focus: function() {
  6012. this.$input.focus();
  6013. },
  6014. /**
  6015. * Returns the internal input element
  6016. */
  6017. input: function() {
  6018. return this.$input;
  6019. },
  6020. /**
  6021. * Returns the element which is wrapped around the internal input. This
  6022. * is normally the $container, but typeahead.js moves the $input element.
  6023. */
  6024. findInputWrapper: function() {
  6025. var elt = this.$input[0],
  6026. container = this.$container[0];
  6027. while(elt && elt.parentNode !== container)
  6028. elt = elt.parentNode;
  6029. return $(elt);
  6030. }
  6031. };
  6032. /**
  6033. * Register JQuery plugin
  6034. */
  6035. $.fn.tagsinput = function(arg1, arg2) {
  6036. var results = [];
  6037. this.each(function() {
  6038. var tagsinput = $(this).data('tagsinput');
  6039. // Initialize a new tags input
  6040. if (!tagsinput) {
  6041. tagsinput = new TagsInput(this, arg1);
  6042. $(this).data('tagsinput', tagsinput);
  6043. results.push(tagsinput);
  6044. if (this.tagName === 'SELECT') {
  6045. $('option', $(this)).attr('selected', 'selected');
  6046. }
  6047. // Init tags from $(this).val()
  6048. $(this).val($(this).val());
  6049. } else if (!arg1 && !arg2) {
  6050. // tagsinput already exists
  6051. // no function, trying to init
  6052. results.push(tagsinput);
  6053. } else if(tagsinput[arg1] !== undefined) {
  6054. // Invoke function on existing tags input
  6055. var retVal = tagsinput[arg1](arg2);
  6056. if (retVal !== undefined)
  6057. results.push(retVal);
  6058. }
  6059. });
  6060. if ( typeof arg1 == 'string') {
  6061. // Return the results from the invoked function calls
  6062. return results.length > 1 ? results : results[0];
  6063. } else {
  6064. return results;
  6065. }
  6066. };
  6067. $.fn.tagsinput.Constructor = TagsInput;
  6068. /**
  6069. * Most options support both a string or number as well as a function as
  6070. * option value. This function makes sure that the option with the given
  6071. * key in the given options is wrapped in a function
  6072. */
  6073. function makeOptionItemFunction(options, key) {
  6074. if (typeof options[key] !== 'function') {
  6075. var propertyName = options[key];
  6076. options[key] = function(item) { return item[propertyName]; };
  6077. }
  6078. }
  6079. function makeOptionFunction(options, key) {
  6080. if (typeof options[key] !== 'function') {
  6081. var value = options[key];
  6082. options[key] = function() { return value; };
  6083. }
  6084. }
  6085. /**
  6086. * HtmlEncodes the given value
  6087. */
  6088. var htmlEncodeContainer = $('<div />');
  6089. function htmlEncode(value) {
  6090. if (value) {
  6091. return htmlEncodeContainer.text(value).html();
  6092. } else {
  6093. return '';
  6094. }
  6095. }
  6096. /**
  6097. * Returns the position of the caret in the given input field
  6098. * http://flightschool.acylt.com/devnotes/caret-position-woes/
  6099. */
  6100. function doGetCaretPosition(oField) {
  6101. var iCaretPos = 0;
  6102. if (document.selection) {
  6103. oField.focus ();
  6104. var oSel = document.selection.createRange();
  6105. oSel.moveStart ('character', -oField.value.length);
  6106. iCaretPos = oSel.text.length;
  6107. } else if (oField.selectionStart || oField.selectionStart == '0') {
  6108. iCaretPos = oField.selectionStart;
  6109. }
  6110. return (iCaretPos);
  6111. }
  6112. /**
  6113. * Returns boolean indicates whether user has pressed an expected key combination.
  6114. * @param object keyPressEvent: JavaScript event object, refer
  6115. * http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
  6116. * @param object lookupList: expected key combinations, as in:
  6117. * [13, {which: 188, shiftKey: true}]
  6118. */
  6119. function keyCombinationInList(keyPressEvent, lookupList) {
  6120. var found = false;
  6121. $.each(lookupList, function (index, keyCombination) {
  6122. if (typeof (keyCombination) === 'number' && keyPressEvent.which === keyCombination) {
  6123. found = true;
  6124. return false;
  6125. }
  6126. if (keyPressEvent.which === keyCombination.which) {
  6127. var alt = !keyCombination.hasOwnProperty('altKey') || keyPressEvent.altKey === keyCombination.altKey,
  6128. shift = !keyCombination.hasOwnProperty('shiftKey') || keyPressEvent.shiftKey === keyCombination.shiftKey,
  6129. ctrl = !keyCombination.hasOwnProperty('ctrlKey') || keyPressEvent.ctrlKey === keyCombination.ctrlKey;
  6130. if (alt && shift && ctrl) {
  6131. found = true;
  6132. return false;
  6133. }
  6134. }
  6135. });
  6136. return found;
  6137. }
  6138. /**
  6139. * Initialize tagsinput behaviour on inputs and selects which have
  6140. * data-role=tagsinput
  6141. */
  6142. $(function() {
  6143. $("input[data-role=tagsinput], select[multiple][data-role=tagsinput]").tagsinput();
  6144. });
  6145. })(window.jQuery);
  6146. /*!
  6147. Holder - client side image placeholders
  6148. Version 2.4.0+bxlim
  6149. © 2014 Ivan Malopinsky - http://imsky.co
  6150. Site: http://imsky.github.io/holder
  6151. Issues: https://github.com/imsky/holder/issues
  6152. License: http://opensource.org/licenses/MIT
  6153. */
  6154. !function(e,t,r){t[e]=r}("onDomReady",this,function(e){"use strict";function t(e){if(!b){if(!a.body)return i(t);for(b=!0;e=S.shift();)i(e)}}function r(e){(y||e.type===s||a[c]===u)&&(n(),t())}function n(){y?(a[x](m,r,d),e[x](s,r,d)):(a[g](v,r),e[g](h,r))}function i(e,t){setTimeout(e,+t>=0?t:1)}function o(e){b?i(e):S.push(e)}null==document.readyState&&document.addEventListener&&(document.addEventListener("DOMContentLoaded",function E(){document.removeEventListener("DOMContentLoaded",E,!1),document.readyState="complete"},!1),document.readyState="loading");var a=e.document,l=a.documentElement,s="load",d=!1,h="on"+s,u="complete",c="readyState",f="attachEvent",g="detachEvent",p="addEventListener",m="DOMContentLoaded",v="onreadystatechange",x="removeEventListener",y=p in a,w=d,b=d,S=[];if(a[c]===u)i(t);else if(y)a[p](m,r,d),e[p](s,r,d);else{a[f](v,r),e[f](h,r);try{w=null==e.frameElement&&l}catch(C){}w&&w.doScroll&&!function k(){if(!b){try{w.doScroll("left")}catch(e){return i(k,50)}n(),t()}}()}return o.version="1.4.0",o.isReady=function(){return b},o}(this)),document.querySelectorAll||(document.querySelectorAll=function(e){var t,r=document.createElement("style"),n=[];for(document.documentElement.firstChild.appendChild(r),document._qsa=[],r.styleSheet.cssText=e+"{x-qsa:expression(document._qsa && document._qsa.push(this))}",window.scrollBy(0,0),r.parentNode.removeChild(r);document._qsa.length;)t=document._qsa.shift(),t.style.removeAttribute("x-qsa"),n.push(t);return document._qsa=null,n}),document.querySelector||(document.querySelector=function(e){var t=document.querySelectorAll(e);return t.length?t[0]:null}),document.getElementsByClassName||(document.getElementsByClassName=function(e){return e=String(e).replace(/^|\s+/g,"."),document.querySelectorAll(e)}),Object.keys||(Object.keys=function(e){if(e!==Object(e))throw TypeError("Object.keys called on non-object");var t,r=[];for(t in e)Object.prototype.hasOwnProperty.call(e,t)&&r.push(t);return r}),function(e){var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";e.atob=e.atob||function(e){e=String(e);var r,n=0,i=[],o=0,a=0;if(e=e.replace(/\s/g,""),e.length%4===0&&(e=e.replace(/=+$/,"")),e.length%4===1)throw Error("InvalidCharacterError");if(/[^+/0-9A-Za-z]/.test(e))throw Error("InvalidCharacterError");for(;n<e.length;)r=t.indexOf(e.charAt(n)),o=o<<6|r,a+=6,24===a&&(i.push(String.fromCharCode(o>>16&255)),i.push(String.fromCharCode(o>>8&255)),i.push(String.fromCharCode(255&o)),a=0,o=0),n+=1;return 12===a?(o>>=4,i.push(String.fromCharCode(255&o))):18===a&&(o>>=2,i.push(String.fromCharCode(o>>8&255)),i.push(String.fromCharCode(255&o))),i.join("")},e.btoa=e.btoa||function(e){e=String(e);var r,n,i,o,a,l,s,d=0,h=[];if(/[^\x00-\xFF]/.test(e))throw Error("InvalidCharacterError");for(;d<e.length;)r=e.charCodeAt(d++),n=e.charCodeAt(d++),i=e.charCodeAt(d++),o=r>>2,a=(3&r)<<4|n>>4,l=(15&n)<<2|i>>6,s=63&i,d===e.length+2?(l=64,s=64):d===e.length+1&&(s=64),h.push(t.charAt(o),t.charAt(a),t.charAt(l),t.charAt(s));return h.join("")}}(this),function(){function e(t,r,n){t.document;var i,o=t.currentStyle[r].match(/([\d\.]+)(%|cm|em|in|mm|pc|pt|)/)||[0,0,""],a=o[1],l=o[2];return n=n?/%|em/.test(l)&&t.parentElement?e(t.parentElement,"fontSize",null):16:n,i="fontSize"==r?n:/width/i.test(r)?t.clientWidth:t.clientHeight,"%"==l?a/100*i:"cm"==l?.3937*a*96:"em"==l?a*n:"in"==l?96*a:"mm"==l?.3937*a*96/10:"pc"==l?12*a*96/72:"pt"==l?96*a/72:a}function t(e,t){var r="border"==t?"Width":"",n=t+"Top"+r,i=t+"Right"+r,o=t+"Bottom"+r,a=t+"Left"+r;e[t]=(e[n]==e[i]&&e[n]==e[o]&&e[n]==e[a]?[e[n]]:e[n]==e[o]&&e[a]==e[i]?[e[n],e[i]]:e[a]==e[i]?[e[n],e[i],e[o]]:[e[n],e[i],e[o],e[a]]).join(" ")}function r(r){var n,i=this,o=r.currentStyle,a=e(r,"fontSize"),l=function(e){return"-"+e.toLowerCase()};for(n in o)if(Array.prototype.push.call(i,"styleFloat"==n?"float":n.replace(/[A-Z]/,l)),"width"==n)i[n]=r.offsetWidth+"px";else if("height"==n)i[n]=r.offsetHeight+"px";else if("styleFloat"==n)i.float=o[n];else if(/margin.|padding.|border.+W/.test(n)&&"auto"!=i[n])i[n]=Math.round(e(r,n,a))+"px";else if(/^outline/.test(n))try{i[n]=o[n]}catch(s){i.outlineColor=o.color,i.outlineStyle=i.outlineStyle||"none",i.outlineWidth=i.outlineWidth||"0px",i.outline=[i.outlineColor,i.outlineWidth,i.outlineStyle].join(" ")}else i[n]=o[n];t(i,"margin"),t(i,"padding"),t(i,"border"),i.fontSize=Math.round(a)+"px"}window.getComputedStyle||(r.prototype={constructor:r,getPropertyPriority:function(){throw new Error("NotSupportedError: DOM Exception 9")},getPropertyValue:function(e){return this[e.replace(/-\w/g,function(e){return e[1].toUpperCase()})]},item:function(e){return this[e]},removeProperty:function(){throw new Error("NoModificationAllowedError: DOM Exception 7")},setProperty:function(){throw new Error("NoModificationAllowedError: DOM Exception 7")},getPropertyCSSValue:function(){throw new Error("NotSupportedError: DOM Exception 9")}},window.getComputedStyle=Window.prototype.getComputedStyle=function(e){return new r(e)})}(),Object.prototype.hasOwnProperty||(Object.prototype.hasOwnProperty=function(e){var t=this.__proto__||this.constructor.prototype;return e in this&&(!(e in t)||t[e]!==this[e])}),function(e,t){e.augment=t()}(this,function(){"use strict";var e=function(){},t=Array.prototype.slice,r=function(r,n){var i=e.prototype="function"==typeof r?r.prototype:r,o=new e,a=n.apply(o,t.call(arguments,2).concat(i));if("object"==typeof a)for(var l in a)o[l]=a[l];if(!o.hasOwnProperty("constructor"))return o;var s=o.constructor;return s.prototype=o,s};return r.defclass=function(e){var t=e.constructor;return t.prototype=e,t},r.extend=function(e,t){return r(e,function(e){return this.uber=e,t})},r}),function(e,t){function r(e,t,r,o){var a=n(r.substr(r.lastIndexOf(e.domain)),e);a&&i(null,o,a,t)}function n(e,t){for(var r={theme:p(A.settings.themes.gray,null),stylesheets:t.stylesheets,holderURL:[]},n=!1,i=String.fromCharCode(11),o=e.replace(/([^\\])\//g,"$1"+i).split(i),a=/%[0-9a-f]{2}/gi,l=o.length,s=0;l>s;s++){var d=o[s];if(d.match(a))try{d=decodeURIComponent(d)}catch(h){d=o[s]}var u=!1;if(A.flags.dimensions.match(d))n=!0,r.dimensions=A.flags.dimensions.output(d),u=!0;else if(A.flags.fluid.match(d))n=!0,r.dimensions=A.flags.fluid.output(d),r.fluid=!0,u=!0;else if(A.flags.textmode.match(d))r.textmode=A.flags.textmode.output(d),u=!0;else if(A.flags.colors.match(d)){var c=A.flags.colors.output(d);r.theme=p(r.theme,c),u=!0}else if(t.themes[d])t.themes.hasOwnProperty(d)&&(r.theme=p(t.themes[d],null)),u=!0;else if(A.flags.font.match(d))r.font=A.flags.font.output(d),u=!0;else if(A.flags.auto.match(d))r.auto=!0,u=!0;else if(A.flags.text.match(d))r.text=A.flags.text.output(d),u=!0;else if(A.flags.random.match(d)){null==A.vars.cache.themeKeys&&(A.vars.cache.themeKeys=Object.keys(t.themes));var f=A.vars.cache.themeKeys[0|Math.random()*A.vars.cache.themeKeys.length];r.theme=p(t.themes[f],null),u=!0}u&&r.holderURL.push(d)}return r.holderURL.unshift(t.domain),r.holderURL=r.holderURL.join("/"),n?r:!1}function i(e,t,r,n){var i=r.dimensions,a=r.theme,l=i.width+"x"+i.height;if(e=null==e?r.fluid?"fluid":"image":e,null!=r.text&&(a.text=r.text,"object"===t.nodeName.toLowerCase())){for(var d=a.text.split("\\n"),u=0;u<d.length;u++)d[u]=b(d[u]);a.text=d.join("\\n")}var f=r.holderURL,g=p(n,null);r.font&&(a.font=r.font,!g.noFontFallback&&"img"===t.nodeName.toLowerCase()&&A.setup.supportsCanvas&&"svg"===g.renderer&&(g=p(g,{renderer:"canvas"}))),r.font&&"canvas"==g.renderer&&(g.reRender=!0),"background"==e?null==t.getAttribute("data-background-src")&&c(t,{"data-background-src":f}):c(t,{"data-src":f}),r.theme=a,t.holderData={flags:r,renderSettings:g},("image"==e||"fluid"==e)&&c(t,{alt:a.text?(a.text.length>16?a.text.substring(0,16)+"…":a.text)+" ["+l+"]":l}),"image"==e?("html"!=g.renderer&&r.auto||(t.style.width=i.width+"px",t.style.height=i.height+"px"),"html"==g.renderer?t.style.backgroundColor=a.background:(o(e,{dimensions:i,theme:a,flags:r},t,g),r.textmode&&"exact"==r.textmode&&(A.vars.resizableImages.push(t),s(t)))):"background"==e&&"html"!=g.renderer?o(e,{dimensions:i,theme:a,flags:r},t,g):"fluid"==e&&("%"==i.height.slice(-1)?t.style.height=i.height:null!=r.auto&&r.auto||(t.style.height=i.height+"px"),"%"==i.width.slice(-1)?t.style.width=i.width:null!=r.auto&&r.auto||(t.style.width=i.width+"px"),("inline"==t.style.display||""===t.style.display||"none"==t.style.display)&&(t.style.display="block"),h(t),"html"==g.renderer?t.style.backgroundColor=a.background:(A.vars.resizableImages.push(t),s(t)))}function o(e,t,r,n){function i(){var e=null;switch(n.renderer){case"canvas":e=L(s);break;case"svg":e=O(s,n);break;default:throw"Holder: invalid renderer: "+n.renderer}return e}var o=null;switch(n.renderer){case"svg":if(!A.setup.supportsSVG)return;break;case"canvas":if(!A.setup.supportsCanvas)return;break;default:return}{var l={width:t.dimensions.width,height:t.dimensions.height,theme:t.theme,flags:t.flags},s=a(l);({text:l.text,width:l.width,height:l.height,textHeight:l.font.size,font:l.font.family,fontWeight:l.font.weight,template:l.theme})}if(o=i(),null==o)throw"Holder: couldn't render placeholder";"background"==e?(r.style.backgroundImage="url("+o+")",r.style.backgroundSize=l.width+"px "+l.height+"px"):("img"===r.nodeName.toLowerCase()?c(r,{src:o}):"object"===r.nodeName.toLowerCase()&&(c(r,{data:o}),c(r,{type:"image/svg+xml"})),n.reRender&&setTimeout(function(){var e=i();if(null==e)throw"Holder: couldn't render placeholder";"img"===r.nodeName.toLowerCase()?c(r,{src:e}):"object"===r.nodeName.toLowerCase()&&(c(r,{data:e}),c(r,{type:"image/svg+xml"}))},100)),c(r,{"data-holder-rendered":!0})}function a(e){function t(e,t,r,n){t.width=r,t.height=n,e.width=Math.max(e.width,t.width),e.height+=t.height,e.add(t)}switch(e.font={family:e.theme.font?e.theme.font:"Arial, Helvetica, Open Sans, sans-serif",size:l(e.width,e.height,e.theme.size?e.theme.size:12),weight:e.theme.fontweight?e.theme.fontweight:"bold"},e.text=e.theme.text?e.theme.text:Math.floor(e.width)+"x"+Math.floor(e.height),e.flags.textmode){case"literal":e.text=e.flags.dimensions.width+"x"+e.flags.dimensions.height;break;case"exact":if(!e.flags.exactDimensions)break;e.text=Math.floor(e.flags.exactDimensions.width)+"x"+Math.floor(e.flags.exactDimensions.height)}var r=new F({width:e.width,height:e.height}),n=r.Shape,i=new n.Rect("holderBg",{fill:e.theme.background});i.resize(e.width,e.height),r.root.add(i);var o=new n.Group("holderTextGroup",{text:e.text,align:"center",font:e.font,fill:e.theme.foreground});o.moveTo(null,null,1),r.root.add(o);var a=o.textPositionData=T(r);if(!a)throw"Holder: staging fallback not supported yet.";o.properties.leading=a.boundingBox.height;var s=null,d=null;if(a.lineCount>1){var h=0,u=0,c=e.width*A.setup.lineWrapRatio,f=0;d=new n.Group("line"+f);for(var g=0;g<a.words.length;g++){var p=a.words[g];s=new n.Text(p.text);var m="\\n"==p.text;(h+p.width>=c||m===!0)&&(t(o,d,h,o.properties.leading),h=0,u+=o.properties.leading,f+=1,d=new n.Group("line"+f),d.y=u),m!==!0&&(s.moveTo(h,0),h+=a.spaceWidth+p.width,d.add(s))}t(o,d,h,o.properties.leading);for(var v in o.children)d=o.children[v],d.moveTo((o.width-d.width)/2,null,null);o.moveTo((e.width-o.width)/2,(e.height-o.height)/2,null),(e.height-o.height)/2<0&&o.moveTo(null,0,null)}else s=new n.Text(e.text),d=new n.Group("line0"),d.add(s),o.add(d),o.moveTo((e.width-a.boundingBox.width)/2,(e.height-a.boundingBox.height)/2,null);return r}function l(e,t,r){t=parseInt(t,10),e=parseInt(e,10);var n=Math.max(t,e),i=Math.min(t,e),o=1/12,a=Math.min(.75*i,.75*n*o);return Math.round(Math.max(r,a))}function s(e){var t;t=null==e||null==e.nodeType?A.vars.resizableImages:[e];for(var r in t)if(t.hasOwnProperty(r)){var n=t[r];if(n.holderData){var i=n.holderData.flags,a=d(n,k.invisibleErrorFn(s));if(a){if(i.fluid&&i.auto){var l=n.holderData.fluidConfig;switch(l.mode){case"width":a.height=a.width/l.ratio;break;case"height":a.width=a.height*l.ratio}}var h={dimensions:a,theme:i.theme,flags:i};i.textmode&&"exact"==i.textmode&&(i.exactDimensions=a,h.dimensions=i.dimensions),o("image",h,n,n.holderData.renderSettings)}}}}function d(e,t){var r={height:e.clientHeight,width:e.clientWidth};return r.height||r.width?(e.removeAttribute("data-holder-invisible"),r):(c(e,{"data-holder-invisible":!0}),void t.call(this,e))}function h(e){if(e.holderData){var t=d(e,k.invisibleErrorFn(h));if(t){var r=e.holderData.flags,n={fluidHeight:"%"==r.dimensions.height.slice(-1),fluidWidth:"%"==r.dimensions.width.slice(-1),mode:null,initialDimensions:t};n.fluidWidth&&!n.fluidHeight?(n.mode="width",n.ratio=n.initialDimensions.width/parseFloat(r.dimensions.height)):!n.fluidWidth&&n.fluidHeight&&(n.mode="height",n.ratio=parseFloat(r.dimensions.width)/n.initialDimensions.height),e.holderData.fluidConfig=n}}}function u(e,t){return null==t?E.createElement(e):E.createElementNS(t,e)}function c(e,t){for(var r in t)e.setAttribute(r,t[r])}function f(e,t,r){if(null==e){e=u("svg",C);var n=u("defs",C);e.appendChild(n)}return e.webkitMatchesSelector&&e.setAttribute("xmlns",C),c(e,{width:t,height:r,viewBox:"0 0 "+t+" "+r,preserveAspectRatio:"none"}),e}function g(e,r){if(t.XMLSerializer){{var n=new XMLSerializer,i="",o=r.stylesheets;e.querySelector("defs")}if(r.svgXMLStylesheet){for(var a=(new DOMParser).parseFromString("<xml />","application/xml"),l=o.length-1;l>=0;l--){var s=a.createProcessingInstruction("xml-stylesheet",'href="'+o[l]+'" rel="stylesheet"');a.insertBefore(s,a.firstChild)}var d=a.createProcessingInstruction("xml",'version="1.0" encoding="UTF-8" standalone="yes"');a.insertBefore(d,a.firstChild),a.removeChild(a.documentElement),i=n.serializeToString(a)}var h=n.serializeToString(e);return h=h.replace(/\&amp;(\#[0-9]{2,}\;)/g,"&$1"),i+h}}function p(e,t){var r={};for(var n in e)e.hasOwnProperty(n)&&(r[n]=e[n]);if(null!=t)for(var i in t)t.hasOwnProperty(i)&&(r[i]=t[i]);return r}function m(e){var t=[];for(var r in e)e.hasOwnProperty(r)&&t.push(r+":"+e[r]);return t.join(";")}function v(e){A.vars.debounceTimer||e.call(this),A.vars.debounceTimer&&clearTimeout(A.vars.debounceTimer),A.vars.debounceTimer=setTimeout(function(){A.vars.debounceTimer=null,e.call(this)},A.setup.debounce)}function x(){v(function(){s(null)})}function y(e){var r=null;return"string"==typeof e?r=E.querySelectorAll(e):t.NodeList&&e instanceof t.NodeList?r=e:t.Node&&e instanceof t.Node?r=[e]:t.HTMLCollection&&e instanceof t.HTMLCollection?r=e:null===e&&(r=[]),r}function w(e,t){var r=new Image;r.onerror=function(){t.call(this,!1,e)},r.onload=function(){t.call(this,!0,e)},r.src=e.src}function b(e){for(var t=[],r=0,n=e.length-1;n>=0;n--)r=e[n].charCodeAt(),t.unshift(r>128?["&#",r,";"].join(""):e[n]);return t.join("")}function S(e){return e.replace(/&#(\d+);/g,function(e,t){return String.fromCharCode(t)})}var C="http://www.w3.org/2000/svg",E=t.document,k={addTheme:function(e,t){return null!=e&&null!=t&&(A.settings.themes[e]=t),delete A.vars.cache.themeKeys,this},addImage:function(e,t){var r=E.querySelectorAll(t);if(r.length)for(var n=0,i=r.length;i>n;n++){var o=u("img");c(o,{"data-src":e}),r[n].appendChild(o)}return this},run:function(e){e=e||{};var o={};A.vars.preempted=!0;var a=p(A.settings,e);o.renderer=a.renderer?a.renderer:A.setup.renderer,-1===A.setup.renderers.join(",").indexOf(o.renderer)&&(o.renderer=A.setup.supportsSVG?"svg":A.setup.supportsCanvas?"canvas":"html"),a.use_canvas?o.renderer="canvas":a.use_svg&&(o.renderer="svg");var l=y(a.images),s=y(a.bgnodes),d=y(a.stylenodes),h=y(a.objects);o.stylesheets=[],o.svgXMLStylesheet=!0,o.noFontFallback=a.noFontFallback?a.noFontFallback:!1;for(var c=0;c<d.length;c++){var f=d[c];if(f.attributes.rel&&f.attributes.href&&"stylesheet"==f.attributes.rel.value){var g=f.attributes.href.value,m=u("a");m.href=g;var v=m.protocol+"//"+m.host+m.pathname+m.search;o.stylesheets.push(v)}}for(c=0;c<s.length;c++){var x=t.getComputedStyle(s[c],null).getPropertyValue("background-image"),b=s[c].getAttribute("data-background-src"),S=null;S=null==b?x:b;var C=null,E="?"+a.domain+"/";if(0===S.indexOf(E))C=S.slice(1);else if(-1!=S.indexOf(E)){var k=S.substr(S.indexOf(E)).slice(1),T=k.match(/([^\"]*)"?\)/);null!=T&&(C=T[1])}if(null!=C){var L=n(C,a);L&&i("background",s[c],L,o)}}for(c=0;c<h.length;c++){var O=h[c],F={};try{F.data=O.getAttribute("data"),F.dataSrc=O.getAttribute("data-src")}catch(z){}var M=null!=F.data&&0===F.data.indexOf(a.domain),D=null!=F.dataSrc&&0===F.dataSrc.indexOf(a.domain);M?r(a,o,F.data,O):D&&r(a,o,F.dataSrc,O)}for(c=0;c<l.length;c++){var R=l[c],j={};try{j.src=R.getAttribute("src"),j.dataSrc=R.getAttribute("data-src"),j.rendered=R.getAttribute("data-holder-rendered")}catch(z){}var B=null!=j.src,P=null!=j.dataSrc&&0===j.dataSrc.indexOf(a.domain),N=null!=j.rendered&&"true"==j.rendered;B?0===j.src.indexOf(a.domain)?r(a,o,j.src,R):P&&(N?r(a,o,j.dataSrc,R):w({src:j.src,options:a,renderSettings:o,dataSrc:j.dataSrc,image:R},function(e,t){e||r(t.options,t.renderSettings,t.dataSrc,t.image)})):P&&r(a,o,j.dataSrc,R)}return this},invisibleErrorFn:function(){return function(e){if(e.hasAttribute("data-holder-invisible"))throw"Holder: invisible placeholder"}}};k.add_theme=k.addTheme,k.add_image=k.addImage,k.invisible_error_fn=k.invisibleErrorFn;var A={settings:{domain:"holder.js",images:"img",objects:"object",bgnodes:"body .holderjs",stylenodes:"head link.holderjs",stylesheets:[],themes:{gray:{background:"#EEEEEE",foreground:"#AAAAAA"},social:{background:"#3a5a97",foreground:"#FFFFFF"},industrial:{background:"#434A52",foreground:"#C2F200"},sky:{background:"#0D8FDB",foreground:"#FFFFFF"},vine:{background:"#39DBAC",foreground:"#1E292C"},lava:{background:"#F8591A",foreground:"#1C2846",size:12}}},flags:{dimensions:{regex:/^(\d+)x(\d+)$/,output:function(e){var t=this.regex.exec(e);return{width:+t[1],height:+t[2]}}},fluid:{regex:/^([0-9]+%?)x([0-9]+%?)$/,output:function(e){var t=this.regex.exec(e);return{width:t[1],height:t[2]}}},colors:{regex:/(?:#|\^)([0-9a-f]{3,})\:(?:#|\^)([0-9a-f]{3,})/i,output:function(e){var t=this.regex.exec(e);return{foreground:"#"+t[2],background:"#"+t[1]}}},text:{regex:/text\:(.*)/,output:function(e){return this.regex.exec(e)[1].replace("\\/","/")}},font:{regex:/font\:(.*)/,output:function(e){return this.regex.exec(e)[1]}},auto:{regex:/^auto$/},textmode:{regex:/textmode\:(.*)/,output:function(e){return this.regex.exec(e)[1]}},random:{regex:/^random$/}}},T=function(){var e=null,t=null,r=null;return function(n){var i=n.root;if(A.setup.supportsSVG){var o=!1,a=function(e){return E.createTextNode(e)};null==e&&(o=!0),e=f(e,i.properties.width,i.properties.height),o&&(t=u("text",C),r=a(null),c(t,{x:0}),t.appendChild(r),e.appendChild(t),E.body.appendChild(e),e.style.visibility="hidden",e.style.position="absolute",e.style.top="-100%",e.style.left="-100%");var l=i.children.holderTextGroup,s=l.properties;c(t,{y:s.font.size,style:m({"font-weight":s.font.weight,"font-size":s.font.size+"px","font-family":s.font.family,"dominant-baseline":"middle"})}),r.nodeValue=s.text;var d=t.getBBox(),h=Math.ceil(d.width/(i.properties.width*A.setup.lineWrapRatio)),g=s.text.split(" "),p=s.text.match(/\\n/g);h+=null==p?0:p.length,r.nodeValue=s.text.replace(/[ ]+/g,"");var v=t.getComputedTextLength(),x=d.width-v,y=Math.round(x/Math.max(1,g.length-1)),w=[];if(h>1){r.nodeValue="";for(var b=0;b<g.length;b++)if(0!==g[b].length){r.nodeValue=S(g[b]);var k=t.getBBox();w.push({text:g[b],width:k.width})}}return{spaceWidth:y,lineCount:h,boundingBox:d,words:w}}return!1}}(),L=function(){var e=u("canvas"),t=null;return function(r){null==t&&(t=e.getContext("2d"));var n=r.root;e.width=A.dpr(n.properties.width),e.height=A.dpr(n.properties.height),t.textBaseline="middle",t.fillStyle=n.children.holderBg.properties.fill,t.fillRect(0,0,A.dpr(n.children.holderBg.width),A.dpr(n.children.holderBg.height));{var i=n.children.holderTextGroup;i.properties}t.font=i.properties.font.weight+" "+A.dpr(i.properties.font.size)+"px "+i.properties.font.family+", monospace",t.fillStyle=i.properties.fill;for(var o in i.children){var a=i.children[o];for(var l in a.children){var s=a.children[l],d=A.dpr(i.x+a.x+s.x),h=A.dpr(i.y+a.y+s.y+i.properties.leading/2);t.fillText(s.properties.text,d,h)}}return e.toDataURL("image/png")}}(),O=function(){if(t.XMLSerializer){var e=f(null,0,0),r=u("rect",C);return e.appendChild(r),function(t,n){var i=t.root;f(e,i.properties.width,i.properties.height);for(var o=e.querySelectorAll("g"),a=0;a<o.length;a++)o[a].parentNode.removeChild(o[a]);c(r,{width:i.children.holderBg.width,height:i.children.holderBg.height,fill:i.children.holderBg.properties.fill});var l=i.children.holderTextGroup,s=l.properties,d=u("g",C);e.appendChild(d);for(var h in l.children){var p=l.children[h];for(var v in p.children){var x=p.children[v],y=l.x+p.x+x.x,w=l.y+p.y+x.y+l.properties.leading/2,b=u("text",C),S=E.createTextNode(null);c(b,{x:y,y:w,style:m({fill:s.fill,"font-weight":s.font.weight,"font-family":s.font.family+", monospace","font-size":s.font.size+"px","dominant-baseline":"central"})}),S.nodeValue=x.properties.text,b.appendChild(S),d.appendChild(b)}}var k="data:image/svg+xml;base64,"+btoa(unescape(encodeURIComponent(g(e,n))));return k}}}(),F=function(e){function t(e,t){for(var r in t)e[r]=t[r];return e}var r=1,n=augment.defclass({constructor:function(e){r++,this.parent=null,this.children={},this.id=r,this.name="n"+r,null!=e&&(this.name=e),this.x=0,this.y=0,this.z=0,this.width=0,this.height=0},resize:function(e,t){null!=e&&(this.width=e),null!=t&&(this.height=t)},moveTo:function(e,t,r){this.x=null!=e?e:this.x,this.y=null!=t?t:this.y,this.z=null!=r?r:this.z},add:function(e){var t=e.name;if(null!=this.children[t])throw"SceneGraph: child with that name already exists: "+t;this.children[t]=e,e.parent=this}}),i=augment(n,function(t){this.constructor=function(){t.constructor.call(this,"root"),this.properties=e}}),o=augment(n,function(e){function r(r,n){if(e.constructor.call(this,r),this.properties={fill:"#000"},null!=n)t(this.properties,n);else if(null!=r&&"string"!=typeof r)throw"SceneGraph: invalid node name"}this.Group=augment.extend(this,{constructor:r,type:"group"}),this.Rect=augment.extend(this,{constructor:r,type:"rect"}),this.Text=augment.extend(this,{constructor:function(e){r.call(this),this.properties.text=e},type:"text"})}),a=new i;return this.Shape=o,this.root=a,this};for(var z in A.flags)A.flags.hasOwnProperty(z)&&(A.flags[z].match=function(e){return e.match(this.regex)});A.setup={renderer:"html",debounce:100,ratio:1,supportsCanvas:!1,supportsSVG:!1,lineWrapRatio:.9,renderers:["html","canvas","svg"]},A.dpr=function(e){return e*A.setup.ratio},A.vars={preempted:!1,resizableImages:[],debounceTimer:null,cache:{}},function(){var e=1,r=1,n=u("canvas"),i=null;n.getContext&&-1!=n.toDataURL("image/png").indexOf("data:image/png")&&(A.setup.renderer="canvas",i=n.getContext("2d"),A.setup.supportsCanvas=!0),A.setup.supportsCanvas&&(e=t.devicePixelRatio||1,r=i.webkitBackingStorePixelRatio||i.mozBackingStorePixelRatio||i.msBackingStorePixelRatio||i.oBackingStorePixelRatio||i.backingStorePixelRatio||1),A.setup.ratio=e/r,E.createElementNS&&E.createElementNS(C,"svg").createSVGRect&&(A.setup.renderer="svg",A.setup.supportsSVG=!0)}(),e(k,"Holder",t),t.onDomReady&&t.onDomReady(function(){A.vars.preempted||k.run(),t.addEventListener?(t.addEventListener("resize",x,!1),t.addEventListener("orientationchange",x,!1)):t.attachEvent("onresize",x),"object"==typeof t.Turbolinks&&t.document.addEventListener("page:change",function(){k.run()})})}(function(e,t,r){var n="function"==typeof define&&define.amd;n?define(e):r[t]=e},this);
  6155. /*!
  6156. * typeahead.js 0.10.5
  6157. * https://github.com/twitter/typeahead.js
  6158. * Copyright 2013-2014 Twitter, Inc. and other contributors; Licensed MIT
  6159. */
  6160. (function($) {
  6161. var _ = function() {
  6162. "use strict";
  6163. return {
  6164. isMsie: function() {
  6165. return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false;
  6166. },
  6167. isBlankString: function(str) {
  6168. return !str || /^\s*$/.test(str);
  6169. },
  6170. escapeRegExChars: function(str) {
  6171. return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
  6172. },
  6173. isString: function(obj) {
  6174. return typeof obj === "string";
  6175. },
  6176. isNumber: function(obj) {
  6177. return typeof obj === "number";
  6178. },
  6179. isArray: $.isArray,
  6180. isFunction: $.isFunction,
  6181. isObject: $.isPlainObject,
  6182. isUndefined: function(obj) {
  6183. return typeof obj === "undefined";
  6184. },
  6185. toStr: function toStr(s) {
  6186. return _.isUndefined(s) || s === null ? "" : s + "";
  6187. },
  6188. bind: $.proxy,
  6189. each: function(collection, cb) {
  6190. $.each(collection, reverseArgs);
  6191. function reverseArgs(index, value) {
  6192. return cb(value, index);
  6193. }
  6194. },
  6195. map: $.map,
  6196. filter: $.grep,
  6197. every: function(obj, test) {
  6198. var result = true;
  6199. if (!obj) {
  6200. return result;
  6201. }
  6202. $.each(obj, function(key, val) {
  6203. if (!(result = test.call(null, val, key, obj))) {
  6204. return false;
  6205. }
  6206. });
  6207. return !!result;
  6208. },
  6209. some: function(obj, test) {
  6210. var result = false;
  6211. if (!obj) {
  6212. return result;
  6213. }
  6214. $.each(obj, function(key, val) {
  6215. if (result = test.call(null, val, key, obj)) {
  6216. return false;
  6217. }
  6218. });
  6219. return !!result;
  6220. },
  6221. mixin: $.extend,
  6222. getUniqueId: function() {
  6223. var counter = 0;
  6224. return function() {
  6225. return counter++;
  6226. };
  6227. }(),
  6228. templatify: function templatify(obj) {
  6229. return $.isFunction(obj) ? obj : template;
  6230. function template() {
  6231. return String(obj);
  6232. }
  6233. },
  6234. defer: function(fn) {
  6235. setTimeout(fn, 0);
  6236. },
  6237. debounce: function(func, wait, immediate) {
  6238. var timeout, result;
  6239. return function() {
  6240. var context = this, args = arguments, later, callNow;
  6241. later = function() {
  6242. timeout = null;
  6243. if (!immediate) {
  6244. result = func.apply(context, args);
  6245. }
  6246. };
  6247. callNow = immediate && !timeout;
  6248. clearTimeout(timeout);
  6249. timeout = setTimeout(later, wait);
  6250. if (callNow) {
  6251. result = func.apply(context, args);
  6252. }
  6253. return result;
  6254. };
  6255. },
  6256. throttle: function(func, wait) {
  6257. var context, args, timeout, result, previous, later;
  6258. previous = 0;
  6259. later = function() {
  6260. previous = new Date();
  6261. timeout = null;
  6262. result = func.apply(context, args);
  6263. };
  6264. return function() {
  6265. var now = new Date(), remaining = wait - (now - previous);
  6266. context = this;
  6267. args = arguments;
  6268. if (remaining <= 0) {
  6269. clearTimeout(timeout);
  6270. timeout = null;
  6271. previous = now;
  6272. result = func.apply(context, args);
  6273. } else if (!timeout) {
  6274. timeout = setTimeout(later, remaining);
  6275. }
  6276. return result;
  6277. };
  6278. },
  6279. noop: function() {}
  6280. };
  6281. }();
  6282. var VERSION = "0.10.5";
  6283. var tokenizers = function() {
  6284. "use strict";
  6285. return {
  6286. nonword: nonword,
  6287. whitespace: whitespace,
  6288. obj: {
  6289. nonword: getObjTokenizer(nonword),
  6290. whitespace: getObjTokenizer(whitespace)
  6291. }
  6292. };
  6293. function whitespace(str) {
  6294. str = _.toStr(str);
  6295. return str ? str.split(/\s+/) : [];
  6296. }
  6297. function nonword(str) {
  6298. str = _.toStr(str);
  6299. return str ? str.split(/\W+/) : [];
  6300. }
  6301. function getObjTokenizer(tokenizer) {
  6302. return function setKey() {
  6303. var args = [].slice.call(arguments, 0);
  6304. return function tokenize(o) {
  6305. var tokens = [];
  6306. _.each(args, function(k) {
  6307. tokens = tokens.concat(tokenizer(_.toStr(o[k])));
  6308. });
  6309. return tokens;
  6310. };
  6311. };
  6312. }
  6313. }();
  6314. var LruCache = function() {
  6315. "use strict";
  6316. function LruCache(maxSize) {
  6317. this.maxSize = _.isNumber(maxSize) ? maxSize : 100;
  6318. this.reset();
  6319. if (this.maxSize <= 0) {
  6320. this.set = this.get = $.noop;
  6321. }
  6322. }
  6323. _.mixin(LruCache.prototype, {
  6324. set: function set(key, val) {
  6325. var tailItem = this.list.tail, node;
  6326. if (this.size >= this.maxSize) {
  6327. this.list.remove(tailItem);
  6328. delete this.hash[tailItem.key];
  6329. }
  6330. if (node = this.hash[key]) {
  6331. node.val = val;
  6332. this.list.moveToFront(node);
  6333. } else {
  6334. node = new Node(key, val);
  6335. this.list.add(node);
  6336. this.hash[key] = node;
  6337. this.size++;
  6338. }
  6339. },
  6340. get: function get(key) {
  6341. var node = this.hash[key];
  6342. if (node) {
  6343. this.list.moveToFront(node);
  6344. return node.val;
  6345. }
  6346. },
  6347. reset: function reset() {
  6348. this.size = 0;
  6349. this.hash = {};
  6350. this.list = new List();
  6351. }
  6352. });
  6353. function List() {
  6354. this.head = this.tail = null;
  6355. }
  6356. _.mixin(List.prototype, {
  6357. add: function add(node) {
  6358. if (this.head) {
  6359. node.next = this.head;
  6360. this.head.prev = node;
  6361. }
  6362. this.head = node;
  6363. this.tail = this.tail || node;
  6364. },
  6365. remove: function remove(node) {
  6366. node.prev ? node.prev.next = node.next : this.head = node.next;
  6367. node.next ? node.next.prev = node.prev : this.tail = node.prev;
  6368. },
  6369. moveToFront: function(node) {
  6370. this.remove(node);
  6371. this.add(node);
  6372. }
  6373. });
  6374. function Node(key, val) {
  6375. this.key = key;
  6376. this.val = val;
  6377. this.prev = this.next = null;
  6378. }
  6379. return LruCache;
  6380. }();
  6381. var PersistentStorage = function() {
  6382. "use strict";
  6383. var ls, methods;
  6384. try {
  6385. ls = window.localStorage;
  6386. ls.setItem("~~~", "!");
  6387. ls.removeItem("~~~");
  6388. } catch (err) {
  6389. ls = null;
  6390. }
  6391. function PersistentStorage(namespace) {
  6392. this.prefix = [ "__", namespace, "__" ].join("");
  6393. this.ttlKey = "__ttl__";
  6394. this.keyMatcher = new RegExp("^" + _.escapeRegExChars(this.prefix));
  6395. }
  6396. if (ls && window.JSON) {
  6397. methods = {
  6398. _prefix: function(key) {
  6399. return this.prefix + key;
  6400. },
  6401. _ttlKey: function(key) {
  6402. return this._prefix(key) + this.ttlKey;
  6403. },
  6404. get: function(key) {
  6405. if (this.isExpired(key)) {
  6406. this.remove(key);
  6407. }
  6408. return decode(ls.getItem(this._prefix(key)));
  6409. },
  6410. set: function(key, val, ttl) {
  6411. if (_.isNumber(ttl)) {
  6412. ls.setItem(this._ttlKey(key), encode(now() + ttl));
  6413. } else {
  6414. ls.removeItem(this._ttlKey(key));
  6415. }
  6416. return ls.setItem(this._prefix(key), encode(val));
  6417. },
  6418. remove: function(key) {
  6419. ls.removeItem(this._ttlKey(key));
  6420. ls.removeItem(this._prefix(key));
  6421. return this;
  6422. },
  6423. clear: function() {
  6424. var i, key, keys = [], len = ls.length;
  6425. for (i = 0; i < len; i++) {
  6426. if ((key = ls.key(i)).match(this.keyMatcher)) {
  6427. keys.push(key.replace(this.keyMatcher, ""));
  6428. }
  6429. }
  6430. for (i = keys.length; i--; ) {
  6431. this.remove(keys[i]);
  6432. }
  6433. return this;
  6434. },
  6435. isExpired: function(key) {
  6436. var ttl = decode(ls.getItem(this._ttlKey(key)));
  6437. return _.isNumber(ttl) && now() > ttl ? true : false;
  6438. }
  6439. };
  6440. } else {
  6441. methods = {
  6442. get: _.noop,
  6443. set: _.noop,
  6444. remove: _.noop,
  6445. clear: _.noop,
  6446. isExpired: _.noop
  6447. };
  6448. }
  6449. _.mixin(PersistentStorage.prototype, methods);
  6450. return PersistentStorage;
  6451. function now() {
  6452. return new Date().getTime();
  6453. }
  6454. function encode(val) {
  6455. return JSON.stringify(_.isUndefined(val) ? null : val);
  6456. }
  6457. function decode(val) {
  6458. return JSON.parse(val);
  6459. }
  6460. }();
  6461. var Transport = function() {
  6462. "use strict";
  6463. var pendingRequestsCount = 0, pendingRequests = {}, maxPendingRequests = 6, sharedCache = new LruCache(10);
  6464. function Transport(o) {
  6465. o = o || {};
  6466. this.cancelled = false;
  6467. this.lastUrl = null;
  6468. this._send = o.transport ? callbackToDeferred(o.transport) : $.ajax;
  6469. this._get = o.rateLimiter ? o.rateLimiter(this._get) : this._get;
  6470. this._cache = o.cache === false ? new LruCache(0) : sharedCache;
  6471. }
  6472. Transport.setMaxPendingRequests = function setMaxPendingRequests(num) {
  6473. maxPendingRequests = num;
  6474. };
  6475. Transport.resetCache = function resetCache() {
  6476. sharedCache.reset();
  6477. };
  6478. _.mixin(Transport.prototype, {
  6479. _get: function(url, o, cb) {
  6480. var that = this, jqXhr;
  6481. if (this.cancelled || url !== this.lastUrl) {
  6482. return;
  6483. }
  6484. if (jqXhr = pendingRequests[url]) {
  6485. jqXhr.done(done).fail(fail);
  6486. } else if (pendingRequestsCount < maxPendingRequests) {
  6487. pendingRequestsCount++;
  6488. pendingRequests[url] = this._send(url, o).done(done).fail(fail).always(always);
  6489. } else {
  6490. this.onDeckRequestArgs = [].slice.call(arguments, 0);
  6491. }
  6492. function done(resp) {
  6493. cb && cb(null, resp);
  6494. that._cache.set(url, resp);
  6495. }
  6496. function fail() {
  6497. cb && cb(true);
  6498. }
  6499. function always() {
  6500. pendingRequestsCount--;
  6501. delete pendingRequests[url];
  6502. if (that.onDeckRequestArgs) {
  6503. that._get.apply(that, that.onDeckRequestArgs);
  6504. that.onDeckRequestArgs = null;
  6505. }
  6506. }
  6507. },
  6508. get: function(url, o, cb) {
  6509. var resp;
  6510. if (_.isFunction(o)) {
  6511. cb = o;
  6512. o = {};
  6513. }
  6514. this.cancelled = false;
  6515. this.lastUrl = url;
  6516. if (resp = this._cache.get(url)) {
  6517. _.defer(function() {
  6518. cb && cb(null, resp);
  6519. });
  6520. } else {
  6521. this._get(url, o, cb);
  6522. }
  6523. return !!resp;
  6524. },
  6525. cancel: function() {
  6526. this.cancelled = true;
  6527. }
  6528. });
  6529. return Transport;
  6530. function callbackToDeferred(fn) {
  6531. return function customSendWrapper(url, o) {
  6532. var deferred = $.Deferred();
  6533. fn(url, o, onSuccess, onError);
  6534. return deferred;
  6535. function onSuccess(resp) {
  6536. _.defer(function() {
  6537. deferred.resolve(resp);
  6538. });
  6539. }
  6540. function onError(err) {
  6541. _.defer(function() {
  6542. deferred.reject(err);
  6543. });
  6544. }
  6545. };
  6546. }
  6547. }();
  6548. var SearchIndex = function() {
  6549. "use strict";
  6550. function SearchIndex(o) {
  6551. o = o || {};
  6552. if (!o.datumTokenizer || !o.queryTokenizer) {
  6553. $.error("datumTokenizer and queryTokenizer are both required");
  6554. }
  6555. this.datumTokenizer = o.datumTokenizer;
  6556. this.queryTokenizer = o.queryTokenizer;
  6557. this.reset();
  6558. }
  6559. _.mixin(SearchIndex.prototype, {
  6560. bootstrap: function bootstrap(o) {
  6561. this.datums = o.datums;
  6562. this.trie = o.trie;
  6563. },
  6564. add: function(data) {
  6565. var that = this;
  6566. data = _.isArray(data) ? data : [ data ];
  6567. _.each(data, function(datum) {
  6568. var id, tokens;
  6569. id = that.datums.push(datum) - 1;
  6570. tokens = normalizeTokens(that.datumTokenizer(datum));
  6571. _.each(tokens, function(token) {
  6572. var node, chars, ch;
  6573. node = that.trie;
  6574. chars = token.split("");
  6575. while (ch = chars.shift()) {
  6576. node = node.children[ch] || (node.children[ch] = newNode());
  6577. node.ids.push(id);
  6578. }
  6579. });
  6580. });
  6581. },
  6582. get: function get(query) {
  6583. var that = this, tokens, matches;
  6584. tokens = normalizeTokens(this.queryTokenizer(query));
  6585. _.each(tokens, function(token) {
  6586. var node, chars, ch, ids;
  6587. if (matches && matches.length === 0) {
  6588. return false;
  6589. }
  6590. node = that.trie;
  6591. chars = token.split("");
  6592. while (node && (ch = chars.shift())) {
  6593. node = node.children[ch];
  6594. }
  6595. if (node && chars.length === 0) {
  6596. ids = node.ids.slice(0);
  6597. matches = matches ? getIntersection(matches, ids) : ids;
  6598. } else {
  6599. matches = [];
  6600. return false;
  6601. }
  6602. });
  6603. return matches ? _.map(unique(matches), function(id) {
  6604. return that.datums[id];
  6605. }) : [];
  6606. },
  6607. reset: function reset() {
  6608. this.datums = [];
  6609. this.trie = newNode();
  6610. },
  6611. serialize: function serialize() {
  6612. return {
  6613. datums: this.datums,
  6614. trie: this.trie
  6615. };
  6616. }
  6617. });
  6618. return SearchIndex;
  6619. function normalizeTokens(tokens) {
  6620. tokens = _.filter(tokens, function(token) {
  6621. return !!token;
  6622. });
  6623. tokens = _.map(tokens, function(token) {
  6624. return token.toLowerCase();
  6625. });
  6626. return tokens;
  6627. }
  6628. function newNode() {
  6629. return {
  6630. ids: [],
  6631. children: {}
  6632. };
  6633. }
  6634. function unique(array) {
  6635. var seen = {}, uniques = [];
  6636. for (var i = 0, len = array.length; i < len; i++) {
  6637. if (!seen[array[i]]) {
  6638. seen[array[i]] = true;
  6639. uniques.push(array[i]);
  6640. }
  6641. }
  6642. return uniques;
  6643. }
  6644. function getIntersection(arrayA, arrayB) {
  6645. var ai = 0, bi = 0, intersection = [];
  6646. arrayA = arrayA.sort(compare);
  6647. arrayB = arrayB.sort(compare);
  6648. var lenArrayA = arrayA.length, lenArrayB = arrayB.length;
  6649. while (ai < lenArrayA && bi < lenArrayB) {
  6650. if (arrayA[ai] < arrayB[bi]) {
  6651. ai++;
  6652. } else if (arrayA[ai] > arrayB[bi]) {
  6653. bi++;
  6654. } else {
  6655. intersection.push(arrayA[ai]);
  6656. ai++;
  6657. bi++;
  6658. }
  6659. }
  6660. return intersection;
  6661. function compare(a, b) {
  6662. return a - b;
  6663. }
  6664. }
  6665. }();
  6666. var oParser = function() {
  6667. "use strict";
  6668. return {
  6669. local: getLocal,
  6670. prefetch: getPrefetch,
  6671. remote: getRemote
  6672. };
  6673. function getLocal(o) {
  6674. return o.local || null;
  6675. }
  6676. function getPrefetch(o) {
  6677. var prefetch, defaults;
  6678. defaults = {
  6679. url: null,
  6680. thumbprint: "",
  6681. ttl: 24 * 60 * 60 * 1e3,
  6682. filter: null,
  6683. ajax: {}
  6684. };
  6685. if (prefetch = o.prefetch || null) {
  6686. prefetch = _.isString(prefetch) ? {
  6687. url: prefetch
  6688. } : prefetch;
  6689. prefetch = _.mixin(defaults, prefetch);
  6690. prefetch.thumbprint = VERSION + prefetch.thumbprint;
  6691. prefetch.ajax.type = prefetch.ajax.type || "GET";
  6692. prefetch.ajax.dataType = prefetch.ajax.dataType || "json";
  6693. !prefetch.url && $.error("prefetch requires url to be set");
  6694. }
  6695. return prefetch;
  6696. }
  6697. function getRemote(o) {
  6698. var remote, defaults;
  6699. defaults = {
  6700. url: null,
  6701. cache: true,
  6702. wildcard: "%QUERY",
  6703. replace: null,
  6704. rateLimitBy: "debounce",
  6705. rateLimitWait: 300,
  6706. send: null,
  6707. filter: null,
  6708. ajax: {}
  6709. };
  6710. if (remote = o.remote || null) {
  6711. remote = _.isString(remote) ? {
  6712. url: remote
  6713. } : remote;
  6714. remote = _.mixin(defaults, remote);
  6715. remote.rateLimiter = /^throttle$/i.test(remote.rateLimitBy) ? byThrottle(remote.rateLimitWait) : byDebounce(remote.rateLimitWait);
  6716. remote.ajax.type = remote.ajax.type || "GET";
  6717. remote.ajax.dataType = remote.ajax.dataType || "json";
  6718. delete remote.rateLimitBy;
  6719. delete remote.rateLimitWait;
  6720. !remote.url && $.error("remote requires url to be set");
  6721. }
  6722. return remote;
  6723. function byDebounce(wait) {
  6724. return function(fn) {
  6725. return _.debounce(fn, wait);
  6726. };
  6727. }
  6728. function byThrottle(wait) {
  6729. return function(fn) {
  6730. return _.throttle(fn, wait);
  6731. };
  6732. }
  6733. }
  6734. }();
  6735. (function(root) {
  6736. "use strict";
  6737. var old, keys;
  6738. old = root.Bloodhound;
  6739. keys = {
  6740. data: "data",
  6741. protocol: "protocol",
  6742. thumbprint: "thumbprint"
  6743. };
  6744. root.Bloodhound = Bloodhound;
  6745. function Bloodhound(o) {
  6746. if (!o || !o.local && !o.prefetch && !o.remote) {
  6747. $.error("one of local, prefetch, or remote is required");
  6748. }
  6749. this.limit = o.limit || 5;
  6750. this.sorter = getSorter(o.sorter);
  6751. this.dupDetector = o.dupDetector || ignoreDuplicates;
  6752. this.local = oParser.local(o);
  6753. this.prefetch = oParser.prefetch(o);
  6754. this.remote = oParser.remote(o);
  6755. this.cacheKey = this.prefetch ? this.prefetch.cacheKey || this.prefetch.url : null;
  6756. this.index = new SearchIndex({
  6757. datumTokenizer: o.datumTokenizer,
  6758. queryTokenizer: o.queryTokenizer
  6759. });
  6760. this.storage = this.cacheKey ? new PersistentStorage(this.cacheKey) : null;
  6761. }
  6762. Bloodhound.noConflict = function noConflict() {
  6763. root.Bloodhound = old;
  6764. return Bloodhound;
  6765. };
  6766. Bloodhound.tokenizers = tokenizers;
  6767. _.mixin(Bloodhound.prototype, {
  6768. _loadPrefetch: function loadPrefetch(o) {
  6769. var that = this, serialized, deferred;
  6770. if (serialized = this._readFromStorage(o.thumbprint)) {
  6771. this.index.bootstrap(serialized);
  6772. deferred = $.Deferred().resolve();
  6773. } else {
  6774. deferred = $.ajax(o.url, o.ajax).done(handlePrefetchResponse);
  6775. }
  6776. return deferred;
  6777. function handlePrefetchResponse(resp) {
  6778. that.clear();
  6779. that.add(o.filter ? o.filter(resp) : resp);
  6780. that._saveToStorage(that.index.serialize(), o.thumbprint, o.ttl);
  6781. }
  6782. },
  6783. _getFromRemote: function getFromRemote(query, cb) {
  6784. var that = this, url, uriEncodedQuery;
  6785. if (!this.transport) {
  6786. return;
  6787. }
  6788. query = query || "";
  6789. uriEncodedQuery = encodeURIComponent(query);
  6790. url = this.remote.replace ? this.remote.replace(this.remote.url, query) : this.remote.url.replace(this.remote.wildcard, uriEncodedQuery);
  6791. return this.transport.get(url, this.remote.ajax, handleRemoteResponse);
  6792. function handleRemoteResponse(err, resp) {
  6793. err ? cb([]) : cb(that.remote.filter ? that.remote.filter(resp) : resp);
  6794. }
  6795. },
  6796. _cancelLastRemoteRequest: function cancelLastRemoteRequest() {
  6797. this.transport && this.transport.cancel();
  6798. },
  6799. _saveToStorage: function saveToStorage(data, thumbprint, ttl) {
  6800. if (this.storage) {
  6801. this.storage.set(keys.data, data, ttl);
  6802. this.storage.set(keys.protocol, location.protocol, ttl);
  6803. this.storage.set(keys.thumbprint, thumbprint, ttl);
  6804. }
  6805. },
  6806. _readFromStorage: function readFromStorage(thumbprint) {
  6807. var stored = {}, isExpired;
  6808. if (this.storage) {
  6809. stored.data = this.storage.get(keys.data);
  6810. stored.protocol = this.storage.get(keys.protocol);
  6811. stored.thumbprint = this.storage.get(keys.thumbprint);
  6812. }
  6813. isExpired = stored.thumbprint !== thumbprint || stored.protocol !== location.protocol;
  6814. return stored.data && !isExpired ? stored.data : null;
  6815. },
  6816. _initialize: function initialize() {
  6817. var that = this, local = this.local, deferred;
  6818. deferred = this.prefetch ? this._loadPrefetch(this.prefetch) : $.Deferred().resolve();
  6819. local && deferred.done(addLocalToIndex);
  6820. this.transport = this.remote ? new Transport(this.remote) : null;
  6821. return this.initPromise = deferred.promise();
  6822. function addLocalToIndex() {
  6823. that.add(_.isFunction(local) ? local() : local);
  6824. }
  6825. },
  6826. initialize: function initialize(force) {
  6827. return !this.initPromise || force ? this._initialize() : this.initPromise;
  6828. },
  6829. add: function add(data) {
  6830. this.index.add(data);
  6831. },
  6832. get: function get(query, cb) {
  6833. var that = this, matches = [], cacheHit = false;
  6834. matches = this.index.get(query);
  6835. matches = this.sorter(matches).slice(0, this.limit);
  6836. matches.length < this.limit ? cacheHit = this._getFromRemote(query, returnRemoteMatches) : this._cancelLastRemoteRequest();
  6837. if (!cacheHit) {
  6838. (matches.length > 0 || !this.transport) && cb && cb(matches);
  6839. }
  6840. function returnRemoteMatches(remoteMatches) {
  6841. var matchesWithBackfill = matches.slice(0);
  6842. _.each(remoteMatches, function(remoteMatch) {
  6843. var isDuplicate;
  6844. isDuplicate = _.some(matchesWithBackfill, function(match) {
  6845. return that.dupDetector(remoteMatch, match);
  6846. });
  6847. !isDuplicate && matchesWithBackfill.push(remoteMatch);
  6848. return matchesWithBackfill.length < that.limit;
  6849. });
  6850. cb && cb(that.sorter(matchesWithBackfill));
  6851. }
  6852. },
  6853. clear: function clear() {
  6854. this.index.reset();
  6855. },
  6856. clearPrefetchCache: function clearPrefetchCache() {
  6857. this.storage && this.storage.clear();
  6858. },
  6859. clearRemoteCache: function clearRemoteCache() {
  6860. this.transport && Transport.resetCache();
  6861. },
  6862. ttAdapter: function ttAdapter() {
  6863. return _.bind(this.get, this);
  6864. }
  6865. });
  6866. return Bloodhound;
  6867. function getSorter(sortFn) {
  6868. return _.isFunction(sortFn) ? sort : noSort;
  6869. function sort(array) {
  6870. return array.sort(sortFn);
  6871. }
  6872. function noSort(array) {
  6873. return array;
  6874. }
  6875. }
  6876. function ignoreDuplicates() {
  6877. return false;
  6878. }
  6879. })(this);
  6880. var html = function() {
  6881. return {
  6882. wrapper: '<span class="twitter-typeahead"></span>',
  6883. dropdown: '<span class="tt-dropdown-menu"></span>',
  6884. dataset: '<div class="tt-dataset-%CLASS%"></div>',
  6885. suggestions: '<span class="tt-suggestions"></span>',
  6886. suggestion: '<div class="tt-suggestion"></div>'
  6887. };
  6888. }();
  6889. var css = function() {
  6890. "use strict";
  6891. var css = {
  6892. wrapper: {
  6893. position: "relative",
  6894. display: "inline-block"
  6895. },
  6896. hint: {
  6897. position: "absolute",
  6898. top: "0",
  6899. left: "0",
  6900. borderColor: "transparent",
  6901. boxShadow: "none",
  6902. opacity: "1"
  6903. },
  6904. input: {
  6905. position: "relative",
  6906. verticalAlign: "top",
  6907. backgroundColor: "transparent"
  6908. },
  6909. inputWithNoHint: {
  6910. position: "relative",
  6911. verticalAlign: "top"
  6912. },
  6913. dropdown: {
  6914. position: "absolute",
  6915. top: "100%",
  6916. left: "0",
  6917. zIndex: "100",
  6918. display: "none"
  6919. },
  6920. suggestions: {
  6921. display: "block"
  6922. },
  6923. suggestion: {
  6924. whiteSpace: "nowrap",
  6925. cursor: "pointer"
  6926. },
  6927. suggestionChild: {
  6928. whiteSpace: "normal"
  6929. },
  6930. ltr: {
  6931. left: "0",
  6932. right: "auto"
  6933. },
  6934. rtl: {
  6935. left: "auto",
  6936. right: " 0"
  6937. }
  6938. };
  6939. if (_.isMsie()) {
  6940. _.mixin(css.input, {
  6941. backgroundImage: "url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"
  6942. });
  6943. }
  6944. if (_.isMsie() && _.isMsie() <= 7) {
  6945. _.mixin(css.input, {
  6946. marginTop: "-1px"
  6947. });
  6948. }
  6949. return css;
  6950. }();
  6951. var EventBus = function() {
  6952. "use strict";
  6953. var namespace = "typeahead:";
  6954. function EventBus(o) {
  6955. if (!o || !o.el) {
  6956. $.error("EventBus initialized without el");
  6957. }
  6958. this.$el = $(o.el);
  6959. }
  6960. _.mixin(EventBus.prototype, {
  6961. trigger: function(type) {
  6962. var args = [].slice.call(arguments, 1);
  6963. this.$el.trigger(namespace + type, args);
  6964. }
  6965. });
  6966. return EventBus;
  6967. }();
  6968. var EventEmitter = function() {
  6969. "use strict";
  6970. var splitter = /\s+/, nextTick = getNextTick();
  6971. return {
  6972. onSync: onSync,
  6973. onAsync: onAsync,
  6974. off: off,
  6975. trigger: trigger
  6976. };
  6977. function on(method, types, cb, context) {
  6978. var type;
  6979. if (!cb) {
  6980. return this;
  6981. }
  6982. types = types.split(splitter);
  6983. cb = context ? bindContext(cb, context) : cb;
  6984. this._callbacks = this._callbacks || {};
  6985. while (type = types.shift()) {
  6986. this._callbacks[type] = this._callbacks[type] || {
  6987. sync: [],
  6988. async: []
  6989. };
  6990. this._callbacks[type][method].push(cb);
  6991. }
  6992. return this;
  6993. }
  6994. function onAsync(types, cb, context) {
  6995. return on.call(this, "async", types, cb, context);
  6996. }
  6997. function onSync(types, cb, context) {
  6998. return on.call(this, "sync", types, cb, context);
  6999. }
  7000. function off(types) {
  7001. var type;
  7002. if (!this._callbacks) {
  7003. return this;
  7004. }
  7005. types = types.split(splitter);
  7006. while (type = types.shift()) {
  7007. delete this._callbacks[type];
  7008. }
  7009. return this;
  7010. }
  7011. function trigger(types) {
  7012. var type, callbacks, args, syncFlush, asyncFlush;
  7013. if (!this._callbacks) {
  7014. return this;
  7015. }
  7016. types = types.split(splitter);
  7017. args = [].slice.call(arguments, 1);
  7018. while ((type = types.shift()) && (callbacks = this._callbacks[type])) {
  7019. syncFlush = getFlush(callbacks.sync, this, [ type ].concat(args));
  7020. asyncFlush = getFlush(callbacks.async, this, [ type ].concat(args));
  7021. syncFlush() && nextTick(asyncFlush);
  7022. }
  7023. return this;
  7024. }
  7025. function getFlush(callbacks, context, args) {
  7026. return flush;
  7027. function flush() {
  7028. var cancelled;
  7029. for (var i = 0, len = callbacks.length; !cancelled && i < len; i += 1) {
  7030. cancelled = callbacks[i].apply(context, args) === false;
  7031. }
  7032. return !cancelled;
  7033. }
  7034. }
  7035. function getNextTick() {
  7036. var nextTickFn;
  7037. if (window.setImmediate) {
  7038. nextTickFn = function nextTickSetImmediate(fn) {
  7039. setImmediate(function() {
  7040. fn();
  7041. });
  7042. };
  7043. } else {
  7044. nextTickFn = function nextTickSetTimeout(fn) {
  7045. setTimeout(function() {
  7046. fn();
  7047. }, 0);
  7048. };
  7049. }
  7050. return nextTickFn;
  7051. }
  7052. function bindContext(fn, context) {
  7053. return fn.bind ? fn.bind(context) : function() {
  7054. fn.apply(context, [].slice.call(arguments, 0));
  7055. };
  7056. }
  7057. }();
  7058. var highlight = function(doc) {
  7059. "use strict";
  7060. var defaults = {
  7061. node: null,
  7062. pattern: null,
  7063. tagName: "strong",
  7064. className: null,
  7065. wordsOnly: false,
  7066. caseSensitive: false
  7067. };
  7068. return function hightlight(o) {
  7069. var regex;
  7070. o = _.mixin({}, defaults, o);
  7071. if (!o.node || !o.pattern) {
  7072. return;
  7073. }
  7074. o.pattern = _.isArray(o.pattern) ? o.pattern : [ o.pattern ];
  7075. regex = getRegex(o.pattern, o.caseSensitive, o.wordsOnly);
  7076. traverse(o.node, hightlightTextNode);
  7077. function hightlightTextNode(textNode) {
  7078. var match, patternNode, wrapperNode;
  7079. if (match = regex.exec(textNode.data)) {
  7080. wrapperNode = doc.createElement(o.tagName);
  7081. o.className && (wrapperNode.className = o.className);
  7082. patternNode = textNode.splitText(match.index);
  7083. patternNode.splitText(match[0].length);
  7084. wrapperNode.appendChild(patternNode.cloneNode(true));
  7085. textNode.parentNode.replaceChild(wrapperNode, patternNode);
  7086. }
  7087. return !!match;
  7088. }
  7089. function traverse(el, hightlightTextNode) {
  7090. var childNode, TEXT_NODE_TYPE = 3;
  7091. for (var i = 0; i < el.childNodes.length; i++) {
  7092. childNode = el.childNodes[i];
  7093. if (childNode.nodeType === TEXT_NODE_TYPE) {
  7094. i += hightlightTextNode(childNode) ? 1 : 0;
  7095. } else {
  7096. traverse(childNode, hightlightTextNode);
  7097. }
  7098. }
  7099. }
  7100. };
  7101. function getRegex(patterns, caseSensitive, wordsOnly) {
  7102. var escapedPatterns = [], regexStr;
  7103. for (var i = 0, len = patterns.length; i < len; i++) {
  7104. escapedPatterns.push(_.escapeRegExChars(patterns[i]));
  7105. }
  7106. regexStr = wordsOnly ? "\\b(" + escapedPatterns.join("|") + ")\\b" : "(" + escapedPatterns.join("|") + ")";
  7107. return caseSensitive ? new RegExp(regexStr) : new RegExp(regexStr, "i");
  7108. }
  7109. }(window.document);
  7110. var Input = function() {
  7111. "use strict";
  7112. var specialKeyCodeMap;
  7113. specialKeyCodeMap = {
  7114. 9: "tab",
  7115. 27: "esc",
  7116. 37: "left",
  7117. 39: "right",
  7118. 13: "enter",
  7119. 38: "up",
  7120. 40: "down"
  7121. };
  7122. function Input(o) {
  7123. var that = this, onBlur, onFocus, onKeydown, onInput;
  7124. o = o || {};
  7125. if (!o.input) {
  7126. $.error("input is missing");
  7127. }
  7128. onBlur = _.bind(this._onBlur, this);
  7129. onFocus = _.bind(this._onFocus, this);
  7130. onKeydown = _.bind(this._onKeydown, this);
  7131. onInput = _.bind(this._onInput, this);
  7132. this.$hint = $(o.hint);
  7133. this.$input = $(o.input).on("blur.tt", onBlur).on("focus.tt", onFocus).on("keydown.tt", onKeydown);
  7134. if (this.$hint.length === 0) {
  7135. this.setHint = this.getHint = this.clearHint = this.clearHintIfInvalid = _.noop;
  7136. }
  7137. if (!_.isMsie()) {
  7138. this.$input.on("input.tt", onInput);
  7139. } else {
  7140. this.$input.on("keydown.tt keypress.tt cut.tt paste.tt", function($e) {
  7141. if (specialKeyCodeMap[$e.which || $e.keyCode]) {
  7142. return;
  7143. }
  7144. _.defer(_.bind(that._onInput, that, $e));
  7145. });
  7146. }
  7147. this.query = this.$input.val();
  7148. this.$overflowHelper = buildOverflowHelper(this.$input);
  7149. }
  7150. Input.normalizeQuery = function(str) {
  7151. return (str || "").replace(/^\s*/g, "").replace(/\s{2,}/g, " ");
  7152. };
  7153. _.mixin(Input.prototype, EventEmitter, {
  7154. _onBlur: function onBlur() {
  7155. this.resetInputValue();
  7156. this.trigger("blurred");
  7157. },
  7158. _onFocus: function onFocus() {
  7159. this.trigger("focused");
  7160. },
  7161. _onKeydown: function onKeydown($e) {
  7162. var keyName = specialKeyCodeMap[$e.which || $e.keyCode];
  7163. this._managePreventDefault(keyName, $e);
  7164. if (keyName && this._shouldTrigger(keyName, $e)) {
  7165. this.trigger(keyName + "Keyed", $e);
  7166. }
  7167. },
  7168. _onInput: function onInput() {
  7169. this._checkInputValue();
  7170. },
  7171. _managePreventDefault: function managePreventDefault(keyName, $e) {
  7172. var preventDefault, hintValue, inputValue;
  7173. switch (keyName) {
  7174. case "tab":
  7175. hintValue = this.getHint();
  7176. inputValue = this.getInputValue();
  7177. preventDefault = hintValue && hintValue !== inputValue && !withModifier($e);
  7178. break;
  7179. case "up":
  7180. case "down":
  7181. preventDefault = !withModifier($e);
  7182. break;
  7183. default:
  7184. preventDefault = false;
  7185. }
  7186. preventDefault && $e.preventDefault();
  7187. },
  7188. _shouldTrigger: function shouldTrigger(keyName, $e) {
  7189. var trigger;
  7190. switch (keyName) {
  7191. case "tab":
  7192. trigger = !withModifier($e);
  7193. break;
  7194. default:
  7195. trigger = true;
  7196. }
  7197. return trigger;
  7198. },
  7199. _checkInputValue: function checkInputValue() {
  7200. var inputValue, areEquivalent, hasDifferentWhitespace;
  7201. inputValue = this.getInputValue();
  7202. areEquivalent = areQueriesEquivalent(inputValue, this.query);
  7203. hasDifferentWhitespace = areEquivalent ? this.query.length !== inputValue.length : false;
  7204. this.query = inputValue;
  7205. if (!areEquivalent) {
  7206. this.trigger("queryChanged", this.query);
  7207. } else if (hasDifferentWhitespace) {
  7208. this.trigger("whitespaceChanged", this.query);
  7209. }
  7210. },
  7211. focus: function focus() {
  7212. this.$input.focus();
  7213. },
  7214. blur: function blur() {
  7215. this.$input.blur();
  7216. },
  7217. getQuery: function getQuery() {
  7218. return this.query;
  7219. },
  7220. setQuery: function setQuery(query) {
  7221. this.query = query;
  7222. },
  7223. getInputValue: function getInputValue() {
  7224. return this.$input.val();
  7225. },
  7226. setInputValue: function setInputValue(value, silent) {
  7227. this.$input.val(value);
  7228. silent ? this.clearHint() : this._checkInputValue();
  7229. },
  7230. resetInputValue: function resetInputValue() {
  7231. this.setInputValue(this.query, true);
  7232. },
  7233. getHint: function getHint() {
  7234. return this.$hint.val();
  7235. },
  7236. setHint: function setHint(value) {
  7237. this.$hint.val(value);
  7238. },
  7239. clearHint: function clearHint() {
  7240. this.setHint("");
  7241. },
  7242. clearHintIfInvalid: function clearHintIfInvalid() {
  7243. var val, hint, valIsPrefixOfHint, isValid;
  7244. val = this.getInputValue();
  7245. hint = this.getHint();
  7246. valIsPrefixOfHint = val !== hint && hint.indexOf(val) === 0;
  7247. isValid = val !== "" && valIsPrefixOfHint && !this.hasOverflow();
  7248. !isValid && this.clearHint();
  7249. },
  7250. getLanguageDirection: function getLanguageDirection() {
  7251. return (this.$input.css("direction") || "ltr").toLowerCase();
  7252. },
  7253. hasOverflow: function hasOverflow() {
  7254. var constraint = this.$input.width() - 2;
  7255. this.$overflowHelper.text(this.getInputValue());
  7256. return this.$overflowHelper.width() >= constraint;
  7257. },
  7258. isCursorAtEnd: function() {
  7259. var valueLength, selectionStart, range;
  7260. valueLength = this.$input.val().length;
  7261. selectionStart = this.$input[0].selectionStart;
  7262. if (_.isNumber(selectionStart)) {
  7263. return selectionStart === valueLength;
  7264. } else if (document.selection) {
  7265. range = document.selection.createRange();
  7266. range.moveStart("character", -valueLength);
  7267. return valueLength === range.text.length;
  7268. }
  7269. return true;
  7270. },
  7271. destroy: function destroy() {
  7272. this.$hint.off(".tt");
  7273. this.$input.off(".tt");
  7274. this.$hint = this.$input = this.$overflowHelper = null;
  7275. }
  7276. });
  7277. return Input;
  7278. function buildOverflowHelper($input) {
  7279. return $('<pre aria-hidden="true"></pre>').css({
  7280. position: "absolute",
  7281. visibility: "hidden",
  7282. whiteSpace: "pre",
  7283. fontFamily: $input.css("font-family"),
  7284. fontSize: $input.css("font-size"),
  7285. fontStyle: $input.css("font-style"),
  7286. fontVariant: $input.css("font-variant"),
  7287. fontWeight: $input.css("font-weight"),
  7288. wordSpacing: $input.css("word-spacing"),
  7289. letterSpacing: $input.css("letter-spacing"),
  7290. textIndent: $input.css("text-indent"),
  7291. textRendering: $input.css("text-rendering"),
  7292. textTransform: $input.css("text-transform")
  7293. }).insertAfter($input);
  7294. }
  7295. function areQueriesEquivalent(a, b) {
  7296. return Input.normalizeQuery(a) === Input.normalizeQuery(b);
  7297. }
  7298. function withModifier($e) {
  7299. return $e.altKey || $e.ctrlKey || $e.metaKey || $e.shiftKey;
  7300. }
  7301. }();
  7302. var Dataset = function() {
  7303. "use strict";
  7304. var datasetKey = "ttDataset", valueKey = "ttValue", datumKey = "ttDatum";
  7305. function Dataset(o) {
  7306. o = o || {};
  7307. o.templates = o.templates || {};
  7308. if (!o.source) {
  7309. $.error("missing source");
  7310. }
  7311. if (o.name && !isValidName(o.name)) {
  7312. $.error("invalid dataset name: " + o.name);
  7313. }
  7314. this.query = null;
  7315. this.highlight = !!o.highlight;
  7316. this.name = o.name || _.getUniqueId();
  7317. this.source = o.source;
  7318. this.displayFn = getDisplayFn(o.display || o.displayKey);
  7319. this.templates = getTemplates(o.templates, this.displayFn);
  7320. this.$el = $(html.dataset.replace("%CLASS%", this.name));
  7321. }
  7322. Dataset.extractDatasetName = function extractDatasetName(el) {
  7323. return $(el).data(datasetKey);
  7324. };
  7325. Dataset.extractValue = function extractDatum(el) {
  7326. return $(el).data(valueKey);
  7327. };
  7328. Dataset.extractDatum = function extractDatum(el) {
  7329. return $(el).data(datumKey);
  7330. };
  7331. _.mixin(Dataset.prototype, EventEmitter, {
  7332. _render: function render(query, suggestions) {
  7333. if (!this.$el) {
  7334. return;
  7335. }
  7336. var that = this, hasSuggestions;
  7337. this.$el.empty();
  7338. hasSuggestions = suggestions && suggestions.length;
  7339. if (!hasSuggestions && this.templates.empty) {
  7340. this.$el.html(getEmptyHtml()).prepend(that.templates.header ? getHeaderHtml() : null).append(that.templates.footer ? getFooterHtml() : null);
  7341. } else if (hasSuggestions) {
  7342. this.$el.html(getSuggestionsHtml()).prepend(that.templates.header ? getHeaderHtml() : null).append(that.templates.footer ? getFooterHtml() : null);
  7343. }
  7344. this.trigger("rendered");
  7345. function getEmptyHtml() {
  7346. return that.templates.empty({
  7347. query: query,
  7348. isEmpty: true
  7349. });
  7350. }
  7351. function getSuggestionsHtml() {
  7352. var $suggestions, nodes;
  7353. $suggestions = $(html.suggestions).css(css.suggestions);
  7354. nodes = _.map(suggestions, getSuggestionNode);
  7355. $suggestions.append.apply($suggestions, nodes);
  7356. that.highlight && highlight({
  7357. className: "tt-highlight",
  7358. node: $suggestions[0],
  7359. pattern: query
  7360. });
  7361. return $suggestions;
  7362. function getSuggestionNode(suggestion) {
  7363. var $el;
  7364. $el = $(html.suggestion).append(that.templates.suggestion(suggestion)).data(datasetKey, that.name).data(valueKey, that.displayFn(suggestion)).data(datumKey, suggestion);
  7365. $el.children().each(function() {
  7366. $(this).css(css.suggestionChild);
  7367. });
  7368. return $el;
  7369. }
  7370. }
  7371. function getHeaderHtml() {
  7372. return that.templates.header({
  7373. query: query,
  7374. isEmpty: !hasSuggestions
  7375. });
  7376. }
  7377. function getFooterHtml() {
  7378. return that.templates.footer({
  7379. query: query,
  7380. isEmpty: !hasSuggestions
  7381. });
  7382. }
  7383. },
  7384. getRoot: function getRoot() {
  7385. return this.$el;
  7386. },
  7387. update: function update(query) {
  7388. var that = this;
  7389. this.query = query;
  7390. this.canceled = false;
  7391. this.source(query, render);
  7392. function render(suggestions) {
  7393. if (!that.canceled && query === that.query) {
  7394. that._render(query, suggestions);
  7395. }
  7396. }
  7397. },
  7398. cancel: function cancel() {
  7399. this.canceled = true;
  7400. },
  7401. clear: function clear() {
  7402. this.cancel();
  7403. this.$el.empty();
  7404. this.trigger("rendered");
  7405. },
  7406. isEmpty: function isEmpty() {
  7407. return this.$el.is(":empty");
  7408. },
  7409. destroy: function destroy() {
  7410. this.$el = null;
  7411. }
  7412. });
  7413. return Dataset;
  7414. function getDisplayFn(display) {
  7415. display = display || "value";
  7416. return _.isFunction(display) ? display : displayFn;
  7417. function displayFn(obj) {
  7418. return obj[display];
  7419. }
  7420. }
  7421. function getTemplates(templates, displayFn) {
  7422. return {
  7423. empty: templates.empty && _.templatify(templates.empty),
  7424. header: templates.header && _.templatify(templates.header),
  7425. footer: templates.footer && _.templatify(templates.footer),
  7426. suggestion: templates.suggestion || suggestionTemplate
  7427. };
  7428. function suggestionTemplate(context) {
  7429. return "<p>" + displayFn(context) + "</p>";
  7430. }
  7431. }
  7432. function isValidName(str) {
  7433. return /^[_a-zA-Z0-9-]+$/.test(str);
  7434. }
  7435. }();
  7436. var Dropdown = function() {
  7437. "use strict";
  7438. function Dropdown(o) {
  7439. var that = this, onSuggestionClick, onSuggestionMouseEnter, onSuggestionMouseLeave;
  7440. o = o || {};
  7441. if (!o.menu) {
  7442. $.error("menu is required");
  7443. }
  7444. this.isOpen = false;
  7445. this.isEmpty = true;
  7446. this.datasets = _.map(o.datasets, initializeDataset);
  7447. onSuggestionClick = _.bind(this._onSuggestionClick, this);
  7448. onSuggestionMouseEnter = _.bind(this._onSuggestionMouseEnter, this);
  7449. onSuggestionMouseLeave = _.bind(this._onSuggestionMouseLeave, this);
  7450. this.$menu = $(o.menu).on("click.tt", ".tt-suggestion", onSuggestionClick).on("mouseenter.tt", ".tt-suggestion", onSuggestionMouseEnter).on("mouseleave.tt", ".tt-suggestion", onSuggestionMouseLeave);
  7451. _.each(this.datasets, function(dataset) {
  7452. that.$menu.append(dataset.getRoot());
  7453. dataset.onSync("rendered", that._onRendered, that);
  7454. });
  7455. }
  7456. _.mixin(Dropdown.prototype, EventEmitter, {
  7457. _onSuggestionClick: function onSuggestionClick($e) {
  7458. this.trigger("suggestionClicked", $($e.currentTarget));
  7459. },
  7460. _onSuggestionMouseEnter: function onSuggestionMouseEnter($e) {
  7461. this._removeCursor();
  7462. this._setCursor($($e.currentTarget), true);
  7463. },
  7464. _onSuggestionMouseLeave: function onSuggestionMouseLeave() {
  7465. this._removeCursor();
  7466. },
  7467. _onRendered: function onRendered() {
  7468. this.isEmpty = _.every(this.datasets, isDatasetEmpty);
  7469. this.isEmpty ? this._hide() : this.isOpen && this._show();
  7470. this.trigger("datasetRendered");
  7471. function isDatasetEmpty(dataset) {
  7472. return dataset.isEmpty();
  7473. }
  7474. },
  7475. _hide: function() {
  7476. this.$menu.hide();
  7477. },
  7478. _show: function() {
  7479. this.$menu.css("display", "block");
  7480. },
  7481. _getSuggestions: function getSuggestions() {
  7482. return this.$menu.find(".tt-suggestion");
  7483. },
  7484. _getCursor: function getCursor() {
  7485. return this.$menu.find(".tt-cursor").first();
  7486. },
  7487. _setCursor: function setCursor($el, silent) {
  7488. $el.first().addClass("tt-cursor");
  7489. !silent && this.trigger("cursorMoved");
  7490. },
  7491. _removeCursor: function removeCursor() {
  7492. this._getCursor().removeClass("tt-cursor");
  7493. },
  7494. _moveCursor: function moveCursor(increment) {
  7495. var $suggestions, $oldCursor, newCursorIndex, $newCursor;
  7496. if (!this.isOpen) {
  7497. return;
  7498. }
  7499. $oldCursor = this._getCursor();
  7500. $suggestions = this._getSuggestions();
  7501. this._removeCursor();
  7502. newCursorIndex = $suggestions.index($oldCursor) + increment;
  7503. newCursorIndex = (newCursorIndex + 1) % ($suggestions.length + 1) - 1;
  7504. if (newCursorIndex === -1) {
  7505. this.trigger("cursorRemoved");
  7506. return;
  7507. } else if (newCursorIndex < -1) {
  7508. newCursorIndex = $suggestions.length - 1;
  7509. }
  7510. this._setCursor($newCursor = $suggestions.eq(newCursorIndex));
  7511. this._ensureVisible($newCursor);
  7512. },
  7513. _ensureVisible: function ensureVisible($el) {
  7514. var elTop, elBottom, menuScrollTop, menuHeight;
  7515. elTop = $el.position().top;
  7516. elBottom = elTop + $el.outerHeight(true);
  7517. menuScrollTop = this.$menu.scrollTop();
  7518. menuHeight = this.$menu.height() + parseInt(this.$menu.css("paddingTop"), 10) + parseInt(this.$menu.css("paddingBottom"), 10);
  7519. if (elTop < 0) {
  7520. this.$menu.scrollTop(menuScrollTop + elTop);
  7521. } else if (menuHeight < elBottom) {
  7522. this.$menu.scrollTop(menuScrollTop + (elBottom - menuHeight));
  7523. }
  7524. },
  7525. close: function close() {
  7526. if (this.isOpen) {
  7527. this.isOpen = false;
  7528. this._removeCursor();
  7529. this._hide();
  7530. this.trigger("closed");
  7531. }
  7532. },
  7533. open: function open() {
  7534. if (!this.isOpen) {
  7535. this.isOpen = true;
  7536. !this.isEmpty && this._show();
  7537. this.trigger("opened");
  7538. }
  7539. },
  7540. setLanguageDirection: function setLanguageDirection(dir) {
  7541. this.$menu.css(dir === "ltr" ? css.ltr : css.rtl);
  7542. },
  7543. moveCursorUp: function moveCursorUp() {
  7544. this._moveCursor(-1);
  7545. },
  7546. moveCursorDown: function moveCursorDown() {
  7547. this._moveCursor(+1);
  7548. },
  7549. getDatumForSuggestion: function getDatumForSuggestion($el) {
  7550. var datum = null;
  7551. if ($el.length) {
  7552. datum = {
  7553. raw: Dataset.extractDatum($el),
  7554. value: Dataset.extractValue($el),
  7555. datasetName: Dataset.extractDatasetName($el)
  7556. };
  7557. }
  7558. return datum;
  7559. },
  7560. getDatumForCursor: function getDatumForCursor() {
  7561. return this.getDatumForSuggestion(this._getCursor().first());
  7562. },
  7563. getDatumForTopSuggestion: function getDatumForTopSuggestion() {
  7564. return this.getDatumForSuggestion(this._getSuggestions().first());
  7565. },
  7566. update: function update(query) {
  7567. _.each(this.datasets, updateDataset);
  7568. function updateDataset(dataset) {
  7569. dataset.update(query);
  7570. }
  7571. },
  7572. empty: function empty() {
  7573. _.each(this.datasets, clearDataset);
  7574. this.isEmpty = true;
  7575. function clearDataset(dataset) {
  7576. dataset.clear();
  7577. }
  7578. },
  7579. isVisible: function isVisible() {
  7580. return this.isOpen && !this.isEmpty;
  7581. },
  7582. destroy: function destroy() {
  7583. this.$menu.off(".tt");
  7584. this.$menu = null;
  7585. _.each(this.datasets, destroyDataset);
  7586. function destroyDataset(dataset) {
  7587. dataset.destroy();
  7588. }
  7589. }
  7590. });
  7591. return Dropdown;
  7592. function initializeDataset(oDataset) {
  7593. return new Dataset(oDataset);
  7594. }
  7595. }();
  7596. var Typeahead = function() {
  7597. "use strict";
  7598. var attrsKey = "ttAttrs";
  7599. function Typeahead(o) {
  7600. var $menu, $input, $hint;
  7601. o = o || {};
  7602. if (!o.input) {
  7603. $.error("missing input");
  7604. }
  7605. this.isActivated = false;
  7606. this.autoselect = !!o.autoselect;
  7607. this.minLength = _.isNumber(o.minLength) ? o.minLength : 1;
  7608. this.$node = buildDom(o.input, o.withHint);
  7609. $menu = this.$node.find(".tt-dropdown-menu");
  7610. $input = this.$node.find(".tt-input");
  7611. $hint = this.$node.find(".tt-hint");
  7612. $input.on("blur.tt", function($e) {
  7613. var active, isActive, hasActive;
  7614. active = document.activeElement;
  7615. isActive = $menu.is(active);
  7616. hasActive = $menu.has(active).length > 0;
  7617. if (_.isMsie() && (isActive || hasActive)) {
  7618. $e.preventDefault();
  7619. $e.stopImmediatePropagation();
  7620. _.defer(function() {
  7621. $input.focus();
  7622. });
  7623. }
  7624. });
  7625. $menu.on("mousedown.tt", function($e) {
  7626. $e.preventDefault();
  7627. });
  7628. this.eventBus = o.eventBus || new EventBus({
  7629. el: $input
  7630. });
  7631. this.dropdown = new Dropdown({
  7632. menu: $menu,
  7633. datasets: o.datasets
  7634. }).onSync("suggestionClicked", this._onSuggestionClicked, this).onSync("cursorMoved", this._onCursorMoved, this).onSync("cursorRemoved", this._onCursorRemoved, this).onSync("opened", this._onOpened, this).onSync("closed", this._onClosed, this).onAsync("datasetRendered", this._onDatasetRendered, this);
  7635. this.input = new Input({
  7636. input: $input,
  7637. hint: $hint
  7638. }).onSync("focused", this._onFocused, this).onSync("blurred", this._onBlurred, this).onSync("enterKeyed", this._onEnterKeyed, this).onSync("tabKeyed", this._onTabKeyed, this).onSync("escKeyed", this._onEscKeyed, this).onSync("upKeyed", this._onUpKeyed, this).onSync("downKeyed", this._onDownKeyed, this).onSync("leftKeyed", this._onLeftKeyed, this).onSync("rightKeyed", this._onRightKeyed, this).onSync("queryChanged", this._onQueryChanged, this).onSync("whitespaceChanged", this._onWhitespaceChanged, this);
  7639. this._setLanguageDirection();
  7640. }
  7641. _.mixin(Typeahead.prototype, {
  7642. _onSuggestionClicked: function onSuggestionClicked(type, $el) {
  7643. var datum;
  7644. if (datum = this.dropdown.getDatumForSuggestion($el)) {
  7645. this._select(datum);
  7646. }
  7647. },
  7648. _onCursorMoved: function onCursorMoved() {
  7649. var datum = this.dropdown.getDatumForCursor();
  7650. this.input.setInputValue(datum.value, true);
  7651. this.eventBus.trigger("cursorchanged", datum.raw, datum.datasetName);
  7652. },
  7653. _onCursorRemoved: function onCursorRemoved() {
  7654. this.input.resetInputValue();
  7655. this._updateHint();
  7656. },
  7657. _onDatasetRendered: function onDatasetRendered() {
  7658. this._updateHint();
  7659. },
  7660. _onOpened: function onOpened() {
  7661. this._updateHint();
  7662. this.eventBus.trigger("opened");
  7663. },
  7664. _onClosed: function onClosed() {
  7665. this.input.clearHint();
  7666. this.eventBus.trigger("closed");
  7667. },
  7668. _onFocused: function onFocused() {
  7669. this.isActivated = true;
  7670. this.dropdown.open();
  7671. },
  7672. _onBlurred: function onBlurred() {
  7673. this.isActivated = false;
  7674. this.dropdown.empty();
  7675. this.dropdown.close();
  7676. },
  7677. _onEnterKeyed: function onEnterKeyed(type, $e) {
  7678. var cursorDatum, topSuggestionDatum;
  7679. cursorDatum = this.dropdown.getDatumForCursor();
  7680. topSuggestionDatum = this.dropdown.getDatumForTopSuggestion();
  7681. if (cursorDatum) {
  7682. this._select(cursorDatum);
  7683. $e.preventDefault();
  7684. } else if (this.autoselect && topSuggestionDatum) {
  7685. this._select(topSuggestionDatum);
  7686. $e.preventDefault();
  7687. }
  7688. },
  7689. _onTabKeyed: function onTabKeyed(type, $e) {
  7690. var datum;
  7691. if (datum = this.dropdown.getDatumForCursor()) {
  7692. this._select(datum);
  7693. $e.preventDefault();
  7694. } else {
  7695. this._autocomplete(true);
  7696. }
  7697. },
  7698. _onEscKeyed: function onEscKeyed() {
  7699. this.dropdown.close();
  7700. this.input.resetInputValue();
  7701. },
  7702. _onUpKeyed: function onUpKeyed() {
  7703. var query = this.input.getQuery();
  7704. this.dropdown.isEmpty && query.length >= this.minLength ? this.dropdown.update(query) : this.dropdown.moveCursorUp();
  7705. this.dropdown.open();
  7706. },
  7707. _onDownKeyed: function onDownKeyed() {
  7708. var query = this.input.getQuery();
  7709. this.dropdown.isEmpty && query.length >= this.minLength ? this.dropdown.update(query) : this.dropdown.moveCursorDown();
  7710. this.dropdown.open();
  7711. },
  7712. _onLeftKeyed: function onLeftKeyed() {
  7713. this.dir === "rtl" && this._autocomplete();
  7714. },
  7715. _onRightKeyed: function onRightKeyed() {
  7716. this.dir === "ltr" && this._autocomplete();
  7717. },
  7718. _onQueryChanged: function onQueryChanged(e, query) {
  7719. this.input.clearHintIfInvalid();
  7720. query.length >= this.minLength ? this.dropdown.update(query) : this.dropdown.empty();
  7721. this.dropdown.open();
  7722. this._setLanguageDirection();
  7723. },
  7724. _onWhitespaceChanged: function onWhitespaceChanged() {
  7725. this._updateHint();
  7726. this.dropdown.open();
  7727. },
  7728. _setLanguageDirection: function setLanguageDirection() {
  7729. var dir;
  7730. if (this.dir !== (dir = this.input.getLanguageDirection())) {
  7731. this.dir = dir;
  7732. this.$node.css("direction", dir);
  7733. this.dropdown.setLanguageDirection(dir);
  7734. }
  7735. },
  7736. _updateHint: function updateHint() {
  7737. var datum, val, query, escapedQuery, frontMatchRegEx, match;
  7738. datum = this.dropdown.getDatumForTopSuggestion();
  7739. if (datum && this.dropdown.isVisible() && !this.input.hasOverflow()) {
  7740. val = this.input.getInputValue();
  7741. query = Input.normalizeQuery(val);
  7742. escapedQuery = _.escapeRegExChars(query);
  7743. frontMatchRegEx = new RegExp("^(?:" + escapedQuery + ")(.+$)", "i");
  7744. match = frontMatchRegEx.exec(datum.value);
  7745. match ? this.input.setHint(val + match[1]) : this.input.clearHint();
  7746. } else {
  7747. this.input.clearHint();
  7748. }
  7749. },
  7750. _autocomplete: function autocomplete(laxCursor) {
  7751. var hint, query, isCursorAtEnd, datum;
  7752. hint = this.input.getHint();
  7753. query = this.input.getQuery();
  7754. isCursorAtEnd = laxCursor || this.input.isCursorAtEnd();
  7755. if (hint && query !== hint && isCursorAtEnd) {
  7756. datum = this.dropdown.getDatumForTopSuggestion();
  7757. datum && this.input.setInputValue(datum.value);
  7758. this.eventBus.trigger("autocompleted", datum.raw, datum.datasetName);
  7759. }
  7760. },
  7761. _select: function select(datum) {
  7762. this.input.setQuery(datum.value);
  7763. this.input.setInputValue(datum.value, true);
  7764. this._setLanguageDirection();
  7765. this.eventBus.trigger("selected", datum.raw, datum.datasetName);
  7766. this.dropdown.close();
  7767. _.defer(_.bind(this.dropdown.empty, this.dropdown));
  7768. },
  7769. open: function open() {
  7770. this.dropdown.open();
  7771. },
  7772. close: function close() {
  7773. this.dropdown.close();
  7774. },
  7775. setVal: function setVal(val) {
  7776. val = _.toStr(val);
  7777. if (this.isActivated) {
  7778. this.input.setInputValue(val);
  7779. } else {
  7780. this.input.setQuery(val);
  7781. this.input.setInputValue(val, true);
  7782. }
  7783. this._setLanguageDirection();
  7784. },
  7785. getVal: function getVal() {
  7786. return this.input.getQuery();
  7787. },
  7788. destroy: function destroy() {
  7789. this.input.destroy();
  7790. this.dropdown.destroy();
  7791. destroyDomStructure(this.$node);
  7792. this.$node = null;
  7793. }
  7794. });
  7795. return Typeahead;
  7796. function buildDom(input, withHint) {
  7797. var $input, $wrapper, $dropdown, $hint;
  7798. $input = $(input);
  7799. $wrapper = $(html.wrapper).css(css.wrapper);
  7800. $dropdown = $(html.dropdown).css(css.dropdown);
  7801. $hint = $input.clone().css(css.hint).css(getBackgroundStyles($input));
  7802. $hint.val("").removeData().addClass("tt-hint").removeAttr("id name placeholder required").prop("readonly", true).attr({
  7803. autocomplete: "off",
  7804. spellcheck: "false",
  7805. tabindex: -1
  7806. });
  7807. $input.data(attrsKey, {
  7808. dir: $input.attr("dir"),
  7809. autocomplete: $input.attr("autocomplete"),
  7810. spellcheck: $input.attr("spellcheck"),
  7811. style: $input.attr("style")
  7812. });
  7813. $input.addClass("tt-input").attr({
  7814. autocomplete: "off",
  7815. spellcheck: false
  7816. }).css(withHint ? css.input : css.inputWithNoHint);
  7817. try {
  7818. !$input.attr("dir") && $input.attr("dir", "auto");
  7819. } catch (e) {}
  7820. return $input.wrap($wrapper).parent().prepend(withHint ? $hint : null).append($dropdown);
  7821. }
  7822. function getBackgroundStyles($el) {
  7823. return {
  7824. backgroundAttachment: $el.css("background-attachment"),
  7825. backgroundClip: $el.css("background-clip"),
  7826. backgroundColor: $el.css("background-color"),
  7827. backgroundImage: $el.css("background-image"),
  7828. backgroundOrigin: $el.css("background-origin"),
  7829. backgroundPosition: $el.css("background-position"),
  7830. backgroundRepeat: $el.css("background-repeat"),
  7831. backgroundSize: $el.css("background-size")
  7832. };
  7833. }
  7834. function destroyDomStructure($node) {
  7835. var $input = $node.find(".tt-input");
  7836. _.each($input.data(attrsKey), function(val, key) {
  7837. _.isUndefined(val) ? $input.removeAttr(key) : $input.attr(key, val);
  7838. });
  7839. $input.detach().removeData(attrsKey).removeClass("tt-input").insertAfter($node);
  7840. $node.remove();
  7841. }
  7842. }();
  7843. (function() {
  7844. "use strict";
  7845. var old, typeaheadKey, methods;
  7846. old = $.fn.typeahead;
  7847. typeaheadKey = "ttTypeahead";
  7848. methods = {
  7849. initialize: function initialize(o, datasets) {
  7850. datasets = _.isArray(datasets) ? datasets : [].slice.call(arguments, 1);
  7851. o = o || {};
  7852. return this.each(attach);
  7853. function attach() {
  7854. var $input = $(this), eventBus, typeahead;
  7855. _.each(datasets, function(d) {
  7856. d.highlight = !!o.highlight;
  7857. });
  7858. typeahead = new Typeahead({
  7859. input: $input,
  7860. eventBus: eventBus = new EventBus({
  7861. el: $input
  7862. }),
  7863. withHint: _.isUndefined(o.hint) ? true : !!o.hint,
  7864. minLength: o.minLength,
  7865. autoselect: o.autoselect,
  7866. datasets: datasets
  7867. });
  7868. $input.data(typeaheadKey, typeahead);
  7869. }
  7870. },
  7871. open: function open() {
  7872. return this.each(openTypeahead);
  7873. function openTypeahead() {
  7874. var $input = $(this), typeahead;
  7875. if (typeahead = $input.data(typeaheadKey)) {
  7876. typeahead.open();
  7877. }
  7878. }
  7879. },
  7880. close: function close() {
  7881. return this.each(closeTypeahead);
  7882. function closeTypeahead() {
  7883. var $input = $(this), typeahead;
  7884. if (typeahead = $input.data(typeaheadKey)) {
  7885. typeahead.close();
  7886. }
  7887. }
  7888. },
  7889. val: function val(newVal) {
  7890. return !arguments.length ? getVal(this.first()) : this.each(setVal);
  7891. function setVal() {
  7892. var $input = $(this), typeahead;
  7893. if (typeahead = $input.data(typeaheadKey)) {
  7894. typeahead.setVal(newVal);
  7895. }
  7896. }
  7897. function getVal($input) {
  7898. var typeahead, query;
  7899. if (typeahead = $input.data(typeaheadKey)) {
  7900. query = typeahead.getVal();
  7901. }
  7902. return query;
  7903. }
  7904. },
  7905. destroy: function destroy() {
  7906. return this.each(unattach);
  7907. function unattach() {
  7908. var $input = $(this), typeahead;
  7909. if (typeahead = $input.data(typeaheadKey)) {
  7910. typeahead.destroy();
  7911. $input.removeData(typeaheadKey);
  7912. }
  7913. }
  7914. }
  7915. };
  7916. $.fn.typeahead = function(method) {
  7917. var tts;
  7918. if (methods[method] && method !== "initialize") {
  7919. tts = this.filter(function() {
  7920. return !!$(this).data(typeaheadKey);
  7921. });
  7922. return methods[method].apply(tts, [].slice.call(arguments, 1));
  7923. } else {
  7924. return methods.initialize.apply(this, arguments);
  7925. }
  7926. };
  7927. $.fn.typeahead.noConflict = function noConflict() {
  7928. $.fn.typeahead = old;
  7929. return this;
  7930. };
  7931. })();
  7932. })(window.jQuery);
  7933. /*
  7934. Copyright 2012 Igor Vaynberg
  7935. Version: 3.5.1 Timestamp: Tue Jul 22 18:58:56 EDT 2014
  7936. This software is licensed under the Apache License, Version 2.0 (the "Apache License") or the GNU
  7937. General Public License version 2 (the "GPL License"). You may choose either license to govern your
  7938. use of this software only upon the condition that you accept all of the terms of either the Apache
  7939. License or the GPL License.
  7940. You may obtain a copy of the Apache License and the GPL License at:
  7941. http://www.apache.org/licenses/LICENSE-2.0
  7942. http://www.gnu.org/licenses/gpl-2.0.html
  7943. Unless required by applicable law or agreed to in writing, software distributed under the
  7944. Apache License or the GPL License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  7945. CONDITIONS OF ANY KIND, either express or implied. See the Apache License and the GPL License for
  7946. the specific language governing permissions and limitations under the Apache License and the GPL License.
  7947. */
  7948. (function ($) {
  7949. if(typeof $.fn.each2 == "undefined") {
  7950. $.extend($.fn, {
  7951. /*
  7952. * 4-10 times faster .each replacement
  7953. * use it carefully, as it overrides jQuery context of element on each iteration
  7954. */
  7955. each2 : function (c) {
  7956. var j = $([0]), i = -1, l = this.length;
  7957. while (
  7958. ++i < l
  7959. && (j.context = j[0] = this[i])
  7960. && c.call(j[0], i, j) !== false //"this"=DOM, i=index, j=jQuery object
  7961. );
  7962. return this;
  7963. }
  7964. });
  7965. }
  7966. })(jQuery);
  7967. (function ($, undefined) {
  7968. "use strict";
  7969. /*global document, window, jQuery, console */
  7970. if (window.Select2 !== undefined) {
  7971. return;
  7972. }
  7973. var KEY, AbstractSelect2, SingleSelect2, MultiSelect2, nextUid, sizer,
  7974. lastMousePosition={x:0,y:0}, $document, scrollBarDimensions,
  7975. KEY = {
  7976. TAB: 9,
  7977. ENTER: 13,
  7978. ESC: 27,
  7979. SPACE: 32,
  7980. LEFT: 37,
  7981. UP: 38,
  7982. RIGHT: 39,
  7983. DOWN: 40,
  7984. SHIFT: 16,
  7985. CTRL: 17,
  7986. ALT: 18,
  7987. PAGE_UP: 33,
  7988. PAGE_DOWN: 34,
  7989. HOME: 36,
  7990. END: 35,
  7991. BACKSPACE: 8,
  7992. DELETE: 46,
  7993. isArrow: function (k) {
  7994. k = k.which ? k.which : k;
  7995. switch (k) {
  7996. case KEY.LEFT:
  7997. case KEY.RIGHT:
  7998. case KEY.UP:
  7999. case KEY.DOWN:
  8000. return true;
  8001. }
  8002. return false;
  8003. },
  8004. isControl: function (e) {
  8005. var k = e.which;
  8006. switch (k) {
  8007. case KEY.SHIFT:
  8008. case KEY.CTRL:
  8009. case KEY.ALT:
  8010. return true;
  8011. }
  8012. if (e.metaKey) return true;
  8013. return false;
  8014. },
  8015. isFunctionKey: function (k) {
  8016. k = k.which ? k.which : k;
  8017. return k >= 112 && k <= 123;
  8018. }
  8019. },
  8020. MEASURE_SCROLLBAR_TEMPLATE = "<div class='select2-measure-scrollbar'></div>",
  8021. DIACRITICS = {"\u24B6":"A","\uFF21":"A","\u00C0":"A","\u00C1":"A","\u00C2":"A","\u1EA6":"A","\u1EA4":"A","\u1EAA":"A","\u1EA8":"A","\u00C3":"A","\u0100":"A","\u0102":"A","\u1EB0":"A","\u1EAE":"A","\u1EB4":"A","\u1EB2":"A","\u0226":"A","\u01E0":"A","\u00C4":"A","\u01DE":"A","\u1EA2":"A","\u00C5":"A","\u01FA":"A","\u01CD":"A","\u0200":"A","\u0202":"A","\u1EA0":"A","\u1EAC":"A","\u1EB6":"A","\u1E00":"A","\u0104":"A","\u023A":"A","\u2C6F":"A","\uA732":"AA","\u00C6":"AE","\u01FC":"AE","\u01E2":"AE","\uA734":"AO","\uA736":"AU","\uA738":"AV","\uA73A":"AV","\uA73C":"AY","\u24B7":"B","\uFF22":"B","\u1E02":"B","\u1E04":"B","\u1E06":"B","\u0243":"B","\u0182":"B","\u0181":"B","\u24B8":"C","\uFF23":"C","\u0106":"C","\u0108":"C","\u010A":"C","\u010C":"C","\u00C7":"C","\u1E08":"C","\u0187":"C","\u023B":"C","\uA73E":"C","\u24B9":"D","\uFF24":"D","\u1E0A":"D","\u010E":"D","\u1E0C":"D","\u1E10":"D","\u1E12":"D","\u1E0E":"D","\u0110":"D","\u018B":"D","\u018A":"D","\u0189":"D","\uA779":"D","\u01F1":"DZ","\u01C4":"DZ","\u01F2":"Dz","\u01C5":"Dz","\u24BA":"E","\uFF25":"E","\u00C8":"E","\u00C9":"E","\u00CA":"E","\u1EC0":"E","\u1EBE":"E","\u1EC4":"E","\u1EC2":"E","\u1EBC":"E","\u0112":"E","\u1E14":"E","\u1E16":"E","\u0114":"E","\u0116":"E","\u00CB":"E","\u1EBA":"E","\u011A":"E","\u0204":"E","\u0206":"E","\u1EB8":"E","\u1EC6":"E","\u0228":"E","\u1E1C":"E","\u0118":"E","\u1E18":"E","\u1E1A":"E","\u0190":"E","\u018E":"E","\u24BB":"F","\uFF26":"F","\u1E1E":"F","\u0191":"F","\uA77B":"F","\u24BC":"G","\uFF27":"G","\u01F4":"G","\u011C":"G","\u1E20":"G","\u011E":"G","\u0120":"G","\u01E6":"G","\u0122":"G","\u01E4":"G","\u0193":"G","\uA7A0":"G","\uA77D":"G","\uA77E":"G","\u24BD":"H","\uFF28":"H","\u0124":"H","\u1E22":"H","\u1E26":"H","\u021E":"H","\u1E24":"H","\u1E28":"H","\u1E2A":"H","\u0126":"H","\u2C67":"H","\u2C75":"H","\uA78D":"H","\u24BE":"I","\uFF29":"I","\u00CC":"I","\u00CD":"I","\u00CE":"I","\u0128":"I","\u012A":"I","\u012C":"I","\u0130":"I","\u00CF":"I","\u1E2E":"I","\u1EC8":"I","\u01CF":"I","\u0208":"I","\u020A":"I","\u1ECA":"I","\u012E":"I","\u1E2C":"I","\u0197":"I","\u24BF":"J","\uFF2A":"J","\u0134":"J","\u0248":"J","\u24C0":"K","\uFF2B":"K","\u1E30":"K","\u01E8":"K","\u1E32":"K","\u0136":"K","\u1E34":"K","\u0198":"K","\u2C69":"K","\uA740":"K","\uA742":"K","\uA744":"K","\uA7A2":"K","\u24C1":"L","\uFF2C":"L","\u013F":"L","\u0139":"L","\u013D":"L","\u1E36":"L","\u1E38":"L","\u013B":"L","\u1E3C":"L","\u1E3A":"L","\u0141":"L","\u023D":"L","\u2C62":"L","\u2C60":"L","\uA748":"L","\uA746":"L","\uA780":"L","\u01C7":"LJ","\u01C8":"Lj","\u24C2":"M","\uFF2D":"M","\u1E3E":"M","\u1E40":"M","\u1E42":"M","\u2C6E":"M","\u019C":"M","\u24C3":"N","\uFF2E":"N","\u01F8":"N","\u0143":"N","\u00D1":"N","\u1E44":"N","\u0147":"N","\u1E46":"N","\u0145":"N","\u1E4A":"N","\u1E48":"N","\u0220":"N","\u019D":"N","\uA790":"N","\uA7A4":"N","\u01CA":"NJ","\u01CB":"Nj","\u24C4":"O","\uFF2F":"O","\u00D2":"O","\u00D3":"O","\u00D4":"O","\u1ED2":"O","\u1ED0":"O","\u1ED6":"O","\u1ED4":"O","\u00D5":"O","\u1E4C":"O","\u022C":"O","\u1E4E":"O","\u014C":"O","\u1E50":"O","\u1E52":"O","\u014E":"O","\u022E":"O","\u0230":"O","\u00D6":"O","\u022A":"O","\u1ECE":"O","\u0150":"O","\u01D1":"O","\u020C":"O","\u020E":"O","\u01A0":"O","\u1EDC":"O","\u1EDA":"O","\u1EE0":"O","\u1EDE":"O","\u1EE2":"O","\u1ECC":"O","\u1ED8":"O","\u01EA":"O","\u01EC":"O","\u00D8":"O","\u01FE":"O","\u0186":"O","\u019F":"O","\uA74A":"O","\uA74C":"O","\u01A2":"OI","\uA74E":"OO","\u0222":"OU","\u24C5":"P","\uFF30":"P","\u1E54":"P","\u1E56":"P","\u01A4":"P","\u2C63":"P","\uA750":"P","\uA752":"P","\uA754":"P","\u24C6":"Q","\uFF31":"Q","\uA756":"Q","\uA758":"Q","\u024A":"Q","\u24C7":"R","\uFF32":"R","\u0154":"R","\u1E58":"R","\u0158":"R","\u0210":"R","\u0212":"R","\u1E5A":"R","\u1E5C":"R","\u0156":"R","\u1E5E":"R","\u024C":"R","\u2C64":"R","\uA75A":"R","\uA7A6":"R","\uA782":"R","\u24C8":"S","\uFF33":"S","\u1E9E":"S","\u015A":"S","\u1E64":"S","\u015C":"S","\u1E60":"S","\u0160":"S","\u1E66":"S","\u1E62":"S","\u1E68":"S","\u0218":"S","\u015E":"S","\u2C7E":"S","\uA7A8":"S","\uA784":"S","\u24C9":"T","\uFF34":"T","\u1E6A":"T","\u0164":"T","\u1E6C":"T","\u021A":"T","\u0162":"T","\u1E70":"T","\u1E6E":"T","\u0166":"T","\u01AC":"T","\u01AE":"T","\u023E":"T","\uA786":"T","\uA728":"TZ","\u24CA":"U","\uFF35":"U","\u00D9":"U","\u00DA":"U","\u00DB":"U","\u0168":"U","\u1E78":"U","\u016A":"U","\u1E7A":"U","\u016C":"U","\u00DC":"U","\u01DB":"U","\u01D7":"U","\u01D5":"U","\u01D9":"U","\u1EE6":"U","\u016E":"U","\u0170":"U","\u01D3":"U","\u0214":"U","\u0216":"U","\u01AF":"U","\u1EEA":"U","\u1EE8":"U","\u1EEE":"U","\u1EEC":"U","\u1EF0":"U","\u1EE4":"U","\u1E72":"U","\u0172":"U","\u1E76":"U","\u1E74":"U","\u0244":"U","\u24CB":"V","\uFF36":"V","\u1E7C":"V","\u1E7E":"V","\u01B2":"V","\uA75E":"V","\u0245":"V","\uA760":"VY","\u24CC":"W","\uFF37":"W","\u1E80":"W","\u1E82":"W","\u0174":"W","\u1E86":"W","\u1E84":"W","\u1E88":"W","\u2C72":"W","\u24CD":"X","\uFF38":"X","\u1E8A":"X","\u1E8C":"X","\u24CE":"Y","\uFF39":"Y","\u1EF2":"Y","\u00DD":"Y","\u0176":"Y","\u1EF8":"Y","\u0232":"Y","\u1E8E":"Y","\u0178":"Y","\u1EF6":"Y","\u1EF4":"Y","\u01B3":"Y","\u024E":"Y","\u1EFE":"Y","\u24CF":"Z","\uFF3A":"Z","\u0179":"Z","\u1E90":"Z","\u017B":"Z","\u017D":"Z","\u1E92":"Z","\u1E94":"Z","\u01B5":"Z","\u0224":"Z","\u2C7F":"Z","\u2C6B":"Z","\uA762":"Z","\u24D0":"a","\uFF41":"a","\u1E9A":"a","\u00E0":"a","\u00E1":"a","\u00E2":"a","\u1EA7":"a","\u1EA5":"a","\u1EAB":"a","\u1EA9":"a","\u00E3":"a","\u0101":"a","\u0103":"a","\u1EB1":"a","\u1EAF":"a","\u1EB5":"a","\u1EB3":"a","\u0227":"a","\u01E1":"a","\u00E4":"a","\u01DF":"a","\u1EA3":"a","\u00E5":"a","\u01FB":"a","\u01CE":"a","\u0201":"a","\u0203":"a","\u1EA1":"a","\u1EAD":"a","\u1EB7":"a","\u1E01":"a","\u0105":"a","\u2C65":"a","\u0250":"a","\uA733":"aa","\u00E6":"ae","\u01FD":"ae","\u01E3":"ae","\uA735":"ao","\uA737":"au","\uA739":"av","\uA73B":"av","\uA73D":"ay","\u24D1":"b","\uFF42":"b","\u1E03":"b","\u1E05":"b","\u1E07":"b","\u0180":"b","\u0183":"b","\u0253":"b","\u24D2":"c","\uFF43":"c","\u0107":"c","\u0109":"c","\u010B":"c","\u010D":"c","\u00E7":"c","\u1E09":"c","\u0188":"c","\u023C":"c","\uA73F":"c","\u2184":"c","\u24D3":"d","\uFF44":"d","\u1E0B":"d","\u010F":"d","\u1E0D":"d","\u1E11":"d","\u1E13":"d","\u1E0F":"d","\u0111":"d","\u018C":"d","\u0256":"d","\u0257":"d","\uA77A":"d","\u01F3":"dz","\u01C6":"dz","\u24D4":"e","\uFF45":"e","\u00E8":"e","\u00E9":"e","\u00EA":"e","\u1EC1":"e","\u1EBF":"e","\u1EC5":"e","\u1EC3":"e","\u1EBD":"e","\u0113":"e","\u1E15":"e","\u1E17":"e","\u0115":"e","\u0117":"e","\u00EB":"e","\u1EBB":"e","\u011B":"e","\u0205":"e","\u0207":"e","\u1EB9":"e","\u1EC7":"e","\u0229":"e","\u1E1D":"e","\u0119":"e","\u1E19":"e","\u1E1B":"e","\u0247":"e","\u025B":"e","\u01DD":"e","\u24D5":"f","\uFF46":"f","\u1E1F":"f","\u0192":"f","\uA77C":"f","\u24D6":"g","\uFF47":"g","\u01F5":"g","\u011D":"g","\u1E21":"g","\u011F":"g","\u0121":"g","\u01E7":"g","\u0123":"g","\u01E5":"g","\u0260":"g","\uA7A1":"g","\u1D79":"g","\uA77F":"g","\u24D7":"h","\uFF48":"h","\u0125":"h","\u1E23":"h","\u1E27":"h","\u021F":"h","\u1E25":"h","\u1E29":"h","\u1E2B":"h","\u1E96":"h","\u0127":"h","\u2C68":"h","\u2C76":"h","\u0265":"h","\u0195":"hv","\u24D8":"i","\uFF49":"i","\u00EC":"i","\u00ED":"i","\u00EE":"i","\u0129":"i","\u012B":"i","\u012D":"i","\u00EF":"i","\u1E2F":"i","\u1EC9":"i","\u01D0":"i","\u0209":"i","\u020B":"i","\u1ECB":"i","\u012F":"i","\u1E2D":"i","\u0268":"i","\u0131":"i","\u24D9":"j","\uFF4A":"j","\u0135":"j","\u01F0":"j","\u0249":"j","\u24DA":"k","\uFF4B":"k","\u1E31":"k","\u01E9":"k","\u1E33":"k","\u0137":"k","\u1E35":"k","\u0199":"k","\u2C6A":"k","\uA741":"k","\uA743":"k","\uA745":"k","\uA7A3":"k","\u24DB":"l","\uFF4C":"l","\u0140":"l","\u013A":"l","\u013E":"l","\u1E37":"l","\u1E39":"l","\u013C":"l","\u1E3D":"l","\u1E3B":"l","\u017F":"l","\u0142":"l","\u019A":"l","\u026B":"l","\u2C61":"l","\uA749":"l","\uA781":"l","\uA747":"l","\u01C9":"lj","\u24DC":"m","\uFF4D":"m","\u1E3F":"m","\u1E41":"m","\u1E43":"m","\u0271":"m","\u026F":"m","\u24DD":"n","\uFF4E":"n","\u01F9":"n","\u0144":"n","\u00F1":"n","\u1E45":"n","\u0148":"n","\u1E47":"n","\u0146":"n","\u1E4B":"n","\u1E49":"n","\u019E":"n","\u0272":"n","\u0149":"n","\uA791":"n","\uA7A5":"n","\u01CC":"nj","\u24DE":"o","\uFF4F":"o","\u00F2":"o","\u00F3":"o","\u00F4":"o","\u1ED3":"o","\u1ED1":"o","\u1ED7":"o","\u1ED5":"o","\u00F5":"o","\u1E4D":"o","\u022D":"o","\u1E4F":"o","\u014D":"o","\u1E51":"o","\u1E53":"o","\u014F":"o","\u022F":"o","\u0231":"o","\u00F6":"o","\u022B":"o","\u1ECF":"o","\u0151":"o","\u01D2":"o","\u020D":"o","\u020F":"o","\u01A1":"o","\u1EDD":"o","\u1EDB":"o","\u1EE1":"o","\u1EDF":"o","\u1EE3":"o","\u1ECD":"o","\u1ED9":"o","\u01EB":"o","\u01ED":"o","\u00F8":"o","\u01FF":"o","\u0254":"o","\uA74B":"o","\uA74D":"o","\u0275":"o","\u01A3":"oi","\u0223":"ou","\uA74F":"oo","\u24DF":"p","\uFF50":"p","\u1E55":"p","\u1E57":"p","\u01A5":"p","\u1D7D":"p","\uA751":"p","\uA753":"p","\uA755":"p","\u24E0":"q","\uFF51":"q","\u024B":"q","\uA757":"q","\uA759":"q","\u24E1":"r","\uFF52":"r","\u0155":"r","\u1E59":"r","\u0159":"r","\u0211":"r","\u0213":"r","\u1E5B":"r","\u1E5D":"r","\u0157":"r","\u1E5F":"r","\u024D":"r","\u027D":"r","\uA75B":"r","\uA7A7":"r","\uA783":"r","\u24E2":"s","\uFF53":"s","\u00DF":"s","\u015B":"s","\u1E65":"s","\u015D":"s","\u1E61":"s","\u0161":"s","\u1E67":"s","\u1E63":"s","\u1E69":"s","\u0219":"s","\u015F":"s","\u023F":"s","\uA7A9":"s","\uA785":"s","\u1E9B":"s","\u24E3":"t","\uFF54":"t","\u1E6B":"t","\u1E97":"t","\u0165":"t","\u1E6D":"t","\u021B":"t","\u0163":"t","\u1E71":"t","\u1E6F":"t","\u0167":"t","\u01AD":"t","\u0288":"t","\u2C66":"t","\uA787":"t","\uA729":"tz","\u24E4":"u","\uFF55":"u","\u00F9":"u","\u00FA":"u","\u00FB":"u","\u0169":"u","\u1E79":"u","\u016B":"u","\u1E7B":"u","\u016D":"u","\u00FC":"u","\u01DC":"u","\u01D8":"u","\u01D6":"u","\u01DA":"u","\u1EE7":"u","\u016F":"u","\u0171":"u","\u01D4":"u","\u0215":"u","\u0217":"u","\u01B0":"u","\u1EEB":"u","\u1EE9":"u","\u1EEF":"u","\u1EED":"u","\u1EF1":"u","\u1EE5":"u","\u1E73":"u","\u0173":"u","\u1E77":"u","\u1E75":"u","\u0289":"u","\u24E5":"v","\uFF56":"v","\u1E7D":"v","\u1E7F":"v","\u028B":"v","\uA75F":"v","\u028C":"v","\uA761":"vy","\u24E6":"w","\uFF57":"w","\u1E81":"w","\u1E83":"w","\u0175":"w","\u1E87":"w","\u1E85":"w","\u1E98":"w","\u1E89":"w","\u2C73":"w","\u24E7":"x","\uFF58":"x","\u1E8B":"x","\u1E8D":"x","\u24E8":"y","\uFF59":"y","\u1EF3":"y","\u00FD":"y","\u0177":"y","\u1EF9":"y","\u0233":"y","\u1E8F":"y","\u00FF":"y","\u1EF7":"y","\u1E99":"y","\u1EF5":"y","\u01B4":"y","\u024F":"y","\u1EFF":"y","\u24E9":"z","\uFF5A":"z","\u017A":"z","\u1E91":"z","\u017C":"z","\u017E":"z","\u1E93":"z","\u1E95":"z","\u01B6":"z","\u0225":"z","\u0240":"z","\u2C6C":"z","\uA763":"z","\u0386":"\u0391","\u0388":"\u0395","\u0389":"\u0397","\u038A":"\u0399","\u03AA":"\u0399","\u038C":"\u039F","\u038E":"\u03A5","\u03AB":"\u03A5","\u038F":"\u03A9","\u03AC":"\u03B1","\u03AD":"\u03B5","\u03AE":"\u03B7","\u03AF":"\u03B9","\u03CA":"\u03B9","\u0390":"\u03B9","\u03CC":"\u03BF","\u03CD":"\u03C5","\u03CB":"\u03C5","\u03B0":"\u03C5","\u03C9":"\u03C9","\u03C2":"\u03C3"};
  8022. $document = $(document);
  8023. nextUid=(function() { var counter=1; return function() { return counter++; }; }());
  8024. function reinsertElement(element) {
  8025. var placeholder = $(document.createTextNode(''));
  8026. element.before(placeholder);
  8027. placeholder.before(element);
  8028. placeholder.remove();
  8029. }
  8030. function stripDiacritics(str) {
  8031. // Used 'uni range + named function' from http://jsperf.com/diacritics/18
  8032. function match(a) {
  8033. return DIACRITICS[a] || a;
  8034. }
  8035. return str.replace(/[^\u0000-\u007E]/g, match);
  8036. }
  8037. function indexOf(value, array) {
  8038. var i = 0, l = array.length;
  8039. for (; i < l; i = i + 1) {
  8040. if (equal(value, array[i])) return i;
  8041. }
  8042. return -1;
  8043. }
  8044. function measureScrollbar () {
  8045. var $template = $( MEASURE_SCROLLBAR_TEMPLATE );
  8046. $template.appendTo('body');
  8047. var dim = {
  8048. width: $template.width() - $template[0].clientWidth,
  8049. height: $template.height() - $template[0].clientHeight
  8050. };
  8051. $template.remove();
  8052. return dim;
  8053. }
  8054. /**
  8055. * Compares equality of a and b
  8056. * @param a
  8057. * @param b
  8058. */
  8059. function equal(a, b) {
  8060. if (a === b) return true;
  8061. if (a === undefined || b === undefined) return false;
  8062. if (a === null || b === null) return false;
  8063. // Check whether 'a' or 'b' is a string (primitive or object).
  8064. // The concatenation of an empty string (+'') converts its argument to a string's primitive.
  8065. if (a.constructor === String) return a+'' === b+''; // a+'' - in case 'a' is a String object
  8066. if (b.constructor === String) return b+'' === a+''; // b+'' - in case 'b' is a String object
  8067. return false;
  8068. }
  8069. /**
  8070. * Splits the string into an array of values, trimming each value. An empty array is returned for nulls or empty
  8071. * strings
  8072. * @param string
  8073. * @param separator
  8074. */
  8075. function splitVal(string, separator) {
  8076. var val, i, l;
  8077. if (string === null || string.length < 1) return [];
  8078. val = string.split(separator);
  8079. for (i = 0, l = val.length; i < l; i = i + 1) val[i] = $.trim(val[i]);
  8080. return val;
  8081. }
  8082. function getSideBorderPadding(element) {
  8083. return element.outerWidth(false) - element.width();
  8084. }
  8085. function installKeyUpChangeEvent(element) {
  8086. var key="keyup-change-value";
  8087. element.on("keydown", function () {
  8088. if ($.data(element, key) === undefined) {
  8089. $.data(element, key, element.val());
  8090. }
  8091. });
  8092. element.on("keyup", function () {
  8093. var val= $.data(element, key);
  8094. if (val !== undefined && element.val() !== val) {
  8095. $.removeData(element, key);
  8096. element.trigger("keyup-change");
  8097. }
  8098. });
  8099. }
  8100. /**
  8101. * filters mouse events so an event is fired only if the mouse moved.
  8102. *
  8103. * filters out mouse events that occur when mouse is stationary but
  8104. * the elements under the pointer are scrolled.
  8105. */
  8106. function installFilteredMouseMove(element) {
  8107. element.on("mousemove", function (e) {
  8108. var lastpos = lastMousePosition;
  8109. if (lastpos === undefined || lastpos.x !== e.pageX || lastpos.y !== e.pageY) {
  8110. $(e.target).trigger("mousemove-filtered", e);
  8111. }
  8112. });
  8113. }
  8114. /**
  8115. * Debounces a function. Returns a function that calls the original fn function only if no invocations have been made
  8116. * within the last quietMillis milliseconds.
  8117. *
  8118. * @param quietMillis number of milliseconds to wait before invoking fn
  8119. * @param fn function to be debounced
  8120. * @param ctx object to be used as this reference within fn
  8121. * @return debounced version of fn
  8122. */
  8123. function debounce(quietMillis, fn, ctx) {
  8124. ctx = ctx || undefined;
  8125. var timeout;
  8126. return function () {
  8127. var args = arguments;
  8128. window.clearTimeout(timeout);
  8129. timeout = window.setTimeout(function() {
  8130. fn.apply(ctx, args);
  8131. }, quietMillis);
  8132. };
  8133. }
  8134. function installDebouncedScroll(threshold, element) {
  8135. var notify = debounce(threshold, function (e) { element.trigger("scroll-debounced", e);});
  8136. element.on("scroll", function (e) {
  8137. if (indexOf(e.target, element.get()) >= 0) notify(e);
  8138. });
  8139. }
  8140. function focus($el) {
  8141. if ($el[0] === document.activeElement) return;
  8142. /* set the focus in a 0 timeout - that way the focus is set after the processing
  8143. of the current event has finished - which seems like the only reliable way
  8144. to set focus */
  8145. window.setTimeout(function() {
  8146. var el=$el[0], pos=$el.val().length, range;
  8147. $el.focus();
  8148. /* make sure el received focus so we do not error out when trying to manipulate the caret.
  8149. sometimes modals or others listeners may steal it after its set */
  8150. var isVisible = (el.offsetWidth > 0 || el.offsetHeight > 0);
  8151. if (isVisible && el === document.activeElement) {
  8152. /* after the focus is set move the caret to the end, necessary when we val()
  8153. just before setting focus */
  8154. if(el.setSelectionRange)
  8155. {
  8156. el.setSelectionRange(pos, pos);
  8157. }
  8158. else if (el.createTextRange) {
  8159. range = el.createTextRange();
  8160. range.collapse(false);
  8161. range.select();
  8162. }
  8163. }
  8164. }, 0);
  8165. }
  8166. function getCursorInfo(el) {
  8167. el = $(el)[0];
  8168. var offset = 0;
  8169. var length = 0;
  8170. if ('selectionStart' in el) {
  8171. offset = el.selectionStart;
  8172. length = el.selectionEnd - offset;
  8173. } else if ('selection' in document) {
  8174. el.focus();
  8175. var sel = document.selection.createRange();
  8176. length = document.selection.createRange().text.length;
  8177. sel.moveStart('character', -el.value.length);
  8178. offset = sel.text.length - length;
  8179. }
  8180. return { offset: offset, length: length };
  8181. }
  8182. function killEvent(event) {
  8183. event.preventDefault();
  8184. event.stopPropagation();
  8185. }
  8186. function killEventImmediately(event) {
  8187. event.preventDefault();
  8188. event.stopImmediatePropagation();
  8189. }
  8190. function measureTextWidth(e) {
  8191. if (!sizer){
  8192. var style = e[0].currentStyle || window.getComputedStyle(e[0], null);
  8193. sizer = $(document.createElement("div")).css({
  8194. position: "absolute",
  8195. left: "-10000px",
  8196. top: "-10000px",
  8197. display: "none",
  8198. fontSize: style.fontSize,
  8199. fontFamily: style.fontFamily,
  8200. fontStyle: style.fontStyle,
  8201. fontWeight: style.fontWeight,
  8202. letterSpacing: style.letterSpacing,
  8203. textTransform: style.textTransform,
  8204. whiteSpace: "nowrap"
  8205. });
  8206. sizer.attr("class","select2-sizer");
  8207. $("body").append(sizer);
  8208. }
  8209. sizer.text(e.val());
  8210. return sizer.width();
  8211. }
  8212. function syncCssClasses(dest, src, adapter) {
  8213. var classes, replacements = [], adapted;
  8214. classes = $.trim(dest.attr("class"));
  8215. if (classes) {
  8216. classes = '' + classes; // for IE which returns object
  8217. $(classes.split(/\s+/)).each2(function() {
  8218. if (this.indexOf("select2-") === 0) {
  8219. replacements.push(this);
  8220. }
  8221. });
  8222. }
  8223. classes = $.trim(src.attr("class"));
  8224. if (classes) {
  8225. classes = '' + classes; // for IE which returns object
  8226. $(classes.split(/\s+/)).each2(function() {
  8227. if (this.indexOf("select2-") !== 0) {
  8228. adapted = adapter(this);
  8229. if (adapted) {
  8230. replacements.push(adapted);
  8231. }
  8232. }
  8233. });
  8234. }
  8235. dest.attr("class", replacements.join(" "));
  8236. }
  8237. function markMatch(text, term, markup, escapeMarkup) {
  8238. var match=stripDiacritics(text.toUpperCase()).indexOf(stripDiacritics(term.toUpperCase())),
  8239. tl=term.length;
  8240. if (match<0) {
  8241. markup.push(escapeMarkup(text));
  8242. return;
  8243. }
  8244. markup.push(escapeMarkup(text.substring(0, match)));
  8245. markup.push("<span class='select2-match'>");
  8246. markup.push(escapeMarkup(text.substring(match, match + tl)));
  8247. markup.push("</span>");
  8248. markup.push(escapeMarkup(text.substring(match + tl, text.length)));
  8249. }
  8250. function defaultEscapeMarkup(markup) {
  8251. var replace_map = {
  8252. '\\': '&#92;',
  8253. '&': '&amp;',
  8254. '<': '&lt;',
  8255. '>': '&gt;',
  8256. '"': '&quot;',
  8257. "'": '&#39;',
  8258. "/": '&#47;'
  8259. };
  8260. return String(markup).replace(/[&<>"'\/\\]/g, function (match) {
  8261. return replace_map[match];
  8262. });
  8263. }
  8264. /**
  8265. * Produces an ajax-based query function
  8266. *
  8267. * @param options object containing configuration parameters
  8268. * @param options.params parameter map for the transport ajax call, can contain such options as cache, jsonpCallback, etc. see $.ajax
  8269. * @param options.transport function that will be used to execute the ajax request. must be compatible with parameters supported by $.ajax
  8270. * @param options.url url for the data
  8271. * @param options.data a function(searchTerm, pageNumber, context) that should return an object containing query string parameters for the above url.
  8272. * @param options.dataType request data type: ajax, jsonp, other datatypes supported by jQuery's $.ajax function or the transport function if specified
  8273. * @param options.quietMillis (optional) milliseconds to wait before making the ajaxRequest, helps debounce the ajax function if invoked too often
  8274. * @param options.results a function(remoteData, pageNumber, query) that converts data returned form the remote request to the format expected by Select2.
  8275. * The expected format is an object containing the following keys:
  8276. * results array of objects that will be used as choices
  8277. * more (optional) boolean indicating whether there are more results available
  8278. * Example: {results:[{id:1, text:'Red'},{id:2, text:'Blue'}], more:true}
  8279. */
  8280. function ajax(options) {
  8281. var timeout, // current scheduled but not yet executed request
  8282. handler = null,
  8283. quietMillis = options.quietMillis || 100,
  8284. ajaxUrl = options.url,
  8285. self = this;
  8286. return function (query) {
  8287. window.clearTimeout(timeout);
  8288. timeout = window.setTimeout(function () {
  8289. var data = options.data, // ajax data function
  8290. url = ajaxUrl, // ajax url string or function
  8291. transport = options.transport || $.fn.select2.ajaxDefaults.transport,
  8292. // deprecated - to be removed in 4.0 - use params instead
  8293. deprecated = {
  8294. type: options.type || 'GET', // set type of request (GET or POST)
  8295. cache: options.cache || false,
  8296. jsonpCallback: options.jsonpCallback||undefined,
  8297. dataType: options.dataType||"json"
  8298. },
  8299. params = $.extend({}, $.fn.select2.ajaxDefaults.params, deprecated);
  8300. data = data ? data.call(self, query.term, query.page, query.context) : null;
  8301. url = (typeof url === 'function') ? url.call(self, query.term, query.page, query.context) : url;
  8302. if (handler && typeof handler.abort === "function") { handler.abort(); }
  8303. if (options.params) {
  8304. if ($.isFunction(options.params)) {
  8305. $.extend(params, options.params.call(self));
  8306. } else {
  8307. $.extend(params, options.params);
  8308. }
  8309. }
  8310. $.extend(params, {
  8311. url: url,
  8312. dataType: options.dataType,
  8313. data: data,
  8314. success: function (data) {
  8315. // TODO - replace query.page with query so users have access to term, page, etc.
  8316. // added query as third paramter to keep backwards compatibility
  8317. var results = options.results(data, query.page, query);
  8318. query.callback(results);
  8319. },
  8320. error: function(jqXHR, textStatus, errorThrown){
  8321. var results = {
  8322. hasError: true,
  8323. jqXHR: jqXHR,
  8324. textStatus: textStatus,
  8325. errorThrown: errorThrown,
  8326. };
  8327. query.callback(results);
  8328. }
  8329. });
  8330. handler = transport.call(self, params);
  8331. }, quietMillis);
  8332. };
  8333. }
  8334. /**
  8335. * Produces a query function that works with a local array
  8336. *
  8337. * @param options object containing configuration parameters. The options parameter can either be an array or an
  8338. * object.
  8339. *
  8340. * If the array form is used it is assumed that it contains objects with 'id' and 'text' keys.
  8341. *
  8342. * If the object form is used it is assumed that it contains 'data' and 'text' keys. The 'data' key should contain
  8343. * an array of objects that will be used as choices. These objects must contain at least an 'id' key. The 'text'
  8344. * key can either be a String in which case it is expected that each element in the 'data' array has a key with the
  8345. * value of 'text' which will be used to match choices. Alternatively, text can be a function(item) that can extract
  8346. * the text.
  8347. */
  8348. function local(options) {
  8349. var data = options, // data elements
  8350. dataText,
  8351. tmp,
  8352. text = function (item) { return ""+item.text; }; // function used to retrieve the text portion of a data item that is matched against the search
  8353. if ($.isArray(data)) {
  8354. tmp = data;
  8355. data = { results: tmp };
  8356. }
  8357. if ($.isFunction(data) === false) {
  8358. tmp = data;
  8359. data = function() { return tmp; };
  8360. }
  8361. var dataItem = data();
  8362. if (dataItem.text) {
  8363. text = dataItem.text;
  8364. // if text is not a function we assume it to be a key name
  8365. if (!$.isFunction(text)) {
  8366. dataText = dataItem.text; // we need to store this in a separate variable because in the next step data gets reset and data.text is no longer available
  8367. text = function (item) { return item[dataText]; };
  8368. }
  8369. }
  8370. return function (query) {
  8371. var t = query.term, filtered = { results: [] }, process;
  8372. if (t === "") {
  8373. query.callback(data());
  8374. return;
  8375. }
  8376. process = function(datum, collection) {
  8377. var group, attr;
  8378. datum = datum[0];
  8379. if (datum.children) {
  8380. group = {};
  8381. for (attr in datum) {
  8382. if (datum.hasOwnProperty(attr)) group[attr]=datum[attr];
  8383. }
  8384. group.children=[];
  8385. $(datum.children).each2(function(i, childDatum) { process(childDatum, group.children); });
  8386. if (group.children.length || query.matcher(t, text(group), datum)) {
  8387. collection.push(group);
  8388. }
  8389. } else {
  8390. if (query.matcher(t, text(datum), datum)) {
  8391. collection.push(datum);
  8392. }
  8393. }
  8394. };
  8395. $(data().results).each2(function(i, datum) { process(datum, filtered.results); });
  8396. query.callback(filtered);
  8397. };
  8398. }
  8399. // TODO javadoc
  8400. function tags(data) {
  8401. var isFunc = $.isFunction(data);
  8402. return function (query) {
  8403. var t = query.term, filtered = {results: []};
  8404. var result = isFunc ? data(query) : data;
  8405. if ($.isArray(result)) {
  8406. $(result).each(function () {
  8407. var isObject = this.text !== undefined,
  8408. text = isObject ? this.text : this;
  8409. if (t === "" || query.matcher(t, text)) {
  8410. filtered.results.push(isObject ? this : {id: this, text: this});
  8411. }
  8412. });
  8413. query.callback(filtered);
  8414. }
  8415. };
  8416. }
  8417. /**
  8418. * Checks if the formatter function should be used.
  8419. *
  8420. * Throws an error if it is not a function. Returns true if it should be used,
  8421. * false if no formatting should be performed.
  8422. *
  8423. * @param formatter
  8424. */
  8425. function checkFormatter(formatter, formatterName) {
  8426. if ($.isFunction(formatter)) return true;
  8427. if (!formatter) return false;
  8428. if (typeof(formatter) === 'string') return true;
  8429. throw new Error(formatterName +" must be a string, function, or falsy value");
  8430. }
  8431. /**
  8432. * Returns a given value
  8433. * If given a function, returns its output
  8434. *
  8435. * @param val string|function
  8436. * @param context value of "this" to be passed to function
  8437. * @returns {*}
  8438. */
  8439. function evaluate(val, context) {
  8440. if ($.isFunction(val)) {
  8441. var args = Array.prototype.slice.call(arguments, 2);
  8442. return val.apply(context, args);
  8443. }
  8444. return val;
  8445. }
  8446. function countResults(results) {
  8447. var count = 0;
  8448. $.each(results, function(i, item) {
  8449. if (item.children) {
  8450. count += countResults(item.children);
  8451. } else {
  8452. count++;
  8453. }
  8454. });
  8455. return count;
  8456. }
  8457. /**
  8458. * Default tokenizer. This function uses breaks the input on substring match of any string from the
  8459. * opts.tokenSeparators array and uses opts.createSearchChoice to create the choice object. Both of those
  8460. * two options have to be defined in order for the tokenizer to work.
  8461. *
  8462. * @param input text user has typed so far or pasted into the search field
  8463. * @param selection currently selected choices
  8464. * @param selectCallback function(choice) callback tho add the choice to selection
  8465. * @param opts select2's opts
  8466. * @return undefined/null to leave the current input unchanged, or a string to change the input to the returned value
  8467. */
  8468. function defaultTokenizer(input, selection, selectCallback, opts) {
  8469. var original = input, // store the original so we can compare and know if we need to tell the search to update its text
  8470. dupe = false, // check for whether a token we extracted represents a duplicate selected choice
  8471. token, // token
  8472. index, // position at which the separator was found
  8473. i, l, // looping variables
  8474. separator; // the matched separator
  8475. if (!opts.createSearchChoice || !opts.tokenSeparators || opts.tokenSeparators.length < 1) return undefined;
  8476. while (true) {
  8477. index = -1;
  8478. for (i = 0, l = opts.tokenSeparators.length; i < l; i++) {
  8479. separator = opts.tokenSeparators[i];
  8480. index = input.indexOf(separator);
  8481. if (index >= 0) break;
  8482. }
  8483. if (index < 0) break; // did not find any token separator in the input string, bail
  8484. token = input.substring(0, index);
  8485. input = input.substring(index + separator.length);
  8486. if (token.length > 0) {
  8487. token = opts.createSearchChoice.call(this, token, selection);
  8488. if (token !== undefined && token !== null && opts.id(token) !== undefined && opts.id(token) !== null) {
  8489. dupe = false;
  8490. for (i = 0, l = selection.length; i < l; i++) {
  8491. if (equal(opts.id(token), opts.id(selection[i]))) {
  8492. dupe = true; break;
  8493. }
  8494. }
  8495. if (!dupe) selectCallback(token);
  8496. }
  8497. }
  8498. }
  8499. if (original!==input) return input;
  8500. }
  8501. function cleanupJQueryElements() {
  8502. var self = this;
  8503. $.each(arguments, function (i, element) {
  8504. self[element].remove();
  8505. self[element] = null;
  8506. });
  8507. }
  8508. /**
  8509. * Creates a new class
  8510. *
  8511. * @param superClass
  8512. * @param methods
  8513. */
  8514. function clazz(SuperClass, methods) {
  8515. var constructor = function () {};
  8516. constructor.prototype = new SuperClass;
  8517. constructor.prototype.constructor = constructor;
  8518. constructor.prototype.parent = SuperClass.prototype;
  8519. constructor.prototype = $.extend(constructor.prototype, methods);
  8520. return constructor;
  8521. }
  8522. AbstractSelect2 = clazz(Object, {
  8523. // abstract
  8524. bind: function (func) {
  8525. var self = this;
  8526. return function () {
  8527. func.apply(self, arguments);
  8528. };
  8529. },
  8530. // abstract
  8531. init: function (opts) {
  8532. var results, search, resultsSelector = ".select2-results";
  8533. // prepare options
  8534. this.opts = opts = this.prepareOpts(opts);
  8535. this.id=opts.id;
  8536. // destroy if called on an existing component
  8537. if (opts.element.data("select2") !== undefined &&
  8538. opts.element.data("select2") !== null) {
  8539. opts.element.data("select2").destroy();
  8540. }
  8541. this.container = this.createContainer();
  8542. this.liveRegion = $("<span>", {
  8543. role: "status",
  8544. "aria-live": "polite"
  8545. })
  8546. .addClass("select2-hidden-accessible")
  8547. .appendTo(document.body);
  8548. this.containerId="s2id_"+(opts.element.attr("id") || "autogen"+nextUid());
  8549. this.containerEventName= this.containerId
  8550. .replace(/([.])/g, '_')
  8551. .replace(/([;&,\-\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g, '\\$1');
  8552. this.container.attr("id", this.containerId);
  8553. this.container.attr("title", opts.element.attr("title"));
  8554. this.body = $("body");
  8555. syncCssClasses(this.container, this.opts.element, this.opts.adaptContainerCssClass);
  8556. this.container.attr("style", opts.element.attr("style"));
  8557. this.container.css(evaluate(opts.containerCss, this.opts.element));
  8558. this.container.addClass(evaluate(opts.containerCssClass, this.opts.element));
  8559. this.elementTabIndex = this.opts.element.attr("tabindex");
  8560. // swap container for the element
  8561. this.opts.element
  8562. .data("select2", this)
  8563. .attr("tabindex", "-1")
  8564. .before(this.container)
  8565. .on("click.select2", killEvent); // do not leak click events
  8566. this.container.data("select2", this);
  8567. this.dropdown = this.container.find(".select2-drop");
  8568. syncCssClasses(this.dropdown, this.opts.element, this.opts.adaptDropdownCssClass);
  8569. this.dropdown.addClass(evaluate(opts.dropdownCssClass, this.opts.element));
  8570. this.dropdown.data("select2", this);
  8571. this.dropdown.on("click", killEvent);
  8572. this.results = results = this.container.find(resultsSelector);
  8573. this.search = search = this.container.find("input.select2-input");
  8574. this.queryCount = 0;
  8575. this.resultsPage = 0;
  8576. this.context = null;
  8577. // initialize the container
  8578. this.initContainer();
  8579. this.container.on("click", killEvent);
  8580. installFilteredMouseMove(this.results);
  8581. this.dropdown.on("mousemove-filtered", resultsSelector, this.bind(this.highlightUnderEvent));
  8582. this.dropdown.on("touchstart touchmove touchend", resultsSelector, this.bind(function (event) {
  8583. this._touchEvent = true;
  8584. this.highlightUnderEvent(event);
  8585. }));
  8586. this.dropdown.on("touchmove", resultsSelector, this.bind(this.touchMoved));
  8587. this.dropdown.on("touchstart touchend", resultsSelector, this.bind(this.clearTouchMoved));
  8588. // Waiting for a click event on touch devices to select option and hide dropdown
  8589. // otherwise click will be triggered on an underlying element
  8590. this.dropdown.on('click', this.bind(function (event) {
  8591. if (this._touchEvent) {
  8592. this._touchEvent = false;
  8593. this.selectHighlighted();
  8594. }
  8595. }));
  8596. installDebouncedScroll(80, this.results);
  8597. this.dropdown.on("scroll-debounced", resultsSelector, this.bind(this.loadMoreIfNeeded));
  8598. // do not propagate change event from the search field out of the component
  8599. $(this.container).on("change", ".select2-input", function(e) {e.stopPropagation();});
  8600. $(this.dropdown).on("change", ".select2-input", function(e) {e.stopPropagation();});
  8601. // if jquery.mousewheel plugin is installed we can prevent out-of-bounds scrolling of results via mousewheel
  8602. if ($.fn.mousewheel) {
  8603. results.mousewheel(function (e, delta, deltaX, deltaY) {
  8604. var top = results.scrollTop();
  8605. if (deltaY > 0 && top - deltaY <= 0) {
  8606. results.scrollTop(0);
  8607. killEvent(e);
  8608. } else if (deltaY < 0 && results.get(0).scrollHeight - results.scrollTop() + deltaY <= results.height()) {
  8609. results.scrollTop(results.get(0).scrollHeight - results.height());
  8610. killEvent(e);
  8611. }
  8612. });
  8613. }
  8614. installKeyUpChangeEvent(search);
  8615. search.on("keyup-change input paste", this.bind(this.updateResults));
  8616. search.on("focus", function () { search.addClass("select2-focused"); });
  8617. search.on("blur", function () { search.removeClass("select2-focused");});
  8618. this.dropdown.on("mouseup", resultsSelector, this.bind(function (e) {
  8619. if ($(e.target).closest(".select2-result-selectable").length > 0) {
  8620. this.highlightUnderEvent(e);
  8621. this.selectHighlighted(e);
  8622. }
  8623. }));
  8624. // trap all mouse events from leaving the dropdown. sometimes there may be a modal that is listening
  8625. // for mouse events outside of itself so it can close itself. since the dropdown is now outside the select2's
  8626. // dom it will trigger the popup close, which is not what we want
  8627. // focusin can cause focus wars between modals and select2 since the dropdown is outside the modal.
  8628. this.dropdown.on("click mouseup mousedown touchstart touchend focusin", function (e) { e.stopPropagation(); });
  8629. this.nextSearchTerm = undefined;
  8630. if ($.isFunction(this.opts.initSelection)) {
  8631. // initialize selection based on the current value of the source element
  8632. this.initSelection();
  8633. // if the user has provided a function that can set selection based on the value of the source element
  8634. // we monitor the change event on the element and trigger it, allowing for two way synchronization
  8635. this.monitorSource();
  8636. }
  8637. if (opts.maximumInputLength !== null) {
  8638. this.search.attr("maxlength", opts.maximumInputLength);
  8639. }
  8640. var disabled = opts.element.prop("disabled");
  8641. if (disabled === undefined) disabled = false;
  8642. this.enable(!disabled);
  8643. var readonly = opts.element.prop("readonly");
  8644. if (readonly === undefined) readonly = false;
  8645. this.readonly(readonly);
  8646. // Calculate size of scrollbar
  8647. scrollBarDimensions = scrollBarDimensions || measureScrollbar();
  8648. this.autofocus = opts.element.prop("autofocus");
  8649. opts.element.prop("autofocus", false);
  8650. if (this.autofocus) this.focus();
  8651. this.search.attr("placeholder", opts.searchInputPlaceholder);
  8652. },
  8653. // abstract
  8654. destroy: function () {
  8655. var element=this.opts.element, select2 = element.data("select2"), self = this;
  8656. this.close();
  8657. if (element.length && element[0].detachEvent) {
  8658. element.each(function () {
  8659. this.detachEvent("onpropertychange", self._sync);
  8660. });
  8661. }
  8662. if (this.propertyObserver) {
  8663. this.propertyObserver.disconnect();
  8664. this.propertyObserver = null;
  8665. }
  8666. this._sync = null;
  8667. if (select2 !== undefined) {
  8668. select2.container.remove();
  8669. select2.liveRegion.remove();
  8670. select2.dropdown.remove();
  8671. element
  8672. .removeClass("select2-offscreen")
  8673. .removeData("select2")
  8674. .off(".select2")
  8675. .prop("autofocus", this.autofocus || false);
  8676. if (this.elementTabIndex) {
  8677. element.attr({tabindex: this.elementTabIndex});
  8678. } else {
  8679. element.removeAttr("tabindex");
  8680. }
  8681. element.show();
  8682. }
  8683. cleanupJQueryElements.call(this,
  8684. "container",
  8685. "liveRegion",
  8686. "dropdown",
  8687. "results",
  8688. "search"
  8689. );
  8690. },
  8691. // abstract
  8692. optionToData: function(element) {
  8693. if (element.is("option")) {
  8694. return {
  8695. id:element.prop("value"),
  8696. text:element.text(),
  8697. element: element.get(),
  8698. css: element.attr("class"),
  8699. disabled: element.prop("disabled"),
  8700. locked: equal(element.attr("locked"), "locked") || equal(element.data("locked"), true)
  8701. };
  8702. } else if (element.is("optgroup")) {
  8703. return {
  8704. text:element.attr("label"),
  8705. children:[],
  8706. element: element.get(),
  8707. css: element.attr("class")
  8708. };
  8709. }
  8710. },
  8711. // abstract
  8712. prepareOpts: function (opts) {
  8713. var element, select, idKey, ajaxUrl, self = this;
  8714. element = opts.element;
  8715. if (element.get(0).tagName.toLowerCase() === "select") {
  8716. this.select = select = opts.element;
  8717. }
  8718. if (select) {
  8719. // these options are not allowed when attached to a select because they are picked up off the element itself
  8720. $.each(["id", "multiple", "ajax", "query", "createSearchChoice", "initSelection", "data", "tags"], function () {
  8721. if (this in opts) {
  8722. throw new Error("Option '" + this + "' is not allowed for Select2 when attached to a <select> element.");
  8723. }
  8724. });
  8725. }
  8726. opts = $.extend({}, {
  8727. populateResults: function(container, results, query) {
  8728. var populate, id=this.opts.id, liveRegion=this.liveRegion;
  8729. populate=function(results, container, depth) {
  8730. var i, l, result, selectable, disabled, compound, node, label, innerContainer, formatted;
  8731. results = opts.sortResults(results, container, query);
  8732. // collect the created nodes for bulk append
  8733. var nodes = [];
  8734. for (i = 0, l = results.length; i < l; i = i + 1) {
  8735. result=results[i];
  8736. disabled = (result.disabled === true);
  8737. selectable = (!disabled) && (id(result) !== undefined);
  8738. compound=result.children && result.children.length > 0;
  8739. node=$("<li></li>");
  8740. node.addClass("select2-results-dept-"+depth);
  8741. node.addClass("select2-result");
  8742. node.addClass(selectable ? "select2-result-selectable" : "select2-result-unselectable");
  8743. if (disabled) { node.addClass("select2-disabled"); }
  8744. if (compound) { node.addClass("select2-result-with-children"); }
  8745. node.addClass(self.opts.formatResultCssClass(result));
  8746. node.attr("role", "presentation");
  8747. label=$(document.createElement("div"));
  8748. label.addClass("select2-result-label");
  8749. label.attr("id", "select2-result-label-" + nextUid());
  8750. label.attr("role", "option");
  8751. formatted=opts.formatResult(result, label, query, self.opts.escapeMarkup);
  8752. if (formatted!==undefined) {
  8753. label.html(formatted);
  8754. node.append(label);
  8755. }
  8756. if (compound) {
  8757. innerContainer=$("<ul></ul>");
  8758. innerContainer.addClass("select2-result-sub");
  8759. populate(result.children, innerContainer, depth+1);
  8760. node.append(innerContainer);
  8761. }
  8762. node.data("select2-data", result);
  8763. nodes.push(node[0]);
  8764. }
  8765. // bulk append the created nodes
  8766. container.append(nodes);
  8767. liveRegion.text(opts.formatMatches(results.length));
  8768. };
  8769. populate(results, container, 0);
  8770. }
  8771. }, $.fn.select2.defaults, opts);
  8772. if (typeof(opts.id) !== "function") {
  8773. idKey = opts.id;
  8774. opts.id = function (e) { return e[idKey]; };
  8775. }
  8776. if ($.isArray(opts.element.data("select2Tags"))) {
  8777. if ("tags" in opts) {
  8778. throw "tags specified as both an attribute 'data-select2-tags' and in options of Select2 " + opts.element.attr("id");
  8779. }
  8780. opts.tags=opts.element.data("select2Tags");
  8781. }
  8782. if (select) {
  8783. opts.query = this.bind(function (query) {
  8784. var data = { results: [], more: false },
  8785. term = query.term,
  8786. children, placeholderOption, process;
  8787. process=function(element, collection) {
  8788. var group;
  8789. if (element.is("option")) {
  8790. if (query.matcher(term, element.text(), element)) {
  8791. collection.push(self.optionToData(element));
  8792. }
  8793. } else if (element.is("optgroup")) {
  8794. group=self.optionToData(element);
  8795. element.children().each2(function(i, elm) { process(elm, group.children); });
  8796. if (group.children.length>0) {
  8797. collection.push(group);
  8798. }
  8799. }
  8800. };
  8801. children=element.children();
  8802. // ignore the placeholder option if there is one
  8803. if (this.getPlaceholder() !== undefined && children.length > 0) {
  8804. placeholderOption = this.getPlaceholderOption();
  8805. if (placeholderOption) {
  8806. children=children.not(placeholderOption);
  8807. }
  8808. }
  8809. children.each2(function(i, elm) { process(elm, data.results); });
  8810. query.callback(data);
  8811. });
  8812. // this is needed because inside val() we construct choices from options and their id is hardcoded
  8813. opts.id=function(e) { return e.id; };
  8814. } else {
  8815. if (!("query" in opts)) {
  8816. if ("ajax" in opts) {
  8817. ajaxUrl = opts.element.data("ajax-url");
  8818. if (ajaxUrl && ajaxUrl.length > 0) {
  8819. opts.ajax.url = ajaxUrl;
  8820. }
  8821. opts.query = ajax.call(opts.element, opts.ajax);
  8822. } else if ("data" in opts) {
  8823. opts.query = local(opts.data);
  8824. } else if ("tags" in opts) {
  8825. opts.query = tags(opts.tags);
  8826. if (opts.createSearchChoice === undefined) {
  8827. opts.createSearchChoice = function (term) { return {id: $.trim(term), text: $.trim(term)}; };
  8828. }
  8829. if (opts.initSelection === undefined) {
  8830. opts.initSelection = function (element, callback) {
  8831. var data = [];
  8832. $(splitVal(element.val(), opts.separator)).each(function () {
  8833. var obj = { id: this, text: this },
  8834. tags = opts.tags;
  8835. if ($.isFunction(tags)) tags=tags();
  8836. $(tags).each(function() { if (equal(this.id, obj.id)) { obj = this; return false; } });
  8837. data.push(obj);
  8838. });
  8839. callback(data);
  8840. };
  8841. }
  8842. }
  8843. }
  8844. }
  8845. if (typeof(opts.query) !== "function") {
  8846. throw "query function not defined for Select2 " + opts.element.attr("id");
  8847. }
  8848. if (opts.createSearchChoicePosition === 'top') {
  8849. opts.createSearchChoicePosition = function(list, item) { list.unshift(item); };
  8850. }
  8851. else if (opts.createSearchChoicePosition === 'bottom') {
  8852. opts.createSearchChoicePosition = function(list, item) { list.push(item); };
  8853. }
  8854. else if (typeof(opts.createSearchChoicePosition) !== "function") {
  8855. throw "invalid createSearchChoicePosition option must be 'top', 'bottom' or a custom function";
  8856. }
  8857. return opts;
  8858. },
  8859. /**
  8860. * Monitor the original element for changes and update select2 accordingly
  8861. */
  8862. // abstract
  8863. monitorSource: function () {
  8864. var el = this.opts.element, observer, self = this;
  8865. el.on("change.select2", this.bind(function (e) {
  8866. if (this.opts.element.data("select2-change-triggered") !== true) {
  8867. this.initSelection();
  8868. }
  8869. }));
  8870. this._sync = this.bind(function () {
  8871. // sync enabled state
  8872. var disabled = el.prop("disabled");
  8873. if (disabled === undefined) disabled = false;
  8874. this.enable(!disabled);
  8875. var readonly = el.prop("readonly");
  8876. if (readonly === undefined) readonly = false;
  8877. this.readonly(readonly);
  8878. syncCssClasses(this.container, this.opts.element, this.opts.adaptContainerCssClass);
  8879. this.container.addClass(evaluate(this.opts.containerCssClass, this.opts.element));
  8880. syncCssClasses(this.dropdown, this.opts.element, this.opts.adaptDropdownCssClass);
  8881. this.dropdown.addClass(evaluate(this.opts.dropdownCssClass, this.opts.element));
  8882. });
  8883. // IE8-10 (IE9/10 won't fire propertyChange via attachEventListener)
  8884. if (el.length && el[0].attachEvent) {
  8885. el.each(function() {
  8886. this.attachEvent("onpropertychange", self._sync);
  8887. });
  8888. }
  8889. // safari, chrome, firefox, IE11
  8890. observer = window.MutationObserver || window.WebKitMutationObserver|| window.MozMutationObserver;
  8891. if (observer !== undefined) {
  8892. if (this.propertyObserver) { delete this.propertyObserver; this.propertyObserver = null; }
  8893. this.propertyObserver = new observer(function (mutations) {
  8894. $.each(mutations, self._sync);
  8895. });
  8896. this.propertyObserver.observe(el.get(0), { attributes:true, subtree:false });
  8897. }
  8898. },
  8899. // abstract
  8900. triggerSelect: function(data) {
  8901. var evt = $.Event("select2-selecting", { val: this.id(data), object: data, choice: data });
  8902. this.opts.element.trigger(evt);
  8903. return !evt.isDefaultPrevented();
  8904. },
  8905. /**
  8906. * Triggers the change event on the source element
  8907. */
  8908. // abstract
  8909. triggerChange: function (details) {
  8910. details = details || {};
  8911. details= $.extend({}, details, { type: "change", val: this.val() });
  8912. // prevents recursive triggering
  8913. this.opts.element.data("select2-change-triggered", true);
  8914. this.opts.element.trigger(details);
  8915. this.opts.element.data("select2-change-triggered", false);
  8916. // some validation frameworks ignore the change event and listen instead to keyup, click for selects
  8917. // so here we trigger the click event manually
  8918. this.opts.element.click();
  8919. // ValidationEngine ignores the change event and listens instead to blur
  8920. // so here we trigger the blur event manually if so desired
  8921. if (this.opts.blurOnChange)
  8922. this.opts.element.blur();
  8923. },
  8924. //abstract
  8925. isInterfaceEnabled: function()
  8926. {
  8927. return this.enabledInterface === true;
  8928. },
  8929. // abstract
  8930. enableInterface: function() {
  8931. var enabled = this._enabled && !this._readonly,
  8932. disabled = !enabled;
  8933. if (enabled === this.enabledInterface) return false;
  8934. this.container.toggleClass("select2-container-disabled", disabled);
  8935. this.close();
  8936. this.enabledInterface = enabled;
  8937. return true;
  8938. },
  8939. // abstract
  8940. enable: function(enabled) {
  8941. if (enabled === undefined) enabled = true;
  8942. if (this._enabled === enabled) return;
  8943. this._enabled = enabled;
  8944. this.opts.element.prop("disabled", !enabled);
  8945. this.enableInterface();
  8946. },
  8947. // abstract
  8948. disable: function() {
  8949. this.enable(false);
  8950. },
  8951. // abstract
  8952. readonly: function(enabled) {
  8953. if (enabled === undefined) enabled = false;
  8954. if (this._readonly === enabled) return;
  8955. this._readonly = enabled;
  8956. this.opts.element.prop("readonly", enabled);
  8957. this.enableInterface();
  8958. },
  8959. // abstract
  8960. opened: function () {
  8961. return (this.container) ? this.container.hasClass("select2-dropdown-open") : false;
  8962. },
  8963. // abstract
  8964. positionDropdown: function() {
  8965. var $dropdown = this.dropdown,
  8966. offset = this.container.offset(),
  8967. height = this.container.outerHeight(false),
  8968. width = this.container.outerWidth(false),
  8969. dropHeight = $dropdown.outerHeight(false),
  8970. $window = $(window),
  8971. windowWidth = $window.width(),
  8972. windowHeight = $window.height(),
  8973. viewPortRight = $window.scrollLeft() + windowWidth,
  8974. viewportBottom = $window.scrollTop() + windowHeight,
  8975. dropTop = offset.top + height,
  8976. dropLeft = offset.left,
  8977. enoughRoomBelow = dropTop + dropHeight <= viewportBottom,
  8978. enoughRoomAbove = (offset.top - dropHeight) >= $window.scrollTop(),
  8979. dropWidth = $dropdown.outerWidth(false),
  8980. enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight,
  8981. aboveNow = $dropdown.hasClass("select2-drop-above"),
  8982. bodyOffset,
  8983. above,
  8984. changeDirection,
  8985. css,
  8986. resultsListNode;
  8987. // always prefer the current above/below alignment, unless there is not enough room
  8988. if (aboveNow) {
  8989. above = true;
  8990. if (!enoughRoomAbove && enoughRoomBelow) {
  8991. changeDirection = true;
  8992. above = false;
  8993. }
  8994. } else {
  8995. above = false;
  8996. if (!enoughRoomBelow && enoughRoomAbove) {
  8997. changeDirection = true;
  8998. above = true;
  8999. }
  9000. }
  9001. //if we are changing direction we need to get positions when dropdown is hidden;
  9002. if (changeDirection) {
  9003. $dropdown.hide();
  9004. offset = this.container.offset();
  9005. height = this.container.outerHeight(false);
  9006. width = this.container.outerWidth(false);
  9007. dropHeight = $dropdown.outerHeight(false);
  9008. viewPortRight = $window.scrollLeft() + windowWidth;
  9009. viewportBottom = $window.scrollTop() + windowHeight;
  9010. dropTop = offset.top + height;
  9011. dropLeft = offset.left;
  9012. dropWidth = $dropdown.outerWidth(false);
  9013. enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight;
  9014. $dropdown.show();
  9015. // fix so the cursor does not move to the left within the search-textbox in IE
  9016. this.focusSearch();
  9017. }
  9018. if (this.opts.dropdownAutoWidth) {
  9019. resultsListNode = $('.select2-results', $dropdown)[0];
  9020. $dropdown.addClass('select2-drop-auto-width');
  9021. $dropdown.css('width', '');
  9022. // Add scrollbar width to dropdown if vertical scrollbar is present
  9023. dropWidth = $dropdown.outerWidth(false) + (resultsListNode.scrollHeight === resultsListNode.clientHeight ? 0 : scrollBarDimensions.width);
  9024. dropWidth > width ? width = dropWidth : dropWidth = width;
  9025. dropHeight = $dropdown.outerHeight(false);
  9026. enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight;
  9027. }
  9028. else {
  9029. this.container.removeClass('select2-drop-auto-width');
  9030. }
  9031. //console.log("below/ droptop:", dropTop, "dropHeight", dropHeight, "sum", (dropTop+dropHeight)+" viewport bottom", viewportBottom, "enough?", enoughRoomBelow);
  9032. //console.log("above/ offset.top", offset.top, "dropHeight", dropHeight, "top", (offset.top-dropHeight), "scrollTop", this.body.scrollTop(), "enough?", enoughRoomAbove);
  9033. // fix positioning when body has an offset and is not position: static
  9034. if (this.body.css('position') !== 'static') {
  9035. bodyOffset = this.body.offset();
  9036. dropTop -= bodyOffset.top;
  9037. dropLeft -= bodyOffset.left;
  9038. }
  9039. if (!enoughRoomOnRight) {
  9040. dropLeft = offset.left + this.container.outerWidth(false) - dropWidth;
  9041. }
  9042. css = {
  9043. left: dropLeft,
  9044. width: width
  9045. };
  9046. if (above) {
  9047. css.top = offset.top - dropHeight;
  9048. css.bottom = 'auto';
  9049. this.container.addClass("select2-drop-above");
  9050. $dropdown.addClass("select2-drop-above");
  9051. }
  9052. else {
  9053. css.top = dropTop;
  9054. css.bottom = 'auto';
  9055. this.container.removeClass("select2-drop-above");
  9056. $dropdown.removeClass("select2-drop-above");
  9057. }
  9058. css = $.extend(css, evaluate(this.opts.dropdownCss, this.opts.element));
  9059. $dropdown.css(css);
  9060. },
  9061. // abstract
  9062. shouldOpen: function() {
  9063. var event;
  9064. if (this.opened()) return false;
  9065. if (this._enabled === false || this._readonly === true) return false;
  9066. event = $.Event("select2-opening");
  9067. this.opts.element.trigger(event);
  9068. return !event.isDefaultPrevented();
  9069. },
  9070. // abstract
  9071. clearDropdownAlignmentPreference: function() {
  9072. // clear the classes used to figure out the preference of where the dropdown should be opened
  9073. this.container.removeClass("select2-drop-above");
  9074. this.dropdown.removeClass("select2-drop-above");
  9075. },
  9076. /**
  9077. * Opens the dropdown
  9078. *
  9079. * @return {Boolean} whether or not dropdown was opened. This method will return false if, for example,
  9080. * the dropdown is already open, or if the 'open' event listener on the element called preventDefault().
  9081. */
  9082. // abstract
  9083. open: function () {
  9084. if (!this.shouldOpen()) return false;
  9085. this.opening();
  9086. // Only bind the document mousemove when the dropdown is visible
  9087. $document.on("mousemove.select2Event", function (e) {
  9088. lastMousePosition.x = e.pageX;
  9089. lastMousePosition.y = e.pageY;
  9090. });
  9091. return true;
  9092. },
  9093. /**
  9094. * Performs the opening of the dropdown
  9095. */
  9096. // abstract
  9097. opening: function() {
  9098. var cid = this.containerEventName,
  9099. scroll = "scroll." + cid,
  9100. resize = "resize."+cid,
  9101. orient = "orientationchange."+cid,
  9102. mask;
  9103. this.container.addClass("select2-dropdown-open").addClass("select2-container-active");
  9104. this.clearDropdownAlignmentPreference();
  9105. if(this.dropdown[0] !== this.body.children().last()[0]) {
  9106. this.dropdown.detach().appendTo(this.body);
  9107. }
  9108. // create the dropdown mask if doesn't already exist
  9109. mask = $("#select2-drop-mask");
  9110. if (mask.length == 0) {
  9111. mask = $(document.createElement("div"));
  9112. mask.attr("id","select2-drop-mask").attr("class","select2-drop-mask");
  9113. mask.hide();
  9114. mask.appendTo(this.body);
  9115. mask.on("mousedown touchstart click", function (e) {
  9116. // Prevent IE from generating a click event on the body
  9117. reinsertElement(mask);
  9118. var dropdown = $("#select2-drop"), self;
  9119. if (dropdown.length > 0) {
  9120. self=dropdown.data("select2");
  9121. if (self.opts.selectOnBlur) {
  9122. self.selectHighlighted({noFocus: true});
  9123. }
  9124. self.close();
  9125. e.preventDefault();
  9126. e.stopPropagation();
  9127. }
  9128. });
  9129. }
  9130. // ensure the mask is always right before the dropdown
  9131. if (this.dropdown.prev()[0] !== mask[0]) {
  9132. this.dropdown.before(mask);
  9133. }
  9134. // move the global id to the correct dropdown
  9135. $("#select2-drop").removeAttr("id");
  9136. this.dropdown.attr("id", "select2-drop");
  9137. // show the elements
  9138. mask.show();
  9139. this.positionDropdown();
  9140. this.dropdown.show();
  9141. this.positionDropdown();
  9142. this.dropdown.addClass("select2-drop-active");
  9143. // attach listeners to events that can change the position of the container and thus require
  9144. // the position of the dropdown to be updated as well so it does not come unglued from the container
  9145. var that = this;
  9146. this.container.parents().add(window).each(function () {
  9147. $(this).on(resize+" "+scroll+" "+orient, function (e) {
  9148. if (that.opened()) that.positionDropdown();
  9149. });
  9150. });
  9151. },
  9152. // abstract
  9153. close: function () {
  9154. if (!this.opened()) return;
  9155. var cid = this.containerEventName,
  9156. scroll = "scroll." + cid,
  9157. resize = "resize."+cid,
  9158. orient = "orientationchange."+cid;
  9159. // unbind event listeners
  9160. this.container.parents().add(window).each(function () { $(this).off(scroll).off(resize).off(orient); });
  9161. this.clearDropdownAlignmentPreference();
  9162. $("#select2-drop-mask").hide();
  9163. this.dropdown.removeAttr("id"); // only the active dropdown has the select2-drop id
  9164. this.dropdown.hide();
  9165. this.container.removeClass("select2-dropdown-open").removeClass("select2-container-active");
  9166. this.results.empty();
  9167. // Now that the dropdown is closed, unbind the global document mousemove event
  9168. $document.off("mousemove.select2Event");
  9169. this.clearSearch();
  9170. this.search.removeClass("select2-active");
  9171. this.opts.element.trigger($.Event("select2-close"));
  9172. },
  9173. /**
  9174. * Opens control, sets input value, and updates results.
  9175. */
  9176. // abstract
  9177. externalSearch: function (term) {
  9178. this.open();
  9179. this.search.val(term);
  9180. this.updateResults(false);
  9181. },
  9182. // abstract
  9183. clearSearch: function () {
  9184. },
  9185. //abstract
  9186. getMaximumSelectionSize: function() {
  9187. return evaluate(this.opts.maximumSelectionSize, this.opts.element);
  9188. },
  9189. // abstract
  9190. ensureHighlightVisible: function () {
  9191. var results = this.results, children, index, child, hb, rb, y, more, topOffset;
  9192. index = this.highlight();
  9193. if (index < 0) return;
  9194. if (index == 0) {
  9195. // if the first element is highlighted scroll all the way to the top,
  9196. // that way any unselectable headers above it will also be scrolled
  9197. // into view
  9198. results.scrollTop(0);
  9199. return;
  9200. }
  9201. children = this.findHighlightableChoices().find('.select2-result-label');
  9202. child = $(children[index]);
  9203. topOffset = (child.offset() || {}).top || 0;
  9204. hb = topOffset + child.outerHeight(true);
  9205. // if this is the last child lets also make sure select2-more-results is visible
  9206. if (index === children.length - 1) {
  9207. more = results.find("li.select2-more-results");
  9208. if (more.length > 0) {
  9209. hb = more.offset().top + more.outerHeight(true);
  9210. }
  9211. }
  9212. rb = results.offset().top + results.outerHeight(true);
  9213. if (hb > rb) {
  9214. results.scrollTop(results.scrollTop() + (hb - rb));
  9215. }
  9216. y = topOffset - results.offset().top;
  9217. // make sure the top of the element is visible
  9218. if (y < 0 && child.css('display') != 'none' ) {
  9219. results.scrollTop(results.scrollTop() + y); // y is negative
  9220. }
  9221. },
  9222. // abstract
  9223. findHighlightableChoices: function() {
  9224. return this.results.find(".select2-result-selectable:not(.select2-disabled):not(.select2-selected)");
  9225. },
  9226. // abstract
  9227. moveHighlight: function (delta) {
  9228. var choices = this.findHighlightableChoices(),
  9229. index = this.highlight();
  9230. while (index > -1 && index < choices.length) {
  9231. index += delta;
  9232. var choice = $(choices[index]);
  9233. if (choice.hasClass("select2-result-selectable") && !choice.hasClass("select2-disabled") && !choice.hasClass("select2-selected")) {
  9234. this.highlight(index);
  9235. break;
  9236. }
  9237. }
  9238. },
  9239. // abstract
  9240. highlight: function (index) {
  9241. var choices = this.findHighlightableChoices(),
  9242. choice,
  9243. data;
  9244. if (arguments.length === 0) {
  9245. return indexOf(choices.filter(".select2-highlighted")[0], choices.get());
  9246. }
  9247. if (index >= choices.length) index = choices.length - 1;
  9248. if (index < 0) index = 0;
  9249. this.removeHighlight();
  9250. choice = $(choices[index]);
  9251. choice.addClass("select2-highlighted");
  9252. // ensure assistive technology can determine the active choice
  9253. this.search.attr("aria-activedescendant", choice.find(".select2-result-label").attr("id"));
  9254. this.ensureHighlightVisible();
  9255. this.liveRegion.text(choice.text());
  9256. data = choice.data("select2-data");
  9257. if (data) {
  9258. this.opts.element.trigger({ type: "select2-highlight", val: this.id(data), choice: data });
  9259. }
  9260. },
  9261. removeHighlight: function() {
  9262. this.results.find(".select2-highlighted").removeClass("select2-highlighted");
  9263. },
  9264. touchMoved: function() {
  9265. this._touchMoved = true;
  9266. },
  9267. clearTouchMoved: function() {
  9268. this._touchMoved = false;
  9269. },
  9270. // abstract
  9271. countSelectableResults: function() {
  9272. return this.findHighlightableChoices().length;
  9273. },
  9274. // abstract
  9275. highlightUnderEvent: function (event) {
  9276. var el = $(event.target).closest(".select2-result-selectable");
  9277. if (el.length > 0 && !el.is(".select2-highlighted")) {
  9278. var choices = this.findHighlightableChoices();
  9279. this.highlight(choices.index(el));
  9280. } else if (el.length == 0) {
  9281. // if we are over an unselectable item remove all highlights
  9282. this.removeHighlight();
  9283. }
  9284. },
  9285. // abstract
  9286. loadMoreIfNeeded: function () {
  9287. var results = this.results,
  9288. more = results.find("li.select2-more-results"),
  9289. below, // pixels the element is below the scroll fold, below==0 is when the element is starting to be visible
  9290. page = this.resultsPage + 1,
  9291. self=this,
  9292. term=this.search.val(),
  9293. context=this.context;
  9294. if (more.length === 0) return;
  9295. below = more.offset().top - results.offset().top - results.height();
  9296. if (below <= this.opts.loadMorePadding) {
  9297. more.addClass("select2-active");
  9298. this.opts.query({
  9299. element: this.opts.element,
  9300. term: term,
  9301. page: page,
  9302. context: context,
  9303. matcher: this.opts.matcher,
  9304. callback: this.bind(function (data) {
  9305. // ignore a response if the select2 has been closed before it was received
  9306. if (!self.opened()) return;
  9307. self.opts.populateResults.call(this, results, data.results, {term: term, page: page, context:context});
  9308. self.postprocessResults(data, false, false);
  9309. if (data.more===true) {
  9310. more.detach().appendTo(results).text(evaluate(self.opts.formatLoadMore, self.opts.element, page+1));
  9311. window.setTimeout(function() { self.loadMoreIfNeeded(); }, 10);
  9312. } else {
  9313. more.remove();
  9314. }
  9315. self.positionDropdown();
  9316. self.resultsPage = page;
  9317. self.context = data.context;
  9318. this.opts.element.trigger({ type: "select2-loaded", items: data });
  9319. })});
  9320. }
  9321. },
  9322. /**
  9323. * Default tokenizer function which does nothing
  9324. */
  9325. tokenize: function() {
  9326. },
  9327. /**
  9328. * @param initial whether or not this is the call to this method right after the dropdown has been opened
  9329. */
  9330. // abstract
  9331. updateResults: function (initial) {
  9332. var search = this.search,
  9333. results = this.results,
  9334. opts = this.opts,
  9335. data,
  9336. self = this,
  9337. input,
  9338. term = search.val(),
  9339. lastTerm = $.data(this.container, "select2-last-term"),
  9340. // sequence number used to drop out-of-order responses
  9341. queryNumber;
  9342. // prevent duplicate queries against the same term
  9343. if (initial !== true && lastTerm && equal(term, lastTerm)) return;
  9344. $.data(this.container, "select2-last-term", term);
  9345. // if the search is currently hidden we do not alter the results
  9346. if (initial !== true && (this.showSearchInput === false || !this.opened())) {
  9347. return;
  9348. }
  9349. function postRender() {
  9350. search.removeClass("select2-active");
  9351. self.positionDropdown();
  9352. if (results.find('.select2-no-results,.select2-selection-limit,.select2-searching').length) {
  9353. self.liveRegion.text(results.text());
  9354. }
  9355. else {
  9356. self.liveRegion.text(self.opts.formatMatches(results.find('.select2-result-selectable').length));
  9357. }
  9358. }
  9359. function render(html) {
  9360. results.html(html);
  9361. postRender();
  9362. }
  9363. queryNumber = ++this.queryCount;
  9364. var maxSelSize = this.getMaximumSelectionSize();
  9365. if (maxSelSize >=1) {
  9366. data = this.data();
  9367. if ($.isArray(data) && data.length >= maxSelSize && checkFormatter(opts.formatSelectionTooBig, "formatSelectionTooBig")) {
  9368. render("<li class='select2-selection-limit'>" + evaluate(opts.formatSelectionTooBig, opts.element, maxSelSize) + "</li>");
  9369. return;
  9370. }
  9371. }
  9372. if (search.val().length < opts.minimumInputLength) {
  9373. if (checkFormatter(opts.formatInputTooShort, "formatInputTooShort")) {
  9374. render("<li class='select2-no-results'>" + evaluate(opts.formatInputTooShort, opts.element, search.val(), opts.minimumInputLength) + "</li>");
  9375. } else {
  9376. render("");
  9377. }
  9378. if (initial && this.showSearch) this.showSearch(true);
  9379. return;
  9380. }
  9381. if (opts.maximumInputLength && search.val().length > opts.maximumInputLength) {
  9382. if (checkFormatter(opts.formatInputTooLong, "formatInputTooLong")) {
  9383. render("<li class='select2-no-results'>" + evaluate(opts.formatInputTooLong, opts.element, search.val(), opts.maximumInputLength) + "</li>");
  9384. } else {
  9385. render("");
  9386. }
  9387. return;
  9388. }
  9389. if (opts.formatSearching && this.findHighlightableChoices().length === 0) {
  9390. render("<li class='select2-searching'>" + evaluate(opts.formatSearching, opts.element) + "</li>");
  9391. }
  9392. search.addClass("select2-active");
  9393. this.removeHighlight();
  9394. // give the tokenizer a chance to pre-process the input
  9395. input = this.tokenize();
  9396. if (input != undefined && input != null) {
  9397. search.val(input);
  9398. }
  9399. this.resultsPage = 1;
  9400. opts.query({
  9401. element: opts.element,
  9402. term: search.val(),
  9403. page: this.resultsPage,
  9404. context: null,
  9405. matcher: opts.matcher,
  9406. callback: this.bind(function (data) {
  9407. var def; // default choice
  9408. // ignore old responses
  9409. if (queryNumber != this.queryCount) {
  9410. return;
  9411. }
  9412. // ignore a response if the select2 has been closed before it was received
  9413. if (!this.opened()) {
  9414. this.search.removeClass("select2-active");
  9415. return;
  9416. }
  9417. // handle ajax error
  9418. if(data.hasError !== undefined && checkFormatter(opts.formatAjaxError, "formatAjaxError")) {
  9419. render("<li class='select2-ajax-error'>" + evaluate(opts.formatAjaxError, opts.element, data.jqXHR, data.textStatus, data.errorThrown) + "</li>");
  9420. return;
  9421. }
  9422. // save context, if any
  9423. this.context = (data.context===undefined) ? null : data.context;
  9424. // create a default choice and prepend it to the list
  9425. if (this.opts.createSearchChoice && search.val() !== "") {
  9426. def = this.opts.createSearchChoice.call(self, search.val(), data.results);
  9427. if (def !== undefined && def !== null && self.id(def) !== undefined && self.id(def) !== null) {
  9428. if ($(data.results).filter(
  9429. function () {
  9430. return equal(self.id(this), self.id(def));
  9431. }).length === 0) {
  9432. this.opts.createSearchChoicePosition(data.results, def);
  9433. }
  9434. }
  9435. }
  9436. if (data.results.length === 0 && checkFormatter(opts.formatNoMatches, "formatNoMatches")) {
  9437. render("<li class='select2-no-results'>" + evaluate(opts.formatNoMatches, opts.element, search.val()) + "</li>");
  9438. return;
  9439. }
  9440. results.empty();
  9441. self.opts.populateResults.call(this, results, data.results, {term: search.val(), page: this.resultsPage, context:null});
  9442. if (data.more === true && checkFormatter(opts.formatLoadMore, "formatLoadMore")) {
  9443. results.append("<li class='select2-more-results'>" + opts.escapeMarkup(evaluate(opts.formatLoadMore, opts.element, this.resultsPage)) + "</li>");
  9444. window.setTimeout(function() { self.loadMoreIfNeeded(); }, 10);
  9445. }
  9446. this.postprocessResults(data, initial);
  9447. postRender();
  9448. this.opts.element.trigger({ type: "select2-loaded", items: data });
  9449. })});
  9450. },
  9451. // abstract
  9452. cancel: function () {
  9453. this.close();
  9454. },
  9455. // abstract
  9456. blur: function () {
  9457. // if selectOnBlur == true, select the currently highlighted option
  9458. if (this.opts.selectOnBlur)
  9459. this.selectHighlighted({noFocus: true});
  9460. this.close();
  9461. this.container.removeClass("select2-container-active");
  9462. // synonymous to .is(':focus'), which is available in jquery >= 1.6
  9463. if (this.search[0] === document.activeElement) { this.search.blur(); }
  9464. this.clearSearch();
  9465. this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus");
  9466. },
  9467. // abstract
  9468. focusSearch: function () {
  9469. focus(this.search);
  9470. },
  9471. // abstract
  9472. selectHighlighted: function (options) {
  9473. if (this._touchMoved) {
  9474. this.clearTouchMoved();
  9475. return;
  9476. }
  9477. var index=this.highlight(),
  9478. highlighted=this.results.find(".select2-highlighted"),
  9479. data = highlighted.closest('.select2-result').data("select2-data");
  9480. if (data) {
  9481. this.highlight(index);
  9482. this.onSelect(data, options);
  9483. } else if (options && options.noFocus) {
  9484. this.close();
  9485. }
  9486. },
  9487. // abstract
  9488. getPlaceholder: function () {
  9489. var placeholderOption;
  9490. return this.opts.element.attr("placeholder") ||
  9491. this.opts.element.attr("data-placeholder") || // jquery 1.4 compat
  9492. this.opts.element.data("placeholder") ||
  9493. this.opts.placeholder ||
  9494. ((placeholderOption = this.getPlaceholderOption()) !== undefined ? placeholderOption.text() : undefined);
  9495. },
  9496. // abstract
  9497. getPlaceholderOption: function() {
  9498. if (this.select) {
  9499. var firstOption = this.select.children('option').first();
  9500. if (this.opts.placeholderOption !== undefined ) {
  9501. //Determine the placeholder option based on the specified placeholderOption setting
  9502. return (this.opts.placeholderOption === "first" && firstOption) ||
  9503. (typeof this.opts.placeholderOption === "function" && this.opts.placeholderOption(this.select));
  9504. } else if ($.trim(firstOption.text()) === "" && firstOption.val() === "") {
  9505. //No explicit placeholder option specified, use the first if it's blank
  9506. return firstOption;
  9507. }
  9508. }
  9509. },
  9510. /**
  9511. * Get the desired width for the container element. This is
  9512. * derived first from option `width` passed to select2, then
  9513. * the inline 'style' on the original element, and finally
  9514. * falls back to the jQuery calculated element width.
  9515. */
  9516. // abstract
  9517. initContainerWidth: function () {
  9518. function resolveContainerWidth() {
  9519. var style, attrs, matches, i, l, attr;
  9520. if (this.opts.width === "off") {
  9521. return null;
  9522. } else if (this.opts.width === "element"){
  9523. return this.opts.element.outerWidth(false) === 0 ? 'auto' : this.opts.element.outerWidth(false) + 'px';
  9524. } else if (this.opts.width === "copy" || this.opts.width === "resolve") {
  9525. // check if there is inline style on the element that contains width
  9526. style = this.opts.element.attr('style');
  9527. if (style !== undefined) {
  9528. attrs = style.split(';');
  9529. for (i = 0, l = attrs.length; i < l; i = i + 1) {
  9530. attr = attrs[i].replace(/\s/g, '');
  9531. matches = attr.match(/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i);
  9532. if (matches !== null && matches.length >= 1)
  9533. return matches[1];
  9534. }
  9535. }
  9536. if (this.opts.width === "resolve") {
  9537. // next check if css('width') can resolve a width that is percent based, this is sometimes possible
  9538. // when attached to input type=hidden or elements hidden via css
  9539. style = this.opts.element.css('width');
  9540. if (style.indexOf("%") > 0) return style;
  9541. // finally, fallback on the calculated width of the element
  9542. return (this.opts.element.outerWidth(false) === 0 ? 'auto' : this.opts.element.outerWidth(false) + 'px');
  9543. }
  9544. return null;
  9545. } else if ($.isFunction(this.opts.width)) {
  9546. return this.opts.width();
  9547. } else {
  9548. return this.opts.width;
  9549. }
  9550. };
  9551. var width = resolveContainerWidth.call(this);
  9552. if (width !== null) {
  9553. this.container.css("width", width);
  9554. }
  9555. }
  9556. });
  9557. SingleSelect2 = clazz(AbstractSelect2, {
  9558. // single
  9559. createContainer: function () {
  9560. var container = $(document.createElement("div")).attr({
  9561. "class": "select2-container"
  9562. }).html([
  9563. "<a href='javascript:void(0)' class='select2-choice' tabindex='-1'>",
  9564. " <span class='select2-chosen'>&#160;</span><abbr class='select2-search-choice-close'></abbr>",
  9565. " <span class='select2-arrow' role='presentation'><b role='presentation'></b></span>",
  9566. "</a>",
  9567. "<label for='' class='select2-offscreen'></label>",
  9568. "<input class='select2-focusser select2-offscreen' type='text' aria-haspopup='true' role='button' />",
  9569. "<div class='select2-drop select2-display-none'>",
  9570. " <div class='select2-search'>",
  9571. " <label for='' class='select2-offscreen'></label>",
  9572. " <input type='text' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' class='select2-input' role='combobox' aria-expanded='true'",
  9573. " aria-autocomplete='list' />",
  9574. " </div>",
  9575. " <ul class='select2-results' role='listbox'>",
  9576. " </ul>",
  9577. "</div>"].join(""));
  9578. return container;
  9579. },
  9580. // single
  9581. enableInterface: function() {
  9582. if (this.parent.enableInterface.apply(this, arguments)) {
  9583. this.focusser.prop("disabled", !this.isInterfaceEnabled());
  9584. }
  9585. },
  9586. // single
  9587. opening: function () {
  9588. var el, range, len;
  9589. if (this.opts.minimumResultsForSearch >= 0) {
  9590. this.showSearch(true);
  9591. }
  9592. this.parent.opening.apply(this, arguments);
  9593. if (this.showSearchInput !== false) {
  9594. // IE appends focusser.val() at the end of field :/ so we manually insert it at the beginning using a range
  9595. // all other browsers handle this just fine
  9596. this.search.val(this.focusser.val());
  9597. }
  9598. if (this.opts.shouldFocusInput(this)) {
  9599. this.search.focus();
  9600. // move the cursor to the end after focussing, otherwise it will be at the beginning and
  9601. // new text will appear *before* focusser.val()
  9602. el = this.search.get(0);
  9603. if (el.createTextRange) {
  9604. range = el.createTextRange();
  9605. range.collapse(false);
  9606. range.select();
  9607. } else if (el.setSelectionRange) {
  9608. len = this.search.val().length;
  9609. el.setSelectionRange(len, len);
  9610. }
  9611. }
  9612. // initializes search's value with nextSearchTerm (if defined by user)
  9613. // ignore nextSearchTerm if the dropdown is opened by the user pressing a letter
  9614. if(this.search.val() === "") {
  9615. if(this.nextSearchTerm != undefined){
  9616. this.search.val(this.nextSearchTerm);
  9617. this.search.select();
  9618. }
  9619. }
  9620. this.focusser.prop("disabled", true).val("");
  9621. this.updateResults(true);
  9622. this.opts.element.trigger($.Event("select2-open"));
  9623. },
  9624. // single
  9625. close: function () {
  9626. if (!this.opened()) return;
  9627. this.parent.close.apply(this, arguments);
  9628. this.focusser.prop("disabled", false);
  9629. if (this.opts.shouldFocusInput(this)) {
  9630. this.focusser.focus();
  9631. }
  9632. },
  9633. // single
  9634. focus: function () {
  9635. if (this.opened()) {
  9636. this.close();
  9637. } else {
  9638. this.focusser.prop("disabled", false);
  9639. if (this.opts.shouldFocusInput(this)) {
  9640. this.focusser.focus();
  9641. }
  9642. }
  9643. },
  9644. // single
  9645. isFocused: function () {
  9646. return this.container.hasClass("select2-container-active");
  9647. },
  9648. // single
  9649. cancel: function () {
  9650. this.parent.cancel.apply(this, arguments);
  9651. this.focusser.prop("disabled", false);
  9652. if (this.opts.shouldFocusInput(this)) {
  9653. this.focusser.focus();
  9654. }
  9655. },
  9656. // single
  9657. destroy: function() {
  9658. $("label[for='" + this.focusser.attr('id') + "']")
  9659. .attr('for', this.opts.element.attr("id"));
  9660. this.parent.destroy.apply(this, arguments);
  9661. cleanupJQueryElements.call(this,
  9662. "selection",
  9663. "focusser"
  9664. );
  9665. },
  9666. // single
  9667. initContainer: function () {
  9668. var selection,
  9669. container = this.container,
  9670. dropdown = this.dropdown,
  9671. idSuffix = nextUid(),
  9672. elementLabel;
  9673. if (this.opts.minimumResultsForSearch < 0) {
  9674. this.showSearch(false);
  9675. } else {
  9676. this.showSearch(true);
  9677. }
  9678. this.selection = selection = container.find(".select2-choice");
  9679. this.focusser = container.find(".select2-focusser");
  9680. // add aria associations
  9681. selection.find(".select2-chosen").attr("id", "select2-chosen-"+idSuffix);
  9682. this.focusser.attr("aria-labelledby", "select2-chosen-"+idSuffix);
  9683. this.results.attr("id", "select2-results-"+idSuffix);
  9684. this.search.attr("aria-owns", "select2-results-"+idSuffix);
  9685. // rewrite labels from original element to focusser
  9686. this.focusser.attr("id", "s2id_autogen"+idSuffix);
  9687. elementLabel = $("label[for='" + this.opts.element.attr("id") + "']");
  9688. this.focusser.prev()
  9689. .text(elementLabel.text())
  9690. .attr('for', this.focusser.attr('id'));
  9691. // Ensure the original element retains an accessible name
  9692. var originalTitle = this.opts.element.attr("title");
  9693. this.opts.element.attr("title", (originalTitle || elementLabel.text()));
  9694. this.focusser.attr("tabindex", this.elementTabIndex);
  9695. // write label for search field using the label from the focusser element
  9696. this.search.attr("id", this.focusser.attr('id') + '_search');
  9697. this.search.prev()
  9698. .text($("label[for='" + this.focusser.attr('id') + "']").text())
  9699. .attr('for', this.search.attr('id'));
  9700. this.search.on("keydown", this.bind(function (e) {
  9701. if (!this.isInterfaceEnabled()) return;
  9702. // filter 229 keyCodes (input method editor is processing key input)
  9703. if (229 == e.keyCode) return;
  9704. if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN) {
  9705. // prevent the page from scrolling
  9706. killEvent(e);
  9707. return;
  9708. }
  9709. switch (e.which) {
  9710. case KEY.UP:
  9711. case KEY.DOWN:
  9712. this.moveHighlight((e.which === KEY.UP) ? -1 : 1);
  9713. killEvent(e);
  9714. return;
  9715. case KEY.ENTER:
  9716. this.selectHighlighted();
  9717. killEvent(e);
  9718. return;
  9719. case KEY.TAB:
  9720. this.selectHighlighted({noFocus: true});
  9721. return;
  9722. case KEY.ESC:
  9723. this.cancel(e);
  9724. killEvent(e);
  9725. return;
  9726. }
  9727. }));
  9728. this.search.on("blur", this.bind(function(e) {
  9729. // a workaround for chrome to keep the search field focussed when the scroll bar is used to scroll the dropdown.
  9730. // without this the search field loses focus which is annoying
  9731. if (document.activeElement === this.body.get(0)) {
  9732. window.setTimeout(this.bind(function() {
  9733. if (this.opened()) {
  9734. this.search.focus();
  9735. }
  9736. }), 0);
  9737. }
  9738. }));
  9739. this.focusser.on("keydown", this.bind(function (e) {
  9740. if (!this.isInterfaceEnabled()) return;
  9741. if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC) {
  9742. return;
  9743. }
  9744. if (this.opts.openOnEnter === false && e.which === KEY.ENTER) {
  9745. killEvent(e);
  9746. return;
  9747. }
  9748. if (e.which == KEY.DOWN || e.which == KEY.UP
  9749. || (e.which == KEY.ENTER && this.opts.openOnEnter)) {
  9750. if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) return;
  9751. this.open();
  9752. killEvent(e);
  9753. return;
  9754. }
  9755. if (e.which == KEY.DELETE || e.which == KEY.BACKSPACE) {
  9756. if (this.opts.allowClear) {
  9757. this.clear();
  9758. }
  9759. killEvent(e);
  9760. return;
  9761. }
  9762. }));
  9763. installKeyUpChangeEvent(this.focusser);
  9764. this.focusser.on("keyup-change input", this.bind(function(e) {
  9765. if (this.opts.minimumResultsForSearch >= 0) {
  9766. e.stopPropagation();
  9767. if (this.opened()) return;
  9768. this.open();
  9769. }
  9770. }));
  9771. selection.on("mousedown touchstart", "abbr", this.bind(function (e) {
  9772. if (!this.isInterfaceEnabled()) return;
  9773. this.clear();
  9774. killEventImmediately(e);
  9775. this.close();
  9776. this.selection.focus();
  9777. }));
  9778. selection.on("mousedown touchstart", this.bind(function (e) {
  9779. // Prevent IE from generating a click event on the body
  9780. reinsertElement(selection);
  9781. if (!this.container.hasClass("select2-container-active")) {
  9782. this.opts.element.trigger($.Event("select2-focus"));
  9783. }
  9784. if (this.opened()) {
  9785. this.close();
  9786. } else if (this.isInterfaceEnabled()) {
  9787. this.open();
  9788. }
  9789. killEvent(e);
  9790. }));
  9791. dropdown.on("mousedown touchstart", this.bind(function() {
  9792. if (this.opts.shouldFocusInput(this)) {
  9793. this.search.focus();
  9794. }
  9795. }));
  9796. selection.on("focus", this.bind(function(e) {
  9797. killEvent(e);
  9798. }));
  9799. this.focusser.on("focus", this.bind(function(){
  9800. if (!this.container.hasClass("select2-container-active")) {
  9801. this.opts.element.trigger($.Event("select2-focus"));
  9802. }
  9803. this.container.addClass("select2-container-active");
  9804. })).on("blur", this.bind(function() {
  9805. if (!this.opened()) {
  9806. this.container.removeClass("select2-container-active");
  9807. this.opts.element.trigger($.Event("select2-blur"));
  9808. }
  9809. }));
  9810. this.search.on("focus", this.bind(function(){
  9811. if (!this.container.hasClass("select2-container-active")) {
  9812. this.opts.element.trigger($.Event("select2-focus"));
  9813. }
  9814. this.container.addClass("select2-container-active");
  9815. }));
  9816. this.initContainerWidth();
  9817. this.opts.element.addClass("select2-offscreen");
  9818. this.setPlaceholder();
  9819. },
  9820. // single
  9821. clear: function(triggerChange) {
  9822. var data=this.selection.data("select2-data");
  9823. if (data) { // guard against queued quick consecutive clicks
  9824. var evt = $.Event("select2-clearing");
  9825. this.opts.element.trigger(evt);
  9826. if (evt.isDefaultPrevented()) {
  9827. return;
  9828. }
  9829. var placeholderOption = this.getPlaceholderOption();
  9830. this.opts.element.val(placeholderOption ? placeholderOption.val() : "");
  9831. this.selection.find(".select2-chosen").empty();
  9832. this.selection.removeData("select2-data");
  9833. this.setPlaceholder();
  9834. if (triggerChange !== false){
  9835. this.opts.element.trigger({ type: "select2-removed", val: this.id(data), choice: data });
  9836. this.triggerChange({removed:data});
  9837. }
  9838. }
  9839. },
  9840. /**
  9841. * Sets selection based on source element's value
  9842. */
  9843. // single
  9844. initSelection: function () {
  9845. var selected;
  9846. if (this.isPlaceholderOptionSelected()) {
  9847. this.updateSelection(null);
  9848. this.close();
  9849. this.setPlaceholder();
  9850. } else {
  9851. var self = this;
  9852. this.opts.initSelection.call(null, this.opts.element, function(selected){
  9853. if (selected !== undefined && selected !== null) {
  9854. self.updateSelection(selected);
  9855. self.close();
  9856. self.setPlaceholder();
  9857. self.nextSearchTerm = self.opts.nextSearchTerm(selected, self.search.val());
  9858. }
  9859. });
  9860. }
  9861. },
  9862. isPlaceholderOptionSelected: function() {
  9863. var placeholderOption;
  9864. if (this.getPlaceholder() === undefined) return false; // no placeholder specified so no option should be considered
  9865. return ((placeholderOption = this.getPlaceholderOption()) !== undefined && placeholderOption.prop("selected"))
  9866. || (this.opts.element.val() === "")
  9867. || (this.opts.element.val() === undefined)
  9868. || (this.opts.element.val() === null);
  9869. },
  9870. // single
  9871. prepareOpts: function () {
  9872. var opts = this.parent.prepareOpts.apply(this, arguments),
  9873. self=this;
  9874. if (opts.element.get(0).tagName.toLowerCase() === "select") {
  9875. // install the selection initializer
  9876. opts.initSelection = function (element, callback) {
  9877. var selected = element.find("option").filter(function() { return this.selected && !this.disabled });
  9878. // a single select box always has a value, no need to null check 'selected'
  9879. callback(self.optionToData(selected));
  9880. };
  9881. } else if ("data" in opts) {
  9882. // install default initSelection when applied to hidden input and data is local
  9883. opts.initSelection = opts.initSelection || function (element, callback) {
  9884. var id = element.val();
  9885. //search in data by id, storing the actual matching item
  9886. var match = null;
  9887. opts.query({
  9888. matcher: function(term, text, el){
  9889. var is_match = equal(id, opts.id(el));
  9890. if (is_match) {
  9891. match = el;
  9892. }
  9893. return is_match;
  9894. },
  9895. callback: !$.isFunction(callback) ? $.noop : function() {
  9896. callback(match);
  9897. }
  9898. });
  9899. };
  9900. }
  9901. return opts;
  9902. },
  9903. // single
  9904. getPlaceholder: function() {
  9905. // if a placeholder is specified on a single select without a valid placeholder option ignore it
  9906. if (this.select) {
  9907. if (this.getPlaceholderOption() === undefined) {
  9908. return undefined;
  9909. }
  9910. }
  9911. return this.parent.getPlaceholder.apply(this, arguments);
  9912. },
  9913. // single
  9914. setPlaceholder: function () {
  9915. var placeholder = this.getPlaceholder();
  9916. if (this.isPlaceholderOptionSelected() && placeholder !== undefined) {
  9917. // check for a placeholder option if attached to a select
  9918. if (this.select && this.getPlaceholderOption() === undefined) return;
  9919. this.selection.find(".select2-chosen").html(this.opts.escapeMarkup(placeholder));
  9920. this.selection.addClass("select2-default");
  9921. this.container.removeClass("select2-allowclear");
  9922. }
  9923. },
  9924. // single
  9925. postprocessResults: function (data, initial, noHighlightUpdate) {
  9926. var selected = 0, self = this, showSearchInput = true;
  9927. // find the selected element in the result list
  9928. this.findHighlightableChoices().each2(function (i, elm) {
  9929. if (equal(self.id(elm.data("select2-data")), self.opts.element.val())) {
  9930. selected = i;
  9931. return false;
  9932. }
  9933. });
  9934. // and highlight it
  9935. if (noHighlightUpdate !== false) {
  9936. if (initial === true && selected >= 0) {
  9937. this.highlight(selected);
  9938. } else {
  9939. this.highlight(0);
  9940. }
  9941. }
  9942. // hide the search box if this is the first we got the results and there are enough of them for search
  9943. if (initial === true) {
  9944. var min = this.opts.minimumResultsForSearch;
  9945. if (min >= 0) {
  9946. this.showSearch(countResults(data.results) >= min);
  9947. }
  9948. }
  9949. },
  9950. // single
  9951. showSearch: function(showSearchInput) {
  9952. if (this.showSearchInput === showSearchInput) return;
  9953. this.showSearchInput = showSearchInput;
  9954. this.dropdown.find(".select2-search").toggleClass("select2-search-hidden", !showSearchInput);
  9955. this.dropdown.find(".select2-search").toggleClass("select2-offscreen", !showSearchInput);
  9956. //add "select2-with-searchbox" to the container if search box is shown
  9957. $(this.dropdown, this.container).toggleClass("select2-with-searchbox", showSearchInput);
  9958. },
  9959. // single
  9960. onSelect: function (data, options) {
  9961. if (!this.triggerSelect(data)) { return; }
  9962. var old = this.opts.element.val(),
  9963. oldData = this.data();
  9964. this.opts.element.val(this.id(data));
  9965. this.updateSelection(data);
  9966. this.opts.element.trigger({ type: "select2-selected", val: this.id(data), choice: data });
  9967. this.nextSearchTerm = this.opts.nextSearchTerm(data, this.search.val());
  9968. this.close();
  9969. if ((!options || !options.noFocus) && this.opts.shouldFocusInput(this)) {
  9970. this.focusser.focus();
  9971. }
  9972. if (!equal(old, this.id(data))) {
  9973. this.triggerChange({ added: data, removed: oldData });
  9974. }
  9975. },
  9976. // single
  9977. updateSelection: function (data) {
  9978. var container=this.selection.find(".select2-chosen"), formatted, cssClass;
  9979. this.selection.data("select2-data", data);
  9980. container.empty();
  9981. if (data !== null) {
  9982. formatted=this.opts.formatSelection(data, container, this.opts.escapeMarkup);
  9983. }
  9984. if (formatted !== undefined) {
  9985. container.append(formatted);
  9986. }
  9987. cssClass=this.opts.formatSelectionCssClass(data, container);
  9988. if (cssClass !== undefined) {
  9989. container.addClass(cssClass);
  9990. }
  9991. this.selection.removeClass("select2-default");
  9992. if (this.opts.allowClear && this.getPlaceholder() !== undefined) {
  9993. this.container.addClass("select2-allowclear");
  9994. }
  9995. },
  9996. // single
  9997. val: function () {
  9998. var val,
  9999. triggerChange = false,
  10000. data = null,
  10001. self = this,
  10002. oldData = this.data();
  10003. if (arguments.length === 0) {
  10004. return this.opts.element.val();
  10005. }
  10006. val = arguments[0];
  10007. if (arguments.length > 1) {
  10008. triggerChange = arguments[1];
  10009. }
  10010. if (this.select) {
  10011. this.select
  10012. .val(val)
  10013. .find("option").filter(function() { return this.selected }).each2(function (i, elm) {
  10014. data = self.optionToData(elm);
  10015. return false;
  10016. });
  10017. this.updateSelection(data);
  10018. this.setPlaceholder();
  10019. if (triggerChange) {
  10020. this.triggerChange({added: data, removed:oldData});
  10021. }
  10022. } else {
  10023. // val is an id. !val is true for [undefined,null,'',0] - 0 is legal
  10024. if (!val && val !== 0) {
  10025. this.clear(triggerChange);
  10026. return;
  10027. }
  10028. if (this.opts.initSelection === undefined) {
  10029. throw new Error("cannot call val() if initSelection() is not defined");
  10030. }
  10031. this.opts.element.val(val);
  10032. this.opts.initSelection(this.opts.element, function(data){
  10033. self.opts.element.val(!data ? "" : self.id(data));
  10034. self.updateSelection(data);
  10035. self.setPlaceholder();
  10036. if (triggerChange) {
  10037. self.triggerChange({added: data, removed:oldData});
  10038. }
  10039. });
  10040. }
  10041. },
  10042. // single
  10043. clearSearch: function () {
  10044. this.search.val("");
  10045. this.focusser.val("");
  10046. },
  10047. // single
  10048. data: function(value) {
  10049. var data,
  10050. triggerChange = false;
  10051. if (arguments.length === 0) {
  10052. data = this.selection.data("select2-data");
  10053. if (data == undefined) data = null;
  10054. return data;
  10055. } else {
  10056. if (arguments.length > 1) {
  10057. triggerChange = arguments[1];
  10058. }
  10059. if (!value) {
  10060. this.clear(triggerChange);
  10061. } else {
  10062. data = this.data();
  10063. this.opts.element.val(!value ? "" : this.id(value));
  10064. this.updateSelection(value);
  10065. if (triggerChange) {
  10066. this.triggerChange({added: value, removed:data});
  10067. }
  10068. }
  10069. }
  10070. }
  10071. });
  10072. MultiSelect2 = clazz(AbstractSelect2, {
  10073. // multi
  10074. createContainer: function () {
  10075. var container = $(document.createElement("div")).attr({
  10076. "class": "select2-container select2-container-multi"
  10077. }).html([
  10078. "<ul class='select2-choices'>",
  10079. " <li class='select2-search-field'>",
  10080. " <label for='' class='select2-offscreen'></label>",
  10081. " <input type='text' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' class='select2-input'>",
  10082. " </li>",
  10083. "</ul>",
  10084. "<div class='select2-drop select2-drop-multi select2-display-none'>",
  10085. " <ul class='select2-results'>",
  10086. " </ul>",
  10087. "</div>"].join(""));
  10088. return container;
  10089. },
  10090. // multi
  10091. prepareOpts: function () {
  10092. var opts = this.parent.prepareOpts.apply(this, arguments),
  10093. self=this;
  10094. // TODO validate placeholder is a string if specified
  10095. if (opts.element.get(0).tagName.toLowerCase() === "select") {
  10096. // install the selection initializer
  10097. opts.initSelection = function (element, callback) {
  10098. var data = [];
  10099. element.find("option").filter(function() { return this.selected && !this.disabled }).each2(function (i, elm) {
  10100. data.push(self.optionToData(elm));
  10101. });
  10102. callback(data);
  10103. };
  10104. } else if ("data" in opts) {
  10105. // install default initSelection when applied to hidden input and data is local
  10106. opts.initSelection = opts.initSelection || function (element, callback) {
  10107. var ids = splitVal(element.val(), opts.separator);
  10108. //search in data by array of ids, storing matching items in a list
  10109. var matches = [];
  10110. opts.query({
  10111. matcher: function(term, text, el){
  10112. var is_match = $.grep(ids, function(id) {
  10113. return equal(id, opts.id(el));
  10114. }).length;
  10115. if (is_match) {
  10116. matches.push(el);
  10117. }
  10118. return is_match;
  10119. },
  10120. callback: !$.isFunction(callback) ? $.noop : function() {
  10121. // reorder matches based on the order they appear in the ids array because right now
  10122. // they are in the order in which they appear in data array
  10123. var ordered = [];
  10124. for (var i = 0; i < ids.length; i++) {
  10125. var id = ids[i];
  10126. for (var j = 0; j < matches.length; j++) {
  10127. var match = matches[j];
  10128. if (equal(id, opts.id(match))) {
  10129. ordered.push(match);
  10130. matches.splice(j, 1);
  10131. break;
  10132. }
  10133. }
  10134. }
  10135. callback(ordered);
  10136. }
  10137. });
  10138. };
  10139. }
  10140. return opts;
  10141. },
  10142. // multi
  10143. selectChoice: function (choice) {
  10144. var selected = this.container.find(".select2-search-choice-focus");
  10145. if (selected.length && choice && choice[0] == selected[0]) {
  10146. } else {
  10147. if (selected.length) {
  10148. this.opts.element.trigger("choice-deselected", selected);
  10149. }
  10150. selected.removeClass("select2-search-choice-focus");
  10151. if (choice && choice.length) {
  10152. this.close();
  10153. choice.addClass("select2-search-choice-focus");
  10154. this.opts.element.trigger("choice-selected", choice);
  10155. }
  10156. }
  10157. },
  10158. // multi
  10159. destroy: function() {
  10160. $("label[for='" + this.search.attr('id') + "']")
  10161. .attr('for', this.opts.element.attr("id"));
  10162. this.parent.destroy.apply(this, arguments);
  10163. cleanupJQueryElements.call(this,
  10164. "searchContainer",
  10165. "selection"
  10166. );
  10167. },
  10168. // multi
  10169. initContainer: function () {
  10170. var selector = ".select2-choices", selection;
  10171. this.searchContainer = this.container.find(".select2-search-field");
  10172. this.selection = selection = this.container.find(selector);
  10173. var _this = this;
  10174. this.selection.on("click", ".select2-search-choice:not(.select2-locked)", function (e) {
  10175. //killEvent(e);
  10176. _this.search[0].focus();
  10177. _this.selectChoice($(this));
  10178. });
  10179. // rewrite labels from original element to focusser
  10180. this.search.attr("id", "s2id_autogen"+nextUid());
  10181. this.search.prev()
  10182. .text($("label[for='" + this.opts.element.attr("id") + "']").text())
  10183. .attr('for', this.search.attr('id'));
  10184. this.search.on("input paste", this.bind(function() {
  10185. if (this.search.attr('placeholder') && this.search.val().length == 0) return;
  10186. if (!this.isInterfaceEnabled()) return;
  10187. if (!this.opened()) {
  10188. this.open();
  10189. }
  10190. }));
  10191. this.search.attr("tabindex", this.elementTabIndex);
  10192. this.keydowns = 0;
  10193. this.search.on("keydown", this.bind(function (e) {
  10194. if (!this.isInterfaceEnabled()) return;
  10195. ++this.keydowns;
  10196. var selected = selection.find(".select2-search-choice-focus");
  10197. var prev = selected.prev(".select2-search-choice:not(.select2-locked)");
  10198. var next = selected.next(".select2-search-choice:not(.select2-locked)");
  10199. var pos = getCursorInfo(this.search);
  10200. if (selected.length &&
  10201. (e.which == KEY.LEFT || e.which == KEY.RIGHT || e.which == KEY.BACKSPACE || e.which == KEY.DELETE || e.which == KEY.ENTER)) {
  10202. var selectedChoice = selected;
  10203. if (e.which == KEY.LEFT && prev.length) {
  10204. selectedChoice = prev;
  10205. }
  10206. else if (e.which == KEY.RIGHT) {
  10207. selectedChoice = next.length ? next : null;
  10208. }
  10209. else if (e.which === KEY.BACKSPACE) {
  10210. if (this.unselect(selected.first())) {
  10211. this.search.width(10);
  10212. selectedChoice = prev.length ? prev : next;
  10213. }
  10214. } else if (e.which == KEY.DELETE) {
  10215. if (this.unselect(selected.first())) {
  10216. this.search.width(10);
  10217. selectedChoice = next.length ? next : null;
  10218. }
  10219. } else if (e.which == KEY.ENTER) {
  10220. selectedChoice = null;
  10221. }
  10222. this.selectChoice(selectedChoice);
  10223. killEvent(e);
  10224. if (!selectedChoice || !selectedChoice.length) {
  10225. this.open();
  10226. }
  10227. return;
  10228. } else if (((e.which === KEY.BACKSPACE && this.keydowns == 1)
  10229. || e.which == KEY.LEFT) && (pos.offset == 0 && !pos.length)) {
  10230. this.selectChoice(selection.find(".select2-search-choice:not(.select2-locked)").last());
  10231. killEvent(e);
  10232. return;
  10233. } else {
  10234. this.selectChoice(null);
  10235. }
  10236. if (this.opened()) {
  10237. switch (e.which) {
  10238. case KEY.UP:
  10239. case KEY.DOWN:
  10240. this.moveHighlight((e.which === KEY.UP) ? -1 : 1);
  10241. killEvent(e);
  10242. return;
  10243. case KEY.ENTER:
  10244. this.selectHighlighted();
  10245. killEvent(e);
  10246. return;
  10247. case KEY.TAB:
  10248. this.selectHighlighted({noFocus:true});
  10249. this.close();
  10250. return;
  10251. case KEY.ESC:
  10252. this.cancel(e);
  10253. killEvent(e);
  10254. return;
  10255. }
  10256. }
  10257. if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e)
  10258. || e.which === KEY.BACKSPACE || e.which === KEY.ESC) {
  10259. return;
  10260. }
  10261. if (e.which === KEY.ENTER) {
  10262. if (this.opts.openOnEnter === false) {
  10263. return;
  10264. } else if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) {
  10265. return;
  10266. }
  10267. }
  10268. this.open();
  10269. if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN) {
  10270. // prevent the page from scrolling
  10271. killEvent(e);
  10272. }
  10273. if (e.which === KEY.ENTER) {
  10274. // prevent form from being submitted
  10275. killEvent(e);
  10276. }
  10277. }));
  10278. this.search.on("keyup", this.bind(function (e) {
  10279. this.keydowns = 0;
  10280. this.resizeSearch();
  10281. })
  10282. );
  10283. this.search.on("blur", this.bind(function(e) {
  10284. this.container.removeClass("select2-container-active");
  10285. this.search.removeClass("select2-focused");
  10286. this.selectChoice(null);
  10287. if (!this.opened()) this.clearSearch();
  10288. e.stopImmediatePropagation();
  10289. this.opts.element.trigger($.Event("select2-blur"));
  10290. }));
  10291. this.container.on("click", selector, this.bind(function (e) {
  10292. if (!this.isInterfaceEnabled()) return;
  10293. if ($(e.target).closest(".select2-search-choice").length > 0) {
  10294. // clicked inside a select2 search choice, do not open
  10295. return;
  10296. }
  10297. this.selectChoice(null);
  10298. this.clearPlaceholder();
  10299. if (!this.container.hasClass("select2-container-active")) {
  10300. this.opts.element.trigger($.Event("select2-focus"));
  10301. }
  10302. this.open();
  10303. this.focusSearch();
  10304. e.preventDefault();
  10305. }));
  10306. this.container.on("focus", selector, this.bind(function () {
  10307. if (!this.isInterfaceEnabled()) return;
  10308. if (!this.container.hasClass("select2-container-active")) {
  10309. this.opts.element.trigger($.Event("select2-focus"));
  10310. }
  10311. this.container.addClass("select2-container-active");
  10312. this.dropdown.addClass("select2-drop-active");
  10313. this.clearPlaceholder();
  10314. }));
  10315. this.initContainerWidth();
  10316. this.opts.element.addClass("select2-offscreen");
  10317. // set the placeholder if necessary
  10318. this.clearSearch();
  10319. },
  10320. // multi
  10321. enableInterface: function() {
  10322. if (this.parent.enableInterface.apply(this, arguments)) {
  10323. this.search.prop("disabled", !this.isInterfaceEnabled());
  10324. }
  10325. },
  10326. // multi
  10327. initSelection: function () {
  10328. var data;
  10329. if (this.opts.element.val() === "" && this.opts.element.text() === "") {
  10330. this.updateSelection([]);
  10331. this.close();
  10332. // set the placeholder if necessary
  10333. this.clearSearch();
  10334. }
  10335. if (this.select || this.opts.element.val() !== "") {
  10336. var self = this;
  10337. this.opts.initSelection.call(null, this.opts.element, function(data){
  10338. if (data !== undefined && data !== null) {
  10339. self.updateSelection(data);
  10340. self.close();
  10341. // set the placeholder if necessary
  10342. self.clearSearch();
  10343. }
  10344. });
  10345. }
  10346. },
  10347. // multi
  10348. clearSearch: function () {
  10349. var placeholder = this.getPlaceholder(),
  10350. maxWidth = this.getMaxSearchWidth();
  10351. if (placeholder !== undefined && this.getVal().length === 0 && this.search.hasClass("select2-focused") === false) {
  10352. this.search.val(placeholder).addClass("select2-default");
  10353. // stretch the search box to full width of the container so as much of the placeholder is visible as possible
  10354. // we could call this.resizeSearch(), but we do not because that requires a sizer and we do not want to create one so early because of a firefox bug, see #944
  10355. this.search.width(maxWidth > 0 ? maxWidth : this.container.css("width"));
  10356. } else {
  10357. this.search.val("").width(10);
  10358. }
  10359. },
  10360. // multi
  10361. clearPlaceholder: function () {
  10362. if (this.search.hasClass("select2-default")) {
  10363. this.search.val("").removeClass("select2-default");
  10364. }
  10365. },
  10366. // multi
  10367. opening: function () {
  10368. this.clearPlaceholder(); // should be done before super so placeholder is not used to search
  10369. this.resizeSearch();
  10370. this.parent.opening.apply(this, arguments);
  10371. this.focusSearch();
  10372. // initializes search's value with nextSearchTerm (if defined by user)
  10373. // ignore nextSearchTerm if the dropdown is opened by the user pressing a letter
  10374. if(this.search.val() === "") {
  10375. if(this.nextSearchTerm != undefined){
  10376. this.search.val(this.nextSearchTerm);
  10377. this.search.select();
  10378. }
  10379. }
  10380. this.updateResults(true);
  10381. if (this.opts.shouldFocusInput(this)) {
  10382. this.search.focus();
  10383. }
  10384. this.opts.element.trigger($.Event("select2-open"));
  10385. },
  10386. // multi
  10387. close: function () {
  10388. if (!this.opened()) return;
  10389. this.parent.close.apply(this, arguments);
  10390. },
  10391. // multi
  10392. focus: function () {
  10393. this.close();
  10394. this.search.focus();
  10395. },
  10396. // multi
  10397. isFocused: function () {
  10398. return this.search.hasClass("select2-focused");
  10399. },
  10400. // multi
  10401. updateSelection: function (data) {
  10402. var ids = [], filtered = [], self = this;
  10403. // filter out duplicates
  10404. $(data).each(function () {
  10405. if (indexOf(self.id(this), ids) < 0) {
  10406. ids.push(self.id(this));
  10407. filtered.push(this);
  10408. }
  10409. });
  10410. data = filtered;
  10411. this.selection.find(".select2-search-choice").remove();
  10412. $(data).each(function () {
  10413. self.addSelectedChoice(this);
  10414. });
  10415. self.postprocessResults();
  10416. },
  10417. // multi
  10418. tokenize: function() {
  10419. var input = this.search.val();
  10420. input = this.opts.tokenizer.call(this, input, this.data(), this.bind(this.onSelect), this.opts);
  10421. if (input != null && input != undefined) {
  10422. this.search.val(input);
  10423. if (input.length > 0) {
  10424. this.open();
  10425. }
  10426. }
  10427. },
  10428. // multi
  10429. onSelect: function (data, options) {
  10430. if (!this.triggerSelect(data) || data.text === "") { return; }
  10431. this.addSelectedChoice(data);
  10432. this.opts.element.trigger({ type: "selected", val: this.id(data), choice: data });
  10433. // keep track of the search's value before it gets cleared
  10434. this.nextSearchTerm = this.opts.nextSearchTerm(data, this.search.val());
  10435. this.clearSearch();
  10436. this.updateResults();
  10437. if (this.select || !this.opts.closeOnSelect) this.postprocessResults(data, false, this.opts.closeOnSelect===true);
  10438. if (this.opts.closeOnSelect) {
  10439. this.close();
  10440. this.search.width(10);
  10441. } else {
  10442. if (this.countSelectableResults()>0) {
  10443. this.search.width(10);
  10444. this.resizeSearch();
  10445. if (this.getMaximumSelectionSize() > 0 && this.val().length >= this.getMaximumSelectionSize()) {
  10446. // if we reached max selection size repaint the results so choices
  10447. // are replaced with the max selection reached message
  10448. this.updateResults(true);
  10449. } else {
  10450. // initializes search's value with nextSearchTerm and update search result
  10451. if(this.nextSearchTerm != undefined){
  10452. this.search.val(this.nextSearchTerm);
  10453. this.updateResults();
  10454. this.search.select();
  10455. }
  10456. }
  10457. this.positionDropdown();
  10458. } else {
  10459. // if nothing left to select close
  10460. this.close();
  10461. this.search.width(10);
  10462. }
  10463. }
  10464. // since its not possible to select an element that has already been
  10465. // added we do not need to check if this is a new element before firing change
  10466. this.triggerChange({ added: data });
  10467. if (!options || !options.noFocus)
  10468. this.focusSearch();
  10469. },
  10470. // multi
  10471. cancel: function () {
  10472. this.close();
  10473. this.focusSearch();
  10474. },
  10475. addSelectedChoice: function (data) {
  10476. var enableChoice = !data.locked,
  10477. enabledItem = $(
  10478. "<li class='select2-search-choice'>" +
  10479. " <div></div>" +
  10480. " <a href='#' class='select2-search-choice-close' tabindex='-1'></a>" +
  10481. "</li>"),
  10482. disabledItem = $(
  10483. "<li class='select2-search-choice select2-locked'>" +
  10484. "<div></div>" +
  10485. "</li>");
  10486. var choice = enableChoice ? enabledItem : disabledItem,
  10487. id = this.id(data),
  10488. val = this.getVal(),
  10489. formatted,
  10490. cssClass;
  10491. formatted=this.opts.formatSelection(data, choice.find("div"), this.opts.escapeMarkup);
  10492. if (formatted != undefined) {
  10493. choice.find("div").replaceWith("<div>"+formatted+"</div>");
  10494. }
  10495. cssClass=this.opts.formatSelectionCssClass(data, choice.find("div"));
  10496. if (cssClass != undefined) {
  10497. choice.addClass(cssClass);
  10498. }
  10499. if(enableChoice){
  10500. choice.find(".select2-search-choice-close")
  10501. .on("mousedown", killEvent)
  10502. .on("click dblclick", this.bind(function (e) {
  10503. if (!this.isInterfaceEnabled()) return;
  10504. this.unselect($(e.target));
  10505. this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus");
  10506. killEvent(e);
  10507. this.close();
  10508. this.focusSearch();
  10509. })).on("focus", this.bind(function () {
  10510. if (!this.isInterfaceEnabled()) return;
  10511. this.container.addClass("select2-container-active");
  10512. this.dropdown.addClass("select2-drop-active");
  10513. }));
  10514. }
  10515. choice.data("select2-data", data);
  10516. choice.insertBefore(this.searchContainer);
  10517. val.push(id);
  10518. this.setVal(val);
  10519. },
  10520. // multi
  10521. unselect: function (selected) {
  10522. var val = this.getVal(),
  10523. data,
  10524. index;
  10525. selected = selected.closest(".select2-search-choice");
  10526. if (selected.length === 0) {
  10527. throw "Invalid argument: " + selected + ". Must be .select2-search-choice";
  10528. }
  10529. data = selected.data("select2-data");
  10530. if (!data) {
  10531. // prevent a race condition when the 'x' is clicked really fast repeatedly the event can be queued
  10532. // and invoked on an element already removed
  10533. return;
  10534. }
  10535. var evt = $.Event("select2-removing");
  10536. evt.val = this.id(data);
  10537. evt.choice = data;
  10538. this.opts.element.trigger(evt);
  10539. if (evt.isDefaultPrevented()) {
  10540. return false;
  10541. }
  10542. while((index = indexOf(this.id(data), val)) >= 0) {
  10543. val.splice(index, 1);
  10544. this.setVal(val);
  10545. if (this.select) this.postprocessResults();
  10546. }
  10547. selected.remove();
  10548. this.opts.element.trigger({ type: "select2-removed", val: this.id(data), choice: data });
  10549. this.triggerChange({ removed: data });
  10550. return true;
  10551. },
  10552. // multi
  10553. postprocessResults: function (data, initial, noHighlightUpdate) {
  10554. var val = this.getVal(),
  10555. choices = this.results.find(".select2-result"),
  10556. compound = this.results.find(".select2-result-with-children"),
  10557. self = this;
  10558. choices.each2(function (i, choice) {
  10559. var id = self.id(choice.data("select2-data"));
  10560. if (indexOf(id, val) >= 0) {
  10561. choice.addClass("select2-selected");
  10562. // mark all children of the selected parent as selected
  10563. choice.find(".select2-result-selectable").addClass("select2-selected");
  10564. }
  10565. });
  10566. compound.each2(function(i, choice) {
  10567. // hide an optgroup if it doesn't have any selectable children
  10568. if (!choice.is('.select2-result-selectable')
  10569. && choice.find(".select2-result-selectable:not(.select2-selected)").length === 0) {
  10570. choice.addClass("select2-selected");
  10571. }
  10572. });
  10573. if (this.highlight() == -1 && noHighlightUpdate !== false){
  10574. self.highlight(0);
  10575. }
  10576. //If all results are chosen render formatNoMatches
  10577. if(!this.opts.createSearchChoice && !choices.filter('.select2-result:not(.select2-selected)').length > 0){
  10578. if(!data || data && !data.more && this.results.find(".select2-no-results").length === 0) {
  10579. if (checkFormatter(self.opts.formatNoMatches, "formatNoMatches")) {
  10580. this.results.append("<li class='select2-no-results'>" + evaluate(self.opts.formatNoMatches, self.opts.element, self.search.val()) + "</li>");
  10581. }
  10582. }
  10583. }
  10584. },
  10585. // multi
  10586. getMaxSearchWidth: function() {
  10587. return this.selection.width() - getSideBorderPadding(this.search);
  10588. },
  10589. // multi
  10590. resizeSearch: function () {
  10591. var minimumWidth, left, maxWidth, containerLeft, searchWidth,
  10592. sideBorderPadding = getSideBorderPadding(this.search);
  10593. minimumWidth = measureTextWidth(this.search) + 10;
  10594. left = this.search.offset().left;
  10595. maxWidth = this.selection.width();
  10596. containerLeft = this.selection.offset().left;
  10597. searchWidth = maxWidth - (left - containerLeft) - sideBorderPadding;
  10598. if (searchWidth < minimumWidth) {
  10599. searchWidth = maxWidth - sideBorderPadding;
  10600. }
  10601. if (searchWidth < 40) {
  10602. searchWidth = maxWidth - sideBorderPadding;
  10603. }
  10604. if (searchWidth <= 0) {
  10605. searchWidth = minimumWidth;
  10606. }
  10607. this.search.width(Math.floor(searchWidth));
  10608. },
  10609. // multi
  10610. getVal: function () {
  10611. var val;
  10612. if (this.select) {
  10613. val = this.select.val();
  10614. return val === null ? [] : val;
  10615. } else {
  10616. val = this.opts.element.val();
  10617. return splitVal(val, this.opts.separator);
  10618. }
  10619. },
  10620. // multi
  10621. setVal: function (val) {
  10622. var unique;
  10623. if (this.select) {
  10624. this.select.val(val);
  10625. } else {
  10626. unique = [];
  10627. // filter out duplicates
  10628. $(val).each(function () {
  10629. if (indexOf(this, unique) < 0) unique.push(this);
  10630. });
  10631. this.opts.element.val(unique.length === 0 ? "" : unique.join(this.opts.separator));
  10632. }
  10633. },
  10634. // multi
  10635. buildChangeDetails: function (old, current) {
  10636. var current = current.slice(0),
  10637. old = old.slice(0);
  10638. // remove intersection from each array
  10639. for (var i = 0; i < current.length; i++) {
  10640. for (var j = 0; j < old.length; j++) {
  10641. if (equal(this.opts.id(current[i]), this.opts.id(old[j]))) {
  10642. current.splice(i, 1);
  10643. if(i>0){
  10644. i--;
  10645. }
  10646. old.splice(j, 1);
  10647. j--;
  10648. }
  10649. }
  10650. }
  10651. return {added: current, removed: old};
  10652. },
  10653. // multi
  10654. val: function (val, triggerChange) {
  10655. var oldData, self=this;
  10656. if (arguments.length === 0) {
  10657. return this.getVal();
  10658. }
  10659. oldData=this.data();
  10660. if (!oldData.length) oldData=[];
  10661. // val is an id. !val is true for [undefined,null,'',0] - 0 is legal
  10662. if (!val && val !== 0) {
  10663. this.opts.element.val("");
  10664. this.updateSelection([]);
  10665. this.clearSearch();
  10666. if (triggerChange) {
  10667. this.triggerChange({added: this.data(), removed: oldData});
  10668. }
  10669. return;
  10670. }
  10671. // val is a list of ids
  10672. this.setVal(val);
  10673. if (this.select) {
  10674. this.opts.initSelection(this.select, this.bind(this.updateSelection));
  10675. if (triggerChange) {
  10676. this.triggerChange(this.buildChangeDetails(oldData, this.data()));
  10677. }
  10678. } else {
  10679. if (this.opts.initSelection === undefined) {
  10680. throw new Error("val() cannot be called if initSelection() is not defined");
  10681. }
  10682. this.opts.initSelection(this.opts.element, function(data){
  10683. var ids=$.map(data, self.id);
  10684. self.setVal(ids);
  10685. self.updateSelection(data);
  10686. self.clearSearch();
  10687. if (triggerChange) {
  10688. self.triggerChange(self.buildChangeDetails(oldData, self.data()));
  10689. }
  10690. });
  10691. }
  10692. this.clearSearch();
  10693. },
  10694. // multi
  10695. onSortStart: function() {
  10696. if (this.select) {
  10697. throw new Error("Sorting of elements is not supported when attached to <select>. Attach to <input type='hidden'/> instead.");
  10698. }
  10699. // collapse search field into 0 width so its container can be collapsed as well
  10700. this.search.width(0);
  10701. // hide the container
  10702. this.searchContainer.hide();
  10703. },
  10704. // multi
  10705. onSortEnd:function() {
  10706. var val=[], self=this;
  10707. // show search and move it to the end of the list
  10708. this.searchContainer.show();
  10709. // make sure the search container is the last item in the list
  10710. this.searchContainer.appendTo(this.searchContainer.parent());
  10711. // since we collapsed the width in dragStarted, we resize it here
  10712. this.resizeSearch();
  10713. // update selection
  10714. this.selection.find(".select2-search-choice").each(function() {
  10715. val.push(self.opts.id($(this).data("select2-data")));
  10716. });
  10717. this.setVal(val);
  10718. this.triggerChange();
  10719. },
  10720. // multi
  10721. data: function(values, triggerChange) {
  10722. var self=this, ids, old;
  10723. if (arguments.length === 0) {
  10724. return this.selection
  10725. .children(".select2-search-choice")
  10726. .map(function() { return $(this).data("select2-data"); })
  10727. .get();
  10728. } else {
  10729. old = this.data();
  10730. if (!values) { values = []; }
  10731. ids = $.map(values, function(e) { return self.opts.id(e); });
  10732. this.setVal(ids);
  10733. this.updateSelection(values);
  10734. this.clearSearch();
  10735. if (triggerChange) {
  10736. this.triggerChange(this.buildChangeDetails(old, this.data()));
  10737. }
  10738. }
  10739. }
  10740. });
  10741. $.fn.select2 = function () {
  10742. var args = Array.prototype.slice.call(arguments, 0),
  10743. opts,
  10744. select2,
  10745. method, value, multiple,
  10746. allowedMethods = ["val", "destroy", "opened", "open", "close", "focus", "isFocused", "container", "dropdown", "onSortStart", "onSortEnd", "enable", "disable", "readonly", "positionDropdown", "data", "search"],
  10747. valueMethods = ["opened", "isFocused", "container", "dropdown"],
  10748. propertyMethods = ["val", "data"],
  10749. methodsMap = { search: "externalSearch" };
  10750. this.each(function () {
  10751. if (args.length === 0 || typeof(args[0]) === "object") {
  10752. opts = args.length === 0 ? {} : $.extend({}, args[0]);
  10753. opts.element = $(this);
  10754. if (opts.element.get(0).tagName.toLowerCase() === "select") {
  10755. multiple = opts.element.prop("multiple");
  10756. } else {
  10757. multiple = opts.multiple || false;
  10758. if ("tags" in opts) {opts.multiple = multiple = true;}
  10759. }
  10760. select2 = multiple ? new window.Select2["class"].multi() : new window.Select2["class"].single();
  10761. select2.init(opts);
  10762. } else if (typeof(args[0]) === "string") {
  10763. if (indexOf(args[0], allowedMethods) < 0) {
  10764. throw "Unknown method: " + args[0];
  10765. }
  10766. value = undefined;
  10767. select2 = $(this).data("select2");
  10768. if (select2 === undefined) return;
  10769. method=args[0];
  10770. if (method === "container") {
  10771. value = select2.container;
  10772. } else if (method === "dropdown") {
  10773. value = select2.dropdown;
  10774. } else {
  10775. if (methodsMap[method]) method = methodsMap[method];
  10776. value = select2[method].apply(select2, args.slice(1));
  10777. }
  10778. if (indexOf(args[0], valueMethods) >= 0
  10779. || (indexOf(args[0], propertyMethods) >= 0 && args.length == 1)) {
  10780. return false; // abort the iteration, ready to return first matched value
  10781. }
  10782. } else {
  10783. throw "Invalid arguments to select2 plugin: " + args;
  10784. }
  10785. });
  10786. return (value === undefined) ? this : value;
  10787. };
  10788. // plugin defaults, accessible to users
  10789. $.fn.select2.defaults = {
  10790. width: "copy",
  10791. loadMorePadding: 0,
  10792. closeOnSelect: true,
  10793. openOnEnter: true,
  10794. containerCss: {},
  10795. dropdownCss: {},
  10796. containerCssClass: "",
  10797. dropdownCssClass: "",
  10798. formatResult: function(result, container, query, escapeMarkup) {
  10799. var markup=[];
  10800. markMatch(result.text, query.term, markup, escapeMarkup);
  10801. return markup.join("");
  10802. },
  10803. formatSelection: function (data, container, escapeMarkup) {
  10804. return data ? escapeMarkup(data.text) : undefined;
  10805. },
  10806. sortResults: function (results, container, query) {
  10807. return results;
  10808. },
  10809. formatResultCssClass: function(data) {return data.css;},
  10810. formatSelectionCssClass: function(data, container) {return undefined;},
  10811. minimumResultsForSearch: 0,
  10812. minimumInputLength: 0,
  10813. maximumInputLength: null,
  10814. maximumSelectionSize: 0,
  10815. id: function (e) { return e == undefined ? null : e.id; },
  10816. matcher: function(term, text) {
  10817. return stripDiacritics(''+text).toUpperCase().indexOf(stripDiacritics(''+term).toUpperCase()) >= 0;
  10818. },
  10819. separator: ",",
  10820. tokenSeparators: [],
  10821. tokenizer: defaultTokenizer,
  10822. escapeMarkup: defaultEscapeMarkup,
  10823. blurOnChange: false,
  10824. selectOnBlur: false,
  10825. adaptContainerCssClass: function(c) { return c; },
  10826. adaptDropdownCssClass: function(c) { return null; },
  10827. nextSearchTerm: function(selectedObject, currentSearchTerm) { return undefined; },
  10828. searchInputPlaceholder: '',
  10829. createSearchChoicePosition: 'top',
  10830. shouldFocusInput: function (instance) {
  10831. // Attempt to detect touch devices
  10832. var supportsTouchEvents = (('ontouchstart' in window) ||
  10833. (navigator.msMaxTouchPoints > 0));
  10834. // Only devices which support touch events should be special cased
  10835. if (!supportsTouchEvents) {
  10836. return true;
  10837. }
  10838. // Never focus the input if search is disabled
  10839. if (instance.opts.minimumResultsForSearch < 0) {
  10840. return false;
  10841. }
  10842. return true;
  10843. }
  10844. };
  10845. $.fn.select2.locales = [];
  10846. $.fn.select2.locales['en'] = {
  10847. formatMatches: function (matches) { if (matches === 1) { return "One result is available, press enter to select it."; } return matches + " results are available, use up and down arrow keys to navigate."; },
  10848. formatNoMatches: function () { return "No matches found"; },
  10849. formatAjaxError: function (jqXHR, textStatus, errorThrown) { return "Loading failed"; },
  10850. formatInputTooShort: function (input, min) { var n = min - input.length; return "Please enter " + n + " or more character" + (n == 1 ? "" : "s"); },
  10851. formatInputTooLong: function (input, max) { var n = input.length - max; return "Please delete " + n + " character" + (n == 1 ? "" : "s"); },
  10852. formatSelectionTooBig: function (limit) { return "You can only select " + limit + " item" + (limit == 1 ? "" : "s"); },
  10853. formatLoadMore: function (pageNumber) { return "Loading more results…"; },
  10854. formatSearching: function () { return "Searching…"; },
  10855. };
  10856. $.extend($.fn.select2.defaults, $.fn.select2.locales['en']);
  10857. $.fn.select2.ajaxDefaults = {
  10858. transport: $.ajax,
  10859. params: {
  10860. type: "GET",
  10861. cache: false,
  10862. dataType: "json"
  10863. }
  10864. };
  10865. // exports
  10866. window.Select2 = {
  10867. query: {
  10868. ajax: ajax,
  10869. local: local,
  10870. tags: tags
  10871. }, util: {
  10872. debounce: debounce,
  10873. markMatch: markMatch,
  10874. escapeMarkup: defaultEscapeMarkup,
  10875. stripDiacritics: stripDiacritics
  10876. }, "class": {
  10877. "abstract": AbstractSelect2,
  10878. "single": SingleSelect2,
  10879. "multi": MultiSelect2
  10880. }
  10881. };
  10882. }(jQuery));
  10883. /* ============================================================
  10884. * flatui-radiocheck v0.1.0
  10885. * ============================================================ */
  10886. +function (global, $) {
  10887. 'use strict';
  10888. var Radiocheck = function (element, options) {
  10889. this.init('radiocheck', element, options);
  10890. };
  10891. Radiocheck.DEFAULTS = {
  10892. checkboxClass: 'custom-checkbox',
  10893. radioClass: 'custom-radio',
  10894. checkboxTemplate: '<span class="icons"><span class="icon-unchecked"></span><span class="icon-checked"></span></span>',
  10895. radioTemplate: '<span class="icons"><span class="icon-unchecked"></span><span class="icon-checked"></span></span>'
  10896. };
  10897. Radiocheck.prototype.init = function (type, element, options) {
  10898. this.$element = $(element);
  10899. this.options = $.extend({}, Radiocheck.DEFAULTS, this.$element.data(), options);
  10900. if (this.$element.attr('type') == 'checkbox') {
  10901. this.$element.addClass(this.options.checkboxClass);
  10902. this.$element.after(this.options.checkboxTemplate);
  10903. } else if (this.$element.attr('type') == 'radio') {
  10904. this.$element.addClass(this.options.radioClass);
  10905. this.$element.after(this.options.radioTemplate);
  10906. }
  10907. };
  10908. Radiocheck.prototype.check = function () {
  10909. this.$element.prop('checked', true);
  10910. this.$element.trigger('change.radiocheck').trigger('checked.radiocheck');
  10911. },
  10912. Radiocheck.prototype.uncheck = function () {
  10913. this.$element.prop('checked', false);
  10914. this.$element.trigger('change.radiocheck').trigger('unchecked.radiocheck');
  10915. },
  10916. Radiocheck.prototype.toggle = function () {
  10917. this.$element.prop('checked', function (i, value) {
  10918. return !value;
  10919. });
  10920. this.$element.trigger('change.radiocheck').trigger('toggled.radiocheck');
  10921. },
  10922. Radiocheck.prototype.indeterminate = function () {
  10923. this.$element.prop('indeterminate', true);
  10924. this.$element.trigger('change.radiocheck').trigger('indeterminated.radiocheck');
  10925. },
  10926. Radiocheck.prototype.determinate = function () {
  10927. this.$element.prop('indeterminate', false);
  10928. this.$element.trigger('change.radiocheck').trigger('determinated.radiocheck');
  10929. },
  10930. Radiocheck.prototype.disable = function () {
  10931. this.$element.prop('disabled', true);
  10932. this.$element.trigger('change.radiocheck').trigger('disabled.radiocheck');
  10933. },
  10934. Radiocheck.prototype.enable = function () {
  10935. this.$element.prop('disabled', false);
  10936. this.$element.trigger('change.radiocheck').trigger('enabled.radiocheck');
  10937. },
  10938. Radiocheck.prototype.destroy = function () {
  10939. this.$element.removeData().removeClass(this.options.checkboxClass + ' ' + this.options.radioClass).next('.icons').remove();
  10940. this.$element.trigger('destroyed.radiocheck');
  10941. };
  10942. // RADIOCHECK PLUGIN DEFINITION
  10943. // ============================
  10944. function Plugin(option) {
  10945. return this.each(function () {
  10946. var $this = $(this);
  10947. var data = $this.data('radiocheck');
  10948. var options = typeof option == 'object' && option;
  10949. if (!data && option == 'destroy') { return; }
  10950. if (!data) {
  10951. $this.data('radiocheck', (data = new Radiocheck(this, options)));
  10952. }
  10953. if (typeof option == 'string') {
  10954. data[option]();
  10955. }
  10956. // Adding 'nohover' class for mobile devices
  10957. var mobile = /mobile|tablet|phone|ip(ad|od)|android|silk|webos/i.test(global.navigator.userAgent);
  10958. if (mobile === true) {
  10959. $this.parent().hover(function () {
  10960. $this.addClass('nohover');
  10961. }, function () {
  10962. $this.removeClass('nohover');
  10963. });
  10964. }
  10965. });
  10966. }
  10967. var old = $.fn.radiocheck;
  10968. $.fn.radiocheck = Plugin;
  10969. $.fn.radiocheck.Constructor = Radiocheck;
  10970. // RADIOCHECK NO CONFLICT
  10971. // ======================
  10972. $.fn.radiocheck.noConflict = function () {
  10973. $.fn.radiocheck = old;
  10974. return this;
  10975. };
  10976. }(this, jQuery);