single-file.js 807 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273
  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  3. typeof define === 'function' && define.amd ? define(['exports'], factory) :
  4. (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.singlefile = {}));
  5. })(this, (function (exports) { 'use strict';
  6. const { Array: Array$1, Object: Object$1, String: String$1, Number: Number$1, BigInt, Math: Math$1, Date: Date$1, Map: Map$2, Set: Set$3, Response, URL: URL$2, Error: Error$1, Uint8Array: Uint8Array$1, Uint16Array, Uint32Array: Uint32Array$1, DataView: DataView$1, Blob: Blob$3, Promise: Promise$1, TextEncoder: TextEncoder$2, TextDecoder: TextDecoder$2, document: document$4, crypto: crypto$1, btoa, TransformStream, ReadableStream, WritableStream, CompressionStream, DecompressionStream, navigator, Worker } = globalThis;
  7. /*
  8. Copyright (c) 2022 Gildas Lormeau. All rights reserved.
  9. Redistribution and use in source and binary forms, with or without
  10. modification, are permitted provided that the following conditions are met:
  11. 1. Redistributions of source code must retain the above copyright notice,
  12. this list of conditions and the following disclaimer.
  13. 2. Redistributions in binary form must reproduce the above copyright
  14. notice, this list of conditions and the following disclaimer in
  15. the documentation and/or other materials provided with the distribution.
  16. 3. The names of the authors may not be used to endorse or promote products
  17. derived from this software without specific prior written permission.
  18. THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  19. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  20. FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
  21. INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
  22. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  23. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  24. OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  25. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  26. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  27. EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. */
  29. const MAX_32_BITS = 0xffffffff;
  30. const MAX_16_BITS = 0xffff;
  31. const COMPRESSION_METHOD_DEFLATE = 0x08;
  32. const COMPRESSION_METHOD_STORE = 0x00;
  33. const COMPRESSION_METHOD_AES = 0x63;
  34. const LOCAL_FILE_HEADER_SIGNATURE = 0x04034b50;
  35. const SPLIT_ZIP_FILE_SIGNATURE = 0x08074b50;
  36. const DATA_DESCRIPTOR_RECORD_SIGNATURE = SPLIT_ZIP_FILE_SIGNATURE;
  37. const CENTRAL_FILE_HEADER_SIGNATURE = 0x02014b50;
  38. const END_OF_CENTRAL_DIR_SIGNATURE = 0x06054b50;
  39. const ZIP64_END_OF_CENTRAL_DIR_SIGNATURE = 0x06064b50;
  40. const ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE = 0x07064b50;
  41. const END_OF_CENTRAL_DIR_LENGTH = 22;
  42. const ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH = 20;
  43. const ZIP64_END_OF_CENTRAL_DIR_LENGTH = 56;
  44. const ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH = END_OF_CENTRAL_DIR_LENGTH + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH + ZIP64_END_OF_CENTRAL_DIR_LENGTH;
  45. const EXTRAFIELD_TYPE_ZIP64 = 0x0001;
  46. const EXTRAFIELD_TYPE_AES = 0x9901;
  47. const EXTRAFIELD_TYPE_NTFS = 0x000a;
  48. const EXTRAFIELD_TYPE_NTFS_TAG1 = 0x0001;
  49. const EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP = 0x5455;
  50. const EXTRAFIELD_TYPE_UNICODE_PATH = 0x7075;
  51. const EXTRAFIELD_TYPE_UNICODE_COMMENT = 0x6375;
  52. const EXTRAFIELD_TYPE_USDZ = 0x1986;
  53. const BITFLAG_ENCRYPTED = 0x01;
  54. const BITFLAG_LEVEL = 0x06;
  55. const BITFLAG_DATA_DESCRIPTOR = 0x0008;
  56. const BITFLAG_LANG_ENCODING_FLAG = 0x0800;
  57. const FILE_ATTR_MSDOS_DIR_MASK = 0x10;
  58. const VERSION_DEFLATE = 0x14;
  59. const VERSION_ZIP64 = 0x2D;
  60. const VERSION_AES = 0x33;
  61. const DIRECTORY_SIGNATURE = "/";
  62. const MAX_DATE = new Date$1(2107, 11, 31);
  63. const MIN_DATE = new Date$1(1980, 0, 1);
  64. const UNDEFINED_VALUE = undefined;
  65. const UNDEFINED_TYPE$1 = "undefined";
  66. const FUNCTION_TYPE$1 = "function";
  67. /*
  68. Copyright (c) 2022 Gildas Lormeau. All rights reserved.
  69. Redistribution and use in source and binary forms, with or without
  70. modification, are permitted provided that the following conditions are met:
  71. 1. Redistributions of source code must retain the above copyright notice,
  72. this list of conditions and the following disclaimer.
  73. 2. Redistributions in binary form must reproduce the above copyright
  74. notice, this list of conditions and the following disclaimer in
  75. the documentation and/or other materials provided with the distribution.
  76. 3. The names of the authors may not be used to endorse or promote products
  77. derived from this software without specific prior written permission.
  78. THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  79. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  80. FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
  81. INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
  82. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  83. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  84. OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  85. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  86. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  87. EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  88. */
  89. class StreamAdapter {
  90. constructor(Codec) {
  91. return class extends TransformStream {
  92. constructor(_format, options) {
  93. const codec = new Codec(options);
  94. super({
  95. transform(chunk, controller) {
  96. controller.enqueue(codec.append(chunk));
  97. },
  98. flush(controller) {
  99. const chunk = codec.flush();
  100. if (chunk) {
  101. controller.enqueue(chunk);
  102. }
  103. }
  104. });
  105. }
  106. };
  107. }
  108. }
  109. /*
  110. Copyright (c) 2022 Gildas Lormeau. All rights reserved.
  111. Redistribution and use in source and binary forms, with or without
  112. modification, are permitted provided that the following conditions are met:
  113. 1. Redistributions of source code must retain the above copyright notice,
  114. this list of conditions and the following disclaimer.
  115. 2. Redistributions in binary form must reproduce the above copyright
  116. notice, this list of conditions and the following disclaimer in
  117. the documentation and/or other materials provided with the distribution.
  118. 3. The names of the authors may not be used to endorse or promote products
  119. derived from this software without specific prior written permission.
  120. THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  121. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  122. FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
  123. INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
  124. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  125. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  126. OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  127. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  128. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  129. EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  130. */
  131. const MINIMUM_CHUNK_SIZE = 64;
  132. let maxWorkers = 2;
  133. try {
  134. if (typeof navigator != UNDEFINED_TYPE$1 && navigator.hardwareConcurrency) {
  135. maxWorkers = navigator.hardwareConcurrency;
  136. }
  137. } catch (_error) {
  138. // ignored
  139. }
  140. const DEFAULT_CONFIGURATION = {
  141. chunkSize: 512 * 1024,
  142. maxWorkers,
  143. terminateWorkerTimeout: 5000,
  144. useWebWorkers: true,
  145. useCompressionStream: true,
  146. workerScripts: UNDEFINED_VALUE,
  147. CompressionStreamNative: typeof CompressionStream != UNDEFINED_TYPE$1 && CompressionStream,
  148. DecompressionStreamNative: typeof DecompressionStream != UNDEFINED_TYPE$1 && DecompressionStream
  149. };
  150. const config = Object$1.assign({}, DEFAULT_CONFIGURATION);
  151. function getConfiguration() {
  152. return config;
  153. }
  154. function getChunkSize(config) {
  155. return Math$1.max(config.chunkSize, MINIMUM_CHUNK_SIZE);
  156. }
  157. function configure(configuration) {
  158. const {
  159. baseURL,
  160. chunkSize,
  161. maxWorkers,
  162. terminateWorkerTimeout,
  163. useCompressionStream,
  164. useWebWorkers,
  165. Deflate,
  166. Inflate,
  167. CompressionStream,
  168. DecompressionStream,
  169. workerScripts
  170. } = configuration;
  171. setIfDefined("baseURL", baseURL);
  172. setIfDefined("chunkSize", chunkSize);
  173. setIfDefined("maxWorkers", maxWorkers);
  174. setIfDefined("terminateWorkerTimeout", terminateWorkerTimeout);
  175. setIfDefined("useCompressionStream", useCompressionStream);
  176. setIfDefined("useWebWorkers", useWebWorkers);
  177. if (Deflate) {
  178. config.CompressionStream = new StreamAdapter(Deflate);
  179. }
  180. if (Inflate) {
  181. config.DecompressionStream = new StreamAdapter(Inflate);
  182. }
  183. setIfDefined("CompressionStream", CompressionStream);
  184. setIfDefined("DecompressionStream", DecompressionStream);
  185. if (workerScripts !== UNDEFINED_VALUE) {
  186. const { deflate, inflate } = workerScripts;
  187. if (deflate || inflate) {
  188. if (!config.workerScripts) {
  189. config.workerScripts = {};
  190. }
  191. }
  192. if (deflate) {
  193. if (!Array$1.isArray(deflate)) {
  194. throw new Error$1("workerScripts.deflate must be an array");
  195. }
  196. config.workerScripts.deflate = deflate;
  197. }
  198. if (inflate) {
  199. if (!Array$1.isArray(inflate)) {
  200. throw new Error$1("workerScripts.inflate must be an array");
  201. }
  202. config.workerScripts.inflate = inflate;
  203. }
  204. }
  205. }
  206. function setIfDefined(propertyName, propertyValue) {
  207. if (propertyValue !== UNDEFINED_VALUE) {
  208. config[propertyName] = propertyValue;
  209. }
  210. }
  211. function e(e){const t=()=>URL$2.createObjectURL(new Blob$3(['const{Array:e,Object:t,Number:n,Math:r,Error:s,Uint8Array:a,Uint16Array:i,Uint32Array:o,Int32Array:l,Map:c,DataView:h,Promise:f,TextEncoder:u,crypto:p,postMessage:d,TransformStream:g,ReadableStream:w,WritableStream:v,CompressionStream:y,DecompressionStream:b}=self;class m{constructor(e){return class extends g{constructor(t,n){const r=new e(n);super({transform(e,t){t.enqueue(r.append(e))},flush(e){const t=r.flush();t&&e.enqueue(t)}})}}}}const _=[];for(let e=0;256>e;e++){let t=e;for(let e=0;8>e;e++)1&t?t=t>>>1^3988292384:t>>>=1;_[e]=t}class k{constructor(e){this.crc=e||-1}append(e){let t=0|this.crc;for(let n=0,r=0|e.length;r>n;n++)t=t>>>8^_[255&(t^e[n])];this.crc=t}get(){return~this.crc}}class S extends g{constructor(){let e;const t=new k;super({transform(e,n){t.append(e),n.enqueue(e)},flush(){const n=new a(4);new h(n.buffer).setUint32(0,t.get()),e.value=n}}),e=this}}const z={concat(e,t){if(0===e.length||0===t.length)return e.concat(t);const n=e[e.length-1],r=z.getPartial(n);return 32===r?e.concat(t):z._shiftRight(t,r,0|n,e.slice(0,e.length-1))},bitLength(e){const t=e.length;if(0===t)return 0;const n=e[t-1];return 32*(t-1)+z.getPartial(n)},clamp(e,t){if(32*e.length<t)return e;const n=(e=e.slice(0,r.ceil(t/32))).length;return t&=31,n>0&&t&&(e[n-1]=z.partial(t,e[n-1]&2147483648>>t-1,1)),e},partial:(e,t,n)=>32===e?t:(n?0|t:t<<32-e)+1099511627776*e,getPartial:e=>r.round(e/1099511627776)||32,_shiftRight(e,t,n,r){for(void 0===r&&(r=[]);t>=32;t-=32)r.push(n),n=0;if(0===t)return r.concat(e);for(let s=0;s<e.length;s++)r.push(n|e[s]>>>t),n=e[s]<<32-t;const s=e.length?e[e.length-1]:0,a=z.getPartial(s);return r.push(z.partial(t+a&31,t+a>32?n:r.pop(),1)),r}},D={bytes:{fromBits(e){const t=z.bitLength(e)/8,n=new a(t);let r;for(let s=0;t>s;s++)0==(3&s)&&(r=e[s/4]),n[s]=r>>>24,r<<=8;return n},toBits(e){const t=[];let n,r=0;for(n=0;n<e.length;n++)r=r<<8|e[n],3==(3&n)&&(t.push(r),r=0);return 3&n&&t.push(z.partial(8*(3&n),r)),t}}},C=class{constructor(e){const t=this;t.blockSize=512,t._init=[1732584193,4023233417,2562383102,271733878,3285377520],t._key=[1518500249,1859775393,2400959708,3395469782],e?(t._h=e._h.slice(0),t._buffer=e._buffer.slice(0),t._length=e._length):t.reset()}reset(){const e=this;return e._h=e._init.slice(0),e._buffer=[],e._length=0,e}update(e){const t=this;"string"==typeof e&&(e=D.utf8String.toBits(e));const n=t._buffer=z.concat(t._buffer,e),r=t._length,a=t._length=r+z.bitLength(e);if(a>9007199254740991)throw new s("Cannot hash more than 2^53 - 1 bits");const i=new o(n);let l=0;for(let e=t.blockSize+r-(t.blockSize+r&t.blockSize-1);a>=e;e+=t.blockSize)t._block(i.subarray(16*l,16*(l+1))),l+=1;return n.splice(0,16*l),t}finalize(){const e=this;let t=e._buffer;const n=e._h;t=z.concat(t,[z.partial(1,1)]);for(let e=t.length+2;15&e;e++)t.push(0);for(t.push(r.floor(e._length/4294967296)),t.push(0|e._length);t.length;)e._block(t.splice(0,16));return e.reset(),n}_f(e,t,n,r){return e>19?e>39?e>59?e>79?void 0:t^n^r:t&n|t&r|n&r:t^n^r:t&n|~t&r}_S(e,t){return t<<e|t>>>32-e}_block(t){const n=this,s=n._h,a=e(80);for(let e=0;16>e;e++)a[e]=t[e];let i=s[0],o=s[1],l=s[2],c=s[3],h=s[4];for(let e=0;79>=e;e++){16>e||(a[e]=n._S(1,a[e-3]^a[e-8]^a[e-14]^a[e-16]));const t=n._S(5,i)+n._f(e,o,l,c)+h+a[e]+n._key[r.floor(e/20)]|0;h=c,c=l,l=n._S(30,o),o=i,i=t}s[0]=s[0]+i|0,s[1]=s[1]+o|0,s[2]=s[2]+l|0,s[3]=s[3]+c|0,s[4]=s[4]+h|0}},I={getRandomValues(e){const t=new o(e.buffer),n=e=>{let t=987654321;const n=4294967295;return()=>(t=36969*(65535&t)+(t>>16)&n,(((t<<16)+(e=18e3*(65535&e)+(e>>16)&n)&n)/4294967296+.5)*(r.random()>.5?1:-1))};for(let s,a=0;a<e.length;a+=4){const e=n(4294967296*(s||r.random()));s=987654071*e(),t[a/4]=4294967296*e()|0}return e}},x={importKey:e=>new x.hmacSha1(D.bytes.toBits(e)),pbkdf2(e,t,n,r){if(n=n||1e4,0>r||0>n)throw new s("invalid params to pbkdf2");const a=1+(r>>5)<<2;let i,o,l,c,f;const u=new ArrayBuffer(a),p=new h(u);let d=0;const g=z;for(t=D.bytes.toBits(t),f=1;(a||1)>d;f++){for(i=o=e.encrypt(g.concat(t,[f])),l=1;n>l;l++)for(o=e.encrypt(o),c=0;c<o.length;c++)i[c]^=o[c];for(l=0;(a||1)>d&&l<i.length;l++)p.setInt32(d,i[l]),d+=4}return u.slice(0,r/8)},hmacSha1:class{constructor(e){const t=this,n=t._hash=C,r=[[],[]];t._baseHash=[new n,new n];const s=t._baseHash[0].blockSize/32;e.length>s&&(e=(new n).update(e).finalize());for(let t=0;s>t;t++)r[0][t]=909522486^e[t],r[1][t]=1549556828^e[t];t._baseHash[0].update(r[0]),t._baseHash[1].update(r[1]),t._resultHash=new n(t._baseHash[0])}reset(){const e=this;e._resultHash=new e._hash(e._baseHash[0]),e._updated=!1}update(e){this._updated=!0,this._resultHash.update(e)}digest(){const e=this,t=e._resultHash.finalize(),n=new e._hash(e._baseHash[1]).update(t).finalize();return e.reset(),n}encrypt(e){if(this._updated)throw new s("encrypt on already updated hmac called!");return this.update(e),this.digest(e)}}},A=void 0!==p&&"function"==typeof p.getRandomValues,T="Invalid password",R="Invalid signature",H="zipjs-abort-check-password";function q(e){return A?p.getRandomValues(e):I.getRandomValues(e)}const B=16,K={name:"PBKDF2"},V=t.assign({hash:{name:"HMAC"}},K),P=t.assign({iterations:1e3,hash:{name:"SHA-1"}},K),E=["deriveBits"],U=[8,12,16],W=[16,24,32],M=10,N=[0,0,0,0],O="undefined",F="function",L=typeof p!=O,j=L&&p.subtle,G=L&&typeof j!=O,X=D.bytes,J=class{constructor(e){const t=this;t._tables=[[[],[],[],[],[]],[[],[],[],[],[]]],t._tables[0][0][0]||t._precompute();const n=t._tables[0][4],r=t._tables[1],a=e.length;let i,o,l,c=1;if(4!==a&&6!==a&&8!==a)throw new s("invalid aes key size");for(t._key=[o=e.slice(0),l=[]],i=a;4*a+28>i;i++){let e=o[i-1];(i%a==0||8===a&&i%a==4)&&(e=n[e>>>24]<<24^n[e>>16&255]<<16^n[e>>8&255]<<8^n[255&e],i%a==0&&(e=e<<8^e>>>24^c<<24,c=c<<1^283*(c>>7))),o[i]=o[i-a]^e}for(let e=0;i;e++,i--){const t=o[3&e?i:i-4];l[e]=4>=i||4>e?t:r[0][n[t>>>24]]^r[1][n[t>>16&255]]^r[2][n[t>>8&255]]^r[3][n[255&t]]}}encrypt(e){return this._crypt(e,0)}decrypt(e){return this._crypt(e,1)}_precompute(){const e=this._tables[0],t=this._tables[1],n=e[4],r=t[4],s=[],a=[];let i,o,l,c;for(let e=0;256>e;e++)a[(s[e]=e<<1^283*(e>>7))^e]=e;for(let h=i=0;!n[h];h^=o||1,i=a[i]||1){let a=i^i<<1^i<<2^i<<3^i<<4;a=a>>8^255&a^99,n[h]=a,r[a]=h,c=s[l=s[o=s[h]]];let f=16843009*c^65537*l^257*o^16843008*h,u=257*s[a]^16843008*a;for(let n=0;4>n;n++)e[n][h]=u=u<<24^u>>>8,t[n][a]=f=f<<24^f>>>8}for(let n=0;5>n;n++)e[n]=e[n].slice(0),t[n]=t[n].slice(0)}_crypt(e,t){if(4!==e.length)throw new s("invalid aes block size");const n=this._key[t],r=n.length/4-2,a=[0,0,0,0],i=this._tables[t],o=i[0],l=i[1],c=i[2],h=i[3],f=i[4];let u,p,d,g=e[0]^n[0],w=e[t?3:1]^n[1],v=e[2]^n[2],y=e[t?1:3]^n[3],b=4;for(let e=0;r>e;e++)u=o[g>>>24]^l[w>>16&255]^c[v>>8&255]^h[255&y]^n[b],p=o[w>>>24]^l[v>>16&255]^c[y>>8&255]^h[255&g]^n[b+1],d=o[v>>>24]^l[y>>16&255]^c[g>>8&255]^h[255&w]^n[b+2],y=o[y>>>24]^l[g>>16&255]^c[w>>8&255]^h[255&v]^n[b+3],b+=4,g=u,w=p,v=d;for(let e=0;4>e;e++)a[t?3&-e:e]=f[g>>>24]<<24^f[w>>16&255]<<16^f[v>>8&255]<<8^f[255&y]^n[b++],u=g,g=w,w=v,v=y,y=u;return a}},Q=class{constructor(e,t){this._prf=e,this._initIv=t,this._iv=t}reset(){this._iv=this._initIv}update(e){return this.calculate(this._prf,e,this._iv)}incWord(e){if(255==(e>>24&255)){let t=e>>16&255,n=e>>8&255,r=255&e;255===t?(t=0,255===n?(n=0,255===r?r=0:++r):++n):++t,e=0,e+=t<<16,e+=n<<8,e+=r}else e+=1<<24;return e}incCounter(e){0===(e[0]=this.incWord(e[0]))&&(e[1]=this.incWord(e[1]))}calculate(e,t,n){let r;if(!(r=t.length))return[];const s=z.bitLength(t);for(let s=0;r>s;s+=4){this.incCounter(n);const r=e.encrypt(n);t[s]^=r[0],t[s+1]^=r[1],t[s+2]^=r[2],t[s+3]^=r[3]}return z.clamp(t,s)}},Y=x.hmacSha1;let Z=L&&G&&typeof j.importKey==F,$=L&&G&&typeof j.deriveBits==F;class ee extends g{constructor({password:e,signed:n,encryptionStrength:r,checkPasswordOnly:i}){super({start(){t.assign(this,{ready:new f((e=>this.resolveReady=e)),password:e,signed:n,strength:r-1,pending:new a})},async transform(e,t){const n=this,{password:r,strength:o,resolveReady:l,ready:c}=n;r?(await(async(e,t,n,r)=>{const a=await re(e,t,n,ae(r,0,U[t])),i=ae(r,U[t]);if(a[0]!=i[0]||a[1]!=i[1])throw new s(T)})(n,o,r,ae(e,0,U[o]+2)),e=ae(e,U[o]+2),i?t.error(new s(H)):l()):await c;const h=new a(e.length-M-(e.length-M)%B);t.enqueue(ne(n,e,h,0,M,!0))},async flush(e){const{signed:t,ctr:n,hmac:r,pending:i,ready:o}=this;await o;const l=ae(i,0,i.length-M),c=ae(i,i.length-M);let h=new a;if(l.length){const e=oe(X,l);r.update(e);const t=n.update(e);h=ie(X,t)}if(t){const e=ae(ie(X,r.digest()),0,M);for(let t=0;M>t;t++)if(e[t]!=c[t])throw new s(R)}e.enqueue(h)}})}}class te extends g{constructor({password:e,encryptionStrength:n}){let r;super({start(){t.assign(this,{ready:new f((e=>this.resolveReady=e)),password:e,strength:n-1,pending:new a})},async transform(e,t){const n=this,{password:r,strength:s,resolveReady:i,ready:o}=n;let l=new a;r?(l=await(async(e,t,n)=>{const r=q(new a(U[t]));return se(r,await re(e,t,n,r))})(n,s,r),i()):await o;const c=new a(l.length+e.length-e.length%B);c.set(l,0),t.enqueue(ne(n,e,c,l.length,0))},async flush(e){const{ctr:t,hmac:n,pending:s,ready:i}=this;await i;let o=new a;if(s.length){const e=t.update(oe(X,s));n.update(e),o=ie(X,e)}r.signature=ie(X,n.digest()).slice(0,M),e.enqueue(se(o,r.signature))}}),r=this}}function ne(e,t,n,r,s,i){const{ctr:o,hmac:l,pending:c}=e,h=t.length-s;let f;for(c.length&&(t=se(c,t),n=((e,t)=>{if(t&&t>e.length){const n=e;(e=new a(t)).set(n,0)}return e})(n,h-h%B)),f=0;h-B>=f;f+=B){const e=oe(X,ae(t,f,f+B));i&&l.update(e);const s=o.update(e);i||l.update(s),n.set(ie(X,s),f+r)}return e.pending=ae(t,f),n}async function re(n,r,s,i){n.password=null;const o=(e=>{if(void 0===u){const t=new a((e=unescape(encodeURIComponent(e))).length);for(let n=0;n<t.length;n++)t[n]=e.charCodeAt(n);return t}return(new u).encode(e)})(s),l=await(async(e,t,n,r,s)=>{if(!Z)return x.importKey(t);try{return await j.importKey("raw",t,n,!1,s)}catch(e){return Z=!1,x.importKey(t)}})(0,o,V,0,E),c=await(async(e,t,n)=>{if(!$)return x.pbkdf2(t,e.salt,P.iterations,n);try{return await j.deriveBits(e,t,n)}catch(r){return $=!1,x.pbkdf2(t,e.salt,P.iterations,n)}})(t.assign({salt:i},P),l,8*(2*W[r]+2)),h=new a(c),f=oe(X,ae(h,0,W[r])),p=oe(X,ae(h,W[r],2*W[r])),d=ae(h,2*W[r]);return t.assign(n,{keys:{key:f,authentication:p,passwordVerification:d},ctr:new Q(new J(f),e.from(N)),hmac:new Y(p)}),d}function se(e,t){let n=e;return e.length+t.length&&(n=new a(e.length+t.length),n.set(e,0),n.set(t,e.length)),n}function ae(e,t,n){return e.subarray(t,n)}function ie(e,t){return e.fromBits(t)}function oe(e,t){return e.toBits(t)}class le extends g{constructor({password:e,passwordVerification:n,checkPasswordOnly:r}){super({start(){t.assign(this,{password:e,passwordVerification:n}),ue(this,e)},transform(e,t){const n=this;if(n.password){const t=he(n,e.subarray(0,12));if(n.password=null,t[11]!=n.passwordVerification)throw new s(T);e=e.subarray(12)}r?t.error(new s(H)):t.enqueue(he(n,e))}})}}class ce extends g{constructor({password:e,passwordVerification:n}){super({start(){t.assign(this,{password:e,passwordVerification:n}),ue(this,e)},transform(e,t){const n=this;let r,s;if(n.password){n.password=null;const t=q(new a(12));t[11]=n.passwordVerification,r=new a(e.length+t.length),r.set(fe(n,t),0),s=12}else r=new a(e.length),s=0;r.set(fe(n,e),s),t.enqueue(r)}})}}function he(e,t){const n=new a(t.length);for(let r=0;r<t.length;r++)n[r]=de(e)^t[r],pe(e,n[r]);return n}function fe(e,t){const n=new a(t.length);for(let r=0;r<t.length;r++)n[r]=de(e)^t[r],pe(e,t[r]);return n}function ue(e,n){const r=[305419896,591751049,878082192];t.assign(e,{keys:r,crcKey0:new k(r[0]),crcKey2:new k(r[2])});for(let t=0;t<n.length;t++)pe(e,n.charCodeAt(t))}function pe(e,t){let[n,s,a]=e.keys;e.crcKey0.append([t]),n=~e.crcKey0.get(),s=we(r.imul(we(s+ge(n)),134775813)+1),e.crcKey2.append([s>>>24]),a=~e.crcKey2.get(),e.keys=[n,s,a]}function de(e){const t=2|e.keys[2];return ge(r.imul(t,1^t)>>>8)}function ge(e){return 255&e}function we(e){return 4294967295&e}const ve="deflate-raw";class ye extends g{constructor(e,{chunkSize:t,CompressionStream:n,CompressionStreamNative:r}){super({});const{compressed:s,encrypted:a,useCompressionStream:i,zipCrypto:o,signed:l,level:c}=e,f=this;let u,p,d=me(super.readable);a&&!o||!l||(u=new S,d=Se(d,u)),s&&(d=ke(d,i,{level:c,chunkSize:t},r,n)),a&&(o?d=Se(d,new ce(e)):(p=new te(e),d=Se(d,p))),_e(f,d,(()=>{let e;a&&!o&&(e=p.signature),a&&!o||!l||(e=new h(u.value.buffer).getUint32(0)),f.signature=e}))}}class be extends g{constructor(e,{chunkSize:t,DecompressionStream:n,DecompressionStreamNative:r}){super({});const{zipCrypto:a,encrypted:i,signed:o,signature:l,compressed:c,useCompressionStream:f}=e;let u,p,d=me(super.readable);i&&(a?d=Se(d,new le(e)):(p=new ee(e),d=Se(d,p))),c&&(d=ke(d,f,{chunkSize:t},r,n)),i&&!a||!o||(u=new S,d=Se(d,u)),_e(this,d,(()=>{if((!i||a)&&o){const e=new h(u.value.buffer);if(l!=e.getUint32(0,!1))throw new s(R)}}))}}function me(e){return Se(e,new g({transform(e,t){e&&e.length&&t.enqueue(e)}}))}function _e(e,n,r){n=Se(n,new g({flush:r})),t.defineProperty(e,"readable",{get:()=>n})}function ke(e,t,n,r,s){try{e=Se(e,new(t&&r?r:s)(ve,n))}catch(r){if(!t)throw r;e=Se(e,new s(ve,n))}return e}function Se(e,t){return e.pipeThrough(t)}const ze="data";class De extends g{constructor(e,n){super({});const r=this,{codecType:s}=e;let a;s.startsWith("deflate")?a=ye:s.startsWith("inflate")&&(a=be);let i=0;const o=new a(e,n),l=super.readable,c=new g({transform(e,t){e&&e.length&&(i+=e.length,t.enqueue(e))},flush(){const{signature:e}=o;t.assign(r,{signature:e,size:i})}});t.defineProperty(r,"readable",{get:()=>l.pipeThrough(o).pipeThrough(c)})}}const Ce=new c,Ie=new c;let xe=0;async function Ae(e){try{const{options:t,scripts:r,config:s}=e;r&&r.length&&importScripts.apply(void 0,r),self.initCodec&&self.initCodec(),s.CompressionStreamNative=self.CompressionStream,s.DecompressionStreamNative=self.DecompressionStream,self.Deflate&&(s.CompressionStream=new m(self.Deflate)),self.Inflate&&(s.DecompressionStream=new m(self.Inflate));const a={highWaterMark:1,size:()=>s.chunkSize},i=e.readable||new w({async pull(e){const t=new f((e=>Ce.set(xe,e)));Te({type:"pull",messageId:xe}),xe=(xe+1)%n.MAX_SAFE_INTEGER;const{value:r,done:s}=await t;e.enqueue(r),s&&e.close()}},a),o=e.writable||new v({async write(e){let t;const r=new f((e=>t=e));Ie.set(xe,t),Te({type:ze,value:e,messageId:xe}),xe=(xe+1)%n.MAX_SAFE_INTEGER,await r}},a),l=new De(t,s);await i.pipeThrough(l).pipeTo(o,{preventClose:!0,preventAbort:!0});try{await o.getWriter().close()}catch(e){}const{signature:c,size:h}=l;Te({type:"close",result:{signature:c,size:h}})}catch(e){Re(e)}}function Te(e){let{value:t}=e;if(t)if(t.length)try{t=new a(t),e.value=t.buffer,d(e,[e.value])}catch(t){d(e)}else d(e);else d(e)}function Re(e=new s("Unknown error")){const{message:t,stack:n,code:r,name:a}=e;d({error:{message:t,stack:n,code:r,name:a}})}addEventListener("message",(({data:e})=>{const{type:t,messageId:n,value:r,done:s}=e;try{if("start"==t&&Ae(e),t==ze){const e=Ce.get(n);Ce.delete(n),e({value:new a(r),done:s})}if("ack"==t){const e=Ie.get(n);Ie.delete(n),e()}}catch(e){Re(e)}}));var He=a,qe=i,Be=l,Ke=new He([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),Ve=new He([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),Pe=new He([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),Ee=(e,t)=>{for(var n=new qe(31),r=0;31>r;++r)n[r]=t+=1<<e[r-1];var s=new Be(n[30]);for(r=1;30>r;++r)for(var a=n[r];a<n[r+1];++a)s[a]=a-n[r]<<5|r;return{b:n,r:s}},Ue=Ee(Ke,2),We=Ue.b,Me=Ue.r;We[28]=258,Me[258]=28;for(var Ne=Ee(Ve,0),Oe=Ne.b,Fe=Ne.r,Le=new qe(32768),je=0;32768>je;++je){var Ge=(43690&je)>>1|(21845&je)<<1;Ge=(61680&(Ge=(52428&Ge)>>2|(13107&Ge)<<2))>>4|(3855&Ge)<<4,Le[je]=((65280&Ge)>>8|(255&Ge)<<8)>>1}var Xe=(e,t,n)=>{for(var r=e.length,s=0,a=new qe(t);r>s;++s)e[s]&&++a[e[s]-1];var i,o=new qe(t);for(s=1;t>s;++s)o[s]=o[s-1]+a[s-1]<<1;if(n){i=new qe(1<<t);var l=15-t;for(s=0;r>s;++s)if(e[s])for(var c=s<<4|e[s],h=t-e[s],f=o[e[s]-1]++<<h,u=f|(1<<h)-1;u>=f;++f)i[Le[f]>>l]=c}else for(i=new qe(r),s=0;r>s;++s)e[s]&&(i[s]=Le[o[e[s]-1]++]>>15-e[s]);return i},Je=new He(288);for(je=0;144>je;++je)Je[je]=8;for(je=144;256>je;++je)Je[je]=9;for(je=256;280>je;++je)Je[je]=7;for(je=280;288>je;++je)Je[je]=8;var Qe=new He(32);for(je=0;32>je;++je)Qe[je]=5;var Ye=Xe(Je,9,0),Ze=Xe(Je,9,1),$e=Xe(Qe,5,0),et=Xe(Qe,5,1),tt=e=>{for(var t=e[0],n=1;n<e.length;++n)e[n]>t&&(t=e[n]);return t},nt=(e,t,n)=>{var r=t/8|0;return(e[r]|e[r+1]<<8)>>(7&t)&n},rt=(e,t)=>{var n=t/8|0;return(e[n]|e[n+1]<<8|e[n+2]<<16)>>(7&t)},st=e=>(e+7)/8|0,at=(e,t,n)=>{(null==t||0>t)&&(t=0),(null==n||n>e.length)&&(n=e.length);var r=new He(n-t);return r.set(e.subarray(t,n)),r},it=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],ot=(e,t,n)=>{var r=new s(t||it[e]);if(r.code=e,s.captureStackTrace&&s.captureStackTrace(r,ot),!n)throw r;return r},lt=(e,t,n)=>{n<<=7&t;var r=t/8|0;e[r]|=n,e[r+1]|=n>>8},ct=(e,t,n)=>{n<<=7&t;var r=t/8|0;e[r]|=n,e[r+1]|=n>>8,e[r+2]|=n>>16},ht=(e,t)=>{for(var n=[],r=0;r<e.length;++r)e[r]&&n.push({s:r,f:e[r]});var s=n.length,a=n.slice();if(!s)return{t:vt,l:0};if(1==s){var i=new He(n[0].s+1);return i[n[0].s]=1,{t:i,l:1}}n.sort(((e,t)=>e.f-t.f)),n.push({s:-1,f:25001});var o=n[0],l=n[1],c=0,h=1,f=2;for(n[0]={s:-1,f:o.f+l.f,l:o,r:l};h!=s-1;)o=n[n[c].f<n[f].f?c++:f++],l=n[c!=h&&n[c].f<n[f].f?c++:f++],n[h++]={s:-1,f:o.f+l.f,l:o,r:l};var u=a[0].s;for(r=1;s>r;++r)a[r].s>u&&(u=a[r].s);var p=new qe(u+1),d=ft(n[h-1],p,0);if(d>t){r=0;var g=0,w=d-t,v=1<<w;for(a.sort(((e,t)=>p[t.s]-p[e.s]||e.f-t.f));s>r;++r){var y=a[r].s;if(p[y]<=t)break;g+=v-(1<<d-p[y]),p[y]=t}for(g>>=w;g>0;){var b=a[r].s;p[b]<t?g-=1<<t-p[b]++-1:++r}for(;r>=0&&g;--r){var m=a[r].s;p[m]==t&&(--p[m],++g)}d=t}return{t:new He(p),l:d}},ft=(e,t,n)=>-1==e.s?r.max(ft(e.l,t,n+1),ft(e.r,t,n+1)):t[e.s]=n,ut=e=>{for(var t=e.length;t&&!e[--t];);for(var n=new qe(++t),r=0,s=e[0],a=1,i=e=>{n[r++]=e},o=1;t>=o;++o)if(e[o]==s&&o!=t)++a;else{if(!s&&a>2){for(;a>138;a-=138)i(32754);a>2&&(i(a>10?a-11<<5|28690:a-3<<5|12305),a=0)}else if(a>3){for(i(s),--a;a>6;a-=6)i(8304);a>2&&(i(a-3<<5|8208),a=0)}for(;a--;)i(s);a=1,s=e[o]}return{c:n.subarray(0,r),n:t}},pt=(e,t)=>{for(var n=0,r=0;r<t.length;++r)n+=e[r]*t[r];return n},dt=(e,t,n)=>{var r=n.length,s=st(t+2);e[s]=255&r,e[s+1]=r>>8,e[s+2]=255^e[s],e[s+3]=255^e[s+1];for(var a=0;r>a;++a)e[s+a+4]=n[a];return 8*(s+4+r)},gt=(e,t,n,r,s,a,i,o,l,c,h)=>{lt(t,h++,n),++s[256];for(var f=ht(s,15),u=f.t,p=f.l,d=ht(a,15),g=d.t,w=d.l,v=ut(u),y=v.c,b=v.n,m=ut(g),_=m.c,k=m.n,S=new qe(19),z=0;z<y.length;++z)++S[31&y[z]];for(z=0;z<_.length;++z)++S[31&_[z]];for(var D=ht(S,7),C=D.t,I=D.l,x=19;x>4&&!C[Pe[x-1]];--x);var A,T,R,H,q=c+5<<3,B=pt(s,Je)+pt(a,Qe)+i,K=pt(s,u)+pt(a,g)+i+14+3*x+pt(S,C)+2*S[16]+3*S[17]+7*S[18];if(l>=0&&B>=q&&K>=q)return dt(t,h,e.subarray(l,l+c));if(lt(t,h,1+(B>K)),h+=2,B>K){A=Xe(u,p,0),T=u,R=Xe(g,w,0),H=g;var V=Xe(C,I,0);for(lt(t,h,b-257),lt(t,h+5,k-1),lt(t,h+10,x-4),h+=14,z=0;x>z;++z)lt(t,h+3*z,C[Pe[z]]);h+=3*x;for(var P=[y,_],E=0;2>E;++E){var U=P[E];for(z=0;z<U.length;++z){var W=31&U[z];lt(t,h,V[W]),h+=C[W],W>15&&(lt(t,h,U[z]>>5&127),h+=U[z]>>12)}}}else A=Ye,T=Je,R=$e,H=Qe;for(z=0;o>z;++z){var M=r[z];if(M>255){ct(t,h,A[257+(W=M>>18&31)]),h+=T[W+257],W>7&&(lt(t,h,M>>23&31),h+=Ke[W]);var N=31&M;ct(t,h,R[N]),h+=H[N],N>3&&(ct(t,h,M>>5&8191),h+=Ve[N])}else ct(t,h,A[M]),h+=T[M]}return ct(t,h,A[256]),h+T[256]},wt=new Be([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),vt=new He(0),yt=function(){function e(e,t){if("function"==typeof e&&(t=e,e={}),this.ondata=t,this.o=e||{},this.s={l:0,i:32768,w:32768,z:32768},this.b=new He(98304),this.o.dictionary){var n=this.o.dictionary.subarray(-32768);this.b.set(n,32768-n.length),this.s.i=32768-n.length}}return e.prototype.p=function(e,t){this.ondata(((e,t,n,s,a)=>{if(!a&&(a={l:1},t.dictionary)){var i=t.dictionary.subarray(-32768),o=new He(i.length+e.length);o.set(i),o.set(e,i.length),e=o,a.w=i.length}return((e,t,n,s,a,i)=>{var o=i.z||e.length,l=new He(0+o+5*(1+r.ceil(o/7e3))+0),c=l.subarray(0,l.length-0),h=i.l,f=7&(i.r||0);if(t){f&&(c[0]=i.r>>3);for(var u=wt[t-1],p=u>>13,d=8191&u,g=(1<<n)-1,w=i.p||new qe(32768),v=i.h||new qe(g+1),y=r.ceil(n/3),b=2*y,m=t=>(e[t]^e[t+1]<<y^e[t+2]<<b)&g,_=new Be(25e3),k=new qe(288),S=new qe(32),z=0,D=0,C=i.i||0,I=0,x=i.w||0,A=0;o>C+2;++C){var T=m(C),R=32767&C,H=v[T];if(w[R]=H,v[T]=R,C>=x){var q=o-C;if((z>7e3||I>24576)&&(q>423||!h)){f=gt(e,c,0,_,k,S,D,I,A,C-A,f),I=z=D=0,A=C;for(var B=0;286>B;++B)k[B]=0;for(B=0;30>B;++B)S[B]=0}var K=2,V=0,P=d,E=R-H&32767;if(q>2&&T==m(C-E))for(var U=r.min(p,q)-1,W=r.min(32767,C),M=r.min(258,q);W>=E&&--P&&R!=H;){if(e[C+K]==e[C+K-E]){for(var N=0;M>N&&e[C+N]==e[C+N-E];++N);if(N>K){if(K=N,V=E,N>U)break;var O=r.min(E,N-2),F=0;for(B=0;O>B;++B){var L=C-E+B&32767,j=L-w[L]&32767;j>F&&(F=j,H=L)}}}E+=(R=H)-(H=w[R])&32767}if(V){_[I++]=268435456|Me[K]<<18|Fe[V];var G=31&Me[K],X=31&Fe[V];D+=Ke[G]+Ve[X],++k[257+G],++S[X],x=C+K,++z}else _[I++]=e[C],++k[e[C]]}}for(C=r.max(C,x);o>C;++C)_[I++]=e[C],++k[e[C]];f=gt(e,c,h,_,k,S,D,I,A,C-A,f),h||(i.r=7&f|c[f/8|0]<<3,f-=7,i.h=v,i.p=w,i.i=C,i.w=x)}else{for(C=i.w||0;o+h>C;C+=65535){var J=C+65535;o>J||(c[f/8|0]=h,J=o),f=dt(c,f+1,e.subarray(C,J))}i.i=o}return at(l,0,0+st(f)+0)})(e,null==t.level?6:t.level,null==t.mem?r.ceil(1.5*r.max(8,r.min(13,r.log(e.length)))):12+t.mem,0,0,a)})(e,this.o,0,0,this.s),t)},e.prototype.push=function(e,t){this.ondata||ot(5),this.s.l&&ot(4);var n=e.length+this.s.z;if(n>this.b.length){if(n>2*this.b.length-32768){var r=new He(-32768&n);r.set(this.b.subarray(0,this.s.z)),this.b=r}var s=this.b.length-this.s.z;s&&(this.b.set(e.subarray(0,s),this.s.z),this.s.z=this.b.length,this.p(this.b,!1)),this.b.set(this.b.subarray(-32768)),this.b.set(e.subarray(s),32768),this.s.z=e.length-s+32768,this.s.i=32766,this.s.w=32768}else this.b.set(e,this.s.z),this.s.z+=e.length;this.s.l=1&t,(this.s.z>this.s.w+8191||t)&&(this.p(this.b,t||!1),this.s.w=this.s.i,this.s.i-=2)},e}(),bt=function(){function e(e,t){"function"==typeof e&&(t=e,e={}),this.ondata=t;var n=e&&e.dictionary&&e.dictionary.subarray(-32768);this.s={i:0,b:n?n.length:0},this.o=new He(32768),this.p=new He(0),n&&this.o.set(n)}return e.prototype.e=function(e){if(this.ondata||ot(5),this.d&&ot(4),this.p.length){if(e.length){var t=new He(this.p.length+e.length);t.set(this.p),t.set(e,this.p.length),this.p=t}}else this.p=e},e.prototype.c=function(e){this.s.i=+(this.d=e||!1);var t=this.s.b,n=((e,t,n)=>{var s=e.length;if(!s||t.f&&!t.l)return n||new He(0);var a=!n||2!=t.i,i=t.i;n||(n=new He(3*s));var o=e=>{var t=n.length;if(e>t){var s=new He(r.max(2*t,e));s.set(n),n=s}},l=t.f||0,c=t.p||0,h=t.b||0,f=t.l,u=t.d,p=t.m,d=t.n,g=8*s;do{if(!f){l=nt(e,c,1);var w=nt(e,c+1,3);if(c+=3,!w){var v=e[(x=st(c)+4)-4]|e[x-3]<<8,y=x+v;if(y>s){i&&ot(0);break}a&&o(h+v),n.set(e.subarray(x,y),h),t.b=h+=v,t.p=c=8*y,t.f=l;continue}if(1==w)f=Ze,u=et,p=9,d=5;else if(2==w){var b=nt(e,c,31)+257,m=nt(e,c+10,15)+4,_=b+nt(e,c+5,31)+1;c+=14;for(var k=new He(_),S=new He(19),z=0;m>z;++z)S[Pe[z]]=nt(e,c+3*z,7);c+=3*m;var D=tt(S),C=(1<<D)-1,I=Xe(S,D,1);for(z=0;_>z;){var x,A=I[nt(e,c,C)];if(c+=15&A,16>(x=A>>4))k[z++]=x;else{var T=0,R=0;for(16==x?(R=3+nt(e,c,3),c+=2,T=k[z-1]):17==x?(R=3+nt(e,c,7),c+=3):18==x&&(R=11+nt(e,c,127),c+=7);R--;)k[z++]=T}}var H=k.subarray(0,b),q=k.subarray(b);p=tt(H),d=tt(q),f=Xe(H,p,1),u=Xe(q,d,1)}else ot(1);if(c>g){i&&ot(0);break}}a&&o(h+131072);for(var B=(1<<p)-1,K=(1<<d)-1,V=c;;V=c){var P=(T=f[rt(e,c)&B])>>4;if((c+=15&T)>g){i&&ot(0);break}if(T||ot(2),256>P)n[h++]=P;else{if(256==P){V=c,f=null;break}var E=P-254;if(P>264){var U=Ke[z=P-257];E=nt(e,c,(1<<U)-1)+We[z],c+=U}var W=u[rt(e,c)&K],M=W>>4;if(W||ot(3),c+=15&W,q=Oe[M],M>3&&(U=Ve[M],q+=rt(e,c)&(1<<U)-1,c+=U),c>g){i&&ot(0);break}a&&o(h+131072);var N=h+E;if(q>h){var O=0-q,F=r.min(q,N);for(0>O+h&&ot(3);F>h;++h)n[h]=undefined[O+h]}for(;N>h;h+=4)n[h]=n[h-q],n[h+1]=n[h+1-q],n[h+2]=n[h+2-q],n[h+3]=n[h+3-q];h=N}}t.l=f,t.p=V,t.b=h,t.f=l,f&&(l=1,t.m=p,t.d=u,t.n=d)}while(!l);return h==n.length?n:at(n,0,h)})(this.p,this.s,this.o);this.ondata(at(n,t,this.s.b),this.d),this.o=at(n,this.s.b-32768),this.s.b=this.o.length,this.p=at(this.p,this.s.p/8|0),this.s.p&=7},e.prototype.push=function(e,t){this.e(e),this.c(t)},e}(),mt="undefined"!=typeof TextDecoder&&new TextDecoder;try{mt.decode(vt,{stream:!0})}catch(e){}function _t(e,n,r){return class{constructor(s){const i=this;var o,l;o=s,l="level",("function"==typeof t.hasOwn?t.hasOwn(o,l):o.hasOwnProperty(l))&&void 0===s.level&&delete s.level,i.codec=new e(t.assign({},n,s)),r(i.codec,(e=>{if(i.pendingData){const t=i.pendingData;i.pendingData=new a(t.length+e.length);const{pendingData:n}=i;n.set(t,0),n.set(e,t.length)}else i.pendingData=new a(e)}))}append(e){return this.codec.push(e),s(this)}flush(){return this.codec.push(new a,!0),s(this)}};function s(e){if(e.pendingData){const t=e.pendingData;return e.pendingData=null,t}return new a}}const{Deflate:kt,Inflate:St}=((e,t={},n)=>({Deflate:_t(e.Deflate,t.deflate,n),Inflate:_t(e.Inflate,t.inflate,n)}))({Deflate:yt,Inflate:bt},void 0,((e,t)=>e.ondata=t));self.initCodec=()=>{self.Deflate=kt,self.Inflate=St};\n'],{type:"text/javascript"}));e({workerScripts:{inflate:[t],deflate:[t]}});}
  212. /*
  213. Copyright (c) 2022 Gildas Lormeau. All rights reserved.
  214. Redistribution and use in source and binary forms, with or without
  215. modification, are permitted provided that the following conditions are met:
  216. 1. Redistributions of source code must retain the above copyright notice,
  217. this list of conditions and the following disclaimer.
  218. 2. Redistributions in binary form must reproduce the above copyright
  219. notice, this list of conditions and the following disclaimer in
  220. the documentation and/or other materials provided with the distribution.
  221. 3. The names of the authors may not be used to endorse or promote products
  222. derived from this software without specific prior written permission.
  223. THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  224. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  225. FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
  226. INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
  227. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  228. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  229. OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  230. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  231. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  232. EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  233. */
  234. function getMimeType() {
  235. return "application/octet-stream";
  236. }
  237. function initShimAsyncCodec(library, options = {}, registerDataHandler) {
  238. return {
  239. Deflate: createCodecClass(library.Deflate, options.deflate, registerDataHandler),
  240. Inflate: createCodecClass(library.Inflate, options.inflate, registerDataHandler)
  241. };
  242. }
  243. function objectHasOwn(object, propertyName) {
  244. // eslint-disable-next-line no-prototype-builtins
  245. return typeof Object$1.hasOwn === "function" ? Object$1.hasOwn(object, propertyName) : object.hasOwnProperty(propertyName);
  246. }
  247. function createCodecClass(constructor, constructorOptions, registerDataHandler) {
  248. return class {
  249. constructor(options) {
  250. const codecAdapter = this;
  251. const onData = data => {
  252. if (codecAdapter.pendingData) {
  253. const previousPendingData = codecAdapter.pendingData;
  254. codecAdapter.pendingData = new Uint8Array$1(previousPendingData.length + data.length);
  255. const { pendingData } = codecAdapter;
  256. pendingData.set(previousPendingData, 0);
  257. pendingData.set(data, previousPendingData.length);
  258. } else {
  259. codecAdapter.pendingData = new Uint8Array$1(data);
  260. }
  261. };
  262. if (objectHasOwn(options, "level") && options.level === undefined) {
  263. delete options.level;
  264. }
  265. codecAdapter.codec = new constructor(Object$1.assign({}, constructorOptions, options));
  266. registerDataHandler(codecAdapter.codec, onData);
  267. }
  268. append(data) {
  269. this.codec.push(data);
  270. return getResponse(this);
  271. }
  272. flush() {
  273. this.codec.push(new Uint8Array$1(), true);
  274. return getResponse(this);
  275. }
  276. };
  277. function getResponse(codec) {
  278. if (codec.pendingData) {
  279. const output = codec.pendingData;
  280. codec.pendingData = null;
  281. return output;
  282. } else {
  283. return new Uint8Array$1();
  284. }
  285. }
  286. }
  287. /*
  288. Copyright (c) 2022 Gildas Lormeau. All rights reserved.
  289. Redistribution and use in source and binary forms, with or without
  290. modification, are permitted provided that the following conditions are met:
  291. 1. Redistributions of source code must retain the above copyright notice,
  292. this list of conditions and the following disclaimer.
  293. 2. Redistributions in binary form must reproduce the above copyright
  294. notice, this list of conditions and the following disclaimer in
  295. the documentation and/or other materials provided with the distribution.
  296. 3. The names of the authors may not be used to endorse or promote products
  297. derived from this software without specific prior written permission.
  298. THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  299. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  300. FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
  301. INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
  302. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  303. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  304. OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  305. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  306. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  307. EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  308. */
  309. const table = [];
  310. for (let i = 0; i < 256; i++) {
  311. let t = i;
  312. for (let j = 0; j < 8; j++) {
  313. if (t & 1) {
  314. t = (t >>> 1) ^ 0xEDB88320;
  315. } else {
  316. t = t >>> 1;
  317. }
  318. }
  319. table[i] = t;
  320. }
  321. class Crc32 {
  322. constructor(crc) {
  323. this.crc = crc || -1;
  324. }
  325. append(data) {
  326. let crc = this.crc | 0;
  327. for (let offset = 0, length = data.length | 0; offset < length; offset++) {
  328. crc = (crc >>> 8) ^ table[(crc ^ data[offset]) & 0xFF];
  329. }
  330. this.crc = crc;
  331. }
  332. get() {
  333. return ~this.crc;
  334. }
  335. }
  336. /*
  337. Copyright (c) 2022 Gildas Lormeau. All rights reserved.
  338. Redistribution and use in source and binary forms, with or without
  339. modification, are permitted provided that the following conditions are met:
  340. 1. Redistributions of source code must retain the above copyright notice,
  341. this list of conditions and the following disclaimer.
  342. 2. Redistributions in binary form must reproduce the above copyright
  343. notice, this list of conditions and the following disclaimer in
  344. the documentation and/or other materials provided with the distribution.
  345. 3. The names of the authors may not be used to endorse or promote products
  346. derived from this software without specific prior written permission.
  347. THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  348. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  349. FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
  350. INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
  351. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  352. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  353. OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  354. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  355. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  356. EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  357. */
  358. class Crc32Stream extends TransformStream {
  359. constructor() {
  360. let stream;
  361. const crc32 = new Crc32();
  362. super({
  363. transform(chunk, controller) {
  364. crc32.append(chunk);
  365. controller.enqueue(chunk);
  366. },
  367. flush() {
  368. const value = new Uint8Array$1(4);
  369. const dataView = new DataView$1(value.buffer);
  370. dataView.setUint32(0, crc32.get());
  371. stream.value = value;
  372. }
  373. });
  374. stream = this;
  375. }
  376. }
  377. /*
  378. Copyright (c) 2022 Gildas Lormeau. All rights reserved.
  379. Redistribution and use in source and binary forms, with or without
  380. modification, are permitted provided that the following conditions are met:
  381. 1. Redistributions of source code must retain the above copyright notice,
  382. this list of conditions and the following disclaimer.
  383. 2. Redistributions in binary form must reproduce the above copyright
  384. notice, this list of conditions and the following disclaimer in
  385. the documentation and/or other materials provided with the distribution.
  386. 3. The names of the authors may not be used to endorse or promote products
  387. derived from this software without specific prior written permission.
  388. THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  389. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  390. FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
  391. INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
  392. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  393. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  394. OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  395. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  396. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  397. EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  398. */
  399. function encodeText(value) {
  400. if (typeof TextEncoder$2 == "undefined") {
  401. value = unescape(encodeURIComponent(value));
  402. const result = new Uint8Array$1(value.length);
  403. for (let i = 0; i < result.length; i++) {
  404. result[i] = value.charCodeAt(i);
  405. }
  406. return result;
  407. } else {
  408. return new TextEncoder$2().encode(value);
  409. }
  410. }
  411. // Derived from https://github.com/xqdoo00o/jszip/blob/master/lib/sjcl.js and https://github.com/bitwiseshiftleft/sjcl
  412. // deno-lint-ignore-file no-this-alias
  413. /*
  414. * SJCL is open. You can use, modify and redistribute it under a BSD
  415. * license or under the GNU GPL, version 2.0.
  416. */
  417. /** @fileOverview Javascript cryptography implementation.
  418. *
  419. * Crush to remove comments, shorten variable names and
  420. * generally reduce transmission size.
  421. *
  422. * @author Emily Stark
  423. * @author Mike Hamburg
  424. * @author Dan Boneh
  425. */
  426. /*jslint indent: 2, bitwise: false, nomen: false, plusplus: false, white: false, regexp: false */
  427. /** @fileOverview Arrays of bits, encoded as arrays of Numbers.
  428. *
  429. * @author Emily Stark
  430. * @author Mike Hamburg
  431. * @author Dan Boneh
  432. */
  433. /**
  434. * Arrays of bits, encoded as arrays of Numbers.
  435. * @namespace
  436. * @description
  437. * <p>
  438. * These objects are the currency accepted by SJCL's crypto functions.
  439. * </p>
  440. *
  441. * <p>
  442. * Most of our crypto primitives operate on arrays of 4-byte words internally,
  443. * but many of them can take arguments that are not a multiple of 4 bytes.
  444. * This library encodes arrays of bits (whose size need not be a multiple of 8
  445. * bits) as arrays of 32-bit words. The bits are packed, big-endian, into an
  446. * array of words, 32 bits at a time. Since the words are double-precision
  447. * floating point numbers, they fit some extra data. We use this (in a private,
  448. * possibly-changing manner) to encode the number of bits actually present
  449. * in the last word of the array.
  450. * </p>
  451. *
  452. * <p>
  453. * Because bitwise ops clear this out-of-band data, these arrays can be passed
  454. * to ciphers like AES which want arrays of words.
  455. * </p>
  456. */
  457. const bitArray = {
  458. /**
  459. * Concatenate two bit arrays.
  460. * @param {bitArray} a1 The first array.
  461. * @param {bitArray} a2 The second array.
  462. * @return {bitArray} The concatenation of a1 and a2.
  463. */
  464. concat(a1, a2) {
  465. if (a1.length === 0 || a2.length === 0) {
  466. return a1.concat(a2);
  467. }
  468. const last = a1[a1.length - 1], shift = bitArray.getPartial(last);
  469. if (shift === 32) {
  470. return a1.concat(a2);
  471. } else {
  472. return bitArray._shiftRight(a2, shift, last | 0, a1.slice(0, a1.length - 1));
  473. }
  474. },
  475. /**
  476. * Find the length of an array of bits.
  477. * @param {bitArray} a The array.
  478. * @return {Number} The length of a, in bits.
  479. */
  480. bitLength(a) {
  481. const l = a.length;
  482. if (l === 0) {
  483. return 0;
  484. }
  485. const x = a[l - 1];
  486. return (l - 1) * 32 + bitArray.getPartial(x);
  487. },
  488. /**
  489. * Truncate an array.
  490. * @param {bitArray} a The array.
  491. * @param {Number} len The length to truncate to, in bits.
  492. * @return {bitArray} A new array, truncated to len bits.
  493. */
  494. clamp(a, len) {
  495. if (a.length * 32 < len) {
  496. return a;
  497. }
  498. a = a.slice(0, Math$1.ceil(len / 32));
  499. const l = a.length;
  500. len = len & 31;
  501. if (l > 0 && len) {
  502. a[l - 1] = bitArray.partial(len, a[l - 1] & 0x80000000 >> (len - 1), 1);
  503. }
  504. return a;
  505. },
  506. /**
  507. * Make a partial word for a bit array.
  508. * @param {Number} len The number of bits in the word.
  509. * @param {Number} x The bits.
  510. * @param {Number} [_end=0] Pass 1 if x has already been shifted to the high side.
  511. * @return {Number} The partial word.
  512. */
  513. partial(len, x, _end) {
  514. if (len === 32) {
  515. return x;
  516. }
  517. return (_end ? x | 0 : x << (32 - len)) + len * 0x10000000000;
  518. },
  519. /**
  520. * Get the number of bits used by a partial word.
  521. * @param {Number} x The partial word.
  522. * @return {Number} The number of bits used by the partial word.
  523. */
  524. getPartial(x) {
  525. return Math$1.round(x / 0x10000000000) || 32;
  526. },
  527. /** Shift an array right.
  528. * @param {bitArray} a The array to shift.
  529. * @param {Number} shift The number of bits to shift.
  530. * @param {Number} [carry=0] A byte to carry in
  531. * @param {bitArray} [out=[]] An array to prepend to the output.
  532. * @private
  533. */
  534. _shiftRight(a, shift, carry, out) {
  535. if (out === undefined) {
  536. out = [];
  537. }
  538. for (; shift >= 32; shift -= 32) {
  539. out.push(carry);
  540. carry = 0;
  541. }
  542. if (shift === 0) {
  543. return out.concat(a);
  544. }
  545. for (let i = 0; i < a.length; i++) {
  546. out.push(carry | a[i] >>> shift);
  547. carry = a[i] << (32 - shift);
  548. }
  549. const last2 = a.length ? a[a.length - 1] : 0;
  550. const shift2 = bitArray.getPartial(last2);
  551. out.push(bitArray.partial(shift + shift2 & 31, (shift + shift2 > 32) ? carry : out.pop(), 1));
  552. return out;
  553. }
  554. };
  555. /** @fileOverview Bit array codec implementations.
  556. *
  557. * @author Emily Stark
  558. * @author Mike Hamburg
  559. * @author Dan Boneh
  560. */
  561. /**
  562. * Arrays of bytes
  563. * @namespace
  564. */
  565. const codec = {
  566. bytes: {
  567. /** Convert from a bitArray to an array of bytes. */
  568. fromBits(arr) {
  569. const bl = bitArray.bitLength(arr);
  570. const byteLength = bl / 8;
  571. const out = new Uint8Array$1(byteLength);
  572. let tmp;
  573. for (let i = 0; i < byteLength; i++) {
  574. if ((i & 3) === 0) {
  575. tmp = arr[i / 4];
  576. }
  577. out[i] = tmp >>> 24;
  578. tmp <<= 8;
  579. }
  580. return out;
  581. },
  582. /** Convert from an array of bytes to a bitArray. */
  583. toBits(bytes) {
  584. const out = [];
  585. let i;
  586. let tmp = 0;
  587. for (i = 0; i < bytes.length; i++) {
  588. tmp = tmp << 8 | bytes[i];
  589. if ((i & 3) === 3) {
  590. out.push(tmp);
  591. tmp = 0;
  592. }
  593. }
  594. if (i & 3) {
  595. out.push(bitArray.partial(8 * (i & 3), tmp));
  596. }
  597. return out;
  598. }
  599. }
  600. };
  601. const hash = {};
  602. /**
  603. * Context for a SHA-1 operation in progress.
  604. * @constructor
  605. */
  606. hash.sha1 = class {
  607. constructor(hash) {
  608. const sha1 = this;
  609. /**
  610. * The hash's block size, in bits.
  611. * @constant
  612. */
  613. sha1.blockSize = 512;
  614. /**
  615. * The SHA-1 initialization vector.
  616. * @private
  617. */
  618. sha1._init = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0];
  619. /**
  620. * The SHA-1 hash key.
  621. * @private
  622. */
  623. sha1._key = [0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6];
  624. if (hash) {
  625. sha1._h = hash._h.slice(0);
  626. sha1._buffer = hash._buffer.slice(0);
  627. sha1._length = hash._length;
  628. } else {
  629. sha1.reset();
  630. }
  631. }
  632. /**
  633. * Reset the hash state.
  634. * @return this
  635. */
  636. reset() {
  637. const sha1 = this;
  638. sha1._h = sha1._init.slice(0);
  639. sha1._buffer = [];
  640. sha1._length = 0;
  641. return sha1;
  642. }
  643. /**
  644. * Input several words to the hash.
  645. * @param {bitArray|String} data the data to hash.
  646. * @return this
  647. */
  648. update(data) {
  649. const sha1 = this;
  650. if (typeof data === "string") {
  651. data = codec.utf8String.toBits(data);
  652. }
  653. const b = sha1._buffer = bitArray.concat(sha1._buffer, data);
  654. const ol = sha1._length;
  655. const nl = sha1._length = ol + bitArray.bitLength(data);
  656. if (nl > 9007199254740991) {
  657. throw new Error$1("Cannot hash more than 2^53 - 1 bits");
  658. }
  659. const c = new Uint32Array$1(b);
  660. let j = 0;
  661. for (let i = sha1.blockSize + ol - ((sha1.blockSize + ol) & (sha1.blockSize - 1)); i <= nl;
  662. i += sha1.blockSize) {
  663. sha1._block(c.subarray(16 * j, 16 * (j + 1)));
  664. j += 1;
  665. }
  666. b.splice(0, 16 * j);
  667. return sha1;
  668. }
  669. /**
  670. * Complete hashing and output the hash value.
  671. * @return {bitArray} The hash value, an array of 5 big-endian words. TODO
  672. */
  673. finalize() {
  674. const sha1 = this;
  675. let b = sha1._buffer;
  676. const h = sha1._h;
  677. // Round out and push the buffer
  678. b = bitArray.concat(b, [bitArray.partial(1, 1)]);
  679. // Round out the buffer to a multiple of 16 words, less the 2 length words.
  680. for (let i = b.length + 2; i & 15; i++) {
  681. b.push(0);
  682. }
  683. // append the length
  684. b.push(Math$1.floor(sha1._length / 0x100000000));
  685. b.push(sha1._length | 0);
  686. while (b.length) {
  687. sha1._block(b.splice(0, 16));
  688. }
  689. sha1.reset();
  690. return h;
  691. }
  692. /**
  693. * The SHA-1 logical functions f(0), f(1), ..., f(79).
  694. * @private
  695. */
  696. _f(t, b, c, d) {
  697. if (t <= 19) {
  698. return (b & c) | (~b & d);
  699. } else if (t <= 39) {
  700. return b ^ c ^ d;
  701. } else if (t <= 59) {
  702. return (b & c) | (b & d) | (c & d);
  703. } else if (t <= 79) {
  704. return b ^ c ^ d;
  705. }
  706. }
  707. /**
  708. * Circular left-shift operator.
  709. * @private
  710. */
  711. _S(n, x) {
  712. return (x << n) | (x >>> 32 - n);
  713. }
  714. /**
  715. * Perform one cycle of SHA-1.
  716. * @param {Uint32Array|bitArray} words one block of words.
  717. * @private
  718. */
  719. _block(words) {
  720. const sha1 = this;
  721. const h = sha1._h;
  722. // When words is passed to _block, it has 16 elements. SHA1 _block
  723. // function extends words with new elements (at the end there are 80 elements).
  724. // The problem is that if we use Uint32Array instead of Array,
  725. // the length of Uint32Array cannot be changed. Thus, we replace words with a
  726. // normal Array here.
  727. const w = Array$1(80); // do not use Uint32Array here as the instantiation is slower
  728. for (let j = 0; j < 16; j++) {
  729. w[j] = words[j];
  730. }
  731. let a = h[0];
  732. let b = h[1];
  733. let c = h[2];
  734. let d = h[3];
  735. let e = h[4];
  736. for (let t = 0; t <= 79; t++) {
  737. if (t >= 16) {
  738. w[t] = sha1._S(1, w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16]);
  739. }
  740. const tmp = (sha1._S(5, a) + sha1._f(t, b, c, d) + e + w[t] +
  741. sha1._key[Math$1.floor(t / 20)]) | 0;
  742. e = d;
  743. d = c;
  744. c = sha1._S(30, b);
  745. b = a;
  746. a = tmp;
  747. }
  748. h[0] = (h[0] + a) | 0;
  749. h[1] = (h[1] + b) | 0;
  750. h[2] = (h[2] + c) | 0;
  751. h[3] = (h[3] + d) | 0;
  752. h[4] = (h[4] + e) | 0;
  753. }
  754. };
  755. /** @fileOverview Low-level AES implementation.
  756. *
  757. * This file contains a low-level implementation of AES, optimized for
  758. * size and for efficiency on several browsers. It is based on
  759. * OpenSSL's aes_core.c, a public-domain implementation by Vincent
  760. * Rijmen, Antoon Bosselaers and Paulo Barreto.
  761. *
  762. * An older version of this implementation is available in the public
  763. * domain, but this one is (c) Emily Stark, Mike Hamburg, Dan Boneh,
  764. * Stanford University 2008-2010 and BSD-licensed for liability
  765. * reasons.
  766. *
  767. * @author Emily Stark
  768. * @author Mike Hamburg
  769. * @author Dan Boneh
  770. */
  771. const cipher = {};
  772. /**
  773. * Schedule out an AES key for both encryption and decryption. This
  774. * is a low-level class. Use a cipher mode to do bulk encryption.
  775. *
  776. * @constructor
  777. * @param {Array} key The key as an array of 4, 6 or 8 words.
  778. */
  779. cipher.aes = class {
  780. constructor(key) {
  781. /**
  782. * The expanded S-box and inverse S-box tables. These will be computed
  783. * on the client so that we don't have to send them down the wire.
  784. *
  785. * There are two tables, _tables[0] is for encryption and
  786. * _tables[1] is for decryption.
  787. *
  788. * The first 4 sub-tables are the expanded S-box with MixColumns. The
  789. * last (_tables[01][4]) is the S-box itself.
  790. *
  791. * @private
  792. */
  793. const aes = this;
  794. aes._tables = [[[], [], [], [], []], [[], [], [], [], []]];
  795. if (!aes._tables[0][0][0]) {
  796. aes._precompute();
  797. }
  798. const sbox = aes._tables[0][4];
  799. const decTable = aes._tables[1];
  800. const keyLen = key.length;
  801. let i, encKey, decKey, rcon = 1;
  802. if (keyLen !== 4 && keyLen !== 6 && keyLen !== 8) {
  803. throw new Error$1("invalid aes key size");
  804. }
  805. aes._key = [encKey = key.slice(0), decKey = []];
  806. // schedule encryption keys
  807. for (i = keyLen; i < 4 * keyLen + 28; i++) {
  808. let tmp = encKey[i - 1];
  809. // apply sbox
  810. if (i % keyLen === 0 || (keyLen === 8 && i % keyLen === 4)) {
  811. tmp = sbox[tmp >>> 24] << 24 ^ sbox[tmp >> 16 & 255] << 16 ^ sbox[tmp >> 8 & 255] << 8 ^ sbox[tmp & 255];
  812. // shift rows and add rcon
  813. if (i % keyLen === 0) {
  814. tmp = tmp << 8 ^ tmp >>> 24 ^ rcon << 24;
  815. rcon = rcon << 1 ^ (rcon >> 7) * 283;
  816. }
  817. }
  818. encKey[i] = encKey[i - keyLen] ^ tmp;
  819. }
  820. // schedule decryption keys
  821. for (let j = 0; i; j++, i--) {
  822. const tmp = encKey[j & 3 ? i : i - 4];
  823. if (i <= 4 || j < 4) {
  824. decKey[j] = tmp;
  825. } else {
  826. decKey[j] = decTable[0][sbox[tmp >>> 24]] ^
  827. decTable[1][sbox[tmp >> 16 & 255]] ^
  828. decTable[2][sbox[tmp >> 8 & 255]] ^
  829. decTable[3][sbox[tmp & 255]];
  830. }
  831. }
  832. }
  833. // public
  834. /* Something like this might appear here eventually
  835. name: "AES",
  836. blockSize: 4,
  837. keySizes: [4,6,8],
  838. */
  839. /**
  840. * Encrypt an array of 4 big-endian words.
  841. * @param {Array} data The plaintext.
  842. * @return {Array} The ciphertext.
  843. */
  844. encrypt(data) {
  845. return this._crypt(data, 0);
  846. }
  847. /**
  848. * Decrypt an array of 4 big-endian words.
  849. * @param {Array} data The ciphertext.
  850. * @return {Array} The plaintext.
  851. */
  852. decrypt(data) {
  853. return this._crypt(data, 1);
  854. }
  855. /**
  856. * Expand the S-box tables.
  857. *
  858. * @private
  859. */
  860. _precompute() {
  861. const encTable = this._tables[0];
  862. const decTable = this._tables[1];
  863. const sbox = encTable[4];
  864. const sboxInv = decTable[4];
  865. const d = [];
  866. const th = [];
  867. let xInv, x2, x4, x8;
  868. // Compute double and third tables
  869. for (let i = 0; i < 256; i++) {
  870. th[(d[i] = i << 1 ^ (i >> 7) * 283) ^ i] = i;
  871. }
  872. for (let x = xInv = 0; !sbox[x]; x ^= x2 || 1, xInv = th[xInv] || 1) {
  873. // Compute sbox
  874. let s = xInv ^ xInv << 1 ^ xInv << 2 ^ xInv << 3 ^ xInv << 4;
  875. s = s >> 8 ^ s & 255 ^ 99;
  876. sbox[x] = s;
  877. sboxInv[s] = x;
  878. // Compute MixColumns
  879. x8 = d[x4 = d[x2 = d[x]]];
  880. let tDec = x8 * 0x1010101 ^ x4 * 0x10001 ^ x2 * 0x101 ^ x * 0x1010100;
  881. let tEnc = d[s] * 0x101 ^ s * 0x1010100;
  882. for (let i = 0; i < 4; i++) {
  883. encTable[i][x] = tEnc = tEnc << 24 ^ tEnc >>> 8;
  884. decTable[i][s] = tDec = tDec << 24 ^ tDec >>> 8;
  885. }
  886. }
  887. // Compactify. Considerable speedup on Firefox.
  888. for (let i = 0; i < 5; i++) {
  889. encTable[i] = encTable[i].slice(0);
  890. decTable[i] = decTable[i].slice(0);
  891. }
  892. }
  893. /**
  894. * Encryption and decryption core.
  895. * @param {Array} input Four words to be encrypted or decrypted.
  896. * @param dir The direction, 0 for encrypt and 1 for decrypt.
  897. * @return {Array} The four encrypted or decrypted words.
  898. * @private
  899. */
  900. _crypt(input, dir) {
  901. if (input.length !== 4) {
  902. throw new Error$1("invalid aes block size");
  903. }
  904. const key = this._key[dir];
  905. const nInnerRounds = key.length / 4 - 2;
  906. const out = [0, 0, 0, 0];
  907. const table = this._tables[dir];
  908. // load up the tables
  909. const t0 = table[0];
  910. const t1 = table[1];
  911. const t2 = table[2];
  912. const t3 = table[3];
  913. const sbox = table[4];
  914. // state variables a,b,c,d are loaded with pre-whitened data
  915. let a = input[0] ^ key[0];
  916. let b = input[dir ? 3 : 1] ^ key[1];
  917. let c = input[2] ^ key[2];
  918. let d = input[dir ? 1 : 3] ^ key[3];
  919. let kIndex = 4;
  920. let a2, b2, c2;
  921. // Inner rounds. Cribbed from OpenSSL.
  922. for (let i = 0; i < nInnerRounds; i++) {
  923. a2 = t0[a >>> 24] ^ t1[b >> 16 & 255] ^ t2[c >> 8 & 255] ^ t3[d & 255] ^ key[kIndex];
  924. b2 = t0[b >>> 24] ^ t1[c >> 16 & 255] ^ t2[d >> 8 & 255] ^ t3[a & 255] ^ key[kIndex + 1];
  925. c2 = t0[c >>> 24] ^ t1[d >> 16 & 255] ^ t2[a >> 8 & 255] ^ t3[b & 255] ^ key[kIndex + 2];
  926. d = t0[d >>> 24] ^ t1[a >> 16 & 255] ^ t2[b >> 8 & 255] ^ t3[c & 255] ^ key[kIndex + 3];
  927. kIndex += 4;
  928. a = a2; b = b2; c = c2;
  929. }
  930. // Last round.
  931. for (let i = 0; i < 4; i++) {
  932. out[dir ? 3 & -i : i] =
  933. sbox[a >>> 24] << 24 ^
  934. sbox[b >> 16 & 255] << 16 ^
  935. sbox[c >> 8 & 255] << 8 ^
  936. sbox[d & 255] ^
  937. key[kIndex++];
  938. a2 = a; a = b; b = c; c = d; d = a2;
  939. }
  940. return out;
  941. }
  942. };
  943. /**
  944. * Random values
  945. * @namespace
  946. */
  947. const random = {
  948. /**
  949. * Generate random words with pure js, cryptographically not as strong & safe as native implementation.
  950. * @param {TypedArray} typedArray The array to fill.
  951. * @return {TypedArray} The random values.
  952. */
  953. getRandomValues(typedArray) {
  954. const words = new Uint32Array$1(typedArray.buffer);
  955. const r = (m_w) => {
  956. let m_z = 0x3ade68b1;
  957. const mask = 0xffffffff;
  958. return function () {
  959. m_z = (0x9069 * (m_z & 0xFFFF) + (m_z >> 0x10)) & mask;
  960. m_w = (0x4650 * (m_w & 0xFFFF) + (m_w >> 0x10)) & mask;
  961. const result = ((((m_z << 0x10) + m_w) & mask) / 0x100000000) + .5;
  962. return result * (Math$1.random() > .5 ? 1 : -1);
  963. };
  964. };
  965. for (let i = 0, rcache; i < typedArray.length; i += 4) {
  966. const _r = r((rcache || Math$1.random()) * 0x100000000);
  967. rcache = _r() * 0x3ade67b7;
  968. words[i / 4] = (_r() * 0x100000000) | 0;
  969. }
  970. return typedArray;
  971. }
  972. };
  973. /** @fileOverview CTR mode implementation.
  974. *
  975. * Special thanks to Roy Nicholson for pointing out a bug in our
  976. * implementation.
  977. *
  978. * @author Emily Stark
  979. * @author Mike Hamburg
  980. * @author Dan Boneh
  981. */
  982. /** Brian Gladman's CTR Mode.
  983. * @constructor
  984. * @param {Object} _prf The aes instance to generate key.
  985. * @param {bitArray} _iv The iv for ctr mode, it must be 128 bits.
  986. */
  987. const mode = {};
  988. /**
  989. * Brian Gladman's CTR Mode.
  990. * @namespace
  991. */
  992. mode.ctrGladman = class {
  993. constructor(prf, iv) {
  994. this._prf = prf;
  995. this._initIv = iv;
  996. this._iv = iv;
  997. }
  998. reset() {
  999. this._iv = this._initIv;
  1000. }
  1001. /** Input some data to calculate.
  1002. * @param {bitArray} data the data to process, it must be intergral multiple of 128 bits unless it's the last.
  1003. */
  1004. update(data) {
  1005. return this.calculate(this._prf, data, this._iv);
  1006. }
  1007. incWord(word) {
  1008. if (((word >> 24) & 0xff) === 0xff) { //overflow
  1009. let b1 = (word >> 16) & 0xff;
  1010. let b2 = (word >> 8) & 0xff;
  1011. let b3 = word & 0xff;
  1012. if (b1 === 0xff) { // overflow b1
  1013. b1 = 0;
  1014. if (b2 === 0xff) {
  1015. b2 = 0;
  1016. if (b3 === 0xff) {
  1017. b3 = 0;
  1018. } else {
  1019. ++b3;
  1020. }
  1021. } else {
  1022. ++b2;
  1023. }
  1024. } else {
  1025. ++b1;
  1026. }
  1027. word = 0;
  1028. word += (b1 << 16);
  1029. word += (b2 << 8);
  1030. word += b3;
  1031. } else {
  1032. word += (0x01 << 24);
  1033. }
  1034. return word;
  1035. }
  1036. incCounter(counter) {
  1037. if ((counter[0] = this.incWord(counter[0])) === 0) {
  1038. // encr_data in fileenc.c from Dr Brian Gladman's counts only with DWORD j < 8
  1039. counter[1] = this.incWord(counter[1]);
  1040. }
  1041. }
  1042. calculate(prf, data, iv) {
  1043. let l;
  1044. if (!(l = data.length)) {
  1045. return [];
  1046. }
  1047. const bl = bitArray.bitLength(data);
  1048. for (let i = 0; i < l; i += 4) {
  1049. this.incCounter(iv);
  1050. const e = prf.encrypt(iv);
  1051. data[i] ^= e[0];
  1052. data[i + 1] ^= e[1];
  1053. data[i + 2] ^= e[2];
  1054. data[i + 3] ^= e[3];
  1055. }
  1056. return bitArray.clamp(data, bl);
  1057. }
  1058. };
  1059. const misc = {
  1060. importKey(password) {
  1061. return new misc.hmacSha1(codec.bytes.toBits(password));
  1062. },
  1063. pbkdf2(prf, salt, count, length) {
  1064. count = count || 10000;
  1065. if (length < 0 || count < 0) {
  1066. throw new Error$1("invalid params to pbkdf2");
  1067. }
  1068. const byteLength = ((length >> 5) + 1) << 2;
  1069. let u, ui, i, j, k;
  1070. const arrayBuffer = new ArrayBuffer(byteLength);
  1071. const out = new DataView$1(arrayBuffer);
  1072. let outLength = 0;
  1073. const b = bitArray;
  1074. salt = codec.bytes.toBits(salt);
  1075. for (k = 1; outLength < (byteLength || 1); k++) {
  1076. u = ui = prf.encrypt(b.concat(salt, [k]));
  1077. for (i = 1; i < count; i++) {
  1078. ui = prf.encrypt(ui);
  1079. for (j = 0; j < ui.length; j++) {
  1080. u[j] ^= ui[j];
  1081. }
  1082. }
  1083. for (i = 0; outLength < (byteLength || 1) && i < u.length; i++) {
  1084. out.setInt32(outLength, u[i]);
  1085. outLength += 4;
  1086. }
  1087. }
  1088. return arrayBuffer.slice(0, length / 8);
  1089. }
  1090. };
  1091. /** @fileOverview HMAC implementation.
  1092. *
  1093. * @author Emily Stark
  1094. * @author Mike Hamburg
  1095. * @author Dan Boneh
  1096. */
  1097. /** HMAC with the specified hash function.
  1098. * @constructor
  1099. * @param {bitArray} key the key for HMAC.
  1100. * @param {Object} [Hash=hash.sha1] The hash function to use.
  1101. */
  1102. misc.hmacSha1 = class {
  1103. constructor(key) {
  1104. const hmac = this;
  1105. const Hash = hmac._hash = hash.sha1;
  1106. const exKey = [[], []];
  1107. hmac._baseHash = [new Hash(), new Hash()];
  1108. const bs = hmac._baseHash[0].blockSize / 32;
  1109. if (key.length > bs) {
  1110. key = new Hash().update(key).finalize();
  1111. }
  1112. for (let i = 0; i < bs; i++) {
  1113. exKey[0][i] = key[i] ^ 0x36363636;
  1114. exKey[1][i] = key[i] ^ 0x5C5C5C5C;
  1115. }
  1116. hmac._baseHash[0].update(exKey[0]);
  1117. hmac._baseHash[1].update(exKey[1]);
  1118. hmac._resultHash = new Hash(hmac._baseHash[0]);
  1119. }
  1120. reset() {
  1121. const hmac = this;
  1122. hmac._resultHash = new hmac._hash(hmac._baseHash[0]);
  1123. hmac._updated = false;
  1124. }
  1125. update(data) {
  1126. const hmac = this;
  1127. hmac._updated = true;
  1128. hmac._resultHash.update(data);
  1129. }
  1130. digest() {
  1131. const hmac = this;
  1132. const w = hmac._resultHash.finalize();
  1133. const result = new (hmac._hash)(hmac._baseHash[1]).update(w).finalize();
  1134. hmac.reset();
  1135. return result;
  1136. }
  1137. encrypt(data) {
  1138. if (!this._updated) {
  1139. this.update(data);
  1140. return this.digest(data);
  1141. } else {
  1142. throw new Error$1("encrypt on already updated hmac called!");
  1143. }
  1144. }
  1145. };
  1146. /*
  1147. Copyright (c) 2022 Gildas Lormeau. All rights reserved.
  1148. Redistribution and use in source and binary forms, with or without
  1149. modification, are permitted provided that the following conditions are met:
  1150. 1. Redistributions of source code must retain the above copyright notice,
  1151. this list of conditions and the following disclaimer.
  1152. 2. Redistributions in binary form must reproduce the above copyright
  1153. notice, this list of conditions and the following disclaimer in
  1154. the documentation and/or other materials provided with the distribution.
  1155. 3. The names of the authors may not be used to endorse or promote products
  1156. derived from this software without specific prior written permission.
  1157. THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  1158. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  1159. FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
  1160. INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
  1161. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  1162. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  1163. OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  1164. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  1165. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  1166. EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1167. */
  1168. const GET_RANDOM_VALUES_SUPPORTED = typeof crypto$1 != "undefined" && typeof crypto$1.getRandomValues == "function";
  1169. const ERR_INVALID_PASSWORD = "Invalid password";
  1170. const ERR_INVALID_SIGNATURE = "Invalid signature";
  1171. const ERR_ABORT_CHECK_PASSWORD = "zipjs-abort-check-password";
  1172. function getRandomValues(array) {
  1173. if (GET_RANDOM_VALUES_SUPPORTED) {
  1174. return crypto$1.getRandomValues(array);
  1175. } else {
  1176. return random.getRandomValues(array);
  1177. }
  1178. }
  1179. /*
  1180. Copyright (c) 2022 Gildas Lormeau. All rights reserved.
  1181. Redistribution and use in source and binary forms, with or without
  1182. modification, are permitted provided that the following conditions are met:
  1183. 1. Redistributions of source code must retain the above copyright notice,
  1184. this list of conditions and the following disclaimer.
  1185. 2. Redistributions in binary form must reproduce the above copyright
  1186. notice, this list of conditions and the following disclaimer in
  1187. the documentation and/or other materials provided with the distribution.
  1188. 3. The names of the authors may not be used to endorse or promote products
  1189. derived from this software without specific prior written permission.
  1190. THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  1191. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  1192. FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
  1193. INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
  1194. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  1195. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  1196. OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  1197. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  1198. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  1199. EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1200. */
  1201. const BLOCK_LENGTH = 16;
  1202. const RAW_FORMAT = "raw";
  1203. const PBKDF2_ALGORITHM = { name: "PBKDF2" };
  1204. const HASH_ALGORITHM = { name: "HMAC" };
  1205. const HASH_FUNCTION = "SHA-1";
  1206. const BASE_KEY_ALGORITHM = Object$1.assign({ hash: HASH_ALGORITHM }, PBKDF2_ALGORITHM);
  1207. const DERIVED_BITS_ALGORITHM = Object$1.assign({ iterations: 1000, hash: { name: HASH_FUNCTION } }, PBKDF2_ALGORITHM);
  1208. const DERIVED_BITS_USAGE = ["deriveBits"];
  1209. const SALT_LENGTH = [8, 12, 16];
  1210. const KEY_LENGTH = [16, 24, 32];
  1211. const SIGNATURE_LENGTH = 10;
  1212. const COUNTER_DEFAULT_VALUE = [0, 0, 0, 0];
  1213. const UNDEFINED_TYPE = "undefined";
  1214. const FUNCTION_TYPE = "function";
  1215. // deno-lint-ignore valid-typeof
  1216. const CRYPTO_API_SUPPORTED = typeof crypto$1 != UNDEFINED_TYPE;
  1217. const subtle = CRYPTO_API_SUPPORTED && crypto$1.subtle;
  1218. const SUBTLE_API_SUPPORTED = CRYPTO_API_SUPPORTED && typeof subtle != UNDEFINED_TYPE;
  1219. const codecBytes = codec.bytes;
  1220. const Aes = cipher.aes;
  1221. const CtrGladman = mode.ctrGladman;
  1222. const HmacSha1 = misc.hmacSha1;
  1223. let IMPORT_KEY_SUPPORTED = CRYPTO_API_SUPPORTED && SUBTLE_API_SUPPORTED && typeof subtle.importKey == FUNCTION_TYPE;
  1224. let DERIVE_BITS_SUPPORTED = CRYPTO_API_SUPPORTED && SUBTLE_API_SUPPORTED && typeof subtle.deriveBits == FUNCTION_TYPE;
  1225. class AESDecryptionStream extends TransformStream {
  1226. constructor({ password, signed, encryptionStrength, checkPasswordOnly }) {
  1227. super({
  1228. start() {
  1229. Object$1.assign(this, {
  1230. ready: new Promise$1(resolve => this.resolveReady = resolve),
  1231. password,
  1232. signed,
  1233. strength: encryptionStrength - 1,
  1234. pending: new Uint8Array$1()
  1235. });
  1236. },
  1237. async transform(chunk, controller) {
  1238. const aesCrypto = this;
  1239. const {
  1240. password,
  1241. strength,
  1242. resolveReady,
  1243. ready
  1244. } = aesCrypto;
  1245. if (password) {
  1246. await createDecryptionKeys(aesCrypto, strength, password, subarray(chunk, 0, SALT_LENGTH[strength] + 2));
  1247. chunk = subarray(chunk, SALT_LENGTH[strength] + 2);
  1248. if (checkPasswordOnly) {
  1249. controller.error(new Error$1(ERR_ABORT_CHECK_PASSWORD));
  1250. } else {
  1251. resolveReady();
  1252. }
  1253. } else {
  1254. await ready;
  1255. }
  1256. const output = new Uint8Array$1(chunk.length - SIGNATURE_LENGTH - ((chunk.length - SIGNATURE_LENGTH) % BLOCK_LENGTH));
  1257. controller.enqueue(append(aesCrypto, chunk, output, 0, SIGNATURE_LENGTH, true));
  1258. },
  1259. async flush(controller) {
  1260. const {
  1261. signed,
  1262. ctr,
  1263. hmac,
  1264. pending,
  1265. ready
  1266. } = this;
  1267. await ready;
  1268. const chunkToDecrypt = subarray(pending, 0, pending.length - SIGNATURE_LENGTH);
  1269. const originalSignature = subarray(pending, pending.length - SIGNATURE_LENGTH);
  1270. let decryptedChunkArray = new Uint8Array$1();
  1271. if (chunkToDecrypt.length) {
  1272. const encryptedChunk = toBits(codecBytes, chunkToDecrypt);
  1273. hmac.update(encryptedChunk);
  1274. const decryptedChunk = ctr.update(encryptedChunk);
  1275. decryptedChunkArray = fromBits(codecBytes, decryptedChunk);
  1276. }
  1277. if (signed) {
  1278. const signature = subarray(fromBits(codecBytes, hmac.digest()), 0, SIGNATURE_LENGTH);
  1279. for (let indexSignature = 0; indexSignature < SIGNATURE_LENGTH; indexSignature++) {
  1280. if (signature[indexSignature] != originalSignature[indexSignature]) {
  1281. throw new Error$1(ERR_INVALID_SIGNATURE);
  1282. }
  1283. }
  1284. }
  1285. controller.enqueue(decryptedChunkArray);
  1286. }
  1287. });
  1288. }
  1289. }
  1290. class AESEncryptionStream extends TransformStream {
  1291. constructor({ password, encryptionStrength }) {
  1292. // deno-lint-ignore prefer-const
  1293. let stream;
  1294. super({
  1295. start() {
  1296. Object$1.assign(this, {
  1297. ready: new Promise$1(resolve => this.resolveReady = resolve),
  1298. password,
  1299. strength: encryptionStrength - 1,
  1300. pending: new Uint8Array$1()
  1301. });
  1302. },
  1303. async transform(chunk, controller) {
  1304. const aesCrypto = this;
  1305. const {
  1306. password,
  1307. strength,
  1308. resolveReady,
  1309. ready
  1310. } = aesCrypto;
  1311. let preamble = new Uint8Array$1();
  1312. if (password) {
  1313. preamble = await createEncryptionKeys(aesCrypto, strength, password);
  1314. resolveReady();
  1315. } else {
  1316. await ready;
  1317. }
  1318. const output = new Uint8Array$1(preamble.length + chunk.length - (chunk.length % BLOCK_LENGTH));
  1319. output.set(preamble, 0);
  1320. controller.enqueue(append(aesCrypto, chunk, output, preamble.length, 0));
  1321. },
  1322. async flush(controller) {
  1323. const {
  1324. ctr,
  1325. hmac,
  1326. pending,
  1327. ready
  1328. } = this;
  1329. await ready;
  1330. let encryptedChunkArray = new Uint8Array$1();
  1331. if (pending.length) {
  1332. const encryptedChunk = ctr.update(toBits(codecBytes, pending));
  1333. hmac.update(encryptedChunk);
  1334. encryptedChunkArray = fromBits(codecBytes, encryptedChunk);
  1335. }
  1336. stream.signature = fromBits(codecBytes, hmac.digest()).slice(0, SIGNATURE_LENGTH);
  1337. controller.enqueue(concat(encryptedChunkArray, stream.signature));
  1338. }
  1339. });
  1340. stream = this;
  1341. }
  1342. }
  1343. function append(aesCrypto, input, output, paddingStart, paddingEnd, verifySignature) {
  1344. const {
  1345. ctr,
  1346. hmac,
  1347. pending
  1348. } = aesCrypto;
  1349. const inputLength = input.length - paddingEnd;
  1350. if (pending.length) {
  1351. input = concat(pending, input);
  1352. output = expand(output, inputLength - (inputLength % BLOCK_LENGTH));
  1353. }
  1354. let offset;
  1355. for (offset = 0; offset <= inputLength - BLOCK_LENGTH; offset += BLOCK_LENGTH) {
  1356. const inputChunk = toBits(codecBytes, subarray(input, offset, offset + BLOCK_LENGTH));
  1357. if (verifySignature) {
  1358. hmac.update(inputChunk);
  1359. }
  1360. const outputChunk = ctr.update(inputChunk);
  1361. if (!verifySignature) {
  1362. hmac.update(outputChunk);
  1363. }
  1364. output.set(fromBits(codecBytes, outputChunk), offset + paddingStart);
  1365. }
  1366. aesCrypto.pending = subarray(input, offset);
  1367. return output;
  1368. }
  1369. async function createDecryptionKeys(decrypt, strength, password, preamble) {
  1370. const passwordVerificationKey = await createKeys$1(decrypt, strength, password, subarray(preamble, 0, SALT_LENGTH[strength]));
  1371. const passwordVerification = subarray(preamble, SALT_LENGTH[strength]);
  1372. if (passwordVerificationKey[0] != passwordVerification[0] || passwordVerificationKey[1] != passwordVerification[1]) {
  1373. throw new Error$1(ERR_INVALID_PASSWORD);
  1374. }
  1375. }
  1376. async function createEncryptionKeys(encrypt, strength, password) {
  1377. const salt = getRandomValues(new Uint8Array$1(SALT_LENGTH[strength]));
  1378. const passwordVerification = await createKeys$1(encrypt, strength, password, salt);
  1379. return concat(salt, passwordVerification);
  1380. }
  1381. async function createKeys$1(aesCrypto, strength, password, salt) {
  1382. aesCrypto.password = null;
  1383. const encodedPassword = encodeText(password);
  1384. const baseKey = await importKey(RAW_FORMAT, encodedPassword, BASE_KEY_ALGORITHM, false, DERIVED_BITS_USAGE);
  1385. const derivedBits = await deriveBits(Object$1.assign({ salt }, DERIVED_BITS_ALGORITHM), baseKey, 8 * ((KEY_LENGTH[strength] * 2) + 2));
  1386. const compositeKey = new Uint8Array$1(derivedBits);
  1387. const key = toBits(codecBytes, subarray(compositeKey, 0, KEY_LENGTH[strength]));
  1388. const authentication = toBits(codecBytes, subarray(compositeKey, KEY_LENGTH[strength], KEY_LENGTH[strength] * 2));
  1389. const passwordVerification = subarray(compositeKey, KEY_LENGTH[strength] * 2);
  1390. Object$1.assign(aesCrypto, {
  1391. keys: {
  1392. key,
  1393. authentication,
  1394. passwordVerification
  1395. },
  1396. ctr: new CtrGladman(new Aes(key), Array$1.from(COUNTER_DEFAULT_VALUE)),
  1397. hmac: new HmacSha1(authentication)
  1398. });
  1399. return passwordVerification;
  1400. }
  1401. async function importKey(format, password, algorithm, extractable, keyUsages) {
  1402. if (IMPORT_KEY_SUPPORTED) {
  1403. try {
  1404. return await subtle.importKey(format, password, algorithm, extractable, keyUsages);
  1405. } catch (_error) {
  1406. IMPORT_KEY_SUPPORTED = false;
  1407. return misc.importKey(password);
  1408. }
  1409. } else {
  1410. return misc.importKey(password);
  1411. }
  1412. }
  1413. async function deriveBits(algorithm, baseKey, length) {
  1414. if (DERIVE_BITS_SUPPORTED) {
  1415. try {
  1416. return await subtle.deriveBits(algorithm, baseKey, length);
  1417. } catch (_error) {
  1418. DERIVE_BITS_SUPPORTED = false;
  1419. return misc.pbkdf2(baseKey, algorithm.salt, DERIVED_BITS_ALGORITHM.iterations, length);
  1420. }
  1421. } else {
  1422. return misc.pbkdf2(baseKey, algorithm.salt, DERIVED_BITS_ALGORITHM.iterations, length);
  1423. }
  1424. }
  1425. function concat(leftArray, rightArray) {
  1426. let array = leftArray;
  1427. if (leftArray.length + rightArray.length) {
  1428. array = new Uint8Array$1(leftArray.length + rightArray.length);
  1429. array.set(leftArray, 0);
  1430. array.set(rightArray, leftArray.length);
  1431. }
  1432. return array;
  1433. }
  1434. function expand(inputArray, length) {
  1435. if (length && length > inputArray.length) {
  1436. const array = inputArray;
  1437. inputArray = new Uint8Array$1(length);
  1438. inputArray.set(array, 0);
  1439. }
  1440. return inputArray;
  1441. }
  1442. function subarray(array, begin, end) {
  1443. return array.subarray(begin, end);
  1444. }
  1445. function fromBits(codecBytes, chunk) {
  1446. return codecBytes.fromBits(chunk);
  1447. }
  1448. function toBits(codecBytes, chunk) {
  1449. return codecBytes.toBits(chunk);
  1450. }
  1451. /*
  1452. Copyright (c) 2022 Gildas Lormeau. All rights reserved.
  1453. Redistribution and use in source and binary forms, with or without
  1454. modification, are permitted provided that the following conditions are met:
  1455. 1. Redistributions of source code must retain the above copyright notice,
  1456. this list of conditions and the following disclaimer.
  1457. 2. Redistributions in binary form must reproduce the above copyright
  1458. notice, this list of conditions and the following disclaimer in
  1459. the documentation and/or other materials provided with the distribution.
  1460. 3. The names of the authors may not be used to endorse or promote products
  1461. derived from this software without specific prior written permission.
  1462. THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  1463. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  1464. FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
  1465. INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
  1466. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  1467. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  1468. OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  1469. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  1470. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  1471. EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1472. */
  1473. const HEADER_LENGTH = 12;
  1474. class ZipCryptoDecryptionStream extends TransformStream {
  1475. constructor({ password, passwordVerification, checkPasswordOnly }) {
  1476. super({
  1477. start() {
  1478. Object$1.assign(this, {
  1479. password,
  1480. passwordVerification
  1481. });
  1482. createKeys(this, password);
  1483. },
  1484. transform(chunk, controller) {
  1485. const zipCrypto = this;
  1486. if (zipCrypto.password) {
  1487. const decryptedHeader = decrypt(zipCrypto, chunk.subarray(0, HEADER_LENGTH));
  1488. zipCrypto.password = null;
  1489. if (decryptedHeader[HEADER_LENGTH - 1] != zipCrypto.passwordVerification) {
  1490. throw new Error$1(ERR_INVALID_PASSWORD);
  1491. }
  1492. chunk = chunk.subarray(HEADER_LENGTH);
  1493. }
  1494. if (checkPasswordOnly) {
  1495. controller.error(new Error$1(ERR_ABORT_CHECK_PASSWORD));
  1496. } else {
  1497. controller.enqueue(decrypt(zipCrypto, chunk));
  1498. }
  1499. }
  1500. });
  1501. }
  1502. }
  1503. class ZipCryptoEncryptionStream extends TransformStream {
  1504. constructor({ password, passwordVerification }) {
  1505. super({
  1506. start() {
  1507. Object$1.assign(this, {
  1508. password,
  1509. passwordVerification
  1510. });
  1511. createKeys(this, password);
  1512. },
  1513. transform(chunk, controller) {
  1514. const zipCrypto = this;
  1515. let output;
  1516. let offset;
  1517. if (zipCrypto.password) {
  1518. zipCrypto.password = null;
  1519. const header = getRandomValues(new Uint8Array$1(HEADER_LENGTH));
  1520. header[HEADER_LENGTH - 1] = zipCrypto.passwordVerification;
  1521. output = new Uint8Array$1(chunk.length + header.length);
  1522. output.set(encrypt(zipCrypto, header), 0);
  1523. offset = HEADER_LENGTH;
  1524. } else {
  1525. output = new Uint8Array$1(chunk.length);
  1526. offset = 0;
  1527. }
  1528. output.set(encrypt(zipCrypto, chunk), offset);
  1529. controller.enqueue(output);
  1530. }
  1531. });
  1532. }
  1533. }
  1534. function decrypt(target, input) {
  1535. const output = new Uint8Array$1(input.length);
  1536. for (let index = 0; index < input.length; index++) {
  1537. output[index] = getByte(target) ^ input[index];
  1538. updateKeys(target, output[index]);
  1539. }
  1540. return output;
  1541. }
  1542. function encrypt(target, input) {
  1543. const output = new Uint8Array$1(input.length);
  1544. for (let index = 0; index < input.length; index++) {
  1545. output[index] = getByte(target) ^ input[index];
  1546. updateKeys(target, input[index]);
  1547. }
  1548. return output;
  1549. }
  1550. function createKeys(target, password) {
  1551. const keys = [0x12345678, 0x23456789, 0x34567890];
  1552. Object$1.assign(target, {
  1553. keys,
  1554. crcKey0: new Crc32(keys[0]),
  1555. crcKey2: new Crc32(keys[2]),
  1556. });
  1557. for (let index = 0; index < password.length; index++) {
  1558. updateKeys(target, password.charCodeAt(index));
  1559. }
  1560. }
  1561. function updateKeys(target, byte) {
  1562. let [key0, key1, key2] = target.keys;
  1563. target.crcKey0.append([byte]);
  1564. key0 = ~target.crcKey0.get();
  1565. key1 = getInt32(Math$1.imul(getInt32(key1 + getInt8(key0)), 134775813) + 1);
  1566. target.crcKey2.append([key1 >>> 24]);
  1567. key2 = ~target.crcKey2.get();
  1568. target.keys = [key0, key1, key2];
  1569. }
  1570. function getByte(target) {
  1571. const temp = target.keys[2] | 2;
  1572. return getInt8(Math$1.imul(temp, (temp ^ 1)) >>> 8);
  1573. }
  1574. function getInt8(number) {
  1575. return number & 0xFF;
  1576. }
  1577. function getInt32(number) {
  1578. return number & 0xFFFFFFFF;
  1579. }
  1580. /*
  1581. Copyright (c) 2022 Gildas Lormeau. All rights reserved.
  1582. Redistribution and use in source and binary forms, with or without
  1583. modification, are permitted provided that the following conditions are met:
  1584. 1. Redistributions of source code must retain the above copyright notice,
  1585. this list of conditions and the following disclaimer.
  1586. 2. Redistributions in binary form must reproduce the above copyright
  1587. notice, this list of conditions and the following disclaimer in
  1588. the documentation and/or other materials provided with the distribution.
  1589. 3. The names of the authors may not be used to endorse or promote products
  1590. derived from this software without specific prior written permission.
  1591. THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  1592. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  1593. FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
  1594. INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
  1595. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  1596. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  1597. OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  1598. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  1599. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  1600. EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1601. */
  1602. const COMPRESSION_FORMAT = "deflate-raw";
  1603. class DeflateStream extends TransformStream {
  1604. constructor(options, { chunkSize, CompressionStream, CompressionStreamNative }) {
  1605. super({});
  1606. const { compressed, encrypted, useCompressionStream, zipCrypto, signed, level } = options;
  1607. const stream = this;
  1608. let crc32Stream, encryptionStream;
  1609. let readable = filterEmptyChunks(super.readable);
  1610. if ((!encrypted || zipCrypto) && signed) {
  1611. crc32Stream = new Crc32Stream();
  1612. readable = pipeThrough(readable, crc32Stream);
  1613. }
  1614. if (compressed) {
  1615. readable = pipeThroughCommpressionStream(readable, useCompressionStream, { level, chunkSize }, CompressionStreamNative, CompressionStream);
  1616. }
  1617. if (encrypted) {
  1618. if (zipCrypto) {
  1619. readable = pipeThrough(readable, new ZipCryptoEncryptionStream(options));
  1620. } else {
  1621. encryptionStream = new AESEncryptionStream(options);
  1622. readable = pipeThrough(readable, encryptionStream);
  1623. }
  1624. }
  1625. setReadable(stream, readable, () => {
  1626. let signature;
  1627. if (encrypted && !zipCrypto) {
  1628. signature = encryptionStream.signature;
  1629. }
  1630. if ((!encrypted || zipCrypto) && signed) {
  1631. signature = new DataView$1(crc32Stream.value.buffer).getUint32(0);
  1632. }
  1633. stream.signature = signature;
  1634. });
  1635. }
  1636. }
  1637. class InflateStream extends TransformStream {
  1638. constructor(options, { chunkSize, DecompressionStream, DecompressionStreamNative }) {
  1639. super({});
  1640. const { zipCrypto, encrypted, signed, signature, compressed, useCompressionStream } = options;
  1641. let crc32Stream, decryptionStream;
  1642. let readable = filterEmptyChunks(super.readable);
  1643. if (encrypted) {
  1644. if (zipCrypto) {
  1645. readable = pipeThrough(readable, new ZipCryptoDecryptionStream(options));
  1646. } else {
  1647. decryptionStream = new AESDecryptionStream(options);
  1648. readable = pipeThrough(readable, decryptionStream);
  1649. }
  1650. }
  1651. if (compressed) {
  1652. readable = pipeThroughCommpressionStream(readable, useCompressionStream, { chunkSize }, DecompressionStreamNative, DecompressionStream);
  1653. }
  1654. if ((!encrypted || zipCrypto) && signed) {
  1655. crc32Stream = new Crc32Stream();
  1656. readable = pipeThrough(readable, crc32Stream);
  1657. }
  1658. setReadable(this, readable, () => {
  1659. if ((!encrypted || zipCrypto) && signed) {
  1660. const dataViewSignature = new DataView$1(crc32Stream.value.buffer);
  1661. if (signature != dataViewSignature.getUint32(0, false)) {
  1662. throw new Error$1(ERR_INVALID_SIGNATURE);
  1663. }
  1664. }
  1665. });
  1666. }
  1667. }
  1668. function filterEmptyChunks(readable) {
  1669. return pipeThrough(readable, new TransformStream({
  1670. transform(chunk, controller) {
  1671. if (chunk && chunk.length) {
  1672. controller.enqueue(chunk);
  1673. }
  1674. }
  1675. }));
  1676. }
  1677. function setReadable(stream, readable, flush) {
  1678. readable = pipeThrough(readable, new TransformStream({ flush }));
  1679. Object$1.defineProperty(stream, "readable", {
  1680. get() {
  1681. return readable;
  1682. }
  1683. });
  1684. }
  1685. function pipeThroughCommpressionStream(readable, useCompressionStream, options, CodecStreamNative, CodecStream) {
  1686. try {
  1687. const CompressionStream = useCompressionStream && CodecStreamNative ? CodecStreamNative : CodecStream;
  1688. readable = pipeThrough(readable, new CompressionStream(COMPRESSION_FORMAT, options));
  1689. } catch (error) {
  1690. if (useCompressionStream) {
  1691. readable = pipeThrough(readable, new CodecStream(COMPRESSION_FORMAT, options));
  1692. } else {
  1693. throw error;
  1694. }
  1695. }
  1696. return readable;
  1697. }
  1698. function pipeThrough(readable, transformStream) {
  1699. return readable.pipeThrough(transformStream);
  1700. }
  1701. /*
  1702. Copyright (c) 2022 Gildas Lormeau. All rights reserved.
  1703. Redistribution and use in source and binary forms, with or without
  1704. modification, are permitted provided that the following conditions are met:
  1705. 1. Redistributions of source code must retain the above copyright notice,
  1706. this list of conditions and the following disclaimer.
  1707. 2. Redistributions in binary form must reproduce the above copyright
  1708. notice, this list of conditions and the following disclaimer in
  1709. the documentation and/or other materials provided with the distribution.
  1710. 3. The names of the authors may not be used to endorse or promote products
  1711. derived from this software without specific prior written permission.
  1712. THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  1713. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  1714. FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
  1715. INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
  1716. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  1717. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  1718. OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  1719. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  1720. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  1721. EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1722. */
  1723. const MESSAGE_EVENT_TYPE = "message";
  1724. const MESSAGE_START = "start";
  1725. const MESSAGE_PULL = "pull";
  1726. const MESSAGE_DATA = "data";
  1727. const MESSAGE_ACK_DATA = "ack";
  1728. const MESSAGE_CLOSE = "close";
  1729. const CODEC_DEFLATE = "deflate";
  1730. const CODEC_INFLATE = "inflate";
  1731. class CodecStream extends TransformStream {
  1732. constructor(options, config) {
  1733. super({});
  1734. const codec = this;
  1735. const { codecType } = options;
  1736. let Stream;
  1737. if (codecType.startsWith(CODEC_DEFLATE)) {
  1738. Stream = DeflateStream;
  1739. } else if (codecType.startsWith(CODEC_INFLATE)) {
  1740. Stream = InflateStream;
  1741. }
  1742. let size = 0;
  1743. const stream = new Stream(options, config);
  1744. const readable = super.readable;
  1745. const transformStream = new TransformStream({
  1746. transform(chunk, controller) {
  1747. if (chunk && chunk.length) {
  1748. size += chunk.length;
  1749. controller.enqueue(chunk);
  1750. }
  1751. },
  1752. flush() {
  1753. const { signature } = stream;
  1754. Object$1.assign(codec, {
  1755. signature,
  1756. size
  1757. });
  1758. }
  1759. });
  1760. Object$1.defineProperty(codec, "readable", {
  1761. get() {
  1762. return readable.pipeThrough(stream).pipeThrough(transformStream);
  1763. }
  1764. });
  1765. }
  1766. }
  1767. /*
  1768. Copyright (c) 2022 Gildas Lormeau. All rights reserved.
  1769. Redistribution and use in source and binary forms, with or without
  1770. modification, are permitted provided that the following conditions are met:
  1771. 1. Redistributions of source code must retain the above copyright notice,
  1772. this list of conditions and the following disclaimer.
  1773. 2. Redistributions in binary form must reproduce the above copyright
  1774. notice, this list of conditions and the following disclaimer in
  1775. the documentation and/or other materials provided with the distribution.
  1776. 3. The names of the authors may not be used to endorse or promote products
  1777. derived from this software without specific prior written permission.
  1778. THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  1779. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  1780. FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
  1781. INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
  1782. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  1783. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  1784. OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  1785. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  1786. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  1787. EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1788. */
  1789. // deno-lint-ignore valid-typeof
  1790. const WEB_WORKERS_SUPPORTED = typeof Worker != UNDEFINED_TYPE$1;
  1791. class CodecWorker {
  1792. constructor(workerData, { readable, writable }, { options, config, streamOptions, useWebWorkers, transferStreams, scripts }, onTaskFinished) {
  1793. const { signal } = streamOptions;
  1794. Object$1.assign(workerData, {
  1795. busy: true,
  1796. readable: readable.pipeThrough(new ProgressWatcherStream(readable, streamOptions, config), { signal }),
  1797. writable,
  1798. options: Object$1.assign({}, options),
  1799. scripts,
  1800. transferStreams,
  1801. terminate() {
  1802. const { worker, busy } = workerData;
  1803. if (worker && !busy) {
  1804. worker.terminate();
  1805. workerData.interface = null;
  1806. }
  1807. },
  1808. onTaskFinished() {
  1809. workerData.busy = false;
  1810. onTaskFinished(workerData);
  1811. }
  1812. });
  1813. return (useWebWorkers && WEB_WORKERS_SUPPORTED ? createWebWorkerInterface : createWorkerInterface)(workerData, config);
  1814. }
  1815. }
  1816. class ProgressWatcherStream extends TransformStream {
  1817. constructor(readableSource, { onstart, onprogress, size, onend }, { chunkSize }) {
  1818. let chunkOffset = 0;
  1819. super({
  1820. start() {
  1821. if (onstart) {
  1822. callHandler(onstart, size);
  1823. }
  1824. },
  1825. async transform(chunk, controller) {
  1826. chunkOffset += chunk.length;
  1827. if (onprogress) {
  1828. await callHandler(onprogress, chunkOffset, size);
  1829. }
  1830. controller.enqueue(chunk);
  1831. },
  1832. flush() {
  1833. readableSource.size = chunkOffset;
  1834. if (onend) {
  1835. callHandler(onend, chunkOffset);
  1836. }
  1837. }
  1838. }, { highWaterMark: 1, size: () => chunkSize });
  1839. }
  1840. }
  1841. async function callHandler(handler, ...parameters) {
  1842. try {
  1843. await handler(...parameters);
  1844. } catch (_error) {
  1845. // ignored
  1846. }
  1847. }
  1848. function createWorkerInterface(workerData, config) {
  1849. return {
  1850. run: () => runWorker$1(workerData, config)
  1851. };
  1852. }
  1853. function createWebWorkerInterface(workerData, { baseURL, chunkSize }) {
  1854. if (!workerData.interface) {
  1855. Object$1.assign(workerData, {
  1856. worker: getWebWorker(workerData.scripts[0], baseURL, workerData),
  1857. interface: {
  1858. run: () => runWebWorker(workerData, { chunkSize })
  1859. }
  1860. });
  1861. }
  1862. return workerData.interface;
  1863. }
  1864. async function runWorker$1({ options, readable, writable, onTaskFinished }, config) {
  1865. const codecStream = new CodecStream(options, config);
  1866. try {
  1867. await readable.pipeThrough(codecStream).pipeTo(writable, { preventClose: true, preventAbort: true });
  1868. const {
  1869. signature,
  1870. size
  1871. } = codecStream;
  1872. return {
  1873. signature,
  1874. size
  1875. };
  1876. } finally {
  1877. onTaskFinished();
  1878. }
  1879. }
  1880. async function runWebWorker(workerData, config) {
  1881. let resolveResult, rejectResult;
  1882. const result = new Promise$1((resolve, reject) => {
  1883. resolveResult = resolve;
  1884. rejectResult = reject;
  1885. });
  1886. Object$1.assign(workerData, {
  1887. reader: null,
  1888. writer: null,
  1889. resolveResult,
  1890. rejectResult,
  1891. result
  1892. });
  1893. const { readable, options, scripts } = workerData;
  1894. const { writable, closed } = watchClosedStream(workerData.writable);
  1895. const streamsTransferred = sendMessage$1({
  1896. type: MESSAGE_START,
  1897. scripts: scripts.slice(1),
  1898. options,
  1899. config,
  1900. readable,
  1901. writable
  1902. }, workerData);
  1903. if (!streamsTransferred) {
  1904. Object$1.assign(workerData, {
  1905. reader: readable.getReader(),
  1906. writer: writable.getWriter()
  1907. });
  1908. }
  1909. const resultValue = await result;
  1910. try {
  1911. await writable.getWriter().close();
  1912. } catch (_error) {
  1913. // ignored
  1914. }
  1915. await closed;
  1916. return resultValue;
  1917. }
  1918. function watchClosedStream(writableSource) {
  1919. const writer = writableSource.getWriter();
  1920. let resolveStreamClosed;
  1921. const closed = new Promise$1(resolve => resolveStreamClosed = resolve);
  1922. const writable = new WritableStream({
  1923. async write(chunk) {
  1924. await writer.ready;
  1925. await writer.write(chunk);
  1926. },
  1927. close() {
  1928. writer.releaseLock();
  1929. resolveStreamClosed();
  1930. },
  1931. abort(reason) {
  1932. return writer.abort(reason);
  1933. }
  1934. });
  1935. return { writable, closed };
  1936. }
  1937. let classicWorkersSupported = true;
  1938. let transferStreamsSupported = true;
  1939. function getWebWorker(url, baseURL, workerData) {
  1940. const workerOptions = { type: "module" };
  1941. let scriptUrl, worker;
  1942. // deno-lint-ignore valid-typeof
  1943. if (typeof url == FUNCTION_TYPE$1) {
  1944. url = url();
  1945. }
  1946. try {
  1947. scriptUrl = new URL$2(url, baseURL);
  1948. } catch (_error) {
  1949. scriptUrl = url;
  1950. }
  1951. if (classicWorkersSupported) {
  1952. try {
  1953. worker = new Worker(scriptUrl);
  1954. } catch (_error) {
  1955. classicWorkersSupported = false;
  1956. worker = new Worker(scriptUrl, workerOptions);
  1957. }
  1958. } else {
  1959. worker = new Worker(scriptUrl, workerOptions);
  1960. }
  1961. worker.addEventListener(MESSAGE_EVENT_TYPE, event => onMessage(event, workerData));
  1962. return worker;
  1963. }
  1964. function sendMessage$1(message, { worker, writer, onTaskFinished, transferStreams }) {
  1965. try {
  1966. let { value, readable, writable } = message;
  1967. const transferables = [];
  1968. if (value) {
  1969. message.value = value.buffer;
  1970. transferables.push(message.value);
  1971. }
  1972. if (transferStreams && transferStreamsSupported) {
  1973. if (readable) {
  1974. transferables.push(readable);
  1975. }
  1976. if (writable) {
  1977. transferables.push(writable);
  1978. }
  1979. } else {
  1980. message.readable = message.writable = null;
  1981. }
  1982. if (transferables.length) {
  1983. try {
  1984. worker.postMessage(message, transferables);
  1985. return true;
  1986. } catch (_error) {
  1987. transferStreamsSupported = false;
  1988. message.readable = message.writable = null;
  1989. worker.postMessage(message);
  1990. }
  1991. } else {
  1992. worker.postMessage(message);
  1993. }
  1994. } catch (error) {
  1995. if (writer) {
  1996. writer.releaseLock();
  1997. }
  1998. onTaskFinished();
  1999. throw error;
  2000. }
  2001. }
  2002. async function onMessage({ data }, workerData) {
  2003. const { type, value, messageId, result, error } = data;
  2004. const { reader, writer, resolveResult, rejectResult, onTaskFinished } = workerData;
  2005. try {
  2006. if (error) {
  2007. const { message, stack, code, name } = error;
  2008. const responseError = new Error$1(message);
  2009. Object$1.assign(responseError, { stack, code, name });
  2010. close(responseError);
  2011. } else {
  2012. if (type == MESSAGE_PULL) {
  2013. const { value, done } = await reader.read();
  2014. sendMessage$1({ type: MESSAGE_DATA, value, done, messageId }, workerData);
  2015. }
  2016. if (type == MESSAGE_DATA) {
  2017. await writer.ready;
  2018. await writer.write(new Uint8Array$1(value));
  2019. sendMessage$1({ type: MESSAGE_ACK_DATA, messageId }, workerData);
  2020. }
  2021. if (type == MESSAGE_CLOSE) {
  2022. close(null, result);
  2023. }
  2024. }
  2025. } catch (error) {
  2026. close(error);
  2027. }
  2028. function close(error, result) {
  2029. if (error) {
  2030. rejectResult(error);
  2031. } else {
  2032. resolveResult(result);
  2033. }
  2034. if (writer) {
  2035. writer.releaseLock();
  2036. }
  2037. onTaskFinished();
  2038. }
  2039. }
  2040. /*
  2041. Copyright (c) 2022 Gildas Lormeau. All rights reserved.
  2042. Redistribution and use in source and binary forms, with or without
  2043. modification, are permitted provided that the following conditions are met:
  2044. 1. Redistributions of source code must retain the above copyright notice,
  2045. this list of conditions and the following disclaimer.
  2046. 2. Redistributions in binary form must reproduce the above copyright
  2047. notice, this list of conditions and the following disclaimer in
  2048. the documentation and/or other materials provided with the distribution.
  2049. 3. The names of the authors may not be used to endorse or promote products
  2050. derived from this software without specific prior written permission.
  2051. THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  2052. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  2053. FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
  2054. INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
  2055. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  2056. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  2057. OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  2058. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  2059. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  2060. EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  2061. */
  2062. let pool = [];
  2063. const pendingRequests = [];
  2064. let indexWorker = 0;
  2065. async function runWorker(stream, workerOptions) {
  2066. const { options, config } = workerOptions;
  2067. const { transferStreams, useWebWorkers, useCompressionStream, codecType, compressed, signed, encrypted } = options;
  2068. const { workerScripts, maxWorkers, terminateWorkerTimeout } = config;
  2069. workerOptions.transferStreams = transferStreams || transferStreams === UNDEFINED_VALUE;
  2070. const streamCopy = !compressed && !signed && !encrypted && !workerOptions.transferStreams;
  2071. workerOptions.useWebWorkers = !streamCopy && (useWebWorkers || (useWebWorkers === UNDEFINED_VALUE && config.useWebWorkers));
  2072. workerOptions.scripts = workerOptions.useWebWorkers && workerScripts ? workerScripts[codecType] : [];
  2073. options.useCompressionStream = useCompressionStream || (useCompressionStream === UNDEFINED_VALUE && config.useCompressionStream);
  2074. let worker;
  2075. const workerData = pool.find(workerData => !workerData.busy);
  2076. if (workerData) {
  2077. clearTerminateTimeout(workerData);
  2078. worker = new CodecWorker(workerData, stream, workerOptions, onTaskFinished);
  2079. } else if (pool.length < maxWorkers) {
  2080. const workerData = { indexWorker };
  2081. indexWorker++;
  2082. pool.push(workerData);
  2083. worker = new CodecWorker(workerData, stream, workerOptions, onTaskFinished);
  2084. } else {
  2085. worker = await new Promise$1(resolve => pendingRequests.push({ resolve, stream, workerOptions }));
  2086. }
  2087. return worker.run();
  2088. function onTaskFinished(workerData) {
  2089. if (pendingRequests.length) {
  2090. const [{ resolve, stream, workerOptions }] = pendingRequests.splice(0, 1);
  2091. resolve(new CodecWorker(workerData, stream, workerOptions, onTaskFinished));
  2092. } else if (workerData.worker) {
  2093. clearTerminateTimeout(workerData);
  2094. if (Number$1.isFinite(terminateWorkerTimeout) && terminateWorkerTimeout >= 0) {
  2095. workerData.terminateTimeout = setTimeout(() => {
  2096. pool = pool.filter(data => data != workerData);
  2097. workerData.terminate();
  2098. }, terminateWorkerTimeout);
  2099. }
  2100. } else {
  2101. pool = pool.filter(data => data != workerData);
  2102. }
  2103. }
  2104. }
  2105. function clearTerminateTimeout(workerData) {
  2106. const { terminateTimeout } = workerData;
  2107. if (terminateTimeout) {
  2108. clearTimeout(terminateTimeout);
  2109. workerData.terminateTimeout = null;
  2110. }
  2111. }
  2112. function terminateWorkers() {
  2113. pool.forEach(workerData => {
  2114. clearTerminateTimeout(workerData);
  2115. workerData.terminate();
  2116. });
  2117. }
  2118. /*
  2119. Copyright (c) 2022 Gildas Lormeau. All rights reserved.
  2120. Redistribution and use in source and binary forms, with or without
  2121. modification, are permitted provided that the following conditions are met:
  2122. 1. Redistributions of source code must retain the above copyright notice,
  2123. this list of conditions and the following disclaimer.
  2124. 2. Redistributions in binary form must reproduce the above copyright
  2125. notice, this list of conditions and the following disclaimer in
  2126. the documentation and/or other materials provided with the distribution.
  2127. 3. The names of the authors may not be used to endorse or promote products
  2128. derived from this software without specific prior written permission.
  2129. THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  2130. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  2131. FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
  2132. INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
  2133. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  2134. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  2135. OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  2136. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  2137. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  2138. EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  2139. */
  2140. const ERR_HTTP_STATUS = "HTTP error ";
  2141. const ERR_HTTP_RANGE = "HTTP Range not supported";
  2142. const ERR_ITERATOR_COMPLETED_TOO_SOON = "Writer iterator completed too soon";
  2143. const CONTENT_TYPE_TEXT_PLAIN = "text/plain";
  2144. const HTTP_HEADER_CONTENT_LENGTH = "Content-Length";
  2145. const HTTP_HEADER_CONTENT_RANGE = "Content-Range";
  2146. const HTTP_HEADER_ACCEPT_RANGES = "Accept-Ranges";
  2147. const HTTP_HEADER_RANGE = "Range";
  2148. const HTTP_HEADER_CONTENT_TYPE = "Content-Type";
  2149. const HTTP_METHOD_HEAD = "HEAD";
  2150. const HTTP_METHOD_GET = "GET";
  2151. const HTTP_RANGE_UNIT = "bytes";
  2152. const DEFAULT_CHUNK_SIZE = 64 * 1024;
  2153. const PROPERTY_NAME_WRITABLE = "writable";
  2154. class Stream {
  2155. constructor() {
  2156. this.size = 0;
  2157. }
  2158. init() {
  2159. this.initialized = true;
  2160. }
  2161. }
  2162. class Reader extends Stream {
  2163. get readable() {
  2164. const reader = this;
  2165. const { chunkSize = DEFAULT_CHUNK_SIZE } = reader;
  2166. const readable = new ReadableStream({
  2167. start() {
  2168. this.chunkOffset = 0;
  2169. },
  2170. async pull(controller) {
  2171. const { offset = 0, size, diskNumberStart } = readable;
  2172. const { chunkOffset } = this;
  2173. controller.enqueue(await readUint8Array(reader, offset + chunkOffset, Math$1.min(chunkSize, size - chunkOffset), diskNumberStart));
  2174. if (chunkOffset + chunkSize > size) {
  2175. controller.close();
  2176. } else {
  2177. this.chunkOffset += chunkSize;
  2178. }
  2179. }
  2180. });
  2181. return readable;
  2182. }
  2183. }
  2184. class Writer extends Stream {
  2185. constructor() {
  2186. super();
  2187. const writer = this;
  2188. const writable = new WritableStream({
  2189. write(chunk) {
  2190. return writer.writeUint8Array(chunk);
  2191. }
  2192. });
  2193. Object$1.defineProperty(writer, PROPERTY_NAME_WRITABLE, {
  2194. get() {
  2195. return writable;
  2196. }
  2197. });
  2198. }
  2199. writeUint8Array() {
  2200. // abstract
  2201. }
  2202. }
  2203. class Data64URIReader extends Reader {
  2204. constructor(dataURI) {
  2205. super();
  2206. let dataEnd = dataURI.length;
  2207. while (dataURI.charAt(dataEnd - 1) == "=") {
  2208. dataEnd--;
  2209. }
  2210. const dataStart = dataURI.indexOf(",") + 1;
  2211. Object$1.assign(this, {
  2212. dataURI,
  2213. dataStart,
  2214. size: Math$1.floor((dataEnd - dataStart) * 0.75)
  2215. });
  2216. }
  2217. readUint8Array(offset, length) {
  2218. const {
  2219. dataStart,
  2220. dataURI
  2221. } = this;
  2222. const dataArray = new Uint8Array$1(length);
  2223. const start = Math$1.floor(offset / 3) * 4;
  2224. const bytes = atob(dataURI.substring(start + dataStart, Math$1.ceil((offset + length) / 3) * 4 + dataStart));
  2225. const delta = offset - Math$1.floor(start / 4) * 3;
  2226. for (let indexByte = delta; indexByte < delta + length; indexByte++) {
  2227. dataArray[indexByte - delta] = bytes.charCodeAt(indexByte);
  2228. }
  2229. return dataArray;
  2230. }
  2231. }
  2232. class Data64URIWriter extends Writer {
  2233. constructor(contentType) {
  2234. super();
  2235. Object$1.assign(this, {
  2236. data: "data:" + (contentType || "") + ";base64,",
  2237. pending: []
  2238. });
  2239. }
  2240. writeUint8Array(array) {
  2241. const writer = this;
  2242. let indexArray = 0;
  2243. let dataString = writer.pending;
  2244. const delta = writer.pending.length;
  2245. writer.pending = "";
  2246. for (indexArray = 0; indexArray < (Math$1.floor((delta + array.length) / 3) * 3) - delta; indexArray++) {
  2247. dataString += String$1.fromCharCode(array[indexArray]);
  2248. }
  2249. for (; indexArray < array.length; indexArray++) {
  2250. writer.pending += String$1.fromCharCode(array[indexArray]);
  2251. }
  2252. if (dataString.length > 2) {
  2253. writer.data += btoa(dataString);
  2254. } else {
  2255. writer.pending = dataString;
  2256. }
  2257. }
  2258. getData() {
  2259. return this.data + btoa(this.pending);
  2260. }
  2261. }
  2262. class BlobReader extends Reader {
  2263. constructor(blob) {
  2264. super();
  2265. Object$1.assign(this, {
  2266. blob,
  2267. size: blob.size
  2268. });
  2269. }
  2270. async readUint8Array(offset, length) {
  2271. const reader = this;
  2272. const offsetEnd = offset + length;
  2273. const blob = offset || offsetEnd < reader.size ? reader.blob.slice(offset, offsetEnd) : reader.blob;
  2274. let arrayBuffer = await blob.arrayBuffer();
  2275. if (arrayBuffer.byteLength > length) {
  2276. arrayBuffer = arrayBuffer.slice(offset, offsetEnd);
  2277. }
  2278. return new Uint8Array$1(arrayBuffer);
  2279. }
  2280. }
  2281. class BlobWriter extends Stream {
  2282. constructor(contentType) {
  2283. super();
  2284. const writer = this;
  2285. const transformStream = new TransformStream();
  2286. const headers = [];
  2287. if (contentType) {
  2288. headers.push([HTTP_HEADER_CONTENT_TYPE, contentType]);
  2289. }
  2290. Object$1.defineProperty(writer, PROPERTY_NAME_WRITABLE, {
  2291. get() {
  2292. return transformStream.writable;
  2293. }
  2294. });
  2295. writer.blob = new Response(transformStream.readable, { headers }).blob();
  2296. }
  2297. getData() {
  2298. return this.blob;
  2299. }
  2300. }
  2301. class TextReader extends BlobReader {
  2302. constructor(text) {
  2303. super(new Blob$3([text], { type: CONTENT_TYPE_TEXT_PLAIN }));
  2304. }
  2305. }
  2306. class TextWriter extends BlobWriter {
  2307. constructor(encoding) {
  2308. super(encoding);
  2309. Object$1.assign(this, {
  2310. encoding,
  2311. utf8: !encoding || encoding.toLowerCase() == "utf-8"
  2312. });
  2313. }
  2314. async getData() {
  2315. const {
  2316. encoding,
  2317. utf8
  2318. } = this;
  2319. const blob = await super.getData();
  2320. if (blob.text && utf8) {
  2321. return blob.text();
  2322. } else {
  2323. const reader = new FileReader();
  2324. return new Promise$1((resolve, reject) => {
  2325. Object$1.assign(reader, {
  2326. onload: ({ target }) => resolve(target.result),
  2327. onerror: () => reject(reader.error)
  2328. });
  2329. reader.readAsText(blob, encoding);
  2330. });
  2331. }
  2332. }
  2333. }
  2334. class FetchReader extends Reader {
  2335. constructor(url, options) {
  2336. super();
  2337. createHtpReader(this, url, options);
  2338. }
  2339. async init() {
  2340. await initHttpReader(this, sendFetchRequest, getFetchRequestData);
  2341. super.init();
  2342. }
  2343. readUint8Array(index, length) {
  2344. return readUint8ArrayHttpReader(this, index, length, sendFetchRequest, getFetchRequestData);
  2345. }
  2346. }
  2347. class XHRReader extends Reader {
  2348. constructor(url, options) {
  2349. super();
  2350. createHtpReader(this, url, options);
  2351. }
  2352. async init() {
  2353. await initHttpReader(this, sendXMLHttpRequest, getXMLHttpRequestData);
  2354. super.init();
  2355. }
  2356. readUint8Array(index, length) {
  2357. return readUint8ArrayHttpReader(this, index, length, sendXMLHttpRequest, getXMLHttpRequestData);
  2358. }
  2359. }
  2360. function createHtpReader(httpReader, url, options) {
  2361. const {
  2362. preventHeadRequest,
  2363. useRangeHeader,
  2364. forceRangeRequests
  2365. } = options;
  2366. options = Object$1.assign({}, options);
  2367. delete options.preventHeadRequest;
  2368. delete options.useRangeHeader;
  2369. delete options.forceRangeRequests;
  2370. delete options.useXHR;
  2371. Object$1.assign(httpReader, {
  2372. url,
  2373. options,
  2374. preventHeadRequest,
  2375. useRangeHeader,
  2376. forceRangeRequests
  2377. });
  2378. }
  2379. async function initHttpReader(httpReader, sendRequest, getRequestData) {
  2380. const {
  2381. url,
  2382. useRangeHeader,
  2383. forceRangeRequests
  2384. } = httpReader;
  2385. if (isHttpFamily(url) && (useRangeHeader || forceRangeRequests)) {
  2386. const { headers } = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader));
  2387. if (!forceRangeRequests && headers.get(HTTP_HEADER_ACCEPT_RANGES) != HTTP_RANGE_UNIT) {
  2388. throw new Error$1(ERR_HTTP_RANGE);
  2389. } else {
  2390. let contentSize;
  2391. const contentRangeHeader = headers.get(HTTP_HEADER_CONTENT_RANGE);
  2392. if (contentRangeHeader) {
  2393. const splitHeader = contentRangeHeader.trim().split(/\s*\/\s*/);
  2394. if (splitHeader.length) {
  2395. const headerValue = splitHeader[1];
  2396. if (headerValue && headerValue != "*") {
  2397. contentSize = Number$1(headerValue);
  2398. }
  2399. }
  2400. }
  2401. if (contentSize === UNDEFINED_VALUE) {
  2402. await getContentLength(httpReader, sendRequest, getRequestData);
  2403. } else {
  2404. httpReader.size = contentSize;
  2405. }
  2406. }
  2407. } else {
  2408. await getContentLength(httpReader, sendRequest, getRequestData);
  2409. }
  2410. }
  2411. async function readUint8ArrayHttpReader(httpReader, index, length, sendRequest, getRequestData) {
  2412. const {
  2413. useRangeHeader,
  2414. forceRangeRequests,
  2415. options
  2416. } = httpReader;
  2417. if (useRangeHeader || forceRangeRequests) {
  2418. const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, index, length));
  2419. if (response.status != 206) {
  2420. throw new Error$1(ERR_HTTP_RANGE);
  2421. }
  2422. return new Uint8Array$1(await response.arrayBuffer());
  2423. } else {
  2424. const { data } = httpReader;
  2425. if (!data) {
  2426. await getRequestData(httpReader, options);
  2427. }
  2428. return new Uint8Array$1(httpReader.data.subarray(index, index + length));
  2429. }
  2430. }
  2431. function getRangeHeaders(httpReader, index = 0, length = 1) {
  2432. return Object$1.assign({}, getHeaders(httpReader), { [HTTP_HEADER_RANGE]: HTTP_RANGE_UNIT + "=" + index + "-" + (index + length - 1) });
  2433. }
  2434. function getHeaders({ options }) {
  2435. const { headers } = options;
  2436. if (headers) {
  2437. if (Symbol.iterator in headers) {
  2438. return Object$1.fromEntries(headers);
  2439. } else {
  2440. return headers;
  2441. }
  2442. }
  2443. }
  2444. async function getFetchRequestData(httpReader) {
  2445. await getRequestData(httpReader, sendFetchRequest);
  2446. }
  2447. async function getXMLHttpRequestData(httpReader) {
  2448. await getRequestData(httpReader, sendXMLHttpRequest);
  2449. }
  2450. async function getRequestData(httpReader, sendRequest) {
  2451. const response = await sendRequest(HTTP_METHOD_GET, httpReader, getHeaders(httpReader));
  2452. httpReader.data = new Uint8Array$1(await response.arrayBuffer());
  2453. if (!httpReader.size) {
  2454. httpReader.size = httpReader.data.length;
  2455. }
  2456. }
  2457. async function getContentLength(httpReader, sendRequest, getRequestData) {
  2458. if (httpReader.preventHeadRequest) {
  2459. await getRequestData(httpReader, httpReader.options);
  2460. } else {
  2461. const response = await sendRequest(HTTP_METHOD_HEAD, httpReader, getHeaders(httpReader));
  2462. const contentLength = response.headers.get(HTTP_HEADER_CONTENT_LENGTH);
  2463. if (contentLength) {
  2464. httpReader.size = Number$1(contentLength);
  2465. } else {
  2466. await getRequestData(httpReader, httpReader.options);
  2467. }
  2468. }
  2469. }
  2470. async function sendFetchRequest(method, { options, url }, headers) {
  2471. const response = await fetch(url, Object$1.assign({}, options, { method, headers }));
  2472. if (response.status < 400) {
  2473. return response;
  2474. } else {
  2475. throw response.status == 416 ? new Error$1(ERR_HTTP_RANGE) : new Error$1(ERR_HTTP_STATUS + (response.statusText || response.status));
  2476. }
  2477. }
  2478. function sendXMLHttpRequest(method, { url }, headers) {
  2479. return new Promise$1((resolve, reject) => {
  2480. const request = new XMLHttpRequest();
  2481. request.addEventListener("load", () => {
  2482. if (request.status < 400) {
  2483. const headers = [];
  2484. request.getAllResponseHeaders().trim().split(/[\r\n]+/).forEach(header => {
  2485. const splitHeader = header.trim().split(/\s*:\s*/);
  2486. splitHeader[0] = splitHeader[0].trim().replace(/^[a-z]|-[a-z]/g, value => value.toUpperCase());
  2487. headers.push(splitHeader);
  2488. });
  2489. resolve({
  2490. status: request.status,
  2491. arrayBuffer: () => request.response,
  2492. headers: new Map$2(headers)
  2493. });
  2494. } else {
  2495. reject(request.status == 416 ? new Error$1(ERR_HTTP_RANGE) : new Error$1(ERR_HTTP_STATUS + (request.statusText || request.status)));
  2496. }
  2497. }, false);
  2498. request.addEventListener("error", event => reject(event.detail ? event.detail.error : new Error$1("Network error")), false);
  2499. request.open(method, url);
  2500. if (headers) {
  2501. for (const entry of Object$1.entries(headers)) {
  2502. request.setRequestHeader(entry[0], entry[1]);
  2503. }
  2504. }
  2505. request.responseType = "arraybuffer";
  2506. request.send();
  2507. });
  2508. }
  2509. class HttpReader extends Reader {
  2510. constructor(url, options = {}) {
  2511. super();
  2512. Object$1.assign(this, {
  2513. url,
  2514. reader: options.useXHR ? new XHRReader(url, options) : new FetchReader(url, options)
  2515. });
  2516. }
  2517. set size(value) {
  2518. // ignored
  2519. }
  2520. get size() {
  2521. return this.reader.size;
  2522. }
  2523. async init() {
  2524. await this.reader.init();
  2525. super.init();
  2526. }
  2527. readUint8Array(index, length) {
  2528. return this.reader.readUint8Array(index, length);
  2529. }
  2530. }
  2531. class HttpRangeReader extends HttpReader {
  2532. constructor(url, options = {}) {
  2533. options.useRangeHeader = true;
  2534. super(url, options);
  2535. }
  2536. }
  2537. class Uint8ArrayReader extends Reader {
  2538. constructor(array) {
  2539. super();
  2540. Object$1.assign(this, {
  2541. array,
  2542. size: array.length
  2543. });
  2544. }
  2545. readUint8Array(index, length) {
  2546. return this.array.slice(index, index + length);
  2547. }
  2548. }
  2549. class Uint8ArrayWriter extends Writer {
  2550. init(initSize = 0) {
  2551. Object$1.assign(this, {
  2552. offset: 0,
  2553. array: new Uint8Array$1(initSize)
  2554. });
  2555. super.init();
  2556. }
  2557. writeUint8Array(array) {
  2558. const writer = this;
  2559. if (writer.offset + array.length > writer.array.length) {
  2560. const previousArray = writer.array;
  2561. writer.array = new Uint8Array$1(previousArray.length + array.length);
  2562. writer.array.set(previousArray);
  2563. }
  2564. writer.array.set(array, writer.offset);
  2565. writer.offset += array.length;
  2566. }
  2567. getData() {
  2568. return this.array;
  2569. }
  2570. }
  2571. class SplitDataReader extends Reader {
  2572. constructor(readers) {
  2573. super();
  2574. this.readers = readers;
  2575. }
  2576. async init() {
  2577. const reader = this;
  2578. const { readers } = reader;
  2579. reader.lastDiskNumber = 0;
  2580. reader.lastDiskOffset = 0;
  2581. await Promise$1.all(readers.map(async (diskReader, indexDiskReader) => {
  2582. await diskReader.init();
  2583. if (indexDiskReader != readers.length - 1) {
  2584. reader.lastDiskOffset += diskReader.size;
  2585. }
  2586. reader.size += diskReader.size;
  2587. }));
  2588. super.init();
  2589. }
  2590. async readUint8Array(offset, length, diskNumber = 0) {
  2591. const reader = this;
  2592. const { readers } = this;
  2593. let result;
  2594. let currentDiskNumber = diskNumber;
  2595. if (currentDiskNumber == -1) {
  2596. currentDiskNumber = readers.length - 1;
  2597. }
  2598. let currentReaderOffset = offset;
  2599. while (currentReaderOffset >= readers[currentDiskNumber].size) {
  2600. currentReaderOffset -= readers[currentDiskNumber].size;
  2601. currentDiskNumber++;
  2602. }
  2603. const currentReader = readers[currentDiskNumber];
  2604. const currentReaderSize = currentReader.size;
  2605. if (currentReaderOffset + length <= currentReaderSize) {
  2606. result = await readUint8Array(currentReader, currentReaderOffset, length);
  2607. } else {
  2608. const chunkLength = currentReaderSize - currentReaderOffset;
  2609. result = new Uint8Array$1(length);
  2610. result.set(await readUint8Array(currentReader, currentReaderOffset, chunkLength));
  2611. result.set(await reader.readUint8Array(offset + chunkLength, length - chunkLength, diskNumber), chunkLength);
  2612. }
  2613. reader.lastDiskNumber = Math$1.max(currentDiskNumber, reader.lastDiskNumber);
  2614. return result;
  2615. }
  2616. }
  2617. class SplitDataWriter extends Stream {
  2618. constructor(writerGenerator, maxSize = 4294967295) {
  2619. super();
  2620. const zipWriter = this;
  2621. Object$1.assign(zipWriter, {
  2622. diskNumber: 0,
  2623. diskOffset: 0,
  2624. size: 0,
  2625. maxSize,
  2626. availableSize: maxSize
  2627. });
  2628. let diskSourceWriter, diskWritable, diskWriter;
  2629. const writable = new WritableStream({
  2630. async write(chunk) {
  2631. const { availableSize } = zipWriter;
  2632. if (!diskWriter) {
  2633. const { value, done } = await writerGenerator.next();
  2634. if (done && !value) {
  2635. throw new Error$1(ERR_ITERATOR_COMPLETED_TOO_SOON);
  2636. } else {
  2637. diskSourceWriter = value;
  2638. diskSourceWriter.size = 0;
  2639. if (diskSourceWriter.maxSize) {
  2640. zipWriter.maxSize = diskSourceWriter.maxSize;
  2641. }
  2642. zipWriter.availableSize = zipWriter.maxSize;
  2643. await initStream(diskSourceWriter);
  2644. diskWritable = value.writable;
  2645. diskWriter = diskWritable.getWriter();
  2646. }
  2647. await this.write(chunk);
  2648. } else if (chunk.length >= availableSize) {
  2649. await writeChunk(chunk.slice(0, availableSize));
  2650. await closeDisk();
  2651. zipWriter.diskOffset += diskSourceWriter.size;
  2652. zipWriter.diskNumber++;
  2653. diskWriter = null;
  2654. await this.write(chunk.slice(availableSize));
  2655. } else {
  2656. await writeChunk(chunk);
  2657. }
  2658. },
  2659. async close() {
  2660. await diskWriter.ready;
  2661. await closeDisk();
  2662. }
  2663. });
  2664. Object$1.defineProperty(zipWriter, PROPERTY_NAME_WRITABLE, {
  2665. get() {
  2666. return writable;
  2667. }
  2668. });
  2669. async function writeChunk(chunk) {
  2670. const chunkLength = chunk.length;
  2671. if (chunkLength) {
  2672. await diskWriter.ready;
  2673. await diskWriter.write(chunk);
  2674. diskSourceWriter.size += chunkLength;
  2675. zipWriter.size += chunkLength;
  2676. zipWriter.availableSize -= chunkLength;
  2677. }
  2678. }
  2679. async function closeDisk() {
  2680. diskWritable.size = diskSourceWriter.size;
  2681. await diskWriter.close();
  2682. }
  2683. }
  2684. }
  2685. function isHttpFamily(url) {
  2686. const { baseURL } = getConfiguration();
  2687. const { protocol } = new URL$2(url, baseURL);
  2688. return protocol == "http:" || protocol == "https:";
  2689. }
  2690. async function initStream(stream, initSize) {
  2691. if (stream.init && !stream.initialized) {
  2692. await stream.init(initSize);
  2693. }
  2694. }
  2695. function initReader(reader) {
  2696. if (Array$1.isArray(reader)) {
  2697. reader = new SplitDataReader(reader);
  2698. }
  2699. if (reader instanceof ReadableStream) {
  2700. reader = {
  2701. readable: reader
  2702. };
  2703. }
  2704. return reader;
  2705. }
  2706. function initWriter(writer) {
  2707. if (writer.writable === UNDEFINED_VALUE && typeof writer.next == FUNCTION_TYPE$1) {
  2708. writer = new SplitDataWriter(writer);
  2709. }
  2710. if (writer instanceof WritableStream) {
  2711. writer = {
  2712. writable: writer
  2713. };
  2714. }
  2715. const { writable } = writer;
  2716. if (writable.size === UNDEFINED_VALUE) {
  2717. writable.size = 0;
  2718. }
  2719. const splitZipFile = writer instanceof SplitDataWriter;
  2720. if (!splitZipFile) {
  2721. Object$1.assign(writer, {
  2722. diskNumber: 0,
  2723. diskOffset: 0,
  2724. availableSize: Infinity,
  2725. maxSize: Infinity
  2726. });
  2727. }
  2728. return writer;
  2729. }
  2730. function readUint8Array(reader, offset, size, diskNumber) {
  2731. return reader.readUint8Array(offset, size, diskNumber);
  2732. }
  2733. const SplitZipReader = SplitDataReader;
  2734. const SplitZipWriter = SplitDataWriter;
  2735. /*
  2736. Copyright (c) 2022 Gildas Lormeau. All rights reserved.
  2737. Redistribution and use in source and binary forms, with or without
  2738. modification, are permitted provided that the following conditions are met:
  2739. 1. Redistributions of source code must retain the above copyright notice,
  2740. this list of conditions and the following disclaimer.
  2741. 2. Redistributions in binary form must reproduce the above copyright
  2742. notice, this list of conditions and the following disclaimer in
  2743. the documentation and/or other materials provided with the distribution.
  2744. 3. The names of the authors may not be used to endorse or promote products
  2745. derived from this software without specific prior written permission.
  2746. THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  2747. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  2748. FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
  2749. INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
  2750. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  2751. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  2752. OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  2753. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  2754. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  2755. EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  2756. */
  2757. /* global TextDecoder */
  2758. const CP437 = "\0☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ".split("");
  2759. const VALID_CP437 = CP437.length == 256;
  2760. function decodeCP437(stringValue) {
  2761. if (VALID_CP437) {
  2762. let result = "";
  2763. for (let indexCharacter = 0; indexCharacter < stringValue.length; indexCharacter++) {
  2764. result += CP437[stringValue[indexCharacter]];
  2765. }
  2766. return result;
  2767. } else {
  2768. return new TextDecoder$2().decode(stringValue);
  2769. }
  2770. }
  2771. /*
  2772. Copyright (c) 2022 Gildas Lormeau. All rights reserved.
  2773. Redistribution and use in source and binary forms, with or without
  2774. modification, are permitted provided that the following conditions are met:
  2775. 1. Redistributions of source code must retain the above copyright notice,
  2776. this list of conditions and the following disclaimer.
  2777. 2. Redistributions in binary form must reproduce the above copyright
  2778. notice, this list of conditions and the following disclaimer in
  2779. the documentation and/or other materials provided with the distribution.
  2780. 3. The names of the authors may not be used to endorse or promote products
  2781. derived from this software without specific prior written permission.
  2782. THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  2783. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  2784. FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
  2785. INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
  2786. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  2787. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  2788. OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  2789. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  2790. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  2791. EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  2792. */
  2793. function decodeText(value, encoding) {
  2794. if (encoding && encoding.trim().toLowerCase() == "cp437") {
  2795. return decodeCP437(value);
  2796. } else {
  2797. return new TextDecoder$2(encoding).decode(value);
  2798. }
  2799. }
  2800. /*
  2801. Copyright (c) 2022 Gildas Lormeau. All rights reserved.
  2802. Redistribution and use in source and binary forms, with or without
  2803. modification, are permitted provided that the following conditions are met:
  2804. 1. Redistributions of source code must retain the above copyright notice,
  2805. this list of conditions and the following disclaimer.
  2806. 2. Redistributions in binary form must reproduce the above copyright
  2807. notice, this list of conditions and the following disclaimer in
  2808. the documentation and/or other materials provided with the distribution.
  2809. 3. The names of the authors may not be used to endorse or promote products
  2810. derived from this software without specific prior written permission.
  2811. THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  2812. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  2813. FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
  2814. INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
  2815. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  2816. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  2817. OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  2818. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  2819. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  2820. EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  2821. */
  2822. const PROPERTY_NAME_FILENAME = "filename";
  2823. const PROPERTY_NAME_RAW_FILENAME = "rawFilename";
  2824. const PROPERTY_NAME_COMMENT = "comment";
  2825. const PROPERTY_NAME_RAW_COMMENT = "rawComment";
  2826. const PROPERTY_NAME_UNCOMPPRESSED_SIZE = "uncompressedSize";
  2827. const PROPERTY_NAME_COMPPRESSED_SIZE = "compressedSize";
  2828. const PROPERTY_NAME_OFFSET = "offset";
  2829. const PROPERTY_NAME_DISK_NUMBER_START = "diskNumberStart";
  2830. const PROPERTY_NAME_LAST_MODIFICATION_DATE = "lastModDate";
  2831. const PROPERTY_NAME_RAW_LAST_MODIFICATION_DATE = "rawLastModDate";
  2832. const PROPERTY_NAME_LAST_ACCESS_DATE = "lastAccessDate";
  2833. const PROPERTY_NAME_RAW_LAST_ACCESS_DATE = "rawLastAccessDate";
  2834. const PROPERTY_NAME_CREATION_DATE = "creationDate";
  2835. const PROPERTY_NAME_RAW_CREATION_DATE = "rawCreationDate";
  2836. const PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTE = "internalFileAttribute";
  2837. const PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTE = "externalFileAttribute";
  2838. const PROPERTY_NAME_MS_DOS_COMPATIBLE = "msDosCompatible";
  2839. const PROPERTY_NAME_ZIP64 = "zip64";
  2840. const PROPERTY_NAMES = [
  2841. PROPERTY_NAME_FILENAME, PROPERTY_NAME_RAW_FILENAME, PROPERTY_NAME_COMPPRESSED_SIZE, PROPERTY_NAME_UNCOMPPRESSED_SIZE,
  2842. PROPERTY_NAME_LAST_MODIFICATION_DATE, PROPERTY_NAME_RAW_LAST_MODIFICATION_DATE, PROPERTY_NAME_COMMENT, PROPERTY_NAME_RAW_COMMENT,
  2843. PROPERTY_NAME_LAST_ACCESS_DATE, PROPERTY_NAME_CREATION_DATE, PROPERTY_NAME_OFFSET, PROPERTY_NAME_DISK_NUMBER_START,
  2844. PROPERTY_NAME_DISK_NUMBER_START, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTE, PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTE,
  2845. PROPERTY_NAME_MS_DOS_COMPATIBLE, PROPERTY_NAME_ZIP64,
  2846. "directory", "bitFlag", "encrypted", "signature", "filenameUTF8", "commentUTF8", "compressionMethod", "version", "versionMadeBy",
  2847. "extraField", "rawExtraField", "extraFieldZip64", "extraFieldUnicodePath", "extraFieldUnicodeComment", "extraFieldAES", "extraFieldNTFS",
  2848. "extraFieldExtendedTimestamp"];
  2849. class Entry {
  2850. constructor(data) {
  2851. PROPERTY_NAMES.forEach(name => this[name] = data[name]);
  2852. }
  2853. }
  2854. /*
  2855. Copyright (c) 2022 Gildas Lormeau. All rights reserved.
  2856. Redistribution and use in source and binary forms, with or without
  2857. modification, are permitted provided that the following conditions are met:
  2858. 1. Redistributions of source code must retain the above copyright notice,
  2859. this list of conditions and the following disclaimer.
  2860. 2. Redistributions in binary form must reproduce the above copyright
  2861. notice, this list of conditions and the following disclaimer in
  2862. the documentation and/or other materials provided with the distribution.
  2863. 3. The names of the authors may not be used to endorse or promote products
  2864. derived from this software without specific prior written permission.
  2865. THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  2866. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  2867. FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
  2868. INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
  2869. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  2870. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  2871. OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  2872. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  2873. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  2874. EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  2875. */
  2876. const ERR_BAD_FORMAT = "File format is not recognized";
  2877. const ERR_EOCDR_NOT_FOUND = "End of central directory not found";
  2878. const ERR_EOCDR_ZIP64_NOT_FOUND = "End of Zip64 central directory not found";
  2879. const ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND = "End of Zip64 central directory locator not found";
  2880. const ERR_CENTRAL_DIRECTORY_NOT_FOUND = "Central directory header not found";
  2881. const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
  2882. const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
  2883. const ERR_ENCRYPTED = "File contains encrypted entry";
  2884. const ERR_UNSUPPORTED_ENCRYPTION = "Encryption method not supported";
  2885. const ERR_UNSUPPORTED_COMPRESSION = "Compression method not supported";
  2886. const ERR_SPLIT_ZIP_FILE = "Split zip file";
  2887. const CHARSET_UTF8 = "utf-8";
  2888. const CHARSET_CP437 = "cp437";
  2889. const ZIP64_PROPERTIES = [
  2890. [PROPERTY_NAME_UNCOMPPRESSED_SIZE, MAX_32_BITS],
  2891. [PROPERTY_NAME_COMPPRESSED_SIZE, MAX_32_BITS],
  2892. [PROPERTY_NAME_OFFSET, MAX_32_BITS],
  2893. [PROPERTY_NAME_DISK_NUMBER_START, MAX_16_BITS]
  2894. ];
  2895. const ZIP64_EXTRACTION = {
  2896. [MAX_16_BITS]: {
  2897. getValue: getUint32,
  2898. bytes: 4
  2899. },
  2900. [MAX_32_BITS]: {
  2901. getValue: getBigUint64,
  2902. bytes: 8
  2903. }
  2904. };
  2905. class ZipReader {
  2906. constructor(reader, options = {}) {
  2907. Object$1.assign(this, {
  2908. reader: initReader(reader),
  2909. options,
  2910. config: getConfiguration()
  2911. });
  2912. }
  2913. async* getEntriesGenerator(options = {}) {
  2914. const zipReader = this;
  2915. let { reader } = zipReader;
  2916. const { config } = zipReader;
  2917. await initStream(reader);
  2918. if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
  2919. reader = new BlobReader(await new Response(reader.readable).blob());
  2920. await initStream(reader);
  2921. }
  2922. if (reader.size < END_OF_CENTRAL_DIR_LENGTH) {
  2923. throw new Error$1(ERR_BAD_FORMAT);
  2924. }
  2925. reader.chunkSize = getChunkSize(config);
  2926. const endOfDirectoryInfo = await seekSignature(reader, END_OF_CENTRAL_DIR_SIGNATURE, reader.size, END_OF_CENTRAL_DIR_LENGTH, MAX_16_BITS * 16);
  2927. if (!endOfDirectoryInfo) {
  2928. const signatureArray = await readUint8Array(reader, 0, 4);
  2929. const signatureView = getDataView$1(signatureArray);
  2930. if (getUint32(signatureView) == SPLIT_ZIP_FILE_SIGNATURE) {
  2931. throw new Error$1(ERR_SPLIT_ZIP_FILE);
  2932. } else {
  2933. throw new Error$1(ERR_EOCDR_NOT_FOUND);
  2934. }
  2935. }
  2936. const endOfDirectoryView = getDataView$1(endOfDirectoryInfo);
  2937. let directoryDataLength = getUint32(endOfDirectoryView, 12);
  2938. let directoryDataOffset = getUint32(endOfDirectoryView, 16);
  2939. const commentOffset = endOfDirectoryInfo.offset;
  2940. const commentLength = getUint16(endOfDirectoryView, 20);
  2941. const appendedDataOffset = commentOffset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
  2942. let lastDiskNumber = getUint16(endOfDirectoryView, 4);
  2943. const expectedLastDiskNumber = reader.lastDiskNumber || 0;
  2944. let diskNumber = getUint16(endOfDirectoryView, 6);
  2945. let filesLength = getUint16(endOfDirectoryView, 8);
  2946. let prependedDataLength = 0;
  2947. let startOffset = 0;
  2948. if (directoryDataOffset == MAX_32_BITS || directoryDataLength == MAX_32_BITS || filesLength == MAX_16_BITS || diskNumber == MAX_16_BITS) {
  2949. const endOfDirectoryLocatorArray = await readUint8Array(reader, endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH, ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH);
  2950. const endOfDirectoryLocatorView = getDataView$1(endOfDirectoryLocatorArray);
  2951. if (getUint32(endOfDirectoryLocatorView, 0) != ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE) {
  2952. throw new Error$1(ERR_EOCDR_ZIP64_NOT_FOUND);
  2953. }
  2954. directoryDataOffset = getBigUint64(endOfDirectoryLocatorView, 8);
  2955. let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH, -1);
  2956. let endOfDirectoryView = getDataView$1(endOfDirectoryArray);
  2957. const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
  2958. if (getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE && directoryDataOffset != expectedDirectoryDataOffset) {
  2959. const originalDirectoryDataOffset = directoryDataOffset;
  2960. directoryDataOffset = expectedDirectoryDataOffset;
  2961. prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
  2962. endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH, -1);
  2963. endOfDirectoryView = getDataView$1(endOfDirectoryArray);
  2964. }
  2965. if (getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
  2966. throw new Error$1(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
  2967. }
  2968. if (lastDiskNumber == MAX_16_BITS) {
  2969. lastDiskNumber = getUint32(endOfDirectoryView, 16);
  2970. }
  2971. if (diskNumber == MAX_16_BITS) {
  2972. diskNumber = getUint32(endOfDirectoryView, 20);
  2973. }
  2974. if (filesLength == MAX_16_BITS) {
  2975. filesLength = getBigUint64(endOfDirectoryView, 32);
  2976. }
  2977. if (directoryDataLength == MAX_32_BITS) {
  2978. directoryDataLength = getBigUint64(endOfDirectoryView, 40);
  2979. }
  2980. directoryDataOffset -= directoryDataLength;
  2981. }
  2982. if (expectedLastDiskNumber != lastDiskNumber) {
  2983. throw new Error$1(ERR_SPLIT_ZIP_FILE);
  2984. }
  2985. if (directoryDataOffset < 0 || directoryDataOffset >= reader.size) {
  2986. throw new Error$1(ERR_BAD_FORMAT);
  2987. }
  2988. let offset = 0;
  2989. let directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength, diskNumber);
  2990. let directoryView = getDataView$1(directoryArray);
  2991. if (directoryDataLength) {
  2992. const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - directoryDataLength;
  2993. if (getUint32(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE && directoryDataOffset != expectedDirectoryDataOffset) {
  2994. const originalDirectoryDataOffset = directoryDataOffset;
  2995. directoryDataOffset = expectedDirectoryDataOffset;
  2996. prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
  2997. directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength, diskNumber);
  2998. directoryView = getDataView$1(directoryArray);
  2999. }
  3000. }
  3001. const expectedDirectoryDataLength = endOfDirectoryInfo.offset - directoryDataOffset - (reader.lastDiskOffset || 0);
  3002. if (directoryDataLength != expectedDirectoryDataLength && expectedDirectoryDataLength >= 0) {
  3003. directoryDataLength = expectedDirectoryDataLength;
  3004. directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength, diskNumber);
  3005. directoryView = getDataView$1(directoryArray);
  3006. }
  3007. if (directoryDataOffset < 0 || directoryDataOffset >= reader.size) {
  3008. throw new Error$1(ERR_BAD_FORMAT);
  3009. }
  3010. const filenameEncoding = getOptionValue$1(zipReader, options, "filenameEncoding");
  3011. const commentEncoding = getOptionValue$1(zipReader, options, "commentEncoding");
  3012. for (let indexFile = 0; indexFile < filesLength; indexFile++) {
  3013. const fileEntry = new ZipEntry(reader, config, zipReader.options);
  3014. if (getUint32(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
  3015. throw new Error$1(ERR_CENTRAL_DIRECTORY_NOT_FOUND);
  3016. }
  3017. readCommonHeader(fileEntry, directoryView, offset + 6);
  3018. const languageEncodingFlag = Boolean(fileEntry.bitFlag.languageEncodingFlag);
  3019. const filenameOffset = offset + 46;
  3020. const extraFieldOffset = filenameOffset + fileEntry.filenameLength;
  3021. const commentOffset = extraFieldOffset + fileEntry.extraFieldLength;
  3022. const versionMadeBy = getUint16(directoryView, offset + 4);
  3023. const msDosCompatible = (versionMadeBy & 0) == 0;
  3024. const rawFilename = directoryArray.subarray(filenameOffset, extraFieldOffset);
  3025. const commentLength = getUint16(directoryView, offset + 32);
  3026. const endOffset = commentOffset + commentLength;
  3027. const rawComment = directoryArray.subarray(commentOffset, endOffset);
  3028. const filenameUTF8 = languageEncodingFlag;
  3029. const commentUTF8 = languageEncodingFlag;
  3030. const directory = msDosCompatible && ((getUint8(directoryView, offset + 38) & FILE_ATTR_MSDOS_DIR_MASK) == FILE_ATTR_MSDOS_DIR_MASK);
  3031. const offsetFileEntry = getUint32(directoryView, offset + 42) + prependedDataLength;
  3032. Object$1.assign(fileEntry, {
  3033. versionMadeBy,
  3034. msDosCompatible,
  3035. compressedSize: 0,
  3036. uncompressedSize: 0,
  3037. commentLength,
  3038. directory,
  3039. offset: offsetFileEntry,
  3040. diskNumberStart: getUint16(directoryView, offset + 34),
  3041. internalFileAttribute: getUint16(directoryView, offset + 36),
  3042. externalFileAttribute: getUint32(directoryView, offset + 38),
  3043. rawFilename,
  3044. filenameUTF8,
  3045. commentUTF8,
  3046. rawExtraField: directoryArray.subarray(extraFieldOffset, commentOffset)
  3047. });
  3048. const [filename, comment] = await Promise$1.all([
  3049. decodeText(rawFilename, filenameUTF8 ? CHARSET_UTF8 : filenameEncoding || CHARSET_CP437),
  3050. decodeText(rawComment, commentUTF8 ? CHARSET_UTF8 : commentEncoding || CHARSET_CP437)
  3051. ]);
  3052. Object$1.assign(fileEntry, {
  3053. rawComment,
  3054. filename,
  3055. comment,
  3056. directory: directory || filename.endsWith(DIRECTORY_SIGNATURE)
  3057. });
  3058. startOffset = Math$1.max(offsetFileEntry, startOffset);
  3059. await readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6);
  3060. const entry = new Entry(fileEntry);
  3061. entry.getData = (writer, options) => fileEntry.getData(writer, entry, options);
  3062. offset = endOffset;
  3063. const { onprogress } = options;
  3064. if (onprogress) {
  3065. try {
  3066. await onprogress(indexFile + 1, filesLength, new Entry(fileEntry));
  3067. } catch (_error) {
  3068. // ignored
  3069. }
  3070. }
  3071. yield entry;
  3072. }
  3073. const extractPrependedData = getOptionValue$1(zipReader, options, "extractPrependedData");
  3074. const extractAppendedData = getOptionValue$1(zipReader, options, "extractAppendedData");
  3075. if (extractPrependedData) {
  3076. zipReader.prependedData = startOffset > 0 ? await readUint8Array(reader, 0, startOffset) : new Uint8Array$1();
  3077. }
  3078. zipReader.comment = commentLength ? await readUint8Array(reader, commentOffset + END_OF_CENTRAL_DIR_LENGTH, commentLength) : new Uint8Array$1();
  3079. if (extractAppendedData) {
  3080. zipReader.appendedData = appendedDataOffset < reader.size ? await readUint8Array(reader, appendedDataOffset, reader.size - appendedDataOffset) : new Uint8Array$1();
  3081. }
  3082. return true;
  3083. }
  3084. async getEntries(options = {}) {
  3085. const entries = [];
  3086. for await (const entry of this.getEntriesGenerator(options)) {
  3087. entries.push(entry);
  3088. }
  3089. return entries;
  3090. }
  3091. async close() {
  3092. }
  3093. }
  3094. class ZipEntry {
  3095. constructor(reader, config, options) {
  3096. Object$1.assign(this, {
  3097. reader,
  3098. config,
  3099. options
  3100. });
  3101. }
  3102. async getData(writer, fileEntry, options = {}) {
  3103. const zipEntry = this;
  3104. const {
  3105. reader,
  3106. offset,
  3107. diskNumberStart,
  3108. extraFieldAES,
  3109. compressionMethod,
  3110. config,
  3111. bitFlag,
  3112. signature,
  3113. rawLastModDate,
  3114. uncompressedSize,
  3115. compressedSize
  3116. } = zipEntry;
  3117. const localDirectory = fileEntry.localDirectory = {};
  3118. const dataArray = await readUint8Array(reader, offset, 30, diskNumberStart);
  3119. const dataView = getDataView$1(dataArray);
  3120. let password = getOptionValue$1(zipEntry, options, "password");
  3121. password = password && password.length && password;
  3122. if (extraFieldAES) {
  3123. if (extraFieldAES.originalCompressionMethod != COMPRESSION_METHOD_AES) {
  3124. throw new Error$1(ERR_UNSUPPORTED_COMPRESSION);
  3125. }
  3126. }
  3127. if (compressionMethod != COMPRESSION_METHOD_STORE && compressionMethod != COMPRESSION_METHOD_DEFLATE) {
  3128. throw new Error$1(ERR_UNSUPPORTED_COMPRESSION);
  3129. }
  3130. if (getUint32(dataView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
  3131. throw new Error$1(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
  3132. }
  3133. readCommonHeader(localDirectory, dataView, 4);
  3134. localDirectory.rawExtraField = localDirectory.extraFieldLength ?
  3135. await readUint8Array(reader, offset + 30 + localDirectory.filenameLength, localDirectory.extraFieldLength, diskNumberStart) :
  3136. new Uint8Array$1();
  3137. await readCommonFooter(zipEntry, localDirectory, dataView, 4, true);
  3138. Object$1.assign(fileEntry, {
  3139. lastAccessDate: localDirectory.lastAccessDate,
  3140. creationDate: localDirectory.creationDate
  3141. });
  3142. const encrypted = zipEntry.encrypted && localDirectory.encrypted;
  3143. const zipCrypto = encrypted && !extraFieldAES;
  3144. if (encrypted) {
  3145. if (!zipCrypto && extraFieldAES.strength === UNDEFINED_VALUE) {
  3146. throw new Error$1(ERR_UNSUPPORTED_ENCRYPTION);
  3147. } else if (!password) {
  3148. throw new Error$1(ERR_ENCRYPTED);
  3149. }
  3150. }
  3151. const dataOffset = offset + 30 + localDirectory.filenameLength + localDirectory.extraFieldLength;
  3152. const size = compressedSize;
  3153. const readable = reader.readable;
  3154. Object$1.assign(readable, {
  3155. diskNumberStart,
  3156. offset: dataOffset,
  3157. size
  3158. });
  3159. const signal = getOptionValue$1(zipEntry, options, "signal");
  3160. const checkPasswordOnly = getOptionValue$1(zipEntry, options, "checkPasswordOnly");
  3161. if (checkPasswordOnly) {
  3162. writer = new WritableStream();
  3163. }
  3164. writer = initWriter(writer);
  3165. await initStream(writer, uncompressedSize);
  3166. const { writable } = writer;
  3167. const { onstart, onprogress, onend } = options;
  3168. const workerOptions = {
  3169. options: {
  3170. codecType: CODEC_INFLATE,
  3171. password,
  3172. zipCrypto,
  3173. encryptionStrength: extraFieldAES && extraFieldAES.strength,
  3174. signed: getOptionValue$1(zipEntry, options, "checkSignature"),
  3175. passwordVerification: zipCrypto && (bitFlag.dataDescriptor ? ((rawLastModDate >>> 8) & 0xFF) : ((signature >>> 24) & 0xFF)),
  3176. signature,
  3177. compressed: compressionMethod != 0,
  3178. encrypted,
  3179. useWebWorkers: getOptionValue$1(zipEntry, options, "useWebWorkers"),
  3180. useCompressionStream: getOptionValue$1(zipEntry, options, "useCompressionStream"),
  3181. transferStreams: getOptionValue$1(zipEntry, options, "transferStreams"),
  3182. checkPasswordOnly
  3183. },
  3184. config,
  3185. streamOptions: { signal, size, onstart, onprogress, onend }
  3186. };
  3187. let outputSize = 0;
  3188. try {
  3189. ({ outputSize } = (await runWorker({ readable, writable }, workerOptions)));
  3190. } catch (error) {
  3191. if (!checkPasswordOnly || error.message != ERR_ABORT_CHECK_PASSWORD) {
  3192. throw error;
  3193. }
  3194. } finally {
  3195. const preventClose = getOptionValue$1(zipEntry, options, "preventClose");
  3196. writable.size += outputSize;
  3197. if (!preventClose && !writable.locked) {
  3198. await writable.getWriter().close();
  3199. }
  3200. }
  3201. return checkPasswordOnly ? undefined : writer.getData ? writer.getData() : writable;
  3202. }
  3203. }
  3204. function readCommonHeader(directory, dataView, offset) {
  3205. const rawBitFlag = directory.rawBitFlag = getUint16(dataView, offset + 2);
  3206. const encrypted = (rawBitFlag & BITFLAG_ENCRYPTED) == BITFLAG_ENCRYPTED;
  3207. const rawLastModDate = getUint32(dataView, offset + 6);
  3208. Object$1.assign(directory, {
  3209. encrypted,
  3210. version: getUint16(dataView, offset),
  3211. bitFlag: {
  3212. level: (rawBitFlag & BITFLAG_LEVEL) >> 1,
  3213. dataDescriptor: (rawBitFlag & BITFLAG_DATA_DESCRIPTOR) == BITFLAG_DATA_DESCRIPTOR,
  3214. languageEncodingFlag: (rawBitFlag & BITFLAG_LANG_ENCODING_FLAG) == BITFLAG_LANG_ENCODING_FLAG
  3215. },
  3216. rawLastModDate,
  3217. lastModDate: getDate(rawLastModDate),
  3218. filenameLength: getUint16(dataView, offset + 22),
  3219. extraFieldLength: getUint16(dataView, offset + 24)
  3220. });
  3221. }
  3222. async function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory) {
  3223. const { rawExtraField } = directory;
  3224. const extraField = directory.extraField = new Map$2();
  3225. const rawExtraFieldView = getDataView$1(new Uint8Array$1(rawExtraField));
  3226. let offsetExtraField = 0;
  3227. try {
  3228. while (offsetExtraField < rawExtraField.length) {
  3229. const type = getUint16(rawExtraFieldView, offsetExtraField);
  3230. const size = getUint16(rawExtraFieldView, offsetExtraField + 2);
  3231. extraField.set(type, {
  3232. type,
  3233. data: rawExtraField.slice(offsetExtraField + 4, offsetExtraField + 4 + size)
  3234. });
  3235. offsetExtraField += 4 + size;
  3236. }
  3237. } catch (_error) {
  3238. // ignored
  3239. }
  3240. const compressionMethod = getUint16(dataView, offset + 4);
  3241. Object$1.assign(directory, {
  3242. signature: getUint32(dataView, offset + 10),
  3243. uncompressedSize: getUint32(dataView, offset + 18),
  3244. compressedSize: getUint32(dataView, offset + 14)
  3245. });
  3246. const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
  3247. if (extraFieldZip64) {
  3248. readExtraFieldZip64(extraFieldZip64, directory);
  3249. directory.extraFieldZip64 = extraFieldZip64;
  3250. }
  3251. const extraFieldUnicodePath = extraField.get(EXTRAFIELD_TYPE_UNICODE_PATH);
  3252. if (extraFieldUnicodePath) {
  3253. await readExtraFieldUnicode(extraFieldUnicodePath, PROPERTY_NAME_FILENAME, PROPERTY_NAME_RAW_FILENAME, directory, fileEntry);
  3254. directory.extraFieldUnicodePath = extraFieldUnicodePath;
  3255. }
  3256. const extraFieldUnicodeComment = extraField.get(EXTRAFIELD_TYPE_UNICODE_COMMENT);
  3257. if (extraFieldUnicodeComment) {
  3258. await readExtraFieldUnicode(extraFieldUnicodeComment, PROPERTY_NAME_COMMENT, PROPERTY_NAME_RAW_COMMENT, directory, fileEntry);
  3259. directory.extraFieldUnicodeComment = extraFieldUnicodeComment;
  3260. }
  3261. const extraFieldAES = extraField.get(EXTRAFIELD_TYPE_AES);
  3262. if (extraFieldAES) {
  3263. readExtraFieldAES(extraFieldAES, directory, compressionMethod);
  3264. directory.extraFieldAES = extraFieldAES;
  3265. } else {
  3266. directory.compressionMethod = compressionMethod;
  3267. }
  3268. const extraFieldNTFS = extraField.get(EXTRAFIELD_TYPE_NTFS);
  3269. if (extraFieldNTFS) {
  3270. readExtraFieldNTFS(extraFieldNTFS, directory);
  3271. directory.extraFieldNTFS = extraFieldNTFS;
  3272. }
  3273. const extraFieldExtendedTimestamp = extraField.get(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
  3274. if (extraFieldExtendedTimestamp) {
  3275. readExtraFieldExtendedTimestamp(extraFieldExtendedTimestamp, directory, localDirectory);
  3276. directory.extraFieldExtendedTimestamp = extraFieldExtendedTimestamp;
  3277. }
  3278. const extraFieldUSDZ = extraField.get(EXTRAFIELD_TYPE_USDZ);
  3279. if (extraFieldUSDZ) {
  3280. directory.extraFieldUSDZ = extraFieldUSDZ;
  3281. }
  3282. }
  3283. function readExtraFieldZip64(extraFieldZip64, directory) {
  3284. directory.zip64 = true;
  3285. const extraFieldView = getDataView$1(extraFieldZip64.data);
  3286. const missingProperties = ZIP64_PROPERTIES.filter(([propertyName, max]) => directory[propertyName] == max);
  3287. for (let indexMissingProperty = 0, offset = 0; indexMissingProperty < missingProperties.length; indexMissingProperty++) {
  3288. const [propertyName, max] = missingProperties[indexMissingProperty];
  3289. if (directory[propertyName] == max) {
  3290. const extraction = ZIP64_EXTRACTION[max];
  3291. directory[propertyName] = extraFieldZip64[propertyName] = extraction.getValue(extraFieldView, offset);
  3292. offset += extraction.bytes;
  3293. } else if (extraFieldZip64[propertyName]) {
  3294. throw new Error$1(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
  3295. }
  3296. }
  3297. }
  3298. async function readExtraFieldUnicode(extraFieldUnicode, propertyName, rawPropertyName, directory, fileEntry) {
  3299. const extraFieldView = getDataView$1(extraFieldUnicode.data);
  3300. const crc32 = new Crc32();
  3301. crc32.append(fileEntry[rawPropertyName]);
  3302. const dataViewSignature = getDataView$1(new Uint8Array$1(4));
  3303. dataViewSignature.setUint32(0, crc32.get(), true);
  3304. const signature = getUint32(extraFieldView, 1);
  3305. Object$1.assign(extraFieldUnicode, {
  3306. version: getUint8(extraFieldView, 0),
  3307. [propertyName]: decodeText(extraFieldUnicode.data.subarray(5)),
  3308. valid: !fileEntry.bitFlag.languageEncodingFlag && signature == getUint32(dataViewSignature, 0)
  3309. });
  3310. if (extraFieldUnicode.valid) {
  3311. directory[propertyName] = extraFieldUnicode[propertyName];
  3312. directory[propertyName + "UTF8"] = true;
  3313. }
  3314. }
  3315. function readExtraFieldAES(extraFieldAES, directory, compressionMethod) {
  3316. const extraFieldView = getDataView$1(extraFieldAES.data);
  3317. const strength = getUint8(extraFieldView, 4);
  3318. Object$1.assign(extraFieldAES, {
  3319. vendorVersion: getUint8(extraFieldView, 0),
  3320. vendorId: getUint8(extraFieldView, 2),
  3321. strength,
  3322. originalCompressionMethod: compressionMethod,
  3323. compressionMethod: getUint16(extraFieldView, 5)
  3324. });
  3325. directory.compressionMethod = extraFieldAES.compressionMethod;
  3326. }
  3327. function readExtraFieldNTFS(extraFieldNTFS, directory) {
  3328. const extraFieldView = getDataView$1(extraFieldNTFS.data);
  3329. let offsetExtraField = 4;
  3330. let tag1Data;
  3331. try {
  3332. while (offsetExtraField < extraFieldNTFS.data.length && !tag1Data) {
  3333. const tagValue = getUint16(extraFieldView, offsetExtraField);
  3334. const attributeSize = getUint16(extraFieldView, offsetExtraField + 2);
  3335. if (tagValue == EXTRAFIELD_TYPE_NTFS_TAG1) {
  3336. tag1Data = extraFieldNTFS.data.slice(offsetExtraField + 4, offsetExtraField + 4 + attributeSize);
  3337. }
  3338. offsetExtraField += 4 + attributeSize;
  3339. }
  3340. } catch (_error) {
  3341. // ignored
  3342. }
  3343. try {
  3344. if (tag1Data && tag1Data.length == 24) {
  3345. const tag1View = getDataView$1(tag1Data);
  3346. const rawLastModDate = tag1View.getBigUint64(0, true);
  3347. const rawLastAccessDate = tag1View.getBigUint64(8, true);
  3348. const rawCreationDate = tag1View.getBigUint64(16, true);
  3349. Object$1.assign(extraFieldNTFS, {
  3350. rawLastModDate,
  3351. rawLastAccessDate,
  3352. rawCreationDate
  3353. });
  3354. const lastModDate = getDateNTFS(rawLastModDate);
  3355. const lastAccessDate = getDateNTFS(rawLastAccessDate);
  3356. const creationDate = getDateNTFS(rawCreationDate);
  3357. const extraFieldData = { lastModDate, lastAccessDate, creationDate };
  3358. Object$1.assign(extraFieldNTFS, extraFieldData);
  3359. Object$1.assign(directory, extraFieldData);
  3360. }
  3361. } catch (_error) {
  3362. // ignored
  3363. }
  3364. }
  3365. function readExtraFieldExtendedTimestamp(extraFieldExtendedTimestamp, directory, localDirectory) {
  3366. const extraFieldView = getDataView$1(extraFieldExtendedTimestamp.data);
  3367. const flags = getUint8(extraFieldView, 0);
  3368. const timeProperties = [];
  3369. const timeRawProperties = [];
  3370. if (localDirectory) {
  3371. if ((flags & 0x1) == 0x1) {
  3372. timeProperties.push(PROPERTY_NAME_LAST_MODIFICATION_DATE);
  3373. timeRawProperties.push(PROPERTY_NAME_RAW_LAST_MODIFICATION_DATE);
  3374. }
  3375. if ((flags & 0x2) == 0x2) {
  3376. timeProperties.push(PROPERTY_NAME_LAST_ACCESS_DATE);
  3377. timeRawProperties.push(PROPERTY_NAME_RAW_LAST_ACCESS_DATE);
  3378. }
  3379. if ((flags & 0x4) == 0x4) {
  3380. timeProperties.push(PROPERTY_NAME_CREATION_DATE);
  3381. timeRawProperties.push(PROPERTY_NAME_RAW_CREATION_DATE);
  3382. }
  3383. } else if (extraFieldExtendedTimestamp.data.length >= 5) {
  3384. timeProperties.push(PROPERTY_NAME_LAST_MODIFICATION_DATE);
  3385. timeRawProperties.push(PROPERTY_NAME_RAW_LAST_MODIFICATION_DATE);
  3386. }
  3387. let offset = 1;
  3388. timeProperties.forEach((propertyName, indexProperty) => {
  3389. if (extraFieldExtendedTimestamp.data.length >= offset + 4) {
  3390. const time = getUint32(extraFieldView, offset);
  3391. directory[propertyName] = extraFieldExtendedTimestamp[propertyName] = new Date$1(time * 1000);
  3392. const rawPropertyName = timeRawProperties[indexProperty];
  3393. extraFieldExtendedTimestamp[rawPropertyName] = time;
  3394. }
  3395. offset += 4;
  3396. });
  3397. }
  3398. async function seekSignature(reader, signature, startOffset, minimumBytes, maximumLength) {
  3399. const signatureArray = new Uint8Array$1(4);
  3400. const signatureView = getDataView$1(signatureArray);
  3401. setUint32$1(signatureView, 0, signature);
  3402. const maximumBytes = minimumBytes + maximumLength;
  3403. return (await seek(minimumBytes)) || await seek(Math$1.min(maximumBytes, startOffset));
  3404. async function seek(length) {
  3405. const offset = startOffset - length;
  3406. const bytes = await readUint8Array(reader, offset, length);
  3407. for (let indexByte = bytes.length - minimumBytes; indexByte >= 0; indexByte--) {
  3408. if (bytes[indexByte] == signatureArray[0] && bytes[indexByte + 1] == signatureArray[1] &&
  3409. bytes[indexByte + 2] == signatureArray[2] && bytes[indexByte + 3] == signatureArray[3]) {
  3410. return {
  3411. offset: offset + indexByte,
  3412. buffer: bytes.slice(indexByte, indexByte + minimumBytes).buffer
  3413. };
  3414. }
  3415. }
  3416. }
  3417. }
  3418. function getOptionValue$1(zipReader, options, name) {
  3419. return options[name] === UNDEFINED_VALUE ? zipReader.options[name] : options[name];
  3420. }
  3421. function getDate(timeRaw) {
  3422. const date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & 0x0000ffff;
  3423. try {
  3424. return new Date$1(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0);
  3425. } catch (_error) {
  3426. // ignored
  3427. }
  3428. }
  3429. function getDateNTFS(timeRaw) {
  3430. return new Date$1((Number$1((timeRaw / BigInt(10000)) - BigInt(11644473600000))));
  3431. }
  3432. function getUint8(view, offset) {
  3433. return view.getUint8(offset);
  3434. }
  3435. function getUint16(view, offset) {
  3436. return view.getUint16(offset, true);
  3437. }
  3438. function getUint32(view, offset) {
  3439. return view.getUint32(offset, true);
  3440. }
  3441. function getBigUint64(view, offset) {
  3442. return Number$1(view.getBigUint64(offset, true));
  3443. }
  3444. function setUint32$1(view, offset, value) {
  3445. view.setUint32(offset, value, true);
  3446. }
  3447. function getDataView$1(array) {
  3448. return new DataView$1(array.buffer);
  3449. }
  3450. /*
  3451. Copyright (c) 2022 Gildas Lormeau. All rights reserved.
  3452. Redistribution and use in source and binary forms, with or without
  3453. modification, are permitted provided that the following conditions are met:
  3454. 1. Redistributions of source code must retain the above copyright notice,
  3455. this list of conditions and the following disclaimer.
  3456. 2. Redistributions in binary form must reproduce the above copyright
  3457. notice, this list of conditions and the following disclaimer in
  3458. the documentation and/or other materials provided with the distribution.
  3459. 3. The names of the authors may not be used to endorse or promote products
  3460. derived from this software without specific prior written permission.
  3461. THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  3462. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  3463. FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
  3464. INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
  3465. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  3466. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  3467. OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  3468. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  3469. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  3470. EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  3471. */
  3472. const ERR_DUPLICATED_NAME = "File already exists";
  3473. const ERR_INVALID_COMMENT = "Zip file comment exceeds 64KB";
  3474. const ERR_INVALID_ENTRY_COMMENT = "File entry comment exceeds 64KB";
  3475. const ERR_INVALID_ENTRY_NAME = "File entry name exceeds 64KB";
  3476. const ERR_INVALID_VERSION = "Version exceeds 65535";
  3477. const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
  3478. const ERR_INVALID_EXTRAFIELD_TYPE = "Extra field type exceeds 65535";
  3479. const ERR_INVALID_EXTRAFIELD_DATA = "Extra field data exceeds 64KB";
  3480. const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (make sure 'keepOrder' is set to 'true')";
  3481. const EXTRAFIELD_DATA_AES = new Uint8Array$1([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
  3482. let workers = 0;
  3483. const pendingEntries = [];
  3484. class ZipWriter {
  3485. constructor(writer, options = {}) {
  3486. writer = initWriter(writer);
  3487. Object$1.assign(this, {
  3488. writer,
  3489. addSplitZipSignature: writer instanceof SplitDataWriter,
  3490. options,
  3491. config: getConfiguration(),
  3492. files: new Map$2(),
  3493. filenames: new Set$3(),
  3494. offset: writer.writable.size,
  3495. pendingEntriesSize: 0,
  3496. pendingAddFileCalls: new Set$3(),
  3497. bufferedWrites: 0
  3498. });
  3499. }
  3500. async add(name = "", reader, options = {}) {
  3501. const zipWriter = this;
  3502. const {
  3503. pendingAddFileCalls,
  3504. config
  3505. } = zipWriter;
  3506. if (workers < config.maxWorkers) {
  3507. workers++;
  3508. } else {
  3509. await new Promise$1(resolve => pendingEntries.push(resolve));
  3510. }
  3511. let promiseAddFile;
  3512. try {
  3513. name = name.trim();
  3514. if (zipWriter.filenames.has(name)) {
  3515. throw new Error$1(ERR_DUPLICATED_NAME);
  3516. }
  3517. zipWriter.filenames.add(name);
  3518. promiseAddFile = addFile$1(zipWriter, name, reader, options);
  3519. pendingAddFileCalls.add(promiseAddFile);
  3520. return await promiseAddFile;
  3521. } catch (error) {
  3522. zipWriter.filenames.delete(name);
  3523. throw error;
  3524. } finally {
  3525. pendingAddFileCalls.delete(promiseAddFile);
  3526. const pendingEntry = pendingEntries.shift();
  3527. if (pendingEntry) {
  3528. pendingEntry();
  3529. } else {
  3530. workers--;
  3531. }
  3532. }
  3533. }
  3534. async close(comment = new Uint8Array$1(), options = {}) {
  3535. const zipWriter = this;
  3536. const { pendingAddFileCalls, writer } = this;
  3537. const { writable } = writer;
  3538. while (pendingAddFileCalls.size) {
  3539. await Promise$1.all(Array$1.from(pendingAddFileCalls));
  3540. }
  3541. await closeFile(this, comment, options);
  3542. const preventClose = getOptionValue(zipWriter, options, "preventClose");
  3543. if (!preventClose) {
  3544. await writable.getWriter().close();
  3545. }
  3546. return writer.getData ? writer.getData() : writable;
  3547. }
  3548. }
  3549. async function addFile$1(zipWriter, name, reader, options) {
  3550. name = name.trim();
  3551. if (options.directory && (!name.endsWith(DIRECTORY_SIGNATURE))) {
  3552. name += DIRECTORY_SIGNATURE;
  3553. } else {
  3554. options.directory = name.endsWith(DIRECTORY_SIGNATURE);
  3555. }
  3556. const rawFilename = encodeText(name);
  3557. if (getLength(rawFilename) > MAX_16_BITS) {
  3558. throw new Error$1(ERR_INVALID_ENTRY_NAME);
  3559. }
  3560. const comment = options.comment || "";
  3561. const rawComment = encodeText(comment);
  3562. if (getLength(rawComment) > MAX_16_BITS) {
  3563. throw new Error$1(ERR_INVALID_ENTRY_COMMENT);
  3564. }
  3565. const version = getOptionValue(zipWriter, options, "version", VERSION_DEFLATE);
  3566. if (version > MAX_16_BITS) {
  3567. throw new Error$1(ERR_INVALID_VERSION);
  3568. }
  3569. const versionMadeBy = getOptionValue(zipWriter, options, "versionMadeBy", 20);
  3570. if (versionMadeBy > MAX_16_BITS) {
  3571. throw new Error$1(ERR_INVALID_VERSION);
  3572. }
  3573. const lastModDate = getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE, new Date$1());
  3574. const lastAccessDate = getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
  3575. const creationDate = getOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
  3576. const msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE, true);
  3577. const internalFileAttribute = getOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTE, 0);
  3578. const externalFileAttribute = getOptionValue(zipWriter, options, PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTE, 0);
  3579. const password = getOptionValue(zipWriter, options, "password");
  3580. const encryptionStrength = getOptionValue(zipWriter, options, "encryptionStrength", 3);
  3581. const zipCrypto = getOptionValue(zipWriter, options, "zipCrypto");
  3582. const extendedTimestamp = getOptionValue(zipWriter, options, "extendedTimestamp", true);
  3583. const keepOrder = getOptionValue(zipWriter, options, "keepOrder", true);
  3584. const level = getOptionValue(zipWriter, options, "level");
  3585. const useWebWorkers = getOptionValue(zipWriter, options, "useWebWorkers");
  3586. const bufferedWrite = getOptionValue(zipWriter, options, "bufferedWrite");
  3587. const dataDescriptorSignature = getOptionValue(zipWriter, options, "dataDescriptorSignature", false);
  3588. const signal = getOptionValue(zipWriter, options, "signal");
  3589. const useCompressionStream = getOptionValue(zipWriter, options, "useCompressionStream");
  3590. let dataDescriptor = getOptionValue(zipWriter, options, "dataDescriptor", true);
  3591. let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
  3592. if (password !== UNDEFINED_VALUE && encryptionStrength !== UNDEFINED_VALUE && (encryptionStrength < 1 || encryptionStrength > 3)) {
  3593. throw new Error$1(ERR_INVALID_ENCRYPTION_STRENGTH);
  3594. }
  3595. let rawExtraField = new Uint8Array$1();
  3596. const { extraField } = options;
  3597. if (extraField) {
  3598. let extraFieldSize = 0;
  3599. let offset = 0;
  3600. extraField.forEach(data => extraFieldSize += 4 + getLength(data));
  3601. rawExtraField = new Uint8Array$1(extraFieldSize);
  3602. extraField.forEach((data, type) => {
  3603. if (type > MAX_16_BITS) {
  3604. throw new Error$1(ERR_INVALID_EXTRAFIELD_TYPE);
  3605. }
  3606. if (getLength(data) > MAX_16_BITS) {
  3607. throw new Error$1(ERR_INVALID_EXTRAFIELD_DATA);
  3608. }
  3609. arraySet(rawExtraField, new Uint16Array([type]), offset);
  3610. arraySet(rawExtraField, new Uint16Array([getLength(data)]), offset + 2);
  3611. arraySet(rawExtraField, data, offset + 4);
  3612. offset += 4 + getLength(data);
  3613. });
  3614. }
  3615. let maximumCompressedSize = 0;
  3616. let maximumEntrySize = 0;
  3617. let uncompressedSize = 0;
  3618. const zip64Enabled = zip64 === true;
  3619. if (reader) {
  3620. reader = initReader(reader);
  3621. await initStream(reader);
  3622. if (reader.size === UNDEFINED_VALUE) {
  3623. dataDescriptor = true;
  3624. if (zip64 || zip64 === UNDEFINED_VALUE) {
  3625. zip64 = true;
  3626. uncompressedSize = maximumCompressedSize = MAX_32_BITS;
  3627. }
  3628. } else {
  3629. uncompressedSize = reader.size;
  3630. maximumCompressedSize = getMaximumCompressedSize(uncompressedSize);
  3631. }
  3632. }
  3633. const { diskOffset, diskNumber, maxSize } = zipWriter.writer;
  3634. const zip64UncompressedSize = zip64Enabled || uncompressedSize >= MAX_32_BITS;
  3635. const zip64CompressedSize = zip64Enabled || maximumCompressedSize >= MAX_32_BITS;
  3636. const zip64Offset = zip64Enabled || zipWriter.offset + zipWriter.pendingEntriesSize - diskOffset >= MAX_32_BITS;
  3637. const supportZip64SplitFile = getOptionValue(zipWriter, options, "supportZip64SplitFile", true);
  3638. const zip64DiskNumberStart = (supportZip64SplitFile && zip64Enabled) || diskNumber + Math$1.ceil(zipWriter.pendingEntriesSize / maxSize) >= MAX_16_BITS;
  3639. if (zip64Offset || zip64UncompressedSize || zip64CompressedSize || zip64DiskNumberStart) {
  3640. if (zip64 === false || !keepOrder) {
  3641. throw new Error$1(ERR_UNSUPPORTED_FORMAT);
  3642. } else {
  3643. zip64 = true;
  3644. }
  3645. }
  3646. zip64 = zip64 || false;
  3647. options = Object$1.assign({}, options, {
  3648. rawFilename,
  3649. rawComment,
  3650. version,
  3651. versionMadeBy,
  3652. lastModDate,
  3653. lastAccessDate,
  3654. creationDate,
  3655. rawExtraField,
  3656. zip64,
  3657. zip64UncompressedSize,
  3658. zip64CompressedSize,
  3659. zip64Offset,
  3660. zip64DiskNumberStart,
  3661. password,
  3662. level,
  3663. useWebWorkers,
  3664. encryptionStrength,
  3665. extendedTimestamp,
  3666. zipCrypto,
  3667. bufferedWrite,
  3668. keepOrder,
  3669. dataDescriptor,
  3670. dataDescriptorSignature,
  3671. signal,
  3672. msDosCompatible,
  3673. internalFileAttribute,
  3674. externalFileAttribute,
  3675. useCompressionStream
  3676. });
  3677. const headerInfo = getHeaderInfo(options);
  3678. const dataDescriptorInfo = getDataDescriptorInfo(options);
  3679. const metadataSize = getLength(headerInfo.localHeaderArray, dataDescriptorInfo.dataDescriptorArray);
  3680. maximumEntrySize = metadataSize + maximumCompressedSize;
  3681. if (zipWriter.options.usdz) {
  3682. maximumEntrySize += maximumEntrySize + 64;
  3683. }
  3684. zipWriter.pendingEntriesSize += maximumEntrySize;
  3685. let fileEntry;
  3686. try {
  3687. fileEntry = await getFileEntry(zipWriter, name, reader, { headerInfo, dataDescriptorInfo, metadataSize }, options);
  3688. } finally {
  3689. zipWriter.pendingEntriesSize -= maximumEntrySize;
  3690. }
  3691. Object$1.assign(fileEntry, { name, comment, extraField });
  3692. return new Entry(fileEntry);
  3693. }
  3694. async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
  3695. const {
  3696. files,
  3697. writer
  3698. } = zipWriter;
  3699. const {
  3700. keepOrder,
  3701. dataDescriptor,
  3702. signal
  3703. } = options;
  3704. const {
  3705. headerInfo
  3706. } = entryInfo;
  3707. const { usdz } = zipWriter.options;
  3708. const previousFileEntry = Array$1.from(files.values()).pop();
  3709. let fileEntry = {};
  3710. let bufferedWrite;
  3711. let releaseLockWriter;
  3712. let releaseLockCurrentFileEntry;
  3713. let writingBufferedEntryData;
  3714. let writingEntryData;
  3715. let fileWriter;
  3716. files.set(name, fileEntry);
  3717. try {
  3718. let lockPreviousFileEntry;
  3719. if (keepOrder) {
  3720. lockPreviousFileEntry = previousFileEntry && previousFileEntry.lock;
  3721. requestLockCurrentFileEntry();
  3722. }
  3723. if ((options.bufferedWrite || zipWriter.writerLocked || (zipWriter.bufferedWrites && keepOrder) || !dataDescriptor) && !usdz) {
  3724. fileWriter = new BlobWriter();
  3725. fileWriter.writable.size = 0;
  3726. bufferedWrite = true;
  3727. zipWriter.bufferedWrites++;
  3728. await initStream(writer);
  3729. } else {
  3730. fileWriter = writer;
  3731. await requestLockWriter();
  3732. }
  3733. await initStream(fileWriter);
  3734. const { writable } = writer;
  3735. let { diskOffset } = writer;
  3736. if (zipWriter.addSplitZipSignature) {
  3737. delete zipWriter.addSplitZipSignature;
  3738. const signatureArray = new Uint8Array$1(4);
  3739. const signatureArrayView = getDataView(signatureArray);
  3740. setUint32(signatureArrayView, 0, SPLIT_ZIP_FILE_SIGNATURE);
  3741. await writeData$1(writable, signatureArray);
  3742. zipWriter.offset += 4;
  3743. }
  3744. if (!bufferedWrite) {
  3745. await lockPreviousFileEntry;
  3746. await skipDiskIfNeeded(writable);
  3747. }
  3748. const { diskNumber } = writer;
  3749. writingEntryData = true;
  3750. fileEntry.diskNumberStart = diskNumber;
  3751. if (usdz) {
  3752. appendExtraFieldUSDZ(entryInfo, zipWriter.offset - diskOffset);
  3753. }
  3754. fileEntry = await createFileEntry(reader, fileWriter, fileEntry, entryInfo, zipWriter.config, options);
  3755. writingEntryData = false;
  3756. files.set(name, fileEntry);
  3757. fileEntry.filename = name;
  3758. if (bufferedWrite) {
  3759. await fileWriter.writable.getWriter().close();
  3760. let blob = await fileWriter.getData();
  3761. await lockPreviousFileEntry;
  3762. await requestLockWriter();
  3763. writingBufferedEntryData = true;
  3764. if (!dataDescriptor) {
  3765. blob = await writeExtraHeaderInfo(fileEntry, blob, writable, options);
  3766. }
  3767. await skipDiskIfNeeded(writable);
  3768. fileEntry.diskNumberStart = writer.diskNumber;
  3769. diskOffset = writer.diskOffset;
  3770. await blob.stream().pipeTo(writable, { preventClose: true, preventAbort: true, signal });
  3771. writable.size += blob.size;
  3772. writingBufferedEntryData = false;
  3773. }
  3774. fileEntry.offset = zipWriter.offset - diskOffset;
  3775. if (fileEntry.zip64) {
  3776. setZip64ExtraInfo(fileEntry, options);
  3777. } else if (fileEntry.offset >= MAX_32_BITS) {
  3778. throw new Error$1(ERR_UNSUPPORTED_FORMAT);
  3779. }
  3780. zipWriter.offset += fileEntry.length;
  3781. return fileEntry;
  3782. } catch (error) {
  3783. if ((bufferedWrite && writingBufferedEntryData) || (!bufferedWrite && writingEntryData)) {
  3784. zipWriter.hasCorruptedEntries = true;
  3785. if (error) {
  3786. try {
  3787. error.corruptedEntry = true;
  3788. } catch (_error) {
  3789. // ignored
  3790. }
  3791. }
  3792. if (bufferedWrite) {
  3793. zipWriter.offset += fileWriter.writable.size;
  3794. } else {
  3795. zipWriter.offset = fileWriter.writable.size;
  3796. }
  3797. }
  3798. files.delete(name);
  3799. throw error;
  3800. } finally {
  3801. if (bufferedWrite) {
  3802. zipWriter.bufferedWrites--;
  3803. }
  3804. if (releaseLockCurrentFileEntry) {
  3805. releaseLockCurrentFileEntry();
  3806. }
  3807. if (releaseLockWriter) {
  3808. releaseLockWriter();
  3809. }
  3810. }
  3811. function requestLockCurrentFileEntry() {
  3812. fileEntry.lock = new Promise$1(resolve => releaseLockCurrentFileEntry = resolve);
  3813. }
  3814. async function requestLockWriter() {
  3815. zipWriter.writerLocked = true;
  3816. const { lockWriter } = zipWriter;
  3817. zipWriter.lockWriter = new Promise$1(resolve => releaseLockWriter = () => {
  3818. zipWriter.writerLocked = false;
  3819. resolve();
  3820. });
  3821. await lockWriter;
  3822. }
  3823. async function skipDiskIfNeeded(writable) {
  3824. if (headerInfo.localHeaderArray.length > writer.availableSize) {
  3825. writer.availableSize = 0;
  3826. await writeData$1(writable, new Uint8Array$1());
  3827. }
  3828. }
  3829. }
  3830. async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryInfo, config, options) {
  3831. const {
  3832. headerInfo,
  3833. dataDescriptorInfo,
  3834. metadataSize
  3835. } = entryInfo;
  3836. const {
  3837. localHeaderArray,
  3838. headerArray,
  3839. lastModDate,
  3840. rawLastModDate,
  3841. encrypted,
  3842. compressed,
  3843. version,
  3844. compressionMethod,
  3845. rawExtraFieldExtendedTimestamp,
  3846. extraFieldExtendedTimestampFlag,
  3847. rawExtraFieldNTFS,
  3848. rawExtraFieldAES
  3849. } = headerInfo;
  3850. const { dataDescriptorArray } = dataDescriptorInfo;
  3851. const {
  3852. rawFilename,
  3853. lastAccessDate,
  3854. creationDate,
  3855. password,
  3856. level,
  3857. zip64,
  3858. zip64UncompressedSize,
  3859. zip64CompressedSize,
  3860. zip64Offset,
  3861. zip64DiskNumberStart,
  3862. zipCrypto,
  3863. dataDescriptor,
  3864. directory,
  3865. versionMadeBy,
  3866. rawComment,
  3867. rawExtraField,
  3868. useWebWorkers,
  3869. onstart,
  3870. onprogress,
  3871. onend,
  3872. signal,
  3873. encryptionStrength,
  3874. extendedTimestamp,
  3875. msDosCompatible,
  3876. internalFileAttribute,
  3877. externalFileAttribute,
  3878. useCompressionStream
  3879. } = options;
  3880. const fileEntry = {
  3881. lock,
  3882. versionMadeBy,
  3883. zip64,
  3884. directory: Boolean(directory),
  3885. filenameUTF8: true,
  3886. rawFilename,
  3887. commentUTF8: true,
  3888. rawComment,
  3889. rawExtraFieldExtendedTimestamp,
  3890. rawExtraFieldNTFS,
  3891. rawExtraFieldAES,
  3892. rawExtraField,
  3893. extendedTimestamp,
  3894. msDosCompatible,
  3895. internalFileAttribute,
  3896. externalFileAttribute,
  3897. diskNumberStart
  3898. };
  3899. let compressedSize = 0;
  3900. let uncompressedSize = 0;
  3901. let signature;
  3902. const { writable } = writer;
  3903. if (reader) {
  3904. reader.chunkSize = getChunkSize(config);
  3905. await writeData$1(writable, localHeaderArray);
  3906. const readable = reader.readable;
  3907. const size = readable.size = reader.size;
  3908. const workerOptions = {
  3909. options: {
  3910. codecType: CODEC_DEFLATE,
  3911. level,
  3912. password,
  3913. encryptionStrength,
  3914. zipCrypto: encrypted && zipCrypto,
  3915. passwordVerification: encrypted && zipCrypto && (rawLastModDate >> 8) & 0xFF,
  3916. signed: true,
  3917. compressed,
  3918. encrypted,
  3919. useWebWorkers,
  3920. useCompressionStream,
  3921. transferStreams: false
  3922. },
  3923. config,
  3924. streamOptions: { signal, size, onstart, onprogress, onend }
  3925. };
  3926. const result = await runWorker({ readable, writable }, workerOptions);
  3927. writable.size += result.size;
  3928. signature = result.signature;
  3929. uncompressedSize = reader.size = readable.size;
  3930. compressedSize = result.size;
  3931. } else {
  3932. await writeData$1(writable, localHeaderArray);
  3933. }
  3934. let rawExtraFieldZip64;
  3935. if (zip64) {
  3936. let rawExtraFieldZip64Length = 4;
  3937. if (zip64UncompressedSize) {
  3938. rawExtraFieldZip64Length += 8;
  3939. }
  3940. if (zip64CompressedSize) {
  3941. rawExtraFieldZip64Length += 8;
  3942. }
  3943. if (zip64Offset) {
  3944. rawExtraFieldZip64Length += 8;
  3945. }
  3946. if (zip64DiskNumberStart) {
  3947. rawExtraFieldZip64Length += 4;
  3948. }
  3949. rawExtraFieldZip64 = new Uint8Array$1(rawExtraFieldZip64Length);
  3950. } else {
  3951. rawExtraFieldZip64 = new Uint8Array$1();
  3952. }
  3953. setEntryInfo({
  3954. signature,
  3955. rawExtraFieldZip64,
  3956. compressedSize,
  3957. uncompressedSize,
  3958. headerInfo,
  3959. dataDescriptorInfo
  3960. }, options);
  3961. if (dataDescriptor) {
  3962. await writeData$1(writable, dataDescriptorArray);
  3963. }
  3964. Object$1.assign(fileEntry, {
  3965. uncompressedSize,
  3966. compressedSize,
  3967. lastModDate,
  3968. rawLastModDate,
  3969. creationDate,
  3970. lastAccessDate,
  3971. encrypted,
  3972. length: metadataSize + compressedSize,
  3973. compressionMethod,
  3974. version,
  3975. headerArray,
  3976. signature,
  3977. rawExtraFieldZip64,
  3978. extraFieldExtendedTimestampFlag,
  3979. zip64UncompressedSize,
  3980. zip64CompressedSize,
  3981. zip64Offset,
  3982. zip64DiskNumberStart
  3983. });
  3984. return fileEntry;
  3985. }
  3986. function getHeaderInfo(options) {
  3987. const {
  3988. rawFilename,
  3989. lastModDate,
  3990. lastAccessDate,
  3991. creationDate,
  3992. password,
  3993. level,
  3994. zip64,
  3995. zipCrypto,
  3996. dataDescriptor,
  3997. directory,
  3998. rawExtraField,
  3999. encryptionStrength,
  4000. extendedTimestamp
  4001. } = options;
  4002. const compressed = level !== 0 && !directory;
  4003. const encrypted = Boolean(password && getLength(password));
  4004. let version = options.version;
  4005. let rawExtraFieldAES;
  4006. if (encrypted && !zipCrypto) {
  4007. rawExtraFieldAES = new Uint8Array$1(getLength(EXTRAFIELD_DATA_AES) + 2);
  4008. const extraFieldAESView = getDataView(rawExtraFieldAES);
  4009. setUint16(extraFieldAESView, 0, EXTRAFIELD_TYPE_AES);
  4010. arraySet(rawExtraFieldAES, EXTRAFIELD_DATA_AES, 2);
  4011. setUint8(extraFieldAESView, 8, encryptionStrength);
  4012. } else {
  4013. rawExtraFieldAES = new Uint8Array$1();
  4014. }
  4015. let rawExtraFieldNTFS;
  4016. let rawExtraFieldExtendedTimestamp;
  4017. let extraFieldExtendedTimestampFlag;
  4018. if (extendedTimestamp) {
  4019. rawExtraFieldExtendedTimestamp = new Uint8Array$1(9 + (lastAccessDate ? 4 : 0) + (creationDate ? 4 : 0));
  4020. const extraFieldExtendedTimestampView = getDataView(rawExtraFieldExtendedTimestamp);
  4021. setUint16(extraFieldExtendedTimestampView, 0, EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
  4022. setUint16(extraFieldExtendedTimestampView, 2, getLength(rawExtraFieldExtendedTimestamp) - 4);
  4023. extraFieldExtendedTimestampFlag = 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0);
  4024. setUint8(extraFieldExtendedTimestampView, 4, extraFieldExtendedTimestampFlag);
  4025. let offset = 5;
  4026. setUint32(extraFieldExtendedTimestampView, offset, Math$1.floor(lastModDate.getTime() / 1000));
  4027. offset += 4;
  4028. if (lastAccessDate) {
  4029. setUint32(extraFieldExtendedTimestampView, offset, Math$1.floor(lastAccessDate.getTime() / 1000));
  4030. offset += 4;
  4031. }
  4032. if (creationDate) {
  4033. setUint32(extraFieldExtendedTimestampView, offset, Math$1.floor(creationDate.getTime() / 1000));
  4034. }
  4035. try {
  4036. rawExtraFieldNTFS = new Uint8Array$1(36);
  4037. const extraFieldNTFSView = getDataView(rawExtraFieldNTFS);
  4038. const lastModTimeNTFS = getTimeNTFS(lastModDate);
  4039. setUint16(extraFieldNTFSView, 0, EXTRAFIELD_TYPE_NTFS);
  4040. setUint16(extraFieldNTFSView, 2, 32);
  4041. setUint16(extraFieldNTFSView, 8, EXTRAFIELD_TYPE_NTFS_TAG1);
  4042. setUint16(extraFieldNTFSView, 10, 24);
  4043. setBigUint64(extraFieldNTFSView, 12, lastModTimeNTFS);
  4044. setBigUint64(extraFieldNTFSView, 20, getTimeNTFS(lastAccessDate) || lastModTimeNTFS);
  4045. setBigUint64(extraFieldNTFSView, 28, getTimeNTFS(creationDate) || lastModTimeNTFS);
  4046. } catch (_error) {
  4047. rawExtraFieldNTFS = new Uint8Array$1();
  4048. }
  4049. } else {
  4050. rawExtraFieldNTFS = rawExtraFieldExtendedTimestamp = new Uint8Array$1();
  4051. }
  4052. let bitFlag = BITFLAG_LANG_ENCODING_FLAG;
  4053. if (dataDescriptor) {
  4054. bitFlag = bitFlag | BITFLAG_DATA_DESCRIPTOR;
  4055. }
  4056. let compressionMethod = COMPRESSION_METHOD_STORE;
  4057. if (compressed) {
  4058. compressionMethod = COMPRESSION_METHOD_DEFLATE;
  4059. }
  4060. if (zip64) {
  4061. version = version > VERSION_ZIP64 ? version : VERSION_ZIP64;
  4062. }
  4063. if (encrypted) {
  4064. bitFlag = bitFlag | BITFLAG_ENCRYPTED;
  4065. if (!zipCrypto) {
  4066. version = version > VERSION_AES ? version : VERSION_AES;
  4067. compressionMethod = COMPRESSION_METHOD_AES;
  4068. if (compressed) {
  4069. rawExtraFieldAES[9] = COMPRESSION_METHOD_DEFLATE;
  4070. }
  4071. }
  4072. }
  4073. const headerArray = new Uint8Array$1(26);
  4074. const headerView = getDataView(headerArray);
  4075. setUint16(headerView, 0, version);
  4076. setUint16(headerView, 2, bitFlag);
  4077. setUint16(headerView, 4, compressionMethod);
  4078. const dateArray = new Uint32Array$1(1);
  4079. const dateView = getDataView(dateArray);
  4080. let lastModDateMsDos;
  4081. if (lastModDate < MIN_DATE) {
  4082. lastModDateMsDos = MIN_DATE;
  4083. } else if (lastModDate > MAX_DATE) {
  4084. lastModDateMsDos = MAX_DATE;
  4085. } else {
  4086. lastModDateMsDos = lastModDate;
  4087. }
  4088. setUint16(dateView, 0, (((lastModDateMsDos.getHours() << 6) | lastModDateMsDos.getMinutes()) << 5) | lastModDateMsDos.getSeconds() / 2);
  4089. setUint16(dateView, 2, ((((lastModDateMsDos.getFullYear() - 1980) << 4) | (lastModDateMsDos.getMonth() + 1)) << 5) | lastModDateMsDos.getDate());
  4090. const rawLastModDate = dateArray[0];
  4091. setUint32(headerView, 6, rawLastModDate);
  4092. setUint16(headerView, 22, getLength(rawFilename));
  4093. const extraFieldLength = getLength(rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraField);
  4094. setUint16(headerView, 24, extraFieldLength);
  4095. const localHeaderArray = new Uint8Array$1(30 + getLength(rawFilename) + extraFieldLength);
  4096. const localHeaderView = getDataView(localHeaderArray);
  4097. setUint32(localHeaderView, 0, LOCAL_FILE_HEADER_SIGNATURE);
  4098. arraySet(localHeaderArray, headerArray, 4);
  4099. arraySet(localHeaderArray, rawFilename, 30);
  4100. arraySet(localHeaderArray, rawExtraFieldAES, 30 + getLength(rawFilename));
  4101. arraySet(localHeaderArray, rawExtraFieldExtendedTimestamp, 30 + getLength(rawFilename, rawExtraFieldAES));
  4102. arraySet(localHeaderArray, rawExtraFieldNTFS, 30 + getLength(rawFilename, rawExtraFieldAES, rawExtraFieldExtendedTimestamp));
  4103. arraySet(localHeaderArray, rawExtraField, 30 + getLength(rawFilename, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS));
  4104. return {
  4105. localHeaderArray,
  4106. headerArray,
  4107. headerView,
  4108. lastModDate,
  4109. rawLastModDate,
  4110. encrypted,
  4111. compressed,
  4112. version,
  4113. compressionMethod,
  4114. extraFieldExtendedTimestampFlag,
  4115. rawExtraFieldExtendedTimestamp,
  4116. rawExtraFieldNTFS,
  4117. rawExtraFieldAES,
  4118. extraFieldLength
  4119. };
  4120. }
  4121. function appendExtraFieldUSDZ(entryInfo, zipWriterOffset) {
  4122. const { headerInfo } = entryInfo;
  4123. let { localHeaderArray, extraFieldLength } = headerInfo;
  4124. let localHeaderArrayView = getDataView(localHeaderArray);
  4125. let extraBytesLength = 64 - ((zipWriterOffset + localHeaderArray.length) % 64);
  4126. if (extraBytesLength < 4) {
  4127. extraBytesLength += 64;
  4128. }
  4129. const rawExtraFieldUSDZ = new Uint8Array$1(extraBytesLength);
  4130. const extraFieldUSDZView = getDataView(rawExtraFieldUSDZ);
  4131. setUint16(extraFieldUSDZView, 0, EXTRAFIELD_TYPE_USDZ);
  4132. setUint16(extraFieldUSDZView, 2, extraBytesLength - 2);
  4133. const previousLocalHeaderArray = localHeaderArray;
  4134. headerInfo.localHeaderArray = localHeaderArray = new Uint8Array$1(previousLocalHeaderArray.length + extraBytesLength);
  4135. arraySet(localHeaderArray, previousLocalHeaderArray);
  4136. arraySet(localHeaderArray, rawExtraFieldUSDZ, previousLocalHeaderArray.length);
  4137. localHeaderArrayView = getDataView(localHeaderArray);
  4138. setUint16(localHeaderArrayView, 28, extraFieldLength + extraBytesLength);
  4139. entryInfo.metadataSize += extraBytesLength;
  4140. }
  4141. function getDataDescriptorInfo(options) {
  4142. const {
  4143. zip64,
  4144. dataDescriptor,
  4145. dataDescriptorSignature
  4146. } = options;
  4147. let dataDescriptorArray = new Uint8Array$1();
  4148. let dataDescriptorView, dataDescriptorOffset = 0;
  4149. if (dataDescriptor) {
  4150. dataDescriptorArray = new Uint8Array$1(zip64 ? (dataDescriptorSignature ? 24 : 20) : (dataDescriptorSignature ? 16 : 12));
  4151. dataDescriptorView = getDataView(dataDescriptorArray);
  4152. if (dataDescriptorSignature) {
  4153. dataDescriptorOffset = 4;
  4154. setUint32(dataDescriptorView, 0, DATA_DESCRIPTOR_RECORD_SIGNATURE);
  4155. }
  4156. }
  4157. return {
  4158. dataDescriptorArray,
  4159. dataDescriptorView,
  4160. dataDescriptorOffset
  4161. };
  4162. }
  4163. function setEntryInfo(entryInfo, options) {
  4164. const {
  4165. signature,
  4166. rawExtraFieldZip64,
  4167. compressedSize,
  4168. uncompressedSize,
  4169. headerInfo,
  4170. dataDescriptorInfo
  4171. } = entryInfo;
  4172. const {
  4173. headerView,
  4174. encrypted
  4175. } = headerInfo;
  4176. const {
  4177. dataDescriptorView,
  4178. dataDescriptorOffset
  4179. } = dataDescriptorInfo;
  4180. const {
  4181. zip64,
  4182. zip64UncompressedSize,
  4183. zip64CompressedSize,
  4184. zipCrypto,
  4185. dataDescriptor
  4186. } = options;
  4187. if ((!encrypted || zipCrypto) && signature !== UNDEFINED_VALUE) {
  4188. setUint32(headerView, 10, signature);
  4189. if (dataDescriptor) {
  4190. setUint32(dataDescriptorView, dataDescriptorOffset, signature);
  4191. }
  4192. }
  4193. if (zip64) {
  4194. const rawExtraFieldZip64View = getDataView(rawExtraFieldZip64);
  4195. setUint16(rawExtraFieldZip64View, 0, EXTRAFIELD_TYPE_ZIP64);
  4196. setUint16(rawExtraFieldZip64View, 2, rawExtraFieldZip64.length - 4);
  4197. let rawExtraFieldZip64Offset = 4;
  4198. if (zip64UncompressedSize) {
  4199. setUint32(headerView, 18, MAX_32_BITS);
  4200. setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(uncompressedSize));
  4201. rawExtraFieldZip64Offset += 8;
  4202. }
  4203. if (zip64CompressedSize) {
  4204. setUint32(headerView, 14, MAX_32_BITS);
  4205. setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(compressedSize));
  4206. }
  4207. if (dataDescriptor) {
  4208. setBigUint64(dataDescriptorView, dataDescriptorOffset + 4, BigInt(compressedSize));
  4209. setBigUint64(dataDescriptorView, dataDescriptorOffset + 12, BigInt(uncompressedSize));
  4210. }
  4211. } else {
  4212. setUint32(headerView, 14, compressedSize);
  4213. setUint32(headerView, 18, uncompressedSize);
  4214. if (dataDescriptor) {
  4215. setUint32(dataDescriptorView, dataDescriptorOffset + 4, compressedSize);
  4216. setUint32(dataDescriptorView, dataDescriptorOffset + 8, uncompressedSize);
  4217. }
  4218. }
  4219. }
  4220. async function writeExtraHeaderInfo(fileEntry, entryData, writable, { zipCrypto }) {
  4221. let arrayBuffer;
  4222. arrayBuffer = await entryData.slice(0, 26).arrayBuffer();
  4223. if (arrayBuffer.byteLength != 26) {
  4224. arrayBuffer = arrayBuffer.slice(0, 26);
  4225. }
  4226. const arrayBufferView = new DataView$1(arrayBuffer);
  4227. if (!fileEntry.encrypted || zipCrypto) {
  4228. setUint32(arrayBufferView, 14, fileEntry.signature);
  4229. }
  4230. if (fileEntry.zip64) {
  4231. setUint32(arrayBufferView, 18, MAX_32_BITS);
  4232. setUint32(arrayBufferView, 22, MAX_32_BITS);
  4233. } else {
  4234. setUint32(arrayBufferView, 18, fileEntry.compressedSize);
  4235. setUint32(arrayBufferView, 22, fileEntry.uncompressedSize);
  4236. }
  4237. await writeData$1(writable, new Uint8Array$1(arrayBuffer));
  4238. return entryData.slice(arrayBuffer.byteLength);
  4239. }
  4240. function setZip64ExtraInfo(fileEntry, options) {
  4241. const { rawExtraFieldZip64, offset, diskNumberStart } = fileEntry;
  4242. const { zip64UncompressedSize, zip64CompressedSize, zip64Offset, zip64DiskNumberStart } = options;
  4243. const rawExtraFieldZip64View = getDataView(rawExtraFieldZip64);
  4244. let rawExtraFieldZip64Offset = 4;
  4245. if (zip64UncompressedSize) {
  4246. rawExtraFieldZip64Offset += 8;
  4247. }
  4248. if (zip64CompressedSize) {
  4249. rawExtraFieldZip64Offset += 8;
  4250. }
  4251. if (zip64Offset) {
  4252. setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(offset));
  4253. rawExtraFieldZip64Offset += 8;
  4254. }
  4255. if (zip64DiskNumberStart) {
  4256. setUint32(rawExtraFieldZip64View, rawExtraFieldZip64Offset, diskNumberStart);
  4257. }
  4258. }
  4259. async function closeFile(zipWriter, comment, options) {
  4260. const { files, writer } = zipWriter;
  4261. const { diskOffset, writable } = writer;
  4262. let { diskNumber } = writer;
  4263. let offset = 0;
  4264. let directoryDataLength = 0;
  4265. let directoryOffset = zipWriter.offset - diskOffset;
  4266. let filesLength = files.size;
  4267. for (const [, fileEntry] of files) {
  4268. const {
  4269. rawFilename,
  4270. rawExtraFieldZip64,
  4271. rawExtraFieldAES,
  4272. rawComment,
  4273. rawExtraFieldNTFS,
  4274. rawExtraField,
  4275. extendedTimestamp,
  4276. extraFieldExtendedTimestampFlag,
  4277. lastModDate
  4278. } = fileEntry;
  4279. let rawExtraFieldTimestamp;
  4280. if (extendedTimestamp) {
  4281. rawExtraFieldTimestamp = new Uint8Array$1(9);
  4282. const extraFieldExtendedTimestampView = getDataView(rawExtraFieldTimestamp);
  4283. setUint16(extraFieldExtendedTimestampView, 0, EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
  4284. setUint16(extraFieldExtendedTimestampView, 2, 5);
  4285. setUint8(extraFieldExtendedTimestampView, 4, extraFieldExtendedTimestampFlag);
  4286. setUint32(extraFieldExtendedTimestampView, 5, Math$1.floor(lastModDate.getTime() / 1000));
  4287. } else {
  4288. rawExtraFieldTimestamp = new Uint8Array$1();
  4289. }
  4290. fileEntry.rawExtraFieldCDExtendedTimestamp = rawExtraFieldTimestamp;
  4291. directoryDataLength += 46 +
  4292. getLength(
  4293. rawFilename,
  4294. rawComment,
  4295. rawExtraFieldZip64,
  4296. rawExtraFieldAES,
  4297. rawExtraFieldNTFS,
  4298. rawExtraFieldTimestamp,
  4299. rawExtraField);
  4300. }
  4301. const directoryArray = new Uint8Array$1(directoryDataLength);
  4302. const directoryView = getDataView(directoryArray);
  4303. await initStream(writer);
  4304. let directoryDiskOffset = 0;
  4305. for (const [indexFileEntry, fileEntry] of Array$1.from(files.values()).entries()) {
  4306. const {
  4307. offset: fileEntryOffset,
  4308. rawFilename,
  4309. rawExtraFieldZip64,
  4310. rawExtraFieldAES,
  4311. rawExtraFieldCDExtendedTimestamp,
  4312. rawExtraFieldNTFS,
  4313. rawExtraField,
  4314. rawComment,
  4315. versionMadeBy,
  4316. headerArray,
  4317. directory,
  4318. zip64,
  4319. zip64UncompressedSize,
  4320. zip64CompressedSize,
  4321. zip64DiskNumberStart,
  4322. zip64Offset,
  4323. msDosCompatible,
  4324. internalFileAttribute,
  4325. externalFileAttribute,
  4326. diskNumberStart,
  4327. uncompressedSize,
  4328. compressedSize
  4329. } = fileEntry;
  4330. const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldCDExtendedTimestamp, rawExtraFieldNTFS, rawExtraField);
  4331. setUint32(directoryView, offset, CENTRAL_FILE_HEADER_SIGNATURE);
  4332. setUint16(directoryView, offset + 4, versionMadeBy);
  4333. const headerView = getDataView(headerArray);
  4334. if (!zip64UncompressedSize) {
  4335. setUint32(headerView, 18, uncompressedSize);
  4336. }
  4337. if (!zip64CompressedSize) {
  4338. setUint32(headerView, 14, compressedSize);
  4339. }
  4340. arraySet(directoryArray, headerArray, offset + 6);
  4341. setUint16(directoryView, offset + 30, extraFieldLength);
  4342. setUint16(directoryView, offset + 32, getLength(rawComment));
  4343. setUint16(directoryView, offset + 34, zip64 && zip64DiskNumberStart ? MAX_16_BITS : diskNumberStart);
  4344. setUint16(directoryView, offset + 36, internalFileAttribute);
  4345. if (externalFileAttribute) {
  4346. setUint32(directoryView, offset + 38, externalFileAttribute);
  4347. } else if (directory && msDosCompatible) {
  4348. setUint8(directoryView, offset + 38, FILE_ATTR_MSDOS_DIR_MASK);
  4349. }
  4350. setUint32(directoryView, offset + 42, zip64 && zip64Offset ? MAX_32_BITS : fileEntryOffset);
  4351. arraySet(directoryArray, rawFilename, offset + 46);
  4352. arraySet(directoryArray, rawExtraFieldZip64, offset + 46 + getLength(rawFilename));
  4353. arraySet(directoryArray, rawExtraFieldAES, offset + 46 + getLength(rawFilename, rawExtraFieldZip64));
  4354. arraySet(directoryArray, rawExtraFieldCDExtendedTimestamp, offset + 46 + getLength(rawFilename, rawExtraFieldZip64, rawExtraFieldAES));
  4355. arraySet(directoryArray, rawExtraFieldNTFS, offset + 46 + getLength(rawFilename, rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldCDExtendedTimestamp));
  4356. arraySet(directoryArray, rawExtraField, offset + 46 + getLength(rawFilename, rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldCDExtendedTimestamp, rawExtraFieldNTFS));
  4357. arraySet(directoryArray, rawComment, offset + 46 + getLength(rawFilename) + extraFieldLength);
  4358. const directoryEntryLength = 46 + getLength(rawFilename, rawComment) + extraFieldLength;
  4359. if (offset - directoryDiskOffset > writer.availableSize) {
  4360. writer.availableSize = 0;
  4361. await writeData$1(writable, directoryArray.slice(directoryDiskOffset, offset));
  4362. directoryDiskOffset = offset;
  4363. }
  4364. offset += directoryEntryLength;
  4365. if (options.onprogress) {
  4366. try {
  4367. await options.onprogress(indexFileEntry + 1, files.size, new Entry(fileEntry));
  4368. } catch (_error) {
  4369. // ignored
  4370. }
  4371. }
  4372. }
  4373. await writeData$1(writable, directoryDiskOffset ? directoryArray.slice(directoryDiskOffset) : directoryArray);
  4374. let lastDiskNumber = writer.diskNumber;
  4375. const { availableSize } = writer;
  4376. if (availableSize < END_OF_CENTRAL_DIR_LENGTH) {
  4377. lastDiskNumber++;
  4378. }
  4379. let zip64 = getOptionValue(zipWriter, options, "zip64");
  4380. if (directoryOffset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS || filesLength >= MAX_16_BITS || lastDiskNumber >= MAX_16_BITS) {
  4381. if (zip64 === false) {
  4382. throw new Error$1(ERR_UNSUPPORTED_FORMAT);
  4383. } else {
  4384. zip64 = true;
  4385. }
  4386. }
  4387. const endOfdirectoryArray = new Uint8Array$1(zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
  4388. const endOfdirectoryView = getDataView(endOfdirectoryArray);
  4389. offset = 0;
  4390. if (zip64) {
  4391. setUint32(endOfdirectoryView, 0, ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
  4392. setBigUint64(endOfdirectoryView, 4, BigInt(44));
  4393. setUint16(endOfdirectoryView, 12, 45);
  4394. setUint16(endOfdirectoryView, 14, 45);
  4395. setUint32(endOfdirectoryView, 16, lastDiskNumber);
  4396. setUint32(endOfdirectoryView, 20, diskNumber);
  4397. setBigUint64(endOfdirectoryView, 24, BigInt(filesLength));
  4398. setBigUint64(endOfdirectoryView, 32, BigInt(filesLength));
  4399. setBigUint64(endOfdirectoryView, 40, BigInt(directoryDataLength));
  4400. setBigUint64(endOfdirectoryView, 48, BigInt(directoryOffset));
  4401. setUint32(endOfdirectoryView, 56, ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
  4402. setBigUint64(endOfdirectoryView, 64, BigInt(directoryOffset) + BigInt(directoryDataLength));
  4403. setUint32(endOfdirectoryView, 72, lastDiskNumber + 1);
  4404. const supportZip64SplitFile = getOptionValue(zipWriter, options, "supportZip64SplitFile", true);
  4405. if (supportZip64SplitFile) {
  4406. lastDiskNumber = MAX_16_BITS;
  4407. diskNumber = MAX_16_BITS;
  4408. }
  4409. filesLength = MAX_16_BITS;
  4410. directoryOffset = MAX_32_BITS;
  4411. directoryDataLength = MAX_32_BITS;
  4412. offset += ZIP64_END_OF_CENTRAL_DIR_LENGTH + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH;
  4413. }
  4414. setUint32(endOfdirectoryView, offset, END_OF_CENTRAL_DIR_SIGNATURE);
  4415. setUint16(endOfdirectoryView, offset + 4, lastDiskNumber);
  4416. setUint16(endOfdirectoryView, offset + 6, diskNumber);
  4417. setUint16(endOfdirectoryView, offset + 8, filesLength);
  4418. setUint16(endOfdirectoryView, offset + 10, filesLength);
  4419. setUint32(endOfdirectoryView, offset + 12, directoryDataLength);
  4420. setUint32(endOfdirectoryView, offset + 16, directoryOffset);
  4421. const commentLength = getLength(comment);
  4422. if (commentLength) {
  4423. if (commentLength <= MAX_16_BITS) {
  4424. setUint16(endOfdirectoryView, offset + 20, commentLength);
  4425. } else {
  4426. throw new Error$1(ERR_INVALID_COMMENT);
  4427. }
  4428. }
  4429. await writeData$1(writable, endOfdirectoryArray);
  4430. if (commentLength) {
  4431. await writeData$1(writable, comment);
  4432. }
  4433. }
  4434. async function writeData$1(writable, array) {
  4435. const streamWriter = writable.getWriter();
  4436. await streamWriter.ready;
  4437. writable.size += getLength(array);
  4438. await streamWriter.write(array);
  4439. streamWriter.releaseLock();
  4440. }
  4441. function getTimeNTFS(date) {
  4442. if (date) {
  4443. return ((BigInt(date.getTime()) + BigInt(11644473600000)) * BigInt(10000));
  4444. }
  4445. }
  4446. function getOptionValue(zipWriter, options, name, defaultValue) {
  4447. const result = options[name] === UNDEFINED_VALUE ? zipWriter.options[name] : options[name];
  4448. return result === UNDEFINED_VALUE ? defaultValue : result;
  4449. }
  4450. function getMaximumCompressedSize(uncompressedSize) {
  4451. return uncompressedSize + (5 * (Math$1.floor(uncompressedSize / 16383) + 1));
  4452. }
  4453. function setUint8(view, offset, value) {
  4454. view.setUint8(offset, value);
  4455. }
  4456. function setUint16(view, offset, value) {
  4457. view.setUint16(offset, value, true);
  4458. }
  4459. function setUint32(view, offset, value) {
  4460. view.setUint32(offset, value, true);
  4461. }
  4462. function setBigUint64(view, offset, value) {
  4463. view.setBigUint64(offset, value, true);
  4464. }
  4465. function arraySet(array, typedArray, offset) {
  4466. array.set(typedArray, offset);
  4467. }
  4468. function getDataView(array) {
  4469. return new DataView$1(array.buffer);
  4470. }
  4471. function getLength(...arrayLikes) {
  4472. let result = 0;
  4473. arrayLikes.forEach(arrayLike => arrayLike && (result += arrayLike.length));
  4474. return result;
  4475. }
  4476. /*
  4477. Copyright (c) 2022 Gildas Lormeau. All rights reserved.
  4478. Redistribution and use in source and binary forms, with or without
  4479. modification, are permitted provided that the following conditions are met:
  4480. 1. Redistributions of source code must retain the above copyright notice,
  4481. this list of conditions and the following disclaimer.
  4482. 2. Redistributions in binary form must reproduce the above copyright
  4483. notice, this list of conditions and the following disclaimer in
  4484. the documentation and/or other materials provided with the distribution.
  4485. 3. The names of the authors may not be used to endorse or promote products
  4486. derived from this software without specific prior written permission.
  4487. THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  4488. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  4489. FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
  4490. INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
  4491. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  4492. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  4493. OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  4494. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  4495. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  4496. EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  4497. */
  4498. let baseURL;
  4499. try {
  4500. baseURL = (typeof document === 'undefined' && typeof location === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : typeof document === 'undefined' ? location.href : (document.currentScript && document.currentScript.src || new URL('single-file.js', document.baseURI).href));
  4501. } catch (_error) {
  4502. // ignored
  4503. }
  4504. configure({ baseURL });
  4505. e(configure);
  4506. var zip$1 = /*#__PURE__*/Object.freeze({
  4507. __proto__: null,
  4508. BlobReader: BlobReader,
  4509. BlobWriter: BlobWriter,
  4510. Data64URIReader: Data64URIReader,
  4511. Data64URIWriter: Data64URIWriter,
  4512. ERR_BAD_FORMAT: ERR_BAD_FORMAT,
  4513. ERR_CENTRAL_DIRECTORY_NOT_FOUND: ERR_CENTRAL_DIRECTORY_NOT_FOUND,
  4514. ERR_DUPLICATED_NAME: ERR_DUPLICATED_NAME,
  4515. ERR_ENCRYPTED: ERR_ENCRYPTED,
  4516. ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND: ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND,
  4517. ERR_EOCDR_NOT_FOUND: ERR_EOCDR_NOT_FOUND,
  4518. ERR_EOCDR_ZIP64_NOT_FOUND: ERR_EOCDR_ZIP64_NOT_FOUND,
  4519. ERR_EXTRAFIELD_ZIP64_NOT_FOUND: ERR_EXTRAFIELD_ZIP64_NOT_FOUND,
  4520. ERR_HTTP_RANGE: ERR_HTTP_RANGE,
  4521. ERR_INVALID_COMMENT: ERR_INVALID_COMMENT,
  4522. ERR_INVALID_ENCRYPTION_STRENGTH: ERR_INVALID_ENCRYPTION_STRENGTH,
  4523. ERR_INVALID_ENTRY_COMMENT: ERR_INVALID_ENTRY_COMMENT,
  4524. ERR_INVALID_ENTRY_NAME: ERR_INVALID_ENTRY_NAME,
  4525. ERR_INVALID_EXTRAFIELD_DATA: ERR_INVALID_EXTRAFIELD_DATA,
  4526. ERR_INVALID_EXTRAFIELD_TYPE: ERR_INVALID_EXTRAFIELD_TYPE,
  4527. ERR_INVALID_PASSWORD: ERR_INVALID_PASSWORD,
  4528. ERR_INVALID_SIGNATURE: ERR_INVALID_SIGNATURE,
  4529. ERR_INVALID_VERSION: ERR_INVALID_VERSION,
  4530. ERR_ITERATOR_COMPLETED_TOO_SOON: ERR_ITERATOR_COMPLETED_TOO_SOON,
  4531. ERR_LOCAL_FILE_HEADER_NOT_FOUND: ERR_LOCAL_FILE_HEADER_NOT_FOUND,
  4532. ERR_SPLIT_ZIP_FILE: ERR_SPLIT_ZIP_FILE,
  4533. ERR_UNSUPPORTED_COMPRESSION: ERR_UNSUPPORTED_COMPRESSION,
  4534. ERR_UNSUPPORTED_ENCRYPTION: ERR_UNSUPPORTED_ENCRYPTION,
  4535. ERR_UNSUPPORTED_FORMAT: ERR_UNSUPPORTED_FORMAT,
  4536. HttpRangeReader: HttpRangeReader,
  4537. HttpReader: HttpReader,
  4538. Reader: Reader,
  4539. SplitDataReader: SplitDataReader,
  4540. SplitDataWriter: SplitDataWriter,
  4541. SplitZipReader: SplitZipReader,
  4542. SplitZipWriter: SplitZipWriter,
  4543. TextReader: TextReader,
  4544. TextWriter: TextWriter,
  4545. Uint8ArrayReader: Uint8ArrayReader,
  4546. Uint8ArrayWriter: Uint8ArrayWriter,
  4547. Writer: Writer,
  4548. ZipReader: ZipReader,
  4549. ZipWriter: ZipWriter,
  4550. configure: configure,
  4551. getMimeType: getMimeType,
  4552. initReader: initReader,
  4553. initShimAsyncCodec: initShimAsyncCodec,
  4554. initStream: initStream,
  4555. initWriter: initWriter,
  4556. readUint8Array: readUint8Array,
  4557. terminateWorkers: terminateWorkers
  4558. });
  4559. /*
  4560. * Copyright 2010-2022 Gildas Lormeau
  4561. * contact : gildas.lormeau <at> gmail.com
  4562. *
  4563. * This file is part of SingleFile.
  4564. *
  4565. * The code in this file is free software: you can redistribute it and/or
  4566. * modify it under the terms of the GNU Affero General Public License
  4567. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  4568. * of the License, or (at your option) any later version.
  4569. *
  4570. * The code in this file is distributed in the hope that it will be useful,
  4571. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4572. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  4573. * General Public License for more details.
  4574. *
  4575. * As additional permission under GNU AGPL version 3 section 7, you may
  4576. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  4577. * AGPL normally required by section 4, provided you include this license
  4578. * notice and a URL through which recipients can access the Corresponding
  4579. * Source.
  4580. */
  4581. async function extract(content, { password, prompt = () => { }, shadowRootScriptURL, zipOptions = { useWebWorkers: false }, noBlobURL } = {}) {
  4582. const KNOWN_MIMETYPES = {
  4583. "gif": "image/gif",
  4584. "jpg": "image/jpeg",
  4585. "png": "image/png",
  4586. "tif": "image/tiff",
  4587. "tiff": "image/tiff",
  4588. "bmp": "image/bmp",
  4589. "ico": "image/vnd.microsoft.icon",
  4590. "webp": "image/webp",
  4591. "svg": "image/svg+xml",
  4592. "avi": "video/x-msvideo",
  4593. "ogv": "video/ogg",
  4594. "mp4": "video/mp4",
  4595. "mpeg": "video/mpeg",
  4596. "ts": "video/mp2t",
  4597. "webm": "video/webm",
  4598. "3gp": "video/3gpp",
  4599. "3g2": "video/3gpp",
  4600. "mp3": "audio/mpeg",
  4601. "oga": "audio/ogg",
  4602. "mid": "audio/midi",
  4603. "midi": "audio/midi",
  4604. "opus": "audio/opus",
  4605. "wav": "audio/wav",
  4606. "weba": "audio/webm"
  4607. };
  4608. if (Array.isArray(content)) {
  4609. content = new Blob([new Uint8Array(content)]);
  4610. }
  4611. zip.configure(zipOptions);
  4612. const blobReader = new zip.BlobReader(content);
  4613. let resources = [];
  4614. const zipReader = new zip.ZipReader(blobReader);
  4615. const entries = await zipReader.getEntries();
  4616. const options = { password };
  4617. await Promise.all(entries.map(async entry => {
  4618. let dataWriter, content, textContent, name, blob;
  4619. if (!options.password && entry.encrypted) {
  4620. options.password = prompt("Please enter the password to view the page");
  4621. }
  4622. name = entry.filename.match(/^([0-9_]+\/)?(.*)$/)[2];
  4623. if (entry.filename.match(/index\.html$/) || entry.filename.match(/stylesheet_[0-9]+\.css/) || entry.filename.match(/scripts\/[0-9]+\.js/)) {
  4624. dataWriter = new zip.TextWriter();
  4625. textContent = await entry.getData(dataWriter, options);
  4626. } else {
  4627. const extension = entry.filename.match(/\.([^.]+)/);
  4628. let mimeType;
  4629. if (extension && extension[1] && KNOWN_MIMETYPES[extension[1]]) {
  4630. mimeType = KNOWN_MIMETYPES[extension[1]];
  4631. } else {
  4632. mimeType = "application/octet-stream";
  4633. }
  4634. if (entry.filename.match(/frames\//) || noBlobURL) {
  4635. content = await entry.getData(new zip.Data64URIWriter(mimeType), options);
  4636. } else {
  4637. blob = await entry.getData(new zip.BlobWriter(mimeType), options);
  4638. content = URL.createObjectURL(blob);
  4639. }
  4640. }
  4641. resources.push({ filename: entry.filename, name, url: entry.comment, content, blob, textContent, parentResources: [] });
  4642. }));
  4643. await zipReader.close();
  4644. let docContent, origDocContent, url;
  4645. resources = resources.sort((resourceLeft, resourceRight) => resourceRight.filename.length - resourceLeft.filename.length);
  4646. const REGEXP_ESCAPE = /([{}()^$&.*?/+|[\\\\]|\]|-)/g;
  4647. for (const resource of resources) {
  4648. if (resource.textContent !== undefined) {
  4649. let prefixPath = "";
  4650. const prefixPathMatch = resource.filename.match(/(.*\/)[^/]+$/);
  4651. if (prefixPathMatch && prefixPathMatch[1]) {
  4652. prefixPath = prefixPathMatch[1];
  4653. }
  4654. if (resource.filename.match(/^([0-9_]+\/)?index\.html$/)) {
  4655. origDocContent = resource.textContent;
  4656. }
  4657. const isScript = resource.filename.match(/scripts\/[0-9]+\.js/);
  4658. if (!isScript) {
  4659. resources.forEach(innerResource => {
  4660. if (innerResource.filename.startsWith(prefixPath) && innerResource.filename != resource.filename) {
  4661. const filename = innerResource.filename.substring(prefixPath.length);
  4662. if (!filename.match(/manifest\.json$/)) {
  4663. const searchRegExp = new RegExp(filename.replace(REGEXP_ESCAPE, "\\$1"), "g");
  4664. const position = resource.textContent.search(searchRegExp);
  4665. if (position != -1) {
  4666. innerResource.parentResources.push(resource.filename);
  4667. resource.textContent = resource.textContent.replace(searchRegExp, innerResource.content);
  4668. }
  4669. }
  4670. }
  4671. });
  4672. }
  4673. let mimeType;
  4674. if (resource.filename.match(/stylesheet_[0-9]+\.css/)) {
  4675. mimeType = "text/css";
  4676. } else if (isScript) {
  4677. mimeType = "text/javascript";
  4678. } else if (resource.filename.match(/index\.html$/)) {
  4679. mimeType = "text/html";
  4680. if (shadowRootScriptURL) {
  4681. resource.textContent = resource.textContent.replace(/<script data-template-shadow-root.*<\/script>/g, "<script data-template-shadow-root src=" + shadowRootScriptURL + "></" + "script>");
  4682. }
  4683. }
  4684. if (resource.filename.match(/^([0-9_]+\/)?index\.html$/)) {
  4685. docContent = resource.textContent;
  4686. url = resource.url;
  4687. } else {
  4688. const reader = new FileReader();
  4689. if (resource.textContent) {
  4690. reader.readAsDataURL(new Blob([resource.textContent], { type: mimeType + ";charset=utf-8" }));
  4691. resource.content = await new Promise((resolve, reject) => {
  4692. reader.addEventListener("load", () => resolve(reader.result), false);
  4693. reader.addEventListener("error", reject, false);
  4694. });
  4695. } else {
  4696. resource.content = "data:text/plain,";
  4697. }
  4698. }
  4699. }
  4700. }
  4701. return { docContent, origDocContent, resources, url };
  4702. }
  4703. /*
  4704. * Copyright 2010-2022 Gildas Lormeau
  4705. * contact : gildas.lormeau <at> gmail.com
  4706. *
  4707. * This file is part of SingleFile.
  4708. *
  4709. * The code in this file is free software: you can redistribute it and/or
  4710. * modify it under the terms of the GNU Affero General Public License
  4711. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  4712. * of the License, or (at your option) any later version.
  4713. *
  4714. * The code in this file is distributed in the hope that it will be useful,
  4715. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4716. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  4717. * General Public License for more details.
  4718. *
  4719. * As additional permission under GNU AGPL version 3 section 7, you may
  4720. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  4721. * AGPL normally required by section 4, provided you include this license
  4722. * notice and a URL through which recipients can access the Corresponding
  4723. * Source.
  4724. */
  4725. async function display(document, docContent, { disableFramePointerEvents } = {}) {
  4726. const DISABLED_NOSCRIPT_ATTRIBUTE_NAME = "data-single-filez-disabled-noscript";
  4727. const doc = (new DOMParser()).parseFromString(docContent, "text/html");
  4728. doc.querySelectorAll("noscript:not([" + DISABLED_NOSCRIPT_ATTRIBUTE_NAME + "])").forEach(element => {
  4729. element.setAttribute(DISABLED_NOSCRIPT_ATTRIBUTE_NAME, element.innerHTML);
  4730. element.textContent = "";
  4731. });
  4732. if (doc.doctype) {
  4733. if (document.doctype) {
  4734. document.replaceChild(doc.doctype, document.doctype);
  4735. } else {
  4736. document.insertBefore(doc.doctype, document.documentElement);
  4737. }
  4738. } else if (document.doctype) {
  4739. document.doctype.remove();
  4740. }
  4741. if (disableFramePointerEvents) {
  4742. doc.querySelectorAll("iframe").forEach(element => {
  4743. const pointerEvents = "pointer-events";
  4744. element.style.setProperty("-sf-" + pointerEvents, element.style.getPropertyValue(pointerEvents), element.style.getPropertyPriority(pointerEvents));
  4745. element.style.setProperty(pointerEvents, "none", "important");
  4746. });
  4747. }
  4748. document.replaceChild(document.importNode(doc.documentElement, true), document.documentElement);
  4749. document.documentElement.setAttribute("data-sfz", "");
  4750. document.querySelectorAll("link[rel*=icon]").forEach(element => element.parentElement.replaceChild(element, element));
  4751. document.open = document.write = document.close = () => { };
  4752. for (let element of Array.from(document.querySelectorAll("script"))) {
  4753. await new Promise(resolve => {
  4754. const scriptElement = document.createElement("script");
  4755. Array.from(element.attributes).forEach(attribute => scriptElement.setAttribute(attribute.name, attribute.value));
  4756. const async = element.getAttribute("async") == "" || element.getAttribute("async") == "async";
  4757. if (element.textContent) {
  4758. scriptElement.textContent = element.textContent;
  4759. } else if (!async) {
  4760. scriptElement.addEventListener("load", resolve);
  4761. scriptElement.addEventListener("error", () => resolve());
  4762. }
  4763. element.parentElement.replaceChild(scriptElement, element);
  4764. if (element.textContent || async) {
  4765. resolve();
  4766. }
  4767. });
  4768. }
  4769. }
  4770. /*
  4771. * Copyright 2010-2022 Gildas Lormeau
  4772. * contact : gildas.lormeau <at> gmail.com
  4773. *
  4774. * This file is part of SingleFile.
  4775. *
  4776. * The code in this file is free software: you can redistribute it and/or
  4777. * modify it under the terms of the GNU Affero General Public License
  4778. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  4779. * of the License, or (at your option) any later version.
  4780. *
  4781. * The code in this file is distributed in the hope that it will be useful,
  4782. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4783. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  4784. * General Public License for more details.
  4785. *
  4786. * As additional permission under GNU AGPL version 3 section 7, you may
  4787. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  4788. * AGPL normally required by section 4, provided you include this license
  4789. * notice and a URL through which recipients can access the Corresponding
  4790. * Source.
  4791. */
  4792. const { Blob: Blob$2, fetch: fetch$2, TextEncoder: TextEncoder$1, DOMParser: DOMParser$2 } = globalThis;
  4793. const NO_COMPRESSION_EXTENSIONS = [".jpg", ".jpeg", ".png", ".pdf", ".woff2", ".mp4", ".mp3", ".ogg", ".webp", ".webm"];
  4794. const SCRIPT_PATH = "/lib/single-file-zip.min.js";
  4795. const browser$2 = globalThis.browser;
  4796. async function process$9(pageData, options) {
  4797. let script;
  4798. if (options.zipScript) {
  4799. script = options.zipScript;
  4800. } else if (browser$2 && browser$2.runtime && browser$2.runtime.getURL) {
  4801. configure({ workerScripts: { deflate: ["/lib/single-file-z-worker.js"] } });
  4802. script = await (await fetch$2(browser$2.runtime.getURL(SCRIPT_PATH))).text();
  4803. }
  4804. const zipDataWriter = new Uint8ArrayWriter();
  4805. zipDataWriter.init();
  4806. if (options.selfExtractingArchive) {
  4807. let pageContent = "";
  4808. if (options.includeBOM && !options.extractDataFromPage) {
  4809. pageContent += "\ufeff";
  4810. }
  4811. const charset = options.extractDataFromPage ? "windows-1252" : "utf-8";
  4812. const pageDataTitle = pageData.title.replace(/</g, "&lt;").replace(/>/g, "&gt;") || "";
  4813. const title = options.extractDataFromPage ? "" : pageDataTitle;
  4814. pageContent += pageData.doctype + "<html data-sfz><meta charset=" + charset + "><title>" + title + "</title>";
  4815. if (options.insertCanonicalLink) {
  4816. pageContent += "<link rel=canonical href=\"" + options.url + "\">";
  4817. }
  4818. if (options.insertMetaNoIndex) {
  4819. pageContent += "<meta name=robots content=noindex>";
  4820. }
  4821. if (pageData.viewport) {
  4822. pageContent += "<meta name=\"viewport\" content=" + JSON.stringify(pageData.viewport) + ">";
  4823. }
  4824. pageContent += "<body hidden>";
  4825. pageContent += "<div id='sfz-wait-message'>Please wait...</div>";
  4826. pageContent += "<div id='sfz-error-message'><strong>Error</strong>: Cannot open the page from the filesystem.";
  4827. pageContent += "<ul style='line-height:20px;'>";
  4828. pageContent += "<li style='margin-bottom:10px'><strong>Chrome</strong>: Install <a href='https://chrome.google.com/webstore/detail/singlefile/mpiodijhokgodhhofbcjdecpffjipkle'>SingleFile</a> and enable the option \"Allow access to file URLs\" in the details page of the extension (chrome://extensions/?id=offkdfbbigofcgdokjemgjpdockaafjg).</li>";
  4829. pageContent += "<li style='margin-bottom:10px'><strong>Microsoft Edge</strong>: Install <a href='https://microsoftedge.microsoft.com/addons/detail/singlefile/efnbkdcfmcmnhlkaijjjmhjjgladedno'>SingleFile</a> and enable the option \"Allow access to file URLs\" in the details page of the extension (edge://extensions/?id=gofneaifncimeglaecpnanbnmnpfjekk).</li>";
  4830. pageContent += "<li><strong>Safari</strong>: Select \"Security > Disable Local File Restrictions\" in the \"Develop > Developer settings\" menu.</li></ul></div>";
  4831. if (options.insertTextBody) {
  4832. const doc = (new DOMParser$2()).parseFromString(pageData.content, "text/html");
  4833. doc.body.querySelectorAll("style, script, noscript").forEach(element => element.remove());
  4834. let textBody = "";
  4835. if (options.extractDataFromPage) {
  4836. textBody += pageDataTitle + "\n\n";
  4837. }
  4838. textBody += doc.body.innerText;
  4839. doc.body.querySelectorAll("single-file-note").forEach(node => {
  4840. const template = node.querySelector("template");
  4841. if (template) {
  4842. const docTemplate = (new DOMParser$2()).parseFromString(template.innerHTML, "text/html");
  4843. textBody += "\n" + docTemplate.body.querySelector("textarea").value;
  4844. }
  4845. });
  4846. textBody = textBody.replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\n +/g, "\n").replace(/\n\n\n+/g, "\n\n").trim();
  4847. pageContent += "\n<main hidden>\n" + textBody + "\n</main>\n";
  4848. }
  4849. if (options.extractDataFromPageTags) {
  4850. pageContent += options.extractDataFromPageTags[0];
  4851. } else {
  4852. pageContent += "<xmp>";
  4853. }
  4854. await writeData(zipDataWriter.writable, (new TextEncoder$1()).encode(pageContent));
  4855. }
  4856. const zipWriter = new ZipWriter(zipDataWriter, { bufferedWrite: true, keepOrder: false });
  4857. let startOffset = zipDataWriter.offset;
  4858. pageData.url = options.url;
  4859. pageData.archiveTime = (new Date()).toISOString();
  4860. await addPageResources(zipWriter, pageData, { password: options.password }, options.createRootDirectory ? String(Date.now()) + "_" + (options.tabId || 0) + "/" : "", options.url);
  4861. const data = await zipWriter.close(null, { preventClose: true });
  4862. if (options.selfExtractingArchive) {
  4863. const insertionsCRLF = [];
  4864. const substitutionsLF = [];
  4865. if (options.extractDataFromPage) {
  4866. if (!options.extractDataFromPageTags) {
  4867. const textContent = new TextDecoder().decode(data);
  4868. const matchEndTagXMP = textContent.match(/<\/\s*xmp>/i);
  4869. if (matchEndTagXMP) {
  4870. const matchEndTagComment = textContent.match(/-->/i);
  4871. if (matchEndTagComment) {
  4872. const matchTextAreaTagComment = textContent.match(/<\/\s*textarea>/i);
  4873. if (matchTextAreaTagComment) {
  4874. options.extractDataFromPage = false;
  4875. return process$9(pageData, options);
  4876. } else {
  4877. options.extractDataFromPageTags = ["<textarea>", "</textarea>"];
  4878. return process$9(pageData, options);
  4879. }
  4880. } else {
  4881. options.extractDataFromPageTags = ["<!--", "-->"];
  4882. return process$9(pageData, options);
  4883. }
  4884. }
  4885. }
  4886. for (let index = 0; index < data.length; index++) {
  4887. if (data[index] == 13) {
  4888. if (data[index + 1] == 10) {
  4889. insertionsCRLF.push(index - startOffset);
  4890. } else {
  4891. substitutionsLF.push(index - startOffset);
  4892. }
  4893. }
  4894. }
  4895. }
  4896. let pageContent = "";
  4897. if (options.extractDataFromPageTags) {
  4898. pageContent += options.extractDataFromPageTags[1];
  4899. } else {
  4900. pageContent += "</xmp>";
  4901. }
  4902. if (insertionsCRLF.length || substitutionsLF.length) {
  4903. const extraData =
  4904. await arrayToBase64(insertionsCRLF) + "," +
  4905. await arrayToBase64(substitutionsLF) + "," +
  4906. await arrayToBase64([startOffset]);
  4907. pageContent += "<sfz-extra-data>" + extraData + "</sfz-extra-data>";
  4908. }
  4909. script += "document.currentScript.remove();globalThis.bootstrap=(()=>{let bootstrapStarted;return async content=>{if (bootstrapStarted) return bootstrapStarted;bootstrapStarted = (" +
  4910. extract.toString().replace(/\n|\t/g, "") + ")(content,{prompt}).then(({docContent}) => " +
  4911. display.toString().replace(/\n|\t/g, "") + "(document,docContent));return bootstrapStarted;}})();(" +
  4912. getContent.toString().replace(/\n|\t/g, "") + ")().then(globalThis.bootstrap).catch(()=>{});";
  4913. pageContent += "<script>" + script + "</script></body></html>";
  4914. await writeData(zipDataWriter.writable, (new TextEncoder$1()).encode(pageContent));
  4915. }
  4916. await zipDataWriter.writable.close();
  4917. return new Blob$2([zipDataWriter.getData()], { type: "application/octet-stream" });
  4918. }
  4919. async function arrayToBase64(data) {
  4920. const fileReader = new FileReader();
  4921. return await new Promise(resolve => {
  4922. fileReader.onload = event => resolve(event.target.result.substring(37));
  4923. fileReader.readAsDataURL(new Blob$2([new Uint32Array(data)], { type: "application/octet-stream" }));
  4924. });
  4925. }
  4926. async function writeData(writable, array) {
  4927. const streamWriter = writable.getWriter();
  4928. await streamWriter.ready;
  4929. writable.size = array.length;
  4930. await streamWriter.write(array);
  4931. streamWriter.releaseLock();
  4932. }
  4933. async function addPageResources(zipWriter, pageData, options, prefixName, url) {
  4934. const resources = {};
  4935. for (const resourceType of Object.keys(pageData.resources)) {
  4936. for (const data of pageData.resources[resourceType]) {
  4937. data.password = options.password;
  4938. if (data.url && !data.url.startsWith("data:")) {
  4939. resources[data.name] = data.url;
  4940. }
  4941. }
  4942. }
  4943. const jsonContent = JSON.stringify({
  4944. originalUrl: pageData.url,
  4945. title: pageData.title,
  4946. archiveTime: pageData.archiveTime,
  4947. indexFilename: "index.html",
  4948. resources
  4949. }, null, 2);
  4950. await Promise.all([
  4951. Promise.all([
  4952. addFile(zipWriter, prefixName, { name: "index.html", extension: ".html", content: pageData.content, url, password: options.password }),
  4953. addFile(zipWriter, prefixName, { name: "manifest.json", extension: ".json", content: jsonContent, password: options.password })
  4954. ]),
  4955. Promise.all(Object.keys(pageData.resources).map(async resourceType =>
  4956. Promise.all(pageData.resources[resourceType].map(data => {
  4957. if (resourceType == "frames") {
  4958. return addPageResources(zipWriter, data, options, prefixName + data.name, data.url);
  4959. } else {
  4960. return addFile(zipWriter, prefixName, data);
  4961. }
  4962. }))
  4963. ))
  4964. ]);
  4965. }
  4966. async function addFile(zipWriter, prefixName, data) {
  4967. const dataReader = typeof data.content == "string" ? new TextReader(data.content) : new BlobReader(new Blob$2([new Uint8Array(data.content)]));
  4968. const options = { comment: data.url && data.url.startsWith("data:") ? "data:" : data.url, password: data.password, bufferedWrite: true };
  4969. if (NO_COMPRESSION_EXTENSIONS.includes(data.extension)) {
  4970. options.level = 0;
  4971. }
  4972. await zipWriter.add(prefixName + data.name, dataReader, options);
  4973. }
  4974. async function getContent() {
  4975. const { Blob, XMLHttpRequest, fetch, document, setTimeout, clearTimeout, stop } = globalThis;
  4976. const characterMap = new Map([
  4977. [65533, 0], [8364, 128], [8218, 130], [402, 131], [8222, 132], [8230, 133], [8224, 134], [8225, 135], [710, 136], [8240, 137],
  4978. [352, 138], [8249, 139], [338, 140], [381, 142], [8216, 145], [8217, 146], [8220, 147], [8221, 148], [8226, 149], [8211, 150],
  4979. [8212, 151], [732, 152], [8482, 153], [353, 154], [8250, 155], [339, 156], [382, 158], [376, 159]
  4980. ]);
  4981. const xhr = new XMLHttpRequest();
  4982. let displayTimeout;
  4983. Array.from(document.documentElement.childNodes).forEach(node => {
  4984. if (node != document.body && node != document.head) {
  4985. node.remove();
  4986. }
  4987. });
  4988. xhr.responseType = "blob";
  4989. xhr.open("GET", "");
  4990. return new Promise((resolve, reject) => {
  4991. xhr.onerror = () => {
  4992. extractPageData().then(resolve).catch(() => {
  4993. displayTimeout = displayMessage("sfz-error-message");
  4994. reject();
  4995. });
  4996. };
  4997. xhr.send();
  4998. xhr.onload = () => {
  4999. displayTimeout = displayMessage("sfz-wait-message");
  5000. stop();
  5001. if (displayTimeout) {
  5002. clearTimeout(displayTimeout);
  5003. }
  5004. resolve(xhr.response);
  5005. };
  5006. });
  5007. function displayMessage(elementId) {
  5008. return setTimeout(() => {
  5009. if (document.getElementById(elementId)) {
  5010. Array.from(document.body.childNodes).forEach(node => {
  5011. if (node.id != elementId) {
  5012. node.remove();
  5013. }
  5014. });
  5015. document.body.hidden = false;
  5016. }
  5017. }, 1500);
  5018. }
  5019. async function extractPageData() {
  5020. const zipDataElement = document.querySelector("sfz-extra-data");
  5021. if (zipDataElement) {
  5022. const dataNode = zipDataElement.previousSibling;
  5023. const zipData = [];
  5024. let { textContent } = dataNode;
  5025. for (let index = 0; index < textContent.length; index++) {
  5026. const charCode = textContent.charCodeAt(index);
  5027. zipData.push(charCode > 255 ? characterMap.get(charCode) : charCode);
  5028. }
  5029. const [insertionsCRLFData, substitutionsLFData, startOffsetData] = zipDataElement.textContent.split(",");
  5030. const insertionsCRLF = await base64ToUint32Array(insertionsCRLFData);
  5031. const substitutionsLF = await base64ToUint32Array(substitutionsLFData);
  5032. const [startOffset] = await base64ToUint32Array(startOffsetData);
  5033. insertionsCRLF.forEach(index => zipData.splice(index, 1, 13, 10));
  5034. substitutionsLF.forEach(index => zipData[index] = 13);
  5035. return new Blob([new Uint8Array(startOffset), new Uint8Array(zipData)], { type: "application/octet-stream" });
  5036. }
  5037. throw new Error("Extra zip data data not found");
  5038. }
  5039. async function base64ToUint32Array(data) {
  5040. return new Uint32Array(await (await fetch("data:application/octet-stream;base64," + data)).arrayBuffer());
  5041. }
  5042. }
  5043. var compression = /*#__PURE__*/Object.freeze({
  5044. __proto__: null,
  5045. process: process$9
  5046. });
  5047. /*
  5048. * Copyright 2010-2022 Gildas Lormeau
  5049. * contact : gildas.lormeau <at> gmail.com
  5050. *
  5051. * This file is part of SingleFile.
  5052. *
  5053. * The code in this file is free software: you can redistribute it and/or
  5054. * modify it under the terms of the GNU Affero General Public License
  5055. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  5056. * of the License, or (at your option) any later version.
  5057. *
  5058. * The code in this file is distributed in the hope that it will be useful,
  5059. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  5060. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  5061. * General Public License for more details.
  5062. *
  5063. * As additional permission under GNU AGPL version 3 section 7, you may
  5064. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  5065. * AGPL normally required by section 4, provided you include this license
  5066. * notice and a URL through which recipients can access the Corresponding
  5067. * Source.
  5068. */
  5069. /* global globalThis, window */
  5070. const LOAD_DEFERRED_IMAGES_START_EVENT = "single-file-load-deferred-images-start";
  5071. const LOAD_DEFERRED_IMAGES_END_EVENT = "single-file-load-deferred-images-end";
  5072. const LOAD_DEFERRED_IMAGES_KEEP_ZOOM_LEVEL_START_EVENT = "single-file-load-deferred-images-keep-zoom-level-start";
  5073. const LOAD_DEFERRED_IMAGES_KEEP_ZOOM_LEVEL_END_EVENT = "single-file-load-deferred-images-keep-zoom-level-end";
  5074. const LOAD_DEFERRED_IMAGES_RESET_ZOOM_LEVEL_EVENT = "single-file-load-deferred-images-keep-zoom-level-reset";
  5075. const LOAD_DEFERRED_IMAGES_RESET_EVENT = "single-file-load-deferred-images-reset";
  5076. const BLOCK_COOKIES_START_EVENT = "single-file-block-cookies-start";
  5077. const BLOCK_COOKIES_END_EVENT = "single-file-block-cookies-end";
  5078. const DISPATCH_SCROLL_START_EVENT = "single-file-dispatch-scroll-event-start";
  5079. const DISPATCH_SCROLL_END_EVENT = "single-file-dispatch-scroll-event-end";
  5080. const BLOCK_STORAGE_START_EVENT = "single-file-block-storage-start";
  5081. const BLOCK_STORAGE_END_EVENT = "single-file-block-storage-end";
  5082. const LOAD_IMAGE_EVENT = "single-file-load-image";
  5083. const IMAGE_LOADED_EVENT = "single-file-image-loaded";
  5084. const NEW_FONT_FACE_EVENT = "single-file-new-font-face";
  5085. const DELETE_FONT_EVENT = "single-file-delete-font";
  5086. const CLEAR_FONTS_EVENT = "single-file-clear-fonts";
  5087. const FONT_FACE_PROPERTY_NAME = "_singleFile_fontFaces";
  5088. const addEventListener$3 = (type, listener, options) => globalThis.addEventListener(type, listener, options);
  5089. const dispatchEvent$1 = event => { try { globalThis.dispatchEvent(event); } catch (error) { /* ignored */ } };
  5090. const CustomEvent$1 = globalThis.CustomEvent;
  5091. const document$3 = globalThis.document;
  5092. const Document = globalThis.Document;
  5093. const JSON$6 = globalThis.JSON;
  5094. let fontFaces;
  5095. if (window[FONT_FACE_PROPERTY_NAME]) {
  5096. fontFaces = window[FONT_FACE_PROPERTY_NAME];
  5097. } else {
  5098. fontFaces = window[FONT_FACE_PROPERTY_NAME] = new Map();
  5099. }
  5100. if (document$3 instanceof Document) {
  5101. addEventListener$3(NEW_FONT_FACE_EVENT, event => {
  5102. const detail = event.detail;
  5103. const key = Object.assign({}, detail);
  5104. delete key.src;
  5105. fontFaces.set(JSON$6.stringify(key), detail);
  5106. });
  5107. addEventListener$3(DELETE_FONT_EVENT, event => {
  5108. const detail = event.detail;
  5109. const key = Object.assign({}, detail);
  5110. delete key.src;
  5111. fontFaces.delete(JSON$6.stringify(key));
  5112. });
  5113. addEventListener$3(CLEAR_FONTS_EVENT, () => fontFaces = new Map());
  5114. }
  5115. function getFontsData$1() {
  5116. return Array.from(fontFaces.values());
  5117. }
  5118. function loadDeferredImagesStart(options) {
  5119. if (options.loadDeferredImagesBlockCookies) {
  5120. dispatchEvent$1(new CustomEvent$1(BLOCK_COOKIES_START_EVENT));
  5121. }
  5122. if (options.loadDeferredImagesBlockStorage) {
  5123. dispatchEvent$1(new CustomEvent$1(BLOCK_STORAGE_START_EVENT));
  5124. }
  5125. if (options.loadDeferredImagesDispatchScrollEvent) {
  5126. dispatchEvent$1(new CustomEvent$1(DISPATCH_SCROLL_START_EVENT));
  5127. }
  5128. if (options.loadDeferredImagesKeepZoomLevel) {
  5129. dispatchEvent$1(new CustomEvent$1(LOAD_DEFERRED_IMAGES_KEEP_ZOOM_LEVEL_START_EVENT));
  5130. } else {
  5131. dispatchEvent$1(new CustomEvent$1(LOAD_DEFERRED_IMAGES_START_EVENT));
  5132. }
  5133. }
  5134. function loadDeferredImagesEnd(options) {
  5135. if (options.loadDeferredImagesBlockCookies) {
  5136. dispatchEvent$1(new CustomEvent$1(BLOCK_COOKIES_END_EVENT));
  5137. }
  5138. if (options.loadDeferredImagesBlockStorage) {
  5139. dispatchEvent$1(new CustomEvent$1(BLOCK_STORAGE_END_EVENT));
  5140. }
  5141. if (options.loadDeferredImagesDispatchScrollEvent) {
  5142. dispatchEvent$1(new CustomEvent$1(DISPATCH_SCROLL_END_EVENT));
  5143. }
  5144. if (options.loadDeferredImagesKeepZoomLevel) {
  5145. dispatchEvent$1(new CustomEvent$1(LOAD_DEFERRED_IMAGES_KEEP_ZOOM_LEVEL_END_EVENT));
  5146. } else {
  5147. dispatchEvent$1(new CustomEvent$1(LOAD_DEFERRED_IMAGES_END_EVENT));
  5148. }
  5149. }
  5150. function loadDeferredImagesResetZoomLevel(options) {
  5151. if (options.loadDeferredImagesKeepZoomLevel) {
  5152. dispatchEvent$1(new CustomEvent$1(LOAD_DEFERRED_IMAGES_RESET_ZOOM_LEVEL_EVENT));
  5153. } else {
  5154. dispatchEvent$1(new CustomEvent$1(LOAD_DEFERRED_IMAGES_RESET_EVENT));
  5155. }
  5156. }
  5157. var contentHooksFrames = /*#__PURE__*/Object.freeze({
  5158. __proto__: null,
  5159. getFontsData: getFontsData$1,
  5160. loadDeferredImagesStart: loadDeferredImagesStart,
  5161. loadDeferredImagesEnd: loadDeferredImagesEnd,
  5162. loadDeferredImagesResetZoomLevel: loadDeferredImagesResetZoomLevel,
  5163. LOAD_IMAGE_EVENT: LOAD_IMAGE_EVENT,
  5164. IMAGE_LOADED_EVENT: IMAGE_LOADED_EVENT
  5165. });
  5166. /*
  5167. * The MIT License (MIT)
  5168. *
  5169. * Author: Gildas Lormeau
  5170. *
  5171. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5172. * of this software and associated documentation files (the "Software"), to deal
  5173. * in the Software without restriction, including without limitation the rights
  5174. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  5175. * copies of the Software, and to permit persons to whom the Software is
  5176. * furnished to do so, subject to the following conditions:
  5177. *
  5178. * The above copyright notice and this permission notice shall be included in all
  5179. * copies or substantial portions of the Software.
  5180. *
  5181. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  5182. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  5183. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  5184. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  5185. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  5186. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  5187. * SOFTWARE.
  5188. */
  5189. // derived from https://github.com/postcss/postcss-selector-parser/blob/master/src/util/unesc.js
  5190. /*
  5191. * The MIT License (MIT)
  5192. * Copyright (c) Ben Briggs <beneb.info@gmail.com> (http://beneb.info)
  5193. *
  5194. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5195. * of this software and associated documentation files (the "Software"), to deal
  5196. * in the Software without restriction, including without limitation the rights
  5197. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  5198. * copies of the Software, and to permit persons to whom the Software is
  5199. * furnished to do so, subject to the following conditions:
  5200. *
  5201. * The above copyright notice and this permission notice shall be included in
  5202. * all copies or substantial portions of the Software.
  5203. *
  5204. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  5205. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  5206. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  5207. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  5208. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  5209. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  5210. * THE SOFTWARE.
  5211. */
  5212. const whitespace = "[\\x20\\t\\r\\n\\f]";
  5213. const unescapeRegExp = new RegExp("\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig");
  5214. function process$8(str) {
  5215. return str.replace(unescapeRegExp, (_, escaped, escapedWhitespace) => {
  5216. const high = "0x" + escaped - 0x10000;
  5217. // NaN means non-codepoint
  5218. // Workaround erroneous numeric interpretation of +"0x"
  5219. // eslint-disable-next-line no-self-compare
  5220. return high !== high || escapedWhitespace
  5221. ? escaped
  5222. : high < 0
  5223. ? // BMP codepoint
  5224. String.fromCharCode(high + 0x10000)
  5225. : // Supplemental Plane codepoint (surrogate pair)
  5226. String.fromCharCode((high >> 10) | 0xd800, (high & 0x3ff) | 0xdc00);
  5227. });
  5228. }
  5229. var cssUnescape = /*#__PURE__*/Object.freeze({
  5230. __proto__: null,
  5231. process: process$8
  5232. });
  5233. const SINGLE_FILE_PREFIX = "single-file-";
  5234. const COMMENT_HEADER = "Page saved with SingleFile";
  5235. const SINGLE_FILE_SIGNATURE = "SingleFile";
  5236. const WAIT_FOR_USERSCRIPT_PROPERTY_NAME = "_singleFile_waitForUserScript";
  5237. const MESSAGE_PREFIX = "__frameTree__::";
  5238. const NO_SCRIPT_PROPERTY_NAME = "singleFileDisabledNoscript";
  5239. /*
  5240. * Copyright 2010-2022 Gildas Lormeau
  5241. * contact : gildas.lormeau <at> gmail.com
  5242. *
  5243. * This file is part of SingleFile.
  5244. *
  5245. * The code in this file is free software: you can redistribute it and/or
  5246. * modify it under the terms of the GNU Affero General Public License
  5247. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  5248. * of the License, or (at your option) any later version.
  5249. *
  5250. * The code in this file is distributed in the hope that it will be useful,
  5251. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  5252. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  5253. * General Public License for more details.
  5254. *
  5255. * As additional permission under GNU AGPL version 3 section 7, you may
  5256. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  5257. * AGPL normally required by section 4, provided you include this license
  5258. * notice and a URL through which recipients can access the Corresponding
  5259. * Source.
  5260. */
  5261. const INFOBAR_TAGNAME$1 = "single-file-infobar";
  5262. const INFOBAR_STYLES = `
  5263. .infobar,
  5264. .infobar .infobar-icon,
  5265. .infobar .infobar-link-icon {
  5266. min-inline-size: 28px;
  5267. min-block-size: 28px;
  5268. box-sizing: border-box;
  5269. }
  5270. .infobar,
  5271. .infobar .infobar-close-icon,
  5272. .infobar .infobar-link-icon {
  5273. opacity: 0.7;
  5274. transition: opacity 250ms;
  5275. }
  5276. .infobar:hover,
  5277. .infobar .infobar-close-icon:hover,
  5278. .infobar .infobar-link-icon:hover {
  5279. opacity: 1;
  5280. }
  5281. .infobar,
  5282. .infobar-content {
  5283. display: flex;
  5284. }
  5285. .infobar {
  5286. position: fixed;
  5287. top: 16px;
  5288. right: 16px;
  5289. margin-inline-start: 16px;
  5290. margin-block-end: 16px;
  5291. color: #2d2d2d;
  5292. background-color: #737373;
  5293. border: 2px solid;
  5294. border-color: #eee;
  5295. border-radius: 16px;
  5296. z-index: 2147483647;
  5297. }
  5298. .infobar:valid, .infobar:not(:focus-within) .infobar-content {
  5299. display: none;
  5300. }
  5301. .infobar:focus-within {
  5302. background-color: #f9f9f9;
  5303. border-color: #878787;
  5304. border-radius: 8px;
  5305. opacity: 1;
  5306. transition-property: opacity, background-color, border-color, border-radius,
  5307. color;
  5308. }
  5309. .infobar-content {
  5310. align-items: center;
  5311. }
  5312. .infobar-content span {
  5313. font-family: Arial, Helvetica, sans-serif;
  5314. font-size: 14px;
  5315. line-height: 18px;
  5316. word-break: break-word;
  5317. white-space: pre-wrap;
  5318. margin-inline: 4px;
  5319. margin-block: 4px;
  5320. }
  5321. .infobar .infobar-icon,
  5322. .infobar .infobar-close-icon,
  5323. .infobar .infobar-link-icon {
  5324. cursor: pointer;
  5325. background-position: center;
  5326. background-repeat: no-repeat;
  5327. }
  5328. .infobar .infobar-close-icon,
  5329. .infobar .infobar-link-icon {
  5330. align-self: flex-start;
  5331. }
  5332. .infobar .infobar-icon {
  5333. position: absolute;
  5334. min-inline-size: 24px;
  5335. min-block-size: 24px;
  5336. }
  5337. .infobar:focus-within .infobar-icon {
  5338. z-index: -1;
  5339. background-image: none;
  5340. }
  5341. .infobar .infobar-close-icon {
  5342. min-inline-size: 22px;
  5343. min-block-size: 22px;
  5344. }
  5345. .infobar .infobar-icon {
  5346. background-color: transparent;
  5347. background-size: 70%;
  5348. background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABABAMAAABYR2ztAAABhmlDQ1BJQ0MgcHJvZmlsZQAAKJF9kj1Iw0AYht+mSkUrDnYQcchQnSyIijqWKhbBQmkrtOpgcukfNGlIUlwcBdeCgz+LVQcXZ10dXAVB8AfEydFJ0UVK/C4ptIjx4LiH9+59+e67A4RGhalm1wSgapaRisfEbG5VDLyiDwEAvZiVmKkn0osZeI6ve/j4ehfhWd7n/hz9St5kgE8kjjLdsIg3iGc2LZ3zPnGIlSSF+Jx43KACiR+5Lrv8xrnosMAzQ0YmNU8cIhaLHSx3MCsZKvE0cVhRNcoXsi4rnLc4q5Uaa9XJbxjMaytprtMcQRxLSCAJETJqKKMCCxFaNVJMpGg/5uEfdvxJcsnkKoORYwFVqJAcP/gb/O6tWZiadJOCMaD7xbY/RoHALtCs2/b3sW03TwD/M3Cltf3VBjD3SXq9rYWPgIFt4OK6rcl7wOUOMPSkS4bkSH6aQqEAvJ/RM+WAwVv6EGtu31r7OH0AMtSr5Rvg4BAYK1L2use9ezr79u+ZVv9+AFlNcp0UUpiqAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAB3RJTUUH5AsHADIRLMaOHwAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAAPUExURQAAAIqKioyNjY2OjvDw8L2y1DEAAAABdFJOUwBA5thmAAAAAWJLR0QB/wIt3gAAAGNJREFUSMdjYCAJsLi4OBCQx6/CBQwIGIDPCBcXAkYQUsACU+AwlBVQHg6Eg5pgZBGOboIJZugDFwRwoJECJCUOhJI1wZwzqmBUwagCuipgIqTABG9h7YIKaKGAURAFEF/6AQAO4HqSoDP8bgAAAABJRU5ErkJggg==);
  5349. }
  5350. .infobar .infobar-link-icon {
  5351. background-size: 60%;
  5352. background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAgMAAADXB5lNAAABhmlDQ1BJQ0MgcHJvZmlsZQAAKJF9kj1Iw0AYht+mSkUrDnYQcchQnSyIijqWKhbBQmkrtOpgcukfNGlIUlwcBdeCgz+LVQcXZ10dXAVB8AfEydFJ0UVK/C4ptIjx4LiH9+59+e67A4RGhalm1wSgapaRisfEbG5VDLyiDwEAvZiVmKkn0osZeI6ve/j4ehfhWd7n/hz9St5kgE8kjjLdsIg3iGc2LZ3zPnGIlSSF+Jx43KACiR+5Lrv8xrnosMAzQ0YmNU8cIhaLHSx3MCsZKvE0cVhRNcoXsi4rnLc4q5Uaa9XJbxjMaytprtMcQRxLSCAJETJqKKMCCxFaNVJMpGg/5uEfdvxJcsnkKoORYwFVqJAcP/gb/O6tWZiadJOCMaD7xbY/RoHALtCs2/b3sW03TwD/M3Cltf3VBjD3SXq9rYWPgIFt4OK6rcl7wOUOMPSkS4bkSH6aQqEAvJ/RM+WAwVv6EGtu31r7OH0AMtSr5Rvg4BAYK1L2use9ezr79u+ZVv9+AFlNcp0UUpiqAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAB3RJTUUH5AsHAB8H+DhhoQAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAAJUExURQAAAICHi4qKioTuJAkAAAABdFJOUwBA5thmAAAAAWJLR0QCZgt8ZAAAAJJJREFUOI3t070NRCEMA2CnYAOyDyPwpHj/Va7hJ3FzV7zy3ET5JIwoAF6Jk4wzAJAkzxAYG9YRTgB+24wBgKmfrGAKTcEfAY4KRlRoIeBTgKOCERVaCPgU4Khge2GqKOBTgKOCERVaAEC/4PNcnyoSWHpjqkhwKxbcig0Q6AorXYF/+A6eIYD1lVbwG/jdA6/kA2THRAURVubcAAAAAElFTkSuQmCC);
  5353. }
  5354. .infobar .infobar-close-icon {
  5355. appearance: none;
  5356. background-size: 80%;
  5357. background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAgMAAADXB5lNAAABhmlDQ1BJQ0MgcHJvZmlsZQAAKJF9kj1Iw0AYht+mSkUrDnYQcchQnSyIijqWKhbBQmkrtOpgcukfNGlIUlwcBdeCgz+LVQcXZ10dXAVB8AfEydFJ0UVK/C4ptIjx4LiH9+59+e67A4RGhalm1wSgapaRisfEbG5VDLyiDwEAvZiVmKkn0osZeI6ve/j4ehfhWd7n/hz9St5kgE8kjjLdsIg3iGc2LZ3zPnGIlSSF+Jx43KACiR+5Lrv8xrnosMAzQ0YmNU8cIhaLHSx3MCsZKvE0cVhRNcoXsi4rnLc4q5Uaa9XJbxjMaytprtMcQRxLSCAJETJqKKMCCxFaNVJMpGg/5uEfdvxJcsnkKoORYwFVqJAcP/gb/O6tWZiadJOCMaD7xbY/RoHALtCs2/b3sW03TwD/M3Cltf3VBjD3SXq9rYWPgIFt4OK6rcl7wOUOMPSkS4bkSH6aQqEAvJ/RM+WAwVv6EGtu31r7OH0AMtSr5Rvg4BAYK1L2use9ezr79u+ZVv9+AFlNcp0UUpiqAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAB3RJTUUH5AsHAB8VC4EQ6QAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAAJUExURQAAAICHi4qKioTuJAkAAAABdFJOUwBA5thmAAAAAWJLR0QCZgt8ZAAAAJtJREFUOI3NkrsBgCAMRLFwBPdxBArcfxXFkO8rbKWAAJfHJ9faf9vuYX/749T5NmShm3bEwbe2SxeuM4+2oxDL1cDoKtVUjRy+tH78Cv2CS+wIiQNC1AEhk4AQeUTMWUJMfUJMSEJMSEY8kIx4IONroaYAimNxsXp1PA7PxwfVL8QnowwoVC0lig07wDDVUjAdbAnjwtow/z/bDW7eI4M2KruJAAAAAElFTkSuQmCC);
  5358. }
  5359. `;
  5360. function appendInfobar$1(doc, options, useShadowRoot) {
  5361. if (!doc.querySelector(INFOBAR_TAGNAME$1)) {
  5362. let infoData;
  5363. if (options.infobarContent) {
  5364. infoData = options.infobarContent.replace(/\\n/g, "\n").replace(/\\t/g, "\t");
  5365. } else if (options.saveDate) {
  5366. infoData = options.saveDate;
  5367. }
  5368. infoData = infoData || "No info";
  5369. const infobarElement = createElement(doc, INFOBAR_TAGNAME$1, doc.body);
  5370. let infobarContainer;
  5371. if (useShadowRoot) {
  5372. infobarContainer = infobarElement.attachShadow({ mode: "open" });
  5373. } else {
  5374. const shadowRootTemplate = doc.createElement("template");
  5375. shadowRootTemplate.setAttribute("shadowrootmode", "open");
  5376. infobarElement.appendChild(shadowRootTemplate);
  5377. infobarContainer = shadowRootTemplate;
  5378. }
  5379. const shadowRootContent = doc.createElement("div");
  5380. const styleElement = doc.createElement("style");
  5381. styleElement.textContent = INFOBAR_STYLES
  5382. .replace(/ {2}/g, "")
  5383. .replace(/\n/g, "")
  5384. .replace(/: /g, ":")
  5385. .replace(/, /g, ",");
  5386. shadowRootContent.appendChild(styleElement);
  5387. const infobarContent = doc.createElement("form");
  5388. infobarContent.classList.add("infobar");
  5389. shadowRootContent.appendChild(infobarContent);
  5390. const iconElement = doc.createElement("span");
  5391. iconElement.tabIndex = -1;
  5392. iconElement.classList.add("infobar-icon");
  5393. infobarContent.appendChild(iconElement);
  5394. const contentElement = doc.createElement("span");
  5395. contentElement.tabIndex = -1;
  5396. contentElement.classList.add("infobar-content");
  5397. const closeButtonElement = doc.createElement("input");
  5398. closeButtonElement.type = "checkbox";
  5399. closeButtonElement.required = true;
  5400. closeButtonElement.classList.add("infobar-close-icon");
  5401. closeButtonElement.title = "Close";
  5402. contentElement.appendChild(closeButtonElement);
  5403. const textElement = doc.createElement("span");
  5404. textElement.textContent = infoData;
  5405. contentElement.appendChild(textElement);
  5406. const linkElement = doc.createElement("a");
  5407. linkElement.classList.add("infobar-link-icon");
  5408. linkElement.target = "_blank";
  5409. linkElement.rel = "noopener noreferrer";
  5410. linkElement.title = "Open source URL: " + options.saveUrl;
  5411. linkElement.href = options.saveUrl;
  5412. contentElement.appendChild(linkElement);
  5413. infobarContent.appendChild(contentElement);
  5414. if (useShadowRoot) {
  5415. infobarContainer.appendChild(shadowRootContent);
  5416. } else {
  5417. const scriptElement = doc.createElement("script");
  5418. let scriptContent = refreshInfobarInfo.toString();
  5419. scriptContent += extractInfobarData.toString();
  5420. scriptContent += "(" + initInfobar.toString() + ")(document)";
  5421. scriptElement.textContent = scriptContent;
  5422. shadowRootContent.appendChild(scriptElement);
  5423. infobarContainer.innerHTML = shadowRootContent.outerHTML;
  5424. }
  5425. doc.body.appendChild(infobarElement);
  5426. }
  5427. }
  5428. function extractInfobarData(doc) {
  5429. const result = doc.evaluate("//comment()", doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
  5430. let singleFileComment = result && result.singleNodeValue;
  5431. if (singleFileComment && singleFileComment.nodeType == Node.COMMENT_NODE && singleFileComment.textContent.includes(SINGLE_FILE_SIGNATURE)) {
  5432. const info = singleFileComment.textContent.split("\n");
  5433. const [, , urlData, ...optionalData] = info;
  5434. const urlMatch = urlData.match(/^ url: (.*) ?$/);
  5435. const saveUrl = urlMatch && urlMatch[1];
  5436. if (saveUrl) {
  5437. let infobarContent, saveDate;
  5438. if (optionalData.length) {
  5439. saveDate = optionalData[0].split("saved date: ")[1];
  5440. if (saveDate) {
  5441. optionalData.shift();
  5442. }
  5443. if (optionalData.length > 1) {
  5444. let content = optionalData[0].split("info: ")[1].trim();
  5445. for (let indexLine = 1; indexLine < optionalData.length - 1; indexLine++) {
  5446. content += "\n" + optionalData[indexLine].trim();
  5447. }
  5448. infobarContent = content.trim();
  5449. }
  5450. }
  5451. return { saveUrl, infobarContent, saveDate };
  5452. }
  5453. }
  5454. }
  5455. function refreshInfobarInfo(doc, { saveUrl, infobarContent, saveDate }) {
  5456. if (saveUrl) {
  5457. const infobarElement = doc.querySelector("single-file-infobar");
  5458. const shadowRootFragment = infobarElement.shadowRoot;
  5459. const infobarContentElement = shadowRootFragment.querySelector(".infobar-content span");
  5460. infobarContentElement.textContent = infobarContent || saveDate;
  5461. const linkElement = shadowRootFragment.querySelector(".infobar-content .infobar-link-icon");
  5462. linkElement.href = saveUrl;
  5463. linkElement.title = "Open source URL: " + saveUrl;
  5464. }
  5465. }
  5466. function initInfobar(doc) {
  5467. const infoData = extractInfobarData(doc);
  5468. if (infoData && infoData.saveUrl) {
  5469. refreshInfobarInfo(doc, infoData);
  5470. }
  5471. }
  5472. function createElement(doc, tagName, parentElement) {
  5473. const element = doc.createElement(tagName);
  5474. parentElement.appendChild(element);
  5475. Array.from(getComputedStyle(element)).forEach(property => element.style.setProperty(property, "initial", "important"));
  5476. return element;
  5477. }
  5478. /*
  5479. * Copyright 2010-2022 Gildas Lormeau
  5480. * contact : gildas.lormeau <at> gmail.com
  5481. *
  5482. * This file is part of SingleFile.
  5483. *
  5484. * The code in this file is free software: you can redistribute it and/or
  5485. * modify it under the terms of the GNU Affero General Public License
  5486. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  5487. * of the License, or (at your option) any later version.
  5488. *
  5489. * The code in this file is distributed in the hope that it will be useful,
  5490. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  5491. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  5492. * General Public License for more details.
  5493. *
  5494. * As additional permission under GNU AGPL version 3 section 7, you may
  5495. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  5496. * AGPL normally required by section 4, provided you include this license
  5497. * notice and a URL through which recipients can access the Corresponding
  5498. * Source.
  5499. */
  5500. const ON_BEFORE_CAPTURE_EVENT_NAME = SINGLE_FILE_PREFIX + "on-before-capture";
  5501. const ON_AFTER_CAPTURE_EVENT_NAME = SINGLE_FILE_PREFIX + "on-after-capture";
  5502. const GET_ADOPTED_STYLESHEETS_REQUEST_EVENT = SINGLE_FILE_PREFIX + "request-get-adopted-stylesheets";
  5503. const GET_ADOPTED_STYLESHEETS_RESPONSE_EVENT = SINGLE_FILE_PREFIX + "response-get-adopted-stylesheets";
  5504. const UNREGISTER_GET_ADOPTED_STYLESHEETS_REQUEST_EVENT = SINGLE_FILE_PREFIX + "unregister-request-get-adopted-stylesheets";
  5505. const ON_INIT_USERSCRIPT_EVENT = SINGLE_FILE_PREFIX + "user-script-init";
  5506. const REMOVED_CONTENT_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "removed-content";
  5507. const HIDDEN_CONTENT_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "hidden-content";
  5508. const KEPT_CONTENT_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "kept-content";
  5509. const HIDDEN_FRAME_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "hidden-frame";
  5510. const PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "preserved-space-element";
  5511. const SHADOW_ROOT_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "shadow-root-element";
  5512. const WIN_ID_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "win-id";
  5513. const IMAGE_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "image";
  5514. const POSTER_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "poster";
  5515. const VIDEO_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "video";
  5516. const CANVAS_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "canvas";
  5517. const STYLE_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "movable-style";
  5518. const INPUT_VALUE_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "input-value";
  5519. const LAZY_SRC_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "lazy-loaded-src";
  5520. const STYLESHEET_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "stylesheet";
  5521. const DISABLED_NOSCRIPT_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "disabled-noscript";
  5522. const SELECTED_CONTENT_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "selected-content";
  5523. const INVALID_ELEMENT_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "invalid-element";
  5524. const ASYNC_SCRIPT_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "async-script";
  5525. const FLOW_ELEMENTS_SELECTOR = "*:not(base):not(link):not(meta):not(noscript):not(script):not(style):not(template):not(title)";
  5526. const KEPT_TAG_NAMES = ["NOSCRIPT", "DISABLED-NOSCRIPT", "META", "LINK", "STYLE", "TITLE", "TEMPLATE", "SOURCE", "OBJECT", "SCRIPT", "HEAD", "BODY"];
  5527. const REGEXP_SIMPLE_QUOTES_STRING$3 = /^'(.*?)'$/;
  5528. const REGEXP_DOUBLE_QUOTES_STRING$3 = /^"(.*?)"$/;
  5529. const FONT_WEIGHTS = {
  5530. regular: "400",
  5531. normal: "400",
  5532. bold: "700",
  5533. bolder: "700",
  5534. lighter: "100"
  5535. };
  5536. const COMMENT_HEADER_LEGACY = "Archive processed by SingleFile";
  5537. const SINGLE_FILE_UI_ELEMENT_CLASS = "single-file-ui-element";
  5538. const INFOBAR_TAGNAME = INFOBAR_TAGNAME$1;
  5539. const EMPTY_RESOURCE$1 = "data:,";
  5540. const addEventListener$2 = (type, listener, options) => globalThis.addEventListener(type, listener, options);
  5541. const dispatchEvent = event => { try { globalThis.dispatchEvent(event); } catch (error) { /* ignored */ } };
  5542. const JSON$5 = globalThis.JSON;
  5543. function initUserScriptHandler() {
  5544. addEventListener$2(ON_INIT_USERSCRIPT_EVENT, () => globalThis[WAIT_FOR_USERSCRIPT_PROPERTY_NAME] = async eventPrefixName => {
  5545. const event = new CustomEvent(eventPrefixName + "-request", { cancelable: true });
  5546. const promiseResponse = new Promise(resolve => addEventListener$2(eventPrefixName + "-response", resolve));
  5547. dispatchEvent(event);
  5548. if (event.defaultPrevented) {
  5549. await promiseResponse;
  5550. }
  5551. });
  5552. }
  5553. function initDoc(doc) {
  5554. doc.querySelectorAll("meta[http-equiv=refresh]").forEach(element => {
  5555. element.removeAttribute("http-equiv");
  5556. element.setAttribute("disabled-http-equiv", "refresh");
  5557. });
  5558. }
  5559. function preProcessDoc(doc, win, options) {
  5560. doc.querySelectorAll("noscript:not([" + DISABLED_NOSCRIPT_ATTRIBUTE_NAME + "])").forEach(element => {
  5561. element.setAttribute(DISABLED_NOSCRIPT_ATTRIBUTE_NAME, element.textContent);
  5562. element.textContent = "";
  5563. });
  5564. initDoc(doc);
  5565. if (doc.head) {
  5566. doc.head.querySelectorAll(FLOW_ELEMENTS_SELECTOR).forEach(element => element.hidden = true);
  5567. }
  5568. doc.querySelectorAll("svg foreignObject").forEach(element => {
  5569. const flowElements = element.querySelectorAll("html > head > " + FLOW_ELEMENTS_SELECTOR + ", html > body > " + FLOW_ELEMENTS_SELECTOR);
  5570. if (flowElements.length) {
  5571. Array.from(element.childNodes).forEach(node => node.remove());
  5572. flowElements.forEach(flowElement => element.appendChild(flowElement));
  5573. }
  5574. });
  5575. const invalidElements = new Map();
  5576. let elementsInfo;
  5577. if (win && doc.documentElement) {
  5578. doc.querySelectorAll("button button, a a").forEach(element => {
  5579. const placeHolderElement = doc.createElement("template");
  5580. placeHolderElement.setAttribute(INVALID_ELEMENT_ATTRIBUTE_NAME, "");
  5581. placeHolderElement.content.appendChild(element.cloneNode(true));
  5582. invalidElements.set(element, placeHolderElement);
  5583. element.replaceWith(placeHolderElement);
  5584. });
  5585. elementsInfo = getElementsInfo(win, doc, doc.documentElement, options);
  5586. if (options.moveStylesInHead) {
  5587. doc.querySelectorAll("body style, body ~ style").forEach(element => {
  5588. const computedStyle = getComputedStyle$1(win, element);
  5589. if (computedStyle && testHiddenElement(element, computedStyle)) {
  5590. element.setAttribute(STYLE_ATTRIBUTE_NAME, "");
  5591. elementsInfo.markedElements.push(element);
  5592. }
  5593. });
  5594. }
  5595. } else {
  5596. elementsInfo = {
  5597. canvases: [],
  5598. images: [],
  5599. posters: [],
  5600. videos: [],
  5601. usedFonts: [],
  5602. shadowRoots: [],
  5603. markedElements: []
  5604. };
  5605. }
  5606. return {
  5607. canvases: elementsInfo.canvases,
  5608. fonts: getFontsData(),
  5609. stylesheets: getStylesheetsData(doc),
  5610. images: elementsInfo.images,
  5611. posters: elementsInfo.posters,
  5612. videos: elementsInfo.videos,
  5613. usedFonts: Array.from(elementsInfo.usedFonts.values()),
  5614. shadowRoots: elementsInfo.shadowRoots,
  5615. referrer: doc.referrer,
  5616. markedElements: elementsInfo.markedElements,
  5617. invalidElements,
  5618. scrollPosition: { x: win.scrollX, y: win.scrollY },
  5619. adoptedStyleSheets: getStylesheetsContent(doc.adoptedStyleSheets)
  5620. };
  5621. }
  5622. function getElementsInfo(win, doc, element, options, data = { usedFonts: new Map(), canvases: [], images: [], posters: [], videos: [], shadowRoots: [], markedElements: [] }, ascendantHidden) {
  5623. if (element.childNodes) {
  5624. const elements = Array.from(element.childNodes).filter(node => (node instanceof win.HTMLElement) || (node instanceof win.SVGElement));
  5625. elements.forEach(element => {
  5626. let elementHidden, elementKept, computedStyle;
  5627. if (!options.autoSaveExternalSave && (options.removeHiddenElements || options.removeUnusedFonts || options.compressHTML)) {
  5628. computedStyle = getComputedStyle$1(win, element);
  5629. if (element instanceof win.HTMLElement) {
  5630. if (options.removeHiddenElements) {
  5631. elementKept = ((ascendantHidden || element.closest("html > head")) && KEPT_TAG_NAMES.includes(element.tagName.toUpperCase())) || element.closest("details");
  5632. if (!elementKept) {
  5633. elementHidden = ascendantHidden || testHiddenElement(element, computedStyle);
  5634. if (elementHidden) {
  5635. element.setAttribute(HIDDEN_CONTENT_ATTRIBUTE_NAME, "");
  5636. data.markedElements.push(element);
  5637. }
  5638. }
  5639. }
  5640. }
  5641. if (!elementHidden) {
  5642. if (options.compressHTML && computedStyle) {
  5643. const whiteSpace = computedStyle.getPropertyValue("white-space");
  5644. if (whiteSpace && whiteSpace.startsWith("pre")) {
  5645. element.setAttribute(PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME, "");
  5646. data.markedElements.push(element);
  5647. }
  5648. }
  5649. if (options.removeUnusedFonts) {
  5650. getUsedFont(computedStyle, options, data.usedFonts);
  5651. getUsedFont(getComputedStyle$1(win, element, ":first-letter"), options, data.usedFonts);
  5652. getUsedFont(getComputedStyle$1(win, element, ":before"), options, data.usedFonts);
  5653. getUsedFont(getComputedStyle$1(win, element, ":after"), options, data.usedFonts);
  5654. }
  5655. }
  5656. }
  5657. getResourcesInfo(win, doc, element, options, data, elementHidden, computedStyle);
  5658. const shadowRoot = !(element instanceof win.SVGElement) && getShadowRoot(element);
  5659. if (shadowRoot && !element.classList.contains(SINGLE_FILE_UI_ELEMENT_CLASS)) {
  5660. const shadowRootInfo = {};
  5661. element.setAttribute(SHADOW_ROOT_ATTRIBUTE_NAME, data.shadowRoots.length);
  5662. data.markedElements.push(element);
  5663. data.shadowRoots.push(shadowRootInfo);
  5664. try {
  5665. if (shadowRoot.adoptedStyleSheets) {
  5666. if (shadowRoot.adoptedStyleSheets.length) {
  5667. shadowRootInfo.adoptedStyleSheets = getStylesheetsContent(shadowRoot.adoptedStyleSheets);
  5668. } else if (shadowRoot.adoptedStyleSheets.length === undefined) {
  5669. const listener = event => shadowRootInfo.adoptedStyleSheets = event.detail.adoptedStyleSheets;
  5670. element.addEventListener(GET_ADOPTED_STYLESHEETS_RESPONSE_EVENT, listener);
  5671. element.dispatchEvent(new CustomEvent(GET_ADOPTED_STYLESHEETS_REQUEST_EVENT, { bubbles: true }));
  5672. element.removeEventListener(GET_ADOPTED_STYLESHEETS_RESPONSE_EVENT, listener);
  5673. }
  5674. }
  5675. } catch (error) {
  5676. // ignored
  5677. }
  5678. getElementsInfo(win, doc, shadowRoot, options, data, elementHidden);
  5679. shadowRootInfo.content = shadowRoot.innerHTML;
  5680. shadowRootInfo.mode = shadowRoot.mode;
  5681. try {
  5682. if (shadowRoot.adoptedStyleSheets && shadowRoot.adoptedStyleSheets.length === undefined) {
  5683. element.dispatchEvent(new CustomEvent(UNREGISTER_GET_ADOPTED_STYLESHEETS_REQUEST_EVENT, { bubbles: true }));
  5684. }
  5685. } catch (error) {
  5686. // ignored
  5687. }
  5688. }
  5689. getElementsInfo(win, doc, element, options, data, elementHidden);
  5690. if (!options.autoSaveExternalSave && options.removeHiddenElements && ascendantHidden) {
  5691. if (elementKept || element.getAttribute(KEPT_CONTENT_ATTRIBUTE_NAME) == "") {
  5692. if (element.parentElement) {
  5693. element.parentElement.setAttribute(KEPT_CONTENT_ATTRIBUTE_NAME, "");
  5694. data.markedElements.push(element.parentElement);
  5695. }
  5696. } else if (elementHidden) {
  5697. element.setAttribute(REMOVED_CONTENT_ATTRIBUTE_NAME, "");
  5698. data.markedElements.push(element);
  5699. }
  5700. }
  5701. });
  5702. }
  5703. return data;
  5704. }
  5705. function getStylesheetsContent(styleSheets) {
  5706. return styleSheets ? Array.from(styleSheets).map(stylesheet => Array.from(stylesheet.cssRules).map(cssRule => cssRule.cssText).join("\n")) : [];
  5707. }
  5708. function getResourcesInfo(win, doc, element, options, data, elementHidden, computedStyle) {
  5709. const tagName = element.tagName && element.tagName.toUpperCase();
  5710. if (tagName == "CANVAS") {
  5711. try {
  5712. data.canvases.push({
  5713. dataURI: element.toDataURL("image/png", ""),
  5714. backgroundColor: computedStyle.getPropertyValue("background-color")
  5715. });
  5716. element.setAttribute(CANVAS_ATTRIBUTE_NAME, data.canvases.length - 1);
  5717. data.markedElements.push(element);
  5718. } catch (error) {
  5719. // ignored
  5720. }
  5721. }
  5722. if (tagName == "IMG") {
  5723. const imageData = {
  5724. currentSrc: elementHidden ?
  5725. EMPTY_RESOURCE$1 :
  5726. (options.loadDeferredImages && element.getAttribute(LAZY_SRC_ATTRIBUTE_NAME)) || element.currentSrc
  5727. };
  5728. data.images.push(imageData);
  5729. element.setAttribute(IMAGE_ATTRIBUTE_NAME, data.images.length - 1);
  5730. data.markedElements.push(element);
  5731. element.removeAttribute(LAZY_SRC_ATTRIBUTE_NAME);
  5732. computedStyle = computedStyle || getComputedStyle$1(win, element);
  5733. if (computedStyle) {
  5734. imageData.size = getSize(win, element, computedStyle);
  5735. const boxShadow = computedStyle.getPropertyValue("box-shadow");
  5736. const backgroundImage = computedStyle.getPropertyValue("background-image");
  5737. if ((!boxShadow || boxShadow == "none") &&
  5738. (!backgroundImage || backgroundImage == "none") &&
  5739. (imageData.size.pxWidth > 1 || imageData.size.pxHeight > 1)) {
  5740. imageData.replaceable = true;
  5741. imageData.backgroundColor = computedStyle.getPropertyValue("background-color");
  5742. imageData.objectFit = computedStyle.getPropertyValue("object-fit");
  5743. imageData.boxSizing = computedStyle.getPropertyValue("box-sizing");
  5744. imageData.objectPosition = computedStyle.getPropertyValue("object-position");
  5745. }
  5746. }
  5747. }
  5748. if (tagName == "VIDEO") {
  5749. const src = element.currentSrc;
  5750. if (src && !src.startsWith("blob:") && !src.startsWith("data:")) {
  5751. const computedStyle = getComputedStyle$1(win, element.parentNode);
  5752. data.videos.push({
  5753. positionParent: computedStyle && computedStyle.getPropertyValue("position"),
  5754. src,
  5755. size: {
  5756. pxWidth: element.clientWidth,
  5757. pxHeight: element.clientHeight
  5758. },
  5759. currentTime: element.currentTime
  5760. });
  5761. element.setAttribute(VIDEO_ATTRIBUTE_NAME, data.videos.length - 1);
  5762. }
  5763. if (!element.getAttribute("poster")) {
  5764. const canvasElement = doc.createElement("canvas");
  5765. const context = canvasElement.getContext("2d");
  5766. canvasElement.width = element.clientWidth;
  5767. canvasElement.height = element.clientHeight;
  5768. try {
  5769. context.drawImage(element, 0, 0, canvasElement.width, canvasElement.height);
  5770. data.posters.push(canvasElement.toDataURL("image/png", ""));
  5771. element.setAttribute(POSTER_ATTRIBUTE_NAME, data.posters.length - 1);
  5772. data.markedElements.push(element);
  5773. } catch (error) {
  5774. // ignored
  5775. }
  5776. }
  5777. }
  5778. if (tagName == "IFRAME") {
  5779. if (elementHidden && options.removeHiddenElements) {
  5780. element.setAttribute(HIDDEN_FRAME_ATTRIBUTE_NAME, "");
  5781. data.markedElements.push(element);
  5782. }
  5783. }
  5784. if (tagName == "INPUT") {
  5785. if (element.type != "password") {
  5786. element.setAttribute(INPUT_VALUE_ATTRIBUTE_NAME, element.value);
  5787. data.markedElements.push(element);
  5788. }
  5789. if (element.type == "radio" || element.type == "checkbox") {
  5790. element.setAttribute(INPUT_VALUE_ATTRIBUTE_NAME, element.checked);
  5791. data.markedElements.push(element);
  5792. }
  5793. }
  5794. if (tagName == "TEXTAREA") {
  5795. element.setAttribute(INPUT_VALUE_ATTRIBUTE_NAME, element.value);
  5796. data.markedElements.push(element);
  5797. }
  5798. if (tagName == "SELECT") {
  5799. element.querySelectorAll("option").forEach(option => {
  5800. if (option.selected) {
  5801. option.setAttribute(INPUT_VALUE_ATTRIBUTE_NAME, "");
  5802. data.markedElements.push(option);
  5803. }
  5804. });
  5805. }
  5806. if (tagName == "SCRIPT") {
  5807. if (element.async && element.getAttribute("async") != "" && element.getAttribute("async") != "async") {
  5808. element.setAttribute(ASYNC_SCRIPT_ATTRIBUTE_NAME, "");
  5809. data.markedElements.push(element);
  5810. }
  5811. element.textContent = element.textContent.replace(/<\/script>/gi, "<\\/script>");
  5812. }
  5813. }
  5814. function getUsedFont(computedStyle, options, usedFonts) {
  5815. if (computedStyle) {
  5816. const fontStyle = computedStyle.getPropertyValue("font-style") || "normal";
  5817. computedStyle.getPropertyValue("font-family").split(",").forEach(fontFamilyName => {
  5818. fontFamilyName = normalizeFontFamily(fontFamilyName);
  5819. if (!options.loadedFonts || options.loadedFonts.find(font => normalizeFontFamily(font.family) == fontFamilyName && font.style == fontStyle)) {
  5820. const fontWeight = getFontWeight(computedStyle.getPropertyValue("font-weight"));
  5821. const fontVariant = computedStyle.getPropertyValue("font-variant") || "normal";
  5822. const value = [fontFamilyName, fontWeight, fontStyle, fontVariant];
  5823. usedFonts.set(JSON$5.stringify(value), [fontFamilyName, fontWeight, fontStyle, fontVariant]);
  5824. }
  5825. });
  5826. }
  5827. }
  5828. function getShadowRoot(element) {
  5829. const chrome = globalThis.chrome;
  5830. if (element.openOrClosedShadowRoot) {
  5831. return element.openOrClosedShadowRoot;
  5832. } else if (chrome && chrome.dom && chrome.dom.openOrClosedShadowRoot) {
  5833. try {
  5834. return chrome.dom.openOrClosedShadowRoot(element);
  5835. } catch (error) {
  5836. return element.shadowRoot;
  5837. }
  5838. } else {
  5839. return element.shadowRoot;
  5840. }
  5841. }
  5842. function appendInfobar(doc, options, useShadowRoot) {
  5843. return appendInfobar$1(doc, options, useShadowRoot);
  5844. }
  5845. function normalizeFontFamily(fontFamilyName = "") {
  5846. return removeQuotes$1(process$8(fontFamilyName.trim())).toLowerCase();
  5847. }
  5848. function testHiddenElement(element, computedStyle) {
  5849. let hidden = false;
  5850. if (computedStyle) {
  5851. const display = computedStyle.getPropertyValue("display");
  5852. const opacity = computedStyle.getPropertyValue("opacity");
  5853. const visibility = computedStyle.getPropertyValue("visibility");
  5854. hidden = display == "none";
  5855. if (!hidden && (opacity == "0" || visibility == "hidden") && element.getBoundingClientRect) {
  5856. const boundingRect = element.getBoundingClientRect();
  5857. hidden = !boundingRect.width && !boundingRect.height;
  5858. }
  5859. }
  5860. return Boolean(hidden);
  5861. }
  5862. function postProcessDoc(doc, markedElements, invalidElements) {
  5863. doc.querySelectorAll("[" + DISABLED_NOSCRIPT_ATTRIBUTE_NAME + "]").forEach(element => {
  5864. element.textContent = element.getAttribute(DISABLED_NOSCRIPT_ATTRIBUTE_NAME);
  5865. element.removeAttribute(DISABLED_NOSCRIPT_ATTRIBUTE_NAME);
  5866. if (doc.body.firstChild) {
  5867. doc.body.insertBefore(element, doc.body.firstChild);
  5868. } else {
  5869. doc.body.appendChild(element);
  5870. }
  5871. });
  5872. doc.querySelectorAll("meta[disabled-http-equiv]").forEach(element => {
  5873. element.setAttribute("http-equiv", element.getAttribute("disabled-http-equiv"));
  5874. element.removeAttribute("disabled-http-equiv");
  5875. });
  5876. if (doc.head) {
  5877. doc.head.querySelectorAll("*:not(base):not(link):not(meta):not(noscript):not(script):not(style):not(template):not(title)").forEach(element => element.removeAttribute("hidden"));
  5878. }
  5879. if (!markedElements) {
  5880. const singleFileAttributes = [REMOVED_CONTENT_ATTRIBUTE_NAME, HIDDEN_FRAME_ATTRIBUTE_NAME, HIDDEN_CONTENT_ATTRIBUTE_NAME, PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME, IMAGE_ATTRIBUTE_NAME, POSTER_ATTRIBUTE_NAME, VIDEO_ATTRIBUTE_NAME, CANVAS_ATTRIBUTE_NAME, INPUT_VALUE_ATTRIBUTE_NAME, SHADOW_ROOT_ATTRIBUTE_NAME, STYLESHEET_ATTRIBUTE_NAME, ASYNC_SCRIPT_ATTRIBUTE_NAME];
  5881. markedElements = doc.querySelectorAll(singleFileAttributes.map(name => "[" + name + "]").join(","));
  5882. }
  5883. markedElements.forEach(element => {
  5884. element.removeAttribute(REMOVED_CONTENT_ATTRIBUTE_NAME);
  5885. element.removeAttribute(HIDDEN_CONTENT_ATTRIBUTE_NAME);
  5886. element.removeAttribute(KEPT_CONTENT_ATTRIBUTE_NAME);
  5887. element.removeAttribute(HIDDEN_FRAME_ATTRIBUTE_NAME);
  5888. element.removeAttribute(PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME);
  5889. element.removeAttribute(IMAGE_ATTRIBUTE_NAME);
  5890. element.removeAttribute(POSTER_ATTRIBUTE_NAME);
  5891. element.removeAttribute(VIDEO_ATTRIBUTE_NAME);
  5892. element.removeAttribute(CANVAS_ATTRIBUTE_NAME);
  5893. element.removeAttribute(INPUT_VALUE_ATTRIBUTE_NAME);
  5894. element.removeAttribute(SHADOW_ROOT_ATTRIBUTE_NAME);
  5895. element.removeAttribute(STYLESHEET_ATTRIBUTE_NAME);
  5896. element.removeAttribute(ASYNC_SCRIPT_ATTRIBUTE_NAME);
  5897. element.removeAttribute(STYLE_ATTRIBUTE_NAME);
  5898. });
  5899. if (invalidElements) {
  5900. invalidElements.forEach((placeholderElement, element) => placeholderElement.replaceWith(element));
  5901. }
  5902. }
  5903. function getStylesheetsData(doc) {
  5904. if (doc) {
  5905. const contents = [];
  5906. doc.querySelectorAll("style").forEach((styleElement, styleIndex) => {
  5907. try {
  5908. const tempStyleElement = doc.createElement("style");
  5909. tempStyleElement.textContent = styleElement.textContent;
  5910. doc.body.appendChild(tempStyleElement);
  5911. const stylesheet = tempStyleElement.sheet;
  5912. tempStyleElement.remove();
  5913. if (!stylesheet || stylesheet.cssRules.length != styleElement.sheet.cssRules.length) {
  5914. styleElement.setAttribute(STYLESHEET_ATTRIBUTE_NAME, styleIndex);
  5915. contents[styleIndex] = Array.from(styleElement.sheet.cssRules).map(cssRule => cssRule.cssText).join("\n");
  5916. }
  5917. } catch (error) {
  5918. // ignored
  5919. }
  5920. });
  5921. return contents;
  5922. }
  5923. }
  5924. function getSize(win, imageElement, computedStyle) {
  5925. let pxWidth = imageElement.naturalWidth;
  5926. let pxHeight = imageElement.naturalHeight;
  5927. if (!pxWidth && !pxHeight) {
  5928. const noStyleAttribute = imageElement.getAttribute("style") == null;
  5929. computedStyle = computedStyle || getComputedStyle$1(win, imageElement);
  5930. if (computedStyle) {
  5931. let removeBorderWidth = false;
  5932. if (computedStyle.getPropertyValue("box-sizing") == "content-box") {
  5933. const boxSizingValue = imageElement.style.getPropertyValue("box-sizing");
  5934. const boxSizingPriority = imageElement.style.getPropertyPriority("box-sizing");
  5935. const clientWidth = imageElement.clientWidth;
  5936. imageElement.style.setProperty("box-sizing", "border-box", "important");
  5937. removeBorderWidth = imageElement.clientWidth != clientWidth;
  5938. if (boxSizingValue) {
  5939. imageElement.style.setProperty("box-sizing", boxSizingValue, boxSizingPriority);
  5940. } else {
  5941. imageElement.style.removeProperty("box-sizing");
  5942. }
  5943. }
  5944. let paddingLeft, paddingRight, paddingTop, paddingBottom, borderLeft, borderRight, borderTop, borderBottom;
  5945. paddingLeft = getWidth("padding-left", computedStyle);
  5946. paddingRight = getWidth("padding-right", computedStyle);
  5947. paddingTop = getWidth("padding-top", computedStyle);
  5948. paddingBottom = getWidth("padding-bottom", computedStyle);
  5949. if (removeBorderWidth) {
  5950. borderLeft = getWidth("border-left-width", computedStyle);
  5951. borderRight = getWidth("border-right-width", computedStyle);
  5952. borderTop = getWidth("border-top-width", computedStyle);
  5953. borderBottom = getWidth("border-bottom-width", computedStyle);
  5954. } else {
  5955. borderLeft = borderRight = borderTop = borderBottom = 0;
  5956. }
  5957. pxWidth = Math.max(0, imageElement.clientWidth - paddingLeft - paddingRight - borderLeft - borderRight);
  5958. pxHeight = Math.max(0, imageElement.clientHeight - paddingTop - paddingBottom - borderTop - borderBottom);
  5959. if (noStyleAttribute) {
  5960. imageElement.removeAttribute("style");
  5961. }
  5962. }
  5963. }
  5964. return { pxWidth, pxHeight };
  5965. }
  5966. function getWidth(styleName, computedStyle) {
  5967. if (computedStyle.getPropertyValue(styleName).endsWith("px")) {
  5968. return parseFloat(computedStyle.getPropertyValue(styleName));
  5969. }
  5970. }
  5971. function getFontsData() {
  5972. return getFontsData$1();
  5973. }
  5974. function serialize$1(doc) {
  5975. const docType = doc.doctype;
  5976. let docTypeString = "";
  5977. if (docType) {
  5978. docTypeString = "<!DOCTYPE " + docType.nodeName;
  5979. if (docType.publicId) {
  5980. docTypeString += " PUBLIC \"" + docType.publicId + "\"";
  5981. if (docType.systemId) {
  5982. docTypeString += " \"" + docType.systemId + "\"";
  5983. }
  5984. } else if (docType.systemId) {
  5985. docTypeString += " SYSTEM \"" + docType.systemId + "\"";
  5986. } if (docType.internalSubset) {
  5987. docTypeString += " [" + docType.internalSubset + "]";
  5988. }
  5989. docTypeString += "> ";
  5990. }
  5991. return docTypeString + doc.documentElement.outerHTML;
  5992. }
  5993. function removeQuotes$1(string) {
  5994. if (string.match(REGEXP_SIMPLE_QUOTES_STRING$3)) {
  5995. string = string.replace(REGEXP_SIMPLE_QUOTES_STRING$3, "$1");
  5996. } else {
  5997. string = string.replace(REGEXP_DOUBLE_QUOTES_STRING$3, "$1");
  5998. }
  5999. return string.trim();
  6000. }
  6001. function getFontWeight(weight) {
  6002. return FONT_WEIGHTS[weight.toLowerCase().trim()] || weight;
  6003. }
  6004. function flatten(array) {
  6005. return array.flat ? array.flat() : array.reduce((a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []);
  6006. }
  6007. function getComputedStyle$1(win, element, pseudoElement) {
  6008. try {
  6009. return win.getComputedStyle(element, pseudoElement);
  6010. } catch (error) {
  6011. // ignored
  6012. }
  6013. }
  6014. var helper$4 = /*#__PURE__*/Object.freeze({
  6015. __proto__: null,
  6016. initUserScriptHandler: initUserScriptHandler,
  6017. initDoc: initDoc,
  6018. preProcessDoc: preProcessDoc,
  6019. postProcessDoc: postProcessDoc,
  6020. serialize: serialize$1,
  6021. removeQuotes: removeQuotes$1,
  6022. flatten: flatten,
  6023. getFontWeight: getFontWeight,
  6024. normalizeFontFamily: normalizeFontFamily,
  6025. getShadowRoot: getShadowRoot,
  6026. appendInfobar: appendInfobar,
  6027. ON_BEFORE_CAPTURE_EVENT_NAME: ON_BEFORE_CAPTURE_EVENT_NAME,
  6028. ON_AFTER_CAPTURE_EVENT_NAME: ON_AFTER_CAPTURE_EVENT_NAME,
  6029. WIN_ID_ATTRIBUTE_NAME: WIN_ID_ATTRIBUTE_NAME,
  6030. PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME: PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME,
  6031. REMOVED_CONTENT_ATTRIBUTE_NAME: REMOVED_CONTENT_ATTRIBUTE_NAME,
  6032. HIDDEN_CONTENT_ATTRIBUTE_NAME: HIDDEN_CONTENT_ATTRIBUTE_NAME,
  6033. HIDDEN_FRAME_ATTRIBUTE_NAME: HIDDEN_FRAME_ATTRIBUTE_NAME,
  6034. IMAGE_ATTRIBUTE_NAME: IMAGE_ATTRIBUTE_NAME,
  6035. POSTER_ATTRIBUTE_NAME: POSTER_ATTRIBUTE_NAME,
  6036. VIDEO_ATTRIBUTE_NAME: VIDEO_ATTRIBUTE_NAME,
  6037. CANVAS_ATTRIBUTE_NAME: CANVAS_ATTRIBUTE_NAME,
  6038. INPUT_VALUE_ATTRIBUTE_NAME: INPUT_VALUE_ATTRIBUTE_NAME,
  6039. SHADOW_ROOT_ATTRIBUTE_NAME: SHADOW_ROOT_ATTRIBUTE_NAME,
  6040. STYLE_ATTRIBUTE_NAME: STYLE_ATTRIBUTE_NAME,
  6041. LAZY_SRC_ATTRIBUTE_NAME: LAZY_SRC_ATTRIBUTE_NAME,
  6042. STYLESHEET_ATTRIBUTE_NAME: STYLESHEET_ATTRIBUTE_NAME,
  6043. SELECTED_CONTENT_ATTRIBUTE_NAME: SELECTED_CONTENT_ATTRIBUTE_NAME,
  6044. INVALID_ELEMENT_ATTRIBUTE_NAME: INVALID_ELEMENT_ATTRIBUTE_NAME,
  6045. ASYNC_SCRIPT_ATTRIBUTE_NAME: ASYNC_SCRIPT_ATTRIBUTE_NAME,
  6046. COMMENT_HEADER: COMMENT_HEADER,
  6047. COMMENT_HEADER_LEGACY: COMMENT_HEADER_LEGACY,
  6048. SINGLE_FILE_UI_ELEMENT_CLASS: SINGLE_FILE_UI_ELEMENT_CLASS,
  6049. EMPTY_RESOURCE: EMPTY_RESOURCE$1,
  6050. INFOBAR_TAGNAME: INFOBAR_TAGNAME,
  6051. WAIT_FOR_USERSCRIPT_PROPERTY_NAME: WAIT_FOR_USERSCRIPT_PROPERTY_NAME,
  6052. MESSAGE_PREFIX: MESSAGE_PREFIX,
  6053. NO_SCRIPT_PROPERTY_NAME: NO_SCRIPT_PROPERTY_NAME
  6054. });
  6055. /*
  6056. * Copyright 2010-2022 Gildas Lormeau
  6057. * contact : gildas.lormeau <at> gmail.com
  6058. *
  6059. * This file is part of SingleFile.
  6060. *
  6061. * The code in this file is free software: you can redistribute it and/or
  6062. * modify it under the terms of the GNU Affero General Public License
  6063. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  6064. * of the License, or (at your option) any later version.
  6065. *
  6066. * The code in this file is distributed in the hope that it will be useful,
  6067. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  6068. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  6069. * General Public License for more details.
  6070. *
  6071. * As additional permission under GNU AGPL version 3 section 7, you may
  6072. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  6073. * AGPL normally required by section 4, provided you include this license
  6074. * notice and a URL through which recipients can access the Corresponding
  6075. * Source.
  6076. */
  6077. const helper$3 = {
  6078. LAZY_SRC_ATTRIBUTE_NAME,
  6079. SINGLE_FILE_UI_ELEMENT_CLASS
  6080. };
  6081. const MAX_IDLE_TIMEOUT_CALLS = 10;
  6082. const ATTRIBUTES_MUTATION_TYPE = "attributes";
  6083. const browser$1 = globalThis.browser;
  6084. const document$2 = globalThis.document;
  6085. const MutationObserver = globalThis.MutationObserver;
  6086. const addEventListener$1 = (type, listener, options) => globalThis.addEventListener(type, listener, options);
  6087. const removeEventListener = (type, listener, options) => globalThis.removeEventListener(type, listener, options);
  6088. const timeouts = new Map();
  6089. let idleTimeoutCalls;
  6090. if (browser$1 && browser$1.runtime && browser$1.runtime.onMessage && browser$1.runtime.onMessage.addListener) {
  6091. browser$1.runtime.onMessage.addListener(message => {
  6092. if (message.method == "singlefile.lazyTimeout.onTimeout") {
  6093. const timeoutData = timeouts.get(message.type);
  6094. if (timeoutData) {
  6095. timeouts.delete(message.type);
  6096. try {
  6097. timeoutData.callback();
  6098. } catch (error) {
  6099. clearRegularTimeout(message.type);
  6100. }
  6101. }
  6102. }
  6103. });
  6104. }
  6105. async function process$7(options) {
  6106. if (document$2.documentElement) {
  6107. timeouts.clear();
  6108. const bodyHeight = document$2.body ? Math.max(document$2.body.scrollHeight, document$2.documentElement.scrollHeight) : document$2.documentElement.scrollHeight;
  6109. const bodyWidth = document$2.body ? Math.max(document$2.body.scrollWidth, document$2.documentElement.scrollWidth) : document$2.documentElement.scrollWidth;
  6110. if (bodyHeight > globalThis.innerHeight || bodyWidth > globalThis.innerWidth) {
  6111. const maxScrollY = Math.max(bodyHeight - (globalThis.innerHeight * 1.5), 0);
  6112. const maxScrollX = Math.max(bodyWidth - (globalThis.innerWidth * 1.5), 0);
  6113. if (globalThis.scrollY < maxScrollY || globalThis.scrollX < maxScrollX) {
  6114. return triggerLazyLoading(options);
  6115. }
  6116. }
  6117. }
  6118. }
  6119. function resetZoomLevel(options) {
  6120. loadDeferredImagesResetZoomLevel(options);
  6121. }
  6122. function triggerLazyLoading(options) {
  6123. idleTimeoutCalls = 0;
  6124. return new Promise(async resolve => { // eslint-disable-line no-async-promise-executor
  6125. let loadingImages;
  6126. const pendingImages = new Set();
  6127. const observer = new MutationObserver(async mutations => {
  6128. mutations = mutations.filter(mutation => mutation.type == ATTRIBUTES_MUTATION_TYPE);
  6129. if (mutations.length) {
  6130. const updated = mutations.filter(mutation => {
  6131. if (mutation.attributeName == "src") {
  6132. mutation.target.setAttribute(helper$3.LAZY_SRC_ATTRIBUTE_NAME, mutation.target.src);
  6133. mutation.target.addEventListener("load", onResourceLoad);
  6134. }
  6135. if (mutation.attributeName == "src" || mutation.attributeName == "srcset" ||
  6136. (mutation.target.tagName && mutation.target.tagName.toUpperCase() == "SOURCE")) {
  6137. return !mutation.target.classList || !mutation.target.classList.contains(helper$3.SINGLE_FILE_UI_ELEMENT_CLASS);
  6138. }
  6139. });
  6140. if (updated.length) {
  6141. loadingImages = true;
  6142. await deferForceLazyLoadEnd(observer, options, cleanupAndResolve);
  6143. if (!pendingImages.size) {
  6144. await deferLazyLoadEnd(observer, options, cleanupAndResolve);
  6145. }
  6146. }
  6147. }
  6148. });
  6149. await setIdleTimeout(options.loadDeferredImagesMaxIdleTime * 2);
  6150. await deferForceLazyLoadEnd(observer, options, cleanupAndResolve);
  6151. observer.observe(document$2, { subtree: true, childList: true, attributes: true });
  6152. addEventListener$1(LOAD_IMAGE_EVENT, onImageLoadEvent);
  6153. addEventListener$1(IMAGE_LOADED_EVENT, onImageLoadedEvent);
  6154. loadDeferredImagesStart(options);
  6155. async function setIdleTimeout(delay) {
  6156. await setAsyncTimeout("idleTimeout", async () => {
  6157. if (!loadingImages) {
  6158. clearAsyncTimeout("loadTimeout");
  6159. clearAsyncTimeout("maxTimeout");
  6160. lazyLoadEnd(observer, options, cleanupAndResolve);
  6161. } else if (idleTimeoutCalls < MAX_IDLE_TIMEOUT_CALLS) {
  6162. idleTimeoutCalls++;
  6163. clearAsyncTimeout("idleTimeout");
  6164. await setIdleTimeout(Math.max(500, delay / 2));
  6165. }
  6166. }, delay, options.loadDeferredImagesNativeTimeout);
  6167. }
  6168. function onResourceLoad(event) {
  6169. const element = event.target;
  6170. element.removeAttribute(helper$3.LAZY_SRC_ATTRIBUTE_NAME);
  6171. element.removeEventListener("load", onResourceLoad);
  6172. }
  6173. async function onImageLoadEvent(event) {
  6174. loadingImages = true;
  6175. await deferForceLazyLoadEnd(observer, options, cleanupAndResolve);
  6176. await deferLazyLoadEnd(observer, options, cleanupAndResolve);
  6177. if (event.detail) {
  6178. pendingImages.add(event.detail);
  6179. }
  6180. }
  6181. async function onImageLoadedEvent(event) {
  6182. await deferForceLazyLoadEnd(observer, options, cleanupAndResolve);
  6183. await deferLazyLoadEnd(observer, options, cleanupAndResolve);
  6184. pendingImages.delete(event.detail);
  6185. if (!pendingImages.size) {
  6186. await deferLazyLoadEnd(observer, options, cleanupAndResolve);
  6187. }
  6188. }
  6189. function cleanupAndResolve(value) {
  6190. observer.disconnect();
  6191. removeEventListener(LOAD_IMAGE_EVENT, onImageLoadEvent);
  6192. removeEventListener(IMAGE_LOADED_EVENT, onImageLoadedEvent);
  6193. resolve(value);
  6194. }
  6195. });
  6196. }
  6197. async function deferLazyLoadEnd(observer, options, resolve) {
  6198. await setAsyncTimeout("loadTimeout", () => lazyLoadEnd(observer, options, resolve), options.loadDeferredImagesMaxIdleTime, options.loadDeferredImagesNativeTimeout);
  6199. }
  6200. async function deferForceLazyLoadEnd(observer, options, resolve) {
  6201. await setAsyncTimeout("maxTimeout", async () => {
  6202. await clearAsyncTimeout("loadTimeout");
  6203. await lazyLoadEnd(observer, options, resolve);
  6204. }, options.loadDeferredImagesMaxIdleTime * 10, options.loadDeferredImagesNativeTimeout);
  6205. }
  6206. async function lazyLoadEnd(observer, options, resolve) {
  6207. await clearAsyncTimeout("idleTimeout");
  6208. loadDeferredImagesEnd(options);
  6209. await setAsyncTimeout("endTimeout", async () => {
  6210. await clearAsyncTimeout("maxTimeout");
  6211. resolve();
  6212. }, options.loadDeferredImagesMaxIdleTime / 2, options.loadDeferredImagesNativeTimeout);
  6213. observer.disconnect();
  6214. }
  6215. async function setAsyncTimeout(type, callback, delay, forceNativeTimeout) {
  6216. if (browser$1 && browser$1.runtime && browser$1.runtime.sendMessage && !forceNativeTimeout) {
  6217. if (!timeouts.get(type) || !timeouts.get(type).pending) {
  6218. const timeoutData = { callback, pending: true };
  6219. timeouts.set(type, timeoutData);
  6220. try {
  6221. await browser$1.runtime.sendMessage({ method: "singlefile.lazyTimeout.setTimeout", type, delay });
  6222. } catch (error) {
  6223. setRegularTimeout(type, callback, delay);
  6224. }
  6225. timeoutData.pending = false;
  6226. }
  6227. } else {
  6228. setRegularTimeout(type, callback, delay);
  6229. }
  6230. }
  6231. function setRegularTimeout(type, callback, delay) {
  6232. const timeoutId = timeouts.get(type);
  6233. if (timeoutId) {
  6234. globalThis.clearTimeout(timeoutId);
  6235. }
  6236. timeouts.set(type, callback);
  6237. globalThis.setTimeout(callback, delay);
  6238. }
  6239. async function clearAsyncTimeout(type) {
  6240. if (browser$1 && browser$1.runtime && browser$1.runtime.sendMessage) {
  6241. try {
  6242. await browser$1.runtime.sendMessage({ method: "singlefile.lazyTimeout.clearTimeout", type });
  6243. } catch (error) {
  6244. clearRegularTimeout(type);
  6245. }
  6246. } else {
  6247. clearRegularTimeout(type);
  6248. }
  6249. }
  6250. function clearRegularTimeout(type) {
  6251. const previousTimeoutId = timeouts.get(type);
  6252. timeouts.delete(type);
  6253. if (previousTimeoutId) {
  6254. globalThis.clearTimeout(previousTimeoutId);
  6255. }
  6256. }
  6257. var contentLazyLoader = /*#__PURE__*/Object.freeze({
  6258. __proto__: null,
  6259. process: process$7,
  6260. resetZoomLevel: resetZoomLevel
  6261. });
  6262. /*
  6263. * Copyright 2010-2022 Gildas Lormeau
  6264. * contact : gildas.lormeau <at> gmail.com
  6265. *
  6266. * This file is part of SingleFile.
  6267. *
  6268. * The code in this file is free software: you can redistribute it and/or
  6269. * modify it under the terms of the GNU Affero General Public License
  6270. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  6271. * of the License, or (at your option) any later version.
  6272. *
  6273. * The code in this file is distributed in the hope that it will be useful,
  6274. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  6275. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  6276. * General Public License for more details.
  6277. *
  6278. * As additional permission under GNU AGPL version 3 section 7, you may
  6279. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  6280. * AGPL normally required by section 4, provided you include this license
  6281. * notice and a URL through which recipients can access the Corresponding
  6282. * Source.
  6283. */
  6284. const helper$2 = {
  6285. ON_BEFORE_CAPTURE_EVENT_NAME,
  6286. ON_AFTER_CAPTURE_EVENT_NAME,
  6287. WIN_ID_ATTRIBUTE_NAME,
  6288. WAIT_FOR_USERSCRIPT_PROPERTY_NAME,
  6289. preProcessDoc,
  6290. serialize: serialize$1,
  6291. postProcessDoc,
  6292. getShadowRoot
  6293. };
  6294. const FRAMES_CSS_SELECTOR = "iframe, frame, object[type=\"text/html\"][data]";
  6295. const ALL_ELEMENTS_CSS_SELECTOR = "*";
  6296. const INIT_REQUEST_MESSAGE = "singlefile.frameTree.initRequest";
  6297. const ACK_INIT_REQUEST_MESSAGE = "singlefile.frameTree.ackInitRequest";
  6298. const CLEANUP_REQUEST_MESSAGE = "singlefile.frameTree.cleanupRequest";
  6299. const INIT_RESPONSE_MESSAGE = "singlefile.frameTree.initResponse";
  6300. const TARGET_ORIGIN = "*";
  6301. const TIMEOUT_INIT_REQUEST_MESSAGE = 5000;
  6302. const TIMEOUT_INIT_RESPONSE_MESSAGE = 10000;
  6303. const TOP_WINDOW_ID = "0";
  6304. const WINDOW_ID_SEPARATOR = ".";
  6305. const TOP_WINDOW = globalThis.window == globalThis.top;
  6306. const browser = globalThis.browser;
  6307. const addEventListener = (type, listener, options) => globalThis.addEventListener(type, listener, options);
  6308. const top = globalThis.top;
  6309. const MessageChannel = globalThis.MessageChannel;
  6310. const document$1 = globalThis.document;
  6311. const JSON$4 = globalThis.JSON;
  6312. let sessions = globalThis.sessions;
  6313. if (!sessions) {
  6314. sessions = globalThis.sessions = new Map();
  6315. }
  6316. let windowId;
  6317. if (TOP_WINDOW) {
  6318. windowId = TOP_WINDOW_ID;
  6319. if (browser && browser.runtime && browser.runtime.onMessage && browser.runtime.onMessage.addListener) {
  6320. browser.runtime.onMessage.addListener(message => {
  6321. if (message.method == INIT_RESPONSE_MESSAGE) {
  6322. initResponse(message);
  6323. return Promise.resolve({});
  6324. } else if (message.method == ACK_INIT_REQUEST_MESSAGE) {
  6325. clearFrameTimeout("requestTimeouts", message.sessionId, message.windowId);
  6326. createFrameResponseTimeout(message.sessionId, message.windowId);
  6327. return Promise.resolve({});
  6328. }
  6329. });
  6330. }
  6331. }
  6332. addEventListener("message", async event => {
  6333. if (typeof event.data == "string" && event.data.startsWith(MESSAGE_PREFIX)) {
  6334. event.preventDefault();
  6335. event.stopPropagation();
  6336. const message = JSON$4.parse(event.data.substring(MESSAGE_PREFIX.length));
  6337. if (message.method == INIT_REQUEST_MESSAGE) {
  6338. if (event.source) {
  6339. sendMessage(event.source, { method: ACK_INIT_REQUEST_MESSAGE, windowId: message.windowId, sessionId: message.sessionId });
  6340. }
  6341. if (!TOP_WINDOW) {
  6342. globalThis.stop();
  6343. if (message.options.loadDeferredImages) {
  6344. process$7(message.options);
  6345. }
  6346. await initRequestAsync(message);
  6347. }
  6348. } else if (message.method == ACK_INIT_REQUEST_MESSAGE) {
  6349. clearFrameTimeout("requestTimeouts", message.sessionId, message.windowId);
  6350. createFrameResponseTimeout(message.sessionId, message.windowId);
  6351. } else if (message.method == CLEANUP_REQUEST_MESSAGE) {
  6352. cleanupRequest(message);
  6353. } else if (message.method == INIT_RESPONSE_MESSAGE && sessions.get(message.sessionId)) {
  6354. const port = event.ports[0];
  6355. port.onmessage = event => initResponse(event.data);
  6356. }
  6357. }
  6358. }, true);
  6359. function getAsync(options) {
  6360. const sessionId = getNewSessionId();
  6361. options = JSON$4.parse(JSON$4.stringify(options));
  6362. return new Promise(resolve => {
  6363. sessions.set(sessionId, {
  6364. frames: [],
  6365. requestTimeouts: {},
  6366. responseTimeouts: {},
  6367. resolve: frames => {
  6368. frames.sessionId = sessionId;
  6369. resolve(frames);
  6370. }
  6371. });
  6372. initRequestAsync({ windowId, sessionId, options });
  6373. });
  6374. }
  6375. function getSync(options) {
  6376. const sessionId = getNewSessionId();
  6377. options = JSON$4.parse(JSON$4.stringify(options));
  6378. sessions.set(sessionId, {
  6379. frames: [],
  6380. requestTimeouts: {},
  6381. responseTimeouts: {}
  6382. });
  6383. initRequestSync({ windowId, sessionId, options });
  6384. const frames = sessions.get(sessionId).frames;
  6385. frames.sessionId = sessionId;
  6386. return frames;
  6387. }
  6388. function cleanup(sessionId) {
  6389. sessions.delete(sessionId);
  6390. cleanupRequest({ windowId, sessionId, options: { sessionId } });
  6391. }
  6392. function getNewSessionId() {
  6393. return globalThis.crypto.getRandomValues(new Uint32Array(32)).join("");
  6394. }
  6395. function initRequestSync(message) {
  6396. const sessionId = message.sessionId;
  6397. const waitForUserScript = globalThis[helper$2.WAIT_FOR_USERSCRIPT_PROPERTY_NAME];
  6398. delete globalThis._singleFile_cleaningUp;
  6399. if (!TOP_WINDOW) {
  6400. windowId = globalThis.frameId = message.windowId;
  6401. }
  6402. processFrames(document$1, message.options, windowId, sessionId);
  6403. if (!TOP_WINDOW) {
  6404. if (message.options.userScriptEnabled && waitForUserScript) {
  6405. waitForUserScript(helper$2.ON_BEFORE_CAPTURE_EVENT_NAME);
  6406. }
  6407. sendInitResponse({ frames: [getFrameData(document$1, globalThis, windowId, message.options, message.scrolling)], sessionId, requestedFrameId: document$1.documentElement.dataset.requestedFrameId && windowId });
  6408. if (message.options.userScriptEnabled && waitForUserScript) {
  6409. waitForUserScript(helper$2.ON_AFTER_CAPTURE_EVENT_NAME);
  6410. }
  6411. delete document$1.documentElement.dataset.requestedFrameId;
  6412. }
  6413. }
  6414. async function initRequestAsync(message) {
  6415. const sessionId = message.sessionId;
  6416. const waitForUserScript = globalThis[helper$2.WAIT_FOR_USERSCRIPT_PROPERTY_NAME];
  6417. delete globalThis._singleFile_cleaningUp;
  6418. if (!TOP_WINDOW) {
  6419. windowId = globalThis.frameId = message.windowId;
  6420. }
  6421. processFrames(document$1, message.options, windowId, sessionId);
  6422. if (!TOP_WINDOW) {
  6423. if (message.options.userScriptEnabled && waitForUserScript) {
  6424. await waitForUserScript(helper$2.ON_BEFORE_CAPTURE_EVENT_NAME);
  6425. }
  6426. sendInitResponse({ frames: [getFrameData(document$1, globalThis, windowId, message.options, message.scrolling)], sessionId, requestedFrameId: document$1.documentElement.dataset.requestedFrameId && windowId });
  6427. if (message.options.userScriptEnabled && waitForUserScript) {
  6428. await waitForUserScript(helper$2.ON_AFTER_CAPTURE_EVENT_NAME);
  6429. }
  6430. delete document$1.documentElement.dataset.requestedFrameId;
  6431. }
  6432. }
  6433. function cleanupRequest(message) {
  6434. if (!globalThis._singleFile_cleaningUp) {
  6435. globalThis._singleFile_cleaningUp = true;
  6436. const sessionId = message.sessionId;
  6437. cleanupFrames(getFrames(document$1), message.windowId, sessionId);
  6438. }
  6439. }
  6440. function initResponse(message) {
  6441. message.frames.forEach(frameData => clearFrameTimeout("responseTimeouts", message.sessionId, frameData.windowId));
  6442. const windowData = sessions.get(message.sessionId);
  6443. if (windowData) {
  6444. if (message.requestedFrameId) {
  6445. windowData.requestedFrameId = message.requestedFrameId;
  6446. }
  6447. message.frames.forEach(messageFrameData => {
  6448. let frameData = windowData.frames.find(frameData => messageFrameData.windowId == frameData.windowId);
  6449. if (!frameData) {
  6450. frameData = { windowId: messageFrameData.windowId };
  6451. windowData.frames.push(frameData);
  6452. }
  6453. if (!frameData.processed) {
  6454. frameData.content = messageFrameData.content;
  6455. frameData.baseURI = messageFrameData.baseURI;
  6456. frameData.title = messageFrameData.title;
  6457. frameData.url = messageFrameData.url;
  6458. frameData.canvases = messageFrameData.canvases;
  6459. frameData.fonts = messageFrameData.fonts;
  6460. frameData.stylesheets = messageFrameData.stylesheets;
  6461. frameData.images = messageFrameData.images;
  6462. frameData.posters = messageFrameData.posters;
  6463. frameData.videos = messageFrameData.videos;
  6464. frameData.usedFonts = messageFrameData.usedFonts;
  6465. frameData.shadowRoots = messageFrameData.shadowRoots;
  6466. frameData.processed = messageFrameData.processed;
  6467. frameData.scrollPosition = messageFrameData.scrollPosition;
  6468. frameData.scrolling = messageFrameData.scrolling;
  6469. frameData.adoptedStyleSheets = messageFrameData.adoptedStyleSheets;
  6470. }
  6471. });
  6472. const remainingFrames = windowData.frames.filter(frameData => !frameData.processed).length;
  6473. if (!remainingFrames) {
  6474. windowData.frames = windowData.frames.sort((frame1, frame2) => frame2.windowId.split(WINDOW_ID_SEPARATOR).length - frame1.windowId.split(WINDOW_ID_SEPARATOR).length);
  6475. if (windowData.resolve) {
  6476. if (windowData.requestedFrameId) {
  6477. windowData.frames.forEach(frameData => {
  6478. if (frameData.windowId == windowData.requestedFrameId) {
  6479. frameData.requestedFrame = true;
  6480. }
  6481. });
  6482. }
  6483. windowData.resolve(windowData.frames);
  6484. }
  6485. }
  6486. }
  6487. }
  6488. function processFrames(doc, options, parentWindowId, sessionId) {
  6489. const frameElements = getFrames(doc);
  6490. processFramesAsync(doc, frameElements, options, parentWindowId, sessionId);
  6491. if (frameElements.length) {
  6492. processFramesSync(doc, frameElements, options, parentWindowId, sessionId);
  6493. }
  6494. }
  6495. function processFramesAsync(doc, frameElements, options, parentWindowId, sessionId) {
  6496. const frames = [];
  6497. let requestTimeouts;
  6498. if (sessions.get(sessionId)) {
  6499. requestTimeouts = sessions.get(sessionId).requestTimeouts;
  6500. } else {
  6501. requestTimeouts = {};
  6502. sessions.set(sessionId, { requestTimeouts });
  6503. }
  6504. frameElements.forEach((frameElement, frameIndex) => {
  6505. const windowId = parentWindowId + WINDOW_ID_SEPARATOR + frameIndex;
  6506. frameElement.setAttribute(helper$2.WIN_ID_ATTRIBUTE_NAME, windowId);
  6507. frames.push({ windowId });
  6508. });
  6509. sendInitResponse({ frames, sessionId, requestedFrameId: doc.documentElement.dataset.requestedFrameId && parentWindowId });
  6510. frameElements.forEach((frameElement, frameIndex) => {
  6511. const windowId = parentWindowId + WINDOW_ID_SEPARATOR + frameIndex;
  6512. try {
  6513. sendMessage(frameElement.contentWindow, { method: INIT_REQUEST_MESSAGE, windowId, sessionId, options, scrolling: frameElement.scrolling });
  6514. } catch (error) {
  6515. // ignored
  6516. }
  6517. requestTimeouts[windowId] = globalThis.setTimeout(() => sendInitResponse({ frames: [{ windowId, processed: true }], sessionId }), TIMEOUT_INIT_REQUEST_MESSAGE);
  6518. });
  6519. delete doc.documentElement.dataset.requestedFrameId;
  6520. }
  6521. function processFramesSync(doc, frameElements, options, parentWindowId, sessionId) {
  6522. const frames = [];
  6523. frameElements.forEach((frameElement, frameIndex) => {
  6524. const windowId = parentWindowId + WINDOW_ID_SEPARATOR + frameIndex;
  6525. let frameDoc;
  6526. try {
  6527. frameDoc = frameElement.contentDocument;
  6528. } catch (error) {
  6529. // ignored
  6530. }
  6531. if (frameDoc) {
  6532. try {
  6533. const frameWindow = frameElement.contentWindow;
  6534. frameWindow.stop();
  6535. clearFrameTimeout("requestTimeouts", sessionId, windowId);
  6536. processFrames(frameDoc, options, windowId, sessionId);
  6537. frames.push(getFrameData(frameDoc, frameWindow, windowId, options, frameElement.scrolling));
  6538. } catch (error) {
  6539. frames.push({ windowId, processed: true });
  6540. }
  6541. }
  6542. });
  6543. sendInitResponse({ frames, sessionId, requestedFrameId: doc.documentElement.dataset.requestedFrameId && parentWindowId });
  6544. delete doc.documentElement.dataset.requestedFrameId;
  6545. }
  6546. function clearFrameTimeout(type, sessionId, windowId) {
  6547. const session = sessions.get(sessionId);
  6548. if (session && session[type]) {
  6549. const timeout = session[type][windowId];
  6550. if (timeout) {
  6551. globalThis.clearTimeout(timeout);
  6552. delete session[type][windowId];
  6553. }
  6554. }
  6555. }
  6556. function createFrameResponseTimeout(sessionId, windowId) {
  6557. const session = sessions.get(sessionId);
  6558. if (session && session.responseTimeouts) {
  6559. session.responseTimeouts[windowId] = globalThis.setTimeout(() => sendInitResponse({ frames: [{ windowId: windowId, processed: true }], sessionId: sessionId }), TIMEOUT_INIT_RESPONSE_MESSAGE);
  6560. }
  6561. }
  6562. function cleanupFrames(frameElements, parentWindowId, sessionId) {
  6563. frameElements.forEach((frameElement, frameIndex) => {
  6564. const windowId = parentWindowId + WINDOW_ID_SEPARATOR + frameIndex;
  6565. frameElement.removeAttribute(helper$2.WIN_ID_ATTRIBUTE_NAME);
  6566. try {
  6567. sendMessage(frameElement.contentWindow, { method: CLEANUP_REQUEST_MESSAGE, windowId, sessionId });
  6568. } catch (error) {
  6569. // ignored
  6570. }
  6571. });
  6572. frameElements.forEach((frameElement, frameIndex) => {
  6573. const windowId = parentWindowId + WINDOW_ID_SEPARATOR + frameIndex;
  6574. let frameDoc;
  6575. try {
  6576. frameDoc = frameElement.contentDocument;
  6577. } catch (error) {
  6578. // ignored
  6579. }
  6580. if (frameDoc) {
  6581. try {
  6582. cleanupFrames(getFrames(frameDoc), windowId, sessionId);
  6583. } catch (error) {
  6584. // ignored
  6585. }
  6586. }
  6587. });
  6588. }
  6589. function sendInitResponse(message) {
  6590. message.method = INIT_RESPONSE_MESSAGE;
  6591. try {
  6592. top.singlefile.processors.frameTree.initResponse(message);
  6593. } catch (error) {
  6594. sendMessage(top, message, true);
  6595. }
  6596. }
  6597. function sendMessage(targetWindow, message, useChannel) {
  6598. if (targetWindow == top && browser && browser.runtime && browser.runtime.sendMessage) {
  6599. browser.runtime.sendMessage(message);
  6600. } else {
  6601. if (useChannel) {
  6602. const channel = new MessageChannel();
  6603. targetWindow.postMessage(MESSAGE_PREFIX + JSON$4.stringify({ method: message.method, sessionId: message.sessionId }), TARGET_ORIGIN, [channel.port2]);
  6604. channel.port1.postMessage(message);
  6605. } else {
  6606. targetWindow.postMessage(MESSAGE_PREFIX + JSON$4.stringify(message), TARGET_ORIGIN);
  6607. }
  6608. }
  6609. }
  6610. function getFrameData(document, globalThis, windowId, options, scrolling) {
  6611. const docData = helper$2.preProcessDoc(document, globalThis, options);
  6612. const content = helper$2.serialize(document);
  6613. helper$2.postProcessDoc(document, docData.markedElements, docData.invalidElements);
  6614. const baseURI = document.baseURI.split("#")[0];
  6615. return {
  6616. windowId,
  6617. content,
  6618. baseURI,
  6619. url: document.location.href,
  6620. title: document.title,
  6621. canvases: docData.canvases,
  6622. fonts: docData.fonts,
  6623. stylesheets: docData.stylesheets,
  6624. images: docData.images,
  6625. posters: docData.posters,
  6626. videos: docData.videos,
  6627. usedFonts: docData.usedFonts,
  6628. shadowRoots: docData.shadowRoots,
  6629. scrollPosition: docData.scrollPosition,
  6630. scrolling,
  6631. adoptedStyleSheets: docData.adoptedStyleSheets,
  6632. processed: true
  6633. };
  6634. }
  6635. function getFrames(document) {
  6636. let frames = Array.from(document.querySelectorAll(FRAMES_CSS_SELECTOR));
  6637. document.querySelectorAll(ALL_ELEMENTS_CSS_SELECTOR).forEach(element => {
  6638. const shadowRoot = helper$2.getShadowRoot(element);
  6639. if (shadowRoot) {
  6640. frames = frames.concat(...shadowRoot.querySelectorAll(FRAMES_CSS_SELECTOR));
  6641. }
  6642. });
  6643. return frames;
  6644. }
  6645. var contentFrameTree = /*#__PURE__*/Object.freeze({
  6646. __proto__: null,
  6647. getAsync: getAsync,
  6648. getSync: getSync,
  6649. cleanup: cleanup,
  6650. initResponse: initResponse,
  6651. TIMEOUT_INIT_REQUEST_MESSAGE: TIMEOUT_INIT_REQUEST_MESSAGE
  6652. });
  6653. /*
  6654. * Copyright 2010-2022 Gildas Lormeau
  6655. * contact : gildas.lormeau <at> gmail.com
  6656. *
  6657. * This file is part of SingleFile.
  6658. *
  6659. * The code in this file is free software: you can redistribute it and/or
  6660. * modify it under the terms of the GNU Affero General Public License
  6661. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  6662. * of the License, or (at your option) any later version.
  6663. *
  6664. * The code in this file is distributed in the hope that it will be useful,
  6665. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  6666. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  6667. * General Public License for more details.
  6668. *
  6669. * As additional permission under GNU AGPL version 3 section 7, you may
  6670. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  6671. * AGPL normally required by section 4, provided you include this license
  6672. * notice and a URL through which recipients can access the Corresponding
  6673. * Source.
  6674. */
  6675. var index$2 = /*#__PURE__*/Object.freeze({
  6676. __proto__: null,
  6677. compression: compression,
  6678. frameTree: contentFrameTree,
  6679. hooksFrames: contentHooksFrames,
  6680. lazy: contentLazyLoader
  6681. });
  6682. // dist/csstree.esm.js from https://github.com/csstree/csstree/tree/612cc5f2922b2304869497d165a0cc65257f7a8b
  6683. /*
  6684. * Copyright (C) 2016-2022 by Roman Dvornov
  6685. *
  6686. * Permission is hereby granted, free of charge, to any person obtaining a copy
  6687. * of this software and associated documentation files (the "Software"), to deal
  6688. * in the Software without restriction, including without limitation the rights
  6689. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  6690. * copies of the Software, and to permit persons to whom the Software is
  6691. * furnished to do so, subject to the following conditions:
  6692. *
  6693. * The above copyright notice and this permission notice shall be included in
  6694. * all copies or substantial portions of the Software.
  6695. *
  6696. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  6697. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  6698. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  6699. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  6700. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  6701. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  6702. * THE SOFTWARE.
  6703. */
  6704. var rs=Object.create;var tr=Object.defineProperty;var ns=Object.getOwnPropertyDescriptor;var os=Object.getOwnPropertyNames;var is=Object.getPrototypeOf,as=Object.prototype.hasOwnProperty;var Oe=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),b=(e,t)=>{for(var r in t)tr(e,r,{get:t[r],enumerable:!0});},ss=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of os(t))!as.call(e,o)&&o!==r&&tr(e,o,{get:()=>t[o],enumerable:!(n=ns(t,o))||n.enumerable});return e};var ls=(e,t,r)=>(r=e!=null?rs(is(e)):{},ss(t||!e||!e.__esModule?tr(r,"default",{value:e,enumerable:!0}):r,e));var Jo=Oe(ur=>{var Zo="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");ur.encode=function(e){if(0<=e&&e<Zo.length)return Zo[e];throw new TypeError("Must be between 0 and 63: "+e)};ur.decode=function(e){var t=65,r=90,n=97,o=122,i=48,s=57,u=43,c=47,a=26,l=52;return t<=e&&e<=r?e-t:n<=e&&e<=o?e-n+a:i<=e&&e<=s?e-i+l:e==u?62:e==c?63:-1};});var oi=Oe(hr=>{var ei=Jo(),pr=5,ti=1<<pr,ri=ti-1,ni=ti;function ks(e){return e<0?(-e<<1)+1:(e<<1)+0}function ws(e){var t=(e&1)===1,r=e>>1;return t?-r:r}hr.encode=function(t){var r="",n,o=ks(t);do n=o&ri,o>>>=pr,o>0&&(n|=ni),r+=ei.encode(n);while(o>0);return r};hr.decode=function(t,r,n){var o=t.length,i=0,s=0,u,c;do{if(r>=o)throw new Error("Expected more digits in base 64 VLQ value.");if(c=ei.decode(t.charCodeAt(r++)),c===-1)throw new Error("Invalid base64 digit: "+t.charAt(r-1));u=!!(c&ni),c&=ri,i=i+(c<<s),s+=pr;}while(u);n.value=ws(i),n.rest=r;};});var Et=Oe(K=>{function vs(e,t,r){if(t in e)return e[t];if(arguments.length===3)return r;throw new Error('"'+t+'" is a required argument.')}K.getArg=vs;var ii=/^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/,Ss=/^data:.+\,.+$/;function nt(e){var t=e.match(ii);return t?{scheme:t[1],auth:t[2],host:t[3],port:t[4],path:t[5]}:null}K.urlParse=nt;function Ue(e){var t="";return e.scheme&&(t+=e.scheme+":"),t+="//",e.auth&&(t+=e.auth+"@"),e.host&&(t+=e.host),e.port&&(t+=":"+e.port),e.path&&(t+=e.path),t}K.urlGenerate=Ue;var Cs=32;function As(e){var t=[];return function(r){for(var n=0;n<t.length;n++)if(t[n].input===r){var o=t[0];return t[0]=t[n],t[n]=o,t[0].result}var i=e(r);return t.unshift({input:r,result:i}),t.length>Cs&&t.pop(),i}}var mr=As(function(t){var r=t,n=nt(t);if(n){if(!n.path)return t;r=n.path;}for(var o=K.isAbsolute(r),i=[],s=0,u=0;;)if(s=u,u=r.indexOf("/",s),u===-1){i.push(r.slice(s));break}else for(i.push(r.slice(s,u));u<r.length&&r[u]==="/";)u++;for(var c,a=0,u=i.length-1;u>=0;u--)c=i[u],c==="."?i.splice(u,1):c===".."?a++:a>0&&(c===""?(i.splice(u+1,a),a=0):(i.splice(u,2),a--));return r=i.join("/"),r===""&&(r=o?"/":"."),n?(n.path=r,Ue(n)):r});K.normalize=mr;function ai(e,t){e===""&&(e="."),t===""&&(t=".");var r=nt(t),n=nt(e);if(n&&(e=n.path||"/"),r&&!r.scheme)return n&&(r.scheme=n.scheme),Ue(r);if(r||t.match(Ss))return t;if(n&&!n.host&&!n.path)return n.host=t,Ue(n);var o=t.charAt(0)==="/"?t:mr(e.replace(/\/+$/,"")+"/"+t);return n?(n.path=o,Ue(n)):o}K.join=ai;K.isAbsolute=function(e){return e.charAt(0)==="/"||ii.test(e)};function Ts(e,t){e===""&&(e="."),e=e.replace(/\/$/,"");for(var r=0;t.indexOf(e+"/")!==0;){var n=e.lastIndexOf("/");if(n<0||(e=e.slice(0,n),e.match(/^([^\/]+:\/)?\/*$/)))return t;++r;}return Array(r+1).join("../")+t.substr(e.length+1)}K.relative=Ts;var si=function(){var e=Object.create(null);return !("__proto__"in e)}();function li(e){return e}function Es(e){return ci(e)?"$"+e:e}K.toSetString=si?li:Es;function Ls(e){return ci(e)?e.slice(1):e}K.fromSetString=si?li:Ls;function ci(e){if(!e)return !1;var t=e.length;if(t<9||e.charCodeAt(t-1)!==95||e.charCodeAt(t-2)!==95||e.charCodeAt(t-3)!==111||e.charCodeAt(t-4)!==116||e.charCodeAt(t-5)!==111||e.charCodeAt(t-6)!==114||e.charCodeAt(t-7)!==112||e.charCodeAt(t-8)!==95||e.charCodeAt(t-9)!==95)return !1;for(var r=t-10;r>=0;r--)if(e.charCodeAt(r)!==36)return !1;return !0}function Ps(e,t,r){var n=be(e.source,t.source);return n!==0||(n=e.originalLine-t.originalLine,n!==0)||(n=e.originalColumn-t.originalColumn,n!==0||r)||(n=e.generatedColumn-t.generatedColumn,n!==0)||(n=e.generatedLine-t.generatedLine,n!==0)?n:be(e.name,t.name)}K.compareByOriginalPositions=Ps;function Is(e,t,r){var n;return n=e.originalLine-t.originalLine,n!==0||(n=e.originalColumn-t.originalColumn,n!==0||r)||(n=e.generatedColumn-t.generatedColumn,n!==0)||(n=e.generatedLine-t.generatedLine,n!==0)?n:be(e.name,t.name)}K.compareByOriginalPositionsNoSource=Is;function Ds(e,t,r){var n=e.generatedLine-t.generatedLine;return n!==0||(n=e.generatedColumn-t.generatedColumn,n!==0||r)||(n=be(e.source,t.source),n!==0)||(n=e.originalLine-t.originalLine,n!==0)||(n=e.originalColumn-t.originalColumn,n!==0)?n:be(e.name,t.name)}K.compareByGeneratedPositionsDeflated=Ds;function Os(e,t,r){var n=e.generatedColumn-t.generatedColumn;return n!==0||r||(n=be(e.source,t.source),n!==0)||(n=e.originalLine-t.originalLine,n!==0)||(n=e.originalColumn-t.originalColumn,n!==0)?n:be(e.name,t.name)}K.compareByGeneratedPositionsDeflatedNoLine=Os;function be(e,t){return e===t?0:e===null?1:t===null?-1:e>t?1:-1}function Ns(e,t){var r=e.generatedLine-t.generatedLine;return r!==0||(r=e.generatedColumn-t.generatedColumn,r!==0)||(r=be(e.source,t.source),r!==0)||(r=e.originalLine-t.originalLine,r!==0)||(r=e.originalColumn-t.originalColumn,r!==0)?r:be(e.name,t.name)}K.compareByGeneratedPositionsInflated=Ns;function zs(e){return JSON.parse(e.replace(/^\)]}'[^\n]*\n/,""))}K.parseSourceMapInput=zs;function Ms(e,t,r){if(t=t||"",e&&(e[e.length-1]!=="/"&&t[0]!=="/"&&(e+="/"),t=e+t),r){var n=nt(r);if(!n)throw new Error("sourceMapURL could not be parsed");if(n.path){var o=n.path.lastIndexOf("/");o>=0&&(n.path=n.path.substring(0,o+1));}t=ai(Ue(n),t);}return mr(t)}K.computeSourceURL=Ms;});var pi=Oe(ui=>{var fr=Et(),dr=Object.prototype.hasOwnProperty,Le=typeof Map<"u";function xe(){this._array=[],this._set=Le?new Map:Object.create(null);}xe.fromArray=function(t,r){for(var n=new xe,o=0,i=t.length;o<i;o++)n.add(t[o],r);return n};xe.prototype.size=function(){return Le?this._set.size:Object.getOwnPropertyNames(this._set).length};xe.prototype.add=function(t,r){var n=Le?t:fr.toSetString(t),o=Le?this.has(t):dr.call(this._set,n),i=this._array.length;(!o||r)&&this._array.push(t),o||(Le?this._set.set(t,i):this._set[n]=i);};xe.prototype.has=function(t){if(Le)return this._set.has(t);var r=fr.toSetString(t);return dr.call(this._set,r)};xe.prototype.indexOf=function(t){if(Le){var r=this._set.get(t);if(r>=0)return r}else {var n=fr.toSetString(t);if(dr.call(this._set,n))return this._set[n]}throw new Error('"'+t+'" is not in the set.')};xe.prototype.at=function(t){if(t>=0&&t<this._array.length)return this._array[t];throw new Error("No element indexed by "+t)};xe.prototype.toArray=function(){return this._array.slice()};ui.ArraySet=xe;});var fi=Oe(mi=>{var hi=Et();function Rs(e,t){var r=e.generatedLine,n=t.generatedLine,o=e.generatedColumn,i=t.generatedColumn;return n>r||n==r&&i>=o||hi.compareByGeneratedPositionsInflated(e,t)<=0}function Lt(){this._array=[],this._sorted=!0,this._last={generatedLine:-1,generatedColumn:0};}Lt.prototype.unsortedForEach=function(t,r){this._array.forEach(t,r);};Lt.prototype.add=function(t){Rs(this._last,t)?(this._last=t,this._array.push(t)):(this._sorted=!1,this._array.push(t));};Lt.prototype.toArray=function(){return this._sorted||(this._array.sort(hi.compareByGeneratedPositionsInflated),this._sorted=!0),this._array};mi.MappingList=Lt;});var gi=Oe(di=>{var ot=oi(),q=Et(),Pt=pi().ArraySet,Fs=fi().MappingList;function oe(e){e||(e={}),this._file=q.getArg(e,"file",null),this._sourceRoot=q.getArg(e,"sourceRoot",null),this._skipValidation=q.getArg(e,"skipValidation",!1),this._sources=new Pt,this._names=new Pt,this._mappings=new Fs,this._sourcesContents=null;}oe.prototype._version=3;oe.fromSourceMap=function(t){var r=t.sourceRoot,n=new oe({file:t.file,sourceRoot:r});return t.eachMapping(function(o){var i={generated:{line:o.generatedLine,column:o.generatedColumn}};o.source!=null&&(i.source=o.source,r!=null&&(i.source=q.relative(r,i.source)),i.original={line:o.originalLine,column:o.originalColumn},o.name!=null&&(i.name=o.name)),n.addMapping(i);}),t.sources.forEach(function(o){var i=o;r!==null&&(i=q.relative(r,o)),n._sources.has(i)||n._sources.add(i);var s=t.sourceContentFor(o);s!=null&&n.setSourceContent(o,s);}),n};oe.prototype.addMapping=function(t){var r=q.getArg(t,"generated"),n=q.getArg(t,"original",null),o=q.getArg(t,"source",null),i=q.getArg(t,"name",null);this._skipValidation||this._validateMapping(r,n,o,i),o!=null&&(o=String(o),this._sources.has(o)||this._sources.add(o)),i!=null&&(i=String(i),this._names.has(i)||this._names.add(i)),this._mappings.add({generatedLine:r.line,generatedColumn:r.column,originalLine:n!=null&&n.line,originalColumn:n!=null&&n.column,source:o,name:i});};oe.prototype.setSourceContent=function(t,r){var n=t;this._sourceRoot!=null&&(n=q.relative(this._sourceRoot,n)),r!=null?(this._sourcesContents||(this._sourcesContents=Object.create(null)),this._sourcesContents[q.toSetString(n)]=r):this._sourcesContents&&(delete this._sourcesContents[q.toSetString(n)],Object.keys(this._sourcesContents).length===0&&(this._sourcesContents=null));};oe.prototype.applySourceMap=function(t,r,n){var o=r;if(r==null){if(t.file==null)throw new Error(`SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, or the source map's "file" property. Both were omitted.`);o=t.file;}var i=this._sourceRoot;i!=null&&(o=q.relative(i,o));var s=new Pt,u=new Pt;this._mappings.unsortedForEach(function(c){if(c.source===o&&c.originalLine!=null){var a=t.originalPositionFor({line:c.originalLine,column:c.originalColumn});a.source!=null&&(c.source=a.source,n!=null&&(c.source=q.join(n,c.source)),i!=null&&(c.source=q.relative(i,c.source)),c.originalLine=a.line,c.originalColumn=a.column,a.name!=null&&(c.name=a.name));}var l=c.source;l!=null&&!s.has(l)&&s.add(l);var p=c.name;p!=null&&!u.has(p)&&u.add(p);},this),this._sources=s,this._names=u,t.sources.forEach(function(c){var a=t.sourceContentFor(c);a!=null&&(n!=null&&(c=q.join(n,c)),i!=null&&(c=q.relative(i,c)),this.setSourceContent(c,a));},this);};oe.prototype._validateMapping=function(t,r,n,o){if(r&&typeof r.line!="number"&&typeof r.column!="number")throw new Error("original.line and original.column are not numbers -- you probably meant to omit the original mapping entirely and only map the generated position. If so, pass null for the original mapping instead of an object with empty or null values.");if(!(t&&"line"in t&&"column"in t&&t.line>0&&t.column>=0&&!r&&!n&&!o)){if(t&&"line"in t&&"column"in t&&r&&"line"in r&&"column"in r&&t.line>0&&t.column>=0&&r.line>0&&r.column>=0&&n)return;throw new Error("Invalid mapping: "+JSON.stringify({generated:t,source:n,original:r,name:o}))}};oe.prototype._serializeMappings=function(){for(var t=0,r=1,n=0,o=0,i=0,s=0,u="",c,a,l,p,m=this._mappings.toArray(),f=0,P=m.length;f<P;f++){if(a=m[f],c="",a.generatedLine!==r)for(t=0;a.generatedLine!==r;)c+=";",r++;else if(f>0){if(!q.compareByGeneratedPositionsInflated(a,m[f-1]))continue;c+=",";}c+=ot.encode(a.generatedColumn-t),t=a.generatedColumn,a.source!=null&&(p=this._sources.indexOf(a.source),c+=ot.encode(p-s),s=p,c+=ot.encode(a.originalLine-1-o),o=a.originalLine-1,c+=ot.encode(a.originalColumn-n),n=a.originalColumn,a.name!=null&&(l=this._names.indexOf(a.name),c+=ot.encode(l-i),i=l)),u+=c;}return u};oe.prototype._generateSourcesContent=function(t,r){return t.map(function(n){if(!this._sourcesContents)return null;r!=null&&(n=q.relative(r,n));var o=q.toSetString(n);return Object.prototype.hasOwnProperty.call(this._sourcesContents,o)?this._sourcesContents[o]:null},this)};oe.prototype.toJSON=function(){var t={version:this._version,sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};return this._file!=null&&(t.file=this._file),this._sourceRoot!=null&&(t.sourceRoot=this._sourceRoot),this._sourcesContents&&(t.sourcesContent=this._generateSourcesContent(t.sources,t.sourceRoot)),t};oe.prototype.toString=function(){return JSON.stringify(this.toJSON())};di.SourceMapGenerator=oe;});var $e={};b($e,{AtKeyword:()=>I,BadString:()=>Ae,BadUrl:()=>Y,CDC:()=>j,CDO:()=>ue,Colon:()=>O,Comma:()=>G,Comment:()=>E,Delim:()=>g,Dimension:()=>y,EOF:()=>Xe,Function:()=>x,Hash:()=>v,Ident:()=>h,LeftCurlyBracket:()=>M,LeftParenthesis:()=>T,LeftSquareBracket:()=>U,Number:()=>d,Percentage:()=>A,RightCurlyBracket:()=>H,RightParenthesis:()=>w,RightSquareBracket:()=>V,Semicolon:()=>_,String:()=>W,Url:()=>F,WhiteSpace:()=>k});var Xe=0,h=1,x=2,I=3,v=4,W=5,Ae=6,F=7,Y=8,g=9,d=10,A=11,y=12,k=13,ue=14,j=15,O=16,_=17,G=18,U=19,V=20,T=21,w=22,M=23,H=24,E=25;function B(e){return e>=48&&e<=57}function ee(e){return B(e)||e>=65&&e<=70||e>=97&&e<=102}function yt(e){return e>=65&&e<=90}function cs(e){return e>=97&&e<=122}function us(e){return yt(e)||cs(e)}function ps(e){return e>=128}function xt(e){return us(e)||ps(e)||e===95}function Ne(e){return xt(e)||B(e)||e===45}function hs(e){return e>=0&&e<=8||e===11||e>=14&&e<=31||e===127}function Ze(e){return e===10||e===13||e===12}function pe(e){return Ze(e)||e===32||e===9}function $(e,t){return !(e!==92||Ze(t)||t===0)}function ze(e,t,r){return e===45?xt(t)||t===45||$(t,r):xt(e)?!0:e===92?$(e,t):!1}function kt(e,t,r){return e===43||e===45?B(t)?2:t===46&&B(r)?3:0:e===46?B(t)?2:0:B(e)?1:0}function wt(e){return e===65279||e===65534?1:0}var rr=new Array(128),ms=128,Je=130,nr=131,vt=132,or=133;for(let e=0;e<rr.length;e++)rr[e]=pe(e)&&Je||B(e)&&nr||xt(e)&&vt||hs(e)&&or||e||ms;function St(e){return e<128?rr[e]:vt}function Me(e,t){return t<e.length?e.charCodeAt(t):0}function Ct(e,t,r){return r===13&&Me(e,t+1)===10?2:1}function de(e,t,r){let n=e.charCodeAt(t);return yt(n)&&(n=n|32),n===r}function ge(e,t,r,n){if(r-t!==n.length||t<0||r>e.length)return !1;for(let o=t;o<r;o++){let i=n.charCodeAt(o-t),s=e.charCodeAt(o);if(yt(s)&&(s=s|32),s!==i)return !1}return !0}function Uo(e,t){for(;t>=0&&pe(e.charCodeAt(t));t--);return t+1}function et(e,t){for(;t<e.length&&pe(e.charCodeAt(t));t++);return t}function ir(e,t){for(;t<e.length&&B(e.charCodeAt(t));t++);return t}function se(e,t){if(t+=2,ee(Me(e,t-1))){for(let n=Math.min(e.length,t+5);t<n&&ee(Me(e,t));t++);let r=Me(e,t);pe(r)&&(t+=Ct(e,t,r));}return t}function tt(e,t){for(;t<e.length;t++){let r=e.charCodeAt(t);if(!Ne(r)){if($(r,Me(e,t+1))){t=se(e,t)-1;continue}break}}return t}function Te(e,t){let r=e.charCodeAt(t);if((r===43||r===45)&&(r=e.charCodeAt(t+=1)),B(r)&&(t=ir(e,t+1),r=e.charCodeAt(t)),r===46&&B(e.charCodeAt(t+1))&&(t+=2,t=ir(e,t)),de(e,t,101)){let n=0;r=e.charCodeAt(t+1),(r===45||r===43)&&(n=1,r=e.charCodeAt(t+2)),B(r)&&(t=ir(e,t+1+n+1));}return t}function At(e,t){for(;t<e.length;t++){let r=e.charCodeAt(t);if(r===41){t++;break}$(r,Me(e,t+1))&&(t=se(e,t));}return t}function Re(e){if(e.length===1&&!ee(e.charCodeAt(0)))return e[0];let t=parseInt(e,16);return (t===0||t>=55296&&t<=57343||t>1114111)&&(t=65533),String.fromCodePoint(t)}var Fe=["EOF-token","ident-token","function-token","at-keyword-token","hash-token","string-token","bad-string-token","url-token","bad-url-token","delim-token","number-token","percentage-token","dimension-token","whitespace-token","CDO-token","CDC-token","colon-token","semicolon-token","comma-token","[-token","]-token","(-token",")-token","{-token","}-token","comment-token"];function Be(e=null,t){return e===null||e.length<t?new Uint32Array(Math.max(t+1024,16384)):e}var jo=10,fs=12,qo=13;function Wo(e){let t=e.source,r=t.length,n=t.length>0?wt(t.charCodeAt(0)):0,o=Be(e.lines,r),i=Be(e.columns,r),s=e.startLine,u=e.startColumn;for(let c=n;c<r;c++){let a=t.charCodeAt(c);o[c]=s,i[c]=u++,(a===jo||a===qo||a===fs)&&(a===qo&&c+1<r&&t.charCodeAt(c+1)===jo&&(c++,o[c]=s,i[c]=u),s++,u=1);}o[r]=s,i[r]=u,e.lines=o,e.columns=i,e.computed=!0;}var Tt=class{constructor(){this.lines=null,this.columns=null,this.computed=!1;}setSource(t,r=0,n=1,o=1){this.source=t,this.startOffset=r,this.startLine=n,this.startColumn=o,this.computed=!1;}getLocation(t,r){return this.computed||Wo(this),{source:r,offset:this.startOffset+t,line:this.lines[t],column:this.columns[t]}}getLocationRange(t,r,n){return this.computed||Wo(this),{source:n,start:{offset:this.startOffset+t,line:this.lines[t],column:this.columns[t]},end:{offset:this.startOffset+r,line:this.lines[r],column:this.columns[r]}}}};var ne=16777215,we=24,ds=new Map([[2,22],[21,22],[19,20],[23,24]]),rt=class{constructor(t,r){this.setSource(t,r);}reset(){this.eof=!1,this.tokenIndex=-1,this.tokenType=0,this.tokenStart=this.firstCharOffset,this.tokenEnd=this.firstCharOffset;}setSource(t="",r=()=>{}){t=String(t||"");let n=t.length,o=Be(this.offsetAndType,t.length+1),i=Be(this.balance,t.length+1),s=0,u=0,c=0,a=-1;for(this.offsetAndType=null,this.balance=null,r(t,(l,p,m)=>{switch(l){default:i[s]=n;break;case u:{let f=c&ne;for(c=i[f],u=c>>we,i[s]=f,i[f++]=s;f<s;f++)i[f]===n&&(i[f]=s);break}case 21:case 2:case 19:case 23:i[s]=c,u=ds.get(l),c=u<<we|s;break}o[s++]=l<<we|m,a===-1&&(a=p);}),o[s]=0<<we|n,i[s]=n,i[n]=n;c!==0;){let l=c&ne;c=i[l],i[l]=n;}this.source=t,this.firstCharOffset=a===-1?0:a,this.tokenCount=s,this.offsetAndType=o,this.balance=i,this.reset(),this.next();}lookupType(t){return t+=this.tokenIndex,t<this.tokenCount?this.offsetAndType[t]>>we:0}lookupOffset(t){return t+=this.tokenIndex,t<this.tokenCount?this.offsetAndType[t-1]&ne:this.source.length}lookupValue(t,r){return t+=this.tokenIndex,t<this.tokenCount?ge(this.source,this.offsetAndType[t-1]&ne,this.offsetAndType[t]&ne,r):!1}getTokenStart(t){return t===this.tokenIndex?this.tokenStart:t>0?t<this.tokenCount?this.offsetAndType[t-1]&ne:this.offsetAndType[this.tokenCount]&ne:this.firstCharOffset}substrToCursor(t){return this.source.substring(t,this.tokenStart)}isBalanceEdge(t){return this.balance[this.tokenIndex]<t}isDelim(t,r){return r?this.lookupType(r)===9&&this.source.charCodeAt(this.lookupOffset(r))===t:this.tokenType===9&&this.source.charCodeAt(this.tokenStart)===t}skip(t){let r=this.tokenIndex+t;r<this.tokenCount?(this.tokenIndex=r,this.tokenStart=this.offsetAndType[r-1]&ne,r=this.offsetAndType[r],this.tokenType=r>>we,this.tokenEnd=r&ne):(this.tokenIndex=this.tokenCount,this.next());}next(){let t=this.tokenIndex+1;t<this.tokenCount?(this.tokenIndex=t,this.tokenStart=this.tokenEnd,t=this.offsetAndType[t],this.tokenType=t>>we,this.tokenEnd=t&ne):(this.eof=!0,this.tokenIndex=this.tokenCount,this.tokenType=0,this.tokenStart=this.tokenEnd=this.source.length);}skipSC(){for(;this.tokenType===13||this.tokenType===25;)this.next();}skipUntilBalanced(t,r){let n=t,o,i;e:for(;n<this.tokenCount;n++){if(o=this.balance[n],o<t)break e;switch(i=n>0?this.offsetAndType[n-1]&ne:this.firstCharOffset,r(this.source.charCodeAt(i))){case 1:break e;case 2:n++;break e;default:this.balance[o]===n&&(n=o);}}this.skip(n-this.tokenIndex);}forEachToken(t){for(let r=0,n=this.firstCharOffset;r<this.tokenCount;r++){let o=n,i=this.offsetAndType[r],s=i&ne,u=i>>we;n=s,t(u,o,s,r);}}dump(){let t=new Array(this.tokenCount);return this.forEachToken((r,n,o,i)=>{t[i]={idx:i,type:Fe[r],chunk:this.source.substring(n,o),balance:this.balance[i]};}),t}};function ve(e,t){function r(p){return p<u?e.charCodeAt(p):0}function n(){if(a=Te(e,a),ze(r(a),r(a+1),r(a+2))){l=12,a=tt(e,a);return}if(r(a)===37){l=11,a++;return}l=10;}function o(){let p=a;if(a=tt(e,a),ge(e,p,a,"url")&&r(a)===40){if(a=et(e,a+1),r(a)===34||r(a)===39){l=2,a=p+4;return}s();return}if(r(a)===40){l=2,a++;return}l=1;}function i(p){for(p||(p=r(a++)),l=5;a<e.length;a++){let m=e.charCodeAt(a);switch(St(m)){case p:a++;return;case Je:if(Ze(m)){a+=Ct(e,a,m),l=6;return}break;case 92:if(a===e.length-1)break;let f=r(a+1);Ze(f)?a+=Ct(e,a+1,f):$(m,f)&&(a=se(e,a)-1);break}}}function s(){for(l=7,a=et(e,a);a<e.length;a++){let p=e.charCodeAt(a);switch(St(p)){case 41:a++;return;case Je:if(a=et(e,a),r(a)===41||a>=e.length){a<e.length&&a++;return}a=At(e,a),l=8;return;case 34:case 39:case 40:case or:a=At(e,a),l=8;return;case 92:if($(p,r(a+1))){a=se(e,a)-1;break}a=At(e,a),l=8;return}}}e=String(e||"");let u=e.length,c=wt(r(0)),a=c,l;for(;a<u;){let p=e.charCodeAt(a);switch(St(p)){case Je:l=13,a=et(e,a+1);break;case 34:i();break;case 35:Ne(r(a+1))||$(r(a+1),r(a+2))?(l=4,a=tt(e,a+1)):(l=9,a++);break;case 39:i();break;case 40:l=21,a++;break;case 41:l=22,a++;break;case 43:kt(p,r(a+1),r(a+2))?n():(l=9,a++);break;case 44:l=18,a++;break;case 45:kt(p,r(a+1),r(a+2))?n():r(a+1)===45&&r(a+2)===62?(l=15,a=a+3):ze(p,r(a+1),r(a+2))?o():(l=9,a++);break;case 46:kt(p,r(a+1),r(a+2))?n():(l=9,a++);break;case 47:r(a+1)===42?(l=25,a=e.indexOf("*/",a+2),a=a===-1?e.length:a+2):(l=9,a++);break;case 58:l=16,a++;break;case 59:l=17,a++;break;case 60:r(a+1)===33&&r(a+2)===45&&r(a+3)===45?(l=14,a=a+4):(l=9,a++);break;case 64:ze(r(a+1),r(a+2),r(a+3))?(l=3,a=tt(e,a+1)):(l=9,a++);break;case 91:l=19,a++;break;case 92:$(p,r(a+1))?o():(l=9,a++);break;case 93:l=20,a++;break;case 123:l=23,a++;break;case 125:l=24,a++;break;case nr:n();break;case vt:o();break;default:l=9,a++;}t(l,c,c=a);}}var _e=null,D=class{static createItem(t){return {prev:null,next:null,data:t}}constructor(){this.head=null,this.tail=null,this.cursor=null;}createItem(t){return D.createItem(t)}allocateCursor(t,r){let n;return _e!==null?(n=_e,_e=_e.cursor,n.prev=t,n.next=r,n.cursor=this.cursor):n={prev:t,next:r,cursor:this.cursor},this.cursor=n,n}releaseCursor(){let{cursor:t}=this;this.cursor=t.cursor,t.prev=null,t.next=null,t.cursor=_e,_e=t;}updateCursors(t,r,n,o){let{cursor:i}=this;for(;i!==null;)i.prev===t&&(i.prev=r),i.next===n&&(i.next=o),i=i.cursor;}*[Symbol.iterator](){for(let t=this.head;t!==null;t=t.next)yield t.data;}get size(){let t=0;for(let r=this.head;r!==null;r=r.next)t++;return t}get isEmpty(){return this.head===null}get first(){return this.head&&this.head.data}get last(){return this.tail&&this.tail.data}fromArray(t){let r=null;this.head=null;for(let n of t){let o=D.createItem(n);r!==null?r.next=o:this.head=o,o.prev=r,r=o;}return this.tail=r,this}toArray(){return [...this]}toJSON(){return [...this]}forEach(t,r=this){let n=this.allocateCursor(null,this.head);for(;n.next!==null;){let o=n.next;n.next=o.next,t.call(r,o.data,o,this);}this.releaseCursor();}forEachRight(t,r=this){let n=this.allocateCursor(this.tail,null);for(;n.prev!==null;){let o=n.prev;n.prev=o.prev,t.call(r,o.data,o,this);}this.releaseCursor();}reduce(t,r,n=this){let o=this.allocateCursor(null,this.head),i=r,s;for(;o.next!==null;)s=o.next,o.next=s.next,i=t.call(n,i,s.data,s,this);return this.releaseCursor(),i}reduceRight(t,r,n=this){let o=this.allocateCursor(this.tail,null),i=r,s;for(;o.prev!==null;)s=o.prev,o.prev=s.prev,i=t.call(n,i,s.data,s,this);return this.releaseCursor(),i}some(t,r=this){for(let n=this.head;n!==null;n=n.next)if(t.call(r,n.data,n,this))return !0;return !1}map(t,r=this){let n=new D;for(let o=this.head;o!==null;o=o.next)n.appendData(t.call(r,o.data,o,this));return n}filter(t,r=this){let n=new D;for(let o=this.head;o!==null;o=o.next)t.call(r,o.data,o,this)&&n.appendData(o.data);return n}nextUntil(t,r,n=this){if(t===null)return;let o=this.allocateCursor(null,t);for(;o.next!==null;){let i=o.next;if(o.next=i.next,r.call(n,i.data,i,this))break}this.releaseCursor();}prevUntil(t,r,n=this){if(t===null)return;let o=this.allocateCursor(t,null);for(;o.prev!==null;){let i=o.prev;if(o.prev=i.prev,r.call(n,i.data,i,this))break}this.releaseCursor();}clear(){this.head=null,this.tail=null;}copy(){let t=new D;for(let r of this)t.appendData(r);return t}prepend(t){return this.updateCursors(null,t,this.head,t),this.head!==null?(this.head.prev=t,t.next=this.head):this.tail=t,this.head=t,this}prependData(t){return this.prepend(D.createItem(t))}append(t){return this.insert(t)}appendData(t){return this.insert(D.createItem(t))}insert(t,r=null){if(r!==null)if(this.updateCursors(r.prev,t,r,t),r.prev===null){if(this.head!==r)throw new Error("before doesn't belong to list");this.head=t,r.prev=t,t.next=r,this.updateCursors(null,t);}else r.prev.next=t,t.prev=r.prev,r.prev=t,t.next=r;else this.updateCursors(this.tail,t,null,t),this.tail!==null?(this.tail.next=t,t.prev=this.tail):this.head=t,this.tail=t;return this}insertData(t,r){return this.insert(D.createItem(t),r)}remove(t){if(this.updateCursors(t,t.prev,t,t.next),t.prev!==null)t.prev.next=t.next;else {if(this.head!==t)throw new Error("item doesn't belong to list");this.head=t.next;}if(t.next!==null)t.next.prev=t.prev;else {if(this.tail!==t)throw new Error("item doesn't belong to list");this.tail=t.prev;}return t.prev=null,t.next=null,t}push(t){this.insert(D.createItem(t));}pop(){return this.tail!==null?this.remove(this.tail):null}unshift(t){this.prepend(D.createItem(t));}shift(){return this.head!==null?this.remove(this.head):null}prependList(t){return this.insertList(t,this.head)}appendList(t){return this.insertList(t)}insertList(t,r){return t.head===null?this:(r!=null?(this.updateCursors(r.prev,t.tail,r,t.head),r.prev!==null?(r.prev.next=t.head,t.head.prev=r.prev):this.head=t.head,r.prev=t.tail,t.tail.next=r):(this.updateCursors(this.tail,t.tail,null,t.head),this.tail!==null?(this.tail.next=t.head,t.head.prev=this.tail):this.head=t.head,this.tail=t.tail),t.head=null,t.tail=null,this)}replace(t,r){"head"in r?this.insertList(r,t):this.insert(r,t),this.remove(t);}};function Ee(e,t){let r=Object.create(SyntaxError.prototype),n=new Error;return Object.assign(r,{name:e,message:t,get stack(){return (n.stack||"").replace(/^(.+\n){1,3}/,`${e}: ${t}
  6705. `)}})}var ar=100,Ho=60,Yo=" ";function Go({source:e,line:t,column:r},n){function o(l,p){return i.slice(l,p).map((m,f)=>String(l+f+1).padStart(c)+" |"+m).join(`
  6706. `)}let i=e.split(/\r\n?|\n|\f/),s=Math.max(1,t-n)-1,u=Math.min(t+n,i.length+1),c=Math.max(4,String(u).length)+1,a=0;r+=(Yo.length-1)*(i[t-1].substr(0,r-1).match(/\t/g)||[]).length,r>ar&&(a=r-Ho+3,r=Ho-2);for(let l=s;l<=u;l++)l>=0&&l<i.length&&(i[l]=i[l].replace(/\t/g,Yo),i[l]=(a>0&&i[l].length>a?"\u2026":"")+i[l].substr(a,ar-2)+(i[l].length>a+ar-1?"\u2026":""));return [o(s,t),new Array(r+c+2).join("-")+"^",o(t,u)].filter(Boolean).join(`
  6707. `)}function sr(e,t,r,n,o){return Object.assign(Ee("SyntaxError",e),{source:t,offset:r,line:n,column:o,sourceFragment(s){return Go({source:t,line:n,column:o},isNaN(s)?0:s)},get formattedMessage(){return `Parse error: ${e}
  6708. `+Go({source:t,line:n,column:o},2)}})}function Vo(e){let t=this.createList(),r=!1,n={recognizer:e};for(;!this.eof;){switch(this.tokenType){case 25:this.next();continue;case 13:r=!0,this.next();continue}let o=e.getNode.call(this,n);if(o===void 0)break;r&&(e.onWhiteSpace&&e.onWhiteSpace.call(this,o,t,n),r=!1),t.push(o);}return r&&e.onWhiteSpace&&e.onWhiteSpace.call(this,null,t,n),t}var Ko=()=>{},gs=33,bs=35,lr=59,Qo=123,Xo=0;function xs(e){return function(){return this[e]()}}function cr(e){let t=Object.create(null);for(let r in e){let n=e[r],o=n.parse||n;o&&(t[r]=o);}return t}function ys(e){let t={context:Object.create(null),scope:Object.assign(Object.create(null),e.scope),atrule:cr(e.atrule),pseudo:cr(e.pseudo),node:cr(e.node)};for(let r in e.parseContext)switch(typeof e.parseContext[r]){case"function":t.context[r]=e.parseContext[r];break;case"string":t.context[r]=xs(e.parseContext[r]);break}return {config:t,...t,...t.node}}function $o(e){let t="",r="<unknown>",n=!1,o=Ko,i=!1,s=new Tt,u=Object.assign(new rt,ys(e||{}),{parseAtrulePrelude:!0,parseRulePrelude:!0,parseValue:!0,parseCustomProperty:!1,readSequence:Vo,consumeUntilBalanceEnd:()=>0,consumeUntilLeftCurlyBracket(a){return a===Qo?1:0},consumeUntilLeftCurlyBracketOrSemicolon(a){return a===Qo||a===lr?1:0},consumeUntilExclamationMarkOrSemicolon(a){return a===gs||a===lr?1:0},consumeUntilSemicolonIncluded(a){return a===lr?2:0},createList(){return new D},createSingleNodeList(a){return new D().appendData(a)},getFirstListNode(a){return a&&a.first},getLastListNode(a){return a&&a.last},parseWithFallback(a,l){let p=this.tokenIndex;try{return a.call(this)}catch(m){if(i)throw m;let f=l.call(this,p);return i=!0,o(m,f),i=!1,f}},lookupNonWSType(a){let l;do if(l=this.lookupType(a++),l!==13)return l;while(l!==Xo);return Xo},charCodeAt(a){return a>=0&&a<t.length?t.charCodeAt(a):0},substring(a,l){return t.substring(a,l)},substrToCursor(a){return this.source.substring(a,this.tokenStart)},cmpChar(a,l){return de(t,a,l)},cmpStr(a,l,p){return ge(t,a,l,p)},consume(a){let l=this.tokenStart;return this.eat(a),this.substrToCursor(l)},consumeFunctionName(){let a=t.substring(this.tokenStart,this.tokenEnd-1);return this.eat(2),a},consumeNumber(a){let l=t.substring(this.tokenStart,Te(t,this.tokenStart));return this.eat(a),l},eat(a){if(this.tokenType!==a){let l=Fe[a].slice(0,-6).replace(/-/g," ").replace(/^./,f=>f.toUpperCase()),p=`${/[[\](){}]/.test(l)?`"${l}"`:l} is expected`,m=this.tokenStart;switch(a){case 1:this.tokenType===2||this.tokenType===7?(m=this.tokenEnd-1,p="Identifier is expected but function found"):p="Identifier is expected";break;case 4:this.isDelim(bs)&&(this.next(),m++,p="Name is expected");break;case 11:this.tokenType===10&&(m=this.tokenEnd,p="Percent sign is expected");break}this.error(p,m);}this.next();},eatIdent(a){(this.tokenType!==1||this.lookupValue(0,a)===!1)&&this.error(`Identifier "${a}" is expected`),this.next();},eatDelim(a){this.isDelim(a)||this.error(`Delim "${String.fromCharCode(a)}" is expected`),this.next();},getLocation(a,l){return n?s.getLocationRange(a,l,r):null},getLocationFromList(a){if(n){let l=this.getFirstListNode(a),p=this.getLastListNode(a);return s.getLocationRange(l!==null?l.loc.start.offset-s.startOffset:this.tokenStart,p!==null?p.loc.end.offset-s.startOffset:this.tokenStart,r)}return null},error(a,l){let p=typeof l<"u"&&l<t.length?s.getLocation(l):this.eof?s.getLocation(Uo(t,t.length-1)):s.getLocation(this.tokenStart);throw new sr(a||"Unexpected input",t,p.offset,p.line,p.column)}});return Object.assign(function(a,l){t=a,l=l||{},u.setSource(t,ve),s.setSource(t,l.offset,l.line,l.column),r=l.filename||"<unknown>",n=Boolean(l.positions),o=typeof l.onParseError=="function"?l.onParseError:Ko,i=!1,u.parseAtrulePrelude="parseAtrulePrelude"in l?Boolean(l.parseAtrulePrelude):!0,u.parseRulePrelude="parseRulePrelude"in l?Boolean(l.parseRulePrelude):!0,u.parseValue="parseValue"in l?Boolean(l.parseValue):!0,u.parseCustomProperty="parseCustomProperty"in l?Boolean(l.parseCustomProperty):!1;let{context:p="default",onComment:m}=l;if(!(p in u.context))throw new Error("Unknown context `"+p+"`");typeof m=="function"&&u.forEachToken((P,te,X)=>{if(P===25){let S=u.getLocation(te,X),R=ge(t,X-2,X,"*/")?t.slice(te+2,X-2):t.slice(te+2,X);m(R,S);}});let f=u.context[p].call(u,l);return u.eof||u.error(),f},{SyntaxError:sr,config:u.config})}var xi=ls(gi(),1),bi=new Set(["Atrule","Selector","Declaration"]);function yi(e){let t=new xi.SourceMapGenerator,r={line:1,column:0},n={line:0,column:0},o={line:1,column:0},i={generated:o},s=1,u=0,c=!1,a=e.node;e.node=function(m){if(m.loc&&m.loc.start&&bi.has(m.type)){let f=m.loc.start.line,P=m.loc.start.column-1;(n.line!==f||n.column!==P)&&(n.line=f,n.column=P,r.line=s,r.column=u,c&&(c=!1,(r.line!==o.line||r.column!==o.column)&&t.addMapping(i)),c=!0,t.addMapping({source:m.loc.source,original:n,generated:r}));}a.call(this,m),c&&bi.has(m.type)&&(o.line=s,o.column=u);};let l=e.emit;e.emit=function(m,f,P){for(let te=0;te<m.length;te++)m.charCodeAt(te)===10?(s++,u=0):u++;l(m,f,P);};let p=e.result;return e.result=function(){return c&&t.addMapping(i),{css:p(),map:t}},e}var It={};b(It,{safe:()=>br,spec:()=>js});var Bs=43,_s=45,gr=(e,t)=>{if(e===9&&(e=t),typeof e=="string"){let r=e.charCodeAt(0);return r>127?32768:r<<8}return e},ki=[[1,1],[1,2],[1,7],[1,8],[1,"-"],[1,10],[1,11],[1,12],[1,15],[1,21],[3,1],[3,2],[3,7],[3,8],[3,"-"],[3,10],[3,11],[3,12],[3,15],[4,1],[4,2],[4,7],[4,8],[4,"-"],[4,10],[4,11],[4,12],[4,15],[12,1],[12,2],[12,7],[12,8],[12,"-"],[12,10],[12,11],[12,12],[12,15],["#",1],["#",2],["#",7],["#",8],["#","-"],["#",10],["#",11],["#",12],["#",15],["-",1],["-",2],["-",7],["-",8],["-","-"],["-",10],["-",11],["-",12],["-",15],[10,1],[10,2],[10,7],[10,8],[10,10],[10,11],[10,12],[10,"%"],[10,15],["@",1],["@",2],["@",7],["@",8],["@","-"],["@",15],[".",10],[".",11],[".",12],["+",10],["+",11],["+",12],["/","*"]],Us=ki.concat([[1,4],[12,4],[4,4],[3,21],[3,5],[3,16],[11,11],[11,12],[11,2],[11,"-"],[22,1],[22,2],[22,11],[22,12],[22,4],[22,"-"]]);function wi(e){let t=new Set(e.map(([r,n])=>gr(r)<<16|gr(n)));return function(r,n,o){let i=gr(n,o),s=o.charCodeAt(0);return (s===_s&&n!==1&&n!==2&&n!==15||s===Bs?t.has(r<<16|s<<8):t.has(r<<16|i))&&this.emit(" ",13,!0),i}}var js=wi(ki),br=wi(Us);var qs=92;function Ws(e,t){if(typeof t=="function"){let r=null;e.children.forEach(n=>{r!==null&&t.call(this,r),this.node(n),r=n;});return}e.children.forEach(this.node,this);}function Hs(e){ve(e,(t,r,n)=>{this.token(t,e.slice(r,n));});}function vi(e){let t=new Map;for(let r in e.node){let n=e.node[r];typeof(n.generate||n)=="function"&&t.set(r,n.generate||n);}return function(r,n){let o="",i=0,s={node(c){if(t.has(c.type))t.get(c.type).call(u,c);else throw new Error("Unknown node type: "+c.type)},tokenBefore:br,token(c,a){i=this.tokenBefore(i,c,a),this.emit(a,c,!1),c===9&&a.charCodeAt(0)===qs&&this.emit(`
  6709. `,13,!0);},emit(c){o+=c;},result(){return o}};n&&(typeof n.decorator=="function"&&(s=n.decorator(s)),n.sourceMap&&(s=yi(s)),n.mode in It&&(s.tokenBefore=It[n.mode]));let u={node:c=>s.node(c),children:Ws,token:(c,a)=>s.token(c,a),tokenize:Hs};return s.node(r),s.result()}}function Si(e){return {fromPlainObject(t){return e(t,{enter(r){r.children&&!(r.children instanceof D)&&(r.children=new D().fromArray(r.children));}}),t},toPlainObject(t){return e(t,{leave(r){r.children&&r.children instanceof D&&(r.children=r.children.toArray());}}),t}}}var{hasOwnProperty:xr}=Object.prototype,it=function(){};function Ci(e){return typeof e=="function"?e:it}function Ai(e,t){return function(r,n,o){r.type===t&&e.call(this,r,n,o);}}function Ys(e,t){let r=t.structure,n=[];for(let o in r){if(xr.call(r,o)===!1)continue;let i=r[o],s={name:o,type:!1,nullable:!1};Array.isArray(i)||(i=[i]);for(let u of i)u===null?s.nullable=!0:typeof u=="string"?s.type="node":Array.isArray(u)&&(s.type="list");s.type&&n.push(s);}return n.length?{context:t.walkContext,fields:n}:null}function Gs(e){let t={};for(let r in e.node)if(xr.call(e.node,r)){let n=e.node[r];if(!n.structure)throw new Error("Missed `structure` field in `"+r+"` node type definition");t[r]=Ys(r,n);}return t}function Ti(e,t){let r=e.fields.slice(),n=e.context,o=typeof n=="string";return t&&r.reverse(),function(i,s,u,c){let a;o&&(a=s[n],s[n]=i);for(let l of r){let p=i[l.name];if(!l.nullable||p){if(l.type==="list"){if(t?p.reduceRight(c,!1):p.reduce(c,!1))return !0}else if(u(p))return !0}}o&&(s[n]=a);}}function Ei({StyleSheet:e,Atrule:t,Rule:r,Block:n,DeclarationList:o}){return {Atrule:{StyleSheet:e,Atrule:t,Rule:r,Block:n},Rule:{StyleSheet:e,Atrule:t,Rule:r,Block:n},Declaration:{StyleSheet:e,Atrule:t,Rule:r,Block:n,DeclarationList:o}}}function Li(e){let t=Gs(e),r={},n={},o=Symbol("break-walk"),i=Symbol("skip-node");for(let a in t)xr.call(t,a)&&t[a]!==null&&(r[a]=Ti(t[a],!1),n[a]=Ti(t[a],!0));let s=Ei(r),u=Ei(n),c=function(a,l){function p(S,R,ke){let z=m.call(X,S,R,ke);return z===o?!0:z===i?!1:!!(P.hasOwnProperty(S.type)&&P[S.type](S,X,p,te)||f.call(X,S,R,ke)===o)}let m=it,f=it,P=r,te=(S,R,ke,z)=>S||p(R,ke,z),X={break:o,skip:i,root:a,stylesheet:null,atrule:null,atrulePrelude:null,rule:null,selector:null,block:null,declaration:null,function:null};if(typeof l=="function")m=l;else if(l&&(m=Ci(l.enter),f=Ci(l.leave),l.reverse&&(P=n),l.visit)){if(s.hasOwnProperty(l.visit))P=l.reverse?u[l.visit]:s[l.visit];else if(!t.hasOwnProperty(l.visit))throw new Error("Bad value `"+l.visit+"` for `visit` option (should be: "+Object.keys(t).sort().join(", ")+")");m=Ai(m,l.visit),f=Ai(f,l.visit);}if(m===it&&f===it)throw new Error("Neither `enter` nor `leave` walker handler is set or both aren't a function");p(a);};return c.break=o,c.skip=i,c.find=function(a,l){let p=null;return c(a,function(m,f,P){if(l.call(this,m,f,P))return p=m,o}),p},c.findLast=function(a,l){let p=null;return c(a,{reverse:!0,enter(m,f,P){if(l.call(this,m,f,P))return p=m,o}}),p},c.findAll=function(a,l){let p=[];return c(a,function(m,f,P){l.call(this,m,f,P)&&p.push(m);}),p},c}function Vs(e){return e}function Ks(e){let{min:t,max:r,comma:n}=e;return t===0&&r===0?n?"#?":"*":t===0&&r===1?"?":t===1&&r===0?n?"#":"+":t===1&&r===1?"":(n?"#":"")+(t===r?"{"+t+"}":"{"+t+","+(r!==0?r:"")+"}")}function Qs(e){switch(e.type){case"Range":return " ["+(e.min===null?"-\u221E":e.min)+","+(e.max===null?"\u221E":e.max)+"]";default:throw new Error("Unknown node type `"+e.type+"`")}}function Xs(e,t,r,n){let o=e.combinator===" "||n?e.combinator:" "+e.combinator+" ",i=e.terms.map(s=>yr(s,t,r,n)).join(o);return e.explicit||r?(n||i[0]===","?"[":"[ ")+i+(n?"]":" ]"):i}function yr(e,t,r,n){let o;switch(e.type){case"Group":o=Xs(e,t,r,n)+(e.disallowEmpty?"!":"");break;case"Multiplier":return yr(e.term,t,r,n)+t(Ks(e),e);case"Type":o="<"+e.name+(e.opts?t(Qs(e.opts),e.opts):"")+">";break;case"Property":o="<'"+e.name+"'>";break;case"Keyword":o=e.name;break;case"AtKeyword":o="@"+e.name;break;case"Function":o=e.name+"(";break;case"String":case"Token":o=e.value;break;case"Comma":o=",";break;default:throw new Error("Unknown node type `"+e.type+"`")}return t(o,e)}function Pe(e,t){let r=Vs,n=!1,o=!1;return typeof t=="function"?r=t:t&&(n=Boolean(t.forceBraces),o=Boolean(t.compact),typeof t.decorate=="function"&&(r=t.decorate)),yr(e,r,n,o)}var Pi={offset:0,line:1,column:1};function $s(e,t){let r=e.tokens,n=e.longestMatch,o=n<r.length&&r[n].node||null,i=o!==t?o:null,s=0,u=0,c=0,a="",l,p;for(let m=0;m<r.length;m++){let f=r[m].value;m===n&&(u=f.length,s=a.length),i!==null&&r[m].node===i&&(m<=n?c++:c=0),a+=f;}return n===r.length||c>1?(l=Dt(i||t,"end")||at(Pi,a),p=at(l)):(l=Dt(i,"start")||at(Dt(t,"start")||Pi,a.slice(0,s)),p=Dt(i,"end")||at(l,a.substr(s,u))),{css:a,mismatchOffset:s,mismatchLength:u,start:l,end:p}}function Dt(e,t){let r=e&&e.loc&&e.loc[t];return r?"line"in r?at(r):r:null}function at({offset:e,line:t,column:r},n){let o={offset:e,line:t,column:r};if(n){let i=n.split(/\n|\r\n?|\f/);o.offset+=n.length,o.line+=i.length-1,o.column=i.length===1?o.column+n.length:i.pop().length+1;}return o}var je=function(e,t){let r=Ee("SyntaxReferenceError",e+(t?" `"+t+"`":""));return r.reference=t,r},Ii=function(e,t,r,n){let o=Ee("SyntaxMatchError",e),{css:i,mismatchOffset:s,mismatchLength:u,start:c,end:a}=$s(n,r);return o.rawMessage=e,o.syntax=t?Pe(t):"<generic>",o.css=i,o.mismatchOffset=s,o.mismatchLength=u,o.message=e+`
  6710. syntax: `+o.syntax+`
  6711. value: `+(i||"<empty string>")+`
  6712. --------`+new Array(o.mismatchOffset+1).join("-")+"^",Object.assign(o,c),o.loc={source:r&&r.loc&&r.loc.source||"<unknown>",start:c,end:a},o};var Ot=new Map,qe=new Map,Nt=45,zt=Zs,kr=Js,Ym=wr;function Mt(e,t){return t=t||0,e.length-t>=2&&e.charCodeAt(t)===Nt&&e.charCodeAt(t+1)===Nt}function wr(e,t){if(t=t||0,e.length-t>=3&&e.charCodeAt(t)===Nt&&e.charCodeAt(t+1)!==Nt){let r=e.indexOf("-",t+2);if(r!==-1)return e.substring(t,r+1)}return ""}function Zs(e){if(Ot.has(e))return Ot.get(e);let t=e.toLowerCase(),r=Ot.get(t);if(r===void 0){let n=Mt(t,0),o=n?"":wr(t,0);r=Object.freeze({basename:t.substr(o.length),name:t,prefix:o,vendor:o,custom:n});}return Ot.set(e,r),r}function Js(e){if(qe.has(e))return qe.get(e);let t=e,r=e[0];r==="/"?r=e[1]==="/"?"//":"/":r!=="_"&&r!=="*"&&r!=="$"&&r!=="#"&&r!=="+"&&r!=="&"&&(r="");let n=Mt(t,r.length);if(!n&&(t=t.toLowerCase(),qe.has(t))){let u=qe.get(t);return qe.set(e,u),u}let o=n?"":wr(t,r.length),i=t.substr(0,r.length+o.length),s=Object.freeze({basename:t.substr(i.length),name:t.substr(r.length),hack:r,vendor:o,prefix:i,custom:n});return qe.set(e,s),s}var Rt=["initial","inherit","unset","revert","revert-layer"];var lt=43,he=45,vr=110,We=!0,tl=!1;function Cr(e,t){return e!==null&&e.type===9&&e.value.charCodeAt(0)===t}function st(e,t,r){for(;e!==null&&(e.type===13||e.type===25);)e=r(++t);return t}function Se(e,t,r,n){if(!e)return 0;let o=e.value.charCodeAt(t);if(o===lt||o===he){if(r)return 0;t++;}for(;t<e.value.length;t++)if(!B(e.value.charCodeAt(t)))return 0;return n+1}function Sr(e,t,r){let n=!1,o=st(e,t,r);if(e=r(o),e===null)return t;if(e.type!==10)if(Cr(e,lt)||Cr(e,he)){if(n=!0,o=st(r(++o),o,r),e=r(o),e===null||e.type!==10)return 0}else return t;if(!n){let i=e.value.charCodeAt(0);if(i!==lt&&i!==he)return 0}return Se(e,n?0:1,n,o)}function Ar(e,t){let r=0;if(!e)return 0;if(e.type===10)return Se(e,0,tl,r);if(e.type===1&&e.value.charCodeAt(0)===he){if(!de(e.value,1,vr))return 0;switch(e.value.length){case 2:return Sr(t(++r),r,t);case 3:return e.value.charCodeAt(2)!==he?0:(r=st(t(++r),r,t),e=t(r),Se(e,0,We,r));default:return e.value.charCodeAt(2)!==he?0:Se(e,3,We,r)}}else if(e.type===1||Cr(e,lt)&&t(r+1).type===1){if(e.type!==1&&(e=t(++r)),e===null||!de(e.value,0,vr))return 0;switch(e.value.length){case 1:return Sr(t(++r),r,t);case 2:return e.value.charCodeAt(1)!==he?0:(r=st(t(++r),r,t),e=t(r),Se(e,0,We,r));default:return e.value.charCodeAt(1)!==he?0:Se(e,2,We,r)}}else if(e.type===12){let n=e.value.charCodeAt(0),o=n===lt||n===he?1:0,i=o;for(;i<e.value.length&&B(e.value.charCodeAt(i));i++);return i===o||!de(e.value,i,vr)?0:i+1===e.value.length?Sr(t(++r),r,t):e.value.charCodeAt(i+1)!==he?0:i+2===e.value.length?(r=st(t(++r),r,t),e=t(r),Se(e,0,We,r)):Se(e,i+2,We,r)}return 0}var rl=43,Di=45,Oi=63,nl=117;function Tr(e,t){return e!==null&&e.type===9&&e.value.charCodeAt(0)===t}function ol(e,t){return e.value.charCodeAt(0)===t}function ct(e,t,r){let n=0;for(let o=t;o<e.value.length;o++){let i=e.value.charCodeAt(o);if(i===Di&&r&&n!==0)return ct(e,t+n+1,!1),6;if(!ee(i)||++n>6)return 0}return n}function Ft(e,t,r){if(!e)return 0;for(;Tr(r(t),Oi);){if(++e>6)return 0;t++;}return t}function Er(e,t){let r=0;if(e===null||e.type!==1||!de(e.value,0,nl)||(e=t(++r),e===null))return 0;if(Tr(e,rl))return e=t(++r),e===null?0:e.type===1?Ft(ct(e,0,!0),++r,t):Tr(e,Oi)?Ft(1,++r,t):0;if(e.type===10){let n=ct(e,1,!0);return n===0?0:(e=t(++r),e===null?r:e.type===12||e.type===10?!ol(e,Di)||!ct(e,1,!1)?0:r+1:Ft(n,r,t))}return e.type===12?Ft(ct(e,1,!0),++r,t):0}var il=["calc(","-moz-calc(","-webkit-calc("],Lr=new Map([[2,22],[21,22],[19,20],[23,24]]);function le(e,t){return t<e.length?e.charCodeAt(t):0}function Ni(e,t){return ge(e,0,e.length,t)}function zi(e,t){for(let r=0;r<t.length;r++)if(Ni(e,t[r]))return !0;return !1}function Mi(e,t){return t!==e.length-2?!1:le(e,t)===92&&B(le(e,t+1))}function Bt(e,t,r){if(e&&e.type==="Range"){let n=Number(r!==void 0&&r!==t.length?t.substr(0,r):t);if(isNaN(n)||e.min!==null&&n<e.min&&typeof e.min!="string"||e.max!==null&&n>e.max&&typeof e.max!="string")return !0}return !1}function al(e,t){let r=0,n=[],o=0;e:do{switch(e.type){case 24:case 22:case 20:if(e.type!==r)break e;if(r=n.pop(),n.length===0){o++;break e}break;case 2:case 21:case 19:case 23:n.push(r),r=Lr.get(e.type);break}o++;}while(e=t(o));return o}function ie(e){return function(t,r,n){return t===null?0:t.type===2&&zi(t.value,il)?al(t,r):e(t,r,n)}}function N(e){return function(t){return t===null||t.type!==e?0:1}}function sl(e){if(e===null||e.type!==1)return 0;let t=e.value.toLowerCase();return zi(t,Rt)||Ni(t,"default")?0:1}function ll(e){return e===null||e.type!==1||le(e.value,0)!==45||le(e.value,1)!==45?0:1}function cl(e){if(e===null||e.type!==4)return 0;let t=e.value.length;if(t!==4&&t!==5&&t!==7&&t!==9)return 0;for(let r=1;r<t;r++)if(!ee(le(e.value,r)))return 0;return 1}function ul(e){return e===null||e.type!==4||!ze(le(e.value,1),le(e.value,2),le(e.value,3))?0:1}function pl(e,t){if(!e)return 0;let r=0,n=[],o=0;e:do{switch(e.type){case 6:case 8:break e;case 24:case 22:case 20:if(e.type!==r)break e;r=n.pop();break;case 17:if(r===0)break e;break;case 9:if(r===0&&e.value==="!")break e;break;case 2:case 21:case 19:case 23:n.push(r),r=Lr.get(e.type);break}o++;}while(e=t(o));return o}function hl(e,t){if(!e)return 0;let r=0,n=[],o=0;e:do{switch(e.type){case 6:case 8:break e;case 24:case 22:case 20:if(e.type!==r)break e;r=n.pop();break;case 2:case 21:case 19:case 23:n.push(r),r=Lr.get(e.type);break}o++;}while(e=t(o));return o}function ye(e){return e&&(e=new Set(e)),function(t,r,n){if(t===null||t.type!==12)return 0;let o=Te(t.value,0);if(e!==null){let i=t.value.indexOf("\\",o),s=i===-1||!Mi(t.value,i)?t.value.substr(o):t.value.substring(o,i);if(e.has(s.toLowerCase())===!1)return 0}return Bt(n,t.value,o)?0:1}}function ml(e,t,r){return e===null||e.type!==11||Bt(r,e.value,e.value.length-1)?0:1}function Ri(e){return typeof e!="function"&&(e=function(){return 0}),function(t,r,n){return t!==null&&t.type===10&&Number(t.value)===0?1:e(t,r,n)}}function fl(e,t,r){if(e===null)return 0;let n=Te(e.value,0);return !(n===e.value.length)&&!Mi(e.value,n)||Bt(r,e.value,n)?0:1}function dl(e,t,r){if(e===null||e.type!==10)return 0;let n=le(e.value,0)===43||le(e.value,0)===45?1:0;for(;n<e.value.length;n++)if(!B(le(e.value,n)))return 0;return Bt(r,e.value,n)?0:1}var gl={"ident-token":N(1),"function-token":N(2),"at-keyword-token":N(3),"hash-token":N(4),"string-token":N(5),"bad-string-token":N(6),"url-token":N(7),"bad-url-token":N(8),"delim-token":N(9),"number-token":N(10),"percentage-token":N(11),"dimension-token":N(12),"whitespace-token":N(13),"CDO-token":N(14),"CDC-token":N(15),"colon-token":N(16),"semicolon-token":N(17),"comma-token":N(18),"[-token":N(19),"]-token":N(20),"(-token":N(21),")-token":N(22),"{-token":N(23),"}-token":N(24)},bl={string:N(5),ident:N(1),percentage:ie(ml),zero:Ri(),number:ie(fl),integer:ie(dl),"custom-ident":sl,"custom-property-name":ll,"hex-color":cl,"id-selector":ul,"an-plus-b":Ar,urange:Er,"declaration-value":pl,"any-value":hl};function xl(e){let{angle:t,decibel:r,frequency:n,flex:o,length:i,resolution:s,semitones:u,time:c}=e||{};return {dimension:ie(ye(null)),angle:ie(ye(t)),decibel:ie(ye(r)),frequency:ie(ye(n)),flex:ie(ye(o)),length:ie(Ri(ye(i))),resolution:ie(ye(s)),semitones:ie(ye(u)),time:ie(ye(c))}}function Fi(e){return {...gl,...bl,...xl(e)}}var _t={};b(_t,{angle:()=>kl,decibel:()=>Al,flex:()=>Cl,frequency:()=>vl,length:()=>yl,resolution:()=>Sl,semitones:()=>Tl,time:()=>wl});var yl=["cm","mm","q","in","pt","pc","px","em","rem","ex","rex","cap","rcap","ch","rch","ic","ric","lh","rlh","vw","svw","lvw","dvw","vh","svh","lvh","dvh","vi","svi","lvi","dvi","vb","svb","lvb","dvb","vmin","svmin","lvmin","dvmin","vmax","svmax","lvmax","dvmax","cqw","cqh","cqi","cqb","cqmin","cqmax"],kl=["deg","grad","rad","turn"],wl=["s","ms"],vl=["hz","khz"],Sl=["dpi","dpcm","dppx","x"],Cl=["fr"],Al=["db"],Tl=["st"];var $i={};b($i,{SyntaxError:()=>Ut,generate:()=>Pe,parse:()=>Ge,walk:()=>Vt});function Ut(e,t,r){return Object.assign(Ee("SyntaxError",e),{input:t,offset:r,rawMessage:e,message:e+`
  6713. `+t+`
  6714. --`+new Array((r||t.length)+1).join("-")+"^"})}var El=9,Ll=10,Pl=12,Il=13,Dl=32,jt=class{constructor(t){this.str=t,this.pos=0;}charCodeAt(t){return t<this.str.length?this.str.charCodeAt(t):0}charCode(){return this.charCodeAt(this.pos)}nextCharCode(){return this.charCodeAt(this.pos+1)}nextNonWsCode(t){return this.charCodeAt(this.findWsEnd(t))}findWsEnd(t){for(;t<this.str.length;t++){let r=this.str.charCodeAt(t);if(r!==Il&&r!==Ll&&r!==Pl&&r!==Dl&&r!==El)break}return t}substringToPos(t){return this.str.substring(this.pos,this.pos=t)}eat(t){this.charCode()!==t&&this.error("Expect `"+String.fromCharCode(t)+"`"),this.pos++;}peek(){return this.pos<this.str.length?this.str.charAt(this.pos++):""}error(t){throw new Ut(t,this.str,this.pos)}};var Ol=9,Nl=10,zl=12,Ml=13,Rl=32,Yi=33,Dr=35,Bi=38,qt=39,Gi=40,Fl=41,Vi=42,Or=43,Nr=44,_i=45,zr=60,Ki=62,Ir=63,Bl=64,Gt=91,Mr=93,Wt=123,Ui=124,ji=125,qi=8734,ut=new Uint8Array(128).map((e,t)=>/[a-zA-Z0-9\-]/.test(String.fromCharCode(t))?1:0),Wi={" ":1,"&&":2,"||":3,"|":4};function Ht(e){return e.substringToPos(e.findWsEnd(e.pos))}function He(e){let t=e.pos;for(;t<e.str.length;t++){let r=e.str.charCodeAt(t);if(r>=128||ut[r]===0)break}return e.pos===t&&e.error("Expect a keyword"),e.substringToPos(t)}function Yt(e){let t=e.pos;for(;t<e.str.length;t++){let r=e.str.charCodeAt(t);if(r<48||r>57)break}return e.pos===t&&e.error("Expect a number"),e.substringToPos(t)}function _l(e){let t=e.str.indexOf("'",e.pos+1);return t===-1&&(e.pos=e.str.length,e.error("Expect an apostrophe")),e.substringToPos(t+1)}function Hi(e){let t=null,r=null;return e.eat(Wt),t=Yt(e),e.charCode()===Nr?(e.pos++,e.charCode()!==ji&&(r=Yt(e))):r=t,e.eat(ji),{min:Number(t),max:r?Number(r):0}}function Ul(e){let t=null,r=!1;switch(e.charCode()){case Vi:e.pos++,t={min:0,max:0};break;case Or:e.pos++,t={min:1,max:0};break;case Ir:e.pos++,t={min:0,max:1};break;case Dr:e.pos++,r=!0,e.charCode()===Wt?t=Hi(e):e.charCode()===Ir?(e.pos++,t={min:0,max:0}):t={min:1,max:0};break;case Wt:t=Hi(e);break;default:return null}return {type:"Multiplier",comma:r,min:t.min,max:t.max,term:null}}function Ye(e,t){let r=Ul(e);return r!==null?(r.term=t,e.charCode()===Dr&&e.charCodeAt(e.pos-1)===Or?Ye(e,r):r):t}function Pr(e){let t=e.peek();return t===""?null:{type:"Token",value:t}}function jl(e){let t;return e.eat(zr),e.eat(qt),t=He(e),e.eat(qt),e.eat(Ki),Ye(e,{type:"Property",name:t})}function ql(e){let t=null,r=null,n=1;return e.eat(Gt),e.charCode()===_i&&(e.peek(),n=-1),n==-1&&e.charCode()===qi?e.peek():(t=n*Number(Yt(e)),ut[e.charCode()]!==0&&(t+=He(e))),Ht(e),e.eat(Nr),Ht(e),e.charCode()===qi?e.peek():(n=1,e.charCode()===_i&&(e.peek(),n=-1),r=n*Number(Yt(e)),ut[e.charCode()]!==0&&(r+=He(e))),e.eat(Mr),{type:"Range",min:t,max:r}}function Wl(e){let t,r=null;return e.eat(zr),t=He(e),e.charCode()===Gi&&e.nextCharCode()===Fl&&(e.pos+=2,t+="()"),e.charCodeAt(e.findWsEnd(e.pos))===Gt&&(Ht(e),r=ql(e)),e.eat(Ki),Ye(e,{type:"Type",name:t,opts:r})}function Hl(e){let t=He(e);return e.charCode()===Gi?(e.pos++,{type:"Function",name:t}):Ye(e,{type:"Keyword",name:t})}function Yl(e,t){function r(o,i){return {type:"Group",terms:o,combinator:i,disallowEmpty:!1,explicit:!1}}let n;for(t=Object.keys(t).sort((o,i)=>Wi[o]-Wi[i]);t.length>0;){n=t.shift();let o=0,i=0;for(;o<e.length;o++){let s=e[o];s.type==="Combinator"&&(s.value===n?(i===-1&&(i=o-1),e.splice(o,1),o--):(i!==-1&&o-i>1&&(e.splice(i,o-i,r(e.slice(i,o),n)),o=i+1),i=-1));}i!==-1&&t.length&&e.splice(i,o-i,r(e.slice(i,o),n));}return n}function Qi(e){let t=[],r={},n,o=null,i=e.pos;for(;n=Vl(e);)n.type!=="Spaces"&&(n.type==="Combinator"?((o===null||o.type==="Combinator")&&(e.pos=i,e.error("Unexpected combinator")),r[n.value]=!0):o!==null&&o.type!=="Combinator"&&(r[" "]=!0,t.push({type:"Combinator",value:" "})),t.push(n),o=n,i=e.pos);return o!==null&&o.type==="Combinator"&&(e.pos-=i,e.error("Unexpected combinator")),{type:"Group",terms:t,combinator:Yl(t,r)||" ",disallowEmpty:!1,explicit:!1}}function Gl(e){let t;return e.eat(Gt),t=Qi(e),e.eat(Mr),t.explicit=!0,e.charCode()===Yi&&(e.pos++,t.disallowEmpty=!0),t}function Vl(e){let t=e.charCode();if(t<128&&ut[t]===1)return Hl(e);switch(t){case Mr:break;case Gt:return Ye(e,Gl(e));case zr:return e.nextCharCode()===qt?jl(e):Wl(e);case Ui:return {type:"Combinator",value:e.substringToPos(e.pos+(e.nextCharCode()===Ui?2:1))};case Bi:return e.pos++,e.eat(Bi),{type:"Combinator",value:"&&"};case Nr:return e.pos++,{type:"Comma"};case qt:return Ye(e,{type:"String",value:_l(e)});case Rl:case Ol:case Nl:case Ml:case zl:return {type:"Spaces",value:Ht(e)};case Bl:return t=e.nextCharCode(),t<128&&ut[t]===1?(e.pos++,{type:"AtKeyword",name:He(e)}):Pr(e);case Vi:case Or:case Ir:case Dr:case Yi:break;case Wt:if(t=e.nextCharCode(),t<48||t>57)return Pr(e);break;default:return Pr(e)}}function Ge(e){let t=new jt(e),r=Qi(t);return t.pos!==e.length&&t.error("Unexpected input"),r.terms.length===1&&r.terms[0].type==="Group"?r.terms[0]:r}var pt=function(){};function Xi(e){return typeof e=="function"?e:pt}function Vt(e,t,r){function n(s){switch(o.call(r,s),s.type){case"Group":s.terms.forEach(n);break;case"Multiplier":n(s.term);break;case"Type":case"Property":case"Keyword":case"AtKeyword":case"Function":case"String":case"Token":case"Comma":break;default:throw new Error("Unknown type: "+s.type)}i.call(r,s);}let o=pt,i=pt;if(typeof t=="function"?o=t:t&&(o=Xi(t.enter),i=Xi(t.leave)),o===pt&&i===pt)throw new Error("Neither `enter` nor `leave` walker handler is set or both aren't a function");n(e);}var Kl={decorator(e){let t=[],r=null;return {...e,node(n){let o=r;r=n,e.node.call(this,n),r=o;},emit(n,o,i){t.push({type:o,value:n,node:i?null:r});},result(){return t}}}};function Ql(e){let t=[];return ve(e,(r,n,o)=>t.push({type:r,value:e.slice(n,o),node:null})),t}function Zi(e,t){return typeof e=="string"?Ql(e):t.generate(e,Kl)}var C={type:"Match"},L={type:"Mismatch"},Kt={type:"DisallowEmpty"},Xl=40,$l=41;function Z(e,t,r){return t===C&&r===L||e===C&&t===C&&r===C?e:(e.type==="If"&&e.else===L&&t===C&&(t=e.then,e=e.match),{type:"If",match:e,then:t,else:r})}function ea(e){return e.length>2&&e.charCodeAt(e.length-2)===Xl&&e.charCodeAt(e.length-1)===$l}function Ji(e){return e.type==="Keyword"||e.type==="AtKeyword"||e.type==="Function"||e.type==="Type"&&ea(e.name)}function Rr(e,t,r){switch(e){case" ":{let n=C;for(let o=t.length-1;o>=0;o--){let i=t[o];n=Z(i,n,L);}return n}case"|":{let n=L,o=null;for(let i=t.length-1;i>=0;i--){let s=t[i];if(Ji(s)&&(o===null&&i>0&&Ji(t[i-1])&&(o=Object.create(null),n=Z({type:"Enum",map:o},C,n)),o!==null)){let u=(ea(s.name)?s.name.slice(0,-1):s.name).toLowerCase();if(!(u in o)){o[u]=s;continue}}o=null,n=Z(s,C,n);}return n}case"&&":{if(t.length>5)return {type:"MatchOnce",terms:t,all:!0};let n=L;for(let o=t.length-1;o>=0;o--){let i=t[o],s;t.length>1?s=Rr(e,t.filter(function(u){return u!==i}),!1):s=C,n=Z(i,s,n);}return n}case"||":{if(t.length>5)return {type:"MatchOnce",terms:t,all:!1};let n=r?C:L;for(let o=t.length-1;o>=0;o--){let i=t[o],s;t.length>1?s=Rr(e,t.filter(function(u){return u!==i}),!0):s=C,n=Z(i,s,n);}return n}}}function Zl(e){let t=C,r=Fr(e.term);if(e.max===0)r=Z(r,Kt,L),t=Z(r,null,L),t.then=Z(C,C,t),e.comma&&(t.then.else=Z({type:"Comma",syntax:e},t,L));else for(let n=e.min||1;n<=e.max;n++)e.comma&&t!==C&&(t=Z({type:"Comma",syntax:e},t,L)),t=Z(r,Z(C,C,t),L);if(e.min===0)t=Z(C,C,t);else for(let n=0;n<e.min-1;n++)e.comma&&t!==C&&(t=Z({type:"Comma",syntax:e},t,L)),t=Z(r,t,L);return t}function Fr(e){if(typeof e=="function")return {type:"Generic",fn:e};switch(e.type){case"Group":{let t=Rr(e.combinator,e.terms.map(Fr),!1);return e.disallowEmpty&&(t=Z(t,Kt,L)),t}case"Multiplier":return Zl(e);case"Type":case"Property":return {type:e.type,name:e.name,syntax:e};case"Keyword":return {type:e.type,name:e.name.toLowerCase(),syntax:e};case"AtKeyword":return {type:e.type,name:"@"+e.name.toLowerCase(),syntax:e};case"Function":return {type:e.type,name:e.name.toLowerCase()+"(",syntax:e};case"String":return e.value.length===3?{type:"Token",value:e.value.charAt(1),syntax:e}:{type:e.type,value:e.value.substr(1,e.value.length-2).replace(/\\'/g,"'"),syntax:e};case"Token":return {type:e.type,value:e.value,syntax:e};case"Comma":return {type:e.type,syntax:e};default:throw new Error("Unknown node type:",e.type)}}function Qt(e,t){return typeof e=="string"&&(e=Ge(e)),{type:"MatchGraph",match:Fr(e),syntax:t||null,source:e}}var {hasOwnProperty:ta}=Object.prototype,Jl=0,ec=1,_r=2,aa=3,ra="Match",tc="Mismatch",rc="Maximum iteration number exceeded (please fill an issue on https://github.com/csstree/csstree/issues)",na=15e3;function oc(e){let t=null,r=null,n=e;for(;n!==null;)r=n.prev,n.prev=t,t=n,n=r;return t}function Br(e,t){if(e.length!==t.length)return !1;for(let r=0;r<e.length;r++){let n=t.charCodeAt(r),o=e.charCodeAt(r);if(o>=65&&o<=90&&(o=o|32),o!==n)return !1}return !0}function ic(e){return e.type!==9?!1:e.value!=="?"}function oa(e){return e===null?!0:e.type===18||e.type===2||e.type===21||e.type===19||e.type===23||ic(e)}function ia(e){return e===null?!0:e.type===22||e.type===20||e.type===24||e.type===9&&e.value==="/"}function ac(e,t,r){function n(){do R++,S=R<e.length?e[R]:null;while(S!==null&&(S.type===13||S.type===25))}function o(ae){let fe=R+ae;return fe<e.length?e[fe]:null}function i(ae,fe){return {nextState:ae,matchStack:z,syntaxStack:p,thenStack:m,tokenIndex:R,prev:fe}}function s(ae){m={nextState:ae,matchStack:z,syntaxStack:p,prev:m};}function u(ae){f=i(ae,f);}function c(){z={type:ec,syntax:t.syntax,token:S,prev:z},n(),P=null,R>ke&&(ke=R);}function a(){p={syntax:t.syntax,opts:t.syntax.opts||p!==null&&p.opts||null,prev:p},z={type:_r,syntax:t.syntax,token:z.token,prev:z};}function l(){z.type===_r?z=z.prev:z={type:aa,syntax:p.syntax,token:z.token,prev:z},p=p.prev;}let p=null,m=null,f=null,P=null,te=0,X=null,S=null,R=-1,ke=0,z={type:Jl,syntax:null,token:null,prev:null};for(n();X===null&&++te<na;)switch(t.type){case"Match":if(m===null){if(S!==null&&(R!==e.length-1||S.value!=="\\0"&&S.value!=="\\9")){t=L;break}X=ra;break}if(t=m.nextState,t===Kt)if(m.matchStack===z){t=L;break}else t=C;for(;m.syntaxStack!==p;)l();m=m.prev;break;case"Mismatch":if(P!==null&&P!==!1)(f===null||R>f.tokenIndex)&&(f=P,P=!1);else if(f===null){X=tc;break}t=f.nextState,m=f.thenStack,p=f.syntaxStack,z=f.matchStack,R=f.tokenIndex,S=R<e.length?e[R]:null,f=f.prev;break;case"MatchGraph":t=t.match;break;case"If":t.else!==L&&u(t.else),t.then!==C&&s(t.then),t=t.match;break;case"MatchOnce":t={type:"MatchOnceBuffer",syntax:t,index:0,mask:0};break;case"MatchOnceBuffer":{let Q=t.syntax.terms;if(t.index===Q.length){if(t.mask===0||t.syntax.all){t=L;break}t=C;break}if(t.mask===(1<<Q.length)-1){t=C;break}for(;t.index<Q.length;t.index++){let J=1<<t.index;if((t.mask&J)===0){u(t),s({type:"AddMatchOnce",syntax:t.syntax,mask:t.mask|J}),t=Q[t.index++];break}}break}case"AddMatchOnce":t={type:"MatchOnceBuffer",syntax:t.syntax,index:0,mask:t.mask};break;case"Enum":if(S!==null){let Q=S.value.toLowerCase();if(Q.indexOf("\\")!==-1&&(Q=Q.replace(/\\[09].*$/,"")),ta.call(t.map,Q)){t=t.map[Q];break}}t=L;break;case"Generic":{let Q=p!==null?p.opts:null,J=R+Math.floor(t.fn(S,o,Q));if(!isNaN(J)&&J>R){for(;R<J;)c();t=C;}else t=L;break}case"Type":case"Property":{let Q=t.type==="Type"?"types":"properties",J=ta.call(r,Q)?r[Q][t.name]:null;if(!J||!J.match)throw new Error("Bad syntax reference: "+(t.type==="Type"?"<"+t.name+">":"<'"+t.name+"'>"));if(P!==!1&&S!==null&&t.type==="Type"&&(t.name==="custom-ident"&&S.type===1||t.name==="length"&&S.value==="0")){P===null&&(P=i(t,f)),t=L;break}a(),t=J.match;break}case"Keyword":{let Q=t.name;if(S!==null){let J=S.value;if(J.indexOf("\\")!==-1&&(J=J.replace(/\\[09].*$/,"")),Br(J,Q)){c(),t=C;break}}t=L;break}case"AtKeyword":case"Function":if(S!==null&&Br(S.value,t.name)){c(),t=C;break}t=L;break;case"Token":if(S!==null&&S.value===t.value){c(),t=C;break}t=L;break;case"Comma":S!==null&&S.type===18?oa(z.token)?t=L:(c(),t=ia(S)?L:C):t=oa(z.token)||ia(S)?C:L;break;case"String":let ae="",fe=R;for(;fe<e.length&&ae.length<t.value.length;fe++)ae+=e[fe].value;if(Br(ae,t.value)){for(;R<fe;)c();t=C;}else t=L;break;default:throw new Error("Unknown node type: "+t.type)}switch(X){case null:console.warn("[csstree-match] BREAK after "+na+" iterations"),X=rc,z=null;break;case ra:for(;p!==null;)l();break;default:z=null;}return {tokens:e,reason:X,iterations:te,match:z,longestMatch:ke}}function Ur(e,t,r){let n=ac(e,t,r||{});if(n.match===null)return n;let o=n.match,i=n.match={syntax:t.syntax||null,match:[]},s=[i];for(o=oc(o).prev;o!==null;){switch(o.type){case _r:i.match.push(i={syntax:o.syntax,match:[]}),s.push(i);break;case aa:s.pop(),i=s[s.length-1];break;default:i.match.push({syntax:o.syntax||null,token:o.token.value,node:o.token.node});}o=o.prev;}return n}var qr={};b(qr,{getTrace:()=>sa,isKeyword:()=>cc,isProperty:()=>lc,isType:()=>sc});function sa(e){function t(o){return o===null?!1:o.type==="Type"||o.type==="Property"||o.type==="Keyword"}function r(o){if(Array.isArray(o.match)){for(let i=0;i<o.match.length;i++)if(r(o.match[i]))return t(o.syntax)&&n.unshift(o.syntax),!0}else if(o.node===e)return n=t(o.syntax)?[o.syntax]:[],!0;return !1}let n=null;return this.matched!==null&&r(this.matched),n}function sc(e,t){return jr(this,e,r=>r.type==="Type"&&r.name===t)}function lc(e,t){return jr(this,e,r=>r.type==="Property"&&r.name===t)}function cc(e){return jr(this,e,t=>t.type==="Keyword")}function jr(e,t,r){let n=sa.call(e,t);return n===null?!1:n.some(r)}function la(e){return "node"in e?e.node:la(e.match[0])}function ca(e){return "node"in e?e.node:ca(e.match[e.match.length-1])}function Wr(e,t,r,n,o){function i(u){if(u.syntax!==null&&u.syntax.type===n&&u.syntax.name===o){let c=la(u),a=ca(u);e.syntax.walk(t,function(l,p,m){if(l===c){let f=new D;do{if(f.appendData(p.data),p.data===a)break;p=p.next;}while(p!==null);s.push({parent:m,nodes:f});}});}Array.isArray(u.match)&&u.match.forEach(i);}let s=[];return r.matched!==null&&i(r.matched),s}var{hasOwnProperty:ht}=Object.prototype;function Hr(e){return typeof e=="number"&&isFinite(e)&&Math.floor(e)===e&&e>=0}function ua(e){return Boolean(e)&&Hr(e.offset)&&Hr(e.line)&&Hr(e.column)}function uc(e,t){return function(n,o){if(!n||n.constructor!==Object)return o(n,"Type of node should be an Object");for(let i in n){let s=!0;if(ht.call(n,i)!==!1){if(i==="type")n.type!==e&&o(n,"Wrong node type `"+n.type+"`, expected `"+e+"`");else if(i==="loc"){if(n.loc===null)continue;if(n.loc&&n.loc.constructor===Object)if(typeof n.loc.source!="string")i+=".source";else if(!ua(n.loc.start))i+=".start";else if(!ua(n.loc.end))i+=".end";else continue;s=!1;}else if(t.hasOwnProperty(i)){s=!1;for(let u=0;!s&&u<t[i].length;u++){let c=t[i][u];switch(c){case String:s=typeof n[i]=="string";break;case Boolean:s=typeof n[i]=="boolean";break;case null:s=n[i]===null;break;default:typeof c=="string"?s=n[i]&&n[i].type===c:Array.isArray(c)&&(s=n[i]instanceof D);}}}else o(n,"Unknown field `"+i+"` for "+e+" node type");s||o(n,"Bad value for `"+e+"."+i+"`");}}for(let i in t)ht.call(t,i)&&ht.call(n,i)===!1&&o(n,"Field `"+e+"."+i+"` is missed");}}function pc(e,t){let r=t.structure,n={type:String,loc:!0},o={type:'"'+e+'"'};for(let i in r){if(ht.call(r,i)===!1)continue;let s=[],u=n[i]=Array.isArray(r[i])?r[i].slice():[r[i]];for(let c=0;c<u.length;c++){let a=u[c];if(a===String||a===Boolean)s.push(a.name);else if(a===null)s.push("null");else if(typeof a=="string")s.push("<"+a+">");else if(Array.isArray(a))s.push("List");else throw new Error("Wrong value `"+a+"` in `"+e+"."+i+"` structure definition")}o[i]=s.join(" | ");}return {docs:o,check:uc(e,n)}}function pa(e){let t={};if(e.node){for(let r in e.node)if(ht.call(e.node,r)){let n=e.node[r];if(n.structure)t[r]=pc(r,n);else throw new Error("Missed `structure` field in `"+r+"` node type definition")}}return t}var hc=Qt(Rt.join(" | "));function Yr(e,t,r){let n={};for(let o in e)e[o].syntax&&(n[o]=r?e[o].syntax:Pe(e[o].syntax,{compact:t}));return n}function mc(e,t,r){let n={};for(let[o,i]of Object.entries(e))n[o]={prelude:i.prelude&&(r?i.prelude.syntax:Pe(i.prelude.syntax,{compact:t})),descriptors:i.descriptors&&Yr(i.descriptors,t,r)};return n}function fc(e){for(let t=0;t<e.length;t++)if(e[t].value.toLowerCase()==="var(")return !0;return !1}function ce(e,t,r){return {matched:e,iterations:r,error:t,...qr}}function Ve(e,t,r,n){let o=Zi(r,e.syntax),i;return fc(o)?ce(null,new Error("Matching for a tree with var() is not supported")):(n&&(i=Ur(o,e.cssWideKeywordsSyntax,e)),(!n||!i.match)&&(i=Ur(o,t.match,e),!i.match)?ce(null,new Ii(i.reason,t.syntax,r,i),i.iterations):ce(i.match,null,i.iterations))}var Ke=class{constructor(t,r,n){if(this.cssWideKeywordsSyntax=hc,this.syntax=r,this.generic=!1,this.units={..._t},this.atrules=Object.create(null),this.properties=Object.create(null),this.types=Object.create(null),this.structure=n||pa(t),t){if(t.units)for(let o of Object.keys(_t))Array.isArray(t.units[o])&&(this.units[o]=t.units[o]);if(t.types)for(let o in t.types)this.addType_(o,t.types[o]);if(t.generic){this.generic=!0;for(let[o,i]of Object.entries(Fi(this.units)))this.addType_(o,i);}if(t.atrules)for(let o in t.atrules)this.addAtrule_(o,t.atrules[o]);if(t.properties)for(let o in t.properties)this.addProperty_(o,t.properties[o]);}}checkStructure(t){function r(i,s){o.push({node:i,message:s});}let n=this.structure,o=[];return this.syntax.walk(t,function(i){n.hasOwnProperty(i.type)?n[i.type].check(i,r):r(i,"Unknown node type `"+i.type+"`");}),o.length?o:!1}createDescriptor(t,r,n,o=null){let i={type:r,name:n},s={type:r,name:n,parent:o,serializable:typeof t=="string"||t&&typeof t.type=="string",syntax:null,match:null};return typeof t=="function"?s.match=Qt(t,i):(typeof t=="string"?Object.defineProperty(s,"syntax",{get(){return Object.defineProperty(s,"syntax",{value:Ge(t)}),s.syntax}}):s.syntax=t,Object.defineProperty(s,"match",{get(){return Object.defineProperty(s,"match",{value:Qt(s.syntax,i)}),s.match}})),s}addAtrule_(t,r){!r||(this.atrules[t]={type:"Atrule",name:t,prelude:r.prelude?this.createDescriptor(r.prelude,"AtrulePrelude",t):null,descriptors:r.descriptors?Object.keys(r.descriptors).reduce((n,o)=>(n[o]=this.createDescriptor(r.descriptors[o],"AtruleDescriptor",o,t),n),Object.create(null)):null});}addProperty_(t,r){!r||(this.properties[t]=this.createDescriptor(r,"Property",t));}addType_(t,r){!r||(this.types[t]=this.createDescriptor(r,"Type",t));}checkAtruleName(t){if(!this.getAtrule(t))return new je("Unknown at-rule","@"+t)}checkAtrulePrelude(t,r){let n=this.checkAtruleName(t);if(n)return n;let o=this.getAtrule(t);if(!o.prelude&&r)return new SyntaxError("At-rule `@"+t+"` should not contain a prelude");if(o.prelude&&!r&&!Ve(this,o.prelude,"",!1).matched)return new SyntaxError("At-rule `@"+t+"` should contain a prelude")}checkAtruleDescriptorName(t,r){let n=this.checkAtruleName(t);if(n)return n;let o=this.getAtrule(t),i=zt(r);if(!o.descriptors)return new SyntaxError("At-rule `@"+t+"` has no known descriptors");if(!o.descriptors[i.name]&&!o.descriptors[i.basename])return new je("Unknown at-rule descriptor",r)}checkPropertyName(t){if(!this.getProperty(t))return new je("Unknown property",t)}matchAtrulePrelude(t,r){let n=this.checkAtrulePrelude(t,r);if(n)return ce(null,n);let o=this.getAtrule(t);return o.prelude?Ve(this,o.prelude,r||"",!1):ce(null,null)}matchAtruleDescriptor(t,r,n){let o=this.checkAtruleDescriptorName(t,r);if(o)return ce(null,o);let i=this.getAtrule(t),s=zt(r);return Ve(this,i.descriptors[s.name]||i.descriptors[s.basename],n,!1)}matchDeclaration(t){return t.type!=="Declaration"?ce(null,new Error("Not a Declaration node")):this.matchProperty(t.property,t.value)}matchProperty(t,r){if(kr(t).custom)return ce(null,new Error("Lexer matching doesn't applicable for custom properties"));let n=this.checkPropertyName(t);return n?ce(null,n):Ve(this,this.getProperty(t),r,!0)}matchType(t,r){let n=this.getType(t);return n?Ve(this,n,r,!1):ce(null,new je("Unknown type",t))}match(t,r){return typeof t!="string"&&(!t||!t.type)?ce(null,new je("Bad syntax")):((typeof t=="string"||!t.match)&&(t=this.createDescriptor(t,"Type","anonymous")),Ve(this,t,r,!1))}findValueFragments(t,r,n,o){return Wr(this,r,this.matchProperty(t,r),n,o)}findDeclarationValueFragments(t,r,n){return Wr(this,t.value,this.matchDeclaration(t),r,n)}findAllFragments(t,r,n){let o=[];return this.syntax.walk(t,{visit:"Declaration",enter:i=>{o.push.apply(o,this.findDeclarationValueFragments(i,r,n));}}),o}getAtrule(t,r=!0){let n=zt(t);return (n.vendor&&r?this.atrules[n.name]||this.atrules[n.basename]:this.atrules[n.name])||null}getAtrulePrelude(t,r=!0){let n=this.getAtrule(t,r);return n&&n.prelude||null}getAtruleDescriptor(t,r){return this.atrules.hasOwnProperty(t)&&this.atrules.declarators&&this.atrules[t].declarators[r]||null}getProperty(t,r=!0){let n=kr(t);return (n.vendor&&r?this.properties[n.name]||this.properties[n.basename]:this.properties[n.name])||null}getType(t){return hasOwnProperty.call(this.types,t)?this.types[t]:null}validate(){function t(o,i,s,u){if(s.has(i))return s.get(i);s.set(i,!1),u.syntax!==null&&Vt(u.syntax,function(c){if(c.type!=="Type"&&c.type!=="Property")return;let a=c.type==="Type"?o.types:o.properties,l=c.type==="Type"?r:n;(!hasOwnProperty.call(a,c.name)||t(o,c.name,l,a[c.name]))&&s.set(i,!0);},this);}let r=new Map,n=new Map;for(let o in this.types)t(this,o,r,this.types[o]);for(let o in this.properties)t(this,o,n,this.properties[o]);return r=[...r.keys()].filter(o=>r.get(o)),n=[...n.keys()].filter(o=>n.get(o)),r.length||n.length?{types:r,properties:n}:null}dump(t,r){return {generic:this.generic,units:this.units,types:Yr(this.types,!r,t),properties:Yr(this.properties,!r,t),atrules:mc(this.atrules,!r,t)}}toString(){return JSON.stringify(this.dump())}};function Gr(e,t){return typeof t=="string"&&/^\s*\|/.test(t)?typeof e=="string"?e+t:t.replace(/^\s*\|\s*/,""):t||null}function ha(e,t){let r=Object.create(null);for(let[n,o]of Object.entries(e))if(o){r[n]={};for(let i of Object.keys(o))t.includes(i)&&(r[n][i]=o[i]);}return r}function mt(e,t){let r={...e};for(let[n,o]of Object.entries(t))switch(n){case"generic":r[n]=Boolean(o);break;case"units":r[n]={...e[n]};for(let[i,s]of Object.entries(o))r[n][i]=Array.isArray(s)?s:[];break;case"atrules":r[n]={...e[n]};for(let[i,s]of Object.entries(o)){let u=r[n][i]||{},c=r[n][i]={prelude:u.prelude||null,descriptors:{...u.descriptors}};if(!!s){c.prelude=s.prelude?Gr(c.prelude,s.prelude):c.prelude||null;for(let[a,l]of Object.entries(s.descriptors||{}))c.descriptors[a]=l?Gr(c.descriptors[a],l):null;Object.keys(c.descriptors).length||(c.descriptors=null);}}break;case"types":case"properties":r[n]={...e[n]};for(let[i,s]of Object.entries(o))r[n][i]=Gr(r[n][i],s);break;case"scope":r[n]={...e[n]};for(let[i,s]of Object.entries(o))r[n][i]={...r[n][i],...s};break;case"parseContext":r[n]={...e[n],...o};break;case"atrule":case"pseudo":r[n]={...e[n],...ha(o,["parse"])};break;case"node":r[n]={...e[n],...ha(o,["name","structure","parse","generate","walkContext"])};break}return r}function ma(e){let t=$o(e),r=Li(e),n=vi(e),{fromPlainObject:o,toPlainObject:i}=Si(r),s={lexer:null,createLexer:u=>new Ke(u,s,s.lexer.structure),tokenize:ve,parse:t,generate:n,walk:r,find:r.find,findLast:r.findLast,findAll:r.findAll,fromPlainObject:o,toPlainObject:i,fork(u){let c=mt({},e);return ma(typeof u=="function"?u(c,Object.assign):mt(c,u))}};return s.lexer=new Ke({generic:!0,units:e.units,types:e.types,atrules:e.atrules,properties:e.properties,node:e.node},s),s}var Vr=e=>ma(mt({},e));var fa={generic:!0,units:{angle:["deg","grad","rad","turn"],decibel:["db"],flex:["fr"],frequency:["hz","khz"],length:["cm","mm","q","in","pt","pc","px","em","rem","ex","rex","cap","rcap","ch","rch","ic","ric","lh","rlh","vw","svw","lvw","dvw","vh","svh","lvh","dvh","vi","svi","lvi","dvi","vb","svb","lvb","dvb","vmin","svmin","lvmin","dvmin","vmax","svmax","lvmax","dvmax","cqw","cqh","cqi","cqb","cqmin","cqmax"],resolution:["dpi","dpcm","dppx","x"],semitones:["st"],time:["s","ms"]},types:{"abs()":"abs( <calc-sum> )","absolute-size":"xx-small|x-small|small|medium|large|x-large|xx-large|xxx-large","acos()":"acos( <calc-sum> )","alpha-value":"<number>|<percentage>","angle-percentage":"<angle>|<percentage>","angular-color-hint":"<angle-percentage>","angular-color-stop":"<color>&&<color-stop-angle>?","angular-color-stop-list":"[<angular-color-stop> [, <angular-color-hint>]?]# , <angular-color-stop>","animateable-feature":"scroll-position|contents|<custom-ident>","asin()":"asin( <calc-sum> )","atan()":"atan( <calc-sum> )","atan2()":"atan2( <calc-sum> , <calc-sum> )",attachment:"scroll|fixed|local","attr()":"attr( <attr-name> <type-or-unit>? [, <attr-fallback>]? )","attr-matcher":"['~'|'|'|'^'|'$'|'*']? '='","attr-modifier":"i|s","attribute-selector":"'[' <wq-name> ']'|'[' <wq-name> <attr-matcher> [<string-token>|<ident-token>] <attr-modifier>? ']'","auto-repeat":"repeat( [auto-fill|auto-fit] , [<line-names>? <fixed-size>]+ <line-names>? )","auto-track-list":"[<line-names>? [<fixed-size>|<fixed-repeat>]]* <line-names>? <auto-repeat> [<line-names>? [<fixed-size>|<fixed-repeat>]]* <line-names>?",axis:"block|inline|vertical|horizontal","baseline-position":"[first|last]? baseline","basic-shape":"<inset()>|<circle()>|<ellipse()>|<polygon()>|<path()>","bg-image":"none|<image>","bg-layer":"<bg-image>||<bg-position> [/ <bg-size>]?||<repeat-style>||<attachment>||<box>||<box>","bg-position":"[[left|center|right|top|bottom|<length-percentage>]|[left|center|right|<length-percentage>] [top|center|bottom|<length-percentage>]|[center|[left|right] <length-percentage>?]&&[center|[top|bottom] <length-percentage>?]]","bg-size":"[<length-percentage>|auto]{1,2}|cover|contain","blur()":"blur( <length> )","blend-mode":"normal|multiply|screen|overlay|darken|lighten|color-dodge|color-burn|hard-light|soft-light|difference|exclusion|hue|saturation|color|luminosity",box:"border-box|padding-box|content-box","brightness()":"brightness( <number-percentage> )","calc()":"calc( <calc-sum> )","calc-sum":"<calc-product> [['+'|'-'] <calc-product>]*","calc-product":"<calc-value> ['*' <calc-value>|'/' <number>]*","calc-value":"<number>|<dimension>|<percentage>|<calc-constant>|( <calc-sum> )","calc-constant":"e|pi|infinity|-infinity|NaN","cf-final-image":"<image>|<color>","cf-mixing-image":"<percentage>?&&<image>","circle()":"circle( [<shape-radius>]? [at <position>]? )","clamp()":"clamp( <calc-sum>#{3} )","class-selector":"'.' <ident-token>","clip-source":"<url>",color:"<rgb()>|<rgba()>|<hsl()>|<hsla()>|<hwb()>|<lab()>|<lch()>|<hex-color>|<named-color>|currentcolor|<deprecated-system-color>","color-stop":"<color-stop-length>|<color-stop-angle>","color-stop-angle":"<angle-percentage>{1,2}","color-stop-length":"<length-percentage>{1,2}","color-stop-list":"[<linear-color-stop> [, <linear-color-hint>]?]# , <linear-color-stop>",combinator:"'>'|'+'|'~'|['||']","common-lig-values":"[common-ligatures|no-common-ligatures]","compat-auto":"searchfield|textarea|push-button|slider-horizontal|checkbox|radio|square-button|menulist|listbox|meter|progress-bar|button","composite-style":"clear|copy|source-over|source-in|source-out|source-atop|destination-over|destination-in|destination-out|destination-atop|xor","compositing-operator":"add|subtract|intersect|exclude","compound-selector":"[<type-selector>? <subclass-selector>* [<pseudo-element-selector> <pseudo-class-selector>*]*]!","compound-selector-list":"<compound-selector>#","complex-selector":"<compound-selector> [<combinator>? <compound-selector>]*","complex-selector-list":"<complex-selector>#","conic-gradient()":"conic-gradient( [from <angle>]? [at <position>]? , <angular-color-stop-list> )","contextual-alt-values":"[contextual|no-contextual]","content-distribution":"space-between|space-around|space-evenly|stretch","content-list":"[<string>|contents|<image>|<counter>|<quote>|<target>|<leader()>|<attr()>]+","content-position":"center|start|end|flex-start|flex-end","content-replacement":"<image>","contrast()":"contrast( [<number-percentage>] )","cos()":"cos( <calc-sum> )",counter:"<counter()>|<counters()>","counter()":"counter( <counter-name> , <counter-style>? )","counter-name":"<custom-ident>","counter-style":"<counter-style-name>|symbols( )","counter-style-name":"<custom-ident>","counters()":"counters( <counter-name> , <string> , <counter-style>? )","cross-fade()":"cross-fade( <cf-mixing-image> , <cf-final-image>? )","cubic-bezier-timing-function":"ease|ease-in|ease-out|ease-in-out|cubic-bezier( <number [0,1]> , <number> , <number [0,1]> , <number> )","deprecated-system-color":"ActiveBorder|ActiveCaption|AppWorkspace|Background|ButtonFace|ButtonHighlight|ButtonShadow|ButtonText|CaptionText|GrayText|Highlight|HighlightText|InactiveBorder|InactiveCaption|InactiveCaptionText|InfoBackground|InfoText|Menu|MenuText|Scrollbar|ThreeDDarkShadow|ThreeDFace|ThreeDHighlight|ThreeDLightShadow|ThreeDShadow|Window|WindowFrame|WindowText","discretionary-lig-values":"[discretionary-ligatures|no-discretionary-ligatures]","display-box":"contents|none","display-inside":"flow|flow-root|table|flex|grid|ruby","display-internal":"table-row-group|table-header-group|table-footer-group|table-row|table-cell|table-column-group|table-column|table-caption|ruby-base|ruby-text|ruby-base-container|ruby-text-container","display-legacy":"inline-block|inline-list-item|inline-table|inline-flex|inline-grid","display-listitem":"<display-outside>?&&[flow|flow-root]?&&list-item","display-outside":"block|inline|run-in","drop-shadow()":"drop-shadow( <length>{2,3} <color>? )","east-asian-variant-values":"[jis78|jis83|jis90|jis04|simplified|traditional]","east-asian-width-values":"[full-width|proportional-width]","element()":"element( <custom-ident> , [first|start|last|first-except]? )|element( <id-selector> )","ellipse()":"ellipse( [<shape-radius>{2}]? [at <position>]? )","ending-shape":"circle|ellipse","env()":"env( <custom-ident> , <declaration-value>? )","exp()":"exp( <calc-sum> )","explicit-track-list":"[<line-names>? <track-size>]+ <line-names>?","family-name":"<string>|<custom-ident>+","feature-tag-value":"<string> [<integer>|on|off]?","feature-type":"@stylistic|@historical-forms|@styleset|@character-variant|@swash|@ornaments|@annotation","feature-value-block":"<feature-type> '{' <feature-value-declaration-list> '}'","feature-value-block-list":"<feature-value-block>+","feature-value-declaration":"<custom-ident> : <integer>+ ;","feature-value-declaration-list":"<feature-value-declaration>","feature-value-name":"<custom-ident>","fill-rule":"nonzero|evenodd","filter-function":"<blur()>|<brightness()>|<contrast()>|<drop-shadow()>|<grayscale()>|<hue-rotate()>|<invert()>|<opacity()>|<saturate()>|<sepia()>","filter-function-list":"[<filter-function>|<url>]+","final-bg-layer":"<'background-color'>||<bg-image>||<bg-position> [/ <bg-size>]?||<repeat-style>||<attachment>||<box>||<box>","fixed-breadth":"<length-percentage>","fixed-repeat":"repeat( [<integer [1,\u221E]>] , [<line-names>? <fixed-size>]+ <line-names>? )","fixed-size":"<fixed-breadth>|minmax( <fixed-breadth> , <track-breadth> )|minmax( <inflexible-breadth> , <fixed-breadth> )","font-stretch-absolute":"normal|ultra-condensed|extra-condensed|condensed|semi-condensed|semi-expanded|expanded|extra-expanded|ultra-expanded|<percentage>","font-variant-css21":"[normal|small-caps]","font-weight-absolute":"normal|bold|<number [1,1000]>","frequency-percentage":"<frequency>|<percentage>","general-enclosed":"[<function-token> <any-value> )]|( <ident> <any-value> )","generic-family":"serif|sans-serif|cursive|fantasy|monospace|-apple-system","generic-name":"serif|sans-serif|cursive|fantasy|monospace","geometry-box":"<shape-box>|fill-box|stroke-box|view-box",gradient:"<linear-gradient()>|<repeating-linear-gradient()>|<radial-gradient()>|<repeating-radial-gradient()>|<conic-gradient()>|<repeating-conic-gradient()>|<-legacy-gradient>","grayscale()":"grayscale( <number-percentage> )","grid-line":"auto|<custom-ident>|[<integer>&&<custom-ident>?]|[span&&[<integer>||<custom-ident>]]","historical-lig-values":"[historical-ligatures|no-historical-ligatures]","hsl()":"hsl( <hue> <percentage> <percentage> [/ <alpha-value>]? )|hsl( <hue> , <percentage> , <percentage> , <alpha-value>? )","hsla()":"hsla( <hue> <percentage> <percentage> [/ <alpha-value>]? )|hsla( <hue> , <percentage> , <percentage> , <alpha-value>? )",hue:"<number>|<angle>","hue-rotate()":"hue-rotate( <angle> )","hwb()":"hwb( [<hue>|none] [<percentage>|none] [<percentage>|none] [/ [<alpha-value>|none]]? )","hypot()":"hypot( <calc-sum># )",image:"<url>|<image()>|<image-set()>|<element()>|<paint()>|<cross-fade()>|<gradient>","image()":"image( <image-tags>? [<image-src>? , <color>?]! )","image-set()":"image-set( <image-set-option># )","image-set-option":"[<image>|<string>] [<resolution>||type( <string> )]","image-src":"<url>|<string>","image-tags":"ltr|rtl","inflexible-breadth":"<length-percentage>|min-content|max-content|auto","inset()":"inset( <length-percentage>{1,4} [round <'border-radius'>]? )","invert()":"invert( <number-percentage> )","keyframes-name":"<custom-ident>|<string>","keyframe-block":"<keyframe-selector># { <declaration-list> }","keyframe-block-list":"<keyframe-block>+","keyframe-selector":"from|to|<percentage>","lab()":"lab( [<percentage>|<number>|none] [<percentage>|<number>|none] [<percentage>|<number>|none] [/ [<alpha-value>|none]]? )","layer()":"layer( <layer-name> )","layer-name":"<ident> ['.' <ident>]*","lch()":"lch( [<percentage>|<number>|none] [<percentage>|<number>|none] [<hue>|none] [/ [<alpha-value>|none]]? )","leader()":"leader( <leader-type> )","leader-type":"dotted|solid|space|<string>","length-percentage":"<length>|<percentage>","line-names":"'[' <custom-ident>* ']'","line-name-list":"[<line-names>|<name-repeat>]+","line-style":"none|hidden|dotted|dashed|solid|double|groove|ridge|inset|outset","line-width":"<length>|thin|medium|thick","linear-color-hint":"<length-percentage>","linear-color-stop":"<color> <color-stop-length>?","linear-gradient()":"linear-gradient( [<angle>|to <side-or-corner>]? , <color-stop-list> )","log()":"log( <calc-sum> , <calc-sum>? )","mask-layer":"<mask-reference>||<position> [/ <bg-size>]?||<repeat-style>||<geometry-box>||[<geometry-box>|no-clip]||<compositing-operator>||<masking-mode>","mask-position":"[<length-percentage>|left|center|right] [<length-percentage>|top|center|bottom]?","mask-reference":"none|<image>|<mask-source>","mask-source":"<url>","masking-mode":"alpha|luminance|match-source","matrix()":"matrix( <number>#{6} )","matrix3d()":"matrix3d( <number>#{16} )","max()":"max( <calc-sum># )","media-and":"<media-in-parens> [and <media-in-parens>]+","media-condition":"<media-not>|<media-and>|<media-or>|<media-in-parens>","media-condition-without-or":"<media-not>|<media-and>|<media-in-parens>","media-feature":"( [<mf-plain>|<mf-boolean>|<mf-range>] )","media-in-parens":"( <media-condition> )|<media-feature>|<general-enclosed>","media-not":"not <media-in-parens>","media-or":"<media-in-parens> [or <media-in-parens>]+","media-query":"<media-condition>|[not|only]? <media-type> [and <media-condition-without-or>]?","media-query-list":"<media-query>#","media-type":"<ident>","mf-boolean":"<mf-name>","mf-name":"<ident>","mf-plain":"<mf-name> : <mf-value>","mf-range":"<mf-name> ['<'|'>']? '='? <mf-value>|<mf-value> ['<'|'>']? '='? <mf-name>|<mf-value> '<' '='? <mf-name> '<' '='? <mf-value>|<mf-value> '>' '='? <mf-name> '>' '='? <mf-value>","mf-value":"<number>|<dimension>|<ident>|<ratio>","min()":"min( <calc-sum># )","minmax()":"minmax( [<length-percentage>|min-content|max-content|auto] , [<length-percentage>|<flex>|min-content|max-content|auto] )","mod()":"mod( <calc-sum> , <calc-sum> )","name-repeat":"repeat( [<integer [1,\u221E]>|auto-fill] , <line-names>+ )","named-color":"transparent|aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen|<-non-standard-color>","namespace-prefix":"<ident>","ns-prefix":"[<ident-token>|'*']? '|'","number-percentage":"<number>|<percentage>","numeric-figure-values":"[lining-nums|oldstyle-nums]","numeric-fraction-values":"[diagonal-fractions|stacked-fractions]","numeric-spacing-values":"[proportional-nums|tabular-nums]",nth:"<an-plus-b>|even|odd","opacity()":"opacity( [<number-percentage>] )","overflow-position":"unsafe|safe","outline-radius":"<length>|<percentage>","page-body":"<declaration>? [; <page-body>]?|<page-margin-box> <page-body>","page-margin-box":"<page-margin-box-type> '{' <declaration-list> '}'","page-margin-box-type":"@top-left-corner|@top-left|@top-center|@top-right|@top-right-corner|@bottom-left-corner|@bottom-left|@bottom-center|@bottom-right|@bottom-right-corner|@left-top|@left-middle|@left-bottom|@right-top|@right-middle|@right-bottom","page-selector-list":"[<page-selector>#]?","page-selector":"<pseudo-page>+|<ident> <pseudo-page>*","page-size":"A5|A4|A3|B5|B4|JIS-B5|JIS-B4|letter|legal|ledger","path()":"path( [<fill-rule> ,]? <string> )","paint()":"paint( <ident> , <declaration-value>? )","perspective()":"perspective( [<length [0,\u221E]>|none] )","polygon()":"polygon( <fill-rule>? , [<length-percentage> <length-percentage>]# )",position:"[[left|center|right]||[top|center|bottom]|[left|center|right|<length-percentage>] [top|center|bottom|<length-percentage>]?|[[left|right] <length-percentage>]&&[[top|bottom] <length-percentage>]]","pow()":"pow( <calc-sum> , <calc-sum> )","pseudo-class-selector":"':' <ident-token>|':' <function-token> <any-value> ')'","pseudo-element-selector":"':' <pseudo-class-selector>","pseudo-page":": [left|right|first|blank]",quote:"open-quote|close-quote|no-open-quote|no-close-quote","radial-gradient()":"radial-gradient( [<ending-shape>||<size>]? [at <position>]? , <color-stop-list> )",ratio:"<number [0,\u221E]> [/ <number [0,\u221E]>]?","relative-selector":"<combinator>? <complex-selector>","relative-selector-list":"<relative-selector>#","relative-size":"larger|smaller","rem()":"rem( <calc-sum> , <calc-sum> )","repeat-style":"repeat-x|repeat-y|[repeat|space|round|no-repeat]{1,2}","repeating-conic-gradient()":"repeating-conic-gradient( [from <angle>]? [at <position>]? , <angular-color-stop-list> )","repeating-linear-gradient()":"repeating-linear-gradient( [<angle>|to <side-or-corner>]? , <color-stop-list> )","repeating-radial-gradient()":"repeating-radial-gradient( [<ending-shape>||<size>]? [at <position>]? , <color-stop-list> )","reversed-counter-name":"reversed( <counter-name> )","rgb()":"rgb( <percentage>{3} [/ <alpha-value>]? )|rgb( <number>{3} [/ <alpha-value>]? )|rgb( <percentage>#{3} , <alpha-value>? )|rgb( <number>#{3} , <alpha-value>? )","rgba()":"rgba( <percentage>{3} [/ <alpha-value>]? )|rgba( <number>{3} [/ <alpha-value>]? )|rgba( <percentage>#{3} , <alpha-value>? )|rgba( <number>#{3} , <alpha-value>? )","rotate()":"rotate( [<angle>|<zero>] )","rotate3d()":"rotate3d( <number> , <number> , <number> , [<angle>|<zero>] )","rotateX()":"rotateX( [<angle>|<zero>] )","rotateY()":"rotateY( [<angle>|<zero>] )","rotateZ()":"rotateZ( [<angle>|<zero>] )","round()":"round( <rounding-strategy>? , <calc-sum> , <calc-sum> )","rounding-strategy":"nearest|up|down|to-zero","saturate()":"saturate( <number-percentage> )","scale()":"scale( [<number>|<percentage>]#{1,2} )","scale3d()":"scale3d( [<number>|<percentage>]#{3} )","scaleX()":"scaleX( [<number>|<percentage>] )","scaleY()":"scaleY( [<number>|<percentage>] )","scaleZ()":"scaleZ( [<number>|<percentage>] )",scroller:"root|nearest","self-position":"center|start|end|self-start|self-end|flex-start|flex-end","shape-radius":"<length-percentage>|closest-side|farthest-side","sign()":"sign( <calc-sum> )","skew()":"skew( [<angle>|<zero>] , [<angle>|<zero>]? )","skewX()":"skewX( [<angle>|<zero>] )","skewY()":"skewY( [<angle>|<zero>] )","sepia()":"sepia( <number-percentage> )",shadow:"inset?&&<length>{2,4}&&<color>?","shadow-t":"[<length>{2,3}&&<color>?]",shape:"rect( <top> , <right> , <bottom> , <left> )|rect( <top> <right> <bottom> <left> )","shape-box":"<box>|margin-box","side-or-corner":"[left|right]||[top|bottom]","sin()":"sin( <calc-sum> )","single-animation":"<time>||<easing-function>||<time>||<single-animation-iteration-count>||<single-animation-direction>||<single-animation-fill-mode>||<single-animation-play-state>||[none|<keyframes-name>]","single-animation-direction":"normal|reverse|alternate|alternate-reverse","single-animation-fill-mode":"none|forwards|backwards|both","single-animation-iteration-count":"infinite|<number>","single-animation-play-state":"running|paused","single-animation-timeline":"auto|none|<timeline-name>|scroll( <axis>? <scroller>? )","single-transition":"[none|<single-transition-property>]||<time>||<easing-function>||<time>","single-transition-property":"all|<custom-ident>",size:"closest-side|farthest-side|closest-corner|farthest-corner|<length>|<length-percentage>{2}","sqrt()":"sqrt( <calc-sum> )","step-position":"jump-start|jump-end|jump-none|jump-both|start|end","step-timing-function":"step-start|step-end|steps( <integer> [, <step-position>]? )","subclass-selector":"<id-selector>|<class-selector>|<attribute-selector>|<pseudo-class-selector>","supports-condition":"not <supports-in-parens>|<supports-in-parens> [and <supports-in-parens>]*|<supports-in-parens> [or <supports-in-parens>]*","supports-in-parens":"( <supports-condition> )|<supports-feature>|<general-enclosed>","supports-feature":"<supports-decl>|<supports-selector-fn>","supports-decl":"( <declaration> )","supports-selector-fn":"selector( <complex-selector> )",symbol:"<string>|<image>|<custom-ident>","tan()":"tan( <calc-sum> )",target:"<target-counter()>|<target-counters()>|<target-text()>","target-counter()":"target-counter( [<string>|<url>] , <custom-ident> , <counter-style>? )","target-counters()":"target-counters( [<string>|<url>] , <custom-ident> , <string> , <counter-style>? )","target-text()":"target-text( [<string>|<url>] , [content|before|after|first-letter]? )","time-percentage":"<time>|<percentage>","timeline-name":"<custom-ident>|<string>","easing-function":"linear|<cubic-bezier-timing-function>|<step-timing-function>","track-breadth":"<length-percentage>|<flex>|min-content|max-content|auto","track-list":"[<line-names>? [<track-size>|<track-repeat>]]+ <line-names>?","track-repeat":"repeat( [<integer [1,\u221E]>] , [<line-names>? <track-size>]+ <line-names>? )","track-size":"<track-breadth>|minmax( <inflexible-breadth> , <track-breadth> )|fit-content( <length-percentage> )","transform-function":"<matrix()>|<translate()>|<translateX()>|<translateY()>|<scale()>|<scaleX()>|<scaleY()>|<rotate()>|<skew()>|<skewX()>|<skewY()>|<matrix3d()>|<translate3d()>|<translateZ()>|<scale3d()>|<scaleZ()>|<rotate3d()>|<rotateX()>|<rotateY()>|<rotateZ()>|<perspective()>","transform-list":"<transform-function>+","translate()":"translate( <length-percentage> , <length-percentage>? )","translate3d()":"translate3d( <length-percentage> , <length-percentage> , <length> )","translateX()":"translateX( <length-percentage> )","translateY()":"translateY( <length-percentage> )","translateZ()":"translateZ( <length> )","type-or-unit":"string|color|url|integer|number|length|angle|time|frequency|cap|ch|em|ex|ic|lh|rlh|rem|vb|vi|vw|vh|vmin|vmax|mm|Q|cm|in|pt|pc|px|deg|grad|rad|turn|ms|s|Hz|kHz|%","type-selector":"<wq-name>|<ns-prefix>? '*'","var()":"var( <custom-property-name> , <declaration-value>? )","viewport-length":"auto|<length-percentage>","visual-box":"content-box|padding-box|border-box","wq-name":"<ns-prefix>? <ident-token>","-legacy-gradient":"<-webkit-gradient()>|<-legacy-linear-gradient>|<-legacy-repeating-linear-gradient>|<-legacy-radial-gradient>|<-legacy-repeating-radial-gradient>","-legacy-linear-gradient":"-moz-linear-gradient( <-legacy-linear-gradient-arguments> )|-webkit-linear-gradient( <-legacy-linear-gradient-arguments> )|-o-linear-gradient( <-legacy-linear-gradient-arguments> )","-legacy-repeating-linear-gradient":"-moz-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )|-webkit-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )|-o-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )","-legacy-linear-gradient-arguments":"[<angle>|<side-or-corner>]? , <color-stop-list>","-legacy-radial-gradient":"-moz-radial-gradient( <-legacy-radial-gradient-arguments> )|-webkit-radial-gradient( <-legacy-radial-gradient-arguments> )|-o-radial-gradient( <-legacy-radial-gradient-arguments> )","-legacy-repeating-radial-gradient":"-moz-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )|-webkit-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )|-o-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )","-legacy-radial-gradient-arguments":"[<position> ,]? [[[<-legacy-radial-gradient-shape>||<-legacy-radial-gradient-size>]|[<length>|<percentage>]{2}] ,]? <color-stop-list>","-legacy-radial-gradient-size":"closest-side|closest-corner|farthest-side|farthest-corner|contain|cover","-legacy-radial-gradient-shape":"circle|ellipse","-non-standard-font":"-apple-system-body|-apple-system-headline|-apple-system-subheadline|-apple-system-caption1|-apple-system-caption2|-apple-system-footnote|-apple-system-short-body|-apple-system-short-headline|-apple-system-short-subheadline|-apple-system-short-caption1|-apple-system-short-footnote|-apple-system-tall-body","-non-standard-color":"-moz-ButtonDefault|-moz-ButtonHoverFace|-moz-ButtonHoverText|-moz-CellHighlight|-moz-CellHighlightText|-moz-Combobox|-moz-ComboboxText|-moz-Dialog|-moz-DialogText|-moz-dragtargetzone|-moz-EvenTreeRow|-moz-Field|-moz-FieldText|-moz-html-CellHighlight|-moz-html-CellHighlightText|-moz-mac-accentdarkestshadow|-moz-mac-accentdarkshadow|-moz-mac-accentface|-moz-mac-accentlightesthighlight|-moz-mac-accentlightshadow|-moz-mac-accentregularhighlight|-moz-mac-accentregularshadow|-moz-mac-chrome-active|-moz-mac-chrome-inactive|-moz-mac-focusring|-moz-mac-menuselect|-moz-mac-menushadow|-moz-mac-menutextselect|-moz-MenuHover|-moz-MenuHoverText|-moz-MenuBarText|-moz-MenuBarHoverText|-moz-nativehyperlinktext|-moz-OddTreeRow|-moz-win-communicationstext|-moz-win-mediatext|-moz-activehyperlinktext|-moz-default-background-color|-moz-default-color|-moz-hyperlinktext|-moz-visitedhyperlinktext|-webkit-activelink|-webkit-focus-ring-color|-webkit-link|-webkit-text","-non-standard-image-rendering":"optimize-contrast|-moz-crisp-edges|-o-crisp-edges|-webkit-optimize-contrast","-non-standard-overflow":"-moz-scrollbars-none|-moz-scrollbars-horizontal|-moz-scrollbars-vertical|-moz-hidden-unscrollable","-non-standard-width":"fill-available|min-intrinsic|intrinsic|-moz-available|-moz-fit-content|-moz-min-content|-moz-max-content|-webkit-min-content|-webkit-max-content","-webkit-gradient()":"-webkit-gradient( <-webkit-gradient-type> , <-webkit-gradient-point> [, <-webkit-gradient-point>|, <-webkit-gradient-radius> , <-webkit-gradient-point>] [, <-webkit-gradient-radius>]? [, <-webkit-gradient-color-stop>]* )","-webkit-gradient-color-stop":"from( <color> )|color-stop( [<number-zero-one>|<percentage>] , <color> )|to( <color> )","-webkit-gradient-point":"[left|center|right|<length-percentage>] [top|center|bottom|<length-percentage>]","-webkit-gradient-radius":"<length>|<percentage>","-webkit-gradient-type":"linear|radial","-webkit-mask-box-repeat":"repeat|stretch|round","-webkit-mask-clip-style":"border|border-box|padding|padding-box|content|content-box|text","-ms-filter-function-list":"<-ms-filter-function>+","-ms-filter-function":"<-ms-filter-function-progid>|<-ms-filter-function-legacy>","-ms-filter-function-progid":"'progid:' [<ident-token> '.']* [<ident-token>|<function-token> <any-value>? )]","-ms-filter-function-legacy":"<ident-token>|<function-token> <any-value>? )","-ms-filter":"<string>",age:"child|young|old","attr-name":"<wq-name>","attr-fallback":"<any-value>","bg-clip":"<box>|border|text",bottom:"<length>|auto","generic-voice":"[<age>? <gender> <integer>?]",gender:"male|female|neutral",left:"<length>|auto","mask-image":"<mask-reference>#",paint:"none|<color>|<url> [none|<color>]?|context-fill|context-stroke",right:"<length>|auto","single-animation-composition":"replace|add|accumulate","svg-length":"<percentage>|<length>|<number>","svg-writing-mode":"lr-tb|rl-tb|tb-rl|lr|rl|tb",top:"<length>|auto",x:"<number>",y:"<number>",declaration:"<ident-token> : <declaration-value>? ['!' important]?","declaration-list":"[<declaration>? ';']* <declaration>?",url:"url( <string> <url-modifier>* )|<url-token>","url-modifier":"<ident>|<function-token> <any-value> )","number-zero-one":"<number [0,1]>","number-one-or-greater":"<number [1,\u221E]>","-non-standard-display":"-ms-inline-flexbox|-ms-grid|-ms-inline-grid|-webkit-flex|-webkit-inline-flex|-webkit-box|-webkit-inline-box|-moz-inline-stack|-moz-box|-moz-inline-box"},properties:{"--*":"<declaration-value>","-ms-accelerator":"false|true","-ms-block-progression":"tb|rl|bt|lr","-ms-content-zoom-chaining":"none|chained","-ms-content-zooming":"none|zoom","-ms-content-zoom-limit":"<'-ms-content-zoom-limit-min'> <'-ms-content-zoom-limit-max'>","-ms-content-zoom-limit-max":"<percentage>","-ms-content-zoom-limit-min":"<percentage>","-ms-content-zoom-snap":"<'-ms-content-zoom-snap-type'>||<'-ms-content-zoom-snap-points'>","-ms-content-zoom-snap-points":"snapInterval( <percentage> , <percentage> )|snapList( <percentage># )","-ms-content-zoom-snap-type":"none|proximity|mandatory","-ms-filter":"<string>","-ms-flow-from":"[none|<custom-ident>]#","-ms-flow-into":"[none|<custom-ident>]#","-ms-grid-columns":"none|<track-list>|<auto-track-list>","-ms-grid-rows":"none|<track-list>|<auto-track-list>","-ms-high-contrast-adjust":"auto|none","-ms-hyphenate-limit-chars":"auto|<integer>{1,3}","-ms-hyphenate-limit-lines":"no-limit|<integer>","-ms-hyphenate-limit-zone":"<percentage>|<length>","-ms-ime-align":"auto|after","-ms-overflow-style":"auto|none|scrollbar|-ms-autohiding-scrollbar","-ms-scrollbar-3dlight-color":"<color>","-ms-scrollbar-arrow-color":"<color>","-ms-scrollbar-base-color":"<color>","-ms-scrollbar-darkshadow-color":"<color>","-ms-scrollbar-face-color":"<color>","-ms-scrollbar-highlight-color":"<color>","-ms-scrollbar-shadow-color":"<color>","-ms-scrollbar-track-color":"<color>","-ms-scroll-chaining":"chained|none","-ms-scroll-limit":"<'-ms-scroll-limit-x-min'> <'-ms-scroll-limit-y-min'> <'-ms-scroll-limit-x-max'> <'-ms-scroll-limit-y-max'>","-ms-scroll-limit-x-max":"auto|<length>","-ms-scroll-limit-x-min":"<length>","-ms-scroll-limit-y-max":"auto|<length>","-ms-scroll-limit-y-min":"<length>","-ms-scroll-rails":"none|railed","-ms-scroll-snap-points-x":"snapInterval( <length-percentage> , <length-percentage> )|snapList( <length-percentage># )","-ms-scroll-snap-points-y":"snapInterval( <length-percentage> , <length-percentage> )|snapList( <length-percentage># )","-ms-scroll-snap-type":"none|proximity|mandatory","-ms-scroll-snap-x":"<'-ms-scroll-snap-type'> <'-ms-scroll-snap-points-x'>","-ms-scroll-snap-y":"<'-ms-scroll-snap-type'> <'-ms-scroll-snap-points-y'>","-ms-scroll-translation":"none|vertical-to-horizontal","-ms-text-autospace":"none|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space","-ms-touch-select":"grippers|none","-ms-user-select":"none|element|text","-ms-wrap-flow":"auto|both|start|end|maximum|clear","-ms-wrap-margin":"<length>","-ms-wrap-through":"wrap|none","-moz-appearance":"none|button|button-arrow-down|button-arrow-next|button-arrow-previous|button-arrow-up|button-bevel|button-focus|caret|checkbox|checkbox-container|checkbox-label|checkmenuitem|dualbutton|groupbox|listbox|listitem|menuarrow|menubar|menucheckbox|menuimage|menuitem|menuitemtext|menulist|menulist-button|menulist-text|menulist-textfield|menupopup|menuradio|menuseparator|meterbar|meterchunk|progressbar|progressbar-vertical|progresschunk|progresschunk-vertical|radio|radio-container|radio-label|radiomenuitem|range|range-thumb|resizer|resizerpanel|scale-horizontal|scalethumbend|scalethumb-horizontal|scalethumbstart|scalethumbtick|scalethumb-vertical|scale-vertical|scrollbarbutton-down|scrollbarbutton-left|scrollbarbutton-right|scrollbarbutton-up|scrollbarthumb-horizontal|scrollbarthumb-vertical|scrollbartrack-horizontal|scrollbartrack-vertical|searchfield|separator|sheet|spinner|spinner-downbutton|spinner-textfield|spinner-upbutton|splitter|statusbar|statusbarpanel|tab|tabpanel|tabpanels|tab-scroll-arrow-back|tab-scroll-arrow-forward|textfield|textfield-multiline|toolbar|toolbarbutton|toolbarbutton-dropdown|toolbargripper|toolbox|tooltip|treeheader|treeheadercell|treeheadersortarrow|treeitem|treeline|treetwisty|treetwistyopen|treeview|-moz-mac-unified-toolbar|-moz-win-borderless-glass|-moz-win-browsertabbar-toolbox|-moz-win-communicationstext|-moz-win-communications-toolbox|-moz-win-exclude-glass|-moz-win-glass|-moz-win-mediatext|-moz-win-media-toolbox|-moz-window-button-box|-moz-window-button-box-maximized|-moz-window-button-close|-moz-window-button-maximize|-moz-window-button-minimize|-moz-window-button-restore|-moz-window-frame-bottom|-moz-window-frame-left|-moz-window-frame-right|-moz-window-titlebar|-moz-window-titlebar-maximized","-moz-binding":"<url>|none","-moz-border-bottom-colors":"<color>+|none","-moz-border-left-colors":"<color>+|none","-moz-border-right-colors":"<color>+|none","-moz-border-top-colors":"<color>+|none","-moz-context-properties":"none|[fill|fill-opacity|stroke|stroke-opacity]#","-moz-float-edge":"border-box|content-box|margin-box|padding-box","-moz-force-broken-image-icon":"0|1","-moz-image-region":"<shape>|auto","-moz-orient":"inline|block|horizontal|vertical","-moz-outline-radius":"<outline-radius>{1,4} [/ <outline-radius>{1,4}]?","-moz-outline-radius-bottomleft":"<outline-radius>","-moz-outline-radius-bottomright":"<outline-radius>","-moz-outline-radius-topleft":"<outline-radius>","-moz-outline-radius-topright":"<outline-radius>","-moz-stack-sizing":"ignore|stretch-to-fit","-moz-text-blink":"none|blink","-moz-user-focus":"ignore|normal|select-after|select-before|select-menu|select-same|select-all|none","-moz-user-input":"auto|none|enabled|disabled","-moz-user-modify":"read-only|read-write|write-only","-moz-window-dragging":"drag|no-drag","-moz-window-shadow":"default|menu|tooltip|sheet|none","-webkit-appearance":"none|button|button-bevel|caps-lock-indicator|caret|checkbox|default-button|inner-spin-button|listbox|listitem|media-controls-background|media-controls-fullscreen-background|media-current-time-display|media-enter-fullscreen-button|media-exit-fullscreen-button|media-fullscreen-button|media-mute-button|media-overlay-play-button|media-play-button|media-seek-back-button|media-seek-forward-button|media-slider|media-sliderthumb|media-time-remaining-display|media-toggle-closed-captions-button|media-volume-slider|media-volume-slider-container|media-volume-sliderthumb|menulist|menulist-button|menulist-text|menulist-textfield|meter|progress-bar|progress-bar-value|push-button|radio|scrollbarbutton-down|scrollbarbutton-left|scrollbarbutton-right|scrollbarbutton-up|scrollbargripper-horizontal|scrollbargripper-vertical|scrollbarthumb-horizontal|scrollbarthumb-vertical|scrollbartrack-horizontal|scrollbartrack-vertical|searchfield|searchfield-cancel-button|searchfield-decoration|searchfield-results-button|searchfield-results-decoration|slider-horizontal|slider-vertical|sliderthumb-horizontal|sliderthumb-vertical|square-button|textarea|textfield|-apple-pay-button","-webkit-border-before":"<'border-width'>||<'border-style'>||<color>","-webkit-border-before-color":"<color>","-webkit-border-before-style":"<'border-style'>","-webkit-border-before-width":"<'border-width'>","-webkit-box-reflect":"[above|below|right|left]? <length>? <image>?","-webkit-line-clamp":"none|<integer>","-webkit-mask":"[<mask-reference>||<position> [/ <bg-size>]?||<repeat-style>||[<box>|border|padding|content|text]||[<box>|border|padding|content]]#","-webkit-mask-attachment":"<attachment>#","-webkit-mask-clip":"[<box>|border|padding|content|text]#","-webkit-mask-composite":"<composite-style>#","-webkit-mask-image":"<mask-reference>#","-webkit-mask-origin":"[<box>|border|padding|content]#","-webkit-mask-position":"<position>#","-webkit-mask-position-x":"[<length-percentage>|left|center|right]#","-webkit-mask-position-y":"[<length-percentage>|top|center|bottom]#","-webkit-mask-repeat":"<repeat-style>#","-webkit-mask-repeat-x":"repeat|no-repeat|space|round","-webkit-mask-repeat-y":"repeat|no-repeat|space|round","-webkit-mask-size":"<bg-size>#","-webkit-overflow-scrolling":"auto|touch","-webkit-tap-highlight-color":"<color>","-webkit-text-fill-color":"<color>","-webkit-text-stroke":"<length>||<color>","-webkit-text-stroke-color":"<color>","-webkit-text-stroke-width":"<length>","-webkit-touch-callout":"default|none","-webkit-user-modify":"read-only|read-write|read-write-plaintext-only","accent-color":"auto|<color>","align-content":"normal|<baseline-position>|<content-distribution>|<overflow-position>? <content-position>","align-items":"normal|stretch|<baseline-position>|[<overflow-position>? <self-position>]","align-self":"auto|normal|stretch|<baseline-position>|<overflow-position>? <self-position>","align-tracks":"[normal|<baseline-position>|<content-distribution>|<overflow-position>? <content-position>]#",all:"initial|inherit|unset|revert|revert-layer",animation:"<single-animation>#","animation-composition":"<single-animation-composition>#","animation-delay":"<time>#","animation-direction":"<single-animation-direction>#","animation-duration":"<time>#","animation-fill-mode":"<single-animation-fill-mode>#","animation-iteration-count":"<single-animation-iteration-count>#","animation-name":"[none|<keyframes-name>]#","animation-play-state":"<single-animation-play-state>#","animation-timing-function":"<easing-function>#","animation-timeline":"<single-animation-timeline>#",appearance:"none|auto|textfield|menulist-button|<compat-auto>","aspect-ratio":"auto|<ratio>",azimuth:"<angle>|[[left-side|far-left|left|center-left|center|center-right|right|far-right|right-side]||behind]|leftwards|rightwards","backdrop-filter":"none|<filter-function-list>","backface-visibility":"visible|hidden",background:"[<bg-layer> ,]* <final-bg-layer>","background-attachment":"<attachment>#","background-blend-mode":"<blend-mode>#","background-clip":"<bg-clip>#","background-color":"<color>","background-image":"<bg-image>#","background-origin":"<box>#","background-position":"<bg-position>#","background-position-x":"[center|[[left|right|x-start|x-end]? <length-percentage>?]!]#","background-position-y":"[center|[[top|bottom|y-start|y-end]? <length-percentage>?]!]#","background-repeat":"<repeat-style>#","background-size":"<bg-size>#","block-overflow":"clip|ellipsis|<string>","block-size":"<'width'>",border:"<line-width>||<line-style>||<color>","border-block":"<'border-top-width'>||<'border-top-style'>||<color>","border-block-color":"<'border-top-color'>{1,2}","border-block-style":"<'border-top-style'>","border-block-width":"<'border-top-width'>","border-block-end":"<'border-top-width'>||<'border-top-style'>||<color>","border-block-end-color":"<'border-top-color'>","border-block-end-style":"<'border-top-style'>","border-block-end-width":"<'border-top-width'>","border-block-start":"<'border-top-width'>||<'border-top-style'>||<color>","border-block-start-color":"<'border-top-color'>","border-block-start-style":"<'border-top-style'>","border-block-start-width":"<'border-top-width'>","border-bottom":"<line-width>||<line-style>||<color>","border-bottom-color":"<'border-top-color'>","border-bottom-left-radius":"<length-percentage>{1,2}","border-bottom-right-radius":"<length-percentage>{1,2}","border-bottom-style":"<line-style>","border-bottom-width":"<line-width>","border-collapse":"collapse|separate","border-color":"<color>{1,4}","border-end-end-radius":"<length-percentage>{1,2}","border-end-start-radius":"<length-percentage>{1,2}","border-image":"<'border-image-source'>||<'border-image-slice'> [/ <'border-image-width'>|/ <'border-image-width'>? / <'border-image-outset'>]?||<'border-image-repeat'>","border-image-outset":"[<length>|<number>]{1,4}","border-image-repeat":"[stretch|repeat|round|space]{1,2}","border-image-slice":"<number-percentage>{1,4}&&fill?","border-image-source":"none|<image>","border-image-width":"[<length-percentage>|<number>|auto]{1,4}","border-inline":"<'border-top-width'>||<'border-top-style'>||<color>","border-inline-end":"<'border-top-width'>||<'border-top-style'>||<color>","border-inline-color":"<'border-top-color'>{1,2}","border-inline-style":"<'border-top-style'>","border-inline-width":"<'border-top-width'>","border-inline-end-color":"<'border-top-color'>","border-inline-end-style":"<'border-top-style'>","border-inline-end-width":"<'border-top-width'>","border-inline-start":"<'border-top-width'>||<'border-top-style'>||<color>","border-inline-start-color":"<'border-top-color'>","border-inline-start-style":"<'border-top-style'>","border-inline-start-width":"<'border-top-width'>","border-left":"<line-width>||<line-style>||<color>","border-left-color":"<color>","border-left-style":"<line-style>","border-left-width":"<line-width>","border-radius":"<length-percentage>{1,4} [/ <length-percentage>{1,4}]?","border-right":"<line-width>||<line-style>||<color>","border-right-color":"<color>","border-right-style":"<line-style>","border-right-width":"<line-width>","border-spacing":"<length> <length>?","border-start-end-radius":"<length-percentage>{1,2}","border-start-start-radius":"<length-percentage>{1,2}","border-style":"<line-style>{1,4}","border-top":"<line-width>||<line-style>||<color>","border-top-color":"<color>","border-top-left-radius":"<length-percentage>{1,2}","border-top-right-radius":"<length-percentage>{1,2}","border-top-style":"<line-style>","border-top-width":"<line-width>","border-width":"<line-width>{1,4}",bottom:"<length>|<percentage>|auto","box-align":"start|center|end|baseline|stretch","box-decoration-break":"slice|clone","box-direction":"normal|reverse|inherit","box-flex":"<number>","box-flex-group":"<integer>","box-lines":"single|multiple","box-ordinal-group":"<integer>","box-orient":"horizontal|vertical|inline-axis|block-axis|inherit","box-pack":"start|center|end|justify","box-shadow":"none|<shadow>#","box-sizing":"content-box|border-box","break-after":"auto|avoid|always|all|avoid-page|page|left|right|recto|verso|avoid-column|column|avoid-region|region","break-before":"auto|avoid|always|all|avoid-page|page|left|right|recto|verso|avoid-column|column|avoid-region|region","break-inside":"auto|avoid|avoid-page|avoid-column|avoid-region","caption-side":"top|bottom|block-start|block-end|inline-start|inline-end",caret:"<'caret-color'>||<'caret-shape'>","caret-color":"auto|<color>","caret-shape":"auto|bar|block|underscore",clear:"none|left|right|both|inline-start|inline-end",clip:"<shape>|auto","clip-path":"<clip-source>|[<basic-shape>||<geometry-box>]|none",color:"<color>","print-color-adjust":"economy|exact","color-scheme":"normal|[light|dark|<custom-ident>]+&&only?","column-count":"<integer>|auto","column-fill":"auto|balance|balance-all","column-gap":"normal|<length-percentage>","column-rule":"<'column-rule-width'>||<'column-rule-style'>||<'column-rule-color'>","column-rule-color":"<color>","column-rule-style":"<'border-style'>","column-rule-width":"<'border-width'>","column-span":"none|all","column-width":"<length>|auto",columns:"<'column-width'>||<'column-count'>",contain:"none|strict|content|[[size||inline-size]||layout||style||paint]","contain-intrinsic-size":"[none|<length>|auto <length>]{1,2}","contain-intrinsic-block-size":"none|<length>|auto <length>","contain-intrinsic-height":"none|<length>|auto <length>","contain-intrinsic-inline-size":"none|<length>|auto <length>","contain-intrinsic-width":"none|<length>|auto <length>",content:"normal|none|[<content-replacement>|<content-list>] [/ [<string>|<counter>]+]?","content-visibility":"visible|auto|hidden","counter-increment":"[<counter-name> <integer>?]+|none","counter-reset":"[<counter-name> <integer>?|<reversed-counter-name> <integer>?]+|none","counter-set":"[<counter-name> <integer>?]+|none",cursor:"[[<url> [<x> <y>]? ,]* [auto|default|none|context-menu|help|pointer|progress|wait|cell|crosshair|text|vertical-text|alias|copy|move|no-drop|not-allowed|e-resize|n-resize|ne-resize|nw-resize|s-resize|se-resize|sw-resize|w-resize|ew-resize|ns-resize|nesw-resize|nwse-resize|col-resize|row-resize|all-scroll|zoom-in|zoom-out|grab|grabbing|hand|-webkit-grab|-webkit-grabbing|-webkit-zoom-in|-webkit-zoom-out|-moz-grab|-moz-grabbing|-moz-zoom-in|-moz-zoom-out]]",direction:"ltr|rtl",display:"[<display-outside>||<display-inside>]|<display-listitem>|<display-internal>|<display-box>|<display-legacy>|<-non-standard-display>","empty-cells":"show|hide",filter:"none|<filter-function-list>|<-ms-filter-function-list>",flex:"none|[<'flex-grow'> <'flex-shrink'>?||<'flex-basis'>]","flex-basis":"content|<'width'>","flex-direction":"row|row-reverse|column|column-reverse","flex-flow":"<'flex-direction'>||<'flex-wrap'>","flex-grow":"<number>","flex-shrink":"<number>","flex-wrap":"nowrap|wrap|wrap-reverse",float:"left|right|none|inline-start|inline-end",font:"[[<'font-style'>||<font-variant-css21>||<'font-weight'>||<'font-stretch'>]? <'font-size'> [/ <'line-height'>]? <'font-family'>]|caption|icon|menu|message-box|small-caption|status-bar","font-family":"[<family-name>|<generic-family>]#","font-feature-settings":"normal|<feature-tag-value>#","font-kerning":"auto|normal|none","font-language-override":"normal|<string>","font-optical-sizing":"auto|none","font-variation-settings":"normal|[<string> <number>]#","font-size":"<absolute-size>|<relative-size>|<length-percentage>","font-size-adjust":"none|[ex-height|cap-height|ch-width|ic-width|ic-height]? [from-font|<number>]","font-smooth":"auto|never|always|<absolute-size>|<length>","font-stretch":"<font-stretch-absolute>","font-style":"normal|italic|oblique <angle>?","font-synthesis":"none|[weight||style||small-caps]","font-variant":"normal|none|[<common-lig-values>||<discretionary-lig-values>||<historical-lig-values>||<contextual-alt-values>||stylistic( <feature-value-name> )||historical-forms||styleset( <feature-value-name># )||character-variant( <feature-value-name># )||swash( <feature-value-name> )||ornaments( <feature-value-name> )||annotation( <feature-value-name> )||[small-caps|all-small-caps|petite-caps|all-petite-caps|unicase|titling-caps]||<numeric-figure-values>||<numeric-spacing-values>||<numeric-fraction-values>||ordinal||slashed-zero||<east-asian-variant-values>||<east-asian-width-values>||ruby]","font-variant-alternates":"normal|[stylistic( <feature-value-name> )||historical-forms||styleset( <feature-value-name># )||character-variant( <feature-value-name># )||swash( <feature-value-name> )||ornaments( <feature-value-name> )||annotation( <feature-value-name> )]","font-variant-caps":"normal|small-caps|all-small-caps|petite-caps|all-petite-caps|unicase|titling-caps","font-variant-east-asian":"normal|[<east-asian-variant-values>||<east-asian-width-values>||ruby]","font-variant-ligatures":"normal|none|[<common-lig-values>||<discretionary-lig-values>||<historical-lig-values>||<contextual-alt-values>]","font-variant-numeric":"normal|[<numeric-figure-values>||<numeric-spacing-values>||<numeric-fraction-values>||ordinal||slashed-zero]","font-variant-position":"normal|sub|super","font-weight":"<font-weight-absolute>|bolder|lighter","forced-color-adjust":"auto|none",gap:"<'row-gap'> <'column-gap'>?",grid:"<'grid-template'>|<'grid-template-rows'> / [auto-flow&&dense?] <'grid-auto-columns'>?|[auto-flow&&dense?] <'grid-auto-rows'>? / <'grid-template-columns'>","grid-area":"<grid-line> [/ <grid-line>]{0,3}","grid-auto-columns":"<track-size>+","grid-auto-flow":"[row|column]||dense","grid-auto-rows":"<track-size>+","grid-column":"<grid-line> [/ <grid-line>]?","grid-column-end":"<grid-line>","grid-column-gap":"<length-percentage>","grid-column-start":"<grid-line>","grid-gap":"<'grid-row-gap'> <'grid-column-gap'>?","grid-row":"<grid-line> [/ <grid-line>]?","grid-row-end":"<grid-line>","grid-row-gap":"<length-percentage>","grid-row-start":"<grid-line>","grid-template":"none|[<'grid-template-rows'> / <'grid-template-columns'>]|[<line-names>? <string> <track-size>? <line-names>?]+ [/ <explicit-track-list>]?","grid-template-areas":"none|<string>+","grid-template-columns":"none|<track-list>|<auto-track-list>|subgrid <line-name-list>?","grid-template-rows":"none|<track-list>|<auto-track-list>|subgrid <line-name-list>?","hanging-punctuation":"none|[first||[force-end|allow-end]||last]",height:"auto|<length>|<percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )","hyphenate-character":"auto|<string>",hyphens:"none|manual|auto","image-orientation":"from-image|<angle>|[<angle>? flip]","image-rendering":"auto|crisp-edges|pixelated|optimizeSpeed|optimizeQuality|<-non-standard-image-rendering>","image-resolution":"[from-image||<resolution>]&&snap?","ime-mode":"auto|normal|active|inactive|disabled","initial-letter":"normal|[<number> <integer>?]","initial-letter-align":"[auto|alphabetic|hanging|ideographic]","inline-size":"<'width'>","input-security":"auto|none",inset:"<'top'>{1,4}","inset-block":"<'top'>{1,2}","inset-block-end":"<'top'>","inset-block-start":"<'top'>","inset-inline":"<'top'>{1,2}","inset-inline-end":"<'top'>","inset-inline-start":"<'top'>",isolation:"auto|isolate","justify-content":"normal|<content-distribution>|<overflow-position>? [<content-position>|left|right]","justify-items":"normal|stretch|<baseline-position>|<overflow-position>? [<self-position>|left|right]|legacy|legacy&&[left|right|center]","justify-self":"auto|normal|stretch|<baseline-position>|<overflow-position>? [<self-position>|left|right]","justify-tracks":"[normal|<content-distribution>|<overflow-position>? [<content-position>|left|right]]#",left:"<length>|<percentage>|auto","letter-spacing":"normal|<length-percentage>","line-break":"auto|loose|normal|strict|anywhere","line-clamp":"none|<integer>","line-height":"normal|<number>|<length>|<percentage>","line-height-step":"<length>","list-style":"<'list-style-type'>||<'list-style-position'>||<'list-style-image'>","list-style-image":"<image>|none","list-style-position":"inside|outside","list-style-type":"<counter-style>|<string>|none",margin:"[<length>|<percentage>|auto]{1,4}","margin-block":"<'margin-left'>{1,2}","margin-block-end":"<'margin-left'>","margin-block-start":"<'margin-left'>","margin-bottom":"<length>|<percentage>|auto","margin-inline":"<'margin-left'>{1,2}","margin-inline-end":"<'margin-left'>","margin-inline-start":"<'margin-left'>","margin-left":"<length>|<percentage>|auto","margin-right":"<length>|<percentage>|auto","margin-top":"<length>|<percentage>|auto","margin-trim":"none|in-flow|all",mask:"<mask-layer>#","mask-border":"<'mask-border-source'>||<'mask-border-slice'> [/ <'mask-border-width'>? [/ <'mask-border-outset'>]?]?||<'mask-border-repeat'>||<'mask-border-mode'>","mask-border-mode":"luminance|alpha","mask-border-outset":"[<length>|<number>]{1,4}","mask-border-repeat":"[stretch|repeat|round|space]{1,2}","mask-border-slice":"<number-percentage>{1,4} fill?","mask-border-source":"none|<image>","mask-border-width":"[<length-percentage>|<number>|auto]{1,4}","mask-clip":"[<geometry-box>|no-clip]#","mask-composite":"<compositing-operator>#","mask-image":"<mask-reference>#","mask-mode":"<masking-mode>#","mask-origin":"<geometry-box>#","mask-position":"<position>#","mask-repeat":"<repeat-style>#","mask-size":"<bg-size>#","mask-type":"luminance|alpha","masonry-auto-flow":"[pack|next]||[definite-first|ordered]","math-depth":"auto-add|add( <integer> )|<integer>","math-shift":"normal|compact","math-style":"normal|compact","max-block-size":"<'max-width'>","max-height":"none|<length-percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )","max-inline-size":"<'max-width'>","max-lines":"none|<integer>","max-width":"none|<length-percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )|<-non-standard-width>","min-block-size":"<'min-width'>","min-height":"auto|<length>|<percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )","min-inline-size":"<'min-width'>","min-width":"auto|<length>|<percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )|<-non-standard-width>","mix-blend-mode":"<blend-mode>|plus-lighter","object-fit":"fill|contain|cover|none|scale-down","object-position":"<position>",offset:"[<'offset-position'>? [<'offset-path'> [<'offset-distance'>||<'offset-rotate'>]?]?]! [/ <'offset-anchor'>]?","offset-anchor":"auto|<position>","offset-distance":"<length-percentage>","offset-path":"none|ray( [<angle>&&<size>&&contain?] )|<path()>|<url>|[<basic-shape>||<geometry-box>]","offset-position":"auto|<position>","offset-rotate":"[auto|reverse]||<angle>",opacity:"<alpha-value>",order:"<integer>",orphans:"<integer>",outline:"[<'outline-color'>||<'outline-style'>||<'outline-width'>]","outline-color":"<color>|invert","outline-offset":"<length>","outline-style":"auto|<'border-style'>","outline-width":"<line-width>",overflow:"[visible|hidden|clip|scroll|auto]{1,2}|<-non-standard-overflow>","overflow-anchor":"auto|none","overflow-block":"visible|hidden|clip|scroll|auto","overflow-clip-box":"padding-box|content-box","overflow-clip-margin":"<visual-box>||<length [0,\u221E]>","overflow-inline":"visible|hidden|clip|scroll|auto","overflow-wrap":"normal|break-word|anywhere","overflow-x":"visible|hidden|clip|scroll|auto","overflow-y":"visible|hidden|clip|scroll|auto","overscroll-behavior":"[contain|none|auto]{1,2}","overscroll-behavior-block":"contain|none|auto","overscroll-behavior-inline":"contain|none|auto","overscroll-behavior-x":"contain|none|auto","overscroll-behavior-y":"contain|none|auto",padding:"[<length>|<percentage>]{1,4}","padding-block":"<'padding-left'>{1,2}","padding-block-end":"<'padding-left'>","padding-block-start":"<'padding-left'>","padding-bottom":"<length>|<percentage>","padding-inline":"<'padding-left'>{1,2}","padding-inline-end":"<'padding-left'>","padding-inline-start":"<'padding-left'>","padding-left":"<length>|<percentage>","padding-right":"<length>|<percentage>","padding-top":"<length>|<percentage>","page-break-after":"auto|always|avoid|left|right|recto|verso","page-break-before":"auto|always|avoid|left|right|recto|verso","page-break-inside":"auto|avoid","paint-order":"normal|[fill||stroke||markers]",perspective:"none|<length>","perspective-origin":"<position>","place-content":"<'align-content'> <'justify-content'>?","place-items":"<'align-items'> <'justify-items'>?","place-self":"<'align-self'> <'justify-self'>?","pointer-events":"auto|none|visiblePainted|visibleFill|visibleStroke|visible|painted|fill|stroke|all|inherit",position:"static|relative|absolute|sticky|fixed|-webkit-sticky",quotes:"none|auto|[<string> <string>]+",resize:"none|both|horizontal|vertical|block|inline",right:"<length>|<percentage>|auto",rotate:"none|<angle>|[x|y|z|<number>{3}]&&<angle>","row-gap":"normal|<length-percentage>","ruby-align":"start|center|space-between|space-around","ruby-merge":"separate|collapse|auto","ruby-position":"[alternate||[over|under]]|inter-character",scale:"none|<number>{1,3}","scrollbar-color":"auto|<color>{2}","scrollbar-gutter":"auto|stable&&both-edges?","scrollbar-width":"auto|thin|none","scroll-behavior":"auto|smooth","scroll-margin":"<length>{1,4}","scroll-margin-block":"<length>{1,2}","scroll-margin-block-start":"<length>","scroll-margin-block-end":"<length>","scroll-margin-bottom":"<length>","scroll-margin-inline":"<length>{1,2}","scroll-margin-inline-start":"<length>","scroll-margin-inline-end":"<length>","scroll-margin-left":"<length>","scroll-margin-right":"<length>","scroll-margin-top":"<length>","scroll-padding":"[auto|<length-percentage>]{1,4}","scroll-padding-block":"[auto|<length-percentage>]{1,2}","scroll-padding-block-start":"auto|<length-percentage>","scroll-padding-block-end":"auto|<length-percentage>","scroll-padding-bottom":"auto|<length-percentage>","scroll-padding-inline":"[auto|<length-percentage>]{1,2}","scroll-padding-inline-start":"auto|<length-percentage>","scroll-padding-inline-end":"auto|<length-percentage>","scroll-padding-left":"auto|<length-percentage>","scroll-padding-right":"auto|<length-percentage>","scroll-padding-top":"auto|<length-percentage>","scroll-snap-align":"[none|start|end|center]{1,2}","scroll-snap-coordinate":"none|<position>#","scroll-snap-destination":"<position>","scroll-snap-points-x":"none|repeat( <length-percentage> )","scroll-snap-points-y":"none|repeat( <length-percentage> )","scroll-snap-stop":"normal|always","scroll-snap-type":"none|[x|y|block|inline|both] [mandatory|proximity]?","scroll-snap-type-x":"none|mandatory|proximity","scroll-snap-type-y":"none|mandatory|proximity","scroll-timeline":"[<'scroll-timeline-name'>||<'scroll-timeline-axis'>]#","scroll-timeline-axis":"[block|inline|vertical|horizontal]#","scroll-timeline-name":"none|<custom-ident>#","shape-image-threshold":"<alpha-value>","shape-margin":"<length-percentage>","shape-outside":"none|[<shape-box>||<basic-shape>]|<image>","tab-size":"<integer>|<length>","table-layout":"auto|fixed","text-align":"start|end|left|right|center|justify|match-parent","text-align-last":"auto|start|end|left|right|center|justify","text-combine-upright":"none|all|[digits <integer>?]","text-decoration":"<'text-decoration-line'>||<'text-decoration-style'>||<'text-decoration-color'>||<'text-decoration-thickness'>","text-decoration-color":"<color>","text-decoration-line":"none|[underline||overline||line-through||blink]|spelling-error|grammar-error","text-decoration-skip":"none|[objects||[spaces|[leading-spaces||trailing-spaces]]||edges||box-decoration]","text-decoration-skip-ink":"auto|all|none","text-decoration-style":"solid|double|dotted|dashed|wavy","text-decoration-thickness":"auto|from-font|<length>|<percentage>","text-emphasis":"<'text-emphasis-style'>||<'text-emphasis-color'>","text-emphasis-color":"<color>","text-emphasis-position":"[over|under]&&[right|left]","text-emphasis-style":"none|[[filled|open]||[dot|circle|double-circle|triangle|sesame]]|<string>","text-indent":"<length-percentage>&&hanging?&&each-line?","text-justify":"auto|inter-character|inter-word|none","text-orientation":"mixed|upright|sideways","text-overflow":"[clip|ellipsis|<string>]{1,2}","text-rendering":"auto|optimizeSpeed|optimizeLegibility|geometricPrecision","text-shadow":"none|<shadow-t>#","text-size-adjust":"none|auto|<percentage>","text-transform":"none|capitalize|uppercase|lowercase|full-width|full-size-kana","text-underline-offset":"auto|<length>|<percentage>","text-underline-position":"auto|from-font|[under||[left|right]]",top:"<length>|<percentage>|auto","touch-action":"auto|none|[[pan-x|pan-left|pan-right]||[pan-y|pan-up|pan-down]||pinch-zoom]|manipulation",transform:"none|<transform-list>","transform-box":"content-box|border-box|fill-box|stroke-box|view-box","transform-origin":"[<length-percentage>|left|center|right|top|bottom]|[[<length-percentage>|left|center|right]&&[<length-percentage>|top|center|bottom]] <length>?","transform-style":"flat|preserve-3d",transition:"<single-transition>#","transition-delay":"<time>#","transition-duration":"<time>#","transition-property":"none|<single-transition-property>#","transition-timing-function":"<easing-function>#",translate:"none|<length-percentage> [<length-percentage> <length>?]?","unicode-bidi":"normal|embed|isolate|bidi-override|isolate-override|plaintext|-moz-isolate|-moz-isolate-override|-moz-plaintext|-webkit-isolate|-webkit-isolate-override|-webkit-plaintext","user-select":"auto|text|none|contain|all","vertical-align":"baseline|sub|super|text-top|text-bottom|middle|top|bottom|<percentage>|<length>",visibility:"visible|hidden|collapse","white-space":"normal|pre|nowrap|pre-wrap|pre-line|break-spaces",widows:"<integer>",width:"auto|<length>|<percentage>|min-content|max-content|fit-content|fit-content( <length-percentage> )|fill|stretch|intrinsic|-moz-max-content|-webkit-max-content|-moz-fit-content|-webkit-fit-content","will-change":"auto|<animateable-feature>#","word-break":"normal|break-all|keep-all|break-word","word-spacing":"normal|<length>","word-wrap":"normal|break-word","writing-mode":"horizontal-tb|vertical-rl|vertical-lr|sideways-rl|sideways-lr|<svg-writing-mode>","z-index":"auto|<integer>",zoom:"normal|reset|<number>|<percentage>","-moz-background-clip":"padding|border","-moz-border-radius-bottomleft":"<'border-bottom-left-radius'>","-moz-border-radius-bottomright":"<'border-bottom-right-radius'>","-moz-border-radius-topleft":"<'border-top-left-radius'>","-moz-border-radius-topright":"<'border-bottom-right-radius'>","-moz-control-character-visibility":"visible|hidden","-moz-osx-font-smoothing":"auto|grayscale","-moz-user-select":"none|text|all|-moz-none","-ms-flex-align":"start|end|center|baseline|stretch","-ms-flex-item-align":"auto|start|end|center|baseline|stretch","-ms-flex-line-pack":"start|end|center|justify|distribute|stretch","-ms-flex-negative":"<'flex-shrink'>","-ms-flex-pack":"start|end|center|justify|distribute","-ms-flex-order":"<integer>","-ms-flex-positive":"<'flex-grow'>","-ms-flex-preferred-size":"<'flex-basis'>","-ms-interpolation-mode":"nearest-neighbor|bicubic","-ms-grid-column-align":"start|end|center|stretch","-ms-grid-row-align":"start|end|center|stretch","-ms-hyphenate-limit-last":"none|always|column|page|spread","-webkit-background-clip":"[<box>|border|padding|content|text]#","-webkit-column-break-after":"always|auto|avoid","-webkit-column-break-before":"always|auto|avoid","-webkit-column-break-inside":"always|auto|avoid","-webkit-font-smoothing":"auto|none|antialiased|subpixel-antialiased","-webkit-mask-box-image":"[<url>|<gradient>|none] [<length-percentage>{4} <-webkit-mask-box-repeat>{2}]?","-webkit-print-color-adjust":"economy|exact","-webkit-text-security":"none|circle|disc|square","-webkit-user-drag":"none|element|auto","-webkit-user-select":"auto|none|text|all","alignment-baseline":"auto|baseline|before-edge|text-before-edge|middle|central|after-edge|text-after-edge|ideographic|alphabetic|hanging|mathematical","baseline-shift":"baseline|sub|super|<svg-length>",behavior:"<url>+","clip-rule":"nonzero|evenodd",cue:"<'cue-before'> <'cue-after'>?","cue-after":"<url> <decibel>?|none","cue-before":"<url> <decibel>?|none","dominant-baseline":"auto|use-script|no-change|reset-size|ideographic|alphabetic|hanging|mathematical|central|middle|text-after-edge|text-before-edge",fill:"<paint>","fill-opacity":"<number-zero-one>","fill-rule":"nonzero|evenodd","glyph-orientation-horizontal":"<angle>","glyph-orientation-vertical":"<angle>",kerning:"auto|<svg-length>",marker:"none|<url>","marker-end":"none|<url>","marker-mid":"none|<url>","marker-start":"none|<url>",pause:"<'pause-before'> <'pause-after'>?","pause-after":"<time>|none|x-weak|weak|medium|strong|x-strong","pause-before":"<time>|none|x-weak|weak|medium|strong|x-strong",rest:"<'rest-before'> <'rest-after'>?","rest-after":"<time>|none|x-weak|weak|medium|strong|x-strong","rest-before":"<time>|none|x-weak|weak|medium|strong|x-strong","shape-rendering":"auto|optimizeSpeed|crispEdges|geometricPrecision",src:"[<url> [format( <string># )]?|local( <family-name> )]#",speak:"auto|none|normal","speak-as":"normal|spell-out||digits||[literal-punctuation|no-punctuation]",stroke:"<paint>","stroke-dasharray":"none|[<svg-length>+]#","stroke-dashoffset":"<svg-length>","stroke-linecap":"butt|round|square","stroke-linejoin":"miter|round|bevel","stroke-miterlimit":"<number-one-or-greater>","stroke-opacity":"<number-zero-one>","stroke-width":"<svg-length>","text-anchor":"start|middle|end","unicode-range":"<urange>#","voice-balance":"<number>|left|center|right|leftwards|rightwards","voice-duration":"auto|<time>","voice-family":"[[<family-name>|<generic-voice>] ,]* [<family-name>|<generic-voice>]|preserve","voice-pitch":"<frequency>&&absolute|[[x-low|low|medium|high|x-high]||[<frequency>|<semitones>|<percentage>]]","voice-range":"<frequency>&&absolute|[[x-low|low|medium|high|x-high]||[<frequency>|<semitones>|<percentage>]]","voice-rate":"[normal|x-slow|slow|medium|fast|x-fast]||<percentage>","voice-stress":"normal|strong|moderate|none|reduced","voice-volume":"silent|[[x-soft|soft|medium|loud|x-loud]||<decibel>]"},atrules:{charset:{prelude:"<string>",descriptors:null},"counter-style":{prelude:"<counter-style-name>",descriptors:{"additive-symbols":"[<integer>&&<symbol>]#",fallback:"<counter-style-name>",negative:"<symbol> <symbol>?",pad:"<integer>&&<symbol>",prefix:"<symbol>",range:"[[<integer>|infinite]{2}]#|auto","speak-as":"auto|bullets|numbers|words|spell-out|<counter-style-name>",suffix:"<symbol>",symbols:"<symbol>+",system:"cyclic|numeric|alphabetic|symbolic|additive|[fixed <integer>?]|[extends <counter-style-name>]"}},document:{prelude:"[<url>|url-prefix( <string> )|domain( <string> )|media-document( <string> )|regexp( <string> )]#",descriptors:null},"font-face":{prelude:null,descriptors:{"ascent-override":"normal|<percentage>","descent-override":"normal|<percentage>","font-display":"[auto|block|swap|fallback|optional]","font-family":"<family-name>","font-feature-settings":"normal|<feature-tag-value>#","font-variation-settings":"normal|[<string> <number>]#","font-stretch":"<font-stretch-absolute>{1,2}","font-style":"normal|italic|oblique <angle>{0,2}","font-weight":"<font-weight-absolute>{1,2}","font-variant":"normal|none|[<common-lig-values>||<discretionary-lig-values>||<historical-lig-values>||<contextual-alt-values>||stylistic( <feature-value-name> )||historical-forms||styleset( <feature-value-name># )||character-variant( <feature-value-name># )||swash( <feature-value-name> )||ornaments( <feature-value-name> )||annotation( <feature-value-name> )||[small-caps|all-small-caps|petite-caps|all-petite-caps|unicase|titling-caps]||<numeric-figure-values>||<numeric-spacing-values>||<numeric-fraction-values>||ordinal||slashed-zero||<east-asian-variant-values>||<east-asian-width-values>||ruby]","line-gap-override":"normal|<percentage>","size-adjust":"<percentage>",src:"[<url> [format( <string># )]?|local( <family-name> )]#","unicode-range":"<urange>#"}},"font-feature-values":{prelude:"<family-name>#",descriptors:null},import:{prelude:"[<string>|<url>] [layer|layer( <layer-name> )]? [supports( [<supports-condition>|<declaration>] )]? <media-query-list>?",descriptors:null},keyframes:{prelude:"<keyframes-name>",descriptors:null},layer:{prelude:"[<layer-name>#|<layer-name>?]",descriptors:null},media:{prelude:"<media-query-list>",descriptors:null},namespace:{prelude:"<namespace-prefix>? [<string>|<url>]",descriptors:null},page:{prelude:"<page-selector-list>",descriptors:{bleed:"auto|<length>",marks:"none|[crop||cross]",size:"<length>{1,2}|auto|[<page-size>||[portrait|landscape]]"}},property:{prelude:"<custom-property-name>",descriptors:{syntax:"<string>",inherits:"true|false","initial-value":"<string>"}},"scroll-timeline":{prelude:"<timeline-name>",descriptors:null},supports:{prelude:"<supports-condition>",descriptors:null},viewport:{prelude:null,descriptors:{height:"<viewport-length>{1,2}","max-height":"<viewport-length>","max-width":"<viewport-length>","max-zoom":"auto|<number>|<percentage>","min-height":"<viewport-length>","min-width":"<viewport-length>","min-zoom":"auto|<number>|<percentage>",orientation:"auto|portrait|landscape","user-zoom":"zoom|fixed","viewport-fit":"auto|contain|cover",width:"<viewport-length>{1,2}",zoom:"auto|<number>|<percentage>"}},nest:{prelude:"<complex-selector-list>",descriptors:null}}};var gt={};b(gt,{AnPlusB:()=>Xr,Atrule:()=>Zr,AtrulePrelude:()=>en,AttributeSelector:()=>nn,Block:()=>an,Brackets:()=>ln,CDC:()=>un,CDO:()=>hn,ClassSelector:()=>fn,Combinator:()=>gn,Comment:()=>xn,Declaration:()=>kn,DeclarationList:()=>Sn,Dimension:()=>An,Function:()=>En,Hash:()=>Pn,IdSelector:()=>Nn,Identifier:()=>Dn,MediaFeature:()=>Mn,MediaQuery:()=>Fn,MediaQueryList:()=>_n,NestingSelector:()=>jn,Nth:()=>Wn,Number:()=>Yn,Operator:()=>Vn,Parentheses:()=>Qn,Percentage:()=>$n,PseudoClassSelector:()=>Jn,PseudoElementSelector:()=>to,Ratio:()=>no,Raw:()=>io,Rule:()=>so,Selector:()=>co,SelectorList:()=>po,String:()=>bo,StyleSheet:()=>yo,TypeSelector:()=>vo,UnicodeRange:()=>Ao,Url:()=>Do,Value:()=>No,WhiteSpace:()=>Mo});var Xr={};b(Xr,{generate:()=>xc,name:()=>gc,parse:()=>Qr,structure:()=>bc});var me=43,re=45,Xt=110,Ie=!0,dc=!1;function $t(e,t){let r=this.tokenStart+e,n=this.charCodeAt(r);for((n===me||n===re)&&(t&&this.error("Number sign is not allowed"),r++);r<this.tokenEnd;r++)B(this.charCodeAt(r))||this.error("Integer is expected",r);}function Qe(e){return $t.call(this,0,e)}function Ce(e,t){if(!this.cmpChar(this.tokenStart+e,t)){let r="";switch(t){case Xt:r="N is expected";break;case re:r="HyphenMinus is expected";break}this.error(r,this.tokenStart+e);}}function Kr(){let e=0,t=0,r=this.tokenType;for(;r===13||r===25;)r=this.lookupType(++e);if(r!==10)if(this.isDelim(me,e)||this.isDelim(re,e)){t=this.isDelim(me,e)?me:re;do r=this.lookupType(++e);while(r===13||r===25);r!==10&&(this.skip(e),Qe.call(this,Ie));}else return null;return e>0&&this.skip(e),t===0&&(r=this.charCodeAt(this.tokenStart),r!==me&&r!==re&&this.error("Number sign is expected")),Qe.call(this,t!==0),t===re?"-"+this.consume(10):this.consume(10)}var gc="AnPlusB",bc={a:[String,null],b:[String,null]};function Qr(){let e=this.tokenStart,t=null,r=null;if(this.tokenType===10)Qe.call(this,dc),r=this.consume(10);else if(this.tokenType===1&&this.cmpChar(this.tokenStart,re))switch(t="-1",Ce.call(this,1,Xt),this.tokenEnd-this.tokenStart){case 2:this.next(),r=Kr.call(this);break;case 3:Ce.call(this,2,re),this.next(),this.skipSC(),Qe.call(this,Ie),r="-"+this.consume(10);break;default:Ce.call(this,2,re),$t.call(this,3,Ie),this.next(),r=this.substrToCursor(e+2);}else if(this.tokenType===1||this.isDelim(me)&&this.lookupType(1)===1){let n=0;switch(t="1",this.isDelim(me)&&(n=1,this.next()),Ce.call(this,0,Xt),this.tokenEnd-this.tokenStart){case 1:this.next(),r=Kr.call(this);break;case 2:Ce.call(this,1,re),this.next(),this.skipSC(),Qe.call(this,Ie),r="-"+this.consume(10);break;default:Ce.call(this,1,re),$t.call(this,2,Ie),this.next(),r=this.substrToCursor(e+n+1);}}else if(this.tokenType===12){let n=this.charCodeAt(this.tokenStart),o=n===me||n===re,i=this.tokenStart+o;for(;i<this.tokenEnd&&B(this.charCodeAt(i));i++);i===this.tokenStart+o&&this.error("Integer is expected",this.tokenStart+o),Ce.call(this,i-this.tokenStart,Xt),t=this.substring(e,i),i+1===this.tokenEnd?(this.next(),r=Kr.call(this)):(Ce.call(this,i-this.tokenStart+1,re),i+2===this.tokenEnd?(this.next(),this.skipSC(),Qe.call(this,Ie),r="-"+this.consume(10)):($t.call(this,i-this.tokenStart+2,Ie),this.next(),r=this.substrToCursor(i+1)));}else this.error();return t!==null&&t.charCodeAt(0)===me&&(t=t.substr(1)),r!==null&&r.charCodeAt(0)===me&&(r=r.substr(1)),{type:"AnPlusB",loc:this.getLocation(e,this.tokenStart),a:t,b:r}}function xc(e){if(e.a){let t=e.a==="+1"&&"n"||e.a==="1"&&"n"||e.a==="-1"&&"-n"||e.a+"n";if(e.b){let r=e.b[0]==="-"||e.b[0]==="+"?e.b:"+"+e.b;this.tokenize(t+r);}else this.tokenize(t);}else this.tokenize(e.b);}var Zr={};b(Zr,{generate:()=>Sc,name:()=>kc,parse:()=>$r,structure:()=>vc,walkContext:()=>wc});function da(e){return this.Raw(e,this.consumeUntilLeftCurlyBracketOrSemicolon,!0)}function yc(){for(let e=1,t;t=this.lookupType(e);e++){if(t===24)return !0;if(t===23||t===3)return !1}return !1}var kc="Atrule",wc="atrule",vc={name:String,prelude:["AtrulePrelude","Raw",null],block:["Block",null]};function $r(e=!1){let t=this.tokenStart,r,n,o=null,i=null;switch(this.eat(3),r=this.substrToCursor(t+1),n=r.toLowerCase(),this.skipSC(),this.eof===!1&&this.tokenType!==23&&this.tokenType!==17&&(this.parseAtrulePrelude?o=this.parseWithFallback(this.AtrulePrelude.bind(this,r,e),da):o=da.call(this,this.tokenIndex),this.skipSC()),this.tokenType){case 17:this.next();break;case 23:hasOwnProperty.call(this.atrule,n)&&typeof this.atrule[n].block=="function"?i=this.atrule[n].block.call(this,e):i=this.Block(yc.call(this));break}return {type:"Atrule",loc:this.getLocation(t,this.tokenStart),name:r,prelude:o,block:i}}function Sc(e){this.token(3,"@"+e.name),e.prelude!==null&&this.node(e.prelude),e.block?this.node(e.block):this.token(17,";");}var en={};b(en,{generate:()=>Ec,name:()=>Cc,parse:()=>Jr,structure:()=>Tc,walkContext:()=>Ac});var Cc="AtrulePrelude",Ac="atrulePrelude",Tc={children:[[]]};function Jr(e){let t=null;return e!==null&&(e=e.toLowerCase()),this.skipSC(),hasOwnProperty.call(this.atrule,e)&&typeof this.atrule[e].prelude=="function"?t=this.atrule[e].prelude.call(this):t=this.readSequence(this.scope.AtrulePrelude),this.skipSC(),this.eof!==!0&&this.tokenType!==23&&this.tokenType!==17&&this.error("Semicolon or block is expected"),{type:"AtrulePrelude",loc:this.getLocationFromList(t),children:t}}function Ec(e){this.children(e);}var nn={};b(nn,{generate:()=>Mc,name:()=>Nc,parse:()=>rn,structure:()=>zc});var Lc=36,ga=42,Zt=61,Pc=94,tn=124,Ic=126;function Dc(){this.eof&&this.error("Unexpected end of input");let e=this.tokenStart,t=!1;return this.isDelim(ga)?(t=!0,this.next()):this.isDelim(tn)||this.eat(1),this.isDelim(tn)?this.charCodeAt(this.tokenStart+1)!==Zt?(this.next(),this.eat(1)):t&&this.error("Identifier is expected",this.tokenEnd):t&&this.error("Vertical line is expected"),{type:"Identifier",loc:this.getLocation(e,this.tokenStart),name:this.substrToCursor(e)}}function Oc(){let e=this.tokenStart,t=this.charCodeAt(e);return t!==Zt&&t!==Ic&&t!==Pc&&t!==Lc&&t!==ga&&t!==tn&&this.error("Attribute selector (=, ~=, ^=, $=, *=, |=) is expected"),this.next(),t!==Zt&&(this.isDelim(Zt)||this.error("Equal sign is expected"),this.next()),this.substrToCursor(e)}var Nc="AttributeSelector",zc={name:"Identifier",matcher:[String,null],value:["String","Identifier",null],flags:[String,null]};function rn(){let e=this.tokenStart,t,r=null,n=null,o=null;return this.eat(19),this.skipSC(),t=Dc.call(this),this.skipSC(),this.tokenType!==20&&(this.tokenType!==1&&(r=Oc.call(this),this.skipSC(),n=this.tokenType===5?this.String():this.Identifier(),this.skipSC()),this.tokenType===1&&(o=this.consume(1),this.skipSC())),this.eat(20),{type:"AttributeSelector",loc:this.getLocation(e,this.tokenStart),name:t,matcher:r,value:n,flags:o}}function Mc(e){this.token(9,"["),this.node(e.name),e.matcher!==null&&(this.tokenize(e.matcher),this.node(e.value)),e.flags!==null&&this.token(1,e.flags),this.token(9,"]");}var an={};b(an,{generate:()=>jc,name:()=>Bc,parse:()=>on,structure:()=>Uc,walkContext:()=>_c});var Rc=38;function ya(e){return this.Raw(e,null,!0)}function ba(){return this.parseWithFallback(this.Rule,ya)}function xa(e){return this.Raw(e,this.consumeUntilSemicolonIncluded,!0)}function Fc(){if(this.tokenType===17)return xa.call(this,this.tokenIndex);let e=this.parseWithFallback(this.Declaration,xa);return this.tokenType===17&&this.next(),e}var Bc="Block",_c="block",Uc={children:[["Atrule","Rule","Declaration"]]};function on(e){let t=e?Fc:ba,r=this.tokenStart,n=this.createList();this.eat(23);e:for(;!this.eof;)switch(this.tokenType){case 24:break e;case 13:case 25:this.next();break;case 3:n.push(this.parseWithFallback(this.Atrule.bind(this,e),ya));break;default:e&&this.isDelim(Rc)?n.push(ba.call(this)):n.push(t.call(this));}return this.eof||this.eat(24),{type:"Block",loc:this.getLocation(r,this.tokenStart),children:n}}function jc(e){this.token(23,"{"),this.children(e,t=>{t.type==="Declaration"&&this.token(17,";");}),this.token(24,"}");}var ln={};b(ln,{generate:()=>Hc,name:()=>qc,parse:()=>sn,structure:()=>Wc});var qc="Brackets",Wc={children:[[]]};function sn(e,t){let r=this.tokenStart,n=null;return this.eat(19),n=e.call(this,t),this.eof||this.eat(20),{type:"Brackets",loc:this.getLocation(r,this.tokenStart),children:n}}function Hc(e){this.token(9,"["),this.children(e),this.token(9,"]");}var un={};b(un,{generate:()=>Vc,name:()=>Yc,parse:()=>cn,structure:()=>Gc});var Yc="CDC",Gc=[];function cn(){let e=this.tokenStart;return this.eat(15),{type:"CDC",loc:this.getLocation(e,this.tokenStart)}}function Vc(){this.token(15,"-->");}var hn={};b(hn,{generate:()=>Xc,name:()=>Kc,parse:()=>pn,structure:()=>Qc});var Kc="CDO",Qc=[];function pn(){let e=this.tokenStart;return this.eat(14),{type:"CDO",loc:this.getLocation(e,this.tokenStart)}}function Xc(){this.token(14,"<!--");}var fn={};b(fn,{generate:()=>eu,name:()=>Zc,parse:()=>mn,structure:()=>Jc});var $c=46,Zc="ClassSelector",Jc={name:String};function mn(){return this.eatDelim($c),{type:"ClassSelector",loc:this.getLocation(this.tokenStart-1,this.tokenEnd),name:this.consume(1)}}function eu(e){this.token(9,"."),this.token(1,e.name);}var gn={};b(gn,{generate:()=>au,name:()=>ou,parse:()=>dn,structure:()=>iu});var tu=43,ka=47,ru=62,nu=126,ou="Combinator",iu={name:String};function dn(){let e=this.tokenStart,t;switch(this.tokenType){case 13:t=" ";break;case 9:switch(this.charCodeAt(this.tokenStart)){case ru:case tu:case nu:this.next();break;case ka:this.next(),this.eatIdent("deep"),this.eatDelim(ka);break;default:this.error("Combinator is expected");}t=this.substrToCursor(e);break}return {type:"Combinator",loc:this.getLocation(e,this.tokenStart),name:t}}function au(e){this.tokenize(e.name);}var xn={};b(xn,{generate:()=>pu,name:()=>cu,parse:()=>bn,structure:()=>uu});var su=42,lu=47,cu="Comment",uu={value:String};function bn(){let e=this.tokenStart,t=this.tokenEnd;return this.eat(25),t-e+2>=2&&this.charCodeAt(t-2)===su&&this.charCodeAt(t-1)===lu&&(t-=2),{type:"Comment",loc:this.getLocation(e,this.tokenStart),value:this.substring(e+2,t)}}function pu(e){this.token(25,"/*"+e.value+"*/");}var kn={};b(kn,{generate:()=>Su,name:()=>ku,parse:()=>yn,structure:()=>vu,walkContext:()=>wu});var va=33,hu=35,mu=36,fu=38,du=42,gu=43,wa=47;function bu(e){return this.Raw(e,this.consumeUntilExclamationMarkOrSemicolon,!0)}function xu(e){return this.Raw(e,this.consumeUntilExclamationMarkOrSemicolon,!1)}function yu(){let e=this.tokenIndex,t=this.Value();return t.type!=="Raw"&&this.eof===!1&&this.tokenType!==17&&this.isDelim(va)===!1&&this.isBalanceEdge(e)===!1&&this.error(),t}var ku="Declaration",wu="declaration",vu={important:[Boolean,String],property:String,value:["Value","Raw"]};function yn(){let e=this.tokenStart,t=this.tokenIndex,r=Cu.call(this),n=Mt(r),o=n?this.parseCustomProperty:this.parseValue,i=n?xu:bu,s=!1,u;this.skipSC(),this.eat(16);let c=this.tokenIndex;if(n||this.skipSC(),o?u=this.parseWithFallback(yu,i):u=i.call(this,this.tokenIndex),n&&u.type==="Value"&&u.children.isEmpty){for(let a=c-this.tokenIndex;a<=0;a++)if(this.lookupType(a)===13){u.children.appendData({type:"WhiteSpace",loc:null,value:" "});break}}return this.isDelim(va)&&(s=Au.call(this),this.skipSC()),this.eof===!1&&this.tokenType!==17&&this.isBalanceEdge(t)===!1&&this.error(),{type:"Declaration",loc:this.getLocation(e,this.tokenStart),important:s,property:r,value:u}}function Su(e){this.token(1,e.property),this.token(16,":"),this.node(e.value),e.important&&(this.token(9,"!"),this.token(1,e.important===!0?"important":e.important));}function Cu(){let e=this.tokenStart;if(this.tokenType===9)switch(this.charCodeAt(this.tokenStart)){case du:case mu:case gu:case hu:case fu:this.next();break;case wa:this.next(),this.isDelim(wa)&&this.next();break}return this.tokenType===4?this.eat(4):this.eat(1),this.substrToCursor(e)}function Au(){this.eat(9),this.skipSC();let e=this.consume(1);return e==="important"?!0:e}var Sn={};b(Sn,{generate:()=>Pu,name:()=>Eu,parse:()=>vn,structure:()=>Lu});var Tu=38;function wn(e){return this.Raw(e,this.consumeUntilSemicolonIncluded,!0)}var Eu="DeclarationList",Lu={children:[["Declaration","Atrule","Rule"]]};function vn(){let e=this.createList();for(;!this.eof;)switch(this.tokenType){case 13:case 25:case 17:this.next();break;case 3:e.push(this.parseWithFallback(this.Atrule.bind(this,!0),wn));break;default:this.isDelim(Tu)?e.push(this.parseWithFallback(this.Rule,wn)):e.push(this.parseWithFallback(this.Declaration,wn));}return {type:"DeclarationList",loc:this.getLocationFromList(e),children:e}}function Pu(e){this.children(e,t=>{t.type==="Declaration"&&this.token(17,";");});}var An={};b(An,{generate:()=>Ou,name:()=>Iu,parse:()=>Cn,structure:()=>Du});var Iu="Dimension",Du={value:String,unit:String};function Cn(){let e=this.tokenStart,t=this.consumeNumber(12);return {type:"Dimension",loc:this.getLocation(e,this.tokenStart),value:t,unit:this.substring(e+t.length,this.tokenStart)}}function Ou(e){this.token(12,e.value+e.unit);}var En={};b(En,{generate:()=>Ru,name:()=>Nu,parse:()=>Tn,structure:()=>Mu,walkContext:()=>zu});var Nu="Function",zu="function",Mu={name:String,children:[[]]};function Tn(e,t){let r=this.tokenStart,n=this.consumeFunctionName(),o=n.toLowerCase(),i;return i=t.hasOwnProperty(o)?t[o].call(this,t):e.call(this,t),this.eof||this.eat(22),{type:"Function",loc:this.getLocation(r,this.tokenStart),name:n,children:i}}function Ru(e){this.token(2,e.name+"("),this.children(e),this.token(22,")");}var Pn={};b(Pn,{generate:()=>Uu,name:()=>Bu,parse:()=>Ln,structure:()=>_u,xxx:()=>Fu});var Fu="XXX",Bu="Hash",_u={value:String};function Ln(){let e=this.tokenStart;return this.eat(4),{type:"Hash",loc:this.getLocation(e,this.tokenStart),value:this.substrToCursor(e+1)}}function Uu(e){this.token(4,"#"+e.value);}var Dn={};b(Dn,{generate:()=>Wu,name:()=>ju,parse:()=>In,structure:()=>qu});var ju="Identifier",qu={name:String};function In(){return {type:"Identifier",loc:this.getLocation(this.tokenStart,this.tokenEnd),name:this.consume(1)}}function Wu(e){this.token(1,e.name);}var Nn={};b(Nn,{generate:()=>Gu,name:()=>Hu,parse:()=>On,structure:()=>Yu});var Hu="IdSelector",Yu={name:String};function On(){let e=this.tokenStart;return this.eat(4),{type:"IdSelector",loc:this.getLocation(e,this.tokenStart),name:this.substrToCursor(e+1)}}function Gu(e){this.token(9,"#"+e.name);}var Mn={};b(Mn,{generate:()=>Qu,name:()=>Vu,parse:()=>zn,structure:()=>Ku});var Vu="MediaFeature",Ku={name:String,value:["Identifier","Number","Dimension","Ratio",null]};function zn(){let e=this.tokenStart,t,r=null;if(this.eat(21),this.skipSC(),t=this.consume(1),this.skipSC(),this.tokenType!==22){switch(this.eat(16),this.skipSC(),this.tokenType){case 10:this.lookupNonWSType(1)===9?r=this.Ratio():r=this.Number();break;case 12:r=this.Dimension();break;case 1:r=this.Identifier();break;default:this.error("Number, dimension, ratio or identifier is expected");}this.skipSC();}return this.eat(22),{type:"MediaFeature",loc:this.getLocation(e,this.tokenStart),name:t,value:r}}function Qu(e){this.token(21,"("),this.token(1,e.name),e.value!==null&&(this.token(16,":"),this.node(e.value)),this.token(22,")");}var Fn={};b(Fn,{generate:()=>Zu,name:()=>Xu,parse:()=>Rn,structure:()=>$u});var Xu="MediaQuery",$u={children:[["Identifier","MediaFeature","WhiteSpace"]]};function Rn(){let e=this.createList(),t=null;this.skipSC();e:for(;!this.eof;){switch(this.tokenType){case 25:case 13:this.next();continue;case 1:t=this.Identifier();break;case 21:t=this.MediaFeature();break;default:break e}e.push(t);}return t===null&&this.error("Identifier or parenthesis is expected"),{type:"MediaQuery",loc:this.getLocationFromList(e),children:e}}function Zu(e){this.children(e);}var _n={};b(_n,{generate:()=>tp,name:()=>Ju,parse:()=>Bn,structure:()=>ep});var Ju="MediaQueryList",ep={children:[["MediaQuery"]]};function Bn(){let e=this.createList();for(this.skipSC();!this.eof&&(e.push(this.MediaQuery()),this.tokenType===18);)this.next();return {type:"MediaQueryList",loc:this.getLocationFromList(e),children:e}}function tp(e){this.children(e,()=>this.token(18,","));}var jn={};b(jn,{generate:()=>ip,name:()=>np,parse:()=>Un,structure:()=>op});var rp=38,np="NestingSelector",op={};function Un(){let e=this.tokenStart;return this.eatDelim(rp),{type:"NestingSelector",loc:this.getLocation(e,this.tokenStart)}}function ip(){this.token(9,"&");}var Wn={};b(Wn,{generate:()=>lp,name:()=>ap,parse:()=>qn,structure:()=>sp});var ap="Nth",sp={nth:["AnPlusB","Identifier"],selector:["SelectorList",null]};function qn(){this.skipSC();let e=this.tokenStart,t=e,r=null,n;return this.lookupValue(0,"odd")||this.lookupValue(0,"even")?n=this.Identifier():n=this.AnPlusB(),t=this.tokenStart,this.skipSC(),this.lookupValue(0,"of")&&(this.next(),r=this.SelectorList(),t=this.tokenStart),{type:"Nth",loc:this.getLocation(e,t),nth:n,selector:r}}function lp(e){this.node(e.nth),e.selector!==null&&(this.token(1,"of"),this.node(e.selector));}var Yn={};b(Yn,{generate:()=>pp,name:()=>cp,parse:()=>Hn,structure:()=>up});var cp="Number",up={value:String};function Hn(){return {type:"Number",loc:this.getLocation(this.tokenStart,this.tokenEnd),value:this.consume(10)}}function pp(e){this.token(10,e.value);}var Vn={};b(Vn,{generate:()=>fp,name:()=>hp,parse:()=>Gn,structure:()=>mp});var hp="Operator",mp={value:String};function Gn(){let e=this.tokenStart;return this.next(),{type:"Operator",loc:this.getLocation(e,this.tokenStart),value:this.substrToCursor(e)}}function fp(e){this.tokenize(e.value);}var Qn={};b(Qn,{generate:()=>bp,name:()=>dp,parse:()=>Kn,structure:()=>gp});var dp="Parentheses",gp={children:[[]]};function Kn(e,t){let r=this.tokenStart,n=null;return this.eat(21),n=e.call(this,t),this.eof||this.eat(22),{type:"Parentheses",loc:this.getLocation(r,this.tokenStart),children:n}}function bp(e){this.token(21,"("),this.children(e),this.token(22,")");}var $n={};b($n,{generate:()=>kp,name:()=>xp,parse:()=>Xn,structure:()=>yp});var xp="Percentage",yp={value:String};function Xn(){return {type:"Percentage",loc:this.getLocation(this.tokenStart,this.tokenEnd),value:this.consumeNumber(11)}}function kp(e){this.token(11,e.value+"%");}var Jn={};b(Jn,{generate:()=>Cp,name:()=>wp,parse:()=>Zn,structure:()=>Sp,walkContext:()=>vp});var wp="PseudoClassSelector",vp="function",Sp={name:String,children:[["Raw"],null]};function Zn(){let e=this.tokenStart,t=null,r,n;return this.eat(16),this.tokenType===2?(r=this.consumeFunctionName(),n=r.toLowerCase(),this.lookupNonWSType(0)==22?t=this.createList():hasOwnProperty.call(this.pseudo,n)?(this.skipSC(),t=this.pseudo[n].call(this),this.skipSC()):(t=this.createList(),t.push(this.Raw(this.tokenIndex,null,!1))),this.eat(22)):r=this.consume(1),{type:"PseudoClassSelector",loc:this.getLocation(e,this.tokenStart),name:r,children:t}}function Cp(e){this.token(16,":"),e.children===null?this.token(1,e.name):(this.token(2,e.name+"("),this.children(e),this.token(22,")"));}var to={};b(to,{generate:()=>Lp,name:()=>Ap,parse:()=>eo,structure:()=>Ep,walkContext:()=>Tp});var Ap="PseudoElementSelector",Tp="function",Ep={name:String,children:[["Raw"],null]};function eo(){let e=this.tokenStart,t=null,r,n;return this.eat(16),this.eat(16),this.tokenType===2?(r=this.consumeFunctionName(),n=r.toLowerCase(),this.lookupNonWSType(0)==22?t=this.createList():hasOwnProperty.call(this.pseudo,n)?(this.skipSC(),t=this.pseudo[n].call(this),this.skipSC()):(t=this.createList(),t.push(this.Raw(this.tokenIndex,null,!1))),this.eat(22)):r=this.consume(1),{type:"PseudoElementSelector",loc:this.getLocation(e,this.tokenStart),name:r,children:t}}function Lp(e){this.token(16,":"),this.token(16,":"),e.children===null?this.token(1,e.name):(this.token(2,e.name+"("),this.children(e),this.token(22,")"));}var no={};b(no,{generate:()=>Np,name:()=>Dp,parse:()=>ro,structure:()=>Op});var Pp=47,Ip=46;function Sa(){this.skipSC();let e=this.consume(10);for(let t=0;t<e.length;t++){let r=e.charCodeAt(t);!B(r)&&r!==Ip&&this.error("Unsigned number is expected",this.tokenStart-e.length+t);}return Number(e)===0&&this.error("Zero number is not allowed",this.tokenStart-e.length),e}var Dp="Ratio",Op={left:String,right:String};function ro(){let e=this.tokenStart,t=Sa.call(this),r;return this.skipSC(),this.eatDelim(Pp),r=Sa.call(this),{type:"Ratio",loc:this.getLocation(e,this.tokenStart),left:t,right:r}}function Np(e){this.token(10,e.left),this.token(9,"/"),this.token(10,e.right);}var io={};b(io,{generate:()=>Fp,name:()=>Mp,parse:()=>oo,structure:()=>Rp});function zp(){return this.tokenIndex>0&&this.lookupType(-1)===13?this.tokenIndex>1?this.getTokenStart(this.tokenIndex-1):this.firstCharOffset:this.tokenStart}var Mp="Raw",Rp={value:String};function oo(e,t,r){let n=this.getTokenStart(e),o;return this.skipUntilBalanced(e,t||this.consumeUntilBalanceEnd),r&&this.tokenStart>n?o=zp.call(this):o=this.tokenStart,{type:"Raw",loc:this.getLocation(n,o),value:this.substring(n,o)}}function Fp(e){this.tokenize(e.value);}var so={};b(so,{generate:()=>qp,name:()=>_p,parse:()=>ao,structure:()=>jp,walkContext:()=>Up});function Ca(e){return this.Raw(e,this.consumeUntilLeftCurlyBracket,!0)}function Bp(){let e=this.SelectorList();return e.type!=="Raw"&&this.eof===!1&&this.tokenType!==23&&this.error(),e}var _p="Rule",Up="rule",jp={prelude:["SelectorList","Raw"],block:["Block"]};function ao(){let e=this.tokenIndex,t=this.tokenStart,r,n;return this.parseRulePrelude?r=this.parseWithFallback(Bp,Ca):r=Ca.call(this,e),n=this.Block(!0),{type:"Rule",loc:this.getLocation(t,this.tokenStart),prelude:r,block:n}}function qp(e){this.node(e.prelude),this.node(e.block);}var co={};b(co,{generate:()=>Yp,name:()=>Wp,parse:()=>lo,structure:()=>Hp});var Wp="Selector",Hp={children:[["TypeSelector","IdSelector","ClassSelector","AttributeSelector","PseudoClassSelector","PseudoElementSelector","Combinator","WhiteSpace"]]};function lo(){let e=this.readSequence(this.scope.Selector);return this.getFirstListNode(e)===null&&this.error("Selector is expected"),{type:"Selector",loc:this.getLocationFromList(e),children:e}}function Yp(e){this.children(e);}var po={};b(po,{generate:()=>Qp,name:()=>Gp,parse:()=>uo,structure:()=>Kp,walkContext:()=>Vp});var Gp="SelectorList",Vp="selector",Kp={children:[["Selector","Raw"]]};function uo(){let e=this.createList();for(;!this.eof;){if(e.push(this.Selector()),this.tokenType===18){this.next();continue}break}return {type:"SelectorList",loc:this.getLocationFromList(e),children:e}}function Qp(e){this.children(e,()=>this.token(18,","));}var bo={};b(bo,{generate:()=>Zp,name:()=>Xp,parse:()=>go,structure:()=>$p});var fo={};b(fo,{decode:()=>ft,encode:()=>mo});var ho=92,Aa=34,Ta=39;function ft(e){let t=e.length,r=e.charCodeAt(0),n=r===Aa||r===Ta?1:0,o=n===1&&t>1&&e.charCodeAt(t-1)===r?t-2:t-1,i="";for(let s=n;s<=o;s++){let u=e.charCodeAt(s);if(u===ho){if(s===o){s!==t-1&&(i=e.substr(s+1));break}if(u=e.charCodeAt(++s),$(ho,u)){let c=s-1,a=se(e,c);s=a-1,i+=Re(e.substring(c+1,a));}else u===13&&e.charCodeAt(s+1)===10&&s++;}else i+=e[s];}return i}function mo(e,t){let r=t?"'":'"',n=t?Ta:Aa,o="",i=!1;for(let s=0;s<e.length;s++){let u=e.charCodeAt(s);if(u===0){o+="\uFFFD";continue}if(u<=31||u===127){o+="\\"+u.toString(16),i=!0;continue}u===n||u===ho?(o+="\\"+e.charAt(s),i=!1):(i&&(ee(u)||pe(u))&&(o+=" "),o+=e.charAt(s),i=!1);}return r+o+r}var Xp="String",$p={value:String};function go(){return {type:"String",loc:this.getLocation(this.tokenStart,this.tokenEnd),value:ft(this.consume(5))}}function Zp(e){this.token(5,mo(e.value));}var yo={};b(yo,{generate:()=>nh,name:()=>eh,parse:()=>xo,structure:()=>rh,walkContext:()=>th});var Jp=33;function Ea(e){return this.Raw(e,null,!1)}var eh="StyleSheet",th="stylesheet",rh={children:[["Comment","CDO","CDC","Atrule","Rule","Raw"]]};function xo(){let e=this.tokenStart,t=this.createList(),r;for(;!this.eof;){switch(this.tokenType){case 13:this.next();continue;case 25:if(this.charCodeAt(this.tokenStart+2)!==Jp){this.next();continue}r=this.Comment();break;case 14:r=this.CDO();break;case 15:r=this.CDC();break;case 3:r=this.parseWithFallback(this.Atrule,Ea);break;default:r=this.parseWithFallback(this.Rule,Ea);}t.push(r);}return {type:"StyleSheet",loc:this.getLocation(e,this.tokenStart),children:t}}function nh(e){this.children(e);}var vo={};b(vo,{generate:()=>sh,name:()=>ih,parse:()=>wo,structure:()=>ah});var oh=42,La=124;function ko(){this.tokenType!==1&&this.isDelim(oh)===!1&&this.error("Identifier or asterisk is expected"),this.next();}var ih="TypeSelector",ah={name:String};function wo(){let e=this.tokenStart;return this.isDelim(La)?(this.next(),ko.call(this)):(ko.call(this),this.isDelim(La)&&(this.next(),ko.call(this))),{type:"TypeSelector",loc:this.getLocation(e,this.tokenStart),name:this.substrToCursor(e)}}function sh(e){this.tokenize(e.name);}var Ao={};b(Ao,{generate:()=>hh,name:()=>uh,parse:()=>Co,structure:()=>ph});var Pa=43,Ia=45,So=63;function dt(e,t){let r=0;for(let n=this.tokenStart+e;n<this.tokenEnd;n++){let o=this.charCodeAt(n);if(o===Ia&&t&&r!==0)return dt.call(this,e+r+1,!1),-1;ee(o)||this.error(t&&r!==0?"Hyphen minus"+(r<6?" or hex digit":"")+" is expected":r<6?"Hex digit is expected":"Unexpected input",n),++r>6&&this.error("Too many hex digits",n);}return this.next(),r}function Jt(e){let t=0;for(;this.isDelim(So);)++t>e&&this.error("Too many question marks"),this.next();}function lh(e){this.charCodeAt(this.tokenStart)!==e&&this.error((e===Pa?"Plus sign":"Hyphen minus")+" is expected");}function ch(){let e=0;switch(this.tokenType){case 10:if(e=dt.call(this,1,!0),this.isDelim(So)){Jt.call(this,6-e);break}if(this.tokenType===12||this.tokenType===10){lh.call(this,Ia),dt.call(this,1,!1);break}break;case 12:e=dt.call(this,1,!0),e>0&&Jt.call(this,6-e);break;default:if(this.eatDelim(Pa),this.tokenType===1){e=dt.call(this,0,!0),e>0&&Jt.call(this,6-e);break}if(this.isDelim(So)){this.next(),Jt.call(this,5);break}this.error("Hex digit or question mark is expected");}}var uh="UnicodeRange",ph={value:String};function Co(){let e=this.tokenStart;return this.eatIdent("u"),ch.call(this),{type:"UnicodeRange",loc:this.getLocation(e,this.tokenStart),value:this.substrToCursor(e)}}function hh(e){this.tokenize(e.value);}var Do={};b(Do,{generate:()=>yh,name:()=>bh,parse:()=>Io,structure:()=>xh});var Po={};b(Po,{decode:()=>Eo,encode:()=>Lo});var mh=32,To=92,fh=34,dh=39,gh=40,Da=41;function Eo(e){let t=e.length,r=4,n=e.charCodeAt(t-1)===Da?t-2:t-1,o="";for(;r<n&&pe(e.charCodeAt(r));)r++;for(;r<n&&pe(e.charCodeAt(n));)n--;for(let i=r;i<=n;i++){let s=e.charCodeAt(i);if(s===To){if(i===n){i!==t-1&&(o=e.substr(i+1));break}if(s=e.charCodeAt(++i),$(To,s)){let u=i-1,c=se(e,u);i=c-1,o+=Re(e.substring(u+1,c));}else s===13&&e.charCodeAt(i+1)===10&&i++;}else o+=e[i];}return o}function Lo(e){let t="",r=!1;for(let n=0;n<e.length;n++){let o=e.charCodeAt(n);if(o===0){t+="\uFFFD";continue}if(o<=31||o===127){t+="\\"+o.toString(16),r=!0;continue}o===mh||o===To||o===fh||o===dh||o===gh||o===Da?(t+="\\"+e.charAt(n),r=!1):(r&&ee(o)&&(t+=" "),t+=e.charAt(n),r=!1);}return "url("+t+")"}var bh="Url",xh={value:String};function Io(){let e=this.tokenStart,t;switch(this.tokenType){case 7:t=Eo(this.consume(7));break;case 2:this.cmpStr(this.tokenStart,this.tokenEnd,"url(")||this.error("Function name must be `url`"),this.eat(2),this.skipSC(),t=ft(this.consume(5)),this.skipSC(),this.eof||this.eat(22);break;default:this.error("Url or Function is expected");}return {type:"Url",loc:this.getLocation(e,this.tokenStart),value:t}}function yh(e){this.token(7,Lo(e.value));}var No={};b(No,{generate:()=>vh,name:()=>kh,parse:()=>Oo,structure:()=>wh});var kh="Value",wh={children:[[]]};function Oo(){let e=this.tokenStart,t=this.readSequence(this.scope.Value);return {type:"Value",loc:this.getLocation(e,this.tokenStart),children:t}}function vh(e){this.children(e);}var Mo={};b(Mo,{generate:()=>Th,name:()=>Ch,parse:()=>zo,structure:()=>Ah});var Sh=Object.freeze({type:"WhiteSpace",loc:null,value:" "}),Ch="WhiteSpace",Ah={value:String};function zo(){return this.eat(13),Sh}function Th(e){this.token(13,e.value);}var Oa={generic:!0,...fa,node:gt};var Ro={};b(Ro,{AtrulePrelude:()=>za,Selector:()=>Ra,Value:()=>Ua});var Eh=35,Lh=42,Na=43,Ph=45,Ih=47,Dh=117;function bt(e){switch(this.tokenType){case 4:return this.Hash();case 18:return this.Operator();case 21:return this.Parentheses(this.readSequence,e.recognizer);case 19:return this.Brackets(this.readSequence,e.recognizer);case 5:return this.String();case 12:return this.Dimension();case 11:return this.Percentage();case 10:return this.Number();case 2:return this.cmpStr(this.tokenStart,this.tokenEnd,"url(")?this.Url():this.Function(this.readSequence,e.recognizer);case 7:return this.Url();case 1:return this.cmpChar(this.tokenStart,Dh)&&this.cmpChar(this.tokenStart+1,Na)?this.UnicodeRange():this.Identifier();case 9:{let t=this.charCodeAt(this.tokenStart);if(t===Ih||t===Lh||t===Na||t===Ph)return this.Operator();t===Eh&&this.error("Hex or identifier is expected",this.tokenStart+1);break}}}var za={getNode:bt};var Oh=35,Nh=38,zh=42,Mh=43,Rh=47,Ma=46,Fh=62,Bh=124,_h=126;function Uh(e,t){t.last!==null&&t.last.type!=="Combinator"&&e!==null&&e.type!=="Combinator"&&t.push({type:"Combinator",loc:null,name:" "});}function jh(){switch(this.tokenType){case 19:return this.AttributeSelector();case 4:return this.IdSelector();case 16:return this.lookupType(1)===16?this.PseudoElementSelector():this.PseudoClassSelector();case 1:return this.TypeSelector();case 10:case 11:return this.Percentage();case 12:this.charCodeAt(this.tokenStart)===Ma&&this.error("Identifier is expected",this.tokenStart+1);break;case 9:{switch(this.charCodeAt(this.tokenStart)){case Mh:case Fh:case _h:case Rh:return this.Combinator();case Ma:return this.ClassSelector();case zh:case Bh:return this.TypeSelector();case Oh:return this.IdSelector();case Nh:return this.NestingSelector()}break}}}var Ra={onWhiteSpace:Uh,getNode:jh};function Fa(){return this.createSingleNodeList(this.Raw(this.tokenIndex,null,!1))}function Ba(){let e=this.createList();if(this.skipSC(),e.push(this.Identifier()),this.skipSC(),this.tokenType===18){e.push(this.Operator());let t=this.tokenIndex,r=this.parseCustomProperty?this.Value(null):this.Raw(this.tokenIndex,this.consumeUntilExclamationMarkOrSemicolon,!1);if(r.type==="Value"&&r.children.isEmpty){for(let n=t-this.tokenIndex;n<=0;n++)if(this.lookupType(n)===13){r.children.appendData({type:"WhiteSpace",loc:null,value:" "});break}}e.push(r);}return e}function _a(e){return e!==null&&e.type==="Operator"&&(e.value[e.value.length-1]==="-"||e.value[e.value.length-1]==="+")}var Ua={getNode:bt,onWhiteSpace(e,t){_a(e)&&(e.value=" "+e.value),_a(t.last)&&(t.last.value+=" ");},expression:Fa,var:Ba};var ja={parse:{prelude:null,block(){return this.Block(!0)}}};var qa={parse:{prelude(){let e=this.createList();switch(this.skipSC(),this.tokenType){case 5:e.push(this.String());break;case 7:case 2:e.push(this.Url());break;default:this.error("String or url() is expected");}return (this.lookupNonWSType(0)===1||this.lookupNonWSType(0)===21)&&e.push(this.MediaQueryList()),e},block:null}};var Wa={parse:{prelude(){return this.createSingleNodeList(this.MediaQueryList())},block(e=!1){return this.Block(e)}}};var Ha={parse:{prelude(){return this.createSingleNodeList(this.SelectorList())},block(){return this.Block(!0)}}};var Ya={parse:{prelude(){return this.createSingleNodeList(this.SelectorList())},block(){return this.Block(!0)}}};function qh(){return this.createSingleNodeList(this.Raw(this.tokenIndex,null,!1))}function Wh(){return this.skipSC(),this.tokenType===1&&this.lookupNonWSType(1)===16?this.createSingleNodeList(this.Declaration()):Ga.call(this)}function Ga(){let e=this.createList(),t;this.skipSC();e:for(;!this.eof;){switch(this.tokenType){case 25:case 13:this.next();continue;case 2:t=this.Function(qh,this.scope.AtrulePrelude);break;case 1:t=this.Identifier();break;case 21:t=this.Parentheses(Wh,this.scope.AtrulePrelude);break;default:break e}e.push(t);}return e}var Va={parse:{prelude(){let e=Ga.call(this);return this.getFirstListNode(e)===null&&this.error("Condition is expected"),e},block(e=!1){return this.Block(e)}}};var Ka={"font-face":ja,import:qa,media:Wa,nest:Ha,page:Ya,supports:Va};var De={parse(){return this.createSingleNodeList(this.SelectorList())}},Fo={parse(){return this.createSingleNodeList(this.Selector())}},Qa={parse(){return this.createSingleNodeList(this.Identifier())}},er={parse(){return this.createSingleNodeList(this.Nth())}},Xa={dir:Qa,has:De,lang:Qa,matches:De,is:De,"-moz-any":De,"-webkit-any":De,where:De,not:De,"nth-child":er,"nth-last-child":er,"nth-last-of-type":er,"nth-of-type":er,slotted:Fo,host:Fo,"host-context":Fo};var Bo={};b(Bo,{AnPlusB:()=>Qr,Atrule:()=>$r,AtrulePrelude:()=>Jr,AttributeSelector:()=>rn,Block:()=>on,Brackets:()=>sn,CDC:()=>cn,CDO:()=>pn,ClassSelector:()=>mn,Combinator:()=>dn,Comment:()=>bn,Declaration:()=>yn,DeclarationList:()=>vn,Dimension:()=>Cn,Function:()=>Tn,Hash:()=>Ln,IdSelector:()=>On,Identifier:()=>In,MediaFeature:()=>zn,MediaQuery:()=>Rn,MediaQueryList:()=>Bn,NestingSelector:()=>Un,Nth:()=>qn,Number:()=>Hn,Operator:()=>Gn,Parentheses:()=>Kn,Percentage:()=>Xn,PseudoClassSelector:()=>Zn,PseudoElementSelector:()=>eo,Ratio:()=>ro,Raw:()=>oo,Rule:()=>ao,Selector:()=>lo,SelectorList:()=>uo,String:()=>go,StyleSheet:()=>xo,TypeSelector:()=>wo,UnicodeRange:()=>Co,Url:()=>Io,Value:()=>Oo,WhiteSpace:()=>zo});var $a={parseContext:{default:"StyleSheet",stylesheet:"StyleSheet",atrule:"Atrule",atrulePrelude(e){return this.AtrulePrelude(e.atrule?String(e.atrule):null)},mediaQueryList:"MediaQueryList",mediaQuery:"MediaQuery",rule:"Rule",selectorList:"SelectorList",selector:"Selector",block(){return this.Block(!0)},declarationList:"DeclarationList",declaration:"Declaration",value:"Value"},scope:Ro,atrule:Ka,pseudo:Xa,node:Bo};var Za={node:gt};var Ja=Vr({...Oa,...$a,...Za});var lb="2.3.1";function _o(e){let t={};for(let r in e){let n=e[r];n&&(Array.isArray(n)||n instanceof D?n=n.map(_o):n.constructor===Object&&(n=_o(n))),t[r]=n;}return t}var ts={};b(ts,{decode:()=>Hh,encode:()=>Yh});var es=92;function Hh(e){let t=e.length-1,r="";for(let n=0;n<e.length;n++){let o=e.charCodeAt(n);if(o===es){if(n===t)break;if(o=e.charCodeAt(++n),$(es,o)){let i=n-1,s=se(e,i);n=s-1,r+=Re(e.substring(i+1,s));}else o===13&&e.charCodeAt(n+1)===10&&n++;}else r+=e[n];}return r}function Yh(e){let t="";if(e.length===1&&e.charCodeAt(0)===45)return "\\-";for(let r=0;r<e.length;r++){let n=e.charCodeAt(r);if(n===0){t+="\uFFFD";continue}if(n<=31||n===127||n>=48&&n<=57&&(r===0||r===1&&e.charCodeAt(0)===45)){t+="\\"+n.toString(16)+" ";continue}Ne(n)?t+=e.charAt(r):t+="\\"+e.charAt(r);}return t}var{tokenize:fb,parse:db,generate:gb,lexer:bb,createLexer:xb,walk:yb,find:kb,findLast:wb,findAll:vb,toPlainObject:Sb,fromPlainObject:Cb,fork:Ab}=Ja;
  6715. var cssTree$1 = /*#__PURE__*/Object.freeze({
  6716. __proto__: null,
  6717. Lexer: Ke,
  6718. List: D,
  6719. TokenStream: rt,
  6720. clone: _o,
  6721. createLexer: xb,
  6722. createSyntax: Vr,
  6723. definitionSyntax: $i,
  6724. find: kb,
  6725. findAll: vb,
  6726. findLast: wb,
  6727. fork: Ab,
  6728. fromPlainObject: Cb,
  6729. generate: gb,
  6730. ident: ts,
  6731. isCustomProperty: Mt,
  6732. keyword: zt,
  6733. lexer: bb,
  6734. parse: db,
  6735. property: kr,
  6736. string: fo,
  6737. toPlainObject: Sb,
  6738. tokenNames: Fe,
  6739. tokenTypes: $e,
  6740. tokenize: fb,
  6741. url: Po,
  6742. vendorPrefix: Ym,
  6743. version: lb,
  6744. walk: yb
  6745. });
  6746. /*
  6747. * The MIT License (MIT)
  6748. *
  6749. * Author: Gildas Lormeau
  6750. *
  6751. * Permission is hereby granted, free of charge, to any person obtaining a copy
  6752. * of this software and associated documentation files (the "Software"), to deal
  6753. * in the Software without restriction, including without limitation the rights
  6754. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  6755. * copies of the Software, and to permit persons to whom the Software is
  6756. * furnished to do so, subject to the following conditions:
  6757. *
  6758. * The above copyright notice and this permission notice shall be included in all
  6759. * copies or substantial portions of the Software.
  6760. *
  6761. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  6762. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  6763. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  6764. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  6765. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  6766. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  6767. * SOFTWARE.
  6768. */
  6769. const REGEXP_SIMPLE_QUOTES_STRING$2 = /^'(.*?)'$/;
  6770. const REGEXP_DOUBLE_QUOTES_STRING$2 = /^"(.*?)"$/;
  6771. const globalKeywords = [
  6772. "inherit",
  6773. "initial",
  6774. "unset"
  6775. ];
  6776. const systemFontKeywords = [
  6777. "caption",
  6778. "icon",
  6779. "menu",
  6780. "message-box",
  6781. "small-caption",
  6782. "status-bar"
  6783. ];
  6784. const fontWeightKeywords = [
  6785. "normal",
  6786. "bold",
  6787. "bolder",
  6788. "lighter",
  6789. "100",
  6790. "200",
  6791. "300",
  6792. "400",
  6793. "500",
  6794. "600",
  6795. "700",
  6796. "800",
  6797. "900"
  6798. ];
  6799. const fontStyleKeywords = [
  6800. "normal",
  6801. "italic",
  6802. "oblique"
  6803. ];
  6804. const fontStretchKeywords = [
  6805. "normal",
  6806. "condensed",
  6807. "semi-condensed",
  6808. "extra-condensed",
  6809. "ultra-condensed",
  6810. "expanded",
  6811. "semi-expanded",
  6812. "extra-expanded",
  6813. "ultra-expanded"
  6814. ];
  6815. const errorPrefix = "[parse-css-font] ";
  6816. function parse(value) {
  6817. const stringValue = gb(value);
  6818. if (systemFontKeywords.indexOf(stringValue) !== -1) {
  6819. return { system: stringValue };
  6820. }
  6821. const tokens = value.children;
  6822. const font = {
  6823. lineHeight: "normal",
  6824. stretch: "normal",
  6825. style: "normal",
  6826. variant: "normal",
  6827. weight: "normal",
  6828. };
  6829. let isLocked = false;
  6830. for (let tokenNode = tokens.head; tokenNode; tokenNode = tokenNode.next) {
  6831. const token = gb(tokenNode.data);
  6832. if (token === "normal" || globalKeywords.indexOf(token) !== -1) {
  6833. ["style", "variant", "weight", "stretch"].forEach((prop) => {
  6834. font[prop] = token;
  6835. });
  6836. isLocked = true;
  6837. continue;
  6838. }
  6839. if (fontWeightKeywords.indexOf(token) !== -1) {
  6840. if (isLocked) {
  6841. continue;
  6842. }
  6843. font.weight = token;
  6844. continue;
  6845. }
  6846. if (fontStyleKeywords.indexOf(token) !== -1) {
  6847. if (isLocked) {
  6848. continue;
  6849. }
  6850. font.style = token;
  6851. continue;
  6852. }
  6853. if (fontStretchKeywords.indexOf(token) !== -1) {
  6854. if (isLocked) {
  6855. continue;
  6856. }
  6857. font.stretch = token;
  6858. continue;
  6859. }
  6860. if (tokenNode.data.type == "Dimension") {
  6861. font.size = gb(tokenNode.data);
  6862. tokenNode = tokenNode.next;
  6863. if (tokenNode && tokenNode.data.type == "Operator" && tokenNode.data.value == "/" && tokenNode.next) {
  6864. tokenNode = tokenNode.next;
  6865. font.lineHeight = gb(tokenNode.data);
  6866. tokenNode = tokenNode.next;
  6867. } else if (tokens.head.data.type == "Operator" && tokens.head.data.value == "/" && tokens.head.next) {
  6868. font.lineHeight = gb(tokens.head.next.data);
  6869. tokenNode = tokens.head.next.next;
  6870. }
  6871. if (!tokenNode) {
  6872. throw error("Missing required font-family.");
  6873. }
  6874. font.family = [];
  6875. let familyName = "";
  6876. while (tokenNode) {
  6877. while (tokenNode && tokenNode.data.type == "Operator" && tokenNode.data.value == ",") {
  6878. tokenNode = tokenNode.next;
  6879. }
  6880. if (tokenNode) {
  6881. if (tokenNode.data.type == "Identifier") {
  6882. while (tokenNode && tokenNode.data.type == "Identifier") {
  6883. familyName += " " + gb(tokenNode.data);
  6884. tokenNode = tokenNode.next;
  6885. }
  6886. } else {
  6887. familyName = removeQuotes(gb(tokenNode.data));
  6888. tokenNode = tokenNode.next;
  6889. }
  6890. }
  6891. familyName = familyName.trim();
  6892. if (familyName) {
  6893. font.family.push(familyName);
  6894. familyName = "";
  6895. }
  6896. }
  6897. return font;
  6898. }
  6899. if (font.variant !== "normal") {
  6900. throw error("Unknown or unsupported font token: " + font.variant);
  6901. }
  6902. if (isLocked) {
  6903. continue;
  6904. }
  6905. font.variant = token;
  6906. }
  6907. throw error("Missing required font-size.");
  6908. }
  6909. function error(message) {
  6910. return new Error(errorPrefix + message);
  6911. }
  6912. function removeQuotes(string) {
  6913. if (string.match(REGEXP_SIMPLE_QUOTES_STRING$2)) {
  6914. string = string.replace(REGEXP_SIMPLE_QUOTES_STRING$2, "$1");
  6915. } else {
  6916. string = string.replace(REGEXP_DOUBLE_QUOTES_STRING$2, "$1");
  6917. }
  6918. return string.trim();
  6919. }
  6920. var cssFontPropertyParser = /*#__PURE__*/Object.freeze({
  6921. __proto__: null,
  6922. parse: parse
  6923. });
  6924. /*
  6925. * The MIT License (MIT)
  6926. *
  6927. * Author: Gildas Lormeau
  6928. *
  6929. * Permission is hereby granted, free of charge, to any person obtaining a copy
  6930. * of this software and associated documentation files (the "Software"), to deal
  6931. * in the Software without restriction, including without limitation the rights
  6932. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  6933. * copies of the Software, and to permit persons to whom the Software is
  6934. * furnished to do so, subject to the following conditions:
  6935. *
  6936. * The above copyright notice and this permission notice shall be included in all
  6937. * copies or substantial portions of the Software.
  6938. *
  6939. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  6940. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  6941. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  6942. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  6943. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  6944. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  6945. * SOFTWARE.
  6946. */
  6947. // derived from https://github.com/dryoma/postcss-media-query-parser
  6948. /*
  6949. * The MIT License (MIT)
  6950. *
  6951. * Permission is hereby granted, free of charge, to any person obtaining a copy
  6952. * of this software and associated documentation files (the "Software"), to deal
  6953. * in the Software without restriction, including without limitation the rights
  6954. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  6955. * copies of the Software, and to permit persons to whom the Software is
  6956. * furnished to do so, subject to the following conditions:
  6957. *
  6958. * The above copyright notice and this permission notice shall be included in
  6959. * all copies or substantial portions of the Software.
  6960. *
  6961. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  6962. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  6963. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  6964. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  6965. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  6966. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  6967. * THE SOFTWARE.
  6968. */
  6969. /**
  6970. * Parses a media feature expression, e.g. `max-width: 10px`, `(color)`
  6971. *
  6972. * @param {string} string - the source expression string, can be inside parens
  6973. * @param {Number} index - the index of `string` in the overall input
  6974. *
  6975. * @return {Array} an array of Nodes, the first element being a media feature,
  6976. * the second - its value (may be missing)
  6977. */
  6978. function parseMediaFeature(string, index = 0) {
  6979. const modesEntered = [{
  6980. mode: "normal",
  6981. character: null,
  6982. }];
  6983. const result = [];
  6984. let lastModeIndex = 0, mediaFeature = "", colon = null, mediaFeatureValue = null, indexLocal = index;
  6985. let stringNormalized = string;
  6986. // Strip trailing parens (if any), and correct the starting index
  6987. if (string[0] === "(" && string[string.length - 1] === ")") {
  6988. stringNormalized = string.substring(1, string.length - 1);
  6989. indexLocal++;
  6990. }
  6991. for (let i = 0; i < stringNormalized.length; i++) {
  6992. const character = stringNormalized[i];
  6993. // If entering/exiting a string
  6994. if (character === "'" || character === "\"") {
  6995. if (modesEntered[lastModeIndex].isCalculationEnabled === true) {
  6996. modesEntered.push({
  6997. mode: "string",
  6998. isCalculationEnabled: false,
  6999. character,
  7000. });
  7001. lastModeIndex++;
  7002. } else if (modesEntered[lastModeIndex].mode === "string" &&
  7003. modesEntered[lastModeIndex].character === character &&
  7004. stringNormalized[i - 1] !== "\\"
  7005. ) {
  7006. modesEntered.pop();
  7007. lastModeIndex--;
  7008. }
  7009. }
  7010. // If entering/exiting interpolation
  7011. if (character === "{") {
  7012. modesEntered.push({
  7013. mode: "interpolation",
  7014. isCalculationEnabled: true,
  7015. });
  7016. lastModeIndex++;
  7017. } else if (character === "}") {
  7018. modesEntered.pop();
  7019. lastModeIndex--;
  7020. }
  7021. // If a : is met outside of a string, function call or interpolation, than
  7022. // this : separates a media feature and a value
  7023. if (modesEntered[lastModeIndex].mode === "normal" && character === ":") {
  7024. const mediaFeatureValueStr = stringNormalized.substring(i + 1);
  7025. mediaFeatureValue = {
  7026. type: "value",
  7027. before: /^(\s*)/.exec(mediaFeatureValueStr)[1],
  7028. after: /(\s*)$/.exec(mediaFeatureValueStr)[1],
  7029. value: mediaFeatureValueStr.trim(),
  7030. };
  7031. // +1 for the colon
  7032. mediaFeatureValue.sourceIndex =
  7033. mediaFeatureValue.before.length + i + 1 + indexLocal;
  7034. colon = {
  7035. type: "colon",
  7036. sourceIndex: i + indexLocal,
  7037. after: mediaFeatureValue.before,
  7038. value: ":", // for consistency only
  7039. };
  7040. break;
  7041. }
  7042. mediaFeature += character;
  7043. }
  7044. // Forming a media feature node
  7045. mediaFeature = {
  7046. type: "media-feature",
  7047. before: /^(\s*)/.exec(mediaFeature)[1],
  7048. after: /(\s*)$/.exec(mediaFeature)[1],
  7049. value: mediaFeature.trim(),
  7050. };
  7051. mediaFeature.sourceIndex = mediaFeature.before.length + indexLocal;
  7052. result.push(mediaFeature);
  7053. if (colon !== null) {
  7054. colon.before = mediaFeature.after;
  7055. result.push(colon);
  7056. }
  7057. if (mediaFeatureValue !== null) {
  7058. result.push(mediaFeatureValue);
  7059. }
  7060. return result;
  7061. }
  7062. /**
  7063. * Parses a media query, e.g. `screen and (color)`, `only tv`
  7064. *
  7065. * @param {string} string - the source media query string
  7066. * @param {Number} index - the index of `string` in the overall input
  7067. *
  7068. * @return {Array} an array of Nodes and Containers
  7069. */
  7070. function parseMediaQuery(string, index = 0) {
  7071. const result = [];
  7072. // How many times the parser entered parens/curly braces
  7073. let localLevel = 0;
  7074. // Has any keyword, media type, media feature expression or interpolation
  7075. // ('element' hereafter) started
  7076. let insideSomeValue = false, node;
  7077. function resetNode() {
  7078. return {
  7079. before: "",
  7080. after: "",
  7081. value: "",
  7082. };
  7083. }
  7084. node = resetNode();
  7085. for (let i = 0; i < string.length; i++) {
  7086. const character = string[i];
  7087. // If not yet entered any element
  7088. if (!insideSomeValue) {
  7089. if (character.search(/\s/) !== -1) {
  7090. // A whitespace
  7091. // Don't form 'after' yet; will do it later
  7092. node.before += character;
  7093. } else {
  7094. // Not a whitespace - entering an element
  7095. // Expression start
  7096. if (character === "(") {
  7097. node.type = "media-feature-expression";
  7098. localLevel++;
  7099. }
  7100. node.value = character;
  7101. node.sourceIndex = index + i;
  7102. insideSomeValue = true;
  7103. }
  7104. } else {
  7105. // Already in the middle of some element
  7106. node.value += character;
  7107. // Here parens just increase localLevel and don't trigger a start of
  7108. // a media feature expression (since they can't be nested)
  7109. // Interpolation start
  7110. if (character === "{" || character === "(") { localLevel++; }
  7111. // Interpolation/function call/media feature expression end
  7112. if (character === ")" || character === "}") { localLevel--; }
  7113. }
  7114. // If exited all parens/curlies and the next symbol
  7115. if (insideSomeValue && localLevel === 0 &&
  7116. (character === ")" || i === string.length - 1 ||
  7117. string[i + 1].search(/\s/) !== -1)
  7118. ) {
  7119. if (["not", "only", "and"].indexOf(node.value) !== -1) {
  7120. node.type = "keyword";
  7121. }
  7122. // if it's an expression, parse its contents
  7123. if (node.type === "media-feature-expression") {
  7124. node.nodes = parseMediaFeature(node.value, node.sourceIndex);
  7125. }
  7126. result.push(Array.isArray(node.nodes) ?
  7127. new Container(node) : new Node$1(node));
  7128. node = resetNode();
  7129. insideSomeValue = false;
  7130. }
  7131. }
  7132. // Now process the result array - to specify undefined types of the nodes
  7133. // and specify the `after` prop
  7134. for (let i = 0; i < result.length; i++) {
  7135. node = result[i];
  7136. if (i > 0) { result[i - 1].after = node.before; }
  7137. // Node types. Might not be set because contains interpolation/function
  7138. // calls or fully consists of them
  7139. if (node.type === undefined) {
  7140. if (i > 0) {
  7141. // only `and` can follow an expression
  7142. if (result[i - 1].type === "media-feature-expression") {
  7143. node.type = "keyword";
  7144. continue;
  7145. }
  7146. // Anything after 'only|not' is a media type
  7147. if (result[i - 1].value === "not" || result[i - 1].value === "only") {
  7148. node.type = "media-type";
  7149. continue;
  7150. }
  7151. // Anything after 'and' is an expression
  7152. if (result[i - 1].value === "and") {
  7153. node.type = "media-feature-expression";
  7154. continue;
  7155. }
  7156. if (result[i - 1].type === "media-type") {
  7157. // if it is the last element - it might be an expression
  7158. // or 'and' depending on what is after it
  7159. if (!result[i + 1]) {
  7160. node.type = "media-feature-expression";
  7161. } else {
  7162. node.type = result[i + 1].type === "media-feature-expression" ?
  7163. "keyword" : "media-feature-expression";
  7164. }
  7165. }
  7166. }
  7167. if (i === 0) {
  7168. // `screen`, `fn( ... )`, `#{ ... }`. Not an expression, since then
  7169. // its type would have been set by now
  7170. if (!result[i + 1]) {
  7171. node.type = "media-type";
  7172. continue;
  7173. }
  7174. // `screen and` or `#{...} (max-width: 10px)`
  7175. if (result[i + 1] &&
  7176. (result[i + 1].type === "media-feature-expression" ||
  7177. result[i + 1].type === "keyword")
  7178. ) {
  7179. node.type = "media-type";
  7180. continue;
  7181. }
  7182. if (result[i + 2]) {
  7183. // `screen and (color) ...`
  7184. if (result[i + 2].type === "media-feature-expression") {
  7185. node.type = "media-type";
  7186. result[i + 1].type = "keyword";
  7187. continue;
  7188. }
  7189. // `only screen and ...`
  7190. if (result[i + 2].type === "keyword") {
  7191. node.type = "keyword";
  7192. result[i + 1].type = "media-type";
  7193. continue;
  7194. }
  7195. }
  7196. if (result[i + 3]) {
  7197. // `screen and (color) ...`
  7198. if (result[i + 3].type === "media-feature-expression") {
  7199. node.type = "keyword";
  7200. result[i + 1].type = "media-type";
  7201. result[i + 2].type = "keyword";
  7202. continue;
  7203. }
  7204. }
  7205. }
  7206. }
  7207. }
  7208. return result;
  7209. }
  7210. /**
  7211. * Parses a media query list. Takes a possible `url()` at the start into
  7212. * account, and divides the list into media queries that are parsed separately
  7213. *
  7214. * @param {string} string - the source media query list string
  7215. *
  7216. * @return {Array} an array of Nodes/Containers
  7217. */
  7218. function parseMediaList(string) {
  7219. const result = [];
  7220. let interimIndex = 0, levelLocal = 0;
  7221. // Check for a `url(...)` part (if it is contents of an @import rule)
  7222. const doesHaveUrl = /^(\s*)url\s*\(/.exec(string);
  7223. if (doesHaveUrl !== null) {
  7224. let i = doesHaveUrl[0].length;
  7225. let parenthesesLv = 1;
  7226. while (parenthesesLv > 0) {
  7227. const character = string[i];
  7228. if (character === "(") { parenthesesLv++; }
  7229. if (character === ")") { parenthesesLv--; }
  7230. i++;
  7231. }
  7232. result.unshift(new Node$1({
  7233. type: "url",
  7234. value: string.substring(0, i).trim(),
  7235. sourceIndex: doesHaveUrl[1].length,
  7236. before: doesHaveUrl[1],
  7237. after: /^(\s*)/.exec(string.substring(i))[1],
  7238. }));
  7239. interimIndex = i;
  7240. }
  7241. // Start processing the media query list
  7242. for (let i = interimIndex; i < string.length; i++) {
  7243. const character = string[i];
  7244. // Dividing the media query list into comma-separated media queries
  7245. // Only count commas that are outside of any parens
  7246. // (i.e., not part of function call params list, etc.)
  7247. if (character === "(") { levelLocal++; }
  7248. if (character === ")") { levelLocal--; }
  7249. if (levelLocal === 0 && character === ",") {
  7250. const mediaQueryString = string.substring(interimIndex, i);
  7251. const spaceBefore = /^(\s*)/.exec(mediaQueryString)[1];
  7252. result.push(new Container({
  7253. type: "media-query",
  7254. value: mediaQueryString.trim(),
  7255. sourceIndex: interimIndex + spaceBefore.length,
  7256. nodes: parseMediaQuery(mediaQueryString, interimIndex),
  7257. before: spaceBefore,
  7258. after: /(\s*)$/.exec(mediaQueryString)[1],
  7259. }));
  7260. interimIndex = i + 1;
  7261. }
  7262. }
  7263. const mediaQueryString = string.substring(interimIndex);
  7264. const spaceBefore = /^(\s*)/.exec(mediaQueryString)[1];
  7265. result.push(new Container({
  7266. type: "media-query",
  7267. value: mediaQueryString.trim(),
  7268. sourceIndex: interimIndex + spaceBefore.length,
  7269. nodes: parseMediaQuery(mediaQueryString, interimIndex),
  7270. before: spaceBefore,
  7271. after: /(\s*)$/.exec(mediaQueryString)[1],
  7272. }));
  7273. return result;
  7274. }
  7275. function Container(opts) {
  7276. this.constructor(opts);
  7277. this.nodes = opts.nodes;
  7278. if (this.after === undefined) {
  7279. this.after = this.nodes.length > 0 ?
  7280. this.nodes[this.nodes.length - 1].after : "";
  7281. }
  7282. if (this.before === undefined) {
  7283. this.before = this.nodes.length > 0 ?
  7284. this.nodes[0].before : "";
  7285. }
  7286. if (this.sourceIndex === undefined) {
  7287. this.sourceIndex = this.before.length;
  7288. }
  7289. this.nodes.forEach(node => {
  7290. node.parent = this; // eslint-disable-line no-param-reassign
  7291. });
  7292. }
  7293. Container.prototype = Object.create(Node$1.prototype);
  7294. Container.constructor = Node$1;
  7295. /**
  7296. * Iterate over descendant nodes of the node
  7297. *
  7298. * @param {RegExp|string} filter - Optional. Only nodes with node.type that
  7299. * satisfies the filter will be traversed over
  7300. * @param {function} cb - callback to call on each node. Takes these params:
  7301. * node - the node being processed, i - it's index, nodes - the array
  7302. * of all nodes
  7303. * If false is returned, the iteration breaks
  7304. *
  7305. * @return (boolean) false, if the iteration was broken
  7306. */
  7307. Container.prototype.walk = function walk(filter, cb) {
  7308. const hasFilter = typeof filter === "string" || filter instanceof RegExp;
  7309. const callback = hasFilter ? cb : filter;
  7310. const filterReg = typeof filter === "string" ? new RegExp(filter) : filter;
  7311. for (let i = 0; i < this.nodes.length; i++) {
  7312. const node = this.nodes[i];
  7313. const filtered = hasFilter ? filterReg.test(node.type) : true;
  7314. if (filtered && callback && callback(node, i, this.nodes) === false) {
  7315. return false;
  7316. }
  7317. if (node.nodes && node.walk(filter, cb) === false) { return false; }
  7318. }
  7319. return true;
  7320. };
  7321. /**
  7322. * Iterate over immediate children of the node
  7323. *
  7324. * @param {function} cb - callback to call on each node. Takes these params:
  7325. * node - the node being processed, i - it's index, nodes - the array
  7326. * of all nodes
  7327. * If false is returned, the iteration breaks
  7328. *
  7329. * @return (boolean) false, if the iteration was broken
  7330. */
  7331. Container.prototype.each = function each(cb = () => { }) {
  7332. for (let i = 0; i < this.nodes.length; i++) {
  7333. const node = this.nodes[i];
  7334. if (cb(node, i, this.nodes) === false) { return false; }
  7335. }
  7336. return true;
  7337. };
  7338. /**
  7339. * A very generic node. Pretty much any element of a media query
  7340. */
  7341. function Node$1(opts) {
  7342. this.after = opts.after;
  7343. this.before = opts.before;
  7344. this.type = opts.type;
  7345. this.value = opts.value;
  7346. this.sourceIndex = opts.sourceIndex;
  7347. }
  7348. var cssMediaQueryParser = /*#__PURE__*/Object.freeze({
  7349. __proto__: null,
  7350. parseMediaList: parseMediaList
  7351. });
  7352. /*
  7353. * The MIT License (MIT)
  7354. *
  7355. * Author: Gildas Lormeau
  7356. *
  7357. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7358. * of this software and associated documentation files (the "Software"), to deal
  7359. * in the Software without restriction, including without limitation the rights
  7360. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7361. * copies of the Software, and to permit persons to whom the Software is
  7362. * furnished to do so, subject to the following conditions:
  7363. *
  7364. * The above copyright notice and this permission notice shall be included in all
  7365. * copies or substantial portions of the Software.
  7366. *
  7367. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  7368. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  7369. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  7370. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  7371. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  7372. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  7373. * SOFTWARE.
  7374. */
  7375. // derived from https://github.com/fmarcia/UglifyCSS
  7376. /**
  7377. * UglifyCSS
  7378. * Port of YUI CSS Compressor to NodeJS
  7379. * Author: Franck Marcia - https://github.com/fmarcia
  7380. * MIT licenced
  7381. */
  7382. /**
  7383. * cssmin.js
  7384. * Author: Stoyan Stefanov - http://phpied.com/
  7385. * This is a JavaScript port of the CSS minification tool
  7386. * distributed with YUICompressor, itself a port
  7387. * of the cssmin utility by Isaac Schlueter - http://foohack.com/
  7388. * Permission is hereby granted to use the JavaScript version under the same
  7389. * conditions as the YUICompressor (original YUICompressor note below).
  7390. */
  7391. /**
  7392. * YUI Compressor
  7393. * http://developer.yahoo.com/yui/compressor/
  7394. * Author: Julien Lecomte - http://www.julienlecomte.net/
  7395. * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
  7396. * The copyrights embodied in the content of this file are licensed
  7397. * by Yahoo! Inc. under the BSD (revised) open source license.
  7398. */
  7399. /**
  7400. * @type {string} - placeholder prefix
  7401. */
  7402. const ___PRESERVED_TOKEN_ = "___PRESERVED_TOKEN_";
  7403. /**
  7404. * @typedef {object} options - UglifyCSS options
  7405. * @property {number} [maxLineLen=0] - Maximum line length of uglified CSS
  7406. * @property {boolean} [expandVars=false] - Expand variables
  7407. * @property {boolean} [uglyComments=false] - Removes newlines within preserved comments
  7408. * @property {boolean} [cuteComments=false] - Preserves newlines within and around preserved comments
  7409. * @property {boolean} [debug=false] - Prints full error stack on error
  7410. * @property {string} [output=''] - Output file name
  7411. */
  7412. /**
  7413. * @type {options} - UglifyCSS options
  7414. */
  7415. const defaultOptions = {
  7416. maxLineLen: 0,
  7417. expandVars: false,
  7418. uglyComments: false,
  7419. cuteComments: false,
  7420. debug: false,
  7421. output: ""
  7422. };
  7423. const REGEXP_DATA_URI = /url\(\s*(["']?)data:/g;
  7424. const REGEXP_WHITE_SPACES = /\s+/g;
  7425. const REGEXP_NEW_LINE = /\n/g;
  7426. /**
  7427. * extractDataUrls replaces all data urls with tokens before we start
  7428. * compressing, to avoid performance issues running some of the subsequent
  7429. * regexes against large strings chunks.
  7430. *
  7431. * @param {string} css - CSS content
  7432. * @param {string[]} preservedTokens - Global array of tokens to preserve
  7433. *
  7434. * @return {string} Processed CSS
  7435. */
  7436. function extractDataUrls(css, preservedTokens) {
  7437. // Leave data urls alone to increase parse performance.
  7438. const pattern = REGEXP_DATA_URI;
  7439. const maxIndex = css.length - 1;
  7440. const sb = [];
  7441. let appendIndex = 0, match;
  7442. // Since we need to account for non-base64 data urls, we need to handle
  7443. // ' and ) being part of the data string. Hence switching to indexOf,
  7444. // to determine whether or not we have matching string terminators and
  7445. // handling sb appends directly, instead of using matcher.append* methods.
  7446. while ((match = pattern.exec(css)) !== null) {
  7447. const startIndex = match.index + 4; // 'url('.length()
  7448. let terminator = match[1]; // ', " or empty (not quoted)
  7449. if (terminator.length === 0) {
  7450. terminator = ")";
  7451. }
  7452. let foundTerminator = false, endIndex = pattern.lastIndex - 1;
  7453. while (foundTerminator === false && endIndex + 1 <= maxIndex && endIndex != -1) {
  7454. endIndex = css.indexOf(terminator, endIndex + 1);
  7455. // endIndex == 0 doesn't really apply here
  7456. if ((endIndex > 0) && (css.charAt(endIndex - 1) !== "\\")) {
  7457. foundTerminator = true;
  7458. if (")" != terminator) {
  7459. endIndex = css.indexOf(")", endIndex);
  7460. }
  7461. }
  7462. }
  7463. // Enough searching, start moving stuff over to the buffer
  7464. sb.push(css.substring(appendIndex, match.index));
  7465. if (foundTerminator) {
  7466. let token = css.substring(startIndex, endIndex);
  7467. const parts = token.split(",");
  7468. if (parts.length > 1 && parts[0].slice(-7) == ";base64") {
  7469. token = token.replace(REGEXP_WHITE_SPACES, "");
  7470. } else {
  7471. token = token.replace(REGEXP_NEW_LINE, " ");
  7472. token = token.replace(REGEXP_WHITE_SPACES, " ");
  7473. token = token.replace(REGEXP_PRESERVE_HSLA1, "");
  7474. }
  7475. preservedTokens.push(token);
  7476. const preserver = "url(" + ___PRESERVED_TOKEN_ + (preservedTokens.length - 1) + "___)";
  7477. sb.push(preserver);
  7478. appendIndex = endIndex + 1;
  7479. } else {
  7480. // No end terminator found, re-add the whole match. Should we throw/warn here?
  7481. sb.push(css.substring(match.index, pattern.lastIndex));
  7482. appendIndex = pattern.lastIndex;
  7483. }
  7484. }
  7485. sb.push(css.substring(appendIndex));
  7486. return sb.join("");
  7487. }
  7488. const REGEXP_HEX_COLORS = /(=\s*?["']?)?#([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])(\}|[^0-9a-f{][^{]*?\})/gi;
  7489. /**
  7490. * compressHexColors compresses hex color values of the form #AABBCC to #ABC.
  7491. *
  7492. * DOES NOT compress CSS ID selectors which match the above pattern (which would
  7493. * break things), like #AddressForm { ... }
  7494. *
  7495. * DOES NOT compress IE filters, which have hex color values (which would break
  7496. * things), like chroma(color='#FFFFFF');
  7497. *
  7498. * DOES NOT compress invalid hex values, like background-color: #aabbccdd
  7499. *
  7500. * @param {string} css - CSS content
  7501. *
  7502. * @return {string} Processed CSS
  7503. */
  7504. function compressHexColors(css) {
  7505. // Look for hex colors inside { ... } (to avoid IDs) and which don't have a =, or a " in front of them (to avoid filters)
  7506. const pattern = REGEXP_HEX_COLORS;
  7507. const sb = [];
  7508. let index = 0, match;
  7509. while ((match = pattern.exec(css)) !== null) {
  7510. sb.push(css.substring(index, match.index));
  7511. const isFilter = match[1];
  7512. if (isFilter) {
  7513. // Restore, maintain case, otherwise filter will break
  7514. sb.push(match[1] + "#" + (match[2] + match[3] + match[4] + match[5] + match[6] + match[7]));
  7515. } else {
  7516. if (match[2].toLowerCase() == match[3].toLowerCase() &&
  7517. match[4].toLowerCase() == match[5].toLowerCase() &&
  7518. match[6].toLowerCase() == match[7].toLowerCase()) {
  7519. // Compress.
  7520. sb.push("#" + (match[3] + match[5] + match[7]).toLowerCase());
  7521. } else {
  7522. // Non compressible color, restore but lower case.
  7523. sb.push("#" + (match[2] + match[3] + match[4] + match[5] + match[6] + match[7]).toLowerCase());
  7524. }
  7525. }
  7526. index = pattern.lastIndex = pattern.lastIndex - match[8].length;
  7527. }
  7528. sb.push(css.substring(index));
  7529. return sb.join("");
  7530. }
  7531. const REGEXP_KEYFRAMES = /@[a-z0-9-_]*keyframes\s+[a-z0-9-_]+\s*{/gi;
  7532. const REGEXP_WHITE_SPACE = /(^\s|\s$)/g;
  7533. /** keyframes preserves 0 followed by unit in keyframes steps
  7534. *
  7535. * @param {string} content - CSS content
  7536. * @param {string[]} preservedTokens - Global array of tokens to preserve
  7537. *
  7538. * @return {string} Processed CSS
  7539. */
  7540. function keyframes(content, preservedTokens) {
  7541. const pattern = REGEXP_KEYFRAMES;
  7542. let index = 0, buffer;
  7543. const preserve = (part, i) => {
  7544. part = part.replace(REGEXP_WHITE_SPACE, "");
  7545. if (part.charAt(0) === "0") {
  7546. preservedTokens.push(part);
  7547. buffer[i] = ___PRESERVED_TOKEN_ + (preservedTokens.length - 1) + "___";
  7548. }
  7549. };
  7550. while (true) { // eslint-disable-line no-constant-condition
  7551. let level = 0;
  7552. buffer = "";
  7553. let startIndex = content.slice(index).search(pattern);
  7554. if (startIndex < 0) {
  7555. break;
  7556. }
  7557. index += startIndex;
  7558. startIndex = index;
  7559. const len = content.length;
  7560. const buffers = [];
  7561. for (; index < len; ++index) {
  7562. const ch = content.charAt(index);
  7563. if (ch === "{") {
  7564. if (level === 0) {
  7565. buffers.push(buffer.replace(REGEXP_WHITE_SPACE, ""));
  7566. } else if (level === 1) {
  7567. buffer = buffer.split(",");
  7568. buffer.forEach(preserve);
  7569. buffers.push(buffer.join(",").replace(REGEXP_WHITE_SPACE, ""));
  7570. }
  7571. buffer = "";
  7572. level += 1;
  7573. } else if (ch === "}") {
  7574. if (level === 2) {
  7575. buffers.push("{" + buffer.replace(REGEXP_WHITE_SPACE, "") + "}");
  7576. buffer = "";
  7577. } else if (level === 1) {
  7578. content = content.slice(0, startIndex) +
  7579. buffers.shift() + "{" +
  7580. buffers.join("") +
  7581. content.slice(index);
  7582. break;
  7583. }
  7584. level -= 1;
  7585. }
  7586. if (level < 0) {
  7587. break;
  7588. } else if (ch !== "{" && ch !== "}") {
  7589. buffer += ch;
  7590. }
  7591. }
  7592. }
  7593. return content;
  7594. }
  7595. /**
  7596. * collectComments collects all comment blocks and return new content with comment placeholders
  7597. *
  7598. * @param {string} content - CSS content
  7599. * @param {string[]} comments - Global array of extracted comments
  7600. *
  7601. * @return {string} Processed CSS
  7602. */
  7603. function collectComments(content, comments) {
  7604. const table = [];
  7605. let from = 0, end;
  7606. while (true) { // eslint-disable-line no-constant-condition
  7607. const start = content.indexOf("/*", from);
  7608. if (start > -1) {
  7609. end = content.indexOf("*/", start + 2);
  7610. if (end > -1) {
  7611. comments.push(content.slice(start + 2, end));
  7612. table.push(content.slice(from, start));
  7613. table.push("/*___PRESERVE_CANDIDATE_COMMENT_" + (comments.length - 1) + "___*/");
  7614. from = end + 2;
  7615. } else {
  7616. // unterminated comment
  7617. end = -2;
  7618. break;
  7619. }
  7620. } else {
  7621. break;
  7622. }
  7623. }
  7624. table.push(content.slice(end + 2));
  7625. return table.join("");
  7626. }
  7627. /**
  7628. * processString uglifies a CSS string
  7629. *
  7630. * @param {string} content - CSS string
  7631. * @param {options} options - UglifyCSS options
  7632. *
  7633. * @return {string} Uglified result
  7634. */
  7635. // const REGEXP_EMPTY_RULES = /[^};{/]+\{\}/g;
  7636. const REGEXP_PRESERVE_STRING1 = /"([^\\"])*"/g;
  7637. const REGEXP_PRESERVE_STRING1_BIS = /"(\\.)*"/g;
  7638. const REGEXP_PRESERVE_STRING1_TER = /"(\\)*"/g;
  7639. const REGEXP_PRESERVE_STRING2 = /'([^\\']|\\.|\\)*'/g;
  7640. const REGEXP_MINIFY_ALPHA = /progid:DXImageTransform.Microsoft.Alpha\(Opacity=/gi;
  7641. const REGEXP_PRESERVE_TOKEN1 = /\r\n/g;
  7642. const REGEXP_PRESERVE_TOKEN2 = /[\r\n]/g;
  7643. const REGEXP_VARIABLES = /@variables\s*\{\s*([^}]+)\s*\}/g;
  7644. const REGEXP_VARIABLE = /\s*([a-z0-9-]+)\s*:\s*([^;}]+)\s*/gi;
  7645. const REGEXP_VARIABLE_VALUE = /var\s*\(\s*([^)]+)\s*\)/g;
  7646. const REGEXP_PRESERVE_CALC = /calc\(([^;}]*)\)/g;
  7647. const REGEXP_TRIM = /(^\s*|\s*$)/g;
  7648. const REGEXP_PRESERVE_CALC2 = /\( /g;
  7649. const REGEXP_PRESERVE_CALC3 = / \)/g;
  7650. const REGEXP_PRESERVE_MATRIX = /\s*filter:\s*progid:DXImageTransform.Microsoft.Matrix\(([^)]+)\);/g;
  7651. const REGEXP_REMOVE_SPACES = /(^|\})(([^{:])+:)+([^{]*{)/g;
  7652. const REGEXP_REMOVE_SPACES2 = /\s+([!{;:>+()\],])/g;
  7653. const REGEXP_REMOVE_SPACES2_BIS = /([^\\])\s+([}])/g;
  7654. const REGEXP_RESTORE_SPACE_IMPORTANT = /!important/g;
  7655. const REGEXP_PSEUDOCLASSCOLON = /___PSEUDOCLASSCOLON___/g;
  7656. const REGEXP_COLUMN = /:/g;
  7657. const REGEXP_PRESERVE_ZERO_UNIT = /\s*(animation|animation-delay|animation-duration|transition|transition-delay|transition-duration):\s*([^;}]+)/gi;
  7658. const REGEXP_PRESERVE_ZERO_UNIT1 = /(^|\D)0?\.?0(m?s)/gi;
  7659. const REGEXP_PRESERVE_FLEX = /\s*(flex|flex-basis):\s*([^;}]+)/gi;
  7660. const REGEXP_SPACES = /\s+/;
  7661. const REGEXP_PRESERVE_HSLA = /(hsla?)\(([^)]+)\)/g;
  7662. const REGEXP_PRESERVE_HSLA1 = /(^\s+|\s+$)/g;
  7663. const REGEXP_RETAIN_SPACE_IE6 = /:first-(line|letter)(\{|,)/gi;
  7664. const REGEXP_CHARSET = /^(.*)(@charset)( "[^"]*";)/gi;
  7665. const REGEXP_REMOVE_SECOND_CHARSET = /^((\s*)(@charset)( [^;]+;\s*))+/gi;
  7666. const REGEXP_LOWERCASE_DIRECTIVES = /@(font-face|import|(?:-(?:atsc|khtml|moz|ms|o|wap|webkit)-)?keyframe|media|page|namespace)/gi;
  7667. const REGEXP_LOWERCASE_PSEUDO_ELEMENTS = /:(active|after|before|checked|disabled|empty|enabled|first-(?:child|of-type)|focus|hover|last-(?:child|of-type)|link|only-(?:child|of-type)|root|:selection|target|visited)/gi;
  7668. const REGEXP_CHARSET2 = /^(.*)(@charset "[^"]*";)/g;
  7669. const REGEXP_CHARSET3 = /^(\s*@charset [^;]+;\s*)+/g;
  7670. const REGEXP_LOWERCASE_FUNCTIONS = /:(lang|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|(?:-(?:atsc|khtml|moz|ms|o|wap|webkit)-)?any)\(/gi;
  7671. const REGEXP_LOWERCASE_FUNCTIONS2 = /([:,( ]\s*)(attr|color-stop|from|rgba|to|url|(?:-(?:atsc|khtml|moz|ms|o|wap|webkit)-)?(?:calc|max|min|(?:repeating-)?(?:linear|radial)-gradient)|-webkit-gradient)/gi;
  7672. const REGEXP_NEWLINE1 = /\s*\/\*/g;
  7673. const REGEXP_NEWLINE2 = /\*\/\s*/g;
  7674. const REGEXP_RESTORE_SPACE1 = /\band\(/gi;
  7675. const REGEXP_RESTORE_SPACE2 = /([^:])not\(/gi;
  7676. const REGEXP_RESTORE_SPACE3 = /\bor\(/gi;
  7677. const REGEXP_REMOVE_SPACES3 = /([!{}:;>+([,])\s+/g;
  7678. const REGEXP_REMOVE_SEMI_COLUMNS = /;+\}/g;
  7679. // const REGEXP_REPLACE_ZERO = /(^|[^.0-9\\])(?:0?\.)?0(?:ex|ch|r?em|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|g?rad|turn|ms|k?Hz|dpi|dpcm|dppx|%)(?![a-z0-9])/gi;
  7680. const REGEXP_REPLACE_ZERO_DOT = /([0-9])\.0(ex|ch|r?em|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|g?rad|turn|m?s|k?Hz|dpi|dpcm|dppx|%| |;)/gi;
  7681. const REGEXP_REPLACE_4_ZEROS = /:0 0 0 0(;|\})/g;
  7682. const REGEXP_REPLACE_3_ZEROS = /:0 0 0(;|\})/g;
  7683. // const REGEXP_REPLACE_2_ZEROS = /:0 0(;|\})/g;
  7684. const REGEXP_REPLACE_1_ZERO = /(transform-origin|webkit-transform-origin|moz-transform-origin|o-transform-origin|ms-transform-origin|box-shadow):0(;|\})/gi;
  7685. const REGEXP_REPLACE_ZERO_DOT_DECIMAL = /(:|\s)0+\.(\d+)/g;
  7686. const REGEXP_REPLACE_RGB = /rgb\s*\(\s*([0-9,\s]+)\s*\)/gi;
  7687. const REGEXP_REPLACE_BORDER_ZERO = /(border|border-top|border-right|border-bottom|border-left|outline|background):none(;|\})/gi;
  7688. const REGEXP_REPLACE_IE_OPACITY = /progid:DXImageTransform\.Microsoft\.Alpha\(Opacity=/gi;
  7689. const REGEXP_REPLACE_QUERY_FRACTION = /\(([-A-Za-z]+):([0-9]+)\/([0-9]+)\)/g;
  7690. const REGEXP_QUERY_FRACTION = /___QUERY_FRACTION___/g;
  7691. const REGEXP_REPLACE_SEMI_COLUMNS = /;;+/g;
  7692. const REGEXP_REPLACE_HASH_COLOR = /(:|\s)(#f00)(;|})/g;
  7693. const REGEXP_PRESERVED_NEWLINE = /___PRESERVED_NEWLINE___/g;
  7694. const REGEXP_REPLACE_HASH_COLOR_SHORT1 = /(:|\s)(#000080)(;|})/g;
  7695. const REGEXP_REPLACE_HASH_COLOR_SHORT2 = /(:|\s)(#808080)(;|})/g;
  7696. const REGEXP_REPLACE_HASH_COLOR_SHORT3 = /(:|\s)(#808000)(;|})/g;
  7697. const REGEXP_REPLACE_HASH_COLOR_SHORT4 = /(:|\s)(#800080)(;|})/g;
  7698. const REGEXP_REPLACE_HASH_COLOR_SHORT5 = /(:|\s)(#c0c0c0)(;|})/g;
  7699. const REGEXP_REPLACE_HASH_COLOR_SHORT6 = /(:|\s)(#008080)(;|})/g;
  7700. const REGEXP_REPLACE_HASH_COLOR_SHORT7 = /(:|\s)(#ffa500)(;|})/g;
  7701. const REGEXP_REPLACE_HASH_COLOR_SHORT8 = /(:|\s)(#800000)(;|})/g;
  7702. function processString(content = "", options = defaultOptions) {
  7703. const comments = [];
  7704. const preservedTokens = [];
  7705. let pattern;
  7706. const originalContent = content;
  7707. content = extractDataUrls(content, preservedTokens);
  7708. content = collectComments(content, comments);
  7709. // preserve strings so their content doesn't get accidentally minified
  7710. preserveString(REGEXP_PRESERVE_STRING1);
  7711. preserveString(REGEXP_PRESERVE_STRING1_BIS);
  7712. preserveString(REGEXP_PRESERVE_STRING1_TER);
  7713. preserveString(REGEXP_PRESERVE_STRING2);
  7714. function preserveString(pattern) {
  7715. content = content.replace(pattern, token => {
  7716. const quote = token.substring(0, 1);
  7717. token = token.slice(1, -1);
  7718. // maybe the string contains a comment-like substring or more? put'em back then
  7719. if (token.indexOf("___PRESERVE_CANDIDATE_COMMENT_") >= 0) {
  7720. for (let i = 0, len = comments.length; i < len; i += 1) {
  7721. token = token.replace("___PRESERVE_CANDIDATE_COMMENT_" + i + "___", comments[i]);
  7722. }
  7723. }
  7724. // minify alpha opacity in filter strings
  7725. token = token.replace(REGEXP_MINIFY_ALPHA, "alpha(opacity=");
  7726. preservedTokens.push(token);
  7727. return quote + ___PRESERVED_TOKEN_ + (preservedTokens.length - 1) + "___" + quote;
  7728. });
  7729. }
  7730. // strings are safe, now wrestle the comments
  7731. for (let i = 0, len = comments.length; i < len; i += 1) {
  7732. const token = comments[i];
  7733. const placeholder = "___PRESERVE_CANDIDATE_COMMENT_" + i + "___";
  7734. // ! in the first position of the comment means preserve
  7735. // so push to the preserved tokens keeping the !
  7736. if (token.charAt(0) === "!") {
  7737. if (options.cuteComments) {
  7738. preservedTokens.push(token.substring(1).replace(REGEXP_PRESERVE_TOKEN1, "\n"));
  7739. } else if (options.uglyComments) {
  7740. preservedTokens.push(token.substring(1).replace(REGEXP_PRESERVE_TOKEN2, ""));
  7741. } else {
  7742. preservedTokens.push(token);
  7743. }
  7744. content = content.replace(placeholder, ___PRESERVED_TOKEN_ + (preservedTokens.length - 1) + "___");
  7745. continue;
  7746. }
  7747. // \ in the last position looks like hack for Mac/IE5
  7748. // shorten that to /*\*/ and the next one to /**/
  7749. if (token.charAt(token.length - 1) === "\\") {
  7750. preservedTokens.push("\\");
  7751. content = content.replace(placeholder, ___PRESERVED_TOKEN_ + (preservedTokens.length - 1) + "___");
  7752. i = i + 1; // attn: advancing the loop
  7753. preservedTokens.push("");
  7754. content = content.replace(
  7755. "___PRESERVE_CANDIDATE_COMMENT_" + i + "___",
  7756. ___PRESERVED_TOKEN_ + (preservedTokens.length - 1) + "___"
  7757. );
  7758. continue;
  7759. }
  7760. // keep empty comments after child selectors (IE7 hack)
  7761. // e.g. html >/**/ body
  7762. if (token.length === 0) {
  7763. const startIndex = content.indexOf(placeholder);
  7764. if (startIndex > 2) {
  7765. if (content.charAt(startIndex - 3) === ">") {
  7766. preservedTokens.push("");
  7767. content = content.replace(placeholder, ___PRESERVED_TOKEN_ + (preservedTokens.length - 1) + "___");
  7768. }
  7769. }
  7770. }
  7771. // in all other cases kill the comment
  7772. content = content.replace(`/*${placeholder}*/`, "");
  7773. }
  7774. // parse simple @variables blocks and remove them
  7775. if (options.expandVars) {
  7776. const vars = {};
  7777. pattern = REGEXP_VARIABLES;
  7778. content = content.replace(pattern, (_, f1) => {
  7779. pattern = REGEXP_VARIABLE;
  7780. f1.replace(pattern, (_, f1, f2) => {
  7781. if (f1 && f2) {
  7782. vars[f1] = f2;
  7783. }
  7784. return "";
  7785. });
  7786. return "";
  7787. });
  7788. // replace var(x) with the value of x
  7789. pattern = REGEXP_VARIABLE_VALUE;
  7790. content = content.replace(pattern, (_, f1) => {
  7791. return vars[f1] || "none";
  7792. });
  7793. }
  7794. // normalize all whitespace strings to single spaces. Easier to work with that way.
  7795. content = content.replace(REGEXP_WHITE_SPACES, " ");
  7796. // preserve formulas in calc() before removing spaces
  7797. pattern = REGEXP_PRESERVE_CALC;
  7798. content = content.replace(pattern, (_, f1) => {
  7799. preservedTokens.push(
  7800. "calc(" +
  7801. f1.replace(REGEXP_TRIM, "")
  7802. .replace(REGEXP_PRESERVE_CALC2, "(")
  7803. .replace(REGEXP_PRESERVE_CALC3, ")") +
  7804. ")"
  7805. );
  7806. return ___PRESERVED_TOKEN_ + (preservedTokens.length - 1) + "___";
  7807. });
  7808. // preserve matrix
  7809. pattern = REGEXP_PRESERVE_MATRIX;
  7810. content = content.replace(pattern, (_, f1) => {
  7811. preservedTokens.push(f1);
  7812. return "filter:progid:DXImageTransform.Microsoft.Matrix(" + ___PRESERVED_TOKEN_ + (preservedTokens.length - 1) + "___);";
  7813. });
  7814. // remove the spaces before the things that should not have spaces before them.
  7815. // but, be careful not to turn 'p :link {...}' into 'p:link{...}'
  7816. // swap out any pseudo-class colons with the token, and then swap back.
  7817. try {
  7818. pattern = REGEXP_REMOVE_SPACES;
  7819. content = content.replace(pattern, token => token.replace(REGEXP_COLUMN, "___PSEUDOCLASSCOLON___"));
  7820. } catch (_error) {
  7821. // ignored
  7822. }
  7823. // remove spaces before the things that should not have spaces before them.
  7824. content = content.replace(REGEXP_REMOVE_SPACES2, "$1");
  7825. content = content.replace(REGEXP_REMOVE_SPACES2_BIS, "$1$2");
  7826. // restore spaces for !important
  7827. content = content.replace(REGEXP_RESTORE_SPACE_IMPORTANT, " !important");
  7828. // bring back the colon
  7829. content = content.replace(REGEXP_PSEUDOCLASSCOLON, ":");
  7830. // preserve 0 followed by a time unit for properties using time units
  7831. pattern = REGEXP_PRESERVE_ZERO_UNIT;
  7832. content = content.replace(pattern, (_, f1, f2) => {
  7833. f2 = f2.replace(REGEXP_PRESERVE_ZERO_UNIT1, (_, g1, g2) => {
  7834. preservedTokens.push("0" + g2);
  7835. return g1 + ___PRESERVED_TOKEN_ + (preservedTokens.length - 1) + "___";
  7836. });
  7837. return f1 + ":" + f2;
  7838. });
  7839. // preserve unit for flex-basis within flex and flex-basis (ie10 bug)
  7840. pattern = REGEXP_PRESERVE_FLEX;
  7841. content = content.replace(pattern, (_, f1, f2) => {
  7842. let f2b = f2.split(REGEXP_SPACES);
  7843. preservedTokens.push(f2b.pop());
  7844. f2b.push(___PRESERVED_TOKEN_ + (preservedTokens.length - 1) + "___");
  7845. f2b = f2b.join(" ");
  7846. return `${f1}:${f2b}`;
  7847. });
  7848. // preserve 0% in hsl and hsla color definitions
  7849. content = content.replace(REGEXP_PRESERVE_HSLA, (_, f1, f2) => {
  7850. const f0 = [];
  7851. f2.split(",").forEach(part => {
  7852. part = part.replace(REGEXP_PRESERVE_HSLA1, "");
  7853. if (part === "0%") {
  7854. preservedTokens.push("0%");
  7855. f0.push(___PRESERVED_TOKEN_ + (preservedTokens.length - 1) + "___");
  7856. } else {
  7857. f0.push(part);
  7858. }
  7859. });
  7860. return f1 + "(" + f0.join(",") + ")";
  7861. });
  7862. // preserve 0 followed by unit in keyframes steps (WIP)
  7863. content = keyframes(content, preservedTokens);
  7864. // retain space for special IE6 cases
  7865. content = content.replace(REGEXP_RETAIN_SPACE_IE6, (_, f1, f2) => ":first-" + f1.toLowerCase() + " " + f2);
  7866. // newlines before and after the end of a preserved comment
  7867. if (options.cuteComments) {
  7868. content = content.replace(REGEXP_NEWLINE1, "___PRESERVED_NEWLINE___/*");
  7869. content = content.replace(REGEXP_NEWLINE2, "*/___PRESERVED_NEWLINE___");
  7870. // no space after the end of a preserved comment
  7871. } else {
  7872. content = content.replace(REGEXP_NEWLINE2, "*/");
  7873. }
  7874. // If there are multiple @charset directives, push them to the top of the file.
  7875. pattern = REGEXP_CHARSET;
  7876. content = content.replace(pattern, (_, f1, f2, f3) => f2.toLowerCase() + f3 + f1);
  7877. // When all @charset are at the top, remove the second and after (as they are completely ignored).
  7878. pattern = REGEXP_REMOVE_SECOND_CHARSET;
  7879. content = content.replace(pattern, (_, __, f2, f3, f4) => f2 + f3.toLowerCase() + f4);
  7880. // lowercase some popular @directives (@charset is done right above)
  7881. pattern = REGEXP_LOWERCASE_DIRECTIVES;
  7882. content = content.replace(pattern, (_, f1) => "@" + f1.toLowerCase());
  7883. // lowercase some more common pseudo-elements
  7884. pattern = REGEXP_LOWERCASE_PSEUDO_ELEMENTS;
  7885. content = content.replace(pattern, (_, f1) => ":" + f1.toLowerCase());
  7886. // if there is a @charset, then only allow one, and push to the top of the file.
  7887. content = content.replace(REGEXP_CHARSET2, "$2$1");
  7888. content = content.replace(REGEXP_CHARSET3, "$1");
  7889. // lowercase some more common functions
  7890. pattern = REGEXP_LOWERCASE_FUNCTIONS;
  7891. content = content.replace(pattern, (_, f1) => ":" + f1.toLowerCase() + "(");
  7892. // lower case some common function that can be values
  7893. // NOTE: rgb() isn't useful as we replace with #hex later, as well as and() is already done for us right after this
  7894. pattern = REGEXP_LOWERCASE_FUNCTIONS2;
  7895. content = content.replace(pattern, (_, f1, f2) => f1 + f2.toLowerCase());
  7896. // put the space back in some cases, to support stuff like
  7897. // @media screen and (-webkit-min-device-pixel-ratio:0){
  7898. content = content.replace(REGEXP_RESTORE_SPACE1, "and (");
  7899. content = content.replace(REGEXP_RESTORE_SPACE2, "$1not (");
  7900. content = content.replace(REGEXP_RESTORE_SPACE3, "or (");
  7901. // remove the spaces after the things that should not have spaces after them.
  7902. content = content.replace(REGEXP_REMOVE_SPACES3, "$1");
  7903. // remove unnecessary semicolons
  7904. content = content.replace(REGEXP_REMOVE_SEMI_COLUMNS, "}");
  7905. // replace 0(px,em,%) with 0.
  7906. // content = content.replace(REGEXP_REPLACE_ZERO, "$10");
  7907. // Replace x.0(px,em,%) with x(px,em,%).
  7908. content = content.replace(REGEXP_REPLACE_ZERO_DOT, "$1$2");
  7909. // replace 0 0 0 0; with 0.
  7910. content = content.replace(REGEXP_REPLACE_4_ZEROS, ":0$1");
  7911. content = content.replace(REGEXP_REPLACE_3_ZEROS, ":0$1");
  7912. // content = content.replace(REGEXP_REPLACE_2_ZEROS, ":0$1");
  7913. // replace background-position:0; with background-position:0 0;
  7914. // same for transform-origin and box-shadow
  7915. pattern = REGEXP_REPLACE_1_ZERO;
  7916. content = content.replace(pattern, (_, f1, f2) => f1.toLowerCase() + ":0 0" + f2);
  7917. // replace 0.6 to .6, but only when preceded by : or a white-space
  7918. content = content.replace(REGEXP_REPLACE_ZERO_DOT_DECIMAL, "$1.$2");
  7919. // shorten colors from rgb(51,102,153) to #336699
  7920. // this makes it more likely that it'll get further compressed in the next step.
  7921. pattern = REGEXP_REPLACE_RGB;
  7922. content = content.replace(pattern, (_, f1) => {
  7923. const rgbcolors = f1.split(",");
  7924. let hexcolor = "#";
  7925. for (let i = 0; i < rgbcolors.length; i += 1) {
  7926. let val = parseInt(rgbcolors[i], 10);
  7927. if (val < 16) {
  7928. hexcolor += "0";
  7929. }
  7930. if (val > 255) {
  7931. val = 255;
  7932. }
  7933. hexcolor += val.toString(16);
  7934. }
  7935. return hexcolor;
  7936. });
  7937. // Shorten colors from #AABBCC to #ABC.
  7938. content = compressHexColors(content);
  7939. // Replace #f00 -> red
  7940. content = content.replace(REGEXP_REPLACE_HASH_COLOR, "$1red$3");
  7941. // Replace other short color keywords
  7942. content = content.replace(REGEXP_REPLACE_HASH_COLOR_SHORT1, "$1navy$3");
  7943. content = content.replace(REGEXP_REPLACE_HASH_COLOR_SHORT2, "$1gray$3");
  7944. content = content.replace(REGEXP_REPLACE_HASH_COLOR_SHORT3, "$1olive$3");
  7945. content = content.replace(REGEXP_REPLACE_HASH_COLOR_SHORT4, "$1purple$3");
  7946. content = content.replace(REGEXP_REPLACE_HASH_COLOR_SHORT5, "$1silver$3");
  7947. content = content.replace(REGEXP_REPLACE_HASH_COLOR_SHORT6, "$1teal$3");
  7948. content = content.replace(REGEXP_REPLACE_HASH_COLOR_SHORT7, "$1orange$3");
  7949. content = content.replace(REGEXP_REPLACE_HASH_COLOR_SHORT8, "$1maroon$3");
  7950. // border: none -> border:0
  7951. pattern = REGEXP_REPLACE_BORDER_ZERO;
  7952. content = content.replace(pattern, (_, f1, f2) => f1.toLowerCase() + ":0" + f2);
  7953. // shorter opacity IE filter
  7954. content = content.replace(REGEXP_REPLACE_IE_OPACITY, "alpha(opacity=");
  7955. // Find a fraction that is used for Opera's -o-device-pixel-ratio query
  7956. // Add token to add the '\' back in later
  7957. content = content.replace(REGEXP_REPLACE_QUERY_FRACTION, "($1:$2___QUERY_FRACTION___$3)");
  7958. // remove empty rules.
  7959. // content = content.replace(REGEXP_EMPTY_RULES, "");
  7960. // Add '\' back to fix Opera -o-device-pixel-ratio query
  7961. content = content.replace(REGEXP_QUERY_FRACTION, "/");
  7962. // some source control tools don't like it when files containing lines longer
  7963. // than, say 8000 characters, are checked in. The linebreak option is used in
  7964. // that case to split long lines after a specific column.
  7965. if (options.maxLineLen > 0) {
  7966. const lines = [];
  7967. let line = [];
  7968. for (let i = 0, len = content.length; i < len; i += 1) {
  7969. const ch = content.charAt(i);
  7970. line.push(ch);
  7971. if (ch === "}" && line.length > options.maxLineLen) {
  7972. lines.push(line.join(""));
  7973. line = [];
  7974. }
  7975. }
  7976. if (line.length) {
  7977. lines.push(line.join(""));
  7978. }
  7979. content = lines.join("\n");
  7980. }
  7981. // replace multiple semi-colons in a row by a single one
  7982. // see SF bug #1980989
  7983. content = content.replace(REGEXP_REPLACE_SEMI_COLUMNS, ";");
  7984. // trim the final string (for any leading or trailing white spaces)
  7985. content = content.replace(REGEXP_TRIM, "");
  7986. if (preservedTokens.length > 1000) {
  7987. return originalContent;
  7988. }
  7989. // restore preserved tokens
  7990. for (let i = preservedTokens.length - 1; i >= 0; i--) {
  7991. content = content.replace(___PRESERVED_TOKEN_ + i + "___", preservedTokens[i], "g");
  7992. }
  7993. // restore preserved newlines
  7994. content = content.replace(REGEXP_PRESERVED_NEWLINE, "\n");
  7995. // return
  7996. return content;
  7997. }
  7998. var cssMinifier = /*#__PURE__*/Object.freeze({
  7999. __proto__: null,
  8000. defaultOptions: defaultOptions,
  8001. processString: processString
  8002. });
  8003. /*
  8004. * The MIT License (MIT)
  8005. *
  8006. * Author: Gildas Lormeau
  8007. *
  8008. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8009. * of this software and associated documentation files (the "Software"), to deal
  8010. * in the Software without restriction, including without limitation the rights
  8011. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8012. * copies of the Software, and to permit persons to whom the Software is
  8013. * furnished to do so, subject to the following conditions:
  8014. *
  8015. * The above copyright notice and this permission notice shall be included in all
  8016. * copies or substantial portions of the Software.
  8017. *
  8018. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  8019. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  8020. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  8021. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  8022. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  8023. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  8024. * SOFTWARE.
  8025. */
  8026. // 1. Let input be the value passed to this algorithm.
  8027. function process$6(input) {
  8028. // UTILITY FUNCTIONS
  8029. // Manual is faster than RegEx
  8030. // http://bjorn.tipling.com/state-and-regular-expressions-in-javascript
  8031. // http://jsperf.com/whitespace-character/5
  8032. function isSpace(c) {
  8033. return (c === "\u0020" || // space
  8034. c === "\u0009" || // horizontal tab
  8035. c === "\u000A" || // new line
  8036. c === "\u000C" || // form feed
  8037. c === "\u000D"); // carriage return
  8038. }
  8039. function collectCharacters(regEx) {
  8040. let chars;
  8041. const match = regEx.exec(input.substring(pos));
  8042. if (match) {
  8043. chars = match[0];
  8044. pos += chars.length;
  8045. return chars;
  8046. }
  8047. }
  8048. const inputLength = input.length;
  8049. // (Don"t use \s, to avoid matching non-breaking space)
  8050. /* eslint-disable no-control-regex */
  8051. const regexLeadingSpaces = /^[ \t\n\r\u000c]+/;
  8052. const regexLeadingCommasOrSpaces = /^[, \t\n\r\u000c]+/;
  8053. const regexLeadingNotSpaces = /^[^ \t\n\r\u000c]+/;
  8054. const regexTrailingCommas = /[,]+$/;
  8055. const regexNonNegativeInteger = /^\d+$/;
  8056. /* eslint-enable no-control-regex */
  8057. // ( Positive or negative or unsigned integers or decimals, without or without exponents.
  8058. // Must include at least one digit.
  8059. // According to spec tests any decimal point must be followed by a digit.
  8060. // No leading plus sign is allowed.)
  8061. // https://html.spec.whatwg.org/multipage/infrastructure.html#valid-floating-point-number
  8062. const regexFloatingPoint = /^-?(?:[0-9]+|[0-9]*\.[0-9]+)(?:[eE][+-]?[0-9]+)?$/;
  8063. let url, descriptors, currentDescriptor, state, c,
  8064. // 2. Let position be a pointer into input, initially pointing at the start
  8065. // of the string.
  8066. pos = 0;
  8067. // 3. Let candidates be an initially empty source set.
  8068. const candidates = [];
  8069. // 4. Splitting loop: Collect a sequence of characters that are space
  8070. // characters or U+002C COMMA characters. If any U+002C COMMA characters
  8071. // were collected, that is a parse error.
  8072. while (true) { // eslint-disable-line no-constant-condition
  8073. collectCharacters(regexLeadingCommasOrSpaces);
  8074. // 5. If position is past the end of input, return candidates and abort these steps.
  8075. if (pos >= inputLength) {
  8076. return candidates; // (we"re done, this is the sole return path)
  8077. }
  8078. // 6. Collect a sequence of characters that are not space characters,
  8079. // and let that be url.
  8080. url = collectCharacters(regexLeadingNotSpaces);
  8081. // 7. Let descriptors be a new empty list.
  8082. descriptors = [];
  8083. // 8. If url ends with a U+002C COMMA character (,), follow these substeps:
  8084. // (1). Remove all trailing U+002C COMMA characters from url. If this removed
  8085. // more than one character, that is a parse error.
  8086. if (url.slice(-1) === ",") {
  8087. url = url.replace(regexTrailingCommas, "");
  8088. // (Jump ahead to step 9 to skip tokenization and just push the candidate).
  8089. parseDescriptors();
  8090. // Otherwise, follow these substeps:
  8091. } else {
  8092. tokenize();
  8093. } // (close else of step 8)
  8094. // 16. Return to the step labeled splitting loop.
  8095. } // (Close of big while loop.)
  8096. /**
  8097. * Tokenizes descriptor properties prior to parsing
  8098. * Returns undefined.
  8099. */
  8100. function tokenize() {
  8101. // 8.1. Descriptor tokeniser: Skip whitespace
  8102. collectCharacters(regexLeadingSpaces);
  8103. // 8.2. Let current descriptor be the empty string.
  8104. currentDescriptor = "";
  8105. // 8.3. Let state be in descriptor.
  8106. state = "in descriptor";
  8107. while (true) { // eslint-disable-line no-constant-condition
  8108. // 8.4. Let c be the character at position.
  8109. c = input.charAt(pos);
  8110. // Do the following depending on the value of state.
  8111. // For the purpose of this step, "EOF" is a special character representing
  8112. // that position is past the end of input.
  8113. // In descriptor
  8114. if (state === "in descriptor") {
  8115. // Do the following, depending on the value of c:
  8116. // Space character
  8117. // If current descriptor is not empty, append current descriptor to
  8118. // descriptors and let current descriptor be the empty string.
  8119. // Set state to after descriptor.
  8120. if (isSpace(c)) {
  8121. if (currentDescriptor) {
  8122. descriptors.push(currentDescriptor);
  8123. currentDescriptor = "";
  8124. state = "after descriptor";
  8125. }
  8126. // U+002C COMMA (,)
  8127. // Advance position to the next character in input. If current descriptor
  8128. // is not empty, append current descriptor to descriptors. Jump to the step
  8129. // labeled descriptor parser.
  8130. } else if (c === ",") {
  8131. pos += 1;
  8132. if (currentDescriptor) {
  8133. descriptors.push(currentDescriptor);
  8134. }
  8135. parseDescriptors();
  8136. return;
  8137. // U+0028 LEFT PARENTHESIS (()
  8138. // Append c to current descriptor. Set state to in parens.
  8139. } else if (c === "\u0028") {
  8140. currentDescriptor = currentDescriptor + c;
  8141. state = "in parens";
  8142. // EOF
  8143. // If current descriptor is not empty, append current descriptor to
  8144. // descriptors. Jump to the step labeled descriptor parser.
  8145. } else if (c === "") {
  8146. if (currentDescriptor) {
  8147. descriptors.push(currentDescriptor);
  8148. }
  8149. parseDescriptors();
  8150. return;
  8151. // Anything else
  8152. // Append c to current descriptor.
  8153. } else {
  8154. currentDescriptor = currentDescriptor + c;
  8155. }
  8156. // (end "in descriptor"
  8157. // In parens
  8158. } else if (state === "in parens") {
  8159. // U+0029 RIGHT PARENTHESIS ())
  8160. // Append c to current descriptor. Set state to in descriptor.
  8161. if (c === ")") {
  8162. currentDescriptor = currentDescriptor + c;
  8163. state = "in descriptor";
  8164. // EOF
  8165. // Append current descriptor to descriptors. Jump to the step labeled
  8166. // descriptor parser.
  8167. } else if (c === "") {
  8168. descriptors.push(currentDescriptor);
  8169. parseDescriptors();
  8170. return;
  8171. // Anything else
  8172. // Append c to current descriptor.
  8173. } else {
  8174. currentDescriptor = currentDescriptor + c;
  8175. }
  8176. // After descriptor
  8177. } else if (state === "after descriptor") {
  8178. // Do the following, depending on the value of c:
  8179. // Space character: Stay in this state.
  8180. if (isSpace(c)) ; else if (c === "") {
  8181. parseDescriptors();
  8182. return;
  8183. // Anything else
  8184. // Set state to in descriptor. Set position to the previous character in input.
  8185. } else {
  8186. state = "in descriptor";
  8187. pos -= 1;
  8188. }
  8189. }
  8190. // Advance position to the next character in input.
  8191. pos += 1;
  8192. // Repeat this step.
  8193. } // (close while true loop)
  8194. }
  8195. /**
  8196. * Adds descriptor properties to a candidate, pushes to the candidates array
  8197. * @return undefined
  8198. */
  8199. // Declared outside of the while loop so that it"s only created once.
  8200. function parseDescriptors() {
  8201. // 9. Descriptor parser: Let error be no.
  8202. let pError = false,
  8203. // 10. Let width be absent.
  8204. // 11. Let density be absent.
  8205. // 12. Let future-compat-h be absent. (We"re implementing it now as h)
  8206. w, d, h, i,
  8207. desc, lastChar, value, intVal, floatVal;
  8208. const candidate = {};
  8209. // 13. For each descriptor in descriptors, run the appropriate set of steps
  8210. // from the following list:
  8211. for (i = 0; i < descriptors.length; i++) {
  8212. desc = descriptors[i];
  8213. lastChar = desc[desc.length - 1];
  8214. value = desc.substring(0, desc.length - 1);
  8215. intVal = parseInt(value, 10);
  8216. floatVal = parseFloat(value);
  8217. // If the descriptor consists of a valid non-negative integer followed by
  8218. // a U+0077 LATIN SMALL LETTER W character
  8219. if (regexNonNegativeInteger.test(value) && (lastChar === "w")) {
  8220. // If width and density are not both absent, then let error be yes.
  8221. if (w || d) { pError = true; }
  8222. // Apply the rules for parsing non-negative integers to the descriptor.
  8223. // If the result is zero, let error be yes.
  8224. // Otherwise, let width be the result.
  8225. if (intVal === 0) { pError = true; } else { w = intVal; }
  8226. // If the descriptor consists of a valid floating-point number followed by
  8227. // a U+0078 LATIN SMALL LETTER X character
  8228. } else if (regexFloatingPoint.test(value) && (lastChar === "x")) {
  8229. // If width, density and future-compat-h are not all absent, then let error
  8230. // be yes.
  8231. if (w || d || h) { pError = true; }
  8232. // Apply the rules for parsing floating-point number values to the descriptor.
  8233. // If the result is less than zero, let error be yes. Otherwise, let density
  8234. // be the result.
  8235. if (floatVal < 0) { pError = true; } else { d = floatVal; }
  8236. // If the descriptor consists of a valid non-negative integer followed by
  8237. // a U+0068 LATIN SMALL LETTER H character
  8238. } else if (regexNonNegativeInteger.test(value) && (lastChar === "h")) {
  8239. // If height and density are not both absent, then let error be yes.
  8240. if (h || d) { pError = true; }
  8241. // Apply the rules for parsing non-negative integers to the descriptor.
  8242. // If the result is zero, let error be yes. Otherwise, let future-compat-h
  8243. // be the result.
  8244. if (intVal === 0) { pError = true; } else { h = intVal; }
  8245. // Anything else, Let error be yes.
  8246. } else { pError = true; }
  8247. } // (close step 13 for loop)
  8248. // 15. If error is still no, then append a new image source to candidates whose
  8249. // URL is url, associated with a width width if not absent and a pixel
  8250. // density density if not absent. Otherwise, there is a parse error.
  8251. if (!pError) {
  8252. candidate.url = url;
  8253. if (w) { candidate.w = w; }
  8254. if (d) { candidate.d = d; }
  8255. if (h) { candidate.h = h; }
  8256. candidates.push(candidate);
  8257. } else if (console && console.log) { // eslint-disable-line no-console
  8258. console.log("Invalid srcset descriptor found in \"" + input + "\" at \"" + desc + "\"."); // eslint-disable-line no-console
  8259. }
  8260. } // (close parseDescriptors fn)
  8261. }
  8262. var htmlSrcsetParser = /*#__PURE__*/Object.freeze({
  8263. __proto__: null,
  8264. process: process$6
  8265. });
  8266. /*
  8267. * The MIT License (MIT)
  8268. *
  8269. * Author: Gildas Lormeau
  8270. *
  8271. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8272. * of this software and associated documentation files (the "Software"), to deal
  8273. * in the Software without restriction, including without limitation the rights
  8274. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8275. * copies of the Software, and to permit persons to whom the Software is
  8276. * furnished to do so, subject to the following conditions:
  8277. *
  8278. * The above copyright notice and this permission notice shall be included in all
  8279. * copies or substantial portions of the Software.
  8280. *
  8281. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  8282. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  8283. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  8284. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  8285. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  8286. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  8287. * SOFTWARE.
  8288. */
  8289. // derived from https://github.com/jsdom/whatwg-mimetype
  8290. /*
  8291. * Copyright © 2017–2018 Domenic Denicola <d@domenic.me>
  8292. *
  8293. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8294. * of this software and associated documentation files (the "Software"), to deal
  8295. * in the Software without restriction, including without limitation the rights
  8296. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8297. * copies of the Software, and to permit persons to whom the Software is
  8298. * furnished to do so, subject to the following conditions:
  8299. * The above copyright notice and this permission notice shall be included in all
  8300. * copies or substantial portions of the Software.
  8301. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  8302. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  8303. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  8304. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  8305. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  8306. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  8307. * SOFTWARE.
  8308. */
  8309. let utils, parser, serializer, MIMEType;
  8310. // lib/utils.js
  8311. {
  8312. utils = {};
  8313. utils.removeLeadingAndTrailingHTTPWhitespace = string => {
  8314. return string.replace(/^[ \t\n\r]+/, "").replace(/[ \t\n\r]+$/, "");
  8315. };
  8316. utils.removeTrailingHTTPWhitespace = string => {
  8317. return string.replace(/[ \t\n\r]+$/, "");
  8318. };
  8319. utils.isHTTPWhitespaceChar = char => {
  8320. return char === " " || char === "\t" || char === "\n" || char === "\r";
  8321. };
  8322. utils.solelyContainsHTTPTokenCodePoints = string => {
  8323. return /^[-!#$%&'*+.^_`|~A-Za-z0-9]*$/.test(string);
  8324. };
  8325. utils.soleyContainsHTTPQuotedStringTokenCodePoints = string => {
  8326. return /^[\t\u0020-\u007E\u0080-\u00FF]*$/.test(string);
  8327. };
  8328. utils.asciiLowercase = string => {
  8329. return string.replace(/[A-Z]/g, l => l.toLowerCase());
  8330. };
  8331. // This variant only implements it with the extract-value flag set.
  8332. utils.collectAnHTTPQuotedString = (input, position) => {
  8333. let value = "";
  8334. position++;
  8335. // eslint-disable-next-line no-constant-condition
  8336. while (true) {
  8337. while (position < input.length && input[position] !== "\"" && input[position] !== "\\") {
  8338. value += input[position];
  8339. ++position;
  8340. }
  8341. if (position >= input.length) {
  8342. break;
  8343. }
  8344. const quoteOrBackslash = input[position];
  8345. ++position;
  8346. if (quoteOrBackslash === "\\") {
  8347. if (position >= input.length) {
  8348. value += "\\";
  8349. break;
  8350. }
  8351. value += input[position];
  8352. ++position;
  8353. } else {
  8354. break;
  8355. }
  8356. }
  8357. return [value, position];
  8358. };
  8359. }
  8360. // lib/serializer.js
  8361. {
  8362. const { solelyContainsHTTPTokenCodePoints } = utils;
  8363. serializer = mimeType => {
  8364. let serialization = `${mimeType.type}/${mimeType.subtype}`;
  8365. if (mimeType.parameters.size === 0) {
  8366. return serialization;
  8367. }
  8368. for (let [name, value] of mimeType.parameters) {
  8369. serialization += ";";
  8370. serialization += name;
  8371. serialization += "=";
  8372. if (!solelyContainsHTTPTokenCodePoints(value) || value.length === 0) {
  8373. value = value.replace(/(["\\])/g, "\\$1");
  8374. value = `"${value}"`;
  8375. }
  8376. serialization += value;
  8377. }
  8378. return serialization;
  8379. };
  8380. }
  8381. // lib/parser.js
  8382. {
  8383. const {
  8384. removeLeadingAndTrailingHTTPWhitespace,
  8385. removeTrailingHTTPWhitespace,
  8386. isHTTPWhitespaceChar,
  8387. solelyContainsHTTPTokenCodePoints,
  8388. soleyContainsHTTPQuotedStringTokenCodePoints,
  8389. asciiLowercase,
  8390. collectAnHTTPQuotedString
  8391. } = utils;
  8392. parser = input => {
  8393. input = removeLeadingAndTrailingHTTPWhitespace(input);
  8394. let position = 0;
  8395. let type = "";
  8396. while (position < input.length && input[position] !== "/") {
  8397. type += input[position];
  8398. ++position;
  8399. }
  8400. if (type.length === 0 || !solelyContainsHTTPTokenCodePoints(type)) {
  8401. return null;
  8402. }
  8403. if (position >= input.length) {
  8404. return null;
  8405. }
  8406. // Skips past "/"
  8407. ++position;
  8408. let subtype = "";
  8409. while (position < input.length && input[position] !== ";") {
  8410. subtype += input[position];
  8411. ++position;
  8412. }
  8413. subtype = removeTrailingHTTPWhitespace(subtype);
  8414. if (subtype.length === 0 || !solelyContainsHTTPTokenCodePoints(subtype)) {
  8415. return null;
  8416. }
  8417. const mimeType = {
  8418. type: asciiLowercase(type),
  8419. subtype: asciiLowercase(subtype),
  8420. parameters: new Map()
  8421. };
  8422. while (position < input.length) {
  8423. // Skip past ";"
  8424. ++position;
  8425. while (isHTTPWhitespaceChar(input[position])) {
  8426. ++position;
  8427. }
  8428. let parameterName = "";
  8429. while (position < input.length && input[position] !== ";" && input[position] !== "=") {
  8430. parameterName += input[position];
  8431. ++position;
  8432. }
  8433. parameterName = asciiLowercase(parameterName);
  8434. if (position < input.length) {
  8435. if (input[position] === ";") {
  8436. continue;
  8437. }
  8438. // Skip past "="
  8439. ++position;
  8440. }
  8441. let parameterValue = null;
  8442. if (input[position] === "\"") {
  8443. [parameterValue, position] = collectAnHTTPQuotedString(input, position);
  8444. while (position < input.length && input[position] !== ";") {
  8445. ++position;
  8446. }
  8447. } else {
  8448. parameterValue = "";
  8449. while (position < input.length && input[position] !== ";") {
  8450. parameterValue += input[position];
  8451. ++position;
  8452. }
  8453. parameterValue = removeTrailingHTTPWhitespace(parameterValue);
  8454. if (parameterValue === "") {
  8455. continue;
  8456. }
  8457. }
  8458. if (parameterName.length > 0 &&
  8459. solelyContainsHTTPTokenCodePoints(parameterName) &&
  8460. soleyContainsHTTPQuotedStringTokenCodePoints(parameterValue) &&
  8461. !mimeType.parameters.has(parameterName)) {
  8462. mimeType.parameters.set(parameterName, parameterValue);
  8463. }
  8464. }
  8465. return mimeType;
  8466. };
  8467. }
  8468. // lib/mime-type.js
  8469. {
  8470. const parse = parser;
  8471. const serialize = serializer;
  8472. const {
  8473. asciiLowercase,
  8474. solelyContainsHTTPTokenCodePoints,
  8475. soleyContainsHTTPQuotedStringTokenCodePoints
  8476. } = utils;
  8477. MIMEType = class MIMEType {
  8478. constructor(string) {
  8479. string = String(string);
  8480. const result = parse(string);
  8481. if (result === null) {
  8482. throw new Error(`Could not parse MIME type string "${string}"`);
  8483. }
  8484. this._type = result.type;
  8485. this._subtype = result.subtype;
  8486. this._parameters = new MIMETypeParameters(result.parameters);
  8487. }
  8488. static parse(string) {
  8489. try {
  8490. return new this(string);
  8491. } catch (e) {
  8492. return null;
  8493. }
  8494. }
  8495. get essence() {
  8496. return `${this.type}/${this.subtype}`;
  8497. }
  8498. get type() {
  8499. return this._type;
  8500. }
  8501. set type(value) {
  8502. value = asciiLowercase(String(value));
  8503. if (value.length === 0) {
  8504. throw new Error("Invalid type: must be a non-empty string");
  8505. }
  8506. if (!solelyContainsHTTPTokenCodePoints(value)) {
  8507. throw new Error(`Invalid type ${value}: must contain only HTTP token code points`);
  8508. }
  8509. this._type = value;
  8510. }
  8511. get subtype() {
  8512. return this._subtype;
  8513. }
  8514. set subtype(value) {
  8515. value = asciiLowercase(String(value));
  8516. if (value.length === 0) {
  8517. throw new Error("Invalid subtype: must be a non-empty string");
  8518. }
  8519. if (!solelyContainsHTTPTokenCodePoints(value)) {
  8520. throw new Error(`Invalid subtype ${value}: must contain only HTTP token code points`);
  8521. }
  8522. this._subtype = value;
  8523. }
  8524. get parameters() {
  8525. return this._parameters;
  8526. }
  8527. toString() {
  8528. // The serialize function works on both "MIME type records" (i.e. the results of parse) and on this class, since
  8529. // this class's interface is identical.
  8530. return serialize(this);
  8531. }
  8532. isJavaScript({ allowParameters = false } = {}) {
  8533. switch (this._type) {
  8534. case "text": {
  8535. switch (this._subtype) {
  8536. case "ecmascript":
  8537. case "javascript":
  8538. case "javascript1.0":
  8539. case "javascript1.1":
  8540. case "javascript1.2":
  8541. case "javascript1.3":
  8542. case "javascript1.4":
  8543. case "javascript1.5":
  8544. case "jscript":
  8545. case "livescript":
  8546. case "x-ecmascript":
  8547. case "x-javascript": {
  8548. return allowParameters || this._parameters.size === 0;
  8549. }
  8550. default: {
  8551. return false;
  8552. }
  8553. }
  8554. }
  8555. case "application": {
  8556. switch (this._subtype) {
  8557. case "ecmascript":
  8558. case "javascript":
  8559. case "x-ecmascript":
  8560. case "x-javascript": {
  8561. return allowParameters || this._parameters.size === 0;
  8562. }
  8563. default: {
  8564. return false;
  8565. }
  8566. }
  8567. }
  8568. default: {
  8569. return false;
  8570. }
  8571. }
  8572. }
  8573. isXML() {
  8574. return (this._subtype === "xml" && (this._type === "text" || this._type === "application")) ||
  8575. this._subtype.endsWith("+xml");
  8576. }
  8577. isHTML() {
  8578. return this._subtype === "html" && this._type === "text";
  8579. }
  8580. };
  8581. class MIMETypeParameters {
  8582. constructor(map) {
  8583. this._map = map;
  8584. }
  8585. get size() {
  8586. return this._map.size;
  8587. }
  8588. get(name) {
  8589. name = asciiLowercase(String(name));
  8590. return this._map.get(name);
  8591. }
  8592. has(name) {
  8593. name = asciiLowercase(String(name));
  8594. return this._map.has(name);
  8595. }
  8596. set(name, value) {
  8597. name = asciiLowercase(String(name));
  8598. value = String(value);
  8599. if (!solelyContainsHTTPTokenCodePoints(name)) {
  8600. throw new Error(`Invalid MIME type parameter name "${name}": only HTTP token code points are valid.`);
  8601. }
  8602. if (!soleyContainsHTTPQuotedStringTokenCodePoints(value)) {
  8603. throw new Error(`Invalid MIME type parameter value "${value}": only HTTP quoted-string token code points are valid.`);
  8604. }
  8605. return this._map.set(name, value);
  8606. }
  8607. clear() {
  8608. this._map.clear();
  8609. }
  8610. delete(name) {
  8611. name = asciiLowercase(String(name));
  8612. return this._map.delete(name);
  8613. }
  8614. forEach(callbackFn, thisArg) {
  8615. this._map.forEach(callbackFn, thisArg);
  8616. }
  8617. keys() {
  8618. return this._map.keys();
  8619. }
  8620. values() {
  8621. return this._map.values();
  8622. }
  8623. entries() {
  8624. return this._map.entries();
  8625. }
  8626. [Symbol.iterator]() {
  8627. return this._map[Symbol.iterator]();
  8628. }
  8629. }
  8630. }
  8631. /*
  8632. * Copyright 2010-2022 Gildas Lormeau
  8633. * contact : gildas.lormeau <at> gmail.com
  8634. *
  8635. * This file is part of SingleFile.
  8636. *
  8637. * The code in this file is free software: you can redistribute it and/or
  8638. * modify it under the terms of the GNU Affero General Public License
  8639. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  8640. * of the License, or (at your option) any later version.
  8641. *
  8642. * The code in this file is distributed in the hope that it will be useful,
  8643. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  8644. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  8645. * General Public License for more details.
  8646. *
  8647. * As additional permission under GNU AGPL version 3 section 7, you may
  8648. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  8649. * AGPL normally required by section 4, provided you include this license
  8650. * notice and a URL through which recipients can access the Corresponding
  8651. * Source.
  8652. */
  8653. var index$1 = /*#__PURE__*/Object.freeze({
  8654. __proto__: null,
  8655. zip: zip$1,
  8656. fontPropertyParser: cssFontPropertyParser,
  8657. mediaQueryParser: cssMediaQueryParser,
  8658. cssMinifier: cssMinifier,
  8659. cssUnescape: cssUnescape,
  8660. srcsetParser: htmlSrcsetParser,
  8661. get MIMEType () { return MIMEType; }
  8662. });
  8663. /*
  8664. * Copyright 2010-2022 Gildas Lormeau
  8665. * contact : gildas.lormeau <at> gmail.com
  8666. *
  8667. * This file is part of SingleFile.
  8668. *
  8669. * The code in this file is free software: you can redistribute it and/or
  8670. * modify it under the terms of the GNU Affero General Public License
  8671. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  8672. * of the License, or (at your option) any later version.
  8673. *
  8674. * The code in this file is distributed in the hope that it will be useful,
  8675. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  8676. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  8677. * General Public License for more details.
  8678. *
  8679. * As additional permission under GNU AGPL version 3 section 7, you may
  8680. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  8681. * AGPL normally required by section 4, provided you include this license
  8682. * notice and a URL through which recipients can access the Corresponding
  8683. * Source.
  8684. */
  8685. const helper$1 = {
  8686. normalizeFontFamily,
  8687. flatten,
  8688. getFontWeight,
  8689. removeQuotes: removeQuotes$1
  8690. };
  8691. const REGEXP_COMMA = /\s*,\s*/;
  8692. const REGEXP_DASH = /-/;
  8693. const REGEXP_QUESTION_MARK = /\?/g;
  8694. const REGEXP_STARTS_U_PLUS = /^U\+/i;
  8695. const VALID_FONT_STYLES = [/^normal$/, /^italic$/, /^oblique$/, /^oblique\s+/];
  8696. function process$5(doc, stylesheets, styles, options) {
  8697. const stats = { rules: { processed: 0, discarded: 0 }, fonts: { processed: 0, discarded: 0 } };
  8698. const fontsInfo = { declared: [], used: [] };
  8699. const workStyleElement = doc.createElement("style");
  8700. let docContent = "";
  8701. doc.body.appendChild(workStyleElement);
  8702. stylesheets.forEach(stylesheetInfo => {
  8703. const cssRules = stylesheetInfo.stylesheet.children;
  8704. if (cssRules) {
  8705. stats.processed += cssRules.size;
  8706. stats.discarded += cssRules.size;
  8707. getFontsInfo(cssRules, fontsInfo);
  8708. docContent = getRulesTextContent(doc, cssRules, workStyleElement, docContent);
  8709. }
  8710. });
  8711. styles.forEach(declarations => {
  8712. const fontFamilyNames = getFontFamilyNames(declarations);
  8713. if (fontFamilyNames.length) {
  8714. fontsInfo.used.push(fontFamilyNames);
  8715. }
  8716. docContent = getDeclarationsTextContent(declarations.children, workStyleElement, docContent);
  8717. });
  8718. workStyleElement.remove();
  8719. docContent += doc.body.innerText;
  8720. if (globalThis.getComputedStyle && options.doc) {
  8721. fontsInfo.used = fontsInfo.used.map(fontNames => fontNames.map(familyName => {
  8722. const matchedVar = familyName.match(/^var\((--.*)\)$/);
  8723. if (matchedVar && matchedVar[1]) {
  8724. const computedFamilyName = globalThis.getComputedStyle(options.doc.body).getPropertyValue(matchedVar[1]);
  8725. return (computedFamilyName && computedFamilyName.split(",").map(name => helper$1.normalizeFontFamily(name))) || familyName;
  8726. }
  8727. return familyName;
  8728. }));
  8729. fontsInfo.used = fontsInfo.used.map(fontNames => helper$1.flatten(fontNames));
  8730. }
  8731. const variableFound = fontsInfo.used.find(fontNames => fontNames.find(fontName => fontName.match(/^var\(--/)));
  8732. let unusedFonts, filteredUsedFonts;
  8733. if (variableFound) {
  8734. unusedFonts = [];
  8735. } else {
  8736. filteredUsedFonts = new Map();
  8737. fontsInfo.used.forEach(fontNames => fontNames.forEach(familyName => {
  8738. if (fontsInfo.declared.find(fontInfo => fontInfo.fontFamily == familyName)) {
  8739. const optionalData = options.usedFonts && options.usedFonts.filter(fontInfo => fontInfo[0] == familyName);
  8740. if (optionalData && optionalData.length) {
  8741. filteredUsedFonts.set(familyName, optionalData);
  8742. }
  8743. }
  8744. }));
  8745. unusedFonts = fontsInfo.declared.filter(fontInfo => !filteredUsedFonts.has(fontInfo.fontFamily));
  8746. }
  8747. stylesheets.forEach(stylesheetInfo => {
  8748. const cssRules = stylesheetInfo.stylesheet.children;
  8749. if (cssRules) {
  8750. filterUnusedFonts(cssRules, fontsInfo.declared, unusedFonts, filteredUsedFonts, docContent);
  8751. stats.rules.discarded -= cssRules.size;
  8752. }
  8753. });
  8754. return stats;
  8755. }
  8756. function getFontsInfo(cssRules, fontsInfo) {
  8757. cssRules.forEach(ruleData => {
  8758. if (ruleData.type == "Atrule" && (ruleData.name == "media" || ruleData.name == "supports") && ruleData.block && ruleData.block.children) {
  8759. getFontsInfo(ruleData.block.children, fontsInfo);
  8760. } else if (ruleData.type == "Rule") {
  8761. const fontFamilyNames = getFontFamilyNames(ruleData.block);
  8762. if (fontFamilyNames.length) {
  8763. fontsInfo.used.push(fontFamilyNames);
  8764. }
  8765. } else {
  8766. if (ruleData.type == "Atrule" && ruleData.name == "font-face") {
  8767. const fontFamily = helper$1.normalizeFontFamily(getDeclarationValue(ruleData.block.children, "font-family"));
  8768. if (fontFamily) {
  8769. const fontWeight = getDeclarationValue(ruleData.block.children, "font-weight") || "400";
  8770. const fontStyle = getDeclarationValue(ruleData.block.children, "font-style") || "normal";
  8771. const fontVariant = getDeclarationValue(ruleData.block.children, "font-variant") || "normal";
  8772. fontWeight.split(",").forEach(weightValue =>
  8773. fontsInfo.declared.push({ fontFamily, fontWeight: helper$1.getFontWeight(helper$1.removeQuotes(weightValue)), fontStyle, fontVariant }));
  8774. }
  8775. }
  8776. }
  8777. });
  8778. }
  8779. function filterUnusedFonts(cssRules, declaredFonts, unusedFonts, filteredUsedFonts, docContent) {
  8780. const removedRules = [];
  8781. for (let cssRule = cssRules.head; cssRule; cssRule = cssRule.next) {
  8782. const ruleData = cssRule.data;
  8783. if (ruleData.type == "Atrule" && (ruleData.name == "media" || ruleData.name == "supports") && ruleData.block && ruleData.block.children) {
  8784. filterUnusedFonts(ruleData.block.children, declaredFonts, unusedFonts, filteredUsedFonts, docContent);
  8785. } else if (ruleData.type == "Atrule" && ruleData.name == "font-face") {
  8786. const fontFamily = helper$1.normalizeFontFamily(getDeclarationValue(ruleData.block.children, "font-family"));
  8787. if (fontFamily) {
  8788. const unicodeRange = getDeclarationValue(ruleData.block.children, "unicode-range");
  8789. if (unusedFonts.find(fontInfo => fontInfo.fontFamily == fontFamily) || !testUnicodeRange(docContent, unicodeRange) || !testUsedFont(ruleData, fontFamily, declaredFonts, filteredUsedFonts)) {
  8790. removedRules.push(cssRule);
  8791. }
  8792. }
  8793. const removedDeclarations = [];
  8794. for (let declaration = ruleData.block.children.head; declaration; declaration = declaration.next) {
  8795. if (declaration.data.property == "font-display") {
  8796. removedDeclarations.push(declaration);
  8797. }
  8798. }
  8799. if (removedDeclarations.length) {
  8800. removedDeclarations.forEach(removedDeclaration => ruleData.block.children.remove(removedDeclaration));
  8801. }
  8802. }
  8803. }
  8804. removedRules.forEach(cssRule => cssRules.remove(cssRule));
  8805. }
  8806. function testUsedFont(ruleData, familyName, declaredFonts, filteredUsedFonts) {
  8807. let test;
  8808. const optionalUsedFonts = filteredUsedFonts && filteredUsedFonts.get(familyName);
  8809. if (optionalUsedFonts && optionalUsedFonts.length) {
  8810. let fontStyle = getDeclarationValue(ruleData.block.children, "font-style") || "normal";
  8811. if (VALID_FONT_STYLES.find(rule => fontStyle.trim().match(rule))) {
  8812. const fontWeight = helper$1.getFontWeight(getDeclarationValue(ruleData.block.children, "font-weight") || "400");
  8813. const declaredFontsWeights = declaredFonts
  8814. .filter(fontInfo => fontInfo.fontFamily == familyName && fontInfo.fontStyle == fontStyle)
  8815. .map(fontInfo => fontInfo.fontWeight)
  8816. .sort((weight1, weight2) => Number.parseInt(weight1, 10) - Number.parseInt(weight2, 10));
  8817. let usedFontWeights = optionalUsedFonts.map(fontInfo => getUsedFontWeight(fontInfo, fontStyle, declaredFontsWeights));
  8818. test = testFontweight(fontWeight, usedFontWeights);
  8819. if (!test) {
  8820. usedFontWeights = optionalUsedFonts.map(fontInfo => {
  8821. fontInfo = Array.from(fontInfo);
  8822. fontInfo[2] = "normal";
  8823. return getUsedFontWeight(fontInfo, fontStyle, declaredFontsWeights);
  8824. });
  8825. }
  8826. test = testFontweight(fontWeight, usedFontWeights);
  8827. } else {
  8828. test = true;
  8829. }
  8830. } else {
  8831. test = true;
  8832. }
  8833. return test;
  8834. }
  8835. function testFontweight(fontWeight, usedFontWeights) {
  8836. let test;
  8837. for (const value of fontWeight.split(/[ ,]/)) {
  8838. test = test || usedFontWeights.includes(helper$1.getFontWeight(helper$1.removeQuotes(value)));
  8839. }
  8840. return test;
  8841. }
  8842. function getDeclarationValue(declarations, propertyName) {
  8843. let property;
  8844. if (declarations) {
  8845. property = declarations.filter(declaration => declaration.property == propertyName).tail;
  8846. }
  8847. if (property) {
  8848. try {
  8849. return helper$1.removeQuotes(gb(property.data.value)).toLowerCase();
  8850. } catch (error) {
  8851. // ignored
  8852. }
  8853. }
  8854. }
  8855. function getFontFamilyNames(declarations) {
  8856. let fontFamilyName = declarations.children.filter(node => node.property == "font-family").tail;
  8857. let fontFamilyNames = [];
  8858. if (fontFamilyName) {
  8859. if (fontFamilyName.data.value.children) {
  8860. parseFamilyNames(fontFamilyName.data.value, fontFamilyNames);
  8861. } else {
  8862. fontFamilyName = gb(fontFamilyName.data.value);
  8863. if (fontFamilyName) {
  8864. fontFamilyNames.push(helper$1.normalizeFontFamily(fontFamilyName));
  8865. }
  8866. }
  8867. }
  8868. const font = declarations.children.filter(node => node.property == "font").tail;
  8869. if (font && font.data && font.data.value) {
  8870. try {
  8871. const parsedFont = parse(font.data.value);
  8872. parsedFont.family.forEach(familyName => fontFamilyNames.push(helper$1.normalizeFontFamily(familyName)));
  8873. } catch (error) {
  8874. // ignored
  8875. }
  8876. }
  8877. return fontFamilyNames;
  8878. }
  8879. function parseFamilyNames(fontFamilyNameTokenData, fontFamilyNames) {
  8880. let nextToken = fontFamilyNameTokenData.children.head;
  8881. while (nextToken) {
  8882. if (nextToken.data.type == "Identifier") {
  8883. let familyName = nextToken.data.name;
  8884. let nextIdentifierToken = nextToken.next;
  8885. while (nextIdentifierToken && nextIdentifierToken.data.type != "Operator" && nextIdentifierToken.data.value != ",") {
  8886. familyName += " " + nextIdentifierToken.data.name;
  8887. nextIdentifierToken = nextIdentifierToken.next;
  8888. }
  8889. fontFamilyNames.push(helper$1.normalizeFontFamily(familyName));
  8890. nextToken = nextToken.next;
  8891. } else if (nextToken.data.type == "Function" && nextToken.data.name == "var" && nextToken.data.children) {
  8892. const varName = nextToken.data.children.head.data.name;
  8893. fontFamilyNames.push(helper$1.normalizeFontFamily("var(" + varName + ")"));
  8894. let nextValueToken = nextToken.data.children.head.next;
  8895. while (nextValueToken && nextValueToken.data.type == "Operator" && nextValueToken.data.value == ",") {
  8896. nextValueToken = nextValueToken.next;
  8897. }
  8898. const fallbackToken = nextValueToken;
  8899. if (fallbackToken) {
  8900. if (fallbackToken.data.children) {
  8901. parseFamilyNames(fallbackToken.data, fontFamilyNames);
  8902. } else {
  8903. fontFamilyNames.push(helper$1.normalizeFontFamily(fallbackToken.data.value));
  8904. }
  8905. }
  8906. nextToken = nextToken.next;
  8907. } else if (nextToken.data.type == "String") {
  8908. fontFamilyNames.push(helper$1.normalizeFontFamily(nextToken.data.value));
  8909. nextToken = nextToken.next;
  8910. } else if (nextToken.data.type == "Operator" && nextToken.data.value == ",") {
  8911. nextToken = nextToken.next;
  8912. }
  8913. }
  8914. }
  8915. function getUsedFontWeight(fontInfo, fontStyle, fontWeights) {
  8916. let foundWeight;
  8917. fontWeights = fontWeights.map(weight => String(Number.parseInt(weight, 10)));
  8918. if (fontInfo[2] == fontStyle) {
  8919. let fontWeight = Number(fontInfo[1]);
  8920. if (fontWeights.length > 1) {
  8921. if (fontWeight >= 400 && fontWeight <= 500) {
  8922. foundWeight = fontWeights.find(weight => weight >= fontWeight && weight <= 500);
  8923. if (!foundWeight) {
  8924. foundWeight = findDescendingFontWeight(fontWeight, fontWeights);
  8925. }
  8926. if (!foundWeight) {
  8927. foundWeight = findAscendingFontWeight(fontWeight, fontWeights);
  8928. }
  8929. }
  8930. if (fontWeight < 400) {
  8931. foundWeight = fontWeights.slice().reverse().find(weight => weight <= fontWeight);
  8932. if (!foundWeight) {
  8933. foundWeight = findAscendingFontWeight(fontWeight, fontWeights);
  8934. }
  8935. }
  8936. if (fontWeight > 500) {
  8937. foundWeight = fontWeights.find(weight => weight >= fontWeight);
  8938. if (!foundWeight) {
  8939. foundWeight = findDescendingFontWeight(fontWeight, fontWeights);
  8940. }
  8941. }
  8942. } else {
  8943. foundWeight = fontWeights[0];
  8944. }
  8945. }
  8946. return foundWeight;
  8947. }
  8948. function findDescendingFontWeight(fontWeight, fontWeights) {
  8949. return fontWeights.slice().reverse().find(weight => weight < fontWeight);
  8950. }
  8951. function findAscendingFontWeight(fontWeight, fontWeights) {
  8952. return fontWeights.find(weight => weight > fontWeight);
  8953. }
  8954. function getRulesTextContent(doc, cssRules, workStylesheet, content) {
  8955. cssRules.forEach(ruleData => {
  8956. if (ruleData.block && ruleData.block.children && ruleData.prelude && ruleData.prelude.children) {
  8957. if (ruleData.type == "Atrule" && (ruleData.name == "media" || ruleData.name == "supports")) {
  8958. content = getRulesTextContent(doc, ruleData.block.children, workStylesheet, content);
  8959. } else if (ruleData.type == "Rule") {
  8960. content = getDeclarationsTextContent(ruleData.block.children, workStylesheet, content);
  8961. }
  8962. }
  8963. });
  8964. return content;
  8965. }
  8966. function getDeclarationsTextContent(declarations, workStylesheet, content) {
  8967. const contentText = getDeclarationUnescapedValue(declarations, "content", workStylesheet);
  8968. const quotesText = getDeclarationUnescapedValue(declarations, "quotes", workStylesheet);
  8969. if (!content.includes(contentText)) {
  8970. content += contentText;
  8971. }
  8972. if (!content.includes(quotesText)) {
  8973. content += quotesText;
  8974. }
  8975. return content;
  8976. }
  8977. function getDeclarationUnescapedValue(declarations, property, workStylesheet) {
  8978. const rawValue = getDeclarationValue(declarations, property) || "";
  8979. if (rawValue) {
  8980. workStylesheet.textContent = "tmp { content:\"" + rawValue + "\"}";
  8981. if (workStylesheet.sheet && workStylesheet.sheet.cssRules) {
  8982. return helper$1.removeQuotes(workStylesheet.sheet.cssRules[0].style.getPropertyValue("content"));
  8983. } else {
  8984. return rawValue;
  8985. }
  8986. }
  8987. return "";
  8988. }
  8989. function testUnicodeRange(docContent, unicodeRange) {
  8990. if (unicodeRange) {
  8991. const unicodeRanges = unicodeRange.split(REGEXP_COMMA);
  8992. let invalid;
  8993. const result = unicodeRanges.filter(rangeValue => {
  8994. const range = rangeValue.split(REGEXP_DASH);
  8995. let regExpString;
  8996. if (range.length == 2) {
  8997. range[0] = transformRange(range[0]);
  8998. regExpString = "[" + range[0] + "-" + transformRange("U+" + range[1]) + "]";
  8999. }
  9000. if (range.length == 1) {
  9001. if (range[0].includes("?")) {
  9002. const firstRange = transformRange(range[0]);
  9003. const secondRange = firstRange;
  9004. regExpString = "[" + firstRange.replace(REGEXP_QUESTION_MARK, "0") + "-" + secondRange.replace(REGEXP_QUESTION_MARK, "F") + "]";
  9005. } else if (range[0]) {
  9006. regExpString = "[" + transformRange(range[0]) + "]";
  9007. }
  9008. }
  9009. if (regExpString) {
  9010. try {
  9011. return (new RegExp(regExpString, "u")).test(docContent);
  9012. } catch (error) {
  9013. invalid = true;
  9014. return false;
  9015. }
  9016. }
  9017. return true;
  9018. });
  9019. return !invalid && (!unicodeRanges.length || result.length);
  9020. }
  9021. return true;
  9022. }
  9023. function transformRange(range) {
  9024. range = range.replace(REGEXP_STARTS_U_PLUS, "");
  9025. while (range.length < 6) {
  9026. range = "0" + range;
  9027. }
  9028. return "\\u{" + range + "}";
  9029. }
  9030. var cssFontsMinifier = /*#__PURE__*/Object.freeze({
  9031. __proto__: null,
  9032. process: process$5
  9033. });
  9034. /*
  9035. * Copyright 2010-2022 Gildas Lormeau
  9036. * contact : gildas.lormeau <at> gmail.com
  9037. *
  9038. * This file is part of SingleFile.
  9039. *
  9040. * The code in this file is free software: you can redistribute it and/or
  9041. * modify it under the terms of the GNU Affero General Public License
  9042. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  9043. * of the License, or (at your option) any later version.
  9044. *
  9045. * The code in this file is distributed in the hope that it will be useful,
  9046. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9047. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  9048. * General Public License for more details.
  9049. *
  9050. * As additional permission under GNU AGPL version 3 section 7, you may
  9051. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  9052. * AGPL normally required by section 4, provided you include this license
  9053. * notice and a URL through which recipients can access the Corresponding
  9054. * Source.
  9055. */
  9056. const MEDIA_ALL$3 = "all";
  9057. const IGNORED_PSEUDO_ELEMENTS = ["after", "before", "first-letter", "first-line", "placeholder", "selection", "part", "marker"];
  9058. const SINGLE_FILE_HIDDEN_CLASS_NAME = "sf-hidden";
  9059. const DISPLAY_STYLE = "display";
  9060. const REGEXP_VENDOR_IDENTIFIER = /-(ms|webkit|moz|o)-/;
  9061. class MatchedRules {
  9062. constructor(doc, stylesheets, styles) {
  9063. this.doc = doc;
  9064. this.mediaAllInfo = createMediaInfo(MEDIA_ALL$3);
  9065. const matchedElementsCache = new Map();
  9066. let sheetIndex = 0;
  9067. const workStyleSheet = doc.createElement("style");
  9068. doc.body.appendChild(workStyleSheet);
  9069. const workStyleElement = doc.createElement("span");
  9070. doc.body.appendChild(workStyleElement);
  9071. stylesheets.forEach(stylesheetInfo => {
  9072. if (!stylesheetInfo.scoped) {
  9073. const cssRules = stylesheetInfo.stylesheet.children;
  9074. if (cssRules) {
  9075. if (stylesheetInfo.mediaText && stylesheetInfo.mediaText != MEDIA_ALL$3) {
  9076. const mediaInfo = createMediaInfo(stylesheetInfo.mediaText);
  9077. this.mediaAllInfo.medias.set("style-" + sheetIndex + "-" + stylesheetInfo.mediaText, mediaInfo);
  9078. getMatchedElementsRules(doc, cssRules, mediaInfo, sheetIndex, styles, matchedElementsCache, workStyleSheet);
  9079. } else {
  9080. getMatchedElementsRules(doc, cssRules, this.mediaAllInfo, sheetIndex, styles, matchedElementsCache, workStyleSheet);
  9081. }
  9082. }
  9083. }
  9084. sheetIndex++;
  9085. });
  9086. sortRules(this.mediaAllInfo);
  9087. computeCascade(this.mediaAllInfo, [], this.mediaAllInfo, workStyleSheet, workStyleElement);
  9088. workStyleSheet.remove();
  9089. workStyleElement.remove();
  9090. }
  9091. getMediaAllInfo() {
  9092. return this.mediaAllInfo;
  9093. }
  9094. }
  9095. function getMediaAllInfo(doc, stylesheets, styles) {
  9096. return new MatchedRules(doc, stylesheets, styles).getMediaAllInfo();
  9097. }
  9098. function createMediaInfo(media) {
  9099. const mediaInfo = { media: media, elements: new Map(), medias: new Map(), rules: new Map(), pseudoRules: new Map() };
  9100. if (media == MEDIA_ALL$3) {
  9101. mediaInfo.matchedStyles = new Map();
  9102. }
  9103. return mediaInfo;
  9104. }
  9105. function getMatchedElementsRules(doc, cssRules, mediaInfo, sheetIndex, styles, matchedElementsCache, workStylesheet) {
  9106. let mediaIndex = 0;
  9107. let ruleIndex = 0;
  9108. cssRules.forEach(ruleData => {
  9109. if (ruleData.block && ruleData.block.children && ruleData.prelude && ruleData.prelude.children) {
  9110. if (ruleData.type == "Atrule" && ruleData.name == "media") {
  9111. const mediaText = gb(ruleData.prelude);
  9112. const ruleMediaInfo = createMediaInfo(mediaText);
  9113. mediaInfo.medias.set("rule-" + sheetIndex + "-" + mediaIndex + "-" + mediaText, ruleMediaInfo);
  9114. mediaIndex++;
  9115. getMatchedElementsRules(doc, ruleData.block.children, ruleMediaInfo, sheetIndex, styles, matchedElementsCache, workStylesheet);
  9116. } else if (ruleData.type == "Rule") {
  9117. const selectors = ruleData.prelude.children.toArray();
  9118. const selectorsText = ruleData.prelude.children.toArray().map(selector => gb(selector));
  9119. const ruleInfo = { ruleData, mediaInfo, ruleIndex, sheetIndex, matchedSelectors: new Set(), declarations: new Set(), selectors, selectorsText };
  9120. if (!invalidSelector(selectorsText.join(","), workStylesheet) || selectorsText.find(selectorText => selectorText.includes("|"))) {
  9121. for (let selector = ruleData.prelude.children.head, selectorIndex = 0; selector; selector = selector.next, selectorIndex++) {
  9122. const selectorText = selectorsText[selectorIndex];
  9123. const selectorInfo = { selector, selectorText, ruleInfo };
  9124. getMatchedElementsSelector(doc, selectorInfo, styles, matchedElementsCache);
  9125. }
  9126. }
  9127. ruleIndex++;
  9128. }
  9129. }
  9130. });
  9131. }
  9132. function invalidSelector(selectorText, workStylesheet) {
  9133. workStylesheet.textContent = selectorText + "{}";
  9134. return workStylesheet.sheet ? !workStylesheet.sheet.cssRules.length : workStylesheet.sheet;
  9135. }
  9136. function getMatchedElementsSelector(doc, selectorInfo, styles, matchedElementsCache) {
  9137. const filteredSelectorText = getFilteredSelector(selectorInfo.selector, selectorInfo.selectorText);
  9138. const selectorText = filteredSelectorText != selectorInfo.selectorText ? filteredSelectorText : selectorInfo.selectorText;
  9139. const cachedMatchedElements = matchedElementsCache.get(selectorText);
  9140. let matchedElements = cachedMatchedElements;
  9141. if (!matchedElements) {
  9142. try {
  9143. matchedElements = doc.querySelectorAll(selectorText);
  9144. if (selectorText != "." + SINGLE_FILE_HIDDEN_CLASS_NAME) {
  9145. matchedElements = Array.from(doc.querySelectorAll(selectorText)).filter(matchedElement =>
  9146. !matchedElement.classList.contains(SINGLE_FILE_HIDDEN_CLASS_NAME) &&
  9147. (matchedElement.style.getPropertyValue(DISPLAY_STYLE) != "none" || matchedElement.style.getPropertyPriority("display") != "important")
  9148. );
  9149. }
  9150. } catch (error) {
  9151. // ignored
  9152. }
  9153. }
  9154. if (matchedElements) {
  9155. if (!cachedMatchedElements) {
  9156. matchedElementsCache.set(selectorText, matchedElements);
  9157. }
  9158. if (matchedElements.length) {
  9159. if (filteredSelectorText == selectorInfo.selectorText) {
  9160. matchedElements.forEach(element => addRule(element, selectorInfo, styles));
  9161. } else {
  9162. let pseudoSelectors = selectorInfo.ruleInfo.mediaInfo.pseudoRules.get(selectorInfo.ruleInfo.ruleData);
  9163. if (!pseudoSelectors) {
  9164. pseudoSelectors = new Set();
  9165. selectorInfo.ruleInfo.mediaInfo.pseudoRules.set(selectorInfo.ruleInfo.ruleData, pseudoSelectors);
  9166. }
  9167. pseudoSelectors.add(selectorInfo.selectorText);
  9168. }
  9169. }
  9170. }
  9171. }
  9172. function getFilteredSelector(selector, selectorText) {
  9173. const removedSelectors = [];
  9174. let namespaceFound;
  9175. selector = { data: db(gb(selector.data), { context: "selector" }) };
  9176. filterNamespace(selector);
  9177. if (namespaceFound) {
  9178. selectorText = gb(selector.data).trim();
  9179. }
  9180. filterPseudoClasses(selector);
  9181. if (removedSelectors.length) {
  9182. removedSelectors.forEach(({ parentSelector, selector }) => {
  9183. if (parentSelector.data.children.size == 0 || !selector.prev || selector.prev.data.type == "Combinator" || selector.prev.data.type == "WhiteSpace") {
  9184. parentSelector.data.children.replace(selector, db("*", { context: "selector" }).children.head);
  9185. } else {
  9186. parentSelector.data.children.remove(selector);
  9187. }
  9188. });
  9189. selectorText = gb(selector.data).trim();
  9190. }
  9191. return selectorText;
  9192. function filterPseudoClasses(selector, parentSelector) {
  9193. if (selector.data.children) {
  9194. for (let childSelector = selector.data.children.head; childSelector; childSelector = childSelector.next) {
  9195. filterPseudoClasses(childSelector, selector);
  9196. }
  9197. }
  9198. if ((selector.data.type == "PseudoClassSelector") ||
  9199. (selector.data.type == "PseudoElementSelector" && (testVendorPseudo(selector) || IGNORED_PSEUDO_ELEMENTS.includes(selector.data.name)))) {
  9200. removedSelectors.push({ parentSelector, selector });
  9201. }
  9202. }
  9203. function filterNamespace(selector) {
  9204. if (selector.data.children) {
  9205. for (let childSelector = selector.data.children.head; childSelector; childSelector = childSelector.next) {
  9206. filterNamespace(childSelector);
  9207. }
  9208. }
  9209. if (selector.data.type == "TypeSelector" && selector.data.name.includes("|")) {
  9210. namespaceFound = true;
  9211. selector.data.name = selector.data.name.substring(selector.data.name.lastIndexOf("|") + 1);
  9212. }
  9213. }
  9214. function testVendorPseudo(selector) {
  9215. const name = selector.data.name;
  9216. return name.startsWith("-") || name.startsWith("\\-");
  9217. }
  9218. }
  9219. function addRule(element, selectorInfo, styles) {
  9220. const mediaInfo = selectorInfo.ruleInfo.mediaInfo;
  9221. const elementStyle = styles.get(element);
  9222. let elementInfo = mediaInfo.elements.get(element);
  9223. if (!elementInfo) {
  9224. elementInfo = [];
  9225. if (elementStyle) {
  9226. elementInfo.push({ styleInfo: { styleData: elementStyle, declarations: new Set() } });
  9227. }
  9228. mediaInfo.elements.set(element, elementInfo);
  9229. }
  9230. const specificity = computeSpecificity(selectorInfo.selector.data);
  9231. specificity.ruleIndex = selectorInfo.ruleInfo.ruleIndex;
  9232. specificity.sheetIndex = selectorInfo.ruleInfo.sheetIndex;
  9233. selectorInfo.specificity = specificity;
  9234. elementInfo.push(selectorInfo);
  9235. }
  9236. function computeCascade(mediaInfo, parentMediaInfo, mediaAllInfo, workStylesheet, workStyleElement) {
  9237. mediaInfo.elements.forEach((elementInfo/*, element*/) =>
  9238. getDeclarationsInfo(elementInfo, workStylesheet, workStyleElement/*, element*/).forEach((declarationsInfo, property) => {
  9239. if (declarationsInfo.selectorInfo.ruleInfo || mediaInfo == mediaAllInfo) {
  9240. let info;
  9241. if (declarationsInfo.selectorInfo.ruleInfo) {
  9242. info = declarationsInfo.selectorInfo.ruleInfo;
  9243. const ruleData = info.ruleData;
  9244. const ascendantMedia = [mediaInfo, ...parentMediaInfo].find(media => media.rules.get(ruleData)) || mediaInfo;
  9245. ascendantMedia.rules.set(ruleData, info);
  9246. if (ruleData) {
  9247. info.matchedSelectors.add(declarationsInfo.selectorInfo.selectorText);
  9248. }
  9249. } else {
  9250. info = declarationsInfo.selectorInfo.styleInfo;
  9251. const styleData = info.styleData;
  9252. const matchedStyleInfo = mediaAllInfo.matchedStyles.get(styleData);
  9253. if (!matchedStyleInfo) {
  9254. mediaAllInfo.matchedStyles.set(styleData, info);
  9255. }
  9256. }
  9257. if (!info.declarations.has(property)) {
  9258. info.declarations.add(property);
  9259. }
  9260. }
  9261. }));
  9262. delete mediaInfo.elements;
  9263. mediaInfo.medias.forEach(childMediaInfo => computeCascade(childMediaInfo, [mediaInfo, ...parentMediaInfo], mediaAllInfo, workStylesheet, workStyleElement));
  9264. }
  9265. function getDeclarationsInfo(elementInfo, workStylesheet, workStyleElement/*, element*/) {
  9266. const declarationsInfo = new Map();
  9267. const processedProperties = new Set();
  9268. elementInfo.forEach(selectorInfo => {
  9269. let declarations;
  9270. if (selectorInfo.styleInfo) {
  9271. declarations = selectorInfo.styleInfo.styleData.children;
  9272. } else {
  9273. declarations = selectorInfo.ruleInfo.ruleData.block.children;
  9274. }
  9275. processDeclarations(declarationsInfo, declarations, selectorInfo, processedProperties, workStylesheet, workStyleElement);
  9276. });
  9277. return declarationsInfo;
  9278. }
  9279. function processDeclarations(declarationsInfo, declarations, selectorInfo, processedProperties, workStylesheet, workStyleElement) {
  9280. for (let declaration = declarations.tail; declaration; declaration = declaration.prev) {
  9281. const declarationData = declaration.data;
  9282. const declarationText = gb(declarationData);
  9283. if (declarationData.type == "Declaration" &&
  9284. (declarationText.match(REGEXP_VENDOR_IDENTIFIER) || !processedProperties.has(declarationData.property) || declarationData.important) && !invalidDeclaration(declarationText, workStyleElement)) {
  9285. const declarationInfo = declarationsInfo.get(declarationData);
  9286. if (!declarationInfo || (declarationData.important && !declarationInfo.important)) {
  9287. declarationsInfo.set(declarationData, { selectorInfo, important: declarationData.important });
  9288. if (!declarationText.match(REGEXP_VENDOR_IDENTIFIER)) {
  9289. processedProperties.add(declarationData.property);
  9290. }
  9291. }
  9292. }
  9293. }
  9294. }
  9295. function invalidDeclaration(declarationText, workStyleElement) {
  9296. let invalidDeclaration;
  9297. workStyleElement.style = declarationText;
  9298. if (!workStyleElement.style.length) {
  9299. if (!declarationText.match(REGEXP_VENDOR_IDENTIFIER)) {
  9300. invalidDeclaration = true;
  9301. }
  9302. }
  9303. return invalidDeclaration;
  9304. }
  9305. function sortRules(media) {
  9306. media.elements.forEach(elementRules => elementRules.sort((ruleInfo1, ruleInfo2) =>
  9307. ruleInfo1.styleInfo && !ruleInfo2.styleInfo ? -1 :
  9308. !ruleInfo1.styleInfo && ruleInfo2.styleInfo ? 1 :
  9309. compareSpecificity(ruleInfo1.specificity, ruleInfo2.specificity)));
  9310. media.medias.forEach(sortRules);
  9311. }
  9312. function computeSpecificity(selector, specificity = { a: 0, b: 0, c: 0 }) {
  9313. if (selector.type == "IdSelector") {
  9314. specificity.a++;
  9315. }
  9316. if (selector.type == "ClassSelector" || selector.type == "AttributeSelector" || (selector.type == "PseudoClassSelector" && selector.name != "not")) {
  9317. specificity.b++;
  9318. }
  9319. if ((selector.type == "TypeSelector" && selector.name != "*") || selector.type == "PseudoElementSelector") {
  9320. specificity.c++;
  9321. }
  9322. if (selector.children) {
  9323. selector.children.forEach(selector => computeSpecificity(selector, specificity));
  9324. }
  9325. return specificity;
  9326. }
  9327. function compareSpecificity(specificity1, specificity2) {
  9328. if (specificity1.a > specificity2.a) {
  9329. return -1;
  9330. } else if (specificity1.a < specificity2.a) {
  9331. return 1;
  9332. } else if (specificity1.b > specificity2.b) {
  9333. return -1;
  9334. } else if (specificity1.b < specificity2.b) {
  9335. return 1;
  9336. } else if (specificity1.c > specificity2.c) {
  9337. return -1;
  9338. } else if (specificity1.c < specificity2.c) {
  9339. return 1;
  9340. } else if (specificity1.sheetIndex > specificity2.sheetIndex) {
  9341. return -1;
  9342. } else if (specificity1.sheetIndex < specificity2.sheetIndex) {
  9343. return 1;
  9344. } else if (specificity1.ruleIndex > specificity2.ruleIndex) {
  9345. return -1;
  9346. } else if (specificity1.ruleIndex < specificity2.ruleIndex) {
  9347. return 1;
  9348. } else {
  9349. return -1;
  9350. }
  9351. }
  9352. var cssMatchedRules = /*#__PURE__*/Object.freeze({
  9353. __proto__: null,
  9354. getMediaAllInfo: getMediaAllInfo
  9355. });
  9356. /*
  9357. * Copyright 2010-2022 Gildas Lormeau
  9358. * contact : gildas.lormeau <at> gmail.com
  9359. *
  9360. * This file is part of SingleFile.
  9361. *
  9362. * The code in this file is free software: you can redistribute it and/or
  9363. * modify it under the terms of the GNU Affero General Public License
  9364. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  9365. * of the License, or (at your option) any later version.
  9366. *
  9367. * The code in this file is distributed in the hope that it will be useful,
  9368. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9369. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  9370. * General Public License for more details.
  9371. *
  9372. * As additional permission under GNU AGPL version 3 section 7, you may
  9373. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  9374. * AGPL normally required by section 4, provided you include this license
  9375. * notice and a URL through which recipients can access the Corresponding
  9376. * Source.
  9377. */
  9378. const helper = {
  9379. flatten
  9380. };
  9381. const MEDIA_ALL$2 = "all";
  9382. const MEDIA_SCREEN = "screen";
  9383. function process$4(stylesheets) {
  9384. const stats = { processed: 0, discarded: 0 };
  9385. stylesheets.forEach((stylesheetInfo, element) => {
  9386. if (matchesMediaType(stylesheetInfo.mediaText || MEDIA_ALL$2, MEDIA_SCREEN) && stylesheetInfo.stylesheet.children) {
  9387. const removedRules = processRules$1(stylesheetInfo.stylesheet.children, stats);
  9388. removedRules.forEach(({ cssRules, cssRule }) => cssRules.remove(cssRule));
  9389. } else {
  9390. stylesheets.delete(element);
  9391. }
  9392. });
  9393. return stats;
  9394. }
  9395. function processRules$1(cssRules, stats, removedRules = []) {
  9396. for (let cssRule = cssRules.head; cssRule; cssRule = cssRule.next) {
  9397. const ruleData = cssRule.data;
  9398. if (ruleData.type == "Atrule" && ruleData.name == "media" && ruleData.block && ruleData.block.children && ruleData.prelude && ruleData.prelude.children) {
  9399. stats.processed++;
  9400. if (matchesMediaType(gb(ruleData.prelude), MEDIA_SCREEN)) {
  9401. processRules$1(ruleData.block.children, stats, removedRules);
  9402. } else {
  9403. removedRules.push({ cssRules, cssRule });
  9404. stats.discarded++;
  9405. }
  9406. }
  9407. }
  9408. return removedRules;
  9409. }
  9410. function matchesMediaType(mediaText, mediaType) {
  9411. const foundMediaTypes = helper.flatten(parseMediaList(mediaText).map(node => getMediaTypes(node, mediaType)));
  9412. return foundMediaTypes.find(mediaTypeInfo => (!mediaTypeInfo.not && (mediaTypeInfo.value == mediaType || mediaTypeInfo.value == MEDIA_ALL$2))
  9413. || (mediaTypeInfo.not && (mediaTypeInfo.value == MEDIA_ALL$2 || mediaTypeInfo.value != mediaType)));
  9414. }
  9415. function getMediaTypes(parentNode, mediaType, mediaTypes = []) {
  9416. parentNode.nodes.map((node, indexNode) => {
  9417. if (node.type == "media-query") {
  9418. return getMediaTypes(node, mediaType, mediaTypes);
  9419. } else {
  9420. if (node.type == "media-type") {
  9421. const nodeMediaType = { not: Boolean(indexNode && parentNode.nodes[0].type == "keyword" && parentNode.nodes[0].value == "not"), value: node.value };
  9422. if (!mediaTypes.find(mediaType => nodeMediaType.not == mediaType.not && nodeMediaType.value == mediaType.value)) {
  9423. mediaTypes.push(nodeMediaType);
  9424. }
  9425. }
  9426. }
  9427. });
  9428. if (!mediaTypes.length) {
  9429. mediaTypes.push({ not: false, value: MEDIA_ALL$2 });
  9430. }
  9431. return mediaTypes;
  9432. }
  9433. var cssMediasAltMinifier = /*#__PURE__*/Object.freeze({
  9434. __proto__: null,
  9435. process: process$4
  9436. });
  9437. /*
  9438. * Copyright 2010-2022 Gildas Lormeau
  9439. * contact : gildas.lormeau <at> gmail.com
  9440. *
  9441. * This file is part of SingleFile.
  9442. *
  9443. * The code in this file is free software: you can redistribute it and/or
  9444. * modify it under the terms of the GNU Affero General Public License
  9445. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  9446. * of the License, or (at your option) any later version.
  9447. *
  9448. * The code in this file is distributed in the hope that it will be useful,
  9449. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9450. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  9451. * General Public License for more details.
  9452. *
  9453. * As additional permission under GNU AGPL version 3 section 7, you may
  9454. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  9455. * AGPL normally required by section 4, provided you include this license
  9456. * notice and a URL through which recipients can access the Corresponding
  9457. * Source.
  9458. */
  9459. function process$3(stylesheets, styles, mediaAllInfo) {
  9460. const stats = { processed: 0, discarded: 0 };
  9461. let sheetIndex = 0;
  9462. stylesheets.forEach(stylesheetInfo => {
  9463. if (!stylesheetInfo.scoped) {
  9464. const cssRules = stylesheetInfo.stylesheet.children;
  9465. if (cssRules) {
  9466. stats.processed += cssRules.size;
  9467. stats.discarded += cssRules.size;
  9468. let mediaInfo;
  9469. if (stylesheetInfo.mediaText && stylesheetInfo.mediaText != "all") {
  9470. mediaInfo = mediaAllInfo.medias.get("style-" + sheetIndex + "-" + stylesheetInfo.mediaText);
  9471. } else {
  9472. mediaInfo = mediaAllInfo;
  9473. }
  9474. processRules(cssRules, sheetIndex, mediaInfo);
  9475. stats.discarded -= cssRules.size;
  9476. }
  9477. }
  9478. sheetIndex++;
  9479. });
  9480. styles.forEach(style => processStyleAttribute(style, mediaAllInfo));
  9481. return stats;
  9482. }
  9483. function processRules(cssRules, sheetIndex, mediaInfo) {
  9484. let mediaRuleIndex = 0;
  9485. const removedCssRules = [];
  9486. for (let cssRule = cssRules.head; cssRule; cssRule = cssRule.next) {
  9487. const ruleData = cssRule.data;
  9488. if (ruleData.block && ruleData.block.children && ruleData.prelude && ruleData.prelude.children) {
  9489. if (ruleData.type == "Atrule" && ruleData.name == "media") {
  9490. const mediaText = gb(ruleData.prelude);
  9491. processRules(ruleData.block.children, sheetIndex, mediaInfo.medias.get("rule-" + sheetIndex + "-" + mediaRuleIndex + "-" + mediaText));
  9492. if (!ruleData.prelude.children.size || !ruleData.block.children.size) {
  9493. removedCssRules.push(cssRule);
  9494. }
  9495. mediaRuleIndex++;
  9496. } else if (ruleData.type == "Rule") {
  9497. const ruleInfo = mediaInfo.rules.get(ruleData);
  9498. const pseudoSelectors = mediaInfo.pseudoRules.get(ruleData);
  9499. if (!ruleInfo && !pseudoSelectors) {
  9500. removedCssRules.push(cssRule);
  9501. } else if (ruleInfo) {
  9502. processRuleInfo(ruleData, ruleInfo, pseudoSelectors);
  9503. if (!ruleData.prelude.children.size || !ruleData.block.children.size) {
  9504. removedCssRules.push(cssRule);
  9505. }
  9506. }
  9507. }
  9508. } else {
  9509. if (!ruleData || ruleData.type == "Raw" || (ruleData.type == "Rule" && (!ruleData.prelude || ruleData.prelude.type == "Raw"))) {
  9510. removedCssRules.push(cssRule);
  9511. }
  9512. }
  9513. }
  9514. removedCssRules.forEach(cssRule => cssRules.remove(cssRule));
  9515. }
  9516. function processRuleInfo(ruleData, ruleInfo, pseudoSelectors) {
  9517. const removedDeclarations = [];
  9518. const removedSelectors = [];
  9519. let pseudoSelectorFound;
  9520. for (let selector = ruleData.prelude.children.head; selector; selector = selector.next) {
  9521. const selectorText = gb(selector.data);
  9522. if (pseudoSelectors && pseudoSelectors.has(selectorText)) {
  9523. pseudoSelectorFound = true;
  9524. }
  9525. if (!ruleInfo.matchedSelectors.has(selectorText) && (!pseudoSelectors || !pseudoSelectors.has(selectorText))) {
  9526. removedSelectors.push(selector);
  9527. }
  9528. }
  9529. if (!pseudoSelectorFound) {
  9530. for (let declaration = ruleData.block.children.tail; declaration; declaration = declaration.prev) {
  9531. if (!ruleInfo.declarations.has(declaration.data)) {
  9532. removedDeclarations.push(declaration);
  9533. }
  9534. }
  9535. }
  9536. removedDeclarations.forEach(declaration => ruleData.block.children.remove(declaration));
  9537. removedSelectors.forEach(selector => ruleData.prelude.children.remove(selector));
  9538. }
  9539. function processStyleAttribute(styleData, mediaAllInfo) {
  9540. const removedDeclarations = [];
  9541. const styleInfo = mediaAllInfo.matchedStyles.get(styleData);
  9542. if (styleInfo) {
  9543. let propertyFound;
  9544. for (let declaration = styleData.children.head; declaration && !propertyFound; declaration = declaration.next) {
  9545. if (!styleInfo.declarations.has(declaration.data)) {
  9546. removedDeclarations.push(declaration);
  9547. }
  9548. }
  9549. removedDeclarations.forEach(declaration => styleData.children.remove(declaration));
  9550. }
  9551. }
  9552. var cssRulesMinifier = /*#__PURE__*/Object.freeze({
  9553. __proto__: null,
  9554. process: process$3
  9555. });
  9556. /*
  9557. * Copyright 2010-2022 Gildas Lormeau
  9558. * contact : gildas.lormeau <at> gmail.com
  9559. *
  9560. * This file is part of SingleFile.
  9561. *
  9562. * The code in this file is free software: you can redistribute it and/or
  9563. * modify it under the terms of the GNU Affero General Public License
  9564. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  9565. * of the License, or (at your option) any later version.
  9566. *
  9567. * The code in this file is distributed in the hope that it will be useful,
  9568. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9569. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  9570. * General Public License for more details.
  9571. *
  9572. * As additional permission under GNU AGPL version 3 section 7, you may
  9573. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  9574. * AGPL normally required by section 4, provided you include this license
  9575. * notice and a URL through which recipients can access the Corresponding
  9576. * Source.
  9577. */
  9578. const EMPTY_RESOURCE = "data:,";
  9579. function process$2(doc) {
  9580. doc.querySelectorAll("picture").forEach(pictureElement => {
  9581. const imgElement = pictureElement.querySelector("img");
  9582. if (imgElement) {
  9583. let { src, srcset } = getImgSrcData(imgElement);
  9584. if (!src) {
  9585. const data = getSourceSrcData(Array.from(pictureElement.querySelectorAll("source")).reverse());
  9586. src = data.src;
  9587. if (!srcset) {
  9588. srcset = data.srcset;
  9589. }
  9590. }
  9591. setSrc({ src, srcset }, imgElement, pictureElement);
  9592. }
  9593. });
  9594. doc.querySelectorAll(":not(picture) > img[srcset]").forEach(imgElement => setSrc(getImgSrcData(imgElement), imgElement));
  9595. }
  9596. function getImgSrcData(imgElement) {
  9597. let src = imgElement.getAttribute("src");
  9598. if (src == EMPTY_RESOURCE) {
  9599. src = null;
  9600. }
  9601. let srcset = getSourceSrc(imgElement.getAttribute("srcset"));
  9602. if (srcset == EMPTY_RESOURCE) {
  9603. srcset = null;
  9604. }
  9605. return { src, srcset };
  9606. }
  9607. function getSourceSrcData(sources) {
  9608. let source = sources.find(source => source.src);
  9609. let src = source && source.src;
  9610. let srcset = source && source.srcset;
  9611. if (!src) {
  9612. source = sources.find(source => getSourceSrc(source.src));
  9613. src = source && source.src;
  9614. if (src == EMPTY_RESOURCE) {
  9615. src = null;
  9616. }
  9617. }
  9618. if (!srcset) {
  9619. source = sources.find(source => getSourceSrc(source.srcset));
  9620. srcset = source && source.srcset;
  9621. if (srcset == EMPTY_RESOURCE) {
  9622. srcset = null;
  9623. }
  9624. }
  9625. return { src, srcset };
  9626. }
  9627. function setSrc(srcData, imgElement, pictureElement) {
  9628. if (srcData.src) {
  9629. imgElement.setAttribute("src", srcData.src);
  9630. imgElement.setAttribute("srcset", "");
  9631. imgElement.setAttribute("sizes", "");
  9632. } else {
  9633. imgElement.setAttribute("src", EMPTY_RESOURCE);
  9634. if (srcData.srcset) {
  9635. imgElement.setAttribute("srcset", srcData.srcset);
  9636. } else {
  9637. imgElement.setAttribute("srcset", "");
  9638. imgElement.setAttribute("sizes", "");
  9639. }
  9640. }
  9641. if (pictureElement) {
  9642. pictureElement.querySelectorAll("source").forEach(sourceElement => sourceElement.remove());
  9643. }
  9644. }
  9645. function getSourceSrc(sourceSrcSet) {
  9646. if (sourceSrcSet) {
  9647. try {
  9648. const srcset = process$6(sourceSrcSet);
  9649. if (srcset.length) {
  9650. return (srcset.find(srcset => srcset.url)).url;
  9651. }
  9652. } catch (error) {
  9653. // ignored
  9654. }
  9655. }
  9656. }
  9657. var htmlImagesAltMinifier = /*#__PURE__*/Object.freeze({
  9658. __proto__: null,
  9659. process: process$2
  9660. });
  9661. /*
  9662. * Copyright 2010-2022 Gildas Lormeau
  9663. * contact : gildas.lormeau <at> gmail.com
  9664. *
  9665. * This file is part of SingleFile.
  9666. *
  9667. * The code in this file is free software: you can redistribute it and/or
  9668. * modify it under the terms of the GNU Affero General Public License
  9669. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  9670. * of the License, or (at your option) any later version.
  9671. *
  9672. * The code in this file is distributed in the hope that it will be useful,
  9673. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9674. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  9675. * General Public License for more details.
  9676. *
  9677. * As additional permission under GNU AGPL version 3 section 7, you may
  9678. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  9679. * AGPL normally required by section 4, provided you include this license
  9680. * notice and a URL through which recipients can access the Corresponding
  9681. * Source.
  9682. */
  9683. // Derived from the work of Kirill Maltsev - https://github.com/posthtml/htmlnano
  9684. // Source: https://github.com/kangax/html-minifier/issues/63
  9685. const booleanAttributes = [
  9686. "allowfullscreen",
  9687. "async",
  9688. "autofocus",
  9689. "autoplay",
  9690. "checked",
  9691. "compact",
  9692. "controls",
  9693. "declare",
  9694. "default",
  9695. "defaultchecked",
  9696. "defaultmuted",
  9697. "defaultselected",
  9698. "defer",
  9699. "disabled",
  9700. "enabled",
  9701. "formnovalidate",
  9702. "hidden",
  9703. "indeterminate",
  9704. "inert",
  9705. "ismap",
  9706. "itemscope",
  9707. "loop",
  9708. "multiple",
  9709. "muted",
  9710. "nohref",
  9711. "noresize",
  9712. "noshade",
  9713. "novalidate",
  9714. "nowrap",
  9715. "open",
  9716. "pauseonexit",
  9717. "readonly",
  9718. "required",
  9719. "reversed",
  9720. "scoped",
  9721. "seamless",
  9722. "selected",
  9723. "sortable",
  9724. "truespeed",
  9725. "typemustmatch",
  9726. "visible"
  9727. ];
  9728. const noWhitespaceCollapseElements = ["SCRIPT", "STYLE", "PRE", "TEXTAREA"];
  9729. // Source: https://www.w3.org/TR/html4/sgml/dtd.html#events (Generic Attributes)
  9730. const safeToRemoveAttrs = [
  9731. "id",
  9732. "class",
  9733. "style",
  9734. "lang",
  9735. "dir",
  9736. "onclick",
  9737. "ondblclick",
  9738. "onmousedown",
  9739. "onmouseup",
  9740. "onmouseover",
  9741. "onmousemove",
  9742. "onmouseout",
  9743. "onkeypress",
  9744. "onkeydown",
  9745. "onkeyup"
  9746. ];
  9747. const redundantAttributes = {
  9748. "FORM": {
  9749. "method": "get"
  9750. },
  9751. "SCRIPT": {
  9752. "language": "javascript",
  9753. "type": "text/javascript",
  9754. // Remove attribute if the function returns false
  9755. "charset": node => {
  9756. // The charset attribute only really makes sense on “external” SCRIPT elements:
  9757. // http://perfectionkills.com/optimizing-html/#8_script_charset
  9758. return !node.getAttribute("src");
  9759. }
  9760. },
  9761. "STYLE": {
  9762. "media": "all",
  9763. "type": "text/css"
  9764. },
  9765. "LINK": {
  9766. "media": "all"
  9767. }
  9768. };
  9769. const REGEXP_WHITESPACE = /[ \t\f\r]+/g;
  9770. const REGEXP_NEWLINE = /[\n]+/g;
  9771. const REGEXP_ENDS_WHITESPACE = /^\s+$/;
  9772. const NodeFilter_SHOW_ALL = 4294967295;
  9773. const Node_ELEMENT_NODE$1 = 1;
  9774. const Node_TEXT_NODE$1 = 3;
  9775. const Node_COMMENT_NODE$1 = 8;
  9776. const modules = [
  9777. collapseBooleanAttributes,
  9778. mergeTextNodes,
  9779. collapseWhitespace,
  9780. removeComments,
  9781. removeEmptyAttributes,
  9782. removeRedundantAttributes,
  9783. compressJSONLD,
  9784. node => mergeElements(node, "style", (node, previousSibling) => node.parentElement && getTagName$1(node.parentElement) == "HEAD" && node.media == previousSibling.media && node.title == previousSibling.title)
  9785. ];
  9786. function process$1(doc, options) {
  9787. removeEmptyInlineElements(doc);
  9788. const nodesWalker = doc.createTreeWalker(doc.documentElement, NodeFilter_SHOW_ALL, null, false);
  9789. let node = nodesWalker.nextNode();
  9790. while (node) {
  9791. const deletedNode = modules.find(module => module(node, options));
  9792. const previousNode = node;
  9793. node = nodesWalker.nextNode();
  9794. if (deletedNode) {
  9795. previousNode.remove();
  9796. }
  9797. }
  9798. }
  9799. function collapseBooleanAttributes(node) {
  9800. if (node.nodeType == Node_ELEMENT_NODE$1) {
  9801. Array.from(node.attributes).forEach(attribute => {
  9802. if (booleanAttributes.includes(attribute.name)) {
  9803. node.setAttribute(attribute.name, "");
  9804. }
  9805. });
  9806. }
  9807. }
  9808. function mergeTextNodes(node) {
  9809. if (node.nodeType == Node_TEXT_NODE$1) {
  9810. if (node.previousSibling && node.previousSibling.nodeType == Node_TEXT_NODE$1) {
  9811. node.textContent = node.previousSibling.textContent + node.textContent;
  9812. node.previousSibling.remove();
  9813. }
  9814. }
  9815. }
  9816. function mergeElements(node, tagName, acceptMerge) {
  9817. if (node.nodeType == Node_ELEMENT_NODE$1 && getTagName$1(node) == tagName.toUpperCase()) {
  9818. let previousSibling = node.previousSibling;
  9819. const previousSiblings = [];
  9820. while (previousSibling && previousSibling.nodeType == Node_TEXT_NODE$1 && !previousSibling.textContent.trim()) {
  9821. previousSiblings.push(previousSibling);
  9822. previousSibling = previousSibling.previousSibling;
  9823. }
  9824. if (previousSibling && previousSibling.nodeType == Node_ELEMENT_NODE$1 && previousSibling.tagName == node.tagName && acceptMerge(node, previousSibling)) {
  9825. node.textContent = previousSibling.textContent + node.textContent;
  9826. previousSiblings.forEach(node => node.remove());
  9827. previousSibling.remove();
  9828. }
  9829. }
  9830. }
  9831. function collapseWhitespace(node, options) {
  9832. if (node.nodeType == Node_TEXT_NODE$1) {
  9833. let element = node.parentElement;
  9834. const spacePreserved = element.getAttribute(options.PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME) == "";
  9835. if (!spacePreserved) {
  9836. const textContent = node.textContent;
  9837. let noWhitespace = noWhitespaceCollapse(element);
  9838. while (noWhitespace) {
  9839. element = element.parentElement;
  9840. noWhitespace = element && noWhitespaceCollapse(element);
  9841. }
  9842. if ((!element || noWhitespace) && textContent.length > 1) {
  9843. node.textContent = textContent.replace(REGEXP_WHITESPACE, getWhiteSpace(node)).replace(REGEXP_NEWLINE, "\n");
  9844. }
  9845. }
  9846. }
  9847. }
  9848. function getWhiteSpace(node) {
  9849. return node.parentElement && getTagName$1(node.parentElement) == "HEAD" ? "\n" : " ";
  9850. }
  9851. function noWhitespaceCollapse(element) {
  9852. return element && !noWhitespaceCollapseElements.includes(getTagName$1(element));
  9853. }
  9854. function removeComments(node) {
  9855. if (node.nodeType == Node_COMMENT_NODE$1 && getTagName$1(node.parentElement) != "HTML") {
  9856. return !node.textContent.toLowerCase().trim().startsWith("[if");
  9857. }
  9858. }
  9859. function removeEmptyAttributes(node) {
  9860. if (node.nodeType == Node_ELEMENT_NODE$1) {
  9861. Array.from(node.attributes).forEach(attribute => {
  9862. if (safeToRemoveAttrs.includes(attribute.name.toLowerCase())) {
  9863. const attributeValue = node.getAttribute(attribute.name);
  9864. if (attributeValue == "" || (attributeValue || "").match(REGEXP_ENDS_WHITESPACE)) {
  9865. node.removeAttribute(attribute.name);
  9866. }
  9867. }
  9868. });
  9869. }
  9870. }
  9871. function removeRedundantAttributes(node) {
  9872. if (node.nodeType == Node_ELEMENT_NODE$1) {
  9873. const tagRedundantAttributes = redundantAttributes[getTagName$1(node)];
  9874. if (tagRedundantAttributes) {
  9875. Object.keys(tagRedundantAttributes).forEach(redundantAttributeName => {
  9876. const tagRedundantAttributeValue = tagRedundantAttributes[redundantAttributeName];
  9877. if (typeof tagRedundantAttributeValue == "function" ? tagRedundantAttributeValue(node) : node.getAttribute(redundantAttributeName) == tagRedundantAttributeValue) {
  9878. node.removeAttribute(redundantAttributeName);
  9879. }
  9880. });
  9881. }
  9882. }
  9883. }
  9884. function compressJSONLD(node) {
  9885. if (node.nodeType == Node_ELEMENT_NODE$1 && getTagName$1(node) == "SCRIPT" && node.type == "application/ld+json" && node.textContent.trim()) {
  9886. try {
  9887. node.textContent = JSON.stringify(JSON.parse(node.textContent));
  9888. } catch (error) {
  9889. // ignored
  9890. }
  9891. }
  9892. }
  9893. function removeEmptyInlineElements(doc) {
  9894. doc.querySelectorAll("style, script:not([src])").forEach(element => {
  9895. if (!element.textContent.trim()) {
  9896. element.remove();
  9897. }
  9898. });
  9899. }
  9900. function getTagName$1(element) {
  9901. return element.tagName && element.tagName.toUpperCase();
  9902. }
  9903. var htmlMinifier = /*#__PURE__*/Object.freeze({
  9904. __proto__: null,
  9905. process: process$1
  9906. });
  9907. /*
  9908. * Copyright 2010-2022 Gildas Lormeau
  9909. * contact : gildas.lormeau <at> gmail.com
  9910. *
  9911. * This file is part of SingleFile.
  9912. *
  9913. * The code in this file is free software: you can redistribute it and/or
  9914. * modify it under the terms of the GNU Affero General Public License
  9915. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  9916. * of the License, or (at your option) any later version.
  9917. *
  9918. * The code in this file is distributed in the hope that it will be useful,
  9919. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9920. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  9921. * General Public License for more details.
  9922. *
  9923. * As additional permission under GNU AGPL version 3 section 7, you may
  9924. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  9925. * AGPL normally required by section 4, provided you include this license
  9926. * notice and a URL through which recipients can access the Corresponding
  9927. * Source.
  9928. */
  9929. const SELF_CLOSED_TAG_NAMES = ["AREA", "BASE", "BR", "COL", "COMMAND", "EMBED", "HR", "IMG", "INPUT", "KEYGEN", "LINK", "META", "PARAM", "SOURCE", "TRACK", "WBR"];
  9930. const Node_ELEMENT_NODE = 1;
  9931. const Node_TEXT_NODE = 3;
  9932. const Node_COMMENT_NODE = 8;
  9933. // see https://www.w3.org/TR/html5/syntax.html#optional-tags
  9934. const OMITTED_START_TAGS = [
  9935. { tagName: "HEAD", accept: element => !element.childNodes.length || element.childNodes[0].nodeType == Node_ELEMENT_NODE },
  9936. { tagName: "BODY", accept: element => !element.childNodes.length }
  9937. ];
  9938. const OMITTED_END_TAGS = [
  9939. { tagName: "HTML", accept: next => !next || next.nodeType != Node_COMMENT_NODE },
  9940. { tagName: "HEAD", accept: next => !next || (next.nodeType != Node_COMMENT_NODE && (next.nodeType != Node_TEXT_NODE || !startsWithSpaceChar(next.textContent))) },
  9941. { tagName: "BODY", accept: next => !next || next.nodeType != Node_COMMENT_NODE },
  9942. { tagName: "LI", accept: (next, element) => (!next && element.parentElement && (getTagName(element.parentElement) == "UL" || getTagName(element.parentElement) == "OL")) || (next && ["LI"].includes(getTagName(next))) },
  9943. { tagName: "DT", accept: next => !next || ["DT", "DD"].includes(getTagName(next)) },
  9944. { tagName: "P", accept: next => next && ["ADDRESS", "ARTICLE", "ASIDE", "BLOCKQUOTE", "DETAILS", "DIV", "DL", "FIELDSET", "FIGCAPTION", "FIGURE", "FOOTER", "FORM", "H1", "H2", "H3", "H4", "H5", "H6", "HEADER", "HR", "MAIN", "NAV", "OL", "P", "PRE", "SECTION", "TABLE", "UL"].includes(getTagName(next)) },
  9945. { tagName: "DD", accept: next => !next || ["DT", "DD"].includes(getTagName(next)) },
  9946. { tagName: "RT", accept: next => !next || ["RT", "RP"].includes(getTagName(next)) },
  9947. { tagName: "RP", accept: next => !next || ["RT", "RP"].includes(getTagName(next)) },
  9948. { tagName: "OPTGROUP", accept: next => !next || ["OPTGROUP"].includes(getTagName(next)) },
  9949. { tagName: "OPTION", accept: next => !next || ["OPTION", "OPTGROUP"].includes(getTagName(next)) },
  9950. { tagName: "COLGROUP", accept: next => !next || (next.nodeType != Node_COMMENT_NODE && (next.nodeType != Node_TEXT_NODE || !startsWithSpaceChar(next.textContent))) },
  9951. { tagName: "CAPTION", accept: next => !next || (next.nodeType != Node_COMMENT_NODE && (next.nodeType != Node_TEXT_NODE || !startsWithSpaceChar(next.textContent))) },
  9952. { tagName: "THEAD", accept: next => !next || ["TBODY", "TFOOT"].includes(getTagName(next)) },
  9953. { tagName: "TBODY", accept: next => !next || ["TBODY", "TFOOT"].includes(getTagName(next)) },
  9954. { tagName: "TFOOT", accept: next => !next },
  9955. { tagName: "TR", accept: next => !next || ["TR"].includes(getTagName(next)) },
  9956. { tagName: "TD", accept: next => !next || ["TD", "TH"].includes(getTagName(next)) },
  9957. { tagName: "TH", accept: next => !next || ["TD", "TH"].includes(getTagName(next)) }
  9958. ];
  9959. const TEXT_NODE_TAGS = ["STYLE", "SCRIPT", "XMP", "IFRAME", "NOEMBED", "NOFRAMES", "PLAINTEXT", "NOSCRIPT"];
  9960. function process(doc, compressHTML) {
  9961. const docType = doc.doctype;
  9962. let docTypeString = "";
  9963. if (docType) {
  9964. docTypeString = "<!DOCTYPE " + docType.nodeName;
  9965. if (docType.publicId) {
  9966. docTypeString += " PUBLIC \"" + docType.publicId + "\"";
  9967. if (docType.systemId)
  9968. docTypeString += " \"" + docType.systemId + "\"";
  9969. } else if (docType.systemId)
  9970. docTypeString += " SYSTEM \"" + docType.systemId + "\"";
  9971. if (docType.internalSubset)
  9972. docTypeString += " [" + docType.internalSubset + "]";
  9973. docTypeString += "> ";
  9974. }
  9975. return docTypeString + serialize(doc.documentElement, compressHTML);
  9976. }
  9977. function serialize(node, compressHTML, isSVG) {
  9978. if (node.nodeType == Node_TEXT_NODE) {
  9979. return serializeTextNode(node);
  9980. } else if (node.nodeType == Node_COMMENT_NODE) {
  9981. return serializeCommentNode(node);
  9982. } else if (node.nodeType == Node_ELEMENT_NODE) {
  9983. return serializeElement(node, compressHTML, isSVG);
  9984. }
  9985. }
  9986. function serializeTextNode(textNode) {
  9987. const parentNode = textNode.parentNode;
  9988. let parentTagName;
  9989. if (parentNode && parentNode.nodeType == Node_ELEMENT_NODE) {
  9990. parentTagName = getTagName(parentNode);
  9991. }
  9992. if (!parentTagName || TEXT_NODE_TAGS.includes(parentTagName)) {
  9993. if (parentTagName == "SCRIPT" || parentTagName == "STYLE") {
  9994. return textNode.textContent.replace(/<\//gi, "<\\/").replace(/\/>/gi, "\\/>");
  9995. }
  9996. return textNode.textContent;
  9997. } else {
  9998. return textNode.textContent.replace(/&/g, "&amp;").replace(/\u00a0/g, "&nbsp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
  9999. }
  10000. }
  10001. function serializeCommentNode(commentNode) {
  10002. return "<!--" + commentNode.textContent + "-->";
  10003. }
  10004. function serializeElement(element, compressHTML, isSVG) {
  10005. const tagName = getTagName(element);
  10006. const omittedStartTag = compressHTML && OMITTED_START_TAGS.find(omittedStartTag => tagName == getTagName(omittedStartTag) && omittedStartTag.accept(element));
  10007. let content = "";
  10008. if (!omittedStartTag || element.attributes.length) {
  10009. content = "<" + tagName.toLowerCase();
  10010. Array.from(element.attributes).forEach(attribute => content += serializeAttribute(attribute, element, compressHTML));
  10011. content += ">";
  10012. }
  10013. if (tagName == "TEMPLATE" && !element.childNodes.length) {
  10014. content += element.innerHTML;
  10015. } else {
  10016. Array.from(element.childNodes).forEach(childNode => content += serialize(childNode, compressHTML, isSVG || tagName == "svg"));
  10017. }
  10018. const omittedEndTag = compressHTML && OMITTED_END_TAGS.find(omittedEndTag => tagName == getTagName(omittedEndTag) && omittedEndTag.accept(element.nextSibling, element));
  10019. if (isSVG || (!omittedEndTag && !SELF_CLOSED_TAG_NAMES.includes(tagName))) {
  10020. content += "</" + tagName.toLowerCase() + ">";
  10021. }
  10022. return content;
  10023. }
  10024. function serializeAttribute(attribute, element, compressHTML) {
  10025. const name = attribute.name;
  10026. let content = "";
  10027. if (!name.match(/["'>/=]/)) {
  10028. let value = attribute.value;
  10029. if (compressHTML && name == "class") {
  10030. value = Array.from(element.classList).map(className => className.trim()).join(" ");
  10031. }
  10032. let simpleQuotesValue;
  10033. value = value.replace(/&/g, "&amp;").replace(/\u00a0/g, "&nbsp;");
  10034. if (value.includes("\"")) {
  10035. if (value.includes("'") || !compressHTML) {
  10036. value = value.replace(/"/g, "&quot;");
  10037. } else {
  10038. simpleQuotesValue = true;
  10039. }
  10040. }
  10041. const invalidUnquotedValue = !compressHTML || value.match(/[ \t\n\f\r'"`=<>]/);
  10042. content += " ";
  10043. if (!attribute.namespace) {
  10044. content += name;
  10045. } else if (attribute.namespaceURI == "http://www.w3.org/XML/1998/namespace") {
  10046. content += "xml:" + name;
  10047. } else if (attribute.namespaceURI == "http://www.w3.org/2000/xmlns/") {
  10048. if (name !== "xmlns") {
  10049. content += "xmlns:";
  10050. }
  10051. content += name;
  10052. } else if (attribute.namespaceURI == "http://www.w3.org/1999/xlink") {
  10053. content += "xlink:" + name;
  10054. } else {
  10055. content += name;
  10056. }
  10057. if (value != "") {
  10058. content += "=";
  10059. if (invalidUnquotedValue) {
  10060. content += simpleQuotesValue ? "'" : "\"";
  10061. }
  10062. content += value;
  10063. if (invalidUnquotedValue) {
  10064. content += simpleQuotesValue ? "'" : "\"";
  10065. }
  10066. }
  10067. }
  10068. return content;
  10069. }
  10070. function startsWithSpaceChar(textContent) {
  10071. return Boolean(textContent.match(/^[ \t\n\f\r]/));
  10072. }
  10073. function getTagName(element) {
  10074. return element.tagName && element.tagName.toUpperCase();
  10075. }
  10076. var htmlSerializer = /*#__PURE__*/Object.freeze({
  10077. __proto__: null,
  10078. process: process
  10079. });
  10080. /*
  10081. * Copyright 2010-2022 Gildas Lormeau
  10082. * contact : gildas.lormeau <at> gmail.com
  10083. *
  10084. * This file is part of SingleFile.
  10085. *
  10086. * The code in this file is free software: you can redistribute it and/or
  10087. * modify it under the terms of the GNU Affero General Public License
  10088. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  10089. * of the License, or (at your option) any later version.
  10090. *
  10091. * The code in this file is distributed in the hope that it will be useful,
  10092. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10093. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  10094. * General Public License for more details.
  10095. *
  10096. * As additional permission under GNU AGPL version 3 section 7, you may
  10097. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  10098. * AGPL normally required by section 4, provided you include this license
  10099. * notice and a URL through which recipients can access the Corresponding
  10100. * Source.
  10101. */
  10102. /* global Blob, FileReader, URL, URLSearchParams */
  10103. // eslint-disable-next-line quotes
  10104. const DEFAULT_REPLACED_CHARACTERS$1 = ["~", "+", "\\\\", "?", "%", "*", ":", "|", '"', "<", ">", "\x00-\x1f", "\x7F"];
  10105. const DEFAULT_REPLACEMENT_CHARACTER$1 = "_";
  10106. const EMOJI_NAMES = {
  10107. "😀": "grinning-face",
  10108. "😃": "grinning-face-with-big-eyes",
  10109. "😄": "grinning-face-with-smiling-eyes",
  10110. "😁": "beaming-face-with-smiling-eyes",
  10111. "😆": "grinning-squinting-face",
  10112. "😅": "grinning-face-with-sweat",
  10113. "🤣": "rolling-on-the-floor-laughing",
  10114. "😂": "face-with-tears-of-joy",
  10115. "🙂": "slightly-smiling-face",
  10116. "🙃": "upside-down-face",
  10117. "🫠": "melting-face",
  10118. "😉": "winking-face",
  10119. "😊": "smiling-face-with-smiling-eyes",
  10120. "😇": "smiling-face-with-halo",
  10121. "🥰": "smiling-face-with-hearts",
  10122. "😍": "smiling-face-with-heart-eyes",
  10123. "🤩": "star-struck",
  10124. "😘": "face-blowing-a-kiss",
  10125. "😗": "kissing-face",
  10126. "☺": "smiling-face",
  10127. "😚": "kissing-face-with-closed-eyes",
  10128. "😙": "kissing-face-with-smiling-eyes",
  10129. "🥲": "smiling-face-with-tear",
  10130. "😋": "face-savoring-food",
  10131. "😛": "face-with-tongue",
  10132. "😜": "winking-face-with-tongue",
  10133. "🤪": "zany-face",
  10134. "😝": "squinting-face-with-tongue",
  10135. "🤑": "money-mouth-face",
  10136. "🤗": "smiling-face-with-open-hands",
  10137. "🤭": "face-with-hand-over-mouth",
  10138. "🫢": "face-with-open-eyes-and-hand-over-mouth",
  10139. "🫣": "face-with-peeking-eye",
  10140. "🤫": "shushing-face",
  10141. "🤔": "thinking-face",
  10142. "🫡": "saluting-face",
  10143. "🤐": "zipper-mouth-face",
  10144. "🤨": "face-with-raised-eyebrow",
  10145. "😐": "neutral-face",
  10146. "😑": "expressionless-face",
  10147. "😶": "face-without-mouth",
  10148. "🫥": "dotted-line-face",
  10149. "😶‍🌫️": "face-in-clouds",
  10150. "😏": "smirking-face",
  10151. "😒": "unamused-face",
  10152. "🙄": "face-with-rolling-eyes",
  10153. "😬": "grimacing-face",
  10154. "😮‍💨": "face-exhaling",
  10155. "🤥": "lying-face",
  10156. "🫨": "⊛-shaking-face",
  10157. "😌": "relieved-face",
  10158. "😔": "pensive-face",
  10159. "😪": "sleepy-face",
  10160. "🤤": "drooling-face",
  10161. "😴": "sleeping-face",
  10162. "😷": "face-with-medical-mask",
  10163. "🤒": "face-with-thermometer",
  10164. "🤕": "face-with-head-bandage",
  10165. "🤢": "nauseated-face",
  10166. "🤮": "face-vomiting",
  10167. "🤧": "sneezing-face",
  10168. "🥵": "hot-face",
  10169. "🥶": "cold-face",
  10170. "🥴": "woozy-face",
  10171. "😵": "face-with-crossed-out-eyes",
  10172. "😵‍💫": "face-with-spiral-eyes",
  10173. "🤯": "exploding-head",
  10174. "🤠": "cowboy-hat-face",
  10175. "🥳": "partying-face",
  10176. "🥸": "disguised-face",
  10177. "😎": "smiling-face-with-sunglasses",
  10178. "🤓": "nerd-face",
  10179. "🧐": "face-with-monocle",
  10180. "😕": "confused-face",
  10181. "🫤": "face-with-diagonal-mouth",
  10182. "😟": "worried-face",
  10183. "🙁": "slightly-frowning-face",
  10184. "☹": "frowning-face",
  10185. "😮": "face-with-open-mouth",
  10186. "😯": "hushed-face",
  10187. "😲": "astonished-face",
  10188. "😳": "flushed-face",
  10189. "🥺": "pleading-face",
  10190. "🥹": "face-holding-back-tears",
  10191. "😦": "frowning-face-with-open-mouth",
  10192. "😧": "anguished-face",
  10193. "😨": "fearful-face",
  10194. "😰": "anxious-face-with-sweat",
  10195. "😥": "sad-but-relieved-face",
  10196. "😢": "crying-face",
  10197. "😭": "loudly-crying-face",
  10198. "😱": "face-screaming-in-fear",
  10199. "😖": "confounded-face",
  10200. "😣": "persevering-face",
  10201. "😞": "disappointed-face",
  10202. "😓": "downcast-face-with-sweat",
  10203. "😩": "weary-face",
  10204. "😫": "tired-face",
  10205. "🥱": "yawning-face",
  10206. "😤": "face-with-steam-from-nose",
  10207. "😡": "enraged-face",
  10208. "😠": "angry-face",
  10209. "🤬": "face-with-symbols-on-mouth",
  10210. "😈": "smiling-face-with-horns",
  10211. "👿": "angry-face-with-horns",
  10212. "💀": "skull",
  10213. "☠": "skull-and-crossbones",
  10214. "💩": "pile-of-poo",
  10215. "🤡": "clown-face",
  10216. "👹": "ogre",
  10217. "👺": "goblin",
  10218. "👻": "ghost",
  10219. "👽": "alien",
  10220. "👾": "alien-monster",
  10221. "🤖": "robot",
  10222. "😺": "grinning-cat",
  10223. "😸": "grinning-cat-with-smiling-eyes",
  10224. "😹": "cat-with-tears-of-joy",
  10225. "😻": "smiling-cat-with-heart-eyes",
  10226. "😼": "cat-with-wry-smile",
  10227. "😽": "kissing-cat",
  10228. "🙀": "weary-cat",
  10229. "😿": "crying-cat",
  10230. "😾": "pouting-cat",
  10231. "🙈": "see-no-evil-monkey",
  10232. "🙉": "hear-no-evil-monkey",
  10233. "🙊": "speak-no-evil-monkey",
  10234. "💌": "love-letter",
  10235. "💘": "heart-with-arrow",
  10236. "💝": "heart-with-ribbon",
  10237. "💖": "sparkling-heart",
  10238. "💗": "growing-heart",
  10239. "💓": "beating-heart",
  10240. "💞": "revolving-hearts",
  10241. "💕": "two-hearts",
  10242. "💟": "heart-decoration",
  10243. "❣": "heart-exclamation",
  10244. "💔": "broken-heart",
  10245. "❤️‍🔥": "heart-on-fire",
  10246. "❤️‍🩹": "mending-heart",
  10247. "❤": "red-heart",
  10248. "🩷": "⊛-pink-heart",
  10249. "🧡": "orange-heart",
  10250. "💛": "yellow-heart",
  10251. "💚": "green-heart",
  10252. "💙": "blue-heart",
  10253. "🩵": "⊛-light-blue-heart",
  10254. "💜": "purple-heart",
  10255. "🤎": "brown-heart",
  10256. "🖤": "black-heart",
  10257. "🩶": "⊛-grey-heart",
  10258. "🤍": "white-heart",
  10259. "💋": "kiss-mark",
  10260. "💯": "hundred-points",
  10261. "💢": "anger-symbol",
  10262. "💥": "collision",
  10263. "💫": "dizzy",
  10264. "💦": "sweat-droplets",
  10265. "💨": "dashing-away",
  10266. "🕳": "hole",
  10267. "💬": "speech-balloon",
  10268. "👁️‍🗨️": "eye-in-speech-bubble",
  10269. "🗨": "left-speech-bubble",
  10270. "🗯": "right-anger-bubble",
  10271. "💭": "thought-balloon",
  10272. "💤": "zzz",
  10273. "👋": "waving-hand",
  10274. "🤚": "raised-back-of-hand",
  10275. "🖐": "hand-with-fingers-splayed",
  10276. "✋": "raised-hand",
  10277. "🖖": "vulcan-salute",
  10278. "🫱": "rightwards-hand",
  10279. "🫲": "leftwards-hand",
  10280. "🫳": "palm-down-hand",
  10281. "🫴": "palm-up-hand",
  10282. "🫷": "⊛-leftwards-pushing-hand",
  10283. "🫸": "⊛-rightwards-pushing-hand",
  10284. "👌": "ok-hand",
  10285. "🤌": "pinched-fingers",
  10286. "🤏": "pinching-hand",
  10287. "✌": "victory-hand",
  10288. "🤞": "crossed-fingers",
  10289. "🫰": "hand-with-index-finger-and-thumb-crossed",
  10290. "🤟": "love-you-gesture",
  10291. "🤘": "sign-of-the-horns",
  10292. "🤙": "call-me-hand",
  10293. "👈": "backhand-index-pointing-left",
  10294. "👉": "backhand-index-pointing-right",
  10295. "👆": "backhand-index-pointing-up",
  10296. "🖕": "middle-finger",
  10297. "👇": "backhand-index-pointing-down",
  10298. "☝": "index-pointing-up",
  10299. "🫵": "index-pointing-at-the-viewer",
  10300. "👍": "thumbs-up",
  10301. "👎": "thumbs-down",
  10302. "✊": "raised-fist",
  10303. "👊": "oncoming-fist",
  10304. "🤛": "left-facing-fist",
  10305. "🤜": "right-facing-fist",
  10306. "👏": "clapping-hands",
  10307. "🙌": "raising-hands",
  10308. "🫶": "heart-hands",
  10309. "👐": "open-hands",
  10310. "🤲": "palms-up-together",
  10311. "🤝": "handshake",
  10312. "🙏": "folded-hands",
  10313. "✍": "writing-hand",
  10314. "💅": "nail-polish",
  10315. "🤳": "selfie",
  10316. "💪": "flexed-biceps",
  10317. "🦾": "mechanical-arm",
  10318. "🦿": "mechanical-leg",
  10319. "🦵": "leg",
  10320. "🦶": "foot",
  10321. "👂": "ear",
  10322. "🦻": "ear-with-hearing-aid",
  10323. "👃": "nose",
  10324. "🧠": "brain",
  10325. "🫀": "anatomical-heart",
  10326. "🫁": "lungs",
  10327. "🦷": "tooth",
  10328. "🦴": "bone",
  10329. "👀": "eyes",
  10330. "👁": "eye",
  10331. "👅": "tongue",
  10332. "👄": "mouth",
  10333. "🫦": "biting-lip",
  10334. "👶": "baby",
  10335. "🧒": "child",
  10336. "👦": "boy",
  10337. "👧": "girl",
  10338. "🧑": "person",
  10339. "👱": "person-blond-hair",
  10340. "👨": "man",
  10341. "🧔": "person-beard",
  10342. "🧔‍♂️": "man-beard",
  10343. "🧔‍♀️": "woman-beard",
  10344. "👨‍🦰": "man-red-hair",
  10345. "👨‍🦱": "man-curly-hair",
  10346. "👨‍🦳": "man-white-hair",
  10347. "👨‍🦲": "man-bald",
  10348. "👩": "woman",
  10349. "👩‍🦰": "woman-red-hair",
  10350. "🧑‍🦰": "person-red-hair",
  10351. "👩‍🦱": "woman-curly-hair",
  10352. "🧑‍🦱": "person-curly-hair",
  10353. "👩‍🦳": "woman-white-hair",
  10354. "🧑‍🦳": "person-white-hair",
  10355. "👩‍🦲": "woman-bald",
  10356. "🧑‍🦲": "person-bald",
  10357. "👱‍♀️": "woman-blond-hair",
  10358. "👱‍♂️": "man-blond-hair",
  10359. "🧓": "older-person",
  10360. "👴": "old-man",
  10361. "👵": "old-woman",
  10362. "🙍": "person-frowning",
  10363. "🙍‍♂️": "man-frowning",
  10364. "🙍‍♀️": "woman-frowning",
  10365. "🙎": "person-pouting",
  10366. "🙎‍♂️": "man-pouting",
  10367. "🙎‍♀️": "woman-pouting",
  10368. "🙅": "person-gesturing-no",
  10369. "🙅‍♂️": "man-gesturing-no",
  10370. "🙅‍♀️": "woman-gesturing-no",
  10371. "🙆": "person-gesturing-ok",
  10372. "🙆‍♂️": "man-gesturing-ok",
  10373. "🙆‍♀️": "woman-gesturing-ok",
  10374. "💁": "person-tipping-hand",
  10375. "💁‍♂️": "man-tipping-hand",
  10376. "💁‍♀️": "woman-tipping-hand",
  10377. "🙋": "person-raising-hand",
  10378. "🙋‍♂️": "man-raising-hand",
  10379. "🙋‍♀️": "woman-raising-hand",
  10380. "🧏": "deaf-person",
  10381. "🧏‍♂️": "deaf-man",
  10382. "🧏‍♀️": "deaf-woman",
  10383. "🙇": "person-bowing",
  10384. "🙇‍♂️": "man-bowing",
  10385. "🙇‍♀️": "woman-bowing",
  10386. "🤦": "person-facepalming",
  10387. "🤦‍♂️": "man-facepalming",
  10388. "🤦‍♀️": "woman-facepalming",
  10389. "🤷": "person-shrugging",
  10390. "🤷‍♂️": "man-shrugging",
  10391. "🤷‍♀️": "woman-shrugging",
  10392. "🧑‍⚕️": "health-worker",
  10393. "👨‍⚕️": "man-health-worker",
  10394. "👩‍⚕️": "woman-health-worker",
  10395. "🧑‍🎓": "student",
  10396. "👨‍🎓": "man-student",
  10397. "👩‍🎓": "woman-student",
  10398. "🧑‍🏫": "teacher",
  10399. "👨‍🏫": "man-teacher",
  10400. "👩‍🏫": "woman-teacher",
  10401. "🧑‍⚖️": "judge",
  10402. "👨‍⚖️": "man-judge",
  10403. "👩‍⚖️": "woman-judge",
  10404. "🧑‍🌾": "farmer",
  10405. "👨‍🌾": "man-farmer",
  10406. "👩‍🌾": "woman-farmer",
  10407. "🧑‍🍳": "cook",
  10408. "👨‍🍳": "man-cook",
  10409. "👩‍🍳": "woman-cook",
  10410. "🧑‍🔧": "mechanic",
  10411. "👨‍🔧": "man-mechanic",
  10412. "👩‍🔧": "woman-mechanic",
  10413. "🧑‍🏭": "factory-worker",
  10414. "👨‍🏭": "man-factory-worker",
  10415. "👩‍🏭": "woman-factory-worker",
  10416. "🧑‍💼": "office-worker",
  10417. "👨‍💼": "man-office-worker",
  10418. "👩‍💼": "woman-office-worker",
  10419. "🧑‍🔬": "scientist",
  10420. "👨‍🔬": "man-scientist",
  10421. "👩‍🔬": "woman-scientist",
  10422. "🧑‍💻": "technologist",
  10423. "👨‍💻": "man-technologist",
  10424. "👩‍💻": "woman-technologist",
  10425. "🧑‍🎤": "singer",
  10426. "👨‍🎤": "man-singer",
  10427. "👩‍🎤": "woman-singer",
  10428. "🧑‍🎨": "artist",
  10429. "👨‍🎨": "man-artist",
  10430. "👩‍🎨": "woman-artist",
  10431. "🧑‍✈️": "pilot",
  10432. "👨‍✈️": "man-pilot",
  10433. "👩‍✈️": "woman-pilot",
  10434. "🧑‍🚀": "astronaut",
  10435. "👨‍🚀": "man-astronaut",
  10436. "👩‍🚀": "woman-astronaut",
  10437. "🧑‍🚒": "firefighter",
  10438. "👨‍🚒": "man-firefighter",
  10439. "👩‍🚒": "woman-firefighter",
  10440. "👮": "police-officer",
  10441. "👮‍♂️": "man-police-officer",
  10442. "👮‍♀️": "woman-police-officer",
  10443. "🕵": "detective",
  10444. "🕵️‍♂️": "man-detective",
  10445. "🕵️‍♀️": "woman-detective",
  10446. "💂": "guard",
  10447. "💂‍♂️": "man-guard",
  10448. "💂‍♀️": "woman-guard",
  10449. "🥷": "ninja",
  10450. "👷": "construction-worker",
  10451. "👷‍♂️": "man-construction-worker",
  10452. "👷‍♀️": "woman-construction-worker",
  10453. "🫅": "person-with-crown",
  10454. "🤴": "prince",
  10455. "👸": "princess",
  10456. "👳": "person-wearing-turban",
  10457. "👳‍♂️": "man-wearing-turban",
  10458. "👳‍♀️": "woman-wearing-turban",
  10459. "👲": "person-with-skullcap",
  10460. "🧕": "woman-with-headscarf",
  10461. "🤵": "person-in-tuxedo",
  10462. "🤵‍♂️": "man-in-tuxedo",
  10463. "🤵‍♀️": "woman-in-tuxedo",
  10464. "👰": "person-with-veil",
  10465. "👰‍♂️": "man-with-veil",
  10466. "👰‍♀️": "woman-with-veil",
  10467. "🤰": "pregnant-woman",
  10468. "🫃": "pregnant-man",
  10469. "🫄": "pregnant-person",
  10470. "🤱": "breast-feeding",
  10471. "👩‍🍼": "woman-feeding-baby",
  10472. "👨‍🍼": "man-feeding-baby",
  10473. "🧑‍🍼": "person-feeding-baby",
  10474. "👼": "baby-angel",
  10475. "🎅": "santa-claus",
  10476. "🤶": "mrs-claus",
  10477. "🧑‍🎄": "mx-claus",
  10478. "🦸": "superhero",
  10479. "🦸‍♂️": "man-superhero",
  10480. "🦸‍♀️": "woman-superhero",
  10481. "🦹": "supervillain",
  10482. "🦹‍♂️": "man-supervillain",
  10483. "🦹‍♀️": "woman-supervillain",
  10484. "🧙": "mage",
  10485. "🧙‍♂️": "man-mage",
  10486. "🧙‍♀️": "woman-mage",
  10487. "🧚": "fairy",
  10488. "🧚‍♂️": "man-fairy",
  10489. "🧚‍♀️": "woman-fairy",
  10490. "🧛": "vampire",
  10491. "🧛‍♂️": "man-vampire",
  10492. "🧛‍♀️": "woman-vampire",
  10493. "🧜": "merperson",
  10494. "🧜‍♂️": "merman",
  10495. "🧜‍♀️": "mermaid",
  10496. "🧝": "elf",
  10497. "🧝‍♂️": "man-elf",
  10498. "🧝‍♀️": "woman-elf",
  10499. "🧞": "genie",
  10500. "🧞‍♂️": "man-genie",
  10501. "🧞‍♀️": "woman-genie",
  10502. "🧟": "zombie",
  10503. "🧟‍♂️": "man-zombie",
  10504. "🧟‍♀️": "woman-zombie",
  10505. "🧌": "troll",
  10506. "💆": "person-getting-massage",
  10507. "💆‍♂️": "man-getting-massage",
  10508. "💆‍♀️": "woman-getting-massage",
  10509. "💇": "person-getting-haircut",
  10510. "💇‍♂️": "man-getting-haircut",
  10511. "💇‍♀️": "woman-getting-haircut",
  10512. "🚶": "person-walking",
  10513. "🚶‍♂️": "man-walking",
  10514. "🚶‍♀️": "woman-walking",
  10515. "🧍": "person-standing",
  10516. "🧍‍♂️": "man-standing",
  10517. "🧍‍♀️": "woman-standing",
  10518. "🧎": "person-kneeling",
  10519. "🧎‍♂️": "man-kneeling",
  10520. "🧎‍♀️": "woman-kneeling",
  10521. "🧑‍🦯": "person-with-white-cane",
  10522. "👨‍🦯": "man-with-white-cane",
  10523. "👩‍🦯": "woman-with-white-cane",
  10524. "🧑‍🦼": "person-in-motorized-wheelchair",
  10525. "👨‍🦼": "man-in-motorized-wheelchair",
  10526. "👩‍🦼": "woman-in-motorized-wheelchair",
  10527. "🧑‍🦽": "person-in-manual-wheelchair",
  10528. "👨‍🦽": "man-in-manual-wheelchair",
  10529. "👩‍🦽": "woman-in-manual-wheelchair",
  10530. "🏃": "person-running",
  10531. "🏃‍♂️": "man-running",
  10532. "🏃‍♀️": "woman-running",
  10533. "💃": "woman-dancing",
  10534. "🕺": "man-dancing",
  10535. "🕴": "person-in-suit-levitating",
  10536. "👯": "people-with-bunny-ears",
  10537. "👯‍♂️": "men-with-bunny-ears",
  10538. "👯‍♀️": "women-with-bunny-ears",
  10539. "🧖": "person-in-steamy-room",
  10540. "🧖‍♂️": "man-in-steamy-room",
  10541. "🧖‍♀️": "woman-in-steamy-room",
  10542. "🧗": "person-climbing",
  10543. "🧗‍♂️": "man-climbing",
  10544. "🧗‍♀️": "woman-climbing",
  10545. "🤺": "person-fencing",
  10546. "🏇": "horse-racing",
  10547. "⛷": "skier",
  10548. "🏂": "snowboarder",
  10549. "🏌": "person-golfing",
  10550. "🏌️‍♂️": "man-golfing",
  10551. "🏌️‍♀️": "woman-golfing",
  10552. "🏄": "person-surfing",
  10553. "🏄‍♂️": "man-surfing",
  10554. "🏄‍♀️": "woman-surfing",
  10555. "🚣": "person-rowing-boat",
  10556. "🚣‍♂️": "man-rowing-boat",
  10557. "🚣‍♀️": "woman-rowing-boat",
  10558. "🏊": "person-swimming",
  10559. "🏊‍♂️": "man-swimming",
  10560. "🏊‍♀️": "woman-swimming",
  10561. "⛹": "person-bouncing-ball",
  10562. "⛹️‍♂️": "man-bouncing-ball",
  10563. "⛹️‍♀️": "woman-bouncing-ball",
  10564. "🏋": "person-lifting-weights",
  10565. "🏋️‍♂️": "man-lifting-weights",
  10566. "🏋️‍♀️": "woman-lifting-weights",
  10567. "🚴": "person-biking",
  10568. "🚴‍♂️": "man-biking",
  10569. "🚴‍♀️": "woman-biking",
  10570. "🚵": "person-mountain-biking",
  10571. "🚵‍♂️": "man-mountain-biking",
  10572. "🚵‍♀️": "woman-mountain-biking",
  10573. "🤸": "person-cartwheeling",
  10574. "🤸‍♂️": "man-cartwheeling",
  10575. "🤸‍♀️": "woman-cartwheeling",
  10576. "🤼": "people-wrestling",
  10577. "🤼‍♂️": "men-wrestling",
  10578. "🤼‍♀️": "women-wrestling",
  10579. "🤽": "person-playing-water-polo",
  10580. "🤽‍♂️": "man-playing-water-polo",
  10581. "🤽‍♀️": "woman-playing-water-polo",
  10582. "🤾": "person-playing-handball",
  10583. "🤾‍♂️": "man-playing-handball",
  10584. "🤾‍♀️": "woman-playing-handball",
  10585. "🤹": "person-juggling",
  10586. "🤹‍♂️": "man-juggling",
  10587. "🤹‍♀️": "woman-juggling",
  10588. "🧘": "person-in-lotus-position",
  10589. "🧘‍♂️": "man-in-lotus-position",
  10590. "🧘‍♀️": "woman-in-lotus-position",
  10591. "🛀": "person-taking-bath",
  10592. "🛌": "person-in-bed",
  10593. "🧑‍🤝‍🧑": "people-holding-hands",
  10594. "👭": "women-holding-hands",
  10595. "👫": "woman-and-man-holding-hands",
  10596. "👬": "men-holding-hands",
  10597. "💏": "kiss",
  10598. "👩‍❤️‍💋‍👨": "kiss-woman,-man",
  10599. "👨‍❤️‍💋‍👨": "kiss-man,-man",
  10600. "👩‍❤️‍💋‍👩": "kiss-woman,-woman",
  10601. "💑": "couple-with-heart",
  10602. "👩‍❤️‍👨": "couple-with-heart-woman,-man",
  10603. "👨‍❤️‍👨": "couple-with-heart-man,-man",
  10604. "👩‍❤️‍👩": "couple-with-heart-woman,-woman",
  10605. "👪": "family",
  10606. "👨‍👩‍👦": "family-man,-woman,-boy",
  10607. "👨‍👩‍👧": "family-man,-woman,-girl",
  10608. "👨‍👩‍👧‍👦": "family-man,-woman,-girl,-boy",
  10609. "👨‍👩‍👦‍👦": "family-man,-woman,-boy,-boy",
  10610. "👨‍👩‍👧‍👧": "family-man,-woman,-girl,-girl",
  10611. "👨‍👨‍👦": "family-man,-man,-boy",
  10612. "👨‍👨‍👧": "family-man,-man,-girl",
  10613. "👨‍👨‍👧‍👦": "family-man,-man,-girl,-boy",
  10614. "👨‍👨‍👦‍👦": "family-man,-man,-boy,-boy",
  10615. "👨‍👨‍👧‍👧": "family-man,-man,-girl,-girl",
  10616. "👩‍👩‍👦": "family-woman,-woman,-boy",
  10617. "👩‍👩‍👧": "family-woman,-woman,-girl",
  10618. "👩‍👩‍👧‍👦": "family-woman,-woman,-girl,-boy",
  10619. "👩‍👩‍👦‍👦": "family-woman,-woman,-boy,-boy",
  10620. "👩‍👩‍👧‍👧": "family-woman,-woman,-girl,-girl",
  10621. "👨‍👦": "family-man,-boy",
  10622. "👨‍👦‍👦": "family-man,-boy,-boy",
  10623. "👨‍👧": "family-man,-girl",
  10624. "👨‍👧‍👦": "family-man,-girl,-boy",
  10625. "👨‍👧‍👧": "family-man,-girl,-girl",
  10626. "👩‍👦": "family-woman,-boy",
  10627. "👩‍👦‍👦": "family-woman,-boy,-boy",
  10628. "👩‍👧": "family-woman,-girl",
  10629. "👩‍👧‍👦": "family-woman,-girl,-boy",
  10630. "👩‍👧‍👧": "family-woman,-girl,-girl",
  10631. "🗣": "speaking-head",
  10632. "👤": "bust-in-silhouette",
  10633. "👥": "busts-in-silhouette",
  10634. "🫂": "people-hugging",
  10635. "👣": "footprints",
  10636. "🦰": "red-hair",
  10637. "🦱": "curly-hair",
  10638. "🦳": "white-hair",
  10639. "🦲": "bald",
  10640. "🐵": "monkey-face",
  10641. "🐒": "monkey",
  10642. "🦍": "gorilla",
  10643. "🦧": "orangutan",
  10644. "🐶": "dog-face",
  10645. "🐕": "dog",
  10646. "🦮": "guide-dog",
  10647. "🐕‍🦺": "service-dog",
  10648. "🐩": "poodle",
  10649. "🐺": "wolf",
  10650. "🦊": "fox",
  10651. "🦝": "raccoon",
  10652. "🐱": "cat-face",
  10653. "🐈": "cat",
  10654. "🐈‍⬛": "black-cat",
  10655. "🦁": "lion",
  10656. "🐯": "tiger-face",
  10657. "🐅": "tiger",
  10658. "🐆": "leopard",
  10659. "🐴": "horse-face",
  10660. "🫎": "⊛-moose",
  10661. "🫏": "⊛-donkey",
  10662. "🐎": "horse",
  10663. "🦄": "unicorn",
  10664. "🦓": "zebra",
  10665. "🦌": "deer",
  10666. "🦬": "bison",
  10667. "🐮": "cow-face",
  10668. "🐂": "ox",
  10669. "🐃": "water-buffalo",
  10670. "🐄": "cow",
  10671. "🐷": "pig-face",
  10672. "🐖": "pig",
  10673. "🐗": "boar",
  10674. "🐽": "pig-nose",
  10675. "🐏": "ram",
  10676. "🐑": "ewe",
  10677. "🐐": "goat",
  10678. "🐪": "camel",
  10679. "🐫": "two-hump-camel",
  10680. "🦙": "llama",
  10681. "🦒": "giraffe",
  10682. "🐘": "elephant",
  10683. "🦣": "mammoth",
  10684. "🦏": "rhinoceros",
  10685. "🦛": "hippopotamus",
  10686. "🐭": "mouse-face",
  10687. "🐁": "mouse",
  10688. "🐀": "rat",
  10689. "🐹": "hamster",
  10690. "🐰": "rabbit-face",
  10691. "🐇": "rabbit",
  10692. "🐿": "chipmunk",
  10693. "🦫": "beaver",
  10694. "🦔": "hedgehog",
  10695. "🦇": "bat",
  10696. "🐻": "bear",
  10697. "🐻‍❄️": "polar-bear",
  10698. "🐨": "koala",
  10699. "🐼": "panda",
  10700. "🦥": "sloth",
  10701. "🦦": "otter",
  10702. "🦨": "skunk",
  10703. "🦘": "kangaroo",
  10704. "🦡": "badger",
  10705. "🐾": "paw-prints",
  10706. "🦃": "turkey",
  10707. "🐔": "chicken",
  10708. "🐓": "rooster",
  10709. "🐣": "hatching-chick",
  10710. "🐤": "baby-chick",
  10711. "🐥": "front-facing-baby-chick",
  10712. "🐦": "bird",
  10713. "🐧": "penguin",
  10714. "🕊": "dove",
  10715. "🦅": "eagle",
  10716. "🦆": "duck",
  10717. "🦢": "swan",
  10718. "🦉": "owl",
  10719. "🦤": "dodo",
  10720. "🪶": "feather",
  10721. "🦩": "flamingo",
  10722. "🦚": "peacock",
  10723. "🦜": "parrot",
  10724. "🪽": "⊛-wing",
  10725. "🐦‍⬛": "⊛-black-bird",
  10726. "🪿": "⊛-goose",
  10727. "🐸": "frog",
  10728. "🐊": "crocodile",
  10729. "🐢": "turtle",
  10730. "🦎": "lizard",
  10731. "🐍": "snake",
  10732. "🐲": "dragon-face",
  10733. "🐉": "dragon",
  10734. "🦕": "sauropod",
  10735. "🦖": "t-rex",
  10736. "🐳": "spouting-whale",
  10737. "🐋": "whale",
  10738. "🐬": "dolphin",
  10739. "🦭": "seal",
  10740. "🐟": "fish",
  10741. "🐠": "tropical-fish",
  10742. "🐡": "blowfish",
  10743. "🦈": "shark",
  10744. "🐙": "octopus",
  10745. "🐚": "spiral-shell",
  10746. "🪸": "coral",
  10747. "🪼": "⊛-jellyfish",
  10748. "🐌": "snail",
  10749. "🦋": "butterfly",
  10750. "🐛": "bug",
  10751. "🐜": "ant",
  10752. "🐝": "honeybee",
  10753. "🪲": "beetle",
  10754. "🐞": "lady-beetle",
  10755. "🦗": "cricket",
  10756. "🪳": "cockroach",
  10757. "🕷": "spider",
  10758. "🕸": "spider-web",
  10759. "🦂": "scorpion",
  10760. "🦟": "mosquito",
  10761. "🪰": "fly",
  10762. "🪱": "worm",
  10763. "🦠": "microbe",
  10764. "💐": "bouquet",
  10765. "🌸": "cherry-blossom",
  10766. "💮": "white-flower",
  10767. "🪷": "lotus",
  10768. "🏵": "rosette",
  10769. "🌹": "rose",
  10770. "🥀": "wilted-flower",
  10771. "🌺": "hibiscus",
  10772. "🌻": "sunflower",
  10773. "🌼": "blossom",
  10774. "🌷": "tulip",
  10775. "🪻": "⊛-hyacinth",
  10776. "🌱": "seedling",
  10777. "🪴": "potted-plant",
  10778. "🌲": "evergreen-tree",
  10779. "🌳": "deciduous-tree",
  10780. "🌴": "palm-tree",
  10781. "🌵": "cactus",
  10782. "🌾": "sheaf-of-rice",
  10783. "🌿": "herb",
  10784. "☘": "shamrock",
  10785. "🍀": "four-leaf-clover",
  10786. "🍁": "maple-leaf",
  10787. "🍂": "fallen-leaf",
  10788. "🍃": "leaf-fluttering-in-wind",
  10789. "🪹": "empty-nest",
  10790. "🪺": "nest-with-eggs",
  10791. "🍄": "mushroom",
  10792. "🍇": "grapes",
  10793. "🍈": "melon",
  10794. "🍉": "watermelon",
  10795. "🍊": "tangerine",
  10796. "🍋": "lemon",
  10797. "🍌": "banana",
  10798. "🍍": "pineapple",
  10799. "🥭": "mango",
  10800. "🍎": "red-apple",
  10801. "🍏": "green-apple",
  10802. "🍐": "pear",
  10803. "🍑": "peach",
  10804. "🍒": "cherries",
  10805. "🍓": "strawberry",
  10806. "🫐": "blueberries",
  10807. "🥝": "kiwi-fruit",
  10808. "🍅": "tomato",
  10809. "🫒": "olive",
  10810. "🥥": "coconut",
  10811. "🥑": "avocado",
  10812. "🍆": "eggplant",
  10813. "🥔": "potato",
  10814. "🥕": "carrot",
  10815. "🌽": "ear-of-corn",
  10816. "🌶": "hot-pepper",
  10817. "🫑": "bell-pepper",
  10818. "🥒": "cucumber",
  10819. "🥬": "leafy-green",
  10820. "🥦": "broccoli",
  10821. "🧄": "garlic",
  10822. "🧅": "onion",
  10823. "🥜": "peanuts",
  10824. "🫘": "beans",
  10825. "🌰": "chestnut",
  10826. "🫚": "⊛-ginger-root",
  10827. "🫛": "⊛-pea-pod",
  10828. "🍞": "bread",
  10829. "🥐": "croissant",
  10830. "🥖": "baguette-bread",
  10831. "🫓": "flatbread",
  10832. "🥨": "pretzel",
  10833. "🥯": "bagel",
  10834. "🥞": "pancakes",
  10835. "🧇": "waffle",
  10836. "🧀": "cheese-wedge",
  10837. "🍖": "meat-on-bone",
  10838. "🍗": "poultry-leg",
  10839. "🥩": "cut-of-meat",
  10840. "🥓": "bacon",
  10841. "🍔": "hamburger",
  10842. "🍟": "french-fries",
  10843. "🍕": "pizza",
  10844. "🌭": "hot-dog",
  10845. "🥪": "sandwich",
  10846. "🌮": "taco",
  10847. "🌯": "burrito",
  10848. "🫔": "tamale",
  10849. "🥙": "stuffed-flatbread",
  10850. "🧆": "falafel",
  10851. "🥚": "egg",
  10852. "🍳": "cooking",
  10853. "🥘": "shallow-pan-of-food",
  10854. "🍲": "pot-of-food",
  10855. "🫕": "fondue",
  10856. "🥣": "bowl-with-spoon",
  10857. "🥗": "green-salad",
  10858. "🍿": "popcorn",
  10859. "🧈": "butter",
  10860. "🧂": "salt",
  10861. "🥫": "canned-food",
  10862. "🍱": "bento-box",
  10863. "🍘": "rice-cracker",
  10864. "🍙": "rice-ball",
  10865. "🍚": "cooked-rice",
  10866. "🍛": "curry-rice",
  10867. "🍜": "steaming-bowl",
  10868. "🍝": "spaghetti",
  10869. "🍠": "roasted-sweet-potato",
  10870. "🍢": "oden",
  10871. "🍣": "sushi",
  10872. "🍤": "fried-shrimp",
  10873. "🍥": "fish-cake-with-swirl",
  10874. "🥮": "moon-cake",
  10875. "🍡": "dango",
  10876. "🥟": "dumpling",
  10877. "🥠": "fortune-cookie",
  10878. "🥡": "takeout-box",
  10879. "🦀": "crab",
  10880. "🦞": "lobster",
  10881. "🦐": "shrimp",
  10882. "🦑": "squid",
  10883. "🦪": "oyster",
  10884. "🍦": "soft-ice-cream",
  10885. "🍧": "shaved-ice",
  10886. "🍨": "ice-cream",
  10887. "🍩": "doughnut",
  10888. "🍪": "cookie",
  10889. "🎂": "birthday-cake",
  10890. "🍰": "shortcake",
  10891. "🧁": "cupcake",
  10892. "🥧": "pie",
  10893. "🍫": "chocolate-bar",
  10894. "🍬": "candy",
  10895. "🍭": "lollipop",
  10896. "🍮": "custard",
  10897. "🍯": "honey-pot",
  10898. "🍼": "baby-bottle",
  10899. "🥛": "glass-of-milk",
  10900. "☕": "hot-beverage",
  10901. "🫖": "teapot",
  10902. "🍵": "teacup-without-handle",
  10903. "🍶": "sake",
  10904. "🍾": "bottle-with-popping-cork",
  10905. "🍷": "wine-glass",
  10906. "🍸": "cocktail-glass",
  10907. "🍹": "tropical-drink",
  10908. "🍺": "beer-mug",
  10909. "🍻": "clinking-beer-mugs",
  10910. "🥂": "clinking-glasses",
  10911. "🥃": "tumbler-glass",
  10912. "🫗": "pouring-liquid",
  10913. "🥤": "cup-with-straw",
  10914. "🧋": "bubble-tea",
  10915. "🧃": "beverage-box",
  10916. "🧉": "mate",
  10917. "🧊": "ice",
  10918. "🥢": "chopsticks",
  10919. "🍽": "fork-and-knife-with-plate",
  10920. "🍴": "fork-and-knife",
  10921. "🥄": "spoon",
  10922. "🔪": "kitchen-knife",
  10923. "🫙": "jar",
  10924. "🏺": "amphora",
  10925. "🌍": "globe-showing-europe-africa",
  10926. "🌎": "globe-showing-americas",
  10927. "🌏": "globe-showing-asia-australia",
  10928. "🌐": "globe-with-meridians",
  10929. "🗺": "world-map",
  10930. "🗾": "map-of-japan",
  10931. "🧭": "compass",
  10932. "🏔": "snow-capped-mountain",
  10933. "⛰": "mountain",
  10934. "🌋": "volcano",
  10935. "🗻": "mount-fuji",
  10936. "🏕": "camping",
  10937. "🏖": "beach-with-umbrella",
  10938. "🏜": "desert",
  10939. "🏝": "desert-island",
  10940. "🏞": "national-park",
  10941. "🏟": "stadium",
  10942. "🏛": "classical-building",
  10943. "🏗": "building-construction",
  10944. "🧱": "brick",
  10945. "🪨": "rock",
  10946. "🪵": "wood",
  10947. "🛖": "hut",
  10948. "🏘": "houses",
  10949. "🏚": "derelict-house",
  10950. "🏠": "house",
  10951. "🏡": "house-with-garden",
  10952. "🏢": "office-building",
  10953. "🏣": "japanese-post-office",
  10954. "🏤": "post-office",
  10955. "🏥": "hospital",
  10956. "🏦": "bank",
  10957. "🏨": "hotel",
  10958. "🏩": "love-hotel",
  10959. "🏪": "convenience-store",
  10960. "🏫": "school",
  10961. "🏬": "department-store",
  10962. "🏭": "factory",
  10963. "🏯": "japanese-castle",
  10964. "🏰": "castle",
  10965. "💒": "wedding",
  10966. "🗼": "tokyo-tower",
  10967. "🗽": "statue-of-liberty",
  10968. "⛪": "church",
  10969. "🕌": "mosque",
  10970. "🛕": "hindu-temple",
  10971. "🕍": "synagogue",
  10972. "⛩": "shinto-shrine",
  10973. "🕋": "kaaba",
  10974. "⛲": "fountain",
  10975. "⛺": "tent",
  10976. "🌁": "foggy",
  10977. "🌃": "night-with-stars",
  10978. "🏙": "cityscape",
  10979. "🌄": "sunrise-over-mountains",
  10980. "🌅": "sunrise",
  10981. "🌆": "cityscape-at-dusk",
  10982. "🌇": "sunset",
  10983. "🌉": "bridge-at-night",
  10984. "♨": "hot-springs",
  10985. "🎠": "carousel-horse",
  10986. "🛝": "playground-slide",
  10987. "🎡": "ferris-wheel",
  10988. "🎢": "roller-coaster",
  10989. "💈": "barber-pole",
  10990. "🎪": "circus-tent",
  10991. "🚂": "locomotive",
  10992. "🚃": "railway-car",
  10993. "🚄": "high-speed-train",
  10994. "🚅": "bullet-train",
  10995. "🚆": "train",
  10996. "🚇": "metro",
  10997. "🚈": "light-rail",
  10998. "🚉": "station",
  10999. "🚊": "tram",
  11000. "🚝": "monorail",
  11001. "🚞": "mountain-railway",
  11002. "🚋": "tram-car",
  11003. "🚌": "bus",
  11004. "🚍": "oncoming-bus",
  11005. "🚎": "trolleybus",
  11006. "🚐": "minibus",
  11007. "🚑": "ambulance",
  11008. "🚒": "fire-engine",
  11009. "🚓": "police-car",
  11010. "🚔": "oncoming-police-car",
  11011. "🚕": "taxi",
  11012. "🚖": "oncoming-taxi",
  11013. "🚗": "automobile",
  11014. "🚘": "oncoming-automobile",
  11015. "🚙": "sport-utility-vehicle",
  11016. "🛻": "pickup-truck",
  11017. "🚚": "delivery-truck",
  11018. "🚛": "articulated-lorry",
  11019. "🚜": "tractor",
  11020. "🏎": "racing-car",
  11021. "🏍": "motorcycle",
  11022. "🛵": "motor-scooter",
  11023. "🦽": "manual-wheelchair",
  11024. "🦼": "motorized-wheelchair",
  11025. "🛺": "auto-rickshaw",
  11026. "🚲": "bicycle",
  11027. "🛴": "kick-scooter",
  11028. "🛹": "skateboard",
  11029. "🛼": "roller-skate",
  11030. "🚏": "bus-stop",
  11031. "🛣": "motorway",
  11032. "🛤": "railway-track",
  11033. "🛢": "oil-drum",
  11034. "⛽": "fuel-pump",
  11035. "🛞": "wheel",
  11036. "🚨": "police-car-light",
  11037. "🚥": "horizontal-traffic-light",
  11038. "🚦": "vertical-traffic-light",
  11039. "🛑": "stop-sign",
  11040. "🚧": "construction",
  11041. "⚓": "anchor",
  11042. "🛟": "ring-buoy",
  11043. "⛵": "sailboat",
  11044. "🛶": "canoe",
  11045. "🚤": "speedboat",
  11046. "🛳": "passenger-ship",
  11047. "⛴": "ferry",
  11048. "🛥": "motor-boat",
  11049. "🚢": "ship",
  11050. "✈": "airplane",
  11051. "🛩": "small-airplane",
  11052. "🛫": "airplane-departure",
  11053. "🛬": "airplane-arrival",
  11054. "🪂": "parachute",
  11055. "💺": "seat",
  11056. "🚁": "helicopter",
  11057. "🚟": "suspension-railway",
  11058. "🚠": "mountain-cableway",
  11059. "🚡": "aerial-tramway",
  11060. "🛰": "satellite",
  11061. "🚀": "rocket",
  11062. "🛸": "flying-saucer",
  11063. "🛎": "bellhop-bell",
  11064. "🧳": "luggage",
  11065. "⌛": "hourglass-done",
  11066. "⏳": "hourglass-not-done",
  11067. "⌚": "watch",
  11068. "⏰": "alarm-clock",
  11069. "⏱": "stopwatch",
  11070. "⏲": "timer-clock",
  11071. "🕰": "mantelpiece-clock",
  11072. "🕛": "twelve-o-clock",
  11073. "🕧": "twelve-thirty",
  11074. "🕐": "one-o-clock",
  11075. "🕜": "one-thirty",
  11076. "🕑": "two-o-clock",
  11077. "🕝": "two-thirty",
  11078. "🕒": "three-o-clock",
  11079. "🕞": "three-thirty",
  11080. "🕓": "four-o-clock",
  11081. "🕟": "four-thirty",
  11082. "🕔": "five-o-clock",
  11083. "🕠": "five-thirty",
  11084. "🕕": "six-o-clock",
  11085. "🕡": "six-thirty",
  11086. "🕖": "seven-o-clock",
  11087. "🕢": "seven-thirty",
  11088. "🕗": "eight-o-clock",
  11089. "🕣": "eight-thirty",
  11090. "🕘": "nine-o-clock",
  11091. "🕤": "nine-thirty",
  11092. "🕙": "ten-o-clock",
  11093. "🕥": "ten-thirty",
  11094. "🕚": "eleven-o-clock",
  11095. "🕦": "eleven-thirty",
  11096. "🌑": "new-moon",
  11097. "🌒": "waxing-crescent-moon",
  11098. "🌓": "first-quarter-moon",
  11099. "🌔": "waxing-gibbous-moon",
  11100. "🌕": "full-moon",
  11101. "🌖": "waning-gibbous-moon",
  11102. "🌗": "last-quarter-moon",
  11103. "🌘": "waning-crescent-moon",
  11104. "🌙": "crescent-moon",
  11105. "🌚": "new-moon-face",
  11106. "🌛": "first-quarter-moon-face",
  11107. "🌜": "last-quarter-moon-face",
  11108. "🌡": "thermometer",
  11109. "☀": "sun",
  11110. "🌝": "full-moon-face",
  11111. "🌞": "sun-with-face",
  11112. "🪐": "ringed-planet",
  11113. "⭐": "star",
  11114. "🌟": "glowing-star",
  11115. "🌠": "shooting-star",
  11116. "🌌": "milky-way",
  11117. "☁": "cloud",
  11118. "⛅": "sun-behind-cloud",
  11119. "⛈": "cloud-with-lightning-and-rain",
  11120. "🌤": "sun-behind-small-cloud",
  11121. "🌥": "sun-behind-large-cloud",
  11122. "🌦": "sun-behind-rain-cloud",
  11123. "🌧": "cloud-with-rain",
  11124. "🌨": "cloud-with-snow",
  11125. "🌩": "cloud-with-lightning",
  11126. "🌪": "tornado",
  11127. "🌫": "fog",
  11128. "🌬": "wind-face",
  11129. "🌀": "cyclone",
  11130. "🌈": "rainbow",
  11131. "🌂": "closed-umbrella",
  11132. "☂": "umbrella",
  11133. "☔": "umbrella-with-rain-drops",
  11134. "⛱": "umbrella-on-ground",
  11135. "⚡": "high-voltage",
  11136. "❄": "snowflake",
  11137. "☃": "snowman",
  11138. "⛄": "snowman-without-snow",
  11139. "☄": "comet",
  11140. "🔥": "fire",
  11141. "💧": "droplet",
  11142. "🌊": "water-wave",
  11143. "🎃": "jack-o-lantern",
  11144. "🎄": "christmas-tree",
  11145. "🎆": "fireworks",
  11146. "🎇": "sparkler",
  11147. "🧨": "firecracker",
  11148. "✨": "sparkles",
  11149. "🎈": "balloon",
  11150. "🎉": "party-popper",
  11151. "🎊": "confetti-ball",
  11152. "🎋": "tanabata-tree",
  11153. "🎍": "pine-decoration",
  11154. "🎎": "japanese-dolls",
  11155. "🎏": "carp-streamer",
  11156. "🎐": "wind-chime",
  11157. "🎑": "moon-viewing-ceremony",
  11158. "🧧": "red-envelope",
  11159. "🎀": "ribbon",
  11160. "🎁": "wrapped-gift",
  11161. "🎗": "reminder-ribbon",
  11162. "🎟": "admission-tickets",
  11163. "🎫": "ticket",
  11164. "🎖": "military-medal",
  11165. "🏆": "trophy",
  11166. "🏅": "sports-medal",
  11167. "🥇": "1st-place-medal",
  11168. "🥈": "2nd-place-medal",
  11169. "🥉": "3rd-place-medal",
  11170. "⚽": "soccer-ball",
  11171. "⚾": "baseball",
  11172. "🥎": "softball",
  11173. "🏀": "basketball",
  11174. "🏐": "volleyball",
  11175. "🏈": "american-football",
  11176. "🏉": "rugby-football",
  11177. "🎾": "tennis",
  11178. "🥏": "flying-disc",
  11179. "🎳": "bowling",
  11180. "🏏": "cricket-game",
  11181. "🏑": "field-hockey",
  11182. "🏒": "ice-hockey",
  11183. "🥍": "lacrosse",
  11184. "🏓": "ping-pong",
  11185. "🏸": "badminton",
  11186. "🥊": "boxing-glove",
  11187. "🥋": "martial-arts-uniform",
  11188. "🥅": "goal-net",
  11189. "⛳": "flag-in-hole",
  11190. "⛸": "ice-skate",
  11191. "🎣": "fishing-pole",
  11192. "🤿": "diving-mask",
  11193. "🎽": "running-shirt",
  11194. "🎿": "skis",
  11195. "🛷": "sled",
  11196. "🥌": "curling-stone",
  11197. "🎯": "bullseye",
  11198. "🪀": "yo-yo",
  11199. "🪁": "kite",
  11200. "🔫": "water-pistol",
  11201. "🎱": "pool-8-ball",
  11202. "🔮": "crystal-ball",
  11203. "🪄": "magic-wand",
  11204. "🎮": "video-game",
  11205. "🕹": "joystick",
  11206. "🎰": "slot-machine",
  11207. "🎲": "game-die",
  11208. "🧩": "puzzle-piece",
  11209. "🧸": "teddy-bear",
  11210. "🪅": "piñata",
  11211. "🪩": "mirror-ball",
  11212. "🪆": "nesting-dolls",
  11213. "♠": "spade-suit",
  11214. "♥": "heart-suit",
  11215. "♦": "diamond-suit",
  11216. "♣": "club-suit",
  11217. "♟": "chess-pawn",
  11218. "🃏": "joker",
  11219. "🀄": "mahjong-red-dragon",
  11220. "🎴": "flower-playing-cards",
  11221. "🎭": "performing-arts",
  11222. "🖼": "framed-picture",
  11223. "🎨": "artist-palette",
  11224. "🧵": "thread",
  11225. "🪡": "sewing-needle",
  11226. "🧶": "yarn",
  11227. "🪢": "knot",
  11228. "👓": "glasses",
  11229. "🕶": "sunglasses",
  11230. "🥽": "goggles",
  11231. "🥼": "lab-coat",
  11232. "🦺": "safety-vest",
  11233. "👔": "necktie",
  11234. "👕": "t-shirt",
  11235. "👖": "jeans",
  11236. "🧣": "scarf",
  11237. "🧤": "gloves",
  11238. "🧥": "coat",
  11239. "🧦": "socks",
  11240. "👗": "dress",
  11241. "👘": "kimono",
  11242. "🥻": "sari",
  11243. "🩱": "one-piece-swimsuit",
  11244. "🩲": "briefs",
  11245. "🩳": "shorts",
  11246. "👙": "bikini",
  11247. "👚": "woman-s-clothes",
  11248. "🪭": "⊛-folding-hand-fan",
  11249. "👛": "purse",
  11250. "👜": "handbag",
  11251. "👝": "clutch-bag",
  11252. "🛍": "shopping-bags",
  11253. "🎒": "backpack",
  11254. "🩴": "thong-sandal",
  11255. "👞": "man-s-shoe",
  11256. "👟": "running-shoe",
  11257. "🥾": "hiking-boot",
  11258. "🥿": "flat-shoe",
  11259. "👠": "high-heeled-shoe",
  11260. "👡": "woman-s-sandal",
  11261. "🩰": "ballet-shoes",
  11262. "👢": "woman-s-boot",
  11263. "🪮": "⊛-hair-pick",
  11264. "👑": "crown",
  11265. "👒": "woman-s-hat",
  11266. "🎩": "top-hat",
  11267. "🎓": "graduation-cap",
  11268. "🧢": "billed-cap",
  11269. "🪖": "military-helmet",
  11270. "⛑": "rescue-worker-s-helmet",
  11271. "📿": "prayer-beads",
  11272. "💄": "lipstick",
  11273. "💍": "ring",
  11274. "💎": "gem-stone",
  11275. "🔇": "muted-speaker",
  11276. "🔈": "speaker-low-volume",
  11277. "🔉": "speaker-medium-volume",
  11278. "🔊": "speaker-high-volume",
  11279. "📢": "loudspeaker",
  11280. "📣": "megaphone",
  11281. "📯": "postal-horn",
  11282. "🔔": "bell",
  11283. "🔕": "bell-with-slash",
  11284. "🎼": "musical-score",
  11285. "🎵": "musical-note",
  11286. "🎶": "musical-notes",
  11287. "🎙": "studio-microphone",
  11288. "🎚": "level-slider",
  11289. "🎛": "control-knobs",
  11290. "🎤": "microphone",
  11291. "🎧": "headphone",
  11292. "📻": "radio",
  11293. "🎷": "saxophone",
  11294. "🪗": "accordion",
  11295. "🎸": "guitar",
  11296. "🎹": "musical-keyboard",
  11297. "🎺": "trumpet",
  11298. "🎻": "violin",
  11299. "🪕": "banjo",
  11300. "🥁": "drum",
  11301. "🪘": "long-drum",
  11302. "🪇": "maracas",
  11303. "🪈": "flute",
  11304. "📱": "mobile-phone",
  11305. "📲": "mobile-phone-with-arrow",
  11306. "☎": "telephone",
  11307. "📞": "telephone-receiver",
  11308. "📟": "pager",
  11309. "📠": "fax-machine",
  11310. "🔋": "battery",
  11311. "🪫": "low-battery",
  11312. "🔌": "electric-plug",
  11313. "💻": "laptop",
  11314. "🖥": "desktop-computer",
  11315. "🖨": "printer",
  11316. "⌨": "keyboard",
  11317. "🖱": "computer-mouse",
  11318. "🖲": "trackball",
  11319. "💽": "computer-disk",
  11320. "💾": "floppy-disk",
  11321. "💿": "optical-disk",
  11322. "📀": "dvd",
  11323. "🧮": "abacus",
  11324. "🎥": "movie-camera",
  11325. "🎞": "film-frames",
  11326. "📽": "film-projector",
  11327. "🎬": "clapper-board",
  11328. "📺": "television",
  11329. "📷": "camera",
  11330. "📸": "camera-with-flash",
  11331. "📹": "video-camera",
  11332. "📼": "videocassette",
  11333. "🔍": "magnifying-glass-tilted-left",
  11334. "🔎": "magnifying-glass-tilted-right",
  11335. "🕯": "candle",
  11336. "💡": "light-bulb",
  11337. "🔦": "flashlight",
  11338. "🏮": "red-paper-lantern",
  11339. "🪔": "diya-lamp",
  11340. "📔": "notebook-with-decorative-cover",
  11341. "📕": "closed-book",
  11342. "📖": "open-book",
  11343. "📗": "green-book",
  11344. "📘": "blue-book",
  11345. "📙": "orange-book",
  11346. "📚": "books",
  11347. "📓": "notebook",
  11348. "📒": "ledger",
  11349. "📃": "page-with-curl",
  11350. "📜": "scroll",
  11351. "📄": "page-facing-up",
  11352. "📰": "newspaper",
  11353. "🗞": "rolled-up-newspaper",
  11354. "📑": "bookmark-tabs",
  11355. "🔖": "bookmark",
  11356. "🏷": "label",
  11357. "💰": "money-bag",
  11358. "🪙": "coin",
  11359. "💴": "yen-banknote",
  11360. "💵": "dollar-banknote",
  11361. "💶": "euro-banknote",
  11362. "💷": "pound-banknote",
  11363. "💸": "money-with-wings",
  11364. "💳": "credit-card",
  11365. "🧾": "receipt",
  11366. "💹": "chart-increasing-with-yen",
  11367. "✉": "envelope",
  11368. "📧": "e-mail",
  11369. "📨": "incoming-envelope",
  11370. "📩": "envelope-with-arrow",
  11371. "📤": "outbox-tray",
  11372. "📥": "inbox-tray",
  11373. "📦": "package",
  11374. "📫": "closed-mailbox-with-raised-flag",
  11375. "📪": "closed-mailbox-with-lowered-flag",
  11376. "📬": "open-mailbox-with-raised-flag",
  11377. "📭": "open-mailbox-with-lowered-flag",
  11378. "📮": "postbox",
  11379. "🗳": "ballot-box-with-ballot",
  11380. "✏": "pencil",
  11381. "✒": "black-nib",
  11382. "🖋": "fountain-pen",
  11383. "🖊": "pen",
  11384. "🖌": "paintbrush",
  11385. "🖍": "crayon",
  11386. "📝": "memo",
  11387. "💼": "briefcase",
  11388. "📁": "file-folder",
  11389. "📂": "open-file-folder",
  11390. "🗂": "card-index-dividers",
  11391. "📅": "calendar",
  11392. "📆": "tear-off-calendar",
  11393. "🗒": "spiral-notepad",
  11394. "🗓": "spiral-calendar",
  11395. "📇": "card-index",
  11396. "📈": "chart-increasing",
  11397. "📉": "chart-decreasing",
  11398. "📊": "bar-chart",
  11399. "📋": "clipboard",
  11400. "📌": "pushpin",
  11401. "📍": "round-pushpin",
  11402. "📎": "paperclip",
  11403. "🖇": "linked-paperclips",
  11404. "📏": "straight-ruler",
  11405. "📐": "triangular-ruler",
  11406. "✂": "scissors",
  11407. "🗃": "card-file-box",
  11408. "🗄": "file-cabinet",
  11409. "🗑": "wastebasket",
  11410. "🔒": "locked",
  11411. "🔓": "unlocked",
  11412. "🔏": "locked-with-pen",
  11413. "🔐": "locked-with-key",
  11414. "🔑": "key",
  11415. "🗝": "old-key",
  11416. "🔨": "hammer",
  11417. "🪓": "axe",
  11418. "⛏": "pick",
  11419. "⚒": "hammer-and-pick",
  11420. "🛠": "hammer-and-wrench",
  11421. "🗡": "dagger",
  11422. "⚔": "crossed-swords",
  11423. "💣": "bomb",
  11424. "🪃": "boomerang",
  11425. "🏹": "bow-and-arrow",
  11426. "🛡": "shield",
  11427. "🪚": "carpentry-saw",
  11428. "🔧": "wrench",
  11429. "🪛": "screwdriver",
  11430. "🔩": "nut-and-bolt",
  11431. "⚙": "gear",
  11432. "🗜": "clamp",
  11433. "⚖": "balance-scale",
  11434. "🦯": "white-cane",
  11435. "🔗": "link",
  11436. "⛓": "chains",
  11437. "🪝": "hook",
  11438. "🧰": "toolbox",
  11439. "🧲": "magnet",
  11440. "🪜": "ladder",
  11441. "⚗": "alembic",
  11442. "🧪": "test-tube",
  11443. "🧫": "petri-dish",
  11444. "🧬": "dna",
  11445. "🔬": "microscope",
  11446. "🔭": "telescope",
  11447. "📡": "satellite-antenna",
  11448. "💉": "syringe",
  11449. "🩸": "drop-of-blood",
  11450. "💊": "pill",
  11451. "🩹": "adhesive-bandage",
  11452. "🩼": "crutch",
  11453. "🩺": "stethoscope",
  11454. "🩻": "x-ray",
  11455. "🚪": "door",
  11456. "🛗": "elevator",
  11457. "🪞": "mirror",
  11458. "🪟": "window",
  11459. "🛏": "bed",
  11460. "🛋": "couch-and-lamp",
  11461. "🪑": "chair",
  11462. "🚽": "toilet",
  11463. "🪠": "plunger",
  11464. "🚿": "shower",
  11465. "🛁": "bathtub",
  11466. "🪤": "mouse-trap",
  11467. "🪒": "razor",
  11468. "🧴": "lotion-bottle",
  11469. "🧷": "safety-pin",
  11470. "🧹": "broom",
  11471. "🧺": "basket",
  11472. "🧻": "roll-of-paper",
  11473. "🪣": "bucket",
  11474. "🧼": "soap",
  11475. "🫧": "bubbles",
  11476. "🪥": "toothbrush",
  11477. "🧽": "sponge",
  11478. "🧯": "fire-extinguisher",
  11479. "🛒": "shopping-cart",
  11480. "🚬": "cigarette",
  11481. "⚰": "coffin",
  11482. "🪦": "headstone",
  11483. "⚱": "funeral-urn",
  11484. "🧿": "nazar-amulet",
  11485. "🪬": "hamsa",
  11486. "🗿": "moai",
  11487. "🪧": "placard",
  11488. "🪪": "identification-card",
  11489. "🏧": "atm-sign",
  11490. "🚮": "litter-in-bin-sign",
  11491. "🚰": "potable-water",
  11492. "♿": "wheelchair-symbol",
  11493. "🚹": "men-s-room",
  11494. "🚺": "women-s-room",
  11495. "🚻": "restroom",
  11496. "🚼": "baby-symbol",
  11497. "🚾": "water-closet",
  11498. "🛂": "passport-control",
  11499. "🛃": "customs",
  11500. "🛄": "baggage-claim",
  11501. "🛅": "left-luggage",
  11502. "⚠": "warning",
  11503. "🚸": "children-crossing",
  11504. "⛔": "no-entry",
  11505. "🚫": "prohibited",
  11506. "🚳": "no-bicycles",
  11507. "🚭": "no-smoking",
  11508. "🚯": "no-littering",
  11509. "🚱": "non-potable-water",
  11510. "🚷": "no-pedestrians",
  11511. "📵": "no-mobile-phones",
  11512. "🔞": "no-one-under-eighteen",
  11513. "☢": "radioactive",
  11514. "☣": "biohazard",
  11515. "⬆": "up-arrow",
  11516. "↗": "up-right-arrow",
  11517. "➡": "right-arrow",
  11518. "↘": "down-right-arrow",
  11519. "⬇": "down-arrow",
  11520. "↙": "down-left-arrow",
  11521. "⬅": "left-arrow",
  11522. "↖": "up-left-arrow",
  11523. "↕": "up-down-arrow",
  11524. "↔": "left-right-arrow",
  11525. "↩": "right-arrow-curving-left",
  11526. "↪": "left-arrow-curving-right",
  11527. "⤴": "right-arrow-curving-up",
  11528. "⤵": "right-arrow-curving-down",
  11529. "🔃": "clockwise-vertical-arrows",
  11530. "🔄": "counterclockwise-arrows-button",
  11531. "🔙": "back-arrow",
  11532. "🔚": "end-arrow",
  11533. "🔛": "on!-arrow",
  11534. "🔜": "soon-arrow",
  11535. "🔝": "top-arrow",
  11536. "🛐": "place-of-worship",
  11537. "⚛": "atom-symbol",
  11538. "🕉": "om",
  11539. "✡": "star-of-david",
  11540. "☸": "wheel-of-dharma",
  11541. "☯": "yin-yang",
  11542. "✝": "latin-cross",
  11543. "☦": "orthodox-cross",
  11544. "☪": "star-and-crescent",
  11545. "☮": "peace-symbol",
  11546. "🕎": "menorah",
  11547. "🔯": "dotted-six-pointed-star",
  11548. "🪯": "⊛-khanda",
  11549. "♈": "aries",
  11550. "♉": "taurus",
  11551. "♊": "gemini",
  11552. "♋": "cancer",
  11553. "♌": "leo",
  11554. "♍": "virgo",
  11555. "♎": "libra",
  11556. "♏": "scorpio",
  11557. "♐": "sagittarius",
  11558. "♑": "capricorn",
  11559. "♒": "aquarius",
  11560. "♓": "pisces",
  11561. "⛎": "ophiuchus",
  11562. "🔀": "shuffle-tracks-button",
  11563. "🔁": "repeat-button",
  11564. "🔂": "repeat-single-button",
  11565. "▶": "play-button",
  11566. "⏩": "fast-forward-button",
  11567. "⏭": "next-track-button",
  11568. "⏯": "play-or-pause-button",
  11569. "◀": "reverse-button",
  11570. "⏪": "fast-reverse-button",
  11571. "⏮": "last-track-button",
  11572. "🔼": "upwards-button",
  11573. "⏫": "fast-up-button",
  11574. "🔽": "downwards-button",
  11575. "⏬": "fast-down-button",
  11576. "⏸": "pause-button",
  11577. "⏹": "stop-button",
  11578. "⏺": "record-button",
  11579. "⏏": "eject-button",
  11580. "🎦": "cinema",
  11581. "🔅": "dim-button",
  11582. "🔆": "bright-button",
  11583. "📶": "antenna-bars",
  11584. "🛜": "⊛-wireless",
  11585. "📳": "vibration-mode",
  11586. "📴": "mobile-phone-off",
  11587. "♀": "female-sign",
  11588. "♂": "male-sign",
  11589. "⚧": "transgender-symbol",
  11590. "✖": "multiply",
  11591. "➕": "plus",
  11592. "➖": "minus",
  11593. "➗": "divide",
  11594. "🟰": "heavy-equals-sign",
  11595. "♾": "infinity",
  11596. "‼": "double-exclamation-mark",
  11597. "⁉": "exclamation-question-mark",
  11598. "❓": "red-question-mark",
  11599. "❔": "white-question-mark",
  11600. "❕": "white-exclamation-mark",
  11601. "❗": "red-exclamation-mark",
  11602. "〰": "wavy-dash",
  11603. "💱": "currency-exchange",
  11604. "💲": "heavy-dollar-sign",
  11605. "⚕": "medical-symbol",
  11606. "♻": "recycling-symbol",
  11607. "⚜": "fleur-de-lis",
  11608. "🔱": "trident-emblem",
  11609. "📛": "name-badge",
  11610. "🔰": "japanese-symbol-for-beginner",
  11611. "⭕": "hollow-red-circle",
  11612. "✅": "check-mark-button",
  11613. "☑": "check-box-with-check",
  11614. "✔": "check-mark",
  11615. "❌": "cross-mark",
  11616. "❎": "cross-mark-button",
  11617. "➰": "curly-loop",
  11618. "➿": "double-curly-loop",
  11619. "〽": "part-alternation-mark",
  11620. "✳": "eight-spoked-asterisk",
  11621. "✴": "eight-pointed-star",
  11622. "❇": "sparkle",
  11623. "©": "copyright",
  11624. "®": "registered",
  11625. "™": "trade-mark",
  11626. "#️⃣": "keycap-#",
  11627. "*️⃣": "keycap-*",
  11628. "0️⃣": "keycap-0",
  11629. "1️⃣": "keycap-1",
  11630. "2️⃣": "keycap-2",
  11631. "3️⃣": "keycap-3",
  11632. "4️⃣": "keycap-4",
  11633. "5️⃣": "keycap-5",
  11634. "6️⃣": "keycap-6",
  11635. "7️⃣": "keycap-7",
  11636. "8️⃣": "keycap-8",
  11637. "9️⃣": "keycap-9",
  11638. "🔟": "keycap-10",
  11639. "🔠": "input-latin-uppercase",
  11640. "🔡": "input-latin-lowercase",
  11641. "🔢": "input-numbers",
  11642. "🔣": "input-symbols",
  11643. "🔤": "input-latin-letters",
  11644. "🅰": "a-button-(blood-type)",
  11645. "🆎": "ab-button-(blood-type)",
  11646. "🅱": "b-button-(blood-type)",
  11647. "🆑": "cl-button",
  11648. "🆒": "cool-button",
  11649. "🆓": "free-button",
  11650. ℹ: "information",
  11651. "🆔": "id-button",
  11652. "Ⓜ": "circled-m",
  11653. "🆕": "new-button",
  11654. "🆖": "ng-button",
  11655. "🅾": "o-button-(blood-type)",
  11656. "🆗": "ok-button",
  11657. "🅿": "p-button",
  11658. "🆘": "sos-button",
  11659. "🆙": "up!-button",
  11660. "🆚": "vs-button",
  11661. "🈁": "japanese-here-button",
  11662. "🈂": "japanese-service-charge-button",
  11663. "🈷": "japanese-monthly-amount-button",
  11664. "🈶": "japanese-not-free-of-charge-button",
  11665. "🈯": "japanese-reserved-button",
  11666. "🉐": "japanese-bargain-button",
  11667. "🈹": "japanese-discount-button",
  11668. "🈚": "japanese-free-of-charge-button",
  11669. "🈲": "japanese-prohibited-button",
  11670. "🉑": "japanese-acceptable-button",
  11671. "🈸": "japanese-application-button",
  11672. "🈴": "japanese-passing-grade-button",
  11673. "🈳": "japanese-vacancy-button",
  11674. "㊗": "japanese-congratulations-button",
  11675. "㊙": "japanese-secret-button",
  11676. "🈺": "japanese-open-for-business-button",
  11677. "🈵": "japanese-no-vacancy-button",
  11678. "🔴": "red-circle",
  11679. "🟠": "orange-circle",
  11680. "🟡": "yellow-circle",
  11681. "🟢": "green-circle",
  11682. "🔵": "blue-circle",
  11683. "🟣": "purple-circle",
  11684. "🟤": "brown-circle",
  11685. "⚫": "black-circle",
  11686. "⚪": "white-circle",
  11687. "🟥": "red-square",
  11688. "🟧": "orange-square",
  11689. "🟨": "yellow-square",
  11690. "🟩": "green-square",
  11691. "🟦": "blue-square",
  11692. "🟪": "purple-square",
  11693. "🟫": "brown-square",
  11694. "⬛": "black-large-square",
  11695. "⬜": "white-large-square",
  11696. "◼": "black-medium-square",
  11697. "◻": "white-medium-square",
  11698. "◾": "black-medium-small-square",
  11699. "◽": "white-medium-small-square",
  11700. "▪": "black-small-square",
  11701. "▫": "white-small-square",
  11702. "🔶": "large-orange-diamond",
  11703. "🔷": "large-blue-diamond",
  11704. "🔸": "small-orange-diamond",
  11705. "🔹": "small-blue-diamond",
  11706. "🔺": "red-triangle-pointed-up",
  11707. "🔻": "red-triangle-pointed-down",
  11708. "💠": "diamond-with-a-dot",
  11709. "🔘": "radio-button",
  11710. "🔳": "white-square-button",
  11711. "🔲": "black-square-button",
  11712. "🏁": "chequered-flag",
  11713. "🚩": "triangular-flag",
  11714. "🎌": "crossed-flags",
  11715. "🏴": "black-flag",
  11716. "🏳": "white-flag",
  11717. "🏳️‍🌈": "rainbow-flag",
  11718. "🏳️‍⚧️": "transgender-flag",
  11719. "🏴‍☠️": "pirate-flag",
  11720. "🇦🇨": "flag-ascension-island",
  11721. "🇦🇩": "flag-andorra",
  11722. "🇦🇪": "flag-united-arab-emirates",
  11723. "🇦🇫": "flag-afghanistan",
  11724. "🇦🇬": "flag-antigua-and-barbuda",
  11725. "🇦🇮": "flag-anguilla",
  11726. "🇦🇱": "flag-albania",
  11727. "🇦🇲": "flag-armenia",
  11728. "🇦🇴": "flag-angola",
  11729. "🇦🇶": "flag-antarctica",
  11730. "🇦🇷": "flag-argentina",
  11731. "🇦🇸": "flag-american-samoa",
  11732. "🇦🇹": "flag-austria",
  11733. "🇦🇺": "flag-australia",
  11734. "🇦🇼": "flag-aruba",
  11735. "🇦🇽": "flag-åland-islands",
  11736. "🇦🇿": "flag-azerbaijan",
  11737. "🇧🇦": "flag-bosnia-and-herzegovina",
  11738. "🇧🇧": "flag-barbados",
  11739. "🇧🇩": "flag-bangladesh",
  11740. "🇧🇪": "flag-belgium",
  11741. "🇧🇫": "flag-burkina-faso",
  11742. "🇧🇬": "flag-bulgaria",
  11743. "🇧🇭": "flag-bahrain",
  11744. "🇧🇮": "flag-burundi",
  11745. "🇧🇯": "flag-benin",
  11746. "🇧🇱": "flag-st-barthelemy",
  11747. "🇧🇲": "flag-bermuda",
  11748. "🇧🇳": "flag-brunei",
  11749. "🇧🇴": "flag-bolivia",
  11750. "🇧🇶": "flag-caribbean-netherlands",
  11751. "🇧🇷": "flag-brazil",
  11752. "🇧🇸": "flag-bahamas",
  11753. "🇧🇹": "flag-bhutan",
  11754. "🇧🇻": "flag-bouvet-island",
  11755. "🇧🇼": "flag-botswana",
  11756. "🇧🇾": "flag-belarus",
  11757. "🇧🇿": "flag-belize",
  11758. "🇨🇦": "flag-canada",
  11759. "🇨🇨": "flag-cocos-(keeling)-islands",
  11760. "🇨🇩": "flag-congo---kinshasa",
  11761. "🇨🇫": "flag-central-african-republic",
  11762. "🇨🇬": "flag-congo---brazzaville",
  11763. "🇨🇭": "flag-switzerland",
  11764. "🇨🇮": "flag-côte-d-ivoire",
  11765. "🇨🇰": "flag-cook-islands",
  11766. "🇨🇱": "flag-chile",
  11767. "🇨🇲": "flag-cameroon",
  11768. "🇨🇳": "flag-china",
  11769. "🇨🇴": "flag-colombia",
  11770. "🇨🇵": "flag-clipperton-island",
  11771. "🇨🇷": "flag-costa-rica",
  11772. "🇨🇺": "flag-cuba",
  11773. "🇨🇻": "flag-cape-verde",
  11774. "🇨🇼": "flag-curaçao",
  11775. "🇨🇽": "flag-christmas-island",
  11776. "🇨🇾": "flag-cyprus",
  11777. "🇨🇿": "flag-czechia",
  11778. "🇩🇪": "flag-germany",
  11779. "🇩🇬": "flag-diego-garcia",
  11780. "🇩🇯": "flag-djibouti",
  11781. "🇩🇰": "flag-denmark",
  11782. "🇩🇲": "flag-dominica",
  11783. "🇩🇴": "flag-dominican-republic",
  11784. "🇩🇿": "flag-algeria",
  11785. "🇪🇦": "flag-ceuta-and-melilla",
  11786. "🇪🇨": "flag-ecuador",
  11787. "🇪🇪": "flag-estonia",
  11788. "🇪🇬": "flag-egypt",
  11789. "🇪🇭": "flag-western-sahara",
  11790. "🇪🇷": "flag-eritrea",
  11791. "🇪🇸": "flag-spain",
  11792. "🇪🇹": "flag-ethiopia",
  11793. "🇪🇺": "flag-european-union",
  11794. "🇫🇮": "flag-finland",
  11795. "🇫🇯": "flag-fiji",
  11796. "🇫🇰": "flag-falkland-islands",
  11797. "🇫🇲": "flag-micronesia",
  11798. "🇫🇴": "flag-faroe-islands",
  11799. "🇫🇷": "flag-france",
  11800. "🇬🇦": "flag-gabon",
  11801. "🇬🇧": "flag-united-kingdom",
  11802. "🇬🇩": "flag-grenada",
  11803. "🇬🇪": "flag-georgia",
  11804. "🇬🇫": "flag-french-guiana",
  11805. "🇬🇬": "flag-guernsey",
  11806. "🇬🇭": "flag-ghana",
  11807. "🇬🇮": "flag-gibraltar",
  11808. "🇬🇱": "flag-greenland",
  11809. "🇬🇲": "flag-gambia",
  11810. "🇬🇳": "flag-guinea",
  11811. "🇬🇵": "flag-guadeloupe",
  11812. "🇬🇶": "flag-equatorial-guinea",
  11813. "🇬🇷": "flag-greece",
  11814. "🇬🇸": "flag-south-georgia-and-south-sandwich-islands",
  11815. "🇬🇹": "flag-guatemala",
  11816. "🇬🇺": "flag-guam",
  11817. "🇬🇼": "flag-guinea-bissau",
  11818. "🇬🇾": "flag-guyana",
  11819. "🇭🇰": "flag-hong-kong-sar-china",
  11820. "🇭🇲": "flag-heard-and-mcdonald-islands",
  11821. "🇭🇳": "flag-honduras",
  11822. "🇭🇷": "flag-croatia",
  11823. "🇭🇹": "flag-haiti",
  11824. "🇭🇺": "flag-hungary",
  11825. "🇮🇨": "flag-canary-islands",
  11826. "🇮🇩": "flag-indonesia",
  11827. "🇮🇪": "flag-ireland",
  11828. "🇮🇱": "flag-israel",
  11829. "🇮🇲": "flag-isle-of-man",
  11830. "🇮🇳": "flag-india",
  11831. "🇮🇴": "flag-british-indian-ocean-territory",
  11832. "🇮🇶": "flag-iraq",
  11833. "🇮🇷": "flag-iran",
  11834. "🇮🇸": "flag-iceland",
  11835. "🇮🇹": "flag-italy",
  11836. "🇯🇪": "flag-jersey",
  11837. "🇯🇲": "flag-jamaica",
  11838. "🇯🇴": "flag-jordan",
  11839. "🇯🇵": "flag-japan",
  11840. "🇰🇪": "flag-kenya",
  11841. "🇰🇬": "flag-kyrgyzstan",
  11842. "🇰🇭": "flag-cambodia",
  11843. "🇰🇮": "flag-kiribati",
  11844. "🇰🇲": "flag-comoros",
  11845. "🇰🇳": "flag-st-kitts-and-nevis",
  11846. "🇰🇵": "flag-north-korea",
  11847. "🇰🇷": "flag-south-korea",
  11848. "🇰🇼": "flag-kuwait",
  11849. "🇰🇾": "flag-cayman-islands",
  11850. "🇰🇿": "flag-kazakhstan",
  11851. "🇱🇦": "flag-laos",
  11852. "🇱🇧": "flag-lebanon",
  11853. "🇱🇨": "flag-st-lucia",
  11854. "🇱🇮": "flag-liechtenstein",
  11855. "🇱🇰": "flag-sri-lanka",
  11856. "🇱🇷": "flag-liberia",
  11857. "🇱🇸": "flag-lesotho",
  11858. "🇱🇹": "flag-lithuania",
  11859. "🇱🇺": "flag-luxembourg",
  11860. "🇱🇻": "flag-latvia",
  11861. "🇱🇾": "flag-libya",
  11862. "🇲🇦": "flag-morocco",
  11863. "🇲🇨": "flag-monaco",
  11864. "🇲🇩": "flag-moldova",
  11865. "🇲🇪": "flag-montenegro",
  11866. "🇲🇫": "flag-st-martin",
  11867. "🇲🇬": "flag-madagascar",
  11868. "🇲🇭": "flag-marshall-islands",
  11869. "🇲🇰": "flag-north-macedonia",
  11870. "🇲🇱": "flag-mali",
  11871. "🇲🇲": "flag-myanmar-(burma)",
  11872. "🇲🇳": "flag-mongolia",
  11873. "🇲🇴": "flag-macao-sar-china",
  11874. "🇲🇵": "flag-northern-mariana-islands",
  11875. "🇲🇶": "flag-martinique",
  11876. "🇲🇷": "flag-mauritania",
  11877. "🇲🇸": "flag-montserrat",
  11878. "🇲🇹": "flag-malta",
  11879. "🇲🇺": "flag-mauritius",
  11880. "🇲🇻": "flag-maldives",
  11881. "🇲🇼": "flag-malawi",
  11882. "🇲🇽": "flag-mexico",
  11883. "🇲🇾": "flag-malaysia",
  11884. "🇲🇿": "flag-mozambique",
  11885. "🇳🇦": "flag-namibia",
  11886. "🇳🇨": "flag-new-caledonia",
  11887. "🇳🇪": "flag-niger",
  11888. "🇳🇫": "flag-norfolk-island",
  11889. "🇳🇬": "flag-nigeria",
  11890. "🇳🇮": "flag-nicaragua",
  11891. "🇳🇱": "flag-netherlands",
  11892. "🇳🇴": "flag-norway",
  11893. "🇳🇵": "flag-nepal",
  11894. "🇳🇷": "flag-nauru",
  11895. "🇳🇺": "flag-niue",
  11896. "🇳🇿": "flag-new-zealand",
  11897. "🇴🇲": "flag-oman",
  11898. "🇵🇦": "flag-panama",
  11899. "🇵🇪": "flag-peru",
  11900. "🇵🇫": "flag-french-polynesia",
  11901. "🇵🇬": "flag-papua-new-guinea",
  11902. "🇵🇭": "flag-philippines",
  11903. "🇵🇰": "flag-pakistan",
  11904. "🇵🇱": "flag-poland",
  11905. "🇵🇲": "flag-st-pierre-and-miquelon",
  11906. "🇵🇳": "flag-pitcairn-islands",
  11907. "🇵🇷": "flag-puerto-rico",
  11908. "🇵🇸": "flag-palestinian-territories",
  11909. "🇵🇹": "flag-portugal",
  11910. "🇵🇼": "flag-palau",
  11911. "🇵🇾": "flag-paraguay",
  11912. "🇶🇦": "flag-qatar",
  11913. "🇷🇪": "flag-reunion",
  11914. "🇷🇴": "flag-romania",
  11915. "🇷🇸": "flag-serbia",
  11916. "🇷🇺": "flag-russia",
  11917. "🇷🇼": "flag-rwanda",
  11918. "🇸🇦": "flag-saudi-arabia",
  11919. "🇸🇧": "flag-solomon-islands",
  11920. "🇸🇨": "flag-seychelles",
  11921. "🇸🇩": "flag-sudan",
  11922. "🇸🇪": "flag-sweden",
  11923. "🇸🇬": "flag-singapore",
  11924. "🇸🇭": "flag-st-helena",
  11925. "🇸🇮": "flag-slovenia",
  11926. "🇸🇯": "flag-svalbard-and-jan-mayen",
  11927. "🇸🇰": "flag-slovakia",
  11928. "🇸🇱": "flag-sierra-leone",
  11929. "🇸🇲": "flag-san-marino",
  11930. "🇸🇳": "flag-senegal",
  11931. "🇸🇴": "flag-somalia",
  11932. "🇸🇷": "flag-suriname",
  11933. "🇸🇸": "flag-south-sudan",
  11934. "🇸🇹": "flag-são-tome-and-príncipe",
  11935. "🇸🇻": "flag-el-salvador",
  11936. "🇸🇽": "flag-sint-maarten",
  11937. "🇸🇾": "flag-syria",
  11938. "🇸🇿": "flag-eswatini",
  11939. "🇹🇦": "flag-tristan-da-cunha",
  11940. "🇹🇨": "flag-turks-and-caicos-islands",
  11941. "🇹🇩": "flag-chad",
  11942. "🇹🇫": "flag-french-southern-territories",
  11943. "🇹🇬": "flag-togo",
  11944. "🇹🇭": "flag-thailand",
  11945. "🇹🇯": "flag-tajikistan",
  11946. "🇹🇰": "flag-tokelau",
  11947. "🇹🇱": "flag-timor-leste",
  11948. "🇹🇲": "flag-turkmenistan",
  11949. "🇹🇳": "flag-tunisia",
  11950. "🇹🇴": "flag-tonga",
  11951. "🇹🇷": "flag-turkey",
  11952. "🇹🇹": "flag-trinidad-and-tobago",
  11953. "🇹🇻": "flag-tuvalu",
  11954. "🇹🇼": "flag-taiwan",
  11955. "🇹🇿": "flag-tanzania",
  11956. "🇺🇦": "flag-ukraine",
  11957. "🇺🇬": "flag-uganda",
  11958. "🇺🇲": "flag-us-outlying-islands",
  11959. "🇺🇳": "flag-united-nations",
  11960. "🇺🇸": "flag-united-states",
  11961. "🇺🇾": "flag-uruguay",
  11962. "🇺🇿": "flag-uzbekistan",
  11963. "🇻🇦": "flag-vatican-city",
  11964. "🇻🇨": "flag-st-vincent-and-grenadines",
  11965. "🇻🇪": "flag-venezuela",
  11966. "🇻🇬": "flag-british-virgin-islands",
  11967. "🇻🇮": "flag-us-virgin-islands",
  11968. "🇻🇳": "flag-vietnam",
  11969. "🇻🇺": "flag-vanuatu",
  11970. "🇼🇫": "flag-wallis-and-futuna",
  11971. "🇼🇸": "flag-samoa",
  11972. "🇽🇰": "flag-kosovo",
  11973. "🇾🇪": "flag-yemen",
  11974. "🇾🇹": "flag-mayotte",
  11975. "🇿🇦": "flag-south-africa",
  11976. "🇿🇲": "flag-zambia",
  11977. "🇿🇼": "flag-zimbabwe",
  11978. "🏴󠁧󠁢󠁥󠁮󠁧󠁿": "flag-england",
  11979. "🏴󠁧󠁢󠁳󠁣󠁴󠁿": "flag-scotland",
  11980. "🏴󠁧󠁢󠁷󠁬󠁳󠁿": "flag-wales"
  11981. };
  11982. const EMOJIS = Object.keys(EMOJI_NAMES);
  11983. async function formatFilename(content, options, util) {
  11984. let filename = (await evalTemplate(options.filenameTemplate, options, util, content)) || "";
  11985. if (options.replaceEmojisInFilename) {
  11986. EMOJIS.forEach(emoji => (filename = filename.replaceAll(emoji, " _" + EMOJI_NAMES[emoji] + "_ ")));
  11987. }
  11988. const replacementCharacter = options.filenameReplacementCharacter;
  11989. filename = getValidFilename(filename, options.filenameReplacedCharacters, replacementCharacter);
  11990. if (!options.backgroundSave) {
  11991. filename = filename.replace(/\//g, replacementCharacter);
  11992. }
  11993. if (!options.keepFilename && ((options.filenameMaxLengthUnit == "bytes" && util.getContentSize(filename) > options.filenameMaxLength) || filename.length > options.filenameMaxLength)) {
  11994. const extensionMatch = filename.match(/(\.[^.]{3,4})$/);
  11995. const extension = extensionMatch && extensionMatch[0] && extensionMatch[0].length > 1 ? extensionMatch[0] : "";
  11996. filename = options.filenameMaxLengthUnit == "bytes" ? await truncateText(filename, options.filenameMaxLength - extension.length) : filename.substring(0, options.filenameMaxLength - extension.length);
  11997. filename = filename + "…" + extension;
  11998. }
  11999. if (!filename) {
  12000. filename = "Unnamed page";
  12001. }
  12002. return filename;
  12003. }
  12004. async function evalTemplate(template = "", options, util, content, dontReplaceSlash) {
  12005. const url = new URL(options.saveUrl);
  12006. template = await evalTemplateVariable(template, "page-title", () => options.title || "No title", dontReplaceSlash, options.filenameReplacementCharacter);
  12007. template = await evalTemplateVariable(template, "page-heading", () => options.info.heading || "No heading", dontReplaceSlash, options.filenameReplacementCharacter);
  12008. template = await evalTemplateVariable(template, "page-language", () => options.info.lang || "No language", dontReplaceSlash, options.filenameReplacementCharacter);
  12009. template = await evalTemplateVariable(template, "page-description", () => options.info.description || "No description", dontReplaceSlash, options.filenameReplacementCharacter);
  12010. template = await evalTemplateVariable(template, "page-author", () => options.info.author || "No author", dontReplaceSlash, options.filenameReplacementCharacter);
  12011. template = await evalTemplateVariable(template, "page-creator", () => options.info.creator || "No creator", dontReplaceSlash, options.filenameReplacementCharacter);
  12012. template = await evalTemplateVariable(template, "page-publisher", () => options.info.publisher || "No publisher", dontReplaceSlash, options.filenameReplacementCharacter);
  12013. await evalDate(options.saveDate);
  12014. await evalDate(options.visitDate, "visit-");
  12015. template = await evalTemplateVariable(template, "url-hash", () => url.hash.substring(1) || "No hash", dontReplaceSlash, options.filenameReplacementCharacter);
  12016. template = await evalTemplateVariable(template, "url-host", () => url.host.replace(/\/$/, "") || "No host", dontReplaceSlash, options.filenameReplacementCharacter);
  12017. template = await evalTemplateVariable(template, "url-hostname", () => url.hostname.replace(/\/$/, "") || "No hostname", dontReplaceSlash, options.filenameReplacementCharacter);
  12018. const urlHref = decode(url.href);
  12019. template = await evalTemplateVariable(template, "url-href", () => urlHref || "No href", dontReplaceSlash === undefined ? true : dontReplaceSlash, options.filenameReplacementCharacter);
  12020. template = await evalTemplateVariable(template, "url-href-digest-sha-1", urlHref ? async () => util.digest("SHA-1", urlHref) : "No href", dontReplaceSlash, options.filenameReplacementCharacter);
  12021. template = await evalTemplateVariable(template, "url-href-flat", () => decode(url.href) || "No href", false, options.filenameReplacementCharacter);
  12022. template = await evalTemplateVariable(template, "url-referrer", () => decode(options.referrer) || "No referrer", dontReplaceSlash === undefined ? true : dontReplaceSlash, options.filenameReplacementCharacter);
  12023. template = await evalTemplateVariable(template, "url-referrer-flat", () => decode(options.referrer) || "No referrer", false, options.filenameReplacementCharacter);
  12024. template = await evalTemplateVariable(template, "url-password", () => url.password || "No password", dontReplaceSlash, options.filenameReplacementCharacter);
  12025. template = await evalTemplateVariable(template, "url-pathname", () => decode(url.pathname).replace(/^\//, "").replace(/\/$/, "") || "No pathname", dontReplaceSlash === undefined ? true : dontReplaceSlash, options.filenameReplacementCharacter);
  12026. template = await evalTemplateVariable(template, "url-pathname-flat", () => decode(url.pathname) || "No pathname", false, options.filenameReplacementCharacter);
  12027. template = await evalTemplateVariable(template, "url-port", () => url.port || "No port", dontReplaceSlash, options.filenameReplacementCharacter);
  12028. template = await evalTemplateVariable(template, "url-protocol", () => url.protocol || "No protocol", dontReplaceSlash, options.filenameReplacementCharacter);
  12029. template = await evalTemplateVariable(template, "url-search", () => url.search.substring(1) || "No search", dontReplaceSlash, options.filenameReplacementCharacter);
  12030. const params = Array.from(new URLSearchParams(url.search));
  12031. for (const [name, value] of params) {
  12032. template = await evalTemplateVariable(template, "url-search-" + name, () => value || "", dontReplaceSlash, options.filenameReplacementCharacter);
  12033. }
  12034. template = template.replace(/{\s*url-search-[^}\s]*\s*}/gi, "");
  12035. template = await evalTemplateVariable(template, "url-username", () => url.username || "No username", dontReplaceSlash, options.filenameReplacementCharacter);
  12036. template = await evalTemplateVariable(template, "tab-id", () => String(options.tabId || "No tab id"), dontReplaceSlash, options.filenameReplacementCharacter);
  12037. template = await evalTemplateVariable(template, "tab-index", () => String(options.tabIndex || "No tab index"), dontReplaceSlash, options.filenameReplacementCharacter);
  12038. template = await evalTemplateVariable(template, "url-last-segment", () => decode(getLastSegment(url, options.filenameReplacementCharacter)) || "No last segment", dontReplaceSlash, options.filenameReplacementCharacter);
  12039. if (content) {
  12040. template = await evalTemplateVariable(template, "digest-sha-256", async () => util.digest("SHA-256", content), dontReplaceSlash, options.filenameReplacementCharacter);
  12041. template = await evalTemplateVariable(template, "digest-sha-384", async () => util.digest("SHA-384", content), dontReplaceSlash, options.filenameReplacementCharacter);
  12042. template = await evalTemplateVariable(template, "digest-sha-512", async () => util.digest("SHA-512", content), dontReplaceSlash, options.filenameReplacementCharacter);
  12043. }
  12044. const bookmarkFolder = (options.bookmarkFolders && options.bookmarkFolders.join("/")) || "";
  12045. template = await evalTemplateVariable(template, "bookmark-pathname", () => bookmarkFolder, dontReplaceSlash === undefined ? true : dontReplaceSlash, options.filenameReplacementCharacter);
  12046. template = await evalTemplateVariable(template, "bookmark-pathname-flat", () => bookmarkFolder, false, options.filenameReplacementCharacter);
  12047. template = await evalTemplateVariable(template, "profile-name", () => options.profileName, dontReplaceSlash, options.filenameReplacementCharacter);
  12048. return template.trim();
  12049. function decode(value) {
  12050. try {
  12051. return decodeURI(value);
  12052. } catch (error) {
  12053. return value;
  12054. }
  12055. }
  12056. async function evalDate(date, prefix = "") {
  12057. if (date) {
  12058. template = await evalTemplateVariable(template, prefix + "datetime-iso", () => date.toISOString(), dontReplaceSlash, options.filenameReplacementCharacter);
  12059. template = await evalTemplateVariable(template, prefix + "date-iso", () => date.toISOString().split("T")[0], dontReplaceSlash, options.filenameReplacementCharacter);
  12060. template = await evalTemplateVariable(template, prefix + "time-iso", () => date.toISOString().split("T")[1].split("Z")[0], dontReplaceSlash, options.filenameReplacementCharacter);
  12061. template = await evalTemplateVariable(template, prefix + "date-locale", () => date.toLocaleDateString(), dontReplaceSlash, options.filenameReplacementCharacter);
  12062. template = await evalTemplateVariable(template, prefix + "time-locale", () => date.toLocaleTimeString(), dontReplaceSlash, options.filenameReplacementCharacter);
  12063. template = await evalTemplateVariable(template, prefix + "day-locale", () => String(date.getDate()).padStart(2, "0"), dontReplaceSlash, options.filenameReplacementCharacter);
  12064. template = await evalTemplateVariable(template, prefix + "month-locale", () => String(date.getMonth() + 1).padStart(2, "0"), dontReplaceSlash, options.filenameReplacementCharacter);
  12065. template = await evalTemplateVariable(template, prefix + "year-locale", () => String(date.getFullYear()), dontReplaceSlash, options.filenameReplacementCharacter);
  12066. template = await evalTemplateVariable(template, prefix + "datetime-locale", () => date.toLocaleString(), dontReplaceSlash, options.filenameReplacementCharacter);
  12067. template = await evalTemplateVariable(template, prefix + "datetime-utc", () => date.toUTCString(), dontReplaceSlash, options.filenameReplacementCharacter);
  12068. template = await evalTemplateVariable(template, prefix + "day-utc", () => String(date.getUTCDate()).padStart(2, "0"), dontReplaceSlash, options.filenameReplacementCharacter);
  12069. template = await evalTemplateVariable(template, prefix + "month-utc", () => String(date.getUTCMonth() + 1).padStart(2, "0"), dontReplaceSlash, options.filenameReplacementCharacter);
  12070. template = await evalTemplateVariable(template, prefix + "year-utc", () => String(date.getUTCFullYear()), dontReplaceSlash, options.filenameReplacementCharacter);
  12071. template = await evalTemplateVariable(template, prefix + "hours-locale", () => String(date.getHours()).padStart(2, "0"), dontReplaceSlash, options.filenameReplacementCharacter);
  12072. template = await evalTemplateVariable(template, prefix + "minutes-locale", () => String(date.getMinutes()).padStart(2, "0"), dontReplaceSlash, options.filenameReplacementCharacter);
  12073. template = await evalTemplateVariable(template, prefix + "seconds-locale", () => String(date.getSeconds()).padStart(2, "0"), dontReplaceSlash, options.filenameReplacementCharacter);
  12074. template = await evalTemplateVariable(template, prefix + "hours-utc", () => String(date.getUTCHours()).padStart(2, "0"), dontReplaceSlash, options.filenameReplacementCharacter);
  12075. template = await evalTemplateVariable(template, prefix + "minutes-utc", () => String(date.getUTCMinutes()).padStart(2, "0"), dontReplaceSlash, options.filenameReplacementCharacter);
  12076. template = await evalTemplateVariable(template, prefix + "seconds-utc", () => String(date.getUTCSeconds()).padStart(2, "0"), dontReplaceSlash, options.filenameReplacementCharacter);
  12077. template = await evalTemplateVariable(template, prefix + "time-ms", () => String(date.getTime()), dontReplaceSlash, options.filenameReplacementCharacter);
  12078. }
  12079. }
  12080. async function evalTemplateVariable(template, variableName, valueGetter, dontReplaceSlash, replacementCharacter) {
  12081. let maxLength, maxCharLength;
  12082. if (template) {
  12083. const regExpVariable = "{\\s*" + variableName.replace(/\W|_/g, "[$&]") + "\\s*}";
  12084. let replaceRegExp = new RegExp(regExpVariable + "\\[\\d+(ch)?\\]", "g");
  12085. if (template.match(replaceRegExp)) {
  12086. const matchedLength = template.match(replaceRegExp)[0];
  12087. if (matchedLength.match(/\[(\d+)\]$/)) {
  12088. maxLength = Number(matchedLength.match(/\[(\d+)\]$/)[1]);
  12089. if (isNaN(maxLength) || maxLength <= 0) {
  12090. maxLength = null;
  12091. }
  12092. } else {
  12093. maxCharLength = Number(matchedLength.match(/\[(\d+)ch\]$/)[1]);
  12094. if (isNaN(maxCharLength) || maxCharLength <= 0) {
  12095. maxCharLength = null;
  12096. }
  12097. }
  12098. } else {
  12099. replaceRegExp = new RegExp(regExpVariable, "g");
  12100. }
  12101. if (template.match(replaceRegExp)) {
  12102. let value = await valueGetter();
  12103. if (!dontReplaceSlash) {
  12104. value = value.replace(/\/+/g, replacementCharacter);
  12105. }
  12106. if (maxLength) {
  12107. value = await truncateText(value, maxLength);
  12108. } else if (maxCharLength) {
  12109. value = value.substring(0, maxCharLength);
  12110. }
  12111. return template.replace(replaceRegExp, value);
  12112. }
  12113. }
  12114. return template;
  12115. }
  12116. }
  12117. function getLastSegment(url, replacementCharacter) {
  12118. let lastSegmentMatch = url.pathname.match(/\/([^/]+)$/),
  12119. lastSegment = lastSegmentMatch && lastSegmentMatch[0];
  12120. if (!lastSegment) {
  12121. lastSegmentMatch = url.href.match(/([^/]+)\/?$/);
  12122. lastSegment = lastSegmentMatch && lastSegmentMatch[0];
  12123. }
  12124. if (!lastSegment) {
  12125. lastSegmentMatch = lastSegment.match(/(.*)\.[^.]+$/);
  12126. lastSegment = lastSegmentMatch && lastSegmentMatch[0];
  12127. }
  12128. if (!lastSegment) {
  12129. lastSegment = url.hostname.replace(/\/+/g, replacementCharacter).replace(/\/$/, "");
  12130. }
  12131. lastSegmentMatch = lastSegment.match(/(.*)\.[^.]+$/);
  12132. if (lastSegmentMatch && lastSegmentMatch[1]) {
  12133. lastSegment = lastSegmentMatch[1];
  12134. }
  12135. lastSegment = lastSegment.replace(/\/$/, "").replace(/^\//, "");
  12136. return lastSegment;
  12137. }
  12138. function getValidFilename(filename, replacedCharacters = DEFAULT_REPLACED_CHARACTERS$1, replacementCharacter = DEFAULT_REPLACEMENT_CHARACTER$1) {
  12139. replacedCharacters.forEach(replacedCharacter => (filename = filename.replace(new RegExp("[" + replacedCharacter + "]+", "g"), replacementCharacter)));
  12140. filename = filename
  12141. .replace(/\.\.\//g, "")
  12142. .replace(/^\/+/, "")
  12143. .replace(/\/+/g, "/")
  12144. .replace(/\/$/, "")
  12145. .replace(/\.$/, "")
  12146. .replace(/\.\//g, "." + replacementCharacter)
  12147. .replace(/\/\./g, "/" + replacementCharacter);
  12148. return filename;
  12149. }
  12150. function truncateText(content, maxSize) {
  12151. const blob = new Blob([content]);
  12152. const reader = new FileReader();
  12153. reader.readAsText(blob.slice(0, maxSize));
  12154. return new Promise((resolve, reject) => {
  12155. reader.addEventListener(
  12156. "load",
  12157. () => {
  12158. if (content.startsWith(reader.result)) {
  12159. resolve(reader.result);
  12160. } else {
  12161. truncateText(content, maxSize - 1)
  12162. .then(resolve)
  12163. .catch(reject);
  12164. }
  12165. },
  12166. false
  12167. );
  12168. reader.addEventListener("error", reject, false);
  12169. });
  12170. }
  12171. var templateFormatter = /*#__PURE__*/Object.freeze({
  12172. __proto__: null,
  12173. formatFilename: formatFilename,
  12174. evalTemplate: evalTemplate
  12175. });
  12176. /*
  12177. * Copyright 2010-2022 Gildas Lormeau
  12178. * contact : gildas.lormeau <at> gmail.com
  12179. *
  12180. * This file is part of SingleFile.
  12181. *
  12182. * The code in this file is free software: you can redistribute it and/or
  12183. * modify it under the terms of the GNU Affero General Public License
  12184. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  12185. * of the License, or (at your option) any later version.
  12186. *
  12187. * The code in this file is distributed in the hope that it will be useful,
  12188. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12189. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  12190. * General Public License for more details.
  12191. *
  12192. * As additional permission under GNU AGPL version 3 section 7, you may
  12193. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  12194. * AGPL normally required by section 4, provided you include this license
  12195. * notice and a URL through which recipients can access the Corresponding
  12196. * Source.
  12197. */
  12198. var index = /*#__PURE__*/Object.freeze({
  12199. __proto__: null,
  12200. fontsMinifier: cssFontsMinifier,
  12201. matchedRules: cssMatchedRules,
  12202. mediasAltMinifier: cssMediasAltMinifier,
  12203. cssRulesMinifier: cssRulesMinifier,
  12204. imagesAltMinifier: htmlImagesAltMinifier,
  12205. htmlMinifier: htmlMinifier,
  12206. serializer: htmlSerializer,
  12207. templateFormatter: templateFormatter
  12208. });
  12209. /*
  12210. * Copyright 2010-2022 Gildas Lormeau
  12211. * contact : gildas.lormeau <at> gmail.com
  12212. *
  12213. * This file is part of SingleFile.
  12214. *
  12215. * The code in this file is free software: you can redistribute it and/or
  12216. * modify it under the terms of the GNU Affero General Public License
  12217. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  12218. * of the License, or (at your option) any later version.
  12219. *
  12220. * The code in this file is distributed in the hope that it will be useful,
  12221. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12222. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  12223. * General Public License for more details.
  12224. *
  12225. * As additional permission under GNU AGPL version 3 section 7, you may
  12226. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  12227. * AGPL normally required by section 4, provided you include this license
  12228. * notice and a URL through which recipients can access the Corresponding
  12229. * Source.
  12230. */
  12231. const DATA_URI_PREFIX$1 = "data:";
  12232. const ABOUT_BLANK_URI$3 = "about:blank";
  12233. const REGEXP_URL_HASH = /(#.+?)$/;
  12234. const BLOB_URI_PREFIX$1 = "blob:";
  12235. const HTTP_URI_PREFIX$1 = /^https?:\/\//;
  12236. const FILE_URI_PREFIX$1 = /^file:\/\//;
  12237. const EMPTY_URL$1 = /^https?:\/\/+\s*$/;
  12238. const NOT_EMPTY_URL$1 = /^(https?:\/\/|file:\/\/|blob:).+/;
  12239. const PREFIX_DATA_URI_IMAGE_SVG$1 = "data:image/svg+xml";
  12240. const UTF8_CHARSET$3 = "utf-8";
  12241. let util$3, cssTree;
  12242. function getProcessorHelperCommonClass(utilInstance, cssTreeInstance) {
  12243. util$3 = utilInstance;
  12244. cssTree = cssTreeInstance;
  12245. return ProcessorHelperCommon;
  12246. }
  12247. class ProcessorHelperCommon {
  12248. setBackgroundImage(element, url, style) {
  12249. element.style.setProperty("background-blend-mode", "normal", "important");
  12250. element.style.setProperty("background-clip", "content-box", "important");
  12251. element.style.setProperty("background-position", style && style["background-position"] ? style["background-position"] : "center", "important");
  12252. element.style.setProperty("background-color", style && style["background-color"] ? style["background-color"] : "transparent", "important");
  12253. element.style.setProperty("background-image", url, "important");
  12254. element.style.setProperty("background-size", style && style["background-size"] ? style["background-size"] : "100% 100%", "important");
  12255. element.style.setProperty("background-origin", "content-box", "important");
  12256. element.style.setProperty("background-repeat", "no-repeat", "important");
  12257. }
  12258. async getStylesheetContent(resourceURL, options) {
  12259. const content = await util$3.getContent(resourceURL, {
  12260. inline: options.inline,
  12261. maxResourceSize: options.maxResourceSize,
  12262. maxResourceSizeEnabled: options.maxResourceSizeEnabled,
  12263. validateTextContentType: true,
  12264. frameId: options.frameId,
  12265. charset: options.charset,
  12266. resourceReferrer: options.resourceReferrer,
  12267. baseURI: options.baseURI,
  12268. blockMixedContent: options.blockMixedContent,
  12269. expectedType: "stylesheet",
  12270. acceptHeaders: options.acceptHeaders,
  12271. networkTimeout: options.networkTimeout
  12272. });
  12273. if (!(matchCharsetEquals(content.data, content.charset) || matchCharsetEquals(content.data, options.charset))) {
  12274. options = Object.assign({}, options, { charset: getCharset(content.data) });
  12275. return util$3.getContent(resourceURL, {
  12276. inline: options.inline,
  12277. maxResourceSize: options.maxResourceSize,
  12278. maxResourceSizeEnabled: options.maxResourceSizeEnabled,
  12279. validateTextContentType: true,
  12280. frameId: options.frameId,
  12281. charset: options.charset,
  12282. resourceReferrer: options.resourceReferrer,
  12283. baseURI: options.baseURI,
  12284. blockMixedContent: options.blockMixedContent,
  12285. expectedType: "stylesheet",
  12286. acceptHeaders: options.acceptHeaders,
  12287. networkTimeout: options.networkTimeout
  12288. });
  12289. } else {
  12290. return content;
  12291. }
  12292. }
  12293. processShortcutIcons(doc) {
  12294. let shortcutIcon = findShortcutIcon(Array.from(doc.querySelectorAll("link[href][rel=\"shortcut icon\"]")));
  12295. if (!shortcutIcon) {
  12296. shortcutIcon = findShortcutIcon(Array.from(doc.querySelectorAll("link[href][rel=\"icon\"]")));
  12297. }
  12298. if (!shortcutIcon) {
  12299. shortcutIcon = findShortcutIcon(Array.from(doc.querySelectorAll("link[href][rel*=\"icon\"]")));
  12300. if (shortcutIcon) {
  12301. shortcutIcon.rel = "shortcut icon";
  12302. }
  12303. }
  12304. if (shortcutIcon) {
  12305. doc.querySelectorAll("link[href][rel*=\"icon\"]").forEach(linkElement => {
  12306. if (linkElement != shortcutIcon) {
  12307. linkElement.remove();
  12308. }
  12309. });
  12310. }
  12311. }
  12312. removeSingleLineCssComments(stylesheet) {
  12313. if (stylesheet.children) {
  12314. const removedRules = [];
  12315. for (let cssRule = stylesheet.children.head; cssRule; cssRule = cssRule.next) {
  12316. const ruleData = cssRule.data;
  12317. if (ruleData.type == "Raw" && ruleData.value && ruleData.value.trim().startsWith("//")) {
  12318. removedRules.push(cssRule);
  12319. }
  12320. }
  12321. removedRules.forEach(cssRule => stylesheet.children.remove(cssRule));
  12322. }
  12323. }
  12324. replacePseudoClassDefined(stylesheet) {
  12325. const removedSelectors = [];
  12326. if (stylesheet.children) {
  12327. for (let cssRule = stylesheet.children.head; cssRule; cssRule = cssRule.next) {
  12328. const ruleData = cssRule.data;
  12329. if (ruleData.type == "Rule" && ruleData.prelude && ruleData.prelude.children) {
  12330. for (let selector = ruleData.prelude.children.head; selector; selector = selector.next) {
  12331. replacePseudoDefinedSelector(selector, ruleData.prelude);
  12332. }
  12333. }
  12334. }
  12335. }
  12336. if (removedSelectors.length) {
  12337. removedSelectors.forEach(({ parentSelector, selector }) => {
  12338. if (parentSelector.data.children.size == 0 || !selector.prev || selector.prev.data.type == "Combinator" || selector.prev.data.type == "WhiteSpace") {
  12339. parentSelector.data.children.replace(selector, cssTree.parse("*", { context: "selector" }).children.head);
  12340. } else {
  12341. parentSelector.data.children.remove(selector);
  12342. }
  12343. });
  12344. }
  12345. function replacePseudoDefinedSelector(selector, parentSelector) {
  12346. if (selector.data.children) {
  12347. for (let childSelector = selector.data.children.head; childSelector; childSelector = childSelector.next) {
  12348. replacePseudoDefinedSelector(childSelector, selector);
  12349. }
  12350. }
  12351. if (selector.data.type == "PseudoClassSelector" && selector.data.name == "defined") {
  12352. removedSelectors.push({ parentSelector, selector });
  12353. }
  12354. }
  12355. }
  12356. resolveStylesheetURLs(stylesheet, baseURI, workStylesheet) {
  12357. const urls = getUrlFunctions(stylesheet);
  12358. urls.map(urlNode => {
  12359. const originalResourceURL = urlNode.value;
  12360. let resourceURL = normalizeURL$1(originalResourceURL);
  12361. if (!testIgnoredPath$1(resourceURL)) {
  12362. workStylesheet.textContent = "tmp { content:\"" + resourceURL + "\"}";
  12363. if (workStylesheet.sheet && workStylesheet.sheet.cssRules) {
  12364. resourceURL = util$3.removeQuotes(workStylesheet.sheet.cssRules[0].style.getPropertyValue("content"));
  12365. }
  12366. if (!testIgnoredPath$1(resourceURL)) {
  12367. if (!resourceURL || testValidPath$1(resourceURL)) {
  12368. let resolvedURL;
  12369. if (!originalResourceURL.startsWith("#")) {
  12370. try {
  12371. resolvedURL = util$3.resolveURL(resourceURL, baseURI);
  12372. } catch (error) {
  12373. // ignored
  12374. }
  12375. }
  12376. if (testValidURL$1(resolvedURL)) {
  12377. urlNode.value = resolvedURL;
  12378. }
  12379. } else {
  12380. urlNode.value = util$3.EMPTY_RESOURCE;
  12381. }
  12382. }
  12383. }
  12384. });
  12385. }
  12386. async processXLinks(resourceElements, doc, baseURI, options, batchRequest) {
  12387. let attributeName = "xlink:href";
  12388. await Promise.all(Array.from(resourceElements).map(async resourceElement => {
  12389. let originalResourceURL = resourceElement.getAttribute(attributeName);
  12390. if (originalResourceURL == null) {
  12391. attributeName = "href";
  12392. originalResourceURL = resourceElement.getAttribute(attributeName);
  12393. }
  12394. if (options.saveOriginalURLs && !isDataURL$1(originalResourceURL)) {
  12395. resourceElement.setAttribute("data-sf-original-href", originalResourceURL);
  12396. }
  12397. let resourceURL = normalizeURL$1(originalResourceURL);
  12398. if (!options.blockImages) {
  12399. if (testValidPath$1(resourceURL) && !testIgnoredPath$1(resourceURL)) {
  12400. resourceElement.setAttribute(attributeName, util$3.EMPTY_RESOURCE);
  12401. try {
  12402. resourceURL = util$3.resolveURL(resourceURL, baseURI);
  12403. } catch (error) {
  12404. // ignored
  12405. }
  12406. if (testValidURL$1(resourceURL)) {
  12407. const hashMatch = originalResourceURL.match(REGEXP_URL_HASH);
  12408. if (originalResourceURL.startsWith(baseURI + "#")) {
  12409. resourceElement.setAttribute(attributeName, hashMatch[0]);
  12410. } else {
  12411. const response = await batchRequest.addURL(resourceURL, { expectedType: "image" });
  12412. const svgDoc = util$3.parseSVGContent(response.content);
  12413. if (hashMatch && hashMatch[0]) {
  12414. let symbolElement;
  12415. try {
  12416. symbolElement = svgDoc.querySelector(hashMatch[0]);
  12417. } catch (error) {
  12418. // ignored
  12419. }
  12420. if (symbolElement) {
  12421. resourceElement.setAttribute(attributeName, hashMatch[0]);
  12422. resourceElement.parentElement.insertBefore(symbolElement, resourceElement.parentElement.firstChild);
  12423. }
  12424. } else {
  12425. const content = await batchRequest.addURL(resourceURL, { expectedType: "image" });
  12426. resourceElement.setAttribute(attributeName, PREFIX_DATA_URI_IMAGE_SVG$1 + "," + content);
  12427. }
  12428. }
  12429. }
  12430. } else if (resourceURL == options.url) {
  12431. resourceElement.setAttribute(attributeName, originalResourceURL.substring(resourceURL.length));
  12432. }
  12433. } else {
  12434. resourceElement.setAttribute(attributeName, util$3.EMPTY_RESOURCE);
  12435. }
  12436. }));
  12437. }
  12438. }
  12439. function getUpdatedResourceContent(resourceURL, content, options) {
  12440. if (options.rootDocument && options.updatedResources[resourceURL]) {
  12441. options.updatedResources[resourceURL].retrieved = true;
  12442. return options.updatedResources[resourceURL].content;
  12443. } else {
  12444. return content.data || "";
  12445. }
  12446. }
  12447. function normalizeURL$1(url) {
  12448. if (!url || url.startsWith(DATA_URI_PREFIX$1)) {
  12449. return url;
  12450. } else {
  12451. return url.split("#")[0];
  12452. }
  12453. }
  12454. function matchCharsetEquals(stylesheetContent = "", charset = UTF8_CHARSET$3) {
  12455. const stylesheetCharset = getCharset(stylesheetContent);
  12456. if (stylesheetCharset) {
  12457. return stylesheetCharset == charset.toLowerCase();
  12458. } else {
  12459. return true;
  12460. }
  12461. }
  12462. function getCharset(stylesheetContent = "") {
  12463. const match = stylesheetContent.match(/^@charset\s+"([^"]*)";/i);
  12464. if (match && match[1]) {
  12465. return match[1].toLowerCase().trim();
  12466. }
  12467. }
  12468. function getUrlFunctions(declarationList) {
  12469. return cssTree.findAll(declarationList, node => node.type == "Url");
  12470. }
  12471. function getImportFunctions(declarationList) {
  12472. return cssTree.findAll(declarationList, node => node.type == "Atrule" && node.name == "import");
  12473. }
  12474. function findShortcutIcon(shortcutIcons) {
  12475. shortcutIcons = shortcutIcons.filter(linkElement => linkElement.href != util$3.EMPTY_RESOURCE);
  12476. shortcutIcons.sort((linkElement1, linkElement2) => (parseInt(linkElement2.sizes, 10) || 16) - (parseInt(linkElement1.sizes, 10) || 16));
  12477. return shortcutIcons[0];
  12478. }
  12479. function isDataURL$1(url) {
  12480. return url && (url.startsWith(DATA_URI_PREFIX$1) || url.startsWith(BLOB_URI_PREFIX$1));
  12481. }
  12482. function replaceOriginalURLs(stylesheetContent) {
  12483. return stylesheetContent.replace(/url\(-sf-url-original\\\(\\"(.*?)\\"\\\)\\ /g, "/* original URL: $1 */url(");
  12484. }
  12485. function testIgnoredPath$1(resourceURL) {
  12486. return resourceURL && (resourceURL.startsWith(DATA_URI_PREFIX$1) || resourceURL == ABOUT_BLANK_URI$3);
  12487. }
  12488. function testValidPath$1(resourceURL) {
  12489. return resourceURL && !resourceURL.match(EMPTY_URL$1);
  12490. }
  12491. function testValidURL$1(resourceURL) {
  12492. return testValidPath$1(resourceURL) && (resourceURL.match(HTTP_URI_PREFIX$1) || resourceURL.match(FILE_URI_PREFIX$1) || resourceURL.startsWith(BLOB_URI_PREFIX$1)) && resourceURL.match(NOT_EMPTY_URL$1);
  12493. }
  12494. /*
  12495. * Copyright 2010-2022 Gildas Lormeau
  12496. * contact : gildas.lormeau <at> gmail.com
  12497. *
  12498. * This file is part of SingleFile.
  12499. *
  12500. * The code in this file is free software: you can redistribute it and/or
  12501. * modify it under the terms of the GNU Affero General Public License
  12502. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  12503. * of the License, or (at your option) any later version.
  12504. *
  12505. * The code in this file is distributed in the hope that it will be useful,
  12506. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12507. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  12508. * General Public License for more details.
  12509. *
  12510. * As additional permission under GNU AGPL version 3 section 7, you may
  12511. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  12512. * AGPL normally required by section 4, provided you include this license
  12513. * notice and a URL through which recipients can access the Corresponding
  12514. * Source.
  12515. */
  12516. const JSON$3 = globalThis.JSON;
  12517. const FontFace$1 = globalThis.FontFace;
  12518. const Set$2 = globalThis.Set;
  12519. const setTimeout$1 = globalThis.setTimeout;
  12520. const clearTimeout$1 = globalThis.clearTimeout;
  12521. const Image = globalThis.Image;
  12522. const ABOUT_BLANK_URI$2 = "about:blank";
  12523. const UTF8_CHARSET$2 = "utf-8";
  12524. const PREFIX_DATA_URI_IMAGE_SVG = "data:image/svg+xml";
  12525. const PREFIXES_FORBIDDEN_DATA_URI = ["data:text/"];
  12526. const SCRIPT_TAG_FOUND = /<script/gi;
  12527. const NOSCRIPT_TAG_FOUND = /<noscript/gi;
  12528. const CANVAS_TAG_FOUND = /<canvas/gi;
  12529. const SINGLE_FILE_VARIABLE_NAME_PREFIX$1 = "--sf-img-";
  12530. const SINGLE_FILE_VARIABLE_MAX_SIZE = 512 * 1024;
  12531. const REGEXP_URL_SIMPLE_QUOTES_FN$1 = /url\s*\(\s*'(.*?)'\s*\)/i;
  12532. const REGEXP_URL_DOUBLE_QUOTES_FN$1 = /url\s*\(\s*"(.*?)"\s*\)/i;
  12533. const REGEXP_URL_NO_QUOTES_FN$1 = /url\s*\(\s*(.*?)\s*\)/i;
  12534. const REGEXP_URL_FUNCTION$1 = /(url|local|-sf-url-original)\(.*?\)\s*(,|$)/g;
  12535. const REGEXP_SIMPLE_QUOTES_STRING$1 = /^'(.*?)'$/;
  12536. const REGEXP_DOUBLE_QUOTES_STRING$1 = /^"(.*?)"$/;
  12537. const REGEXP_URL_FUNCTION_WOFF$1 = /^url\(\s*["']?data:font\/(woff2?)/;
  12538. const REGEXP_URL_FUNCTION_WOFF_ALT$1 = /^url\(\s*["']?data:application\/x-font-(woff)/;
  12539. const REGEXP_FONT_FORMAT$1 = /\.([^.?#]+)((\?|#).*?)?$/;
  12540. const REGEXP_FONT_FORMAT_VALUE$1 = /format\((.*?)\)\s*,?$/;
  12541. const REGEXP_FONT_SRC$1 = /(.*?)\s*,?$/;
  12542. const EMPTY_URL_SOURCE$1 = /^url\(["']?data:[^,]*,?["']?\)/;
  12543. const LOCAL_SOURCE$1 = "local(";
  12544. const MEDIA_ALL$1 = "all";
  12545. const FONT_STRETCHES$1 = {
  12546. "ultra-condensed": "50%",
  12547. "extra-condensed": "62.5%",
  12548. "condensed": "75%",
  12549. "semi-condensed": "87.5%",
  12550. "normal": "100%",
  12551. "semi-expanded": "112.5%",
  12552. "expanded": "125%",
  12553. "extra-expanded": "150%",
  12554. "ultra-expanded": "200%"
  12555. };
  12556. const FONT_MAX_LOAD_DELAY$1 = 5000;
  12557. let util$2;
  12558. function getProcessorHelperClass$2(utilInstance) {
  12559. util$2 = utilInstance;
  12560. const ProcessorHelperCommon = getProcessorHelperCommonClass(util$2, cssTree$1);
  12561. return class ProcessorHelper extends ProcessorHelperCommon {
  12562. async processPageResources(doc, baseURI, options, resources, styles, batchRequest) {
  12563. const processAttributeArgs = [
  12564. ["link[href][rel*=\"icon\"]", "href", false, true],
  12565. ["object[type=\"image/svg+xml\"], object[type=\"image/svg-xml\"], object[data*=\".svg\"]", "data"],
  12566. ["img[src], input[src][type=image]", "src", true],
  12567. ["embed[src*=\".svg\"]", "src"],
  12568. ["video[poster]", "poster"],
  12569. ["*[background]", "background"],
  12570. ["image", "xlink:href"],
  12571. ["image", "href"]
  12572. ];
  12573. if (options.blockImages) {
  12574. doc.querySelectorAll("svg").forEach(element => element.remove());
  12575. }
  12576. let resourcePromises = processAttributeArgs.map(([selector, attributeName, processDuplicates, removeElementIfMissing]) =>
  12577. this.processAttribute(doc.querySelectorAll(selector), attributeName, baseURI, options, "image", resources, styles, batchRequest, processDuplicates, removeElementIfMissing)
  12578. );
  12579. resourcePromises = resourcePromises.concat([
  12580. this.processXLinks(doc.querySelectorAll("use"), doc, baseURI, options, batchRequest),
  12581. this.processSrcset(doc.querySelectorAll("img[srcset], source[srcset]"), baseURI, options, batchRequest)
  12582. ]);
  12583. resourcePromises.push(this.processAttribute(doc.querySelectorAll("object[data*=\".pdf\"]"), "data", baseURI, options, null, resources, styles, batchRequest));
  12584. resourcePromises.push(this.processAttribute(doc.querySelectorAll("embed[src*=\".pdf\"]"), "src", baseURI, options, null, resources, styles, batchRequest));
  12585. resourcePromises.push(this.processAttribute(doc.querySelectorAll("audio[src], audio > source[src]"), "src", baseURI, options, "audio", resources, styles, batchRequest));
  12586. resourcePromises.push(this.processAttribute(doc.querySelectorAll("video[src], video > source[src]"), "src", baseURI, options, "video", resources, styles, batchRequest));
  12587. resourcePromises.push(this.processAttribute(doc.querySelectorAll("model[src]"), "src", baseURI, options, null, resources, styles, batchRequest));
  12588. await Promise.all(resourcePromises);
  12589. if (options.saveFavicon) {
  12590. this.processShortcutIcons(doc);
  12591. }
  12592. }
  12593. async processLinkElement(element, stylesheetInfo, stylesheets, baseURI, options, workStyleElement) {
  12594. if (element.tagName.toUpperCase() == "LINK" && element.charset) {
  12595. options.charset = element.charset;
  12596. }
  12597. await this.processStylesheetElement(element, stylesheetInfo, stylesheets, baseURI, options, workStyleElement);
  12598. }
  12599. async processStylesheetElement(element, stylesheetInfo, stylesheets, baseURI, options, workStyleElement) {
  12600. let stylesheet;
  12601. stylesheets.set(element, stylesheetInfo);
  12602. if (!options.blockStylesheets) {
  12603. if (element.tagName.toUpperCase() == "LINK") {
  12604. stylesheet = await this.resolveLinkStylesheetURLs(element.href, baseURI, options, workStyleElement);
  12605. } else {
  12606. stylesheet = db(element.textContent, { context: "stylesheet", parseCustomProperty: true });
  12607. const importFound = await this.resolveImportURLs(stylesheet, baseURI, options, workStyleElement);
  12608. if (importFound) {
  12609. stylesheet = db(gb(stylesheet), { context: "stylesheet", parseCustomProperty: true });
  12610. }
  12611. }
  12612. }
  12613. if (stylesheet && stylesheet.children) {
  12614. if (options.compressCSS) {
  12615. this.removeSingleLineCssComments(stylesheet);
  12616. }
  12617. this.replacePseudoClassDefined(stylesheet);
  12618. stylesheetInfo.stylesheet = stylesheet;
  12619. } else {
  12620. stylesheets.delete(element);
  12621. }
  12622. }
  12623. replaceStylesheets(doc, stylesheets, resources, options) {
  12624. doc.querySelectorAll("style").forEach(styleElement => {
  12625. const stylesheetInfo = stylesheets.get(styleElement);
  12626. if (stylesheetInfo) {
  12627. stylesheets.delete(styleElement);
  12628. styleElement.textContent = this.generateStylesheetContent(stylesheetInfo.stylesheet, options);
  12629. if (stylesheetInfo.mediaText) {
  12630. styleElement.media = stylesheetInfo.mediaText;
  12631. }
  12632. } else {
  12633. styleElement.remove();
  12634. }
  12635. });
  12636. doc.querySelectorAll("link[rel*=stylesheet]").forEach(linkElement => {
  12637. const stylesheetInfo = stylesheets.get(linkElement);
  12638. if (stylesheetInfo) {
  12639. stylesheets.delete(linkElement);
  12640. const styleElement = doc.createElement("style");
  12641. if (stylesheetInfo.mediaText) {
  12642. styleElement.media = stylesheetInfo.mediaText;
  12643. }
  12644. styleElement.textContent = this.generateStylesheetContent(stylesheetInfo.stylesheet, options);
  12645. linkElement.parentElement.replaceChild(styleElement, linkElement);
  12646. } else {
  12647. linkElement.remove();
  12648. }
  12649. });
  12650. }
  12651. async resolveImportURLs(stylesheet, baseURI, options, workStylesheet, importedStyleSheets = new Set$2()) {
  12652. let importFound;
  12653. this.resolveStylesheetURLs(stylesheet, baseURI, workStylesheet);
  12654. const imports = getImportFunctions(stylesheet);
  12655. await Promise.all(imports.map(async node => {
  12656. const urlNode = kb(node, node => node.type == "Url") || kb(node, node => node.type == "String");
  12657. if (urlNode) {
  12658. let resourceURL = normalizeURL$1(urlNode.value);
  12659. if (!testIgnoredPath$1(resourceURL) && testValidPath$1(resourceURL)) {
  12660. urlNode.value = util$2.EMPTY_RESOURCE;
  12661. try {
  12662. resourceURL = util$2.resolveURL(resourceURL, baseURI);
  12663. } catch (error) {
  12664. // ignored
  12665. }
  12666. if (testValidURL$1(resourceURL) && !importedStyleSheets.has(resourceURL)) {
  12667. options.inline = true;
  12668. const content = await this.getStylesheetContent(resourceURL, options);
  12669. resourceURL = content.resourceURL;
  12670. content.data = getUpdatedResourceContent(resourceURL, content, options);
  12671. if (content.data && content.data.match(/^<!doctype /i)) {
  12672. content.data = "";
  12673. }
  12674. const mediaQueryListNode = kb(node, node => node.type == "MediaQueryList");
  12675. if (mediaQueryListNode) {
  12676. content.data = this.wrapMediaQuery(content.data, gb(mediaQueryListNode));
  12677. }
  12678. content.data = content.data.replace(/:defined/gi, "*");
  12679. const importedStylesheet = db(content.data, { context: "stylesheet", parseCustomProperty: true });
  12680. const ancestorStyleSheets = new Set$2(importedStyleSheets);
  12681. ancestorStyleSheets.add(resourceURL);
  12682. await this.resolveImportURLs(importedStylesheet, resourceURL, options, workStylesheet, ancestorStyleSheets);
  12683. for (let keyName of Object.keys(importedStylesheet)) {
  12684. node[keyName] = importedStylesheet[keyName];
  12685. }
  12686. importFound = true;
  12687. }
  12688. }
  12689. }
  12690. }));
  12691. return importFound;
  12692. }
  12693. async resolveLinkStylesheetURLs(resourceURL, baseURI, options, workStylesheet) {
  12694. resourceURL = normalizeURL$1(resourceURL);
  12695. if (resourceURL && resourceURL != baseURI && resourceURL != ABOUT_BLANK_URI$2) {
  12696. const content = await util$2.getContent(resourceURL, {
  12697. inline: true,
  12698. maxResourceSize: options.maxResourceSize,
  12699. maxResourceSizeEnabled: options.maxResourceSizeEnabled,
  12700. charset: options.charset,
  12701. frameId: options.frameId,
  12702. resourceReferrer: options.resourceReferrer,
  12703. validateTextContentType: true,
  12704. baseURI: baseURI,
  12705. blockMixedContent: options.blockMixedContent,
  12706. expectedType: "stylesheet",
  12707. acceptHeaders: options.acceptHeaders,
  12708. networkTimeout: options.networkTimeout
  12709. });
  12710. if (!(matchCharsetEquals(content.data, content.charset) || matchCharsetEquals(content.data, options.charset))) {
  12711. options = Object.assign({}, options, { charset: getCharset(content.data) });
  12712. return this.resolveLinkStylesheetURLs(resourceURL, baseURI, options, workStylesheet);
  12713. }
  12714. resourceURL = content.resourceURL;
  12715. content.data = getUpdatedResourceContent(content.resourceURL, content, options);
  12716. if (content.data && content.data.match(/^<!doctype /i)) {
  12717. content.data = "";
  12718. }
  12719. content.data = content.data.replace(/:defined/gi, "*");
  12720. let stylesheet = db(content.data, { context: "stylesheet", parseCustomProperty: true });
  12721. const importFound = await this.resolveImportURLs(stylesheet, resourceURL, options, workStylesheet);
  12722. if (importFound) {
  12723. stylesheet = db(gb(stylesheet), { context: "stylesheet", parseCustomProperty: true });
  12724. }
  12725. return stylesheet;
  12726. }
  12727. }
  12728. async processFrame(frameElement, pageData) {
  12729. let sandbox = "allow-popups allow-top-navigation allow-top-navigation-by-user-activation";
  12730. if (pageData.content.match(NOSCRIPT_TAG_FOUND) || pageData.content.match(CANVAS_TAG_FOUND) || pageData.content.match(SCRIPT_TAG_FOUND)) {
  12731. sandbox += " allow-scripts allow-same-origin";
  12732. }
  12733. frameElement.setAttribute("sandbox", sandbox);
  12734. if (frameElement.tagName.toUpperCase() == "OBJECT") {
  12735. frameElement.setAttribute("data", "data:text/html," + pageData.content);
  12736. } else {
  12737. if (frameElement.tagName.toUpperCase() == "FRAME") {
  12738. frameElement.setAttribute("src", "data:text/html," + pageData.content.replace(/%/g, "%25").replace(/#/g, "%23"));
  12739. } else {
  12740. frameElement.setAttribute("srcdoc", pageData.content);
  12741. frameElement.removeAttribute("src");
  12742. }
  12743. }
  12744. }
  12745. async processStylesheet(cssRules, baseURI, options, resources, batchRequest) {
  12746. const promises = [];
  12747. const removedRules = [];
  12748. for (let cssRule = cssRules.head; cssRule; cssRule = cssRule.next) {
  12749. const ruleData = cssRule.data;
  12750. if (ruleData.type == "Atrule" && ruleData.name == "charset") {
  12751. removedRules.push(cssRule);
  12752. } else if (ruleData.block && ruleData.block.children) {
  12753. if (ruleData.type == "Rule") {
  12754. promises.push(this.processStyle(ruleData, options, resources, batchRequest));
  12755. } else if (ruleData.type == "Atrule" && (ruleData.name == "media" || ruleData.name == "supports")) {
  12756. promises.push(this.processStylesheet(ruleData.block.children, baseURI, options, resources, batchRequest));
  12757. } else if (ruleData.type == "Atrule" && ruleData.name == "font-face") {
  12758. promises.push(processFontFaceRule(ruleData));
  12759. }
  12760. }
  12761. }
  12762. removedRules.forEach(cssRule => cssRules.remove(cssRule));
  12763. await Promise.all(promises);
  12764. async function processFontFaceRule(ruleData) {
  12765. const urls = getUrlFunctions(ruleData);
  12766. await Promise.all(urls.map(async urlNode => {
  12767. const originalResourceURL = urlNode.value;
  12768. if (!options.blockFonts) {
  12769. const resourceURL = normalizeURL$1(originalResourceURL);
  12770. if (!testIgnoredPath$1(resourceURL) && testValidURL$1(resourceURL)) {
  12771. let { content } = await batchRequest.addURL(resourceURL, { asBinary: true, expectedType: "font", baseURI, blockMixedContent: options.blockMixedContent });
  12772. let resourceURLs = resources.fonts.get(urlNode);
  12773. if (!resourceURLs) {
  12774. resourceURLs = [];
  12775. resources.fonts.set(urlNode, resourceURLs);
  12776. }
  12777. resourceURLs.push(resourceURL);
  12778. if (!isDataURL$1(resourceURL) && options.saveOriginalURLs) {
  12779. urlNode.value = "-sf-url-original(" + JSON$3.stringify(originalResourceURL) + ") " + content;
  12780. } else {
  12781. urlNode.value = content;
  12782. }
  12783. }
  12784. } else {
  12785. urlNode.value = util$2.EMPTY_RESOURCE;
  12786. }
  12787. }));
  12788. }
  12789. }
  12790. async processStyle(ruleData, options, { cssVariables }, batchRequest) {
  12791. const urls = getUrlFunctions(ruleData);
  12792. await Promise.all(urls.map(async urlNode => {
  12793. const originalResourceURL = urlNode.value;
  12794. if (!options.blockImages) {
  12795. const resourceURL = normalizeURL$1(originalResourceURL);
  12796. if (!testIgnoredPath$1(resourceURL) && testValidURL$1(resourceURL)) {
  12797. let { content, indexResource, duplicate } = await batchRequest.addURL(resourceURL, { asBinary: true, expectedType: "image", groupDuplicates: options.groupDuplicateImages });
  12798. if (!originalResourceURL.startsWith("#")) {
  12799. const maxSizeDuplicateImages = options.maxSizeDuplicateImages || SINGLE_FILE_VARIABLE_MAX_SIZE;
  12800. if (duplicate && options.groupDuplicateImages && util$2.getContentSize(content) < maxSizeDuplicateImages) {
  12801. const varNode = db("var(" + SINGLE_FILE_VARIABLE_NAME_PREFIX$1 + indexResource + ")", { context: "value" });
  12802. for (let keyName of Object.keys(varNode.children.head.data)) {
  12803. urlNode[keyName] = varNode.children.head.data[keyName];
  12804. }
  12805. cssVariables.set(indexResource, { content, url: originalResourceURL });
  12806. } else {
  12807. if (!isDataURL$1(resourceURL) && options.saveOriginalURLs) {
  12808. urlNode.value = "-sf-url-original(" + JSON$3.stringify(originalResourceURL) + ") " + content;
  12809. } else {
  12810. urlNode.value = content;
  12811. }
  12812. }
  12813. }
  12814. }
  12815. } else {
  12816. urlNode.value = util$2.EMPTY_RESOURCE;
  12817. }
  12818. }));
  12819. }
  12820. async processAttribute(resourceElements, attributeName, baseURI, options, expectedType, { cssVariables }, styles, batchRequest, processDuplicates, removeElementIfMissing) {
  12821. await Promise.all(Array.from(resourceElements).map(async resourceElement => {
  12822. let resourceURL = resourceElement.getAttribute(attributeName);
  12823. if (resourceURL != null) {
  12824. resourceURL = normalizeURL$1(resourceURL);
  12825. let originURL = resourceElement.dataset.singleFileOriginURL;
  12826. if (options.saveOriginalURLs && !isDataURL$1(resourceURL)) {
  12827. resourceElement.setAttribute("data-sf-original-" + attributeName, resourceURL);
  12828. }
  12829. delete resourceElement.dataset.singleFileOriginURL;
  12830. if (!options["block" + expectedType.charAt(0).toUpperCase() + expectedType.substring(1) + "s"]) {
  12831. if (!testIgnoredPath$1(resourceURL)) {
  12832. setAttributeEmpty(resourceElement, attributeName, expectedType);
  12833. if (testValidPath$1(resourceURL)) {
  12834. try {
  12835. resourceURL = util$2.resolveURL(resourceURL, baseURI);
  12836. } catch (error) {
  12837. // ignored
  12838. }
  12839. if (testValidURL$1(resourceURL)) {
  12840. let { content, indexResource, duplicate } = await batchRequest.addURL(
  12841. resourceURL,
  12842. { asBinary: true, expectedType, groupDuplicates: options.groupDuplicateImages && resourceElement.tagName.toUpperCase() == "IMG" && attributeName == "src" });
  12843. if (originURL) {
  12844. if (this.testEmptyResource(content)) {
  12845. try {
  12846. originURL = util$2.resolveURL(originURL, baseURI);
  12847. } catch (error) {
  12848. // ignored
  12849. }
  12850. try {
  12851. resourceURL = originURL;
  12852. content = (await util$2.getContent(resourceURL, {
  12853. asBinary: true,
  12854. inline: true,
  12855. expectedType,
  12856. maxResourceSize: options.maxResourceSize,
  12857. maxResourceSizeEnabled: options.maxResourceSizeEnabled,
  12858. frameId: options.windowId,
  12859. resourceReferrer: options.resourceReferrer,
  12860. acceptHeaders: options.acceptHeaders,
  12861. networkTimeout: options.networkTimeout
  12862. })).data;
  12863. } catch (error) {
  12864. // ignored
  12865. }
  12866. }
  12867. }
  12868. if (removeElementIfMissing && this.testEmptyResource(content)) {
  12869. resourceElement.remove();
  12870. } else if (!this.testEmptyResource(content)) {
  12871. let forbiddenPrefixFound = PREFIXES_FORBIDDEN_DATA_URI.filter(prefixDataURI => content.startsWith(prefixDataURI)).length;
  12872. if (expectedType == "image") {
  12873. if (forbiddenPrefixFound && Image) {
  12874. forbiddenPrefixFound = await new Promise((resolve) => {
  12875. const image = new Image();
  12876. const timeoutId = setTimeout$1(() => resolve(true), 100);
  12877. image.src = content;
  12878. image.onload = () => cleanupAndResolve();
  12879. image.onerror = () => cleanupAndResolve(true);
  12880. function cleanupAndResolve(value) {
  12881. clearTimeout$1(timeoutId);
  12882. resolve(value);
  12883. }
  12884. });
  12885. }
  12886. if (!forbiddenPrefixFound) {
  12887. const isSVG = content.startsWith(PREFIX_DATA_URI_IMAGE_SVG);
  12888. const maxSizeDuplicateImages = options.maxSizeDuplicateImages || SINGLE_FILE_VARIABLE_MAX_SIZE;
  12889. if (processDuplicates && duplicate && !isSVG && util$2.getContentSize(content) < maxSizeDuplicateImages) {
  12890. if (this.replaceImageSource(resourceElement, SINGLE_FILE_VARIABLE_NAME_PREFIX$1 + indexResource, options)) {
  12891. cssVariables.set(indexResource, { content, url: originURL });
  12892. const declarationList = db(resourceElement.getAttribute("style"), { context: "declarationList", parseCustomProperty: true });
  12893. styles.set(resourceElement, declarationList);
  12894. } else {
  12895. resourceElement.setAttribute(attributeName, content);
  12896. }
  12897. } else {
  12898. resourceElement.setAttribute(attributeName, content);
  12899. }
  12900. }
  12901. } else {
  12902. resourceElement.setAttribute(attributeName, content);
  12903. }
  12904. }
  12905. }
  12906. }
  12907. }
  12908. } else {
  12909. setAttributeEmpty(resourceElement, attributeName, expectedType);
  12910. }
  12911. }
  12912. }));
  12913. function setAttributeEmpty(resourceElement, attributeName, expectedType) {
  12914. if (expectedType == "video" || expectedType == "audio") {
  12915. resourceElement.removeAttribute(attributeName);
  12916. } else {
  12917. resourceElement.setAttribute(attributeName, util$2.EMPTY_RESOURCE);
  12918. }
  12919. }
  12920. }
  12921. async processSrcset(resourceElements, baseURI, options, batchRequest) {
  12922. await Promise.all(Array.from(resourceElements).map(async resourceElement => {
  12923. const originSrcset = resourceElement.getAttribute("srcset");
  12924. const srcset = util$2.parseSrcset(originSrcset);
  12925. if (options.saveOriginalURLs && !isDataURL$1(originSrcset)) {
  12926. resourceElement.setAttribute("data-sf-original-srcset", originSrcset);
  12927. }
  12928. if (!options.blockImages) {
  12929. const srcsetValues = await Promise.all(srcset.map(async srcsetValue => {
  12930. let resourceURL = normalizeURL$1(srcsetValue.url);
  12931. if (!testIgnoredPath$1(resourceURL)) {
  12932. if (testValidPath$1(resourceURL)) {
  12933. try {
  12934. resourceURL = util$2.resolveURL(resourceURL, baseURI);
  12935. } catch (error) {
  12936. // ignored
  12937. }
  12938. if (testValidURL$1(resourceURL)) {
  12939. const { content } = await batchRequest.addURL(resourceURL, { asBinary: true, expectedType: "image" });
  12940. const forbiddenPrefixFound = PREFIXES_FORBIDDEN_DATA_URI.filter(prefixDataURI => content.startsWith(prefixDataURI)).length;
  12941. if (forbiddenPrefixFound) {
  12942. return "";
  12943. }
  12944. return content + (srcsetValue.w ? " " + srcsetValue.w + "w" : srcsetValue.d ? " " + srcsetValue.d + "x" : "");
  12945. } else {
  12946. return "";
  12947. }
  12948. } else {
  12949. return "";
  12950. }
  12951. } else {
  12952. return resourceURL + (srcsetValue.w ? " " + srcsetValue.w + "w" : srcsetValue.d ? " " + srcsetValue.d + "x" : "");
  12953. }
  12954. }));
  12955. resourceElement.setAttribute("srcset", srcsetValues.join(", "));
  12956. } else {
  12957. resourceElement.setAttribute("srcset", "");
  12958. }
  12959. }));
  12960. }
  12961. testEmptyResource(resource) {
  12962. return resource == util$2.EMPTY_RESOURCE;
  12963. }
  12964. generateStylesheetContent(stylesheet, options) {
  12965. let stylesheetContent = gb(stylesheet);
  12966. if (options.compressCSS) {
  12967. stylesheetContent = util$2.compressCSS(stylesheetContent);
  12968. }
  12969. if (options.saveOriginalURLs) {
  12970. stylesheetContent = replaceOriginalURLs(stylesheetContent);
  12971. }
  12972. return stylesheetContent;
  12973. }
  12974. replaceImageSource(imgElement, variableName, options) {
  12975. const attributeValue = imgElement.getAttribute(util$2.IMAGE_ATTRIBUTE_NAME);
  12976. if (attributeValue) {
  12977. const imageData = options.images[Number(imgElement.getAttribute(util$2.IMAGE_ATTRIBUTE_NAME))];
  12978. if (imageData && imageData.replaceable) {
  12979. imgElement.setAttribute("src", `${PREFIX_DATA_URI_IMAGE_SVG},<svg xmlns="http://www.w3.org/2000/svg" width="${imageData.size.pxWidth}" height="${imageData.size.pxHeight}"><rect fill-opacity="0"/></svg>`);
  12980. const backgroundStyle = {};
  12981. const backgroundSize = (imageData.objectFit == "content" || imageData.objectFit == "cover") && imageData.objectFit;
  12982. if (backgroundSize) {
  12983. backgroundStyle["background-size"] = imageData.objectFit;
  12984. }
  12985. if (imageData.objectPosition) {
  12986. backgroundStyle["background-position"] = imageData.objectPosition;
  12987. }
  12988. if (imageData.backgroundColor) {
  12989. backgroundStyle["background-color"] = imageData.backgroundColor;
  12990. }
  12991. this.setBackgroundImage(imgElement, "var(" + variableName + ")", backgroundStyle);
  12992. imgElement.removeAttribute(util$2.IMAGE_ATTRIBUTE_NAME);
  12993. return true;
  12994. }
  12995. }
  12996. }
  12997. wrapMediaQuery(stylesheetContent, mediaQuery) {
  12998. if (mediaQuery) {
  12999. return "@media " + mediaQuery + "{ " + stylesheetContent + " }";
  13000. } else {
  13001. return stylesheetContent;
  13002. }
  13003. }
  13004. getAdditionalPageData() {
  13005. return { };
  13006. }
  13007. removeAlternativeFonts(doc, stylesheets, fonts, fontTests) {
  13008. return removeAlternativeFonts$1(doc, stylesheets, fonts, fontTests);
  13009. }
  13010. async processScript(element, resourceURL) {
  13011. const content = await util$2.getContent(resourceURL, {
  13012. asBinary: true,
  13013. inline: true,
  13014. charset: this.charset != UTF8_CHARSET$2 && this.charset,
  13015. maxResourceSize: this.options.maxResourceSize,
  13016. maxResourceSizeEnabled: this.options.maxResourceSizeEnabled,
  13017. frameId: this.options.windowId,
  13018. resourceReferrer: this.options.resourceReferrer,
  13019. baseURI: this.options.baseURI,
  13020. blockMixedContent: this.options.blockMixedContent,
  13021. expectedType: "script",
  13022. acceptHeaders: this.options.acceptHeaders,
  13023. networkTimeout: this.options.networkTimeout
  13024. });
  13025. content.data = getUpdatedResourceContent(resourceURL, content, this.options);
  13026. element.setAttribute("src", content.data);
  13027. }
  13028. setMetaCSP(metaElement) {
  13029. metaElement.content = "default-src 'none'; font-src 'self' data:; img-src 'self' data:; style-src 'unsafe-inline'; media-src 'self' data:; script-src 'unsafe-inline' data:; object-src 'self' data:; frame-src 'self' data:;";
  13030. }
  13031. removeUnusedStylesheets(doc) {
  13032. doc.querySelectorAll("link[rel*=stylesheet][rel*=alternate][title]").forEach(element => element.remove());
  13033. }
  13034. };
  13035. }
  13036. async function removeAlternativeFonts$1(doc, stylesheets, fontDeclarations, fontTests) {
  13037. const fontsDetails = {
  13038. fonts: new Map(),
  13039. medias: new Map(),
  13040. supports: new Map()
  13041. };
  13042. const stats = { rules: { processed: 0, discarded: 0 }, fonts: { processed: 0, discarded: 0 } };
  13043. let sheetIndex = 0;
  13044. stylesheets.forEach(stylesheetInfo => {
  13045. const cssRules = stylesheetInfo.stylesheet.children;
  13046. if (cssRules) {
  13047. stats.rules.processed += cssRules.size;
  13048. stats.rules.discarded += cssRules.size;
  13049. if (stylesheetInfo.mediaText && stylesheetInfo.mediaText != MEDIA_ALL$1) {
  13050. const mediaFontsDetails = createFontsDetailsInfo$1();
  13051. fontsDetails.medias.set("media-" + sheetIndex + "-" + stylesheetInfo.mediaText, mediaFontsDetails);
  13052. getFontsDetails$1(doc, cssRules, sheetIndex, mediaFontsDetails);
  13053. } else {
  13054. getFontsDetails$1(doc, cssRules, sheetIndex, fontsDetails);
  13055. }
  13056. }
  13057. sheetIndex++;
  13058. });
  13059. processFontDetails$1(fontsDetails);
  13060. await Promise.all([...stylesheets].map(async ([, stylesheetInfo], sheetIndex) => {
  13061. const cssRules = stylesheetInfo.stylesheet.children;
  13062. const media = stylesheetInfo.mediaText;
  13063. if (cssRules) {
  13064. if (media && media != MEDIA_ALL$1) {
  13065. await processFontFaceRules$1(cssRules, sheetIndex, fontsDetails.medias.get("media-" + sheetIndex + "-" + media), fontDeclarations, fontTests, stats);
  13066. } else {
  13067. await processFontFaceRules$1(cssRules, sheetIndex, fontsDetails, fontDeclarations, fontTests, stats);
  13068. }
  13069. stats.rules.discarded -= cssRules.size;
  13070. }
  13071. }));
  13072. return stats;
  13073. }
  13074. function getFontsDetails$1(doc, cssRules, sheetIndex, mediaFontsDetails) {
  13075. let mediaIndex = 0, supportsIndex = 0;
  13076. cssRules.forEach(ruleData => {
  13077. if (ruleData.type == "Atrule" && ruleData.name == "media" && ruleData.block && ruleData.block.children && ruleData.prelude) {
  13078. const mediaText = gb(ruleData.prelude);
  13079. const fontsDetails = createFontsDetailsInfo$1();
  13080. mediaFontsDetails.medias.set("media-" + sheetIndex + "-" + mediaIndex + "-" + mediaText, fontsDetails);
  13081. mediaIndex++;
  13082. getFontsDetails$1(doc, ruleData.block.children, sheetIndex, fontsDetails);
  13083. } else if (ruleData.type == "Atrule" && ruleData.name == "supports" && ruleData.block && ruleData.block.children && ruleData.prelude) {
  13084. const supportsText = gb(ruleData.prelude);
  13085. const fontsDetails = createFontsDetailsInfo$1();
  13086. mediaFontsDetails.supports.set("supports-" + sheetIndex + "-" + supportsIndex + "-" + supportsText, fontsDetails);
  13087. supportsIndex++;
  13088. getFontsDetails$1(doc, ruleData.block.children, sheetIndex, fontsDetails);
  13089. } else if (ruleData.type == "Atrule" && ruleData.name == "font-face" && ruleData.block && ruleData.block.children) {
  13090. const fontKey = getFontKey$1(ruleData);
  13091. let fontInfo = mediaFontsDetails.fonts.get(fontKey);
  13092. if (!fontInfo) {
  13093. fontInfo = [];
  13094. mediaFontsDetails.fonts.set(fontKey, fontInfo);
  13095. }
  13096. const src = getPropertyValue$1(ruleData, "src");
  13097. if (src) {
  13098. const fontSources = src.match(REGEXP_URL_FUNCTION$1);
  13099. if (fontSources) {
  13100. fontSources.forEach(source => fontInfo.unshift(source));
  13101. }
  13102. }
  13103. }
  13104. });
  13105. }
  13106. function processFontDetails$1(fontsDetails) {
  13107. fontsDetails.fonts.forEach((fontInfo, fontKey) => {
  13108. fontsDetails.fonts.set(fontKey, fontInfo.map(fontSource => {
  13109. const fontFormatMatch = fontSource.match(REGEXP_FONT_FORMAT_VALUE$1);
  13110. let fontFormat;
  13111. const fontUrl = getURL$1(fontSource);
  13112. if (fontFormatMatch && fontFormatMatch[1]) {
  13113. fontFormat = fontFormatMatch[1].replace(REGEXP_SIMPLE_QUOTES_STRING$1, "$1").replace(REGEXP_DOUBLE_QUOTES_STRING$1, "$1").toLowerCase();
  13114. }
  13115. if (!fontFormat) {
  13116. const fontFormatMatch = fontSource.match(REGEXP_URL_FUNCTION_WOFF$1);
  13117. if (fontFormatMatch && fontFormatMatch[1]) {
  13118. fontFormat = fontFormatMatch[1];
  13119. } else {
  13120. const fontFormatMatch = fontSource.match(REGEXP_URL_FUNCTION_WOFF_ALT$1);
  13121. if (fontFormatMatch && fontFormatMatch[1]) {
  13122. fontFormat = fontFormatMatch[1];
  13123. }
  13124. }
  13125. }
  13126. if (!fontFormat && fontUrl) {
  13127. const fontFormatMatch = fontUrl.match(REGEXP_FONT_FORMAT$1);
  13128. if (fontFormatMatch && fontFormatMatch[1]) {
  13129. fontFormat = fontFormatMatch[1];
  13130. }
  13131. }
  13132. return { src: fontSource.match(REGEXP_FONT_SRC$1)[1], fontUrl, format: fontFormat };
  13133. }));
  13134. });
  13135. fontsDetails.medias.forEach(mediaFontsDetails => processFontDetails$1(mediaFontsDetails));
  13136. fontsDetails.supports.forEach(supportsFontsDetails => processFontDetails$1(supportsFontsDetails));
  13137. }
  13138. async function processFontFaceRules$1(cssRules, sheetIndex, fontsDetails, fontDeclarations, fontTests, stats) {
  13139. const removedRules = [];
  13140. let mediaIndex = 0, supportsIndex = 0;
  13141. for (let cssRule = cssRules.head; cssRule; cssRule = cssRule.next) {
  13142. const ruleData = cssRule.data;
  13143. if (ruleData.type == "Atrule" && ruleData.name == "media" && ruleData.block && ruleData.block.children && ruleData.prelude) {
  13144. const mediaText = gb(ruleData.prelude);
  13145. await processFontFaceRules$1(ruleData.block.children, sheetIndex, fontsDetails.medias.get("media-" + sheetIndex + "-" + mediaIndex + "-" + mediaText), fontDeclarations, fontTests, stats);
  13146. mediaIndex++;
  13147. } else if (ruleData.type == "Atrule" && ruleData.name == "supports" && ruleData.block && ruleData.block.children && ruleData.prelude) {
  13148. const supportsText = gb(ruleData.prelude);
  13149. await processFontFaceRules$1(ruleData.block.children, sheetIndex, fontsDetails.supports.get("supports-" + sheetIndex + "-" + supportsIndex + "-" + supportsText), fontDeclarations, fontTests, stats);
  13150. supportsIndex++;
  13151. } else if (ruleData.type == "Atrule" && ruleData.name == "font-face") {
  13152. const key = getFontKey$1(ruleData);
  13153. const fontInfo = fontsDetails.fonts.get(key);
  13154. if (fontInfo) {
  13155. const processed = await processFontFaceRule$1(ruleData, fontInfo, fontDeclarations, fontTests, stats);
  13156. if (processed) {
  13157. fontsDetails.fonts.delete(key);
  13158. }
  13159. } else {
  13160. removedRules.push(cssRule);
  13161. }
  13162. }
  13163. }
  13164. removedRules.forEach(cssRule => cssRules.remove(cssRule));
  13165. }
  13166. async function processFontFaceRule$1(ruleData, fontInfo, fontDeclarations, fontTests, stats) {
  13167. const removedNodes = [];
  13168. for (let node = ruleData.block.children.head; node; node = node.next) {
  13169. if (node.data.property == "src") {
  13170. removedNodes.push(node);
  13171. }
  13172. }
  13173. removedNodes.pop();
  13174. removedNodes.forEach(node => ruleData.block.children.remove(node));
  13175. const srcDeclaration = ruleData.block.children.filter(node => node.property == "src").tail;
  13176. if (srcDeclaration) {
  13177. await Promise.all(fontInfo.map(async source => {
  13178. if (fontTests.has(source.src)) {
  13179. source.valid = fontTests.get(source.src);
  13180. } else {
  13181. if (FontFace$1 && source.fontUrl) {
  13182. const fontFace = new FontFace$1("test-font", source.src);
  13183. try {
  13184. let timeout;
  13185. await Promise.race([
  13186. fontFace.load().then(() => fontFace.loaded).then(() => { source.valid = true; globalThis.clearTimeout(timeout); }),
  13187. new Promise(resolve => timeout = globalThis.setTimeout(() => { source.valid = true; resolve(); }, FONT_MAX_LOAD_DELAY$1))
  13188. ]);
  13189. } catch (error) {
  13190. const urlNodes = vb(srcDeclaration.data, node => node.type == "Url");
  13191. const declarationFontURLs = Array.from(fontDeclarations).find(([node]) => urlNodes.includes(node) && node.value == source.fontUrl);
  13192. if (declarationFontURLs && declarationFontURLs[1].length) {
  13193. const fontURL = declarationFontURLs[1][0];
  13194. if (fontURL) {
  13195. const fontFace = new FontFace$1("test-font", "url(" + fontURL + ")");
  13196. try {
  13197. let timeout;
  13198. await Promise.race([
  13199. fontFace.load().then(() => fontFace.loaded).then(() => { source.valid = true; globalThis.clearTimeout(timeout); }),
  13200. new Promise(resolve => timeout = globalThis.setTimeout(() => { source.valid = true; resolve(); }, FONT_MAX_LOAD_DELAY$1))
  13201. ]);
  13202. } catch (error) {
  13203. // ignored
  13204. }
  13205. }
  13206. } else {
  13207. source.valid = true;
  13208. }
  13209. }
  13210. } else {
  13211. source.valid = true;
  13212. }
  13213. fontTests.set(source.src, source.valid);
  13214. }
  13215. }));
  13216. const findSourceByFormat = (fontFormat, testValidity) => fontInfo.find(source => !source.src.match(EMPTY_URL_SOURCE$1) && source.format == fontFormat && (!testValidity || source.valid));
  13217. const filterSources = fontSource => fontInfo.filter(source => source == fontSource || source.src.startsWith(LOCAL_SOURCE$1));
  13218. stats.fonts.processed += fontInfo.length;
  13219. stats.fonts.discarded += fontInfo.length;
  13220. const woffFontFound =
  13221. findSourceByFormat("woff2-variations", true) || findSourceByFormat("woff2", true) || findSourceByFormat("woff", true);
  13222. if (woffFontFound) {
  13223. fontInfo = filterSources(woffFontFound);
  13224. } else {
  13225. const ttfFontFound =
  13226. findSourceByFormat("truetype-variations", true) || findSourceByFormat("truetype", true);
  13227. if (ttfFontFound) {
  13228. fontInfo = filterSources(ttfFontFound);
  13229. } else {
  13230. const otfFontFound =
  13231. findSourceByFormat("opentype") || findSourceByFormat("embedded-opentype");
  13232. if (otfFontFound) {
  13233. fontInfo = filterSources(otfFontFound);
  13234. } else {
  13235. fontInfo = fontInfo.filter(source => !source.src.match(EMPTY_URL_SOURCE$1) && (source.valid) || source.src.startsWith(LOCAL_SOURCE$1));
  13236. }
  13237. }
  13238. }
  13239. stats.fonts.discarded -= fontInfo.length;
  13240. fontInfo.reverse();
  13241. try {
  13242. srcDeclaration.data.value = db(fontInfo.map(fontSource => fontSource.src).join(","), { context: "value", parseCustomProperty: true });
  13243. }
  13244. catch (error) {
  13245. // ignored
  13246. }
  13247. return true;
  13248. } else {
  13249. return false;
  13250. }
  13251. }
  13252. function getPropertyValue$1(ruleData, propertyName) {
  13253. let property;
  13254. if (ruleData.block.children) {
  13255. property = ruleData.block.children.filter(node => {
  13256. try {
  13257. return node.property == propertyName && !gb(node.value).match(/\\9$/);
  13258. } catch (error) {
  13259. return node.property == propertyName;
  13260. }
  13261. }).tail;
  13262. }
  13263. if (property) {
  13264. try {
  13265. return gb(property.data.value);
  13266. } catch (error) {
  13267. // ignored
  13268. }
  13269. }
  13270. }
  13271. function getFontKey$1(ruleData) {
  13272. return JSON$3.stringify([
  13273. normalizeFontFamily(getPropertyValue$1(ruleData, "font-family")),
  13274. getFontWeight(getPropertyValue$1(ruleData, "font-weight") || "400"),
  13275. getPropertyValue$1(ruleData, "font-style") || "normal",
  13276. getPropertyValue$1(ruleData, "unicode-range"),
  13277. getFontStretch$1(getPropertyValue$1(ruleData, "font-stretch")),
  13278. getPropertyValue$1(ruleData, "font-variant") || "normal",
  13279. getPropertyValue$1(ruleData, "font-feature-settings"),
  13280. getPropertyValue$1(ruleData, "font-variation-settings")
  13281. ]);
  13282. }
  13283. function getFontStretch$1(stretch) {
  13284. return FONT_STRETCHES$1[stretch] || stretch;
  13285. }
  13286. function createFontsDetailsInfo$1() {
  13287. return {
  13288. fonts: new Map(),
  13289. medias: new Map(),
  13290. supports: new Map()
  13291. };
  13292. }
  13293. function getURL$1(urlFunction) {
  13294. urlFunction = urlFunction.replace(/url\(-sf-url-original\\\(\\"(.*?)\\"\\\)\\ /g, "");
  13295. const urlMatch = urlFunction.match(REGEXP_URL_SIMPLE_QUOTES_FN$1) ||
  13296. urlFunction.match(REGEXP_URL_DOUBLE_QUOTES_FN$1) ||
  13297. urlFunction.match(REGEXP_URL_NO_QUOTES_FN$1);
  13298. return urlMatch && urlMatch[1];
  13299. }
  13300. /*
  13301. * Copyright 2010-2022 Gildas Lormeau
  13302. * contact : gildas.lormeau <at> gmail.com
  13303. *
  13304. * This file is part of SingleFile.
  13305. *
  13306. * The code in this file is free software: you can redistribute it and/or
  13307. * modify it under the terms of the GNU Affero General Public License
  13308. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  13309. * of the License, or (at your option) any later version.
  13310. *
  13311. * The code in this file is distributed in the hope that it will be useful,
  13312. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13313. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  13314. * General Public License for more details.
  13315. *
  13316. * As additional permission under GNU AGPL version 3 section 7, you may
  13317. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  13318. * AGPL normally required by section 4, provided you include this license
  13319. * notice and a URL through which recipients can access the Corresponding
  13320. * Source.
  13321. */
  13322. const JSON$2 = globalThis.JSON;
  13323. const FontFace = globalThis.FontFace;
  13324. const ABOUT_BLANK_URI$1 = "about:blank";
  13325. const UTF8_CHARSET$1 = "utf-8";
  13326. const REGEXP_URL_SIMPLE_QUOTES_FN = /url\s*\(\s*'(.*?)'\s*\)/i;
  13327. const REGEXP_URL_DOUBLE_QUOTES_FN = /url\s*\(\s*"(.*?)"\s*\)/i;
  13328. const REGEXP_URL_NO_QUOTES_FN = /url\s*\(\s*(.*?)\s*\)/i;
  13329. const REGEXP_URL_FUNCTION = /(url|local|-sf-url-original)\(.*?\)\s*(,|$)/g;
  13330. const REGEXP_SIMPLE_QUOTES_STRING = /^'(.*?)'$/;
  13331. const REGEXP_DOUBLE_QUOTES_STRING = /^"(.*?)"$/;
  13332. const REGEXP_URL_FUNCTION_WOFF = /^url\(\s*["']?data:font\/(woff2?)/;
  13333. const REGEXP_URL_FUNCTION_WOFF_ALT = /^url\(\s*["']?data:application\/x-font-(woff)/;
  13334. const REGEXP_FONT_FORMAT = /\.([^.?#]+)((\?|#).*?)?$/;
  13335. const REGEXP_FONT_FORMAT_VALUE = /format\((.*?)\)\s*,?$/;
  13336. const REGEXP_FONT_SRC = /(.*?)\s*,?$/;
  13337. const EMPTY_URL_SOURCE = /^url\(["']?data:[^,]*,?["']?\)/;
  13338. const LOCAL_SOURCE = "local(";
  13339. const MEDIA_ALL = "all";
  13340. const FONT_STRETCHES = {
  13341. "ultra-condensed": "50%",
  13342. "extra-condensed": "62.5%",
  13343. "condensed": "75%",
  13344. "semi-condensed": "87.5%",
  13345. "normal": "100%",
  13346. "semi-expanded": "112.5%",
  13347. "expanded": "125%",
  13348. "extra-expanded": "150%",
  13349. "ultra-expanded": "200%"
  13350. };
  13351. const FONT_MAX_LOAD_DELAY = 5000;
  13352. let util$1;
  13353. function getProcessorHelperClass$1(utilInstance) {
  13354. util$1 = utilInstance;
  13355. const ProcessorHelperCommon = getProcessorHelperCommonClass(util$1, cssTree$1);
  13356. return class ProcessorHelper extends ProcessorHelperCommon {
  13357. async processPageResources(doc, baseURI, options, resources, styles, batchRequest) {
  13358. const processAttributeArgs = [
  13359. ["link[href][rel*=\"icon\"]", "href", true],
  13360. ["object[type=\"image/svg+xml\"], object[type=\"image/svg-xml\"], object[data*=\".svg\"]", "data"],
  13361. ["img[src], input[src][type=image]", "src"],
  13362. ["embed[src*=\".svg\"]", "src"],
  13363. ["video[poster]", "poster"],
  13364. ["*[background]", "background"],
  13365. ["image", "xlink:href"],
  13366. ["image", "href"]
  13367. ];
  13368. if (options.blockImages) {
  13369. doc.querySelectorAll("svg").forEach(element => element.remove());
  13370. }
  13371. let resourcePromises = processAttributeArgs.map(([selector, attributeName, removeElementIfMissing]) =>
  13372. this.processAttribute(doc.querySelectorAll(selector), attributeName, baseURI, options, "image", resources, batchRequest, removeElementIfMissing)
  13373. );
  13374. resourcePromises = resourcePromises.concat([
  13375. this.processXLinks(doc.querySelectorAll("use"), doc, baseURI, options, batchRequest),
  13376. this.processSrcset(doc.querySelectorAll("img[srcset], source[srcset]"), baseURI, options, resources, batchRequest)
  13377. ]);
  13378. resourcePromises.push(this.processAttribute(doc.querySelectorAll("object[data*=\".pdf\"]"), "data", baseURI, options, null, resources, batchRequest));
  13379. resourcePromises.push(this.processAttribute(doc.querySelectorAll("embed[src*=\".pdf\"]"), "src", baseURI, options, null, resources, batchRequest));
  13380. resourcePromises.push(this.processAttribute(doc.querySelectorAll("audio[src], audio > source[src]"), "src", baseURI, options, "audio", resources, batchRequest));
  13381. resourcePromises.push(this.processAttribute(doc.querySelectorAll("video[src], video > source[src]"), "src", baseURI, options, "video", resources, batchRequest));
  13382. resourcePromises.push(this.processAttribute(doc.querySelectorAll("model[src]"), "src", baseURI, options, null, resources, batchRequest));
  13383. await Promise.all(resourcePromises);
  13384. if (options.saveFavicon) {
  13385. this.processShortcutIcons(doc);
  13386. }
  13387. }
  13388. async processLinkElement(element, stylesheetInfo, stylesheets, baseURI, options, workStyleElement, resources) {
  13389. if (element.tagName.toUpperCase() == "LINK") {
  13390. element.removeAttribute("integrity");
  13391. if (element.charset) {
  13392. options.charset = element.charset;
  13393. }
  13394. stylesheetInfo.url = element.href;
  13395. }
  13396. await this.processStylesheetElement(element, stylesheetInfo, stylesheets, baseURI, options, workStyleElement, resources);
  13397. }
  13398. async processStylesheetElement(element, stylesheetInfo, stylesheets, baseURI, options, workStyleElement, resources) {
  13399. if (options.blockStylesheets) {
  13400. if (element.tagName.toUpperCase() == "LINK") {
  13401. element.href = util$1.EMPTY_RESOURCE;
  13402. } else {
  13403. element.textContent = "";
  13404. }
  13405. } else {
  13406. if (element.tagName.toUpperCase() == "LINK") {
  13407. await this.resolveLinkStylesheetURLs(stylesheetInfo, element, element.href, baseURI, options, workStyleElement, resources, stylesheets);
  13408. } else {
  13409. stylesheets.set({ element }, stylesheetInfo);
  13410. stylesheetInfo.stylesheet = db(element.textContent, { context: "stylesheet", parseCustomProperty: true });
  13411. await this.resolveImportURLs(stylesheetInfo, baseURI, options, workStyleElement, resources, stylesheets);
  13412. }
  13413. }
  13414. }
  13415. replaceStylesheets(doc, stylesheets, resources, options) {
  13416. for (const [key, stylesheetInfo] of stylesheets) {
  13417. if (key.urlNode) {
  13418. const name = "stylesheet_" + resources.stylesheets.size + ".css";
  13419. if (!isDataURL$1(stylesheetInfo.url) && options.saveOriginalURLs) {
  13420. key.urlNode.value = "-sf-url-original(" + JSON$2.stringify(stylesheetInfo.url) + ") " + name;
  13421. } else {
  13422. key.urlNode.value = name;
  13423. }
  13424. resources.stylesheets.set(resources.stylesheets.size, { name, content: this.generateStylesheetContent(stylesheetInfo.stylesheet, options), url: stylesheetInfo.url });
  13425. }
  13426. }
  13427. for (const [key, stylesheetInfo] of stylesheets) {
  13428. if (key.element) {
  13429. if (key.element.tagName.toUpperCase() == "LINK") {
  13430. const linkElement = key.element;
  13431. const name = "stylesheet_" + resources.stylesheets.size + ".css";
  13432. linkElement.setAttribute("href", name);
  13433. resources.stylesheets.set(resources.stylesheets.size, { name, content: this.generateStylesheetContent(stylesheetInfo.stylesheet, options), url: stylesheetInfo.url });
  13434. } else {
  13435. const styleElement = key.element;
  13436. styleElement.textContent = this.generateStylesheetContent(stylesheetInfo.stylesheet, options);
  13437. }
  13438. }
  13439. }
  13440. }
  13441. async resolveImportURLs(stylesheetInfo, baseURI, options, workStylesheet, resources, stylesheets) {
  13442. const stylesheet = stylesheetInfo.stylesheet;
  13443. const scoped = stylesheetInfo.scoped;
  13444. this.resolveStylesheetURLs(stylesheet, baseURI, workStylesheet);
  13445. const imports = getImportFunctions(stylesheet);
  13446. await Promise.all(imports.map(async node => {
  13447. const urlNode = kb(node, node => node.type == "Url") || kb(node, node => node.type == "String");
  13448. if (urlNode) {
  13449. let resourceURL = normalizeURL$1(urlNode.value);
  13450. if (!testIgnoredPath$1(resourceURL) && testValidPath$1(resourceURL)) {
  13451. urlNode.value = util$1.EMPTY_RESOURCE;
  13452. try {
  13453. resourceURL = util$1.resolveURL(resourceURL, baseURI);
  13454. } catch (error) {
  13455. // ignored
  13456. }
  13457. if (testValidURL$1(resourceURL)) {
  13458. const mediaQueryListNode = kb(node, node => node.type == "MediaQueryList");
  13459. let mediaText;
  13460. if (mediaQueryListNode) {
  13461. mediaText = gb(mediaQueryListNode);
  13462. }
  13463. const existingStylesheet = Array.from(stylesheets).find(([, stylesheetInfo]) => stylesheetInfo.resourceURL == resourceURL);
  13464. if (existingStylesheet) {
  13465. stylesheets.set({ urlNode }, {
  13466. url: resourceURL,
  13467. stylesheet: existingStylesheet[1].stylesheet, scoped
  13468. });
  13469. } else {
  13470. const stylesheetInfo = {
  13471. scoped,
  13472. mediaText
  13473. };
  13474. stylesheets.set({ urlNode }, stylesheetInfo);
  13475. const content = await this.getStylesheetContent(resourceURL, options);
  13476. stylesheetInfo.url = resourceURL = content.resourceURL;
  13477. const existingStylesheet = Array.from(stylesheets).find(([, stylesheetInfo]) => stylesheetInfo.resourceURL == resourceURL);
  13478. if (existingStylesheet) {
  13479. stylesheets.set({ urlNode }, { url: resourceURL, stylesheet: existingStylesheet[1].stylesheet, scoped });
  13480. } else {
  13481. content.data = getUpdatedResourceContent(resourceURL, content, options);
  13482. stylesheetInfo.stylesheet = db(content.data, { context: "stylesheet", parseCustomProperty: true });
  13483. await this.resolveImportURLs(stylesheetInfo, resourceURL, options, workStylesheet, resources, stylesheets);
  13484. }
  13485. }
  13486. }
  13487. }
  13488. }
  13489. }));
  13490. }
  13491. async resolveLinkStylesheetURLs(stylesheetInfo, element, resourceURL, baseURI, options, workStylesheet, resources, stylesheets) {
  13492. resourceURL = normalizeURL$1(resourceURL);
  13493. if (resourceURL && resourceURL != baseURI && resourceURL != ABOUT_BLANK_URI$1) {
  13494. const existingStylesheet = Array.from(stylesheets).find(([, otherStylesheetInfo]) => otherStylesheetInfo.resourceURL == resourceURL);
  13495. if (existingStylesheet) {
  13496. stylesheets.set({ element }, {
  13497. url: resourceURL,
  13498. stylesheet: existingStylesheet[1].stylesheet,
  13499. mediaText: stylesheetInfo.mediaText
  13500. });
  13501. } else {
  13502. stylesheets.set({ element }, stylesheetInfo);
  13503. const content = await util$1.getContent(resourceURL, {
  13504. maxResourceSize: options.maxResourceSize,
  13505. maxResourceSizeEnabled: options.maxResourceSizeEnabled,
  13506. charset: options.charset,
  13507. frameId: options.frameId,
  13508. resourceReferrer: options.resourceReferrer,
  13509. validateTextContentType: true,
  13510. baseURI: baseURI,
  13511. blockMixedContent: options.blockMixedContent,
  13512. expectedType: "stylesheet",
  13513. acceptHeaders: options.acceptHeaders,
  13514. networkTimeout: options.networkTimeout
  13515. });
  13516. if (!(matchCharsetEquals(content.data, content.charset) || matchCharsetEquals(content.data, options.charset))) {
  13517. options = Object.assign({}, options, { charset: getCharset(content.data) });
  13518. this.resolveLinkStylesheetURLs(stylesheetInfo, element, resourceURL, baseURI, options, workStylesheet, resources, stylesheets);
  13519. }
  13520. resourceURL = content.resourceURL;
  13521. if (existingStylesheet) {
  13522. stylesheets.set({ element }, {
  13523. url: resourceURL,
  13524. stylesheet: existingStylesheet[1].stylesheet,
  13525. mediaText: stylesheetInfo.mediaText
  13526. });
  13527. } else {
  13528. content.data = getUpdatedResourceContent(content.resourceURL, content, options);
  13529. stylesheetInfo.stylesheet = db(content.data, { context: "stylesheet", parseCustomProperty: true });
  13530. await this.resolveImportURLs(stylesheetInfo, resourceURL, options, workStylesheet, resources, stylesheets);
  13531. }
  13532. }
  13533. }
  13534. }
  13535. async processFrame(frameElement, pageData, resources, frameWindowId, frameData) {
  13536. const name = "frames/" + resources.frames.size + "/";
  13537. if (frameElement.tagName.toUpperCase() == "OBJECT") {
  13538. frameElement.setAttribute("data", name + "index.html");
  13539. } else {
  13540. frameElement.setAttribute("src", name + "index.html");
  13541. }
  13542. resources.frames.set(frameWindowId, { name, content: pageData.content, resources: pageData.resources, url: frameData.url });
  13543. }
  13544. async processStylesheet(cssRules, baseURI, options, resources, batchRequest) {
  13545. const promises = [];
  13546. const removedRules = [];
  13547. for (let cssRule = cssRules.head; cssRule; cssRule = cssRule.next) {
  13548. const ruleData = cssRule.data;
  13549. if (ruleData.type == "Atrule" && ruleData.name == "charset") {
  13550. removedRules.push(cssRule);
  13551. } else if (ruleData.block && ruleData.block.children) {
  13552. if (ruleData.type == "Rule") {
  13553. promises.push(this.processStyle(ruleData, options, resources, batchRequest));
  13554. } else if (ruleData.type == "Atrule" && (ruleData.name == "media" || ruleData.name == "supports")) {
  13555. promises.push(this.processStylesheet(ruleData.block.children, baseURI, options, resources, batchRequest));
  13556. } else if (ruleData.type == "Atrule" && ruleData.name == "font-face") {
  13557. promises.push(processFontFaceRule(ruleData));
  13558. }
  13559. }
  13560. }
  13561. removedRules.forEach(cssRule => cssRules.remove(cssRule));
  13562. await Promise.all(promises);
  13563. async function processFontFaceRule(ruleData) {
  13564. const urls = getUrlFunctions(ruleData);
  13565. await Promise.all(urls.map(async urlNode => {
  13566. const originalResourceURL = urlNode.value;
  13567. if (!options.blockFonts) {
  13568. const resourceURL = normalizeURL$1(originalResourceURL);
  13569. if (!testIgnoredPath$1(resourceURL) && testValidURL$1(resourceURL)) {
  13570. let { content, extension, indexResource, contentType } = await batchRequest.addURL(resourceURL,
  13571. { asBinary: true, expectedType: "font", baseURI, blockMixedContent: options.blockMixedContent });
  13572. const name = "fonts/" + indexResource + extension;
  13573. if (!isDataURL$1(resourceURL) && options.saveOriginalURLs) {
  13574. urlNode.value = "-sf-url-original(" + JSON$2.stringify(originalResourceURL) + ") " + name;
  13575. } else {
  13576. urlNode.value = name;
  13577. }
  13578. resources.fonts.set(indexResource, { name, content, extension, contentType, url: resourceURL });
  13579. }
  13580. } else {
  13581. urlNode.value = util$1.EMPTY_RESOURCE;
  13582. }
  13583. }));
  13584. }
  13585. }
  13586. async processStyle(ruleData, options, resources, batchRequest) {
  13587. const urls = getUrlFunctions(ruleData);
  13588. await Promise.all(urls.map(async urlNode => {
  13589. const originalResourceURL = urlNode.value;
  13590. if (!options.blockImages) {
  13591. const resourceURL = normalizeURL$1(originalResourceURL);
  13592. if (!testIgnoredPath$1(resourceURL) && testValidURL$1(resourceURL)) {
  13593. let { content, indexResource, contentType, extension } = await batchRequest.addURL(resourceURL,
  13594. { asBinary: true, expectedType: "image" });
  13595. const name = "images/" + indexResource + extension;
  13596. if (!isDataURL$1(resourceURL) && options.saveOriginalURLs) {
  13597. urlNode.value = "-sf-url-original(" + JSON$2.stringify(originalResourceURL) + ") " + name;
  13598. } else {
  13599. urlNode.value = name;
  13600. }
  13601. resources.images.set(indexResource, { name, content, extension, contentType, url: resourceURL });
  13602. }
  13603. } else {
  13604. urlNode.value = util$1.EMPTY_RESOURCE;
  13605. }
  13606. }));
  13607. }
  13608. async processAttribute(resourceElements, attributeName, baseURI, options, expectedType, resources, batchRequest, removeElementIfMissing) {
  13609. await Promise.all(Array.from(resourceElements).map(async resourceElement => {
  13610. let resourceURL = resourceElement.getAttribute(attributeName);
  13611. if (resourceURL != null) {
  13612. resourceURL = normalizeURL$1(resourceURL);
  13613. let originURL = resourceElement.dataset.singleFileOriginURL;
  13614. if (options.saveOriginalURLs && !isDataURL$1(resourceURL)) {
  13615. resourceElement.setAttribute("data-sf-original-" + attributeName, resourceURL);
  13616. }
  13617. delete resourceElement.dataset.singleFileOriginURL;
  13618. if (!options["block" + expectedType.charAt(0).toUpperCase() + expectedType.substring(1) + "s"]) {
  13619. if (!testIgnoredPath$1(resourceURL)) {
  13620. setAttributeEmpty(resourceElement, attributeName, expectedType);
  13621. if (testValidPath$1(resourceURL)) {
  13622. try {
  13623. resourceURL = util$1.resolveURL(resourceURL, baseURI);
  13624. } catch (error) {
  13625. // ignored
  13626. }
  13627. if (testValidURL$1(resourceURL)) {
  13628. let { content, indexResource, extension, contentType } = await batchRequest.addURL(resourceURL,
  13629. { asBinary: true, expectedType });
  13630. if (originURL) {
  13631. if (this.testEmptyResource(content)) {
  13632. try {
  13633. originURL = util$1.resolveURL(originURL, baseURI);
  13634. } catch (error) {
  13635. // ignored
  13636. }
  13637. try {
  13638. resourceURL = originURL;
  13639. content = (await util$1.getContent(resourceURL, {
  13640. asBinary: true,
  13641. expectedType,
  13642. maxResourceSize: options.maxResourceSize,
  13643. maxResourceSizeEnabled: options.maxResourceSizeEnabled,
  13644. frameId: options.windowId,
  13645. resourceReferrer: options.resourceReferrer,
  13646. acceptHeaders: options.acceptHeaders,
  13647. networkTimeout: options.networkTimeout
  13648. })).data;
  13649. } catch (error) {
  13650. // ignored
  13651. }
  13652. }
  13653. }
  13654. if (removeElementIfMissing && this.testEmptyResource(content)) {
  13655. resourceElement.remove();
  13656. } else if (!this.testEmptyResource(content)) {
  13657. const name = "images/" + indexResource + extension;
  13658. resourceElement.setAttribute(attributeName, name);
  13659. resources.images.set(indexResource, { name, content, extension, contentType, url: resourceURL });
  13660. }
  13661. }
  13662. }
  13663. }
  13664. } else {
  13665. setAttributeEmpty(resourceElement, attributeName, expectedType);
  13666. }
  13667. }
  13668. }));
  13669. function setAttributeEmpty(resourceElement, attributeName, expectedType) {
  13670. if (expectedType == "video" || expectedType == "audio") {
  13671. resourceElement.removeAttribute(attributeName);
  13672. } else {
  13673. resourceElement.setAttribute(attributeName, util$1.EMPTY_RESOURCE);
  13674. }
  13675. }
  13676. }
  13677. async processSrcset(resourceElements, baseURI, options, resources, batchRequest) {
  13678. await Promise.all(Array.from(resourceElements).map(async resourceElement => {
  13679. const originSrcset = resourceElement.getAttribute("srcset");
  13680. const srcset = util$1.parseSrcset(originSrcset);
  13681. if (options.saveOriginalURLs && !isDataURL$1(originSrcset)) {
  13682. resourceElement.setAttribute("data-sf-original-srcset", originSrcset);
  13683. }
  13684. if (!options.blockImages) {
  13685. const srcsetValues = await Promise.all(srcset.map(async srcsetValue => {
  13686. let resourceURL = normalizeURL$1(srcsetValue.url);
  13687. if (!testIgnoredPath$1(resourceURL)) {
  13688. if (testValidPath$1(resourceURL)) {
  13689. try {
  13690. resourceURL = util$1.resolveURL(resourceURL, baseURI);
  13691. } catch (error) {
  13692. // ignored
  13693. }
  13694. if (testValidURL$1(resourceURL)) {
  13695. const { content, indexResource, extension, contentType } = await batchRequest.addURL(resourceURL, { asBinary: true, expectedType: "image" });
  13696. const name = "images/" + indexResource + extension;
  13697. resources.images.set(indexResource, { name, content, extension, contentType, url: resourceURL });
  13698. return name + (srcsetValue.w ? " " + srcsetValue.w + "w" : srcsetValue.d ? " " + srcsetValue.d + "x" : "");
  13699. } else {
  13700. return "";
  13701. }
  13702. } else {
  13703. return "";
  13704. }
  13705. } else {
  13706. return resourceURL + (srcsetValue.w ? " " + srcsetValue.w + "w" : srcsetValue.d ? " " + srcsetValue.d + "x" : "");
  13707. }
  13708. }));
  13709. resourceElement.setAttribute("srcset", srcsetValues.join(", "));
  13710. } else {
  13711. resourceElement.setAttribute("srcset", "");
  13712. }
  13713. }));
  13714. }
  13715. testEmptyResource(resource) {
  13716. return !resource;
  13717. }
  13718. generateStylesheetContent(stylesheet, options) {
  13719. if (options.compressCSS) {
  13720. this.removeSingleLineCssComments(stylesheet);
  13721. }
  13722. this.replacePseudoClassDefined(stylesheet);
  13723. let stylesheetContent = gb(stylesheet);
  13724. if (options.compressCSS) {
  13725. stylesheetContent = util$1.compressCSS(stylesheetContent);
  13726. }
  13727. if (options.saveOriginalURLs) {
  13728. stylesheetContent = replaceOriginalURLs(stylesheetContent);
  13729. }
  13730. return stylesheetContent;
  13731. }
  13732. getAdditionalPageData(doc, content, pageResources) {
  13733. const resources = {};
  13734. let textContent = content;
  13735. pageResources.stylesheets.forEach(resource => textContent += resource.content);
  13736. Object.keys(pageResources).forEach(resourceType => {
  13737. const unusedResources = Array.from(pageResources[resourceType]).filter(([, value]) => !textContent.includes(value.name));
  13738. unusedResources.forEach(([indexResource]) => pageResources[resourceType].delete(indexResource));
  13739. resources[resourceType] = Array.from(pageResources[resourceType].values());
  13740. });
  13741. const viewportElement = doc.head.querySelector("meta[name=viewport]");
  13742. const viewport = viewportElement ? viewportElement.content : null;
  13743. const doctype = util$1.getDoctypeString(doc);
  13744. return {
  13745. doctype,
  13746. resources,
  13747. viewport
  13748. };
  13749. }
  13750. removeAlternativeFonts(doc, stylesheets, fontResources, fontTests) {
  13751. return removeAlternativeFonts(doc, stylesheets, fontResources, fontTests);
  13752. }
  13753. async processScript(element, resourceURL) {
  13754. const content = await util$1.getContent(resourceURL, {
  13755. asBinary: true,
  13756. charset: this.charset != UTF8_CHARSET$1 && this.charset,
  13757. maxResourceSize: this.options.maxResourceSize,
  13758. maxResourceSizeEnabled: this.options.maxResourceSizeEnabled,
  13759. frameId: this.options.windowId,
  13760. resourceReferrer: this.options.resourceReferrer,
  13761. baseURI: this.options.baseURI,
  13762. blockMixedContent: this.options.blockMixedContent,
  13763. expectedType: "script",
  13764. acceptHeaders: this.options.acceptHeaders,
  13765. networkTimeout: this.options.networkTimeout
  13766. });
  13767. content.data = getUpdatedResourceContent(resourceURL, content, this.options);
  13768. element.setAttribute("src", content.data);
  13769. }
  13770. setMetaCSP(metaElement) {
  13771. metaElement.content = "default-src 'none'; font-src 'self' data: blob:; img-src 'self' data: blob:; style-src 'self' 'unsafe-inline' data: blob:; frame-src 'self' data: blob:; media-src 'self' data: blob:; script-src 'self' 'unsafe-inline' data: blob:; object-src 'self' data: blob:;";
  13772. }
  13773. removeUnusedStylesheets() {
  13774. }
  13775. };
  13776. }
  13777. async function removeAlternativeFonts(doc, stylesheets, fontResources, fontTests) {
  13778. const fontsDetails = {
  13779. fonts: new Map(),
  13780. medias: new Map(),
  13781. supports: new Map()
  13782. };
  13783. const stats = { rules: { processed: 0, discarded: 0 }, fonts: { processed: 0, discarded: 0 } };
  13784. let sheetIndex = 0;
  13785. stylesheets.forEach(stylesheetInfo => {
  13786. const cssRules = stylesheetInfo.stylesheet.children;
  13787. if (cssRules) {
  13788. stats.rules.processed += cssRules.size;
  13789. stats.rules.discarded += cssRules.size;
  13790. if (stylesheetInfo.mediaText && stylesheetInfo.mediaText != MEDIA_ALL) {
  13791. const mediaFontsDetails = createFontsDetailsInfo();
  13792. fontsDetails.medias.set("media-" + sheetIndex + "-" + stylesheetInfo.mediaText, mediaFontsDetails);
  13793. getFontsDetails(doc, cssRules, sheetIndex, mediaFontsDetails);
  13794. } else {
  13795. getFontsDetails(doc, cssRules, sheetIndex, fontsDetails);
  13796. }
  13797. }
  13798. sheetIndex++;
  13799. });
  13800. processFontDetails(fontsDetails, fontResources);
  13801. await Promise.all([...stylesheets].map(async ([, stylesheetInfo], sheetIndex) => {
  13802. const cssRules = stylesheetInfo.stylesheet.children;
  13803. const media = stylesheetInfo.mediaText;
  13804. if (cssRules) {
  13805. if (media && media != MEDIA_ALL) {
  13806. await processFontFaceRules(cssRules, sheetIndex, fontsDetails.medias.get("media-" + sheetIndex + "-" + media), fontResources, fontTests, stats);
  13807. } else {
  13808. await processFontFaceRules(cssRules, sheetIndex, fontsDetails, fontResources, fontTests, stats);
  13809. }
  13810. stats.rules.discarded -= cssRules.size;
  13811. }
  13812. }));
  13813. return stats;
  13814. }
  13815. function getFontsDetails(doc, cssRules, sheetIndex, mediaFontsDetails) {
  13816. let mediaIndex = 0, supportsIndex = 0;
  13817. cssRules.forEach(ruleData => {
  13818. if (ruleData.type == "Atrule" && ruleData.name == "media" && ruleData.block && ruleData.block.children && ruleData.prelude) {
  13819. const mediaText = gb(ruleData.prelude);
  13820. const fontsDetails = createFontsDetailsInfo();
  13821. mediaFontsDetails.medias.set("media-" + sheetIndex + "-" + mediaIndex + "-" + mediaText, fontsDetails);
  13822. mediaIndex++;
  13823. getFontsDetails(doc, ruleData.block.children, sheetIndex, fontsDetails);
  13824. } else if (ruleData.type == "Atrule" && ruleData.name == "supports" && ruleData.block && ruleData.block.children && ruleData.prelude) {
  13825. const supportsText = gb(ruleData.prelude);
  13826. const fontsDetails = createFontsDetailsInfo();
  13827. mediaFontsDetails.supports.set("supports-" + sheetIndex + "-" + supportsIndex + "-" + supportsText, fontsDetails);
  13828. supportsIndex++;
  13829. getFontsDetails(doc, ruleData.block.children, sheetIndex, fontsDetails);
  13830. } else if (ruleData.type == "Atrule" && ruleData.name == "font-face" && ruleData.block && ruleData.block.children) {
  13831. const fontKey = getFontKey(ruleData);
  13832. let fontInfo = mediaFontsDetails.fonts.get(fontKey);
  13833. if (!fontInfo) {
  13834. fontInfo = [];
  13835. mediaFontsDetails.fonts.set(fontKey, fontInfo);
  13836. }
  13837. const src = getPropertyValue(ruleData, "src");
  13838. if (src) {
  13839. const fontSources = src.match(REGEXP_URL_FUNCTION);
  13840. if (fontSources) {
  13841. fontSources.forEach(source => fontInfo.unshift(source));
  13842. }
  13843. }
  13844. }
  13845. });
  13846. }
  13847. function processFontDetails(fontsDetails, fontResources) {
  13848. fontsDetails.fonts.forEach((fontInfo, fontKey) => {
  13849. fontsDetails.fonts.set(fontKey, fontInfo.map(fontSource => {
  13850. const fontFormatMatch = fontSource.match(REGEXP_FONT_FORMAT_VALUE);
  13851. let fontFormat;
  13852. const fontUrl = getURL(fontSource);
  13853. if (fontFormatMatch && fontFormatMatch[1]) {
  13854. fontFormat = fontFormatMatch[1].replace(REGEXP_SIMPLE_QUOTES_STRING, "$1").replace(REGEXP_DOUBLE_QUOTES_STRING, "$1").toLowerCase();
  13855. }
  13856. if (!fontFormat) {
  13857. const fontFormatMatch = fontSource.match(REGEXP_URL_FUNCTION_WOFF);
  13858. if (fontFormatMatch && fontFormatMatch[1]) {
  13859. fontFormat = fontFormatMatch[1];
  13860. } else {
  13861. const fontFormatMatch = fontSource.match(REGEXP_URL_FUNCTION_WOFF_ALT);
  13862. if (fontFormatMatch && fontFormatMatch[1]) {
  13863. fontFormat = fontFormatMatch[1];
  13864. }
  13865. }
  13866. }
  13867. if (!fontFormat && fontUrl) {
  13868. const fontFormatMatch = fontUrl.match(REGEXP_FONT_FORMAT);
  13869. if (fontFormatMatch && fontFormatMatch[1]) {
  13870. fontFormat = fontFormatMatch[1];
  13871. }
  13872. }
  13873. const fontResource = Array.from(fontResources.values()).find(info => info.name == fontUrl);
  13874. return { src: fontSource.match(REGEXP_FONT_SRC)[1], fontUrl, format: fontFormat, contentType: fontResource && fontResource.contentType };
  13875. }));
  13876. });
  13877. fontsDetails.medias.forEach(mediaFontsDetails => processFontDetails(mediaFontsDetails, fontResources));
  13878. fontsDetails.supports.forEach(supportsFontsDetails => processFontDetails(supportsFontsDetails, fontResources));
  13879. }
  13880. async function processFontFaceRules(cssRules, sheetIndex, fontsDetails, fontResources, fontTests, stats) {
  13881. const removedRules = [];
  13882. let mediaIndex = 0, supportsIndex = 0;
  13883. for (let cssRule = cssRules.head; cssRule; cssRule = cssRule.next) {
  13884. const ruleData = cssRule.data;
  13885. if (ruleData.type == "Atrule" && ruleData.name == "media" && ruleData.block && ruleData.block.children && ruleData.prelude) {
  13886. const mediaText = gb(ruleData.prelude);
  13887. await processFontFaceRules(ruleData.block.children, sheetIndex, fontsDetails.medias.get("media-" + sheetIndex + "-" + mediaIndex + "-" + mediaText), fontResources, fontTests, stats);
  13888. mediaIndex++;
  13889. } else if (ruleData.type == "Atrule" && ruleData.name == "supports" && ruleData.block && ruleData.block.children && ruleData.prelude) {
  13890. const supportsText = gb(ruleData.prelude);
  13891. await processFontFaceRules(ruleData.block.children, sheetIndex, fontsDetails.supports.get("supports-" + sheetIndex + "-" + supportsIndex + "-" + supportsText), fontResources, fontTests, stats);
  13892. supportsIndex++;
  13893. } else if (ruleData.type == "Atrule" && ruleData.name == "font-face") {
  13894. const key = getFontKey(ruleData);
  13895. const fontInfo = fontsDetails.fonts.get(key);
  13896. if (fontInfo) {
  13897. fontsDetails.fonts.delete(key);
  13898. await processFontFaceRule(ruleData, fontInfo, fontResources, fontTests, stats);
  13899. } else {
  13900. removedRules.push(cssRule);
  13901. }
  13902. }
  13903. }
  13904. removedRules.forEach(cssRule => cssRules.remove(cssRule));
  13905. }
  13906. async function processFontFaceRule(ruleData, fontInfo, fontResources, fontTests, stats) {
  13907. await Promise.all(fontInfo.map(async source => {
  13908. if (fontTests.has(source.src)) {
  13909. source.valid = fontTests.get(source.src);
  13910. } else {
  13911. if (FontFace && source.fontUrl) {
  13912. const resourceEntry = [...fontResources].find(([, resource]) => source.fontUrl && resource.name == source.fontUrl);
  13913. if (resourceEntry) {
  13914. const resource = resourceEntry[1];
  13915. const fontFace = new FontFace("test-font", new Uint8Array(resource.content).buffer);
  13916. try {
  13917. let timeout;
  13918. await Promise.race([
  13919. fontFace.load().then(() => fontFace.loaded).then(() => { source.valid = true; globalThis.clearTimeout(timeout); }),
  13920. new Promise(resolve => timeout = globalThis.setTimeout(() => { source.valid = true; resolve(); }, FONT_MAX_LOAD_DELAY))
  13921. ]);
  13922. } catch (error) {
  13923. const fontFace = new FontFace("test-font", "url(" + resource.url + ")");
  13924. try {
  13925. let timeout;
  13926. await Promise.race([
  13927. fontFace.load().then(() => fontFace.loaded).then(() => { source.valid = true; globalThis.clearTimeout(timeout); }),
  13928. new Promise(resolve => timeout = globalThis.setTimeout(() => { source.valid = true; resolve(); }, FONT_MAX_LOAD_DELAY))
  13929. ]);
  13930. } catch (error) {
  13931. // ignored
  13932. }
  13933. }
  13934. } else {
  13935. source.valid = true;
  13936. }
  13937. } else {
  13938. source.valid = true;
  13939. }
  13940. fontTests.set(source.src, source.valid);
  13941. }
  13942. }));
  13943. const findSourceByFormat = (fontFormat, testValidity) => fontInfo.find(source => !source.src.match(EMPTY_URL_SOURCE) && source.format == fontFormat && (!testValidity || source.valid));
  13944. const findSourceByContentType = (contentType, testValidity) => fontInfo.find(source => !source.src.match(EMPTY_URL_SOURCE) && source.contentType == contentType && (!testValidity || source.valid));
  13945. const filterSources = fontSource => fontInfo.filter(source => source == fontSource || source.src.startsWith(LOCAL_SOURCE));
  13946. stats.fonts.processed += fontInfo.length;
  13947. stats.fonts.discarded += fontInfo.length;
  13948. const woffFontFound =
  13949. findSourceByFormat("woff2-variations", true) || findSourceByFormat("woff2", true) || findSourceByFormat("woff", true) ||
  13950. findSourceByContentType("font/woff2", true) || findSourceByContentType("font/woff", true) || findSourceByContentType("application/font-woff", true) || findSourceByContentType("application/x-font-woff", true);
  13951. if (woffFontFound) {
  13952. fontInfo = filterSources(woffFontFound);
  13953. } else {
  13954. const ttfFontFound =
  13955. findSourceByFormat("truetype-variations", true) || findSourceByFormat("truetype", true) ||
  13956. findSourceByContentType("font/ttf", true) || findSourceByContentType("application/x-font-ttf", true) || findSourceByContentType("application/x-font-ttf", true) || findSourceByContentType("application/x-font-truetype", true);
  13957. if (ttfFontFound) {
  13958. fontInfo = filterSources(ttfFontFound);
  13959. } else {
  13960. const otfFontFound =
  13961. findSourceByFormat("opentype") || findSourceByFormat("embedded-opentype") ||
  13962. findSourceByContentType("font/otf") || findSourceByContentType("application/x-font-opentype") || findSourceByContentType("application/font-sfnt");
  13963. if (otfFontFound) {
  13964. fontInfo = filterSources(otfFontFound);
  13965. } else {
  13966. fontInfo = fontInfo.filter(source => !source.src.match(EMPTY_URL_SOURCE) && (source.valid) || source.src.startsWith(LOCAL_SOURCE));
  13967. }
  13968. }
  13969. }
  13970. stats.fonts.discarded -= fontInfo.length;
  13971. const removedNodes = [];
  13972. for (let node = ruleData.block.children.head; node; node = node.next) {
  13973. if (node.data.property == "src") {
  13974. removedNodes.push(node);
  13975. }
  13976. }
  13977. removedNodes.pop();
  13978. removedNodes.forEach(node => ruleData.block.children.remove(node));
  13979. const srcDeclaration = ruleData.block.children.filter(node => node.property == "src").tail;
  13980. if (srcDeclaration) {
  13981. fontInfo.reverse();
  13982. try {
  13983. srcDeclaration.data.value = db(fontInfo.map(fontSource => fontSource.src).join(","), { context: "value", parseCustomProperty: true });
  13984. }
  13985. catch (error) {
  13986. // ignored
  13987. }
  13988. }
  13989. }
  13990. function getPropertyValue(ruleData, propertyName) {
  13991. let property;
  13992. if (ruleData.block.children) {
  13993. property = ruleData.block.children.filter(node => {
  13994. try {
  13995. return node.property == propertyName && !gb(node.value).match(/\\9$/);
  13996. } catch (error) {
  13997. return node.property == propertyName;
  13998. }
  13999. }).tail;
  14000. }
  14001. if (property) {
  14002. try {
  14003. return gb(property.data.value);
  14004. } catch (error) {
  14005. // ignored
  14006. }
  14007. }
  14008. }
  14009. function getFontKey(ruleData) {
  14010. return JSON$2.stringify([
  14011. normalizeFontFamily(getPropertyValue(ruleData, "font-family")),
  14012. getFontWeight(getPropertyValue(ruleData, "font-weight") || "400"),
  14013. getPropertyValue(ruleData, "font-style") || "normal",
  14014. getPropertyValue(ruleData, "unicode-range"),
  14015. getFontStretch(getPropertyValue(ruleData, "font-stretch")),
  14016. getPropertyValue(ruleData, "font-variant") || "normal",
  14017. getPropertyValue(ruleData, "font-feature-settings"),
  14018. getPropertyValue(ruleData, "font-variation-settings")
  14019. ]);
  14020. }
  14021. function getFontStretch(stretch) {
  14022. return FONT_STRETCHES[stretch] || stretch;
  14023. }
  14024. function createFontsDetailsInfo() {
  14025. return {
  14026. fonts: new Map(),
  14027. medias: new Map(),
  14028. supports: new Map()
  14029. };
  14030. }
  14031. function getURL(urlFunction) {
  14032. urlFunction = urlFunction.replace(/url\(-sf-url-original\\\(\\"(.*?)\\"\\\)\\ /g, "");
  14033. const urlMatch = urlFunction.match(REGEXP_URL_SIMPLE_QUOTES_FN) ||
  14034. urlFunction.match(REGEXP_URL_DOUBLE_QUOTES_FN) ||
  14035. urlFunction.match(REGEXP_URL_NO_QUOTES_FN);
  14036. return urlMatch && urlMatch[1];
  14037. }
  14038. /*
  14039. * Copyright 2010-2022 Gildas Lormeau
  14040. * contact : gildas.lormeau <at> gmail.com
  14041. *
  14042. * This file is part of SingleFile.
  14043. *
  14044. * The code in this file is free software: you can redistribute it and/or
  14045. * modify it under the terms of the GNU Affero General Public License
  14046. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  14047. * of the License, or (at your option) any later version.
  14048. *
  14049. * The code in this file is distributed in the hope that it will be useful,
  14050. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14051. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  14052. * General Public License for more details.
  14053. *
  14054. * As additional permission under GNU AGPL version 3 section 7, you may
  14055. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  14056. * AGPL normally required by section 4, provided you include this license
  14057. * notice and a URL through which recipients can access the Corresponding
  14058. * Source.
  14059. */
  14060. function getProcessorHelperClass(options, utilInstance) {
  14061. return options.compressContent ? getProcessorHelperClass$1(utilInstance) : getProcessorHelperClass$2(utilInstance);
  14062. }
  14063. /*
  14064. * Copyright 2010-2022 Gildas Lormeau
  14065. * contact : gildas.lormeau <at> gmail.com
  14066. *
  14067. * This file is part of SingleFile.
  14068. *
  14069. * The code in this file is free software: you can redistribute it and/or
  14070. * modify it under the terms of the GNU Affero General Public License
  14071. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  14072. * of the License, or (at your option) any later version.
  14073. *
  14074. * The code in this file is distributed in the hope that it will be useful,
  14075. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14076. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  14077. * General Public License for more details.
  14078. *
  14079. * As additional permission under GNU AGPL version 3 section 7, you may
  14080. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  14081. * AGPL normally required by section 4, provided you include this license
  14082. * notice and a URL through which recipients can access the Corresponding
  14083. * Source.
  14084. */
  14085. const Set$1 = globalThis.Set;
  14086. const Map$1 = globalThis.Map;
  14087. const JSON$1 = globalThis.JSON;
  14088. let util;
  14089. function getClass(...args) {
  14090. [util] = args;
  14091. return SingleFileClass;
  14092. }
  14093. class SingleFileClass {
  14094. constructor(options) {
  14095. this.options = options;
  14096. const ProcessorHelper = getProcessorHelperClass(options, util);
  14097. this.processorHelper = new ProcessorHelper();
  14098. }
  14099. async run() {
  14100. const waitForUserScript = globalThis[util.WAIT_FOR_USERSCRIPT_PROPERTY_NAME];
  14101. if (this.options.userScriptEnabled && waitForUserScript) {
  14102. await waitForUserScript(util.ON_BEFORE_CAPTURE_EVENT_NAME);
  14103. }
  14104. this.runner = new Runner(this.options, this.processorHelper, true);
  14105. await this.runner.loadPage();
  14106. await this.runner.initialize();
  14107. if (this.options.userScriptEnabled && waitForUserScript) {
  14108. await waitForUserScript(util.ON_AFTER_CAPTURE_EVENT_NAME);
  14109. }
  14110. await this.runner.run();
  14111. }
  14112. cancel() {
  14113. this.cancelled = true;
  14114. if (this.runner) {
  14115. this.runner.cancel();
  14116. }
  14117. }
  14118. getPageData() {
  14119. return this.runner.getPageData();
  14120. }
  14121. }
  14122. // -------------
  14123. // ProgressEvent
  14124. // -------------
  14125. const PAGE_LOADING = "page-loading";
  14126. const PAGE_LOADED = "page-loaded";
  14127. const RESOURCES_INITIALIZING = "resource-initializing";
  14128. const RESOURCES_INITIALIZED = "resources-initialized";
  14129. const RESOURCE_LOADED = "resource-loaded";
  14130. const PAGE_ENDED = "page-ended";
  14131. const STAGE_STARTED = "stage-started";
  14132. const STAGE_ENDED = "stage-ended";
  14133. const STAGE_TASK_STARTED = "stage-task-started";
  14134. const STAGE_TASK_ENDED = "stage-task-ended";
  14135. class ProgressEvent {
  14136. constructor(type, detail) {
  14137. return { type, detail, PAGE_LOADING, PAGE_LOADED, RESOURCES_INITIALIZING, RESOURCES_INITIALIZED, RESOURCE_LOADED, PAGE_ENDED, STAGE_STARTED, STAGE_ENDED, STAGE_TASK_STARTED, STAGE_TASK_ENDED };
  14138. }
  14139. }
  14140. // ------
  14141. // Runner
  14142. // ------
  14143. const RESOLVE_URLS_STAGE = 0;
  14144. const REPLACE_DATA_STAGE = 1;
  14145. const REPLACE_DOCS_STAGE = 2;
  14146. const POST_PROCESS_STAGE = 3;
  14147. const STAGES = [{
  14148. sequential: [
  14149. { action: "preProcessPage" },
  14150. { option: "loadDeferredImagesKeepZoomLevel", action: "resetZoomLevel" },
  14151. { action: "replaceStyleContents" },
  14152. { action: "replaceInvalidElements" },
  14153. { action: "resetCharsetMeta" },
  14154. { option: "saveFavicon", action: "saveFavicon" },
  14155. { action: "insertFonts" },
  14156. { action: "insertShadowRootContents" },
  14157. { action: "replaceCanvasElements" },
  14158. { action: "setInputValues" },
  14159. { option: "moveStylesInHead", action: "moveStylesInHead" },
  14160. { option: "blockScripts", action: "removeEmbedScripts" },
  14161. { option: "selected", action: "removeUnselectedElements" },
  14162. { option: "blockVideos", action: "insertVideoPosters" },
  14163. { option: "blockVideos", action: "insertVideoLinks" },
  14164. { option: "removeFrames", action: "removeFrames" },
  14165. { action: "removeDiscardedResources" },
  14166. { option: "removeHiddenElements", action: "removeHiddenElements" },
  14167. { action: "saveScrollPosition" },
  14168. { action: "resolveHrefs" },
  14169. { action: "resolveStyleAttributeURLs" }
  14170. ],
  14171. parallel: [
  14172. { option: "blockVideos", action: "insertMissingVideoPosters" },
  14173. { action: "resolveStylesheetsURLs" },
  14174. { option: "!removeFrames", action: "resolveFrameURLs" }
  14175. ]
  14176. }, {
  14177. sequential: [
  14178. { option: "removeUnusedStyles", action: "removeUnusedStyles" },
  14179. { option: "removeAlternativeMedias", action: "removeAlternativeMedias" },
  14180. { option: "removeUnusedFonts", action: "removeUnusedFonts" }
  14181. ],
  14182. parallel: [
  14183. { action: "processStylesheets" },
  14184. { action: "processStyleAttributes" },
  14185. { action: "processPageResources" },
  14186. { action: "processScripts" }
  14187. ]
  14188. }, {
  14189. sequential: [
  14190. { option: "removeAlternativeImages", action: "removeAlternativeImages" }
  14191. ],
  14192. parallel: [
  14193. { option: "removeAlternativeFonts", action: "removeAlternativeFonts" },
  14194. { option: "!removeFrames", action: "processFrames" }
  14195. ]
  14196. }, {
  14197. sequential: [
  14198. { action: "replaceStylesheets" },
  14199. { action: "replaceStyleAttributes" },
  14200. { action: "insertVariables" },
  14201. { option: "compressHTML", action: "compressHTML" },
  14202. { action: "cleanupPage" }
  14203. ],
  14204. parallel: [
  14205. { option: "enableMaff", action: "insertMAFFMetaData" },
  14206. { action: "setDocInfo" }
  14207. ]
  14208. }];
  14209. class Runner {
  14210. constructor(options, processorHelper, root) {
  14211. const rootDocDefined = root && options.doc;
  14212. this.root = root;
  14213. this.options = options;
  14214. this.options.url = this.options.url || (rootDocDefined && this.options.doc.location.href);
  14215. const matchResourceReferrer = this.options.url.match(/^.*\//);
  14216. this.options.resourceReferrer = this.options.passReferrerOnError && matchResourceReferrer && matchResourceReferrer[0];
  14217. this.options.baseURI = rootDocDefined && this.options.doc.baseURI;
  14218. this.options.rootDocument = root;
  14219. this.options.updatedResources = this.options.updatedResources || {};
  14220. this.options.fontTests = new Map$1();
  14221. this.batchRequest = new BatchRequest();
  14222. this.processor = new Processor(options, processorHelper, this.batchRequest);
  14223. if (rootDocDefined) {
  14224. const docData = util.preProcessDoc(this.options.doc, this.options.win, this.options);
  14225. this.options.canvases = docData.canvases;
  14226. this.options.fonts = docData.fonts;
  14227. this.options.stylesheets = docData.stylesheets;
  14228. this.options.images = docData.images;
  14229. this.options.posters = docData.posters;
  14230. this.options.videos = docData.videos;
  14231. this.options.usedFonts = docData.usedFonts;
  14232. this.options.shadowRoots = docData.shadowRoots;
  14233. this.options.referrer = docData.referrer;
  14234. this.options.adoptedStyleSheets = docData.adoptedStyleSheets;
  14235. this.markedElements = docData.markedElements;
  14236. this.invalidElements = docData.invalidElements;
  14237. }
  14238. if (this.options.saveRawPage) {
  14239. this.options.removeFrames = true;
  14240. }
  14241. this.options.content = this.options.content || (rootDocDefined ? util.serialize(this.options.doc) : null);
  14242. this.onprogress = options.onprogress || (() => { });
  14243. }
  14244. async loadPage() {
  14245. this.onprogress(new ProgressEvent(PAGE_LOADING, { pageURL: this.options.url, frame: !this.root }));
  14246. await this.processor.loadPage(this.options.content);
  14247. this.onprogress(new ProgressEvent(PAGE_LOADED, { pageURL: this.options.url, frame: !this.root }));
  14248. }
  14249. async initialize() {
  14250. this.onprogress(new ProgressEvent(RESOURCES_INITIALIZING, { pageURL: this.options.url }));
  14251. await this.executeStage(RESOLVE_URLS_STAGE);
  14252. this.pendingPromises = this.executeStage(REPLACE_DATA_STAGE);
  14253. if (this.root && this.options.doc) {
  14254. util.postProcessDoc(this.options.doc, this.markedElements, this.invalidElements);
  14255. }
  14256. }
  14257. cancel() {
  14258. this.cancelled = true;
  14259. this.batchRequest.cancel();
  14260. if (this.root) {
  14261. if (this.options.frames) {
  14262. this.options.frames.forEach(cancelRunner);
  14263. }
  14264. }
  14265. function cancelRunner(resourceData) {
  14266. if (resourceData.runner) {
  14267. resourceData.runner.cancel();
  14268. }
  14269. }
  14270. }
  14271. async run() {
  14272. if (this.root) {
  14273. this.processor.initialize(this.batchRequest);
  14274. this.onprogress(new ProgressEvent(RESOURCES_INITIALIZED, { pageURL: this.options.url, max: this.processor.maxResources }));
  14275. }
  14276. await this.batchRequest.run(detail => {
  14277. detail.pageURL = this.options.url;
  14278. this.onprogress(new ProgressEvent(RESOURCE_LOADED, detail));
  14279. }, this.options);
  14280. await this.pendingPromises;
  14281. this.options.doc = null;
  14282. this.options.win = null;
  14283. await this.executeStage(REPLACE_DOCS_STAGE);
  14284. await this.executeStage(POST_PROCESS_STAGE);
  14285. this.processor.finalize();
  14286. }
  14287. getDocument() {
  14288. return this.processor.doc;
  14289. }
  14290. getStyleSheets() {
  14291. return this.processor.stylesheets;
  14292. }
  14293. getPageData() {
  14294. if (this.root) {
  14295. this.onprogress(new ProgressEvent(PAGE_ENDED, { pageURL: this.options.url }));
  14296. }
  14297. return this.processor.getPageData();
  14298. }
  14299. async executeStage(step) {
  14300. const frame = !this.root;
  14301. this.onprogress(new ProgressEvent(STAGE_STARTED, { pageURL: this.options.url, step, frame }));
  14302. STAGES[step].sequential.forEach(task => {
  14303. this.onprogress(new ProgressEvent(STAGE_TASK_STARTED, { pageURL: this.options.url, step, task: task.action, frame }));
  14304. if (!this.cancelled) {
  14305. this.executeTask(task);
  14306. }
  14307. this.onprogress(new ProgressEvent(STAGE_TASK_ENDED, { pageURL: this.options.url, step, task: task.action, frame }));
  14308. });
  14309. let parallelTasksPromise;
  14310. if (STAGES[step].parallel) {
  14311. parallelTasksPromise = await Promise.all(STAGES[step].parallel.map(async task => {
  14312. this.onprogress(new ProgressEvent(STAGE_TASK_STARTED, { pageURL: this.options.url, step, task: task.action, frame }));
  14313. if (!this.cancelled) {
  14314. await this.executeTask(task);
  14315. }
  14316. this.onprogress(new ProgressEvent(STAGE_TASK_ENDED, { pageURL: this.options.url, step, task: task.action, frame }));
  14317. }));
  14318. } else {
  14319. parallelTasksPromise = Promise.resolve();
  14320. }
  14321. this.onprogress(new ProgressEvent(STAGE_ENDED, { pageURL: this.options.url, step, frame }));
  14322. return parallelTasksPromise;
  14323. }
  14324. executeTask(task) {
  14325. if (!task.option || ((task.option.startsWith("!") && !this.options[task.option]) || this.options[task.option])) {
  14326. return this.processor[task.action]();
  14327. }
  14328. }
  14329. }
  14330. // ------------
  14331. // BatchRequest
  14332. // ------------
  14333. class BatchRequest {
  14334. constructor() {
  14335. this.requests = new Map$1();
  14336. this.duplicates = new Map$1();
  14337. }
  14338. addURL(resourceURL, { asBinary, expectedType, groupDuplicates, baseURI, blockMixedContent } = {}) {
  14339. return new Promise((resolve, reject) => {
  14340. const requestKey = JSON$1.stringify([resourceURL, asBinary, expectedType, baseURI, blockMixedContent]);
  14341. let resourceRequests = this.requests.get(requestKey);
  14342. if (!resourceRequests) {
  14343. resourceRequests = [];
  14344. this.requests.set(requestKey, resourceRequests);
  14345. }
  14346. const callbacks = { resolve, reject };
  14347. resourceRequests.push(callbacks);
  14348. if (groupDuplicates) {
  14349. let duplicateRequests = this.duplicates.get(requestKey);
  14350. if (!duplicateRequests) {
  14351. duplicateRequests = [];
  14352. this.duplicates.set(requestKey, duplicateRequests);
  14353. }
  14354. duplicateRequests.push(callbacks);
  14355. }
  14356. });
  14357. }
  14358. getMaxResources() {
  14359. return this.requests.size;
  14360. }
  14361. run(onloadListener, options) {
  14362. const resourceURLs = [...this.requests.keys()];
  14363. let indexResource = 0;
  14364. return Promise.all(resourceURLs.map(async requestKey => {
  14365. const [resourceURL, asBinary, expectedType, baseURI, blockMixedContent] = JSON$1.parse(requestKey);
  14366. const resourceRequests = this.requests.get(requestKey);
  14367. try {
  14368. const currentIndexResource = indexResource;
  14369. indexResource = indexResource + 1;
  14370. const content = await util.getContent(resourceURL, {
  14371. asBinary,
  14372. inline: !options.compressContent,
  14373. expectedType,
  14374. maxResourceSize: options.maxResourceSize,
  14375. maxResourceSizeEnabled: options.maxResourceSizeEnabled,
  14376. frameId: options.windowId,
  14377. resourceReferrer: options.resourceReferrer,
  14378. baseURI,
  14379. blockMixedContent,
  14380. acceptHeaders: options.acceptHeaders,
  14381. networkTimeout: options.networkTimeout
  14382. });
  14383. onloadListener({ url: resourceURL });
  14384. if (!this.cancelled) {
  14385. const extension = util.getContentTypeExtension(content.contentType) || util.getFilenameExtension(resourceURL, options.filenameReplacedCharacters, options.filenameReplacementCharacter);
  14386. resourceRequests.forEach(callbacks => {
  14387. const duplicateCallbacks = this.duplicates.get(requestKey);
  14388. const duplicate = duplicateCallbacks && duplicateCallbacks.length > 1 && duplicateCallbacks.includes(callbacks);
  14389. callbacks.resolve({ content: content.data, indexResource: currentIndexResource, duplicate, contentType: content.contentType, extension });
  14390. });
  14391. }
  14392. } catch (error) {
  14393. indexResource = indexResource + 1;
  14394. onloadListener({ url: resourceURL });
  14395. resourceRequests.forEach(resourceRequest => resourceRequest.reject(error));
  14396. }
  14397. this.requests.delete(requestKey);
  14398. }));
  14399. }
  14400. cancel() {
  14401. this.cancelled = true;
  14402. const resourceURLs = [...this.requests.keys()];
  14403. resourceURLs.forEach(requestKey => {
  14404. const resourceRequests = this.requests.get(requestKey);
  14405. resourceRequests.forEach(callbacks => callbacks.reject());
  14406. this.requests.delete(requestKey);
  14407. });
  14408. }
  14409. }
  14410. // ---------
  14411. // Processor
  14412. // ---------
  14413. const SHADOWROOT_ATTRIBUTE_NAME = "shadowrootmode";
  14414. const SCRIPT_TEMPLATE_SHADOW_ROOT = "data-template-shadow-root";
  14415. const UTF8_CHARSET = "utf-8";
  14416. class Processor {
  14417. constructor(options, processorHelper, batchRequest) {
  14418. this.options = options;
  14419. this.processorHelper = processorHelper;
  14420. this.stats = new Stats(options);
  14421. this.baseURI = normalizeURL(options.baseURI || options.url);
  14422. this.batchRequest = batchRequest;
  14423. this.stylesheets = new Map$1();
  14424. this.styles = new Map$1();
  14425. this.resources = {
  14426. cssVariables: new Map$1(),
  14427. fonts: new Map$1(),
  14428. stylesheets: new Map$1(),
  14429. scripts: new Map$1(),
  14430. images: new Map$1(),
  14431. frames: new Map$1()
  14432. };
  14433. this.fontTests = options.fontTests;
  14434. }
  14435. initialize() {
  14436. this.options.saveDate = new Date();
  14437. this.options.saveUrl = this.options.url;
  14438. if (this.options.enableMaff) {
  14439. this.maffMetaDataPromise = this.batchRequest.addURL(util.resolveURL("index.rdf", this.options.baseURI || this.options.url), { expectedType: "document" });
  14440. }
  14441. this.maxResources = this.batchRequest.getMaxResources();
  14442. if (!this.options.saveRawPage && !this.options.removeFrames && this.options.frames) {
  14443. this.options.frames.forEach(frameData => this.maxResources += frameData.maxResources || 0);
  14444. }
  14445. this.stats.set("processed", "resources", this.maxResources);
  14446. }
  14447. async loadPage(pageContent, charset) {
  14448. let content;
  14449. if (!pageContent || this.options.saveRawPage) {
  14450. content = await util.getContent(this.baseURI, {
  14451. inline: !this.options.compressContent,
  14452. maxResourceSize: this.options.maxResourceSize,
  14453. maxResourceSizeEnabled: this.options.maxResourceSizeEnabled,
  14454. charset,
  14455. frameId: this.options.windowId,
  14456. resourceReferrer: this.options.resourceReferrer,
  14457. expectedType: "document",
  14458. acceptHeaders: this.options.acceptHeaders,
  14459. networkTimeout: this.options.networkTimeout
  14460. });
  14461. pageContent = content.data || "";
  14462. }
  14463. this.doc = util.parseDocContent(pageContent, this.baseURI);
  14464. if (this.options.saveRawPage) {
  14465. let charset;
  14466. this.doc.querySelectorAll("meta[charset], meta[http-equiv=\"content-type\"]").forEach(element => {
  14467. const charsetDeclaration = element.content.split(";")[1];
  14468. if (charsetDeclaration && !charset) {
  14469. charset = charsetDeclaration.split("=")[1].trim().toLowerCase();
  14470. }
  14471. });
  14472. if (charset && content.charset && charset.toLowerCase() != content.charset.toLowerCase()) {
  14473. return this.loadPage(pageContent, charset);
  14474. }
  14475. }
  14476. this.workStyleElement = this.doc.createElement("style");
  14477. this.doc.body.appendChild(this.workStyleElement);
  14478. this.onEventAttributeNames = getOnEventAttributeNames(this.doc);
  14479. }
  14480. finalize() {
  14481. if (this.workStyleElement.parentNode) {
  14482. this.workStyleElement.remove();
  14483. }
  14484. }
  14485. async getPageData() {
  14486. util.postProcessDoc(this.doc);
  14487. const url = util.parseURL(this.baseURI);
  14488. if (this.options.insertSingleFileComment) {
  14489. const firstComment = this.doc.documentElement.firstChild;
  14490. let infobarURL = this.options.saveUrl, infobarSaveDate = this.options.saveDate;
  14491. if (firstComment.nodeType == 8 && (firstComment.textContent.includes(util.COMMENT_HEADER_LEGACY) || firstComment.textContent.includes(util.COMMENT_HEADER))) {
  14492. const info = this.doc.documentElement.firstChild.textContent.split("\n");
  14493. try {
  14494. const [, , url, saveDate] = info;
  14495. infobarURL = url.split("url: ")[1];
  14496. infobarSaveDate = saveDate.split("saved date: ")[1];
  14497. firstComment.remove();
  14498. } catch (error) {
  14499. // ignored
  14500. }
  14501. }
  14502. const infobarContent = (this.options.infobarContent || "").replace(/\\n/g, "\n").replace(/\\t/g, "\t");
  14503. const commentNode = this.doc.createComment(
  14504. "\n " + (this.options.useLegacyCommentHeader ? util.COMMENT_HEADER_LEGACY : util.COMMENT_HEADER) +
  14505. " \n url: " + infobarURL +
  14506. (this.options.removeSavedDate ? " " : " \n saved date: " + infobarSaveDate) +
  14507. (infobarContent ? " \n info: " + infobarContent : "") + "\n"
  14508. );
  14509. this.doc.documentElement.insertBefore(commentNode, this.doc.documentElement.firstChild);
  14510. }
  14511. const legacyInfobarElement = this.doc.querySelector("singlefile-infobar");
  14512. if (legacyInfobarElement) {
  14513. legacyInfobarElement.remove();
  14514. }
  14515. const infobarElement = this.doc.querySelector(util.INFOBAR_TAGNAME);
  14516. if (infobarElement) {
  14517. infobarElement.remove();
  14518. }
  14519. if (this.options.includeInfobar) {
  14520. util.appendInfobar(this.doc, this.options);
  14521. }
  14522. if (this.doc.querySelector("template[" + SHADOWROOT_ATTRIBUTE_NAME + "]") || (this.options.shadowRoots && this.options.shadowRoots.length)) {
  14523. if (this.options.blockScripts) {
  14524. this.doc.querySelectorAll("script[" + SCRIPT_TEMPLATE_SHADOW_ROOT + "]").forEach(element => element.remove());
  14525. }
  14526. const scriptElement = this.doc.createElement("script");
  14527. scriptElement.setAttribute(SCRIPT_TEMPLATE_SHADOW_ROOT, "");
  14528. scriptElement.textContent = `(()=>{document.currentScript.remove();processNode(document);function processNode(node){node.querySelectorAll("template[${SHADOWROOT_ATTRIBUTE_NAME}]").forEach(element=>{let shadowRoot = element.parentElement.shadowRoot;if (!shadowRoot) {try {shadowRoot=element.parentElement.attachShadow({mode:element.getAttribute("${SHADOWROOT_ATTRIBUTE_NAME}")});shadowRoot.innerHTML=element.innerHTML;element.remove()} catch (error) {} if (shadowRoot) {processNode(shadowRoot)}}})}})()`;
  14529. this.doc.body.appendChild(scriptElement);
  14530. }
  14531. if (this.options.insertCanonicalLink && this.options.saveUrl.match(HTTP_URI_PREFIX)) {
  14532. let canonicalLink = this.doc.querySelector("link[rel=canonical]");
  14533. if (!canonicalLink) {
  14534. canonicalLink = this.doc.createElement("link");
  14535. canonicalLink.setAttribute("rel", "canonical");
  14536. this.doc.head.appendChild(canonicalLink);
  14537. }
  14538. if (canonicalLink && !canonicalLink.href) {
  14539. canonicalLink.href = this.options.saveUrl;
  14540. }
  14541. }
  14542. if (this.options.insertMetaCSP) {
  14543. const metaElement = this.doc.createElement("meta");
  14544. metaElement.httpEquiv = "content-security-policy";
  14545. this.processorHelper.setMetaCSP(metaElement);
  14546. this.doc.head.appendChild(metaElement);
  14547. }
  14548. if (this.options.insertMetaNoIndex) {
  14549. let metaElement = this.doc.querySelector("meta[name=robots][content*=noindex]");
  14550. if (!metaElement) {
  14551. metaElement = this.doc.createElement("meta");
  14552. metaElement.setAttribute("name", "robots");
  14553. metaElement.setAttribute("content", "noindex");
  14554. this.doc.head.appendChild(metaElement);
  14555. }
  14556. }
  14557. const styleElement = this.doc.createElement("style");
  14558. styleElement.textContent = "img[src=\"data:,\"],source[src=\"data:,\"]{display:none!important}";
  14559. this.doc.head.appendChild(styleElement);
  14560. let size;
  14561. if (this.options.displayStats) {
  14562. size = util.getContentSize(this.doc.documentElement.outerHTML);
  14563. }
  14564. const content = util.serialize(this.doc, this.options.compressHTML);
  14565. if (this.options.displayStats) {
  14566. const contentSize = util.getContentSize(content);
  14567. this.stats.set("processed", "HTML bytes", contentSize);
  14568. this.stats.add("discarded", "HTML bytes", size - contentSize);
  14569. }
  14570. const filename = await util.formatFilename(content, this.options);
  14571. const matchTitle = this.baseURI.match(/([^/]*)\/?(\.html?.*)$/) || this.baseURI.match(/\/\/([^/]*)\/?$/);
  14572. const additionalData = this.processorHelper.getAdditionalPageData(this.doc, content, this.resources);
  14573. const pageData = Object.assign({
  14574. stats: this.stats.data,
  14575. title: this.options.title || (this.baseURI && matchTitle ? matchTitle[1] : url.hostname ? url.hostname : ""),
  14576. filename,
  14577. content
  14578. }, additionalData);
  14579. if (this.options.addProof) {
  14580. pageData.hash = await util.digest("SHA-256", content);
  14581. }
  14582. if (this.options.retrieveLinks) {
  14583. pageData.links = Array.from(new Set$1(Array.from(this.doc.links).map(linkElement => linkElement.href)));
  14584. }
  14585. return pageData;
  14586. }
  14587. preProcessPage() {
  14588. if (this.options.win) {
  14589. this.doc.body.querySelectorAll(":not(svg) title, meta, link[href][rel*=\"icon\"]").forEach(element => element instanceof this.options.win.HTMLElement && this.doc.head.appendChild(element));
  14590. }
  14591. if (this.options.images && !this.options.saveRawPage) {
  14592. this.doc.querySelectorAll("img[" + util.IMAGE_ATTRIBUTE_NAME + "]").forEach(imgElement => {
  14593. const attributeValue = imgElement.getAttribute(util.IMAGE_ATTRIBUTE_NAME);
  14594. if (attributeValue) {
  14595. const imageData = this.options.images[Number(attributeValue)];
  14596. if (imageData) {
  14597. if (this.options.removeHiddenElements && (
  14598. (imageData.size && !imageData.size.pxWidth && !imageData.size.pxHeight) ||
  14599. imgElement.getAttribute(util.HIDDEN_CONTENT_ATTRIBUTE_NAME) == "")
  14600. ) {
  14601. imgElement.setAttribute("src", util.EMPTY_RESOURCE);
  14602. } else {
  14603. if (imageData.currentSrc) {
  14604. imgElement.dataset.singleFileOriginURL = imgElement.getAttribute("src");
  14605. imgElement.setAttribute("src", imageData.currentSrc);
  14606. }
  14607. if (this.options.loadDeferredImages) {
  14608. if ((!imgElement.getAttribute("src") || imgElement.getAttribute("src") == util.EMPTY_RESOURCE) && imgElement.getAttribute("data-src")) {
  14609. imageData.src = imgElement.dataset.src;
  14610. imgElement.setAttribute("src", imgElement.dataset.src);
  14611. imgElement.removeAttribute("data-src");
  14612. }
  14613. }
  14614. }
  14615. }
  14616. }
  14617. });
  14618. if (this.options.loadDeferredImages) {
  14619. this.doc.querySelectorAll("img[data-srcset]").forEach(imgElement => {
  14620. if (!imgElement.getAttribute("srcset") && imgElement.getAttribute("data-srcset")) {
  14621. imgElement.setAttribute("srcset", imgElement.dataset.srcset);
  14622. imgElement.removeAttribute("data-srcset");
  14623. }
  14624. });
  14625. }
  14626. }
  14627. }
  14628. replaceStyleContents() {
  14629. if (this.options.stylesheets) {
  14630. this.doc.querySelectorAll("style").forEach((styleElement, styleIndex) => {
  14631. const attributeValue = styleElement.getAttribute(util.STYLESHEET_ATTRIBUTE_NAME);
  14632. if (attributeValue) {
  14633. const stylesheetContent = this.options.stylesheets[Number(styleIndex)];
  14634. if (stylesheetContent) {
  14635. styleElement.textContent = stylesheetContent;
  14636. }
  14637. }
  14638. });
  14639. }
  14640. if (this.options.adoptedStyleSheets && this.options.adoptedStyleSheets.length) {
  14641. const styleElement = this.doc.createElement("style");
  14642. styleElement.textContent = this.options.adoptedStyleSheets.join("\n");
  14643. this.doc.body.appendChild(styleElement);
  14644. }
  14645. }
  14646. removeUnselectedElements() {
  14647. removeUnmarkedElements(this.doc.body);
  14648. this.doc.body.removeAttribute(util.SELECTED_CONTENT_ATTRIBUTE_NAME);
  14649. function removeUnmarkedElements(element) {
  14650. let selectedElementFound = false;
  14651. Array.from(element.childNodes).forEach(node => {
  14652. if (node.nodeType == 1) {
  14653. const isSelectedElement = node.getAttribute(util.SELECTED_CONTENT_ATTRIBUTE_NAME) == "";
  14654. selectedElementFound = selectedElementFound || isSelectedElement;
  14655. if (isSelectedElement) {
  14656. node.removeAttribute(util.SELECTED_CONTENT_ATTRIBUTE_NAME);
  14657. removeUnmarkedElements(node);
  14658. } else if (selectedElementFound) {
  14659. removeNode(node);
  14660. } else {
  14661. hideNode(node);
  14662. }
  14663. }
  14664. });
  14665. }
  14666. function removeNode(node) {
  14667. if ((node.nodeType != 1 || !node.querySelector("svg,style,link")) && canHideNode(node)) {
  14668. node.remove();
  14669. } else {
  14670. hideNode(node);
  14671. }
  14672. }
  14673. function hideNode(node) {
  14674. if (canHideNode(node)) {
  14675. node.style.setProperty("display", "none", "important");
  14676. node.removeAttribute("src");
  14677. node.removeAttribute("srcset");
  14678. node.removeAttribute("srcdoc");
  14679. Array.from(node.childNodes).forEach(removeNode);
  14680. }
  14681. }
  14682. function canHideNode(node) {
  14683. if (node.nodeType == 1) {
  14684. const tagName = node.tagName && node.tagName.toUpperCase();
  14685. return tagName != "SVG" && tagName != "STYLE" && tagName != "LINK";
  14686. }
  14687. }
  14688. }
  14689. insertVideoPosters() {
  14690. if (this.options.posters) {
  14691. this.doc.querySelectorAll("video, video > source").forEach(element => {
  14692. let videoElement;
  14693. if (element.tagName.toUpperCase() == "VIDEO") {
  14694. videoElement = element;
  14695. } else {
  14696. videoElement = element.parentElement;
  14697. }
  14698. const attributeValue = element.getAttribute(util.POSTER_ATTRIBUTE_NAME);
  14699. if (attributeValue) {
  14700. const posterURL = this.options.posters[Number(attributeValue)];
  14701. if (!videoElement.getAttribute("poster") && posterURL) {
  14702. videoElement.setAttribute("poster", posterURL);
  14703. }
  14704. }
  14705. });
  14706. }
  14707. }
  14708. insertVideoLinks() {
  14709. const LINK_ICON = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAgMAAADXB5lNAAABhmlDQ1BJQ0MgcHJvZmlsZQAAKJF9kj1Iw0AYht+mSkUrDnYQcchQnSyIijqWKhbBQmkrtOpgcukfNGlIUlwcBdeCgz+LVQcXZ10dXAVB8AfEydFJ0UVK/C4ptIjx4LiH9+59+e67A4RGhalm1wSgapaRisfEbG5VDLyiDwEAvZiVmKkn0osZeI6ve/j4ehfhWd7n/hz9St5kgE8kjjLdsIg3iGc2LZ3zPnGIlSSF+Jx43KACiR+5Lrv8xrnosMAzQ0YmNU8cIhaLHSx3MCsZKvE0cVhRNcoXsi4rnLc4q5Uaa9XJbxjMaytprtMcQRxLSCAJETJqKKMCCxFaNVJMpGg/5uEfdvxJcsnkKoORYwFVqJAcP/gb/O6tWZiadJOCMaD7xbY/RoHALtCs2/b3sW03TwD/M3Cltf3VBjD3SXq9rYWPgIFt4OK6rcl7wOUOMPSkS4bkSH6aQqEAvJ/RM+WAwVv6EGtu31r7OH0AMtSr5Rvg4BAYK1L2use9ezr79u+ZVv9+AFlNcp0UUpiqAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAB3RJTUUH5AsHAB8H+DhhoQAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAAJUExURQAAAICHi4qKioTuJAkAAAABdFJOUwBA5thmAAAAAWJLR0QCZgt8ZAAAAJJJREFUOI3t070NRCEMA2CnYAOyDyPwpHj/Va7hJ3FzV7zy3ET5JIwoAF6Jk4wzAJAkzxAYG9YRTgB+24wBgKmfrGAKTcEfAY4KRlRoIeBTgKOCERVaCPgU4Khge2GqKOBTgKOCERVaAEC/4PNcnyoSWHpjqkhwKxbcig0Q6AorXYF/+A6eIYD1lVbwG/jdA6/kA2THRAURVubcAAAAAElFTkSuQmCC";
  14710. const ICON_SIZE = "16px";
  14711. this.doc.querySelectorAll("video").forEach(videoElement => {
  14712. const attributeValue = videoElement.getAttribute(util.VIDEO_ATTRIBUTE_NAME);
  14713. if (attributeValue) {
  14714. const videoData = this.options.videos[Number(attributeValue)];
  14715. const src = videoData.src || videoElement.src;
  14716. if (videoElement && src) {
  14717. const linkElement = this.doc.createElement("a");
  14718. const imgElement = this.doc.createElement("img");
  14719. linkElement.href = src;
  14720. linkElement.target = "_blank";
  14721. linkElement.style.setProperty("z-index", 2147483647, "important");
  14722. linkElement.style.setProperty("position", "absolute", "important");
  14723. linkElement.style.setProperty("top", "8px", "important");
  14724. linkElement.style.setProperty("left", "8px", "important");
  14725. linkElement.style.setProperty("width", ICON_SIZE, "important");
  14726. linkElement.style.setProperty("height", ICON_SIZE, "important");
  14727. linkElement.style.setProperty("min-width", ICON_SIZE, "important");
  14728. linkElement.style.setProperty("min-height", ICON_SIZE, "important");
  14729. linkElement.style.setProperty("max-width", ICON_SIZE, "important");
  14730. linkElement.style.setProperty("max-height", ICON_SIZE, "important");
  14731. imgElement.src = LINK_ICON;
  14732. imgElement.style.setProperty("width", ICON_SIZE, "important");
  14733. imgElement.style.setProperty("height", ICON_SIZE, "important");
  14734. imgElement.style.setProperty("min-width", ICON_SIZE, "important");
  14735. imgElement.style.setProperty("min-height", ICON_SIZE, "important");
  14736. imgElement.style.setProperty("max-width", ICON_SIZE, "important");
  14737. imgElement.style.setProperty("max-height", ICON_SIZE, "important");
  14738. linkElement.appendChild(imgElement);
  14739. videoElement.insertAdjacentElement("afterend", linkElement);
  14740. const positionInlineParent = videoElement.parentNode.style.getPropertyValue("position");
  14741. if ((!videoData.positionParent && (!positionInlineParent || positionInlineParent != "static")) || videoData.positionParent == "static") {
  14742. videoElement.parentNode.style.setProperty("position", "relative", "important");
  14743. }
  14744. }
  14745. }
  14746. });
  14747. }
  14748. removeFrames() {
  14749. const frameElements = this.doc.querySelectorAll("iframe, frame, object[type=\"text/html\"][data]");
  14750. this.stats.set("discarded", "frames", frameElements.length);
  14751. this.stats.set("processed", "frames", frameElements.length);
  14752. this.doc.querySelectorAll("iframe, frame, object[type=\"text/html\"][data]").forEach(element => element.remove());
  14753. }
  14754. removeEmbedScripts() {
  14755. const JAVASCRIPT_URI_PREFIX = "javascript:";
  14756. const DISABLED_SCRIPT = "javascript:void(0)";
  14757. this.onEventAttributeNames.forEach(attributeName => this.doc.querySelectorAll("[" + attributeName + "]").forEach(element => element.removeAttribute(attributeName)));
  14758. this.doc.querySelectorAll("[href]").forEach(element => {
  14759. if (element.href && element.href.match && element.href.trim().startsWith(JAVASCRIPT_URI_PREFIX)) {
  14760. element.setAttribute("href", DISABLED_SCRIPT);
  14761. }
  14762. });
  14763. this.doc.querySelectorAll("[src]").forEach(element => {
  14764. if (element.src && element.src.trim().startsWith(JAVASCRIPT_URI_PREFIX)) {
  14765. element.setAttribute("src", DISABLED_SCRIPT);
  14766. }
  14767. });
  14768. const scriptElements = this.doc.querySelectorAll("script:not([type=\"application/ld+json\"]):not([" + SCRIPT_TEMPLATE_SHADOW_ROOT + "])");
  14769. this.stats.set("discarded", "scripts", scriptElements.length);
  14770. this.stats.set("processed", "scripts", scriptElements.length);
  14771. scriptElements.forEach(element => element.remove());
  14772. }
  14773. removeDiscardedResources() {
  14774. this.doc.querySelectorAll("." + util.SINGLE_FILE_UI_ELEMENT_CLASS).forEach(element => element.remove());
  14775. const noscriptPlaceholders = new Map$1();
  14776. this.doc.querySelectorAll("noscript").forEach(noscriptElement => {
  14777. const placeholderElement = this.doc.createElement("div");
  14778. placeholderElement.innerHTML = noscriptElement.dataset[util.NO_SCRIPT_PROPERTY_NAME];
  14779. noscriptElement.replaceWith(placeholderElement);
  14780. noscriptPlaceholders.set(placeholderElement, noscriptElement);
  14781. });
  14782. this.doc.querySelectorAll("meta[http-equiv=refresh], meta[disabled-http-equiv]").forEach(element => element.remove());
  14783. noscriptPlaceholders.forEach((noscriptElement, placeholderElement) => {
  14784. noscriptElement.dataset[util.NO_SCRIPT_PROPERTY_NAME] = placeholderElement.innerHTML;
  14785. placeholderElement.replaceWith(noscriptElement);
  14786. });
  14787. this.doc.querySelectorAll("meta[http-equiv=\"content-security-policy\"]").forEach(element => element.remove());
  14788. const objectElements = this.doc.querySelectorAll("applet, object[data]:not([type=\"image/svg+xml\"]):not([type=\"image/svg-xml\"]):not([type=\"text/html\"]):not([data*=\".svg\"]):not([data*=\".pdf\"]), embed[src]:not([src*=\".svg\"]):not([src*=\".pdf\"])");
  14789. this.stats.set("discarded", "objects", objectElements.length);
  14790. this.stats.set("processed", "objects", objectElements.length);
  14791. objectElements.forEach(element => element.remove());
  14792. const replacedAttributeValue = this.doc.querySelectorAll("link[rel~=preconnect], link[rel~=prerender], link[rel~=dns-prefetch], link[rel~=preload], link[rel~=manifest], link[rel~=prefetch]");
  14793. replacedAttributeValue.forEach(element => {
  14794. const relValue = element
  14795. .getAttribute("rel")
  14796. .replace(/(preconnect|prerender|dns-prefetch|preload|prefetch|manifest)/g, "")
  14797. .trim();
  14798. if (relValue.length) {
  14799. element.setAttribute("rel", relValue);
  14800. } else {
  14801. element.remove();
  14802. }
  14803. });
  14804. this.processorHelper.removeUnusedStylesheets(this.doc);
  14805. this.doc.querySelectorAll("link[rel*=stylesheet]:not([href]),link[rel*=stylesheet][href=\"\"]").forEach(element => element.remove());
  14806. if (this.options.removeHiddenElements) {
  14807. this.doc.querySelectorAll("input[type=hidden]").forEach(element => element.remove());
  14808. }
  14809. if (!this.options.saveFavicon) {
  14810. this.doc.querySelectorAll("link[rel*=\"icon\"]").forEach(element => element.remove());
  14811. }
  14812. this.doc.querySelectorAll("a[ping]").forEach(element => element.removeAttribute("ping"));
  14813. this.doc.querySelectorAll("link[rel=import][href]").forEach(element => element.remove());
  14814. }
  14815. replaceInvalidElements() {
  14816. this.doc.querySelectorAll("template[" + util.INVALID_ELEMENT_ATTRIBUTE_NAME + "]").forEach(templateElement => {
  14817. const placeHolderElement = this.doc.createElement("span");
  14818. if (templateElement.content) {
  14819. const originalElement = templateElement.content.firstChild;
  14820. if (originalElement) {
  14821. if (originalElement.hasAttributes()) {
  14822. Array.from(originalElement.attributes).forEach(attribute => placeHolderElement.setAttribute(attribute.name, attribute.value));
  14823. }
  14824. originalElement.childNodes.forEach(childNode => placeHolderElement.appendChild(childNode.cloneNode(true)));
  14825. }
  14826. templateElement.replaceWith(placeHolderElement);
  14827. }
  14828. });
  14829. }
  14830. resetCharsetMeta() {
  14831. let charset;
  14832. this.doc.querySelectorAll("meta[charset], meta[http-equiv=\"content-type\"]").forEach(element => {
  14833. const charsetDeclaration = element.content.split(";")[1];
  14834. if (charsetDeclaration && !charset) {
  14835. charset = charsetDeclaration.split("=")[1];
  14836. if (charset) {
  14837. this.charset = charset.trim().toLowerCase();
  14838. }
  14839. }
  14840. element.remove();
  14841. });
  14842. const metaElement = this.doc.createElement("meta");
  14843. metaElement.setAttribute("charset", UTF8_CHARSET);
  14844. if (this.doc.head.firstChild) {
  14845. this.doc.head.insertBefore(metaElement, this.doc.head.firstChild);
  14846. } else {
  14847. this.doc.head.appendChild(metaElement);
  14848. }
  14849. }
  14850. setInputValues() {
  14851. this.doc.querySelectorAll("input:not([type=radio]):not([type=checkbox])").forEach(input => {
  14852. const value = input.getAttribute(util.INPUT_VALUE_ATTRIBUTE_NAME);
  14853. input.setAttribute("value", value || "");
  14854. });
  14855. this.doc.querySelectorAll("input[type=radio], input[type=checkbox]").forEach(input => {
  14856. const value = input.getAttribute(util.INPUT_VALUE_ATTRIBUTE_NAME);
  14857. if (value == "true") {
  14858. input.setAttribute("checked", "");
  14859. }
  14860. });
  14861. this.doc.querySelectorAll("textarea").forEach(textarea => {
  14862. const value = textarea.getAttribute(util.INPUT_VALUE_ATTRIBUTE_NAME);
  14863. textarea.textContent = value || "";
  14864. });
  14865. this.doc.querySelectorAll("select").forEach(select => {
  14866. select.querySelectorAll("option").forEach(option => {
  14867. const selected = option.getAttribute(util.INPUT_VALUE_ATTRIBUTE_NAME) != null;
  14868. if (selected) {
  14869. option.setAttribute("selected", "");
  14870. }
  14871. });
  14872. });
  14873. }
  14874. moveStylesInHead() {
  14875. this.doc.querySelectorAll("style").forEach(stylesheet => {
  14876. if (stylesheet.getAttribute(util.STYLE_ATTRIBUTE_NAME) == "") {
  14877. this.doc.head.appendChild(stylesheet);
  14878. }
  14879. });
  14880. }
  14881. saveFavicon() {
  14882. let faviconElement = this.doc.querySelector("link[href][rel=\"shortcut icon\"]");
  14883. if (!faviconElement) {
  14884. faviconElement = this.doc.querySelector("link[href][rel=\"icon\"]");
  14885. }
  14886. if (!faviconElement) {
  14887. faviconElement = this.doc.createElement("link");
  14888. faviconElement.setAttribute("type", "image/x-icon");
  14889. faviconElement.setAttribute("rel", "shortcut icon");
  14890. faviconElement.setAttribute("href", "/favicon.ico");
  14891. }
  14892. this.doc.head.appendChild(faviconElement);
  14893. }
  14894. saveScrollPosition() {
  14895. if (this.options.scrollPosition && this.options.scrolling == "no" && (this.options.scrollPosition.x || this.options.scrollPosition.y)) {
  14896. const scriptElement = this.doc.createElement("script");
  14897. scriptElement.textContent = "document.currentScript.remove();addEventListener(\"load\",()=>scrollTo(" + this.options.scrollPosition.x + "," + this.options.scrollPosition.y + "))";
  14898. this.doc.body.appendChild(scriptElement);
  14899. }
  14900. }
  14901. replaceCanvasElements() {
  14902. if (this.options.canvases) {
  14903. this.doc.querySelectorAll("canvas").forEach(canvasElement => {
  14904. const attributeValue = canvasElement.getAttribute(util.CANVAS_ATTRIBUTE_NAME);
  14905. if (attributeValue) {
  14906. const canvasData = this.options.canvases[Number(attributeValue)];
  14907. if (canvasData) {
  14908. const backgroundStyle = {};
  14909. if (canvasData.backgroundColor) {
  14910. backgroundStyle["background-color"] = canvasData.backgroundColor;
  14911. }
  14912. this.processorHelper.setBackgroundImage(canvasElement, "url(" + canvasData.dataURI + ")", backgroundStyle);
  14913. this.stats.add("processed", "canvas", 1);
  14914. }
  14915. }
  14916. });
  14917. }
  14918. }
  14919. insertFonts() {
  14920. if (this.options.fonts && this.options.fonts.length) {
  14921. let firstStylesheet = this.doc.querySelector("style, link[rel=stylesheet]"), previousStyleElement;
  14922. this.options.fonts.forEach(fontData => {
  14923. if (fontData["font-family"] && fontData.src) {
  14924. let stylesheetContent = "@font-face{";
  14925. let stylesContent = "";
  14926. Object.keys(fontData).forEach(fontStyle => {
  14927. if (stylesContent) {
  14928. stylesContent += ";";
  14929. }
  14930. stylesContent += fontStyle + ":" + fontData[fontStyle];
  14931. });
  14932. stylesheetContent += stylesContent + "}";
  14933. const styleElement = this.doc.createElement("style");
  14934. styleElement.textContent = stylesheetContent;
  14935. if (previousStyleElement) {
  14936. previousStyleElement.insertAdjacentElement("afterend", styleElement);
  14937. } else if (firstStylesheet) {
  14938. firstStylesheet.parentElement.insertBefore(styleElement, firstStylesheet);
  14939. } else {
  14940. this.doc.head.appendChild(styleElement);
  14941. }
  14942. previousStyleElement = styleElement;
  14943. }
  14944. });
  14945. }
  14946. }
  14947. removeHiddenElements() {
  14948. const hiddenElements = this.doc.querySelectorAll("[" + util.HIDDEN_CONTENT_ATTRIBUTE_NAME + "]");
  14949. const removedElements = this.doc.querySelectorAll("[" + util.REMOVED_CONTENT_ATTRIBUTE_NAME + "]");
  14950. this.stats.set("discarded", "hidden elements", removedElements.length);
  14951. this.stats.set("processed", "hidden elements", removedElements.length);
  14952. if (hiddenElements.length) {
  14953. const styleElement = this.doc.createElement("style");
  14954. styleElement.textContent = ".sf-hidden{display:none!important;}";
  14955. this.doc.head.appendChild(styleElement);
  14956. hiddenElements.forEach(element => {
  14957. if (element.style.getPropertyValue("display") != "none") {
  14958. if (element.style.getPropertyPriority("display") == "important") {
  14959. element.style.setProperty("display", "none", "important");
  14960. } else {
  14961. element.classList.add("sf-hidden");
  14962. }
  14963. }
  14964. });
  14965. }
  14966. removedElements.forEach(element => element.remove());
  14967. }
  14968. resolveHrefs() {
  14969. this.doc.querySelectorAll("a[href], area[href], link[href]").forEach(element => {
  14970. const href = element.getAttribute("href").trim();
  14971. if (element.tagName.toUpperCase() == "LINK" && element.rel.includes("stylesheet")) {
  14972. if (this.options.saveOriginalURLs && !isDataURL(href)) {
  14973. element.setAttribute("data-sf-original-href", href);
  14974. }
  14975. }
  14976. if (!testIgnoredPath(href)) {
  14977. let resolvedURL;
  14978. try {
  14979. resolvedURL = util.resolveURL(href, this.options.baseURI || this.options.url);
  14980. } catch (error) {
  14981. // ignored
  14982. }
  14983. if (resolvedURL) {
  14984. const url = normalizeURL(this.options.url);
  14985. if (resolvedURL.startsWith(url + "#") && !resolvedURL.startsWith(url + "#!") && !this.options.resolveFragmentIdentifierURLs) {
  14986. resolvedURL = resolvedURL.substring(url.length);
  14987. }
  14988. try {
  14989. element.setAttribute("href", resolvedURL);
  14990. } catch (error) {
  14991. // ignored
  14992. }
  14993. }
  14994. }
  14995. });
  14996. }
  14997. async insertMissingVideoPosters() {
  14998. await Promise.all(Array.from(this.doc.querySelectorAll("video[src], video > source[src]")).map(async element => {
  14999. let videoElement;
  15000. if (element.tagName.toUpperCase() == "VIDEO") {
  15001. videoElement = element;
  15002. } else {
  15003. videoElement = element.parentElement;
  15004. }
  15005. if (!videoElement.poster) {
  15006. const attributeValue = videoElement.getAttribute(util.VIDEO_ATTRIBUTE_NAME);
  15007. if (attributeValue) {
  15008. const videoData = this.options.videos[Number(attributeValue)];
  15009. const src = videoData.src || videoElement.src;
  15010. if (src) {
  15011. const temporaryVideoElement = this.doc.createElement("video");
  15012. temporaryVideoElement.src = src;
  15013. temporaryVideoElement.style.setProperty("width", videoData.size.pxWidth + "px", "important");
  15014. temporaryVideoElement.style.setProperty("height", videoData.size.pxHeight + "px", "important");
  15015. temporaryVideoElement.style.setProperty("display", "none", "important");
  15016. temporaryVideoElement.crossOrigin = "anonymous";
  15017. const canvasElement = this.doc.createElement("canvas");
  15018. const context = canvasElement.getContext("2d");
  15019. this.options.doc.body.appendChild(temporaryVideoElement);
  15020. return new Promise(resolve => {
  15021. temporaryVideoElement.currentTime = videoData.currentTime;
  15022. temporaryVideoElement.oncanplay = () => {
  15023. canvasElement.width = videoData.size.pxWidth;
  15024. canvasElement.height = videoData.size.pxHeight;
  15025. context.drawImage(temporaryVideoElement, 0, 0, canvasElement.width, canvasElement.height);
  15026. try {
  15027. videoElement.poster = canvasElement.toDataURL("image/png", "");
  15028. } catch (error) {
  15029. // ignored
  15030. }
  15031. temporaryVideoElement.remove();
  15032. resolve();
  15033. };
  15034. temporaryVideoElement.onerror = () => {
  15035. temporaryVideoElement.remove();
  15036. resolve();
  15037. };
  15038. });
  15039. }
  15040. }
  15041. }
  15042. }));
  15043. }
  15044. resolveStyleAttributeURLs() {
  15045. this.doc.querySelectorAll("[style]").forEach(element => {
  15046. if (this.options.blockStylesheets) {
  15047. element.removeAttribute("style");
  15048. } else {
  15049. const styleContent = element.getAttribute("style");
  15050. const declarationList = db(styleContent, { context: "declarationList", parseCustomProperty: true });
  15051. this.processorHelper.resolveStylesheetURLs(declarationList, this.baseURI, this.workStyleElement);
  15052. this.styles.set(element, declarationList);
  15053. }
  15054. });
  15055. }
  15056. async resolveStylesheetsURLs() {
  15057. await Promise.all(Array.from(this.doc.querySelectorAll("style, link[rel*=stylesheet]")).map(async element => {
  15058. const options = Object.assign({}, this.options, { charset: this.charset });
  15059. let mediaText;
  15060. if (element.media) {
  15061. mediaText = element.media.toLowerCase();
  15062. }
  15063. const scoped = Boolean(element.closest("[" + SHADOWROOT_ATTRIBUTE_NAME + "]"));
  15064. const stylesheetInfo = {
  15065. mediaText,
  15066. scoped
  15067. };
  15068. await this.processorHelper.processLinkElement(element, stylesheetInfo, this.stylesheets, this.baseURI, options, this.workStyleElement, this.resources);
  15069. }));
  15070. if (this.options.rootDocument) {
  15071. const newResources = Object.keys(this.options.updatedResources)
  15072. .filter(url => this.options.updatedResources[url].type == "stylesheet" && !this.options.updatedResources[url].retrieved)
  15073. .map(url => this.options.updatedResources[url]);
  15074. await Promise.all(newResources.map(async resource => {
  15075. resource.retrieved = true;
  15076. if (!this.options.blockStylesheets) {
  15077. const stylesheetInfo = {};
  15078. const element = this.doc.createElement("style");
  15079. this.doc.body.appendChild(element);
  15080. element.textContent = resource.content;
  15081. await this.processorHelper.processStylesheetElement(element, stylesheetInfo, this.stylesheets, this.baseURI, this.options, this.workStyleElement, this.resources);
  15082. }
  15083. }));
  15084. }
  15085. }
  15086. async resolveFrameURLs() {
  15087. const processorHelper = this.processorHelper;
  15088. if (!this.options.saveRawPage) {
  15089. const frameElements = Array.from(this.doc.querySelectorAll("iframe, frame, object[type=\"text/html\"][data]"));
  15090. await Promise.all(frameElements.map(async frameElement => {
  15091. if (frameElement.tagName.toUpperCase() == "OBJECT") {
  15092. frameElement.setAttribute("data", "data:text/html,");
  15093. } else {
  15094. const src = frameElement.getAttribute("src");
  15095. if (this.options.saveOriginalURLs && src && !isDataURL(src)) {
  15096. frameElement.setAttribute("data-sf-original-src", src);
  15097. }
  15098. frameElement.removeAttribute("src");
  15099. frameElement.removeAttribute("srcdoc");
  15100. }
  15101. Array.from(frameElement.childNodes).forEach(node => node.remove());
  15102. const frameWindowId = frameElement.getAttribute(util.WIN_ID_ATTRIBUTE_NAME);
  15103. if (this.options.frames && frameWindowId) {
  15104. const frameData = this.options.frames.find(frame => frame.windowId == frameWindowId);
  15105. if (frameData) {
  15106. await initializeProcessor(frameData, frameElement, frameWindowId, this.batchRequest, Object.create(this.options));
  15107. }
  15108. }
  15109. }));
  15110. }
  15111. async function initializeProcessor(frameData, frameElement, frameWindowId, batchRequest, options) {
  15112. options.insertSingleFileComment = false;
  15113. options.insertCanonicalLink = false;
  15114. options.insertMetaNoIndex = false;
  15115. options.saveFavicon = false;
  15116. options.includeInfobar = false;
  15117. options.url = frameData.baseURI;
  15118. options.windowId = frameWindowId;
  15119. if (frameData.content) {
  15120. options.content = frameData.content;
  15121. options.canvases = frameData.canvases;
  15122. options.fonts = frameData.fonts;
  15123. options.stylesheets = frameData.stylesheets;
  15124. options.images = frameData.images;
  15125. options.posters = frameData.posters;
  15126. options.videos = frameData.videos;
  15127. options.usedFonts = frameData.usedFonts;
  15128. options.shadowRoots = frameData.shadowRoots;
  15129. options.scrollPosition = frameData.scrollPosition;
  15130. options.scrolling = frameData.scrolling;
  15131. options.adoptedStyleSheets = frameData.adoptedStyleSheets;
  15132. frameData.runner = new Runner(options, processorHelper);
  15133. frameData.frameElement = frameElement;
  15134. await frameData.runner.loadPage();
  15135. await frameData.runner.initialize();
  15136. frameData.maxResources = batchRequest.getMaxResources();
  15137. }
  15138. }
  15139. }
  15140. insertShadowRootContents() {
  15141. const doc = this.doc;
  15142. const options = this.options;
  15143. if (options.shadowRoots && options.shadowRoots.length) {
  15144. processElement(this.doc);
  15145. }
  15146. function processElement(element) {
  15147. const shadowRootElements = Array.from(element.querySelectorAll("[" + util.SHADOW_ROOT_ATTRIBUTE_NAME + "]"));
  15148. shadowRootElements.forEach(element => {
  15149. const attributeValue = element.getAttribute(util.SHADOW_ROOT_ATTRIBUTE_NAME);
  15150. if (attributeValue) {
  15151. const shadowRootData = options.shadowRoots[Number(attributeValue)];
  15152. if (shadowRootData) {
  15153. const templateElement = doc.createElement("template");
  15154. templateElement.setAttribute(SHADOWROOT_ATTRIBUTE_NAME, shadowRootData.mode);
  15155. if (shadowRootData.adoptedStyleSheets && shadowRootData.adoptedStyleSheets.length) {
  15156. shadowRootData.adoptedStyleSheets.forEach(stylesheetContent => {
  15157. const styleElement = doc.createElement("style");
  15158. styleElement.textContent = stylesheetContent;
  15159. templateElement.appendChild(styleElement);
  15160. });
  15161. }
  15162. const shadowDoc = util.parseDocContent(shadowRootData.content);
  15163. if (shadowDoc.head) {
  15164. const metaCharset = shadowDoc.head.querySelector("meta[charset]");
  15165. if (metaCharset) {
  15166. metaCharset.remove();
  15167. }
  15168. shadowDoc.head.childNodes.forEach(node => templateElement.appendChild(shadowDoc.importNode(node, true)));
  15169. }
  15170. if (shadowDoc.body) {
  15171. shadowDoc.body.childNodes.forEach(node => templateElement.appendChild(shadowDoc.importNode(node, true)));
  15172. }
  15173. processElement(templateElement);
  15174. if (element.firstChild) {
  15175. element.insertBefore(templateElement, element.firstChild);
  15176. } else {
  15177. element.appendChild(templateElement);
  15178. }
  15179. }
  15180. }
  15181. });
  15182. }
  15183. }
  15184. removeUnusedStyles() {
  15185. if (!this.mediaAllInfo) {
  15186. this.mediaAllInfo = util.getMediaAllInfo(this.doc, this.stylesheets, this.styles);
  15187. }
  15188. const stats = util.minifyCSSRules(this.stylesheets, this.styles, this.mediaAllInfo);
  15189. this.stats.set("processed", "CSS rules", stats.processed);
  15190. this.stats.set("discarded", "CSS rules", stats.discarded);
  15191. }
  15192. removeUnusedFonts() {
  15193. util.removeUnusedFonts(this.doc, this.stylesheets, this.styles, this.options);
  15194. }
  15195. removeAlternativeMedias() {
  15196. const stats = util.minifyMedias(this.stylesheets);
  15197. this.stats.set("processed", "medias", stats.processed);
  15198. this.stats.set("discarded", "medias", stats.discarded);
  15199. }
  15200. async processStylesheets() {
  15201. await Promise.all([...this.stylesheets].map(([, stylesheetInfo]) =>
  15202. this.processorHelper.processStylesheet(stylesheetInfo.stylesheet.children, this.baseURI, this.options, this.resources, this.batchRequest)
  15203. ));
  15204. }
  15205. async processStyleAttributes() {
  15206. return Promise.all([...this.styles].map(([, stylesheet]) =>
  15207. this.processorHelper.processStyle(stylesheet, this.options, this.resources, this.batchRequest)
  15208. ));
  15209. }
  15210. async processPageResources() {
  15211. await this.processorHelper.processPageResources(this.doc, this.baseURI, this.options, this.resources, this.styles, this.batchRequest);
  15212. }
  15213. async processScripts() {
  15214. await Promise.all(Array.from(this.doc.querySelectorAll("script[src]")).map(async element => {
  15215. let resourceURL;
  15216. let scriptSrc;
  15217. scriptSrc = element.getAttribute("src");
  15218. if (this.options.saveOriginalURLs && !isDataURL(scriptSrc)) {
  15219. element.setAttribute("data-sf-original-src", scriptSrc);
  15220. }
  15221. element.removeAttribute("integrity");
  15222. if (!this.options.blockScripts) {
  15223. element.textContent = "";
  15224. try {
  15225. resourceURL = util.resolveURL(scriptSrc, this.baseURI);
  15226. } catch (error) {
  15227. // ignored
  15228. }
  15229. if (testValidURL(resourceURL)) {
  15230. element.removeAttribute("src");
  15231. await this.processorHelper.processScript(element, resourceURL);
  15232. if (element.getAttribute("async") == "async" || element.getAttribute(util.ASYNC_SCRIPT_ATTRIBUTE_NAME) == "") {
  15233. element.setAttribute("async", "");
  15234. }
  15235. }
  15236. } else {
  15237. element.removeAttribute("src");
  15238. }
  15239. this.stats.add("processed", "scripts", 1);
  15240. }));
  15241. }
  15242. removeAlternativeImages() {
  15243. util.removeAlternativeImages(this.doc);
  15244. }
  15245. async removeAlternativeFonts() {
  15246. await this.processorHelper.removeAlternativeFonts(this.doc, this.stylesheets, this.resources.fonts, this.options.fontTests);
  15247. }
  15248. async processFrames() {
  15249. if (this.options.frames) {
  15250. const frameElements = Array.from(this.doc.querySelectorAll("iframe, frame, object[type=\"text/html\"][data]"));
  15251. await Promise.all(frameElements.map(async frameElement => {
  15252. const frameWindowId = frameElement.getAttribute(util.WIN_ID_ATTRIBUTE_NAME);
  15253. if (frameWindowId) {
  15254. const frameData = this.options.frames.find(frame => frame.windowId == frameWindowId);
  15255. if (frameData) {
  15256. this.options.frames = this.options.frames.filter(frame => frame.windowId != frameWindowId);
  15257. if (frameData.runner && frameElement.getAttribute(util.HIDDEN_FRAME_ATTRIBUTE_NAME) != "") {
  15258. this.stats.add("processed", "frames", 1);
  15259. await frameData.runner.run();
  15260. const pageData = await frameData.runner.getPageData();
  15261. frameElement.removeAttribute(util.WIN_ID_ATTRIBUTE_NAME);
  15262. this.processorHelper.processFrame(frameElement, pageData, this.resources, frameWindowId, frameData);
  15263. this.stats.addAll(pageData);
  15264. } else {
  15265. frameElement.removeAttribute(util.WIN_ID_ATTRIBUTE_NAME);
  15266. this.stats.add("discarded", "frames", 1);
  15267. }
  15268. }
  15269. }
  15270. }));
  15271. }
  15272. }
  15273. replaceStylesheets() {
  15274. this.processorHelper.replaceStylesheets(this.doc, this.stylesheets, this.resources, this.options);
  15275. }
  15276. replaceStyleAttributes() {
  15277. this.doc.querySelectorAll("[style]").forEach(element => {
  15278. const declarationList = this.styles.get(element);
  15279. if (declarationList) {
  15280. this.styles.delete(element);
  15281. element.setAttribute("style", this.processorHelper.generateStylesheetContent(declarationList, this.options));
  15282. } else {
  15283. element.setAttribute("style", "");
  15284. }
  15285. });
  15286. }
  15287. insertVariables() {
  15288. const { cssVariables } = this.resources;
  15289. if (cssVariables.size) {
  15290. const styleElement = this.doc.createElement("style");
  15291. const firstStyleElement = this.doc.head.querySelector("style");
  15292. if (firstStyleElement) {
  15293. this.doc.head.insertBefore(styleElement, firstStyleElement);
  15294. } else {
  15295. this.doc.head.appendChild(styleElement);
  15296. }
  15297. let stylesheetContent = "";
  15298. cssVariables.forEach(({ content, url }, indexResource) => {
  15299. cssVariables.delete(indexResource);
  15300. if (stylesheetContent) {
  15301. stylesheetContent += ";";
  15302. }
  15303. stylesheetContent += `${SINGLE_FILE_VARIABLE_NAME_PREFIX + indexResource}: `;
  15304. if (this.options.saveOriginalURLs) {
  15305. stylesheetContent += `/* original URL: ${url} */ `;
  15306. }
  15307. stylesheetContent += `url("${content}")`;
  15308. });
  15309. styleElement.textContent = ":root{" + stylesheetContent + "}";
  15310. }
  15311. }
  15312. compressHTML() {
  15313. let size;
  15314. if (this.options.displayStats) {
  15315. size = util.getContentSize(this.doc.documentElement.outerHTML);
  15316. }
  15317. util.minifyHTML(this.doc, { PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME: util.PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME });
  15318. if (this.options.displayStats) {
  15319. this.stats.add("discarded", "HTML bytes", size - util.getContentSize(this.doc.documentElement.outerHTML));
  15320. }
  15321. }
  15322. cleanupPage() {
  15323. this.doc.querySelectorAll("base").forEach(element => element.remove());
  15324. const metaCharset = this.doc.head.querySelector("meta[charset]");
  15325. if (metaCharset) {
  15326. this.doc.head.insertBefore(metaCharset, this.doc.head.firstChild);
  15327. if (this.doc.head.querySelectorAll("*").length == 1 && this.doc.body.childNodes.length == 0) {
  15328. this.doc.head.querySelector("meta[charset]").remove();
  15329. }
  15330. }
  15331. }
  15332. resetZoomLevel() {
  15333. const transform = this.doc.documentElement.style.getPropertyValue("-sf-transform");
  15334. const transformPriority = this.doc.documentElement.style.getPropertyPriority("-sf-transform");
  15335. const transformOrigin = this.doc.documentElement.style.getPropertyValue("-sf-transform-origin");
  15336. const transformOriginPriority = this.doc.documentElement.style.getPropertyPriority("-sf-transform-origin");
  15337. const minHeight = this.doc.documentElement.style.getPropertyValue("-sf-min-height");
  15338. const minHeightPriority = this.doc.documentElement.style.getPropertyPriority("-sf-min-height");
  15339. this.doc.documentElement.style.setProperty("transform", transform, transformPriority);
  15340. this.doc.documentElement.style.setProperty("transform-origin", transformOrigin, transformOriginPriority);
  15341. this.doc.documentElement.style.setProperty("min-height", minHeight, minHeightPriority);
  15342. this.doc.documentElement.style.removeProperty("-sf-transform");
  15343. this.doc.documentElement.style.removeProperty("-sf-transform-origin");
  15344. this.doc.documentElement.style.removeProperty("-sf-min-height");
  15345. }
  15346. async insertMAFFMetaData() {
  15347. const maffMetaData = await this.maffMetaDataPromise;
  15348. if (maffMetaData && maffMetaData.content) {
  15349. const NAMESPACE_RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
  15350. const maffDoc = util.parseXMLContent(maffMetaData.content);
  15351. const originalURLElement = maffDoc.querySelector("RDF > Description > originalurl");
  15352. const archiveTimeElement = maffDoc.querySelector("RDF > Description > archivetime");
  15353. if (originalURLElement) {
  15354. this.options.saveUrl = originalURLElement.getAttributeNS(NAMESPACE_RDF, "resource");
  15355. }
  15356. if (archiveTimeElement) {
  15357. const value = archiveTimeElement.getAttributeNS(NAMESPACE_RDF, "resource");
  15358. if (value) {
  15359. const date = new Date(value);
  15360. if (!isNaN(date.getTime())) {
  15361. this.options.saveDate = new Date(value);
  15362. }
  15363. }
  15364. }
  15365. }
  15366. }
  15367. async setDocInfo() {
  15368. const titleElement = this.doc.querySelector("title");
  15369. const descriptionElement = this.doc.querySelector("meta[name=description]");
  15370. const authorElement = this.doc.querySelector("meta[name=author]");
  15371. const creatorElement = this.doc.querySelector("meta[name=creator]");
  15372. const publisherElement = this.doc.querySelector("meta[name=publisher]");
  15373. const headingElement = this.doc.querySelector("h1");
  15374. this.options.title = titleElement ? titleElement.textContent.trim() : "";
  15375. this.options.info = {
  15376. description: descriptionElement && descriptionElement.content ? descriptionElement.content.trim() : "",
  15377. lang: this.doc.documentElement.lang,
  15378. author: authorElement && authorElement.content ? authorElement.content.trim() : "",
  15379. creator: creatorElement && creatorElement.content ? creatorElement.content.trim() : "",
  15380. publisher: publisherElement && publisherElement.content ? publisherElement.content.trim() : "",
  15381. heading: headingElement && headingElement.textContent ? headingElement.textContent.trim() : ""
  15382. };
  15383. this.options.infobarContent = await util.evalTemplate(this.options.infobarTemplate, this.options, null, true);
  15384. }
  15385. }
  15386. // ----
  15387. // Util
  15388. // ----
  15389. const DATA_URI_PREFIX = "data:";
  15390. const ABOUT_BLANK_URI = "about:blank";
  15391. const BLOB_URI_PREFIX = "blob:";
  15392. const HTTP_URI_PREFIX = /^https?:\/\//;
  15393. const FILE_URI_PREFIX = /^file:\/\//;
  15394. const EMPTY_URL = /^https?:\/\/+\s*$/;
  15395. const NOT_EMPTY_URL = /^(https?:\/\/|file:\/\/|blob:).+/;
  15396. const SINGLE_FILE_VARIABLE_NAME_PREFIX = "--sf-img-";
  15397. function normalizeURL(url) {
  15398. if (!url || url.startsWith(DATA_URI_PREFIX)) {
  15399. return url;
  15400. } else {
  15401. return url.split("#")[0];
  15402. }
  15403. }
  15404. function getOnEventAttributeNames(doc) {
  15405. const element = doc.createElement("div");
  15406. const attributeNames = [];
  15407. for (const propertyName in element) {
  15408. if (propertyName.startsWith("on")) {
  15409. attributeNames.push(propertyName);
  15410. }
  15411. }
  15412. attributeNames.push("onunload");
  15413. return attributeNames;
  15414. }
  15415. function isDataURL(url) {
  15416. return url && (url.startsWith(DATA_URI_PREFIX) || url.startsWith(BLOB_URI_PREFIX));
  15417. }
  15418. function testIgnoredPath(resourceURL) {
  15419. return resourceURL && (resourceURL.startsWith(DATA_URI_PREFIX) || resourceURL == ABOUT_BLANK_URI);
  15420. }
  15421. function testValidPath(resourceURL) {
  15422. return resourceURL && !resourceURL.match(EMPTY_URL);
  15423. }
  15424. function testValidURL(resourceURL) {
  15425. return testValidPath(resourceURL) && (resourceURL.match(HTTP_URI_PREFIX) || resourceURL.match(FILE_URI_PREFIX) || resourceURL.startsWith(BLOB_URI_PREFIX)) && resourceURL.match(NOT_EMPTY_URL);
  15426. }
  15427. // -----
  15428. // Stats
  15429. // -----
  15430. const STATS_DEFAULT_VALUES = {
  15431. discarded: {
  15432. "HTML bytes": 0,
  15433. "hidden elements": 0,
  15434. scripts: 0,
  15435. objects: 0,
  15436. "audio sources": 0,
  15437. "video sources": 0,
  15438. frames: 0,
  15439. "CSS rules": 0,
  15440. canvas: 0,
  15441. stylesheets: 0,
  15442. resources: 0,
  15443. medias: 0
  15444. },
  15445. processed: {
  15446. "HTML bytes": 0,
  15447. "hidden elements": 0,
  15448. scripts: 0,
  15449. objects: 0,
  15450. "audio sources": 0,
  15451. "video sources": 0,
  15452. frames: 0,
  15453. "CSS rules": 0,
  15454. canvas: 0,
  15455. stylesheets: 0,
  15456. resources: 0,
  15457. medias: 0
  15458. }
  15459. };
  15460. class Stats {
  15461. constructor(options) {
  15462. this.options = options;
  15463. if (options.displayStats) {
  15464. this.data = JSON$1.parse(JSON$1.stringify(STATS_DEFAULT_VALUES));
  15465. }
  15466. }
  15467. set(type, subType, value) {
  15468. if (this.options.displayStats) {
  15469. this.data[type][subType] = value;
  15470. }
  15471. }
  15472. add(type, subType, value) {
  15473. if (this.options.displayStats) {
  15474. this.data[type][subType] += value;
  15475. }
  15476. }
  15477. addAll(pageData) {
  15478. if (this.options.displayStats) {
  15479. Object.keys(this.data.discarded).forEach(key => this.add("discarded", key, pageData.stats.discarded[key] || 0));
  15480. Object.keys(this.data.processed).forEach(key => this.add("processed", key, pageData.stats.processed[key] || 0));
  15481. }
  15482. }
  15483. }
  15484. /*
  15485. * Copyright 2010-2022 Gildas Lormeau
  15486. * contact : gildas.lormeau <at> gmail.com
  15487. *
  15488. * This file is part of SingleFile.
  15489. *
  15490. * The code in this file is free software: you can redistribute it and/or
  15491. * modify it under the terms of the GNU Affero General Public License
  15492. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  15493. * of the License, or (at your option) any later version.
  15494. *
  15495. * The code in this file is distributed in the hope that it will be useful,
  15496. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15497. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  15498. * General Public License for more details.
  15499. *
  15500. * As additional permission under GNU AGPL version 3 section 7, you may
  15501. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  15502. * AGPL normally required by section 4, provided you include this license
  15503. * notice and a URL through which recipients can access the Corresponding
  15504. * Source.
  15505. */
  15506. const DEBUG = false;
  15507. const ONE_MB = 1024 * 1024;
  15508. const PREFIX_CONTENT_TYPE_TEXT = "text/";
  15509. const DEFAULT_REPLACED_CHARACTERS = ["~", "+", "\\\\", "?", "%", "*", ":", "|", "\"", "<", ">", "\x00-\x1f", "\x7F"];
  15510. const DEFAULT_REPLACEMENT_CHARACTER = "_";
  15511. const CONTENT_TYPE_EXTENSIONS = {
  15512. "image/svg+xml": ".svg",
  15513. "image/png": ".png",
  15514. "image/jpeg": ".jpg",
  15515. "image/gif": ".gif",
  15516. "image/webp": ".webp"
  15517. };
  15518. const URL$1 = globalThis.URL;
  15519. const DOMParser$1 = globalThis.DOMParser;
  15520. const Blob$1 = globalThis.Blob;
  15521. const FileReader$1 = globalThis.FileReader;
  15522. const fetch$1 = (url, options) => globalThis.fetch(url, options);
  15523. const crypto = globalThis.crypto;
  15524. const TextDecoder$1 = globalThis.TextDecoder;
  15525. const TextEncoder = globalThis.TextEncoder;
  15526. function getInstance(utilOptions) {
  15527. utilOptions = utilOptions || {};
  15528. utilOptions.fetch = utilOptions.fetch || fetch$1;
  15529. utilOptions.frameFetch = utilOptions.frameFetch || utilOptions.fetch || fetch$1;
  15530. return {
  15531. getDoctypeString,
  15532. getFilenameExtension(resourceURL, replacedCharacters, replacementCharacter) {
  15533. const matchExtension = new URL$1(resourceURL).pathname.match(/(\.[^\\/.]*)$/);
  15534. return ((matchExtension && matchExtension[1] && this.getValidFilename(matchExtension[1], replacedCharacters, replacementCharacter)) || "").toLowerCase();
  15535. },
  15536. getContentTypeExtension(contentType) {
  15537. return CONTENT_TYPE_EXTENSIONS[contentType] || "";
  15538. },
  15539. getContent,
  15540. parseURL(resourceURL, baseURI) {
  15541. if (baseURI === undefined) {
  15542. return new URL$1(resourceURL);
  15543. } else {
  15544. return new URL$1(resourceURL, baseURI);
  15545. }
  15546. },
  15547. resolveURL(resourceURL, baseURI) {
  15548. return this.parseURL(resourceURL, baseURI).href;
  15549. },
  15550. getSearchParams(searchParams) {
  15551. return Array.from(new URLSearchParams(searchParams));
  15552. },
  15553. getValidFilename(filename, replacedCharacters = DEFAULT_REPLACED_CHARACTERS, replacementCharacter = DEFAULT_REPLACEMENT_CHARACTER) {
  15554. replacedCharacters.forEach(replacedCharacter => filename = filename.replace(new RegExp("[" + replacedCharacter + "]+", "g"), replacementCharacter));
  15555. filename = filename
  15556. .replace(/\.\.\//g, "")
  15557. .replace(/^\/+/, "")
  15558. .replace(/\/+/g, "/")
  15559. .replace(/\/$/, "")
  15560. .replace(/\.$/, "")
  15561. .replace(/\.\//g, "." + replacementCharacter)
  15562. .replace(/\/\./g, "/" + replacementCharacter);
  15563. return filename;
  15564. },
  15565. parseDocContent(content, baseURI) {
  15566. const doc = (new DOMParser$1()).parseFromString(content, "text/html");
  15567. if (!doc.head) {
  15568. doc.documentElement.insertBefore(doc.createElement("HEAD"), doc.body);
  15569. }
  15570. let baseElement = doc.querySelector("base");
  15571. if (!baseElement || !baseElement.getAttribute("href")) {
  15572. if (baseElement) {
  15573. baseElement.remove();
  15574. }
  15575. baseElement = doc.createElement("base");
  15576. baseElement.setAttribute("href", baseURI);
  15577. doc.head.insertBefore(baseElement, doc.head.firstChild);
  15578. }
  15579. return doc;
  15580. },
  15581. parseXMLContent(content) {
  15582. return (new DOMParser$1()).parseFromString(content, "text/xml");
  15583. },
  15584. parseSVGContent(content) {
  15585. const doc = (new DOMParser$1()).parseFromString(content, "image/svg+xml");
  15586. if (doc.querySelector("parsererror")) {
  15587. return (new DOMParser$1()).parseFromString(content, "text/html");
  15588. } else {
  15589. return doc;
  15590. }
  15591. },
  15592. async digest(algo, text) {
  15593. try {
  15594. const hash = await crypto.subtle.digest(algo, new TextEncoder("utf-8").encode(text));
  15595. return hex(hash);
  15596. } catch (error) {
  15597. return "";
  15598. }
  15599. },
  15600. getContentSize(content) {
  15601. return new Blob$1([content]).size;
  15602. },
  15603. formatFilename(content, options) {
  15604. return formatFilename(content, options, this);
  15605. },
  15606. evalTemplate(template, options, content, dontReplaceSlash) {
  15607. return evalTemplate(template, options, this, content, dontReplaceSlash);
  15608. },
  15609. minifyHTML(doc, options) {
  15610. return process$1(doc, options);
  15611. },
  15612. minifyCSSRules(stylesheets, styles, mediaAllInfo) {
  15613. return process$3(stylesheets, styles, mediaAllInfo);
  15614. },
  15615. removeUnusedFonts(doc, stylesheets, styles, options) {
  15616. return process$5(doc, stylesheets, styles, options);
  15617. },
  15618. getMediaAllInfo(doc, stylesheets, styles) {
  15619. return getMediaAllInfo(doc, stylesheets, styles);
  15620. },
  15621. compressCSS(content, options) {
  15622. return processString(content, options);
  15623. },
  15624. minifyMedias(stylesheets) {
  15625. return process$4(stylesheets);
  15626. },
  15627. removeAlternativeImages(doc) {
  15628. return process$2(doc);
  15629. },
  15630. parseSrcset(srcset) {
  15631. return process$6(srcset);
  15632. },
  15633. preProcessDoc(doc, win, options) {
  15634. return preProcessDoc(doc, win, options);
  15635. },
  15636. postProcessDoc(doc, markedElements, invalidElements) {
  15637. postProcessDoc(doc, markedElements, invalidElements);
  15638. },
  15639. serialize(doc, compressHTML) {
  15640. return process(doc, compressHTML);
  15641. },
  15642. removeQuotes(string) {
  15643. return removeQuotes$1(string);
  15644. },
  15645. appendInfobar(doc, options) {
  15646. return appendInfobar(doc, options);
  15647. },
  15648. ON_BEFORE_CAPTURE_EVENT_NAME: ON_BEFORE_CAPTURE_EVENT_NAME,
  15649. ON_AFTER_CAPTURE_EVENT_NAME: ON_AFTER_CAPTURE_EVENT_NAME,
  15650. WIN_ID_ATTRIBUTE_NAME: WIN_ID_ATTRIBUTE_NAME,
  15651. REMOVED_CONTENT_ATTRIBUTE_NAME: REMOVED_CONTENT_ATTRIBUTE_NAME,
  15652. HIDDEN_CONTENT_ATTRIBUTE_NAME: HIDDEN_CONTENT_ATTRIBUTE_NAME,
  15653. HIDDEN_FRAME_ATTRIBUTE_NAME: HIDDEN_FRAME_ATTRIBUTE_NAME,
  15654. IMAGE_ATTRIBUTE_NAME: IMAGE_ATTRIBUTE_NAME,
  15655. POSTER_ATTRIBUTE_NAME: POSTER_ATTRIBUTE_NAME,
  15656. VIDEO_ATTRIBUTE_NAME: VIDEO_ATTRIBUTE_NAME,
  15657. CANVAS_ATTRIBUTE_NAME: CANVAS_ATTRIBUTE_NAME,
  15658. STYLE_ATTRIBUTE_NAME: STYLE_ATTRIBUTE_NAME,
  15659. INPUT_VALUE_ATTRIBUTE_NAME: INPUT_VALUE_ATTRIBUTE_NAME,
  15660. SHADOW_ROOT_ATTRIBUTE_NAME: SHADOW_ROOT_ATTRIBUTE_NAME,
  15661. PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME: PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME,
  15662. STYLESHEET_ATTRIBUTE_NAME: STYLESHEET_ATTRIBUTE_NAME,
  15663. SELECTED_CONTENT_ATTRIBUTE_NAME: SELECTED_CONTENT_ATTRIBUTE_NAME,
  15664. INVALID_ELEMENT_ATTRIBUTE_NAME: INVALID_ELEMENT_ATTRIBUTE_NAME,
  15665. COMMENT_HEADER: COMMENT_HEADER,
  15666. COMMENT_HEADER_LEGACY: COMMENT_HEADER_LEGACY,
  15667. SINGLE_FILE_UI_ELEMENT_CLASS: SINGLE_FILE_UI_ELEMENT_CLASS,
  15668. EMPTY_RESOURCE: EMPTY_RESOURCE$1,
  15669. INFOBAR_TAGNAME: INFOBAR_TAGNAME,
  15670. WAIT_FOR_USERSCRIPT_PROPERTY_NAME: WAIT_FOR_USERSCRIPT_PROPERTY_NAME,
  15671. NO_SCRIPT_PROPERTY_NAME: NO_SCRIPT_PROPERTY_NAME
  15672. };
  15673. async function getContent(resourceURL, options) {
  15674. let response, startTime, networkTimeoutId, networkTimeoutPromise, resolveNetworkTimeoutPromise;
  15675. const fetchResource = utilOptions.fetch;
  15676. const fetchFrameResource = utilOptions.frameFetch;
  15677. if (options.blockMixedContent && /^https:/i.test(options.baseURI) && !/^https:/i.test(resourceURL)) {
  15678. return getFetchResponse(resourceURL, options);
  15679. }
  15680. if (options.networkTimeout) {
  15681. networkTimeoutPromise = new Promise((resolve, reject) => {
  15682. resolveNetworkTimeoutPromise = resolve;
  15683. networkTimeoutId = globalThis.setTimeout(() => reject(new Error("network timeout")), options.networkTimeout);
  15684. });
  15685. } else {
  15686. networkTimeoutPromise = new Promise(resolve => {
  15687. resolveNetworkTimeoutPromise = resolve;
  15688. });
  15689. }
  15690. try {
  15691. const accept = options.acceptHeaders ? options.acceptHeaders[options.expectedType] : "*/*";
  15692. if (options.frameId) {
  15693. try {
  15694. response = await Promise.race([
  15695. fetchFrameResource(resourceURL, { frameId: options.frameId, referrer: options.resourceReferrer, headers: { accept } }),
  15696. networkTimeoutPromise
  15697. ]);
  15698. } catch (error) {
  15699. response = await Promise.race([
  15700. fetchResource(resourceURL, { headers: { accept } }),
  15701. networkTimeoutPromise
  15702. ]);
  15703. }
  15704. } else {
  15705. response = await Promise.race([
  15706. fetchResource(resourceURL, { referrer: options.resourceReferrer, headers: { accept } }),
  15707. networkTimeoutPromise
  15708. ]);
  15709. }
  15710. } catch (error) {
  15711. return getFetchResponse(resourceURL, options);
  15712. } finally {
  15713. resolveNetworkTimeoutPromise();
  15714. if (options.networkTimeout) {
  15715. globalThis.clearTimeout(networkTimeoutId);
  15716. }
  15717. }
  15718. let buffer;
  15719. try {
  15720. buffer = await response.arrayBuffer();
  15721. } catch (error) {
  15722. return options.inline ? { data: options.asBinary ? EMPTY_RESOURCE$1 : "", resourceURL } : { resourceURL };
  15723. }
  15724. resourceURL = response.url || resourceURL;
  15725. let contentType = "", charset;
  15726. try {
  15727. const mimeType = new MIMEType(response.headers.get("content-type"));
  15728. contentType = mimeType.type + "/" + mimeType.subtype;
  15729. charset = mimeType.parameters.get("charset");
  15730. } catch (error) {
  15731. // ignored
  15732. }
  15733. if (!contentType) {
  15734. contentType = guessMIMEType(options.expectedType, buffer);
  15735. }
  15736. if (!charset && options.charset) {
  15737. charset = options.charset;
  15738. }
  15739. if (options.asBinary) {
  15740. if (response.status >= 400) {
  15741. return getFetchResponse(resourceURL, options);
  15742. }
  15743. try {
  15744. if (DEBUG) ;
  15745. if (options.maxResourceSizeEnabled && buffer.byteLength > options.maxResourceSize * ONE_MB) {
  15746. return getFetchResponse(resourceURL, options);
  15747. } else {
  15748. return getFetchResponse(resourceURL, options, buffer, null, contentType);
  15749. }
  15750. } catch (error) {
  15751. return getFetchResponse(resourceURL, options);
  15752. }
  15753. } else {
  15754. if (response.status >= 400 || (options.validateTextContentType && contentType && !contentType.startsWith(PREFIX_CONTENT_TYPE_TEXT))) {
  15755. return getFetchResponse(resourceURL, options);
  15756. }
  15757. if (!charset) {
  15758. charset = "utf-8";
  15759. }
  15760. if (options.maxResourceSizeEnabled && buffer.byteLength > options.maxResourceSize * ONE_MB) {
  15761. return getFetchResponse(resourceURL, options, null, charset);
  15762. } else {
  15763. try {
  15764. return getFetchResponse(resourceURL, options, buffer, charset, contentType);
  15765. } catch (error) {
  15766. return getFetchResponse(resourceURL, options, null, charset);
  15767. }
  15768. }
  15769. }
  15770. }
  15771. }
  15772. async function getFetchResponse(resourceURL, options, data, charset, contentType) {
  15773. if (data) {
  15774. if (options.asBinary) {
  15775. if (options.inline) {
  15776. const reader = new FileReader$1();
  15777. reader.readAsDataURL(new Blob$1([data], { type: contentType + (options.charset ? ";charset=" + options.charset : "") }));
  15778. data = await new Promise((resolve, reject) => {
  15779. reader.addEventListener("load", () => resolve(reader.result), false);
  15780. reader.addEventListener("error", reject, false);
  15781. });
  15782. } else {
  15783. data = new Uint8Array(data);
  15784. }
  15785. } else {
  15786. const firstBytes = new Uint8Array(data.slice(0, 4));
  15787. if (firstBytes[0] == 132 && firstBytes[1] == 49 && firstBytes[2] == 149 && firstBytes[3] == 51) {
  15788. charset = "gb18030";
  15789. } else if (firstBytes[0] == 255 && firstBytes[1] == 254) {
  15790. charset = "utf-16le";
  15791. } else if (firstBytes[0] == 254 && firstBytes[1] == 255) {
  15792. charset = "utf-16be";
  15793. }
  15794. try {
  15795. data = new TextDecoder$1(charset).decode(data);
  15796. } catch (error) {
  15797. charset = "utf-8";
  15798. data = new TextDecoder$1(charset).decode(data);
  15799. }
  15800. data = data.replace(/\ufeff/gi, "");
  15801. }
  15802. } else if (options.inline) {
  15803. data = options.asBinary ? EMPTY_RESOURCE$1 : "";
  15804. }
  15805. return { data, resourceURL, charset, contentType };
  15806. }
  15807. function guessMIMEType(expectedType, buffer) {
  15808. if (expectedType == "image") {
  15809. if (compareBytes([255, 255, 255, 255], [0, 0, 1, 0])) {
  15810. return "image/x-icon";
  15811. }
  15812. if (compareBytes([255, 255, 255, 255], [0, 0, 2, 0])) {
  15813. return "image/x-icon";
  15814. }
  15815. if (compareBytes([255, 255], [78, 77])) {
  15816. return "image/bmp";
  15817. }
  15818. if (compareBytes([255, 255, 255, 255, 255, 255], [71, 73, 70, 56, 57, 97])) {
  15819. return "image/gif";
  15820. }
  15821. if (compareBytes([255, 255, 255, 255, 255, 255], [71, 73, 70, 56, 59, 97])) {
  15822. return "image/gif";
  15823. }
  15824. if (compareBytes([255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255], [82, 73, 70, 70, 0, 0, 0, 0, 87, 69, 66, 80, 86, 80])) {
  15825. return "image/webp";
  15826. }
  15827. if (compareBytes([255, 255, 255, 255, 255, 255, 255, 255], [137, 80, 78, 71, 13, 10, 26, 10])) {
  15828. return "image/png";
  15829. }
  15830. if (compareBytes([255, 255, 255], [255, 216, 255])) {
  15831. return "image/jpeg";
  15832. }
  15833. }
  15834. if (expectedType == "font") {
  15835. if (compareBytes([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255],
  15836. [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 80])) {
  15837. return "application/vnd.ms-fontobject";
  15838. }
  15839. if (compareBytes([255, 255, 255, 255], [0, 1, 0, 0])) {
  15840. return "font/ttf";
  15841. }
  15842. if (compareBytes([255, 255, 255, 255], [79, 84, 84, 79])) {
  15843. return "font/otf";
  15844. }
  15845. if (compareBytes([255, 255, 255, 255], [116, 116, 99, 102])) {
  15846. return "font/collection";
  15847. }
  15848. if (compareBytes([255, 255, 255, 255], [119, 79, 70, 70])) {
  15849. return "font/woff";
  15850. }
  15851. if (compareBytes([255, 255, 255, 255], [119, 79, 70, 50])) {
  15852. return "font/woff2";
  15853. }
  15854. }
  15855. function compareBytes(mask, pattern) {
  15856. let patternMatch = true, index = 0;
  15857. if (buffer.byteLength >= pattern.length) {
  15858. const value = new Uint8Array(buffer, 0, mask.length);
  15859. for (index = 0; index < mask.length && patternMatch; index++) {
  15860. patternMatch = patternMatch && ((value[index] & mask[index]) == pattern[index]);
  15861. }
  15862. return patternMatch;
  15863. }
  15864. }
  15865. }
  15866. // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest
  15867. function hex(buffer) {
  15868. const hexCodes = [];
  15869. const view = new DataView(buffer);
  15870. for (let i = 0; i < view.byteLength; i += 4) {
  15871. const value = view.getUint32(i);
  15872. const stringValue = value.toString(16);
  15873. const padding = "00000000";
  15874. const paddedValue = (padding + stringValue).slice(-padding.length);
  15875. hexCodes.push(paddedValue);
  15876. }
  15877. return hexCodes.join("");
  15878. }
  15879. function getDoctypeString(doc) {
  15880. const docType = doc.doctype;
  15881. let docTypeString = "";
  15882. if (docType) {
  15883. docTypeString = "<!DOCTYPE " + docType.nodeName;
  15884. if (docType.publicId) {
  15885. docTypeString += " PUBLIC \"" + docType.publicId + "\"";
  15886. if (docType.systemId)
  15887. docTypeString += " \"" + docType.systemId + "\"";
  15888. } else if (docType.systemId)
  15889. docTypeString += " SYSTEM \"" + docType.systemId + "\"";
  15890. if (docType.internalSubset)
  15891. docTypeString += " [" + docType.internalSubset + "]";
  15892. docTypeString += "> ";
  15893. }
  15894. return docTypeString;
  15895. }
  15896. function log(...args) {
  15897. console.log("S-File <browser>", ...args); // eslint-disable-line no-console
  15898. }
  15899. /*
  15900. * Copyright 2010-2022 Gildas Lormeau
  15901. * contact : gildas.lormeau <at> gmail.com
  15902. *
  15903. * This file is part of SingleFile.
  15904. *
  15905. * The code in this file is free software: you can redistribute it and/or
  15906. * modify it under the terms of the GNU Affero General Public License
  15907. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  15908. * of the License, or (at your option) any later version.
  15909. *
  15910. * The code in this file is distributed in the hope that it will be useful,
  15911. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15912. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  15913. * General Public License for more details.
  15914. *
  15915. * As additional permission under GNU AGPL version 3 section 7, you may
  15916. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  15917. * AGPL normally required by section 4, provided you include this license
  15918. * notice and a URL through which recipients can access the Corresponding
  15919. * Source.
  15920. */
  15921. exports.SingleFile = void 0;
  15922. function init(initOptions) {
  15923. if (typeof exports.SingleFile == "undefined") {
  15924. exports.SingleFile = getClass(getInstance(initOptions));
  15925. }
  15926. }
  15927. async function getPageData(options = {}, initOptions, doc = globalThis.document, win = globalThis) {
  15928. const frames = contentFrameTree;
  15929. let framesSessionId;
  15930. init(initOptions);
  15931. if (doc && win) {
  15932. initDoc(doc);
  15933. const preInitializationPromises = [];
  15934. if (!options.saveRawPage) {
  15935. let lazyLoadPromise;
  15936. if (options.loadDeferredImages) {
  15937. lazyLoadPromise = process$7(options);
  15938. if (options.loadDeferredImagesBeforeFrames) {
  15939. await lazyLoadPromise;
  15940. }
  15941. }
  15942. if (!options.removeFrames && frames && globalThis.frames) {
  15943. let frameTreePromise;
  15944. if (options.loadDeferredImages) {
  15945. frameTreePromise = new Promise(resolve => globalThis.setTimeout(() => resolve(frames.getAsync(options)), options.loadDeferredImagesBeforeFrames || !options.loadDeferredImages ? 0 : options.loadDeferredImagesMaxIdleTime));
  15946. } else {
  15947. frameTreePromise = frames.getAsync(options);
  15948. }
  15949. if (options.loadDeferredImagesBeforeFrames) {
  15950. options.frames = await frameTreePromise;
  15951. } else {
  15952. preInitializationPromises.push(frameTreePromise);
  15953. }
  15954. }
  15955. if (options.loadDeferredImages && !options.loadDeferredImagesBeforeFrames) {
  15956. preInitializationPromises.push(lazyLoadPromise);
  15957. }
  15958. }
  15959. if (!options.loadDeferredImagesBeforeFrames) {
  15960. [options.frames] = await Promise.all(preInitializationPromises);
  15961. }
  15962. framesSessionId = options.frames && options.frames.sessionId;
  15963. }
  15964. options.doc = doc;
  15965. options.win = win;
  15966. options.insertCanonicalLink = true;
  15967. options.onprogress = event => {
  15968. if (event.type === event.RESOURCES_INITIALIZED && doc && win && options.loadDeferredImages) {
  15969. resetZoomLevel(options);
  15970. }
  15971. };
  15972. const processor = new exports.SingleFile(options);
  15973. await processor.run();
  15974. if (framesSessionId) {
  15975. frames.cleanup(framesSessionId);
  15976. }
  15977. const pageData = await processor.getPageData();
  15978. if (options.compressContent) {
  15979. const blob = await process$9(pageData, {
  15980. insertTextBody: options.insertTextBody,
  15981. url: options.url,
  15982. createRootDirectory: options.createRootDirectory,
  15983. selfExtractingArchive: options.selfExtractingArchive,
  15984. extractDataFromPage: options.extractDataFromPage,
  15985. insertCanonicalLink: options.insertCanonicalLink,
  15986. insertMetaNoIndex: options.insertMetaNoIndex,
  15987. password: options.password,
  15988. zipScript: options.zipScript
  15989. });
  15990. delete pageData.resources;
  15991. const reader = new globalThis.FileReader();
  15992. reader.readAsArrayBuffer(blob);
  15993. const arrayBuffer = await new Promise((resolve, reject) => {
  15994. reader.addEventListener("load", () => resolve(reader.result), false);
  15995. reader.addEventListener("error", event => reject(event.detail.error), false);
  15996. });
  15997. pageData.content = Array.from(new Uint8Array(arrayBuffer));
  15998. }
  15999. return pageData;
  16000. }
  16001. exports.getPageData = getPageData;
  16002. exports.helper = helper$4;
  16003. exports.init = init;
  16004. exports.modules = index;
  16005. exports.processors = index$2;
  16006. exports.vendor = index$1;
  16007. Object.defineProperty(exports, '__esModule', { value: true });
  16008. }));