astx
Version:
super powerful structural search and replace for JavaScript and TypeScript to automate your refactoring
349 lines (308 loc) • 35.7 kB
JavaScript
import CompilePathError from '../util/CompilePathError.mjs'
import compileMatcher, { mergeCaptures } from './index.mjs'
import indentDebug from './indentDebug.mjs'
const defaultUnorderedFields = {}
for (const [type, field] of [
['ClassBody', 'body'],
['ClassDeclaration', 'implements'],
['DeclareClass', 'implements'],
['DeclareExportDeclaration', 'specifiers'],
['DeclareInterface', 'extends'],
['EnumDeclaration', 'body'],
['ExportNamedDeclaration', 'specifiers'],
['ImportDeclaration', 'specifiers'],
['InterfaceDeclaration', 'extends'],
['IntersectionTypeAnnotation', 'types'],
['JSXOpeningElement', 'attributes'],
['ObjectExpression', 'properties'],
['ObjectPattern', 'properties'],
['ObjectTypeAnnotation', 'properties'],
['TSEnumDeclaration', 'members'],
['TSInterfaceBody', 'body'],
['TSInterfaceDeclaration', 'extends'],
['TSIntersectionType', 'types'],
['TSTypeLiteral', 'members'],
['TSUnionType', 'types'],
['UnionTypeAnnotation', 'types'],
]) {
const forType =
defaultUnorderedFields[type] || (defaultUnorderedFields[type] = {})
forType[field] = true
}
function getDefaultUnordered(path) {
var _defaultUnorderedFiel
if (Array.isArray(path)) {
var _path$
const parent =
(_path$ = path[0]) === null || _path$ === void 0
? void 0
: _path$.parentPath
if (!parent) return false
return getDefaultUnordered(parent)
}
if (!path.node || !path.name) return false
return Boolean(
(_defaultUnorderedFiel = defaultUnorderedFields[path.node.type]) === null ||
_defaultUnorderedFiel === void 0
? void 0
: _defaultUnorderedFiel[path.name]
)
}
export default function compileGenericArrayMatcher(
path,
compileOptions,
{
compileElemMatcher = compileMatcher,
defaultUnordered = getDefaultUnordered(path),
skipElement = () => false,
} = {}
) {
const paths = Array.isArray(path) ? path : path.filter(() => true)
const pattern = path.map((p) => p.node)
const { debug } = compileOptions
const elemOptions = { ...compileOptions, debug: indentDebug(debug, 2) }
let matchers = pattern.map((value, i) =>
compileElemMatcher(paths[i], elemOptions)
)
assertArrayMatchersValid(matchers)
const unordered =
matchers.some((m) => m.restPlaceholder || m.placeholder === '$Unordered') ||
(defaultUnordered &&
!matchers.some((m) => m.placeholder === '$Ordered' || m.arrayPlaceholder))
matchers = matchers.filter(
(m) => m.placeholder !== '$Ordered' && m.placeholder !== '$Unordered'
)
if (unordered) {
return compileUnorderedArrayMatcher(paths, compileOptions, {
matchers,
})
}
if (matchers.some((m) => m.placeholder || m.arrayPlaceholder)) {
return compileOrderedArrayMatcher(paths, compileOptions, {
matchers,
skipElement,
})
}
return compileExactArrayMatcher(paths, compileOptions, {
matchers,
skipElement,
})
}
function assertArrayMatchersValid(matchers) {
const otherMatchers = []
let arrayMatcherCount = 0
let restMatcher
for (let i = 0; i < matchers.length; i++) {
if (matchers[i].restPlaceholder) {
if (restMatcher) {
throw new CompilePathError(
`can't have two or more rest matchers as siblings`,
matchers[i].pattern
)
} else if (arrayMatcherCount) {
throw new CompilePathError(
`can't mix array and rest matchers`,
matchers[i].pattern
)
} else {
restMatcher = matchers[i]
}
} else if (matchers[i].arrayPlaceholder) {
if (restMatcher) {
throw new CompilePathError(
`can't mix array and rest matchers`,
matchers[i].pattern
)
}
arrayMatcherCount++
} else {
otherMatchers.push(matchers[i])
}
}
}
function compileOrderedArrayMatcher(
paths,
compileOptions,
{ matchers, skipElement = () => false }
) {
const { debug } = compileOptions
function remainingElements(matcherIndex) {
let count = 0
for (let i = matcherIndex; i < matchers.length; i++) {
if (!matchers[i].arrayPlaceholder) count++
}
return count
}
function matchElem(paths, sliceStart, arrayIndex, matcherIndex, matchSoFar) {
while (arrayIndex < paths.length && skipElement(paths[arrayIndex]))
arrayIndex++
if (arrayIndex === paths.length) {
return remainingElements(matcherIndex) === 0 ? matchSoFar || {} : null
}
if (matcherIndex === matchers.length) return null
const matcher = matchers[matcherIndex]
const { arrayPlaceholder } = matcher
if (arrayPlaceholder) {
if (matcherIndex === matchers.length - 1) {
return mergeCaptures(matchSoFar, {
arrayCaptures: {
[arrayPlaceholder]: paths.slice(sliceStart),
},
})
}
return matchElem(
paths,
sliceStart,
arrayIndex,
matcherIndex + 1,
matchSoFar
)
} else {
var _matchers
const origMatchSoFar = matchSoFar
const prevArrayPlaceholder =
(_matchers = matchers[matcherIndex - 1]) === null ||
_matchers === void 0
? void 0
: _matchers.arrayPlaceholder
const end = prevArrayPlaceholder
? paths.length - remainingElements(matcherIndex + 1)
: arrayIndex + 1
for (let i = arrayIndex; i < end; i++) {
const elemPath = paths[i]
if (skipElement(elemPath)) continue
matchSoFar = matcher.match(elemPath, origMatchSoFar)
if (!matchSoFar) continue
if (prevArrayPlaceholder) {
matchSoFar = mergeCaptures(matchSoFar, {
arrayCaptures: {
[prevArrayPlaceholder]: paths.slice(sliceStart, i),
},
})
}
const restMatch = matchElem(
paths,
i + 1,
i + 1,
matcherIndex + 1,
matchSoFar
)
if (restMatch) return restMatch
}
}
return null
}
return {
pattern: paths,
match: (path, matchSoFar) => {
debug('Array (ordered)')
if (!Array.isArray(path.value)) return null
const paths = path.filter(() => true)
let result = matchElem(paths, 0, 0, 0, matchSoFar)
if (!result) return result // make sure all * captures are present in results
// (if there are more than one adjacent *, all captured paths will be in the
// last one and the rest will be empty)
for (const matcher of matchers) {
var _result, _result$arrayCaptures
const { arrayPlaceholder } = matcher
if (!arrayPlaceholder) continue
if (
!(
(_result = result) !== null &&
_result !== void 0 &&
(_result$arrayCaptures = _result.arrayCaptures) !== null &&
_result$arrayCaptures !== void 0 &&
_result$arrayCaptures[arrayPlaceholder]
)
)
result = mergeCaptures(result, {
arrayCaptures: {
[arrayPlaceholder]: [],
},
})
}
return result
},
}
}
function compileUnorderedArrayMatcher(
paths,
compileOptions,
{ matchers, skipElement = () => false }
) {
const { debug } = compileOptions
const restMatcher = matchers.find((m) => m.restPlaceholder)
matchers = matchers.filter((m) => !m.restPlaceholder)
const restPlaceholder =
restMatcher === null || restMatcher === void 0
? void 0
: restMatcher.restPlaceholder
return {
pattern: paths,
match: (path, result) => {
debug('Array (unordered)')
if (!Array.isArray(path.value)) return null
const paths = path.filter(() => true)
for (const m of matchers) {
let i
let found = false
for (i = 0; i < paths.length; i++) {
if (skipElement(paths[i])) {
i++
continue
}
const match = m.match(paths[i], result)
if (!match) continue
result = match
paths.splice(i, 1)
found = true
break
}
if (!found) {
return null
}
}
if (restPlaceholder) {
return mergeCaptures(result, {
arrayCaptures: {
[restPlaceholder]: paths,
},
})
} else {
if (paths.length) {
return null
}
return result || {}
}
},
}
}
function compileExactArrayMatcher(
paths,
compileOptions,
{ matchers, skipElement = () => false }
) {
const { debug } = compileOptions
return {
pattern: paths,
match: (path, matchSoFar) => {
debug('Array (exact)')
if (!Array.isArray(path.value)) return null
const paths = path.filter((p) => !skipElement(p))
let m = 0,
i = 0
while (i < paths.length || m < matchers.length) {
debug(' [%d]', i)
if (i >= paths.length || m >= matchers.length) {
debug(' length mismatch')
return null
}
matchSoFar = matchers[m].match(paths[i], matchSoFar)
if (!matchSoFar) return null
m++
i++
}
return matchSoFar || {}
},
}
} //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJDb21waWxlUGF0aEVycm9yIiwiY29tcGlsZU1hdGNoZXIiLCJtZXJnZUNhcHR1cmVzIiwiaW5kZW50RGVidWciLCJkZWZhdWx0VW5vcmRlcmVkRmllbGRzIiwidHlwZSIsImZpZWxkIiwiZm9yVHlwZSIsImdldERlZmF1bHRVbm9yZGVyZWQiLCJwYXRoIiwiQXJyYXkiLCJpc0FycmF5IiwicGFyZW50IiwicGFyZW50UGF0aCIsIm5vZGUiLCJuYW1lIiwiQm9vbGVhbiIsImNvbXBpbGVHZW5lcmljQXJyYXlNYXRjaGVyIiwiY29tcGlsZU9wdGlvbnMiLCJjb21waWxlRWxlbU1hdGNoZXIiLCJkZWZhdWx0VW5vcmRlcmVkIiwic2tpcEVsZW1lbnQiLCJwYXRocyIsImZpbHRlciIsInBhdHRlcm4iLCJtYXAiLCJwIiwiZGVidWciLCJlbGVtT3B0aW9ucyIsIm1hdGNoZXJzIiwidmFsdWUiLCJpIiwiYXNzZXJ0QXJyYXlNYXRjaGVyc1ZhbGlkIiwidW5vcmRlcmVkIiwic29tZSIsIm0iLCJyZXN0UGxhY2Vob2xkZXIiLCJwbGFjZWhvbGRlciIsImFycmF5UGxhY2Vob2xkZXIiLCJjb21waWxlVW5vcmRlcmVkQXJyYXlNYXRjaGVyIiwiY29tcGlsZU9yZGVyZWRBcnJheU1hdGNoZXIiLCJjb21waWxlRXhhY3RBcnJheU1hdGNoZXIiLCJvdGhlck1hdGNoZXJzIiwiYXJyYXlNYXRjaGVyQ291bnQiLCJyZXN0TWF0Y2hlciIsImxlbmd0aCIsInB1c2giLCJyZW1haW5pbmdFbGVtZW50cyIsIm1hdGNoZXJJbmRleCIsImNvdW50IiwibWF0Y2hFbGVtIiwic2xpY2VTdGFydCIsImFycmF5SW5kZXgiLCJtYXRjaFNvRmFyIiwibWF0Y2hlciIsImFycmF5Q2FwdHVyZXMiLCJzbGljZSIsIm9yaWdNYXRjaFNvRmFyIiwicHJldkFycmF5UGxhY2Vob2xkZXIiLCJlbmQiLCJlbGVtUGF0aCIsIm1hdGNoIiwicmVzdE1hdGNoIiwicmVzdWx0IiwiZmluZCIsImZvdW5kIiwic3BsaWNlIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbXBpbGVNYXRjaGVyL0dlbmVyaWNBcnJheU1hdGNoZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTm9kZVBhdGgsIE5vZGUgfSBmcm9tICcuLi90eXBlcydcbmltcG9ydCBDb21waWxlUGF0aEVycm9yIGZyb20gJy4uL3V0aWwvQ29tcGlsZVBhdGhFcnJvcidcbmltcG9ydCBjb21waWxlTWF0Y2hlciwge1xuICBDb21waWxlZE1hdGNoZXIsXG4gIENvbXBpbGVPcHRpb25zLFxuICBNYXRjaFJlc3VsdCxcbiAgbWVyZ2VDYXB0dXJlcyxcbn0gZnJvbSAnLidcbmltcG9ydCBpbmRlbnREZWJ1ZyBmcm9tICcuL2luZGVudERlYnVnJ1xuXG5jb25zdCBkZWZhdWx0VW5vcmRlcmVkRmllbGRzOiB7IFtrIGluIHN0cmluZ10/OiB7IFtrIGluIHN0cmluZ10/OiB0cnVlIH0gfSA9IHt9XG5mb3IgKGNvbnN0IFt0eXBlLCBmaWVsZF0gb2YgW1xuICBbJ0NsYXNzQm9keScsICdib2R5J10sXG4gIFsnQ2xhc3NEZWNsYXJhdGlvbicsICdpbXBsZW1lbnRzJ10sXG4gIFsnRGVjbGFyZUNsYXNzJywgJ2ltcGxlbWVudHMnXSxcbiAgWydEZWNsYXJlRXhwb3J0RGVjbGFyYXRpb24nLCAnc3BlY2lmaWVycyddLFxuICBbJ0RlY2xhcmVJbnRlcmZhY2UnLCAnZXh0ZW5kcyddLFxuICBbJ0VudW1EZWNsYXJhdGlvbicsICdib2R5J10sXG4gIFsnRXhwb3J0TmFtZWREZWNsYXJhdGlvbicsICdzcGVjaWZpZXJzJ10sXG4gIFsnSW1wb3J0RGVjbGFyYXRpb24nLCAnc3BlY2lmaWVycyddLFxuICBbJ0ludGVyZmFjZURlY2xhcmF0aW9uJywgJ2V4dGVuZHMnXSxcbiAgWydJbnRlcnNlY3Rpb25UeXBlQW5ub3RhdGlvbicsICd0eXBlcyddLFxuICBbJ0pTWE9wZW5pbmdFbGVtZW50JywgJ2F0dHJpYnV0ZXMnXSxcbiAgWydPYmplY3RFeHByZXNzaW9uJywgJ3Byb3BlcnRpZXMnXSxcbiAgWydPYmplY3RQYXR0ZXJuJywgJ3Byb3BlcnRpZXMnXSxcbiAgWydPYmplY3RUeXBlQW5ub3RhdGlvbicsICdwcm9wZXJ0aWVzJ10sXG4gIFsnVFNFbnVtRGVjbGFyYXRpb24nLCAnbWVtYmVycyddLFxuICBbJ1RTSW50ZXJmYWNlQm9keScsICdib2R5J10sXG4gIFsnVFNJbnRlcmZhY2VEZWNsYXJhdGlvbicsICdleHRlbmRzJ10sXG4gIFsnVFNJbnRlcnNlY3Rpb25UeXBlJywgJ3R5cGVzJ10sXG4gIFsnVFNUeXBlTGl0ZXJhbCcsICdtZW1iZXJzJ10sXG4gIFsnVFNVbmlvblR5cGUnLCAndHlwZXMnXSxcbiAgWydVbmlvblR5cGVBbm5vdGF0aW9uJywgJ3R5cGVzJ10sXG5dKSB7XG4gIGNvbnN0IGZvclR5cGUgPVxuICAgIGRlZmF1bHRVbm9yZGVyZWRGaWVsZHNbdHlwZV0gfHwgKGRlZmF1bHRVbm9yZGVyZWRGaWVsZHNbdHlwZV0gPSB7fSlcbiAgZm9yVHlwZVtmaWVsZF0gPSB0cnVlXG59XG5cbmZ1bmN0aW9uIGdldERlZmF1bHRVbm9yZGVyZWQoXG4gIHBhdGg6IE5vZGVQYXRoPE5vZGUsIE5vZGVbXT4gfCBOb2RlUGF0aDxOb2RlLCBOb2RlPltdXG4pOiBib29sZWFuIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkocGF0aCkpIHtcbiAgICBjb25zdCBwYXJlbnQgPSBwYXRoWzBdPy5wYXJlbnRQYXRoXG4gICAgaWYgKCFwYXJlbnQpIHJldHVybiBmYWxzZVxuICAgIHJldHVybiBnZXREZWZhdWx0VW5vcmRlcmVkKHBhcmVudClcbiAgfVxuICBpZiAoIXBhdGgubm9kZSB8fCAhcGF0aC5uYW1lKSByZXR1cm4gZmFsc2VcbiAgcmV0dXJuIEJvb2xlYW4oZGVmYXVsdFVub3JkZXJlZEZpZWxkc1twYXRoLm5vZGUudHlwZV0/LltwYXRoLm5hbWVdKVxufVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBjb21waWxlR2VuZXJpY0FycmF5TWF0Y2hlcihcbiAgcGF0aDogTm9kZVBhdGg8Tm9kZSwgTm9kZVtdPiB8IE5vZGVQYXRoPE5vZGUsIE5vZGU+W10sXG4gIGNvbXBpbGVPcHRpb25zOiBDb21waWxlT3B0aW9ucyxcbiAge1xuICAgIGNvbXBpbGVFbGVtTWF0Y2hlciA9IGNvbXBpbGVNYXRjaGVyLFxuICAgIGRlZmF1bHRVbm9yZGVyZWQgPSBnZXREZWZhdWx0VW5vcmRlcmVkKHBhdGgpLFxuICAgIHNraXBFbGVtZW50ID0gKCkgPT4gZmFsc2UsXG4gIH06IHtcbiAgICBjb21waWxlRWxlbU1hdGNoZXI/OiAoXG4gICAgICBwYXRoOiBOb2RlUGF0aCxcbiAgICAgIG9wdGlvbnM6IENvbXBpbGVPcHRpb25zXG4gICAgKSA9PiBDb21waWxlZE1hdGNoZXJcbiAgICBkZWZhdWx0VW5vcmRlcmVkPzogYm9vbGVhblxuICAgIHNraXBFbGVtZW50PzogKHBhdGg6IE5vZGVQYXRoKSA9PiBib29sZWFuXG4gIH0gPSB7fVxuKTogQ29tcGlsZWRNYXRjaGVyIHtcbiAgY29uc3QgcGF0aHMgPSBBcnJheS5pc0FycmF5KHBhdGgpID8gcGF0aCA6IHBhdGguZmlsdGVyKCgpID0+IHRydWUpXG4gIGNvbnN0IHBhdHRlcm46IE5vZGVbXSA9IHBhdGgubWFwKChwOiBOb2RlUGF0aCkgPT4gcC5ub2RlKVxuICBjb25zdCB7IGRlYnVnIH0gPSBjb21waWxlT3B0aW9uc1xuICBjb25zdCBlbGVtT3B0aW9ucyA9IHtcbiAgICAuLi5jb21waWxlT3B0aW9ucyxcbiAgICBkZWJ1ZzogaW5kZW50RGVidWcoZGVidWcsIDIpLFxuICB9XG4gIGxldCBtYXRjaGVyczogQ29tcGlsZWRNYXRjaGVyW10gPSBwYXR0ZXJuLm1hcCgodmFsdWUsIGkpID0+XG4gICAgY29tcGlsZUVsZW1NYXRjaGVyKHBhdGhzW2ldLCBlbGVtT3B0aW9ucylcbiAgKVxuXG4gIGFzc2VydEFycmF5TWF0Y2hlcnNWYWxpZChtYXRjaGVycylcblxuICBjb25zdCB1bm9yZGVyZWQgPVxuICAgIG1hdGNoZXJzLnNvbWUoKG0pID0+IG0ucmVzdFBsYWNlaG9sZGVyIHx8IG0ucGxhY2Vob2xkZXIgPT09ICckVW5vcmRlcmVkJykgfHxcbiAgICAoZGVmYXVsdFVub3JkZXJlZCAmJlxuICAgICAgIW1hdGNoZXJzLnNvbWUoKG0pID0+IG0ucGxhY2Vob2xkZXIgPT09ICckT3JkZXJlZCcgfHwgbS5hcnJheVBsYWNlaG9sZGVyKSlcblxuICBtYXRjaGVycyA9IG1hdGNoZXJzLmZpbHRlcihcbiAgICAobSkgPT4gbS5wbGFjZWhvbGRlciAhPT0gJyRPcmRlcmVkJyAmJiBtLnBsYWNlaG9sZGVyICE9PSAnJFVub3JkZXJlZCdcbiAgKVxuXG4gIGlmICh1bm9yZGVyZWQpIHtcbiAgICByZXR1cm4gY29tcGlsZVVub3JkZXJlZEFycmF5TWF0Y2hlcihwYXRocywgY29tcGlsZU9wdGlvbnMsIHtcbiAgICAgIG1hdGNoZXJzLFxuICAgIH0pXG4gIH1cblxuICBpZiAobWF0Y2hlcnMuc29tZSgobSkgPT4gbS5wbGFjZWhvbGRlciB8fCBtLmFycmF5UGxhY2Vob2xkZXIpKSB7XG4gICAgcmV0dXJuIGNvbXBpbGVPcmRlcmVkQXJyYXlNYXRjaGVyKHBhdGhzLCBjb21waWxlT3B0aW9ucywge1xuICAgICAgbWF0Y2hlcnMsXG4gICAgICBza2lwRWxlbWVudCxcbiAgICB9KVxuICB9XG5cbiAgcmV0dXJuIGNvbXBpbGVFeGFjdEFycmF5TWF0Y2hlcihwYXRocywgY29tcGlsZU9wdGlvbnMsIHtcbiAgICBtYXRjaGVycyxcbiAgICBza2lwRWxlbWVudCxcbiAgfSlcbn1cblxuZnVuY3Rpb24gYXNzZXJ0QXJyYXlNYXRjaGVyc1ZhbGlkKG1hdGNoZXJzOiBDb21waWxlZE1hdGNoZXJbXSkge1xuICBjb25zdCBvdGhlck1hdGNoZXJzOiBDb21waWxlZE1hdGNoZXJbXSA9IFtdXG4gIGxldCBhcnJheU1hdGNoZXJDb3VudCA9IDBcbiAgbGV0IHJlc3RNYXRjaGVyXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbWF0Y2hlcnMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAobWF0Y2hlcnNbaV0ucmVzdFBsYWNlaG9sZGVyKSB7XG4gICAgICBpZiAocmVzdE1hdGNoZXIpIHtcbiAgICAgICAgdGhyb3cgbmV3IENvbXBpbGVQYXRoRXJyb3IoXG4gICAgICAgICAgYGNhbid0IGhhdmUgdHdvIG9yIG1vcmUgcmVzdCBtYXRjaGVycyBhcyBzaWJsaW5nc2AsXG4gICAgICAgICAgbWF0Y2hlcnNbaV0ucGF0dGVybiBhcyBOb2RlUGF0aFxuICAgICAgICApXG4gICAgICB9IGVsc2UgaWYgKGFycmF5TWF0Y2hlckNvdW50KSB7XG4gICAgICAgIHRocm93IG5ldyBDb21waWxlUGF0aEVycm9yKFxuICAgICAgICAgIGBjYW4ndCBtaXggYXJyYXkgYW5kIHJlc3QgbWF0Y2hlcnNgLFxuICAgICAgICAgIG1hdGNoZXJzW2ldLnBhdHRlcm4gYXMgTm9kZVBhdGhcbiAgICAgICAgKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdE1hdGNoZXIgPSBtYXRjaGVyc1tpXVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobWF0Y2hlcnNbaV0uYXJyYXlQbGFjZWhvbGRlcikge1xuICAgICAgaWYgKHJlc3RNYXRjaGVyKSB7XG4gICAgICAgIHRocm93IG5ldyBDb21waWxlUGF0aEVycm9yKFxuICAgICAgICAgIGBjYW4ndCBtaXggYXJyYXkgYW5kIHJlc3QgbWF0Y2hlcnNgLFxuICAgICAgICAgIG1hdGNoZXJzW2ldLnBhdHRlcm4gYXMgTm9kZVBhdGhcbiAgICAgICAgKVxuICAgICAgfVxuICAgICAgYXJyYXlNYXRjaGVyQ291bnQrK1xuICAgIH0gZWxzZSB7XG4gICAgICBvdGhlck1hdGNoZXJzLnB1c2gobWF0Y2hlcnNbaV0pXG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNvbXBpbGVPcmRlcmVkQXJyYXlNYXRjaGVyKFxuICBwYXRoczogTm9kZVBhdGg8Tm9kZSwgTm9kZT5bXSxcbiAgY29tcGlsZU9wdGlvbnM6IENvbXBpbGVPcHRpb25zLFxuICB7XG4gICAgbWF0Y2hlcnMsXG4gICAgc2tpcEVsZW1lbnQgPSAoKSA9PiBmYWxzZSxcbiAgfToge1xuICAgIG1hdGNoZXJzOiBDb21waWxlZE1hdGNoZXJbXVxuICAgIHNraXBFbGVtZW50PzogKHBhdGg6IE5vZGVQYXRoKSA9PiBib29sZWFuXG4gIH1cbik6IENvbXBpbGVkTWF0Y2hlciB7XG4gIGNvbnN0IHsgZGVidWcgfSA9IGNvbXBpbGVPcHRpb25zXG5cbiAgZnVuY3Rpb24gcmVtYWluaW5nRWxlbWVudHMobWF0Y2hlckluZGV4OiBudW1iZXIpOiBudW1iZXIge1xuICAgIGxldCBjb3VudCA9IDBcbiAgICBmb3IgKGxldCBpID0gbWF0Y2hlckluZGV4OyBpIDwgbWF0Y2hlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmICghbWF0Y2hlcnNbaV0uYXJyYXlQbGFjZWhvbGRlcikgY291bnQrK1xuICAgIH1cbiAgICByZXR1cm4gY291bnRcbiAgfVxuXG4gIGZ1bmN0aW9uIG1hdGNoRWxlbShcbiAgICBwYXRoczogTm9kZVBhdGhbXSxcbiAgICBzbGljZVN0YXJ0OiBudW1iZXIsXG4gICAgYXJyYXlJbmRleDogbnVtYmVyLFxuICAgIG1hdGNoZXJJbmRleDogbnVtYmVyLFxuICAgIG1hdGNoU29GYXI6IE1hdGNoUmVzdWx0XG4gICk6IE1hdGNoUmVzdWx0IHtcbiAgICB3aGlsZSAoYXJyYXlJbmRleCA8IHBhdGhzLmxlbmd0aCAmJiBza2lwRWxlbWVudChwYXRoc1thcnJheUluZGV4XSkpXG4gICAgICBhcnJheUluZGV4KytcblxuICAgIGlmIChhcnJheUluZGV4ID09PSBwYXRocy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiByZW1haW5pbmdFbGVtZW50cyhtYXRjaGVySW5kZXgpID09PSAwID8gbWF0Y2hTb0ZhciB8fCB7fSA6IG51bGxcbiAgICB9XG5cbiAgICBpZiAobWF0Y2hlckluZGV4ID09PSBtYXRjaGVycy5sZW5ndGgpIHJldHVybiBudWxsXG5cbiAgICBjb25zdCBtYXRjaGVyID0gbWF0Y2hlcnNbbWF0Y2hlckluZGV4XVxuXG4gICAgY29uc3QgeyBhcnJheVBsYWNlaG9sZGVyIH0gPSBtYXRjaGVyXG5cbiAgICBpZiAoYXJyYXlQbGFjZWhvbGRlcikge1xuICAgICAgaWYgKG1hdGNoZXJJbmRleCA9PT0gbWF0Y2hlcnMubGVuZ3RoIC0gMSkge1xuICAgICAgICByZXR1cm4gbWVyZ2VDYXB0dXJlcyhtYXRjaFNvRmFyLCB7XG4gICAgICAgICAgYXJyYXlDYXB0dXJlczoge1xuICAgICAgICAgICAgW2FycmF5UGxhY2Vob2xkZXJdOiBwYXRocy5zbGljZShzbGljZVN0YXJ0KSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gbWF0Y2hFbGVtKFxuICAgICAgICBwYXRocyxcbiAgICAgICAgc2xpY2VTdGFydCxcbiAgICAgICAgYXJyYXlJbmRleCxcbiAgICAgICAgbWF0Y2hlckluZGV4ICsgMSxcbiAgICAgICAgbWF0Y2hTb0ZhclxuICAgICAgKVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBvcmlnTWF0Y2hTb0ZhciA9IG1hdGNoU29GYXJcbiAgICAgIGNvbnN0IHByZXZBcnJheVBsYWNlaG9sZGVyID0gbWF0Y2hlcnNbbWF0Y2hlckluZGV4IC0gMV0/LmFycmF5UGxhY2Vob2xkZXJcbiAgICAgIGNvbnN0IGVuZCA9IHByZXZBcnJheVBsYWNlaG9sZGVyXG4gICAgICAgID8gcGF0aHMubGVuZ3RoIC0gcmVtYWluaW5nRWxlbWVudHMobWF0Y2hlckluZGV4ICsgMSlcbiAgICAgICAgOiBhcnJheUluZGV4ICsgMVxuXG4gICAgICBmb3IgKGxldCBpID0gYXJyYXlJbmRleDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGVsZW1QYXRoID0gcGF0aHNbaV1cblxuICAgICAgICBpZiAoc2tpcEVsZW1lbnQoZWxlbVBhdGgpKSBjb250aW51ZVxuXG4gICAgICAgIG1hdGNoU29GYXIgPSBtYXRjaGVyLm1hdGNoKGVsZW1QYXRoLCBvcmlnTWF0Y2hTb0ZhcilcblxuICAgICAgICBpZiAoIW1hdGNoU29GYXIpIGNvbnRpbnVlXG5cbiAgICAgICAgaWYgKHByZXZBcnJheVBsYWNlaG9sZGVyKSB7XG4gICAgICAgICAgbWF0Y2hTb0ZhciA9IG1lcmdlQ2FwdHVyZXMobWF0Y2hTb0Zhciwge1xuICAgICAgICAgICAgYXJyYXlDYXB0dXJlczoge1xuICAgICAgICAgICAgICBbcHJldkFycmF5UGxhY2Vob2xkZXJdOiBwYXRocy5zbGljZShzbGljZVN0YXJ0LCBpKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3RNYXRjaCA9IG1hdGNoRWxlbShcbiAgICAgICAgICBwYXRocyxcbiAgICAgICAgICBpICsgMSxcbiAgICAgICAgICBpICsgMSxcbiAgICAgICAgICBtYXRjaGVySW5kZXggKyAxLFxuICAgICAgICAgIG1hdGNoU29GYXJcbiAgICAgICAgKVxuXG4gICAgICAgIGlmIChyZXN0TWF0Y2gpIHJldHVybiByZXN0TWF0Y2hcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBwYXR0ZXJuOiBwYXRocyxcbiAgICBtYXRjaDogKHBhdGg6IE5vZGVQYXRoLCBtYXRjaFNvRmFyOiBNYXRjaFJlc3VsdCk6IE1hdGNoUmVzdWx0ID0+IHtcbiAgICAgIGRlYnVnKCdBcnJheSAob3JkZXJlZCknKVxuXG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkocGF0aC52YWx1ZSkpIHJldHVybiBudWxsXG4gICAgICBjb25zdCBwYXRocyA9IChwYXRoIGFzIE5vZGVQYXRoPE5vZGUsIE5vZGVbXT4pLmZpbHRlcigoKSA9PiB0cnVlKVxuXG4gICAgICBsZXQgcmVzdWx0ID0gbWF0Y2hFbGVtKHBhdGhzLCAwLCAwLCAwLCBtYXRjaFNvRmFyKVxuICAgICAgaWYgKCFyZXN1bHQpIHJldHVybiByZXN1bHRcblxuICAgICAgLy8gbWFrZSBzdXJlIGFsbCAqIGNhcHR1cmVzIGFyZSBwcmVzZW50IGluIHJlc3VsdHNcbiAgICAgIC8vIChpZiB0aGVyZSBhcmUgbW9yZSB0aGFuIG9uZSBhZGphY2VudCAqLCBhbGwgY2FwdHVyZWQgcGF0aHMgd2lsbCBiZSBpbiB0aGVcbiAgICAgIC8vIGxhc3Qgb25lIGFuZCB0aGUgcmVzdCB3aWxsIGJlIGVtcHR5KVxuICAgICAgZm9yIChjb25zdCBtYXRjaGVyIG9mIG1hdGNoZXJzKSB7XG4gICAgICAgIGNvbnN0IHsgYXJyYXlQbGFjZWhvbGRlciB9ID0gbWF0Y2hlclxuICAgICAgICBpZiAoIWFycmF5UGxhY2Vob2xkZXIpIGNvbnRpbnVlXG4gICAgICAgIGlmICghcmVzdWx0Py5hcnJheUNhcHR1cmVzPy5bYXJyYXlQbGFjZWhvbGRlcl0pXG4gICAgICAgICAgcmVzdWx0ID0gbWVyZ2VDYXB0dXJlcyhyZXN1bHQsIHtcbiAgICAgICAgICAgIGFycmF5Q2FwdHVyZXM6IHsgW2FycmF5UGxhY2Vob2xkZXJdOiBbXSB9LFxuICAgICAgICAgIH0pXG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0XG4gICAgfSxcbiAgfVxufVxuXG5mdW5jdGlvbiBjb21waWxlVW5vcmRlcmVkQXJyYXlNYXRjaGVyKFxuICBwYXRoczogTm9kZVBhdGg8Tm9kZSwgTm9kZT5bXSxcbiAgY29tcGlsZU9wdGlvbnM6IENvbXBpbGVPcHRpb25zLFxuICB7XG4gICAgbWF0Y2hlcnMsXG4gICAgc2tpcEVsZW1lbnQgPSAoKSA9PiBmYWxzZSxcbiAgfToge1xuICAgIG1hdGNoZXJzOiBDb21waWxlZE1hdGNoZXJbXVxuICAgIHNraXBFbGVtZW50PzogKHBhdGg6IE5vZGVQYXRoKSA9PiBib29sZWFuXG4gIH1cbik6IENvbXBpbGVkTWF0Y2hlciB7XG4gIGNvbnN0IHsgZGVidWcgfSA9IGNvbXBpbGVPcHRpb25zXG5cbiAgY29uc3QgcmVzdE1hdGNoZXIgPSBtYXRjaGVycy5maW5kKChtKSA9PiBtLnJlc3RQbGFjZWhvbGRlcilcbiAgbWF0Y2hlcnMgPSBtYXRjaGVycy5maWx0ZXIoKG0pID0+ICFtLnJlc3RQbGFjZWhvbGRlcilcbiAgY29uc3QgcmVzdFBsYWNlaG9sZGVyID0gcmVzdE1hdGNoZXI/LnJlc3RQbGFjZWhvbGRlclxuXG4gIHJldHVybiB7XG4gICAgcGF0dGVybjogcGF0aHMsXG4gICAgbWF0Y2g6IChwYXRoOiBOb2RlUGF0aCwgcmVzdWx0OiBNYXRjaFJlc3VsdCk6IE1hdGNoUmVzdWx0ID0+IHtcbiAgICAgIGRlYnVnKCdBcnJheSAodW5vcmRlcmVkKScpXG5cbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShwYXRoLnZhbHVlKSkgcmV0dXJuIG51bGxcblxuICAgICAgY29uc3QgcGF0aHMgPSAocGF0aCBhcyBOb2RlUGF0aDxOb2RlLCBOb2RlW10+KS5maWx0ZXIoKCkgPT4gdHJ1ZSlcblxuICAgICAgZm9yIChjb25zdCBtIG9mIG1hdGNoZXJzKSB7XG4gICAgICAgIGxldCBpXG4gICAgICAgIGxldCBmb3VuZCA9IGZhbHNlXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBwYXRocy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGlmIChza2lwRWxlbWVudChwYXRoc1tpXSkpIHtcbiAgICAgICAgICAgIGkrK1xuICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgbWF0Y2ggPSBtLm1hdGNoKHBhdGhzW2ldLCByZXN1bHQpXG4gICAgICAgICAgaWYgKCFtYXRjaCkgY29udGludWVcbiAgICAgICAgICByZXN1bHQgPSBtYXRjaFxuICAgICAgICAgIHBhdGhzLnNwbGljZShpLCAxKVxuICAgICAgICAgIGZvdW5kID0gdHJ1ZVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFmb3VuZCkge1xuICAgICAgICAgIHJldHVybiBudWxsXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChyZXN0UGxhY2Vob2xkZXIpIHtcbiAgICAgICAgcmV0dXJuIG1lcmdlQ2FwdHVyZXMocmVzdWx0LCB7XG4gICAgICAgICAgYXJyYXlDYXB0dXJlczogeyBbcmVzdFBsYWNlaG9sZGVyXTogcGF0aHMgfSxcbiAgICAgICAgfSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChwYXRocy5sZW5ndGgpIHtcbiAgICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwge31cbiAgICAgIH1cbiAgICB9LFxuICB9XG59XG5cbmZ1bmN0aW9uIGNvbXBpbGVFeGFjdEFycmF5TWF0Y2hlcihcbiAgcGF0aHM6IE5vZGVQYXRoPE5vZGUsIE5vZGU+W10sXG4gIGNvbXBpbGVPcHRpb25zOiBDb21waWxlT3B0aW9ucyxcbiAge1xuICAgIG1hdGNoZXJzLFxuICAgIHNraXBFbGVtZW50ID0gKCkgPT4gZmFsc2UsXG4gIH06IHtcbiAgICBtYXRjaGVyczogQ29tcGlsZWRNYXRjaGVyW11cbiAgICBza2lwRWxlbWVudD86IChwYXRoOiBOb2RlUGF0aCkgPT4gYm9vbGVhblxuICB9XG4pOiBDb21waWxlZE1hdGNoZXIge1xuICBjb25zdCB7IGRlYnVnIH0gPSBjb21waWxlT3B0aW9uc1xuICByZXR1cm4ge1xuICAgIHBhdHRlcm46IHBhdGhzLFxuICAgIG1hdGNoOiAocGF0aDogTm9kZVBhdGgsIG1hdGNoU29GYXI6IE1hdGNoUmVzdWx0KTogTWF0Y2hSZXN1bHQgPT4ge1xuICAgICAgZGVidWcoJ0FycmF5IChleGFjdCknKVxuXG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkocGF0aC52YWx1ZSkpIHJldHVybiBudWxsXG5cbiAgICAgIGNvbnN0IHBhdGhzID0gcGF0aC5maWx0ZXIoKHApID0+ICFza2lwRWxlbWVudChwKSlcblxuICAgICAgbGV0IG0gPSAwLFxuICAgICAgICBpID0gMFxuICAgICAgd2hpbGUgKGkgPCBwYXRocy5sZW5ndGggfHwgbSA8IG1hdGNoZXJzLmxlbmd0aCkge1xuICAgICAgICBkZWJ1ZygnICBbJWRdJywgaSlcbiAgICAgICAgaWYgKGkgPj0gcGF0aHMubGVuZ3RoIHx8IG0gPj0gbWF0Y2hlcnMubGVuZ3RoKSB7XG4gICAgICAgICAgZGVidWcoJyAgICBsZW5ndGggbWlzbWF0Y2gnKVxuICAgICAgICAgIHJldHVybiBudWxsXG4gICAgICAgIH1cbiAgICAgICAgbWF0Y2hTb0ZhciA9IG1hdGNoZXJzW21dLm1hdGNoKHBhdGhzW2ldLCBtYXRjaFNvRmFyKVxuICAgICAgICBpZiAoIW1hdGNoU29GYXIpIHJldHVybiBudWxsXG4gICAgICAgIG0rK1xuICAgICAgICBpKytcbiAgICAgIH1cbiAgICAgIHJldHVybiBtYXRjaFNvRmFyIHx8IHt9XG4gICAgfSxcbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiO0FBQ0EsT0FBT0EsZ0JBQVAsTUFBNkIsMEJBQTdCO0FBQ0EsT0FBT0MsY0FBUDs7OztBQUlFQyxhQUpGO0FBS08sR0FMUDtBQU1BLE9BQU9DLFdBQVAsTUFBd0IsZUFBeEI7O0FBRUEsTUFBTUMsc0JBQW9FLEdBQUcsRUFBN0U7QUFDQSxLQUFLLE1BQU0sQ0FBQ0MsSUFBRCxFQUFPQyxLQUFQLENBQVgsSUFBNEI7QUFDMUIsQ0FBQyxXQUFELEVBQWMsTUFBZCxDQUQwQjtBQUUxQixDQUFDLGtCQUFELEVBQXFCLFlBQXJCLENBRjBCO0FBRzFCLENBQUMsY0FBRCxFQUFpQixZQUFqQixDQUgwQjtBQUkxQixDQUFDLDBCQUFELEVBQTZCLFlBQTdCLENBSjBCO0FBSzFCLENBQUMsa0JBQUQsRUFBcUIsU0FBckIsQ0FMMEI7QUFNMUIsQ0FBQyxpQkFBRCxFQUFvQixNQUFwQixDQU4wQjtBQU8xQixDQUFDLHdCQUFELEVBQTJCLFlBQTNCLENBUDBCO0FBUTFCLENBQUMsbUJBQUQsRUFBc0IsWUFBdEIsQ0FSMEI7QUFTMUIsQ0FBQyxzQkFBRCxFQUF5QixTQUF6QixDQVQwQjtBQVUxQixDQUFDLDRCQUFELEVBQStCLE9BQS9CLENBVjBCO0FBVzFCLENBQUMsbUJBQUQsRUFBc0IsWUFBdEIsQ0FYMEI7QUFZMUIsQ0FBQyxrQkFBRCxFQUFxQixZQUFyQixDQVowQjtBQWEx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