jquery-ui.js 509 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809
  1. /*! jQuery UI - v1.14.1 - 2024-10-30
  2. * https://jqueryui.com
  3. * Includes: widget.js, position.js, data.js, disable-selection.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js, focusable.js, form-reset-mixin.js, jquery-patch.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/draggable.js, widgets/droppable.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/resizable.js, widgets/selectable.js, widgets/selectmenu.js, widgets/slider.js, widgets/sortable.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js
  4. * Copyright OpenJS Foundation and other contributors; Licensed MIT */
  5. ( function( factory ) {
  6. "use strict";
  7. if ( typeof define === "function" && define.amd ) {
  8. // AMD. Register as an anonymous module.
  9. define( [ "jquery" ], factory );
  10. } else {
  11. // Browser globals
  12. factory( jQuery );
  13. }
  14. } )( function( $ ) {
  15. "use strict";
  16. $.ui = $.ui || {};
  17. var version = $.ui.version = "1.14.1";
  18. /*!
  19. * jQuery UI Widget 1.14.1
  20. * https://jqueryui.com
  21. *
  22. * Copyright OpenJS Foundation and other contributors
  23. * Released under the MIT license.
  24. * https://jquery.org/license
  25. */
  26. //>>label: Widget
  27. //>>group: Core
  28. //>>description: Provides a factory for creating stateful widgets with a common API.
  29. //>>docs: https://api.jqueryui.com/jQuery.widget/
  30. //>>demos: https://jqueryui.com/widget/
  31. var widgetUuid = 0;
  32. var widgetHasOwnProperty = Array.prototype.hasOwnProperty;
  33. var widgetSlice = Array.prototype.slice;
  34. $.cleanData = ( function( orig ) {
  35. return function( elems ) {
  36. var events, elem, i;
  37. for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
  38. // Only trigger remove when necessary to save time
  39. events = $._data( elem, "events" );
  40. if ( events && events.remove ) {
  41. $( elem ).triggerHandler( "remove" );
  42. }
  43. }
  44. orig( elems );
  45. };
  46. } )( $.cleanData );
  47. $.widget = function( name, base, prototype ) {
  48. var existingConstructor, constructor, basePrototype;
  49. // ProxiedPrototype allows the provided prototype to remain unmodified
  50. // so that it can be used as a mixin for multiple widgets (#8876)
  51. var proxiedPrototype = {};
  52. var namespace = name.split( "." )[ 0 ];
  53. name = name.split( "." )[ 1 ];
  54. if ( name === "__proto__" || name === "constructor" ) {
  55. return $.error( "Invalid widget name: " + name );
  56. }
  57. var fullName = namespace + "-" + name;
  58. if ( !prototype ) {
  59. prototype = base;
  60. base = $.Widget;
  61. }
  62. if ( Array.isArray( prototype ) ) {
  63. prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
  64. }
  65. // Create selector for plugin
  66. $.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) {
  67. return !!$.data( elem, fullName );
  68. };
  69. $[ namespace ] = $[ namespace ] || {};
  70. existingConstructor = $[ namespace ][ name ];
  71. constructor = $[ namespace ][ name ] = function( options, element ) {
  72. // Allow instantiation without "new" keyword
  73. if ( !this || !this._createWidget ) {
  74. return new constructor( options, element );
  75. }
  76. // Allow instantiation without initializing for simple inheritance
  77. // must use "new" keyword (the code above always passes args)
  78. if ( arguments.length ) {
  79. this._createWidget( options, element );
  80. }
  81. };
  82. // Extend with the existing constructor to carry over any static properties
  83. $.extend( constructor, existingConstructor, {
  84. version: prototype.version,
  85. // Copy the object used to create the prototype in case we need to
  86. // redefine the widget later
  87. _proto: $.extend( {}, prototype ),
  88. // Track widgets that inherit from this widget in case this widget is
  89. // redefined after a widget inherits from it
  90. _childConstructors: []
  91. } );
  92. basePrototype = new base();
  93. // We need to make the options hash a property directly on the new instance
  94. // otherwise we'll modify the options hash on the prototype that we're
  95. // inheriting from
  96. basePrototype.options = $.widget.extend( {}, basePrototype.options );
  97. $.each( prototype, function( prop, value ) {
  98. if ( typeof value !== "function" ) {
  99. proxiedPrototype[ prop ] = value;
  100. return;
  101. }
  102. proxiedPrototype[ prop ] = ( function() {
  103. function _super() {
  104. return base.prototype[ prop ].apply( this, arguments );
  105. }
  106. function _superApply( args ) {
  107. return base.prototype[ prop ].apply( this, args );
  108. }
  109. return function() {
  110. var __super = this._super;
  111. var __superApply = this._superApply;
  112. var returnValue;
  113. this._super = _super;
  114. this._superApply = _superApply;
  115. returnValue = value.apply( this, arguments );
  116. this._super = __super;
  117. this._superApply = __superApply;
  118. return returnValue;
  119. };
  120. } )();
  121. } );
  122. constructor.prototype = $.widget.extend( basePrototype, {
  123. // TODO: remove support for widgetEventPrefix
  124. // always use the name + a colon as the prefix, e.g., draggable:start
  125. // don't prefix for widgets that aren't DOM-based
  126. widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
  127. }, proxiedPrototype, {
  128. constructor: constructor,
  129. namespace: namespace,
  130. widgetName: name,
  131. widgetFullName: fullName
  132. } );
  133. // If this widget is being redefined then we need to find all widgets that
  134. // are inheriting from it and redefine all of them so that they inherit from
  135. // the new version of this widget. We're essentially trying to replace one
  136. // level in the prototype chain.
  137. if ( existingConstructor ) {
  138. $.each( existingConstructor._childConstructors, function( i, child ) {
  139. var childPrototype = child.prototype;
  140. // Redefine the child widget using the same prototype that was
  141. // originally used, but inherit from the new version of the base
  142. $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
  143. child._proto );
  144. } );
  145. // Remove the list of existing child constructors from the old constructor
  146. // so the old child constructors can be garbage collected
  147. delete existingConstructor._childConstructors;
  148. } else {
  149. base._childConstructors.push( constructor );
  150. }
  151. $.widget.bridge( name, constructor );
  152. return constructor;
  153. };
  154. $.widget.extend = function( target ) {
  155. var input = widgetSlice.call( arguments, 1 );
  156. var inputIndex = 0;
  157. var inputLength = input.length;
  158. var key;
  159. var value;
  160. for ( ; inputIndex < inputLength; inputIndex++ ) {
  161. for ( key in input[ inputIndex ] ) {
  162. value = input[ inputIndex ][ key ];
  163. if ( widgetHasOwnProperty.call( input[ inputIndex ], key ) && value !== undefined ) {
  164. // Clone objects
  165. if ( $.isPlainObject( value ) ) {
  166. target[ key ] = $.isPlainObject( target[ key ] ) ?
  167. $.widget.extend( {}, target[ key ], value ) :
  168. // Don't extend strings, arrays, etc. with objects
  169. $.widget.extend( {}, value );
  170. // Copy everything else by reference
  171. } else {
  172. target[ key ] = value;
  173. }
  174. }
  175. }
  176. }
  177. return target;
  178. };
  179. $.widget.bridge = function( name, object ) {
  180. var fullName = object.prototype.widgetFullName || name;
  181. $.fn[ name ] = function( options ) {
  182. var isMethodCall = typeof options === "string";
  183. var args = widgetSlice.call( arguments, 1 );
  184. var returnValue = this;
  185. if ( isMethodCall ) {
  186. // If this is an empty collection, we need to have the instance method
  187. // return undefined instead of the jQuery instance
  188. if ( !this.length && options === "instance" ) {
  189. returnValue = undefined;
  190. } else {
  191. this.each( function() {
  192. var methodValue;
  193. var instance = $.data( this, fullName );
  194. if ( options === "instance" ) {
  195. returnValue = instance;
  196. return false;
  197. }
  198. if ( !instance ) {
  199. return $.error( "cannot call methods on " + name +
  200. " prior to initialization; " +
  201. "attempted to call method '" + options + "'" );
  202. }
  203. if ( typeof instance[ options ] !== "function" ||
  204. options.charAt( 0 ) === "_" ) {
  205. return $.error( "no such method '" + options + "' for " + name +
  206. " widget instance" );
  207. }
  208. methodValue = instance[ options ].apply( instance, args );
  209. if ( methodValue !== instance && methodValue !== undefined ) {
  210. returnValue = methodValue && methodValue.jquery ?
  211. returnValue.pushStack( methodValue.get() ) :
  212. methodValue;
  213. return false;
  214. }
  215. } );
  216. }
  217. } else {
  218. // Allow multiple hashes to be passed on init
  219. if ( args.length ) {
  220. options = $.widget.extend.apply( null, [ options ].concat( args ) );
  221. }
  222. this.each( function() {
  223. var instance = $.data( this, fullName );
  224. if ( instance ) {
  225. instance.option( options || {} );
  226. if ( instance._init ) {
  227. instance._init();
  228. }
  229. } else {
  230. $.data( this, fullName, new object( options, this ) );
  231. }
  232. } );
  233. }
  234. return returnValue;
  235. };
  236. };
  237. $.Widget = function( /* options, element */ ) {};
  238. $.Widget._childConstructors = [];
  239. $.Widget.prototype = {
  240. widgetName: "widget",
  241. widgetEventPrefix: "",
  242. defaultElement: "<div>",
  243. options: {
  244. classes: {},
  245. disabled: false,
  246. // Callbacks
  247. create: null
  248. },
  249. _createWidget: function( options, element ) {
  250. element = $( element || this.defaultElement || this )[ 0 ];
  251. this.element = $( element );
  252. this.uuid = widgetUuid++;
  253. this.eventNamespace = "." + this.widgetName + this.uuid;
  254. this.bindings = $();
  255. this.hoverable = $();
  256. this.focusable = $();
  257. this.classesElementLookup = {};
  258. if ( element !== this ) {
  259. $.data( element, this.widgetFullName, this );
  260. this._on( true, this.element, {
  261. remove: function( event ) {
  262. if ( event.target === element ) {
  263. this.destroy();
  264. }
  265. }
  266. } );
  267. this.document = $( element.style ?
  268. // Element within the document
  269. element.ownerDocument :
  270. // Element is window or document
  271. element.document || element );
  272. this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
  273. }
  274. this.options = $.widget.extend( {},
  275. this.options,
  276. this._getCreateOptions(),
  277. options );
  278. this._create();
  279. if ( this.options.disabled ) {
  280. this._setOptionDisabled( this.options.disabled );
  281. }
  282. this._trigger( "create", null, this._getCreateEventData() );
  283. this._init();
  284. },
  285. _getCreateOptions: function() {
  286. return {};
  287. },
  288. _getCreateEventData: $.noop,
  289. _create: $.noop,
  290. _init: $.noop,
  291. destroy: function() {
  292. var that = this;
  293. this._destroy();
  294. $.each( this.classesElementLookup, function( key, value ) {
  295. that._removeClass( value, key );
  296. } );
  297. // We can probably remove the unbind calls in 2.0
  298. // all event bindings should go through this._on()
  299. this.element
  300. .off( this.eventNamespace )
  301. .removeData( this.widgetFullName );
  302. this.widget()
  303. .off( this.eventNamespace )
  304. .removeAttr( "aria-disabled" );
  305. // Clean up events and states
  306. this.bindings.off( this.eventNamespace );
  307. },
  308. _destroy: $.noop,
  309. widget: function() {
  310. return this.element;
  311. },
  312. option: function( key, value ) {
  313. var options = key;
  314. var parts;
  315. var curOption;
  316. var i;
  317. if ( arguments.length === 0 ) {
  318. // Don't return a reference to the internal hash
  319. return $.widget.extend( {}, this.options );
  320. }
  321. if ( typeof key === "string" ) {
  322. // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
  323. options = {};
  324. parts = key.split( "." );
  325. key = parts.shift();
  326. if ( parts.length ) {
  327. curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
  328. for ( i = 0; i < parts.length - 1; i++ ) {
  329. curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
  330. curOption = curOption[ parts[ i ] ];
  331. }
  332. key = parts.pop();
  333. if ( arguments.length === 1 ) {
  334. return curOption[ key ] === undefined ? null : curOption[ key ];
  335. }
  336. curOption[ key ] = value;
  337. } else {
  338. if ( arguments.length === 1 ) {
  339. return this.options[ key ] === undefined ? null : this.options[ key ];
  340. }
  341. options[ key ] = value;
  342. }
  343. }
  344. this._setOptions( options );
  345. return this;
  346. },
  347. _setOptions: function( options ) {
  348. var key;
  349. for ( key in options ) {
  350. this._setOption( key, options[ key ] );
  351. }
  352. return this;
  353. },
  354. _setOption: function( key, value ) {
  355. if ( key === "classes" ) {
  356. this._setOptionClasses( value );
  357. }
  358. this.options[ key ] = value;
  359. if ( key === "disabled" ) {
  360. this._setOptionDisabled( value );
  361. }
  362. return this;
  363. },
  364. _setOptionClasses: function( value ) {
  365. var classKey, elements, currentElements;
  366. for ( classKey in value ) {
  367. currentElements = this.classesElementLookup[ classKey ];
  368. if ( value[ classKey ] === this.options.classes[ classKey ] ||
  369. !currentElements ||
  370. !currentElements.length ) {
  371. continue;
  372. }
  373. // We are doing this to create a new jQuery object because the _removeClass() call
  374. // on the next line is going to destroy the reference to the current elements being
  375. // tracked. We need to save a copy of this collection so that we can add the new classes
  376. // below.
  377. elements = $( currentElements.get() );
  378. this._removeClass( currentElements, classKey );
  379. // We don't use _addClass() here, because that uses this.options.classes
  380. // for generating the string of classes. We want to use the value passed in from
  381. // _setOption(), this is the new value of the classes option which was passed to
  382. // _setOption(). We pass this value directly to _classes().
  383. elements.addClass( this._classes( {
  384. element: elements,
  385. keys: classKey,
  386. classes: value,
  387. add: true
  388. } ) );
  389. }
  390. },
  391. _setOptionDisabled: function( value ) {
  392. this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
  393. // If the widget is becoming disabled, then nothing is interactive
  394. if ( value ) {
  395. this._removeClass( this.hoverable, null, "ui-state-hover" );
  396. this._removeClass( this.focusable, null, "ui-state-focus" );
  397. }
  398. },
  399. enable: function() {
  400. return this._setOptions( { disabled: false } );
  401. },
  402. disable: function() {
  403. return this._setOptions( { disabled: true } );
  404. },
  405. _classes: function( options ) {
  406. var full = [];
  407. var that = this;
  408. options = $.extend( {
  409. element: this.element,
  410. classes: this.options.classes || {}
  411. }, options );
  412. function bindRemoveEvent() {
  413. var nodesToBind = [];
  414. options.element.each( function( _, element ) {
  415. var isTracked = $.map( that.classesElementLookup, function( elements ) {
  416. return elements;
  417. } )
  418. .some( function( elements ) {
  419. return elements.is( element );
  420. } );
  421. if ( !isTracked ) {
  422. nodesToBind.push( element );
  423. }
  424. } );
  425. that._on( $( nodesToBind ), {
  426. remove: "_untrackClassesElement"
  427. } );
  428. }
  429. function processClassString( classes, checkOption ) {
  430. var current, i;
  431. for ( i = 0; i < classes.length; i++ ) {
  432. current = that.classesElementLookup[ classes[ i ] ] || $();
  433. if ( options.add ) {
  434. bindRemoveEvent();
  435. current = $( $.uniqueSort( current.get().concat( options.element.get() ) ) );
  436. } else {
  437. current = $( current.not( options.element ).get() );
  438. }
  439. that.classesElementLookup[ classes[ i ] ] = current;
  440. full.push( classes[ i ] );
  441. if ( checkOption && options.classes[ classes[ i ] ] ) {
  442. full.push( options.classes[ classes[ i ] ] );
  443. }
  444. }
  445. }
  446. if ( options.keys ) {
  447. processClassString( options.keys.match( /\S+/g ) || [], true );
  448. }
  449. if ( options.extra ) {
  450. processClassString( options.extra.match( /\S+/g ) || [] );
  451. }
  452. return full.join( " " );
  453. },
  454. _untrackClassesElement: function( event ) {
  455. var that = this;
  456. $.each( that.classesElementLookup, function( key, value ) {
  457. if ( $.inArray( event.target, value ) !== -1 ) {
  458. that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
  459. }
  460. } );
  461. this._off( $( event.target ) );
  462. },
  463. _removeClass: function( element, keys, extra ) {
  464. return this._toggleClass( element, keys, extra, false );
  465. },
  466. _addClass: function( element, keys, extra ) {
  467. return this._toggleClass( element, keys, extra, true );
  468. },
  469. _toggleClass: function( element, keys, extra, add ) {
  470. add = ( typeof add === "boolean" ) ? add : extra;
  471. var shift = ( typeof element === "string" || element === null ),
  472. options = {
  473. extra: shift ? keys : extra,
  474. keys: shift ? element : keys,
  475. element: shift ? this.element : element,
  476. add: add
  477. };
  478. options.element.toggleClass( this._classes( options ), add );
  479. return this;
  480. },
  481. _on: function( suppressDisabledCheck, element, handlers ) {
  482. var delegateElement;
  483. var instance = this;
  484. // No suppressDisabledCheck flag, shuffle arguments
  485. if ( typeof suppressDisabledCheck !== "boolean" ) {
  486. handlers = element;
  487. element = suppressDisabledCheck;
  488. suppressDisabledCheck = false;
  489. }
  490. // No element argument, shuffle and use this.element
  491. if ( !handlers ) {
  492. handlers = element;
  493. element = this.element;
  494. delegateElement = this.widget();
  495. } else {
  496. element = delegateElement = $( element );
  497. this.bindings = this.bindings.add( element );
  498. }
  499. $.each( handlers, function( event, handler ) {
  500. function handlerProxy() {
  501. // Allow widgets to customize the disabled handling
  502. // - disabled as an array instead of boolean
  503. // - disabled class as method for disabling individual parts
  504. if ( !suppressDisabledCheck &&
  505. ( instance.options.disabled === true ||
  506. $( this ).hasClass( "ui-state-disabled" ) ) ) {
  507. return;
  508. }
  509. return ( typeof handler === "string" ? instance[ handler ] : handler )
  510. .apply( instance, arguments );
  511. }
  512. // Copy the guid so direct unbinding works
  513. if ( typeof handler !== "string" ) {
  514. handlerProxy.guid = handler.guid =
  515. handler.guid || handlerProxy.guid || $.guid++;
  516. }
  517. var match = event.match( /^([\w:-]*)\s*(.*)$/ );
  518. var eventName = match[ 1 ] + instance.eventNamespace;
  519. var selector = match[ 2 ];
  520. if ( selector ) {
  521. delegateElement.on( eventName, selector, handlerProxy );
  522. } else {
  523. element.on( eventName, handlerProxy );
  524. }
  525. } );
  526. },
  527. _off: function( element, eventName ) {
  528. eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
  529. this.eventNamespace;
  530. element.off( eventName );
  531. // Clear the stack to avoid memory leaks (#10056)
  532. this.bindings = $( this.bindings.not( element ).get() );
  533. this.focusable = $( this.focusable.not( element ).get() );
  534. this.hoverable = $( this.hoverable.not( element ).get() );
  535. },
  536. _delay: function( handler, delay ) {
  537. function handlerProxy() {
  538. return ( typeof handler === "string" ? instance[ handler ] : handler )
  539. .apply( instance, arguments );
  540. }
  541. var instance = this;
  542. return setTimeout( handlerProxy, delay || 0 );
  543. },
  544. _hoverable: function( element ) {
  545. this.hoverable = this.hoverable.add( element );
  546. this._on( element, {
  547. mouseenter: function( event ) {
  548. this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
  549. },
  550. mouseleave: function( event ) {
  551. this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
  552. }
  553. } );
  554. },
  555. _focusable: function( element ) {
  556. this.focusable = this.focusable.add( element );
  557. this._on( element, {
  558. focusin: function( event ) {
  559. this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
  560. },
  561. focusout: function( event ) {
  562. this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
  563. }
  564. } );
  565. },
  566. _trigger: function( type, event, data ) {
  567. var prop, orig;
  568. var callback = this.options[ type ];
  569. data = data || {};
  570. event = $.Event( event );
  571. event.type = ( type === this.widgetEventPrefix ?
  572. type :
  573. this.widgetEventPrefix + type ).toLowerCase();
  574. // The original event may come from any element
  575. // so we need to reset the target on the new event
  576. event.target = this.element[ 0 ];
  577. // Copy original event properties over to the new event
  578. orig = event.originalEvent;
  579. if ( orig ) {
  580. for ( prop in orig ) {
  581. if ( !( prop in event ) ) {
  582. event[ prop ] = orig[ prop ];
  583. }
  584. }
  585. }
  586. this.element.trigger( event, data );
  587. return !( typeof callback === "function" &&
  588. callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
  589. event.isDefaultPrevented() );
  590. }
  591. };
  592. $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
  593. $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
  594. if ( typeof options === "string" ) {
  595. options = { effect: options };
  596. }
  597. var hasOptions;
  598. var effectName = !options ?
  599. method :
  600. options === true || typeof options === "number" ?
  601. defaultEffect :
  602. options.effect || defaultEffect;
  603. options = options || {};
  604. if ( typeof options === "number" ) {
  605. options = { duration: options };
  606. } else if ( options === true ) {
  607. options = {};
  608. }
  609. hasOptions = !$.isEmptyObject( options );
  610. options.complete = callback;
  611. if ( options.delay ) {
  612. element.delay( options.delay );
  613. }
  614. if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
  615. element[ method ]( options );
  616. } else if ( effectName !== method && element[ effectName ] ) {
  617. element[ effectName ]( options.duration, options.easing, callback );
  618. } else {
  619. element.queue( function( next ) {
  620. $( this )[ method ]();
  621. if ( callback ) {
  622. callback.call( element[ 0 ] );
  623. }
  624. next();
  625. } );
  626. }
  627. };
  628. } );
  629. var widget = $.widget;
  630. /*!
  631. * jQuery UI Position 1.14.1
  632. * https://jqueryui.com
  633. *
  634. * Copyright OpenJS Foundation and other contributors
  635. * Released under the MIT license.
  636. * https://jquery.org/license
  637. *
  638. * https://api.jqueryui.com/position/
  639. */
  640. //>>label: Position
  641. //>>group: Core
  642. //>>description: Positions elements relative to other elements.
  643. //>>docs: https://api.jqueryui.com/position/
  644. //>>demos: https://jqueryui.com/position/
  645. ( function() {
  646. var cachedScrollbarWidth,
  647. max = Math.max,
  648. abs = Math.abs,
  649. rhorizontal = /left|center|right/,
  650. rvertical = /top|center|bottom/,
  651. roffset = /[\+\-]\d+(\.[\d]+)?%?/,
  652. rposition = /^\w+/,
  653. rpercent = /%$/,
  654. _position = $.fn.position;
  655. function getOffsets( offsets, width, height ) {
  656. return [
  657. parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
  658. parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
  659. ];
  660. }
  661. function parseCss( element, property ) {
  662. return parseInt( $.css( element, property ), 10 ) || 0;
  663. }
  664. function isWindow( obj ) {
  665. return obj != null && obj === obj.window;
  666. }
  667. function getDimensions( elem ) {
  668. var raw = elem[ 0 ];
  669. if ( raw.nodeType === 9 ) {
  670. return {
  671. width: elem.width(),
  672. height: elem.height(),
  673. offset: { top: 0, left: 0 }
  674. };
  675. }
  676. if ( isWindow( raw ) ) {
  677. return {
  678. width: elem.width(),
  679. height: elem.height(),
  680. offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
  681. };
  682. }
  683. if ( raw.preventDefault ) {
  684. return {
  685. width: 0,
  686. height: 0,
  687. offset: { top: raw.pageY, left: raw.pageX }
  688. };
  689. }
  690. return {
  691. width: elem.outerWidth(),
  692. height: elem.outerHeight(),
  693. offset: elem.offset()
  694. };
  695. }
  696. $.position = {
  697. scrollbarWidth: function() {
  698. if ( cachedScrollbarWidth !== undefined ) {
  699. return cachedScrollbarWidth;
  700. }
  701. var w1, w2,
  702. div = $( "<div style=" +
  703. "'display:block;position:absolute;width:200px;height:200px;overflow:hidden;'>" +
  704. "<div style='height:300px;width:auto;'></div></div>" ),
  705. innerDiv = div.children()[ 0 ];
  706. $( "body" ).append( div );
  707. w1 = innerDiv.offsetWidth;
  708. div.css( "overflow", "scroll" );
  709. w2 = innerDiv.offsetWidth;
  710. if ( w1 === w2 ) {
  711. w2 = div[ 0 ].clientWidth;
  712. }
  713. div.remove();
  714. return ( cachedScrollbarWidth = w1 - w2 );
  715. },
  716. getScrollInfo: function( within ) {
  717. var overflowX = within.isWindow || within.isDocument ? "" :
  718. within.element.css( "overflow-x" ),
  719. overflowY = within.isWindow || within.isDocument ? "" :
  720. within.element.css( "overflow-y" ),
  721. hasOverflowX = overflowX === "scroll" ||
  722. ( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ),
  723. hasOverflowY = overflowY === "scroll" ||
  724. ( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight );
  725. return {
  726. width: hasOverflowY ? $.position.scrollbarWidth() : 0,
  727. height: hasOverflowX ? $.position.scrollbarWidth() : 0
  728. };
  729. },
  730. getWithinInfo: function( element ) {
  731. var withinElement = $( element || window ),
  732. isElemWindow = isWindow( withinElement[ 0 ] ),
  733. isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9,
  734. hasOffset = !isElemWindow && !isDocument;
  735. return {
  736. element: withinElement,
  737. isWindow: isElemWindow,
  738. isDocument: isDocument,
  739. offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 },
  740. scrollLeft: withinElement.scrollLeft(),
  741. scrollTop: withinElement.scrollTop(),
  742. width: withinElement.outerWidth(),
  743. height: withinElement.outerHeight()
  744. };
  745. }
  746. };
  747. $.fn.position = function( options ) {
  748. if ( !options || !options.of ) {
  749. return _position.apply( this, arguments );
  750. }
  751. // Make a copy, we don't want to modify arguments
  752. options = $.extend( {}, options );
  753. var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
  754. // Make sure string options are treated as CSS selectors
  755. target = typeof options.of === "string" ?
  756. $( document ).find( options.of ) :
  757. $( options.of ),
  758. within = $.position.getWithinInfo( options.within ),
  759. scrollInfo = $.position.getScrollInfo( within ),
  760. collision = ( options.collision || "flip" ).split( " " ),
  761. offsets = {};
  762. dimensions = getDimensions( target );
  763. if ( target[ 0 ].preventDefault ) {
  764. // Force left top to allow flipping
  765. options.at = "left top";
  766. }
  767. targetWidth = dimensions.width;
  768. targetHeight = dimensions.height;
  769. targetOffset = dimensions.offset;
  770. // Clone to reuse original targetOffset later
  771. basePosition = $.extend( {}, targetOffset );
  772. // Force my and at to have valid horizontal and vertical positions
  773. // if a value is missing or invalid, it will be converted to center
  774. $.each( [ "my", "at" ], function() {
  775. var pos = ( options[ this ] || "" ).split( " " ),
  776. horizontalOffset,
  777. verticalOffset;
  778. if ( pos.length === 1 ) {
  779. pos = rhorizontal.test( pos[ 0 ] ) ?
  780. pos.concat( [ "center" ] ) :
  781. rvertical.test( pos[ 0 ] ) ?
  782. [ "center" ].concat( pos ) :
  783. [ "center", "center" ];
  784. }
  785. pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
  786. pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
  787. // Calculate offsets
  788. horizontalOffset = roffset.exec( pos[ 0 ] );
  789. verticalOffset = roffset.exec( pos[ 1 ] );
  790. offsets[ this ] = [
  791. horizontalOffset ? horizontalOffset[ 0 ] : 0,
  792. verticalOffset ? verticalOffset[ 0 ] : 0
  793. ];
  794. // Reduce to just the positions without the offsets
  795. options[ this ] = [
  796. rposition.exec( pos[ 0 ] )[ 0 ],
  797. rposition.exec( pos[ 1 ] )[ 0 ]
  798. ];
  799. } );
  800. // Normalize collision option
  801. if ( collision.length === 1 ) {
  802. collision[ 1 ] = collision[ 0 ];
  803. }
  804. if ( options.at[ 0 ] === "right" ) {
  805. basePosition.left += targetWidth;
  806. } else if ( options.at[ 0 ] === "center" ) {
  807. basePosition.left += targetWidth / 2;
  808. }
  809. if ( options.at[ 1 ] === "bottom" ) {
  810. basePosition.top += targetHeight;
  811. } else if ( options.at[ 1 ] === "center" ) {
  812. basePosition.top += targetHeight / 2;
  813. }
  814. atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
  815. basePosition.left += atOffset[ 0 ];
  816. basePosition.top += atOffset[ 1 ];
  817. return this.each( function() {
  818. var collisionPosition, using,
  819. elem = $( this ),
  820. elemWidth = elem.outerWidth(),
  821. elemHeight = elem.outerHeight(),
  822. marginLeft = parseCss( this, "marginLeft" ),
  823. marginTop = parseCss( this, "marginTop" ),
  824. collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) +
  825. scrollInfo.width,
  826. collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) +
  827. scrollInfo.height,
  828. position = $.extend( {}, basePosition ),
  829. myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
  830. if ( options.my[ 0 ] === "right" ) {
  831. position.left -= elemWidth;
  832. } else if ( options.my[ 0 ] === "center" ) {
  833. position.left -= elemWidth / 2;
  834. }
  835. if ( options.my[ 1 ] === "bottom" ) {
  836. position.top -= elemHeight;
  837. } else if ( options.my[ 1 ] === "center" ) {
  838. position.top -= elemHeight / 2;
  839. }
  840. position.left += myOffset[ 0 ];
  841. position.top += myOffset[ 1 ];
  842. collisionPosition = {
  843. marginLeft: marginLeft,
  844. marginTop: marginTop
  845. };
  846. $.each( [ "left", "top" ], function( i, dir ) {
  847. if ( $.ui.position[ collision[ i ] ] ) {
  848. $.ui.position[ collision[ i ] ][ dir ]( position, {
  849. targetWidth: targetWidth,
  850. targetHeight: targetHeight,
  851. elemWidth: elemWidth,
  852. elemHeight: elemHeight,
  853. collisionPosition: collisionPosition,
  854. collisionWidth: collisionWidth,
  855. collisionHeight: collisionHeight,
  856. offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
  857. my: options.my,
  858. at: options.at,
  859. within: within,
  860. elem: elem
  861. } );
  862. }
  863. } );
  864. if ( options.using ) {
  865. // Adds feedback as second argument to using callback, if present
  866. using = function( props ) {
  867. var left = targetOffset.left - position.left,
  868. right = left + targetWidth - elemWidth,
  869. top = targetOffset.top - position.top,
  870. bottom = top + targetHeight - elemHeight,
  871. feedback = {
  872. target: {
  873. element: target,
  874. left: targetOffset.left,
  875. top: targetOffset.top,
  876. width: targetWidth,
  877. height: targetHeight
  878. },
  879. element: {
  880. element: elem,
  881. left: position.left,
  882. top: position.top,
  883. width: elemWidth,
  884. height: elemHeight
  885. },
  886. horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
  887. vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
  888. };
  889. if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
  890. feedback.horizontal = "center";
  891. }
  892. if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
  893. feedback.vertical = "middle";
  894. }
  895. if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
  896. feedback.important = "horizontal";
  897. } else {
  898. feedback.important = "vertical";
  899. }
  900. options.using.call( this, props, feedback );
  901. };
  902. }
  903. elem.offset( $.extend( position, { using: using } ) );
  904. } );
  905. };
  906. $.ui.position = {
  907. fit: {
  908. left: function( position, data ) {
  909. var within = data.within,
  910. withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
  911. outerWidth = within.width,
  912. collisionPosLeft = position.left - data.collisionPosition.marginLeft,
  913. overLeft = withinOffset - collisionPosLeft,
  914. overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
  915. newOverRight;
  916. // Element is wider than within
  917. if ( data.collisionWidth > outerWidth ) {
  918. // Element is initially over the left side of within
  919. if ( overLeft > 0 && overRight <= 0 ) {
  920. newOverRight = position.left + overLeft + data.collisionWidth - outerWidth -
  921. withinOffset;
  922. position.left += overLeft - newOverRight;
  923. // Element is initially over right side of within
  924. } else if ( overRight > 0 && overLeft <= 0 ) {
  925. position.left = withinOffset;
  926. // Element is initially over both left and right sides of within
  927. } else {
  928. if ( overLeft > overRight ) {
  929. position.left = withinOffset + outerWidth - data.collisionWidth;
  930. } else {
  931. position.left = withinOffset;
  932. }
  933. }
  934. // Too far left -> align with left edge
  935. } else if ( overLeft > 0 ) {
  936. position.left += overLeft;
  937. // Too far right -> align with right edge
  938. } else if ( overRight > 0 ) {
  939. position.left -= overRight;
  940. // Adjust based on position and margin
  941. } else {
  942. position.left = max( position.left - collisionPosLeft, position.left );
  943. }
  944. },
  945. top: function( position, data ) {
  946. var within = data.within,
  947. withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
  948. outerHeight = data.within.height,
  949. collisionPosTop = position.top - data.collisionPosition.marginTop,
  950. overTop = withinOffset - collisionPosTop,
  951. overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
  952. newOverBottom;
  953. // Element is taller than within
  954. if ( data.collisionHeight > outerHeight ) {
  955. // Element is initially over the top of within
  956. if ( overTop > 0 && overBottom <= 0 ) {
  957. newOverBottom = position.top + overTop + data.collisionHeight - outerHeight -
  958. withinOffset;
  959. position.top += overTop - newOverBottom;
  960. // Element is initially over bottom of within
  961. } else if ( overBottom > 0 && overTop <= 0 ) {
  962. position.top = withinOffset;
  963. // Element is initially over both top and bottom of within
  964. } else {
  965. if ( overTop > overBottom ) {
  966. position.top = withinOffset + outerHeight - data.collisionHeight;
  967. } else {
  968. position.top = withinOffset;
  969. }
  970. }
  971. // Too far up -> align with top
  972. } else if ( overTop > 0 ) {
  973. position.top += overTop;
  974. // Too far down -> align with bottom edge
  975. } else if ( overBottom > 0 ) {
  976. position.top -= overBottom;
  977. // Adjust based on position and margin
  978. } else {
  979. position.top = max( position.top - collisionPosTop, position.top );
  980. }
  981. }
  982. },
  983. flip: {
  984. left: function( position, data ) {
  985. var within = data.within,
  986. withinOffset = within.offset.left + within.scrollLeft,
  987. outerWidth = within.width,
  988. offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
  989. collisionPosLeft = position.left - data.collisionPosition.marginLeft,
  990. overLeft = collisionPosLeft - offsetLeft,
  991. overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
  992. myOffset = data.my[ 0 ] === "left" ?
  993. -data.elemWidth :
  994. data.my[ 0 ] === "right" ?
  995. data.elemWidth :
  996. 0,
  997. atOffset = data.at[ 0 ] === "left" ?
  998. data.targetWidth :
  999. data.at[ 0 ] === "right" ?
  1000. -data.targetWidth :
  1001. 0,
  1002. offset = -2 * data.offset[ 0 ],
  1003. newOverRight,
  1004. newOverLeft;
  1005. if ( overLeft < 0 ) {
  1006. newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -
  1007. outerWidth - withinOffset;
  1008. if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
  1009. position.left += myOffset + atOffset + offset;
  1010. }
  1011. } else if ( overRight > 0 ) {
  1012. newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +
  1013. atOffset + offset - offsetLeft;
  1014. if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
  1015. position.left += myOffset + atOffset + offset;
  1016. }
  1017. }
  1018. },
  1019. top: function( position, data ) {
  1020. var within = data.within,
  1021. withinOffset = within.offset.top + within.scrollTop,
  1022. outerHeight = within.height,
  1023. offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
  1024. collisionPosTop = position.top - data.collisionPosition.marginTop,
  1025. overTop = collisionPosTop - offsetTop,
  1026. overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
  1027. top = data.my[ 1 ] === "top",
  1028. myOffset = top ?
  1029. -data.elemHeight :
  1030. data.my[ 1 ] === "bottom" ?
  1031. data.elemHeight :
  1032. 0,
  1033. atOffset = data.at[ 1 ] === "top" ?
  1034. data.targetHeight :
  1035. data.at[ 1 ] === "bottom" ?
  1036. -data.targetHeight :
  1037. 0,
  1038. offset = -2 * data.offset[ 1 ],
  1039. newOverTop,
  1040. newOverBottom;
  1041. if ( overTop < 0 ) {
  1042. newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -
  1043. outerHeight - withinOffset;
  1044. if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
  1045. position.top += myOffset + atOffset + offset;
  1046. }
  1047. } else if ( overBottom > 0 ) {
  1048. newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +
  1049. offset - offsetTop;
  1050. if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
  1051. position.top += myOffset + atOffset + offset;
  1052. }
  1053. }
  1054. }
  1055. },
  1056. flipfit: {
  1057. left: function() {
  1058. $.ui.position.flip.left.apply( this, arguments );
  1059. $.ui.position.fit.left.apply( this, arguments );
  1060. },
  1061. top: function() {
  1062. $.ui.position.flip.top.apply( this, arguments );
  1063. $.ui.position.fit.top.apply( this, arguments );
  1064. }
  1065. }
  1066. };
  1067. } )();
  1068. var position = $.ui.position;
  1069. /*!
  1070. * jQuery UI :data 1.14.1
  1071. * https://jqueryui.com
  1072. *
  1073. * Copyright OpenJS Foundation and other contributors
  1074. * Released under the MIT license.
  1075. * https://jquery.org/license
  1076. */
  1077. //>>label: :data Selector
  1078. //>>group: Core
  1079. //>>description: Selects elements which have data stored under the specified key.
  1080. //>>docs: https://api.jqueryui.com/data-selector/
  1081. var data = $.extend( $.expr.pseudos, {
  1082. data: $.expr.createPseudo( function( dataName ) {
  1083. return function( elem ) {
  1084. return !!$.data( elem, dataName );
  1085. };
  1086. } )
  1087. } );
  1088. /*!
  1089. * jQuery UI Disable Selection 1.14.1
  1090. * https://jqueryui.com
  1091. *
  1092. * Copyright OpenJS Foundation and other contributors
  1093. * Released under the MIT license.
  1094. * https://jquery.org/license
  1095. */
  1096. //>>label: disableSelection
  1097. //>>group: Core
  1098. //>>description: Disable selection of text content within the set of matched elements.
  1099. //>>docs: https://api.jqueryui.com/disableSelection/
  1100. // This file is deprecated
  1101. var disableSelection = $.fn.extend( {
  1102. disableSelection: ( function() {
  1103. var eventType = "onselectstart" in document.createElement( "div" ) ?
  1104. "selectstart" :
  1105. "mousedown";
  1106. return function() {
  1107. return this.on( eventType + ".ui-disableSelection", function( event ) {
  1108. event.preventDefault();
  1109. } );
  1110. };
  1111. } )(),
  1112. enableSelection: function() {
  1113. return this.off( ".ui-disableSelection" );
  1114. }
  1115. } );
  1116. // Create a local jQuery because jQuery Color relies on it and the
  1117. // global may not exist with AMD and a custom build (#10199).
  1118. // This module is a noop if used as a regular AMD module.
  1119. // eslint-disable-next-line no-unused-vars
  1120. var jQuery = $;
  1121. /*!
  1122. * jQuery Color Animations v3.0.0
  1123. * https://github.com/jquery/jquery-color
  1124. *
  1125. * Copyright OpenJS Foundation and other contributors
  1126. * Released under the MIT license.
  1127. * https://jquery.org/license
  1128. *
  1129. * Date: Wed May 15 16:49:44 2024 +0200
  1130. */
  1131. var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " +
  1132. "borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
  1133. class2type = {},
  1134. toString = class2type.toString,
  1135. // plusequals test for += 100 -= 100
  1136. rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
  1137. // a set of RE's that can match strings and generate color tuples.
  1138. stringParsers = [ {
  1139. re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
  1140. parse: function( execResult ) {
  1141. return [
  1142. execResult[ 1 ],
  1143. execResult[ 2 ],
  1144. execResult[ 3 ],
  1145. execResult[ 4 ]
  1146. ];
  1147. }
  1148. }, {
  1149. re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
  1150. parse: function( execResult ) {
  1151. return [
  1152. execResult[ 1 ] * 2.55,
  1153. execResult[ 2 ] * 2.55,
  1154. execResult[ 3 ] * 2.55,
  1155. execResult[ 4 ]
  1156. ];
  1157. }
  1158. }, {
  1159. // this regex ignores A-F because it's compared against an already lowercased string
  1160. re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?/,
  1161. parse: function( execResult ) {
  1162. return [
  1163. parseInt( execResult[ 1 ], 16 ),
  1164. parseInt( execResult[ 2 ], 16 ),
  1165. parseInt( execResult[ 3 ], 16 ),
  1166. execResult[ 4 ] ?
  1167. ( parseInt( execResult[ 4 ], 16 ) / 255 ).toFixed( 2 ) :
  1168. 1
  1169. ];
  1170. }
  1171. }, {
  1172. // this regex ignores A-F because it's compared against an already lowercased string
  1173. re: /#([a-f0-9])([a-f0-9])([a-f0-9])([a-f0-9])?/,
  1174. parse: function( execResult ) {
  1175. return [
  1176. parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
  1177. parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
  1178. parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ),
  1179. execResult[ 4 ] ?
  1180. ( parseInt( execResult[ 4 ] + execResult[ 4 ], 16 ) / 255 )
  1181. .toFixed( 2 ) :
  1182. 1
  1183. ];
  1184. }
  1185. }, {
  1186. re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
  1187. space: "hsla",
  1188. parse: function( execResult ) {
  1189. return [
  1190. execResult[ 1 ],
  1191. execResult[ 2 ] / 100,
  1192. execResult[ 3 ] / 100,
  1193. execResult[ 4 ]
  1194. ];
  1195. }
  1196. } ],
  1197. // jQuery.Color( )
  1198. color = jQuery.Color = function( color, green, blue, alpha ) {
  1199. return new jQuery.Color.fn.parse( color, green, blue, alpha );
  1200. },
  1201. spaces = {
  1202. rgba: {
  1203. props: {
  1204. red: {
  1205. idx: 0,
  1206. type: "byte"
  1207. },
  1208. green: {
  1209. idx: 1,
  1210. type: "byte"
  1211. },
  1212. blue: {
  1213. idx: 2,
  1214. type: "byte"
  1215. }
  1216. }
  1217. },
  1218. hsla: {
  1219. props: {
  1220. hue: {
  1221. idx: 0,
  1222. type: "degrees"
  1223. },
  1224. saturation: {
  1225. idx: 1,
  1226. type: "percent"
  1227. },
  1228. lightness: {
  1229. idx: 2,
  1230. type: "percent"
  1231. }
  1232. }
  1233. }
  1234. },
  1235. propTypes = {
  1236. "byte": {
  1237. floor: true,
  1238. max: 255
  1239. },
  1240. "percent": {
  1241. max: 1
  1242. },
  1243. "degrees": {
  1244. mod: 360,
  1245. floor: true
  1246. }
  1247. },
  1248. // colors = jQuery.Color.names
  1249. colors,
  1250. // local aliases of functions called often
  1251. each = jQuery.each;
  1252. // define cache name and alpha properties
  1253. // for rgba and hsla spaces
  1254. each( spaces, function( spaceName, space ) {
  1255. space.cache = "_" + spaceName;
  1256. space.props.alpha = {
  1257. idx: 3,
  1258. type: "percent",
  1259. def: 1
  1260. };
  1261. } );
  1262. // Populate the class2type map
  1263. jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
  1264. function( _i, name ) {
  1265. class2type[ "[object " + name + "]" ] = name.toLowerCase();
  1266. } );
  1267. function getType( obj ) {
  1268. if ( obj == null ) {
  1269. return obj + "";
  1270. }
  1271. return typeof obj === "object" ?
  1272. class2type[ toString.call( obj ) ] || "object" :
  1273. typeof obj;
  1274. }
  1275. function clamp( value, prop, allowEmpty ) {
  1276. var type = propTypes[ prop.type ] || {};
  1277. if ( value == null ) {
  1278. return ( allowEmpty || !prop.def ) ? null : prop.def;
  1279. }
  1280. // ~~ is an short way of doing floor for positive numbers
  1281. value = type.floor ? ~~value : parseFloat( value );
  1282. if ( type.mod ) {
  1283. // we add mod before modding to make sure that negatives values
  1284. // get converted properly: -10 -> 350
  1285. return ( value + type.mod ) % type.mod;
  1286. }
  1287. // for now all property types without mod have min and max
  1288. return Math.min( type.max, Math.max( 0, value ) );
  1289. }
  1290. function stringParse( string ) {
  1291. var inst = color(),
  1292. rgba = inst._rgba = [];
  1293. string = string.toLowerCase();
  1294. each( stringParsers, function( _i, parser ) {
  1295. var parsed,
  1296. match = parser.re.exec( string ),
  1297. values = match && parser.parse( match ),
  1298. spaceName = parser.space || "rgba";
  1299. if ( values ) {
  1300. parsed = inst[ spaceName ]( values );
  1301. // if this was an rgba parse the assignment might happen twice
  1302. // oh well....
  1303. inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
  1304. rgba = inst._rgba = parsed._rgba;
  1305. // exit each( stringParsers ) here because we matched
  1306. return false;
  1307. }
  1308. } );
  1309. // Found a stringParser that handled it
  1310. if ( rgba.length ) {
  1311. // if this came from a parsed string, force "transparent" when alpha is 0
  1312. // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
  1313. if ( rgba.join() === "0,0,0,0" ) {
  1314. jQuery.extend( rgba, colors.transparent );
  1315. }
  1316. return inst;
  1317. }
  1318. // named colors
  1319. return colors[ string ];
  1320. }
  1321. color.fn = jQuery.extend( color.prototype, {
  1322. parse: function( red, green, blue, alpha ) {
  1323. if ( red === undefined ) {
  1324. this._rgba = [ null, null, null, null ];
  1325. return this;
  1326. }
  1327. if ( red.jquery || red.nodeType ) {
  1328. red = jQuery( red ).css( green );
  1329. green = undefined;
  1330. }
  1331. var inst = this,
  1332. type = getType( red ),
  1333. rgba = this._rgba = [];
  1334. // more than 1 argument specified - assume ( red, green, blue, alpha )
  1335. if ( green !== undefined ) {
  1336. red = [ red, green, blue, alpha ];
  1337. type = "array";
  1338. }
  1339. if ( type === "string" ) {
  1340. return this.parse( stringParse( red ) || colors._default );
  1341. }
  1342. if ( type === "array" ) {
  1343. each( spaces.rgba.props, function( _key, prop ) {
  1344. rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
  1345. } );
  1346. return this;
  1347. }
  1348. if ( type === "object" ) {
  1349. if ( red instanceof color ) {
  1350. each( spaces, function( _spaceName, space ) {
  1351. if ( red[ space.cache ] ) {
  1352. inst[ space.cache ] = red[ space.cache ].slice();
  1353. }
  1354. } );
  1355. } else {
  1356. each( spaces, function( _spaceName, space ) {
  1357. var cache = space.cache;
  1358. each( space.props, function( key, prop ) {
  1359. // if the cache doesn't exist, and we know how to convert
  1360. if ( !inst[ cache ] && space.to ) {
  1361. // if the value was null, we don't need to copy it
  1362. // if the key was alpha, we don't need to copy it either
  1363. if ( key === "alpha" || red[ key ] == null ) {
  1364. return;
  1365. }
  1366. inst[ cache ] = space.to( inst._rgba );
  1367. }
  1368. // this is the only case where we allow nulls for ALL properties.
  1369. // call clamp with alwaysAllowEmpty
  1370. inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
  1371. } );
  1372. // everything defined but alpha?
  1373. if ( inst[ cache ] && jQuery.inArray(
  1374. null,
  1375. inst[ cache ].slice( 0, 3 )
  1376. ) < 0 ) {
  1377. // use the default of 1
  1378. if ( inst[ cache ][ 3 ] == null ) {
  1379. inst[ cache ][ 3 ] = 1;
  1380. }
  1381. if ( space.from ) {
  1382. inst._rgba = space.from( inst[ cache ] );
  1383. }
  1384. }
  1385. } );
  1386. }
  1387. return this;
  1388. }
  1389. },
  1390. is: function( compare ) {
  1391. var is = color( compare ),
  1392. same = true,
  1393. inst = this;
  1394. each( spaces, function( _, space ) {
  1395. var localCache,
  1396. isCache = is[ space.cache ];
  1397. if ( isCache ) {
  1398. localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
  1399. each( space.props, function( _, prop ) {
  1400. if ( isCache[ prop.idx ] != null ) {
  1401. same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
  1402. return same;
  1403. }
  1404. } );
  1405. }
  1406. return same;
  1407. } );
  1408. return same;
  1409. },
  1410. _space: function() {
  1411. var used = [],
  1412. inst = this;
  1413. each( spaces, function( spaceName, space ) {
  1414. if ( inst[ space.cache ] ) {
  1415. used.push( spaceName );
  1416. }
  1417. } );
  1418. return used.pop();
  1419. },
  1420. transition: function( other, distance ) {
  1421. var end = color( other ),
  1422. spaceName = end._space(),
  1423. space = spaces[ spaceName ],
  1424. startColor = this.alpha() === 0 ? color( "transparent" ) : this,
  1425. start = startColor[ space.cache ] || space.to( startColor._rgba ),
  1426. result = start.slice();
  1427. end = end[ space.cache ];
  1428. each( space.props, function( _key, prop ) {
  1429. var index = prop.idx,
  1430. startValue = start[ index ],
  1431. endValue = end[ index ],
  1432. type = propTypes[ prop.type ] || {};
  1433. // if null, don't override start value
  1434. if ( endValue === null ) {
  1435. return;
  1436. }
  1437. // if null - use end
  1438. if ( startValue === null ) {
  1439. result[ index ] = endValue;
  1440. } else {
  1441. if ( type.mod ) {
  1442. if ( endValue - startValue > type.mod / 2 ) {
  1443. startValue += type.mod;
  1444. } else if ( startValue - endValue > type.mod / 2 ) {
  1445. startValue -= type.mod;
  1446. }
  1447. }
  1448. result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
  1449. }
  1450. } );
  1451. return this[ spaceName ]( result );
  1452. },
  1453. blend: function( opaque ) {
  1454. // if we are already opaque - return ourself
  1455. if ( this._rgba[ 3 ] === 1 ) {
  1456. return this;
  1457. }
  1458. var rgb = this._rgba.slice(),
  1459. a = rgb.pop(),
  1460. blend = color( opaque )._rgba;
  1461. return color( jQuery.map( rgb, function( v, i ) {
  1462. return ( 1 - a ) * blend[ i ] + a * v;
  1463. } ) );
  1464. },
  1465. toRgbaString: function() {
  1466. var prefix = "rgba(",
  1467. rgba = jQuery.map( this._rgba, function( v, i ) {
  1468. if ( v != null ) {
  1469. return v;
  1470. }
  1471. return i > 2 ? 1 : 0;
  1472. } );
  1473. if ( rgba[ 3 ] === 1 ) {
  1474. rgba.pop();
  1475. prefix = "rgb(";
  1476. }
  1477. return prefix + rgba.join( ", " ) + ")";
  1478. },
  1479. toHslaString: function() {
  1480. var prefix = "hsla(",
  1481. hsla = jQuery.map( this.hsla(), function( v, i ) {
  1482. if ( v == null ) {
  1483. v = i > 2 ? 1 : 0;
  1484. }
  1485. // catch 1 and 2
  1486. if ( i && i < 3 ) {
  1487. v = Math.round( v * 100 ) + "%";
  1488. }
  1489. return v;
  1490. } );
  1491. if ( hsla[ 3 ] === 1 ) {
  1492. hsla.pop();
  1493. prefix = "hsl(";
  1494. }
  1495. return prefix + hsla.join( ", " ) + ")";
  1496. },
  1497. toHexString: function( includeAlpha ) {
  1498. var rgba = this._rgba.slice(),
  1499. alpha = rgba.pop();
  1500. if ( includeAlpha ) {
  1501. rgba.push( ~~( alpha * 255 ) );
  1502. }
  1503. return "#" + jQuery.map( rgba, function( v ) {
  1504. // default to 0 when nulls exist
  1505. return ( "0" + ( v || 0 ).toString( 16 ) ).substr( -2 );
  1506. } ).join( "" );
  1507. },
  1508. toString: function() {
  1509. return this.toRgbaString();
  1510. }
  1511. } );
  1512. color.fn.parse.prototype = color.fn;
  1513. // hsla conversions adapted from:
  1514. // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
  1515. function hue2rgb( p, q, h ) {
  1516. h = ( h + 1 ) % 1;
  1517. if ( h * 6 < 1 ) {
  1518. return p + ( q - p ) * h * 6;
  1519. }
  1520. if ( h * 2 < 1 ) {
  1521. return q;
  1522. }
  1523. if ( h * 3 < 2 ) {
  1524. return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
  1525. }
  1526. return p;
  1527. }
  1528. spaces.hsla.to = function( rgba ) {
  1529. if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
  1530. return [ null, null, null, rgba[ 3 ] ];
  1531. }
  1532. var r = rgba[ 0 ] / 255,
  1533. g = rgba[ 1 ] / 255,
  1534. b = rgba[ 2 ] / 255,
  1535. a = rgba[ 3 ],
  1536. max = Math.max( r, g, b ),
  1537. min = Math.min( r, g, b ),
  1538. diff = max - min,
  1539. add = max + min,
  1540. l = add * 0.5,
  1541. h, s;
  1542. if ( min === max ) {
  1543. h = 0;
  1544. } else if ( r === max ) {
  1545. h = ( 60 * ( g - b ) / diff ) + 360;
  1546. } else if ( g === max ) {
  1547. h = ( 60 * ( b - r ) / diff ) + 120;
  1548. } else {
  1549. h = ( 60 * ( r - g ) / diff ) + 240;
  1550. }
  1551. // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
  1552. // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
  1553. if ( diff === 0 ) {
  1554. s = 0;
  1555. } else if ( l <= 0.5 ) {
  1556. s = diff / add;
  1557. } else {
  1558. s = diff / ( 2 - add );
  1559. }
  1560. return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ];
  1561. };
  1562. spaces.hsla.from = function( hsla ) {
  1563. if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
  1564. return [ null, null, null, hsla[ 3 ] ];
  1565. }
  1566. var h = hsla[ 0 ] / 360,
  1567. s = hsla[ 1 ],
  1568. l = hsla[ 2 ],
  1569. a = hsla[ 3 ],
  1570. q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
  1571. p = 2 * l - q;
  1572. return [
  1573. Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
  1574. Math.round( hue2rgb( p, q, h ) * 255 ),
  1575. Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
  1576. a
  1577. ];
  1578. };
  1579. each( spaces, function( spaceName, space ) {
  1580. var props = space.props,
  1581. cache = space.cache,
  1582. to = space.to,
  1583. from = space.from;
  1584. // makes rgba() and hsla()
  1585. color.fn[ spaceName ] = function( value ) {
  1586. // generate a cache for this space if it doesn't exist
  1587. if ( to && !this[ cache ] ) {
  1588. this[ cache ] = to( this._rgba );
  1589. }
  1590. if ( value === undefined ) {
  1591. return this[ cache ].slice();
  1592. }
  1593. var ret,
  1594. type = getType( value ),
  1595. arr = ( type === "array" || type === "object" ) ? value : arguments,
  1596. local = this[ cache ].slice();
  1597. each( props, function( key, prop ) {
  1598. var val = arr[ type === "object" ? key : prop.idx ];
  1599. if ( val == null ) {
  1600. val = local[ prop.idx ];
  1601. }
  1602. local[ prop.idx ] = clamp( val, prop );
  1603. } );
  1604. if ( from ) {
  1605. ret = color( from( local ) );
  1606. ret[ cache ] = local;
  1607. return ret;
  1608. } else {
  1609. return color( local );
  1610. }
  1611. };
  1612. // makes red() green() blue() alpha() hue() saturation() lightness()
  1613. each( props, function( key, prop ) {
  1614. // alpha is included in more than one space
  1615. if ( color.fn[ key ] ) {
  1616. return;
  1617. }
  1618. color.fn[ key ] = function( value ) {
  1619. var local, cur, match, fn,
  1620. vtype = getType( value );
  1621. if ( key === "alpha" ) {
  1622. fn = this._hsla ? "hsla" : "rgba";
  1623. } else {
  1624. fn = spaceName;
  1625. }
  1626. local = this[ fn ]();
  1627. cur = local[ prop.idx ];
  1628. if ( vtype === "undefined" ) {
  1629. return cur;
  1630. }
  1631. if ( vtype === "function" ) {
  1632. value = value.call( this, cur );
  1633. vtype = getType( value );
  1634. }
  1635. if ( value == null && prop.empty ) {
  1636. return this;
  1637. }
  1638. if ( vtype === "string" ) {
  1639. match = rplusequals.exec( value );
  1640. if ( match ) {
  1641. value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
  1642. }
  1643. }
  1644. local[ prop.idx ] = value;
  1645. return this[ fn ]( local );
  1646. };
  1647. } );
  1648. } );
  1649. // add cssHook and .fx.step function for each named hook.
  1650. // accept a space separated string of properties
  1651. color.hook = function( hook ) {
  1652. var hooks = hook.split( " " );
  1653. each( hooks, function( _i, hook ) {
  1654. jQuery.cssHooks[ hook ] = {
  1655. set: function( elem, value ) {
  1656. var parsed;
  1657. if ( value !== "transparent" &&
  1658. ( getType( value ) !== "string" ||
  1659. ( parsed = stringParse( value ) ) ) ) {
  1660. value = color( parsed || value );
  1661. value = value.toRgbaString();
  1662. }
  1663. elem.style[ hook ] = value;
  1664. }
  1665. };
  1666. jQuery.fx.step[ hook ] = function( fx ) {
  1667. if ( !fx.colorInit ) {
  1668. fx.start = color( fx.elem, hook );
  1669. fx.end = color( fx.end );
  1670. fx.colorInit = true;
  1671. }
  1672. jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
  1673. };
  1674. } );
  1675. };
  1676. color.hook( stepHooks );
  1677. jQuery.cssHooks.borderColor = {
  1678. expand: function( value ) {
  1679. var expanded = {};
  1680. each( [ "Top", "Right", "Bottom", "Left" ], function( _i, part ) {
  1681. expanded[ "border" + part + "Color" ] = value;
  1682. } );
  1683. return expanded;
  1684. }
  1685. };
  1686. // Basic color names only.
  1687. // Usage of any of the other color names requires adding yourself or including
  1688. // jquery.color.svg-names.js.
  1689. colors = jQuery.Color.names = {
  1690. // 4.1. Basic color keywords
  1691. aqua: "#00ffff",
  1692. black: "#000000",
  1693. blue: "#0000ff",
  1694. fuchsia: "#ff00ff",
  1695. gray: "#808080",
  1696. green: "#008000",
  1697. lime: "#00ff00",
  1698. maroon: "#800000",
  1699. navy: "#000080",
  1700. olive: "#808000",
  1701. purple: "#800080",
  1702. red: "#ff0000",
  1703. silver: "#c0c0c0",
  1704. teal: "#008080",
  1705. white: "#ffffff",
  1706. yellow: "#ffff00",
  1707. // 4.2.3. "transparent" color keyword
  1708. transparent: [ null, null, null, 0 ],
  1709. _default: "#ffffff"
  1710. };
  1711. /*!
  1712. * jQuery UI Effects 1.14.1
  1713. * https://jqueryui.com
  1714. *
  1715. * Copyright OpenJS Foundation and other contributors
  1716. * Released under the MIT license.
  1717. * https://jquery.org/license
  1718. */
  1719. //>>label: Effects Core
  1720. //>>group: Effects
  1721. /* eslint-disable max-len */
  1722. //>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects.
  1723. /* eslint-enable max-len */
  1724. //>>docs: https://api.jqueryui.com/category/effects-core/
  1725. //>>demos: https://jqueryui.com/effect/
  1726. var dataSpace = "ui-effects-",
  1727. dataSpaceStyle = "ui-effects-style",
  1728. dataSpaceAnimated = "ui-effects-animated";
  1729. $.effects = {
  1730. effect: {}
  1731. };
  1732. /******************************************************************************/
  1733. /****************************** CLASS ANIMATIONS ******************************/
  1734. /******************************************************************************/
  1735. ( function() {
  1736. var classAnimationActions = [ "add", "remove", "toggle" ],
  1737. shorthandStyles = {
  1738. border: 1,
  1739. borderBottom: 1,
  1740. borderColor: 1,
  1741. borderLeft: 1,
  1742. borderRight: 1,
  1743. borderTop: 1,
  1744. borderWidth: 1,
  1745. margin: 1,
  1746. padding: 1
  1747. };
  1748. $.each(
  1749. [ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ],
  1750. function( _, prop ) {
  1751. $.fx.step[ prop ] = function( fx ) {
  1752. if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
  1753. jQuery.style( fx.elem, prop, fx.end );
  1754. fx.setAttr = true;
  1755. }
  1756. };
  1757. }
  1758. );
  1759. function camelCase( string ) {
  1760. return string.replace( /-([\da-z])/gi, function( all, letter ) {
  1761. return letter.toUpperCase();
  1762. } );
  1763. }
  1764. function getElementStyles( elem ) {
  1765. var key, len,
  1766. style = elem.ownerDocument.defaultView.getComputedStyle( elem ),
  1767. styles = {};
  1768. len = style.length;
  1769. while ( len-- ) {
  1770. key = style[ len ];
  1771. if ( typeof style[ key ] === "string" ) {
  1772. styles[ camelCase( key ) ] = style[ key ];
  1773. }
  1774. }
  1775. return styles;
  1776. }
  1777. function styleDifference( oldStyle, newStyle ) {
  1778. var diff = {},
  1779. name, value;
  1780. for ( name in newStyle ) {
  1781. value = newStyle[ name ];
  1782. if ( oldStyle[ name ] !== value ) {
  1783. if ( !shorthandStyles[ name ] ) {
  1784. if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
  1785. diff[ name ] = value;
  1786. }
  1787. }
  1788. }
  1789. }
  1790. return diff;
  1791. }
  1792. $.effects.animateClass = function( value, duration, easing, callback ) {
  1793. var o = $.speed( duration, easing, callback );
  1794. return this.queue( function() {
  1795. var animated = $( this ),
  1796. baseClass = animated.attr( "class" ) || "",
  1797. applyClassChange,
  1798. allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
  1799. // Map the animated objects to store the original styles.
  1800. allAnimations = allAnimations.map( function() {
  1801. var el = $( this );
  1802. return {
  1803. el: el,
  1804. start: getElementStyles( this )
  1805. };
  1806. } );
  1807. // Apply class change
  1808. applyClassChange = function() {
  1809. $.each( classAnimationActions, function( i, action ) {
  1810. if ( value[ action ] ) {
  1811. animated[ action + "Class" ]( value[ action ] );
  1812. }
  1813. } );
  1814. };
  1815. applyClassChange();
  1816. // Map all animated objects again - calculate new styles and diff
  1817. allAnimations = allAnimations.map( function() {
  1818. this.end = getElementStyles( this.el[ 0 ] );
  1819. this.diff = styleDifference( this.start, this.end );
  1820. return this;
  1821. } );
  1822. // Apply original class
  1823. animated.attr( "class", baseClass );
  1824. // Map all animated objects again - this time collecting a promise
  1825. allAnimations = allAnimations.map( function() {
  1826. var styleInfo = this,
  1827. dfd = $.Deferred(),
  1828. opts = $.extend( {}, o, {
  1829. queue: false,
  1830. complete: function() {
  1831. dfd.resolve( styleInfo );
  1832. }
  1833. } );
  1834. this.el.animate( this.diff, opts );
  1835. return dfd.promise();
  1836. } );
  1837. // Once all animations have completed:
  1838. $.when.apply( $, allAnimations.get() ).done( function() {
  1839. // Set the final class
  1840. applyClassChange();
  1841. // For each animated element,
  1842. // clear all css properties that were animated
  1843. $.each( arguments, function() {
  1844. var el = this.el;
  1845. $.each( this.diff, function( key ) {
  1846. el.css( key, "" );
  1847. } );
  1848. } );
  1849. // This is guarnteed to be there if you use jQuery.speed()
  1850. // it also handles dequeuing the next anim...
  1851. o.complete.call( animated[ 0 ] );
  1852. } );
  1853. } );
  1854. };
  1855. $.fn.extend( {
  1856. addClass: ( function( orig ) {
  1857. return function( classNames, speed, easing, callback ) {
  1858. return speed ?
  1859. $.effects.animateClass.call( this,
  1860. { add: classNames }, speed, easing, callback ) :
  1861. orig.apply( this, arguments );
  1862. };
  1863. } )( $.fn.addClass ),
  1864. removeClass: ( function( orig ) {
  1865. return function( classNames, speed, easing, callback ) {
  1866. return arguments.length > 1 ?
  1867. $.effects.animateClass.call( this,
  1868. { remove: classNames }, speed, easing, callback ) :
  1869. orig.apply( this, arguments );
  1870. };
  1871. } )( $.fn.removeClass ),
  1872. toggleClass: ( function( orig ) {
  1873. return function( classNames, force, speed, easing, callback ) {
  1874. if ( typeof force === "boolean" || force === undefined ) {
  1875. if ( !speed ) {
  1876. // Without speed parameter
  1877. return orig.apply( this, arguments );
  1878. } else {
  1879. return $.effects.animateClass.call( this,
  1880. ( force ? { add: classNames } : { remove: classNames } ),
  1881. speed, easing, callback );
  1882. }
  1883. } else {
  1884. // Without force parameter
  1885. return $.effects.animateClass.call( this,
  1886. { toggle: classNames }, force, speed, easing );
  1887. }
  1888. };
  1889. } )( $.fn.toggleClass ),
  1890. switchClass: function( remove, add, speed, easing, callback ) {
  1891. return $.effects.animateClass.call( this, {
  1892. add: add,
  1893. remove: remove
  1894. }, speed, easing, callback );
  1895. }
  1896. } );
  1897. } )();
  1898. /******************************************************************************/
  1899. /*********************************** EFFECTS **********************************/
  1900. /******************************************************************************/
  1901. ( function() {
  1902. if ( $.expr && $.expr.pseudos && $.expr.pseudos.animated ) {
  1903. $.expr.pseudos.animated = ( function( orig ) {
  1904. return function( elem ) {
  1905. return !!$( elem ).data( dataSpaceAnimated ) || orig( elem );
  1906. };
  1907. } )( $.expr.pseudos.animated );
  1908. }
  1909. if ( $.uiBackCompat === true ) {
  1910. $.extend( $.effects, {
  1911. // Saves a set of properties in a data storage
  1912. save: function( element, set ) {
  1913. var i = 0, length = set.length;
  1914. for ( ; i < length; i++ ) {
  1915. if ( set[ i ] !== null ) {
  1916. element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
  1917. }
  1918. }
  1919. },
  1920. // Restores a set of previously saved properties from a data storage
  1921. restore: function( element, set ) {
  1922. var val, i = 0, length = set.length;
  1923. for ( ; i < length; i++ ) {
  1924. if ( set[ i ] !== null ) {
  1925. val = element.data( dataSpace + set[ i ] );
  1926. element.css( set[ i ], val );
  1927. }
  1928. }
  1929. },
  1930. setMode: function( el, mode ) {
  1931. if ( mode === "toggle" ) {
  1932. mode = el.is( ":hidden" ) ? "show" : "hide";
  1933. }
  1934. return mode;
  1935. },
  1936. // Wraps the element around a wrapper that copies position properties
  1937. createWrapper: function( element ) {
  1938. // If the element is already wrapped, return it
  1939. if ( element.parent().is( ".ui-effects-wrapper" ) ) {
  1940. return element.parent();
  1941. }
  1942. // Wrap the element
  1943. var props = {
  1944. width: element.outerWidth( true ),
  1945. height: element.outerHeight( true ),
  1946. "float": element.css( "float" )
  1947. },
  1948. wrapper = $( "<div></div>" )
  1949. .addClass( "ui-effects-wrapper" )
  1950. .css( {
  1951. fontSize: "100%",
  1952. background: "transparent",
  1953. border: "none",
  1954. margin: 0,
  1955. padding: 0
  1956. } ),
  1957. // Store the size in case width/height are defined in % - Fixes #5245
  1958. size = {
  1959. width: element.width(),
  1960. height: element.height()
  1961. },
  1962. active = document.activeElement;
  1963. // Support: Firefox
  1964. // Firefox incorrectly exposes anonymous content
  1965. // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
  1966. try {
  1967. // eslint-disable-next-line no-unused-expressions
  1968. active.id;
  1969. } catch ( e ) {
  1970. active = document.body;
  1971. }
  1972. element.wrap( wrapper );
  1973. // Fixes #7595 - Elements lose focus when wrapped.
  1974. if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
  1975. $( active ).trigger( "focus" );
  1976. }
  1977. // Hotfix for jQuery 1.4 since some change in wrap() seems to actually
  1978. // lose the reference to the wrapped element
  1979. wrapper = element.parent();
  1980. // Transfer positioning properties to the wrapper
  1981. if ( element.css( "position" ) === "static" ) {
  1982. wrapper.css( { position: "relative" } );
  1983. element.css( { position: "relative" } );
  1984. } else {
  1985. $.extend( props, {
  1986. position: element.css( "position" ),
  1987. zIndex: element.css( "z-index" )
  1988. } );
  1989. $.each( [ "top", "left", "bottom", "right" ], function( i, pos ) {
  1990. props[ pos ] = element.css( pos );
  1991. if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
  1992. props[ pos ] = "auto";
  1993. }
  1994. } );
  1995. element.css( {
  1996. position: "relative",
  1997. top: 0,
  1998. left: 0,
  1999. right: "auto",
  2000. bottom: "auto"
  2001. } );
  2002. }
  2003. element.css( size );
  2004. return wrapper.css( props ).show();
  2005. },
  2006. removeWrapper: function( element ) {
  2007. var active = document.activeElement;
  2008. if ( element.parent().is( ".ui-effects-wrapper" ) ) {
  2009. element.parent().replaceWith( element );
  2010. // Fixes #7595 - Elements lose focus when wrapped.
  2011. if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
  2012. $( active ).trigger( "focus" );
  2013. }
  2014. }
  2015. return element;
  2016. }
  2017. } );
  2018. }
  2019. $.extend( $.effects, {
  2020. version: "1.14.1",
  2021. define: function( name, mode, effect ) {
  2022. if ( !effect ) {
  2023. effect = mode;
  2024. mode = "effect";
  2025. }
  2026. $.effects.effect[ name ] = effect;
  2027. $.effects.effect[ name ].mode = mode;
  2028. return effect;
  2029. },
  2030. scaledDimensions: function( element, percent, direction ) {
  2031. if ( percent === 0 ) {
  2032. return {
  2033. height: 0,
  2034. width: 0,
  2035. outerHeight: 0,
  2036. outerWidth: 0
  2037. };
  2038. }
  2039. var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1,
  2040. y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1;
  2041. return {
  2042. height: element.height() * y,
  2043. width: element.width() * x,
  2044. outerHeight: element.outerHeight() * y,
  2045. outerWidth: element.outerWidth() * x
  2046. };
  2047. },
  2048. clipToBox: function( animation ) {
  2049. return {
  2050. width: animation.clip.right - animation.clip.left,
  2051. height: animation.clip.bottom - animation.clip.top,
  2052. left: animation.clip.left,
  2053. top: animation.clip.top
  2054. };
  2055. },
  2056. // Injects recently queued functions to be first in line (after "inprogress")
  2057. unshift: function( element, queueLength, count ) {
  2058. var queue = element.queue();
  2059. if ( queueLength > 1 ) {
  2060. queue.splice.apply( queue,
  2061. [ 1, 0 ].concat( queue.splice( queueLength, count ) ) );
  2062. }
  2063. element.dequeue();
  2064. },
  2065. saveStyle: function( element ) {
  2066. element.data( dataSpaceStyle, element[ 0 ].style.cssText );
  2067. },
  2068. restoreStyle: function( element ) {
  2069. element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || "";
  2070. element.removeData( dataSpaceStyle );
  2071. },
  2072. mode: function( element, mode ) {
  2073. var hidden = element.is( ":hidden" );
  2074. if ( mode === "toggle" ) {
  2075. mode = hidden ? "show" : "hide";
  2076. }
  2077. if ( hidden ? mode === "hide" : mode === "show" ) {
  2078. mode = "none";
  2079. }
  2080. return mode;
  2081. },
  2082. // Translates a [top,left] array into a baseline value
  2083. getBaseline: function( origin, original ) {
  2084. var y, x;
  2085. switch ( origin[ 0 ] ) {
  2086. case "top":
  2087. y = 0;
  2088. break;
  2089. case "middle":
  2090. y = 0.5;
  2091. break;
  2092. case "bottom":
  2093. y = 1;
  2094. break;
  2095. default:
  2096. y = origin[ 0 ] / original.height;
  2097. }
  2098. switch ( origin[ 1 ] ) {
  2099. case "left":
  2100. x = 0;
  2101. break;
  2102. case "center":
  2103. x = 0.5;
  2104. break;
  2105. case "right":
  2106. x = 1;
  2107. break;
  2108. default:
  2109. x = origin[ 1 ] / original.width;
  2110. }
  2111. return {
  2112. x: x,
  2113. y: y
  2114. };
  2115. },
  2116. // Creates a placeholder element so that the original element can be made absolute
  2117. createPlaceholder: function( element ) {
  2118. var placeholder,
  2119. cssPosition = element.css( "position" ),
  2120. position = element.position();
  2121. // Lock in margins first to account for form elements, which
  2122. // will change margin if you explicitly set height
  2123. // see: https://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380
  2124. // Support: Safari
  2125. element.css( {
  2126. marginTop: element.css( "marginTop" ),
  2127. marginBottom: element.css( "marginBottom" ),
  2128. marginLeft: element.css( "marginLeft" ),
  2129. marginRight: element.css( "marginRight" )
  2130. } )
  2131. .outerWidth( element.outerWidth() )
  2132. .outerHeight( element.outerHeight() );
  2133. if ( /^(static|relative)/.test( cssPosition ) ) {
  2134. cssPosition = "absolute";
  2135. placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( {
  2136. // Convert inline to inline block to account for inline elements
  2137. // that turn to inline block based on content (like img)
  2138. display: /^(inline|ruby)/.test( element.css( "display" ) ) ?
  2139. "inline-block" :
  2140. "block",
  2141. visibility: "hidden",
  2142. // Margins need to be set to account for margin collapse
  2143. marginTop: element.css( "marginTop" ),
  2144. marginBottom: element.css( "marginBottom" ),
  2145. marginLeft: element.css( "marginLeft" ),
  2146. marginRight: element.css( "marginRight" ),
  2147. "float": element.css( "float" )
  2148. } )
  2149. .outerWidth( element.outerWidth() )
  2150. .outerHeight( element.outerHeight() )
  2151. .addClass( "ui-effects-placeholder" );
  2152. element.data( dataSpace + "placeholder", placeholder );
  2153. }
  2154. element.css( {
  2155. position: cssPosition,
  2156. left: position.left,
  2157. top: position.top
  2158. } );
  2159. return placeholder;
  2160. },
  2161. removePlaceholder: function( element ) {
  2162. var dataKey = dataSpace + "placeholder",
  2163. placeholder = element.data( dataKey );
  2164. if ( placeholder ) {
  2165. placeholder.remove();
  2166. element.removeData( dataKey );
  2167. }
  2168. },
  2169. // Removes a placeholder if it exists and restores
  2170. // properties that were modified during placeholder creation
  2171. cleanUp: function( element ) {
  2172. $.effects.restoreStyle( element );
  2173. $.effects.removePlaceholder( element );
  2174. },
  2175. setTransition: function( element, list, factor, value ) {
  2176. value = value || {};
  2177. $.each( list, function( i, x ) {
  2178. var unit = element.cssUnit( x );
  2179. if ( unit[ 0 ] > 0 ) {
  2180. value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
  2181. }
  2182. } );
  2183. return value;
  2184. }
  2185. } );
  2186. // Return an effect options object for the given parameters:
  2187. function _normalizeArguments( effect, options, speed, callback ) {
  2188. // Allow passing all options as the first parameter
  2189. if ( $.isPlainObject( effect ) ) {
  2190. options = effect;
  2191. effect = effect.effect;
  2192. }
  2193. // Convert to an object
  2194. effect = { effect: effect };
  2195. // Catch (effect, null, ...)
  2196. if ( options == null ) {
  2197. options = {};
  2198. }
  2199. // Catch (effect, callback)
  2200. if ( typeof options === "function" ) {
  2201. callback = options;
  2202. speed = null;
  2203. options = {};
  2204. }
  2205. // Catch (effect, speed, ?)
  2206. if ( typeof options === "number" || $.fx.speeds[ options ] ) {
  2207. callback = speed;
  2208. speed = options;
  2209. options = {};
  2210. }
  2211. // Catch (effect, options, callback)
  2212. if ( typeof speed === "function" ) {
  2213. callback = speed;
  2214. speed = null;
  2215. }
  2216. // Add options to effect
  2217. if ( options ) {
  2218. $.extend( effect, options );
  2219. }
  2220. speed = speed || options.duration;
  2221. effect.duration = $.fx.off ? 0 :
  2222. typeof speed === "number" ? speed :
  2223. speed in $.fx.speeds ? $.fx.speeds[ speed ] :
  2224. $.fx.speeds._default;
  2225. effect.complete = callback || options.complete;
  2226. return effect;
  2227. }
  2228. function standardAnimationOption( option ) {
  2229. // Valid standard speeds (nothing, number, named speed)
  2230. if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
  2231. return true;
  2232. }
  2233. // Invalid strings - treat as "normal" speed
  2234. if ( typeof option === "string" && !$.effects.effect[ option ] ) {
  2235. return true;
  2236. }
  2237. // Complete callback
  2238. if ( typeof option === "function" ) {
  2239. return true;
  2240. }
  2241. // Options hash (but not naming an effect)
  2242. if ( typeof option === "object" && !option.effect ) {
  2243. return true;
  2244. }
  2245. // Didn't match any standard API
  2246. return false;
  2247. }
  2248. $.fn.extend( {
  2249. effect: function( /* effect, options, speed, callback */ ) {
  2250. var args = _normalizeArguments.apply( this, arguments ),
  2251. effectMethod = $.effects.effect[ args.effect ],
  2252. defaultMode = effectMethod.mode,
  2253. queue = args.queue,
  2254. queueName = queue || "fx",
  2255. complete = args.complete,
  2256. mode = args.mode,
  2257. modes = [],
  2258. prefilter = function( next ) {
  2259. var el = $( this ),
  2260. normalizedMode = $.effects.mode( el, mode ) || defaultMode;
  2261. // Sentinel for duck-punching the :animated pseudo-selector
  2262. el.data( dataSpaceAnimated, true );
  2263. // Save effect mode for later use,
  2264. // we can't just call $.effects.mode again later,
  2265. // as the .show() below destroys the initial state
  2266. modes.push( normalizedMode );
  2267. // See $.uiBackCompat inside of run() for removal of defaultMode in 1.14
  2268. if ( defaultMode && ( normalizedMode === "show" ||
  2269. ( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) {
  2270. el.show();
  2271. }
  2272. if ( !defaultMode || normalizedMode !== "none" ) {
  2273. $.effects.saveStyle( el );
  2274. }
  2275. if ( typeof next === "function" ) {
  2276. next();
  2277. }
  2278. };
  2279. if ( $.fx.off || !effectMethod ) {
  2280. // Delegate to the original method (e.g., .show()) if possible
  2281. if ( mode ) {
  2282. return this[ mode ]( args.duration, complete );
  2283. } else {
  2284. return this.each( function() {
  2285. if ( complete ) {
  2286. complete.call( this );
  2287. }
  2288. } );
  2289. }
  2290. }
  2291. function run( next ) {
  2292. var elem = $( this );
  2293. function cleanup() {
  2294. elem.removeData( dataSpaceAnimated );
  2295. $.effects.cleanUp( elem );
  2296. if ( args.mode === "hide" ) {
  2297. elem.hide();
  2298. }
  2299. done();
  2300. }
  2301. function done() {
  2302. if ( typeof complete === "function" ) {
  2303. complete.call( elem[ 0 ] );
  2304. }
  2305. if ( typeof next === "function" ) {
  2306. next();
  2307. }
  2308. }
  2309. // Override mode option on a per element basis,
  2310. // as toggle can be either show or hide depending on element state
  2311. args.mode = modes.shift();
  2312. if ( $.uiBackCompat === true && !defaultMode ) {
  2313. if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
  2314. // Call the core method to track "olddisplay" properly
  2315. elem[ mode ]();
  2316. done();
  2317. } else {
  2318. effectMethod.call( elem[ 0 ], args, done );
  2319. }
  2320. } else {
  2321. if ( args.mode === "none" ) {
  2322. // Call the core method to track "olddisplay" properly
  2323. elem[ mode ]();
  2324. done();
  2325. } else {
  2326. effectMethod.call( elem[ 0 ], args, cleanup );
  2327. }
  2328. }
  2329. }
  2330. // Run prefilter on all elements first to ensure that
  2331. // any showing or hiding happens before placeholder creation,
  2332. // which ensures that any layout changes are correctly captured.
  2333. return queue === false ?
  2334. this.each( prefilter ).each( run ) :
  2335. this.queue( queueName, prefilter ).queue( queueName, run );
  2336. },
  2337. show: ( function( orig ) {
  2338. return function( option ) {
  2339. if ( standardAnimationOption( option ) ) {
  2340. return orig.apply( this, arguments );
  2341. } else {
  2342. var args = _normalizeArguments.apply( this, arguments );
  2343. args.mode = "show";
  2344. return this.effect.call( this, args );
  2345. }
  2346. };
  2347. } )( $.fn.show ),
  2348. hide: ( function( orig ) {
  2349. return function( option ) {
  2350. if ( standardAnimationOption( option ) ) {
  2351. return orig.apply( this, arguments );
  2352. } else {
  2353. var args = _normalizeArguments.apply( this, arguments );
  2354. args.mode = "hide";
  2355. return this.effect.call( this, args );
  2356. }
  2357. };
  2358. } )( $.fn.hide ),
  2359. toggle: ( function( orig ) {
  2360. return function( option ) {
  2361. if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
  2362. return orig.apply( this, arguments );
  2363. } else {
  2364. var args = _normalizeArguments.apply( this, arguments );
  2365. args.mode = "toggle";
  2366. return this.effect.call( this, args );
  2367. }
  2368. };
  2369. } )( $.fn.toggle ),
  2370. cssUnit: function( key ) {
  2371. var style = this.css( key ),
  2372. val = [];
  2373. $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
  2374. if ( style.indexOf( unit ) > 0 ) {
  2375. val = [ parseFloat( style ), unit ];
  2376. }
  2377. } );
  2378. return val;
  2379. },
  2380. cssClip: function( clipObj ) {
  2381. if ( clipObj ) {
  2382. return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " +
  2383. clipObj.bottom + "px " + clipObj.left + "px)" );
  2384. }
  2385. return parseClip( this.css( "clip" ), this );
  2386. },
  2387. transfer: function( options, done ) {
  2388. var element = $( this ),
  2389. target = $( options.to ),
  2390. targetFixed = target.css( "position" ) === "fixed",
  2391. body = $( "body" ),
  2392. fixTop = targetFixed ? body.scrollTop() : 0,
  2393. fixLeft = targetFixed ? body.scrollLeft() : 0,
  2394. endPosition = target.offset(),
  2395. animation = {
  2396. top: endPosition.top - fixTop,
  2397. left: endPosition.left - fixLeft,
  2398. height: target.innerHeight(),
  2399. width: target.innerWidth()
  2400. },
  2401. startPosition = element.offset(),
  2402. transfer = $( "<div class='ui-effects-transfer'></div>" );
  2403. transfer
  2404. .appendTo( "body" )
  2405. .addClass( options.className )
  2406. .css( {
  2407. top: startPosition.top - fixTop,
  2408. left: startPosition.left - fixLeft,
  2409. height: element.innerHeight(),
  2410. width: element.innerWidth(),
  2411. position: targetFixed ? "fixed" : "absolute"
  2412. } )
  2413. .animate( animation, options.duration, options.easing, function() {
  2414. transfer.remove();
  2415. if ( typeof done === "function" ) {
  2416. done();
  2417. }
  2418. } );
  2419. }
  2420. } );
  2421. function parseClip( str, element ) {
  2422. var outerWidth = element.outerWidth(),
  2423. outerHeight = element.outerHeight(),
  2424. clipRegex = /^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/,
  2425. values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ];
  2426. return {
  2427. top: parseFloat( values[ 1 ] ) || 0,
  2428. right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ),
  2429. bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ),
  2430. left: parseFloat( values[ 4 ] ) || 0
  2431. };
  2432. }
  2433. $.fx.step.clip = function( fx ) {
  2434. if ( !fx.clipInit ) {
  2435. fx.start = $( fx.elem ).cssClip();
  2436. if ( typeof fx.end === "string" ) {
  2437. fx.end = parseClip( fx.end, fx.elem );
  2438. }
  2439. fx.clipInit = true;
  2440. }
  2441. $( fx.elem ).cssClip( {
  2442. top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top,
  2443. right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right,
  2444. bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom,
  2445. left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left
  2446. } );
  2447. };
  2448. } )();
  2449. /******************************************************************************/
  2450. /*********************************** EASING ***********************************/
  2451. /******************************************************************************/
  2452. ( function() {
  2453. // Based on easing equations from Robert Penner (http://robertpenner.com/easing)
  2454. var baseEasings = {};
  2455. $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
  2456. baseEasings[ name ] = function( p ) {
  2457. return Math.pow( p, i + 2 );
  2458. };
  2459. } );
  2460. $.extend( baseEasings, {
  2461. Sine: function( p ) {
  2462. return 1 - Math.cos( p * Math.PI / 2 );
  2463. },
  2464. Circ: function( p ) {
  2465. return 1 - Math.sqrt( 1 - p * p );
  2466. },
  2467. Elastic: function( p ) {
  2468. return p === 0 || p === 1 ? p :
  2469. -Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 );
  2470. },
  2471. Back: function( p ) {
  2472. return p * p * ( 3 * p - 2 );
  2473. },
  2474. Bounce: function( p ) {
  2475. var pow2,
  2476. bounce = 4;
  2477. while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
  2478. return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
  2479. }
  2480. } );
  2481. $.each( baseEasings, function( name, easeIn ) {
  2482. $.easing[ "easeIn" + name ] = easeIn;
  2483. $.easing[ "easeOut" + name ] = function( p ) {
  2484. return 1 - easeIn( 1 - p );
  2485. };
  2486. $.easing[ "easeInOut" + name ] = function( p ) {
  2487. return p < 0.5 ?
  2488. easeIn( p * 2 ) / 2 :
  2489. 1 - easeIn( p * -2 + 2 ) / 2;
  2490. };
  2491. } );
  2492. } )();
  2493. var effect = $.effects;
  2494. /*!
  2495. * jQuery UI Effects Blind 1.14.1
  2496. * https://jqueryui.com
  2497. *
  2498. * Copyright OpenJS Foundation and other contributors
  2499. * Released under the MIT license.
  2500. * https://jquery.org/license
  2501. */
  2502. //>>label: Blind Effect
  2503. //>>group: Effects
  2504. //>>description: Blinds the element.
  2505. //>>docs: https://api.jqueryui.com/blind-effect/
  2506. //>>demos: https://jqueryui.com/effect/
  2507. var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) {
  2508. var map = {
  2509. up: [ "bottom", "top" ],
  2510. vertical: [ "bottom", "top" ],
  2511. down: [ "top", "bottom" ],
  2512. left: [ "right", "left" ],
  2513. horizontal: [ "right", "left" ],
  2514. right: [ "left", "right" ]
  2515. },
  2516. element = $( this ),
  2517. direction = options.direction || "up",
  2518. start = element.cssClip(),
  2519. animate = { clip: $.extend( {}, start ) },
  2520. placeholder = $.effects.createPlaceholder( element );
  2521. animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ];
  2522. if ( options.mode === "show" ) {
  2523. element.cssClip( animate.clip );
  2524. if ( placeholder ) {
  2525. placeholder.css( $.effects.clipToBox( animate ) );
  2526. }
  2527. animate.clip = start;
  2528. }
  2529. if ( placeholder ) {
  2530. placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing );
  2531. }
  2532. element.animate( animate, {
  2533. queue: false,
  2534. duration: options.duration,
  2535. easing: options.easing,
  2536. complete: done
  2537. } );
  2538. } );
  2539. /*!
  2540. * jQuery UI Effects Bounce 1.14.1
  2541. * https://jqueryui.com
  2542. *
  2543. * Copyright OpenJS Foundation and other contributors
  2544. * Released under the MIT license.
  2545. * https://jquery.org/license
  2546. */
  2547. //>>label: Bounce Effect
  2548. //>>group: Effects
  2549. //>>description: Bounces an element horizontally or vertically n times.
  2550. //>>docs: https://api.jqueryui.com/bounce-effect/
  2551. //>>demos: https://jqueryui.com/effect/
  2552. var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) {
  2553. var upAnim, downAnim, refValue,
  2554. element = $( this ),
  2555. // Defaults:
  2556. mode = options.mode,
  2557. hide = mode === "hide",
  2558. show = mode === "show",
  2559. direction = options.direction || "up",
  2560. distance = options.distance,
  2561. times = options.times || 5,
  2562. // Number of internal animations
  2563. anims = times * 2 + ( show || hide ? 1 : 0 ),
  2564. speed = options.duration / anims,
  2565. easing = options.easing,
  2566. // Utility:
  2567. ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
  2568. motion = ( direction === "up" || direction === "left" ),
  2569. i = 0,
  2570. queuelen = element.queue().length;
  2571. $.effects.createPlaceholder( element );
  2572. refValue = element.css( ref );
  2573. // Default distance for the BIGGEST bounce is the outer Distance / 3
  2574. if ( !distance ) {
  2575. distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
  2576. }
  2577. if ( show ) {
  2578. downAnim = { opacity: 1 };
  2579. downAnim[ ref ] = refValue;
  2580. // If we are showing, force opacity 0 and set the initial position
  2581. // then do the "first" animation
  2582. element
  2583. .css( "opacity", 0 )
  2584. .css( ref, motion ? -distance * 2 : distance * 2 )
  2585. .animate( downAnim, speed, easing );
  2586. }
  2587. // Start at the smallest distance if we are hiding
  2588. if ( hide ) {
  2589. distance = distance / Math.pow( 2, times - 1 );
  2590. }
  2591. downAnim = {};
  2592. downAnim[ ref ] = refValue;
  2593. // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
  2594. for ( ; i < times; i++ ) {
  2595. upAnim = {};
  2596. upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
  2597. element
  2598. .animate( upAnim, speed, easing )
  2599. .animate( downAnim, speed, easing );
  2600. distance = hide ? distance * 2 : distance / 2;
  2601. }
  2602. // Last Bounce when Hiding
  2603. if ( hide ) {
  2604. upAnim = { opacity: 0 };
  2605. upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
  2606. element.animate( upAnim, speed, easing );
  2607. }
  2608. element.queue( done );
  2609. $.effects.unshift( element, queuelen, anims + 1 );
  2610. } );
  2611. /*!
  2612. * jQuery UI Effects Clip 1.14.1
  2613. * https://jqueryui.com
  2614. *
  2615. * Copyright OpenJS Foundation and other contributors
  2616. * Released under the MIT license.
  2617. * https://jquery.org/license
  2618. */
  2619. //>>label: Clip Effect
  2620. //>>group: Effects
  2621. //>>description: Clips the element on and off like an old TV.
  2622. //>>docs: https://api.jqueryui.com/clip-effect/
  2623. //>>demos: https://jqueryui.com/effect/
  2624. var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) {
  2625. var start,
  2626. animate = {},
  2627. element = $( this ),
  2628. direction = options.direction || "vertical",
  2629. both = direction === "both",
  2630. horizontal = both || direction === "horizontal",
  2631. vertical = both || direction === "vertical";
  2632. start = element.cssClip();
  2633. animate.clip = {
  2634. top: vertical ? ( start.bottom - start.top ) / 2 : start.top,
  2635. right: horizontal ? ( start.right - start.left ) / 2 : start.right,
  2636. bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom,
  2637. left: horizontal ? ( start.right - start.left ) / 2 : start.left
  2638. };
  2639. $.effects.createPlaceholder( element );
  2640. if ( options.mode === "show" ) {
  2641. element.cssClip( animate.clip );
  2642. animate.clip = start;
  2643. }
  2644. element.animate( animate, {
  2645. queue: false,
  2646. duration: options.duration,
  2647. easing: options.easing,
  2648. complete: done
  2649. } );
  2650. } );
  2651. /*!
  2652. * jQuery UI Effects Drop 1.14.1
  2653. * https://jqueryui.com
  2654. *
  2655. * Copyright OpenJS Foundation and other contributors
  2656. * Released under the MIT license.
  2657. * https://jquery.org/license
  2658. */
  2659. //>>label: Drop Effect
  2660. //>>group: Effects
  2661. //>>description: Moves an element in one direction and hides it at the same time.
  2662. //>>docs: https://api.jqueryui.com/drop-effect/
  2663. //>>demos: https://jqueryui.com/effect/
  2664. var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) {
  2665. var distance,
  2666. element = $( this ),
  2667. mode = options.mode,
  2668. show = mode === "show",
  2669. direction = options.direction || "left",
  2670. ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
  2671. motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=",
  2672. oppositeMotion = ( motion === "+=" ) ? "-=" : "+=",
  2673. animation = {
  2674. opacity: 0
  2675. };
  2676. $.effects.createPlaceholder( element );
  2677. distance = options.distance ||
  2678. element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
  2679. animation[ ref ] = motion + distance;
  2680. if ( show ) {
  2681. element.css( animation );
  2682. animation[ ref ] = oppositeMotion + distance;
  2683. animation.opacity = 1;
  2684. }
  2685. // Animate
  2686. element.animate( animation, {
  2687. queue: false,
  2688. duration: options.duration,
  2689. easing: options.easing,
  2690. complete: done
  2691. } );
  2692. } );
  2693. /*!
  2694. * jQuery UI Effects Explode 1.14.1
  2695. * https://jqueryui.com
  2696. *
  2697. * Copyright OpenJS Foundation and other contributors
  2698. * Released under the MIT license.
  2699. * https://jquery.org/license
  2700. */
  2701. //>>label: Explode Effect
  2702. //>>group: Effects
  2703. /* eslint-disable max-len */
  2704. //>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness.
  2705. /* eslint-enable max-len */
  2706. //>>docs: https://api.jqueryui.com/explode-effect/
  2707. //>>demos: https://jqueryui.com/effect/
  2708. var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) {
  2709. var i, j, left, top, mx, my,
  2710. rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3,
  2711. cells = rows,
  2712. element = $( this ),
  2713. mode = options.mode,
  2714. show = mode === "show",
  2715. // Show and then visibility:hidden the element before calculating offset
  2716. offset = element.show().css( "visibility", "hidden" ).offset(),
  2717. // Width and height of a piece
  2718. width = Math.ceil( element.outerWidth() / cells ),
  2719. height = Math.ceil( element.outerHeight() / rows ),
  2720. pieces = [];
  2721. // Children animate complete:
  2722. function childComplete() {
  2723. pieces.push( this );
  2724. if ( pieces.length === rows * cells ) {
  2725. animComplete();
  2726. }
  2727. }
  2728. // Clone the element for each row and cell.
  2729. for ( i = 0; i < rows; i++ ) { // ===>
  2730. top = offset.top + i * height;
  2731. my = i - ( rows - 1 ) / 2;
  2732. for ( j = 0; j < cells; j++ ) { // |||
  2733. left = offset.left + j * width;
  2734. mx = j - ( cells - 1 ) / 2;
  2735. // Create a clone of the now hidden main element that will be absolute positioned
  2736. // within a wrapper div off the -left and -top equal to size of our pieces
  2737. element
  2738. .clone()
  2739. .appendTo( "body" )
  2740. .wrap( "<div></div>" )
  2741. .css( {
  2742. position: "absolute",
  2743. visibility: "visible",
  2744. left: -j * width,
  2745. top: -i * height
  2746. } )
  2747. // Select the wrapper - make it overflow: hidden and absolute positioned based on
  2748. // where the original was located +left and +top equal to the size of pieces
  2749. .parent()
  2750. .addClass( "ui-effects-explode" )
  2751. .css( {
  2752. position: "absolute",
  2753. overflow: "hidden",
  2754. width: width,
  2755. height: height,
  2756. left: left + ( show ? mx * width : 0 ),
  2757. top: top + ( show ? my * height : 0 ),
  2758. opacity: show ? 0 : 1
  2759. } )
  2760. .animate( {
  2761. left: left + ( show ? 0 : mx * width ),
  2762. top: top + ( show ? 0 : my * height ),
  2763. opacity: show ? 1 : 0
  2764. }, options.duration || 500, options.easing, childComplete );
  2765. }
  2766. }
  2767. function animComplete() {
  2768. element.css( {
  2769. visibility: "visible"
  2770. } );
  2771. $( pieces ).remove();
  2772. done();
  2773. }
  2774. } );
  2775. /*!
  2776. * jQuery UI Effects Fade 1.14.1
  2777. * https://jqueryui.com
  2778. *
  2779. * Copyright OpenJS Foundation and other contributors
  2780. * Released under the MIT license.
  2781. * https://jquery.org/license
  2782. */
  2783. //>>label: Fade Effect
  2784. //>>group: Effects
  2785. //>>description: Fades the element.
  2786. //>>docs: https://api.jqueryui.com/fade-effect/
  2787. //>>demos: https://jqueryui.com/effect/
  2788. var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) {
  2789. var show = options.mode === "show";
  2790. $( this )
  2791. .css( "opacity", show ? 0 : 1 )
  2792. .animate( {
  2793. opacity: show ? 1 : 0
  2794. }, {
  2795. queue: false,
  2796. duration: options.duration,
  2797. easing: options.easing,
  2798. complete: done
  2799. } );
  2800. } );
  2801. /*!
  2802. * jQuery UI Effects Fold 1.14.1
  2803. * https://jqueryui.com
  2804. *
  2805. * Copyright OpenJS Foundation and other contributors
  2806. * Released under the MIT license.
  2807. * https://jquery.org/license
  2808. */
  2809. //>>label: Fold Effect
  2810. //>>group: Effects
  2811. //>>description: Folds an element first horizontally and then vertically.
  2812. //>>docs: https://api.jqueryui.com/fold-effect/
  2813. //>>demos: https://jqueryui.com/effect/
  2814. var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) {
  2815. // Create element
  2816. var element = $( this ),
  2817. mode = options.mode,
  2818. show = mode === "show",
  2819. hide = mode === "hide",
  2820. size = options.size || 15,
  2821. percent = /([0-9]+)%/.exec( size ),
  2822. horizFirst = !!options.horizFirst,
  2823. ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ],
  2824. duration = options.duration / 2,
  2825. placeholder = $.effects.createPlaceholder( element ),
  2826. start = element.cssClip(),
  2827. animation1 = { clip: $.extend( {}, start ) },
  2828. animation2 = { clip: $.extend( {}, start ) },
  2829. distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ],
  2830. queuelen = element.queue().length;
  2831. if ( percent ) {
  2832. size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
  2833. }
  2834. animation1.clip[ ref[ 0 ] ] = size;
  2835. animation2.clip[ ref[ 0 ] ] = size;
  2836. animation2.clip[ ref[ 1 ] ] = 0;
  2837. if ( show ) {
  2838. element.cssClip( animation2.clip );
  2839. if ( placeholder ) {
  2840. placeholder.css( $.effects.clipToBox( animation2 ) );
  2841. }
  2842. animation2.clip = start;
  2843. }
  2844. // Animate
  2845. element
  2846. .queue( function( next ) {
  2847. if ( placeholder ) {
  2848. placeholder
  2849. .animate( $.effects.clipToBox( animation1 ), duration, options.easing )
  2850. .animate( $.effects.clipToBox( animation2 ), duration, options.easing );
  2851. }
  2852. next();
  2853. } )
  2854. .animate( animation1, duration, options.easing )
  2855. .animate( animation2, duration, options.easing )
  2856. .queue( done );
  2857. $.effects.unshift( element, queuelen, 4 );
  2858. } );
  2859. /*!
  2860. * jQuery UI Effects Highlight 1.14.1
  2861. * https://jqueryui.com
  2862. *
  2863. * Copyright OpenJS Foundation and other contributors
  2864. * Released under the MIT license.
  2865. * https://jquery.org/license
  2866. */
  2867. //>>label: Highlight Effect
  2868. //>>group: Effects
  2869. //>>description: Highlights the background of an element in a defined color for a custom duration.
  2870. //>>docs: https://api.jqueryui.com/highlight-effect/
  2871. //>>demos: https://jqueryui.com/effect/
  2872. var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) {
  2873. var element = $( this ),
  2874. animation = {
  2875. backgroundColor: element.css( "backgroundColor" )
  2876. };
  2877. if ( options.mode === "hide" ) {
  2878. animation.opacity = 0;
  2879. }
  2880. $.effects.saveStyle( element );
  2881. element
  2882. .css( {
  2883. backgroundImage: "none",
  2884. backgroundColor: options.color || "#ffff99"
  2885. } )
  2886. .animate( animation, {
  2887. queue: false,
  2888. duration: options.duration,
  2889. easing: options.easing,
  2890. complete: done
  2891. } );
  2892. } );
  2893. /*!
  2894. * jQuery UI Effects Size 1.14.1
  2895. * https://jqueryui.com
  2896. *
  2897. * Copyright OpenJS Foundation and other contributors
  2898. * Released under the MIT license.
  2899. * https://jquery.org/license
  2900. */
  2901. //>>label: Size Effect
  2902. //>>group: Effects
  2903. //>>description: Resize an element to a specified width and height.
  2904. //>>docs: https://api.jqueryui.com/size-effect/
  2905. //>>demos: https://jqueryui.com/effect/
  2906. var effectsEffectSize = $.effects.define( "size", function( options, done ) {
  2907. // Create element
  2908. var baseline, factor, temp,
  2909. element = $( this ),
  2910. // Copy for children
  2911. cProps = [ "fontSize" ],
  2912. vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
  2913. hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
  2914. // Set options
  2915. mode = options.mode,
  2916. restore = mode !== "effect",
  2917. scale = options.scale || "both",
  2918. origin = options.origin || [ "middle", "center" ],
  2919. position = element.css( "position" ),
  2920. pos = element.position(),
  2921. original = $.effects.scaledDimensions( element ),
  2922. from = options.from || original,
  2923. to = options.to || $.effects.scaledDimensions( element, 0 );
  2924. $.effects.createPlaceholder( element );
  2925. if ( mode === "show" ) {
  2926. temp = from;
  2927. from = to;
  2928. to = temp;
  2929. }
  2930. // Set scaling factor
  2931. factor = {
  2932. from: {
  2933. y: from.height / original.height,
  2934. x: from.width / original.width
  2935. },
  2936. to: {
  2937. y: to.height / original.height,
  2938. x: to.width / original.width
  2939. }
  2940. };
  2941. // Scale the css box
  2942. if ( scale === "box" || scale === "both" ) {
  2943. // Vertical props scaling
  2944. if ( factor.from.y !== factor.to.y ) {
  2945. from = $.effects.setTransition( element, vProps, factor.from.y, from );
  2946. to = $.effects.setTransition( element, vProps, factor.to.y, to );
  2947. }
  2948. // Horizontal props scaling
  2949. if ( factor.from.x !== factor.to.x ) {
  2950. from = $.effects.setTransition( element, hProps, factor.from.x, from );
  2951. to = $.effects.setTransition( element, hProps, factor.to.x, to );
  2952. }
  2953. }
  2954. // Scale the content
  2955. if ( scale === "content" || scale === "both" ) {
  2956. // Vertical props scaling
  2957. if ( factor.from.y !== factor.to.y ) {
  2958. from = $.effects.setTransition( element, cProps, factor.from.y, from );
  2959. to = $.effects.setTransition( element, cProps, factor.to.y, to );
  2960. }
  2961. }
  2962. // Adjust the position properties based on the provided origin points
  2963. if ( origin ) {
  2964. baseline = $.effects.getBaseline( origin, original );
  2965. from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top;
  2966. from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left;
  2967. to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top;
  2968. to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left;
  2969. }
  2970. delete from.outerHeight;
  2971. delete from.outerWidth;
  2972. element.css( from );
  2973. // Animate the children if desired
  2974. if ( scale === "content" || scale === "both" ) {
  2975. vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps );
  2976. hProps = hProps.concat( [ "marginLeft", "marginRight" ] );
  2977. // Only animate children with width attributes specified
  2978. // TODO: is this right? should we include anything with css width specified as well
  2979. element.find( "*[width]" ).each( function() {
  2980. var child = $( this ),
  2981. childOriginal = $.effects.scaledDimensions( child ),
  2982. childFrom = {
  2983. height: childOriginal.height * factor.from.y,
  2984. width: childOriginal.width * factor.from.x,
  2985. outerHeight: childOriginal.outerHeight * factor.from.y,
  2986. outerWidth: childOriginal.outerWidth * factor.from.x
  2987. },
  2988. childTo = {
  2989. height: childOriginal.height * factor.to.y,
  2990. width: childOriginal.width * factor.to.x,
  2991. outerHeight: childOriginal.height * factor.to.y,
  2992. outerWidth: childOriginal.width * factor.to.x
  2993. };
  2994. // Vertical props scaling
  2995. if ( factor.from.y !== factor.to.y ) {
  2996. childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom );
  2997. childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo );
  2998. }
  2999. // Horizontal props scaling
  3000. if ( factor.from.x !== factor.to.x ) {
  3001. childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom );
  3002. childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo );
  3003. }
  3004. if ( restore ) {
  3005. $.effects.saveStyle( child );
  3006. }
  3007. // Animate children
  3008. child.css( childFrom );
  3009. child.animate( childTo, options.duration, options.easing, function() {
  3010. // Restore children
  3011. if ( restore ) {
  3012. $.effects.restoreStyle( child );
  3013. }
  3014. } );
  3015. } );
  3016. }
  3017. // Animate
  3018. element.animate( to, {
  3019. queue: false,
  3020. duration: options.duration,
  3021. easing: options.easing,
  3022. complete: function() {
  3023. var offset = element.offset();
  3024. if ( to.opacity === 0 ) {
  3025. element.css( "opacity", from.opacity );
  3026. }
  3027. if ( !restore ) {
  3028. element
  3029. .css( "position", position === "static" ? "relative" : position )
  3030. .offset( offset );
  3031. // Need to save style here so that automatic style restoration
  3032. // doesn't restore to the original styles from before the animation.
  3033. $.effects.saveStyle( element );
  3034. }
  3035. done();
  3036. }
  3037. } );
  3038. } );
  3039. /*!
  3040. * jQuery UI Effects Scale 1.14.1
  3041. * https://jqueryui.com
  3042. *
  3043. * Copyright OpenJS Foundation and other contributors
  3044. * Released under the MIT license.
  3045. * https://jquery.org/license
  3046. */
  3047. //>>label: Scale Effect
  3048. //>>group: Effects
  3049. //>>description: Grows or shrinks an element and its content.
  3050. //>>docs: https://api.jqueryui.com/scale-effect/
  3051. //>>demos: https://jqueryui.com/effect/
  3052. var effectsEffectScale = $.effects.define( "scale", function( options, done ) {
  3053. // Create element
  3054. var el = $( this ),
  3055. mode = options.mode,
  3056. percent = parseInt( options.percent, 10 ) ||
  3057. ( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ),
  3058. newOptions = $.extend( true, {
  3059. from: $.effects.scaledDimensions( el ),
  3060. to: $.effects.scaledDimensions( el, percent, options.direction || "both" ),
  3061. origin: options.origin || [ "middle", "center" ]
  3062. }, options );
  3063. // Fade option to support puff
  3064. if ( options.fade ) {
  3065. newOptions.from.opacity = 1;
  3066. newOptions.to.opacity = 0;
  3067. }
  3068. $.effects.effect.size.call( this, newOptions, done );
  3069. } );
  3070. /*!
  3071. * jQuery UI Effects Puff 1.14.1
  3072. * https://jqueryui.com
  3073. *
  3074. * Copyright OpenJS Foundation and other contributors
  3075. * Released under the MIT license.
  3076. * https://jquery.org/license
  3077. */
  3078. //>>label: Puff Effect
  3079. //>>group: Effects
  3080. //>>description: Creates a puff effect by scaling the element up and hiding it at the same time.
  3081. //>>docs: https://api.jqueryui.com/puff-effect/
  3082. //>>demos: https://jqueryui.com/effect/
  3083. var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) {
  3084. var newOptions = $.extend( true, {}, options, {
  3085. fade: true,
  3086. percent: parseInt( options.percent, 10 ) || 150
  3087. } );
  3088. $.effects.effect.scale.call( this, newOptions, done );
  3089. } );
  3090. /*!
  3091. * jQuery UI Effects Pulsate 1.14.1
  3092. * https://jqueryui.com
  3093. *
  3094. * Copyright OpenJS Foundation and other contributors
  3095. * Released under the MIT license.
  3096. * https://jquery.org/license
  3097. */
  3098. //>>label: Pulsate Effect
  3099. //>>group: Effects
  3100. //>>description: Pulsates an element n times by changing the opacity to zero and back.
  3101. //>>docs: https://api.jqueryui.com/pulsate-effect/
  3102. //>>demos: https://jqueryui.com/effect/
  3103. var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) {
  3104. var element = $( this ),
  3105. mode = options.mode,
  3106. show = mode === "show",
  3107. hide = mode === "hide",
  3108. showhide = show || hide,
  3109. // Showing or hiding leaves off the "last" animation
  3110. anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
  3111. duration = options.duration / anims,
  3112. animateTo = 0,
  3113. i = 1,
  3114. queuelen = element.queue().length;
  3115. if ( show || !element.is( ":visible" ) ) {
  3116. element.css( "opacity", 0 ).show();
  3117. animateTo = 1;
  3118. }
  3119. // Anims - 1 opacity "toggles"
  3120. for ( ; i < anims; i++ ) {
  3121. element.animate( { opacity: animateTo }, duration, options.easing );
  3122. animateTo = 1 - animateTo;
  3123. }
  3124. element.animate( { opacity: animateTo }, duration, options.easing );
  3125. element.queue( done );
  3126. $.effects.unshift( element, queuelen, anims + 1 );
  3127. } );
  3128. /*!
  3129. * jQuery UI Effects Shake 1.14.1
  3130. * https://jqueryui.com
  3131. *
  3132. * Copyright OpenJS Foundation and other contributors
  3133. * Released under the MIT license.
  3134. * https://jquery.org/license
  3135. */
  3136. //>>label: Shake Effect
  3137. //>>group: Effects
  3138. //>>description: Shakes an element horizontally or vertically n times.
  3139. //>>docs: https://api.jqueryui.com/shake-effect/
  3140. //>>demos: https://jqueryui.com/effect/
  3141. var effectsEffectShake = $.effects.define( "shake", function( options, done ) {
  3142. var i = 1,
  3143. element = $( this ),
  3144. direction = options.direction || "left",
  3145. distance = options.distance || 20,
  3146. times = options.times || 3,
  3147. anims = times * 2 + 1,
  3148. speed = Math.round( options.duration / anims ),
  3149. ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
  3150. positiveMotion = ( direction === "up" || direction === "left" ),
  3151. animation = {},
  3152. animation1 = {},
  3153. animation2 = {},
  3154. queuelen = element.queue().length;
  3155. $.effects.createPlaceholder( element );
  3156. // Animation
  3157. animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
  3158. animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
  3159. animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
  3160. // Animate
  3161. element.animate( animation, speed, options.easing );
  3162. // Shakes
  3163. for ( ; i < times; i++ ) {
  3164. element
  3165. .animate( animation1, speed, options.easing )
  3166. .animate( animation2, speed, options.easing );
  3167. }
  3168. element
  3169. .animate( animation1, speed, options.easing )
  3170. .animate( animation, speed / 2, options.easing )
  3171. .queue( done );
  3172. $.effects.unshift( element, queuelen, anims + 1 );
  3173. } );
  3174. /*!
  3175. * jQuery UI Effects Slide 1.14.1
  3176. * https://jqueryui.com
  3177. *
  3178. * Copyright OpenJS Foundation and other contributors
  3179. * Released under the MIT license.
  3180. * https://jquery.org/license
  3181. */
  3182. //>>label: Slide Effect
  3183. //>>group: Effects
  3184. //>>description: Slides an element in and out of the viewport.
  3185. //>>docs: https://api.jqueryui.com/slide-effect/
  3186. //>>demos: https://jqueryui.com/effect/
  3187. var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) {
  3188. var startClip, startRef,
  3189. element = $( this ),
  3190. map = {
  3191. up: [ "bottom", "top" ],
  3192. down: [ "top", "bottom" ],
  3193. left: [ "right", "left" ],
  3194. right: [ "left", "right" ]
  3195. },
  3196. mode = options.mode,
  3197. direction = options.direction || "left",
  3198. ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
  3199. positiveMotion = ( direction === "up" || direction === "left" ),
  3200. distance = options.distance ||
  3201. element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ),
  3202. animation = {};
  3203. $.effects.createPlaceholder( element );
  3204. startClip = element.cssClip();
  3205. startRef = element.position()[ ref ];
  3206. // Define hide animation
  3207. animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef;
  3208. animation.clip = element.cssClip();
  3209. animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ];
  3210. // Reverse the animation if we're showing
  3211. if ( mode === "show" ) {
  3212. element.cssClip( animation.clip );
  3213. element.css( ref, animation[ ref ] );
  3214. animation.clip = startClip;
  3215. animation[ ref ] = startRef;
  3216. }
  3217. // Actually animate
  3218. element.animate( animation, {
  3219. queue: false,
  3220. duration: options.duration,
  3221. easing: options.easing,
  3222. complete: done
  3223. } );
  3224. } );
  3225. /*!
  3226. * jQuery UI Effects Transfer 1.14.1
  3227. * https://jqueryui.com
  3228. *
  3229. * Copyright OpenJS Foundation and other contributors
  3230. * Released under the MIT license.
  3231. * https://jquery.org/license
  3232. */
  3233. //>>label: Transfer Effect
  3234. //>>group: Effects
  3235. //>>description: Displays a transfer effect from one element to another.
  3236. //>>docs: https://api.jqueryui.com/transfer-effect/
  3237. //>>demos: https://jqueryui.com/effect/
  3238. var effect;
  3239. if ( $.uiBackCompat === true ) {
  3240. effect = $.effects.define( "transfer", function( options, done ) {
  3241. $( this ).transfer( options, done );
  3242. } );
  3243. }
  3244. var effectsEffectTransfer = effect;
  3245. /*!
  3246. * jQuery UI Focusable 1.14.1
  3247. * https://jqueryui.com
  3248. *
  3249. * Copyright OpenJS Foundation and other contributors
  3250. * Released under the MIT license.
  3251. * https://jquery.org/license
  3252. */
  3253. //>>label: :focusable Selector
  3254. //>>group: Core
  3255. //>>description: Selects elements which can be focused.
  3256. //>>docs: https://api.jqueryui.com/focusable-selector/
  3257. // Selectors
  3258. $.ui.focusable = function( element, hasTabindex ) {
  3259. var map, mapName, img, focusableIfVisible, fieldset,
  3260. nodeName = element.nodeName.toLowerCase();
  3261. if ( "area" === nodeName ) {
  3262. map = element.parentNode;
  3263. mapName = map.name;
  3264. if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
  3265. return false;
  3266. }
  3267. img = $( "img[usemap='#" + mapName + "']" );
  3268. return img.length > 0 && img.is( ":visible" );
  3269. }
  3270. if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) {
  3271. focusableIfVisible = !element.disabled;
  3272. if ( focusableIfVisible ) {
  3273. // Form controls within a disabled fieldset are disabled.
  3274. // However, controls within the fieldset's legend do not get disabled.
  3275. // Since controls generally aren't placed inside legends, we skip
  3276. // this portion of the check.
  3277. fieldset = $( element ).closest( "fieldset" )[ 0 ];
  3278. if ( fieldset ) {
  3279. focusableIfVisible = !fieldset.disabled;
  3280. }
  3281. }
  3282. } else if ( "a" === nodeName ) {
  3283. focusableIfVisible = element.href || hasTabindex;
  3284. } else {
  3285. focusableIfVisible = hasTabindex;
  3286. }
  3287. return focusableIfVisible && $( element ).is( ":visible" ) &&
  3288. $( element ).css( "visibility" ) === "visible";
  3289. };
  3290. $.extend( $.expr.pseudos, {
  3291. focusable: function( element ) {
  3292. return $.ui.focusable( element, $.attr( element, "tabindex" ) != null );
  3293. }
  3294. } );
  3295. var focusable = $.ui.focusable;
  3296. /*!
  3297. * jQuery UI Form Reset Mixin 1.14.1
  3298. * https://jqueryui.com
  3299. *
  3300. * Copyright OpenJS Foundation and other contributors
  3301. * Released under the MIT license.
  3302. * https://jquery.org/license
  3303. */
  3304. //>>label: Form Reset Mixin
  3305. //>>group: Core
  3306. //>>description: Refresh input widgets when their form is reset
  3307. //>>docs: https://api.jqueryui.com/form-reset-mixin/
  3308. var formResetMixin = $.ui.formResetMixin = {
  3309. _formResetHandler: function() {
  3310. var form = $( this );
  3311. // Wait for the form reset to actually happen before refreshing
  3312. setTimeout( function() {
  3313. var instances = form.data( "ui-form-reset-instances" );
  3314. $.each( instances, function() {
  3315. this.refresh();
  3316. } );
  3317. } );
  3318. },
  3319. _bindFormResetHandler: function() {
  3320. this.form = $( this.element.prop( "form" ) );
  3321. if ( !this.form.length ) {
  3322. return;
  3323. }
  3324. var instances = this.form.data( "ui-form-reset-instances" ) || [];
  3325. if ( !instances.length ) {
  3326. // We don't use _on() here because we use a single event handler per form
  3327. this.form.on( "reset.ui-form-reset", this._formResetHandler );
  3328. }
  3329. instances.push( this );
  3330. this.form.data( "ui-form-reset-instances", instances );
  3331. },
  3332. _unbindFormResetHandler: function() {
  3333. if ( !this.form.length ) {
  3334. return;
  3335. }
  3336. var instances = this.form.data( "ui-form-reset-instances" );
  3337. instances.splice( $.inArray( this, instances ), 1 );
  3338. if ( instances.length ) {
  3339. this.form.data( "ui-form-reset-instances", instances );
  3340. } else {
  3341. this.form
  3342. .removeData( "ui-form-reset-instances" )
  3343. .off( "reset.ui-form-reset" );
  3344. }
  3345. }
  3346. };
  3347. /*!
  3348. * jQuery UI Legacy jQuery Core patches 1.14.1
  3349. * https://jqueryui.com
  3350. *
  3351. * Copyright OpenJS Foundation and other contributors
  3352. * Released under the MIT license.
  3353. * https://jquery.org/license
  3354. *
  3355. */
  3356. //>>label: Legacy jQuery Core patches
  3357. //>>group: Core
  3358. //>>description: Backport `.even()`, `.odd()` and `$.escapeSelector` to older jQuery Core versions (deprecated)
  3359. // Support: jQuery 2.2.x or older.
  3360. // This method has been defined in jQuery 3.0.0.
  3361. // Code from https://github.com/jquery/jquery/blob/e539bac79e666bba95bba86d690b4e609dca2286/src/selector/escapeSelector.js
  3362. if ( !$.escapeSelector ) {
  3363. $.escapeSelector = function( id ) {
  3364. return CSS.escape( id + "" );
  3365. };
  3366. }
  3367. // Support: jQuery 3.4.x or older
  3368. // These methods have been defined in jQuery 3.5.0.
  3369. if ( !$.fn.even || !$.fn.odd ) {
  3370. $.fn.extend( {
  3371. even: function() {
  3372. return this.filter( function( i ) {
  3373. return i % 2 === 0;
  3374. } );
  3375. },
  3376. odd: function() {
  3377. return this.filter( function( i ) {
  3378. return i % 2 === 1;
  3379. } );
  3380. }
  3381. } );
  3382. }
  3383. ;
  3384. /*!
  3385. * jQuery UI Keycode 1.14.1
  3386. * https://jqueryui.com
  3387. *
  3388. * Copyright OpenJS Foundation and other contributors
  3389. * Released under the MIT license.
  3390. * https://jquery.org/license
  3391. */
  3392. //>>label: Keycode
  3393. //>>group: Core
  3394. //>>description: Provide keycodes as keynames
  3395. //>>docs: https://api.jqueryui.com/jQuery.ui.keyCode/
  3396. var keycode = $.ui.keyCode = {
  3397. BACKSPACE: 8,
  3398. COMMA: 188,
  3399. DELETE: 46,
  3400. DOWN: 40,
  3401. END: 35,
  3402. ENTER: 13,
  3403. ESCAPE: 27,
  3404. HOME: 36,
  3405. LEFT: 37,
  3406. PAGE_DOWN: 34,
  3407. PAGE_UP: 33,
  3408. PERIOD: 190,
  3409. RIGHT: 39,
  3410. SPACE: 32,
  3411. TAB: 9,
  3412. UP: 38
  3413. };
  3414. /*!
  3415. * jQuery UI Labels 1.14.1
  3416. * https://jqueryui.com
  3417. *
  3418. * Copyright OpenJS Foundation and other contributors
  3419. * Released under the MIT license.
  3420. * https://jquery.org/license
  3421. */
  3422. //>>label: labels
  3423. //>>group: Core
  3424. //>>description: Find all the labels associated with a given input
  3425. //>>docs: https://api.jqueryui.com/labels/
  3426. var labels = $.fn.labels = function() {
  3427. var ancestor, selector, id, labels, ancestors;
  3428. if ( !this.length ) {
  3429. return this.pushStack( [] );
  3430. }
  3431. // Check control.labels first
  3432. if ( this[ 0 ].labels && this[ 0 ].labels.length ) {
  3433. return this.pushStack( this[ 0 ].labels );
  3434. }
  3435. // If `control.labels` is empty - e.g. inside of document fragments - find
  3436. // the labels manually
  3437. labels = this.eq( 0 ).parents( "label" );
  3438. // Look for the label based on the id
  3439. id = this.attr( "id" );
  3440. if ( id ) {
  3441. // We don't search against the document in case the element
  3442. // is disconnected from the DOM
  3443. ancestor = this.eq( 0 ).parents().last();
  3444. // Get a full set of top level ancestors
  3445. ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() );
  3446. // Create a selector for the label based on the id
  3447. selector = "label[for='" + CSS.escape( id ) + "']";
  3448. labels = labels.add( ancestors.find( selector ).addBack( selector ) );
  3449. }
  3450. // Return whatever we have found for labels
  3451. return this.pushStack( labels );
  3452. };
  3453. /*!
  3454. * jQuery UI Scroll Parent 1.14.1
  3455. * https://jqueryui.com
  3456. *
  3457. * Copyright OpenJS Foundation and other contributors
  3458. * Released under the MIT license.
  3459. * https://jquery.org/license
  3460. */
  3461. //>>label: scrollParent
  3462. //>>group: Core
  3463. //>>description: Get the closest ancestor element that is scrollable.
  3464. //>>docs: https://api.jqueryui.com/scrollParent/
  3465. var scrollParent = $.fn.scrollParent = function( includeHidden ) {
  3466. var position = this.css( "position" ),
  3467. excludeStaticParent = position === "absolute",
  3468. overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
  3469. scrollParent = this.parents().filter( function() {
  3470. var parent = $( this );
  3471. if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
  3472. return false;
  3473. }
  3474. return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
  3475. parent.css( "overflow-x" ) );
  3476. } ).eq( 0 );
  3477. return position === "fixed" || !scrollParent.length ?
  3478. $( this[ 0 ].ownerDocument || document ) :
  3479. scrollParent;
  3480. };
  3481. /*!
  3482. * jQuery UI Tabbable 1.14.1
  3483. * https://jqueryui.com
  3484. *
  3485. * Copyright OpenJS Foundation and other contributors
  3486. * Released under the MIT license.
  3487. * https://jquery.org/license
  3488. */
  3489. //>>label: :tabbable Selector
  3490. //>>group: Core
  3491. //>>description: Selects elements which can be tabbed to.
  3492. //>>docs: https://api.jqueryui.com/tabbable-selector/
  3493. var tabbable = $.extend( $.expr.pseudos, {
  3494. tabbable: function( element ) {
  3495. var tabIndex = $.attr( element, "tabindex" ),
  3496. hasTabindex = tabIndex != null;
  3497. return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex );
  3498. }
  3499. } );
  3500. /*!
  3501. * jQuery UI Unique ID 1.14.1
  3502. * https://jqueryui.com
  3503. *
  3504. * Copyright OpenJS Foundation and other contributors
  3505. * Released under the MIT license.
  3506. * https://jquery.org/license
  3507. */
  3508. //>>label: uniqueId
  3509. //>>group: Core
  3510. //>>description: Functions to generate and remove uniqueId's
  3511. //>>docs: https://api.jqueryui.com/uniqueId/
  3512. var uniqueId = $.fn.extend( {
  3513. uniqueId: ( function() {
  3514. var uuid = 0;
  3515. return function() {
  3516. return this.each( function() {
  3517. if ( !this.id ) {
  3518. this.id = "ui-id-" + ( ++uuid );
  3519. }
  3520. } );
  3521. };
  3522. } )(),
  3523. removeUniqueId: function() {
  3524. return this.each( function() {
  3525. if ( /^ui-id-\d+$/.test( this.id ) ) {
  3526. $( this ).removeAttr( "id" );
  3527. }
  3528. } );
  3529. }
  3530. } );
  3531. /*!
  3532. * jQuery UI Accordion 1.14.1
  3533. * https://jqueryui.com
  3534. *
  3535. * Copyright OpenJS Foundation and other contributors
  3536. * Released under the MIT license.
  3537. * https://jquery.org/license
  3538. */
  3539. //>>label: Accordion
  3540. //>>group: Widgets
  3541. /* eslint-disable max-len */
  3542. //>>description: Displays collapsible content panels for presenting information in a limited amount of space.
  3543. /* eslint-enable max-len */
  3544. //>>docs: https://api.jqueryui.com/accordion/
  3545. //>>demos: https://jqueryui.com/accordion/
  3546. //>>css.structure: ../../themes/base/core.css
  3547. //>>css.structure: ../../themes/base/accordion.css
  3548. //>>css.theme: ../../themes/base/theme.css
  3549. var widgetsAccordion = $.widget( "ui.accordion", {
  3550. version: "1.14.1",
  3551. options: {
  3552. active: 0,
  3553. animate: {},
  3554. classes: {
  3555. "ui-accordion-header": "ui-corner-top",
  3556. "ui-accordion-header-collapsed": "ui-corner-all",
  3557. "ui-accordion-content": "ui-corner-bottom"
  3558. },
  3559. collapsible: false,
  3560. event: "click",
  3561. header: function( elem ) {
  3562. return elem
  3563. .find( "> li > :first-child" )
  3564. .add(
  3565. elem.find( "> :not(li)" )
  3566. // Support: jQuery <3.5 only
  3567. // We could use `.even()` but that's unavailable in older jQuery.
  3568. .filter( function( i ) {
  3569. return i % 2 === 0;
  3570. } )
  3571. );
  3572. },
  3573. heightStyle: "auto",
  3574. icons: {
  3575. activeHeader: "ui-icon-triangle-1-s",
  3576. header: "ui-icon-triangle-1-e"
  3577. },
  3578. // Callbacks
  3579. activate: null,
  3580. beforeActivate: null
  3581. },
  3582. hideProps: {
  3583. borderTopWidth: "hide",
  3584. borderBottomWidth: "hide",
  3585. paddingTop: "hide",
  3586. paddingBottom: "hide",
  3587. height: "hide"
  3588. },
  3589. showProps: {
  3590. borderTopWidth: "show",
  3591. borderBottomWidth: "show",
  3592. paddingTop: "show",
  3593. paddingBottom: "show",
  3594. height: "show"
  3595. },
  3596. _create: function() {
  3597. var options = this.options;
  3598. this.prevShow = this.prevHide = $();
  3599. this._addClass( "ui-accordion", "ui-widget ui-helper-reset" );
  3600. this.element.attr( "role", "tablist" );
  3601. // Don't allow collapsible: false and active: false / null
  3602. if ( !options.collapsible && ( options.active === false || options.active == null ) ) {
  3603. options.active = 0;
  3604. }
  3605. this._processPanels();
  3606. // handle negative values
  3607. if ( options.active < 0 ) {
  3608. options.active += this.headers.length;
  3609. }
  3610. this._refresh();
  3611. },
  3612. _getCreateEventData: function() {
  3613. return {
  3614. header: this.active,
  3615. panel: !this.active.length ? $() : this.active.next()
  3616. };
  3617. },
  3618. _createIcons: function() {
  3619. var icon, children,
  3620. icons = this.options.icons;
  3621. if ( icons ) {
  3622. icon = $( "<span>" );
  3623. this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header );
  3624. icon.prependTo( this.headers );
  3625. children = this.active.children( ".ui-accordion-header-icon" );
  3626. this._removeClass( children, icons.header )
  3627. ._addClass( children, null, icons.activeHeader )
  3628. ._addClass( this.headers, "ui-accordion-icons" );
  3629. }
  3630. },
  3631. _destroyIcons: function() {
  3632. this._removeClass( this.headers, "ui-accordion-icons" );
  3633. this.headers.children( ".ui-accordion-header-icon" ).remove();
  3634. },
  3635. _destroy: function() {
  3636. var contents;
  3637. // Clean up main element
  3638. this.element.removeAttr( "role" );
  3639. // Clean up headers
  3640. this.headers
  3641. .removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" )
  3642. .removeUniqueId();
  3643. this._destroyIcons();
  3644. // Clean up content panels
  3645. contents = this.headers.next()
  3646. .css( "display", "" )
  3647. .removeAttr( "role aria-hidden aria-labelledby" )
  3648. .removeUniqueId();
  3649. if ( this.options.heightStyle !== "content" ) {
  3650. contents.css( "height", "" );
  3651. }
  3652. },
  3653. _setOption: function( key, value ) {
  3654. if ( key === "active" ) {
  3655. // _activate() will handle invalid values and update this.options
  3656. this._activate( value );
  3657. return;
  3658. }
  3659. if ( key === "event" ) {
  3660. if ( this.options.event ) {
  3661. this._off( this.headers, this.options.event );
  3662. }
  3663. this._setupEvents( value );
  3664. }
  3665. this._super( key, value );
  3666. // Setting collapsible: false while collapsed; open first panel
  3667. if ( key === "collapsible" && !value && this.options.active === false ) {
  3668. this._activate( 0 );
  3669. }
  3670. if ( key === "icons" ) {
  3671. this._destroyIcons();
  3672. if ( value ) {
  3673. this._createIcons();
  3674. }
  3675. }
  3676. },
  3677. _setOptionDisabled: function( value ) {
  3678. this._super( value );
  3679. this.element.attr( "aria-disabled", value );
  3680. this._toggleClass( null, "ui-state-disabled", !!value );
  3681. },
  3682. _keydown: function( event ) {
  3683. if ( event.altKey || event.ctrlKey ) {
  3684. return;
  3685. }
  3686. var keyCode = $.ui.keyCode,
  3687. length = this.headers.length,
  3688. currentIndex = this.headers.index( event.target ),
  3689. toFocus = false;
  3690. switch ( event.keyCode ) {
  3691. case keyCode.RIGHT:
  3692. case keyCode.DOWN:
  3693. toFocus = this.headers[ ( currentIndex + 1 ) % length ];
  3694. break;
  3695. case keyCode.LEFT:
  3696. case keyCode.UP:
  3697. toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
  3698. break;
  3699. case keyCode.SPACE:
  3700. case keyCode.ENTER:
  3701. this._eventHandler( event );
  3702. break;
  3703. case keyCode.HOME:
  3704. toFocus = this.headers[ 0 ];
  3705. break;
  3706. case keyCode.END:
  3707. toFocus = this.headers[ length - 1 ];
  3708. break;
  3709. }
  3710. if ( toFocus ) {
  3711. $( event.target ).attr( "tabIndex", -1 );
  3712. $( toFocus ).attr( "tabIndex", 0 );
  3713. $( toFocus ).trigger( "focus" );
  3714. event.preventDefault();
  3715. }
  3716. },
  3717. _panelKeyDown: function( event ) {
  3718. if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
  3719. $( event.currentTarget ).prev().trigger( "focus" );
  3720. }
  3721. },
  3722. refresh: function() {
  3723. var options = this.options;
  3724. this._processPanels();
  3725. // Was collapsed or no panel
  3726. if ( ( options.active === false && options.collapsible === true ) ||
  3727. !this.headers.length ) {
  3728. options.active = false;
  3729. this.active = $();
  3730. // active false only when collapsible is true
  3731. } else if ( options.active === false ) {
  3732. this._activate( 0 );
  3733. // was active, but active panel is gone
  3734. } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
  3735. // all remaining panel are disabled
  3736. if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) {
  3737. options.active = false;
  3738. this.active = $();
  3739. // activate previous panel
  3740. } else {
  3741. this._activate( Math.max( 0, options.active - 1 ) );
  3742. }
  3743. // was active, active panel still exists
  3744. } else {
  3745. // make sure active index is correct
  3746. options.active = this.headers.index( this.active );
  3747. }
  3748. this._destroyIcons();
  3749. this._refresh();
  3750. },
  3751. _processPanels: function() {
  3752. var prevHeaders = this.headers,
  3753. prevPanels = this.panels;
  3754. if ( typeof this.options.header === "function" ) {
  3755. this.headers = this.options.header( this.element );
  3756. } else {
  3757. this.headers = this.element.find( this.options.header );
  3758. }
  3759. this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed",
  3760. "ui-state-default" );
  3761. this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide();
  3762. this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" );
  3763. // Avoid memory leaks (#10056)
  3764. if ( prevPanels ) {
  3765. this._off( prevHeaders.not( this.headers ) );
  3766. this._off( prevPanels.not( this.panels ) );
  3767. }
  3768. },
  3769. _refresh: function() {
  3770. var maxHeight,
  3771. options = this.options,
  3772. heightStyle = options.heightStyle,
  3773. parent = this.element.parent();
  3774. this.active = this._findActive( options.active );
  3775. this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" )
  3776. ._removeClass( this.active, "ui-accordion-header-collapsed" );
  3777. this._addClass( this.active.next(), "ui-accordion-content-active" );
  3778. this.active.next().show();
  3779. this.headers
  3780. .attr( "role", "tab" )
  3781. .each( function() {
  3782. var header = $( this ),
  3783. headerId = header.uniqueId().attr( "id" ),
  3784. panel = header.next(),
  3785. panelId = panel.uniqueId().attr( "id" );
  3786. header.attr( "aria-controls", panelId );
  3787. panel.attr( "aria-labelledby", headerId );
  3788. } )
  3789. .next()
  3790. .attr( "role", "tabpanel" );
  3791. this.headers
  3792. .not( this.active )
  3793. .attr( {
  3794. "aria-selected": "false",
  3795. "aria-expanded": "false",
  3796. tabIndex: -1
  3797. } )
  3798. .next()
  3799. .attr( {
  3800. "aria-hidden": "true"
  3801. } )
  3802. .hide();
  3803. // Make sure at least one header is in the tab order
  3804. if ( !this.active.length ) {
  3805. this.headers.eq( 0 ).attr( "tabIndex", 0 );
  3806. } else {
  3807. this.active.attr( {
  3808. "aria-selected": "true",
  3809. "aria-expanded": "true",
  3810. tabIndex: 0
  3811. } )
  3812. .next()
  3813. .attr( {
  3814. "aria-hidden": "false"
  3815. } );
  3816. }
  3817. this._createIcons();
  3818. this._setupEvents( options.event );
  3819. if ( heightStyle === "fill" ) {
  3820. maxHeight = parent.height();
  3821. this.element.siblings( ":visible" ).each( function() {
  3822. var elem = $( this ),
  3823. position = elem.css( "position" );
  3824. if ( position === "absolute" || position === "fixed" ) {
  3825. return;
  3826. }
  3827. maxHeight -= elem.outerHeight( true );
  3828. } );
  3829. this.headers.each( function() {
  3830. maxHeight -= $( this ).outerHeight( true );
  3831. } );
  3832. this.headers.next()
  3833. .each( function() {
  3834. $( this ).height( Math.max( 0, maxHeight -
  3835. $( this ).innerHeight() + $( this ).height() ) );
  3836. } )
  3837. .css( "overflow", "auto" );
  3838. } else if ( heightStyle === "auto" ) {
  3839. maxHeight = 0;
  3840. this.headers.next()
  3841. .each( function() {
  3842. var isVisible = $( this ).is( ":visible" );
  3843. if ( !isVisible ) {
  3844. $( this ).show();
  3845. }
  3846. maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
  3847. if ( !isVisible ) {
  3848. $( this ).hide();
  3849. }
  3850. } )
  3851. .height( maxHeight );
  3852. }
  3853. },
  3854. _activate: function( index ) {
  3855. var active = this._findActive( index )[ 0 ];
  3856. // Trying to activate the already active panel
  3857. if ( active === this.active[ 0 ] ) {
  3858. return;
  3859. }
  3860. // Trying to collapse, simulate a click on the currently active header
  3861. active = active || this.active[ 0 ];
  3862. this._eventHandler( {
  3863. target: active,
  3864. currentTarget: active,
  3865. preventDefault: $.noop
  3866. } );
  3867. },
  3868. _findActive: function( selector ) {
  3869. return typeof selector === "number" ? this.headers.eq( selector ) : $();
  3870. },
  3871. _setupEvents: function( event ) {
  3872. var events = {
  3873. keydown: "_keydown"
  3874. };
  3875. if ( event ) {
  3876. $.each( event.split( " " ), function( index, eventName ) {
  3877. events[ eventName ] = "_eventHandler";
  3878. } );
  3879. }
  3880. this._off( this.headers.add( this.headers.next() ) );
  3881. this._on( this.headers, events );
  3882. this._on( this.headers.next(), { keydown: "_panelKeyDown" } );
  3883. this._hoverable( this.headers );
  3884. this._focusable( this.headers );
  3885. },
  3886. _eventHandler: function( event ) {
  3887. var activeChildren, clickedChildren,
  3888. options = this.options,
  3889. active = this.active,
  3890. clicked = $( event.currentTarget ),
  3891. clickedIsActive = clicked[ 0 ] === active[ 0 ],
  3892. collapsing = clickedIsActive && options.collapsible,
  3893. toShow = collapsing ? $() : clicked.next(),
  3894. toHide = active.next(),
  3895. eventData = {
  3896. oldHeader: active,
  3897. oldPanel: toHide,
  3898. newHeader: collapsing ? $() : clicked,
  3899. newPanel: toShow
  3900. };
  3901. event.preventDefault();
  3902. if (
  3903. // click on active header, but not collapsible
  3904. ( clickedIsActive && !options.collapsible ) ||
  3905. // allow canceling activation
  3906. ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
  3907. return;
  3908. }
  3909. options.active = collapsing ? false : this.headers.index( clicked );
  3910. // When the call to ._toggle() comes after the class changes
  3911. // it causes a very odd bug in IE 8 (see #6720)
  3912. this.active = clickedIsActive ? $() : clicked;
  3913. this._toggle( eventData );
  3914. // Switch classes
  3915. // corner classes on the previously active header stay after the animation
  3916. this._removeClass( active, "ui-accordion-header-active", "ui-state-active" );
  3917. if ( options.icons ) {
  3918. activeChildren = active.children( ".ui-accordion-header-icon" );
  3919. this._removeClass( activeChildren, null, options.icons.activeHeader )
  3920. ._addClass( activeChildren, null, options.icons.header );
  3921. }
  3922. if ( !clickedIsActive ) {
  3923. this._removeClass( clicked, "ui-accordion-header-collapsed" )
  3924. ._addClass( clicked, "ui-accordion-header-active", "ui-state-active" );
  3925. if ( options.icons ) {
  3926. clickedChildren = clicked.children( ".ui-accordion-header-icon" );
  3927. this._removeClass( clickedChildren, null, options.icons.header )
  3928. ._addClass( clickedChildren, null, options.icons.activeHeader );
  3929. }
  3930. this._addClass( clicked.next(), "ui-accordion-content-active" );
  3931. }
  3932. },
  3933. _toggle: function( data ) {
  3934. var toShow = data.newPanel,
  3935. toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
  3936. // Handle activating a panel during the animation for another activation
  3937. this.prevShow.add( this.prevHide ).stop( true, true );
  3938. this.prevShow = toShow;
  3939. this.prevHide = toHide;
  3940. if ( this.options.animate ) {
  3941. this._animate( toShow, toHide, data );
  3942. } else {
  3943. toHide.hide();
  3944. toShow.show();
  3945. this._toggleComplete( data );
  3946. }
  3947. toHide.attr( {
  3948. "aria-hidden": "true"
  3949. } );
  3950. toHide.prev().attr( {
  3951. "aria-selected": "false",
  3952. "aria-expanded": "false"
  3953. } );
  3954. // if we're switching panels, remove the old header from the tab order
  3955. // if we're opening from collapsed state, remove the previous header from the tab order
  3956. // if we're collapsing, then keep the collapsing header in the tab order
  3957. if ( toShow.length && toHide.length ) {
  3958. toHide.prev().attr( {
  3959. "tabIndex": -1,
  3960. "aria-expanded": "false"
  3961. } );
  3962. } else if ( toShow.length ) {
  3963. this.headers.filter( function() {
  3964. return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
  3965. } )
  3966. .attr( "tabIndex", -1 );
  3967. }
  3968. toShow
  3969. .attr( "aria-hidden", "false" )
  3970. .prev()
  3971. .attr( {
  3972. "aria-selected": "true",
  3973. "aria-expanded": "true",
  3974. tabIndex: 0
  3975. } );
  3976. },
  3977. _animate: function( toShow, toHide, data ) {
  3978. var total, easing, duration,
  3979. that = this,
  3980. adjust = 0,
  3981. boxSizing = toShow.css( "box-sizing" ),
  3982. down = toShow.length &&
  3983. ( !toHide.length || ( toShow.index() < toHide.index() ) ),
  3984. animate = this.options.animate || {},
  3985. options = down && animate.down || animate,
  3986. complete = function() {
  3987. that._toggleComplete( data );
  3988. };
  3989. if ( typeof options === "number" ) {
  3990. duration = options;
  3991. }
  3992. if ( typeof options === "string" ) {
  3993. easing = options;
  3994. }
  3995. // fall back from options to animation in case of partial down settings
  3996. easing = easing || options.easing || animate.easing;
  3997. duration = duration || options.duration || animate.duration;
  3998. if ( !toHide.length ) {
  3999. return toShow.animate( this.showProps, duration, easing, complete );
  4000. }
  4001. if ( !toShow.length ) {
  4002. return toHide.animate( this.hideProps, duration, easing, complete );
  4003. }
  4004. total = toShow.show().outerHeight();
  4005. toHide.animate( this.hideProps, {
  4006. duration: duration,
  4007. easing: easing,
  4008. step: function( now, fx ) {
  4009. fx.now = Math.round( now );
  4010. }
  4011. } );
  4012. toShow
  4013. .hide()
  4014. .animate( this.showProps, {
  4015. duration: duration,
  4016. easing: easing,
  4017. complete: complete,
  4018. step: function( now, fx ) {
  4019. fx.now = Math.round( now );
  4020. if ( fx.prop !== "height" ) {
  4021. if ( boxSizing === "content-box" ) {
  4022. adjust += fx.now;
  4023. }
  4024. } else if ( that.options.heightStyle !== "content" ) {
  4025. fx.now = Math.round( total - toHide.outerHeight() - adjust );
  4026. adjust = 0;
  4027. }
  4028. }
  4029. } );
  4030. },
  4031. _toggleComplete: function( data ) {
  4032. var toHide = data.oldPanel,
  4033. prev = toHide.prev();
  4034. this._removeClass( toHide, "ui-accordion-content-active" );
  4035. this._removeClass( prev, "ui-accordion-header-active" )
  4036. ._addClass( prev, "ui-accordion-header-collapsed" );
  4037. this._trigger( "activate", null, data );
  4038. }
  4039. } );
  4040. /*!
  4041. * jQuery UI Menu 1.14.1
  4042. * https://jqueryui.com
  4043. *
  4044. * Copyright OpenJS Foundation and other contributors
  4045. * Released under the MIT license.
  4046. * https://jquery.org/license
  4047. */
  4048. //>>label: Menu
  4049. //>>group: Widgets
  4050. //>>description: Creates nestable menus.
  4051. //>>docs: https://api.jqueryui.com/menu/
  4052. //>>demos: https://jqueryui.com/menu/
  4053. //>>css.structure: ../../themes/base/core.css
  4054. //>>css.structure: ../../themes/base/menu.css
  4055. //>>css.theme: ../../themes/base/theme.css
  4056. var widgetsMenu = $.widget( "ui.menu", {
  4057. version: "1.14.1",
  4058. defaultElement: "<ul>",
  4059. delay: 300,
  4060. options: {
  4061. icons: {
  4062. submenu: "ui-icon-caret-1-e"
  4063. },
  4064. items: "> *",
  4065. menus: "ul",
  4066. position: {
  4067. my: "left top",
  4068. at: "right top"
  4069. },
  4070. role: "menu",
  4071. // Callbacks
  4072. blur: null,
  4073. focus: null,
  4074. select: null
  4075. },
  4076. _create: function() {
  4077. this.activeMenu = this.element;
  4078. // Flag used to prevent firing of the click handler
  4079. // as the event bubbles up through nested menus
  4080. this.mouseHandled = false;
  4081. this.lastMousePosition = { x: null, y: null };
  4082. this.element
  4083. .uniqueId()
  4084. .attr( {
  4085. role: this.options.role,
  4086. tabIndex: 0
  4087. } );
  4088. this._addClass( "ui-menu", "ui-widget ui-widget-content" );
  4089. this._on( {
  4090. // Prevent focus from sticking to links inside menu after clicking
  4091. // them (focus should always stay on UL during navigation).
  4092. "mousedown .ui-menu-item": function( event ) {
  4093. event.preventDefault();
  4094. this._activateItem( event );
  4095. },
  4096. "click .ui-menu-item": function( event ) {
  4097. var target = $( event.target );
  4098. var active = $( this.document[ 0 ].activeElement );
  4099. if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
  4100. this.select( event );
  4101. // Only set the mouseHandled flag if the event will bubble, see #9469.
  4102. if ( !event.isPropagationStopped() ) {
  4103. this.mouseHandled = true;
  4104. }
  4105. // Open submenu on click
  4106. if ( target.has( ".ui-menu" ).length ) {
  4107. this.expand( event );
  4108. } else if ( !this.element.is( ":focus" ) &&
  4109. active.closest( ".ui-menu" ).length ) {
  4110. // Redirect focus to the menu
  4111. this.element.trigger( "focus", [ true ] );
  4112. // If the active item is on the top level, let it stay active.
  4113. // Otherwise, blur the active item since it is no longer visible.
  4114. if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
  4115. clearTimeout( this.timer );
  4116. }
  4117. }
  4118. }
  4119. },
  4120. "mouseenter .ui-menu-item": "_activateItem",
  4121. "mousemove .ui-menu-item": "_activateItem",
  4122. mouseleave: "collapseAll",
  4123. "mouseleave .ui-menu": "collapseAll",
  4124. focus: function( event, keepActiveItem ) {
  4125. // If there's already an active item, keep it active
  4126. // If not, activate the first item
  4127. var item = this.active || this._menuItems().first();
  4128. if ( !keepActiveItem ) {
  4129. this.focus( event, item );
  4130. }
  4131. },
  4132. blur: function( event ) {
  4133. this._delay( function() {
  4134. var notContained = !$.contains(
  4135. this.element[ 0 ],
  4136. this.document[ 0 ].activeElement
  4137. );
  4138. if ( notContained ) {
  4139. this.collapseAll( event );
  4140. }
  4141. } );
  4142. },
  4143. keydown: "_keydown"
  4144. } );
  4145. this.refresh();
  4146. // Clicks outside of a menu collapse any open menus
  4147. this._on( this.document, {
  4148. click: function( event ) {
  4149. if ( this._closeOnDocumentClick( event ) ) {
  4150. this.collapseAll( event, true );
  4151. }
  4152. // Reset the mouseHandled flag
  4153. this.mouseHandled = false;
  4154. }
  4155. } );
  4156. },
  4157. _activateItem: function( event ) {
  4158. // Ignore mouse events while typeahead is active, see #10458.
  4159. // Prevents focusing the wrong item when typeahead causes a scroll while the mouse
  4160. // is over an item in the menu
  4161. if ( this.previousFilter ) {
  4162. return;
  4163. }
  4164. // If the mouse didn't actually move, but the page was scrolled, ignore the event (#9356)
  4165. if ( event.clientX === this.lastMousePosition.x &&
  4166. event.clientY === this.lastMousePosition.y ) {
  4167. return;
  4168. }
  4169. this.lastMousePosition = {
  4170. x: event.clientX,
  4171. y: event.clientY
  4172. };
  4173. var actualTarget = $( event.target ).closest( ".ui-menu-item" ),
  4174. target = $( event.currentTarget );
  4175. // Ignore bubbled events on parent items, see #11641
  4176. if ( actualTarget[ 0 ] !== target[ 0 ] ) {
  4177. return;
  4178. }
  4179. // If the item is already active, there's nothing to do
  4180. if ( target.is( ".ui-state-active" ) ) {
  4181. return;
  4182. }
  4183. // Remove ui-state-active class from siblings of the newly focused menu item
  4184. // to avoid a jump caused by adjacent elements both having a class with a border
  4185. this._removeClass( target.siblings().children( ".ui-state-active" ),
  4186. null, "ui-state-active" );
  4187. this.focus( event, target );
  4188. },
  4189. _destroy: function() {
  4190. var items = this.element.find( ".ui-menu-item" )
  4191. .removeAttr( "role aria-disabled" ),
  4192. submenus = items.children( ".ui-menu-item-wrapper" )
  4193. .removeUniqueId()
  4194. .removeAttr( "tabIndex role aria-haspopup" );
  4195. // Destroy (sub)menus
  4196. this.element
  4197. .removeAttr( "aria-activedescendant" )
  4198. .find( ".ui-menu" ).addBack()
  4199. .removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " +
  4200. "tabIndex" )
  4201. .removeUniqueId()
  4202. .show();
  4203. submenus.children().each( function() {
  4204. var elem = $( this );
  4205. if ( elem.data( "ui-menu-submenu-caret" ) ) {
  4206. elem.remove();
  4207. }
  4208. } );
  4209. },
  4210. _keydown: function( event ) {
  4211. var match, prev, character, skip,
  4212. preventDefault = true;
  4213. switch ( event.keyCode ) {
  4214. case $.ui.keyCode.PAGE_UP:
  4215. this.previousPage( event );
  4216. break;
  4217. case $.ui.keyCode.PAGE_DOWN:
  4218. this.nextPage( event );
  4219. break;
  4220. case $.ui.keyCode.HOME:
  4221. this._move( "first", "first", event );
  4222. break;
  4223. case $.ui.keyCode.END:
  4224. this._move( "last", "last", event );
  4225. break;
  4226. case $.ui.keyCode.UP:
  4227. this.previous( event );
  4228. break;
  4229. case $.ui.keyCode.DOWN:
  4230. this.next( event );
  4231. break;
  4232. case $.ui.keyCode.LEFT:
  4233. this.collapse( event );
  4234. break;
  4235. case $.ui.keyCode.RIGHT:
  4236. if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
  4237. this.expand( event );
  4238. }
  4239. break;
  4240. case $.ui.keyCode.ENTER:
  4241. case $.ui.keyCode.SPACE:
  4242. this._activate( event );
  4243. break;
  4244. case $.ui.keyCode.ESCAPE:
  4245. this.collapse( event );
  4246. break;
  4247. default:
  4248. preventDefault = false;
  4249. prev = this.previousFilter || "";
  4250. skip = false;
  4251. // Support number pad values
  4252. character = event.keyCode >= 96 && event.keyCode <= 105 ?
  4253. ( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode );
  4254. clearTimeout( this.filterTimer );
  4255. if ( character === prev ) {
  4256. skip = true;
  4257. } else {
  4258. character = prev + character;
  4259. }
  4260. match = this._filterMenuItems( character );
  4261. match = skip && match.index( this.active.next() ) !== -1 ?
  4262. this.active.nextAll( ".ui-menu-item" ) :
  4263. match;
  4264. // If no matches on the current filter, reset to the last character pressed
  4265. // to move down the menu to the first item that starts with that character
  4266. if ( !match.length ) {
  4267. character = String.fromCharCode( event.keyCode );
  4268. match = this._filterMenuItems( character );
  4269. }
  4270. if ( match.length ) {
  4271. this.focus( event, match );
  4272. this.previousFilter = character;
  4273. this.filterTimer = this._delay( function() {
  4274. delete this.previousFilter;
  4275. }, 1000 );
  4276. } else {
  4277. delete this.previousFilter;
  4278. }
  4279. }
  4280. if ( preventDefault ) {
  4281. event.preventDefault();
  4282. }
  4283. },
  4284. _activate: function( event ) {
  4285. if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
  4286. if ( this.active.children( "[aria-haspopup='true']" ).length ) {
  4287. this.expand( event );
  4288. } else {
  4289. this.select( event );
  4290. }
  4291. }
  4292. },
  4293. refresh: function() {
  4294. var menus, items, newSubmenus, newItems, newWrappers,
  4295. that = this,
  4296. icon = this.options.icons.submenu,
  4297. submenus = this.element.find( this.options.menus );
  4298. this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length );
  4299. // Initialize nested menus
  4300. newSubmenus = submenus.filter( ":not(.ui-menu)" )
  4301. .hide()
  4302. .attr( {
  4303. role: this.options.role,
  4304. "aria-hidden": "true",
  4305. "aria-expanded": "false"
  4306. } )
  4307. .each( function() {
  4308. var menu = $( this ),
  4309. item = menu.prev(),
  4310. submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true );
  4311. that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon );
  4312. item
  4313. .attr( "aria-haspopup", "true" )
  4314. .prepend( submenuCaret );
  4315. menu.attr( "aria-labelledby", item.attr( "id" ) );
  4316. } );
  4317. this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" );
  4318. menus = submenus.add( this.element );
  4319. items = menus.find( this.options.items );
  4320. // Initialize menu-items containing spaces and/or dashes only as dividers
  4321. items.not( ".ui-menu-item" ).each( function() {
  4322. var item = $( this );
  4323. if ( that._isDivider( item ) ) {
  4324. that._addClass( item, "ui-menu-divider", "ui-widget-content" );
  4325. }
  4326. } );
  4327. // Don't refresh list items that are already adapted
  4328. newItems = items.not( ".ui-menu-item, .ui-menu-divider" );
  4329. newWrappers = newItems.children()
  4330. .not( ".ui-menu" )
  4331. .uniqueId()
  4332. .attr( {
  4333. tabIndex: -1,
  4334. role: this._itemRole()
  4335. } );
  4336. this._addClass( newItems, "ui-menu-item" )
  4337. ._addClass( newWrappers, "ui-menu-item-wrapper" );
  4338. // Add aria-disabled attribute to any disabled menu item
  4339. items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
  4340. // If the active item has been removed, blur the menu
  4341. if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
  4342. this.blur();
  4343. }
  4344. },
  4345. _itemRole: function() {
  4346. return {
  4347. menu: "menuitem",
  4348. listbox: "option"
  4349. }[ this.options.role ];
  4350. },
  4351. _setOption: function( key, value ) {
  4352. if ( key === "icons" ) {
  4353. var icons = this.element.find( ".ui-menu-icon" );
  4354. this._removeClass( icons, null, this.options.icons.submenu )
  4355. ._addClass( icons, null, value.submenu );
  4356. }
  4357. this._super( key, value );
  4358. },
  4359. _setOptionDisabled: function( value ) {
  4360. this._super( value );
  4361. this.element.attr( "aria-disabled", String( value ) );
  4362. this._toggleClass( null, "ui-state-disabled", !!value );
  4363. },
  4364. focus: function( event, item ) {
  4365. var nested, focused, activeParent;
  4366. this.blur( event, event && event.type === "focus" );
  4367. this._scrollIntoView( item );
  4368. this.active = item.first();
  4369. focused = this.active.children( ".ui-menu-item-wrapper" );
  4370. this._addClass( focused, null, "ui-state-active" );
  4371. // Only update aria-activedescendant if there's a role
  4372. // otherwise we assume focus is managed elsewhere
  4373. if ( this.options.role ) {
  4374. this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
  4375. }
  4376. // Highlight active parent menu item, if any
  4377. activeParent = this.active
  4378. .parent()
  4379. .closest( ".ui-menu-item" )
  4380. .children( ".ui-menu-item-wrapper" );
  4381. this._addClass( activeParent, null, "ui-state-active" );
  4382. if ( event && event.type === "keydown" ) {
  4383. this._close();
  4384. } else {
  4385. this.timer = this._delay( function() {
  4386. this._close();
  4387. }, this.delay );
  4388. }
  4389. nested = item.children( ".ui-menu" );
  4390. if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
  4391. this._startOpening( nested );
  4392. }
  4393. this.activeMenu = item.parent();
  4394. this._trigger( "focus", event, { item: item } );
  4395. },
  4396. _scrollIntoView: function( item ) {
  4397. var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
  4398. if ( this._hasScroll() ) {
  4399. borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0;
  4400. paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0;
  4401. offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
  4402. scroll = this.activeMenu.scrollTop();
  4403. elementHeight = this.activeMenu.height();
  4404. itemHeight = item.outerHeight();
  4405. if ( offset < 0 ) {
  4406. this.activeMenu.scrollTop( scroll + offset );
  4407. } else if ( offset + itemHeight > elementHeight ) {
  4408. this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
  4409. }
  4410. }
  4411. },
  4412. blur: function( event, fromFocus ) {
  4413. if ( !fromFocus ) {
  4414. clearTimeout( this.timer );
  4415. }
  4416. if ( !this.active ) {
  4417. return;
  4418. }
  4419. this._removeClass( this.active.children( ".ui-menu-item-wrapper" ),
  4420. null, "ui-state-active" );
  4421. this._trigger( "blur", event, { item: this.active } );
  4422. this.active = null;
  4423. },
  4424. _startOpening: function( submenu ) {
  4425. clearTimeout( this.timer );
  4426. // Don't open if already open fixes a Firefox bug that caused a .5 pixel
  4427. // shift in the submenu position when mousing over the caret icon
  4428. if ( submenu.attr( "aria-hidden" ) !== "true" ) {
  4429. return;
  4430. }
  4431. this.timer = this._delay( function() {
  4432. this._close();
  4433. this._open( submenu );
  4434. }, this.delay );
  4435. },
  4436. _open: function( submenu ) {
  4437. var position = $.extend( {
  4438. of: this.active
  4439. }, this.options.position );
  4440. clearTimeout( this.timer );
  4441. this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
  4442. .hide()
  4443. .attr( "aria-hidden", "true" );
  4444. submenu
  4445. .show()
  4446. .removeAttr( "aria-hidden" )
  4447. .attr( "aria-expanded", "true" )
  4448. .position( position );
  4449. },
  4450. collapseAll: function( event, all ) {
  4451. clearTimeout( this.timer );
  4452. this.timer = this._delay( function() {
  4453. // If we were passed an event, look for the submenu that contains the event
  4454. var currentMenu = all ? this.element :
  4455. $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
  4456. // If we found no valid submenu ancestor, use the main menu to close all
  4457. // sub menus anyway
  4458. if ( !currentMenu.length ) {
  4459. currentMenu = this.element;
  4460. }
  4461. this._close( currentMenu );
  4462. this.blur( event );
  4463. // Work around active item staying active after menu is blurred
  4464. this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" );
  4465. this.activeMenu = currentMenu;
  4466. }, all ? 0 : this.delay );
  4467. },
  4468. // With no arguments, closes the currently active menu - if nothing is active
  4469. // it closes all menus. If passed an argument, it will search for menus BELOW
  4470. _close: function( startMenu ) {
  4471. if ( !startMenu ) {
  4472. startMenu = this.active ? this.active.parent() : this.element;
  4473. }
  4474. startMenu.find( ".ui-menu" )
  4475. .hide()
  4476. .attr( "aria-hidden", "true" )
  4477. .attr( "aria-expanded", "false" );
  4478. },
  4479. _closeOnDocumentClick: function( event ) {
  4480. return !$( event.target ).closest( ".ui-menu" ).length;
  4481. },
  4482. _isDivider: function( item ) {
  4483. // Match hyphen, em dash, en dash
  4484. return !/[^\-\u2014\u2013\s]/.test( item.text() );
  4485. },
  4486. collapse: function( event ) {
  4487. var newItem = this.active &&
  4488. this.active.parent().closest( ".ui-menu-item", this.element );
  4489. if ( newItem && newItem.length ) {
  4490. this._close();
  4491. this.focus( event, newItem );
  4492. }
  4493. },
  4494. expand: function( event ) {
  4495. var newItem = this.active && this._menuItems( this.active.children( ".ui-menu" ) ).first();
  4496. if ( newItem && newItem.length ) {
  4497. this._open( newItem.parent() );
  4498. // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
  4499. this._delay( function() {
  4500. this.focus( event, newItem );
  4501. } );
  4502. }
  4503. },
  4504. next: function( event ) {
  4505. this._move( "next", "first", event );
  4506. },
  4507. previous: function( event ) {
  4508. this._move( "prev", "last", event );
  4509. },
  4510. isFirstItem: function() {
  4511. return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
  4512. },
  4513. isLastItem: function() {
  4514. return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
  4515. },
  4516. _menuItems: function( menu ) {
  4517. return ( menu || this.element )
  4518. .find( this.options.items )
  4519. .filter( ".ui-menu-item" );
  4520. },
  4521. _move: function( direction, filter, event ) {
  4522. var next;
  4523. if ( this.active ) {
  4524. if ( direction === "first" || direction === "last" ) {
  4525. next = this.active
  4526. [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
  4527. .last();
  4528. } else {
  4529. next = this.active
  4530. [ direction + "All" ]( ".ui-menu-item" )
  4531. .first();
  4532. }
  4533. }
  4534. if ( !next || !next.length || !this.active ) {
  4535. next = this._menuItems( this.activeMenu )[ filter ]();
  4536. }
  4537. this.focus( event, next );
  4538. },
  4539. nextPage: function( event ) {
  4540. var item, base, height;
  4541. if ( !this.active ) {
  4542. this.next( event );
  4543. return;
  4544. }
  4545. if ( this.isLastItem() ) {
  4546. return;
  4547. }
  4548. if ( this._hasScroll() ) {
  4549. base = this.active.offset().top;
  4550. height = this.element.innerHeight();
  4551. // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back.
  4552. if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) {
  4553. height += this.element[ 0 ].offsetHeight - this.element.outerHeight();
  4554. }
  4555. this.active.nextAll( ".ui-menu-item" ).each( function() {
  4556. item = $( this );
  4557. return item.offset().top - base - height < 0;
  4558. } );
  4559. this.focus( event, item );
  4560. } else {
  4561. this.focus( event, this._menuItems( this.activeMenu )
  4562. [ !this.active ? "first" : "last" ]() );
  4563. }
  4564. },
  4565. previousPage: function( event ) {
  4566. var item, base, height;
  4567. if ( !this.active ) {
  4568. this.next( event );
  4569. return;
  4570. }
  4571. if ( this.isFirstItem() ) {
  4572. return;
  4573. }
  4574. if ( this._hasScroll() ) {
  4575. base = this.active.offset().top;
  4576. height = this.element.innerHeight();
  4577. // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back.
  4578. if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) {
  4579. height += this.element[ 0 ].offsetHeight - this.element.outerHeight();
  4580. }
  4581. this.active.prevAll( ".ui-menu-item" ).each( function() {
  4582. item = $( this );
  4583. return item.offset().top - base + height > 0;
  4584. } );
  4585. this.focus( event, item );
  4586. } else {
  4587. this.focus( event, this._menuItems( this.activeMenu ).first() );
  4588. }
  4589. },
  4590. _hasScroll: function() {
  4591. return this.element.outerHeight() < this.element.prop( "scrollHeight" );
  4592. },
  4593. select: function( event ) {
  4594. // TODO: It should never be possible to not have an active item at this
  4595. // point, but the tests don't trigger mouseenter before click.
  4596. this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
  4597. var ui = { item: this.active };
  4598. if ( !this.active.has( ".ui-menu" ).length ) {
  4599. this.collapseAll( event, true );
  4600. }
  4601. this._trigger( "select", event, ui );
  4602. },
  4603. _filterMenuItems: function( character ) {
  4604. var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
  4605. regex = new RegExp( "^" + escapedCharacter, "i" );
  4606. return this.activeMenu
  4607. .find( this.options.items )
  4608. // Only match on items, not dividers or other content (#10571)
  4609. .filter( ".ui-menu-item" )
  4610. .filter( function() {
  4611. return regex.test(
  4612. String.prototype.trim.call(
  4613. $( this ).children( ".ui-menu-item-wrapper" ).text() ) );
  4614. } );
  4615. }
  4616. } );
  4617. /*!
  4618. * jQuery UI Autocomplete 1.14.1
  4619. * https://jqueryui.com
  4620. *
  4621. * Copyright OpenJS Foundation and other contributors
  4622. * Released under the MIT license.
  4623. * https://jquery.org/license
  4624. */
  4625. //>>label: Autocomplete
  4626. //>>group: Widgets
  4627. //>>description: Lists suggested words as the user is typing.
  4628. //>>docs: https://api.jqueryui.com/autocomplete/
  4629. //>>demos: https://jqueryui.com/autocomplete/
  4630. //>>css.structure: ../../themes/base/core.css
  4631. //>>css.structure: ../../themes/base/autocomplete.css
  4632. //>>css.theme: ../../themes/base/theme.css
  4633. $.widget( "ui.autocomplete", {
  4634. version: "1.14.1",
  4635. defaultElement: "<input>",
  4636. options: {
  4637. appendTo: null,
  4638. autoFocus: false,
  4639. delay: 300,
  4640. minLength: 1,
  4641. position: {
  4642. my: "left top",
  4643. at: "left bottom",
  4644. collision: "none"
  4645. },
  4646. source: null,
  4647. // Callbacks
  4648. change: null,
  4649. close: null,
  4650. focus: null,
  4651. open: null,
  4652. response: null,
  4653. search: null,
  4654. select: null
  4655. },
  4656. requestIndex: 0,
  4657. pending: 0,
  4658. liveRegionTimer: null,
  4659. _create: function() {
  4660. // Some browsers only repeat keydown events, not keypress events,
  4661. // so we use the suppressKeyPress flag to determine if we've already
  4662. // handled the keydown event. #7269
  4663. // Unfortunately the code for & in keypress is the same as the up arrow,
  4664. // so we use the suppressKeyPressRepeat flag to avoid handling keypress
  4665. // events when we know the keydown event was used to modify the
  4666. // search term. #7799
  4667. var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
  4668. nodeName = this.element[ 0 ].nodeName.toLowerCase(),
  4669. isTextarea = nodeName === "textarea",
  4670. isInput = nodeName === "input";
  4671. // Textareas are always multi-line
  4672. // Inputs are always single-line, even if inside a contentEditable element
  4673. // All other element types are determined by whether they're contentEditable
  4674. this.isMultiLine = isTextarea ||
  4675. !isInput && this.element.prop( "contentEditable" ) === "true";
  4676. this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
  4677. this.isNewMenu = true;
  4678. this._addClass( "ui-autocomplete-input" );
  4679. this.element.attr( "autocomplete", "off" );
  4680. this._on( this.element, {
  4681. keydown: function( event ) {
  4682. if ( this.element.prop( "readOnly" ) ) {
  4683. suppressKeyPress = true;
  4684. suppressInput = true;
  4685. suppressKeyPressRepeat = true;
  4686. return;
  4687. }
  4688. suppressKeyPress = false;
  4689. suppressInput = false;
  4690. suppressKeyPressRepeat = false;
  4691. var keyCode = $.ui.keyCode;
  4692. switch ( event.keyCode ) {
  4693. case keyCode.PAGE_UP:
  4694. suppressKeyPress = true;
  4695. this._move( "previousPage", event );
  4696. break;
  4697. case keyCode.PAGE_DOWN:
  4698. suppressKeyPress = true;
  4699. this._move( "nextPage", event );
  4700. break;
  4701. case keyCode.UP:
  4702. suppressKeyPress = true;
  4703. this._keyEvent( "previous", event );
  4704. break;
  4705. case keyCode.DOWN:
  4706. suppressKeyPress = true;
  4707. this._keyEvent( "next", event );
  4708. break;
  4709. case keyCode.ENTER:
  4710. // when menu is open and has focus
  4711. if ( this.menu.active ) {
  4712. // #6055 - Opera still allows the keypress to occur
  4713. // which causes forms to submit
  4714. suppressKeyPress = true;
  4715. event.preventDefault();
  4716. this.menu.select( event );
  4717. }
  4718. break;
  4719. case keyCode.TAB:
  4720. if ( this.menu.active ) {
  4721. this.menu.select( event );
  4722. }
  4723. break;
  4724. case keyCode.ESCAPE:
  4725. if ( this.menu.element.is( ":visible" ) ) {
  4726. if ( !this.isMultiLine ) {
  4727. this._value( this.term );
  4728. }
  4729. this.close( event );
  4730. // Different browsers have different default behavior for escape
  4731. // Single press can mean undo or clear
  4732. event.preventDefault();
  4733. }
  4734. break;
  4735. default:
  4736. suppressKeyPressRepeat = true;
  4737. // search timeout should be triggered before the input value is changed
  4738. this._searchTimeout( event );
  4739. break;
  4740. }
  4741. },
  4742. keypress: function( event ) {
  4743. if ( suppressKeyPress ) {
  4744. suppressKeyPress = false;
  4745. if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
  4746. event.preventDefault();
  4747. }
  4748. return;
  4749. }
  4750. if ( suppressKeyPressRepeat ) {
  4751. return;
  4752. }
  4753. // Replicate some key handlers to allow them to repeat in Firefox and Opera
  4754. var keyCode = $.ui.keyCode;
  4755. switch ( event.keyCode ) {
  4756. case keyCode.PAGE_UP:
  4757. this._move( "previousPage", event );
  4758. break;
  4759. case keyCode.PAGE_DOWN:
  4760. this._move( "nextPage", event );
  4761. break;
  4762. case keyCode.UP:
  4763. this._keyEvent( "previous", event );
  4764. break;
  4765. case keyCode.DOWN:
  4766. this._keyEvent( "next", event );
  4767. break;
  4768. }
  4769. },
  4770. input: function( event ) {
  4771. if ( suppressInput ) {
  4772. suppressInput = false;
  4773. event.preventDefault();
  4774. return;
  4775. }
  4776. this._searchTimeout( event );
  4777. },
  4778. focus: function() {
  4779. this.selectedItem = null;
  4780. this.previous = this._value();
  4781. },
  4782. blur: function( event ) {
  4783. clearTimeout( this.searching );
  4784. this.close( event );
  4785. this._change( event );
  4786. }
  4787. } );
  4788. this._initSource();
  4789. this.menu = $( "<ul>" )
  4790. .appendTo( this._appendTo() )
  4791. .menu( {
  4792. // disable ARIA support, the live region takes care of that
  4793. role: null
  4794. } )
  4795. .hide()
  4796. .menu( "instance" );
  4797. this._addClass( this.menu.element, "ui-autocomplete", "ui-front" );
  4798. this._on( this.menu.element, {
  4799. mousedown: function( event ) {
  4800. // Prevent moving focus out of the text field
  4801. event.preventDefault();
  4802. },
  4803. menufocus: function( event, ui ) {
  4804. var label, item;
  4805. // Support: Firefox
  4806. // Prevent accidental activation of menu items in Firefox (#7024 #9118)
  4807. if ( this.isNewMenu ) {
  4808. this.isNewMenu = false;
  4809. if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
  4810. this.menu.blur();
  4811. this.document.one( "mousemove", function() {
  4812. $( event.target ).trigger( event.originalEvent );
  4813. } );
  4814. return;
  4815. }
  4816. }
  4817. item = ui.item.data( "ui-autocomplete-item" );
  4818. if ( false !== this._trigger( "focus", event, { item: item } ) ) {
  4819. // use value to match what will end up in the input, if it was a key event
  4820. if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
  4821. this._value( item.value );
  4822. }
  4823. }
  4824. // Announce the value in the liveRegion
  4825. label = ui.item.attr( "aria-label" ) || item.value;
  4826. if ( label && String.prototype.trim.call( label ).length ) {
  4827. clearTimeout( this.liveRegionTimer );
  4828. this.liveRegionTimer = this._delay( function() {
  4829. this.liveRegion.html( $( "<div>" ).text( label ) );
  4830. }, 100 );
  4831. }
  4832. },
  4833. menuselect: function( event, ui ) {
  4834. var item = ui.item.data( "ui-autocomplete-item" ),
  4835. previous = this.previous;
  4836. // Only trigger when focus was lost (click on menu)
  4837. if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
  4838. this.element.trigger( "focus" );
  4839. this.previous = previous;
  4840. }
  4841. if ( false !== this._trigger( "select", event, { item: item } ) ) {
  4842. this._value( item.value );
  4843. }
  4844. // reset the term after the select event
  4845. // this allows custom select handling to work properly
  4846. this.term = this._value();
  4847. this.close( event );
  4848. this.selectedItem = item;
  4849. }
  4850. } );
  4851. this.liveRegion = $( "<div>", {
  4852. role: "status",
  4853. "aria-live": "assertive",
  4854. "aria-relevant": "additions"
  4855. } )
  4856. .appendTo( this.document[ 0 ].body );
  4857. this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
  4858. // Turning off autocomplete prevents the browser from remembering the
  4859. // value when navigating through history, so we re-enable autocomplete
  4860. // if the page is unloaded before the widget is destroyed. #7790
  4861. this._on( this.window, {
  4862. beforeunload: function() {
  4863. this.element.removeAttr( "autocomplete" );
  4864. }
  4865. } );
  4866. },
  4867. _destroy: function() {
  4868. clearTimeout( this.searching );
  4869. this.element.removeAttr( "autocomplete" );
  4870. this.menu.element.remove();
  4871. this.liveRegion.remove();
  4872. },
  4873. _setOption: function( key, value ) {
  4874. this._super( key, value );
  4875. if ( key === "source" ) {
  4876. this._initSource();
  4877. }
  4878. if ( key === "appendTo" ) {
  4879. this.menu.element.appendTo( this._appendTo() );
  4880. }
  4881. if ( key === "disabled" && value && this.xhr ) {
  4882. this.xhr.abort();
  4883. }
  4884. },
  4885. _isEventTargetInWidget: function( event ) {
  4886. var menuElement = this.menu.element[ 0 ];
  4887. return event.target === this.element[ 0 ] ||
  4888. event.target === menuElement ||
  4889. $.contains( menuElement, event.target );
  4890. },
  4891. _closeOnClickOutside: function( event ) {
  4892. if ( !this._isEventTargetInWidget( event ) ) {
  4893. this.close();
  4894. }
  4895. },
  4896. _appendTo: function() {
  4897. var element = this.options.appendTo;
  4898. if ( element ) {
  4899. element = element.jquery || element.nodeType ?
  4900. $( element ) :
  4901. this.document.find( element ).eq( 0 );
  4902. }
  4903. if ( !element || !element[ 0 ] ) {
  4904. element = this.element.closest( ".ui-front, dialog" );
  4905. }
  4906. if ( !element.length ) {
  4907. element = this.document[ 0 ].body;
  4908. }
  4909. return element;
  4910. },
  4911. _initSource: function() {
  4912. var array, url,
  4913. that = this;
  4914. if ( Array.isArray( this.options.source ) ) {
  4915. array = this.options.source;
  4916. this.source = function( request, response ) {
  4917. response( $.ui.autocomplete.filter( array, request.term ) );
  4918. };
  4919. } else if ( typeof this.options.source === "string" ) {
  4920. url = this.options.source;
  4921. this.source = function( request, response ) {
  4922. if ( that.xhr ) {
  4923. that.xhr.abort();
  4924. }
  4925. that.xhr = $.ajax( {
  4926. url: url,
  4927. data: request,
  4928. dataType: "json",
  4929. success: function( data ) {
  4930. response( data );
  4931. },
  4932. error: function() {
  4933. response( [] );
  4934. }
  4935. } );
  4936. };
  4937. } else {
  4938. this.source = this.options.source;
  4939. }
  4940. },
  4941. _searchTimeout: function( event ) {
  4942. clearTimeout( this.searching );
  4943. this.searching = this._delay( function() {
  4944. // Search if the value has changed, or if the user retypes the same value (see #7434)
  4945. var equalValues = this.term === this._value(),
  4946. menuVisible = this.menu.element.is( ":visible" ),
  4947. modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
  4948. if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
  4949. this.selectedItem = null;
  4950. this.search( null, event );
  4951. }
  4952. }, this.options.delay );
  4953. },
  4954. search: function( value, event ) {
  4955. value = value != null ? value : this._value();
  4956. // Always save the actual value, not the one passed as an argument
  4957. this.term = this._value();
  4958. if ( value.length < this.options.minLength ) {
  4959. return this.close( event );
  4960. }
  4961. if ( this._trigger( "search", event ) === false ) {
  4962. return;
  4963. }
  4964. return this._search( value );
  4965. },
  4966. _search: function( value ) {
  4967. this.pending++;
  4968. this._addClass( "ui-autocomplete-loading" );
  4969. this.cancelSearch = false;
  4970. this.source( { term: value }, this._response() );
  4971. },
  4972. _response: function() {
  4973. var index = ++this.requestIndex;
  4974. return function( content ) {
  4975. if ( index === this.requestIndex ) {
  4976. this.__response( content );
  4977. }
  4978. this.pending--;
  4979. if ( !this.pending ) {
  4980. this._removeClass( "ui-autocomplete-loading" );
  4981. }
  4982. }.bind( this );
  4983. },
  4984. __response: function( content ) {
  4985. if ( content ) {
  4986. content = this._normalize( content );
  4987. }
  4988. this._trigger( "response", null, { content: content } );
  4989. if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
  4990. this._suggest( content );
  4991. this._trigger( "open" );
  4992. } else {
  4993. // use ._close() instead of .close() so we don't cancel future searches
  4994. this._close();
  4995. }
  4996. },
  4997. close: function( event ) {
  4998. this.cancelSearch = true;
  4999. this._close( event );
  5000. },
  5001. _close: function( event ) {
  5002. // Remove the handler that closes the menu on outside clicks
  5003. this._off( this.document, "mousedown" );
  5004. if ( this.menu.element.is( ":visible" ) ) {
  5005. this.menu.element.hide();
  5006. this.menu.blur();
  5007. this.isNewMenu = true;
  5008. this._trigger( "close", event );
  5009. }
  5010. },
  5011. _change: function( event ) {
  5012. if ( this.previous !== this._value() ) {
  5013. this._trigger( "change", event, { item: this.selectedItem } );
  5014. }
  5015. },
  5016. _normalize: function( items ) {
  5017. // assume all items have the right format when the first item is complete
  5018. if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
  5019. return items;
  5020. }
  5021. return $.map( items, function( item ) {
  5022. if ( typeof item === "string" ) {
  5023. return {
  5024. label: item,
  5025. value: item
  5026. };
  5027. }
  5028. return $.extend( {}, item, {
  5029. label: item.label || item.value,
  5030. value: item.value || item.label
  5031. } );
  5032. } );
  5033. },
  5034. _suggest: function( items ) {
  5035. var ul = this.menu.element.empty();
  5036. this._renderMenu( ul, items );
  5037. this.isNewMenu = true;
  5038. this.menu.refresh();
  5039. // Size and position menu
  5040. ul.show();
  5041. this._resizeMenu();
  5042. ul.position( $.extend( {
  5043. of: this.element
  5044. }, this.options.position ) );
  5045. if ( this.options.autoFocus ) {
  5046. this.menu.next();
  5047. }
  5048. // Listen for interactions outside of the widget (#6642)
  5049. this._on( this.document, {
  5050. mousedown: "_closeOnClickOutside"
  5051. } );
  5052. },
  5053. _resizeMenu: function() {
  5054. var ul = this.menu.element;
  5055. ul.outerWidth( Math.max(
  5056. // Firefox wraps long text (possibly a rounding bug)
  5057. // so we add 1px to avoid the wrapping (#7513)
  5058. ul.width( "" ).outerWidth() + 1,
  5059. this.element.outerWidth()
  5060. ) );
  5061. },
  5062. _renderMenu: function( ul, items ) {
  5063. var that = this;
  5064. $.each( items, function( index, item ) {
  5065. that._renderItemData( ul, item );
  5066. } );
  5067. },
  5068. _renderItemData: function( ul, item ) {
  5069. return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
  5070. },
  5071. _renderItem: function( ul, item ) {
  5072. return $( "<li>" )
  5073. .append( $( "<div>" ).text( item.label ) )
  5074. .appendTo( ul );
  5075. },
  5076. _move: function( direction, event ) {
  5077. if ( !this.menu.element.is( ":visible" ) ) {
  5078. this.search( null, event );
  5079. return;
  5080. }
  5081. if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
  5082. this.menu.isLastItem() && /^next/.test( direction ) ) {
  5083. if ( !this.isMultiLine ) {
  5084. this._value( this.term );
  5085. }
  5086. this.menu.blur();
  5087. return;
  5088. }
  5089. this.menu[ direction ]( event );
  5090. },
  5091. widget: function() {
  5092. return this.menu.element;
  5093. },
  5094. _value: function() {
  5095. return this.valueMethod.apply( this.element, arguments );
  5096. },
  5097. _keyEvent: function( keyEvent, event ) {
  5098. if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
  5099. this._move( keyEvent, event );
  5100. // Prevents moving cursor to beginning/end of the text field in some browsers
  5101. event.preventDefault();
  5102. }
  5103. }
  5104. } );
  5105. $.extend( $.ui.autocomplete, {
  5106. escapeRegex: function( value ) {
  5107. return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
  5108. },
  5109. filter: function( array, term ) {
  5110. var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
  5111. return $.grep( array, function( value ) {
  5112. return matcher.test( value.label || value.value || value );
  5113. } );
  5114. }
  5115. } );
  5116. // Live region extension, adding a `messages` option
  5117. // NOTE: This is an experimental API. We are still investigating
  5118. // a full solution for string manipulation and internationalization.
  5119. $.widget( "ui.autocomplete", $.ui.autocomplete, {
  5120. options: {
  5121. messages: {
  5122. noResults: "No search results.",
  5123. results: function( amount ) {
  5124. return amount + ( amount > 1 ? " results are" : " result is" ) +
  5125. " available, use up and down arrow keys to navigate.";
  5126. }
  5127. }
  5128. },
  5129. __response: function( content ) {
  5130. var message;
  5131. this._superApply( arguments );
  5132. if ( this.options.disabled || this.cancelSearch ) {
  5133. return;
  5134. }
  5135. if ( content && content.length ) {
  5136. message = this.options.messages.results( content.length );
  5137. } else {
  5138. message = this.options.messages.noResults;
  5139. }
  5140. clearTimeout( this.liveRegionTimer );
  5141. this.liveRegionTimer = this._delay( function() {
  5142. this.liveRegion.html( $( "<div>" ).text( message ) );
  5143. }, 100 );
  5144. }
  5145. } );
  5146. var widgetsAutocomplete = $.ui.autocomplete;
  5147. /*!
  5148. * jQuery UI Controlgroup 1.14.1
  5149. * https://jqueryui.com
  5150. *
  5151. * Copyright OpenJS Foundation and other contributors
  5152. * Released under the MIT license.
  5153. * https://jquery.org/license
  5154. */
  5155. //>>label: Controlgroup
  5156. //>>group: Widgets
  5157. //>>description: Visually groups form control widgets
  5158. //>>docs: https://api.jqueryui.com/controlgroup/
  5159. //>>demos: https://jqueryui.com/controlgroup/
  5160. //>>css.structure: ../../themes/base/core.css
  5161. //>>css.structure: ../../themes/base/controlgroup.css
  5162. //>>css.theme: ../../themes/base/theme.css
  5163. var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g;
  5164. var widgetsControlgroup = $.widget( "ui.controlgroup", {
  5165. version: "1.14.1",
  5166. defaultElement: "<div>",
  5167. options: {
  5168. direction: "horizontal",
  5169. disabled: null,
  5170. onlyVisible: true,
  5171. items: {
  5172. "button": "input[type=button], input[type=submit], input[type=reset], button, a",
  5173. "controlgroupLabel": ".ui-controlgroup-label",
  5174. "checkboxradio": "input[type='checkbox'], input[type='radio']",
  5175. "selectmenu": "select",
  5176. "spinner": ".ui-spinner-input"
  5177. }
  5178. },
  5179. _create: function() {
  5180. this._enhance();
  5181. },
  5182. // To support the enhanced option in jQuery Mobile, we isolate DOM manipulation
  5183. _enhance: function() {
  5184. this.element.attr( "role", "toolbar" );
  5185. this.refresh();
  5186. },
  5187. _destroy: function() {
  5188. this._callChildMethod( "destroy" );
  5189. this.childWidgets.removeData( "ui-controlgroup-data" );
  5190. this.element.removeAttr( "role" );
  5191. if ( this.options.items.controlgroupLabel ) {
  5192. this.element
  5193. .find( this.options.items.controlgroupLabel )
  5194. .find( ".ui-controlgroup-label-contents" )
  5195. .contents().unwrap();
  5196. }
  5197. },
  5198. _initWidgets: function() {
  5199. var that = this,
  5200. childWidgets = [];
  5201. // First we iterate over each of the items options
  5202. $.each( this.options.items, function( widget, selector ) {
  5203. var labels;
  5204. var options = {};
  5205. // Make sure the widget has a selector set
  5206. if ( !selector ) {
  5207. return;
  5208. }
  5209. if ( widget === "controlgroupLabel" ) {
  5210. labels = that.element.find( selector );
  5211. labels.each( function() {
  5212. var element = $( this );
  5213. if ( element.children( ".ui-controlgroup-label-contents" ).length ) {
  5214. return;
  5215. }
  5216. element.contents()
  5217. .wrapAll( "<span class='ui-controlgroup-label-contents'></span>" );
  5218. } );
  5219. that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" );
  5220. childWidgets = childWidgets.concat( labels.get() );
  5221. return;
  5222. }
  5223. // Make sure the widget actually exists
  5224. if ( !$.fn[ widget ] ) {
  5225. return;
  5226. }
  5227. // We assume everything is in the middle to start because we can't determine
  5228. // first / last elements until all enhancments are done.
  5229. if ( that[ "_" + widget + "Options" ] ) {
  5230. options = that[ "_" + widget + "Options" ]( "middle" );
  5231. } else {
  5232. options = { classes: {} };
  5233. }
  5234. // Find instances of this widget inside controlgroup and init them
  5235. that.element
  5236. .find( selector )
  5237. .each( function() {
  5238. var element = $( this );
  5239. var instance = element[ widget ]( "instance" );
  5240. // We need to clone the default options for this type of widget to avoid
  5241. // polluting the variable options which has a wider scope than a single widget.
  5242. var instanceOptions = $.widget.extend( {}, options );
  5243. // If the button is the child of a spinner ignore it
  5244. // TODO: Find a more generic solution
  5245. if ( widget === "button" && element.parent( ".ui-spinner" ).length ) {
  5246. return;
  5247. }
  5248. // Create the widget if it doesn't exist
  5249. if ( !instance ) {
  5250. instance = element[ widget ]()[ widget ]( "instance" );
  5251. }
  5252. if ( instance ) {
  5253. instanceOptions.classes =
  5254. that._resolveClassesValues( instanceOptions.classes, instance );
  5255. }
  5256. element[ widget ]( instanceOptions );
  5257. // Store an instance of the controlgroup to be able to reference
  5258. // from the outermost element for changing options and refresh
  5259. var widgetElement = element[ widget ]( "widget" );
  5260. $.data( widgetElement[ 0 ], "ui-controlgroup-data",
  5261. instance ? instance : element[ widget ]( "instance" ) );
  5262. childWidgets.push( widgetElement[ 0 ] );
  5263. } );
  5264. } );
  5265. this.childWidgets = $( $.uniqueSort( childWidgets ) );
  5266. this._addClass( this.childWidgets, "ui-controlgroup-item" );
  5267. },
  5268. _callChildMethod: function( method ) {
  5269. this.childWidgets.each( function() {
  5270. var element = $( this ),
  5271. data = element.data( "ui-controlgroup-data" );
  5272. if ( data && data[ method ] ) {
  5273. data[ method ]();
  5274. }
  5275. } );
  5276. },
  5277. _updateCornerClass: function( element, position ) {
  5278. var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all";
  5279. var add = this._buildSimpleOptions( position, "label" ).classes.label;
  5280. this._removeClass( element, null, remove );
  5281. this._addClass( element, null, add );
  5282. },
  5283. _buildSimpleOptions: function( position, key ) {
  5284. var direction = this.options.direction === "vertical";
  5285. var result = {
  5286. classes: {}
  5287. };
  5288. result.classes[ key ] = {
  5289. "middle": "",
  5290. "first": "ui-corner-" + ( direction ? "top" : "left" ),
  5291. "last": "ui-corner-" + ( direction ? "bottom" : "right" ),
  5292. "only": "ui-corner-all"
  5293. }[ position ];
  5294. return result;
  5295. },
  5296. _spinnerOptions: function( position ) {
  5297. var options = this._buildSimpleOptions( position, "ui-spinner" );
  5298. options.classes[ "ui-spinner-up" ] = "";
  5299. options.classes[ "ui-spinner-down" ] = "";
  5300. return options;
  5301. },
  5302. _buttonOptions: function( position ) {
  5303. return this._buildSimpleOptions( position, "ui-button" );
  5304. },
  5305. _checkboxradioOptions: function( position ) {
  5306. return this._buildSimpleOptions( position, "ui-checkboxradio-label" );
  5307. },
  5308. _selectmenuOptions: function( position ) {
  5309. var direction = this.options.direction === "vertical";
  5310. return {
  5311. width: direction ? "auto" : false,
  5312. classes: {
  5313. middle: {
  5314. "ui-selectmenu-button-open": "",
  5315. "ui-selectmenu-button-closed": ""
  5316. },
  5317. first: {
  5318. "ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ),
  5319. "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" )
  5320. },
  5321. last: {
  5322. "ui-selectmenu-button-open": direction ? "" : "ui-corner-tr",
  5323. "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" )
  5324. },
  5325. only: {
  5326. "ui-selectmenu-button-open": "ui-corner-top",
  5327. "ui-selectmenu-button-closed": "ui-corner-all"
  5328. }
  5329. }[ position ]
  5330. };
  5331. },
  5332. _resolveClassesValues: function( classes, instance ) {
  5333. var result = {};
  5334. $.each( classes, function( key ) {
  5335. var current = instance.options.classes[ key ] || "";
  5336. current = String.prototype.trim.call( current.replace( controlgroupCornerRegex, "" ) );
  5337. result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " );
  5338. } );
  5339. return result;
  5340. },
  5341. _setOption: function( key, value ) {
  5342. if ( key === "direction" ) {
  5343. this._removeClass( "ui-controlgroup-" + this.options.direction );
  5344. }
  5345. this._super( key, value );
  5346. if ( key === "disabled" ) {
  5347. this._callChildMethod( value ? "disable" : "enable" );
  5348. return;
  5349. }
  5350. this.refresh();
  5351. },
  5352. refresh: function() {
  5353. var children,
  5354. that = this;
  5355. this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction );
  5356. if ( this.options.direction === "horizontal" ) {
  5357. this._addClass( null, "ui-helper-clearfix" );
  5358. }
  5359. this._initWidgets();
  5360. children = this.childWidgets;
  5361. // We filter here because we need to track all childWidgets not just the visible ones
  5362. if ( this.options.onlyVisible ) {
  5363. children = children.filter( ":visible" );
  5364. }
  5365. if ( children.length ) {
  5366. // We do this last because we need to make sure all enhancment is done
  5367. // before determining first and last
  5368. $.each( [ "first", "last" ], function( index, value ) {
  5369. var instance = children[ value ]().data( "ui-controlgroup-data" );
  5370. if ( instance && that[ "_" + instance.widgetName + "Options" ] ) {
  5371. var options = that[ "_" + instance.widgetName + "Options" ](
  5372. children.length === 1 ? "only" : value
  5373. );
  5374. options.classes = that._resolveClassesValues( options.classes, instance );
  5375. instance.element[ instance.widgetName ]( options );
  5376. } else {
  5377. that._updateCornerClass( children[ value ](), value );
  5378. }
  5379. } );
  5380. // Finally call the refresh method on each of the child widgets.
  5381. this._callChildMethod( "refresh" );
  5382. }
  5383. }
  5384. } );
  5385. /*!
  5386. * jQuery UI Checkboxradio 1.14.1
  5387. * https://jqueryui.com
  5388. *
  5389. * Copyright OpenJS Foundation and other contributors
  5390. * Released under the MIT license.
  5391. * https://jquery.org/license
  5392. */
  5393. //>>label: Checkboxradio
  5394. //>>group: Widgets
  5395. //>>description: Enhances a form with multiple themeable checkboxes or radio buttons.
  5396. //>>docs: https://api.jqueryui.com/checkboxradio/
  5397. //>>demos: https://jqueryui.com/checkboxradio/
  5398. //>>css.structure: ../../themes/base/core.css
  5399. //>>css.structure: ../../themes/base/button.css
  5400. //>>css.structure: ../../themes/base/checkboxradio.css
  5401. //>>css.theme: ../../themes/base/theme.css
  5402. $.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
  5403. version: "1.14.1",
  5404. options: {
  5405. disabled: null,
  5406. label: null,
  5407. icon: true,
  5408. classes: {
  5409. "ui-checkboxradio-label": "ui-corner-all",
  5410. "ui-checkboxradio-icon": "ui-corner-all"
  5411. }
  5412. },
  5413. _getCreateOptions: function() {
  5414. var disabled, labels, labelContents;
  5415. var options = this._super() || {};
  5416. // We read the type here, because it makes more sense to throw a element type error first,
  5417. // rather then the error for lack of a label. Often if its the wrong type, it
  5418. // won't have a label (e.g. calling on a div, btn, etc)
  5419. this._readType();
  5420. labels = this.element.labels();
  5421. // If there are multiple labels, use the last one
  5422. this.label = $( labels[ labels.length - 1 ] );
  5423. if ( !this.label.length ) {
  5424. $.error( "No label found for checkboxradio widget" );
  5425. }
  5426. this.originalLabel = "";
  5427. // We need to get the label text but this may also need to make sure it does not contain the
  5428. // input itself.
  5429. // The label contents could be text, html, or a mix. We wrap all elements
  5430. // and read the wrapper's `innerHTML` to get a string representation of
  5431. // the label, without the input as part of it.
  5432. labelContents = this.label.contents().not( this.element[ 0 ] );
  5433. if ( labelContents.length ) {
  5434. this.originalLabel += labelContents
  5435. .clone()
  5436. .wrapAll( "<div></div>" )
  5437. .parent()
  5438. .html();
  5439. }
  5440. // Set the label option if we found label text
  5441. if ( this.originalLabel ) {
  5442. options.label = this.originalLabel;
  5443. }
  5444. disabled = this.element[ 0 ].disabled;
  5445. if ( disabled != null ) {
  5446. options.disabled = disabled;
  5447. }
  5448. return options;
  5449. },
  5450. _create: function() {
  5451. var checked = this.element[ 0 ].checked;
  5452. this._bindFormResetHandler();
  5453. if ( this.options.disabled == null ) {
  5454. this.options.disabled = this.element[ 0 ].disabled;
  5455. }
  5456. this._setOption( "disabled", this.options.disabled );
  5457. this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" );
  5458. this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" );
  5459. if ( this.type === "radio" ) {
  5460. this._addClass( this.label, "ui-checkboxradio-radio-label" );
  5461. }
  5462. if ( this.options.label && this.options.label !== this.originalLabel ) {
  5463. this._updateLabel();
  5464. } else if ( this.originalLabel ) {
  5465. this.options.label = this.originalLabel;
  5466. }
  5467. this._enhance();
  5468. if ( checked ) {
  5469. this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" );
  5470. }
  5471. this._on( {
  5472. change: "_toggleClasses",
  5473. focus: function() {
  5474. this._addClass( this.label, null, "ui-state-focus ui-visual-focus" );
  5475. },
  5476. blur: function() {
  5477. this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" );
  5478. }
  5479. } );
  5480. },
  5481. _readType: function() {
  5482. var nodeName = this.element[ 0 ].nodeName.toLowerCase();
  5483. this.type = this.element[ 0 ].type;
  5484. if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) {
  5485. $.error( "Can't create checkboxradio on element.nodeName=" + nodeName +
  5486. " and element.type=" + this.type );
  5487. }
  5488. },
  5489. // Support jQuery Mobile enhanced option
  5490. _enhance: function() {
  5491. this._updateIcon( this.element[ 0 ].checked );
  5492. },
  5493. widget: function() {
  5494. return this.label;
  5495. },
  5496. _getRadioGroup: function() {
  5497. var group;
  5498. var name = this.element[ 0 ].name;
  5499. var nameSelector = "input[name='" + CSS.escape( name ) + "']";
  5500. if ( !name ) {
  5501. return $( [] );
  5502. }
  5503. if ( this.form.length ) {
  5504. group = $( this.form[ 0 ].elements ).filter( nameSelector );
  5505. } else {
  5506. // Not inside a form, check all inputs that also are not inside a form
  5507. group = $( nameSelector ).filter( function() {
  5508. return $( $( this ).prop( "form" ) ).length === 0;
  5509. } );
  5510. }
  5511. return group.not( this.element );
  5512. },
  5513. _toggleClasses: function() {
  5514. var checked = this.element[ 0 ].checked;
  5515. this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
  5516. if ( this.options.icon && this.type === "checkbox" ) {
  5517. this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked )
  5518. ._toggleClass( this.icon, null, "ui-icon-blank", !checked );
  5519. }
  5520. if ( this.type === "radio" ) {
  5521. this._getRadioGroup()
  5522. .each( function() {
  5523. var instance = $( this ).checkboxradio( "instance" );
  5524. if ( instance ) {
  5525. instance._removeClass( instance.label,
  5526. "ui-checkboxradio-checked", "ui-state-active" );
  5527. }
  5528. } );
  5529. }
  5530. },
  5531. _destroy: function() {
  5532. this._unbindFormResetHandler();
  5533. if ( this.icon ) {
  5534. this.icon.remove();
  5535. this.iconSpace.remove();
  5536. }
  5537. },
  5538. _setOption: function( key, value ) {
  5539. // We don't allow the value to be set to nothing
  5540. if ( key === "label" && !value ) {
  5541. return;
  5542. }
  5543. this._super( key, value );
  5544. if ( key === "disabled" ) {
  5545. this._toggleClass( this.label, null, "ui-state-disabled", value );
  5546. this.element[ 0 ].disabled = value;
  5547. // Don't refresh when setting disabled
  5548. return;
  5549. }
  5550. this.refresh();
  5551. },
  5552. _updateIcon: function( checked ) {
  5553. var toAdd = "ui-icon ui-icon-background ";
  5554. if ( this.options.icon ) {
  5555. if ( !this.icon ) {
  5556. this.icon = $( "<span>" );
  5557. this.iconSpace = $( "<span> </span>" );
  5558. this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" );
  5559. }
  5560. if ( this.type === "checkbox" ) {
  5561. toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank";
  5562. this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" );
  5563. } else {
  5564. toAdd += "ui-icon-blank";
  5565. }
  5566. this._addClass( this.icon, "ui-checkboxradio-icon", toAdd );
  5567. if ( !checked ) {
  5568. this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" );
  5569. }
  5570. this.icon.prependTo( this.label ).after( this.iconSpace );
  5571. } else if ( this.icon !== undefined ) {
  5572. this.icon.remove();
  5573. this.iconSpace.remove();
  5574. delete this.icon;
  5575. }
  5576. },
  5577. _updateLabel: function() {
  5578. // Remove the contents of the label ( minus the icon, icon space, and input )
  5579. var contents = this.label.contents().not( this.element[ 0 ] );
  5580. if ( this.icon ) {
  5581. contents = contents.not( this.icon[ 0 ] );
  5582. }
  5583. if ( this.iconSpace ) {
  5584. contents = contents.not( this.iconSpace[ 0 ] );
  5585. }
  5586. contents.remove();
  5587. this.label.append( this.options.label );
  5588. },
  5589. refresh: function() {
  5590. var checked = this.element[ 0 ].checked,
  5591. isDisabled = this.element[ 0 ].disabled;
  5592. this._updateIcon( checked );
  5593. this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
  5594. if ( this.options.label !== null ) {
  5595. this._updateLabel();
  5596. }
  5597. if ( isDisabled !== this.options.disabled ) {
  5598. this._setOptions( { "disabled": isDisabled } );
  5599. }
  5600. }
  5601. } ] );
  5602. var widgetsCheckboxradio = $.ui.checkboxradio;
  5603. /*!
  5604. * jQuery UI Button 1.14.1
  5605. * https://jqueryui.com
  5606. *
  5607. * Copyright OpenJS Foundation and other contributors
  5608. * Released under the MIT license.
  5609. * https://jquery.org/license
  5610. */
  5611. //>>label: Button
  5612. //>>group: Widgets
  5613. //>>description: Enhances a form with themeable buttons.
  5614. //>>docs: https://api.jqueryui.com/button/
  5615. //>>demos: https://jqueryui.com/button/
  5616. //>>css.structure: ../../themes/base/core.css
  5617. //>>css.structure: ../../themes/base/button.css
  5618. //>>css.theme: ../../themes/base/theme.css
  5619. $.widget( "ui.button", {
  5620. version: "1.14.1",
  5621. defaultElement: "<button>",
  5622. options: {
  5623. classes: {
  5624. "ui-button": "ui-corner-all"
  5625. },
  5626. disabled: null,
  5627. icon: null,
  5628. iconPosition: "beginning",
  5629. label: null,
  5630. showLabel: true
  5631. },
  5632. _getCreateOptions: function() {
  5633. var disabled,
  5634. // This is to support cases like in jQuery Mobile where the base widget does have
  5635. // an implementation of _getCreateOptions
  5636. options = this._super() || {};
  5637. this.isInput = this.element.is( "input" );
  5638. disabled = this.element[ 0 ].disabled;
  5639. if ( disabled != null ) {
  5640. options.disabled = disabled;
  5641. }
  5642. this.originalLabel = this.isInput ? this.element.val() : this.element.html();
  5643. if ( this.originalLabel ) {
  5644. options.label = this.originalLabel;
  5645. }
  5646. return options;
  5647. },
  5648. _create: function() {
  5649. if ( !this.option.showLabel & !this.options.icon ) {
  5650. this.options.showLabel = true;
  5651. }
  5652. // We have to check the option again here even though we did in _getCreateOptions,
  5653. // because null may have been passed on init which would override what was set in
  5654. // _getCreateOptions
  5655. if ( this.options.disabled == null ) {
  5656. this.options.disabled = this.element[ 0 ].disabled || false;
  5657. }
  5658. this.hasTitle = !!this.element.attr( "title" );
  5659. // Check to see if the label needs to be set or if its already correct
  5660. if ( this.options.label && this.options.label !== this.originalLabel ) {
  5661. if ( this.isInput ) {
  5662. this.element.val( this.options.label );
  5663. } else {
  5664. this.element.html( this.options.label );
  5665. }
  5666. }
  5667. this._addClass( "ui-button", "ui-widget" );
  5668. this._setOption( "disabled", this.options.disabled );
  5669. this._enhance();
  5670. if ( this.element.is( "a" ) ) {
  5671. this._on( {
  5672. "keyup": function( event ) {
  5673. if ( event.keyCode === $.ui.keyCode.SPACE ) {
  5674. event.preventDefault();
  5675. // If a native click is available use it, so we
  5676. // actually cause navigation. Otherwise, just trigger
  5677. // a click event.
  5678. if ( this.element[ 0 ].click ) {
  5679. this.element[ 0 ].click();
  5680. } else {
  5681. this.element.trigger( "click" );
  5682. }
  5683. }
  5684. }
  5685. } );
  5686. }
  5687. },
  5688. _enhance: function() {
  5689. if ( !this.element.is( "button" ) ) {
  5690. this.element.attr( "role", "button" );
  5691. }
  5692. if ( this.options.icon ) {
  5693. this._updateIcon( "icon", this.options.icon );
  5694. this._updateTooltip();
  5695. }
  5696. },
  5697. _updateTooltip: function() {
  5698. this.title = this.element.attr( "title" );
  5699. if ( !this.options.showLabel && !this.title ) {
  5700. this.element.attr( "title", this.options.label );
  5701. }
  5702. },
  5703. _updateIcon: function( option, value ) {
  5704. var icon = option !== "iconPosition",
  5705. position = icon ? this.options.iconPosition : value,
  5706. displayBlock = position === "top" || position === "bottom";
  5707. // Create icon
  5708. if ( !this.icon ) {
  5709. this.icon = $( "<span>" );
  5710. this._addClass( this.icon, "ui-button-icon", "ui-icon" );
  5711. if ( !this.options.showLabel ) {
  5712. this._addClass( "ui-button-icon-only" );
  5713. }
  5714. } else if ( icon ) {
  5715. // If we are updating the icon remove the old icon class
  5716. this._removeClass( this.icon, null, this.options.icon );
  5717. }
  5718. // If we are updating the icon add the new icon class
  5719. if ( icon ) {
  5720. this._addClass( this.icon, null, value );
  5721. }
  5722. this._attachIcon( position );
  5723. // If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove
  5724. // the iconSpace if there is one.
  5725. if ( displayBlock ) {
  5726. this._addClass( this.icon, null, "ui-widget-icon-block" );
  5727. if ( this.iconSpace ) {
  5728. this.iconSpace.remove();
  5729. }
  5730. } else {
  5731. // Position is beginning or end so remove the ui-widget-icon-block class and add the
  5732. // space if it does not exist
  5733. if ( !this.iconSpace ) {
  5734. this.iconSpace = $( "<span> </span>" );
  5735. this._addClass( this.iconSpace, "ui-button-icon-space" );
  5736. }
  5737. this._removeClass( this.icon, null, "ui-wiget-icon-block" );
  5738. this._attachIconSpace( position );
  5739. }
  5740. },
  5741. _destroy: function() {
  5742. this.element.removeAttr( "role" );
  5743. if ( this.icon ) {
  5744. this.icon.remove();
  5745. }
  5746. if ( this.iconSpace ) {
  5747. this.iconSpace.remove();
  5748. }
  5749. if ( !this.hasTitle ) {
  5750. this.element.removeAttr( "title" );
  5751. }
  5752. },
  5753. _attachIconSpace: function( iconPosition ) {
  5754. this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace );
  5755. },
  5756. _attachIcon: function( iconPosition ) {
  5757. this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon );
  5758. },
  5759. _setOptions: function( options ) {
  5760. var newShowLabel = options.showLabel === undefined ?
  5761. this.options.showLabel :
  5762. options.showLabel,
  5763. newIcon = options.icon === undefined ? this.options.icon : options.icon;
  5764. if ( !newShowLabel && !newIcon ) {
  5765. options.showLabel = true;
  5766. }
  5767. this._super( options );
  5768. },
  5769. _setOption: function( key, value ) {
  5770. if ( key === "icon" ) {
  5771. if ( value ) {
  5772. this._updateIcon( key, value );
  5773. } else if ( this.icon ) {
  5774. this.icon.remove();
  5775. if ( this.iconSpace ) {
  5776. this.iconSpace.remove();
  5777. }
  5778. }
  5779. }
  5780. if ( key === "iconPosition" ) {
  5781. this._updateIcon( key, value );
  5782. }
  5783. // Make sure we can't end up with a button that has neither text nor icon
  5784. if ( key === "showLabel" ) {
  5785. this._toggleClass( "ui-button-icon-only", null, !value );
  5786. this._updateTooltip();
  5787. }
  5788. if ( key === "label" ) {
  5789. if ( this.isInput ) {
  5790. this.element.val( value );
  5791. } else {
  5792. // If there is an icon, append it, else nothing then append the value
  5793. // this avoids removal of the icon when setting label text
  5794. this.element.html( value );
  5795. if ( this.icon ) {
  5796. this._attachIcon( this.options.iconPosition );
  5797. this._attachIconSpace( this.options.iconPosition );
  5798. }
  5799. }
  5800. }
  5801. this._super( key, value );
  5802. if ( key === "disabled" ) {
  5803. this._toggleClass( null, "ui-state-disabled", value );
  5804. this.element[ 0 ].disabled = value;
  5805. if ( value ) {
  5806. this.element.trigger( "blur" );
  5807. }
  5808. }
  5809. },
  5810. refresh: function() {
  5811. // Make sure to only check disabled if its an element that supports this otherwise
  5812. // check for the disabled class to determine state
  5813. var isDisabled = this.element.is( "input, button" ) ?
  5814. this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" );
  5815. if ( isDisabled !== this.options.disabled ) {
  5816. this._setOptions( { disabled: isDisabled } );
  5817. }
  5818. this._updateTooltip();
  5819. }
  5820. } );
  5821. // DEPRECATED
  5822. if ( $.uiBackCompat === true ) {
  5823. // Text and Icons options
  5824. $.widget( "ui.button", $.ui.button, {
  5825. options: {
  5826. text: true,
  5827. icons: {
  5828. primary: null,
  5829. secondary: null
  5830. }
  5831. },
  5832. _create: function() {
  5833. if ( this.options.showLabel && !this.options.text ) {
  5834. this.options.showLabel = this.options.text;
  5835. }
  5836. if ( !this.options.showLabel && this.options.text ) {
  5837. this.options.text = this.options.showLabel;
  5838. }
  5839. if ( !this.options.icon && ( this.options.icons.primary ||
  5840. this.options.icons.secondary ) ) {
  5841. if ( this.options.icons.primary ) {
  5842. this.options.icon = this.options.icons.primary;
  5843. } else {
  5844. this.options.icon = this.options.icons.secondary;
  5845. this.options.iconPosition = "end";
  5846. }
  5847. } else if ( this.options.icon ) {
  5848. this.options.icons.primary = this.options.icon;
  5849. }
  5850. this._super();
  5851. },
  5852. _setOption: function( key, value ) {
  5853. if ( key === "text" ) {
  5854. this._super( "showLabel", value );
  5855. return;
  5856. }
  5857. if ( key === "showLabel" ) {
  5858. this.options.text = value;
  5859. }
  5860. if ( key === "icon" ) {
  5861. this.options.icons.primary = value;
  5862. }
  5863. if ( key === "icons" ) {
  5864. if ( value.primary ) {
  5865. this._super( "icon", value.primary );
  5866. this._super( "iconPosition", "beginning" );
  5867. } else if ( value.secondary ) {
  5868. this._super( "icon", value.secondary );
  5869. this._super( "iconPosition", "end" );
  5870. }
  5871. }
  5872. this._superApply( arguments );
  5873. }
  5874. } );
  5875. $.fn.button = ( function( orig ) {
  5876. return function( options ) {
  5877. var isMethodCall = typeof options === "string";
  5878. var args = Array.prototype.slice.call( arguments, 1 );
  5879. var returnValue = this;
  5880. if ( isMethodCall ) {
  5881. // If this is an empty collection, we need to have the instance method
  5882. // return undefined instead of the jQuery instance
  5883. if ( !this.length && options === "instance" ) {
  5884. returnValue = undefined;
  5885. } else {
  5886. this.each( function() {
  5887. var methodValue;
  5888. var type = $( this ).attr( "type" );
  5889. var name = type !== "checkbox" && type !== "radio" ?
  5890. "button" :
  5891. "checkboxradio";
  5892. var instance = $.data( this, "ui-" + name );
  5893. if ( options === "instance" ) {
  5894. returnValue = instance;
  5895. return false;
  5896. }
  5897. if ( !instance ) {
  5898. return $.error( "cannot call methods on button" +
  5899. " prior to initialization; " +
  5900. "attempted to call method '" + options + "'" );
  5901. }
  5902. if ( typeof instance[ options ] !== "function" ||
  5903. options.charAt( 0 ) === "_" ) {
  5904. return $.error( "no such method '" + options + "' for button" +
  5905. " widget instance" );
  5906. }
  5907. methodValue = instance[ options ].apply( instance, args );
  5908. if ( methodValue !== instance && methodValue !== undefined ) {
  5909. returnValue = methodValue && methodValue.jquery ?
  5910. returnValue.pushStack( methodValue.get() ) :
  5911. methodValue;
  5912. return false;
  5913. }
  5914. } );
  5915. }
  5916. } else {
  5917. // Allow multiple hashes to be passed on init
  5918. if ( args.length ) {
  5919. options = $.widget.extend.apply( null, [ options ].concat( args ) );
  5920. }
  5921. this.each( function() {
  5922. var type = $( this ).attr( "type" );
  5923. var name = type !== "checkbox" && type !== "radio" ? "button" : "checkboxradio";
  5924. var instance = $.data( this, "ui-" + name );
  5925. if ( instance ) {
  5926. instance.option( options || {} );
  5927. if ( instance._init ) {
  5928. instance._init();
  5929. }
  5930. } else {
  5931. if ( name === "button" ) {
  5932. orig.call( $( this ), options );
  5933. return;
  5934. }
  5935. $( this ).checkboxradio( $.extend( { icon: false }, options ) );
  5936. }
  5937. } );
  5938. }
  5939. return returnValue;
  5940. };
  5941. } )( $.fn.button );
  5942. $.fn.buttonset = function() {
  5943. if ( !$.ui.controlgroup ) {
  5944. $.error( "Controlgroup widget missing" );
  5945. }
  5946. if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) {
  5947. return this.controlgroup.apply( this,
  5948. [ arguments[ 0 ], "items.button", arguments[ 2 ] ] );
  5949. }
  5950. if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) {
  5951. return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] );
  5952. }
  5953. if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) {
  5954. arguments[ 0 ].items = {
  5955. button: arguments[ 0 ].items
  5956. };
  5957. }
  5958. return this.controlgroup.apply( this, arguments );
  5959. };
  5960. }
  5961. var widgetsButton = $.ui.button;
  5962. /* eslint-disable max-len, camelcase */
  5963. /*!
  5964. * jQuery UI Datepicker 1.14.1
  5965. * https://jqueryui.com
  5966. *
  5967. * Copyright OpenJS Foundation and other contributors
  5968. * Released under the MIT license.
  5969. * https://jquery.org/license
  5970. */
  5971. //>>label: Datepicker
  5972. //>>group: Widgets
  5973. //>>description: Displays a calendar from an input or inline for selecting dates.
  5974. //>>docs: https://api.jqueryui.com/datepicker/
  5975. //>>demos: https://jqueryui.com/datepicker/
  5976. //>>css.structure: ../../themes/base/core.css
  5977. //>>css.structure: ../../themes/base/datepicker.css
  5978. //>>css.theme: ../../themes/base/theme.css
  5979. $.extend( $.ui, { datepicker: { version: "1.14.1" } } );
  5980. var datepicker_instActive;
  5981. function datepicker_getZindex( elem ) {
  5982. var position, value;
  5983. while ( elem.length && elem[ 0 ] !== document ) {
  5984. // Ignore z-index if position is set to a value where z-index is ignored by the browser
  5985. // This makes behavior of this function consistent across browsers
  5986. // WebKit always returns auto if the element is positioned
  5987. position = elem.css( "position" );
  5988. if ( position === "absolute" || position === "relative" || position === "fixed" ) {
  5989. // IE returns 0 when zIndex is not specified
  5990. // other browsers return a string
  5991. // we ignore the case of nested elements with an explicit value of 0
  5992. // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
  5993. value = parseInt( elem.css( "zIndex" ), 10 );
  5994. if ( !isNaN( value ) && value !== 0 ) {
  5995. return value;
  5996. }
  5997. }
  5998. elem = elem.parent();
  5999. }
  6000. return 0;
  6001. }
  6002. /* Date picker manager.
  6003. Use the singleton instance of this class, $.datepicker, to interact with the date picker.
  6004. Settings for (groups of) date pickers are maintained in an instance object,
  6005. allowing multiple different settings on the same page. */
  6006. function Datepicker() {
  6007. this._curInst = null; // The current instance in use
  6008. this._keyEvent = false; // If the last event was a key event
  6009. this._disabledInputs = []; // List of date picker inputs that have been disabled
  6010. this._datepickerShowing = false; // True if the popup picker is showing , false if not
  6011. this._inDialog = false; // True if showing within a "dialog", false if not
  6012. this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
  6013. this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
  6014. this._appendClass = "ui-datepicker-append"; // The name of the append marker class
  6015. this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
  6016. this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
  6017. this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
  6018. this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
  6019. this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
  6020. this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
  6021. this.regional = []; // Available regional settings, indexed by language code
  6022. this.regional[ "" ] = { // Default regional settings
  6023. closeText: "Done", // Display text for close link
  6024. prevText: "Prev", // Display text for previous month link
  6025. nextText: "Next", // Display text for next month link
  6026. currentText: "Today", // Display text for current month link
  6027. monthNames: [ "January", "February", "March", "April", "May", "June",
  6028. "July", "August", "September", "October", "November", "December" ], // Names of months for drop-down and formatting
  6029. monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting
  6030. dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting
  6031. dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting
  6032. dayNamesMin: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ], // Column headings for days starting at Sunday
  6033. weekHeader: "Wk", // Column header for week of the year
  6034. dateFormat: "mm/dd/yy", // See format options on parseDate
  6035. firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
  6036. isRTL: false, // True if right-to-left language, false if left-to-right
  6037. showMonthAfterYear: false, // True if the year select precedes month, false for month then year
  6038. yearSuffix: "", // Additional text to append to the year in the month headers,
  6039. selectMonthLabel: "Select month", // Invisible label for month selector
  6040. selectYearLabel: "Select year" // Invisible label for year selector
  6041. };
  6042. this._defaults = { // Global defaults for all the date picker instances
  6043. showOn: "focus", // "focus" for popup on focus,
  6044. // "button" for trigger button, or "both" for either
  6045. showAnim: "fadeIn", // Name of jQuery animation for popup
  6046. showOptions: {}, // Options for enhanced animations
  6047. defaultDate: null, // Used when field is blank: actual date,
  6048. // +/-number for offset from today, null for today
  6049. appendText: "", // Display text following the input box, e.g. showing the format
  6050. buttonText: "...", // Text for trigger button
  6051. buttonImage: "", // URL for trigger button image
  6052. buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
  6053. hideIfNoPrevNext: false, // True to hide next/previous month links
  6054. // if not applicable, false to just disable them
  6055. navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
  6056. gotoCurrent: false, // True if today link goes back to current selection instead
  6057. changeMonth: false, // True if month can be selected directly, false if only prev/next
  6058. changeYear: false, // True if year can be selected directly, false if only prev/next
  6059. yearRange: "c-10:c+10", // Range of years to display in drop-down,
  6060. // either relative to today's year (-nn:+nn), relative to currently displayed year
  6061. // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
  6062. showOtherMonths: false, // True to show dates in other months, false to leave blank
  6063. selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
  6064. showWeek: false, // True to show week of the year, false to not show it
  6065. calculateWeek: this.iso8601Week, // How to calculate the week of the year,
  6066. // takes a Date and returns the number of the week for it
  6067. shortYearCutoff: "+10", // Short year values < this are in the current century,
  6068. // > this are in the previous century,
  6069. // string value starting with "+" for current year + value
  6070. minDate: null, // The earliest selectable date, or null for no limit
  6071. maxDate: null, // The latest selectable date, or null for no limit
  6072. duration: "fast", // Duration of display/closure
  6073. beforeShowDay: null, // Function that takes a date and returns an array with
  6074. // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
  6075. // [2] = cell title (optional), e.g. $.datepicker.noWeekends
  6076. beforeShow: null, // Function that takes an input field and
  6077. // returns a set of custom settings for the date picker
  6078. onSelect: null, // Define a callback function when a date is selected
  6079. onChangeMonthYear: null, // Define a callback function when the month or year is changed
  6080. onClose: null, // Define a callback function when the datepicker is closed
  6081. onUpdateDatepicker: null, // Define a callback function when the datepicker is updated
  6082. numberOfMonths: 1, // Number of months to show at a time
  6083. showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
  6084. stepMonths: 1, // Number of months to step back/forward
  6085. stepBigMonths: 12, // Number of months to step back/forward for the big links
  6086. altField: "", // Selector for an alternate field to store selected dates into
  6087. altFormat: "", // The date format to use for the alternate field
  6088. constrainInput: true, // The input is constrained by the current date format
  6089. showButtonPanel: false, // True to show button panel, false to not show it
  6090. autoSize: false, // True to size the input for the date format, false to leave as is
  6091. disabled: false // The initial disabled state
  6092. };
  6093. $.extend( this._defaults, this.regional[ "" ] );
  6094. this.regional.en = $.extend( true, {}, this.regional[ "" ] );
  6095. this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
  6096. this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) );
  6097. }
  6098. $.extend( Datepicker.prototype, {
  6099. /* Class name added to elements to indicate already configured with a date picker. */
  6100. markerClassName: "hasDatepicker",
  6101. //Keep track of the maximum number of rows displayed (see #7043)
  6102. maxRows: 4,
  6103. // TODO rename to "widget" when switching to widget factory
  6104. _widgetDatepicker: function() {
  6105. return this.dpDiv;
  6106. },
  6107. /* Override the default settings for all instances of the date picker.
  6108. * @param settings object - the new settings to use as defaults (anonymous object)
  6109. * @return the manager object
  6110. */
  6111. setDefaults: function( settings ) {
  6112. datepicker_extendRemove( this._defaults, settings || {} );
  6113. return this;
  6114. },
  6115. /* Attach the date picker to a jQuery selection.
  6116. * @param target element - the target input field or division or span
  6117. * @param settings object - the new settings to use for this date picker instance (anonymous)
  6118. */
  6119. _attachDatepicker: function( target, settings ) {
  6120. var nodeName, inline, inst;
  6121. nodeName = target.nodeName.toLowerCase();
  6122. inline = ( nodeName === "div" || nodeName === "span" );
  6123. if ( !target.id ) {
  6124. this.uuid += 1;
  6125. target.id = "dp" + this.uuid;
  6126. }
  6127. inst = this._newInst( $( target ), inline );
  6128. inst.settings = $.extend( {}, settings || {} );
  6129. if ( nodeName === "input" ) {
  6130. this._connectDatepicker( target, inst );
  6131. } else if ( inline ) {
  6132. this._inlineDatepicker( target, inst );
  6133. }
  6134. },
  6135. /* Create a new instance object. */
  6136. _newInst: function( target, inline ) {
  6137. var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars
  6138. return { id: id, input: target, // associated target
  6139. selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
  6140. drawMonth: 0, drawYear: 0, // month being drawn
  6141. inline: inline, // is datepicker inline or not
  6142. dpDiv: ( !inline ? this.dpDiv : // presentation div
  6143. datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) };
  6144. },
  6145. /* Attach the date picker to an input field. */
  6146. _connectDatepicker: function( target, inst ) {
  6147. var input = $( target );
  6148. inst.append = $( [] );
  6149. inst.trigger = $( [] );
  6150. if ( input.hasClass( this.markerClassName ) ) {
  6151. return;
  6152. }
  6153. this._attachments( input, inst );
  6154. input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ).
  6155. on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp );
  6156. this._autoSize( inst );
  6157. $.data( target, "datepicker", inst );
  6158. //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
  6159. if ( inst.settings.disabled ) {
  6160. this._disableDatepicker( target );
  6161. }
  6162. },
  6163. /* Make attachments based on settings. */
  6164. _attachments: function( input, inst ) {
  6165. var showOn, buttonText, buttonImage,
  6166. appendText = this._get( inst, "appendText" ),
  6167. isRTL = this._get( inst, "isRTL" );
  6168. if ( inst.append ) {
  6169. inst.append.remove();
  6170. }
  6171. if ( appendText ) {
  6172. inst.append = $( "<span>" )
  6173. .addClass( this._appendClass )
  6174. .text( appendText );
  6175. input[ isRTL ? "before" : "after" ]( inst.append );
  6176. }
  6177. input.off( "focus", this._showDatepicker );
  6178. if ( inst.trigger ) {
  6179. inst.trigger.remove();
  6180. }
  6181. showOn = this._get( inst, "showOn" );
  6182. if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field
  6183. input.on( "focus", this._showDatepicker );
  6184. }
  6185. if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked
  6186. buttonText = this._get( inst, "buttonText" );
  6187. buttonImage = this._get( inst, "buttonImage" );
  6188. if ( this._get( inst, "buttonImageOnly" ) ) {
  6189. inst.trigger = $( "<img>" )
  6190. .addClass( this._triggerClass )
  6191. .attr( {
  6192. src: buttonImage,
  6193. alt: buttonText,
  6194. title: buttonText
  6195. } );
  6196. } else {
  6197. inst.trigger = $( "<button type='button'>" )
  6198. .addClass( this._triggerClass );
  6199. if ( buttonImage ) {
  6200. inst.trigger.html(
  6201. $( "<img>" )
  6202. .attr( {
  6203. src: buttonImage,
  6204. alt: buttonText,
  6205. title: buttonText
  6206. } )
  6207. );
  6208. } else {
  6209. inst.trigger.text( buttonText );
  6210. }
  6211. }
  6212. input[ isRTL ? "before" : "after" ]( inst.trigger );
  6213. inst.trigger.on( "click", function() {
  6214. if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) {
  6215. $.datepicker._hideDatepicker();
  6216. } else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) {
  6217. $.datepicker._hideDatepicker();
  6218. $.datepicker._showDatepicker( input[ 0 ] );
  6219. } else {
  6220. $.datepicker._showDatepicker( input[ 0 ] );
  6221. }
  6222. return false;
  6223. } );
  6224. }
  6225. },
  6226. /* Apply the maximum length for the date format. */
  6227. _autoSize: function( inst ) {
  6228. if ( this._get( inst, "autoSize" ) && !inst.inline ) {
  6229. var findMax, max, maxI, i,
  6230. date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits
  6231. dateFormat = this._get( inst, "dateFormat" );
  6232. if ( dateFormat.match( /[DM]/ ) ) {
  6233. findMax = function( names ) {
  6234. max = 0;
  6235. maxI = 0;
  6236. for ( i = 0; i < names.length; i++ ) {
  6237. if ( names[ i ].length > max ) {
  6238. max = names[ i ].length;
  6239. maxI = i;
  6240. }
  6241. }
  6242. return maxI;
  6243. };
  6244. date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ?
  6245. "monthNames" : "monthNamesShort" ) ) ) );
  6246. date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ?
  6247. "dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() );
  6248. }
  6249. inst.input.attr( "size", this._formatDate( inst, date ).length );
  6250. }
  6251. },
  6252. /* Attach an inline date picker to a div. */
  6253. _inlineDatepicker: function( target, inst ) {
  6254. var divSpan = $( target );
  6255. if ( divSpan.hasClass( this.markerClassName ) ) {
  6256. return;
  6257. }
  6258. divSpan.addClass( this.markerClassName ).append( inst.dpDiv );
  6259. $.data( target, "datepicker", inst );
  6260. this._setDate( inst, this._getDefaultDate( inst ), true );
  6261. this._updateDatepicker( inst );
  6262. this._updateAlternate( inst );
  6263. //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
  6264. if ( inst.settings.disabled ) {
  6265. this._disableDatepicker( target );
  6266. }
  6267. // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
  6268. // https://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
  6269. inst.dpDiv.css( "display", "block" );
  6270. },
  6271. /* Pop-up the date picker in a "dialog" box.
  6272. * @param input element - ignored
  6273. * @param date string or Date - the initial date to display
  6274. * @param onSelect function - the function to call when a date is selected
  6275. * @param settings object - update the dialog date picker instance's settings (anonymous object)
  6276. * @param pos int[2] - coordinates for the dialog's position within the screen or
  6277. * event - with x/y coordinates or
  6278. * leave empty for default (screen centre)
  6279. * @return the manager object
  6280. */
  6281. _dialogDatepicker: function( input, date, onSelect, settings, pos ) {
  6282. var id, browserWidth, browserHeight, scrollX, scrollY,
  6283. inst = this._dialogInst; // internal instance
  6284. if ( !inst ) {
  6285. this.uuid += 1;
  6286. id = "dp" + this.uuid;
  6287. this._dialogInput = $( "<input type='text' id='" + id +
  6288. "' style='position: absolute; top: -100px; width: 0px;'/>" );
  6289. this._dialogInput.on( "keydown", this._doKeyDown );
  6290. $( "body" ).append( this._dialogInput );
  6291. inst = this._dialogInst = this._newInst( this._dialogInput, false );
  6292. inst.settings = {};
  6293. $.data( this._dialogInput[ 0 ], "datepicker", inst );
  6294. }
  6295. datepicker_extendRemove( inst.settings, settings || {} );
  6296. date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date );
  6297. this._dialogInput.val( date );
  6298. this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null );
  6299. if ( !this._pos ) {
  6300. browserWidth = document.documentElement.clientWidth;
  6301. browserHeight = document.documentElement.clientHeight;
  6302. scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
  6303. scrollY = document.documentElement.scrollTop || document.body.scrollTop;
  6304. this._pos = // should use actual width/height below
  6305. [ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ];
  6306. }
  6307. // Move input on screen for focus, but hidden behind dialog
  6308. this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" );
  6309. inst.settings.onSelect = onSelect;
  6310. this._inDialog = true;
  6311. this.dpDiv.addClass( this._dialogClass );
  6312. this._showDatepicker( this._dialogInput[ 0 ] );
  6313. if ( $.blockUI ) {
  6314. $.blockUI( this.dpDiv );
  6315. }
  6316. $.data( this._dialogInput[ 0 ], "datepicker", inst );
  6317. return this;
  6318. },
  6319. /* Detach a datepicker from its control.
  6320. * @param target element - the target input field or division or span
  6321. */
  6322. _destroyDatepicker: function( target ) {
  6323. var nodeName,
  6324. $target = $( target ),
  6325. inst = $.data( target, "datepicker" );
  6326. if ( !$target.hasClass( this.markerClassName ) ) {
  6327. return;
  6328. }
  6329. nodeName = target.nodeName.toLowerCase();
  6330. $.removeData( target, "datepicker" );
  6331. if ( nodeName === "input" ) {
  6332. inst.append.remove();
  6333. inst.trigger.remove();
  6334. $target.removeClass( this.markerClassName ).
  6335. off( "focus", this._showDatepicker ).
  6336. off( "keydown", this._doKeyDown ).
  6337. off( "keypress", this._doKeyPress ).
  6338. off( "keyup", this._doKeyUp );
  6339. } else if ( nodeName === "div" || nodeName === "span" ) {
  6340. $target.removeClass( this.markerClassName ).empty();
  6341. }
  6342. $.datepicker._hideDatepicker();
  6343. if ( datepicker_instActive === inst ) {
  6344. datepicker_instActive = null;
  6345. this._curInst = null;
  6346. }
  6347. },
  6348. /* Enable the date picker to a jQuery selection.
  6349. * @param target element - the target input field or division or span
  6350. */
  6351. _enableDatepicker: function( target ) {
  6352. var nodeName, inline,
  6353. $target = $( target ),
  6354. inst = $.data( target, "datepicker" );
  6355. if ( !$target.hasClass( this.markerClassName ) ) {
  6356. return;
  6357. }
  6358. nodeName = target.nodeName.toLowerCase();
  6359. if ( nodeName === "input" ) {
  6360. target.disabled = false;
  6361. inst.trigger.filter( "button" ).
  6362. each( function() {
  6363. this.disabled = false;
  6364. } ).end().
  6365. filter( "img" ).css( { opacity: "1.0", cursor: "" } );
  6366. } else if ( nodeName === "div" || nodeName === "span" ) {
  6367. inline = $target.children( "." + this._inlineClass );
  6368. inline.children().removeClass( "ui-state-disabled" );
  6369. inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
  6370. prop( "disabled", false );
  6371. }
  6372. this._disabledInputs = $.map( this._disabledInputs,
  6373. // Delete entry
  6374. function( value ) {
  6375. return ( value === target ? null : value );
  6376. } );
  6377. },
  6378. /* Disable the date picker to a jQuery selection.
  6379. * @param target element - the target input field or division or span
  6380. */
  6381. _disableDatepicker: function( target ) {
  6382. var nodeName, inline,
  6383. $target = $( target ),
  6384. inst = $.data( target, "datepicker" );
  6385. if ( !$target.hasClass( this.markerClassName ) ) {
  6386. return;
  6387. }
  6388. nodeName = target.nodeName.toLowerCase();
  6389. if ( nodeName === "input" ) {
  6390. target.disabled = true;
  6391. inst.trigger.filter( "button" ).
  6392. each( function() {
  6393. this.disabled = true;
  6394. } ).end().
  6395. filter( "img" ).css( { opacity: "0.5", cursor: "default" } );
  6396. } else if ( nodeName === "div" || nodeName === "span" ) {
  6397. inline = $target.children( "." + this._inlineClass );
  6398. inline.children().addClass( "ui-state-disabled" );
  6399. inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
  6400. prop( "disabled", true );
  6401. }
  6402. this._disabledInputs = $.map( this._disabledInputs,
  6403. // Delete entry
  6404. function( value ) {
  6405. return ( value === target ? null : value );
  6406. } );
  6407. this._disabledInputs[ this._disabledInputs.length ] = target;
  6408. },
  6409. /* Is the first field in a jQuery collection disabled as a datepicker?
  6410. * @param target element - the target input field or division or span
  6411. * @return boolean - true if disabled, false if enabled
  6412. */
  6413. _isDisabledDatepicker: function( target ) {
  6414. if ( !target ) {
  6415. return false;
  6416. }
  6417. for ( var i = 0; i < this._disabledInputs.length; i++ ) {
  6418. if ( this._disabledInputs[ i ] === target ) {
  6419. return true;
  6420. }
  6421. }
  6422. return false;
  6423. },
  6424. /* Retrieve the instance data for the target control.
  6425. * @param target element - the target input field or division or span
  6426. * @return object - the associated instance data
  6427. * @throws error if a jQuery problem getting data
  6428. */
  6429. _getInst: function( target ) {
  6430. try {
  6431. return $.data( target, "datepicker" );
  6432. } catch ( err ) {
  6433. throw "Missing instance data for this datepicker";
  6434. }
  6435. },
  6436. /* Update or retrieve the settings for a date picker attached to an input field or division.
  6437. * @param target element - the target input field or division or span
  6438. * @param name object - the new settings to update or
  6439. * string - the name of the setting to change or retrieve,
  6440. * when retrieving also "all" for all instance settings or
  6441. * "defaults" for all global defaults
  6442. * @param value any - the new value for the setting
  6443. * (omit if above is an object or to retrieve a value)
  6444. */
  6445. _optionDatepicker: function( target, name, value ) {
  6446. var settings, date, minDate, maxDate,
  6447. inst = this._getInst( target );
  6448. if ( arguments.length === 2 && typeof name === "string" ) {
  6449. return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) :
  6450. ( inst ? ( name === "all" ? $.extend( {}, inst.settings ) :
  6451. this._get( inst, name ) ) : null ) );
  6452. }
  6453. settings = name || {};
  6454. if ( typeof name === "string" ) {
  6455. settings = {};
  6456. settings[ name ] = value;
  6457. }
  6458. if ( inst ) {
  6459. if ( this._curInst === inst ) {
  6460. this._hideDatepicker();
  6461. }
  6462. date = this._getDateDatepicker( target, true );
  6463. minDate = this._getMinMaxDate( inst, "min" );
  6464. maxDate = this._getMinMaxDate( inst, "max" );
  6465. datepicker_extendRemove( inst.settings, settings );
  6466. // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
  6467. if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) {
  6468. inst.settings.minDate = this._formatDate( inst, minDate );
  6469. }
  6470. if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) {
  6471. inst.settings.maxDate = this._formatDate( inst, maxDate );
  6472. }
  6473. if ( "disabled" in settings ) {
  6474. if ( settings.disabled ) {
  6475. this._disableDatepicker( target );
  6476. } else {
  6477. this._enableDatepicker( target );
  6478. }
  6479. }
  6480. this._attachments( $( target ), inst );
  6481. this._autoSize( inst );
  6482. this._setDate( inst, date );
  6483. this._updateAlternate( inst );
  6484. this._updateDatepicker( inst );
  6485. }
  6486. },
  6487. // Change method deprecated
  6488. _changeDatepicker: function( target, name, value ) {
  6489. this._optionDatepicker( target, name, value );
  6490. },
  6491. /* Redraw the date picker attached to an input field or division.
  6492. * @param target element - the target input field or division or span
  6493. */
  6494. _refreshDatepicker: function( target ) {
  6495. var inst = this._getInst( target );
  6496. if ( inst ) {
  6497. this._updateDatepicker( inst );
  6498. }
  6499. },
  6500. /* Set the dates for a jQuery selection.
  6501. * @param target element - the target input field or division or span
  6502. * @param date Date - the new date
  6503. */
  6504. _setDateDatepicker: function( target, date ) {
  6505. var inst = this._getInst( target );
  6506. if ( inst ) {
  6507. this._setDate( inst, date );
  6508. this._updateDatepicker( inst );
  6509. this._updateAlternate( inst );
  6510. }
  6511. },
  6512. /* Get the date(s) for the first entry in a jQuery selection.
  6513. * @param target element - the target input field or division or span
  6514. * @param noDefault boolean - true if no default date is to be used
  6515. * @return Date - the current date
  6516. */
  6517. _getDateDatepicker: function( target, noDefault ) {
  6518. var inst = this._getInst( target );
  6519. if ( inst && !inst.inline ) {
  6520. this._setDateFromField( inst, noDefault );
  6521. }
  6522. return ( inst ? this._getDate( inst ) : null );
  6523. },
  6524. /* Handle keystrokes. */
  6525. _doKeyDown: function( event ) {
  6526. var onSelect, dateStr, sel,
  6527. inst = $.datepicker._getInst( event.target ),
  6528. handled = true,
  6529. isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" );
  6530. inst._keyEvent = true;
  6531. if ( $.datepicker._datepickerShowing ) {
  6532. switch ( event.keyCode ) {
  6533. case 9: $.datepicker._hideDatepicker();
  6534. handled = false;
  6535. break; // hide on tab out
  6536. case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." +
  6537. $.datepicker._currentClass + ")", inst.dpDiv );
  6538. if ( sel[ 0 ] ) {
  6539. $.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] );
  6540. }
  6541. onSelect = $.datepicker._get( inst, "onSelect" );
  6542. if ( onSelect ) {
  6543. dateStr = $.datepicker._formatDate( inst );
  6544. // Trigger custom callback
  6545. onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );
  6546. } else {
  6547. $.datepicker._hideDatepicker();
  6548. }
  6549. return false; // don't submit the form
  6550. case 27: $.datepicker._hideDatepicker();
  6551. break; // hide on escape
  6552. case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
  6553. -$.datepicker._get( inst, "stepBigMonths" ) :
  6554. -$.datepicker._get( inst, "stepMonths" ) ), "M" );
  6555. break; // previous month/year on page up/+ ctrl
  6556. case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
  6557. +$.datepicker._get( inst, "stepBigMonths" ) :
  6558. +$.datepicker._get( inst, "stepMonths" ) ), "M" );
  6559. break; // next month/year on page down/+ ctrl
  6560. case 35: if ( event.ctrlKey || event.metaKey ) {
  6561. $.datepicker._clearDate( event.target );
  6562. }
  6563. handled = event.ctrlKey || event.metaKey;
  6564. break; // clear on ctrl or command +end
  6565. case 36: if ( event.ctrlKey || event.metaKey ) {
  6566. $.datepicker._gotoToday( event.target );
  6567. }
  6568. handled = event.ctrlKey || event.metaKey;
  6569. break; // current on ctrl or command +home
  6570. case 37: if ( event.ctrlKey || event.metaKey ) {
  6571. $.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" );
  6572. }
  6573. handled = event.ctrlKey || event.metaKey;
  6574. // -1 day on ctrl or command +left
  6575. if ( event.originalEvent.altKey ) {
  6576. $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
  6577. -$.datepicker._get( inst, "stepBigMonths" ) :
  6578. -$.datepicker._get( inst, "stepMonths" ) ), "M" );
  6579. }
  6580. // next month/year on alt +left on Mac
  6581. break;
  6582. case 38: if ( event.ctrlKey || event.metaKey ) {
  6583. $.datepicker._adjustDate( event.target, -7, "D" );
  6584. }
  6585. handled = event.ctrlKey || event.metaKey;
  6586. break; // -1 week on ctrl or command +up
  6587. case 39: if ( event.ctrlKey || event.metaKey ) {
  6588. $.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" );
  6589. }
  6590. handled = event.ctrlKey || event.metaKey;
  6591. // +1 day on ctrl or command +right
  6592. if ( event.originalEvent.altKey ) {
  6593. $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
  6594. +$.datepicker._get( inst, "stepBigMonths" ) :
  6595. +$.datepicker._get( inst, "stepMonths" ) ), "M" );
  6596. }
  6597. // next month/year on alt +right
  6598. break;
  6599. case 40: if ( event.ctrlKey || event.metaKey ) {
  6600. $.datepicker._adjustDate( event.target, +7, "D" );
  6601. }
  6602. handled = event.ctrlKey || event.metaKey;
  6603. break; // +1 week on ctrl or command +down
  6604. default: handled = false;
  6605. }
  6606. } else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home
  6607. $.datepicker._showDatepicker( this );
  6608. } else {
  6609. handled = false;
  6610. }
  6611. if ( handled ) {
  6612. event.preventDefault();
  6613. event.stopPropagation();
  6614. }
  6615. },
  6616. /* Filter entered characters - based on date format. */
  6617. _doKeyPress: function( event ) {
  6618. var chars, chr,
  6619. inst = $.datepicker._getInst( event.target );
  6620. if ( $.datepicker._get( inst, "constrainInput" ) ) {
  6621. chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) );
  6622. chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode );
  6623. return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 );
  6624. }
  6625. },
  6626. /* Synchronise manual entry and field/alternate field. */
  6627. _doKeyUp: function( event ) {
  6628. var date,
  6629. inst = $.datepicker._getInst( event.target );
  6630. if ( inst.input.val() !== inst.lastVal ) {
  6631. try {
  6632. date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
  6633. ( inst.input ? inst.input.val() : null ),
  6634. $.datepicker._getFormatConfig( inst ) );
  6635. if ( date ) { // only if valid
  6636. $.datepicker._setDateFromField( inst );
  6637. $.datepicker._updateAlternate( inst );
  6638. $.datepicker._updateDatepicker( inst );
  6639. }
  6640. } catch ( err ) {
  6641. }
  6642. }
  6643. return true;
  6644. },
  6645. /* Pop-up the date picker for a given input field.
  6646. * If false returned from beforeShow event handler do not show.
  6647. * @param input element - the input field attached to the date picker or
  6648. * event - if triggered by focus
  6649. */
  6650. _showDatepicker: function( input ) {
  6651. input = input.target || input;
  6652. if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger
  6653. input = $( "input", input.parentNode )[ 0 ];
  6654. }
  6655. if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here
  6656. return;
  6657. }
  6658. var inst, beforeShow, beforeShowSettings, isFixed,
  6659. offset, showAnim, duration;
  6660. inst = $.datepicker._getInst( input );
  6661. if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) {
  6662. $.datepicker._curInst.dpDiv.stop( true, true );
  6663. if ( inst && $.datepicker._datepickerShowing ) {
  6664. $.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] );
  6665. }
  6666. }
  6667. beforeShow = $.datepicker._get( inst, "beforeShow" );
  6668. beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {};
  6669. if ( beforeShowSettings === false ) {
  6670. return;
  6671. }
  6672. datepicker_extendRemove( inst.settings, beforeShowSettings );
  6673. inst.lastVal = null;
  6674. $.datepicker._lastInput = input;
  6675. $.datepicker._setDateFromField( inst );
  6676. if ( $.datepicker._inDialog ) { // hide cursor
  6677. input.value = "";
  6678. }
  6679. if ( !$.datepicker._pos ) { // position below input
  6680. $.datepicker._pos = $.datepicker._findPos( input );
  6681. $.datepicker._pos[ 1 ] += input.offsetHeight; // add the height
  6682. }
  6683. isFixed = false;
  6684. $( input ).parents().each( function() {
  6685. isFixed |= $( this ).css( "position" ) === "fixed";
  6686. return !isFixed;
  6687. } );
  6688. offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] };
  6689. $.datepicker._pos = null;
  6690. //to avoid flashes on Firefox
  6691. inst.dpDiv.empty();
  6692. // determine sizing offscreen
  6693. inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } );
  6694. $.datepicker._updateDatepicker( inst );
  6695. // fix width for dynamic number of date pickers
  6696. // and adjust position before showing
  6697. offset = $.datepicker._checkOffset( inst, offset, isFixed );
  6698. inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ?
  6699. "static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none",
  6700. left: offset.left + "px", top: offset.top + "px" } );
  6701. if ( !inst.inline ) {
  6702. showAnim = $.datepicker._get( inst, "showAnim" );
  6703. duration = $.datepicker._get( inst, "duration" );
  6704. inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
  6705. $.datepicker._datepickerShowing = true;
  6706. if ( $.effects && $.effects.effect[ showAnim ] ) {
  6707. inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration );
  6708. } else {
  6709. inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null );
  6710. }
  6711. if ( $.datepicker._shouldFocusInput( inst ) ) {
  6712. inst.input.trigger( "focus" );
  6713. }
  6714. $.datepicker._curInst = inst;
  6715. }
  6716. },
  6717. /* Generate the date picker content. */
  6718. _updateDatepicker: function( inst ) {
  6719. this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
  6720. datepicker_instActive = inst; // for delegate hover events
  6721. inst.dpDiv.empty().append( this._generateHTML( inst ) );
  6722. this._attachHandlers( inst );
  6723. var origyearshtml,
  6724. numMonths = this._getNumberOfMonths( inst ),
  6725. cols = numMonths[ 1 ],
  6726. width = 17,
  6727. activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ),
  6728. onUpdateDatepicker = $.datepicker._get( inst, "onUpdateDatepicker" );
  6729. if ( activeCell.length > 0 ) {
  6730. datepicker_handleMouseover.apply( activeCell.get( 0 ) );
  6731. }
  6732. inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" );
  6733. if ( cols > 1 ) {
  6734. inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" );
  6735. }
  6736. inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) +
  6737. "Class" ]( "ui-datepicker-multi" );
  6738. inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) +
  6739. "Class" ]( "ui-datepicker-rtl" );
  6740. if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
  6741. inst.input.trigger( "focus" );
  6742. }
  6743. // Deffered render of the years select (to avoid flashes on Firefox)
  6744. if ( inst.yearshtml ) {
  6745. origyearshtml = inst.yearshtml;
  6746. setTimeout( function() {
  6747. //assure that inst.yearshtml didn't change.
  6748. if ( origyearshtml === inst.yearshtml && inst.yearshtml ) {
  6749. inst.dpDiv.find( "select.ui-datepicker-year" ).first().replaceWith( inst.yearshtml );
  6750. }
  6751. origyearshtml = inst.yearshtml = null;
  6752. }, 0 );
  6753. }
  6754. if ( onUpdateDatepicker ) {
  6755. onUpdateDatepicker.apply( ( inst.input ? inst.input[ 0 ] : null ), [ inst ] );
  6756. }
  6757. },
  6758. _shouldFocusInput: function( inst ) {
  6759. return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" );
  6760. },
  6761. /* Check positioning to remain on screen. */
  6762. _checkOffset: function( inst, offset, isFixed ) {
  6763. var dpWidth = inst.dpDiv.outerWidth(),
  6764. dpHeight = inst.dpDiv.outerHeight(),
  6765. inputWidth = inst.input ? inst.input.outerWidth() : 0,
  6766. inputHeight = inst.input ? inst.input.outerHeight() : 0,
  6767. viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ),
  6768. viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() );
  6769. offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 );
  6770. offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0;
  6771. offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0;
  6772. // Now check if datepicker is showing outside window viewport - move to a better place if so.
  6773. offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ?
  6774. Math.abs( offset.left + dpWidth - viewWidth ) : 0 );
  6775. offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ?
  6776. Math.abs( dpHeight + inputHeight ) : 0 );
  6777. return offset;
  6778. },
  6779. /* Find an object's position on the screen. */
  6780. _findPos: function( obj ) {
  6781. var position,
  6782. inst = this._getInst( obj ),
  6783. isRTL = this._get( inst, "isRTL" );
  6784. while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.pseudos.hidden( obj ) ) ) {
  6785. obj = obj[ isRTL ? "previousSibling" : "nextSibling" ];
  6786. }
  6787. position = $( obj ).offset();
  6788. return [ position.left, position.top ];
  6789. },
  6790. /* Hide the date picker from view.
  6791. * @param input element - the input field attached to the date picker
  6792. */
  6793. _hideDatepicker: function( input ) {
  6794. var showAnim, duration, postProcess, onClose,
  6795. inst = this._curInst;
  6796. if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) {
  6797. return;
  6798. }
  6799. if ( this._datepickerShowing ) {
  6800. showAnim = this._get( inst, "showAnim" );
  6801. duration = this._get( inst, "duration" );
  6802. postProcess = function() {
  6803. $.datepicker._tidyDialog( inst );
  6804. };
  6805. if ( $.effects && ( $.effects.effect[ showAnim ] ) ) {
  6806. inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess );
  6807. } else {
  6808. inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" :
  6809. ( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess );
  6810. }
  6811. if ( !showAnim ) {
  6812. postProcess();
  6813. }
  6814. this._datepickerShowing = false;
  6815. onClose = this._get( inst, "onClose" );
  6816. if ( onClose ) {
  6817. onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] );
  6818. }
  6819. this._lastInput = null;
  6820. if ( this._inDialog ) {
  6821. this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } );
  6822. if ( $.blockUI ) {
  6823. $.unblockUI();
  6824. $( "body" ).append( this.dpDiv );
  6825. }
  6826. }
  6827. this._inDialog = false;
  6828. }
  6829. },
  6830. /* Tidy up after a dialog display. */
  6831. _tidyDialog: function( inst ) {
  6832. inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" );
  6833. },
  6834. /* Close date picker if clicked elsewhere. */
  6835. _checkExternalClick: function( event ) {
  6836. if ( !$.datepicker._curInst ) {
  6837. return;
  6838. }
  6839. var $target = $( event.target ),
  6840. inst = $.datepicker._getInst( $target[ 0 ] );
  6841. if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId &&
  6842. $target.parents( "#" + $.datepicker._mainDivId ).length === 0 &&
  6843. !$target.hasClass( $.datepicker.markerClassName ) &&
  6844. !$target.closest( "." + $.datepicker._triggerClass ).length &&
  6845. $.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) ||
  6846. ( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) {
  6847. $.datepicker._hideDatepicker();
  6848. }
  6849. },
  6850. /* Adjust one of the date sub-fields. */
  6851. _adjustDate: function( id, offset, period ) {
  6852. var target = $( id ),
  6853. inst = this._getInst( target[ 0 ] );
  6854. if ( this._isDisabledDatepicker( target[ 0 ] ) ) {
  6855. return;
  6856. }
  6857. this._adjustInstDate( inst, offset, period );
  6858. this._updateDatepicker( inst );
  6859. },
  6860. /* Action for current link. */
  6861. _gotoToday: function( id ) {
  6862. var date,
  6863. target = $( id ),
  6864. inst = this._getInst( target[ 0 ] );
  6865. if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) {
  6866. inst.selectedDay = inst.currentDay;
  6867. inst.drawMonth = inst.selectedMonth = inst.currentMonth;
  6868. inst.drawYear = inst.selectedYear = inst.currentYear;
  6869. } else {
  6870. date = new Date();
  6871. inst.selectedDay = date.getDate();
  6872. inst.drawMonth = inst.selectedMonth = date.getMonth();
  6873. inst.drawYear = inst.selectedYear = date.getFullYear();
  6874. }
  6875. this._notifyChange( inst );
  6876. this._adjustDate( target );
  6877. },
  6878. /* Action for selecting a new month/year. */
  6879. _selectMonthYear: function( id, select, period ) {
  6880. var target = $( id ),
  6881. inst = this._getInst( target[ 0 ] );
  6882. inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] =
  6883. inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] =
  6884. parseInt( select.options[ select.selectedIndex ].value, 10 );
  6885. this._notifyChange( inst );
  6886. this._adjustDate( target );
  6887. },
  6888. /* Action for selecting a day. */
  6889. _selectDay: function( id, month, year, td ) {
  6890. var inst,
  6891. target = $( id );
  6892. if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) {
  6893. return;
  6894. }
  6895. inst = this._getInst( target[ 0 ] );
  6896. inst.selectedDay = inst.currentDay = parseInt( $( "a", td ).attr( "data-date" ) );
  6897. inst.selectedMonth = inst.currentMonth = month;
  6898. inst.selectedYear = inst.currentYear = year;
  6899. this._selectDate( id, this._formatDate( inst,
  6900. inst.currentDay, inst.currentMonth, inst.currentYear ) );
  6901. },
  6902. /* Erase the input field and hide the date picker. */
  6903. _clearDate: function( id ) {
  6904. var target = $( id );
  6905. this._selectDate( target, "" );
  6906. },
  6907. /* Update the input field with the selected date. */
  6908. _selectDate: function( id, dateStr ) {
  6909. var onSelect,
  6910. target = $( id ),
  6911. inst = this._getInst( target[ 0 ] );
  6912. dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) );
  6913. if ( inst.input ) {
  6914. inst.input.val( dateStr );
  6915. }
  6916. this._updateAlternate( inst );
  6917. onSelect = this._get( inst, "onSelect" );
  6918. if ( onSelect ) {
  6919. onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); // trigger custom callback
  6920. } else if ( inst.input ) {
  6921. inst.input.trigger( "change" ); // fire the change event
  6922. }
  6923. if ( inst.inline ) {
  6924. this._updateDatepicker( inst );
  6925. } else {
  6926. this._hideDatepicker();
  6927. this._lastInput = inst.input[ 0 ];
  6928. if ( typeof( inst.input[ 0 ] ) !== "object" ) {
  6929. inst.input.trigger( "focus" ); // restore focus
  6930. }
  6931. this._lastInput = null;
  6932. }
  6933. },
  6934. /* Update any alternate field to synchronise with the main field. */
  6935. _updateAlternate: function( inst ) {
  6936. var altFormat, date, dateStr,
  6937. altField = this._get( inst, "altField" );
  6938. if ( altField ) { // update alternate field too
  6939. altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" );
  6940. date = this._getDate( inst );
  6941. dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) );
  6942. $( document ).find( altField ).val( dateStr );
  6943. }
  6944. },
  6945. /* Set as beforeShowDay function to prevent selection of weekends.
  6946. * @param date Date - the date to customise
  6947. * @return [boolean, string] - is this date selectable?, what is its CSS class?
  6948. */
  6949. noWeekends: function( date ) {
  6950. var day = date.getDay();
  6951. return [ ( day > 0 && day < 6 ), "" ];
  6952. },
  6953. /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
  6954. * @param date Date - the date to get the week for
  6955. * @return number - the number of the week within the year that contains this date
  6956. */
  6957. iso8601Week: function( date ) {
  6958. var time,
  6959. checkDate = new Date( date.getTime() );
  6960. // Find Thursday of this week starting on Monday
  6961. checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) );
  6962. time = checkDate.getTime();
  6963. checkDate.setMonth( 0 ); // Compare with Jan 1
  6964. checkDate.setDate( 1 );
  6965. return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1;
  6966. },
  6967. /* Parse a string value into a date object.
  6968. * See formatDate below for the possible formats.
  6969. *
  6970. * @param format string - the expected format of the date
  6971. * @param value string - the date in the above format
  6972. * @param settings Object - attributes include:
  6973. * shortYearCutoff number - the cutoff year for determining the century (optional)
  6974. * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
  6975. * dayNames string[7] - names of the days from Sunday (optional)
  6976. * monthNamesShort string[12] - abbreviated names of the months (optional)
  6977. * monthNames string[12] - names of the months (optional)
  6978. * @return Date - the extracted date value or null if value is blank
  6979. */
  6980. parseDate: function( format, value, settings ) {
  6981. if ( format == null || value == null ) {
  6982. throw "Invalid arguments";
  6983. }
  6984. value = ( typeof value === "object" ? value.toString() : value + "" );
  6985. if ( value === "" ) {
  6986. return null;
  6987. }
  6988. var iFormat, dim, extra,
  6989. iValue = 0,
  6990. shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff,
  6991. shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
  6992. new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ),
  6993. dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
  6994. dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
  6995. monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
  6996. monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
  6997. year = -1,
  6998. month = -1,
  6999. day = -1,
  7000. doy = -1,
  7001. literal = false,
  7002. date,
  7003. // Check whether a format character is doubled
  7004. lookAhead = function( match ) {
  7005. var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
  7006. if ( matches ) {
  7007. iFormat++;
  7008. }
  7009. return matches;
  7010. },
  7011. // Extract a number from the string value
  7012. getNumber = function( match ) {
  7013. var isDoubled = lookAhead( match ),
  7014. size = ( match === "@" ? 14 : ( match === "!" ? 20 :
  7015. ( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ),
  7016. minSize = ( match === "y" ? size : 1 ),
  7017. digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ),
  7018. num = value.substring( iValue ).match( digits );
  7019. if ( !num ) {
  7020. throw "Missing number at position " + iValue;
  7021. }
  7022. iValue += num[ 0 ].length;
  7023. return parseInt( num[ 0 ], 10 );
  7024. },
  7025. // Extract a name from the string value and convert to an index
  7026. getName = function( match, shortNames, longNames ) {
  7027. var index = -1,
  7028. names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) {
  7029. return [ [ k, v ] ];
  7030. } ).sort( function( a, b ) {
  7031. return -( a[ 1 ].length - b[ 1 ].length );
  7032. } );
  7033. $.each( names, function( i, pair ) {
  7034. var name = pair[ 1 ];
  7035. if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) {
  7036. index = pair[ 0 ];
  7037. iValue += name.length;
  7038. return false;
  7039. }
  7040. } );
  7041. if ( index !== -1 ) {
  7042. return index + 1;
  7043. } else {
  7044. throw "Unknown name at position " + iValue;
  7045. }
  7046. },
  7047. // Confirm that a literal character matches the string value
  7048. checkLiteral = function() {
  7049. if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) {
  7050. throw "Unexpected literal at position " + iValue;
  7051. }
  7052. iValue++;
  7053. };
  7054. for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
  7055. if ( literal ) {
  7056. if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
  7057. literal = false;
  7058. } else {
  7059. checkLiteral();
  7060. }
  7061. } else {
  7062. switch ( format.charAt( iFormat ) ) {
  7063. case "d":
  7064. day = getNumber( "d" );
  7065. break;
  7066. case "D":
  7067. getName( "D", dayNamesShort, dayNames );
  7068. break;
  7069. case "o":
  7070. doy = getNumber( "o" );
  7071. break;
  7072. case "m":
  7073. month = getNumber( "m" );
  7074. break;
  7075. case "M":
  7076. month = getName( "M", monthNamesShort, monthNames );
  7077. break;
  7078. case "y":
  7079. year = getNumber( "y" );
  7080. break;
  7081. case "@":
  7082. date = new Date( getNumber( "@" ) );
  7083. year = date.getFullYear();
  7084. month = date.getMonth() + 1;
  7085. day = date.getDate();
  7086. break;
  7087. case "!":
  7088. date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 );
  7089. year = date.getFullYear();
  7090. month = date.getMonth() + 1;
  7091. day = date.getDate();
  7092. break;
  7093. case "'":
  7094. if ( lookAhead( "'" ) ) {
  7095. checkLiteral();
  7096. } else {
  7097. literal = true;
  7098. }
  7099. break;
  7100. default:
  7101. checkLiteral();
  7102. }
  7103. }
  7104. }
  7105. if ( iValue < value.length ) {
  7106. extra = value.substr( iValue );
  7107. if ( !/^\s+/.test( extra ) ) {
  7108. throw "Extra/unparsed characters found in date: " + extra;
  7109. }
  7110. }
  7111. if ( year === -1 ) {
  7112. year = new Date().getFullYear();
  7113. } else if ( year < 100 ) {
  7114. year += new Date().getFullYear() - new Date().getFullYear() % 100 +
  7115. ( year <= shortYearCutoff ? 0 : -100 );
  7116. }
  7117. if ( doy > -1 ) {
  7118. month = 1;
  7119. day = doy;
  7120. do {
  7121. dim = this._getDaysInMonth( year, month - 1 );
  7122. if ( day <= dim ) {
  7123. break;
  7124. }
  7125. month++;
  7126. day -= dim;
  7127. } while ( true );
  7128. }
  7129. date = this._daylightSavingAdjust( new Date( year, month - 1, day ) );
  7130. if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) {
  7131. throw "Invalid date"; // E.g. 31/02/00
  7132. }
  7133. return date;
  7134. },
  7135. /* Standard date formats. */
  7136. ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
  7137. COOKIE: "D, dd M yy",
  7138. ISO_8601: "yy-mm-dd",
  7139. RFC_822: "D, d M y",
  7140. RFC_850: "DD, dd-M-y",
  7141. RFC_1036: "D, d M y",
  7142. RFC_1123: "D, d M yy",
  7143. RFC_2822: "D, d M yy",
  7144. RSS: "D, d M y", // RFC 822
  7145. TICKS: "!",
  7146. TIMESTAMP: "@",
  7147. W3C: "yy-mm-dd", // ISO 8601
  7148. _ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) +
  7149. Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ),
  7150. /* Format a date object into a string value.
  7151. * The format can be combinations of the following:
  7152. * d - day of month (no leading zero)
  7153. * dd - day of month (two digit)
  7154. * o - day of year (no leading zeros)
  7155. * oo - day of year (three digit)
  7156. * D - day name short
  7157. * DD - day name long
  7158. * m - month of year (no leading zero)
  7159. * mm - month of year (two digit)
  7160. * M - month name short
  7161. * MM - month name long
  7162. * y - year (two digit)
  7163. * yy - year (four digit)
  7164. * @ - Unix timestamp (ms since 01/01/1970)
  7165. * ! - Windows ticks (100ns since 01/01/0001)
  7166. * "..." - literal text
  7167. * '' - single quote
  7168. *
  7169. * @param format string - the desired format of the date
  7170. * @param date Date - the date value to format
  7171. * @param settings Object - attributes include:
  7172. * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
  7173. * dayNames string[7] - names of the days from Sunday (optional)
  7174. * monthNamesShort string[12] - abbreviated names of the months (optional)
  7175. * monthNames string[12] - names of the months (optional)
  7176. * @return string - the date in the above format
  7177. */
  7178. formatDate: function( format, date, settings ) {
  7179. if ( !date ) {
  7180. return "";
  7181. }
  7182. var iFormat,
  7183. dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
  7184. dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
  7185. monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
  7186. monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
  7187. // Check whether a format character is doubled
  7188. lookAhead = function( match ) {
  7189. var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
  7190. if ( matches ) {
  7191. iFormat++;
  7192. }
  7193. return matches;
  7194. },
  7195. // Format a number, with leading zero if necessary
  7196. formatNumber = function( match, value, len ) {
  7197. var num = "" + value;
  7198. if ( lookAhead( match ) ) {
  7199. while ( num.length < len ) {
  7200. num = "0" + num;
  7201. }
  7202. }
  7203. return num;
  7204. },
  7205. // Format a name, short or long as requested
  7206. formatName = function( match, value, shortNames, longNames ) {
  7207. return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] );
  7208. },
  7209. output = "",
  7210. literal = false;
  7211. if ( date ) {
  7212. for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
  7213. if ( literal ) {
  7214. if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
  7215. literal = false;
  7216. } else {
  7217. output += format.charAt( iFormat );
  7218. }
  7219. } else {
  7220. switch ( format.charAt( iFormat ) ) {
  7221. case "d":
  7222. output += formatNumber( "d", date.getDate(), 2 );
  7223. break;
  7224. case "D":
  7225. output += formatName( "D", date.getDay(), dayNamesShort, dayNames );
  7226. break;
  7227. case "o":
  7228. output += formatNumber( "o",
  7229. Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 );
  7230. break;
  7231. case "m":
  7232. output += formatNumber( "m", date.getMonth() + 1, 2 );
  7233. break;
  7234. case "M":
  7235. output += formatName( "M", date.getMonth(), monthNamesShort, monthNames );
  7236. break;
  7237. case "y":
  7238. output += ( lookAhead( "y" ) ? date.getFullYear() :
  7239. ( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 );
  7240. break;
  7241. case "@":
  7242. output += date.getTime();
  7243. break;
  7244. case "!":
  7245. output += date.getTime() * 10000 + this._ticksTo1970;
  7246. break;
  7247. case "'":
  7248. if ( lookAhead( "'" ) ) {
  7249. output += "'";
  7250. } else {
  7251. literal = true;
  7252. }
  7253. break;
  7254. default:
  7255. output += format.charAt( iFormat );
  7256. }
  7257. }
  7258. }
  7259. }
  7260. return output;
  7261. },
  7262. /* Extract all possible characters from the date format. */
  7263. _possibleChars: function( format ) {
  7264. var iFormat,
  7265. chars = "",
  7266. literal = false,
  7267. // Check whether a format character is doubled
  7268. lookAhead = function( match ) {
  7269. var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
  7270. if ( matches ) {
  7271. iFormat++;
  7272. }
  7273. return matches;
  7274. };
  7275. for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
  7276. if ( literal ) {
  7277. if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
  7278. literal = false;
  7279. } else {
  7280. chars += format.charAt( iFormat );
  7281. }
  7282. } else {
  7283. switch ( format.charAt( iFormat ) ) {
  7284. case "d": case "m": case "y": case "@":
  7285. chars += "0123456789";
  7286. break;
  7287. case "D": case "M":
  7288. return null; // Accept anything
  7289. case "'":
  7290. if ( lookAhead( "'" ) ) {
  7291. chars += "'";
  7292. } else {
  7293. literal = true;
  7294. }
  7295. break;
  7296. default:
  7297. chars += format.charAt( iFormat );
  7298. }
  7299. }
  7300. }
  7301. return chars;
  7302. },
  7303. /* Get a setting value, defaulting if necessary. */
  7304. _get: function( inst, name ) {
  7305. return inst.settings[ name ] !== undefined ?
  7306. inst.settings[ name ] : this._defaults[ name ];
  7307. },
  7308. /* Parse existing date and initialise date picker. */
  7309. _setDateFromField: function( inst, noDefault ) {
  7310. if ( inst.input.val() === inst.lastVal ) {
  7311. return;
  7312. }
  7313. var dateFormat = this._get( inst, "dateFormat" ),
  7314. dates = inst.lastVal = inst.input ? inst.input.val() : null,
  7315. defaultDate = this._getDefaultDate( inst ),
  7316. date = defaultDate,
  7317. settings = this._getFormatConfig( inst );
  7318. try {
  7319. date = this.parseDate( dateFormat, dates, settings ) || defaultDate;
  7320. } catch ( event ) {
  7321. dates = ( noDefault ? "" : dates );
  7322. }
  7323. inst.selectedDay = date.getDate();
  7324. inst.drawMonth = inst.selectedMonth = date.getMonth();
  7325. inst.drawYear = inst.selectedYear = date.getFullYear();
  7326. inst.currentDay = ( dates ? date.getDate() : 0 );
  7327. inst.currentMonth = ( dates ? date.getMonth() : 0 );
  7328. inst.currentYear = ( dates ? date.getFullYear() : 0 );
  7329. this._adjustInstDate( inst );
  7330. },
  7331. /* Retrieve the default date shown on opening. */
  7332. _getDefaultDate: function( inst ) {
  7333. return this._restrictMinMax( inst,
  7334. this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) );
  7335. },
  7336. /* A date may be specified as an exact value or a relative one. */
  7337. _determineDate: function( inst, date, defaultDate ) {
  7338. var offsetNumeric = function( offset ) {
  7339. var date = new Date();
  7340. date.setDate( date.getDate() + offset );
  7341. return date;
  7342. },
  7343. offsetString = function( offset ) {
  7344. try {
  7345. return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
  7346. offset, $.datepicker._getFormatConfig( inst ) );
  7347. } catch ( e ) {
  7348. // Ignore
  7349. }
  7350. var date = ( offset.toLowerCase().match( /^c/ ) ?
  7351. $.datepicker._getDate( inst ) : null ) || new Date(),
  7352. year = date.getFullYear(),
  7353. month = date.getMonth(),
  7354. day = date.getDate(),
  7355. pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
  7356. matches = pattern.exec( offset );
  7357. while ( matches ) {
  7358. switch ( matches[ 2 ] || "d" ) {
  7359. case "d" : case "D" :
  7360. day += parseInt( matches[ 1 ], 10 ); break;
  7361. case "w" : case "W" :
  7362. day += parseInt( matches[ 1 ], 10 ) * 7; break;
  7363. case "m" : case "M" :
  7364. month += parseInt( matches[ 1 ], 10 );
  7365. day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
  7366. break;
  7367. case "y": case "Y" :
  7368. year += parseInt( matches[ 1 ], 10 );
  7369. day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
  7370. break;
  7371. }
  7372. matches = pattern.exec( offset );
  7373. }
  7374. return new Date( year, month, day );
  7375. },
  7376. newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) :
  7377. ( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) );
  7378. newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate );
  7379. if ( newDate ) {
  7380. newDate.setHours( 0 );
  7381. newDate.setMinutes( 0 );
  7382. newDate.setSeconds( 0 );
  7383. newDate.setMilliseconds( 0 );
  7384. }
  7385. return this._daylightSavingAdjust( newDate );
  7386. },
  7387. /* Handle switch to/from daylight saving.
  7388. * Hours may be non-zero on daylight saving cut-over:
  7389. * > 12 when midnight changeover, but then cannot generate
  7390. * midnight datetime, so jump to 1AM, otherwise reset.
  7391. * @param date (Date) the date to check
  7392. * @return (Date) the corrected date
  7393. */
  7394. _daylightSavingAdjust: function( date ) {
  7395. if ( !date ) {
  7396. return null;
  7397. }
  7398. date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 );
  7399. return date;
  7400. },
  7401. /* Set the date(s) directly. */
  7402. _setDate: function( inst, date, noChange ) {
  7403. var clear = !date,
  7404. origMonth = inst.selectedMonth,
  7405. origYear = inst.selectedYear,
  7406. newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) );
  7407. inst.selectedDay = inst.currentDay = newDate.getDate();
  7408. inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
  7409. inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
  7410. if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) {
  7411. this._notifyChange( inst );
  7412. }
  7413. this._adjustInstDate( inst );
  7414. if ( inst.input ) {
  7415. inst.input.val( clear ? "" : this._formatDate( inst ) );
  7416. }
  7417. },
  7418. /* Retrieve the date(s) directly. */
  7419. _getDate: function( inst ) {
  7420. var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null :
  7421. this._daylightSavingAdjust( new Date(
  7422. inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
  7423. return startDate;
  7424. },
  7425. /* Attach the onxxx handlers. These are declared statically so
  7426. * they work with static code transformers like Caja.
  7427. */
  7428. _attachHandlers: function( inst ) {
  7429. var stepMonths = this._get( inst, "stepMonths" ),
  7430. id = "#" + inst.id.replace( /\\\\/g, "\\" );
  7431. inst.dpDiv.find( "[data-handler]" ).map( function() {
  7432. var handler = {
  7433. prev: function() {
  7434. $.datepicker._adjustDate( id, -stepMonths, "M" );
  7435. },
  7436. next: function() {
  7437. $.datepicker._adjustDate( id, +stepMonths, "M" );
  7438. },
  7439. hide: function() {
  7440. $.datepicker._hideDatepicker();
  7441. },
  7442. today: function() {
  7443. $.datepicker._gotoToday( id );
  7444. },
  7445. selectDay: function() {
  7446. $.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this );
  7447. return false;
  7448. },
  7449. selectMonth: function() {
  7450. $.datepicker._selectMonthYear( id, this, "M" );
  7451. return false;
  7452. },
  7453. selectYear: function() {
  7454. $.datepicker._selectMonthYear( id, this, "Y" );
  7455. return false;
  7456. }
  7457. };
  7458. $( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] );
  7459. } );
  7460. },
  7461. /* Generate the HTML for the current state of the date picker. */
  7462. _generateHTML: function( inst ) {
  7463. var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
  7464. controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
  7465. monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
  7466. selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
  7467. cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
  7468. printDate, dRow, tbody, daySettings, otherMonth, unselectable,
  7469. tempDate = new Date(),
  7470. today = this._daylightSavingAdjust(
  7471. new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time
  7472. isRTL = this._get( inst, "isRTL" ),
  7473. showButtonPanel = this._get( inst, "showButtonPanel" ),
  7474. hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ),
  7475. navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ),
  7476. numMonths = this._getNumberOfMonths( inst ),
  7477. showCurrentAtPos = this._get( inst, "showCurrentAtPos" ),
  7478. stepMonths = this._get( inst, "stepMonths" ),
  7479. isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ),
  7480. currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) :
  7481. new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ),
  7482. minDate = this._getMinMaxDate( inst, "min" ),
  7483. maxDate = this._getMinMaxDate( inst, "max" ),
  7484. drawMonth = inst.drawMonth - showCurrentAtPos,
  7485. drawYear = inst.drawYear;
  7486. if ( drawMonth < 0 ) {
  7487. drawMonth += 12;
  7488. drawYear--;
  7489. }
  7490. if ( maxDate ) {
  7491. maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(),
  7492. maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) );
  7493. maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw );
  7494. while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) {
  7495. drawMonth--;
  7496. if ( drawMonth < 0 ) {
  7497. drawMonth = 11;
  7498. drawYear--;
  7499. }
  7500. }
  7501. }
  7502. inst.drawMonth = drawMonth;
  7503. inst.drawYear = drawYear;
  7504. prevText = this._get( inst, "prevText" );
  7505. prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText,
  7506. this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ),
  7507. this._getFormatConfig( inst ) ) );
  7508. if ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ) {
  7509. prev = $( "<a>" )
  7510. .attr( {
  7511. "class": "ui-datepicker-prev ui-corner-all",
  7512. "data-handler": "prev",
  7513. "data-event": "click",
  7514. title: prevText
  7515. } )
  7516. .append(
  7517. $( "<span>" )
  7518. .addClass( "ui-icon ui-icon-circle-triangle-" +
  7519. ( isRTL ? "e" : "w" ) )
  7520. .text( prevText )
  7521. )[ 0 ].outerHTML;
  7522. } else if ( hideIfNoPrevNext ) {
  7523. prev = "";
  7524. } else {
  7525. prev = $( "<a>" )
  7526. .attr( {
  7527. "class": "ui-datepicker-prev ui-corner-all ui-state-disabled",
  7528. title: prevText
  7529. } )
  7530. .append(
  7531. $( "<span>" )
  7532. .addClass( "ui-icon ui-icon-circle-triangle-" +
  7533. ( isRTL ? "e" : "w" ) )
  7534. .text( prevText )
  7535. )[ 0 ].outerHTML;
  7536. }
  7537. nextText = this._get( inst, "nextText" );
  7538. nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText,
  7539. this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ),
  7540. this._getFormatConfig( inst ) ) );
  7541. if ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ) {
  7542. next = $( "<a>" )
  7543. .attr( {
  7544. "class": "ui-datepicker-next ui-corner-all",
  7545. "data-handler": "next",
  7546. "data-event": "click",
  7547. title: nextText
  7548. } )
  7549. .append(
  7550. $( "<span>" )
  7551. .addClass( "ui-icon ui-icon-circle-triangle-" +
  7552. ( isRTL ? "w" : "e" ) )
  7553. .text( nextText )
  7554. )[ 0 ].outerHTML;
  7555. } else if ( hideIfNoPrevNext ) {
  7556. next = "";
  7557. } else {
  7558. next = $( "<a>" )
  7559. .attr( {
  7560. "class": "ui-datepicker-next ui-corner-all ui-state-disabled",
  7561. title: nextText
  7562. } )
  7563. .append(
  7564. $( "<span>" )
  7565. .attr( "class", "ui-icon ui-icon-circle-triangle-" +
  7566. ( isRTL ? "w" : "e" ) )
  7567. .text( nextText )
  7568. )[ 0 ].outerHTML;
  7569. }
  7570. currentText = this._get( inst, "currentText" );
  7571. gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today );
  7572. currentText = ( !navigationAsDateFormat ? currentText :
  7573. this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) );
  7574. controls = "";
  7575. if ( !inst.inline ) {
  7576. controls = $( "<button>" )
  7577. .attr( {
  7578. type: "button",
  7579. "class": "ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all",
  7580. "data-handler": "hide",
  7581. "data-event": "click"
  7582. } )
  7583. .text( this._get( inst, "closeText" ) )[ 0 ].outerHTML;
  7584. }
  7585. buttonPanel = "";
  7586. if ( showButtonPanel ) {
  7587. buttonPanel = $( "<div class='ui-datepicker-buttonpane ui-widget-content'>" )
  7588. .append( isRTL ? controls : "" )
  7589. .append( this._isInRange( inst, gotoDate ) ?
  7590. $( "<button>" )
  7591. .attr( {
  7592. type: "button",
  7593. "class": "ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all",
  7594. "data-handler": "today",
  7595. "data-event": "click"
  7596. } )
  7597. .text( currentText ) :
  7598. "" )
  7599. .append( isRTL ? "" : controls )[ 0 ].outerHTML;
  7600. }
  7601. firstDay = parseInt( this._get( inst, "firstDay" ), 10 );
  7602. firstDay = ( isNaN( firstDay ) ? 0 : firstDay );
  7603. showWeek = this._get( inst, "showWeek" );
  7604. dayNames = this._get( inst, "dayNames" );
  7605. dayNamesMin = this._get( inst, "dayNamesMin" );
  7606. monthNames = this._get( inst, "monthNames" );
  7607. monthNamesShort = this._get( inst, "monthNamesShort" );
  7608. beforeShowDay = this._get( inst, "beforeShowDay" );
  7609. showOtherMonths = this._get( inst, "showOtherMonths" );
  7610. selectOtherMonths = this._get( inst, "selectOtherMonths" );
  7611. defaultDate = this._getDefaultDate( inst );
  7612. html = "";
  7613. for ( row = 0; row < numMonths[ 0 ]; row++ ) {
  7614. group = "";
  7615. this.maxRows = 4;
  7616. for ( col = 0; col < numMonths[ 1 ]; col++ ) {
  7617. selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) );
  7618. cornerClass = " ui-corner-all";
  7619. calender = "";
  7620. if ( isMultiMonth ) {
  7621. calender += "<div class='ui-datepicker-group";
  7622. if ( numMonths[ 1 ] > 1 ) {
  7623. switch ( col ) {
  7624. case 0: calender += " ui-datepicker-group-first";
  7625. cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break;
  7626. case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last";
  7627. cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break;
  7628. default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
  7629. }
  7630. }
  7631. calender += "'>";
  7632. }
  7633. calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
  7634. ( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) +
  7635. ( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) +
  7636. this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate,
  7637. row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers
  7638. "</div><table class='ui-datepicker-calendar'><thead>" +
  7639. "<tr>";
  7640. thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" );
  7641. for ( dow = 0; dow < 7; dow++ ) { // days of the week
  7642. day = ( dow + firstDay ) % 7;
  7643. thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" +
  7644. "<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>";
  7645. }
  7646. calender += thead + "</tr></thead><tbody>";
  7647. daysInMonth = this._getDaysInMonth( drawYear, drawMonth );
  7648. if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) {
  7649. inst.selectedDay = Math.min( inst.selectedDay, daysInMonth );
  7650. }
  7651. leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7;
  7652. curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate
  7653. numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043)
  7654. this.maxRows = numRows;
  7655. printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) );
  7656. for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows
  7657. calender += "<tr>";
  7658. tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
  7659. this._get( inst, "calculateWeek" )( printDate ) + "</td>" );
  7660. for ( dow = 0; dow < 7; dow++ ) { // create date picker days
  7661. daySettings = ( beforeShowDay ?
  7662. beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] );
  7663. otherMonth = ( printDate.getMonth() !== drawMonth );
  7664. unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] ||
  7665. ( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate );
  7666. tbody += "<td class='" +
  7667. ( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends
  7668. ( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months
  7669. ( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key
  7670. ( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ?
  7671. // or defaultDate is current printedDate and defaultDate is selectedDate
  7672. " " + this._dayOverClass : "" ) + // highlight selected day
  7673. ( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) + // highlight unselectable days
  7674. ( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates
  7675. ( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day
  7676. ( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different)
  7677. ( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "&#39;" ) + "'" : "" ) + // cell title
  7678. ( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions
  7679. ( otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
  7680. ( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
  7681. ( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) +
  7682. ( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day
  7683. ( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months
  7684. "' href='#' aria-current='" + ( printDate.getTime() === currentDate.getTime() ? "true" : "false" ) + // mark date as selected for screen reader
  7685. "' data-date='" + printDate.getDate() + // store date as data
  7686. "'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date
  7687. printDate.setDate( printDate.getDate() + 1 );
  7688. printDate = this._daylightSavingAdjust( printDate );
  7689. }
  7690. calender += tbody + "</tr>";
  7691. }
  7692. drawMonth++;
  7693. if ( drawMonth > 11 ) {
  7694. drawMonth = 0;
  7695. drawYear++;
  7696. }
  7697. calender += "</tbody></table>" + ( isMultiMonth ? "</div>" +
  7698. ( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" );
  7699. group += calender;
  7700. }
  7701. html += group;
  7702. }
  7703. html += buttonPanel;
  7704. inst._keyEvent = false;
  7705. return html;
  7706. },
  7707. /* Generate the month and year header. */
  7708. _generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate,
  7709. secondary, monthNames, monthNamesShort ) {
  7710. var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
  7711. changeMonth = this._get( inst, "changeMonth" ),
  7712. changeYear = this._get( inst, "changeYear" ),
  7713. showMonthAfterYear = this._get( inst, "showMonthAfterYear" ),
  7714. selectMonthLabel = this._get( inst, "selectMonthLabel" ),
  7715. selectYearLabel = this._get( inst, "selectYearLabel" ),
  7716. html = "<div class='ui-datepicker-title'>",
  7717. monthHtml = "";
  7718. // Month selection
  7719. if ( secondary || !changeMonth ) {
  7720. monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>";
  7721. } else {
  7722. inMinYear = ( minDate && minDate.getFullYear() === drawYear );
  7723. inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear );
  7724. monthHtml += "<select class='ui-datepicker-month' aria-label='" + selectMonthLabel + "' data-handler='selectMonth' data-event='change'>";
  7725. for ( month = 0; month < 12; month++ ) {
  7726. if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) {
  7727. monthHtml += "<option value='" + month + "'" +
  7728. ( month === drawMonth ? " selected='selected'" : "" ) +
  7729. ">" + monthNamesShort[ month ] + "</option>";
  7730. }
  7731. }
  7732. monthHtml += "</select>";
  7733. }
  7734. if ( !showMonthAfterYear ) {
  7735. html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" );
  7736. }
  7737. // Year selection
  7738. if ( !inst.yearshtml ) {
  7739. inst.yearshtml = "";
  7740. if ( secondary || !changeYear ) {
  7741. html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
  7742. } else {
  7743. // determine range of years to display
  7744. years = this._get( inst, "yearRange" ).split( ":" );
  7745. thisYear = new Date().getFullYear();
  7746. determineYear = function( value ) {
  7747. var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) :
  7748. ( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) :
  7749. parseInt( value, 10 ) ) );
  7750. return ( isNaN( year ) ? thisYear : year );
  7751. };
  7752. year = determineYear( years[ 0 ] );
  7753. endYear = Math.max( year, determineYear( years[ 1 ] || "" ) );
  7754. year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year );
  7755. endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear );
  7756. inst.yearshtml += "<select class='ui-datepicker-year' aria-label='" + selectYearLabel + "' data-handler='selectYear' data-event='change'>";
  7757. for ( ; year <= endYear; year++ ) {
  7758. inst.yearshtml += "<option value='" + year + "'" +
  7759. ( year === drawYear ? " selected='selected'" : "" ) +
  7760. ">" + year + "</option>";
  7761. }
  7762. inst.yearshtml += "</select>";
  7763. html += inst.yearshtml;
  7764. inst.yearshtml = null;
  7765. }
  7766. }
  7767. html += this._get( inst, "yearSuffix" );
  7768. if ( showMonthAfterYear ) {
  7769. html += ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" ) + monthHtml;
  7770. }
  7771. html += "</div>"; // Close datepicker_header
  7772. return html;
  7773. },
  7774. /* Adjust one of the date sub-fields. */
  7775. _adjustInstDate: function( inst, offset, period ) {
  7776. var year = inst.selectedYear + ( period === "Y" ? offset : 0 ),
  7777. month = inst.selectedMonth + ( period === "M" ? offset : 0 ),
  7778. day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ),
  7779. date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) );
  7780. inst.selectedDay = date.getDate();
  7781. inst.drawMonth = inst.selectedMonth = date.getMonth();
  7782. inst.drawYear = inst.selectedYear = date.getFullYear();
  7783. if ( period === "M" || period === "Y" ) {
  7784. this._notifyChange( inst );
  7785. }
  7786. },
  7787. /* Ensure a date is within any min/max bounds. */
  7788. _restrictMinMax: function( inst, date ) {
  7789. var minDate = this._getMinMaxDate( inst, "min" ),
  7790. maxDate = this._getMinMaxDate( inst, "max" ),
  7791. newDate = ( minDate && date < minDate ? minDate : date );
  7792. return ( maxDate && newDate > maxDate ? maxDate : newDate );
  7793. },
  7794. /* Notify change of month/year. */
  7795. _notifyChange: function( inst ) {
  7796. var onChange = this._get( inst, "onChangeMonthYear" );
  7797. if ( onChange ) {
  7798. onChange.apply( ( inst.input ? inst.input[ 0 ] : null ),
  7799. [ inst.selectedYear, inst.selectedMonth + 1, inst ] );
  7800. }
  7801. },
  7802. /* Determine the number of months to show. */
  7803. _getNumberOfMonths: function( inst ) {
  7804. var numMonths = this._get( inst, "numberOfMonths" );
  7805. return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) );
  7806. },
  7807. /* Determine the current maximum date - ensure no time components are set. */
  7808. _getMinMaxDate: function( inst, minMax ) {
  7809. return this._determineDate( inst, this._get( inst, minMax + "Date" ), null );
  7810. },
  7811. /* Find the number of days in a given month. */
  7812. _getDaysInMonth: function( year, month ) {
  7813. return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate();
  7814. },
  7815. /* Find the day of the week of the first of a month. */
  7816. _getFirstDayOfMonth: function( year, month ) {
  7817. return new Date( year, month, 1 ).getDay();
  7818. },
  7819. /* Determines if we should allow a "next/prev" month display change. */
  7820. _canAdjustMonth: function( inst, offset, curYear, curMonth ) {
  7821. var numMonths = this._getNumberOfMonths( inst ),
  7822. date = this._daylightSavingAdjust( new Date( curYear,
  7823. curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) );
  7824. if ( offset < 0 ) {
  7825. date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) );
  7826. }
  7827. return this._isInRange( inst, date );
  7828. },
  7829. /* Is the given date in the accepted range? */
  7830. _isInRange: function( inst, date ) {
  7831. var yearSplit, currentYear,
  7832. minDate = this._getMinMaxDate( inst, "min" ),
  7833. maxDate = this._getMinMaxDate( inst, "max" ),
  7834. minYear = null,
  7835. maxYear = null,
  7836. years = this._get( inst, "yearRange" );
  7837. if ( years ) {
  7838. yearSplit = years.split( ":" );
  7839. currentYear = new Date().getFullYear();
  7840. minYear = parseInt( yearSplit[ 0 ], 10 );
  7841. maxYear = parseInt( yearSplit[ 1 ], 10 );
  7842. if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) {
  7843. minYear += currentYear;
  7844. }
  7845. if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) {
  7846. maxYear += currentYear;
  7847. }
  7848. }
  7849. return ( ( !minDate || date.getTime() >= minDate.getTime() ) &&
  7850. ( !maxDate || date.getTime() <= maxDate.getTime() ) &&
  7851. ( !minYear || date.getFullYear() >= minYear ) &&
  7852. ( !maxYear || date.getFullYear() <= maxYear ) );
  7853. },
  7854. /* Provide the configuration settings for formatting/parsing. */
  7855. _getFormatConfig: function( inst ) {
  7856. var shortYearCutoff = this._get( inst, "shortYearCutoff" );
  7857. shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff :
  7858. new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) );
  7859. return { shortYearCutoff: shortYearCutoff,
  7860. dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ),
  7861. monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) };
  7862. },
  7863. /* Format the given date for display. */
  7864. _formatDate: function( inst, day, month, year ) {
  7865. if ( !day ) {
  7866. inst.currentDay = inst.selectedDay;
  7867. inst.currentMonth = inst.selectedMonth;
  7868. inst.currentYear = inst.selectedYear;
  7869. }
  7870. var date = ( day ? ( typeof day === "object" ? day :
  7871. this._daylightSavingAdjust( new Date( year, month, day ) ) ) :
  7872. this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
  7873. return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) );
  7874. }
  7875. } );
  7876. /*
  7877. * Bind hover events for datepicker elements.
  7878. * Done via delegate so the binding only occurs once in the lifetime of the parent div.
  7879. * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
  7880. */
  7881. function datepicker_bindHover( dpDiv ) {
  7882. var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
  7883. return dpDiv.on( "mouseout", selector, function() {
  7884. $( this ).removeClass( "ui-state-hover" );
  7885. if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
  7886. $( this ).removeClass( "ui-datepicker-prev-hover" );
  7887. }
  7888. if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
  7889. $( this ).removeClass( "ui-datepicker-next-hover" );
  7890. }
  7891. } )
  7892. .on( "mouseover", selector, datepicker_handleMouseover );
  7893. }
  7894. function datepicker_handleMouseover() {
  7895. if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) {
  7896. $( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" );
  7897. $( this ).addClass( "ui-state-hover" );
  7898. if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
  7899. $( this ).addClass( "ui-datepicker-prev-hover" );
  7900. }
  7901. if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
  7902. $( this ).addClass( "ui-datepicker-next-hover" );
  7903. }
  7904. }
  7905. }
  7906. /* jQuery extend now ignores nulls! */
  7907. function datepicker_extendRemove( target, props ) {
  7908. $.extend( target, props );
  7909. for ( var name in props ) {
  7910. if ( props[ name ] == null ) {
  7911. target[ name ] = props[ name ];
  7912. }
  7913. }
  7914. return target;
  7915. }
  7916. /* Invoke the datepicker functionality.
  7917. @param options string - a command, optionally followed by additional parameters or
  7918. Object - settings for attaching new datepicker functionality
  7919. @return jQuery object */
  7920. $.fn.datepicker = function( options ) {
  7921. /* Verify an empty collection wasn't passed - Fixes #6976 */
  7922. if ( !this.length ) {
  7923. return this;
  7924. }
  7925. /* Initialise the date picker. */
  7926. if ( !$.datepicker.initialized ) {
  7927. $( document ).on( "mousedown", $.datepicker._checkExternalClick );
  7928. $.datepicker.initialized = true;
  7929. }
  7930. /* Append datepicker main container to body if not exist. */
  7931. if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) {
  7932. $( "body" ).append( $.datepicker.dpDiv );
  7933. }
  7934. var otherArgs = Array.prototype.slice.call( arguments, 1 );
  7935. if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) {
  7936. return $.datepicker[ "_" + options + "Datepicker" ].
  7937. apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
  7938. }
  7939. if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) {
  7940. return $.datepicker[ "_" + options + "Datepicker" ].
  7941. apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
  7942. }
  7943. return this.each( function() {
  7944. if ( typeof options === "string" ) {
  7945. $.datepicker[ "_" + options + "Datepicker" ]
  7946. .apply( $.datepicker, [ this ].concat( otherArgs ) );
  7947. } else {
  7948. $.datepicker._attachDatepicker( this, options );
  7949. }
  7950. } );
  7951. };
  7952. $.datepicker = new Datepicker(); // singleton instance
  7953. $.datepicker.initialized = false;
  7954. $.datepicker.uuid = new Date().getTime();
  7955. $.datepicker.version = "1.14.1";
  7956. var widgetsDatepicker = $.datepicker;
  7957. /*!
  7958. * jQuery UI Mouse 1.14.1
  7959. * https://jqueryui.com
  7960. *
  7961. * Copyright OpenJS Foundation and other contributors
  7962. * Released under the MIT license.
  7963. * https://jquery.org/license
  7964. */
  7965. //>>label: Mouse
  7966. //>>group: Widgets
  7967. //>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
  7968. //>>docs: https://api.jqueryui.com/mouse/
  7969. var mouseHandled = false;
  7970. $( document ).on( "mouseup", function() {
  7971. mouseHandled = false;
  7972. } );
  7973. var widgetsMouse = $.widget( "ui.mouse", {
  7974. version: "1.14.1",
  7975. options: {
  7976. cancel: "input, textarea, button, select, option",
  7977. distance: 1,
  7978. delay: 0
  7979. },
  7980. _mouseInit: function() {
  7981. var that = this;
  7982. this.element
  7983. .on( "mousedown." + this.widgetName, function( event ) {
  7984. return that._mouseDown( event );
  7985. } )
  7986. .on( "click." + this.widgetName, function( event ) {
  7987. if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
  7988. $.removeData( event.target, that.widgetName + ".preventClickEvent" );
  7989. event.stopImmediatePropagation();
  7990. return false;
  7991. }
  7992. } );
  7993. this.started = false;
  7994. },
  7995. // TODO: make sure destroying one instance of mouse doesn't mess with
  7996. // other instances of mouse
  7997. _mouseDestroy: function() {
  7998. this.element.off( "." + this.widgetName );
  7999. if ( this._mouseMoveDelegate ) {
  8000. this.document
  8001. .off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
  8002. .off( "mouseup." + this.widgetName, this._mouseUpDelegate );
  8003. }
  8004. },
  8005. _mouseDown: function( event ) {
  8006. // don't let more than one widget handle mouseStart
  8007. if ( mouseHandled ) {
  8008. return;
  8009. }
  8010. this._mouseMoved = false;
  8011. // We may have missed mouseup (out of window)
  8012. if ( this._mouseStarted ) {
  8013. this._mouseUp( event );
  8014. }
  8015. this._mouseDownEvent = event;
  8016. var that = this,
  8017. btnIsLeft = event.which === 1,
  8018. elIsCancel = typeof this.options.cancel === "string" ?
  8019. $( event.target ).closest( this.options.cancel ).length :
  8020. false;
  8021. if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
  8022. return true;
  8023. }
  8024. this.mouseDelayMet = !this.options.delay;
  8025. if ( !this.mouseDelayMet ) {
  8026. this._mouseDelayTimer = setTimeout( function() {
  8027. that.mouseDelayMet = true;
  8028. }, this.options.delay );
  8029. }
  8030. if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
  8031. this._mouseStarted = ( this._mouseStart( event ) !== false );
  8032. if ( !this._mouseStarted ) {
  8033. event.preventDefault();
  8034. return true;
  8035. }
  8036. }
  8037. // Click event may never have fired (Gecko & Opera)
  8038. if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
  8039. $.removeData( event.target, this.widgetName + ".preventClickEvent" );
  8040. }
  8041. // These delegates are required to keep context
  8042. this._mouseMoveDelegate = function( event ) {
  8043. return that._mouseMove( event );
  8044. };
  8045. this._mouseUpDelegate = function( event ) {
  8046. return that._mouseUp( event );
  8047. };
  8048. this.document
  8049. .on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
  8050. .on( "mouseup." + this.widgetName, this._mouseUpDelegate );
  8051. event.preventDefault();
  8052. mouseHandled = true;
  8053. return true;
  8054. },
  8055. _mouseMove: function( event ) {
  8056. // Only check for mouseups outside the document if you've moved inside the document
  8057. // at least once.
  8058. if ( this._mouseMoved && !event.which ) {
  8059. // Support: Safari <=8 - 9
  8060. // Safari sets which to 0 if you press any of the following keys
  8061. // during a drag (#14461)
  8062. if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
  8063. event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
  8064. this.ignoreMissingWhich = true;
  8065. } else if ( !this.ignoreMissingWhich ) {
  8066. return this._mouseUp( event );
  8067. }
  8068. }
  8069. if ( event.which || event.button ) {
  8070. this._mouseMoved = true;
  8071. }
  8072. if ( this._mouseStarted ) {
  8073. this._mouseDrag( event );
  8074. return event.preventDefault();
  8075. }
  8076. if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
  8077. this._mouseStarted =
  8078. ( this._mouseStart( this._mouseDownEvent, event ) !== false );
  8079. if ( this._mouseStarted ) {
  8080. this._mouseDrag( event );
  8081. } else {
  8082. this._mouseUp( event );
  8083. }
  8084. }
  8085. return !this._mouseStarted;
  8086. },
  8087. _mouseUp: function( event ) {
  8088. this.document
  8089. .off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
  8090. .off( "mouseup." + this.widgetName, this._mouseUpDelegate );
  8091. if ( this._mouseStarted ) {
  8092. this._mouseStarted = false;
  8093. if ( event.target === this._mouseDownEvent.target ) {
  8094. $.data( event.target, this.widgetName + ".preventClickEvent", true );
  8095. }
  8096. this._mouseStop( event );
  8097. }
  8098. if ( this._mouseDelayTimer ) {
  8099. clearTimeout( this._mouseDelayTimer );
  8100. delete this._mouseDelayTimer;
  8101. }
  8102. this.ignoreMissingWhich = false;
  8103. mouseHandled = false;
  8104. event.preventDefault();
  8105. },
  8106. _mouseDistanceMet: function( event ) {
  8107. return ( Math.max(
  8108. Math.abs( this._mouseDownEvent.pageX - event.pageX ),
  8109. Math.abs( this._mouseDownEvent.pageY - event.pageY )
  8110. ) >= this.options.distance
  8111. );
  8112. },
  8113. _mouseDelayMet: function( /* event */ ) {
  8114. return this.mouseDelayMet;
  8115. },
  8116. // These are placeholder methods, to be overriden by extending plugin
  8117. _mouseStart: function( /* event */ ) {},
  8118. _mouseDrag: function( /* event */ ) {},
  8119. _mouseStop: function( /* event */ ) {},
  8120. _mouseCapture: function( /* event */ ) {
  8121. return true;
  8122. }
  8123. } );
  8124. // $.ui.plugin is deprecated. Use $.widget() extensions instead.
  8125. var plugin = $.ui.plugin = {
  8126. add: function( module, option, set ) {
  8127. var i,
  8128. proto = $.ui[ module ].prototype;
  8129. for ( i in set ) {
  8130. proto.plugins[ i ] = proto.plugins[ i ] || [];
  8131. proto.plugins[ i ].push( [ option, set[ i ] ] );
  8132. }
  8133. },
  8134. call: function( instance, name, args, allowDisconnected ) {
  8135. var i,
  8136. set = instance.plugins[ name ];
  8137. if ( !set ) {
  8138. return;
  8139. }
  8140. if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
  8141. instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
  8142. return;
  8143. }
  8144. for ( i = 0; i < set.length; i++ ) {
  8145. if ( instance.options[ set[ i ][ 0 ] ] ) {
  8146. set[ i ][ 1 ].apply( instance.element, args );
  8147. }
  8148. }
  8149. }
  8150. };
  8151. /*!
  8152. * jQuery UI Draggable 1.14.1
  8153. * https://jqueryui.com
  8154. *
  8155. * Copyright OpenJS Foundation and other contributors
  8156. * Released under the MIT license.
  8157. * https://jquery.org/license
  8158. */
  8159. //>>label: Draggable
  8160. //>>group: Interactions
  8161. //>>description: Enables dragging functionality for any element.
  8162. //>>docs: https://api.jqueryui.com/draggable/
  8163. //>>demos: https://jqueryui.com/draggable/
  8164. //>>css.structure: ../../themes/base/draggable.css
  8165. $.widget( "ui.draggable", $.ui.mouse, {
  8166. version: "1.14.1",
  8167. widgetEventPrefix: "drag",
  8168. options: {
  8169. addClasses: true,
  8170. appendTo: "parent",
  8171. axis: false,
  8172. connectToSortable: false,
  8173. containment: false,
  8174. cursor: "auto",
  8175. cursorAt: false,
  8176. grid: false,
  8177. handle: false,
  8178. helper: "original",
  8179. iframeFix: false,
  8180. opacity: false,
  8181. refreshPositions: false,
  8182. revert: false,
  8183. revertDuration: 500,
  8184. scope: "default",
  8185. scroll: true,
  8186. scrollSensitivity: 20,
  8187. scrollSpeed: 20,
  8188. snap: false,
  8189. snapMode: "both",
  8190. snapTolerance: 20,
  8191. stack: false,
  8192. zIndex: false,
  8193. // Callbacks
  8194. drag: null,
  8195. start: null,
  8196. stop: null
  8197. },
  8198. _create: function() {
  8199. if ( this.options.helper === "original" ) {
  8200. this._setPositionRelative();
  8201. }
  8202. if ( this.options.addClasses ) {
  8203. this._addClass( "ui-draggable" );
  8204. }
  8205. this._setHandleClassName();
  8206. this._mouseInit();
  8207. },
  8208. _setOption: function( key, value ) {
  8209. this._super( key, value );
  8210. if ( key === "handle" ) {
  8211. this._removeHandleClassName();
  8212. this._setHandleClassName();
  8213. }
  8214. },
  8215. _destroy: function() {
  8216. if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
  8217. this.destroyOnClear = true;
  8218. return;
  8219. }
  8220. this._removeHandleClassName();
  8221. this._mouseDestroy();
  8222. },
  8223. _mouseCapture: function( event ) {
  8224. var o = this.options;
  8225. // Among others, prevent a drag on a resizable-handle
  8226. if ( this.helper || o.disabled ||
  8227. $( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
  8228. return false;
  8229. }
  8230. //Quit if we're not on a valid handle
  8231. this.handle = this._getHandle( event );
  8232. if ( !this.handle ) {
  8233. return false;
  8234. }
  8235. this._blurActiveElement( event );
  8236. this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
  8237. return true;
  8238. },
  8239. _blockFrames: function( selector ) {
  8240. this.iframeBlocks = this.document.find( selector ).map( function() {
  8241. var iframe = $( this );
  8242. return $( "<div>" )
  8243. .css( "position", "absolute" )
  8244. .appendTo( iframe.parent() )
  8245. .outerWidth( iframe.outerWidth() )
  8246. .outerHeight( iframe.outerHeight() )
  8247. .offset( iframe.offset() )[ 0 ];
  8248. } );
  8249. },
  8250. _unblockFrames: function() {
  8251. if ( this.iframeBlocks ) {
  8252. this.iframeBlocks.remove();
  8253. delete this.iframeBlocks;
  8254. }
  8255. },
  8256. _blurActiveElement: function( event ) {
  8257. var activeElement = this.document[ 0 ].activeElement,
  8258. target = $( event.target );
  8259. // Don't blur if the event occurred on an element that is within
  8260. // the currently focused element
  8261. // See #10527, #12472
  8262. if ( target.closest( activeElement ).length ) {
  8263. return;
  8264. }
  8265. // Blur any element that currently has focus, see #4261
  8266. $( activeElement ).trigger( "blur" );
  8267. },
  8268. _mouseStart: function( event ) {
  8269. var o = this.options;
  8270. //Create and append the visible helper
  8271. this.helper = this._createHelper( event );
  8272. this._addClass( this.helper, "ui-draggable-dragging" );
  8273. //Cache the helper size
  8274. this._cacheHelperProportions();
  8275. //If ddmanager is used for droppables, set the global draggable
  8276. if ( $.ui.ddmanager ) {
  8277. $.ui.ddmanager.current = this;
  8278. }
  8279. /*
  8280. * - Position generation -
  8281. * This block generates everything position related - it's the core of draggables.
  8282. */
  8283. //Cache the margins of the original element
  8284. this._cacheMargins();
  8285. //Store the helper's css position
  8286. this.cssPosition = this.helper.css( "position" );
  8287. this.scrollParent = this.helper.scrollParent( true );
  8288. this.offsetParent = this.helper.offsetParent();
  8289. this.hasFixedAncestor = this.helper.parents().filter( function() {
  8290. return $( this ).css( "position" ) === "fixed";
  8291. } ).length > 0;
  8292. //The element's absolute position on the page minus margins
  8293. this.positionAbs = this.element.offset();
  8294. this._refreshOffsets( event );
  8295. //Generate the original position
  8296. this.originalPosition = this.position = this._generatePosition( event, false );
  8297. this.originalPageX = event.pageX;
  8298. this.originalPageY = event.pageY;
  8299. //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
  8300. if ( o.cursorAt ) {
  8301. this._adjustOffsetFromHelper( o.cursorAt );
  8302. }
  8303. //Set a containment if given in the options
  8304. this._setContainment();
  8305. //Trigger event + callbacks
  8306. if ( this._trigger( "start", event ) === false ) {
  8307. this._clear();
  8308. return false;
  8309. }
  8310. //Recache the helper size
  8311. this._cacheHelperProportions();
  8312. //Prepare the droppable offsets
  8313. if ( $.ui.ddmanager && !o.dropBehaviour ) {
  8314. $.ui.ddmanager.prepareOffsets( this, event );
  8315. }
  8316. // Execute the drag once - this causes the helper not to be visible before getting its
  8317. // correct position
  8318. this._mouseDrag( event, true );
  8319. // If the ddmanager is used for droppables, inform the manager that dragging has started
  8320. // (see #5003)
  8321. if ( $.ui.ddmanager ) {
  8322. $.ui.ddmanager.dragStart( this, event );
  8323. }
  8324. return true;
  8325. },
  8326. _refreshOffsets: function( event ) {
  8327. this.offset = {
  8328. top: this.positionAbs.top - this.margins.top,
  8329. left: this.positionAbs.left - this.margins.left,
  8330. scroll: false,
  8331. parent: this._getParentOffset(),
  8332. relative: this._getRelativeOffset()
  8333. };
  8334. this.offset.click = {
  8335. left: event.pageX - this.offset.left,
  8336. top: event.pageY - this.offset.top
  8337. };
  8338. },
  8339. _mouseDrag: function( event, noPropagation ) {
  8340. // reset any necessary cached properties (see #5009)
  8341. if ( this.hasFixedAncestor ) {
  8342. this.offset.parent = this._getParentOffset();
  8343. }
  8344. //Compute the helpers position
  8345. this.position = this._generatePosition( event, true );
  8346. this.positionAbs = this._convertPositionTo( "absolute" );
  8347. //Call plugins and callbacks and use the resulting position if something is returned
  8348. if ( !noPropagation ) {
  8349. var ui = this._uiHash();
  8350. if ( this._trigger( "drag", event, ui ) === false ) {
  8351. this._mouseUp( new $.Event( "mouseup", event ) );
  8352. return false;
  8353. }
  8354. this.position = ui.position;
  8355. }
  8356. this.helper[ 0 ].style.left = this.position.left + "px";
  8357. this.helper[ 0 ].style.top = this.position.top + "px";
  8358. if ( $.ui.ddmanager ) {
  8359. $.ui.ddmanager.drag( this, event );
  8360. }
  8361. return false;
  8362. },
  8363. _mouseStop: function( event ) {
  8364. //If we are using droppables, inform the manager about the drop
  8365. var that = this,
  8366. dropped = false;
  8367. if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
  8368. dropped = $.ui.ddmanager.drop( this, event );
  8369. }
  8370. //if a drop comes from outside (a sortable)
  8371. if ( this.dropped ) {
  8372. dropped = this.dropped;
  8373. this.dropped = false;
  8374. }
  8375. if ( ( this.options.revert === "invalid" && !dropped ) ||
  8376. ( this.options.revert === "valid" && dropped ) ||
  8377. this.options.revert === true || ( typeof this.options.revert === "function" &&
  8378. this.options.revert.call( this.element, dropped ) )
  8379. ) {
  8380. $( this.helper ).animate(
  8381. this.originalPosition,
  8382. parseInt( this.options.revertDuration, 10 ),
  8383. function() {
  8384. if ( that._trigger( "stop", event ) !== false ) {
  8385. that._clear();
  8386. }
  8387. }
  8388. );
  8389. } else {
  8390. if ( this._trigger( "stop", event ) !== false ) {
  8391. this._clear();
  8392. }
  8393. }
  8394. return false;
  8395. },
  8396. _mouseUp: function( event ) {
  8397. this._unblockFrames();
  8398. // If the ddmanager is used for droppables, inform the manager that dragging has stopped
  8399. // (see #5003)
  8400. if ( $.ui.ddmanager ) {
  8401. $.ui.ddmanager.dragStop( this, event );
  8402. }
  8403. // Only need to focus if the event occurred on the draggable itself, see #10527
  8404. if ( this.handleElement.is( event.target ) ) {
  8405. // The interaction is over; whether or not the click resulted in a drag,
  8406. // focus the element
  8407. this.element.trigger( "focus" );
  8408. }
  8409. return $.ui.mouse.prototype._mouseUp.call( this, event );
  8410. },
  8411. cancel: function() {
  8412. if ( this.helper.is( ".ui-draggable-dragging" ) ) {
  8413. this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
  8414. } else {
  8415. this._clear();
  8416. }
  8417. return this;
  8418. },
  8419. _getHandle: function( event ) {
  8420. return this.options.handle ?
  8421. !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
  8422. true;
  8423. },
  8424. _setHandleClassName: function() {
  8425. this.handleElement = this.options.handle ?
  8426. this.element.find( this.options.handle ) : this.element;
  8427. this._addClass( this.handleElement, "ui-draggable-handle" );
  8428. },
  8429. _removeHandleClassName: function() {
  8430. this._removeClass( this.handleElement, "ui-draggable-handle" );
  8431. },
  8432. _createHelper: function( event ) {
  8433. var o = this.options,
  8434. helperIsFunction = typeof o.helper === "function",
  8435. helper = helperIsFunction ?
  8436. $( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
  8437. ( o.helper === "clone" ?
  8438. this.element.clone().removeAttr( "id" ) :
  8439. this.element );
  8440. if ( !helper.parents( "body" ).length ) {
  8441. helper.appendTo( ( o.appendTo === "parent" ?
  8442. this.element[ 0 ].parentNode :
  8443. o.appendTo ) );
  8444. }
  8445. // https://bugs.jqueryui.com/ticket/9446
  8446. // a helper function can return the original element
  8447. // which wouldn't have been set to relative in _create
  8448. if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
  8449. this._setPositionRelative();
  8450. }
  8451. if ( helper[ 0 ] !== this.element[ 0 ] &&
  8452. !( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
  8453. helper.css( "position", "absolute" );
  8454. }
  8455. return helper;
  8456. },
  8457. _setPositionRelative: function() {
  8458. if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
  8459. this.element[ 0 ].style.position = "relative";
  8460. }
  8461. },
  8462. _adjustOffsetFromHelper: function( obj ) {
  8463. if ( typeof obj === "string" ) {
  8464. obj = obj.split( " " );
  8465. }
  8466. if ( Array.isArray( obj ) ) {
  8467. obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
  8468. }
  8469. if ( "left" in obj ) {
  8470. this.offset.click.left = obj.left + this.margins.left;
  8471. }
  8472. if ( "right" in obj ) {
  8473. this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
  8474. }
  8475. if ( "top" in obj ) {
  8476. this.offset.click.top = obj.top + this.margins.top;
  8477. }
  8478. if ( "bottom" in obj ) {
  8479. this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
  8480. }
  8481. },
  8482. _isRootNode: function( element ) {
  8483. return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
  8484. },
  8485. _getParentOffset: function() {
  8486. //Get the offsetParent and cache its position
  8487. var po = this.offsetParent.offset(),
  8488. document = this.document[ 0 ];
  8489. // This is a special case where we need to modify a offset calculated on start, since the
  8490. // following happened:
  8491. // 1. The position of the helper is absolute, so it's position is calculated based on the
  8492. // next positioned parent
  8493. // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
  8494. // the document, which means that the scroll is included in the initial calculation of the
  8495. // offset of the parent, and never recalculated upon drag
  8496. if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
  8497. $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
  8498. po.left += this.scrollParent.scrollLeft();
  8499. po.top += this.scrollParent.scrollTop();
  8500. }
  8501. if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
  8502. po = { top: 0, left: 0 };
  8503. }
  8504. return {
  8505. top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
  8506. left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
  8507. };
  8508. },
  8509. _getRelativeOffset: function() {
  8510. if ( this.cssPosition !== "relative" ) {
  8511. return { top: 0, left: 0 };
  8512. }
  8513. var p = this.element.position(),
  8514. scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
  8515. return {
  8516. top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
  8517. ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
  8518. left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
  8519. ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
  8520. };
  8521. },
  8522. _cacheMargins: function() {
  8523. this.margins = {
  8524. left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
  8525. top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
  8526. right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
  8527. bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
  8528. };
  8529. },
  8530. _cacheHelperProportions: function() {
  8531. this.helperProportions = {
  8532. width: this.helper.outerWidth(),
  8533. height: this.helper.outerHeight()
  8534. };
  8535. },
  8536. _setContainment: function() {
  8537. var isUserScrollable, c, ce,
  8538. o = this.options,
  8539. document = this.document[ 0 ];
  8540. this.relativeContainer = null;
  8541. if ( !o.containment ) {
  8542. this.containment = null;
  8543. return;
  8544. }
  8545. if ( o.containment === "window" ) {
  8546. this.containment = [
  8547. $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
  8548. $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
  8549. $( window ).scrollLeft() + $( window ).width() -
  8550. this.helperProportions.width - this.margins.left,
  8551. $( window ).scrollTop() +
  8552. ( $( window ).height() || document.body.parentNode.scrollHeight ) -
  8553. this.helperProportions.height - this.margins.top
  8554. ];
  8555. return;
  8556. }
  8557. if ( o.containment === "document" ) {
  8558. this.containment = [
  8559. 0,
  8560. 0,
  8561. $( document ).width() - this.helperProportions.width - this.margins.left,
  8562. ( $( document ).height() || document.body.parentNode.scrollHeight ) -
  8563. this.helperProportions.height - this.margins.top
  8564. ];
  8565. return;
  8566. }
  8567. if ( o.containment.constructor === Array ) {
  8568. this.containment = o.containment;
  8569. return;
  8570. }
  8571. if ( o.containment === "parent" ) {
  8572. o.containment = this.helper[ 0 ].parentNode;
  8573. }
  8574. c = $( o.containment );
  8575. ce = c[ 0 ];
  8576. if ( !ce ) {
  8577. return;
  8578. }
  8579. isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
  8580. this.containment = [
  8581. ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
  8582. ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
  8583. ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
  8584. ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
  8585. ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
  8586. ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
  8587. ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
  8588. this.helperProportions.width -
  8589. this.margins.left -
  8590. this.margins.right,
  8591. ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
  8592. ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
  8593. ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
  8594. this.helperProportions.height -
  8595. this.margins.top -
  8596. this.margins.bottom
  8597. ];
  8598. this.relativeContainer = c;
  8599. },
  8600. _convertPositionTo: function( d, pos ) {
  8601. if ( !pos ) {
  8602. pos = this.position;
  8603. }
  8604. var mod = d === "absolute" ? 1 : -1,
  8605. scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
  8606. return {
  8607. top: (
  8608. // The absolute mouse position
  8609. pos.top +
  8610. // Only for relative positioned nodes: Relative offset from element to offset parent
  8611. this.offset.relative.top * mod +
  8612. // The offsetParent's offset without borders (offset + border)
  8613. this.offset.parent.top * mod -
  8614. ( ( this.cssPosition === "fixed" ?
  8615. -this.offset.scroll.top :
  8616. ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
  8617. ),
  8618. left: (
  8619. // The absolute mouse position
  8620. pos.left +
  8621. // Only for relative positioned nodes: Relative offset from element to offset parent
  8622. this.offset.relative.left * mod +
  8623. // The offsetParent's offset without borders (offset + border)
  8624. this.offset.parent.left * mod -
  8625. ( ( this.cssPosition === "fixed" ?
  8626. -this.offset.scroll.left :
  8627. ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
  8628. )
  8629. };
  8630. },
  8631. _generatePosition: function( event, constrainPosition ) {
  8632. var containment, co, top, left,
  8633. o = this.options,
  8634. scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
  8635. pageX = event.pageX,
  8636. pageY = event.pageY;
  8637. // Cache the scroll
  8638. if ( !scrollIsRootNode || !this.offset.scroll ) {
  8639. this.offset.scroll = {
  8640. top: this.scrollParent.scrollTop(),
  8641. left: this.scrollParent.scrollLeft()
  8642. };
  8643. }
  8644. /*
  8645. * - Position constraining -
  8646. * Constrain the position to a mix of grid, containment.
  8647. */
  8648. // If we are not dragging yet, we won't check for options
  8649. if ( constrainPosition ) {
  8650. if ( this.containment ) {
  8651. if ( this.relativeContainer ) {
  8652. co = this.relativeContainer.offset();
  8653. containment = [
  8654. this.containment[ 0 ] + co.left,
  8655. this.containment[ 1 ] + co.top,
  8656. this.containment[ 2 ] + co.left,
  8657. this.containment[ 3 ] + co.top
  8658. ];
  8659. } else {
  8660. containment = this.containment;
  8661. }
  8662. if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
  8663. pageX = containment[ 0 ] + this.offset.click.left;
  8664. }
  8665. if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
  8666. pageY = containment[ 1 ] + this.offset.click.top;
  8667. }
  8668. if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
  8669. pageX = containment[ 2 ] + this.offset.click.left;
  8670. }
  8671. if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
  8672. pageY = containment[ 3 ] + this.offset.click.top;
  8673. }
  8674. }
  8675. if ( o.grid ) {
  8676. //Check for grid elements set to 0 to prevent divide by 0 error causing invalid
  8677. // argument errors in IE (see ticket #6950)
  8678. top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
  8679. this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
  8680. pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
  8681. top - this.offset.click.top > containment[ 3 ] ) ?
  8682. top :
  8683. ( ( top - this.offset.click.top >= containment[ 1 ] ) ?
  8684. top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
  8685. left = o.grid[ 0 ] ? this.originalPageX +
  8686. Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
  8687. this.originalPageX;
  8688. pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
  8689. left - this.offset.click.left > containment[ 2 ] ) ?
  8690. left :
  8691. ( ( left - this.offset.click.left >= containment[ 0 ] ) ?
  8692. left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
  8693. }
  8694. if ( o.axis === "y" ) {
  8695. pageX = this.originalPageX;
  8696. }
  8697. if ( o.axis === "x" ) {
  8698. pageY = this.originalPageY;
  8699. }
  8700. }
  8701. return {
  8702. top: (
  8703. // The absolute mouse position
  8704. pageY -
  8705. // Click offset (relative to the element)
  8706. this.offset.click.top -
  8707. // Only for relative positioned nodes: Relative offset from element to offset parent
  8708. this.offset.relative.top -
  8709. // The offsetParent's offset without borders (offset + border)
  8710. this.offset.parent.top +
  8711. ( this.cssPosition === "fixed" ?
  8712. -this.offset.scroll.top :
  8713. ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
  8714. ),
  8715. left: (
  8716. // The absolute mouse position
  8717. pageX -
  8718. // Click offset (relative to the element)
  8719. this.offset.click.left -
  8720. // Only for relative positioned nodes: Relative offset from element to offset parent
  8721. this.offset.relative.left -
  8722. // The offsetParent's offset without borders (offset + border)
  8723. this.offset.parent.left +
  8724. ( this.cssPosition === "fixed" ?
  8725. -this.offset.scroll.left :
  8726. ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
  8727. )
  8728. };
  8729. },
  8730. _clear: function() {
  8731. this._removeClass( this.helper, "ui-draggable-dragging" );
  8732. if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
  8733. this.helper.remove();
  8734. }
  8735. this.helper = null;
  8736. this.cancelHelperRemoval = false;
  8737. if ( this.destroyOnClear ) {
  8738. this.destroy();
  8739. }
  8740. },
  8741. // From now on bulk stuff - mainly helpers
  8742. _trigger: function( type, event, ui ) {
  8743. ui = ui || this._uiHash();
  8744. $.ui.plugin.call( this, type, [ event, ui, this ], true );
  8745. // Absolute position and offset (see #6884 ) have to be recalculated after plugins
  8746. if ( /^(drag|start|stop)/.test( type ) ) {
  8747. this.positionAbs = this._convertPositionTo( "absolute" );
  8748. ui.offset = this.positionAbs;
  8749. }
  8750. return $.Widget.prototype._trigger.call( this, type, event, ui );
  8751. },
  8752. plugins: {},
  8753. _uiHash: function() {
  8754. return {
  8755. helper: this.helper,
  8756. position: this.position,
  8757. originalPosition: this.originalPosition,
  8758. offset: this.positionAbs
  8759. };
  8760. }
  8761. } );
  8762. $.ui.plugin.add( "draggable", "connectToSortable", {
  8763. start: function( event, ui, draggable ) {
  8764. var uiSortable = $.extend( {}, ui, {
  8765. item: draggable.element
  8766. } );
  8767. draggable.sortables = [];
  8768. $( draggable.options.connectToSortable ).each( function() {
  8769. var sortable = $( this ).sortable( "instance" );
  8770. if ( sortable && !sortable.options.disabled ) {
  8771. draggable.sortables.push( sortable );
  8772. // RefreshPositions is called at drag start to refresh the containerCache
  8773. // which is used in drag. This ensures it's initialized and synchronized
  8774. // with any changes that might have happened on the page since initialization.
  8775. sortable.refreshPositions();
  8776. sortable._trigger( "activate", event, uiSortable );
  8777. }
  8778. } );
  8779. },
  8780. stop: function( event, ui, draggable ) {
  8781. var uiSortable = $.extend( {}, ui, {
  8782. item: draggable.element
  8783. } );
  8784. draggable.cancelHelperRemoval = false;
  8785. $.each( draggable.sortables, function() {
  8786. var sortable = this;
  8787. if ( sortable.isOver ) {
  8788. sortable.isOver = 0;
  8789. // Allow this sortable to handle removing the helper
  8790. draggable.cancelHelperRemoval = true;
  8791. sortable.cancelHelperRemoval = false;
  8792. // Use _storedCSS To restore properties in the sortable,
  8793. // as this also handles revert (#9675) since the draggable
  8794. // may have modified them in unexpected ways (#8809)
  8795. sortable._storedCSS = {
  8796. position: sortable.placeholder.css( "position" ),
  8797. top: sortable.placeholder.css( "top" ),
  8798. left: sortable.placeholder.css( "left" )
  8799. };
  8800. sortable._mouseStop( event );
  8801. // Once drag has ended, the sortable should return to using
  8802. // its original helper, not the shared helper from draggable
  8803. sortable.options.helper = sortable.options._helper;
  8804. } else {
  8805. // Prevent this Sortable from removing the helper.
  8806. // However, don't set the draggable to remove the helper
  8807. // either as another connected Sortable may yet handle the removal.
  8808. sortable.cancelHelperRemoval = true;
  8809. sortable._trigger( "deactivate", event, uiSortable );
  8810. }
  8811. } );
  8812. },
  8813. drag: function( event, ui, draggable ) {
  8814. $.each( draggable.sortables, function() {
  8815. var innermostIntersecting = false,
  8816. sortable = this;
  8817. // Copy over variables that sortable's _intersectsWith uses
  8818. sortable.positionAbs = draggable.positionAbs;
  8819. sortable.helperProportions = draggable.helperProportions;
  8820. sortable.offset.click = draggable.offset.click;
  8821. if ( sortable._intersectsWith( sortable.containerCache ) ) {
  8822. innermostIntersecting = true;
  8823. $.each( draggable.sortables, function() {
  8824. // Copy over variables that sortable's _intersectsWith uses
  8825. this.positionAbs = draggable.positionAbs;
  8826. this.helperProportions = draggable.helperProportions;
  8827. this.offset.click = draggable.offset.click;
  8828. if ( this !== sortable &&
  8829. this._intersectsWith( this.containerCache ) &&
  8830. $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
  8831. innermostIntersecting = false;
  8832. }
  8833. return innermostIntersecting;
  8834. } );
  8835. }
  8836. if ( innermostIntersecting ) {
  8837. // If it intersects, we use a little isOver variable and set it once,
  8838. // so that the move-in stuff gets fired only once.
  8839. if ( !sortable.isOver ) {
  8840. sortable.isOver = 1;
  8841. // Store draggable's parent in case we need to reappend to it later.
  8842. draggable._parent = ui.helper.parent();
  8843. sortable.currentItem = ui.helper
  8844. .appendTo( sortable.element )
  8845. .data( "ui-sortable-item", true );
  8846. // Store helper option to later restore it
  8847. sortable.options._helper = sortable.options.helper;
  8848. sortable.options.helper = function() {
  8849. return ui.helper[ 0 ];
  8850. };
  8851. // Fire the start events of the sortable with our passed browser event,
  8852. // and our own helper (so it doesn't create a new one)
  8853. event.target = sortable.currentItem[ 0 ];
  8854. sortable._mouseCapture( event, true );
  8855. sortable._mouseStart( event, true, true );
  8856. // Because the browser event is way off the new appended portlet,
  8857. // modify necessary variables to reflect the changes
  8858. sortable.offset.click.top = draggable.offset.click.top;
  8859. sortable.offset.click.left = draggable.offset.click.left;
  8860. sortable.offset.parent.left -= draggable.offset.parent.left -
  8861. sortable.offset.parent.left;
  8862. sortable.offset.parent.top -= draggable.offset.parent.top -
  8863. sortable.offset.parent.top;
  8864. draggable._trigger( "toSortable", event );
  8865. // Inform draggable that the helper is in a valid drop zone,
  8866. // used solely in the revert option to handle "valid/invalid".
  8867. draggable.dropped = sortable.element;
  8868. // Need to refreshPositions of all sortables in the case that
  8869. // adding to one sortable changes the location of the other sortables (#9675)
  8870. $.each( draggable.sortables, function() {
  8871. this.refreshPositions();
  8872. } );
  8873. // Hack so receive/update callbacks work (mostly)
  8874. draggable.currentItem = draggable.element;
  8875. sortable.fromOutside = draggable;
  8876. }
  8877. if ( sortable.currentItem ) {
  8878. sortable._mouseDrag( event );
  8879. // Copy the sortable's position because the draggable's can potentially reflect
  8880. // a relative position, while sortable is always absolute, which the dragged
  8881. // element has now become. (#8809)
  8882. ui.position = sortable.position;
  8883. }
  8884. } else {
  8885. // If it doesn't intersect with the sortable, and it intersected before,
  8886. // we fake the drag stop of the sortable, but make sure it doesn't remove
  8887. // the helper by using cancelHelperRemoval.
  8888. if ( sortable.isOver ) {
  8889. sortable.isOver = 0;
  8890. sortable.cancelHelperRemoval = true;
  8891. // Calling sortable's mouseStop would trigger a revert,
  8892. // so revert must be temporarily false until after mouseStop is called.
  8893. sortable.options._revert = sortable.options.revert;
  8894. sortable.options.revert = false;
  8895. sortable._trigger( "out", event, sortable._uiHash( sortable ) );
  8896. sortable._mouseStop( event, true );
  8897. // Restore sortable behaviors that were modfied
  8898. // when the draggable entered the sortable area (#9481)
  8899. sortable.options.revert = sortable.options._revert;
  8900. sortable.options.helper = sortable.options._helper;
  8901. if ( sortable.placeholder ) {
  8902. sortable.placeholder.remove();
  8903. }
  8904. // Restore and recalculate the draggable's offset considering the sortable
  8905. // may have modified them in unexpected ways. (#8809, #10669)
  8906. ui.helper.appendTo( draggable._parent );
  8907. draggable._refreshOffsets( event );
  8908. ui.position = draggable._generatePosition( event, true );
  8909. draggable._trigger( "fromSortable", event );
  8910. // Inform draggable that the helper is no longer in a valid drop zone
  8911. draggable.dropped = false;
  8912. // Need to refreshPositions of all sortables just in case removing
  8913. // from one sortable changes the location of other sortables (#9675)
  8914. $.each( draggable.sortables, function() {
  8915. this.refreshPositions();
  8916. } );
  8917. }
  8918. }
  8919. } );
  8920. }
  8921. } );
  8922. $.ui.plugin.add( "draggable", "cursor", {
  8923. start: function( event, ui, instance ) {
  8924. var t = $( "body" ),
  8925. o = instance.options;
  8926. if ( t.css( "cursor" ) ) {
  8927. o._cursor = t.css( "cursor" );
  8928. }
  8929. t.css( "cursor", o.cursor );
  8930. },
  8931. stop: function( event, ui, instance ) {
  8932. var o = instance.options;
  8933. if ( o._cursor ) {
  8934. $( "body" ).css( "cursor", o._cursor );
  8935. }
  8936. }
  8937. } );
  8938. $.ui.plugin.add( "draggable", "opacity", {
  8939. start: function( event, ui, instance ) {
  8940. var t = $( ui.helper ),
  8941. o = instance.options;
  8942. if ( t.css( "opacity" ) ) {
  8943. o._opacity = t.css( "opacity" );
  8944. }
  8945. t.css( "opacity", o.opacity );
  8946. },
  8947. stop: function( event, ui, instance ) {
  8948. var o = instance.options;
  8949. if ( o._opacity ) {
  8950. $( ui.helper ).css( "opacity", o._opacity );
  8951. }
  8952. }
  8953. } );
  8954. $.ui.plugin.add( "draggable", "scroll", {
  8955. start: function( event, ui, i ) {
  8956. if ( !i.scrollParentNotHidden ) {
  8957. i.scrollParentNotHidden = i.helper.scrollParent( false );
  8958. }
  8959. if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
  8960. i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
  8961. i.overflowOffset = i.scrollParentNotHidden.offset();
  8962. }
  8963. },
  8964. drag: function( event, ui, i ) {
  8965. var o = i.options,
  8966. scrolled = false,
  8967. scrollParent = i.scrollParentNotHidden[ 0 ],
  8968. document = i.document[ 0 ];
  8969. if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
  8970. if ( !o.axis || o.axis !== "x" ) {
  8971. if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
  8972. o.scrollSensitivity ) {
  8973. scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
  8974. } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
  8975. scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
  8976. }
  8977. }
  8978. if ( !o.axis || o.axis !== "y" ) {
  8979. if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
  8980. o.scrollSensitivity ) {
  8981. scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
  8982. } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
  8983. scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
  8984. }
  8985. }
  8986. } else {
  8987. if ( !o.axis || o.axis !== "x" ) {
  8988. if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
  8989. scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
  8990. } else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
  8991. o.scrollSensitivity ) {
  8992. scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
  8993. }
  8994. }
  8995. if ( !o.axis || o.axis !== "y" ) {
  8996. if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
  8997. scrolled = $( document ).scrollLeft(
  8998. $( document ).scrollLeft() - o.scrollSpeed
  8999. );
  9000. } else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
  9001. o.scrollSensitivity ) {
  9002. scrolled = $( document ).scrollLeft(
  9003. $( document ).scrollLeft() + o.scrollSpeed
  9004. );
  9005. }
  9006. }
  9007. }
  9008. if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
  9009. $.ui.ddmanager.prepareOffsets( i, event );
  9010. }
  9011. }
  9012. } );
  9013. $.ui.plugin.add( "draggable", "snap", {
  9014. start: function( event, ui, i ) {
  9015. var o = i.options;
  9016. i.snapElements = [];
  9017. $( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
  9018. .each( function() {
  9019. var $t = $( this ),
  9020. $o = $t.offset();
  9021. if ( this !== i.element[ 0 ] ) {
  9022. i.snapElements.push( {
  9023. item: this,
  9024. width: $t.outerWidth(), height: $t.outerHeight(),
  9025. top: $o.top, left: $o.left
  9026. } );
  9027. }
  9028. } );
  9029. },
  9030. drag: function( event, ui, inst ) {
  9031. var ts, bs, ls, rs, l, r, t, b, i, first,
  9032. o = inst.options,
  9033. d = o.snapTolerance,
  9034. x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
  9035. y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
  9036. for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
  9037. l = inst.snapElements[ i ].left - inst.margins.left;
  9038. r = l + inst.snapElements[ i ].width;
  9039. t = inst.snapElements[ i ].top - inst.margins.top;
  9040. b = t + inst.snapElements[ i ].height;
  9041. if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
  9042. !$.contains( inst.snapElements[ i ].item.ownerDocument,
  9043. inst.snapElements[ i ].item ) ) {
  9044. if ( inst.snapElements[ i ].snapping ) {
  9045. if ( inst.options.snap.release ) {
  9046. inst.options.snap.release.call(
  9047. inst.element,
  9048. event,
  9049. $.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
  9050. );
  9051. }
  9052. }
  9053. inst.snapElements[ i ].snapping = false;
  9054. continue;
  9055. }
  9056. if ( o.snapMode !== "inner" ) {
  9057. ts = Math.abs( t - y2 ) <= d;
  9058. bs = Math.abs( b - y1 ) <= d;
  9059. ls = Math.abs( l - x2 ) <= d;
  9060. rs = Math.abs( r - x1 ) <= d;
  9061. if ( ts ) {
  9062. ui.position.top = inst._convertPositionTo( "relative", {
  9063. top: t - inst.helperProportions.height,
  9064. left: 0
  9065. } ).top;
  9066. }
  9067. if ( bs ) {
  9068. ui.position.top = inst._convertPositionTo( "relative", {
  9069. top: b,
  9070. left: 0
  9071. } ).top;
  9072. }
  9073. if ( ls ) {
  9074. ui.position.left = inst._convertPositionTo( "relative", {
  9075. top: 0,
  9076. left: l - inst.helperProportions.width
  9077. } ).left;
  9078. }
  9079. if ( rs ) {
  9080. ui.position.left = inst._convertPositionTo( "relative", {
  9081. top: 0,
  9082. left: r
  9083. } ).left;
  9084. }
  9085. }
  9086. first = ( ts || bs || ls || rs );
  9087. if ( o.snapMode !== "outer" ) {
  9088. ts = Math.abs( t - y1 ) <= d;
  9089. bs = Math.abs( b - y2 ) <= d;
  9090. ls = Math.abs( l - x1 ) <= d;
  9091. rs = Math.abs( r - x2 ) <= d;
  9092. if ( ts ) {
  9093. ui.position.top = inst._convertPositionTo( "relative", {
  9094. top: t,
  9095. left: 0
  9096. } ).top;
  9097. }
  9098. if ( bs ) {
  9099. ui.position.top = inst._convertPositionTo( "relative", {
  9100. top: b - inst.helperProportions.height,
  9101. left: 0
  9102. } ).top;
  9103. }
  9104. if ( ls ) {
  9105. ui.position.left = inst._convertPositionTo( "relative", {
  9106. top: 0,
  9107. left: l
  9108. } ).left;
  9109. }
  9110. if ( rs ) {
  9111. ui.position.left = inst._convertPositionTo( "relative", {
  9112. top: 0,
  9113. left: r - inst.helperProportions.width
  9114. } ).left;
  9115. }
  9116. }
  9117. if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
  9118. if ( inst.options.snap.snap ) {
  9119. inst.options.snap.snap.call(
  9120. inst.element,
  9121. event,
  9122. $.extend( inst._uiHash(), {
  9123. snapItem: inst.snapElements[ i ].item
  9124. } ) );
  9125. }
  9126. }
  9127. inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
  9128. }
  9129. }
  9130. } );
  9131. $.ui.plugin.add( "draggable", "stack", {
  9132. start: function( event, ui, instance ) {
  9133. var min,
  9134. o = instance.options,
  9135. group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
  9136. return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
  9137. ( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
  9138. } );
  9139. if ( !group.length ) {
  9140. return;
  9141. }
  9142. min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
  9143. $( group ).each( function( i ) {
  9144. $( this ).css( "zIndex", min + i );
  9145. } );
  9146. this.css( "zIndex", ( min + group.length ) );
  9147. }
  9148. } );
  9149. $.ui.plugin.add( "draggable", "zIndex", {
  9150. start: function( event, ui, instance ) {
  9151. var t = $( ui.helper ),
  9152. o = instance.options;
  9153. if ( t.css( "zIndex" ) ) {
  9154. o._zIndex = t.css( "zIndex" );
  9155. }
  9156. t.css( "zIndex", o.zIndex );
  9157. },
  9158. stop: function( event, ui, instance ) {
  9159. var o = instance.options;
  9160. if ( o._zIndex ) {
  9161. $( ui.helper ).css( "zIndex", o._zIndex );
  9162. }
  9163. }
  9164. } );
  9165. var widgetsDraggable = $.ui.draggable;
  9166. /*!
  9167. * jQuery UI Resizable 1.14.1
  9168. * https://jqueryui.com
  9169. *
  9170. * Copyright OpenJS Foundation and other contributors
  9171. * Released under the MIT license.
  9172. * https://jquery.org/license
  9173. */
  9174. //>>label: Resizable
  9175. //>>group: Interactions
  9176. //>>description: Enables resize functionality for any element.
  9177. //>>docs: https://api.jqueryui.com/resizable/
  9178. //>>demos: https://jqueryui.com/resizable/
  9179. //>>css.structure: ../../themes/base/core.css
  9180. //>>css.structure: ../../themes/base/resizable.css
  9181. //>>css.theme: ../../themes/base/theme.css
  9182. $.widget( "ui.resizable", $.ui.mouse, {
  9183. version: "1.14.1",
  9184. widgetEventPrefix: "resize",
  9185. options: {
  9186. alsoResize: false,
  9187. animate: false,
  9188. animateDuration: "slow",
  9189. animateEasing: "swing",
  9190. aspectRatio: false,
  9191. autoHide: false,
  9192. classes: {
  9193. "ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se"
  9194. },
  9195. containment: false,
  9196. ghost: false,
  9197. grid: false,
  9198. handles: "e,s,se",
  9199. helper: false,
  9200. maxHeight: null,
  9201. maxWidth: null,
  9202. minHeight: 10,
  9203. minWidth: 10,
  9204. // See #7960
  9205. zIndex: 90,
  9206. // Callbacks
  9207. resize: null,
  9208. start: null,
  9209. stop: null
  9210. },
  9211. _num: function( value ) {
  9212. return parseFloat( value ) || 0;
  9213. },
  9214. _isNumber: function( value ) {
  9215. return !isNaN( parseFloat( value ) );
  9216. },
  9217. _hasScroll: function( el, a ) {
  9218. var scroll,
  9219. has = false,
  9220. overflow = $( el ).css( "overflow" );
  9221. if ( overflow === "hidden" ) {
  9222. return false;
  9223. }
  9224. if ( overflow === "scroll" ) {
  9225. return true;
  9226. }
  9227. scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop";
  9228. if ( el[ scroll ] > 0 ) {
  9229. return true;
  9230. }
  9231. // TODO: determine which cases actually cause this to happen
  9232. // if the element doesn't have the scroll set, see if it's possible to
  9233. // set the scroll
  9234. try {
  9235. el[ scroll ] = 1;
  9236. has = ( el[ scroll ] > 0 );
  9237. el[ scroll ] = 0;
  9238. } catch ( e ) {
  9239. // `el` might be a string, then setting `scroll` will throw
  9240. // an error in strict mode; ignore it.
  9241. }
  9242. return has;
  9243. },
  9244. _create: function() {
  9245. var margins,
  9246. o = this.options,
  9247. that = this;
  9248. this._addClass( "ui-resizable" );
  9249. $.extend( this, {
  9250. _aspectRatio: !!( o.aspectRatio ),
  9251. aspectRatio: o.aspectRatio,
  9252. originalElement: this.element,
  9253. _proportionallyResizeElements: [],
  9254. _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
  9255. } );
  9256. // Wrap the element if it cannot hold child nodes
  9257. if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) {
  9258. this.element.wrap(
  9259. $( "<div class='ui-wrapper'></div>" ).css( {
  9260. overflow: "hidden",
  9261. position: this.element.css( "position" ),
  9262. width: this.element.outerWidth(),
  9263. height: this.element.outerHeight(),
  9264. top: this.element.css( "top" ),
  9265. left: this.element.css( "left" )
  9266. } )
  9267. );
  9268. this.element = this.element.parent().data(
  9269. "ui-resizable", this.element.resizable( "instance" )
  9270. );
  9271. this.elementIsWrapper = true;
  9272. margins = {
  9273. marginTop: this.originalElement.css( "marginTop" ),
  9274. marginRight: this.originalElement.css( "marginRight" ),
  9275. marginBottom: this.originalElement.css( "marginBottom" ),
  9276. marginLeft: this.originalElement.css( "marginLeft" )
  9277. };
  9278. this.element.css( margins );
  9279. // Support: Safari
  9280. // Prevent Safari textarea resize
  9281. this.originalResizeStyle = this.originalElement.css( "resize" );
  9282. this.originalElement.css( "resize", "none" );
  9283. this._proportionallyResizeElements.push( this.originalElement.css( {
  9284. position: "static",
  9285. zoom: 1,
  9286. display: "block"
  9287. } ) );
  9288. this._proportionallyResize();
  9289. }
  9290. this._setupHandles();
  9291. if ( o.autoHide ) {
  9292. $( this.element )
  9293. .on( "mouseenter", function() {
  9294. if ( o.disabled ) {
  9295. return;
  9296. }
  9297. that._removeClass( "ui-resizable-autohide" );
  9298. that._handles.show();
  9299. } )
  9300. .on( "mouseleave", function() {
  9301. if ( o.disabled ) {
  9302. return;
  9303. }
  9304. if ( !that.resizing ) {
  9305. that._addClass( "ui-resizable-autohide" );
  9306. that._handles.hide();
  9307. }
  9308. } );
  9309. }
  9310. this._mouseInit();
  9311. },
  9312. _destroy: function() {
  9313. this._mouseDestroy();
  9314. this._addedHandles.remove();
  9315. var wrapper,
  9316. _destroy = function( exp ) {
  9317. $( exp )
  9318. .removeData( "resizable" )
  9319. .removeData( "ui-resizable" )
  9320. .off( ".resizable" );
  9321. };
  9322. // TODO: Unwrap at same DOM position
  9323. if ( this.elementIsWrapper ) {
  9324. _destroy( this.element );
  9325. wrapper = this.element;
  9326. this.originalElement.css( {
  9327. position: wrapper.css( "position" ),
  9328. width: wrapper.outerWidth(),
  9329. height: wrapper.outerHeight(),
  9330. top: wrapper.css( "top" ),
  9331. left: wrapper.css( "left" )
  9332. } ).insertAfter( wrapper );
  9333. wrapper.remove();
  9334. }
  9335. this.originalElement.css( "resize", this.originalResizeStyle );
  9336. _destroy( this.originalElement );
  9337. return this;
  9338. },
  9339. _setOption: function( key, value ) {
  9340. this._super( key, value );
  9341. switch ( key ) {
  9342. case "handles":
  9343. this._removeHandles();
  9344. this._setupHandles();
  9345. break;
  9346. case "aspectRatio":
  9347. this._aspectRatio = !!value;
  9348. break;
  9349. default:
  9350. break;
  9351. }
  9352. },
  9353. _setupHandles: function() {
  9354. var o = this.options, handle, i, n, hname, axis, that = this;
  9355. this.handles = o.handles ||
  9356. ( !$( ".ui-resizable-handle", this.element ).length ?
  9357. "e,s,se" : {
  9358. n: ".ui-resizable-n",
  9359. e: ".ui-resizable-e",
  9360. s: ".ui-resizable-s",
  9361. w: ".ui-resizable-w",
  9362. se: ".ui-resizable-se",
  9363. sw: ".ui-resizable-sw",
  9364. ne: ".ui-resizable-ne",
  9365. nw: ".ui-resizable-nw"
  9366. } );
  9367. this._handles = $();
  9368. this._addedHandles = $();
  9369. if ( this.handles.constructor === String ) {
  9370. if ( this.handles === "all" ) {
  9371. this.handles = "n,e,s,w,se,sw,ne,nw";
  9372. }
  9373. n = this.handles.split( "," );
  9374. this.handles = {};
  9375. for ( i = 0; i < n.length; i++ ) {
  9376. handle = String.prototype.trim.call( n[ i ] );
  9377. hname = "ui-resizable-" + handle;
  9378. axis = $( "<div>" );
  9379. this._addClass( axis, "ui-resizable-handle " + hname );
  9380. axis.css( { zIndex: o.zIndex } );
  9381. this.handles[ handle ] = ".ui-resizable-" + handle;
  9382. if ( !this.element.children( this.handles[ handle ] ).length ) {
  9383. this.element.append( axis );
  9384. this._addedHandles = this._addedHandles.add( axis );
  9385. }
  9386. }
  9387. }
  9388. this._renderAxis = function( target ) {
  9389. var i, axis, padPos, padWrapper;
  9390. target = target || this.element;
  9391. for ( i in this.handles ) {
  9392. if ( this.handles[ i ].constructor === String ) {
  9393. this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show();
  9394. } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
  9395. this.handles[ i ] = $( this.handles[ i ] );
  9396. this._on( this.handles[ i ], { "mousedown": that._mouseDown } );
  9397. }
  9398. if ( this.elementIsWrapper &&
  9399. this.originalElement[ 0 ]
  9400. .nodeName
  9401. .match( /^(textarea|input|select|button)$/i ) ) {
  9402. axis = $( this.handles[ i ], this.element );
  9403. padWrapper = /sw|ne|nw|se|n|s/.test( i ) ?
  9404. axis.outerHeight() :
  9405. axis.outerWidth();
  9406. padPos = [ "padding",
  9407. /ne|nw|n/.test( i ) ? "Top" :
  9408. /se|sw|s/.test( i ) ? "Bottom" :
  9409. /^e$/.test( i ) ? "Right" : "Left" ].join( "" );
  9410. target.css( padPos, padWrapper );
  9411. this._proportionallyResize();
  9412. }
  9413. this._handles = this._handles.add( this.handles[ i ] );
  9414. }
  9415. };
  9416. // TODO: make renderAxis a prototype function
  9417. this._renderAxis( this.element );
  9418. this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
  9419. this._handles.disableSelection();
  9420. this._handles.on( "mouseover", function() {
  9421. if ( !that.resizing ) {
  9422. if ( this.className ) {
  9423. axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i );
  9424. }
  9425. that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se";
  9426. }
  9427. } );
  9428. if ( o.autoHide ) {
  9429. this._handles.hide();
  9430. this._addClass( "ui-resizable-autohide" );
  9431. }
  9432. },
  9433. _removeHandles: function() {
  9434. this._addedHandles.remove();
  9435. },
  9436. _mouseCapture: function( event ) {
  9437. var i, handle,
  9438. capture = false;
  9439. for ( i in this.handles ) {
  9440. handle = $( this.handles[ i ] )[ 0 ];
  9441. if ( handle === event.target || $.contains( handle, event.target ) ) {
  9442. capture = true;
  9443. }
  9444. }
  9445. return !this.options.disabled && capture;
  9446. },
  9447. _mouseStart: function( event ) {
  9448. var curleft, curtop, cursor, calculatedSize,
  9449. o = this.options,
  9450. el = this.element;
  9451. this.resizing = true;
  9452. this._renderProxy();
  9453. curleft = this._num( this.helper.css( "left" ) );
  9454. curtop = this._num( this.helper.css( "top" ) );
  9455. if ( o.containment ) {
  9456. curleft += $( o.containment ).scrollLeft() || 0;
  9457. curtop += $( o.containment ).scrollTop() || 0;
  9458. }
  9459. this.offset = this.helper.offset();
  9460. this.position = { left: curleft, top: curtop };
  9461. if ( !this._helper ) {
  9462. calculatedSize = this._calculateAdjustedElementDimensions( el );
  9463. }
  9464. this.size = this._helper ? {
  9465. width: this.helper.width(),
  9466. height: this.helper.height()
  9467. } : {
  9468. width: calculatedSize.width,
  9469. height: calculatedSize.height
  9470. };
  9471. this.originalSize = this._helper ? {
  9472. width: el.outerWidth(),
  9473. height: el.outerHeight()
  9474. } : {
  9475. width: calculatedSize.width,
  9476. height: calculatedSize.height
  9477. };
  9478. this.sizeDiff = {
  9479. width: el.outerWidth() - el.width(),
  9480. height: el.outerHeight() - el.height()
  9481. };
  9482. this.originalPosition = { left: curleft, top: curtop };
  9483. this.originalMousePosition = { left: event.pageX, top: event.pageY };
  9484. this.aspectRatio = ( typeof o.aspectRatio === "number" ) ?
  9485. o.aspectRatio :
  9486. ( ( this.originalSize.width / this.originalSize.height ) || 1 );
  9487. cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" );
  9488. $( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor );
  9489. this._addClass( "ui-resizable-resizing" );
  9490. this._propagate( "start", event );
  9491. return true;
  9492. },
  9493. _mouseDrag: function( event ) {
  9494. var data, props,
  9495. smp = this.originalMousePosition,
  9496. a = this.axis,
  9497. dx = ( event.pageX - smp.left ) || 0,
  9498. dy = ( event.pageY - smp.top ) || 0,
  9499. trigger = this._change[ a ];
  9500. this._updatePrevProperties();
  9501. if ( !trigger ) {
  9502. return false;
  9503. }
  9504. data = trigger.apply( this, [ event, dx, dy ] );
  9505. this._updateVirtualBoundaries( event.shiftKey );
  9506. if ( this._aspectRatio || event.shiftKey ) {
  9507. data = this._updateRatio( data, event );
  9508. }
  9509. data = this._respectSize( data, event );
  9510. this._updateCache( data );
  9511. this._propagate( "resize", event );
  9512. props = this._applyChanges();
  9513. if ( !this._helper && this._proportionallyResizeElements.length ) {
  9514. this._proportionallyResize();
  9515. }
  9516. if ( !$.isEmptyObject( props ) ) {
  9517. this._updatePrevProperties();
  9518. this._trigger( "resize", event, this.ui() );
  9519. this._applyChanges();
  9520. }
  9521. return false;
  9522. },
  9523. _mouseStop: function( event ) {
  9524. this.resizing = false;
  9525. var pr, ista, soffseth, soffsetw, s, left, top,
  9526. o = this.options, that = this;
  9527. if ( this._helper ) {
  9528. pr = this._proportionallyResizeElements;
  9529. ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName );
  9530. soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height;
  9531. soffsetw = ista ? 0 : that.sizeDiff.width;
  9532. s = {
  9533. width: ( that.helper.width() - soffsetw ),
  9534. height: ( that.helper.height() - soffseth )
  9535. };
  9536. left = ( parseFloat( that.element.css( "left" ) ) +
  9537. ( that.position.left - that.originalPosition.left ) ) || null;
  9538. top = ( parseFloat( that.element.css( "top" ) ) +
  9539. ( that.position.top - that.originalPosition.top ) ) || null;
  9540. if ( !o.animate ) {
  9541. this.element.css( $.extend( s, { top: top, left: left } ) );
  9542. }
  9543. that.helper.height( that.size.height );
  9544. that.helper.width( that.size.width );
  9545. if ( this._helper && !o.animate ) {
  9546. this._proportionallyResize();
  9547. }
  9548. }
  9549. $( "body" ).css( "cursor", "auto" );
  9550. this._removeClass( "ui-resizable-resizing" );
  9551. this._propagate( "stop", event );
  9552. if ( this._helper ) {
  9553. this.helper.remove();
  9554. }
  9555. return false;
  9556. },
  9557. _updatePrevProperties: function() {
  9558. this.prevPosition = {
  9559. top: this.position.top,
  9560. left: this.position.left
  9561. };
  9562. this.prevSize = {
  9563. width: this.size.width,
  9564. height: this.size.height
  9565. };
  9566. },
  9567. _applyChanges: function() {
  9568. var props = {};
  9569. if ( this.position.top !== this.prevPosition.top ) {
  9570. props.top = this.position.top + "px";
  9571. }
  9572. if ( this.position.left !== this.prevPosition.left ) {
  9573. props.left = this.position.left + "px";
  9574. }
  9575. this.helper.css( props );
  9576. if ( this.size.width !== this.prevSize.width ) {
  9577. props.width = this.size.width + "px";
  9578. this.helper.width( props.width );
  9579. }
  9580. if ( this.size.height !== this.prevSize.height ) {
  9581. props.height = this.size.height + "px";
  9582. this.helper.height( props.height );
  9583. }
  9584. return props;
  9585. },
  9586. _updateVirtualBoundaries: function( forceAspectRatio ) {
  9587. var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
  9588. o = this.options;
  9589. b = {
  9590. minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0,
  9591. maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity,
  9592. minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0,
  9593. maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity
  9594. };
  9595. if ( this._aspectRatio || forceAspectRatio ) {
  9596. pMinWidth = b.minHeight * this.aspectRatio;
  9597. pMinHeight = b.minWidth / this.aspectRatio;
  9598. pMaxWidth = b.maxHeight * this.aspectRatio;
  9599. pMaxHeight = b.maxWidth / this.aspectRatio;
  9600. if ( pMinWidth > b.minWidth ) {
  9601. b.minWidth = pMinWidth;
  9602. }
  9603. if ( pMinHeight > b.minHeight ) {
  9604. b.minHeight = pMinHeight;
  9605. }
  9606. if ( pMaxWidth < b.maxWidth ) {
  9607. b.maxWidth = pMaxWidth;
  9608. }
  9609. if ( pMaxHeight < b.maxHeight ) {
  9610. b.maxHeight = pMaxHeight;
  9611. }
  9612. }
  9613. this._vBoundaries = b;
  9614. },
  9615. _updateCache: function( data ) {
  9616. this.offset = this.helper.offset();
  9617. if ( this._isNumber( data.left ) ) {
  9618. this.position.left = data.left;
  9619. }
  9620. if ( this._isNumber( data.top ) ) {
  9621. this.position.top = data.top;
  9622. }
  9623. if ( this._isNumber( data.height ) ) {
  9624. this.size.height = data.height;
  9625. }
  9626. if ( this._isNumber( data.width ) ) {
  9627. this.size.width = data.width;
  9628. }
  9629. },
  9630. _updateRatio: function( data ) {
  9631. var cpos = this.position,
  9632. csize = this.size,
  9633. a = this.axis;
  9634. if ( this._isNumber( data.height ) ) {
  9635. data.width = ( data.height * this.aspectRatio );
  9636. } else if ( this._isNumber( data.width ) ) {
  9637. data.height = ( data.width / this.aspectRatio );
  9638. }
  9639. if ( a === "sw" ) {
  9640. data.left = cpos.left + ( csize.width - data.width );
  9641. data.top = null;
  9642. }
  9643. if ( a === "nw" ) {
  9644. data.top = cpos.top + ( csize.height - data.height );
  9645. data.left = cpos.left + ( csize.width - data.width );
  9646. }
  9647. return data;
  9648. },
  9649. _respectSize: function( data ) {
  9650. var o = this._vBoundaries,
  9651. a = this.axis,
  9652. ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ),
  9653. ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ),
  9654. isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ),
  9655. isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ),
  9656. dw = this.originalPosition.left + this.originalSize.width,
  9657. dh = this.originalPosition.top + this.originalSize.height,
  9658. cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a );
  9659. if ( isminw ) {
  9660. data.width = o.minWidth;
  9661. }
  9662. if ( isminh ) {
  9663. data.height = o.minHeight;
  9664. }
  9665. if ( ismaxw ) {
  9666. data.width = o.maxWidth;
  9667. }
  9668. if ( ismaxh ) {
  9669. data.height = o.maxHeight;
  9670. }
  9671. if ( isminw && cw ) {
  9672. data.left = dw - o.minWidth;
  9673. }
  9674. if ( ismaxw && cw ) {
  9675. data.left = dw - o.maxWidth;
  9676. }
  9677. if ( isminh && ch ) {
  9678. data.top = dh - o.minHeight;
  9679. }
  9680. if ( ismaxh && ch ) {
  9681. data.top = dh - o.maxHeight;
  9682. }
  9683. // Fixing jump error on top/left - bug #2330
  9684. if ( !data.width && !data.height && !data.left && data.top ) {
  9685. data.top = null;
  9686. } else if ( !data.width && !data.height && !data.top && data.left ) {
  9687. data.left = null;
  9688. }
  9689. return data;
  9690. },
  9691. _getPaddingPlusBorderDimensions: function( element ) {
  9692. var i = 0,
  9693. widths = [],
  9694. borders = [
  9695. element.css( "borderTopWidth" ),
  9696. element.css( "borderRightWidth" ),
  9697. element.css( "borderBottomWidth" ),
  9698. element.css( "borderLeftWidth" )
  9699. ],
  9700. paddings = [
  9701. element.css( "paddingTop" ),
  9702. element.css( "paddingRight" ),
  9703. element.css( "paddingBottom" ),
  9704. element.css( "paddingLeft" )
  9705. ];
  9706. for ( ; i < 4; i++ ) {
  9707. widths[ i ] = ( parseFloat( borders[ i ] ) || 0 );
  9708. widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 );
  9709. }
  9710. return {
  9711. height: widths[ 0 ] + widths[ 2 ],
  9712. width: widths[ 1 ] + widths[ 3 ]
  9713. };
  9714. },
  9715. _calculateAdjustedElementDimensions: function( element ) {
  9716. var elWidth, elHeight, paddingBorder,
  9717. ce = element.get( 0 );
  9718. if ( element.css( "box-sizing" ) !== "content-box" ||
  9719. ( !this._hasScroll( ce ) && !this._hasScroll( ce, "left" ) ) ) {
  9720. return {
  9721. height: parseFloat( element.css( "height" ) ),
  9722. width: parseFloat( element.css( "width" ) )
  9723. };
  9724. }
  9725. // Check if CSS inline styles are set and use those (usually from previous resizes)
  9726. elWidth = parseFloat( ce.style.width );
  9727. elHeight = parseFloat( ce.style.height );
  9728. paddingBorder = this._getPaddingPlusBorderDimensions( element );
  9729. elWidth = isNaN( elWidth ) ?
  9730. this._getElementTheoreticalSize( element, paddingBorder, "width" ) :
  9731. elWidth;
  9732. elHeight = isNaN( elHeight ) ?
  9733. this._getElementTheoreticalSize( element, paddingBorder, "height" ) :
  9734. elHeight;
  9735. return {
  9736. height: elHeight,
  9737. width: elWidth
  9738. };
  9739. },
  9740. _getElementTheoreticalSize: function( element, extraSize, dimension ) {
  9741. // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
  9742. var size = Math.max( 0, Math.ceil(
  9743. element.get( 0 )[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
  9744. extraSize[ dimension ] -
  9745. 0.5
  9746. // If offsetWidth/offsetHeight is unknown, then we can't determine theoretical size.
  9747. // Use an explicit zero to avoid NaN.
  9748. // See https://github.com/jquery/jquery/issues/3964
  9749. ) ) || 0;
  9750. return size;
  9751. },
  9752. _proportionallyResize: function() {
  9753. if ( !this._proportionallyResizeElements.length ) {
  9754. return;
  9755. }
  9756. var prel,
  9757. i = 0,
  9758. element = this.helper || this.element;
  9759. for ( ; i < this._proportionallyResizeElements.length; i++ ) {
  9760. prel = this._proportionallyResizeElements[ i ];
  9761. // TODO: Seems like a bug to cache this.outerDimensions
  9762. // considering that we are in a loop.
  9763. if ( !this.outerDimensions ) {
  9764. this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
  9765. }
  9766. prel.css( {
  9767. height: ( element.height() - this.outerDimensions.height ) || 0,
  9768. width: ( element.width() - this.outerDimensions.width ) || 0
  9769. } );
  9770. }
  9771. },
  9772. _renderProxy: function() {
  9773. var el = this.element, o = this.options;
  9774. this.elementOffset = el.offset();
  9775. if ( this._helper ) {
  9776. this.helper = this.helper || $( "<div></div>" ).css( { overflow: "hidden" } );
  9777. this._addClass( this.helper, this._helper );
  9778. this.helper.css( {
  9779. width: this.element.outerWidth(),
  9780. height: this.element.outerHeight(),
  9781. position: "absolute",
  9782. left: this.elementOffset.left + "px",
  9783. top: this.elementOffset.top + "px",
  9784. zIndex: ++o.zIndex //TODO: Don't modify option
  9785. } );
  9786. this.helper
  9787. .appendTo( "body" )
  9788. .disableSelection();
  9789. } else {
  9790. this.helper = this.element;
  9791. }
  9792. },
  9793. _change: {
  9794. e: function( event, dx ) {
  9795. return { width: this.originalSize.width + dx };
  9796. },
  9797. w: function( event, dx ) {
  9798. var cs = this.originalSize, sp = this.originalPosition;
  9799. return { left: sp.left + dx, width: cs.width - dx };
  9800. },
  9801. n: function( event, dx, dy ) {
  9802. var cs = this.originalSize, sp = this.originalPosition;
  9803. return { top: sp.top + dy, height: cs.height - dy };
  9804. },
  9805. s: function( event, dx, dy ) {
  9806. return { height: this.originalSize.height + dy };
  9807. },
  9808. se: function( event, dx, dy ) {
  9809. return $.extend( this._change.s.apply( this, arguments ),
  9810. this._change.e.apply( this, [ event, dx, dy ] ) );
  9811. },
  9812. sw: function( event, dx, dy ) {
  9813. return $.extend( this._change.s.apply( this, arguments ),
  9814. this._change.w.apply( this, [ event, dx, dy ] ) );
  9815. },
  9816. ne: function( event, dx, dy ) {
  9817. return $.extend( this._change.n.apply( this, arguments ),
  9818. this._change.e.apply( this, [ event, dx, dy ] ) );
  9819. },
  9820. nw: function( event, dx, dy ) {
  9821. return $.extend( this._change.n.apply( this, arguments ),
  9822. this._change.w.apply( this, [ event, dx, dy ] ) );
  9823. }
  9824. },
  9825. _propagate: function( n, event ) {
  9826. $.ui.plugin.call( this, n, [ event, this.ui() ] );
  9827. if ( n !== "resize" ) {
  9828. this._trigger( n, event, this.ui() );
  9829. }
  9830. },
  9831. plugins: {},
  9832. ui: function() {
  9833. return {
  9834. originalElement: this.originalElement,
  9835. element: this.element,
  9836. helper: this.helper,
  9837. position: this.position,
  9838. size: this.size,
  9839. originalSize: this.originalSize,
  9840. originalPosition: this.originalPosition
  9841. };
  9842. }
  9843. } );
  9844. /*
  9845. * Resizable Extensions
  9846. */
  9847. $.ui.plugin.add( "resizable", "animate", {
  9848. stop: function( event ) {
  9849. var that = $( this ).resizable( "instance" ),
  9850. o = that.options,
  9851. pr = that._proportionallyResizeElements,
  9852. ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ),
  9853. soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height,
  9854. soffsetw = ista ? 0 : that.sizeDiff.width,
  9855. style = {
  9856. width: ( that.size.width - soffsetw ),
  9857. height: ( that.size.height - soffseth )
  9858. },
  9859. left = ( parseFloat( that.element.css( "left" ) ) +
  9860. ( that.position.left - that.originalPosition.left ) ) || null,
  9861. top = ( parseFloat( that.element.css( "top" ) ) +
  9862. ( that.position.top - that.originalPosition.top ) ) || null;
  9863. that.element.animate(
  9864. $.extend( style, top && left ? { top: top, left: left } : {} ), {
  9865. duration: o.animateDuration,
  9866. easing: o.animateEasing,
  9867. step: function() {
  9868. var data = {
  9869. width: parseFloat( that.element.css( "width" ) ),
  9870. height: parseFloat( that.element.css( "height" ) ),
  9871. top: parseFloat( that.element.css( "top" ) ),
  9872. left: parseFloat( that.element.css( "left" ) )
  9873. };
  9874. if ( pr && pr.length ) {
  9875. $( pr[ 0 ] ).css( { width: data.width, height: data.height } );
  9876. }
  9877. // Propagating resize, and updating values for each animation step
  9878. that._updateCache( data );
  9879. that._propagate( "resize", event );
  9880. }
  9881. }
  9882. );
  9883. }
  9884. } );
  9885. $.ui.plugin.add( "resizable", "containment", {
  9886. start: function() {
  9887. var element, p, co, ch, cw, width, height,
  9888. that = $( this ).resizable( "instance" ),
  9889. o = that.options,
  9890. el = that.element,
  9891. oc = o.containment,
  9892. ce = ( oc instanceof $ ) ?
  9893. oc.get( 0 ) :
  9894. ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
  9895. if ( !ce ) {
  9896. return;
  9897. }
  9898. that.containerElement = $( ce );
  9899. if ( /document/.test( oc ) || oc === document ) {
  9900. that.containerOffset = {
  9901. left: 0,
  9902. top: 0
  9903. };
  9904. that.containerPosition = {
  9905. left: 0,
  9906. top: 0
  9907. };
  9908. that.parentData = {
  9909. element: $( document ),
  9910. left: 0,
  9911. top: 0,
  9912. width: $( document ).width(),
  9913. height: $( document ).height() || document.body.parentNode.scrollHeight
  9914. };
  9915. } else {
  9916. element = $( ce );
  9917. p = [];
  9918. $( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) {
  9919. p[ i ] = that._num( element.css( "padding" + name ) );
  9920. } );
  9921. that.containerOffset = element.offset();
  9922. that.containerPosition = element.position();
  9923. that.containerSize = {
  9924. height: ( element.innerHeight() - p[ 3 ] ),
  9925. width: ( element.innerWidth() - p[ 1 ] )
  9926. };
  9927. co = that.containerOffset;
  9928. ch = that.containerSize.height;
  9929. cw = that.containerSize.width;
  9930. width = ( that._hasScroll( ce, "left" ) ? ce.scrollWidth : cw );
  9931. height = ( that._hasScroll( ce ) ? ce.scrollHeight : ch );
  9932. that.parentData = {
  9933. element: ce,
  9934. left: co.left,
  9935. top: co.top,
  9936. width: width,
  9937. height: height
  9938. };
  9939. }
  9940. },
  9941. resize: function( event ) {
  9942. var woset, hoset, isParent, isOffsetRelative,
  9943. that = $( this ).resizable( "instance" ),
  9944. o = that.options,
  9945. co = that.containerOffset,
  9946. cp = that.position,
  9947. pRatio = that._aspectRatio || event.shiftKey,
  9948. cop = {
  9949. top: 0,
  9950. left: 0
  9951. },
  9952. ce = that.containerElement,
  9953. continueResize = true;
  9954. if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
  9955. cop = co;
  9956. }
  9957. if ( cp.left < ( that._helper ? co.left : 0 ) ) {
  9958. that.size.width = that.size.width +
  9959. ( that._helper ?
  9960. ( that.position.left - co.left ) :
  9961. ( that.position.left - cop.left ) );
  9962. if ( pRatio ) {
  9963. that.size.height = that.size.width / that.aspectRatio;
  9964. continueResize = false;
  9965. }
  9966. that.position.left = o.helper ? co.left : 0;
  9967. }
  9968. if ( cp.top < ( that._helper ? co.top : 0 ) ) {
  9969. that.size.height = that.size.height +
  9970. ( that._helper ?
  9971. ( that.position.top - co.top ) :
  9972. that.position.top );
  9973. if ( pRatio ) {
  9974. that.size.width = that.size.height * that.aspectRatio;
  9975. continueResize = false;
  9976. }
  9977. that.position.top = that._helper ? co.top : 0;
  9978. }
  9979. isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
  9980. isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
  9981. if ( isParent && isOffsetRelative ) {
  9982. that.offset.left = that.parentData.left + that.position.left;
  9983. that.offset.top = that.parentData.top + that.position.top;
  9984. } else {
  9985. that.offset.left = that.element.offset().left;
  9986. that.offset.top = that.element.offset().top;
  9987. }
  9988. woset = Math.abs( that.sizeDiff.width +
  9989. ( that._helper ?
  9990. that.offset.left - cop.left :
  9991. ( that.offset.left - co.left ) ) );
  9992. hoset = Math.abs( that.sizeDiff.height +
  9993. ( that._helper ?
  9994. that.offset.top - cop.top :
  9995. ( that.offset.top - co.top ) ) );
  9996. if ( woset + that.size.width >= that.parentData.width ) {
  9997. that.size.width = that.parentData.width - woset;
  9998. if ( pRatio ) {
  9999. that.size.height = that.size.width / that.aspectRatio;
  10000. continueResize = false;
  10001. }
  10002. }
  10003. if ( hoset + that.size.height >= that.parentData.height ) {
  10004. that.size.height = that.parentData.height - hoset;
  10005. if ( pRatio ) {
  10006. that.size.width = that.size.height * that.aspectRatio;
  10007. continueResize = false;
  10008. }
  10009. }
  10010. if ( !continueResize ) {
  10011. that.position.left = that.prevPosition.left;
  10012. that.position.top = that.prevPosition.top;
  10013. that.size.width = that.prevSize.width;
  10014. that.size.height = that.prevSize.height;
  10015. }
  10016. },
  10017. stop: function() {
  10018. var that = $( this ).resizable( "instance" ),
  10019. o = that.options,
  10020. co = that.containerOffset,
  10021. cop = that.containerPosition,
  10022. ce = that.containerElement,
  10023. helper = $( that.helper ),
  10024. ho = helper.offset(),
  10025. w = helper.outerWidth() - that.sizeDiff.width,
  10026. h = helper.outerHeight() - that.sizeDiff.height;
  10027. if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
  10028. $( this ).css( {
  10029. left: ho.left - cop.left - co.left,
  10030. width: w,
  10031. height: h
  10032. } );
  10033. }
  10034. if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
  10035. $( this ).css( {
  10036. left: ho.left - cop.left - co.left,
  10037. width: w,
  10038. height: h
  10039. } );
  10040. }
  10041. }
  10042. } );
  10043. $.ui.plugin.add( "resizable", "alsoResize", {
  10044. start: function() {
  10045. var that = $( this ).resizable( "instance" ),
  10046. o = that.options;
  10047. $( o.alsoResize ).each( function() {
  10048. var el = $( this ),
  10049. elSize = that._calculateAdjustedElementDimensions( el );
  10050. el.data( "ui-resizable-alsoresize", {
  10051. width: elSize.width, height: elSize.height,
  10052. left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) )
  10053. } );
  10054. } );
  10055. },
  10056. resize: function( event, ui ) {
  10057. var that = $( this ).resizable( "instance" ),
  10058. o = that.options,
  10059. os = that.originalSize,
  10060. op = that.originalPosition,
  10061. delta = {
  10062. height: ( that.size.height - os.height ) || 0,
  10063. width: ( that.size.width - os.width ) || 0,
  10064. top: ( that.position.top - op.top ) || 0,
  10065. left: ( that.position.left - op.left ) || 0
  10066. };
  10067. $( o.alsoResize ).each( function() {
  10068. var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {},
  10069. css = el.parents( ui.originalElement[ 0 ] ).length ?
  10070. [ "width", "height" ] :
  10071. [ "width", "height", "top", "left" ];
  10072. $.each( css, function( i, prop ) {
  10073. var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 );
  10074. if ( sum && sum >= 0 ) {
  10075. style[ prop ] = sum || null;
  10076. }
  10077. } );
  10078. el.css( style );
  10079. } );
  10080. },
  10081. stop: function() {
  10082. $( this ).removeData( "ui-resizable-alsoresize" );
  10083. }
  10084. } );
  10085. $.ui.plugin.add( "resizable", "ghost", {
  10086. start: function() {
  10087. var that = $( this ).resizable( "instance" ), cs = that.size;
  10088. that.ghost = that.originalElement.clone();
  10089. that.ghost.css( {
  10090. opacity: 0.25,
  10091. display: "block",
  10092. position: "relative",
  10093. height: cs.height,
  10094. width: cs.width,
  10095. margin: 0,
  10096. left: 0,
  10097. top: 0
  10098. } );
  10099. that._addClass( that.ghost, "ui-resizable-ghost" );
  10100. // DEPRECATED
  10101. // TODO: remove after 1.12
  10102. if ( $.uiBackCompat === true && typeof that.options.ghost === "string" ) {
  10103. // Ghost option
  10104. that.ghost.addClass( this.options.ghost );
  10105. }
  10106. that.ghost.appendTo( that.helper );
  10107. },
  10108. resize: function() {
  10109. var that = $( this ).resizable( "instance" );
  10110. if ( that.ghost ) {
  10111. that.ghost.css( {
  10112. position: "relative",
  10113. height: that.size.height,
  10114. width: that.size.width
  10115. } );
  10116. }
  10117. },
  10118. stop: function() {
  10119. var that = $( this ).resizable( "instance" );
  10120. if ( that.ghost && that.helper ) {
  10121. that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) );
  10122. }
  10123. }
  10124. } );
  10125. $.ui.plugin.add( "resizable", "grid", {
  10126. resize: function() {
  10127. var outerDimensions,
  10128. that = $( this ).resizable( "instance" ),
  10129. o = that.options,
  10130. cs = that.size,
  10131. os = that.originalSize,
  10132. op = that.originalPosition,
  10133. a = that.axis,
  10134. grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
  10135. gridX = ( grid[ 0 ] || 1 ),
  10136. gridY = ( grid[ 1 ] || 1 ),
  10137. ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX,
  10138. oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY,
  10139. newWidth = os.width + ox,
  10140. newHeight = os.height + oy,
  10141. isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ),
  10142. isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ),
  10143. isMinWidth = o.minWidth && ( o.minWidth > newWidth ),
  10144. isMinHeight = o.minHeight && ( o.minHeight > newHeight );
  10145. o.grid = grid;
  10146. if ( isMinWidth ) {
  10147. newWidth += gridX;
  10148. }
  10149. if ( isMinHeight ) {
  10150. newHeight += gridY;
  10151. }
  10152. if ( isMaxWidth ) {
  10153. newWidth -= gridX;
  10154. }
  10155. if ( isMaxHeight ) {
  10156. newHeight -= gridY;
  10157. }
  10158. if ( /^(se|s|e)$/.test( a ) ) {
  10159. that.size.width = newWidth;
  10160. that.size.height = newHeight;
  10161. } else if ( /^(ne)$/.test( a ) ) {
  10162. that.size.width = newWidth;
  10163. that.size.height = newHeight;
  10164. that.position.top = op.top - oy;
  10165. } else if ( /^(sw)$/.test( a ) ) {
  10166. that.size.width = newWidth;
  10167. that.size.height = newHeight;
  10168. that.position.left = op.left - ox;
  10169. } else {
  10170. if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) {
  10171. outerDimensions = that._getPaddingPlusBorderDimensions( this );
  10172. }
  10173. if ( newHeight - gridY > 0 ) {
  10174. that.size.height = newHeight;
  10175. that.position.top = op.top - oy;
  10176. } else {
  10177. newHeight = gridY - outerDimensions.height;
  10178. that.size.height = newHeight;
  10179. that.position.top = op.top + os.height - newHeight;
  10180. }
  10181. if ( newWidth - gridX > 0 ) {
  10182. that.size.width = newWidth;
  10183. that.position.left = op.left - ox;
  10184. } else {
  10185. newWidth = gridX - outerDimensions.width;
  10186. that.size.width = newWidth;
  10187. that.position.left = op.left + os.width - newWidth;
  10188. }
  10189. }
  10190. }
  10191. } );
  10192. var widgetsResizable = $.ui.resizable;
  10193. /*!
  10194. * jQuery UI Dialog 1.14.1
  10195. * https://jqueryui.com
  10196. *
  10197. * Copyright OpenJS Foundation and other contributors
  10198. * Released under the MIT license.
  10199. * https://jquery.org/license
  10200. */
  10201. //>>label: Dialog
  10202. //>>group: Widgets
  10203. //>>description: Displays customizable dialog windows.
  10204. //>>docs: https://api.jqueryui.com/dialog/
  10205. //>>demos: https://jqueryui.com/dialog/
  10206. //>>css.structure: ../../themes/base/core.css
  10207. //>>css.structure: ../../themes/base/dialog.css
  10208. //>>css.theme: ../../themes/base/theme.css
  10209. $.widget( "ui.dialog", {
  10210. version: "1.14.1",
  10211. options: {
  10212. appendTo: "body",
  10213. autoOpen: true,
  10214. buttons: [],
  10215. classes: {
  10216. "ui-dialog": "ui-corner-all",
  10217. "ui-dialog-titlebar": "ui-corner-all"
  10218. },
  10219. closeOnEscape: true,
  10220. closeText: "Close",
  10221. draggable: true,
  10222. hide: null,
  10223. height: "auto",
  10224. maxHeight: null,
  10225. maxWidth: null,
  10226. minHeight: 150,
  10227. minWidth: 150,
  10228. modal: false,
  10229. position: {
  10230. my: "center",
  10231. at: "center",
  10232. of: window,
  10233. collision: "fit",
  10234. // Ensure the titlebar is always visible
  10235. using: function( pos ) {
  10236. var topOffset = $( this ).css( pos ).offset().top;
  10237. if ( topOffset < 0 ) {
  10238. $( this ).css( "top", pos.top - topOffset );
  10239. }
  10240. }
  10241. },
  10242. resizable: true,
  10243. show: null,
  10244. title: null,
  10245. uiDialogTitleHeadingLevel: 0,
  10246. width: 300,
  10247. // Callbacks
  10248. beforeClose: null,
  10249. close: null,
  10250. drag: null,
  10251. dragStart: null,
  10252. dragStop: null,
  10253. focus: null,
  10254. open: null,
  10255. resize: null,
  10256. resizeStart: null,
  10257. resizeStop: null
  10258. },
  10259. sizeRelatedOptions: {
  10260. buttons: true,
  10261. height: true,
  10262. maxHeight: true,
  10263. maxWidth: true,
  10264. minHeight: true,
  10265. minWidth: true,
  10266. width: true
  10267. },
  10268. resizableRelatedOptions: {
  10269. maxHeight: true,
  10270. maxWidth: true,
  10271. minHeight: true,
  10272. minWidth: true
  10273. },
  10274. _create: function() {
  10275. this.originalCss = {
  10276. display: this.element[ 0 ].style.display,
  10277. width: this.element[ 0 ].style.width,
  10278. minHeight: this.element[ 0 ].style.minHeight,
  10279. maxHeight: this.element[ 0 ].style.maxHeight,
  10280. height: this.element[ 0 ].style.height
  10281. };
  10282. this.originalPosition = {
  10283. parent: this.element.parent(),
  10284. index: this.element.parent().children().index( this.element )
  10285. };
  10286. this.originalTitle = this.element.attr( "title" );
  10287. if ( this.options.title == null && this.originalTitle != null ) {
  10288. this.options.title = this.originalTitle;
  10289. }
  10290. // Dialogs can't be disabled
  10291. if ( this.options.disabled ) {
  10292. this.options.disabled = false;
  10293. }
  10294. this._createWrapper();
  10295. this.element
  10296. .show()
  10297. .removeAttr( "title" )
  10298. .appendTo( this.uiDialog );
  10299. this._addClass( "ui-dialog-content", "ui-widget-content" );
  10300. this._createTitlebar();
  10301. this._createButtonPane();
  10302. if ( this.options.draggable && $.fn.draggable ) {
  10303. this._makeDraggable();
  10304. }
  10305. if ( this.options.resizable && $.fn.resizable ) {
  10306. this._makeResizable();
  10307. }
  10308. this._isOpen = false;
  10309. this._trackFocus();
  10310. },
  10311. _init: function() {
  10312. if ( this.options.autoOpen ) {
  10313. this.open();
  10314. }
  10315. },
  10316. _appendTo: function() {
  10317. var element = this.options.appendTo;
  10318. if ( element && ( element.jquery || element.nodeType ) ) {
  10319. return $( element );
  10320. }
  10321. return this.document.find( element || "body" ).eq( 0 );
  10322. },
  10323. _destroy: function() {
  10324. var next,
  10325. originalPosition = this.originalPosition;
  10326. this._untrackInstance();
  10327. this._destroyOverlay();
  10328. this.element
  10329. .removeUniqueId()
  10330. .css( this.originalCss )
  10331. // Without detaching first, the following becomes really slow
  10332. .detach();
  10333. this.uiDialog.remove();
  10334. if ( this.originalTitle ) {
  10335. this.element.attr( "title", this.originalTitle );
  10336. }
  10337. next = originalPosition.parent.children().eq( originalPosition.index );
  10338. // Don't try to place the dialog next to itself (#8613)
  10339. if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
  10340. next.before( this.element );
  10341. } else {
  10342. originalPosition.parent.append( this.element );
  10343. }
  10344. },
  10345. widget: function() {
  10346. return this.uiDialog;
  10347. },
  10348. disable: $.noop,
  10349. enable: $.noop,
  10350. close: function( event ) {
  10351. var that = this;
  10352. if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
  10353. return;
  10354. }
  10355. this._isOpen = false;
  10356. this._focusedElement = null;
  10357. this._destroyOverlay();
  10358. this._untrackInstance();
  10359. if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) {
  10360. // Hiding a focused element doesn't trigger blur in WebKit
  10361. // so in case we have nothing to focus on, explicitly blur the active element
  10362. // https://bugs.webkit.org/show_bug.cgi?id=47182
  10363. $( this.document[ 0 ].activeElement ).trigger( "blur" );
  10364. }
  10365. this._hide( this.uiDialog, this.options.hide, function() {
  10366. that._trigger( "close", event );
  10367. } );
  10368. },
  10369. isOpen: function() {
  10370. return this._isOpen;
  10371. },
  10372. moveToTop: function() {
  10373. this._moveToTop();
  10374. },
  10375. _moveToTop: function( event, silent ) {
  10376. var moved = false,
  10377. zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() {
  10378. return +$( this ).css( "z-index" );
  10379. } ).get(),
  10380. zIndexMax = Math.max.apply( null, zIndices );
  10381. if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
  10382. this.uiDialog.css( "z-index", zIndexMax + 1 );
  10383. moved = true;
  10384. }
  10385. if ( moved && !silent ) {
  10386. this._trigger( "focus", event );
  10387. }
  10388. return moved;
  10389. },
  10390. open: function() {
  10391. var that = this;
  10392. if ( this._isOpen ) {
  10393. if ( this._moveToTop() ) {
  10394. this._focusTabbable();
  10395. }
  10396. return;
  10397. }
  10398. this._isOpen = true;
  10399. this.opener = $( this.document[ 0 ].activeElement );
  10400. this._size();
  10401. this._position();
  10402. this._createOverlay();
  10403. this._moveToTop( null, true );
  10404. // Ensure the overlay is moved to the top with the dialog, but only when
  10405. // opening. The overlay shouldn't move after the dialog is open so that
  10406. // modeless dialogs opened after the modal dialog stack properly.
  10407. if ( this.overlay ) {
  10408. this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
  10409. }
  10410. this._show( this.uiDialog, this.options.show, function() {
  10411. that._focusTabbable();
  10412. that._trigger( "focus" );
  10413. } );
  10414. // Track the dialog immediately upon opening in case a focus event
  10415. // somehow occurs outside of the dialog before an element inside the
  10416. // dialog is focused (#10152)
  10417. this._makeFocusTarget();
  10418. this._trigger( "open" );
  10419. },
  10420. _focusTabbable: function() {
  10421. // Set focus to the first match:
  10422. // 1. An element that was focused previously
  10423. // 2. First element inside the dialog matching [autofocus]
  10424. // 3. Tabbable element inside the content element
  10425. // 4. Tabbable element inside the buttonpane
  10426. // 5. The close button
  10427. // 6. The dialog itself
  10428. var hasFocus = this._focusedElement;
  10429. if ( !hasFocus ) {
  10430. hasFocus = this.element.find( "[autofocus]" );
  10431. }
  10432. if ( !hasFocus.length ) {
  10433. hasFocus = this.element.find( ":tabbable" );
  10434. }
  10435. if ( !hasFocus.length ) {
  10436. hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
  10437. }
  10438. if ( !hasFocus.length ) {
  10439. hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
  10440. }
  10441. if ( !hasFocus.length ) {
  10442. hasFocus = this.uiDialog;
  10443. }
  10444. hasFocus.eq( 0 ).trigger( "focus" );
  10445. },
  10446. _restoreTabbableFocus: function() {
  10447. var activeElement = this.document[ 0 ].activeElement,
  10448. isActive = this.uiDialog[ 0 ] === activeElement ||
  10449. $.contains( this.uiDialog[ 0 ], activeElement );
  10450. if ( !isActive ) {
  10451. this._focusTabbable();
  10452. }
  10453. },
  10454. _keepFocus: function( event ) {
  10455. event.preventDefault();
  10456. this._restoreTabbableFocus();
  10457. },
  10458. _createWrapper: function() {
  10459. this.uiDialog = $( "<div>" )
  10460. .hide()
  10461. .attr( {
  10462. // Setting tabIndex makes the div focusable
  10463. tabIndex: -1,
  10464. role: "dialog",
  10465. "aria-modal": this.options.modal ? "true" : null
  10466. } )
  10467. .appendTo( this._appendTo() );
  10468. this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" );
  10469. this._on( this.uiDialog, {
  10470. keydown: function( event ) {
  10471. if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
  10472. event.keyCode === $.ui.keyCode.ESCAPE ) {
  10473. event.preventDefault();
  10474. this.close( event );
  10475. return;
  10476. }
  10477. // Prevent tabbing out of dialogs
  10478. if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
  10479. return;
  10480. }
  10481. var tabbables = this.uiDialog.find( ":tabbable" ),
  10482. first = tabbables.first(),
  10483. last = tabbables.last();
  10484. if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) &&
  10485. !event.shiftKey ) {
  10486. this._delay( function() {
  10487. first.trigger( "focus" );
  10488. } );
  10489. event.preventDefault();
  10490. } else if ( ( event.target === first[ 0 ] ||
  10491. event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) {
  10492. this._delay( function() {
  10493. last.trigger( "focus" );
  10494. } );
  10495. event.preventDefault();
  10496. }
  10497. },
  10498. mousedown: function( event ) {
  10499. if ( this._moveToTop( event ) ) {
  10500. this._focusTabbable();
  10501. }
  10502. }
  10503. } );
  10504. // We assume that any existing aria-describedby attribute means
  10505. // that the dialog content is marked up properly
  10506. // otherwise we brute force the content as the description
  10507. if ( !this.element.find( "[aria-describedby]" ).length ) {
  10508. this.uiDialog.attr( {
  10509. "aria-describedby": this.element.uniqueId().attr( "id" )
  10510. } );
  10511. }
  10512. },
  10513. _createTitlebar: function() {
  10514. var uiDialogTitle;
  10515. this.uiDialogTitlebar = $( "<div>" );
  10516. this._addClass( this.uiDialogTitlebar,
  10517. "ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" );
  10518. this._on( this.uiDialogTitlebar, {
  10519. mousedown: function( event ) {
  10520. // Don't prevent click on close button (#8838)
  10521. // Focusing a dialog that is partially scrolled out of view
  10522. // causes the browser to scroll it into view, preventing the click event
  10523. if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
  10524. // Dialog isn't getting focus when dragging (#8063)
  10525. this.uiDialog.trigger( "focus" );
  10526. }
  10527. }
  10528. } );
  10529. this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
  10530. .button( {
  10531. label: $( "<a>" ).text( this.options.closeText ).html(),
  10532. icon: "ui-icon-closethick",
  10533. showLabel: false
  10534. } )
  10535. .appendTo( this.uiDialogTitlebar );
  10536. this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" );
  10537. this._on( this.uiDialogTitlebarClose, {
  10538. click: function( event ) {
  10539. event.preventDefault();
  10540. this.close( event );
  10541. }
  10542. } );
  10543. var uiDialogHeadingLevel = Number.isInteger( this.options.uiDialogTitleHeadingLevel ) &&
  10544. this.options.uiDialogTitleHeadingLevel > 0 &&
  10545. this.options.uiDialogTitleHeadingLevel <= 6 ?
  10546. "h" + this.options.uiDialogTitleHeadingLevel : "span";
  10547. uiDialogTitle = $( "<" + uiDialogHeadingLevel + ">" )
  10548. .uniqueId().prependTo( this.uiDialogTitlebar );
  10549. this._addClass( uiDialogTitle, "ui-dialog-title" );
  10550. this._title( uiDialogTitle );
  10551. this.uiDialogTitlebar.prependTo( this.uiDialog );
  10552. this.uiDialog.attr( {
  10553. "aria-labelledby": uiDialogTitle.attr( "id" )
  10554. } );
  10555. },
  10556. _title: function( title ) {
  10557. if ( this.options.title ) {
  10558. title.text( this.options.title );
  10559. } else {
  10560. title.html( "&#160;" );
  10561. }
  10562. },
  10563. _createButtonPane: function() {
  10564. this.uiDialogButtonPane = $( "<div>" );
  10565. this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane",
  10566. "ui-widget-content ui-helper-clearfix" );
  10567. this.uiButtonSet = $( "<div>" )
  10568. .appendTo( this.uiDialogButtonPane );
  10569. this._addClass( this.uiButtonSet, "ui-dialog-buttonset" );
  10570. this._createButtons();
  10571. },
  10572. _createButtons: function() {
  10573. var that = this,
  10574. buttons = this.options.buttons;
  10575. // If we already have a button pane, remove it
  10576. this.uiDialogButtonPane.remove();
  10577. this.uiButtonSet.empty();
  10578. if ( $.isEmptyObject( buttons ) || ( Array.isArray( buttons ) && !buttons.length ) ) {
  10579. this._removeClass( this.uiDialog, "ui-dialog-buttons" );
  10580. return;
  10581. }
  10582. $.each( buttons, function( name, props ) {
  10583. var click, buttonOptions;
  10584. props = typeof props === "function" ?
  10585. { click: props, text: name } :
  10586. props;
  10587. // Default to a non-submitting button
  10588. props = $.extend( { type: "button" }, props );
  10589. // Change the context for the click callback to be the main element
  10590. click = props.click;
  10591. buttonOptions = {
  10592. icon: props.icon,
  10593. iconPosition: props.iconPosition,
  10594. showLabel: props.showLabel,
  10595. // Deprecated options
  10596. icons: props.icons,
  10597. text: props.text
  10598. };
  10599. delete props.click;
  10600. delete props.icon;
  10601. delete props.iconPosition;
  10602. delete props.showLabel;
  10603. // Deprecated options
  10604. delete props.icons;
  10605. if ( typeof props.text === "boolean" ) {
  10606. delete props.text;
  10607. }
  10608. $( "<button></button>", props )
  10609. .button( buttonOptions )
  10610. .appendTo( that.uiButtonSet )
  10611. .on( "click", function() {
  10612. click.apply( that.element[ 0 ], arguments );
  10613. } );
  10614. } );
  10615. this._addClass( this.uiDialog, "ui-dialog-buttons" );
  10616. this.uiDialogButtonPane.appendTo( this.uiDialog );
  10617. },
  10618. _makeDraggable: function() {
  10619. var that = this,
  10620. options = this.options;
  10621. function filteredUi( ui ) {
  10622. return {
  10623. position: ui.position,
  10624. offset: ui.offset
  10625. };
  10626. }
  10627. this.uiDialog.draggable( {
  10628. cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
  10629. handle: ".ui-dialog-titlebar",
  10630. containment: "document",
  10631. start: function( event, ui ) {
  10632. that._addClass( $( this ), "ui-dialog-dragging" );
  10633. that._blockFrames();
  10634. that._trigger( "dragStart", event, filteredUi( ui ) );
  10635. },
  10636. drag: function( event, ui ) {
  10637. that._trigger( "drag", event, filteredUi( ui ) );
  10638. },
  10639. stop: function( event, ui ) {
  10640. var left = ui.offset.left - that.document.scrollLeft(),
  10641. top = ui.offset.top - that.document.scrollTop();
  10642. options.position = {
  10643. my: "left top",
  10644. at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
  10645. "top" + ( top >= 0 ? "+" : "" ) + top,
  10646. of: that.window
  10647. };
  10648. that._removeClass( $( this ), "ui-dialog-dragging" );
  10649. that._unblockFrames();
  10650. that._trigger( "dragStop", event, filteredUi( ui ) );
  10651. }
  10652. } );
  10653. },
  10654. _makeResizable: function() {
  10655. var that = this,
  10656. options = this.options,
  10657. handles = options.resizable,
  10658. // .ui-resizable has position: relative defined in the stylesheet
  10659. // but dialogs have to use absolute or fixed positioning
  10660. position = this.uiDialog.css( "position" ),
  10661. resizeHandles = typeof handles === "string" ?
  10662. handles :
  10663. "n,e,s,w,se,sw,ne,nw";
  10664. function filteredUi( ui ) {
  10665. return {
  10666. originalPosition: ui.originalPosition,
  10667. originalSize: ui.originalSize,
  10668. position: ui.position,
  10669. size: ui.size
  10670. };
  10671. }
  10672. this.uiDialog.resizable( {
  10673. cancel: ".ui-dialog-content",
  10674. containment: "document",
  10675. alsoResize: this.element,
  10676. maxWidth: options.maxWidth,
  10677. maxHeight: options.maxHeight,
  10678. minWidth: options.minWidth,
  10679. minHeight: this._minHeight(),
  10680. handles: resizeHandles,
  10681. start: function( event, ui ) {
  10682. that._addClass( $( this ), "ui-dialog-resizing" );
  10683. that._blockFrames();
  10684. that._trigger( "resizeStart", event, filteredUi( ui ) );
  10685. },
  10686. resize: function( event, ui ) {
  10687. that._trigger( "resize", event, filteredUi( ui ) );
  10688. },
  10689. stop: function( event, ui ) {
  10690. var offset = that.uiDialog.offset(),
  10691. left = offset.left - that.document.scrollLeft(),
  10692. top = offset.top - that.document.scrollTop();
  10693. options.height = that.uiDialog.height();
  10694. options.width = that.uiDialog.width();
  10695. options.position = {
  10696. my: "left top",
  10697. at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
  10698. "top" + ( top >= 0 ? "+" : "" ) + top,
  10699. of: that.window
  10700. };
  10701. that._removeClass( $( this ), "ui-dialog-resizing" );
  10702. that._unblockFrames();
  10703. that._trigger( "resizeStop", event, filteredUi( ui ) );
  10704. }
  10705. } )
  10706. .css( "position", position );
  10707. },
  10708. _trackFocus: function() {
  10709. this._on( this.widget(), {
  10710. focusin: function( event ) {
  10711. this._makeFocusTarget();
  10712. this._focusedElement = $( event.target );
  10713. }
  10714. } );
  10715. },
  10716. _makeFocusTarget: function() {
  10717. this._untrackInstance();
  10718. this._trackingInstances().unshift( this );
  10719. },
  10720. _untrackInstance: function() {
  10721. var instances = this._trackingInstances(),
  10722. exists = $.inArray( this, instances );
  10723. if ( exists !== -1 ) {
  10724. instances.splice( exists, 1 );
  10725. }
  10726. },
  10727. _trackingInstances: function() {
  10728. var instances = this.document.data( "ui-dialog-instances" );
  10729. if ( !instances ) {
  10730. instances = [];
  10731. this.document.data( "ui-dialog-instances", instances );
  10732. }
  10733. return instances;
  10734. },
  10735. _minHeight: function() {
  10736. var options = this.options;
  10737. return options.height === "auto" ?
  10738. options.minHeight :
  10739. Math.min( options.minHeight, options.height );
  10740. },
  10741. _position: function() {
  10742. // Need to show the dialog to get the actual offset in the position plugin
  10743. var isVisible = this.uiDialog.is( ":visible" );
  10744. if ( !isVisible ) {
  10745. this.uiDialog.show();
  10746. }
  10747. this.uiDialog.position( this.options.position );
  10748. if ( !isVisible ) {
  10749. this.uiDialog.hide();
  10750. }
  10751. },
  10752. _setOptions: function( options ) {
  10753. var that = this,
  10754. resize = false,
  10755. resizableOptions = {};
  10756. $.each( options, function( key, value ) {
  10757. that._setOption( key, value );
  10758. if ( key in that.sizeRelatedOptions ) {
  10759. resize = true;
  10760. }
  10761. if ( key in that.resizableRelatedOptions ) {
  10762. resizableOptions[ key ] = value;
  10763. }
  10764. } );
  10765. if ( resize ) {
  10766. this._size();
  10767. this._position();
  10768. }
  10769. if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
  10770. this.uiDialog.resizable( "option", resizableOptions );
  10771. }
  10772. },
  10773. _setOption: function( key, value ) {
  10774. var isDraggable, isResizable,
  10775. uiDialog = this.uiDialog;
  10776. if ( key === "disabled" ) {
  10777. return;
  10778. }
  10779. this._super( key, value );
  10780. if ( key === "appendTo" ) {
  10781. this.uiDialog.appendTo( this._appendTo() );
  10782. }
  10783. if ( key === "buttons" ) {
  10784. this._createButtons();
  10785. }
  10786. if ( key === "closeText" ) {
  10787. this.uiDialogTitlebarClose.button( {
  10788. // Ensure that we always pass a string
  10789. label: $( "<a>" ).text( "" + this.options.closeText ).html()
  10790. } );
  10791. }
  10792. if ( key === "draggable" ) {
  10793. isDraggable = uiDialog.is( ":data(ui-draggable)" );
  10794. if ( isDraggable && !value ) {
  10795. uiDialog.draggable( "destroy" );
  10796. }
  10797. if ( !isDraggable && value ) {
  10798. this._makeDraggable();
  10799. }
  10800. }
  10801. if ( key === "position" ) {
  10802. this._position();
  10803. }
  10804. if ( key === "resizable" ) {
  10805. // currently resizable, becoming non-resizable
  10806. isResizable = uiDialog.is( ":data(ui-resizable)" );
  10807. if ( isResizable && !value ) {
  10808. uiDialog.resizable( "destroy" );
  10809. }
  10810. // Currently resizable, changing handles
  10811. if ( isResizable && typeof value === "string" ) {
  10812. uiDialog.resizable( "option", "handles", value );
  10813. }
  10814. // Currently non-resizable, becoming resizable
  10815. if ( !isResizable && value !== false ) {
  10816. this._makeResizable();
  10817. }
  10818. }
  10819. if ( key === "title" ) {
  10820. this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
  10821. }
  10822. if ( key === "modal" ) {
  10823. uiDialog.attr( "aria-modal", value ? "true" : null );
  10824. }
  10825. },
  10826. _size: function() {
  10827. // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
  10828. // divs will both have width and height set, so we need to reset them
  10829. var nonContentHeight, minContentHeight, maxContentHeight,
  10830. options = this.options;
  10831. // Reset content sizing
  10832. this.element.show().css( {
  10833. width: "auto",
  10834. minHeight: 0,
  10835. maxHeight: "none",
  10836. height: 0
  10837. } );
  10838. if ( options.minWidth > options.width ) {
  10839. options.width = options.minWidth;
  10840. }
  10841. // Reset wrapper sizing
  10842. // determine the height of all the non-content elements
  10843. nonContentHeight = this.uiDialog.css( {
  10844. height: "auto",
  10845. width: options.width
  10846. } )
  10847. .outerHeight();
  10848. minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
  10849. maxContentHeight = typeof options.maxHeight === "number" ?
  10850. Math.max( 0, options.maxHeight - nonContentHeight ) :
  10851. "none";
  10852. if ( options.height === "auto" ) {
  10853. this.element.css( {
  10854. minHeight: minContentHeight,
  10855. maxHeight: maxContentHeight,
  10856. height: "auto"
  10857. } );
  10858. } else {
  10859. this.element.height( Math.max( 0, options.height - nonContentHeight ) );
  10860. }
  10861. if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
  10862. this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
  10863. }
  10864. },
  10865. _blockFrames: function() {
  10866. this.iframeBlocks = this.document.find( "iframe" ).map( function() {
  10867. var iframe = $( this );
  10868. return $( "<div>" )
  10869. .css( {
  10870. position: "absolute",
  10871. width: iframe.outerWidth(),
  10872. height: iframe.outerHeight()
  10873. } )
  10874. .appendTo( iframe.parent() )
  10875. .offset( iframe.offset() )[ 0 ];
  10876. } );
  10877. },
  10878. _unblockFrames: function() {
  10879. if ( this.iframeBlocks ) {
  10880. this.iframeBlocks.remove();
  10881. delete this.iframeBlocks;
  10882. }
  10883. },
  10884. _allowInteraction: function( event ) {
  10885. if ( $( event.target ).closest( ".ui-dialog" ).length ) {
  10886. return true;
  10887. }
  10888. // TODO: Remove hack when datepicker implements
  10889. // the .ui-front logic (#8989)
  10890. return !!$( event.target ).closest( ".ui-datepicker" ).length;
  10891. },
  10892. _createOverlay: function() {
  10893. if ( !this.options.modal ) {
  10894. return;
  10895. }
  10896. // We use a delay in case the overlay is created from an
  10897. // event that we're going to be cancelling (#2804)
  10898. var isOpening = true;
  10899. this._delay( function() {
  10900. isOpening = false;
  10901. } );
  10902. if ( !this.document.data( "ui-dialog-overlays" ) ) {
  10903. // Prevent use of anchors and inputs
  10904. // This doesn't use `_on()` because it is a shared event handler
  10905. // across all open modal dialogs.
  10906. this.document.on( "focusin.ui-dialog", function( event ) {
  10907. if ( isOpening ) {
  10908. return;
  10909. }
  10910. var instance = this._trackingInstances()[ 0 ];
  10911. if ( !instance._allowInteraction( event ) ) {
  10912. event.preventDefault();
  10913. instance._focusTabbable();
  10914. }
  10915. }.bind( this ) );
  10916. }
  10917. this.overlay = $( "<div>" )
  10918. .appendTo( this._appendTo() );
  10919. this._addClass( this.overlay, null, "ui-widget-overlay ui-front" );
  10920. this._on( this.overlay, {
  10921. mousedown: "_keepFocus"
  10922. } );
  10923. this.document.data( "ui-dialog-overlays",
  10924. ( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 );
  10925. },
  10926. _destroyOverlay: function() {
  10927. if ( !this.options.modal ) {
  10928. return;
  10929. }
  10930. if ( this.overlay ) {
  10931. var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
  10932. if ( !overlays ) {
  10933. this.document.off( "focusin.ui-dialog" );
  10934. this.document.removeData( "ui-dialog-overlays" );
  10935. } else {
  10936. this.document.data( "ui-dialog-overlays", overlays );
  10937. }
  10938. this.overlay.remove();
  10939. this.overlay = null;
  10940. }
  10941. }
  10942. } );
  10943. // DEPRECATED
  10944. // TODO: switch return back to widget declaration at top of file when this is removed
  10945. if ( $.uiBackCompat === true ) {
  10946. // Backcompat for dialogClass option
  10947. $.widget( "ui.dialog", $.ui.dialog, {
  10948. options: {
  10949. dialogClass: ""
  10950. },
  10951. _createWrapper: function() {
  10952. this._super();
  10953. this.uiDialog.addClass( this.options.dialogClass );
  10954. },
  10955. _setOption: function( key, value ) {
  10956. if ( key === "dialogClass" ) {
  10957. this.uiDialog
  10958. .removeClass( this.options.dialogClass )
  10959. .addClass( value );
  10960. }
  10961. this._superApply( arguments );
  10962. }
  10963. } );
  10964. }
  10965. var widgetsDialog = $.ui.dialog;
  10966. /*!
  10967. * jQuery UI Droppable 1.14.1
  10968. * https://jqueryui.com
  10969. *
  10970. * Copyright OpenJS Foundation and other contributors
  10971. * Released under the MIT license.
  10972. * https://jquery.org/license
  10973. */
  10974. //>>label: Droppable
  10975. //>>group: Interactions
  10976. //>>description: Enables drop targets for draggable elements.
  10977. //>>docs: https://api.jqueryui.com/droppable/
  10978. //>>demos: https://jqueryui.com/droppable/
  10979. $.widget( "ui.droppable", {
  10980. version: "1.14.1",
  10981. widgetEventPrefix: "drop",
  10982. options: {
  10983. accept: "*",
  10984. addClasses: true,
  10985. greedy: false,
  10986. scope: "default",
  10987. tolerance: "intersect",
  10988. // Callbacks
  10989. activate: null,
  10990. deactivate: null,
  10991. drop: null,
  10992. out: null,
  10993. over: null
  10994. },
  10995. _create: function() {
  10996. var proportions,
  10997. o = this.options,
  10998. accept = o.accept;
  10999. this.isover = false;
  11000. this.isout = true;
  11001. this.accept = typeof accept === "function" ? accept : function( d ) {
  11002. return d.is( accept );
  11003. };
  11004. this.proportions = function( /* valueToWrite */ ) {
  11005. if ( arguments.length ) {
  11006. // Store the droppable's proportions
  11007. proportions = arguments[ 0 ];
  11008. } else {
  11009. // Retrieve or derive the droppable's proportions
  11010. return proportions ?
  11011. proportions :
  11012. proportions = {
  11013. width: this.element[ 0 ].offsetWidth,
  11014. height: this.element[ 0 ].offsetHeight
  11015. };
  11016. }
  11017. };
  11018. this._addToManager( o.scope );
  11019. if ( o.addClasses ) {
  11020. this._addClass( "ui-droppable" );
  11021. }
  11022. },
  11023. _addToManager: function( scope ) {
  11024. // Add the reference and positions to the manager
  11025. $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
  11026. $.ui.ddmanager.droppables[ scope ].push( this );
  11027. },
  11028. _splice: function( drop ) {
  11029. var i = 0;
  11030. for ( ; i < drop.length; i++ ) {
  11031. if ( drop[ i ] === this ) {
  11032. drop.splice( i, 1 );
  11033. }
  11034. }
  11035. },
  11036. _destroy: function() {
  11037. var drop = $.ui.ddmanager.droppables[ this.options.scope ];
  11038. this._splice( drop );
  11039. },
  11040. _setOption: function( key, value ) {
  11041. if ( key === "accept" ) {
  11042. this.accept = typeof value === "function" ? value : function( d ) {
  11043. return d.is( value );
  11044. };
  11045. } else if ( key === "scope" ) {
  11046. var drop = $.ui.ddmanager.droppables[ this.options.scope ];
  11047. this._splice( drop );
  11048. this._addToManager( value );
  11049. }
  11050. this._super( key, value );
  11051. },
  11052. _activate: function( event ) {
  11053. var draggable = $.ui.ddmanager.current;
  11054. this._addActiveClass();
  11055. if ( draggable ) {
  11056. this._trigger( "activate", event, this.ui( draggable ) );
  11057. }
  11058. },
  11059. _deactivate: function( event ) {
  11060. var draggable = $.ui.ddmanager.current;
  11061. this._removeActiveClass();
  11062. if ( draggable ) {
  11063. this._trigger( "deactivate", event, this.ui( draggable ) );
  11064. }
  11065. },
  11066. _over: function( event ) {
  11067. var draggable = $.ui.ddmanager.current;
  11068. // Bail if draggable and droppable are same element
  11069. if ( !draggable || ( draggable.currentItem ||
  11070. draggable.element )[ 0 ] === this.element[ 0 ] ) {
  11071. return;
  11072. }
  11073. if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
  11074. draggable.element ) ) ) {
  11075. this._addHoverClass();
  11076. this._trigger( "over", event, this.ui( draggable ) );
  11077. }
  11078. },
  11079. _out: function( event ) {
  11080. var draggable = $.ui.ddmanager.current;
  11081. // Bail if draggable and droppable are same element
  11082. if ( !draggable || ( draggable.currentItem ||
  11083. draggable.element )[ 0 ] === this.element[ 0 ] ) {
  11084. return;
  11085. }
  11086. if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
  11087. draggable.element ) ) ) {
  11088. this._removeHoverClass();
  11089. this._trigger( "out", event, this.ui( draggable ) );
  11090. }
  11091. },
  11092. _drop: function( event, custom ) {
  11093. var draggable = custom || $.ui.ddmanager.current,
  11094. childrenIntersection = false;
  11095. // Bail if draggable and droppable are same element
  11096. if ( !draggable || ( draggable.currentItem ||
  11097. draggable.element )[ 0 ] === this.element[ 0 ] ) {
  11098. return false;
  11099. }
  11100. this.element
  11101. .find( ":data(ui-droppable)" )
  11102. .not( ".ui-draggable-dragging" )
  11103. .each( function() {
  11104. var inst = $( this ).droppable( "instance" );
  11105. if (
  11106. inst.options.greedy &&
  11107. !inst.options.disabled &&
  11108. inst.options.scope === draggable.options.scope &&
  11109. inst.accept.call(
  11110. inst.element[ 0 ], ( draggable.currentItem || draggable.element )
  11111. ) &&
  11112. $.ui.intersect(
  11113. draggable,
  11114. $.extend( inst, { offset: inst.element.offset() } ),
  11115. inst.options.tolerance, event
  11116. )
  11117. ) {
  11118. childrenIntersection = true;
  11119. return false;
  11120. }
  11121. } );
  11122. if ( childrenIntersection ) {
  11123. return false;
  11124. }
  11125. if ( this.accept.call( this.element[ 0 ],
  11126. ( draggable.currentItem || draggable.element ) ) ) {
  11127. this._removeActiveClass();
  11128. this._removeHoverClass();
  11129. this._trigger( "drop", event, this.ui( draggable ) );
  11130. return this.element;
  11131. }
  11132. return false;
  11133. },
  11134. ui: function( c ) {
  11135. return {
  11136. draggable: ( c.currentItem || c.element ),
  11137. helper: c.helper,
  11138. position: c.position,
  11139. offset: c.positionAbs
  11140. };
  11141. },
  11142. // Extension points just to make backcompat sane and avoid duplicating logic
  11143. // TODO: Remove in 1.14 along with call to it below
  11144. _addHoverClass: function() {
  11145. this._addClass( "ui-droppable-hover" );
  11146. },
  11147. _removeHoverClass: function() {
  11148. this._removeClass( "ui-droppable-hover" );
  11149. },
  11150. _addActiveClass: function() {
  11151. this._addClass( "ui-droppable-active" );
  11152. },
  11153. _removeActiveClass: function() {
  11154. this._removeClass( "ui-droppable-active" );
  11155. }
  11156. } );
  11157. $.ui.intersect = ( function() {
  11158. function isOverAxis( x, reference, size ) {
  11159. return ( x >= reference ) && ( x < ( reference + size ) );
  11160. }
  11161. return function( draggable, droppable, toleranceMode, event ) {
  11162. if ( !droppable.offset ) {
  11163. return false;
  11164. }
  11165. var x1 = ( draggable.positionAbs ||
  11166. draggable.position.absolute ).left + draggable.margins.left,
  11167. y1 = ( draggable.positionAbs ||
  11168. draggable.position.absolute ).top + draggable.margins.top,
  11169. x2 = x1 + draggable.helperProportions.width,
  11170. y2 = y1 + draggable.helperProportions.height,
  11171. l = droppable.offset.left,
  11172. t = droppable.offset.top,
  11173. r = l + droppable.proportions().width,
  11174. b = t + droppable.proportions().height;
  11175. switch ( toleranceMode ) {
  11176. case "fit":
  11177. return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
  11178. case "intersect":
  11179. return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
  11180. x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
  11181. t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
  11182. y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
  11183. case "pointer":
  11184. return isOverAxis( event.pageY, t, droppable.proportions().height ) &&
  11185. isOverAxis( event.pageX, l, droppable.proportions().width );
  11186. case "touch":
  11187. return (
  11188. ( y1 >= t && y1 <= b ) || // Top edge touching
  11189. ( y2 >= t && y2 <= b ) || // Bottom edge touching
  11190. ( y1 < t && y2 > b ) // Surrounded vertically
  11191. ) && (
  11192. ( x1 >= l && x1 <= r ) || // Left edge touching
  11193. ( x2 >= l && x2 <= r ) || // Right edge touching
  11194. ( x1 < l && x2 > r ) // Surrounded horizontally
  11195. );
  11196. default:
  11197. return false;
  11198. }
  11199. };
  11200. } )();
  11201. /*
  11202. This manager tracks offsets of draggables and droppables
  11203. */
  11204. $.ui.ddmanager = {
  11205. current: null,
  11206. droppables: { "default": [] },
  11207. prepareOffsets: function( t, event ) {
  11208. var i, j,
  11209. m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
  11210. type = event ? event.type : null, // workaround for #2317
  11211. list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
  11212. droppablesLoop: for ( i = 0; i < m.length; i++ ) {
  11213. // No disabled and non-accepted
  11214. if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ],
  11215. ( t.currentItem || t.element ) ) ) ) {
  11216. continue;
  11217. }
  11218. // Filter out elements in the current dragged item
  11219. for ( j = 0; j < list.length; j++ ) {
  11220. if ( list[ j ] === m[ i ].element[ 0 ] ) {
  11221. m[ i ].proportions().height = 0;
  11222. continue droppablesLoop;
  11223. }
  11224. }
  11225. m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
  11226. if ( !m[ i ].visible ) {
  11227. continue;
  11228. }
  11229. // Activate the droppable if used directly from draggables
  11230. if ( type === "mousedown" ) {
  11231. m[ i ]._activate.call( m[ i ], event );
  11232. }
  11233. m[ i ].offset = m[ i ].element.offset();
  11234. m[ i ].proportions( {
  11235. width: m[ i ].element[ 0 ].offsetWidth,
  11236. height: m[ i ].element[ 0 ].offsetHeight
  11237. } );
  11238. }
  11239. },
  11240. drop: function( draggable, event ) {
  11241. var dropped = false;
  11242. // Create a copy of the droppables in case the list changes during the drop (#9116)
  11243. $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
  11244. if ( !this.options ) {
  11245. return;
  11246. }
  11247. if ( !this.options.disabled && this.visible &&
  11248. $.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
  11249. dropped = this._drop.call( this, event ) || dropped;
  11250. }
  11251. if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ],
  11252. ( draggable.currentItem || draggable.element ) ) ) {
  11253. this.isout = true;
  11254. this.isover = false;
  11255. this._deactivate.call( this, event );
  11256. }
  11257. } );
  11258. return dropped;
  11259. },
  11260. dragStart: function( draggable, event ) {
  11261. // Listen for scrolling so that if the dragging causes scrolling the position of the
  11262. // droppables can be recalculated (see #5003)
  11263. draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() {
  11264. if ( !draggable.options.refreshPositions ) {
  11265. $.ui.ddmanager.prepareOffsets( draggable, event );
  11266. }
  11267. } );
  11268. },
  11269. drag: function( draggable, event ) {
  11270. // If you have a highly dynamic page, you might try this option. It renders positions
  11271. // every time you move the mouse.
  11272. if ( draggable.options.refreshPositions ) {
  11273. $.ui.ddmanager.prepareOffsets( draggable, event );
  11274. }
  11275. // Run through all droppables and check their positions based on specific tolerance options
  11276. $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
  11277. if ( this.options.disabled || this.greedyChild || !this.visible ) {
  11278. return;
  11279. }
  11280. var parentInstance, scope, parent,
  11281. intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
  11282. c = !intersects && this.isover ?
  11283. "isout" :
  11284. ( intersects && !this.isover ? "isover" : null );
  11285. if ( !c ) {
  11286. return;
  11287. }
  11288. if ( this.options.greedy ) {
  11289. // find droppable parents with same scope
  11290. scope = this.options.scope;
  11291. parent = this.element.parents( ":data(ui-droppable)" ).filter( function() {
  11292. return $( this ).droppable( "instance" ).options.scope === scope;
  11293. } );
  11294. if ( parent.length ) {
  11295. parentInstance = $( parent[ 0 ] ).droppable( "instance" );
  11296. parentInstance.greedyChild = ( c === "isover" );
  11297. }
  11298. }
  11299. // We just moved into a greedy child
  11300. if ( parentInstance && c === "isover" ) {
  11301. parentInstance.isover = false;
  11302. parentInstance.isout = true;
  11303. parentInstance._out.call( parentInstance, event );
  11304. }
  11305. this[ c ] = true;
  11306. this[ c === "isout" ? "isover" : "isout" ] = false;
  11307. this[ c === "isover" ? "_over" : "_out" ].call( this, event );
  11308. // We just moved out of a greedy child
  11309. if ( parentInstance && c === "isout" ) {
  11310. parentInstance.isout = false;
  11311. parentInstance.isover = true;
  11312. parentInstance._over.call( parentInstance, event );
  11313. }
  11314. } );
  11315. },
  11316. dragStop: function( draggable, event ) {
  11317. draggable.element.parentsUntil( "body" ).off( "scroll.droppable" );
  11318. // Call prepareOffsets one final time since IE does not fire return scroll events when
  11319. // overflow was caused by drag (see #5003)
  11320. if ( !draggable.options.refreshPositions ) {
  11321. $.ui.ddmanager.prepareOffsets( draggable, event );
  11322. }
  11323. }
  11324. };
  11325. // DEPRECATED
  11326. // TODO: switch return back to widget declaration at top of file when this is removed
  11327. if ( $.uiBackCompat === true ) {
  11328. // Backcompat for activeClass and hoverClass options
  11329. $.widget( "ui.droppable", $.ui.droppable, {
  11330. options: {
  11331. hoverClass: false,
  11332. activeClass: false
  11333. },
  11334. _addActiveClass: function() {
  11335. this._super();
  11336. if ( this.options.activeClass ) {
  11337. this.element.addClass( this.options.activeClass );
  11338. }
  11339. },
  11340. _removeActiveClass: function() {
  11341. this._super();
  11342. if ( this.options.activeClass ) {
  11343. this.element.removeClass( this.options.activeClass );
  11344. }
  11345. },
  11346. _addHoverClass: function() {
  11347. this._super();
  11348. if ( this.options.hoverClass ) {
  11349. this.element.addClass( this.options.hoverClass );
  11350. }
  11351. },
  11352. _removeHoverClass: function() {
  11353. this._super();
  11354. if ( this.options.hoverClass ) {
  11355. this.element.removeClass( this.options.hoverClass );
  11356. }
  11357. }
  11358. } );
  11359. }
  11360. var widgetsDroppable = $.ui.droppable;
  11361. /*!
  11362. * jQuery UI Progressbar 1.14.1
  11363. * https://jqueryui.com
  11364. *
  11365. * Copyright OpenJS Foundation and other contributors
  11366. * Released under the MIT license.
  11367. * https://jquery.org/license
  11368. */
  11369. //>>label: Progressbar
  11370. //>>group: Widgets
  11371. /* eslint-disable max-len */
  11372. //>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators.
  11373. /* eslint-enable max-len */
  11374. //>>docs: https://api.jqueryui.com/progressbar/
  11375. //>>demos: https://jqueryui.com/progressbar/
  11376. //>>css.structure: ../../themes/base/core.css
  11377. //>>css.structure: ../../themes/base/progressbar.css
  11378. //>>css.theme: ../../themes/base/theme.css
  11379. var widgetsProgressbar = $.widget( "ui.progressbar", {
  11380. version: "1.14.1",
  11381. options: {
  11382. classes: {
  11383. "ui-progressbar": "ui-corner-all",
  11384. "ui-progressbar-value": "ui-corner-left",
  11385. "ui-progressbar-complete": "ui-corner-right"
  11386. },
  11387. max: 100,
  11388. value: 0,
  11389. change: null,
  11390. complete: null
  11391. },
  11392. min: 0,
  11393. _create: function() {
  11394. // Constrain initial value
  11395. this.oldValue = this.options.value = this._constrainedValue();
  11396. this.element.attr( {
  11397. // Only set static values; aria-valuenow and aria-valuemax are
  11398. // set inside _refreshValue()
  11399. role: "progressbar",
  11400. "aria-valuemin": this.min
  11401. } );
  11402. this._addClass( "ui-progressbar", "ui-widget ui-widget-content" );
  11403. this.valueDiv = $( "<div>" ).appendTo( this.element );
  11404. this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" );
  11405. this._refreshValue();
  11406. },
  11407. _destroy: function() {
  11408. this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" );
  11409. this.valueDiv.remove();
  11410. },
  11411. value: function( newValue ) {
  11412. if ( newValue === undefined ) {
  11413. return this.options.value;
  11414. }
  11415. this.options.value = this._constrainedValue( newValue );
  11416. this._refreshValue();
  11417. },
  11418. _constrainedValue: function( newValue ) {
  11419. if ( newValue === undefined ) {
  11420. newValue = this.options.value;
  11421. }
  11422. this.indeterminate = newValue === false;
  11423. // Sanitize value
  11424. if ( typeof newValue !== "number" ) {
  11425. newValue = 0;
  11426. }
  11427. return this.indeterminate ? false :
  11428. Math.min( this.options.max, Math.max( this.min, newValue ) );
  11429. },
  11430. _setOptions: function( options ) {
  11431. // Ensure "value" option is set after other values (like max)
  11432. var value = options.value;
  11433. delete options.value;
  11434. this._super( options );
  11435. this.options.value = this._constrainedValue( value );
  11436. this._refreshValue();
  11437. },
  11438. _setOption: function( key, value ) {
  11439. if ( key === "max" ) {
  11440. // Don't allow a max less than min
  11441. value = Math.max( this.min, value );
  11442. }
  11443. this._super( key, value );
  11444. },
  11445. _setOptionDisabled: function( value ) {
  11446. this._super( value );
  11447. this.element.attr( "aria-disabled", value );
  11448. this._toggleClass( null, "ui-state-disabled", !!value );
  11449. },
  11450. _percentage: function() {
  11451. return this.indeterminate ?
  11452. 100 :
  11453. 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
  11454. },
  11455. _refreshValue: function() {
  11456. var value = this.options.value,
  11457. percentage = this._percentage();
  11458. this.valueDiv
  11459. .toggle( this.indeterminate || value > this.min )
  11460. .width( percentage.toFixed( 0 ) + "%" );
  11461. this
  11462. ._toggleClass( this.valueDiv, "ui-progressbar-complete", null,
  11463. value === this.options.max )
  11464. ._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate );
  11465. if ( this.indeterminate ) {
  11466. this.element.removeAttr( "aria-valuenow" );
  11467. if ( !this.overlayDiv ) {
  11468. this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv );
  11469. this._addClass( this.overlayDiv, "ui-progressbar-overlay" );
  11470. }
  11471. } else {
  11472. this.element.attr( {
  11473. "aria-valuemax": this.options.max,
  11474. "aria-valuenow": value
  11475. } );
  11476. if ( this.overlayDiv ) {
  11477. this.overlayDiv.remove();
  11478. this.overlayDiv = null;
  11479. }
  11480. }
  11481. if ( this.oldValue !== value ) {
  11482. this.oldValue = value;
  11483. this._trigger( "change" );
  11484. }
  11485. if ( value === this.options.max ) {
  11486. this._trigger( "complete" );
  11487. }
  11488. }
  11489. } );
  11490. /*!
  11491. * jQuery UI Selectable 1.14.1
  11492. * https://jqueryui.com
  11493. *
  11494. * Copyright OpenJS Foundation and other contributors
  11495. * Released under the MIT license.
  11496. * https://jquery.org/license
  11497. */
  11498. //>>label: Selectable
  11499. //>>group: Interactions
  11500. //>>description: Allows groups of elements to be selected with the mouse.
  11501. //>>docs: https://api.jqueryui.com/selectable/
  11502. //>>demos: https://jqueryui.com/selectable/
  11503. //>>css.structure: ../../themes/base/selectable.css
  11504. var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, {
  11505. version: "1.14.1",
  11506. options: {
  11507. appendTo: "body",
  11508. autoRefresh: true,
  11509. distance: 0,
  11510. filter: "*",
  11511. tolerance: "touch",
  11512. // Callbacks
  11513. selected: null,
  11514. selecting: null,
  11515. start: null,
  11516. stop: null,
  11517. unselected: null,
  11518. unselecting: null
  11519. },
  11520. _create: function() {
  11521. var that = this;
  11522. this._addClass( "ui-selectable" );
  11523. this.dragged = false;
  11524. // Cache selectee children based on filter
  11525. this.refresh = function() {
  11526. that.elementPos = $( that.element[ 0 ] ).offset();
  11527. that.selectees = $( that.options.filter, that.element[ 0 ] );
  11528. that._addClass( that.selectees, "ui-selectee" );
  11529. that.selectees.each( function() {
  11530. var $this = $( this ),
  11531. selecteeOffset = $this.offset(),
  11532. pos = {
  11533. left: selecteeOffset.left - that.elementPos.left,
  11534. top: selecteeOffset.top - that.elementPos.top
  11535. };
  11536. $.data( this, "selectable-item", {
  11537. element: this,
  11538. $element: $this,
  11539. left: pos.left,
  11540. top: pos.top,
  11541. right: pos.left + $this.outerWidth(),
  11542. bottom: pos.top + $this.outerHeight(),
  11543. startselected: false,
  11544. selected: $this.hasClass( "ui-selected" ),
  11545. selecting: $this.hasClass( "ui-selecting" ),
  11546. unselecting: $this.hasClass( "ui-unselecting" )
  11547. } );
  11548. } );
  11549. };
  11550. this.refresh();
  11551. this._mouseInit();
  11552. this.helper = $( "<div>" );
  11553. this._addClass( this.helper, "ui-selectable-helper" );
  11554. },
  11555. _destroy: function() {
  11556. this.selectees.removeData( "selectable-item" );
  11557. this._mouseDestroy();
  11558. },
  11559. _mouseStart: function( event ) {
  11560. var that = this,
  11561. options = this.options;
  11562. this.opos = [ event.pageX, event.pageY ];
  11563. this.elementPos = $( this.element[ 0 ] ).offset();
  11564. if ( this.options.disabled ) {
  11565. return;
  11566. }
  11567. this.selectees = $( options.filter, this.element[ 0 ] );
  11568. this._trigger( "start", event );
  11569. $( options.appendTo ).append( this.helper );
  11570. // position helper (lasso)
  11571. this.helper.css( {
  11572. "left": event.pageX,
  11573. "top": event.pageY,
  11574. "width": 0,
  11575. "height": 0
  11576. } );
  11577. if ( options.autoRefresh ) {
  11578. this.refresh();
  11579. }
  11580. this.selectees.filter( ".ui-selected" ).each( function() {
  11581. var selectee = $.data( this, "selectable-item" );
  11582. selectee.startselected = true;
  11583. if ( !event.metaKey && !event.ctrlKey ) {
  11584. that._removeClass( selectee.$element, "ui-selected" );
  11585. selectee.selected = false;
  11586. that._addClass( selectee.$element, "ui-unselecting" );
  11587. selectee.unselecting = true;
  11588. // selectable UNSELECTING callback
  11589. that._trigger( "unselecting", event, {
  11590. unselecting: selectee.element
  11591. } );
  11592. }
  11593. } );
  11594. $( event.target ).parents().addBack().each( function() {
  11595. var doSelect,
  11596. selectee = $.data( this, "selectable-item" );
  11597. if ( selectee ) {
  11598. doSelect = ( !event.metaKey && !event.ctrlKey ) ||
  11599. !selectee.$element.hasClass( "ui-selected" );
  11600. that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
  11601. ._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
  11602. selectee.unselecting = !doSelect;
  11603. selectee.selecting = doSelect;
  11604. selectee.selected = doSelect;
  11605. // selectable (UN)SELECTING callback
  11606. if ( doSelect ) {
  11607. that._trigger( "selecting", event, {
  11608. selecting: selectee.element
  11609. } );
  11610. } else {
  11611. that._trigger( "unselecting", event, {
  11612. unselecting: selectee.element
  11613. } );
  11614. }
  11615. return false;
  11616. }
  11617. } );
  11618. },
  11619. _mouseDrag: function( event ) {
  11620. this.dragged = true;
  11621. if ( this.options.disabled ) {
  11622. return;
  11623. }
  11624. var tmp,
  11625. that = this,
  11626. options = this.options,
  11627. x1 = this.opos[ 0 ],
  11628. y1 = this.opos[ 1 ],
  11629. x2 = event.pageX,
  11630. y2 = event.pageY;
  11631. if ( x1 > x2 ) {
  11632. tmp = x2; x2 = x1; x1 = tmp;
  11633. }
  11634. if ( y1 > y2 ) {
  11635. tmp = y2; y2 = y1; y1 = tmp;
  11636. }
  11637. this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
  11638. this.selectees.each( function() {
  11639. var selectee = $.data( this, "selectable-item" ),
  11640. hit = false,
  11641. offset = {};
  11642. //prevent helper from being selected if appendTo: selectable
  11643. if ( !selectee || selectee.element === that.element[ 0 ] ) {
  11644. return;
  11645. }
  11646. offset.left = selectee.left + that.elementPos.left;
  11647. offset.right = selectee.right + that.elementPos.left;
  11648. offset.top = selectee.top + that.elementPos.top;
  11649. offset.bottom = selectee.bottom + that.elementPos.top;
  11650. if ( options.tolerance === "touch" ) {
  11651. hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
  11652. offset.bottom < y1 ) );
  11653. } else if ( options.tolerance === "fit" ) {
  11654. hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
  11655. offset.bottom < y2 );
  11656. }
  11657. if ( hit ) {
  11658. // SELECT
  11659. if ( selectee.selected ) {
  11660. that._removeClass( selectee.$element, "ui-selected" );
  11661. selectee.selected = false;
  11662. }
  11663. if ( selectee.unselecting ) {
  11664. that._removeClass( selectee.$element, "ui-unselecting" );
  11665. selectee.unselecting = false;
  11666. }
  11667. if ( !selectee.selecting ) {
  11668. that._addClass( selectee.$element, "ui-selecting" );
  11669. selectee.selecting = true;
  11670. // selectable SELECTING callback
  11671. that._trigger( "selecting", event, {
  11672. selecting: selectee.element
  11673. } );
  11674. }
  11675. } else {
  11676. // UNSELECT
  11677. if ( selectee.selecting ) {
  11678. if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
  11679. that._removeClass( selectee.$element, "ui-selecting" );
  11680. selectee.selecting = false;
  11681. that._addClass( selectee.$element, "ui-selected" );
  11682. selectee.selected = true;
  11683. } else {
  11684. that._removeClass( selectee.$element, "ui-selecting" );
  11685. selectee.selecting = false;
  11686. if ( selectee.startselected ) {
  11687. that._addClass( selectee.$element, "ui-unselecting" );
  11688. selectee.unselecting = true;
  11689. }
  11690. // selectable UNSELECTING callback
  11691. that._trigger( "unselecting", event, {
  11692. unselecting: selectee.element
  11693. } );
  11694. }
  11695. }
  11696. if ( selectee.selected ) {
  11697. if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
  11698. that._removeClass( selectee.$element, "ui-selected" );
  11699. selectee.selected = false;
  11700. that._addClass( selectee.$element, "ui-unselecting" );
  11701. selectee.unselecting = true;
  11702. // selectable UNSELECTING callback
  11703. that._trigger( "unselecting", event, {
  11704. unselecting: selectee.element
  11705. } );
  11706. }
  11707. }
  11708. }
  11709. } );
  11710. return false;
  11711. },
  11712. _mouseStop: function( event ) {
  11713. var that = this;
  11714. this.dragged = false;
  11715. $( ".ui-unselecting", this.element[ 0 ] ).each( function() {
  11716. var selectee = $.data( this, "selectable-item" );
  11717. that._removeClass( selectee.$element, "ui-unselecting" );
  11718. selectee.unselecting = false;
  11719. selectee.startselected = false;
  11720. that._trigger( "unselected", event, {
  11721. unselected: selectee.element
  11722. } );
  11723. } );
  11724. $( ".ui-selecting", this.element[ 0 ] ).each( function() {
  11725. var selectee = $.data( this, "selectable-item" );
  11726. that._removeClass( selectee.$element, "ui-selecting" )
  11727. ._addClass( selectee.$element, "ui-selected" );
  11728. selectee.selecting = false;
  11729. selectee.selected = true;
  11730. selectee.startselected = true;
  11731. that._trigger( "selected", event, {
  11732. selected: selectee.element
  11733. } );
  11734. } );
  11735. this._trigger( "stop", event );
  11736. this.helper.remove();
  11737. return false;
  11738. }
  11739. } );
  11740. /*!
  11741. * jQuery UI Selectmenu 1.14.1
  11742. * https://jqueryui.com
  11743. *
  11744. * Copyright OpenJS Foundation and other contributors
  11745. * Released under the MIT license.
  11746. * https://jquery.org/license
  11747. */
  11748. //>>label: Selectmenu
  11749. //>>group: Widgets
  11750. /* eslint-disable max-len */
  11751. //>>description: Duplicates and extends the functionality of a native HTML select element, allowing it to be customizable in behavior and appearance far beyond the limitations of a native select.
  11752. /* eslint-enable max-len */
  11753. //>>docs: https://api.jqueryui.com/selectmenu/
  11754. //>>demos: https://jqueryui.com/selectmenu/
  11755. //>>css.structure: ../../themes/base/core.css
  11756. //>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css
  11757. //>>css.theme: ../../themes/base/theme.css
  11758. var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
  11759. version: "1.14.1",
  11760. defaultElement: "<select>",
  11761. options: {
  11762. appendTo: null,
  11763. classes: {
  11764. "ui-selectmenu-button-open": "ui-corner-top",
  11765. "ui-selectmenu-button-closed": "ui-corner-all"
  11766. },
  11767. disabled: null,
  11768. icons: {
  11769. button: "ui-icon-triangle-1-s"
  11770. },
  11771. position: {
  11772. my: "left top",
  11773. at: "left bottom",
  11774. collision: "none"
  11775. },
  11776. width: false,
  11777. // Callbacks
  11778. change: null,
  11779. close: null,
  11780. focus: null,
  11781. open: null,
  11782. select: null
  11783. },
  11784. _create: function() {
  11785. var selectmenuId = this.element.uniqueId().attr( "id" );
  11786. this.ids = {
  11787. element: selectmenuId,
  11788. button: selectmenuId + "-button",
  11789. menu: selectmenuId + "-menu"
  11790. };
  11791. this._drawButton();
  11792. this._drawMenu();
  11793. this._bindFormResetHandler();
  11794. this._rendered = false;
  11795. this.menuItems = $();
  11796. },
  11797. _drawButton: function() {
  11798. var icon,
  11799. that = this,
  11800. item = this._parseOption(
  11801. this.element.find( "option:selected" ),
  11802. this.element[ 0 ].selectedIndex
  11803. );
  11804. // Associate existing label with the new button
  11805. this.labels = this.element.labels().attr( "for", this.ids.button );
  11806. this._on( this.labels, {
  11807. click: function( event ) {
  11808. this.button.trigger( "focus" );
  11809. event.preventDefault();
  11810. }
  11811. } );
  11812. // Hide original select element
  11813. this.element.hide();
  11814. // Create button
  11815. this.button = $( "<span>", {
  11816. tabindex: this.options.disabled ? -1 : 0,
  11817. id: this.ids.button,
  11818. role: "combobox",
  11819. "aria-expanded": "false",
  11820. "aria-autocomplete": "list",
  11821. "aria-owns": this.ids.menu,
  11822. "aria-haspopup": "true",
  11823. title: this.element.attr( "title" )
  11824. } )
  11825. .insertAfter( this.element );
  11826. this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed",
  11827. "ui-button ui-widget" );
  11828. icon = $( "<span>" ).appendTo( this.button );
  11829. this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button );
  11830. this.buttonItem = this._renderButtonItem( item )
  11831. .appendTo( this.button );
  11832. if ( this.options.width !== false ) {
  11833. this._resizeButton();
  11834. }
  11835. this._on( this.button, this._buttonEvents );
  11836. this.button.one( "focusin", function() {
  11837. // Delay rendering the menu items until the button receives focus.
  11838. // The menu may have already been rendered via a programmatic open.
  11839. if ( !that._rendered ) {
  11840. that._refreshMenu();
  11841. }
  11842. } );
  11843. },
  11844. _drawMenu: function() {
  11845. var that = this;
  11846. // Create menu
  11847. this.menu = $( "<ul>", {
  11848. "aria-hidden": "true",
  11849. "aria-labelledby": this.ids.button,
  11850. id: this.ids.menu
  11851. } );
  11852. // Wrap menu
  11853. this.menuWrap = $( "<div>" ).append( this.menu );
  11854. this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" );
  11855. this.menuWrap.appendTo( this._appendTo() );
  11856. // Initialize menu widget
  11857. this.menuInstance = this.menu
  11858. .menu( {
  11859. classes: {
  11860. "ui-menu": "ui-corner-bottom"
  11861. },
  11862. role: "listbox",
  11863. select: function( event, ui ) {
  11864. event.preventDefault();
  11865. that._select( ui.item.data( "ui-selectmenu-item" ), event );
  11866. },
  11867. focus: function( event, ui ) {
  11868. var item = ui.item.data( "ui-selectmenu-item" );
  11869. // Prevent inital focus from firing and check if its a newly focused item
  11870. if ( that.focusIndex != null && item.index !== that.focusIndex ) {
  11871. that._trigger( "focus", event, { item: item } );
  11872. if ( !that.isOpen ) {
  11873. that._select( item, event );
  11874. }
  11875. }
  11876. that.focusIndex = item.index;
  11877. that.button.attr( "aria-activedescendant",
  11878. that.menuItems.eq( item.index ).attr( "id" ) );
  11879. }
  11880. } )
  11881. .menu( "instance" );
  11882. // Don't close the menu on mouseleave
  11883. this.menuInstance._off( this.menu, "mouseleave" );
  11884. // Cancel the menu's collapseAll on document click
  11885. this.menuInstance._closeOnDocumentClick = function() {
  11886. return false;
  11887. };
  11888. // Selects often contain empty items, but never contain dividers
  11889. this.menuInstance._isDivider = function() {
  11890. return false;
  11891. };
  11892. },
  11893. refresh: function() {
  11894. this._refreshMenu();
  11895. this.buttonItem.replaceWith(
  11896. this.buttonItem = this._renderButtonItem(
  11897. // Fall back to an empty object in case there are no options
  11898. this._getSelectedItem().data( "ui-selectmenu-item" ) || {}
  11899. )
  11900. );
  11901. if ( this.options.width === null ) {
  11902. this._resizeButton();
  11903. }
  11904. },
  11905. _refreshMenu: function() {
  11906. var item,
  11907. options = this.element.find( "option" );
  11908. this.menu.empty();
  11909. this._parseOptions( options );
  11910. this._renderMenu( this.menu, this.items );
  11911. this.menuInstance.refresh();
  11912. this.menuItems = this.menu.find( "li" )
  11913. .not( ".ui-selectmenu-optgroup" )
  11914. .find( ".ui-menu-item-wrapper" );
  11915. this._rendered = true;
  11916. if ( !options.length ) {
  11917. return;
  11918. }
  11919. item = this._getSelectedItem();
  11920. // Update the menu to have the correct item focused
  11921. this.menuInstance.focus( null, item );
  11922. this._setAria( item.data( "ui-selectmenu-item" ) );
  11923. // Set disabled state
  11924. this._setOption( "disabled", this.element.prop( "disabled" ) );
  11925. },
  11926. open: function( event ) {
  11927. if ( this.options.disabled ) {
  11928. return;
  11929. }
  11930. // If this is the first time the menu is being opened, render the items
  11931. if ( !this._rendered ) {
  11932. this._refreshMenu();
  11933. } else {
  11934. // Menu clears focus on close, reset focus to selected item
  11935. this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" );
  11936. this.menuInstance.focus( null, this._getSelectedItem() );
  11937. }
  11938. // If there are no options, don't open the menu
  11939. if ( !this.menuItems.length ) {
  11940. return;
  11941. }
  11942. this.isOpen = true;
  11943. this._toggleAttr();
  11944. this._resizeMenu();
  11945. this._position();
  11946. this._on( this.document, this._documentClick );
  11947. this._trigger( "open", event );
  11948. },
  11949. _position: function() {
  11950. this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
  11951. },
  11952. close: function( event ) {
  11953. if ( !this.isOpen ) {
  11954. return;
  11955. }
  11956. this.isOpen = false;
  11957. this._toggleAttr();
  11958. this.range = null;
  11959. this._off( this.document );
  11960. this._trigger( "close", event );
  11961. },
  11962. widget: function() {
  11963. return this.button;
  11964. },
  11965. menuWidget: function() {
  11966. return this.menu;
  11967. },
  11968. _renderButtonItem: function( item ) {
  11969. var buttonItem = $( "<span>" );
  11970. this._setText( buttonItem, item.label );
  11971. this._addClass( buttonItem, "ui-selectmenu-text" );
  11972. return buttonItem;
  11973. },
  11974. _renderMenu: function( ul, items ) {
  11975. var that = this,
  11976. currentOptgroup = "";
  11977. $.each( items, function( index, item ) {
  11978. var li;
  11979. if ( item.optgroup !== currentOptgroup ) {
  11980. li = $( "<li>", {
  11981. text: item.optgroup
  11982. } );
  11983. that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" +
  11984. ( item.element.parent( "optgroup" ).prop( "disabled" ) ?
  11985. " ui-state-disabled" :
  11986. "" ) );
  11987. li.appendTo( ul );
  11988. currentOptgroup = item.optgroup;
  11989. }
  11990. that._renderItemData( ul, item );
  11991. } );
  11992. },
  11993. _renderItemData: function( ul, item ) {
  11994. return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
  11995. },
  11996. _renderItem: function( ul, item ) {
  11997. var li = $( "<li>" ),
  11998. wrapper = $( "<div>", {
  11999. title: item.element.attr( "title" )
  12000. } );
  12001. if ( item.disabled ) {
  12002. this._addClass( li, null, "ui-state-disabled" );
  12003. }
  12004. if ( item.hidden ) {
  12005. li.prop( "hidden", true );
  12006. } else {
  12007. this._setText( wrapper, item.label );
  12008. }
  12009. return li.append( wrapper ).appendTo( ul );
  12010. },
  12011. _setText: function( element, value ) {
  12012. if ( value ) {
  12013. element.text( value );
  12014. } else {
  12015. element.html( "&#160;" );
  12016. }
  12017. },
  12018. _move: function( direction, event ) {
  12019. var item, next,
  12020. filter = ".ui-menu-item";
  12021. if ( this.isOpen ) {
  12022. item = this.menuItems.eq( this.focusIndex ).parent( "li" );
  12023. } else {
  12024. item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
  12025. filter += ":not(.ui-state-disabled)";
  12026. }
  12027. if ( direction === "first" || direction === "last" ) {
  12028. next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
  12029. } else {
  12030. next = item[ direction + "All" ]( filter ).eq( 0 );
  12031. }
  12032. if ( next.length ) {
  12033. this.menuInstance.focus( event, next );
  12034. }
  12035. },
  12036. _getSelectedItem: function() {
  12037. return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
  12038. },
  12039. _toggle: function( event ) {
  12040. this[ this.isOpen ? "close" : "open" ]( event );
  12041. },
  12042. _setSelection: function() {
  12043. var selection;
  12044. if ( !this.range ) {
  12045. return;
  12046. }
  12047. selection = window.getSelection();
  12048. selection.removeAllRanges();
  12049. selection.addRange( this.range );
  12050. },
  12051. _documentClick: {
  12052. mousedown: function( event ) {
  12053. if ( !this.isOpen ) {
  12054. return;
  12055. }
  12056. if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" +
  12057. CSS.escape( this.ids.button ) ).length ) {
  12058. this.close( event );
  12059. }
  12060. }
  12061. },
  12062. _buttonEvents: {
  12063. // Prevent text selection from being reset when interacting with the selectmenu (#10144)
  12064. mousedown: function() {
  12065. var selection = window.getSelection();
  12066. if ( selection.rangeCount ) {
  12067. this.range = selection.getRangeAt( 0 );
  12068. }
  12069. },
  12070. click: function( event ) {
  12071. this._setSelection();
  12072. this._toggle( event );
  12073. },
  12074. keydown: function( event ) {
  12075. var preventDefault = true;
  12076. switch ( event.keyCode ) {
  12077. case $.ui.keyCode.TAB:
  12078. case $.ui.keyCode.ESCAPE:
  12079. this.close( event );
  12080. preventDefault = false;
  12081. break;
  12082. case $.ui.keyCode.ENTER:
  12083. if ( this.isOpen ) {
  12084. this._selectFocusedItem( event );
  12085. }
  12086. break;
  12087. case $.ui.keyCode.UP:
  12088. if ( event.altKey ) {
  12089. this._toggle( event );
  12090. } else {
  12091. this._move( "prev", event );
  12092. }
  12093. break;
  12094. case $.ui.keyCode.DOWN:
  12095. if ( event.altKey ) {
  12096. this._toggle( event );
  12097. } else {
  12098. this._move( "next", event );
  12099. }
  12100. break;
  12101. case $.ui.keyCode.SPACE:
  12102. if ( this.isOpen ) {
  12103. this._selectFocusedItem( event );
  12104. } else {
  12105. this._toggle( event );
  12106. }
  12107. break;
  12108. case $.ui.keyCode.LEFT:
  12109. this._move( "prev", event );
  12110. break;
  12111. case $.ui.keyCode.RIGHT:
  12112. this._move( "next", event );
  12113. break;
  12114. case $.ui.keyCode.HOME:
  12115. case $.ui.keyCode.PAGE_UP:
  12116. this._move( "first", event );
  12117. break;
  12118. case $.ui.keyCode.END:
  12119. case $.ui.keyCode.PAGE_DOWN:
  12120. this._move( "last", event );
  12121. break;
  12122. default:
  12123. this.menu.trigger( event );
  12124. preventDefault = false;
  12125. }
  12126. if ( preventDefault ) {
  12127. event.preventDefault();
  12128. }
  12129. }
  12130. },
  12131. _selectFocusedItem: function( event ) {
  12132. var item = this.menuItems.eq( this.focusIndex ).parent( "li" );
  12133. if ( !item.hasClass( "ui-state-disabled" ) ) {
  12134. this._select( item.data( "ui-selectmenu-item" ), event );
  12135. }
  12136. },
  12137. _select: function( item, event ) {
  12138. var oldIndex = this.element[ 0 ].selectedIndex;
  12139. // Change native select element
  12140. this.element[ 0 ].selectedIndex = item.index;
  12141. this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) );
  12142. this._setAria( item );
  12143. this._trigger( "select", event, { item: item } );
  12144. if ( item.index !== oldIndex ) {
  12145. this._trigger( "change", event, { item: item } );
  12146. }
  12147. this.close( event );
  12148. },
  12149. _setAria: function( item ) {
  12150. var id = this.menuItems.eq( item.index ).attr( "id" );
  12151. this.button.attr( {
  12152. "aria-labelledby": id,
  12153. "aria-activedescendant": id
  12154. } );
  12155. this.menu.attr( "aria-activedescendant", id );
  12156. },
  12157. _setOption: function( key, value ) {
  12158. if ( key === "icons" ) {
  12159. var icon = this.button.find( "span.ui-icon" );
  12160. this._removeClass( icon, null, this.options.icons.button )
  12161. ._addClass( icon, null, value.button );
  12162. }
  12163. this._super( key, value );
  12164. if ( key === "appendTo" ) {
  12165. this.menuWrap.appendTo( this._appendTo() );
  12166. }
  12167. if ( key === "width" ) {
  12168. this._resizeButton();
  12169. }
  12170. },
  12171. _setOptionDisabled: function( value ) {
  12172. this._super( value );
  12173. this.menuInstance.option( "disabled", value );
  12174. this.button.attr( "aria-disabled", value );
  12175. this._toggleClass( this.button, null, "ui-state-disabled", value );
  12176. this.element.prop( "disabled", value );
  12177. if ( value ) {
  12178. this.button.attr( "tabindex", -1 );
  12179. this.close();
  12180. } else {
  12181. this.button.attr( "tabindex", 0 );
  12182. }
  12183. },
  12184. _appendTo: function() {
  12185. var element = this.options.appendTo;
  12186. if ( element ) {
  12187. element = element.jquery || element.nodeType ?
  12188. $( element ) :
  12189. this.document.find( element ).eq( 0 );
  12190. }
  12191. if ( !element || !element[ 0 ] ) {
  12192. element = this.element.closest( ".ui-front, dialog" );
  12193. }
  12194. if ( !element.length ) {
  12195. element = this.document[ 0 ].body;
  12196. }
  12197. return element;
  12198. },
  12199. _toggleAttr: function() {
  12200. this.button.attr( "aria-expanded", this.isOpen );
  12201. // We can't use two _toggleClass() calls here, because we need to make sure
  12202. // we always remove classes first and add them second, otherwise if both classes have the
  12203. // same theme class, it will be removed after we add it.
  12204. this._removeClass( this.button, "ui-selectmenu-button-" +
  12205. ( this.isOpen ? "closed" : "open" ) )
  12206. ._addClass( this.button, "ui-selectmenu-button-" +
  12207. ( this.isOpen ? "open" : "closed" ) )
  12208. ._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen );
  12209. this.menu.attr( "aria-hidden", !this.isOpen );
  12210. },
  12211. _resizeButton: function() {
  12212. var width = this.options.width;
  12213. // For `width: false`, just remove inline style and stop
  12214. if ( width === false ) {
  12215. this.button.css( "width", "" );
  12216. return;
  12217. }
  12218. // For `width: null`, match the width of the original element
  12219. if ( width === null ) {
  12220. width = this.element.show().outerWidth();
  12221. this.element.hide();
  12222. }
  12223. this.button.outerWidth( width );
  12224. },
  12225. _resizeMenu: function() {
  12226. this.menu.outerWidth( Math.max(
  12227. this.button.outerWidth(),
  12228. this.menu.width( "" ).outerWidth()
  12229. ) );
  12230. },
  12231. _getCreateOptions: function() {
  12232. var options = this._super();
  12233. options.disabled = this.element.prop( "disabled" );
  12234. return options;
  12235. },
  12236. _parseOptions: function( options ) {
  12237. var that = this,
  12238. data = [];
  12239. options.each( function( index, item ) {
  12240. data.push( that._parseOption( $( item ), index ) );
  12241. } );
  12242. this.items = data;
  12243. },
  12244. _parseOption: function( option, index ) {
  12245. var optgroup = option.parent( "optgroup" );
  12246. return {
  12247. element: option,
  12248. index: index,
  12249. value: option.val(),
  12250. label: option.text(),
  12251. hidden: optgroup.prop( "hidden" ) || option.prop( "hidden" ),
  12252. optgroup: optgroup.attr( "label" ) || "",
  12253. disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
  12254. };
  12255. },
  12256. _destroy: function() {
  12257. this._unbindFormResetHandler();
  12258. this.menuWrap.remove();
  12259. this.button.remove();
  12260. this.element.show();
  12261. this.element.removeUniqueId();
  12262. this.labels.attr( "for", this.ids.element );
  12263. }
  12264. } ] );
  12265. /*!
  12266. * jQuery UI Slider 1.14.1
  12267. * https://jqueryui.com
  12268. *
  12269. * Copyright OpenJS Foundation and other contributors
  12270. * Released under the MIT license.
  12271. * https://jquery.org/license
  12272. */
  12273. //>>label: Slider
  12274. //>>group: Widgets
  12275. //>>description: Displays a flexible slider with ranges and accessibility via keyboard.
  12276. //>>docs: https://api.jqueryui.com/slider/
  12277. //>>demos: https://jqueryui.com/slider/
  12278. //>>css.structure: ../../themes/base/core.css
  12279. //>>css.structure: ../../themes/base/slider.css
  12280. //>>css.theme: ../../themes/base/theme.css
  12281. var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, {
  12282. version: "1.14.1",
  12283. widgetEventPrefix: "slide",
  12284. options: {
  12285. animate: false,
  12286. classes: {
  12287. "ui-slider": "ui-corner-all",
  12288. "ui-slider-handle": "ui-corner-all",
  12289. // Note: ui-widget-header isn't the most fittingly semantic framework class for this
  12290. // element, but worked best visually with a variety of themes
  12291. "ui-slider-range": "ui-corner-all ui-widget-header"
  12292. },
  12293. distance: 0,
  12294. max: 100,
  12295. min: 0,
  12296. orientation: "horizontal",
  12297. range: false,
  12298. step: 1,
  12299. value: 0,
  12300. values: null,
  12301. // Callbacks
  12302. change: null,
  12303. slide: null,
  12304. start: null,
  12305. stop: null
  12306. },
  12307. // Number of pages in a slider
  12308. // (how many times can you page up/down to go through the whole range)
  12309. numPages: 5,
  12310. _create: function() {
  12311. this._keySliding = false;
  12312. this._mouseSliding = false;
  12313. this._animateOff = true;
  12314. this._handleIndex = null;
  12315. this._detectOrientation();
  12316. this._mouseInit();
  12317. this._calculateNewMax();
  12318. this._addClass( "ui-slider ui-slider-" + this.orientation,
  12319. "ui-widget ui-widget-content" );
  12320. this._refresh();
  12321. this._animateOff = false;
  12322. },
  12323. _refresh: function() {
  12324. this._createRange();
  12325. this._createHandles();
  12326. this._setupEvents();
  12327. this._refreshValue();
  12328. },
  12329. _createHandles: function() {
  12330. var i, handleCount,
  12331. options = this.options,
  12332. existingHandles = this.element.find( ".ui-slider-handle" ),
  12333. handle = "<span tabindex='0'></span>",
  12334. handles = [];
  12335. handleCount = ( options.values && options.values.length ) || 1;
  12336. if ( existingHandles.length > handleCount ) {
  12337. existingHandles.slice( handleCount ).remove();
  12338. existingHandles = existingHandles.slice( 0, handleCount );
  12339. }
  12340. for ( i = existingHandles.length; i < handleCount; i++ ) {
  12341. handles.push( handle );
  12342. }
  12343. this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
  12344. this._addClass( this.handles, "ui-slider-handle", "ui-state-default" );
  12345. this.handle = this.handles.eq( 0 );
  12346. this.handles.each( function( i ) {
  12347. $( this )
  12348. .data( "ui-slider-handle-index", i )
  12349. .attr( "tabIndex", 0 );
  12350. } );
  12351. },
  12352. _createRange: function() {
  12353. var options = this.options;
  12354. if ( options.range ) {
  12355. if ( options.range === true ) {
  12356. if ( !options.values ) {
  12357. options.values = [ this._valueMin(), this._valueMin() ];
  12358. } else if ( options.values.length && options.values.length !== 2 ) {
  12359. options.values = [ options.values[ 0 ], options.values[ 0 ] ];
  12360. } else if ( Array.isArray( options.values ) ) {
  12361. options.values = options.values.slice( 0 );
  12362. }
  12363. }
  12364. if ( !this.range || !this.range.length ) {
  12365. this.range = $( "<div>" )
  12366. .appendTo( this.element );
  12367. this._addClass( this.range, "ui-slider-range" );
  12368. } else {
  12369. this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" );
  12370. // Handle range switching from true to min/max
  12371. this.range.css( {
  12372. "left": "",
  12373. "bottom": ""
  12374. } );
  12375. }
  12376. if ( options.range === "min" || options.range === "max" ) {
  12377. this._addClass( this.range, "ui-slider-range-" + options.range );
  12378. }
  12379. } else {
  12380. if ( this.range ) {
  12381. this.range.remove();
  12382. }
  12383. this.range = null;
  12384. }
  12385. },
  12386. _setupEvents: function() {
  12387. this._off( this.handles );
  12388. this._on( this.handles, this._handleEvents );
  12389. this._hoverable( this.handles );
  12390. this._focusable( this.handles );
  12391. },
  12392. _destroy: function() {
  12393. this.handles.remove();
  12394. if ( this.range ) {
  12395. this.range.remove();
  12396. }
  12397. this._mouseDestroy();
  12398. },
  12399. _mouseCapture: function( event ) {
  12400. var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
  12401. that = this,
  12402. o = this.options;
  12403. if ( o.disabled ) {
  12404. return false;
  12405. }
  12406. this.elementSize = {
  12407. width: this.element.outerWidth(),
  12408. height: this.element.outerHeight()
  12409. };
  12410. this.elementOffset = this.element.offset();
  12411. position = { x: event.pageX, y: event.pageY };
  12412. normValue = this._normValueFromMouse( position );
  12413. distance = this._valueMax() - this._valueMin() + 1;
  12414. this.handles.each( function( i ) {
  12415. var thisDistance = Math.abs( normValue - that.values( i ) );
  12416. if ( ( distance > thisDistance ) ||
  12417. ( distance === thisDistance &&
  12418. ( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) {
  12419. distance = thisDistance;
  12420. closestHandle = $( this );
  12421. index = i;
  12422. }
  12423. } );
  12424. allowed = this._start( event, index );
  12425. if ( allowed === false ) {
  12426. return false;
  12427. }
  12428. this._mouseSliding = true;
  12429. this._handleIndex = index;
  12430. this._addClass( closestHandle, null, "ui-state-active" );
  12431. closestHandle.trigger( "focus" );
  12432. offset = closestHandle.offset();
  12433. mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
  12434. this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
  12435. left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
  12436. top: event.pageY - offset.top -
  12437. ( closestHandle.height() / 2 ) -
  12438. ( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) -
  12439. ( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) +
  12440. ( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 )
  12441. };
  12442. if ( !this.handles.hasClass( "ui-state-hover" ) ) {
  12443. this._slide( event, index, normValue );
  12444. }
  12445. this._animateOff = true;
  12446. return true;
  12447. },
  12448. _mouseStart: function() {
  12449. return true;
  12450. },
  12451. _mouseDrag: function( event ) {
  12452. var position = { x: event.pageX, y: event.pageY },
  12453. normValue = this._normValueFromMouse( position );
  12454. this._slide( event, this._handleIndex, normValue );
  12455. return false;
  12456. },
  12457. _mouseStop: function( event ) {
  12458. this._removeClass( this.handles, null, "ui-state-active" );
  12459. this._mouseSliding = false;
  12460. this._stop( event, this._handleIndex );
  12461. this._change( event, this._handleIndex );
  12462. this._handleIndex = null;
  12463. this._clickOffset = null;
  12464. this._animateOff = false;
  12465. return false;
  12466. },
  12467. _detectOrientation: function() {
  12468. this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
  12469. },
  12470. _normValueFromMouse: function( position ) {
  12471. var pixelTotal,
  12472. pixelMouse,
  12473. percentMouse,
  12474. valueTotal,
  12475. valueMouse;
  12476. if ( this.orientation === "horizontal" ) {
  12477. pixelTotal = this.elementSize.width;
  12478. pixelMouse = position.x - this.elementOffset.left -
  12479. ( this._clickOffset ? this._clickOffset.left : 0 );
  12480. } else {
  12481. pixelTotal = this.elementSize.height;
  12482. pixelMouse = position.y - this.elementOffset.top -
  12483. ( this._clickOffset ? this._clickOffset.top : 0 );
  12484. }
  12485. percentMouse = ( pixelMouse / pixelTotal );
  12486. if ( percentMouse > 1 ) {
  12487. percentMouse = 1;
  12488. }
  12489. if ( percentMouse < 0 ) {
  12490. percentMouse = 0;
  12491. }
  12492. if ( this.orientation === "vertical" ) {
  12493. percentMouse = 1 - percentMouse;
  12494. }
  12495. valueTotal = this._valueMax() - this._valueMin();
  12496. valueMouse = this._valueMin() + percentMouse * valueTotal;
  12497. return this._trimAlignValue( valueMouse );
  12498. },
  12499. _uiHash: function( index, value, values ) {
  12500. var uiHash = {
  12501. handle: this.handles[ index ],
  12502. handleIndex: index,
  12503. value: value !== undefined ? value : this.value()
  12504. };
  12505. if ( this._hasMultipleValues() ) {
  12506. uiHash.value = value !== undefined ? value : this.values( index );
  12507. uiHash.values = values || this.values();
  12508. }
  12509. return uiHash;
  12510. },
  12511. _hasMultipleValues: function() {
  12512. return this.options.values && this.options.values.length;
  12513. },
  12514. _start: function( event, index ) {
  12515. return this._trigger( "start", event, this._uiHash( index ) );
  12516. },
  12517. _slide: function( event, index, newVal ) {
  12518. var allowed, otherVal,
  12519. currentValue = this.value(),
  12520. newValues = this.values();
  12521. if ( this._hasMultipleValues() ) {
  12522. otherVal = this.values( index ? 0 : 1 );
  12523. currentValue = this.values( index );
  12524. if ( this.options.values.length === 2 && this.options.range === true ) {
  12525. newVal = index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal );
  12526. }
  12527. newValues[ index ] = newVal;
  12528. }
  12529. if ( newVal === currentValue ) {
  12530. return;
  12531. }
  12532. allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) );
  12533. // A slide can be canceled by returning false from the slide callback
  12534. if ( allowed === false ) {
  12535. return;
  12536. }
  12537. if ( this._hasMultipleValues() ) {
  12538. this.values( index, newVal );
  12539. } else {
  12540. this.value( newVal );
  12541. }
  12542. },
  12543. _stop: function( event, index ) {
  12544. this._trigger( "stop", event, this._uiHash( index ) );
  12545. },
  12546. _change: function( event, index ) {
  12547. if ( !this._keySliding && !this._mouseSliding ) {
  12548. //store the last changed value index for reference when handles overlap
  12549. this._lastChangedValue = index;
  12550. this._trigger( "change", event, this._uiHash( index ) );
  12551. }
  12552. },
  12553. value: function( newValue ) {
  12554. if ( arguments.length ) {
  12555. this.options.value = this._trimAlignValue( newValue );
  12556. this._refreshValue();
  12557. this._change( null, 0 );
  12558. return;
  12559. }
  12560. return this._value();
  12561. },
  12562. values: function( index, newValue ) {
  12563. var vals,
  12564. newValues,
  12565. i;
  12566. if ( arguments.length > 1 ) {
  12567. this.options.values[ index ] = this._trimAlignValue( newValue );
  12568. this._refreshValue();
  12569. this._change( null, index );
  12570. return;
  12571. }
  12572. if ( arguments.length ) {
  12573. if ( Array.isArray( arguments[ 0 ] ) ) {
  12574. vals = this.options.values;
  12575. newValues = arguments[ 0 ];
  12576. for ( i = 0; i < vals.length; i += 1 ) {
  12577. vals[ i ] = this._trimAlignValue( newValues[ i ] );
  12578. this._change( null, i );
  12579. }
  12580. this._refreshValue();
  12581. } else {
  12582. if ( this._hasMultipleValues() ) {
  12583. return this._values( index );
  12584. } else {
  12585. return this.value();
  12586. }
  12587. }
  12588. } else {
  12589. return this._values();
  12590. }
  12591. },
  12592. _setOption: function( key, value ) {
  12593. var i,
  12594. valsLength = 0;
  12595. if ( key === "range" && this.options.range === true ) {
  12596. if ( value === "min" ) {
  12597. this.options.value = this._values( 0 );
  12598. this.options.values = null;
  12599. } else if ( value === "max" ) {
  12600. this.options.value = this._values( this.options.values.length - 1 );
  12601. this.options.values = null;
  12602. }
  12603. }
  12604. if ( Array.isArray( this.options.values ) ) {
  12605. valsLength = this.options.values.length;
  12606. }
  12607. this._super( key, value );
  12608. switch ( key ) {
  12609. case "orientation":
  12610. this._detectOrientation();
  12611. this._removeClass( "ui-slider-horizontal ui-slider-vertical" )
  12612. ._addClass( "ui-slider-" + this.orientation );
  12613. this._refreshValue();
  12614. if ( this.options.range ) {
  12615. this._refreshRange( value );
  12616. }
  12617. // Reset positioning from previous orientation
  12618. this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
  12619. break;
  12620. case "value":
  12621. this._animateOff = true;
  12622. this._refreshValue();
  12623. this._change( null, 0 );
  12624. this._animateOff = false;
  12625. break;
  12626. case "values":
  12627. this._animateOff = true;
  12628. this._refreshValue();
  12629. // Start from the last handle to prevent unreachable handles (#9046)
  12630. for ( i = valsLength - 1; i >= 0; i-- ) {
  12631. this._change( null, i );
  12632. }
  12633. this._animateOff = false;
  12634. break;
  12635. case "step":
  12636. case "min":
  12637. case "max":
  12638. this._animateOff = true;
  12639. this._calculateNewMax();
  12640. this._refreshValue();
  12641. this._animateOff = false;
  12642. break;
  12643. case "range":
  12644. this._animateOff = true;
  12645. this._refresh();
  12646. this._animateOff = false;
  12647. break;
  12648. }
  12649. },
  12650. _setOptionDisabled: function( value ) {
  12651. this._super( value );
  12652. this._toggleClass( null, "ui-state-disabled", !!value );
  12653. },
  12654. //internal value getter
  12655. // _value() returns value trimmed by min and max, aligned by step
  12656. _value: function() {
  12657. var val = this.options.value;
  12658. val = this._trimAlignValue( val );
  12659. return val;
  12660. },
  12661. //internal values getter
  12662. // _values() returns array of values trimmed by min and max, aligned by step
  12663. // _values( index ) returns single value trimmed by min and max, aligned by step
  12664. _values: function( index ) {
  12665. var val,
  12666. vals,
  12667. i;
  12668. if ( arguments.length ) {
  12669. val = this.options.values[ index ];
  12670. val = this._trimAlignValue( val );
  12671. return val;
  12672. } else if ( this._hasMultipleValues() ) {
  12673. // .slice() creates a copy of the array
  12674. // this copy gets trimmed by min and max and then returned
  12675. vals = this.options.values.slice();
  12676. for ( i = 0; i < vals.length; i += 1 ) {
  12677. vals[ i ] = this._trimAlignValue( vals[ i ] );
  12678. }
  12679. return vals;
  12680. } else {
  12681. return [];
  12682. }
  12683. },
  12684. // Returns the step-aligned value that val is closest to, between (inclusive) min and max
  12685. _trimAlignValue: function( val ) {
  12686. if ( val <= this._valueMin() ) {
  12687. return this._valueMin();
  12688. }
  12689. if ( val >= this._valueMax() ) {
  12690. return this._valueMax();
  12691. }
  12692. var step = ( this.options.step > 0 ) ? this.options.step : 1,
  12693. valModStep = ( val - this._valueMin() ) % step,
  12694. alignValue = val - valModStep;
  12695. if ( Math.abs( valModStep ) * 2 >= step ) {
  12696. alignValue += ( valModStep > 0 ) ? step : ( -step );
  12697. }
  12698. // Since JavaScript has problems with large floats, round
  12699. // the final value to 5 digits after the decimal point (see #4124)
  12700. return parseFloat( alignValue.toFixed( 5 ) );
  12701. },
  12702. _calculateNewMax: function() {
  12703. var max = this.options.max,
  12704. min = this._valueMin(),
  12705. step = this.options.step,
  12706. aboveMin = Math.round( ( max - min ) / step ) * step;
  12707. max = aboveMin + min;
  12708. if ( max > this.options.max ) {
  12709. //If max is not divisible by step, rounding off may increase its value
  12710. max -= step;
  12711. }
  12712. this.max = parseFloat( max.toFixed( this._precision() ) );
  12713. },
  12714. _precision: function() {
  12715. var precision = this._precisionOf( this.options.step );
  12716. if ( this.options.min !== null ) {
  12717. precision = Math.max( precision, this._precisionOf( this.options.min ) );
  12718. }
  12719. return precision;
  12720. },
  12721. _precisionOf: function( num ) {
  12722. var str = num.toString(),
  12723. decimal = str.indexOf( "." );
  12724. return decimal === -1 ? 0 : str.length - decimal - 1;
  12725. },
  12726. _valueMin: function() {
  12727. return this.options.min;
  12728. },
  12729. _valueMax: function() {
  12730. return this.max;
  12731. },
  12732. _refreshRange: function( orientation ) {
  12733. if ( orientation === "vertical" ) {
  12734. this.range.css( { "width": "", "left": "" } );
  12735. }
  12736. if ( orientation === "horizontal" ) {
  12737. this.range.css( { "height": "", "bottom": "" } );
  12738. }
  12739. },
  12740. _refreshValue: function() {
  12741. var lastValPercent, valPercent, value, valueMin, valueMax,
  12742. oRange = this.options.range,
  12743. o = this.options,
  12744. that = this,
  12745. animate = ( !this._animateOff ) ? o.animate : false,
  12746. _set = {};
  12747. if ( this._hasMultipleValues() ) {
  12748. this.handles.each( function( i ) {
  12749. valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() -
  12750. that._valueMin() ) * 100;
  12751. _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
  12752. $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
  12753. if ( that.options.range === true ) {
  12754. if ( that.orientation === "horizontal" ) {
  12755. if ( i === 0 ) {
  12756. that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
  12757. left: valPercent + "%"
  12758. }, o.animate );
  12759. }
  12760. if ( i === 1 ) {
  12761. that.range[ animate ? "animate" : "css" ]( {
  12762. width: ( valPercent - lastValPercent ) + "%"
  12763. }, {
  12764. queue: false,
  12765. duration: o.animate
  12766. } );
  12767. }
  12768. } else {
  12769. if ( i === 0 ) {
  12770. that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
  12771. bottom: ( valPercent ) + "%"
  12772. }, o.animate );
  12773. }
  12774. if ( i === 1 ) {
  12775. that.range[ animate ? "animate" : "css" ]( {
  12776. height: ( valPercent - lastValPercent ) + "%"
  12777. }, {
  12778. queue: false,
  12779. duration: o.animate
  12780. } );
  12781. }
  12782. }
  12783. }
  12784. lastValPercent = valPercent;
  12785. } );
  12786. } else {
  12787. value = this.value();
  12788. valueMin = this._valueMin();
  12789. valueMax = this._valueMax();
  12790. valPercent = ( valueMax !== valueMin ) ?
  12791. ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
  12792. 0;
  12793. _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
  12794. this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
  12795. if ( oRange === "min" && this.orientation === "horizontal" ) {
  12796. this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
  12797. width: valPercent + "%"
  12798. }, o.animate );
  12799. }
  12800. if ( oRange === "max" && this.orientation === "horizontal" ) {
  12801. this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
  12802. width: ( 100 - valPercent ) + "%"
  12803. }, o.animate );
  12804. }
  12805. if ( oRange === "min" && this.orientation === "vertical" ) {
  12806. this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
  12807. height: valPercent + "%"
  12808. }, o.animate );
  12809. }
  12810. if ( oRange === "max" && this.orientation === "vertical" ) {
  12811. this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
  12812. height: ( 100 - valPercent ) + "%"
  12813. }, o.animate );
  12814. }
  12815. }
  12816. },
  12817. _handleEvents: {
  12818. keydown: function( event ) {
  12819. var allowed, curVal, newVal, step,
  12820. index = $( event.target ).data( "ui-slider-handle-index" );
  12821. switch ( event.keyCode ) {
  12822. case $.ui.keyCode.HOME:
  12823. case $.ui.keyCode.END:
  12824. case $.ui.keyCode.PAGE_UP:
  12825. case $.ui.keyCode.PAGE_DOWN:
  12826. case $.ui.keyCode.UP:
  12827. case $.ui.keyCode.RIGHT:
  12828. case $.ui.keyCode.DOWN:
  12829. case $.ui.keyCode.LEFT:
  12830. event.preventDefault();
  12831. if ( !this._keySliding ) {
  12832. this._keySliding = true;
  12833. this._addClass( $( event.target ), null, "ui-state-active" );
  12834. allowed = this._start( event, index );
  12835. if ( allowed === false ) {
  12836. return;
  12837. }
  12838. }
  12839. break;
  12840. }
  12841. step = this.options.step;
  12842. if ( this._hasMultipleValues() ) {
  12843. curVal = newVal = this.values( index );
  12844. } else {
  12845. curVal = newVal = this.value();
  12846. }
  12847. switch ( event.keyCode ) {
  12848. case $.ui.keyCode.HOME:
  12849. newVal = this._valueMin();
  12850. break;
  12851. case $.ui.keyCode.END:
  12852. newVal = this._valueMax();
  12853. break;
  12854. case $.ui.keyCode.PAGE_UP:
  12855. newVal = this._trimAlignValue(
  12856. curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
  12857. );
  12858. break;
  12859. case $.ui.keyCode.PAGE_DOWN:
  12860. newVal = this._trimAlignValue(
  12861. curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) );
  12862. break;
  12863. case $.ui.keyCode.UP:
  12864. case $.ui.keyCode.RIGHT:
  12865. if ( curVal === this._valueMax() ) {
  12866. return;
  12867. }
  12868. newVal = this._trimAlignValue( curVal + step );
  12869. break;
  12870. case $.ui.keyCode.DOWN:
  12871. case $.ui.keyCode.LEFT:
  12872. if ( curVal === this._valueMin() ) {
  12873. return;
  12874. }
  12875. newVal = this._trimAlignValue( curVal - step );
  12876. break;
  12877. }
  12878. this._slide( event, index, newVal );
  12879. },
  12880. keyup: function( event ) {
  12881. var index = $( event.target ).data( "ui-slider-handle-index" );
  12882. if ( this._keySliding ) {
  12883. this._keySliding = false;
  12884. this._stop( event, index );
  12885. this._change( event, index );
  12886. this._removeClass( $( event.target ), null, "ui-state-active" );
  12887. }
  12888. }
  12889. }
  12890. } );
  12891. /*!
  12892. * jQuery UI Sortable 1.14.1
  12893. * https://jqueryui.com
  12894. *
  12895. * Copyright OpenJS Foundation and other contributors
  12896. * Released under the MIT license.
  12897. * https://jquery.org/license
  12898. */
  12899. //>>label: Sortable
  12900. //>>group: Interactions
  12901. //>>description: Enables items in a list to be sorted using the mouse.
  12902. //>>docs: https://api.jqueryui.com/sortable/
  12903. //>>demos: https://jqueryui.com/sortable/
  12904. //>>css.structure: ../../themes/base/sortable.css
  12905. var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, {
  12906. version: "1.14.1",
  12907. widgetEventPrefix: "sort",
  12908. ready: false,
  12909. options: {
  12910. appendTo: "parent",
  12911. axis: false,
  12912. connectWith: false,
  12913. containment: false,
  12914. cursor: "auto",
  12915. cursorAt: false,
  12916. dropOnEmpty: true,
  12917. forcePlaceholderSize: false,
  12918. forceHelperSize: false,
  12919. grid: false,
  12920. handle: false,
  12921. helper: "original",
  12922. items: "> *",
  12923. opacity: false,
  12924. placeholder: false,
  12925. revert: false,
  12926. scroll: true,
  12927. scrollSensitivity: 20,
  12928. scrollSpeed: 20,
  12929. scope: "default",
  12930. tolerance: "intersect",
  12931. zIndex: 1000,
  12932. // Callbacks
  12933. activate: null,
  12934. beforeStop: null,
  12935. change: null,
  12936. deactivate: null,
  12937. out: null,
  12938. over: null,
  12939. receive: null,
  12940. remove: null,
  12941. sort: null,
  12942. start: null,
  12943. stop: null,
  12944. update: null
  12945. },
  12946. _isOverAxis: function( x, reference, size ) {
  12947. return ( x >= reference ) && ( x < ( reference + size ) );
  12948. },
  12949. _isFloating: function( item ) {
  12950. return ( /left|right/ ).test( item.css( "float" ) ) ||
  12951. ( /inline|table-cell/ ).test( item.css( "display" ) );
  12952. },
  12953. _create: function() {
  12954. this.containerCache = {};
  12955. this._addClass( "ui-sortable" );
  12956. //Get the items
  12957. this.refresh();
  12958. //Let's determine the parent's offset
  12959. this.offset = this.element.offset();
  12960. //Initialize mouse events for interaction
  12961. this._mouseInit();
  12962. this._setHandleClassName();
  12963. //We're ready to go
  12964. this.ready = true;
  12965. },
  12966. _setOption: function( key, value ) {
  12967. this._super( key, value );
  12968. if ( key === "handle" ) {
  12969. this._setHandleClassName();
  12970. }
  12971. },
  12972. _setHandleClassName: function() {
  12973. var that = this;
  12974. this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" );
  12975. $.each( this.items, function() {
  12976. that._addClass(
  12977. this.instance.options.handle ?
  12978. this.item.find( this.instance.options.handle ) :
  12979. this.item,
  12980. "ui-sortable-handle"
  12981. );
  12982. } );
  12983. },
  12984. _destroy: function() {
  12985. this._mouseDestroy();
  12986. for ( var i = this.items.length - 1; i >= 0; i-- ) {
  12987. this.items[ i ].item.removeData( this.widgetName + "-item" );
  12988. }
  12989. return this;
  12990. },
  12991. _mouseCapture: function( event, overrideHandle ) {
  12992. var currentItem = null,
  12993. validHandle = false,
  12994. that = this;
  12995. if ( this.reverting ) {
  12996. return false;
  12997. }
  12998. if ( this.options.disabled || this.options.type === "static" ) {
  12999. return false;
  13000. }
  13001. //We have to refresh the items data once first
  13002. this._refreshItems( event );
  13003. //Find out if the clicked node (or one of its parents) is a actual item in this.items
  13004. $( event.target ).parents().each( function() {
  13005. if ( $.data( this, that.widgetName + "-item" ) === that ) {
  13006. currentItem = $( this );
  13007. return false;
  13008. }
  13009. } );
  13010. if ( $.data( event.target, that.widgetName + "-item" ) === that ) {
  13011. currentItem = $( event.target );
  13012. }
  13013. if ( !currentItem ) {
  13014. return false;
  13015. }
  13016. if ( this.options.handle && !overrideHandle ) {
  13017. $( this.options.handle, currentItem ).find( "*" ).addBack().each( function() {
  13018. if ( this === event.target ) {
  13019. validHandle = true;
  13020. }
  13021. } );
  13022. if ( !validHandle ) {
  13023. return false;
  13024. }
  13025. }
  13026. this.currentItem = currentItem;
  13027. this._removeCurrentsFromItems();
  13028. return true;
  13029. },
  13030. _mouseStart: function( event, overrideHandle, noActivation ) {
  13031. var i, body,
  13032. o = this.options;
  13033. this.currentContainer = this;
  13034. //We only need to call refreshPositions, because the refreshItems call has been moved to
  13035. // mouseCapture
  13036. this.refreshPositions();
  13037. //Prepare the dragged items parent
  13038. this.appendTo = $( o.appendTo !== "parent" ?
  13039. o.appendTo :
  13040. this.currentItem.parent() );
  13041. //Create and append the visible helper
  13042. this.helper = this._createHelper( event );
  13043. //Cache the helper size
  13044. this._cacheHelperProportions();
  13045. /*
  13046. * - Position generation -
  13047. * This block generates everything position related - it's the core of draggables.
  13048. */
  13049. //Cache the margins of the original element
  13050. this._cacheMargins();
  13051. //The element's absolute position on the page minus margins
  13052. this.offset = this.currentItem.offset();
  13053. this.offset = {
  13054. top: this.offset.top - this.margins.top,
  13055. left: this.offset.left - this.margins.left
  13056. };
  13057. $.extend( this.offset, {
  13058. click: { //Where the click happened, relative to the element
  13059. left: event.pageX - this.offset.left,
  13060. top: event.pageY - this.offset.top
  13061. },
  13062. // This is a relative to absolute position minus the actual position calculation -
  13063. // only used for relative positioned helper
  13064. relative: this._getRelativeOffset()
  13065. } );
  13066. // After we get the helper offset, but before we get the parent offset we can
  13067. // change the helper's position to absolute
  13068. // TODO: Still need to figure out a way to make relative sorting possible
  13069. this.helper.css( "position", "absolute" );
  13070. this.cssPosition = this.helper.css( "position" );
  13071. //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
  13072. if ( o.cursorAt ) {
  13073. this._adjustOffsetFromHelper( o.cursorAt );
  13074. }
  13075. //Cache the former DOM position
  13076. this.domPosition = {
  13077. prev: this.currentItem.prev()[ 0 ],
  13078. parent: this.currentItem.parent()[ 0 ]
  13079. };
  13080. // If the helper is not the original, hide the original so it's not playing any role during
  13081. // the drag, won't cause anything bad this way
  13082. if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
  13083. this.currentItem.hide();
  13084. }
  13085. //Create the placeholder
  13086. this._createPlaceholder();
  13087. //Get the next scrolling parent
  13088. this.scrollParent = this.placeholder.scrollParent();
  13089. $.extend( this.offset, {
  13090. parent: this._getParentOffset()
  13091. } );
  13092. //Set a containment if given in the options
  13093. if ( o.containment ) {
  13094. this._setContainment();
  13095. }
  13096. if ( o.cursor && o.cursor !== "auto" ) { // cursor option
  13097. body = this.document.find( "body" );
  13098. this._storedStylesheet =
  13099. $( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body );
  13100. }
  13101. // We need to make sure to grab the zIndex before setting the
  13102. // opacity, because setting the opacity to anything lower than 1
  13103. // causes the zIndex to change from "auto" to 0.
  13104. if ( o.zIndex ) { // zIndex option
  13105. if ( this.helper.css( "zIndex" ) ) {
  13106. this._storedZIndex = this.helper.css( "zIndex" );
  13107. }
  13108. this.helper.css( "zIndex", o.zIndex );
  13109. }
  13110. if ( o.opacity ) { // opacity option
  13111. if ( this.helper.css( "opacity" ) ) {
  13112. this._storedOpacity = this.helper.css( "opacity" );
  13113. }
  13114. this.helper.css( "opacity", o.opacity );
  13115. }
  13116. //Prepare scrolling
  13117. if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
  13118. this.scrollParent[ 0 ].tagName !== "HTML" ) {
  13119. this.overflowOffset = this.scrollParent.offset();
  13120. }
  13121. //Call callbacks
  13122. this._trigger( "start", event, this._uiHash() );
  13123. //Recache the helper size
  13124. if ( !this._preserveHelperProportions ) {
  13125. this._cacheHelperProportions();
  13126. }
  13127. //Post "activate" events to possible containers
  13128. if ( !noActivation ) {
  13129. for ( i = this.containers.length - 1; i >= 0; i-- ) {
  13130. this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
  13131. }
  13132. }
  13133. //Prepare possible droppables
  13134. if ( $.ui.ddmanager ) {
  13135. $.ui.ddmanager.current = this;
  13136. }
  13137. if ( $.ui.ddmanager && !o.dropBehaviour ) {
  13138. $.ui.ddmanager.prepareOffsets( this, event );
  13139. }
  13140. this.dragging = true;
  13141. this._addClass( this.helper, "ui-sortable-helper" );
  13142. //Move the helper, if needed
  13143. if ( !this.helper.parent().is( this.appendTo ) ) {
  13144. this.helper.detach().appendTo( this.appendTo );
  13145. //Update position
  13146. this.offset.parent = this._getParentOffset();
  13147. }
  13148. //Generate the original position
  13149. this.position = this.originalPosition = this._generatePosition( event );
  13150. this.originalPageX = event.pageX;
  13151. this.originalPageY = event.pageY;
  13152. this.lastPositionAbs = this.positionAbs = this._convertPositionTo( "absolute" );
  13153. this._mouseDrag( event );
  13154. return true;
  13155. },
  13156. _scroll: function( event ) {
  13157. var o = this.options,
  13158. scrolled = false;
  13159. if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
  13160. this.scrollParent[ 0 ].tagName !== "HTML" ) {
  13161. if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) -
  13162. event.pageY < o.scrollSensitivity ) {
  13163. this.scrollParent[ 0 ].scrollTop =
  13164. scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed;
  13165. } else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) {
  13166. this.scrollParent[ 0 ].scrollTop =
  13167. scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed;
  13168. }
  13169. if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) -
  13170. event.pageX < o.scrollSensitivity ) {
  13171. this.scrollParent[ 0 ].scrollLeft = scrolled =
  13172. this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed;
  13173. } else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) {
  13174. this.scrollParent[ 0 ].scrollLeft = scrolled =
  13175. this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed;
  13176. }
  13177. } else {
  13178. if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) {
  13179. scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed );
  13180. } else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) <
  13181. o.scrollSensitivity ) {
  13182. scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed );
  13183. }
  13184. if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) {
  13185. scrolled = this.document.scrollLeft(
  13186. this.document.scrollLeft() - o.scrollSpeed
  13187. );
  13188. } else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) <
  13189. o.scrollSensitivity ) {
  13190. scrolled = this.document.scrollLeft(
  13191. this.document.scrollLeft() + o.scrollSpeed
  13192. );
  13193. }
  13194. }
  13195. return scrolled;
  13196. },
  13197. _mouseDrag: function( event ) {
  13198. var i, item, itemElement, intersection,
  13199. o = this.options;
  13200. //Compute the helpers position
  13201. this.position = this._generatePosition( event );
  13202. this.positionAbs = this._convertPositionTo( "absolute" );
  13203. //Set the helper position
  13204. if ( !this.options.axis || this.options.axis !== "y" ) {
  13205. this.helper[ 0 ].style.left = this.position.left + "px";
  13206. }
  13207. if ( !this.options.axis || this.options.axis !== "x" ) {
  13208. this.helper[ 0 ].style.top = this.position.top + "px";
  13209. }
  13210. //Do scrolling
  13211. if ( o.scroll ) {
  13212. if ( this._scroll( event ) !== false ) {
  13213. //Update item positions used in position checks
  13214. this._refreshItemPositions( true );
  13215. if ( $.ui.ddmanager && !o.dropBehaviour ) {
  13216. $.ui.ddmanager.prepareOffsets( this, event );
  13217. }
  13218. }
  13219. }
  13220. this.dragDirection = {
  13221. vertical: this._getDragVerticalDirection(),
  13222. horizontal: this._getDragHorizontalDirection()
  13223. };
  13224. //Rearrange
  13225. for ( i = this.items.length - 1; i >= 0; i-- ) {
  13226. //Cache variables and intersection, continue if no intersection
  13227. item = this.items[ i ];
  13228. itemElement = item.item[ 0 ];
  13229. intersection = this._intersectsWithPointer( item );
  13230. if ( !intersection ) {
  13231. continue;
  13232. }
  13233. // Only put the placeholder inside the current Container, skip all
  13234. // items from other containers. This works because when moving
  13235. // an item from one container to another the
  13236. // currentContainer is switched before the placeholder is moved.
  13237. //
  13238. // Without this, moving items in "sub-sortables" can cause
  13239. // the placeholder to jitter between the outer and inner container.
  13240. if ( item.instance !== this.currentContainer ) {
  13241. continue;
  13242. }
  13243. // Cannot intersect with itself
  13244. // no useless actions that have been done before
  13245. // no action if the item moved is the parent of the item checked
  13246. if ( itemElement !== this.currentItem[ 0 ] &&
  13247. this.placeholder[ intersection === 1 ?
  13248. "next" : "prev" ]()[ 0 ] !== itemElement &&
  13249. !$.contains( this.placeholder[ 0 ], itemElement ) &&
  13250. ( this.options.type === "semi-dynamic" ?
  13251. !$.contains( this.element[ 0 ], itemElement ) :
  13252. true
  13253. )
  13254. ) {
  13255. this.direction = intersection === 1 ? "down" : "up";
  13256. if ( this.options.tolerance === "pointer" ||
  13257. this._intersectsWithSides( item ) ) {
  13258. this._rearrange( event, item );
  13259. } else {
  13260. break;
  13261. }
  13262. this._trigger( "change", event, this._uiHash() );
  13263. break;
  13264. }
  13265. }
  13266. //Post events to containers
  13267. this._contactContainers( event );
  13268. //Interconnect with droppables
  13269. if ( $.ui.ddmanager ) {
  13270. $.ui.ddmanager.drag( this, event );
  13271. }
  13272. //Call callbacks
  13273. this._trigger( "sort", event, this._uiHash() );
  13274. this.lastPositionAbs = this.positionAbs;
  13275. return false;
  13276. },
  13277. _mouseStop: function( event, noPropagation ) {
  13278. if ( !event ) {
  13279. return;
  13280. }
  13281. //If we are using droppables, inform the manager about the drop
  13282. if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
  13283. $.ui.ddmanager.drop( this, event );
  13284. }
  13285. if ( this.options.revert ) {
  13286. var that = this,
  13287. cur = this.placeholder.offset(),
  13288. axis = this.options.axis,
  13289. animation = {};
  13290. if ( !axis || axis === "x" ) {
  13291. animation.left = cur.left - this.offset.parent.left - this.margins.left +
  13292. ( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
  13293. 0 :
  13294. this.offsetParent[ 0 ].scrollLeft
  13295. );
  13296. }
  13297. if ( !axis || axis === "y" ) {
  13298. animation.top = cur.top - this.offset.parent.top - this.margins.top +
  13299. ( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
  13300. 0 :
  13301. this.offsetParent[ 0 ].scrollTop
  13302. );
  13303. }
  13304. this.reverting = true;
  13305. $( this.helper ).animate(
  13306. animation,
  13307. parseInt( this.options.revert, 10 ) || 500,
  13308. function() {
  13309. that._clear( event );
  13310. }
  13311. );
  13312. } else {
  13313. this._clear( event, noPropagation );
  13314. }
  13315. return false;
  13316. },
  13317. cancel: function() {
  13318. if ( this.dragging ) {
  13319. this._mouseUp( new $.Event( "mouseup", { target: null } ) );
  13320. if ( this.options.helper === "original" ) {
  13321. this.currentItem.css( this._storedCSS );
  13322. this._removeClass( this.currentItem, "ui-sortable-helper" );
  13323. } else {
  13324. this.currentItem.show();
  13325. }
  13326. //Post deactivating events to containers
  13327. for ( var i = this.containers.length - 1; i >= 0; i-- ) {
  13328. this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) );
  13329. if ( this.containers[ i ].containerCache.over ) {
  13330. this.containers[ i ]._trigger( "out", null, this._uiHash( this ) );
  13331. this.containers[ i ].containerCache.over = 0;
  13332. }
  13333. }
  13334. }
  13335. if ( this.placeholder ) {
  13336. //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
  13337. // it unbinds ALL events from the original node!
  13338. if ( this.placeholder[ 0 ].parentNode ) {
  13339. this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
  13340. }
  13341. if ( this.options.helper !== "original" && this.helper &&
  13342. this.helper[ 0 ].parentNode ) {
  13343. this.helper.remove();
  13344. }
  13345. $.extend( this, {
  13346. helper: null,
  13347. dragging: false,
  13348. reverting: false,
  13349. _noFinalSort: null
  13350. } );
  13351. if ( this.domPosition.prev ) {
  13352. $( this.domPosition.prev ).after( this.currentItem );
  13353. } else {
  13354. $( this.domPosition.parent ).prepend( this.currentItem );
  13355. }
  13356. }
  13357. return this;
  13358. },
  13359. serialize: function( o ) {
  13360. var items = this._getItemsAsjQuery( o && o.connected ),
  13361. str = [];
  13362. o = o || {};
  13363. $( items ).each( function() {
  13364. var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" )
  13365. .match( o.expression || ( /(.+)[\-=_](.+)/ ) );
  13366. if ( res ) {
  13367. str.push(
  13368. ( o.key || res[ 1 ] + "[]" ) +
  13369. "=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) );
  13370. }
  13371. } );
  13372. if ( !str.length && o.key ) {
  13373. str.push( o.key + "=" );
  13374. }
  13375. return str.join( "&" );
  13376. },
  13377. toArray: function( o ) {
  13378. var items = this._getItemsAsjQuery( o && o.connected ),
  13379. ret = [];
  13380. o = o || {};
  13381. items.each( function() {
  13382. ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" );
  13383. } );
  13384. return ret;
  13385. },
  13386. /* Be careful with the following core functions */
  13387. _intersectsWith: function( item ) {
  13388. var x1 = this.positionAbs.left,
  13389. x2 = x1 + this.helperProportions.width,
  13390. y1 = this.positionAbs.top,
  13391. y2 = y1 + this.helperProportions.height,
  13392. l = item.left,
  13393. r = l + item.width,
  13394. t = item.top,
  13395. b = t + item.height,
  13396. dyClick = this.offset.click.top,
  13397. dxClick = this.offset.click.left,
  13398. isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t &&
  13399. ( y1 + dyClick ) < b ),
  13400. isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l &&
  13401. ( x1 + dxClick ) < r ),
  13402. isOverElement = isOverElementHeight && isOverElementWidth;
  13403. if ( this.options.tolerance === "pointer" ||
  13404. this.options.forcePointerForContainers ||
  13405. ( this.options.tolerance !== "pointer" &&
  13406. this.helperProportions[ this.floating ? "width" : "height" ] >
  13407. item[ this.floating ? "width" : "height" ] )
  13408. ) {
  13409. return isOverElement;
  13410. } else {
  13411. return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half
  13412. x2 - ( this.helperProportions.width / 2 ) < r && // Left Half
  13413. t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half
  13414. y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half
  13415. }
  13416. },
  13417. _intersectsWithPointer: function( item ) {
  13418. var verticalDirection, horizontalDirection,
  13419. isOverElementHeight = ( this.options.axis === "x" ) ||
  13420. this._isOverAxis(
  13421. this.positionAbs.top + this.offset.click.top, item.top, item.height ),
  13422. isOverElementWidth = ( this.options.axis === "y" ) ||
  13423. this._isOverAxis(
  13424. this.positionAbs.left + this.offset.click.left, item.left, item.width ),
  13425. isOverElement = isOverElementHeight && isOverElementWidth;
  13426. if ( !isOverElement ) {
  13427. return false;
  13428. }
  13429. verticalDirection = this.dragDirection.vertical;
  13430. horizontalDirection = this.dragDirection.horizontal;
  13431. return this.floating ?
  13432. ( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 ) :
  13433. ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) );
  13434. },
  13435. _intersectsWithSides: function( item ) {
  13436. var isOverBottomHalf = this._isOverAxis( this.positionAbs.top +
  13437. this.offset.click.top, item.top + ( item.height / 2 ), item.height ),
  13438. isOverRightHalf = this._isOverAxis( this.positionAbs.left +
  13439. this.offset.click.left, item.left + ( item.width / 2 ), item.width ),
  13440. verticalDirection = this.dragDirection.vertical,
  13441. horizontalDirection = this.dragDirection.horizontal;
  13442. if ( this.floating && horizontalDirection ) {
  13443. return ( ( horizontalDirection === "right" && isOverRightHalf ) ||
  13444. ( horizontalDirection === "left" && !isOverRightHalf ) );
  13445. } else {
  13446. return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) ||
  13447. ( verticalDirection === "up" && !isOverBottomHalf ) );
  13448. }
  13449. },
  13450. _getDragVerticalDirection: function() {
  13451. var delta = this.positionAbs.top - this.lastPositionAbs.top;
  13452. return delta !== 0 && ( delta > 0 ? "down" : "up" );
  13453. },
  13454. _getDragHorizontalDirection: function() {
  13455. var delta = this.positionAbs.left - this.lastPositionAbs.left;
  13456. return delta !== 0 && ( delta > 0 ? "right" : "left" );
  13457. },
  13458. refresh: function( event ) {
  13459. this._refreshItems( event );
  13460. this._setHandleClassName();
  13461. this.refreshPositions();
  13462. return this;
  13463. },
  13464. _connectWith: function() {
  13465. var options = this.options;
  13466. return options.connectWith.constructor === String ?
  13467. [ options.connectWith ] :
  13468. options.connectWith;
  13469. },
  13470. _getItemsAsjQuery: function( connected ) {
  13471. var i, j, cur, inst,
  13472. items = [],
  13473. queries = [],
  13474. connectWith = this._connectWith();
  13475. if ( connectWith && connected ) {
  13476. for ( i = connectWith.length - 1; i >= 0; i-- ) {
  13477. cur = $( connectWith[ i ], this.document[ 0 ] );
  13478. for ( j = cur.length - 1; j >= 0; j-- ) {
  13479. inst = $.data( cur[ j ], this.widgetFullName );
  13480. if ( inst && inst !== this && !inst.options.disabled ) {
  13481. queries.push( [ typeof inst.options.items === "function" ?
  13482. inst.options.items.call( inst.element ) :
  13483. $( inst.options.items, inst.element )
  13484. .not( ".ui-sortable-helper" )
  13485. .not( ".ui-sortable-placeholder" ), inst ] );
  13486. }
  13487. }
  13488. }
  13489. }
  13490. queries.push( [ typeof this.options.items === "function" ?
  13491. this.options.items
  13492. .call( this.element, null, { options: this.options, item: this.currentItem } ) :
  13493. $( this.options.items, this.element )
  13494. .not( ".ui-sortable-helper" )
  13495. .not( ".ui-sortable-placeholder" ), this ] );
  13496. function addItems() {
  13497. items.push( this );
  13498. }
  13499. for ( i = queries.length - 1; i >= 0; i-- ) {
  13500. queries[ i ][ 0 ].each( addItems );
  13501. }
  13502. return $( items );
  13503. },
  13504. _removeCurrentsFromItems: function() {
  13505. var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" );
  13506. this.items = $.grep( this.items, function( item ) {
  13507. for ( var j = 0; j < list.length; j++ ) {
  13508. if ( list[ j ] === item.item[ 0 ] ) {
  13509. return false;
  13510. }
  13511. }
  13512. return true;
  13513. } );
  13514. },
  13515. _refreshItems: function( event ) {
  13516. this.items = [];
  13517. this.containers = [ this ];
  13518. var i, j, cur, inst, targetData, _queries, item, queriesLength,
  13519. items = this.items,
  13520. queries = [ [ typeof this.options.items === "function" ?
  13521. this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) :
  13522. $( this.options.items, this.element ), this ] ],
  13523. connectWith = this._connectWith();
  13524. //Shouldn't be run the first time through due to massive slow-down
  13525. if ( connectWith && this.ready ) {
  13526. for ( i = connectWith.length - 1; i >= 0; i-- ) {
  13527. cur = $( connectWith[ i ], this.document[ 0 ] );
  13528. for ( j = cur.length - 1; j >= 0; j-- ) {
  13529. inst = $.data( cur[ j ], this.widgetFullName );
  13530. if ( inst && inst !== this && !inst.options.disabled ) {
  13531. queries.push( [ typeof inst.options.items === "function" ?
  13532. inst.options.items
  13533. .call( inst.element[ 0 ], event, { item: this.currentItem } ) :
  13534. $( inst.options.items, inst.element ), inst ] );
  13535. this.containers.push( inst );
  13536. }
  13537. }
  13538. }
  13539. }
  13540. for ( i = queries.length - 1; i >= 0; i-- ) {
  13541. targetData = queries[ i ][ 1 ];
  13542. _queries = queries[ i ][ 0 ];
  13543. for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) {
  13544. item = $( _queries[ j ] );
  13545. // Data for target checking (mouse manager)
  13546. item.data( this.widgetName + "-item", targetData );
  13547. items.push( {
  13548. item: item,
  13549. instance: targetData,
  13550. width: 0, height: 0,
  13551. left: 0, top: 0
  13552. } );
  13553. }
  13554. }
  13555. },
  13556. _refreshItemPositions: function( fast ) {
  13557. var i, item, t, p;
  13558. for ( i = this.items.length - 1; i >= 0; i-- ) {
  13559. item = this.items[ i ];
  13560. //We ignore calculating positions of all connected containers when we're not over them
  13561. if ( this.currentContainer && item.instance !== this.currentContainer &&
  13562. item.item[ 0 ] !== this.currentItem[ 0 ] ) {
  13563. continue;
  13564. }
  13565. t = this.options.toleranceElement ?
  13566. $( this.options.toleranceElement, item.item ) :
  13567. item.item;
  13568. if ( !fast ) {
  13569. item.width = t.outerWidth();
  13570. item.height = t.outerHeight();
  13571. }
  13572. p = t.offset();
  13573. item.left = p.left;
  13574. item.top = p.top;
  13575. }
  13576. },
  13577. refreshPositions: function( fast ) {
  13578. // Determine whether items are being displayed horizontally
  13579. this.floating = this.items.length ?
  13580. this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
  13581. false;
  13582. // This has to be redone because due to the item being moved out/into the offsetParent,
  13583. // the offsetParent's position will change
  13584. if ( this.offsetParent && this.helper ) {
  13585. this.offset.parent = this._getParentOffset();
  13586. }
  13587. this._refreshItemPositions( fast );
  13588. var i, p;
  13589. if ( this.options.custom && this.options.custom.refreshContainers ) {
  13590. this.options.custom.refreshContainers.call( this );
  13591. } else {
  13592. for ( i = this.containers.length - 1; i >= 0; i-- ) {
  13593. p = this.containers[ i ].element.offset();
  13594. this.containers[ i ].containerCache.left = p.left;
  13595. this.containers[ i ].containerCache.top = p.top;
  13596. this.containers[ i ].containerCache.width =
  13597. this.containers[ i ].element.outerWidth();
  13598. this.containers[ i ].containerCache.height =
  13599. this.containers[ i ].element.outerHeight();
  13600. }
  13601. }
  13602. return this;
  13603. },
  13604. _createPlaceholder: function( that ) {
  13605. that = that || this;
  13606. var className, nodeName,
  13607. o = that.options;
  13608. if ( !o.placeholder || o.placeholder.constructor === String ) {
  13609. className = o.placeholder;
  13610. nodeName = that.currentItem[ 0 ].nodeName.toLowerCase();
  13611. o.placeholder = {
  13612. element: function() {
  13613. var element = $( "<" + nodeName + ">", that.document[ 0 ] );
  13614. that._addClass( element, "ui-sortable-placeholder",
  13615. className || that.currentItem[ 0 ].className )
  13616. ._removeClass( element, "ui-sortable-helper" );
  13617. if ( nodeName === "tbody" ) {
  13618. that._createTrPlaceholder(
  13619. that.currentItem.find( "tr" ).eq( 0 ),
  13620. $( "<tr>", that.document[ 0 ] ).appendTo( element )
  13621. );
  13622. } else if ( nodeName === "tr" ) {
  13623. that._createTrPlaceholder( that.currentItem, element );
  13624. } else if ( nodeName === "img" ) {
  13625. element.attr( "src", that.currentItem.attr( "src" ) );
  13626. }
  13627. if ( !className ) {
  13628. element.css( "visibility", "hidden" );
  13629. }
  13630. return element;
  13631. },
  13632. update: function( container, p ) {
  13633. // 1. If a className is set as 'placeholder option, we don't force sizes -
  13634. // the class is responsible for that
  13635. // 2. The option 'forcePlaceholderSize can be enabled to force it even if a
  13636. // class name is specified
  13637. if ( className && !o.forcePlaceholderSize ) {
  13638. return;
  13639. }
  13640. // If the element doesn't have a actual height or width by itself (without
  13641. // styles coming from a stylesheet), it receives the inline height and width
  13642. // from the dragged item. Or, if it's a tbody or tr, it's going to have a height
  13643. // anyway since we're populating them with <td>s above, but they're unlikely to
  13644. // be the correct height on their own if the row heights are dynamic, so we'll
  13645. // always assign the height of the dragged item given forcePlaceholderSize
  13646. // is true.
  13647. if ( !p.height() || ( o.forcePlaceholderSize &&
  13648. ( nodeName === "tbody" || nodeName === "tr" ) ) ) {
  13649. p.height(
  13650. that.currentItem.innerHeight() -
  13651. parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) -
  13652. parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) );
  13653. }
  13654. if ( !p.width() ) {
  13655. p.width(
  13656. that.currentItem.innerWidth() -
  13657. parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) -
  13658. parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) );
  13659. }
  13660. }
  13661. };
  13662. }
  13663. //Create the placeholder
  13664. that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) );
  13665. //Append it after the actual current item
  13666. that.currentItem.after( that.placeholder );
  13667. //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
  13668. o.placeholder.update( that, that.placeholder );
  13669. },
  13670. _createTrPlaceholder: function( sourceTr, targetTr ) {
  13671. var that = this;
  13672. sourceTr.children().each( function() {
  13673. $( "<td>&#160;</td>", that.document[ 0 ] )
  13674. .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
  13675. .appendTo( targetTr );
  13676. } );
  13677. },
  13678. _contactContainers: function( event ) {
  13679. var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,
  13680. floating, axis,
  13681. innermostContainer = null,
  13682. innermostIndex = null;
  13683. // Get innermost container that intersects with item
  13684. for ( i = this.containers.length - 1; i >= 0; i-- ) {
  13685. // Never consider a container that's located within the item itself
  13686. if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) {
  13687. continue;
  13688. }
  13689. if ( this._intersectsWith( this.containers[ i ].containerCache ) ) {
  13690. // If we've already found a container and it's more "inner" than this, then continue
  13691. if ( innermostContainer &&
  13692. $.contains(
  13693. this.containers[ i ].element[ 0 ],
  13694. innermostContainer.element[ 0 ] ) ) {
  13695. continue;
  13696. }
  13697. innermostContainer = this.containers[ i ];
  13698. innermostIndex = i;
  13699. } else {
  13700. // container doesn't intersect. trigger "out" event if necessary
  13701. if ( this.containers[ i ].containerCache.over ) {
  13702. this.containers[ i ]._trigger( "out", event, this._uiHash( this ) );
  13703. this.containers[ i ].containerCache.over = 0;
  13704. }
  13705. }
  13706. }
  13707. // If no intersecting containers found, return
  13708. if ( !innermostContainer ) {
  13709. return;
  13710. }
  13711. // Move the item into the container if it's not there already
  13712. if ( this.containers.length === 1 ) {
  13713. if ( !this.containers[ innermostIndex ].containerCache.over ) {
  13714. this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
  13715. this.containers[ innermostIndex ].containerCache.over = 1;
  13716. }
  13717. } else {
  13718. // When entering a new container, we will find the item with the least distance and
  13719. // append our item near it
  13720. dist = 10000;
  13721. itemWithLeastDistance = null;
  13722. floating = innermostContainer.floating || this._isFloating( this.currentItem );
  13723. posProperty = floating ? "left" : "top";
  13724. sizeProperty = floating ? "width" : "height";
  13725. axis = floating ? "pageX" : "pageY";
  13726. for ( j = this.items.length - 1; j >= 0; j-- ) {
  13727. if ( !$.contains(
  13728. this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] )
  13729. ) {
  13730. continue;
  13731. }
  13732. if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) {
  13733. continue;
  13734. }
  13735. cur = this.items[ j ].item.offset()[ posProperty ];
  13736. nearBottom = false;
  13737. if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
  13738. nearBottom = true;
  13739. }
  13740. if ( Math.abs( event[ axis ] - cur ) < dist ) {
  13741. dist = Math.abs( event[ axis ] - cur );
  13742. itemWithLeastDistance = this.items[ j ];
  13743. this.direction = nearBottom ? "up" : "down";
  13744. }
  13745. }
  13746. //Check if dropOnEmpty is enabled
  13747. if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) {
  13748. return;
  13749. }
  13750. if ( this.currentContainer === this.containers[ innermostIndex ] ) {
  13751. if ( !this.currentContainer.containerCache.over ) {
  13752. this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
  13753. this.currentContainer.containerCache.over = 1;
  13754. }
  13755. return;
  13756. }
  13757. if ( itemWithLeastDistance ) {
  13758. this._rearrange( event, itemWithLeastDistance, null, true );
  13759. } else {
  13760. this._rearrange( event, null, this.containers[ innermostIndex ].element, true );
  13761. }
  13762. this._trigger( "change", event, this._uiHash() );
  13763. this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) );
  13764. this.currentContainer = this.containers[ innermostIndex ];
  13765. //Update the placeholder
  13766. this.options.placeholder.update( this.currentContainer, this.placeholder );
  13767. //Update scrollParent
  13768. this.scrollParent = this.placeholder.scrollParent();
  13769. //Update overflowOffset
  13770. if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
  13771. this.scrollParent[ 0 ].tagName !== "HTML" ) {
  13772. this.overflowOffset = this.scrollParent.offset();
  13773. }
  13774. this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
  13775. this.containers[ innermostIndex ].containerCache.over = 1;
  13776. }
  13777. },
  13778. _createHelper: function( event ) {
  13779. var o = this.options,
  13780. helper = typeof o.helper === "function" ?
  13781. $( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) :
  13782. ( o.helper === "clone" ? this.currentItem.clone() : this.currentItem );
  13783. //Add the helper to the DOM if that didn't happen already
  13784. if ( !helper.parents( "body" ).length ) {
  13785. this.appendTo[ 0 ].appendChild( helper[ 0 ] );
  13786. }
  13787. if ( helper[ 0 ] === this.currentItem[ 0 ] ) {
  13788. this._storedCSS = {
  13789. width: this.currentItem[ 0 ].style.width,
  13790. height: this.currentItem[ 0 ].style.height,
  13791. position: this.currentItem.css( "position" ),
  13792. top: this.currentItem.css( "top" ),
  13793. left: this.currentItem.css( "left" )
  13794. };
  13795. }
  13796. if ( !helper[ 0 ].style.width || o.forceHelperSize ) {
  13797. helper.width( this.currentItem.width() );
  13798. }
  13799. if ( !helper[ 0 ].style.height || o.forceHelperSize ) {
  13800. helper.height( this.currentItem.height() );
  13801. }
  13802. return helper;
  13803. },
  13804. _adjustOffsetFromHelper: function( obj ) {
  13805. if ( typeof obj === "string" ) {
  13806. obj = obj.split( " " );
  13807. }
  13808. if ( Array.isArray( obj ) ) {
  13809. obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
  13810. }
  13811. if ( "left" in obj ) {
  13812. this.offset.click.left = obj.left + this.margins.left;
  13813. }
  13814. if ( "right" in obj ) {
  13815. this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
  13816. }
  13817. if ( "top" in obj ) {
  13818. this.offset.click.top = obj.top + this.margins.top;
  13819. }
  13820. if ( "bottom" in obj ) {
  13821. this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
  13822. }
  13823. },
  13824. _getParentOffset: function() {
  13825. //Get the offsetParent and cache its position
  13826. this.offsetParent = this.helper.offsetParent();
  13827. var po = this.offsetParent.offset();
  13828. // This is a special case where we need to modify a offset calculated on start, since the
  13829. // following happened:
  13830. // 1. The position of the helper is absolute, so it's position is calculated based on the
  13831. // next positioned parent
  13832. // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
  13833. // the document, which means that the scroll is included in the initial calculation of the
  13834. // offset of the parent, and never recalculated upon drag
  13835. if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] &&
  13836. $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
  13837. po.left += this.scrollParent.scrollLeft();
  13838. po.top += this.scrollParent.scrollTop();
  13839. }
  13840. // This needs to be actually done for all browsers, since pageX/pageY includes
  13841. // this information.
  13842. if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ) {
  13843. po = { top: 0, left: 0 };
  13844. }
  13845. return {
  13846. top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
  13847. left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
  13848. };
  13849. },
  13850. _getRelativeOffset: function() {
  13851. if ( this.cssPosition === "relative" ) {
  13852. var p = this.currentItem.position();
  13853. return {
  13854. top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
  13855. this.scrollParent.scrollTop(),
  13856. left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
  13857. this.scrollParent.scrollLeft()
  13858. };
  13859. } else {
  13860. return { top: 0, left: 0 };
  13861. }
  13862. },
  13863. _cacheMargins: function() {
  13864. this.margins = {
  13865. left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ),
  13866. top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 )
  13867. };
  13868. },
  13869. _cacheHelperProportions: function() {
  13870. this.helperProportions = {
  13871. width: this.helper.outerWidth(),
  13872. height: this.helper.outerHeight()
  13873. };
  13874. },
  13875. _setContainment: function() {
  13876. var ce, co, over,
  13877. o = this.options;
  13878. if ( o.containment === "parent" ) {
  13879. o.containment = this.helper[ 0 ].parentNode;
  13880. }
  13881. if ( o.containment === "document" || o.containment === "window" ) {
  13882. this.containment = [
  13883. 0 - this.offset.relative.left - this.offset.parent.left,
  13884. 0 - this.offset.relative.top - this.offset.parent.top,
  13885. o.containment === "document" ?
  13886. this.document.width() :
  13887. this.window.width() - this.helperProportions.width - this.margins.left,
  13888. ( o.containment === "document" ?
  13889. ( this.document.height() || document.body.parentNode.scrollHeight ) :
  13890. this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight
  13891. ) - this.helperProportions.height - this.margins.top
  13892. ];
  13893. }
  13894. if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) {
  13895. ce = $( o.containment )[ 0 ];
  13896. co = $( o.containment ).offset();
  13897. over = ( $( ce ).css( "overflow" ) !== "hidden" );
  13898. this.containment = [
  13899. co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) +
  13900. ( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left,
  13901. co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) +
  13902. ( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top,
  13903. co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
  13904. ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) -
  13905. ( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) -
  13906. this.helperProportions.width - this.margins.left,
  13907. co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
  13908. ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) -
  13909. ( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) -
  13910. this.helperProportions.height - this.margins.top
  13911. ];
  13912. }
  13913. },
  13914. _convertPositionTo: function( d, pos ) {
  13915. if ( !pos ) {
  13916. pos = this.position;
  13917. }
  13918. var mod = d === "absolute" ? 1 : -1,
  13919. scroll = this.cssPosition === "absolute" &&
  13920. !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
  13921. $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
  13922. this.offsetParent :
  13923. this.scrollParent,
  13924. scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
  13925. return {
  13926. top: (
  13927. // The absolute mouse position
  13928. pos.top +
  13929. // Only for relative positioned nodes: Relative offset from element to offset parent
  13930. this.offset.relative.top * mod +
  13931. // The offsetParent's offset without borders (offset + border)
  13932. this.offset.parent.top * mod -
  13933. ( ( this.cssPosition === "fixed" ?
  13934. -this.scrollParent.scrollTop() :
  13935. ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod )
  13936. ),
  13937. left: (
  13938. // The absolute mouse position
  13939. pos.left +
  13940. // Only for relative positioned nodes: Relative offset from element to offset parent
  13941. this.offset.relative.left * mod +
  13942. // The offsetParent's offset without borders (offset + border)
  13943. this.offset.parent.left * mod -
  13944. ( ( this.cssPosition === "fixed" ?
  13945. -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
  13946. scroll.scrollLeft() ) * mod )
  13947. )
  13948. };
  13949. },
  13950. _generatePosition: function( event ) {
  13951. var top, left,
  13952. o = this.options,
  13953. pageX = event.pageX,
  13954. pageY = event.pageY,
  13955. scroll = this.cssPosition === "absolute" &&
  13956. !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
  13957. $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
  13958. this.offsetParent :
  13959. this.scrollParent,
  13960. scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
  13961. // This is another very weird special case that only happens for relative elements:
  13962. // 1. If the css position is relative
  13963. // 2. and the scroll parent is the document or similar to the offset parent
  13964. // we have to refresh the relative offset during the scroll so there are no jumps
  13965. if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
  13966. this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) {
  13967. this.offset.relative = this._getRelativeOffset();
  13968. }
  13969. /*
  13970. * - Position constraining -
  13971. * Constrain the position to a mix of grid, containment.
  13972. */
  13973. if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options
  13974. if ( this.containment ) {
  13975. if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) {
  13976. pageX = this.containment[ 0 ] + this.offset.click.left;
  13977. }
  13978. if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) {
  13979. pageY = this.containment[ 1 ] + this.offset.click.top;
  13980. }
  13981. if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) {
  13982. pageX = this.containment[ 2 ] + this.offset.click.left;
  13983. }
  13984. if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) {
  13985. pageY = this.containment[ 3 ] + this.offset.click.top;
  13986. }
  13987. }
  13988. if ( o.grid ) {
  13989. top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) /
  13990. o.grid[ 1 ] ) * o.grid[ 1 ];
  13991. pageY = this.containment ?
  13992. ( ( top - this.offset.click.top >= this.containment[ 1 ] &&
  13993. top - this.offset.click.top <= this.containment[ 3 ] ) ?
  13994. top :
  13995. ( ( top - this.offset.click.top >= this.containment[ 1 ] ) ?
  13996. top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) :
  13997. top;
  13998. left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) /
  13999. o.grid[ 0 ] ) * o.grid[ 0 ];
  14000. pageX = this.containment ?
  14001. ( ( left - this.offset.click.left >= this.containment[ 0 ] &&
  14002. left - this.offset.click.left <= this.containment[ 2 ] ) ?
  14003. left :
  14004. ( ( left - this.offset.click.left >= this.containment[ 0 ] ) ?
  14005. left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) :
  14006. left;
  14007. }
  14008. }
  14009. return {
  14010. top: (
  14011. // The absolute mouse position
  14012. pageY -
  14013. // Click offset (relative to the element)
  14014. this.offset.click.top -
  14015. // Only for relative positioned nodes: Relative offset from element to offset parent
  14016. this.offset.relative.top -
  14017. // The offsetParent's offset without borders (offset + border)
  14018. this.offset.parent.top +
  14019. ( ( this.cssPosition === "fixed" ?
  14020. -this.scrollParent.scrollTop() :
  14021. ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) )
  14022. ),
  14023. left: (
  14024. // The absolute mouse position
  14025. pageX -
  14026. // Click offset (relative to the element)
  14027. this.offset.click.left -
  14028. // Only for relative positioned nodes: Relative offset from element to offset parent
  14029. this.offset.relative.left -
  14030. // The offsetParent's offset without borders (offset + border)
  14031. this.offset.parent.left +
  14032. ( ( this.cssPosition === "fixed" ?
  14033. -this.scrollParent.scrollLeft() :
  14034. scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
  14035. )
  14036. };
  14037. },
  14038. _rearrange: function( event, i, a, hardRefresh ) {
  14039. if ( a ) {
  14040. a[ 0 ].appendChild( this.placeholder[ 0 ] );
  14041. } else {
  14042. i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ],
  14043. ( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) );
  14044. }
  14045. //Various things done here to improve the performance:
  14046. // 1. we create a setTimeout, that calls refreshPositions
  14047. // 2. on the instance, we have a counter variable, that get's higher after every append
  14048. // 3. on the local scope, we copy the counter variable, and check in the timeout,
  14049. // if it's still the same
  14050. // 4. this lets only the last addition to the timeout stack through
  14051. this.counter = this.counter ? ++this.counter : 1;
  14052. var counter = this.counter;
  14053. this._delay( function() {
  14054. if ( counter === this.counter ) {
  14055. //Precompute after each DOM insertion, NOT on mousemove
  14056. this.refreshPositions( !hardRefresh );
  14057. }
  14058. } );
  14059. },
  14060. _clear: function( event, noPropagation ) {
  14061. this.reverting = false;
  14062. // We delay all events that have to be triggered to after the point where the placeholder
  14063. // has been removed and everything else normalized again
  14064. var i,
  14065. delayedTriggers = [];
  14066. // We first have to update the dom position of the actual currentItem
  14067. // Note: don't do it if the current item is already removed (by a user), or it gets
  14068. // reappended (see #4088)
  14069. if ( !this._noFinalSort && this.currentItem.parent().length ) {
  14070. this.placeholder.before( this.currentItem );
  14071. }
  14072. this._noFinalSort = null;
  14073. if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) {
  14074. for ( i in this._storedCSS ) {
  14075. if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) {
  14076. this._storedCSS[ i ] = "";
  14077. }
  14078. }
  14079. this.currentItem.css( this._storedCSS );
  14080. this._removeClass( this.currentItem, "ui-sortable-helper" );
  14081. } else {
  14082. this.currentItem.show();
  14083. }
  14084. if ( this.fromOutside && !noPropagation ) {
  14085. delayedTriggers.push( function( event ) {
  14086. this._trigger( "receive", event, this._uiHash( this.fromOutside ) );
  14087. } );
  14088. }
  14089. if ( ( this.fromOutside ||
  14090. this.domPosition.prev !==
  14091. this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] ||
  14092. this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) {
  14093. // Trigger update callback if the DOM position has changed
  14094. delayedTriggers.push( function( event ) {
  14095. this._trigger( "update", event, this._uiHash() );
  14096. } );
  14097. }
  14098. // Check if the items Container has Changed and trigger appropriate
  14099. // events.
  14100. if ( this !== this.currentContainer ) {
  14101. if ( !noPropagation ) {
  14102. delayedTriggers.push( function( event ) {
  14103. this._trigger( "remove", event, this._uiHash() );
  14104. } );
  14105. delayedTriggers.push( ( function( c ) {
  14106. return function( event ) {
  14107. c._trigger( "receive", event, this._uiHash( this ) );
  14108. };
  14109. } ).call( this, this.currentContainer ) );
  14110. delayedTriggers.push( ( function( c ) {
  14111. return function( event ) {
  14112. c._trigger( "update", event, this._uiHash( this ) );
  14113. };
  14114. } ).call( this, this.currentContainer ) );
  14115. }
  14116. }
  14117. //Post events to containers
  14118. function delayEvent( type, instance, container ) {
  14119. return function( event ) {
  14120. container._trigger( type, event, instance._uiHash( instance ) );
  14121. };
  14122. }
  14123. for ( i = this.containers.length - 1; i >= 0; i-- ) {
  14124. if ( !noPropagation ) {
  14125. delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
  14126. }
  14127. if ( this.containers[ i ].containerCache.over ) {
  14128. delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
  14129. this.containers[ i ].containerCache.over = 0;
  14130. }
  14131. }
  14132. //Do what was originally in plugins
  14133. if ( this._storedStylesheet ) {
  14134. this._storedStylesheet.remove();
  14135. this._storedStylesheet = null;
  14136. }
  14137. if ( this._storedOpacity ) {
  14138. this.helper.css( "opacity", this._storedOpacity );
  14139. }
  14140. if ( this._storedZIndex ) {
  14141. this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex );
  14142. }
  14143. this.dragging = false;
  14144. if ( !noPropagation ) {
  14145. this._trigger( "beforeStop", event, this._uiHash() );
  14146. }
  14147. //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
  14148. // it unbinds ALL events from the original node!
  14149. this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
  14150. if ( !this.cancelHelperRemoval ) {
  14151. if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
  14152. this.helper.remove();
  14153. }
  14154. this.helper = null;
  14155. }
  14156. if ( !noPropagation ) {
  14157. for ( i = 0; i < delayedTriggers.length; i++ ) {
  14158. // Trigger all delayed events
  14159. delayedTriggers[ i ].call( this, event );
  14160. }
  14161. this._trigger( "stop", event, this._uiHash() );
  14162. }
  14163. this.fromOutside = false;
  14164. return !this.cancelHelperRemoval;
  14165. },
  14166. _trigger: function() {
  14167. if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) {
  14168. this.cancel();
  14169. }
  14170. },
  14171. _uiHash: function( _inst ) {
  14172. var inst = _inst || this;
  14173. return {
  14174. helper: inst.helper,
  14175. placeholder: inst.placeholder || $( [] ),
  14176. position: inst.position,
  14177. originalPosition: inst.originalPosition,
  14178. offset: inst.positionAbs,
  14179. item: inst.currentItem,
  14180. sender: _inst ? _inst.element : null
  14181. };
  14182. }
  14183. } );
  14184. /*!
  14185. * jQuery UI Spinner 1.14.1
  14186. * https://jqueryui.com
  14187. *
  14188. * Copyright OpenJS Foundation and other contributors
  14189. * Released under the MIT license.
  14190. * https://jquery.org/license
  14191. */
  14192. //>>label: Spinner
  14193. //>>group: Widgets
  14194. //>>description: Displays buttons to easily input numbers via the keyboard or mouse.
  14195. //>>docs: https://api.jqueryui.com/spinner/
  14196. //>>demos: https://jqueryui.com/spinner/
  14197. //>>css.structure: ../../themes/base/core.css
  14198. //>>css.structure: ../../themes/base/spinner.css
  14199. //>>css.theme: ../../themes/base/theme.css
  14200. function spinnerModifier( fn ) {
  14201. return function() {
  14202. var previous = this.element.val();
  14203. fn.apply( this, arguments );
  14204. this._refresh();
  14205. if ( previous !== this.element.val() ) {
  14206. this._trigger( "change" );
  14207. }
  14208. };
  14209. }
  14210. $.widget( "ui.spinner", {
  14211. version: "1.14.1",
  14212. defaultElement: "<input>",
  14213. widgetEventPrefix: "spin",
  14214. options: {
  14215. classes: {
  14216. "ui-spinner": "ui-corner-all",
  14217. "ui-spinner-down": "ui-corner-br",
  14218. "ui-spinner-up": "ui-corner-tr"
  14219. },
  14220. culture: null,
  14221. icons: {
  14222. down: "ui-icon-triangle-1-s",
  14223. up: "ui-icon-triangle-1-n"
  14224. },
  14225. incremental: true,
  14226. max: null,
  14227. min: null,
  14228. numberFormat: null,
  14229. page: 10,
  14230. step: 1,
  14231. change: null,
  14232. spin: null,
  14233. start: null,
  14234. stop: null
  14235. },
  14236. _create: function() {
  14237. // handle string values that need to be parsed
  14238. this._setOption( "max", this.options.max );
  14239. this._setOption( "min", this.options.min );
  14240. this._setOption( "step", this.options.step );
  14241. // Only format if there is a value, prevents the field from being marked
  14242. // as invalid in Firefox, see #9573.
  14243. if ( this.value() !== "" ) {
  14244. // Format the value, but don't constrain.
  14245. this._value( this.element.val(), true );
  14246. }
  14247. this._draw();
  14248. this._on( this._events );
  14249. this._refresh();
  14250. // Turning off autocomplete prevents the browser from remembering the
  14251. // value when navigating through history, so we re-enable autocomplete
  14252. // if the page is unloaded before the widget is destroyed. #7790
  14253. this._on( this.window, {
  14254. beforeunload: function() {
  14255. this.element.removeAttr( "autocomplete" );
  14256. }
  14257. } );
  14258. },
  14259. _getCreateOptions: function() {
  14260. var options = this._super();
  14261. var element = this.element;
  14262. $.each( [ "min", "max", "step" ], function( i, option ) {
  14263. var value = element.attr( option );
  14264. if ( value != null && value.length ) {
  14265. options[ option ] = value;
  14266. }
  14267. } );
  14268. return options;
  14269. },
  14270. _events: {
  14271. keydown: function( event ) {
  14272. if ( this._start( event ) && this._keydown( event ) ) {
  14273. event.preventDefault();
  14274. }
  14275. },
  14276. keyup: "_stop",
  14277. focus: function() {
  14278. this.previous = this.element.val();
  14279. },
  14280. blur: function( event ) {
  14281. this._stop();
  14282. this._refresh();
  14283. if ( this.previous !== this.element.val() ) {
  14284. this._trigger( "change", event );
  14285. }
  14286. },
  14287. mousewheel: function( event, delta ) {
  14288. var activeElement = this.document[ 0 ].activeElement;
  14289. var isActive = this.element[ 0 ] === activeElement;
  14290. if ( !isActive || !delta ) {
  14291. return;
  14292. }
  14293. if ( !this.spinning && !this._start( event ) ) {
  14294. return false;
  14295. }
  14296. this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event );
  14297. clearTimeout( this.mousewheelTimer );
  14298. this.mousewheelTimer = this._delay( function() {
  14299. if ( this.spinning ) {
  14300. this._stop( event );
  14301. }
  14302. }, 100 );
  14303. event.preventDefault();
  14304. },
  14305. "mousedown .ui-spinner-button": function( event ) {
  14306. var previous;
  14307. // We never want the buttons to have focus; whenever the user is
  14308. // interacting with the spinner, the focus should be on the input.
  14309. // If the input is focused then this.previous is properly set from
  14310. // when the input first received focus. If the input is not focused
  14311. // then we need to set this.previous based on the value before spinning.
  14312. previous = this.element[ 0 ] === this.document[ 0 ].activeElement ?
  14313. this.previous : this.element.val();
  14314. function checkFocus() {
  14315. var isActive = this.element[ 0 ] === this.document[ 0 ].activeElement;
  14316. if ( !isActive ) {
  14317. this.element.trigger( "focus" );
  14318. this.previous = previous;
  14319. }
  14320. }
  14321. // Ensure focus is on (or stays on) the text field
  14322. event.preventDefault();
  14323. checkFocus.call( this );
  14324. if ( this._start( event ) === false ) {
  14325. return;
  14326. }
  14327. this._repeat( null, $( event.currentTarget )
  14328. .hasClass( "ui-spinner-up" ) ? 1 : -1, event );
  14329. },
  14330. "mouseup .ui-spinner-button": "_stop",
  14331. "mouseenter .ui-spinner-button": function( event ) {
  14332. // button will add ui-state-active if mouse was down while mouseleave and kept down
  14333. if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
  14334. return;
  14335. }
  14336. if ( this._start( event ) === false ) {
  14337. return false;
  14338. }
  14339. this._repeat( null, $( event.currentTarget )
  14340. .hasClass( "ui-spinner-up" ) ? 1 : -1, event );
  14341. },
  14342. // TODO: do we really want to consider this a stop?
  14343. // shouldn't we just stop the repeater and wait until mouseup before
  14344. // we trigger the stop event?
  14345. "mouseleave .ui-spinner-button": "_stop"
  14346. },
  14347. // Support mobile enhanced option and make backcompat more sane
  14348. _enhance: function() {
  14349. this.uiSpinner = this.element
  14350. .attr( "autocomplete", "off" )
  14351. .wrap( "<span>" )
  14352. .parent()
  14353. // Add buttons
  14354. .append(
  14355. "<a></a><a></a>"
  14356. );
  14357. },
  14358. _draw: function() {
  14359. this._enhance();
  14360. this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" );
  14361. this._addClass( "ui-spinner-input" );
  14362. this.element.attr( "role", "spinbutton" );
  14363. // Button bindings
  14364. this.buttons = this.uiSpinner.children( "a" )
  14365. .attr( "tabIndex", -1 )
  14366. .attr( "aria-hidden", true )
  14367. .button( {
  14368. classes: {
  14369. "ui-button": ""
  14370. }
  14371. } );
  14372. // TODO: Right now button does not support classes this is already updated in button PR
  14373. this._removeClass( this.buttons, "ui-corner-all" );
  14374. this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" );
  14375. this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" );
  14376. this.buttons.first().button( {
  14377. "icon": this.options.icons.up,
  14378. "showLabel": false
  14379. } );
  14380. this.buttons.last().button( {
  14381. "icon": this.options.icons.down,
  14382. "showLabel": false
  14383. } );
  14384. // IE 6 doesn't understand height: 50% for the buttons
  14385. // unless the wrapper has an explicit height
  14386. if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) &&
  14387. this.uiSpinner.height() > 0 ) {
  14388. this.uiSpinner.height( this.uiSpinner.height() );
  14389. }
  14390. },
  14391. _keydown: function( event ) {
  14392. var options = this.options,
  14393. keyCode = $.ui.keyCode;
  14394. switch ( event.keyCode ) {
  14395. case keyCode.UP:
  14396. this._repeat( null, 1, event );
  14397. return true;
  14398. case keyCode.DOWN:
  14399. this._repeat( null, -1, event );
  14400. return true;
  14401. case keyCode.PAGE_UP:
  14402. this._repeat( null, options.page, event );
  14403. return true;
  14404. case keyCode.PAGE_DOWN:
  14405. this._repeat( null, -options.page, event );
  14406. return true;
  14407. }
  14408. return false;
  14409. },
  14410. _start: function( event ) {
  14411. if ( !this.spinning && this._trigger( "start", event ) === false ) {
  14412. return false;
  14413. }
  14414. if ( !this.counter ) {
  14415. this.counter = 1;
  14416. }
  14417. this.spinning = true;
  14418. return true;
  14419. },
  14420. _repeat: function( i, steps, event ) {
  14421. i = i || 500;
  14422. clearTimeout( this.timer );
  14423. this.timer = this._delay( function() {
  14424. this._repeat( 40, steps, event );
  14425. }, i );
  14426. this._spin( steps * this.options.step, event );
  14427. },
  14428. _spin: function( step, event ) {
  14429. var value = this.value() || 0;
  14430. if ( !this.counter ) {
  14431. this.counter = 1;
  14432. }
  14433. value = this._adjustValue( value + step * this._increment( this.counter ) );
  14434. if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) {
  14435. this._value( value );
  14436. this.counter++;
  14437. }
  14438. },
  14439. _increment: function( i ) {
  14440. var incremental = this.options.incremental;
  14441. if ( incremental ) {
  14442. return typeof incremental === "function" ?
  14443. incremental( i ) :
  14444. Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
  14445. }
  14446. return 1;
  14447. },
  14448. _precision: function() {
  14449. var precision = this._precisionOf( this.options.step );
  14450. if ( this.options.min !== null ) {
  14451. precision = Math.max( precision, this._precisionOf( this.options.min ) );
  14452. }
  14453. return precision;
  14454. },
  14455. _precisionOf: function( num ) {
  14456. var str = num.toString(),
  14457. decimal = str.indexOf( "." );
  14458. return decimal === -1 ? 0 : str.length - decimal - 1;
  14459. },
  14460. _adjustValue: function( value ) {
  14461. var base, aboveMin,
  14462. options = this.options;
  14463. // Make sure we're at a valid step
  14464. // - find out where we are relative to the base (min or 0)
  14465. base = options.min !== null ? options.min : 0;
  14466. aboveMin = value - base;
  14467. // - round to the nearest step
  14468. aboveMin = Math.round( aboveMin / options.step ) * options.step;
  14469. // - rounding is based on 0, so adjust back to our base
  14470. value = base + aboveMin;
  14471. // Fix precision from bad JS floating point math
  14472. value = parseFloat( value.toFixed( this._precision() ) );
  14473. // Clamp the value
  14474. if ( options.max !== null && value > options.max ) {
  14475. return options.max;
  14476. }
  14477. if ( options.min !== null && value < options.min ) {
  14478. return options.min;
  14479. }
  14480. return value;
  14481. },
  14482. _stop: function( event ) {
  14483. if ( !this.spinning ) {
  14484. return;
  14485. }
  14486. clearTimeout( this.timer );
  14487. clearTimeout( this.mousewheelTimer );
  14488. this.counter = 0;
  14489. this.spinning = false;
  14490. this._trigger( "stop", event );
  14491. },
  14492. _setOption: function( key, value ) {
  14493. var prevValue, first, last;
  14494. if ( key === "culture" || key === "numberFormat" ) {
  14495. prevValue = this._parse( this.element.val() );
  14496. this.options[ key ] = value;
  14497. this.element.val( this._format( prevValue ) );
  14498. return;
  14499. }
  14500. if ( key === "max" || key === "min" || key === "step" ) {
  14501. if ( typeof value === "string" ) {
  14502. value = this._parse( value );
  14503. }
  14504. }
  14505. if ( key === "icons" ) {
  14506. first = this.buttons.first().find( ".ui-icon" );
  14507. this._removeClass( first, null, this.options.icons.up );
  14508. this._addClass( first, null, value.up );
  14509. last = this.buttons.last().find( ".ui-icon" );
  14510. this._removeClass( last, null, this.options.icons.down );
  14511. this._addClass( last, null, value.down );
  14512. }
  14513. this._super( key, value );
  14514. },
  14515. _setOptionDisabled: function( value ) {
  14516. this._super( value );
  14517. this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value );
  14518. this.element.prop( "disabled", !!value );
  14519. this.buttons.button( value ? "disable" : "enable" );
  14520. },
  14521. _setOptions: spinnerModifier( function( options ) {
  14522. this._super( options );
  14523. } ),
  14524. _parse: function( val ) {
  14525. if ( typeof val === "string" && val !== "" ) {
  14526. val = window.Globalize && this.options.numberFormat ?
  14527. Globalize.parseFloat( val, 10, this.options.culture ) : +val;
  14528. }
  14529. return val === "" || isNaN( val ) ? null : val;
  14530. },
  14531. _format: function( value ) {
  14532. if ( value === "" ) {
  14533. return "";
  14534. }
  14535. return window.Globalize && this.options.numberFormat ?
  14536. Globalize.format( value, this.options.numberFormat, this.options.culture ) :
  14537. value;
  14538. },
  14539. _refresh: function() {
  14540. this.element.attr( {
  14541. "aria-valuemin": this.options.min,
  14542. "aria-valuemax": this.options.max,
  14543. // TODO: what should we do with values that can't be parsed?
  14544. "aria-valuenow": this._parse( this.element.val() )
  14545. } );
  14546. },
  14547. isValid: function() {
  14548. var value = this.value();
  14549. // Null is invalid
  14550. if ( value === null ) {
  14551. return false;
  14552. }
  14553. // If value gets adjusted, it's invalid
  14554. return value === this._adjustValue( value );
  14555. },
  14556. // Update the value without triggering change
  14557. _value: function( value, allowAny ) {
  14558. var parsed;
  14559. if ( value !== "" ) {
  14560. parsed = this._parse( value );
  14561. if ( parsed !== null ) {
  14562. if ( !allowAny ) {
  14563. parsed = this._adjustValue( parsed );
  14564. }
  14565. value = this._format( parsed );
  14566. }
  14567. }
  14568. this.element.val( value );
  14569. this._refresh();
  14570. },
  14571. _destroy: function() {
  14572. this.element
  14573. .prop( "disabled", false )
  14574. .removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" );
  14575. this.uiSpinner.replaceWith( this.element );
  14576. },
  14577. stepUp: spinnerModifier( function( steps ) {
  14578. this._stepUp( steps );
  14579. } ),
  14580. _stepUp: function( steps ) {
  14581. if ( this._start() ) {
  14582. this._spin( ( steps || 1 ) * this.options.step );
  14583. this._stop();
  14584. }
  14585. },
  14586. stepDown: spinnerModifier( function( steps ) {
  14587. this._stepDown( steps );
  14588. } ),
  14589. _stepDown: function( steps ) {
  14590. if ( this._start() ) {
  14591. this._spin( ( steps || 1 ) * -this.options.step );
  14592. this._stop();
  14593. }
  14594. },
  14595. pageUp: spinnerModifier( function( pages ) {
  14596. this._stepUp( ( pages || 1 ) * this.options.page );
  14597. } ),
  14598. pageDown: spinnerModifier( function( pages ) {
  14599. this._stepDown( ( pages || 1 ) * this.options.page );
  14600. } ),
  14601. value: function( newVal ) {
  14602. if ( !arguments.length ) {
  14603. return this._parse( this.element.val() );
  14604. }
  14605. spinnerModifier( this._value ).call( this, newVal );
  14606. },
  14607. widget: function() {
  14608. return this.uiSpinner;
  14609. }
  14610. } );
  14611. // DEPRECATED
  14612. // TODO: switch return back to widget declaration at top of file when this is removed
  14613. if ( $.uiBackCompat === true ) {
  14614. // Backcompat for spinner html extension points
  14615. $.widget( "ui.spinner", $.ui.spinner, {
  14616. _enhance: function() {
  14617. this.uiSpinner = this.element
  14618. .attr( "autocomplete", "off" )
  14619. .wrap( this._uiSpinnerHtml() )
  14620. .parent()
  14621. // Add buttons
  14622. .append( this._buttonHtml() );
  14623. },
  14624. _uiSpinnerHtml: function() {
  14625. return "<span>";
  14626. },
  14627. _buttonHtml: function() {
  14628. return "<a></a><a></a>";
  14629. }
  14630. } );
  14631. }
  14632. var widgetsSpinner = $.ui.spinner;
  14633. /*!
  14634. * jQuery UI Tabs 1.14.1
  14635. * https://jqueryui.com
  14636. *
  14637. * Copyright OpenJS Foundation and other contributors
  14638. * Released under the MIT license.
  14639. * https://jquery.org/license
  14640. */
  14641. //>>label: Tabs
  14642. //>>group: Widgets
  14643. //>>description: Transforms a set of container elements into a tab structure.
  14644. //>>docs: https://api.jqueryui.com/tabs/
  14645. //>>demos: https://jqueryui.com/tabs/
  14646. //>>css.structure: ../../themes/base/core.css
  14647. //>>css.structure: ../../themes/base/tabs.css
  14648. //>>css.theme: ../../themes/base/theme.css
  14649. $.widget( "ui.tabs", {
  14650. version: "1.14.1",
  14651. delay: 300,
  14652. options: {
  14653. active: null,
  14654. classes: {
  14655. "ui-tabs": "ui-corner-all",
  14656. "ui-tabs-nav": "ui-corner-all",
  14657. "ui-tabs-panel": "ui-corner-bottom",
  14658. "ui-tabs-tab": "ui-corner-top"
  14659. },
  14660. collapsible: false,
  14661. event: "click",
  14662. heightStyle: "content",
  14663. hide: null,
  14664. show: null,
  14665. // Callbacks
  14666. activate: null,
  14667. beforeActivate: null,
  14668. beforeLoad: null,
  14669. load: null
  14670. },
  14671. _isLocal: ( function() {
  14672. var rhash = /#.*$/;
  14673. return function( anchor ) {
  14674. var anchorUrl, locationUrl;
  14675. anchorUrl = anchor.href.replace( rhash, "" );
  14676. locationUrl = location.href.replace( rhash, "" );
  14677. // Decoding may throw an error if the URL isn't UTF-8 (#9518)
  14678. try {
  14679. anchorUrl = decodeURIComponent( anchorUrl );
  14680. } catch ( error ) {}
  14681. try {
  14682. locationUrl = decodeURIComponent( locationUrl );
  14683. } catch ( error ) {}
  14684. return anchor.hash.length > 1 && anchorUrl === locationUrl;
  14685. };
  14686. } )(),
  14687. _create: function() {
  14688. var that = this,
  14689. options = this.options;
  14690. this.running = false;
  14691. this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
  14692. this._toggleClass( "ui-tabs-collapsible", null, options.collapsible );
  14693. this._processTabs();
  14694. options.active = this._initialActive();
  14695. // Take disabling tabs via class attribute from HTML
  14696. // into account and update option properly.
  14697. if ( Array.isArray( options.disabled ) ) {
  14698. options.disabled = $.uniqueSort( options.disabled.concat(
  14699. $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
  14700. return that.tabs.index( li );
  14701. } )
  14702. ) ).sort();
  14703. }
  14704. // Check for length avoids error when initializing empty list
  14705. if ( this.options.active !== false && this.anchors.length ) {
  14706. this.active = this._findActive( options.active );
  14707. } else {
  14708. this.active = $();
  14709. }
  14710. this._refresh();
  14711. if ( this.active.length ) {
  14712. this.load( options.active );
  14713. }
  14714. },
  14715. _initialActive: function() {
  14716. var active = this.options.active,
  14717. collapsible = this.options.collapsible,
  14718. locationHashDecoded = decodeURIComponent( location.hash.substring( 1 ) );
  14719. if ( active === null ) {
  14720. // check the fragment identifier in the URL
  14721. if ( locationHashDecoded ) {
  14722. this.tabs.each( function( i, tab ) {
  14723. if ( $( tab ).attr( "aria-controls" ) === locationHashDecoded ) {
  14724. active = i;
  14725. return false;
  14726. }
  14727. } );
  14728. }
  14729. // Check for a tab marked active via a class
  14730. if ( active === null ) {
  14731. active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
  14732. }
  14733. // No active tab, set to false
  14734. if ( active === null || active === -1 ) {
  14735. active = this.tabs.length ? 0 : false;
  14736. }
  14737. }
  14738. // Handle numbers: negative, out of range
  14739. if ( active !== false ) {
  14740. active = this.tabs.index( this.tabs.eq( active ) );
  14741. if ( active === -1 ) {
  14742. active = collapsible ? false : 0;
  14743. }
  14744. }
  14745. // Don't allow collapsible: false and active: false
  14746. if ( !collapsible && active === false && this.anchors.length ) {
  14747. active = 0;
  14748. }
  14749. return active;
  14750. },
  14751. _getCreateEventData: function() {
  14752. return {
  14753. tab: this.active,
  14754. panel: !this.active.length ? $() : this._getPanelForTab( this.active )
  14755. };
  14756. },
  14757. _tabKeydown: function( event ) {
  14758. var focusedTab = $( this.document[ 0 ].activeElement ).closest( "li" ),
  14759. selectedIndex = this.tabs.index( focusedTab ),
  14760. goingForward = true;
  14761. if ( this._handlePageNav( event ) ) {
  14762. return;
  14763. }
  14764. switch ( event.keyCode ) {
  14765. case $.ui.keyCode.RIGHT:
  14766. case $.ui.keyCode.DOWN:
  14767. selectedIndex++;
  14768. break;
  14769. case $.ui.keyCode.UP:
  14770. case $.ui.keyCode.LEFT:
  14771. goingForward = false;
  14772. selectedIndex--;
  14773. break;
  14774. case $.ui.keyCode.END:
  14775. selectedIndex = this.anchors.length - 1;
  14776. break;
  14777. case $.ui.keyCode.HOME:
  14778. selectedIndex = 0;
  14779. break;
  14780. case $.ui.keyCode.SPACE:
  14781. // Activate only, no collapsing
  14782. event.preventDefault();
  14783. clearTimeout( this.activating );
  14784. this._activate( selectedIndex );
  14785. return;
  14786. case $.ui.keyCode.ENTER:
  14787. // Toggle (cancel delayed activation, allow collapsing)
  14788. event.preventDefault();
  14789. clearTimeout( this.activating );
  14790. // Determine if we should collapse or activate
  14791. this._activate( selectedIndex === this.options.active ? false : selectedIndex );
  14792. return;
  14793. default:
  14794. return;
  14795. }
  14796. // Focus the appropriate tab, based on which key was pressed
  14797. event.preventDefault();
  14798. clearTimeout( this.activating );
  14799. selectedIndex = this._focusNextTab( selectedIndex, goingForward );
  14800. // Navigating with control/command key will prevent automatic activation
  14801. if ( !event.ctrlKey && !event.metaKey ) {
  14802. // Update aria-selected immediately so that AT think the tab is already selected.
  14803. // Otherwise AT may confuse the user by stating that they need to activate the tab,
  14804. // but the tab will already be activated by the time the announcement finishes.
  14805. focusedTab.attr( "aria-selected", "false" );
  14806. this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
  14807. this.activating = this._delay( function() {
  14808. this.option( "active", selectedIndex );
  14809. }, this.delay );
  14810. }
  14811. },
  14812. _panelKeydown: function( event ) {
  14813. if ( this._handlePageNav( event ) ) {
  14814. return;
  14815. }
  14816. // Ctrl+up moves focus to the current tab
  14817. if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
  14818. event.preventDefault();
  14819. this.active.trigger( "focus" );
  14820. }
  14821. },
  14822. // Alt+page up/down moves focus to the previous/next tab (and activates)
  14823. _handlePageNav: function( event ) {
  14824. if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
  14825. this._activate( this._focusNextTab( this.options.active - 1, false ) );
  14826. return true;
  14827. }
  14828. if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
  14829. this._activate( this._focusNextTab( this.options.active + 1, true ) );
  14830. return true;
  14831. }
  14832. },
  14833. _findNextTab: function( index, goingForward ) {
  14834. var lastTabIndex = this.tabs.length - 1;
  14835. function constrain() {
  14836. if ( index > lastTabIndex ) {
  14837. index = 0;
  14838. }
  14839. if ( index < 0 ) {
  14840. index = lastTabIndex;
  14841. }
  14842. return index;
  14843. }
  14844. while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
  14845. index = goingForward ? index + 1 : index - 1;
  14846. }
  14847. return index;
  14848. },
  14849. _focusNextTab: function( index, goingForward ) {
  14850. index = this._findNextTab( index, goingForward );
  14851. this.tabs.eq( index ).trigger( "focus" );
  14852. return index;
  14853. },
  14854. _setOption: function( key, value ) {
  14855. if ( key === "active" ) {
  14856. // _activate() will handle invalid values and update this.options
  14857. this._activate( value );
  14858. return;
  14859. }
  14860. this._super( key, value );
  14861. if ( key === "collapsible" ) {
  14862. this._toggleClass( "ui-tabs-collapsible", null, value );
  14863. // Setting collapsible: false while collapsed; open first panel
  14864. if ( !value && this.options.active === false ) {
  14865. this._activate( 0 );
  14866. }
  14867. }
  14868. if ( key === "event" ) {
  14869. this._setupEvents( value );
  14870. }
  14871. if ( key === "heightStyle" ) {
  14872. this._setupHeightStyle( value );
  14873. }
  14874. },
  14875. refresh: function() {
  14876. var options = this.options,
  14877. lis = this.tablist.children( ":has(a[href])" );
  14878. // Get disabled tabs from class attribute from HTML
  14879. // this will get converted to a boolean if needed in _refresh()
  14880. options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
  14881. return lis.index( tab );
  14882. } );
  14883. this._processTabs();
  14884. // Was collapsed or no tabs
  14885. if ( options.active === false || !this.anchors.length ) {
  14886. options.active = false;
  14887. this.active = $();
  14888. // was active, but active tab is gone
  14889. } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
  14890. // all remaining tabs are disabled
  14891. if ( this.tabs.length === options.disabled.length ) {
  14892. options.active = false;
  14893. this.active = $();
  14894. // activate previous tab
  14895. } else {
  14896. this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
  14897. }
  14898. // was active, active tab still exists
  14899. } else {
  14900. // make sure active index is correct
  14901. options.active = this.tabs.index( this.active );
  14902. }
  14903. this._refresh();
  14904. },
  14905. _refresh: function() {
  14906. this._setOptionDisabled( this.options.disabled );
  14907. this._setupEvents( this.options.event );
  14908. this._setupHeightStyle( this.options.heightStyle );
  14909. this.tabs.not( this.active ).attr( {
  14910. "aria-selected": "false",
  14911. "aria-expanded": "false",
  14912. tabIndex: -1
  14913. } );
  14914. this.panels.not( this._getPanelForTab( this.active ) )
  14915. .hide()
  14916. .attr( {
  14917. "aria-hidden": "true"
  14918. } );
  14919. // Make sure one tab is in the tab order
  14920. if ( !this.active.length ) {
  14921. this.tabs.eq( 0 ).attr( "tabIndex", 0 );
  14922. } else {
  14923. this.active
  14924. .attr( {
  14925. "aria-selected": "true",
  14926. "aria-expanded": "true",
  14927. tabIndex: 0
  14928. } );
  14929. this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
  14930. this._getPanelForTab( this.active )
  14931. .show()
  14932. .attr( {
  14933. "aria-hidden": "false"
  14934. } );
  14935. }
  14936. },
  14937. _processTabs: function() {
  14938. var that = this,
  14939. prevTabs = this.tabs,
  14940. prevAnchors = this.anchors,
  14941. prevPanels = this.panels;
  14942. this.tablist = this._getList().attr( "role", "tablist" );
  14943. this._addClass( this.tablist, "ui-tabs-nav",
  14944. "ui-helper-reset ui-helper-clearfix ui-widget-header" );
  14945. // Prevent users from focusing disabled tabs via click
  14946. this.tablist
  14947. .on( "mousedown" + this.eventNamespace, "> li", function( event ) {
  14948. if ( $( this ).is( ".ui-state-disabled" ) ) {
  14949. event.preventDefault();
  14950. }
  14951. } );
  14952. this.tabs = this.tablist.find( "> li:has(a[href])" )
  14953. .attr( {
  14954. role: "tab",
  14955. tabIndex: -1
  14956. } );
  14957. this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" );
  14958. this.anchors = this.tabs.map( function() {
  14959. return $( "a", this )[ 0 ];
  14960. } )
  14961. .attr( {
  14962. tabIndex: -1
  14963. } );
  14964. this._addClass( this.anchors, "ui-tabs-anchor" );
  14965. this.panels = $();
  14966. this.anchors.each( function( i, anchor ) {
  14967. var selector, panel, panelId,
  14968. anchorId = $( anchor ).uniqueId().attr( "id" ),
  14969. tab = $( anchor ).closest( "li" ),
  14970. originalAriaControls = tab.attr( "aria-controls" );
  14971. // Inline tab
  14972. if ( that._isLocal( anchor ) ) {
  14973. selector = decodeURIComponent( anchor.hash );
  14974. panelId = selector.substring( 1 );
  14975. panel = that.element.find( "#" + CSS.escape( panelId ) );
  14976. // remote tab
  14977. } else {
  14978. // If the tab doesn't already have aria-controls,
  14979. // generate an id by using a throw-away element
  14980. panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
  14981. selector = "#" + panelId;
  14982. panel = that.element.find( selector );
  14983. if ( !panel.length ) {
  14984. panel = that._createPanel( panelId );
  14985. panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
  14986. }
  14987. panel.attr( "aria-live", "polite" );
  14988. }
  14989. if ( panel.length ) {
  14990. that.panels = that.panels.add( panel );
  14991. }
  14992. if ( originalAriaControls ) {
  14993. tab.data( "ui-tabs-aria-controls", originalAriaControls );
  14994. }
  14995. tab.attr( {
  14996. "aria-controls": panelId,
  14997. "aria-labelledby": anchorId
  14998. } );
  14999. panel.attr( "aria-labelledby", anchorId );
  15000. } );
  15001. this.panels.attr( "role", "tabpanel" );
  15002. this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
  15003. // Avoid memory leaks (#10056)
  15004. if ( prevTabs ) {
  15005. this._off( prevTabs.not( this.tabs ) );
  15006. this._off( prevAnchors.not( this.anchors ) );
  15007. this._off( prevPanels.not( this.panels ) );
  15008. }
  15009. },
  15010. // Allow overriding how to find the list for rare usage scenarios (#7715)
  15011. _getList: function() {
  15012. return this.tablist || this.element.find( "ol, ul" ).eq( 0 );
  15013. },
  15014. _createPanel: function( id ) {
  15015. return $( "<div>" )
  15016. .attr( "id", id )
  15017. .data( "ui-tabs-destroy", true );
  15018. },
  15019. _setOptionDisabled: function( disabled ) {
  15020. var currentItem, li, i;
  15021. if ( Array.isArray( disabled ) ) {
  15022. if ( !disabled.length ) {
  15023. disabled = false;
  15024. } else if ( disabled.length === this.anchors.length ) {
  15025. disabled = true;
  15026. }
  15027. }
  15028. // Disable tabs
  15029. for ( i = 0; ( li = this.tabs[ i ] ); i++ ) {
  15030. currentItem = $( li );
  15031. if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
  15032. currentItem.attr( "aria-disabled", "true" );
  15033. this._addClass( currentItem, null, "ui-state-disabled" );
  15034. } else {
  15035. currentItem.removeAttr( "aria-disabled" );
  15036. this._removeClass( currentItem, null, "ui-state-disabled" );
  15037. }
  15038. }
  15039. this.options.disabled = disabled;
  15040. this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null,
  15041. disabled === true );
  15042. },
  15043. _setupEvents: function( event ) {
  15044. var events = {};
  15045. if ( event ) {
  15046. $.each( event.split( " " ), function( index, eventName ) {
  15047. events[ eventName ] = "_eventHandler";
  15048. } );
  15049. }
  15050. this._off( this.anchors.add( this.tabs ).add( this.panels ) );
  15051. // Always prevent the default action, even when disabled
  15052. this._on( true, this.anchors, {
  15053. click: function( event ) {
  15054. event.preventDefault();
  15055. }
  15056. } );
  15057. this._on( this.anchors, events );
  15058. this._on( this.tabs, { keydown: "_tabKeydown" } );
  15059. this._on( this.panels, { keydown: "_panelKeydown" } );
  15060. this._focusable( this.tabs );
  15061. this._hoverable( this.tabs );
  15062. },
  15063. _setupHeightStyle: function( heightStyle ) {
  15064. var maxHeight,
  15065. parent = this.element.parent();
  15066. if ( heightStyle === "fill" ) {
  15067. maxHeight = parent.height();
  15068. maxHeight -= this.element.outerHeight() - this.element.height();
  15069. this.element.siblings( ":visible" ).each( function() {
  15070. var elem = $( this ),
  15071. position = elem.css( "position" );
  15072. if ( position === "absolute" || position === "fixed" ) {
  15073. return;
  15074. }
  15075. maxHeight -= elem.outerHeight( true );
  15076. } );
  15077. this.element.children().not( this.panels ).each( function() {
  15078. maxHeight -= $( this ).outerHeight( true );
  15079. } );
  15080. this.panels.each( function() {
  15081. $( this ).height( Math.max( 0, maxHeight -
  15082. $( this ).innerHeight() + $( this ).height() ) );
  15083. } )
  15084. .css( "overflow", "auto" );
  15085. } else if ( heightStyle === "auto" ) {
  15086. maxHeight = 0;
  15087. this.panels.each( function() {
  15088. maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
  15089. } ).height( maxHeight );
  15090. }
  15091. },
  15092. _eventHandler: function( event ) {
  15093. var options = this.options,
  15094. active = this.active,
  15095. anchor = $( event.currentTarget ),
  15096. tab = anchor.closest( "li" ),
  15097. clickedIsActive = tab[ 0 ] === active[ 0 ],
  15098. collapsing = clickedIsActive && options.collapsible,
  15099. toShow = collapsing ? $() : this._getPanelForTab( tab ),
  15100. toHide = !active.length ? $() : this._getPanelForTab( active ),
  15101. eventData = {
  15102. oldTab: active,
  15103. oldPanel: toHide,
  15104. newTab: collapsing ? $() : tab,
  15105. newPanel: toShow
  15106. };
  15107. event.preventDefault();
  15108. if ( tab.hasClass( "ui-state-disabled" ) ||
  15109. // tab is already loading
  15110. tab.hasClass( "ui-tabs-loading" ) ||
  15111. // can't switch durning an animation
  15112. this.running ||
  15113. // click on active header, but not collapsible
  15114. ( clickedIsActive && !options.collapsible ) ||
  15115. // allow canceling activation
  15116. ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
  15117. return;
  15118. }
  15119. options.active = collapsing ? false : this.tabs.index( tab );
  15120. this.active = clickedIsActive ? $() : tab;
  15121. if ( this.xhr ) {
  15122. this.xhr.abort();
  15123. }
  15124. if ( !toHide.length && !toShow.length ) {
  15125. $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
  15126. }
  15127. if ( toShow.length ) {
  15128. this.load( this.tabs.index( tab ), event );
  15129. }
  15130. this._toggle( event, eventData );
  15131. },
  15132. // Handles show/hide for selecting tabs
  15133. _toggle: function( event, eventData ) {
  15134. var that = this,
  15135. toShow = eventData.newPanel,
  15136. toHide = eventData.oldPanel;
  15137. this.running = true;
  15138. function complete() {
  15139. that.running = false;
  15140. that._trigger( "activate", event, eventData );
  15141. }
  15142. function show() {
  15143. that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
  15144. if ( toShow.length && that.options.show ) {
  15145. that._show( toShow, that.options.show, complete );
  15146. } else {
  15147. toShow.show();
  15148. complete();
  15149. }
  15150. }
  15151. // Start out by hiding, then showing, then completing
  15152. if ( toHide.length && this.options.hide ) {
  15153. this._hide( toHide, this.options.hide, function() {
  15154. that._removeClass( eventData.oldTab.closest( "li" ),
  15155. "ui-tabs-active", "ui-state-active" );
  15156. show();
  15157. } );
  15158. } else {
  15159. this._removeClass( eventData.oldTab.closest( "li" ),
  15160. "ui-tabs-active", "ui-state-active" );
  15161. toHide.hide();
  15162. show();
  15163. }
  15164. toHide.attr( "aria-hidden", "true" );
  15165. eventData.oldTab.attr( {
  15166. "aria-selected": "false",
  15167. "aria-expanded": "false"
  15168. } );
  15169. // If we're switching tabs, remove the old tab from the tab order.
  15170. // If we're opening from collapsed state, remove the previous tab from the tab order.
  15171. // If we're collapsing, then keep the collapsing tab in the tab order.
  15172. if ( toShow.length && toHide.length ) {
  15173. eventData.oldTab.attr( "tabIndex", -1 );
  15174. } else if ( toShow.length ) {
  15175. this.tabs.filter( function() {
  15176. return $( this ).attr( "tabIndex" ) === 0;
  15177. } )
  15178. .attr( "tabIndex", -1 );
  15179. }
  15180. toShow.attr( "aria-hidden", "false" );
  15181. eventData.newTab.attr( {
  15182. "aria-selected": "true",
  15183. "aria-expanded": "true",
  15184. tabIndex: 0
  15185. } );
  15186. },
  15187. _activate: function( index ) {
  15188. var anchor,
  15189. active = this._findActive( index );
  15190. // Trying to activate the already active panel
  15191. if ( active[ 0 ] === this.active[ 0 ] ) {
  15192. return;
  15193. }
  15194. // Trying to collapse, simulate a click on the current active header
  15195. if ( !active.length ) {
  15196. active = this.active;
  15197. }
  15198. anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
  15199. this._eventHandler( {
  15200. target: anchor,
  15201. currentTarget: anchor,
  15202. preventDefault: $.noop
  15203. } );
  15204. },
  15205. _findActive: function( index ) {
  15206. return index === false ? $() : this.tabs.eq( index );
  15207. },
  15208. _getIndex: function( index ) {
  15209. // meta-function to give users option to provide a href string instead of a numerical index.
  15210. if ( typeof index === "string" ) {
  15211. index = this.anchors.index( this.anchors.filter( "[href$='" +
  15212. CSS.escape( index ) + "']" ) );
  15213. }
  15214. return index;
  15215. },
  15216. _destroy: function() {
  15217. if ( this.xhr ) {
  15218. this.xhr.abort();
  15219. }
  15220. this.tablist
  15221. .removeAttr( "role" )
  15222. .off( this.eventNamespace );
  15223. this.anchors
  15224. .removeAttr( "role tabIndex" )
  15225. .removeUniqueId();
  15226. this.tabs.add( this.panels ).each( function() {
  15227. if ( $.data( this, "ui-tabs-destroy" ) ) {
  15228. $( this ).remove();
  15229. } else {
  15230. $( this ).removeAttr( "role tabIndex " +
  15231. "aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" );
  15232. }
  15233. } );
  15234. this.tabs.each( function() {
  15235. var li = $( this ),
  15236. prev = li.data( "ui-tabs-aria-controls" );
  15237. if ( prev ) {
  15238. li
  15239. .attr( "aria-controls", prev )
  15240. .removeData( "ui-tabs-aria-controls" );
  15241. } else {
  15242. li.removeAttr( "aria-controls" );
  15243. }
  15244. } );
  15245. this.panels.show();
  15246. if ( this.options.heightStyle !== "content" ) {
  15247. this.panels.css( "height", "" );
  15248. }
  15249. },
  15250. enable: function( index ) {
  15251. var disabled = this.options.disabled;
  15252. if ( disabled === false ) {
  15253. return;
  15254. }
  15255. if ( index === undefined ) {
  15256. disabled = false;
  15257. } else {
  15258. index = this._getIndex( index );
  15259. if ( Array.isArray( disabled ) ) {
  15260. disabled = $.map( disabled, function( num ) {
  15261. return num !== index ? num : null;
  15262. } );
  15263. } else {
  15264. disabled = $.map( this.tabs, function( li, num ) {
  15265. return num !== index ? num : null;
  15266. } );
  15267. }
  15268. }
  15269. this._setOptionDisabled( disabled );
  15270. },
  15271. disable: function( index ) {
  15272. var disabled = this.options.disabled;
  15273. if ( disabled === true ) {
  15274. return;
  15275. }
  15276. if ( index === undefined ) {
  15277. disabled = true;
  15278. } else {
  15279. index = this._getIndex( index );
  15280. if ( $.inArray( index, disabled ) !== -1 ) {
  15281. return;
  15282. }
  15283. if ( Array.isArray( disabled ) ) {
  15284. disabled = $.merge( [ index ], disabled ).sort();
  15285. } else {
  15286. disabled = [ index ];
  15287. }
  15288. }
  15289. this._setOptionDisabled( disabled );
  15290. },
  15291. load: function( index, event ) {
  15292. index = this._getIndex( index );
  15293. var that = this,
  15294. tab = this.tabs.eq( index ),
  15295. anchor = tab.find( ".ui-tabs-anchor" ),
  15296. panel = this._getPanelForTab( tab ),
  15297. eventData = {
  15298. tab: tab,
  15299. panel: panel
  15300. },
  15301. complete = function( jqXHR, status ) {
  15302. if ( status === "abort" ) {
  15303. that.panels.stop( false, true );
  15304. }
  15305. that._removeClass( tab, "ui-tabs-loading" );
  15306. panel.removeAttr( "aria-busy" );
  15307. if ( jqXHR === that.xhr ) {
  15308. delete that.xhr;
  15309. }
  15310. };
  15311. // Not remote
  15312. if ( this._isLocal( anchor[ 0 ] ) ) {
  15313. return;
  15314. }
  15315. this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
  15316. if ( this.xhr.statusText !== "canceled" ) {
  15317. this._addClass( tab, "ui-tabs-loading" );
  15318. panel.attr( "aria-busy", "true" );
  15319. this.xhr
  15320. .done( function( response, status, jqXHR ) {
  15321. panel.html( response );
  15322. that._trigger( "load", event, eventData );
  15323. complete( jqXHR, status );
  15324. } )
  15325. .fail( function( jqXHR, status ) {
  15326. complete( jqXHR, status );
  15327. } );
  15328. }
  15329. },
  15330. _ajaxSettings: function( anchor, event, eventData ) {
  15331. var that = this;
  15332. return {
  15333. url: anchor.attr( "href" ),
  15334. beforeSend: function( jqXHR, settings ) {
  15335. return that._trigger( "beforeLoad", event,
  15336. $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
  15337. }
  15338. };
  15339. },
  15340. _getPanelForTab: function( tab ) {
  15341. var id = $( tab ).attr( "aria-controls" );
  15342. return this.element.find( "#" + CSS.escape( id ) );
  15343. }
  15344. } );
  15345. // DEPRECATED
  15346. // TODO: Switch return back to widget declaration at top of file when this is removed
  15347. if ( $.uiBackCompat === true ) {
  15348. // Backcompat for ui-tab class (now ui-tabs-tab)
  15349. $.widget( "ui.tabs", $.ui.tabs, {
  15350. _processTabs: function() {
  15351. this._superApply( arguments );
  15352. this._addClass( this.tabs, "ui-tab" );
  15353. }
  15354. } );
  15355. }
  15356. var widgetsTabs = $.ui.tabs;
  15357. /*!
  15358. * jQuery UI Tooltip 1.14.1
  15359. * https://jqueryui.com
  15360. *
  15361. * Copyright OpenJS Foundation and other contributors
  15362. * Released under the MIT license.
  15363. * https://jquery.org/license
  15364. */
  15365. //>>label: Tooltip
  15366. //>>group: Widgets
  15367. //>>description: Shows additional information for any element on hover or focus.
  15368. //>>docs: https://api.jqueryui.com/tooltip/
  15369. //>>demos: https://jqueryui.com/tooltip/
  15370. //>>css.structure: ../../themes/base/core.css
  15371. //>>css.structure: ../../themes/base/tooltip.css
  15372. //>>css.theme: ../../themes/base/theme.css
  15373. $.widget( "ui.tooltip", {
  15374. version: "1.14.1",
  15375. options: {
  15376. classes: {
  15377. "ui-tooltip": "ui-corner-all ui-widget-shadow"
  15378. },
  15379. content: function() {
  15380. var title = $( this ).attr( "title" );
  15381. // Escape title, since we're going from an attribute to raw HTML
  15382. return $( "<a>" ).text( title ).html();
  15383. },
  15384. hide: true,
  15385. // Disabled elements have inconsistent behavior across browsers (#8661)
  15386. items: "[title]:not([disabled])",
  15387. position: {
  15388. my: "left top+15",
  15389. at: "left bottom",
  15390. collision: "flipfit flip"
  15391. },
  15392. show: true,
  15393. track: false,
  15394. // Callbacks
  15395. close: null,
  15396. open: null
  15397. },
  15398. _addDescribedBy: function( elem, id ) {
  15399. var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ );
  15400. describedby.push( id );
  15401. elem
  15402. .data( "ui-tooltip-id", id )
  15403. .attr( "aria-describedby", String.prototype.trim.call( describedby.join( " " ) ) );
  15404. },
  15405. _removeDescribedBy: function( elem ) {
  15406. var id = elem.data( "ui-tooltip-id" ),
  15407. describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ),
  15408. index = $.inArray( id, describedby );
  15409. if ( index !== -1 ) {
  15410. describedby.splice( index, 1 );
  15411. }
  15412. elem.removeData( "ui-tooltip-id" );
  15413. describedby = String.prototype.trim.call( describedby.join( " " ) );
  15414. if ( describedby ) {
  15415. elem.attr( "aria-describedby", describedby );
  15416. } else {
  15417. elem.removeAttr( "aria-describedby" );
  15418. }
  15419. },
  15420. _create: function() {
  15421. this._on( {
  15422. mouseover: "open",
  15423. focusin: "open"
  15424. } );
  15425. // IDs of generated tooltips, needed for destroy
  15426. this.tooltips = {};
  15427. // IDs of parent tooltips where we removed the title attribute
  15428. this.parents = {};
  15429. // Append the aria-live region so tooltips announce correctly
  15430. this.liveRegion = $( "<div>" )
  15431. .attr( {
  15432. role: "log",
  15433. "aria-live": "assertive",
  15434. "aria-relevant": "additions"
  15435. } )
  15436. .appendTo( this.document[ 0 ].body );
  15437. this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
  15438. this.disabledTitles = $( [] );
  15439. },
  15440. _setOption: function( key, value ) {
  15441. var that = this;
  15442. this._super( key, value );
  15443. if ( key === "content" ) {
  15444. $.each( this.tooltips, function( id, tooltipData ) {
  15445. that._updateContent( tooltipData.element );
  15446. } );
  15447. }
  15448. },
  15449. _setOptionDisabled: function( value ) {
  15450. this[ value ? "_disable" : "_enable" ]();
  15451. },
  15452. _disable: function() {
  15453. var that = this;
  15454. // Close open tooltips
  15455. $.each( this.tooltips, function( id, tooltipData ) {
  15456. var event = $.Event( "blur" );
  15457. event.target = event.currentTarget = tooltipData.element[ 0 ];
  15458. that.close( event, true );
  15459. } );
  15460. // Remove title attributes to prevent native tooltips
  15461. this.disabledTitles = this.disabledTitles.add(
  15462. this.element.find( this.options.items ).addBack()
  15463. .filter( function() {
  15464. var element = $( this );
  15465. if ( element.is( "[title]" ) ) {
  15466. return element
  15467. .data( "ui-tooltip-title", element.attr( "title" ) )
  15468. .removeAttr( "title" );
  15469. }
  15470. } )
  15471. );
  15472. },
  15473. _enable: function() {
  15474. // restore title attributes
  15475. this.disabledTitles.each( function() {
  15476. var element = $( this );
  15477. if ( element.data( "ui-tooltip-title" ) ) {
  15478. element.attr( "title", element.data( "ui-tooltip-title" ) );
  15479. }
  15480. } );
  15481. this.disabledTitles = $( [] );
  15482. },
  15483. open: function( event ) {
  15484. var that = this,
  15485. target = $( event ? event.target : this.element )
  15486. // we need closest here due to mouseover bubbling,
  15487. // but always pointing at the same event target
  15488. .closest( this.options.items );
  15489. // No element to show a tooltip for or the tooltip is already open
  15490. if ( !target.length || target.data( "ui-tooltip-id" ) ) {
  15491. return;
  15492. }
  15493. if ( target.attr( "title" ) ) {
  15494. target.data( "ui-tooltip-title", target.attr( "title" ) );
  15495. }
  15496. target.data( "ui-tooltip-open", true );
  15497. // Kill parent tooltips, custom or native, for hover
  15498. if ( event && event.type === "mouseover" ) {
  15499. target.parents().each( function() {
  15500. var parent = $( this ),
  15501. blurEvent;
  15502. if ( parent.data( "ui-tooltip-open" ) ) {
  15503. blurEvent = $.Event( "blur" );
  15504. blurEvent.target = blurEvent.currentTarget = this;
  15505. that.close( blurEvent, true );
  15506. }
  15507. if ( parent.attr( "title" ) ) {
  15508. parent.uniqueId();
  15509. that.parents[ this.id ] = {
  15510. element: this,
  15511. title: parent.attr( "title" )
  15512. };
  15513. parent.attr( "title", "" );
  15514. }
  15515. } );
  15516. }
  15517. this._registerCloseHandlers( event, target );
  15518. this._updateContent( target, event );
  15519. },
  15520. _updateContent: function( target, event ) {
  15521. var content,
  15522. contentOption = this.options.content,
  15523. that = this,
  15524. eventType = event ? event.type : null;
  15525. if ( typeof contentOption === "string" || contentOption.nodeType ||
  15526. contentOption.jquery ) {
  15527. return this._open( event, target, contentOption );
  15528. }
  15529. content = contentOption.call( target[ 0 ], function( response ) {
  15530. // Ignore async response if tooltip was closed already
  15531. if ( !target.data( "ui-tooltip-open" ) ) {
  15532. return;
  15533. }
  15534. // JQuery creates a special event for focusin when it doesn't
  15535. // exist natively. To improve performance, the native event
  15536. // object is reused and the type is changed. Therefore, we can't
  15537. // rely on the type being correct after the event finished
  15538. // bubbling, so we set it back to the previous value. (#8740)
  15539. if ( event ) {
  15540. event.type = eventType;
  15541. }
  15542. that._open( event, target, response );
  15543. } );
  15544. if ( content ) {
  15545. this._open( event, target, content );
  15546. }
  15547. },
  15548. _open: function( event, target, content ) {
  15549. var tooltipData, tooltip, delayedShow, a11yContent,
  15550. positionOption = $.extend( {}, this.options.position );
  15551. if ( !content ) {
  15552. return;
  15553. }
  15554. // Content can be updated multiple times. If the tooltip already
  15555. // exists, then just update the content and bail.
  15556. tooltipData = this._find( target );
  15557. if ( tooltipData ) {
  15558. tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
  15559. return;
  15560. }
  15561. // If we have a title, clear it to prevent the native tooltip
  15562. // we have to check first to avoid defining a title if none exists
  15563. // (we don't want to cause an element to start matching [title])
  15564. //
  15565. // We use removeAttr only for key events, to allow IE to export the correct
  15566. // accessible attributes. For mouse events, set to empty string to avoid
  15567. // native tooltip showing up (happens only when removing inside mouseover).
  15568. if ( target.is( "[title]" ) ) {
  15569. if ( event && event.type === "mouseover" ) {
  15570. target.attr( "title", "" );
  15571. } else {
  15572. target.removeAttr( "title" );
  15573. }
  15574. }
  15575. tooltipData = this._tooltip( target );
  15576. tooltip = tooltipData.tooltip;
  15577. this._addDescribedBy( target, tooltip.attr( "id" ) );
  15578. tooltip.find( ".ui-tooltip-content" ).html( content );
  15579. // Support: Voiceover on OS X, JAWS on IE <= 9
  15580. // JAWS announces deletions even when aria-relevant="additions"
  15581. // Voiceover will sometimes re-read the entire log region's contents from the beginning
  15582. this.liveRegion.children().hide();
  15583. a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() );
  15584. a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" );
  15585. a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
  15586. a11yContent.appendTo( this.liveRegion );
  15587. function position( event ) {
  15588. positionOption.of = event;
  15589. if ( tooltip.is( ":hidden" ) ) {
  15590. return;
  15591. }
  15592. tooltip.position( positionOption );
  15593. }
  15594. if ( this.options.track && event && /^mouse/.test( event.type ) ) {
  15595. this._on( this.document, {
  15596. mousemove: position
  15597. } );
  15598. // trigger once to override element-relative positioning
  15599. position( event );
  15600. } else {
  15601. tooltip.position( $.extend( {
  15602. of: target
  15603. }, this.options.position ) );
  15604. }
  15605. tooltip.hide();
  15606. this._show( tooltip, this.options.show );
  15607. // Handle tracking tooltips that are shown with a delay (#8644). As soon
  15608. // as the tooltip is visible, position the tooltip using the most recent
  15609. // event.
  15610. // Adds the check to add the timers only when both delay and track options are set (#14682)
  15611. if ( this.options.track && this.options.show && this.options.show.delay ) {
  15612. delayedShow = this.delayedShow = setInterval( function() {
  15613. if ( tooltip.is( ":visible" ) ) {
  15614. position( positionOption.of );
  15615. clearInterval( delayedShow );
  15616. }
  15617. }, 13 );
  15618. }
  15619. this._trigger( "open", event, { tooltip: tooltip } );
  15620. },
  15621. _registerCloseHandlers: function( event, target ) {
  15622. var events = {
  15623. keyup: function( event ) {
  15624. if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
  15625. var fakeEvent = $.Event( event );
  15626. fakeEvent.currentTarget = target[ 0 ];
  15627. this.close( fakeEvent, true );
  15628. }
  15629. }
  15630. };
  15631. // Only bind remove handler for delegated targets. Non-delegated
  15632. // tooltips will handle this in destroy.
  15633. if ( target[ 0 ] !== this.element[ 0 ] ) {
  15634. events.remove = function() {
  15635. var targetElement = this._find( target );
  15636. if ( targetElement ) {
  15637. this._removeTooltip( targetElement.tooltip );
  15638. }
  15639. };
  15640. }
  15641. if ( !event || event.type === "mouseover" ) {
  15642. events.mouseleave = "close";
  15643. }
  15644. if ( !event || event.type === "focusin" ) {
  15645. events.focusout = "close";
  15646. }
  15647. this._on( true, target, events );
  15648. },
  15649. close: function( event ) {
  15650. var tooltip,
  15651. that = this,
  15652. target = $( event ? event.currentTarget : this.element ),
  15653. tooltipData = this._find( target );
  15654. // The tooltip may already be closed
  15655. if ( !tooltipData ) {
  15656. // We set ui-tooltip-open immediately upon open (in open()), but only set the
  15657. // additional data once there's actually content to show (in _open()). So even if the
  15658. // tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
  15659. // the period between open() and _open().
  15660. target.removeData( "ui-tooltip-open" );
  15661. return;
  15662. }
  15663. tooltip = tooltipData.tooltip;
  15664. // Disabling closes the tooltip, so we need to track when we're closing
  15665. // to avoid an infinite loop in case the tooltip becomes disabled on close
  15666. if ( tooltipData.closing ) {
  15667. return;
  15668. }
  15669. // Clear the interval for delayed tracking tooltips
  15670. clearInterval( this.delayedShow );
  15671. // Only set title if we had one before (see comment in _open())
  15672. // If the title attribute has changed since open(), don't restore
  15673. if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
  15674. target.attr( "title", target.data( "ui-tooltip-title" ) );
  15675. }
  15676. this._removeDescribedBy( target );
  15677. tooltipData.hiding = true;
  15678. tooltip.stop( true );
  15679. this._hide( tooltip, this.options.hide, function() {
  15680. that._removeTooltip( $( this ) );
  15681. } );
  15682. target.removeData( "ui-tooltip-open" );
  15683. this._off( target, "mouseleave focusout keyup" );
  15684. // Remove 'remove' binding only on delegated targets
  15685. if ( target[ 0 ] !== this.element[ 0 ] ) {
  15686. this._off( target, "remove" );
  15687. }
  15688. this._off( this.document, "mousemove" );
  15689. if ( event && event.type === "mouseleave" ) {
  15690. $.each( this.parents, function( id, parent ) {
  15691. $( parent.element ).attr( "title", parent.title );
  15692. delete that.parents[ id ];
  15693. } );
  15694. }
  15695. tooltipData.closing = true;
  15696. this._trigger( "close", event, { tooltip: tooltip } );
  15697. if ( !tooltipData.hiding ) {
  15698. tooltipData.closing = false;
  15699. }
  15700. },
  15701. _tooltip: function( element ) {
  15702. var tooltip = $( "<div>" ).attr( "role", "tooltip" ),
  15703. content = $( "<div>" ).appendTo( tooltip ),
  15704. id = tooltip.uniqueId().attr( "id" );
  15705. this._addClass( content, "ui-tooltip-content" );
  15706. this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" );
  15707. tooltip.appendTo( this._appendTo( element ) );
  15708. return this.tooltips[ id ] = {
  15709. element: element,
  15710. tooltip: tooltip
  15711. };
  15712. },
  15713. _find: function( target ) {
  15714. var id = target.data( "ui-tooltip-id" );
  15715. return id ? this.tooltips[ id ] : null;
  15716. },
  15717. _removeTooltip: function( tooltip ) {
  15718. // Clear the interval for delayed tracking tooltips
  15719. clearInterval( this.delayedShow );
  15720. tooltip.remove();
  15721. delete this.tooltips[ tooltip.attr( "id" ) ];
  15722. },
  15723. _appendTo: function( target ) {
  15724. var element = target.closest( ".ui-front, dialog" );
  15725. if ( !element.length ) {
  15726. element = this.document[ 0 ].body;
  15727. }
  15728. return element;
  15729. },
  15730. _destroy: function() {
  15731. var that = this;
  15732. // Close open tooltips
  15733. $.each( this.tooltips, function( id, tooltipData ) {
  15734. // Delegate to close method to handle common cleanup
  15735. var event = $.Event( "blur" ),
  15736. element = tooltipData.element;
  15737. event.target = event.currentTarget = element[ 0 ];
  15738. that.close( event, true );
  15739. // Remove immediately; destroying an open tooltip doesn't use the
  15740. // hide animation
  15741. $( "#" + id ).remove();
  15742. // Restore the title
  15743. if ( element.data( "ui-tooltip-title" ) ) {
  15744. // If the title attribute has changed since open(), don't restore
  15745. if ( !element.attr( "title" ) ) {
  15746. element.attr( "title", element.data( "ui-tooltip-title" ) );
  15747. }
  15748. element.removeData( "ui-tooltip-title" );
  15749. }
  15750. } );
  15751. this.liveRegion.remove();
  15752. }
  15753. } );
  15754. // DEPRECATED
  15755. // TODO: Switch return back to widget declaration at top of file when this is removed
  15756. if ( $.uiBackCompat === true ) {
  15757. // Backcompat for tooltipClass option
  15758. $.widget( "ui.tooltip", $.ui.tooltip, {
  15759. options: {
  15760. tooltipClass: null
  15761. },
  15762. _tooltip: function() {
  15763. var tooltipData = this._superApply( arguments );
  15764. if ( this.options.tooltipClass ) {
  15765. tooltipData.tooltip.addClass( this.options.tooltipClass );
  15766. }
  15767. return tooltipData;
  15768. }
  15769. } );
  15770. }
  15771. var widgetsTooltip = $.ui.tooltip;
  15772. } );