ÿØÿà JFIF    ÿÛ „  ( %"1!%)+...383,7(-.+  -+++--++++---+-+-----+---------------+---+-++7-----ÿÀ  ß â" ÿÄ     ÿÄ H    !1AQaq"‘¡2B±ÁÑð#R“Ò Tbr‚²á3csƒ’ÂñDS¢³$CÿÄ   ÿÄ %  !1AQa"23‘ÿÚ   ? ôÿ ¨pŸªáÿ —åYõõ\?àÒü©ŠÄï¨pŸªáÿ —åYõõ\?àÓü©ŠÄá 0Ÿªáÿ Ÿå[úƒ ú®ði~TÁbqÐ8OÕpÿ ƒOò¤Oè`–RÂáœá™êi€ßÉ< FtŸI“öÌ8úDf´°å}“¾œ6  öFá°y¥jñÇh†ˆ¢ã/ÃÐ:ªcÈ "Y¡ðÑl>ÿ ”ÏËte:qž\oäŠe÷󲍷˜HT4&ÿ ÓÐü6ö®¿øþßèô Ÿ•7Ñi’•j|“ñì>b…þS?*Óôÿ ÓÐü*h¥£ír¶ü UãS炟[AÐaè[ûª•õ&õj?†Éö+EzP—WeÒírJFt ‘BŒ†Ï‡%#tE Øz ¥OÛ«!1›üä±Í™%ºÍãö]°î(–:@<‹ŒÊö×òÆt¦ãº+‡¦%ÌÁ²h´OƒJŒtMÜ>ÀÜÊw3Y´•牋4ǍýʏTì>œú=Íwhyë,¾Ôò×õ¿ßÊa»«þˆѪQ|%6ž™A õ%:øj<>É—ÿ Å_ˆCbõ¥š±ý¯Ýƒï…¶|RëócÍf溪“t.СøTÿ *Ä¿-{†çàczůŽ_–^XþŒ±miB[X±d 1,é”zEù»& î9gœf™9Ð'.;—™i}!ôšåîqêÛ٤ёý£½ÆA–àôe"A$˝Úsäÿ ÷Û #°xŸëí(l »ý3—¥5m! rt`†0~'j2(]S¦¦kv,ÚÇ l¦øJA£Šƒ J3E8ÙiŽ:cÉžúeZ°€¯\®kÖ(79«Ž:¯X”¾³Š&¡* ….‰Ž(ÜíŸ2¥ª‡×Hi²TF¤ò[¨íÈRëÉ䢍mgÑ.Ÿ<öäS0í„ǹÁU´f#Vß;Õ–…P@3ío<ä-±»Ž.L|kªÀê›fÂ6@»eu‚|ÓaÞÆŸ…¨ááå>åŠ?cKü6ùTÍÆ”†sĤÚ;H2RÚ†õ\Ö·Ÿn'¾ ñ#ºI¤Å´%çÁ­‚â7›‹qT3Iï¨ÖÚ5I7Ë!ÅOóŸ¶øÝñØôת¦$Tcö‘[«Ö³šÒ';Aþ ¸èíg A2Z"i¸vdÄ÷.iõ®§)¿]¤À†–‡É&ä{V¶iŽ”.Ó×Õÿ û?h¬Mt–íª[ÿ Ñÿ ÌV(í}=ibÔ¡›¥¢±b Lô¥‡piη_Z<‡z§èŒ)iÖwiÇ 2hÙ3·=’d÷8éŽ1¦¸c¤µ€7›7Ø ð\á)} ¹fËí›pAÃL%âc2 í§æQz¿;T8sæ°qø)QFMð‰XŒÂ±N¢aF¨…8¯!U  Z©RÊ ÖPVÄÀÍin™Ì-GˆªÅËŠ›•zË}º±ŽÍFò¹}Uw×#ä5B¤{î}Ð<ÙD é©¤&‡ïDbàÁôMÁ." ¤‡ú*õ'VŽ|¼´Úgllº¼klz[Æüï÷Aób‡Eÿ dÑ»Xx9ÃÜ£ÁT/`¼¸vI±Ýµ·Ë‚“G³þ*Ÿû´r|*}<¨îºœ @¦mÄ’M¹”.œ«Y–|6ÏU¤jç¥ÕÞqO ˜kDÆÁ¨5ÿ š;ÐЦ¦€GÙk \ –Þ=â¼=SͧµªS°ÚÍpÜãQűÀõ¬?ÃÁ1Ñ•õZà?hóœ€ L¦l{Y*K˜Ù›zc˜–ˆâ ø+¾ ­-Ök¥%ùEÜA'}ˆ><ÊIè“bpÍ/qÞâvoX€w,\úªò6Z[XdÒæ­@Ö—€$òJí#é>'°Ú ôª˜<)4ryÙ£|óAÅn5žêŸyÒäMÝ2{"}‰–¤l÷ûWX\l¾Á¸góÉOÔ /óñB¤f¸çñ[.P˜ZsÊË*ßT܈§QN¢’¡¨§V¼(Üù*eÕ“”5T¨‹Âê¥FŒã½Dü[8'Ò¥a…Ú¶k7a *•›¼'Ò·\8¨ª\@\õ¢¦íq+DÙrmÎ…_ªæ»ŠÓœ¡¯’Ré9MÅ×D™lælffc+ŒÑ,ý™ÿ ¯þǤ=Å’Á7µ÷ÚÛ/“Ü€ñýã¼àí¾ÕÑ+ƒ,uµMâÀÄbm:ÒÎPæ{˜Gz[ƒ¯«® KHà`ߨŠéí¯P8Aq.C‰ à€kòpj´kN¶qô€…Õ,ÜNŠª-­{Zö’æû44‰sŽè‰îVíRœÕm" 6?³D9¡ÇTíÅꋇ`4«¸ÝÁô ï’ýorqКÇZ«x4Žâéþuïf¹µö[P ,Q£éaX±`PÉÍZ ¸äYúg üAx ’6Lê‚xÝÓ*äQ  Ï’¨hÍ =²,6ï#rÃ<¯–£»ƒ‹,–ê•€ aÛsñ'%Æ"®ÛüìBᝠHÚ3ß°©$“XnœÖ’î2ËTeûìxîß ¦å¿çÉ ðK§þ{‘t‚Ϋ¬jéîZ[ ”š7L¥4VÚCE×]m¤Øy”ä4-dz£œ§¸x.*ãÊÊ b÷•h:©‡¦s`BTÁRû¾g⻩‹jø sF¢àJøFl‘È•Xᓁà~*j¯ +(ÚÕ6-£¯÷GŠØy‚<Ç’.F‹Hœw(+)ÜÜâÈzÄäT§FߘãÏ;DmVœ3Àu@mÚüXÝü•3B¨òÌÁÛ<·ÃÜ z,Ì@õÅ·d2]ü8s÷IôÞ¯^Ç9¢u„~ëAŸï4«M? K]­ÅàPl@s_ p:°¬ZR”´›JC[CS.h‹ƒïËœ«Æ]–÷ó‚wR×k7X‰k›‘´ù¦=¡«‰¨¨Â')—71ó’c‡Ðúµ `é.{§p¹ój\Ž{1h{o±Ý=áUÊïGÖŒõ–-BÄm+AZX¶¡ ïHðæ¥JmÙ;…䡟ˆ¦ ° äšiÉg«$üMk5¤L“’çÊvïâï ,=f“"íἊ5ô¬x6{ɏžID0e¸vçmi'︧ºð9$ò¹÷*£’9ÿ ²TÔ…×>JV¥}Œ}$p[bÔ®*[jzS*8 ”·T›Í–ñUîƒwo$áè=LT™ç—~ô·¤ÈÚ$榍q‰„+´kFm)ž‹©i–ËqÞŠ‰à¶ü( ‚•§ •°ò·‡#5ª•µÊ﯅¡X¨šÁ*F#TXJÊ ušJVÍ&=iÄs1‚3•'fý§5Ñ<=[íÞ­ PÚ;ѱÌ_~Ä££8rÞ ²w;’hDT°>ÈG¬8Á²ÚzŽ®ò®qZcqJêäÞ-ö[ܘbň±çb“ж31²n×iƒðÕ;1¶þÉ ªX‰,ßqÏ$>•î íZ¥Z 1{ç൵+ƒÕµ¥°T$§K]á»Ûï*·¤tMI’ÂZbŽÕiÒ˜}bÓ0£ª5›¨ [5Ž^ÝœWøÂÝh° ¢OWun£¤5 a2Z.G2³YL]jåtì”ä ÁÓ‘%"©<Ôúʰsº UZvä‡ÄiÆÒM .÷V·™ø#kèýiíÌ–ª)µT[)BˆõÑ xB¾B€ÖT¨.¥~ð@VĶr#¸ü*åZNDŽH;âi ],©£öØpù(šºãö¼T.uCê•4@ÿ GÕÛ)Cx›®0ø#:ÏðFÒbR\(€€Ä®fã4Þ‰Fä¯HXƒÅ,†öEÑÔÜ]Öv²?tLÃvBY£ú6Êu5ÅAQ³1‘’¬x–HŒÐ‡ ^ ¸KwJôÖŽ5×CÚ¨vÜ«/B0$×k°=ðbÇ(Ï)w±A†Á† 11Í=èQšµ626ŒÜ/`G«µ<}—-Ö7KEHÈÉðóȤmݱû±·ø«Snmá=“䫚mݱŸ¡¶~ó·“äUóJæúòB|E LêŽy´jDÔ$G¢þÐñ7óR8ýÒ…Ç› WVe#·Ÿ p·Fx~•ݤF÷0Èÿ K¯æS<6’¡WШ; ´ÿ ¥Êø\Òuî†åÝ–VNœkÒ7oòX¨Á­Ø÷FÎÑä±g÷ÿ M~Çî=p,X´ ÝÌÚÅ‹’ÃjÖ.ØöÏñ qïQ¤ÓZE†° =6·]܈ s¸>v•Ž^Ý\wq9r‰Î\¸¡kURÒ$­*‹Nq?Þª*!sŠÆ:TU_u±T+øX¡ ®¹¡,ÄâÃBTsÜ$Ø›4m椴zÜK]’’›Pƒ @€#â˜`é¹=I‡fiV•Ôî“nRm+µFPOhÍ0B£ €+¬5c v•:P'ÒyÎ ‰V~‚Ó†ÖuókDoh$å\*ö%Ю=£«…aȼ½÷Û.-½VŒŠ¼'lyî±1¬3ó#ÞE¿ÔS¤gV£m›=§\û"—WU¤ÚǼÿ ÂnÁGŒÃ ‚õN D³õNÚíŒÕ;HôyÄÈ©P¹Ä{:?R‘Ô¨âF÷ø£bÅó® JS|‚R÷ivýáâ€Æé¡è³´IئÑT!§˜•ت‚¬â@q€wnïCWÄ@JU€ê¯m6]Ï:£âx'+ÒðXvÓ¦Úm=–´7œ $ì“B£~p%ÕŸUþ« N@¼üï~w˜ñø5®—'Ôe»¤5ã//€ž~‰Tþ›Å7•#¤× Íö pÄ$ùeåì*«ÓŠEØWEÈsßg ¦ûvžSsLpºÊW–âµEWöˬH; ™!CYõZ ÃÄf æ#1W. \uWâ\,\Çf j’<qTbên›Î[vxx£ë 'ö¨1›˜ÀM¼Pÿ H)ƒêêŒA7s,|F“ 꺸k³9Ìö*ç®;Ö!Ö$Eiž•¹ÒÚ†ýóéÝû¾ÕS®ó$’NÝäŸz¤5r¦ãÄÃD÷Üø!°ø‡Ô&@m™Ì^Ãä­d q5Lnÿ N;.6½·N|#ä"1Nƒx“ã<3('&ñßt  ~ªu”1Tb㫨9ê–›–bìd$ߣ=#ÕãÒmU¯eí$EFù5ýYô櫨æì™Ç—±ssM]·á¿0ÕåJRÓªîiƒ+O58ÖñªŠÒx" \µâá¨i’¤i —Ö ” M+M¤ë9‚‰A¦°Qõ¾ßøK~¼Ã‘g…Ö´~÷Ï[3GUœÒ½#…kàÔ®Ò”‰³·dWV‰IP‰Ú8u¹”E ÖqLj¾êÕCBš{A^Âß;–¨`¯¬ìö ˼ ×tìø.tƐm*n¨y4o&Àx¥n¦×î‡aupáÛj8¿m›è¶ã!o½;ß0y^ý×^EÑ¿ÒjzŒ­)vÚÑnÄL …^ªô× ‡—‚3k Îý­hï]içå–îÏ*÷ñþ»Ô CÒjøjÍznˆ´ ¹#b'Fô‹ ‰v¥'’à'T´ƒHýÍ%M‰ ƒ&ÆÇŒï1 ‘ –Þ ‰i¬s žR-Ÿ kЬá¬7:þ 0ŒÅÒÕ/aÙ¬ÃÝ#Úøœ ©aiVc‰. ¹¦ãµ” ›Yg¦›ÆÎýº°f³7ƒhá·¸­}&D9¡ÂsÉÙÞèŠõØàC™¨ñbFC|´Ü(ŸƒÚÒ-%»'a Ì¿)ËÇn¿úÿ ÞŽX…4ÊÅH^ôΑí@ù¹Eh¶“L8Çjù ¼ÎåVªóR©Ï5uà V4lZß®=€xÖŸ–ÑÈ ÷”¨°¾__yM1tÉ?uÆþIkÄgæ@þ[¢†°XÃJ£j·:nkÅ¢u ‘}âGzö­/IµèЬ¼48q¦F°ŽR¼=ûì{´¯RýicS ÕÛ íNtÍÙï£,w4rêì®»~x(©Uñ§#Ñ&œÕ¤>ÎåÍÓ9’Ö{9eV­[Öjâ²ãu]˜å2›qÑšÕJç0€sÄ|Êëè0튔bÁ>“{×_F`Ø©ºê:µä,v¤ðfc1±"«ÔÍän1#=· Âøv~H½ÐßA¾¿Ü€Óš]Õ; I¾÷ç‚Qi†î¹9ywÔKG˜áñ zQY—§ÃÕZ07§X‚ Áh;ÁM)iÌCH-¯T‘ë|A0{Ò½LÚ–TâÖkÜ’dÀ“rmm»”جPF³ÖcbE§T€ÒxKºû’Ó®7±²(\4ŽÃ¸Uu@j™yĵ;³µ!Á¢b.W¤=mõ´êµK k ¸K^ÜÛ#p*Ü14qkZç5ïë †°5Ï%ÍÛ<Õ¤×Ô¥ê†C Õ´¼ú$ƒÖ“”]Ù¬qÞÚ[4©ý!ûÏ—Áb쳐XµA¬â~`›Çr¸8ìùÝ䫦<>ä÷«?xs´ÇÑ /á;¹øüÊÈÙà{"@Žïzâ¬[âß‚ U_<ÇŸ½4èN˜ú61®qŠu ¦þF£»äJ_ˆÙÎ~ ÞAã–݄ϗrŠD;xTž‘ô`É«…suãO`?³à™ô Lý#Íc5öoæØ‚y´´÷«ZR§<&JÇ+éâô´€i!Àˆ0æAoàðLèÖ-2ŸõW.’t^–(KÁmHµV@xÜÇy®Ñø­â^:Ú3w· 7½¹°ñ¸â¹®:',«Mœ—n­Á+Ãbš LÈ‘ÄnRÓÅœ%¦²‰¨ùQ:¤f‚ "PÕtô¸…cæl…&˜Ú˜Ôkv‹ž+vŠ,=¢v­6—Xy*¥t£«<™:“aîϲ=¦6rO]XI¿Œ÷¤zÚ­›¶ 6÷”w\d ü~v®ˆÌk«^m<ÿ ¢‰Õ\)ùºŽ;… lîÙÅEŠ®cѾ@vnMÏ,¼“ñ•ŽBxðÃzãÇç%3ˆ"}Ù•Åî> BÉú;Ò]V+P˜F_´ßé> Øše|ï‡ÄOmFæÇ ãqÞ$/xÐx­z`ï9"œÜij‚!7.\Td…9M‡•iŽ‹¾‘50ÞŽn¥ß4ÉôO ¹*í^QêËÜÇÌ8=ާs‰'ÂëÙ«á%Pú[O †ÅP¯Vsް.‰,kc¶ ¬A9n˜XÎ-ÞšN["¹QÕ‰ƒMýÁߺXJæÍaLj¾×Ãmã¾ãÚ uñÒþåQô¦¥ /ÄUx:‚ÍÜ’ Đ©ØÝ3V¨‰ÕnÐ6ó*óúK­«…c ¯U òhsý­jóÔj#,ímŒRµ«lbïUTŒÑ8†Ä0œÏr`ð¡¬É Ї ë"À² ™ 6¥ f¶ ¢ÚoܱԷ-<Àî)†a¶ž'Ú»¨TXqØæ¶÷YÄHy˜9ÈIW­YÀuMFë ºÏ’AqÌ4·/Ú †ô'i$øä­=Ä Ý|öK×40è|È6p‘0§)o¥ctî§H+CA-“ xØ|ÐXАç l8íºð3Ø:³¤¬KX¯UÿÙ /* MIT License http://www.opensource.org/licenses/mit-license.php Author Tobias Koppers @sokra */ "use strict"; const NativeModule = require("module"); const { CachedSource, LineToLineMappedSource, OriginalSource, RawSource, SourceMapSource } = require("webpack-sources"); const { getContext, runLoaders } = require("loader-runner"); const WebpackError = require("./WebpackError"); const Module = require("./Module"); const ModuleParseError = require("./ModuleParseError"); const ModuleBuildError = require("./ModuleBuildError"); const ModuleError = require("./ModuleError"); const ModuleWarning = require("./ModuleWarning"); const createHash = require("./util/createHash"); const contextify = require("./util/identifier").contextify; /** @typedef {import("./util/createHash").Hash} Hash */ const asString = buf => { if (Buffer.isBuffer(buf)) { return buf.toString("utf-8"); } return buf; }; const asBuffer = str => { if (!Buffer.isBuffer(str)) { return Buffer.from(str, "utf-8"); } return str; }; class NonErrorEmittedError extends WebpackError { constructor(error) { super(); this.name = "NonErrorEmittedError"; this.message = "(Emitted value instead of an instance of Error) " + error; Error.captureStackTrace(this, this.constructor); } } /** * @typedef {Object} CachedSourceEntry * @property {TODO} source the generated source * @property {string} hash the hash value */ class NormalModule extends Module { constructor({ type, request, userRequest, rawRequest, loaders, resource, matchResource, parser, generator, resolveOptions }) { super(type, getContext(resource)); // Info from Factory this.request = request; this.userRequest = userRequest; this.rawRequest = rawRequest; this.binary = type.startsWith("webassembly"); this.parser = parser; this.generator = generator; this.resource = resource; this.matchResource = matchResource; this.loaders = loaders; if (resolveOptions !== undefined) this.resolveOptions = resolveOptions; // Info from Build this.error = null; this._source = null; this._sourceSize = null; this._buildHash = ""; this.buildTimestamp = undefined; /** @private @type {Map} */ this._cachedSources = new Map(); // Options for the NormalModule set by plugins // TODO refactor this -> options object filled from Factory this.useSourceMap = false; this.lineToLine = false; // Cache this._lastSuccessfulBuildMeta = {}; } identifier() { return this.request; } readableIdentifier(requestShortener) { return requestShortener.shorten(this.userRequest); } libIdent(options) { return contextify(options.context, this.userRequest); } nameForCondition() { const resource = this.matchResource || this.resource; const idx = resource.indexOf("?"); if (idx >= 0) return resource.substr(0, idx); return resource; } updateCacheModule(module) { this.type = module.type; this.request = module.request; this.userRequest = module.userRequest; this.rawRequest = module.rawRequest; this.parser = module.parser; this.generator = module.generator; this.resource = module.resource; this.matchResource = module.matchResource; this.loaders = module.loaders; this.resolveOptions = module.resolveOptions; } createSourceForAsset(name, content, sourceMap) { if (!sourceMap) { return new RawSource(content); } if (typeof sourceMap === "string") { return new OriginalSource(content, sourceMap); } return new SourceMapSource(content, name, sourceMap); } createLoaderContext(resolver, options, compilation, fs) { const requestShortener = compilation.runtimeTemplate.requestShortener; const getCurrentLoaderName = () => { const currentLoader = this.getCurrentLoader(loaderContext); if (!currentLoader) return "(not in loader scope)"; return requestShortener.shorten(currentLoader.loader); }; const loaderContext = { version: 2, emitWarning: warning => { if (!(warning instanceof Error)) { warning = new NonErrorEmittedError(warning); } this.warnings.push( new ModuleWarning(this, warning, { from: getCurrentLoaderName() }) ); }, emitError: error => { if (!(error instanceof Error)) { error = new NonErrorEmittedError(error); } this.errors.push( new ModuleError(this, error, { from: getCurrentLoaderName() }) ); }, getLogger: name => { const currentLoader = this.getCurrentLoader(loaderContext); return compilation.getLogger(() => [currentLoader && currentLoader.loader, name, this.identifier()] .filter(Boolean) .join("|") ); }, // TODO remove in webpack 5 exec: (code, filename) => { // @ts-ignore Argument of type 'this' is not assignable to parameter of type 'Module'. const module = new NativeModule(filename, this); // @ts-ignore _nodeModulePaths is deprecated and undocumented Node.js API module.paths = NativeModule._nodeModulePaths(this.context); module.filename = filename; module._compile(code, filename); return module.exports; }, resolve(context, request, callback) { resolver.resolve({}, context, request, {}, callback); }, getResolve(options) { const child = options ? resolver.withOptions(options) : resolver; return (context, request, callback) => { if (callback) { child.resolve({}, context, request, {}, callback); } else { return new Promise((resolve, reject) => { child.resolve({}, context, request, {}, (err, result) => { if (err) reject(err); else resolve(result); }); }); } }; }, emitFile: (name, content, sourceMap, assetInfo) => { if (!this.buildInfo.assets) { this.buildInfo.assets = Object.create(null); this.buildInfo.assetsInfo = new Map(); } this.buildInfo.assets[name] = this.createSourceForAsset( name, content, sourceMap ); this.buildInfo.assetsInfo.set(name, assetInfo); }, rootContext: options.context, webpack: true, sourceMap: !!this.useSourceMap, mode: options.mode || "production", _module: this, _compilation: compilation, _compiler: compilation.compiler, fs: fs }; compilation.hooks.normalModuleLoader.call(loaderContext, this); if (options.loader) { Object.assign(loaderContext, options.loader); } return loaderContext; } getCurrentLoader(loaderContext, index = loaderContext.loaderIndex) { if ( this.loaders && this.loaders.length && index < this.loaders.length && index >= 0 && this.loaders[index] ) { return this.loaders[index]; } return null; } createSource(source, resourceBuffer, sourceMap) { // if there is no identifier return raw source if (!this.identifier) { return new RawSource(source); } // from here on we assume we have an identifier const identifier = this.identifier(); if (this.lineToLine && resourceBuffer) { return new LineToLineMappedSource( source, identifier, asString(resourceBuffer) ); } if (this.useSourceMap && sourceMap) { return new SourceMapSource(source, identifier, sourceMap); } if (Buffer.isBuffer(source)) { // @ts-ignore // TODO We need to fix @types/webpack-sources to allow RawSource to take a Buffer | string return new RawSource(source); } return new OriginalSource(source, identifier); } doBuild(options, compilation, resolver, fs, callback) { const loaderContext = this.createLoaderContext( resolver, options, compilation, fs ); runLoaders( { resource: this.resource, loaders: this.loaders, context: loaderContext, readResource: fs.readFile.bind(fs) }, (err, result) => { if (result) { this.buildInfo.cacheable = result.cacheable; this.buildInfo.fileDependencies = new Set(result.fileDependencies); this.buildInfo.contextDependencies = new Set( result.contextDependencies ); } if (err) { if (!(err instanceof Error)) { err = new NonErrorEmittedError(err); } const currentLoader = this.getCurrentLoader(loaderContext); const error = new ModuleBuildError(this, err, { from: currentLoader && compilation.runtimeTemplate.requestShortener.shorten( currentLoader.loader ) }); return callback(error); } const resourceBuffer = result.resourceBuffer; const source = result.result[0]; const sourceMap = result.result.length >= 1 ? result.result[1] : null; const extraInfo = result.result.length >= 2 ? result.result[2] : null; if (!Buffer.isBuffer(source) && typeof source !== "string") { const currentLoader = this.getCurrentLoader(loaderContext, 0); const err = new Error( `Final loader (${ currentLoader ? compilation.runtimeTemplate.requestShortener.shorten( currentLoader.loader ) : "unknown" }) didn't return a Buffer or String` ); const error = new ModuleBuildError(this, err); return callback(error); } this._source = this.createSource( this.binary ? asBuffer(source) : asString(source), resourceBuffer, sourceMap ); this._sourceSize = null; this._ast = typeof extraInfo === "object" && extraInfo !== null && extraInfo.webpackAST !== undefined ? extraInfo.webpackAST : null; return callback(); } ); } markModuleAsErrored(error) { // Restore build meta from successful build to keep importing state this.buildMeta = Object.assign({}, this._lastSuccessfulBuildMeta); this.error = error; this.errors.push(this.error); this._source = new RawSource( "throw new Error(" + JSON.stringify(this.error.message) + ");" ); this._sourceSize = null; this._ast = null; } applyNoParseRule(rule, content) { // must start with "rule" if rule is a string if (typeof rule === "string") { return content.indexOf(rule) === 0; } if (typeof rule === "function") { return rule(content); } // we assume rule is a regexp return rule.test(content); } // check if module should not be parsed // returns "true" if the module should !not! be parsed // returns "false" if the module !must! be parsed shouldPreventParsing(noParseRule, request) { // if no noParseRule exists, return false // the module !must! be parsed. if (!noParseRule) { return false; } // we only have one rule to check if (!Array.isArray(noParseRule)) { // returns "true" if the module is !not! to be parsed return this.applyNoParseRule(noParseRule, request); } for (let i = 0; i < noParseRule.length; i++) { const rule = noParseRule[i]; // early exit on first truthy match // this module is !not! to be parsed if (this.applyNoParseRule(rule, request)) { return true; } } // no match found, so this module !should! be parsed return false; } _initBuildHash(compilation) { const hash = createHash(compilation.outputOptions.hashFunction); if (this._source) { hash.update("source"); this._source.updateHash(hash); } hash.update("meta"); hash.update(JSON.stringify(this.buildMeta)); this._buildHash = /** @type {string} */ (hash.digest("hex")); } build(options, compilation, resolver, fs, callback) { this.buildTimestamp = Date.now(); this.built = true; this._source = null; this._sourceSize = null; this._ast = null; this._buildHash = ""; this.error = null; this.errors.length = 0; this.warnings.length = 0; this.buildMeta = {}; this.buildInfo = { cacheable: false, fileDependencies: new Set(), contextDependencies: new Set(), assets: undefined, assetsInfo: undefined }; return this.doBuild(options, compilation, resolver, fs, err => { this._cachedSources.clear(); // if we have an error mark module as failed and exit if (err) { this.markModuleAsErrored(err); this._initBuildHash(compilation); return callback(); } // check if this module should !not! be parsed. // if so, exit here; const noParseRule = options.module && options.module.noParse; if (this.shouldPreventParsing(noParseRule, this.request)) { this._initBuildHash(compilation); return callback(); } const handleParseError = e => { const source = this._source.source(); const loaders = this.loaders.map(item => contextify(options.context, item.loader) ); const error = new ModuleParseError(this, source, e, loaders); this.markModuleAsErrored(error); this._initBuildHash(compilation); return callback(); }; const handleParseResult = result => { this._lastSuccessfulBuildMeta = this.buildMeta; this._initBuildHash(compilation); return callback(); }; try { const result = this.parser.parse( this._ast || this._source.source(), { current: this, module: this, compilation: compilation, options: options }, (err, result) => { if (err) { handleParseError(err); } else { handleParseResult(result); } } ); if (result !== undefined) { // parse is sync handleParseResult(result); } } catch (e) { handleParseError(e); } }); } getHashDigest(dependencyTemplates) { // TODO webpack 5 refactor let dtHash = dependencyTemplates.get("hash"); return `${this.hash}-${dtHash}`; } source(dependencyTemplates, runtimeTemplate, type = "javascript") { const hashDigest = this.getHashDigest(dependencyTemplates); const cacheEntry = this._cachedSources.get(type); if (cacheEntry !== undefined && cacheEntry.hash === hashDigest) { // We can reuse the cached source return cacheEntry.source; } const source = this.generator.generate( this, dependencyTemplates, runtimeTemplate, type ); const cachedSource = new CachedSource(source); this._cachedSources.set(type, { source: cachedSource, hash: hashDigest }); return cachedSource; } originalSource() { return this._source; } needRebuild(fileTimestamps, contextTimestamps) { // always try to rebuild in case of an error if (this.error) return true; // always rebuild when module is not cacheable if (!this.buildInfo.cacheable) return true; // Check timestamps of all dependencies // Missing timestamp -> need rebuild // Timestamp bigger than buildTimestamp -> need rebuild for (const file of this.buildInfo.fileDependencies) { const timestamp = fileTimestamps.get(file); if (!timestamp) return true; if (timestamp >= this.buildTimestamp) return true; } for (const file of this.buildInfo.contextDependencies) { const timestamp = contextTimestamps.get(file); if (!timestamp) return true; if (timestamp >= this.buildTimestamp) return true; } // elsewise -> no rebuild needed return false; } size() { if (this._sourceSize === null) { this._sourceSize = this._source ? this._source.size() : -1; } return this._sourceSize; } /** * @param {Hash} hash the hash used to track dependencies * @returns {void} */ updateHash(hash) { hash.update(this._buildHash); super.updateHash(hash); } } module.exports = NormalModule;