{
  "version": 3,
  "sources": ["../../../src/optimizer/transforms/extract-suffix.ts"],
  "sourcesContent": ["import type {Visitor} from '../../traverser/traverse.js';\nimport {isAlternativeContainer} from '../../parser/node-utils.js';\nimport {createAlternative, createGroup} from '../../parser/parse.js';\nimport {isAllowedSimpleNode, isNodeEqual} from './extract-prefix.js';\n\n/**\nExtract nodes at the end of every alternative into a suffix.\nEx: `aa$|bba$|ca$` -> `(?:a|bb|c)a$`.\nAlso works within groups.\n*/\nconst extractSuffix: Visitor = {\n  '*'({node}) {\n    if (!isAlternativeContainer(node) || node.body.length < 2) {\n      return;\n    }\n    const firstAltEls = node.body[0].body;\n    const suffixNodes = [];\n    let passedSharedSuffix = false;\n    let i = 0;\n    while (!passedSharedSuffix) {\n      const inverseI = firstAltEls.length - 1 - i;\n      suffixNodes.push(firstAltEls[inverseI]);\n      for (const alt of node.body) {\n        const inverseIOfAlt = alt.body.length - 1 - i;\n        const kid = alt.body[inverseIOfAlt];\n        if (!kid || !isAllowedSimpleNode(kid) || !isNodeEqual(kid, suffixNodes[i])) {\n          passedSharedSuffix = true;\n          break;\n        }\n      }\n      i++;\n    }\n    suffixNodes.pop();\n    if (\n      !suffixNodes.length ||\n      // Avoid applying in cases when it would lengthen the pattern without any benefit; ex:\n      // `true|false` -> `(?:tru|fals)e`, or `if|elseif` -> `(?:|else)if`\n      ( suffixNodes.length < 3 &&\n        // Always extract the suffix if it ends with an assertion, since that provides a\n        // readability benefit and is more likely to trigger follow-on optimizations\n        suffixNodes[0].type !== 'Assertion' &&\n        // Four chars are added by the `(?:)` wrapper and one instance of the suffix is added back\n        // at the end, so avoid if the result could be longer\n        (suffixNodes.length * (node.body.length - 1)) < 4 &&\n        // Adjacent alts reduced to 0 or 1 node after extracting the suffix can possibly be\n        // collapsed in follow-on optimizations, providing a performance and/or minification\n        // benefit\n        !node.body.some((alt, i, arr) => {\n          const lastAlt = arr[i - 1];\n          const removed = suffixNodes.length;\n          return alt.body.length - removed < 2 && lastAlt && lastAlt.body.length - removed < 2;\n        })\n      )\n    ) {\n      return;\n    }\n    suffixNodes.reverse();\n\n    for (const alt of node.body) {\n      alt.body = alt.body.slice(0, -suffixNodes.length);\n    }\n    const newContentsAlt = createAlternative();\n    const prefixGroup = createGroup({body: node.body});\n    if (!prefixGroup.body.every(alt => !alt.body.length)) {\n      newContentsAlt.body.push(prefixGroup);\n    }\n    newContentsAlt.body.push(...suffixNodes);\n    node.body = [newContentsAlt];\n  },\n};\n\nexport {\n  extractSuffix,\n};\n"],
  "mappings": "aACA,OAAQ,0BAAAA,MAA6B,6BACrC,OAAQ,qBAAAC,EAAmB,eAAAC,MAAkB,wBAC7C,OAAQ,uBAAAC,EAAqB,eAAAC,MAAkB,sBAO/C,MAAMC,EAAyB,CAC7B,IAAI,CAAC,KAAAC,CAAI,EAAG,CACV,GAAI,CAACN,EAAuBM,CAAI,GAAKA,EAAK,KAAK,OAAS,EACtD,OAEF,MAAMC,EAAcD,EAAK,KAAK,CAAC,EAAE,KAC3BE,EAAc,CAAC,EACrB,IAAIC,EAAqB,GACrBC,EAAI,EACR,KAAO,CAACD,GAAoB,CAC1B,MAAME,EAAWJ,EAAY,OAAS,EAAIG,EAC1CF,EAAY,KAAKD,EAAYI,CAAQ,CAAC,EACtC,UAAWC,KAAON,EAAK,KAAM,CAC3B,MAAMO,EAAgBD,EAAI,KAAK,OAAS,EAAIF,EACtCI,EAAMF,EAAI,KAAKC,CAAa,EAClC,GAAI,CAACC,GAAO,CAACX,EAAoBW,CAAG,GAAK,CAACV,EAAYU,EAAKN,EAAYE,CAAC,CAAC,EAAG,CAC1ED,EAAqB,GACrB,KACF,CACF,CACAC,GACF,CAEA,GADAF,EAAY,IAAI,EAEd,CAACA,EAAY,QAGXA,EAAY,OAAS,GAGrBA,EAAY,CAAC,EAAE,OAAS,aAGvBA,EAAY,QAAUF,EAAK,KAAK,OAAS,GAAM,GAIhD,CAACA,EAAK,KAAK,KAAK,CAACM,EAAK,EAAGG,IAAQ,CAC/B,MAAMC,EAAUD,EAAI,EAAI,CAAC,EACnBE,EAAUT,EAAY,OAC5B,OAAOI,EAAI,KAAK,OAASK,EAAU,GAAKD,GAAWA,EAAQ,KAAK,OAASC,EAAU,CACrF,CAAC,EAGH,OAEFT,EAAY,QAAQ,EAEpB,UAAWI,KAAON,EAAK,KACrBM,EAAI,KAAOA,EAAI,KAAK,MAAM,EAAG,CAACJ,EAAY,MAAM,EAElD,MAAMU,EAAiBjB,EAAkB,EACnCkB,EAAcjB,EAAY,CAAC,KAAMI,EAAK,IAAI,CAAC,EAC5Ca,EAAY,KAAK,MAAMP,GAAO,CAACA,EAAI,KAAK,MAAM,GACjDM,EAAe,KAAK,KAAKC,CAAW,EAEtCD,EAAe,KAAK,KAAK,GAAGV,CAAW,EACvCF,EAAK,KAAO,CAACY,CAAc,CAC7B,CACF,EAEA,OACEb,KAAA",
  "names": ["isAlternativeContainer", "createAlternative", "createGroup", "isAllowedSimpleNode", "isNodeEqual", "extractSuffix", "node", "firstAltEls", "suffixNodes", "passedSharedSuffix", "i", "inverseI", "alt", "inverseIOfAlt", "kid", "arr", "lastAlt", "removed", "newContentsAlt", "prefixGroup"]
}
