{
  "version": 3,
  "sources": ["../../../src/optimizer/transforms/extract-prefix-2.ts"],
  "sourcesContent": ["import type {AlternativeElementNode, AlternativeNode} from '../../parser/parse.js';\nimport 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 alternating prefixes if patterns are repeated for each prefix.\nEx: `^a|!a|^bb|!bb|^c|!c` -> `(?:^|!)(?:a|bb|c)`.\nAlso works within groups.\n*/\nconst extractPrefix2: Visitor = {\n  '*'({node}) {\n    if (!isAlternativeContainer(node)) {\n      return;\n    }\n    const numDiffPrefixes = 2;\n    const numAlts = node.body.length;\n    if (numAlts < (numDiffPrefixes * 2) || numAlts % numDiffPrefixes) {\n      return;\n    }\n    const prefixAltElsByI = [...node.body.slice(0, numDiffPrefixes).map(alt => alt.body)];\n    const prefixNodesByI = Array.from({length: numDiffPrefixes}, (): Array<AlternativeElementNode> => []);\n    const prefixIsFinishedByI = Array(numDiffPrefixes).fill(false);\n    const longestOf = Math.max(...prefixAltElsByI.map(els => els.length));\n    for (let nodeI = 0; nodeI < longestOf; nodeI++) {\n      for (let prefixI = 0; prefixI < numDiffPrefixes; prefixI++) {\n        if (!prefixIsFinishedByI[prefixI]) {\n          const nextNode = prefixAltElsByI[prefixI][nodeI];\n          if (\n            !nextNode ||\n            !isAllowedSimpleNode(nextNode) ||\n            !isPrefixNodeShared(nextNode, node.body, prefixI, nodeI, numDiffPrefixes)\n          ) {\n            prefixIsFinishedByI[prefixI] = true;\n          } else {\n            prefixNodesByI[prefixI].push(nextNode);\n          }\n        }\n      }\n    }\n    if (!prefixNodesByI.some(nodes => nodes.length)) {\n      return;\n    }\n    const strippedAlts = [];\n    let counter = 0;\n    for (let i = 0; i < numAlts; i++) {\n      strippedAlts.push(createAlternative({\n        body: node.body[i].body.slice(prefixNodesByI[counter].length),\n      }));\n      counter = counter < (numDiffPrefixes - 1) ? counter + 1 : 0;\n    }\n    // Check that each set of alts now use the same value after having had their prefixes removed\n    for (let i = 0; i < (numAlts / numDiffPrefixes); i++) {\n      const altComparisonSet = strippedAlts.slice(i * numDiffPrefixes, (i * numDiffPrefixes) + numDiffPrefixes);\n      for (let j = 1; j < altComparisonSet.length; j++) {\n        const els = altComparisonSet[j].body;\n        if (els.length !== altComparisonSet[0].body.length) {\n          return;\n        }\n        if (!els.every((el, k) => (\n          isAllowedSimpleNode(el) &&\n          isNodeEqual(el, altComparisonSet[0].body[k])\n        ))) {\n          return;\n        }\n      }\n    }\n    const prefixAlts = [];\n    for (let i = 0; i < numDiffPrefixes; i++) {\n      prefixAlts.push(createAlternative({body: prefixNodesByI[i]}));\n    }\n    const prefixGroup = createGroup({body: prefixAlts});\n    const newContentsAlt = createAlternative({body: [prefixGroup]});\n    // Only take one (unique) alt from each set of stripped alts\n    const suffixGroup = createGroup({body: strippedAlts.filter((_, i) => i % numDiffPrefixes)});\n    if (suffixGroup.body.every(alt => !alt.body.length)) {\n      node.body = prefixGroup.body;\n    } else {\n      newContentsAlt.body.push(suffixGroup);\n      node.body = [newContentsAlt];\n    }\n  },\n};\n\nfunction isPrefixNodeShared(\n  node: AlternativeElementNode,\n  alts: Array<AlternativeNode>,\n  prefixI: number,\n  nodeI: number,\n  numDiffPrefixes: number\n): boolean {\n  for (let i = prefixI; i < alts.length; i += numDiffPrefixes) {\n    const alt = alts[i];\n    const bNode = alt.body[nodeI];\n    if (!bNode || !isNodeEqual(bNode, node)) {\n      return false;\n    }\n  }\n  return true;\n}\n\nexport {\n  extractPrefix2,\n};\n"],
  "mappings": "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",
  "names": ["isAlternativeContainer", "createAlternative", "createGroup", "isAllowedSimpleNode", "isNodeEqual", "extractPrefix2", "node", "numDiffPrefixes", "numAlts", "prefixAltElsByI", "alt", "prefixNodesByI", "prefixIsFinishedByI", "longestOf", "els", "nodeI", "prefixI", "nextNode", "isPrefixNodeShared", "nodes", "strippedAlts", "counter", "i", "altComparisonSet", "j", "el", "k", "prefixAlts", "prefixGroup", "newContentsAlt", "suffixGroup", "_", "alts", "bNode"]
}
