UNPKG

@shockpkg/dir-projector

Version:

Package for creating Shockwave Director projectors

1 lines 18.8 kB
{"version":3,"sources":["projector.ts"],"names":["join","pathJoin","dirname","ArchiveDir","ArchiveHdi","createArchiveByFileExtension","fse","pathRelativeBase","trimExtension","Projector","Object","constructor","path","shockwave","splashImageFile","splashImageData","lingoFile","lingoData","includeXtras","nestXtrasConfiguration","pathToHdiutil","configExtension","configEncoding","lingoName","lingoEncoding","xtrasName","configurationName","name","extension","configPath","base","splashImagePath","splashImageExtension","lingoPath","xtrasPath","cn","getSplashImageData","readFile","getLingoData","Buffer","from","Array","isArray","lingoNewline","getSkeletonArchive","skeleton","stat","isDirectory","isFile","Error","r","mounterMac","hdiutil","nobrowse","getIncludeXtrasMappings","src","keys","dest","push","findIncludeXtrasMappingsBestMatch","mappings","best","bestScore","map","relative","length","includeXtrasMappingsDest","withFile","configFile","configData","withData","_checkOutput","_writeSkeleton","_modifySkeleton","_writeConfig","_writeSplashImage","_writeLingo","p","pathExists","data","configNewline","outputFile"],"mappings":"AACA,SACCA,IAAI,IAAIC,QADT,EAECC,OAFD,QAGO,MAHP;AAKA,SAECC,UAFD,EAGCC,UAHD,EAICC,4BAJD,QAKO,oCALP;AAMA,OAAOC,GAAP,MAAgB,UAAhB;AAEA,SACCC,gBADD,EAECC,aAFD,QAGO,YAHP;;AAqCA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAeC,SAAf,SAAiCC,MAAjC,CAAwC;AAC9C;AACD;AACA;AACA;AACA;;AAGC;AACD;AACA;AACA;AACA;;AAGC;AACD;AACA;AACA;AACA;;AAGC;AACD;AACA;AACA;AACA;;AAGC;AACD;AACA;AACA;AACA;;AAKC;AACD;AACA;AACA;AACA;;AAGC;AACD;AACA;AACA;AACA;;AAGC;AACD;AACA;AACA;AACA;;AAGC;AACD;AACA;AAGCC,EAAAA,WAAW,CAACC,IAAD,EAAe;AACzB;AADyB,SA1DnBC,SA0DmB,GA1DE,KA0DF;AAAA,SAnDnBC,eAmDmB,GAnDc,IAmDd;AAAA,SA5CnBC,eA4CmB,GA5CwB,IA4CxB;AAAA,SArCnBC,SAqCmB,GArCQ,IAqCR;AAAA,SA9BnBC,SA8BmB,GA5BtB,IA4BsB;AAAA,SArBnBC,YAqBmB,GArB4B,IAqB5B;AAAA,SAdnBC,sBAcmB,GAde,KAcf;AAAA,SAPnBC,aAOmB,GAPY,IAOZ;AAAA,SAFVR,IAEU;AAGzB,SAAKA,IAAL,GAAYA,IAAZ;AACA;AAED;AACD;AACA;AACA;AACA;;;AACC,MAAWS,eAAX,GAA6B;AAC5B,WAAO,MAAP;AACA;AAED;AACD;AACA;AACA;AACA;;;AACC,MAAWC,cAAX,GAA4B;AAC3B,WAAO,OAAP;AACA;AAED;AACD;AACA;AACA;AACA;;;AACC,MAAWC,SAAX,GAAuB;AACtB,WAAO,WAAP;AACA;AAED;AACD;AACA;AACA;AACA;;;AACC,MAAWC,aAAX,GAA2B;AAC1B,WAAO,OAAP;AACA;AAED;AACD;AACA;AACA;AACA;;;AACC,MAAWC,SAAX,GAAuB;AACtB,WAAO,OAAP;AACA;AAED;AACD;AACA;AACA;AACA;;;AACC,MAAWC,iBAAX,GAA+B;AAC9B,WAAO,eAAP;AACA;AAED;AACD;AACA;AACA;AACA;;;AACC,MAAWC,IAAX,GAAkB;AACjB,WAAOnB,aAAa,CAACN,OAAO,CAAC,KAAKU,IAAN,CAAR,EAAqB,KAAKgB,SAA1B,EAAqC,IAArC,CAApB;AACA;AAED;AACD;AACA;AACA;AACA;;;AACC,MAAWC,UAAX,GAAwB;AACvB,UAAMC,IAAI,GAAGtB,aAAa,CAAC,KAAKI,IAAN,EAAY,KAAKgB,SAAjB,EAA4B,IAA5B,CAA1B;AACA,WAAQ,GAAEE,IAAK,GAAE,KAAKT,eAAgB,EAAtC;AACA;AAED;AACD;AACA;AACA;AACA;;;AACC,MAAWU,eAAX,GAA6B;AAC5B,UAAMD,IAAI,GAAGtB,aAAa,CAAC,KAAKI,IAAN,EAAY,KAAKgB,SAAjB,EAA4B,IAA5B,CAA1B;AACA,WAAQ,GAAEE,IAAK,GAAE,KAAKE,oBAAqB,EAA3C;AACA;AAED;AACD;AACA;AACA;AACA;;;AACC,MAAWC,SAAX,GAAuB;AACtB,WAAOhC,QAAQ,CAACC,OAAO,CAAC,KAAKU,IAAN,CAAR,EAAqB,KAAKW,SAA1B,CAAf;AACA;AAED;AACD;AACA;AACA;AACA;;;AACC,MAAWW,SAAX,GAAuB;AACtB,UAAMC,EAAE,GAAG,KAAKT,iBAAhB;AACA,WAAQ,KAAKP,sBAAL,IAA+BgB,EAAhC,GACNlC,QAAQ,CAACC,OAAO,CAAC,KAAKU,IAAN,CAAR,EAAqBuB,EAArB,EAAyB,KAAKV,SAA9B,CADF,GAENxB,QAAQ,CAACC,OAAO,CAAC,KAAKU,IAAN,CAAR,EAAqB,KAAKa,SAA1B,CAFT;AAGA;AAED;AACD;AACA;AACA;AACA;;;AACC,QAAaW,kBAAb,GAAkC;AACjC,UAAM;AAACrB,MAAAA,eAAD;AAAkBD,MAAAA;AAAlB,QAAqC,IAA3C;AACA,WAAOC,eAAe,KACrBD,eAAe,GAAGR,GAAG,CAAC+B,QAAJ,CAAavB,eAAb,CAAH,GAAmC,IAD7B,CAAtB;AAGA;AAED;AACD;AACA;AACA;AACA;;;AACC,QAAawB,YAAb,GAA4B;AAC3B,UAAM;AAACrB,MAAAA,SAAD;AAAYD,MAAAA;AAAZ,QAAyB,IAA/B;;AACA,QAAI,OAAOC,SAAP,KAAqB,QAAzB,EAAmC;AAClC,aAAOsB,MAAM,CAACC,IAAP,CAAYvB,SAAZ,EAAuB,KAAKO,aAA5B,CAAP;AACA;;AACD,QAAIiB,KAAK,CAACC,OAAN,CAAczB,SAAd,CAAJ,EAA8B;AAC7B,aAAOsB,MAAM,CAACC,IAAP,CACNvB,SAAS,CAACjB,IAAV,CAAe,KAAK2C,YAApB,CADM,EAEN,KAAKnB,aAFC,CAAP;AAIA;;AACD,QAAIP,SAAJ,EAAe;AACd,aAAOA,SAAP;AACA;;AACD,WAAOD,SAAS,GAAGV,GAAG,CAAC+B,QAAJ,CAAarB,SAAb,CAAH,GAA6B,IAA7C;AACA;AAED;AACD;AACA;AACA;AACA;AACA;;;AACC,QAAa4B,kBAAb,CAAgCC,QAAhC,EAAoE;AACnE,UAAMC,IAAI,GAAG,MAAMxC,GAAG,CAACwC,IAAJ,CAASD,QAAT,CAAnB;;AACA,QAAIC,IAAI,CAACC,WAAL,EAAJ,EAAwB;AACvB,aAAO,IAAI5C,UAAJ,CAAe0C,QAAf,CAAP;AACA;;AACD,QAAI,CAACC,IAAI,CAACE,MAAL,EAAL,EAAoB;AACnB,YAAM,IAAIC,KAAJ,CAAU,0CAAV,CAAN;AACA;;AAED,UAAMC,CAAC,GAAG7C,4BAA4B,CAACwC,QAAD,CAAtC;;AACA,QAAI,CAACK,CAAL,EAAQ;AACP,YAAM,IAAID,KAAJ,CAAU,8CAAV,CAAN;AACA;;AAED,QAAIC,CAAC,YAAY9C,UAAjB,EAA6B;AAC5B,YAAM;AAACgB,QAAAA;AAAD,UAAkB,IAAxB;;AACA,UAAIA,aAAJ,EAAmB;AAClB8B,QAAAA,CAAC,CAACC,UAAF,CAAaC,OAAb,GAAuBhC,aAAvB;AACA;;AACD8B,MAAAA,CAAC,CAACG,QAAF,GAAa,IAAb;AACA;;AACD,WAAOH,CAAP;AACA;AAED;AACD;AACA;AACA;AACA;;;AACQI,EAAAA,uBAAP,GAAiC;AAChC,UAAM;AAACpC,MAAAA;AAAD,QAAiB,IAAvB;AACA,UAAMgC,CAAwB,GAAG,EAAjC;;AACA,QAAIhC,YAAJ,EAAkB;AACjB,WAAK,MAAMqC,GAAX,IAAkB7C,MAAM,CAAC8C,IAAP,CAAYtC,YAAZ,CAAlB,EAA6C;AAC5C,cAAMuC,IAAI,GAAGvC,YAAY,CAACqC,GAAD,CAAzB;AACAL,QAAAA,CAAC,CAACQ,IAAF,CAAO;AACNH,UAAAA,GADM;AAENE,UAAAA;AAFM,SAAP;AAIA;AACD;;AACD,WAAOP,CAAP;AACA;AAED;AACD;AACA;AACA;AACA;AACA;AACA;AACA;;;AACQS,EAAAA,iCAAP,CACCC,QADD,EAEChD,IAFD,EAGE;AACD,QAAIiD,IAAoC,GAAG,IAA3C;AACA,QAAIC,SAAS,GAAG,CAAC,CAAjB;;AACA,SAAK,MAAMC,GAAX,IAAkBH,QAAlB,EAA4B;AAC3B,YAAM;AAACL,QAAAA;AAAD,UAAQQ,GAAd;AACA,YAAMC,QAAQ,GAAGT,GAAG,KAAK,EAAR,GAChB3C,IADgB,GAEhBL,gBAAgB,CAACK,IAAD,EAAO2C,GAAP,EAAY,IAAZ,CAFjB;;AAGA,UAAIS,QAAQ,KAAK,IAAb,IAAqBF,SAAS,IAAIP,GAAG,CAACU,MAA1C,EAAkD;AACjD;AACA;;AACDJ,MAAAA,IAAI,GAAG;AACNE,QAAAA,GADM;AAENC,QAAAA;AAFM,OAAP;AAIAF,MAAAA,SAAS,GAAGP,GAAG,CAACU,MAAhB;AACA;;AACD,WAAOJ,IAAP;AACA;AAED;AACD;AACA;AACA;AACA;AACA;AACA;;;AACQK,EAAAA,wBAAP,CACCN,QADD,EAEChD,IAFD,EAGE;AACD,UAAMiD,IAAI,GAAG,KAAKF,iCAAL,CAAuCC,QAAvC,EAAiDhD,IAAjD,CAAb;;AACA,QAAI,CAACiD,IAAL,EAAW;AACV,aAAO,IAAP;AACA;;AAED,UAAM;AAACE,MAAAA,GAAD;AAAMC,MAAAA;AAAN,QAAkBH,IAAxB;AACA,UAAM/B,IAAI,GAAGiC,GAAG,CAACN,IAAJ,IAAYM,GAAG,CAACR,GAA7B,CAPC,CAQD;;AACA,WAAOzB,IAAI,GAAIkC,QAAQ,GAAI,GAAElC,IAAK,IAAGkC,QAAS,EAAvB,GAA2BlC,IAAvC,GAA+CkC,QAA1D;AACA;AAED;AACD;AACA;AACA;AACA;AACA;;;AACC,QAAaG,QAAb,CAAsBtB,QAAtB,EAAwCuB,UAAxC,EAAmE;AAClE,UAAMC,UAAU,GAAGD,UAAU,GAAG,MAAM9D,GAAG,CAAC+B,QAAJ,CAAa+B,UAAb,CAAT,GAAoC,IAAjE;AACA,UAAM,KAAKE,QAAL,CAAczB,QAAd,EAAwBwB,UAAxB,CAAN;AACA;AAED;AACD;AACA;AACA;AACA;AACA;;;AACC,QAAaC,QAAb,CACCzB,QADD,EAECwB,UAFD,EAGE;AACD,UAAM,KAAKE,YAAL,EAAN;AACA,UAAM,KAAKC,cAAL,CAAoB3B,QAApB,CAAN;AACA,UAAM,KAAK4B,eAAL,EAAN;AACA,UAAM,KAAKC,YAAL,CAAkBL,UAAlB,CAAN;AACA,UAAM,KAAKM,iBAAL,EAAN;AACA,UAAM,KAAKC,WAAL,EAAN;AACA;AAED;AACD;AACA;;;AACC,QAAgBL,YAAhB,GAA+B;AAC9B,SAAK,MAAMM,CAAX,IAAgB,CACf,KAAKjE,IADU,EAEf,KAAKiB,UAFU,EAGf,KAAKE,eAHU,EAIf,KAAKE,SAJU,CAAhB,EAKG;AACF;AACA,UAAI,MAAM3B,GAAG,CAACwE,UAAJ,CAAeD,CAAf,CAAV,EAA6B;AAC5B,cAAM,IAAI5B,KAAJ,CAAW,+BAA8B4B,CAAE,EAA3C,CAAN;AACA;AACD;AACD;AAED;AACD;AACA;AACA;AACA;;;AACC,QAAgBH,YAAhB,CACCL,UADD,EAEE;AACD,QAAIU,IAA6B,GAAG,IAApC;;AACA,QAAI,OAAOV,UAAP,KAAsB,QAA1B,EAAoC;AACnCU,MAAAA,IAAI,GAAGxC,MAAM,CAACC,IAAP,CAAY6B,UAAZ,EAAwB,KAAK/C,cAA7B,CAAP;AACA,KAFD,MAGK,IAAImB,KAAK,CAACC,OAAN,CAAcqC,IAAd,CAAJ,EAAyB;AAC7BA,MAAAA,IAAI,GAAGxC,MAAM,CAACC,IAAP,CACL6B,UAAD,CAAyBrE,IAAzB,CAA8B,KAAKgF,aAAnC,CADM,EAEN,KAAK1D,cAFC,CAAP;AAIA,KALI,MAMA,IAAI+C,UAAJ,EAAgB;AACpBU,MAAAA,IAAI,GAAGV,UAAP;AACA;;AAED,QAAIU,IAAJ,EAAU;AACT,YAAMzE,GAAG,CAAC2E,UAAJ,CAAe,KAAKpD,UAApB,EAAgCkD,IAAhC,CAAN;AACA;AACD;AAED;AACD;AACA;;;AACC,QAAgBJ,iBAAhB,GAAoC;AACnC,UAAMI,IAAI,GAAG,MAAM,KAAK3C,kBAAL,EAAnB;;AACA,QAAI2C,IAAJ,EAAU;AACT,YAAMzE,GAAG,CAAC2E,UAAJ,CAAe,KAAKlD,eAApB,EAAqCgD,IAArC,CAAN;AACA;AACD;AAED;AACD;AACA;;;AACC,QAAgBH,WAAhB,GAA8B;AAC7B,UAAMG,IAAI,GAAG,MAAM,KAAKzC,YAAL,EAAnB;;AACA,QAAIyC,IAAJ,EAAU;AACT,YAAMzE,GAAG,CAAC2E,UAAJ,CAAe,KAAKhD,SAApB,EAA+B8C,IAA/B,CAAN;AACA;AACD;AAED;AACD;AACA;AACA;AACA;;;AAxZ+C","sourcesContent":["import {TranscodeEncoding} from 'buffer';\nimport {\n\tjoin as pathJoin,\n\tdirname\n} from 'path';\n\nimport {\n\tArchive,\n\tArchiveDir,\n\tArchiveHdi,\n\tcreateArchiveByFileExtension\n} from '@shockpkg/archive-files';\nimport fse from 'fs-extra';\n\nimport {\n\tpathRelativeBase,\n\ttrimExtension\n} from './util';\n\nexport interface IIncludeXtraMapping {\n\n\t/**\n\t * Source path, case insensitive.\n\t * Does not need to match the full path.\n\t */\n\tsrc: string;\n\n\t/**\n\t * Destination path, case sensitive.\n\t * Only matches same amount of the full path as src.\n\t */\n\tdest: string | null;\n}\n\nexport interface IIncludeXtraMappingBest {\n\n\t/**\n\t * Map instance.\n\t */\n\tmap: IIncludeXtraMapping;\n\n\t/**\n\t * Relative path.\n\t */\n\trelative: string;\n}\n\nexport interface IIncludeXtras {\n\t[key: string]: string | null;\n}\n\n/**\n * Projector constructor.\n *\n * @param path Output path.\n */\nexport abstract class Projector extends Object {\n\t/**\n\t * Make a Shockwave projector.\n\t *\n\t * @default false\n\t */\n\tpublic shockwave: boolean = false;\n\n\t/**\n\t * Splash image file.\n\t *\n\t * @default null\n\t */\n\tpublic splashImageFile: string | null = null;\n\n\t/**\n\t * Splash image data.\n\t *\n\t * @default null\n\t */\n\tpublic splashImageData: Readonly<Buffer> | null = null;\n\n\t/**\n\t * Lingo file.\n\t *\n\t * @default null\n\t */\n\tpublic lingoFile: string | null = null;\n\n\t/**\n\t * Lingo data.\n\t *\n\t * @default null\n\t */\n\tpublic lingoData: (\n\t\tReadonly<string[]> | string | Readonly<Buffer> | null\n\t) = null;\n\n\t/**\n\t * Xtras include map.\n\t *\n\t * @default null\n\t */\n\tpublic includeXtras: Readonly<IIncludeXtras> | null = null;\n\n\t/**\n\t * Nest xtras in a Configuration directory.\n\t *\n\t * @default false\n\t */\n\tpublic nestXtrasConfiguration: boolean = false;\n\n\t/**\n\t * Path to hdiutil binary.\n\t *\n\t * @default null\n\t */\n\tpublic pathToHdiutil: string | null = null;\n\n\t/**\n\t * Output path.\n\t */\n\tpublic readonly path: string;\n\n\tconstructor(path: string) {\n\t\tsuper();\n\n\t\tthis.path = path;\n\t}\n\n\t/**\n\t * Config file extension.\n\t *\n\t * @returns File extension.\n\t */\n\tpublic get configExtension() {\n\t\treturn '.INI';\n\t}\n\n\t/**\n\t * Config file encoding.\n\t *\n\t * @returns File encoding.\n\t */\n\tpublic get configEncoding() {\n\t\treturn 'ascii' as TranscodeEncoding;\n\t}\n\n\t/**\n\t * Lingo file name.\n\t *\n\t * @returns File name.\n\t */\n\tpublic get lingoName() {\n\t\treturn 'LINGO.INI';\n\t}\n\n\t/**\n\t * Lingo file encoding.\n\t *\n\t * @returns File encoding.\n\t */\n\tpublic get lingoEncoding() {\n\t\treturn 'ascii' as TranscodeEncoding;\n\t}\n\n\t/**\n\t * Xtras directory name.\n\t *\n\t * @returns Directory encoding.\n\t */\n\tpublic get xtrasName() {\n\t\treturn 'xtras';\n\t}\n\n\t/**\n\t * Configuration directory name.\n\t *\n\t * @returns Directory encoding.\n\t */\n\tpublic get configurationName() {\n\t\treturn 'Configuration';\n\t}\n\n\t/**\n\t * Name of a projector trimming the extension, case insensitive.\n\t *\n\t * @returns Projector name without extension.\n\t */\n\tpublic get name() {\n\t\treturn trimExtension(dirname(this.path), this.extension, true);\n\t}\n\n\t/**\n\t * Config file path.\n\t *\n\t * @returns Config path.\n\t */\n\tpublic get configPath() {\n\t\tconst base = trimExtension(this.path, this.extension, true);\n\t\treturn `${base}${this.configExtension}`;\n\t}\n\n\t/**\n\t * Splash image file path.\n\t *\n\t * @returns Splash image path.\n\t */\n\tpublic get splashImagePath() {\n\t\tconst base = trimExtension(this.path, this.extension, true);\n\t\treturn `${base}${this.splashImageExtension}`;\n\t}\n\n\t/**\n\t * Lingo file path.\n\t *\n\t * @returns Lingo file path.\n\t */\n\tpublic get lingoPath() {\n\t\treturn pathJoin(dirname(this.path), this.lingoName);\n\t}\n\n\t/**\n\t * Get outout Xtras path.\n\t *\n\t * @returns Output path.\n\t */\n\tpublic get xtrasPath() {\n\t\tconst cn = this.configurationName;\n\t\treturn (this.nestXtrasConfiguration && cn) ?\n\t\t\tpathJoin(dirname(this.path), cn, this.xtrasName) :\n\t\t\tpathJoin(dirname(this.path), this.xtrasName);\n\t}\n\n\t/**\n\t * Get splash image data if any specified, from data or file.\n\t *\n\t * @returns Splash image data or null.\n\t */\n\tpublic async getSplashImageData() {\n\t\tconst {splashImageData, splashImageFile} = this;\n\t\treturn splashImageData || (\n\t\t\tsplashImageFile ? fse.readFile(splashImageFile) : null\n\t\t);\n\t}\n\n\t/**\n\t * Get lingo data if any specified, from data or file.\n\t *\n\t * @returns Lingo data or null.\n\t */\n\tpublic async getLingoData() {\n\t\tconst {lingoData, lingoFile} = this;\n\t\tif (typeof lingoData === 'string') {\n\t\t\treturn Buffer.from(lingoData, this.lingoEncoding);\n\t\t}\n\t\tif (Array.isArray(lingoData)) {\n\t\t\treturn Buffer.from(\n\t\t\t\tlingoData.join(this.lingoNewline),\n\t\t\t\tthis.lingoEncoding\n\t\t\t);\n\t\t}\n\t\tif (lingoData) {\n\t\t\treturn lingoData as Readonly<Buffer>;\n\t\t}\n\t\treturn lingoFile ? fse.readFile(lingoFile) : null;\n\t}\n\n\t/**\n\t * Get the skeleton file or directory as an Archive instance.\n\t *\n\t * @param skeleton Skeleton path.\n\t * @returns Archive instance.\n\t */\n\tpublic async getSkeletonArchive(skeleton: string): Promise<Archive> {\n\t\tconst stat = await fse.stat(skeleton);\n\t\tif (stat.isDirectory()) {\n\t\t\treturn new ArchiveDir(skeleton);\n\t\t}\n\t\tif (!stat.isFile()) {\n\t\t\tthrow new Error('Projector skeleton not file or directory');\n\t\t}\n\n\t\tconst r = createArchiveByFileExtension(skeleton);\n\t\tif (!r) {\n\t\t\tthrow new Error('Projector skeleton archive file type unknown');\n\t\t}\n\n\t\tif (r instanceof ArchiveHdi) {\n\t\t\tconst {pathToHdiutil} = this;\n\t\t\tif (pathToHdiutil) {\n\t\t\t\tr.mounterMac.hdiutil = pathToHdiutil;\n\t\t\t}\n\t\t\tr.nobrowse = true;\n\t\t}\n\t\treturn r;\n\t}\n\n\t/**\n\t * Get include Xtras as a list of mappings.\n\t *\n\t * @returns Mappings list.\n\t */\n\tpublic getIncludeXtrasMappings() {\n\t\tconst {includeXtras} = this;\n\t\tconst r: IIncludeXtraMapping[] = [];\n\t\tif (includeXtras) {\n\t\t\tfor (const src of Object.keys(includeXtras)) {\n\t\t\t\tconst dest = includeXtras[src];\n\t\t\t\tr.push({\n\t\t\t\t\tsrc,\n\t\t\t\t\tdest\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn r;\n\t}\n\n\t/**\n\t * Find the best match for a path in a list of Xtras mappings.\n\t * Path search is case-insensitive.\n\t *\n\t * @param mappings Mappings list.\n\t * @param path Path to search for.\n\t * @returns Best match or null.\n\t */\n\tpublic findIncludeXtrasMappingsBestMatch(\n\t\tmappings: Readonly<IIncludeXtraMapping[]>,\n\t\tpath: string\n\t) {\n\t\tlet best: IIncludeXtraMappingBest | null = null;\n\t\tlet bestScore = -1;\n\t\tfor (const map of mappings) {\n\t\t\tconst {src} = map;\n\t\t\tconst relative = src === '' ?\n\t\t\t\tpath :\n\t\t\t\tpathRelativeBase(path, src, true);\n\t\t\tif (relative === null || bestScore >= src.length) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tbest = {\n\t\t\t\tmap,\n\t\t\t\trelative\n\t\t\t};\n\t\t\tbestScore = src.length;\n\t\t}\n\t\treturn best;\n\t}\n\n\t/**\n\t * Find output path for an Xtra.\n\t *\n\t * @param mappings Mappings list.\n\t * @param path Path to search for.\n\t * @returns Output path or null.\n\t */\n\tpublic includeXtrasMappingsDest(\n\t\tmappings: Readonly<IIncludeXtraMapping[]>,\n\t\tpath: string\n\t) {\n\t\tconst best = this.findIncludeXtrasMappingsBestMatch(mappings, path);\n\t\tif (!best) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst {map, relative} = best;\n\t\tconst base = map.dest || map.src;\n\t\t// eslint-disable-next-line no-nested-ternary\n\t\treturn base ? (relative ? `${base}/${relative}` : base) : relative;\n\t}\n\n\t/**\n\t * Write out projector with skeleton and config file.\n\t *\n\t * @param skeleton Skeleton path.\n\t * @param configFile Config file.\n\t */\n\tpublic async withFile(skeleton: string, configFile: string | null) {\n\t\tconst configData = configFile ? await fse.readFile(configFile) : null;\n\t\tawait this.withData(skeleton, configData);\n\t}\n\n\t/**\n\t * Write out projector with skeleton and config data.\n\t *\n\t * @param skeleton Skeleton path.\n\t * @param configData Config data.\n\t */\n\tpublic async withData(\n\t\tskeleton: string,\n\t\tconfigData: Readonly<string[]> | string | Readonly<Buffer> | null\n\t) {\n\t\tawait this._checkOutput();\n\t\tawait this._writeSkeleton(skeleton);\n\t\tawait this._modifySkeleton();\n\t\tawait this._writeConfig(configData);\n\t\tawait this._writeSplashImage();\n\t\tawait this._writeLingo();\n\t}\n\n\t/**\n\t * Check that output path is valid, else throws.\n\t */\n\tprotected async _checkOutput() {\n\t\tfor (const p of [\n\t\t\tthis.path,\n\t\t\tthis.configPath,\n\t\t\tthis.splashImagePath,\n\t\t\tthis.lingoPath\n\t\t]) {\n\t\t\t// eslint-disable-next-line no-await-in-loop\n\t\t\tif (await fse.pathExists(p)) {\n\t\t\t\tthrow new Error(`Output path already exists: ${p}`);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Write out the projector config file.\n\t *\n\t * @param configData Config data.\n\t */\n\tprotected async _writeConfig(\n\t\tconfigData: Readonly<string[]> | string | Readonly<Buffer> | null\n\t) {\n\t\tlet data: Readonly<Buffer> | null = null;\n\t\tif (typeof configData === 'string') {\n\t\t\tdata = Buffer.from(configData, this.configEncoding);\n\t\t}\n\t\telse if (Array.isArray(data)) {\n\t\t\tdata = Buffer.from(\n\t\t\t\t(configData as string[]).join(this.configNewline),\n\t\t\t\tthis.configEncoding\n\t\t\t);\n\t\t}\n\t\telse if (configData) {\n\t\t\tdata = configData as Readonly<Buffer>;\n\t\t}\n\n\t\tif (data) {\n\t\t\tawait fse.outputFile(this.configPath, data);\n\t\t}\n\t}\n\n\t/**\n\t * Write out the projector splash image file.\n\t */\n\tprotected async _writeSplashImage() {\n\t\tconst data = await this.getSplashImageData();\n\t\tif (data) {\n\t\t\tawait fse.outputFile(this.splashImagePath, data);\n\t\t}\n\t}\n\n\t/**\n\t * Write out the projector lingo file.\n\t */\n\tprotected async _writeLingo() {\n\t\tconst data = await this.getLingoData();\n\t\tif (data) {\n\t\t\tawait fse.outputFile(this.lingoPath, data);\n\t\t}\n\t}\n\n\t/**\n\t * Projector file extension.\n\t *\n\t * @returns File extension.\n\t */\n\tpublic abstract get extension(): string;\n\n\t/**\n\t * Splash image file extension.\n\t *\n\t * @returns File extension.\n\t */\n\tpublic abstract get splashImageExtension(): string;\n\n\t/**\n\t * Config file newline characters.\n\t *\n\t * @returns Newline characters.\n\t */\n\tpublic abstract get configNewline(): string;\n\n\t/**\n\t * Lingo file newline characters.\n\t *\n\t * @returns Newline characters.\n\t */\n\tpublic abstract get lingoNewline(): string;\n\n\t/**\n\t * Write the projector skeleton from archive.\n\t *\n\t * @param skeleton Skeleton path.\n\t */\n\tprotected abstract _writeSkeleton(skeleton: string): Promise<void>;\n\n\t/**\n\t * Modify the projector skeleton.\n\t */\n\tprotected abstract _modifySkeleton(): Promise<void>;\n}\n"],"file":"projector.mjs","sourceRoot":"../src"}