{"version":3,"file":"casbin-core.mjs","sources":["../node_modules/base64-js/index.js","../node_modules/ieee754/index.js","../node_modules/buffer/index.js","../src/util/ip.ts","../node_modules/minimatch/lib/path.js","../node_modules/balanced-match/index.js","../node_modules/brace-expansion/index.js","../node_modules/minimatch/minimatch.js","../src/util/builtinOperators.ts","../src/util/util.ts","../src/config.ts","../node_modules/jsep/build/jsep.js","../node_modules/expression-eval/index.ts","../src/effect/effector.ts","../src/effect/defaultEffectorStream.ts","../src/effect/defaultEffector.ts","../src/log/defaultLogger.ts","../src/log/logUtil.ts","../src/rbac/defaultRoleManager.ts","../src/model/model.ts","../src/model/assertion.ts","../src/model/functionMap.ts","../src/enforceContext.ts","../src/persist/helper.ts","../src/persist/memoryAdapter.ts","../src/persist/defaultFilteredAdapter.ts","../src/enforcer.ts","../src/coreEnforcer.ts","../src/internalEnforcer.ts","../src/managementEnforcer.ts","../src/cachedEnforcer.ts","../node_modules/await-lock/src/AwaitLock.ts","../src/syncedEnforcer.ts","../src/frontend.ts"],"sourcesContent":["'use strict'\n\nexports.byteLength = byteLength\nexports.toByteArray = toByteArray\nexports.fromByteArray = fromByteArray\n\nvar lookup = []\nvar revLookup = []\nvar Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array\n\nvar code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\nfor (var i = 0, len = code.length; i < len; ++i) {\n  lookup[i] = code[i]\n  revLookup[code.charCodeAt(i)] = i\n}\n\n// Support decoding URL-safe base64 strings, as Node.js does.\n// See: https://en.wikipedia.org/wiki/Base64#URL_applications\nrevLookup['-'.charCodeAt(0)] = 62\nrevLookup['_'.charCodeAt(0)] = 63\n\nfunction getLens (b64) {\n  var len = b64.length\n\n  if (len % 4 > 0) {\n    throw new Error('Invalid string. Length must be a multiple of 4')\n  }\n\n  // Trim off extra bytes after placeholder bytes are found\n  // See: https://github.com/beatgammit/base64-js/issues/42\n  var validLen = b64.indexOf('=')\n  if (validLen === -1) validLen = len\n\n  var placeHoldersLen = validLen === len\n    ? 0\n    : 4 - (validLen % 4)\n\n  return [validLen, placeHoldersLen]\n}\n\n// base64 is 4/3 + up to two characters of the original data\nfunction byteLength (b64) {\n  var lens = getLens(b64)\n  var validLen = lens[0]\n  var placeHoldersLen = lens[1]\n  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction _byteLength (b64, validLen, placeHoldersLen) {\n  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction toByteArray (b64) {\n  var tmp\n  var lens = getLens(b64)\n  var validLen = lens[0]\n  var placeHoldersLen = lens[1]\n\n  var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))\n\n  var curByte = 0\n\n  // if there are placeholders, only get up to the last complete 4 chars\n  var len = placeHoldersLen > 0\n    ? validLen - 4\n    : validLen\n\n  var i\n  for (i = 0; i < len; i += 4) {\n    tmp =\n      (revLookup[b64.charCodeAt(i)] << 18) |\n      (revLookup[b64.charCodeAt(i + 1)] << 12) |\n      (revLookup[b64.charCodeAt(i + 2)] << 6) |\n      revLookup[b64.charCodeAt(i + 3)]\n    arr[curByte++] = (tmp >> 16) & 0xFF\n    arr[curByte++] = (tmp >> 8) & 0xFF\n    arr[curByte++] = tmp & 0xFF\n  }\n\n  if (placeHoldersLen === 2) {\n    tmp =\n      (revLookup[b64.charCodeAt(i)] << 2) |\n      (revLookup[b64.charCodeAt(i + 1)] >> 4)\n    arr[curByte++] = tmp & 0xFF\n  }\n\n  if (placeHoldersLen === 1) {\n    tmp =\n      (revLookup[b64.charCodeAt(i)] << 10) |\n      (revLookup[b64.charCodeAt(i + 1)] << 4) |\n      (revLookup[b64.charCodeAt(i + 2)] >> 2)\n    arr[curByte++] = (tmp >> 8) & 0xFF\n    arr[curByte++] = tmp & 0xFF\n  }\n\n  return arr\n}\n\nfunction tripletToBase64 (num) {\n  return lookup[num >> 18 & 0x3F] +\n    lookup[num >> 12 & 0x3F] +\n    lookup[num >> 6 & 0x3F] +\n    lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n  var tmp\n  var output = []\n  for (var i = start; i < end; i += 3) {\n    tmp =\n      ((uint8[i] << 16) & 0xFF0000) +\n      ((uint8[i + 1] << 8) & 0xFF00) +\n      (uint8[i + 2] & 0xFF)\n    output.push(tripletToBase64(tmp))\n  }\n  return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n  var tmp\n  var len = uint8.length\n  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n  var parts = []\n  var maxChunkLength = 16383 // must be multiple of 3\n\n  // go through the array every three bytes, we'll deal with trailing stuff later\n  for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n    parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))\n  }\n\n  // pad the end with zeros, but make sure to not forget the extra bytes\n  if (extraBytes === 1) {\n    tmp = uint8[len - 1]\n    parts.push(\n      lookup[tmp >> 2] +\n      lookup[(tmp << 4) & 0x3F] +\n      '=='\n    )\n  } else if (extraBytes === 2) {\n    tmp = (uint8[len - 2] << 8) + uint8[len - 1]\n    parts.push(\n      lookup[tmp >> 10] +\n      lookup[(tmp >> 4) & 0x3F] +\n      lookup[(tmp << 2) & 0x3F] +\n      '='\n    )\n  }\n\n  return parts.join('')\n}\n","/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */\nexports.read = function (buffer, offset, isLE, mLen, nBytes) {\n  var e, m\n  var eLen = (nBytes * 8) - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var nBits = -7\n  var i = isLE ? (nBytes - 1) : 0\n  var d = isLE ? -1 : 1\n  var s = buffer[offset + i]\n\n  i += d\n\n  e = s & ((1 << (-nBits)) - 1)\n  s >>= (-nBits)\n  nBits += eLen\n  for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n  m = e & ((1 << (-nBits)) - 1)\n  e >>= (-nBits)\n  nBits += mLen\n  for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n  if (e === 0) {\n    e = 1 - eBias\n  } else if (e === eMax) {\n    return m ? NaN : ((s ? -1 : 1) * Infinity)\n  } else {\n    m = m + Math.pow(2, mLen)\n    e = e - eBias\n  }\n  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\n}\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n  var e, m, c\n  var eLen = (nBytes * 8) - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\n  var i = isLE ? 0 : (nBytes - 1)\n  var d = isLE ? 1 : -1\n  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\n\n  value = Math.abs(value)\n\n  if (isNaN(value) || value === Infinity) {\n    m = isNaN(value) ? 1 : 0\n    e = eMax\n  } else {\n    e = Math.floor(Math.log(value) / Math.LN2)\n    if (value * (c = Math.pow(2, -e)) < 1) {\n      e--\n      c *= 2\n    }\n    if (e + eBias >= 1) {\n      value += rt / c\n    } else {\n      value += rt * Math.pow(2, 1 - eBias)\n    }\n    if (value * c >= 2) {\n      e++\n      c /= 2\n    }\n\n    if (e + eBias >= eMax) {\n      m = 0\n      e = eMax\n    } else if (e + eBias >= 1) {\n      m = ((value * c) - 1) * Math.pow(2, mLen)\n      e = e + eBias\n    } else {\n      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\n      e = 0\n    }\n  }\n\n  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n  e = (e << mLen) | m\n  eLen += mLen\n  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n  buffer[offset + i - d] |= s * 128\n}\n","/*!\n * The buffer module from node.js, for the browser.\n *\n * @author   Feross Aboukhadijeh <https://feross.org>\n * @license  MIT\n */\n/* eslint-disable no-proto */\n\n'use strict'\n\nconst base64 = require('base64-js')\nconst ieee754 = require('ieee754')\nconst customInspectSymbol =\n  (typeof Symbol === 'function' && typeof Symbol['for'] === 'function') // eslint-disable-line dot-notation\n    ? Symbol['for']('nodejs.util.inspect.custom') // eslint-disable-line dot-notation\n    : null\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\n\nconst K_MAX_LENGTH = 0x7fffffff\nexports.kMaxLength = K_MAX_LENGTH\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n *   === true    Use Uint8Array implementation (fastest)\n *   === false   Print warning and recommend using `buffer` v4.x which has an Object\n *               implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * We report that the browser does not support typed arrays if the are not subclassable\n * using __proto__. Firefox 4-29 lacks support for adding new properties to `Uint8Array`\n * (See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks support\n * for __proto__ and has a buggy typed array implementation.\n */\nBuffer.TYPED_ARRAY_SUPPORT = typedArraySupport()\n\nif (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' &&\n    typeof console.error === 'function') {\n  console.error(\n    'This browser lacks typed array (Uint8Array) support which is required by ' +\n    '`buffer` v5.x. Use `buffer` v4.x if you require old browser support.'\n  )\n}\n\nfunction typedArraySupport () {\n  // Can typed array instances can be augmented?\n  try {\n    const arr = new Uint8Array(1)\n    const proto = { foo: function () { return 42 } }\n    Object.setPrototypeOf(proto, Uint8Array.prototype)\n    Object.setPrototypeOf(arr, proto)\n    return arr.foo() === 42\n  } catch (e) {\n    return false\n  }\n}\n\nObject.defineProperty(Buffer.prototype, 'parent', {\n  enumerable: true,\n  get: function () {\n    if (!Buffer.isBuffer(this)) return undefined\n    return this.buffer\n  }\n})\n\nObject.defineProperty(Buffer.prototype, 'offset', {\n  enumerable: true,\n  get: function () {\n    if (!Buffer.isBuffer(this)) return undefined\n    return this.byteOffset\n  }\n})\n\nfunction createBuffer (length) {\n  if (length > K_MAX_LENGTH) {\n    throw new RangeError('The value \"' + length + '\" is invalid for option \"size\"')\n  }\n  // Return an augmented `Uint8Array` instance\n  const buf = new Uint8Array(length)\n  Object.setPrototypeOf(buf, Buffer.prototype)\n  return buf\n}\n\n/**\n * The Buffer constructor returns instances of `Uint8Array` that have their\n * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of\n * `Uint8Array`, so the returned instances will have all the node `Buffer` methods\n * and the `Uint8Array` methods. Square bracket notation works as expected -- it\n * returns a single octet.\n *\n * The `Uint8Array` prototype remains unmodified.\n */\n\nfunction Buffer (arg, encodingOrOffset, length) {\n  // Common case.\n  if (typeof arg === 'number') {\n    if (typeof encodingOrOffset === 'string') {\n      throw new TypeError(\n        'The \"string\" argument must be of type string. Received type number'\n      )\n    }\n    return allocUnsafe(arg)\n  }\n  return from(arg, encodingOrOffset, length)\n}\n\nBuffer.poolSize = 8192 // not used by this implementation\n\nfunction from (value, encodingOrOffset, length) {\n  if (typeof value === 'string') {\n    return fromString(value, encodingOrOffset)\n  }\n\n  if (ArrayBuffer.isView(value)) {\n    return fromArrayView(value)\n  }\n\n  if (value == null) {\n    throw new TypeError(\n      'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +\n      'or Array-like Object. Received type ' + (typeof value)\n    )\n  }\n\n  if (isInstance(value, ArrayBuffer) ||\n      (value && isInstance(value.buffer, ArrayBuffer))) {\n    return fromArrayBuffer(value, encodingOrOffset, length)\n  }\n\n  if (typeof SharedArrayBuffer !== 'undefined' &&\n      (isInstance(value, SharedArrayBuffer) ||\n      (value && isInstance(value.buffer, SharedArrayBuffer)))) {\n    return fromArrayBuffer(value, encodingOrOffset, length)\n  }\n\n  if (typeof value === 'number') {\n    throw new TypeError(\n      'The \"value\" argument must not be of type number. Received type number'\n    )\n  }\n\n  const valueOf = value.valueOf && value.valueOf()\n  if (valueOf != null && valueOf !== value) {\n    return Buffer.from(valueOf, encodingOrOffset, length)\n  }\n\n  const b = fromObject(value)\n  if (b) return b\n\n  if (typeof Symbol !== 'undefined' && Symbol.toPrimitive != null &&\n      typeof value[Symbol.toPrimitive] === 'function') {\n    return Buffer.from(value[Symbol.toPrimitive]('string'), encodingOrOffset, length)\n  }\n\n  throw new TypeError(\n    'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +\n    'or Array-like Object. Received type ' + (typeof value)\n  )\n}\n\n/**\n * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError\n * if value is a number.\n * Buffer.from(str[, encoding])\n * Buffer.from(array)\n * Buffer.from(buffer)\n * Buffer.from(arrayBuffer[, byteOffset[, length]])\n **/\nBuffer.from = function (value, encodingOrOffset, length) {\n  return from(value, encodingOrOffset, length)\n}\n\n// Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug:\n// https://github.com/feross/buffer/pull/148\nObject.setPrototypeOf(Buffer.prototype, Uint8Array.prototype)\nObject.setPrototypeOf(Buffer, Uint8Array)\n\nfunction assertSize (size) {\n  if (typeof size !== 'number') {\n    throw new TypeError('\"size\" argument must be of type number')\n  } else if (size < 0) {\n    throw new RangeError('The value \"' + size + '\" is invalid for option \"size\"')\n  }\n}\n\nfunction alloc (size, fill, encoding) {\n  assertSize(size)\n  if (size <= 0) {\n    return createBuffer(size)\n  }\n  if (fill !== undefined) {\n    // Only pay attention to encoding if it's a string. This\n    // prevents accidentally sending in a number that would\n    // be interpreted as a start offset.\n    return typeof encoding === 'string'\n      ? createBuffer(size).fill(fill, encoding)\n      : createBuffer(size).fill(fill)\n  }\n  return createBuffer(size)\n}\n\n/**\n * Creates a new filled Buffer instance.\n * alloc(size[, fill[, encoding]])\n **/\nBuffer.alloc = function (size, fill, encoding) {\n  return alloc(size, fill, encoding)\n}\n\nfunction allocUnsafe (size) {\n  assertSize(size)\n  return createBuffer(size < 0 ? 0 : checked(size) | 0)\n}\n\n/**\n * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.\n * */\nBuffer.allocUnsafe = function (size) {\n  return allocUnsafe(size)\n}\n/**\n * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.\n */\nBuffer.allocUnsafeSlow = function (size) {\n  return allocUnsafe(size)\n}\n\nfunction fromString (string, encoding) {\n  if (typeof encoding !== 'string' || encoding === '') {\n    encoding = 'utf8'\n  }\n\n  if (!Buffer.isEncoding(encoding)) {\n    throw new TypeError('Unknown encoding: ' + encoding)\n  }\n\n  const length = byteLength(string, encoding) | 0\n  let buf = createBuffer(length)\n\n  const actual = buf.write(string, encoding)\n\n  if (actual !== length) {\n    // Writing a hex string, for example, that contains invalid characters will\n    // cause everything after the first invalid character to be ignored. (e.g.\n    // 'abxxcd' will be treated as 'ab')\n    buf = buf.slice(0, actual)\n  }\n\n  return buf\n}\n\nfunction fromArrayLike (array) {\n  const length = array.length < 0 ? 0 : checked(array.length) | 0\n  const buf = createBuffer(length)\n  for (let i = 0; i < length; i += 1) {\n    buf[i] = array[i] & 255\n  }\n  return buf\n}\n\nfunction fromArrayView (arrayView) {\n  if (isInstance(arrayView, Uint8Array)) {\n    const copy = new Uint8Array(arrayView)\n    return fromArrayBuffer(copy.buffer, copy.byteOffset, copy.byteLength)\n  }\n  return fromArrayLike(arrayView)\n}\n\nfunction fromArrayBuffer (array, byteOffset, length) {\n  if (byteOffset < 0 || array.byteLength < byteOffset) {\n    throw new RangeError('\"offset\" is outside of buffer bounds')\n  }\n\n  if (array.byteLength < byteOffset + (length || 0)) {\n    throw new RangeError('\"length\" is outside of buffer bounds')\n  }\n\n  let buf\n  if (byteOffset === undefined && length === undefined) {\n    buf = new Uint8Array(array)\n  } else if (length === undefined) {\n    buf = new Uint8Array(array, byteOffset)\n  } else {\n    buf = new Uint8Array(array, byteOffset, length)\n  }\n\n  // Return an augmented `Uint8Array` instance\n  Object.setPrototypeOf(buf, Buffer.prototype)\n\n  return buf\n}\n\nfunction fromObject (obj) {\n  if (Buffer.isBuffer(obj)) {\n    const len = checked(obj.length) | 0\n    const buf = createBuffer(len)\n\n    if (buf.length === 0) {\n      return buf\n    }\n\n    obj.copy(buf, 0, 0, len)\n    return buf\n  }\n\n  if (obj.length !== undefined) {\n    if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) {\n      return createBuffer(0)\n    }\n    return fromArrayLike(obj)\n  }\n\n  if (obj.type === 'Buffer' && Array.isArray(obj.data)) {\n    return fromArrayLike(obj.data)\n  }\n}\n\nfunction checked (length) {\n  // Note: cannot use `length < K_MAX_LENGTH` here because that fails when\n  // length is NaN (which is otherwise coerced to zero.)\n  if (length >= K_MAX_LENGTH) {\n    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n                         'size: 0x' + K_MAX_LENGTH.toString(16) + ' bytes')\n  }\n  return length | 0\n}\n\nfunction SlowBuffer (length) {\n  if (+length != length) { // eslint-disable-line eqeqeq\n    length = 0\n  }\n  return Buffer.alloc(+length)\n}\n\nBuffer.isBuffer = function isBuffer (b) {\n  return b != null && b._isBuffer === true &&\n    b !== Buffer.prototype // so Buffer.isBuffer(Buffer.prototype) will be false\n}\n\nBuffer.compare = function compare (a, b) {\n  if (isInstance(a, Uint8Array)) a = Buffer.from(a, a.offset, a.byteLength)\n  if (isInstance(b, Uint8Array)) b = Buffer.from(b, b.offset, b.byteLength)\n  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\n    throw new TypeError(\n      'The \"buf1\", \"buf2\" arguments must be one of type Buffer or Uint8Array'\n    )\n  }\n\n  if (a === b) return 0\n\n  let x = a.length\n  let y = b.length\n\n  for (let i = 0, len = Math.min(x, y); i < len; ++i) {\n    if (a[i] !== b[i]) {\n      x = a[i]\n      y = b[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\nBuffer.isEncoding = function isEncoding (encoding) {\n  switch (String(encoding).toLowerCase()) {\n    case 'hex':\n    case 'utf8':\n    case 'utf-8':\n    case 'ascii':\n    case 'latin1':\n    case 'binary':\n    case 'base64':\n    case 'ucs2':\n    case 'ucs-2':\n    case 'utf16le':\n    case 'utf-16le':\n      return true\n    default:\n      return false\n  }\n}\n\nBuffer.concat = function concat (list, length) {\n  if (!Array.isArray(list)) {\n    throw new TypeError('\"list\" argument must be an Array of Buffers')\n  }\n\n  if (list.length === 0) {\n    return Buffer.alloc(0)\n  }\n\n  let i\n  if (length === undefined) {\n    length = 0\n    for (i = 0; i < list.length; ++i) {\n      length += list[i].length\n    }\n  }\n\n  const buffer = Buffer.allocUnsafe(length)\n  let pos = 0\n  for (i = 0; i < list.length; ++i) {\n    let buf = list[i]\n    if (isInstance(buf, Uint8Array)) {\n      if (pos + buf.length > buffer.length) {\n        if (!Buffer.isBuffer(buf)) buf = Buffer.from(buf)\n        buf.copy(buffer, pos)\n      } else {\n        Uint8Array.prototype.set.call(\n          buffer,\n          buf,\n          pos\n        )\n      }\n    } else if (!Buffer.isBuffer(buf)) {\n      throw new TypeError('\"list\" argument must be an Array of Buffers')\n    } else {\n      buf.copy(buffer, pos)\n    }\n    pos += buf.length\n  }\n  return buffer\n}\n\nfunction byteLength (string, encoding) {\n  if (Buffer.isBuffer(string)) {\n    return string.length\n  }\n  if (ArrayBuffer.isView(string) || isInstance(string, ArrayBuffer)) {\n    return string.byteLength\n  }\n  if (typeof string !== 'string') {\n    throw new TypeError(\n      'The \"string\" argument must be one of type string, Buffer, or ArrayBuffer. ' +\n      'Received type ' + typeof string\n    )\n  }\n\n  const len = string.length\n  const mustMatch = (arguments.length > 2 && arguments[2] === true)\n  if (!mustMatch && len === 0) return 0\n\n  // Use a for loop to avoid recursion\n  let loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'ascii':\n      case 'latin1':\n      case 'binary':\n        return len\n      case 'utf8':\n      case 'utf-8':\n        return utf8ToBytes(string).length\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return len * 2\n      case 'hex':\n        return len >>> 1\n      case 'base64':\n        return base64ToBytes(string).length\n      default:\n        if (loweredCase) {\n          return mustMatch ? -1 : utf8ToBytes(string).length // assume utf8\n        }\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\nBuffer.byteLength = byteLength\n\nfunction slowToString (encoding, start, end) {\n  let loweredCase = false\n\n  // No need to verify that \"this.length <= MAX_UINT32\" since it's a read-only\n  // property of a typed array.\n\n  // This behaves neither like String nor Uint8Array in that we set start/end\n  // to their upper/lower bounds if the value passed is out of range.\n  // undefined is handled specially as per ECMA-262 6th Edition,\n  // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.\n  if (start === undefined || start < 0) {\n    start = 0\n  }\n  // Return early if start > this.length. Done here to prevent potential uint32\n  // coercion fail below.\n  if (start > this.length) {\n    return ''\n  }\n\n  if (end === undefined || end > this.length) {\n    end = this.length\n  }\n\n  if (end <= 0) {\n    return ''\n  }\n\n  // Force coercion to uint32. This will also coerce falsey/NaN values to 0.\n  end >>>= 0\n  start >>>= 0\n\n  if (end <= start) {\n    return ''\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  while (true) {\n    switch (encoding) {\n      case 'hex':\n        return hexSlice(this, start, end)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Slice(this, start, end)\n\n      case 'ascii':\n        return asciiSlice(this, start, end)\n\n      case 'latin1':\n      case 'binary':\n        return latin1Slice(this, start, end)\n\n      case 'base64':\n        return base64Slice(this, start, end)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return utf16leSlice(this, start, end)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = (encoding + '').toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\n// This property is used by `Buffer.isBuffer` (and the `is-buffer` npm package)\n// to detect a Buffer instance. It's not possible to use `instanceof Buffer`\n// reliably in a browserify context because there could be multiple different\n// copies of the 'buffer' package in use. This method works even for Buffer\n// instances that were created from another copy of the `buffer` package.\n// See: https://github.com/feross/buffer/issues/154\nBuffer.prototype._isBuffer = true\n\nfunction swap (b, n, m) {\n  const i = b[n]\n  b[n] = b[m]\n  b[m] = i\n}\n\nBuffer.prototype.swap16 = function swap16 () {\n  const len = this.length\n  if (len % 2 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 16-bits')\n  }\n  for (let i = 0; i < len; i += 2) {\n    swap(this, i, i + 1)\n  }\n  return this\n}\n\nBuffer.prototype.swap32 = function swap32 () {\n  const len = this.length\n  if (len % 4 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 32-bits')\n  }\n  for (let i = 0; i < len; i += 4) {\n    swap(this, i, i + 3)\n    swap(this, i + 1, i + 2)\n  }\n  return this\n}\n\nBuffer.prototype.swap64 = function swap64 () {\n  const len = this.length\n  if (len % 8 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 64-bits')\n  }\n  for (let i = 0; i < len; i += 8) {\n    swap(this, i, i + 7)\n    swap(this, i + 1, i + 6)\n    swap(this, i + 2, i + 5)\n    swap(this, i + 3, i + 4)\n  }\n  return this\n}\n\nBuffer.prototype.toString = function toString () {\n  const length = this.length\n  if (length === 0) return ''\n  if (arguments.length === 0) return utf8Slice(this, 0, length)\n  return slowToString.apply(this, arguments)\n}\n\nBuffer.prototype.toLocaleString = Buffer.prototype.toString\n\nBuffer.prototype.equals = function equals (b) {\n  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n  if (this === b) return true\n  return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.inspect = function inspect () {\n  let str = ''\n  const max = exports.INSPECT_MAX_BYTES\n  str = this.toString('hex', 0, max).replace(/(.{2})/g, '$1 ').trim()\n  if (this.length > max) str += ' ... '\n  return '<Buffer ' + str + '>'\n}\nif (customInspectSymbol) {\n  Buffer.prototype[customInspectSymbol] = Buffer.prototype.inspect\n}\n\nBuffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {\n  if (isInstance(target, Uint8Array)) {\n    target = Buffer.from(target, target.offset, target.byteLength)\n  }\n  if (!Buffer.isBuffer(target)) {\n    throw new TypeError(\n      'The \"target\" argument must be one of type Buffer or Uint8Array. ' +\n      'Received type ' + (typeof target)\n    )\n  }\n\n  if (start === undefined) {\n    start = 0\n  }\n  if (end === undefined) {\n    end = target ? target.length : 0\n  }\n  if (thisStart === undefined) {\n    thisStart = 0\n  }\n  if (thisEnd === undefined) {\n    thisEnd = this.length\n  }\n\n  if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {\n    throw new RangeError('out of range index')\n  }\n\n  if (thisStart >= thisEnd && start >= end) {\n    return 0\n  }\n  if (thisStart >= thisEnd) {\n    return -1\n  }\n  if (start >= end) {\n    return 1\n  }\n\n  start >>>= 0\n  end >>>= 0\n  thisStart >>>= 0\n  thisEnd >>>= 0\n\n  if (this === target) return 0\n\n  let x = thisEnd - thisStart\n  let y = end - start\n  const len = Math.min(x, y)\n\n  const thisCopy = this.slice(thisStart, thisEnd)\n  const targetCopy = target.slice(start, end)\n\n  for (let i = 0; i < len; ++i) {\n    if (thisCopy[i] !== targetCopy[i]) {\n      x = thisCopy[i]\n      y = targetCopy[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\n// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,\n// OR the last index of `val` in `buffer` at offset <= `byteOffset`.\n//\n// Arguments:\n// - buffer - a Buffer to search\n// - val - a string, Buffer, or number\n// - byteOffset - an index into `buffer`; will be clamped to an int32\n// - encoding - an optional encoding, relevant is val is a string\n// - dir - true for indexOf, false for lastIndexOf\nfunction bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {\n  // Empty buffer means no match\n  if (buffer.length === 0) return -1\n\n  // Normalize byteOffset\n  if (typeof byteOffset === 'string') {\n    encoding = byteOffset\n    byteOffset = 0\n  } else if (byteOffset > 0x7fffffff) {\n    byteOffset = 0x7fffffff\n  } else if (byteOffset < -0x80000000) {\n    byteOffset = -0x80000000\n  }\n  byteOffset = +byteOffset // Coerce to Number.\n  if (numberIsNaN(byteOffset)) {\n    // byteOffset: it it's undefined, null, NaN, \"foo\", etc, search whole buffer\n    byteOffset = dir ? 0 : (buffer.length - 1)\n  }\n\n  // Normalize byteOffset: negative offsets start from the end of the buffer\n  if (byteOffset < 0) byteOffset = buffer.length + byteOffset\n  if (byteOffset >= buffer.length) {\n    if (dir) return -1\n    else byteOffset = buffer.length - 1\n  } else if (byteOffset < 0) {\n    if (dir) byteOffset = 0\n    else return -1\n  }\n\n  // Normalize val\n  if (typeof val === 'string') {\n    val = Buffer.from(val, encoding)\n  }\n\n  // Finally, search either indexOf (if dir is true) or lastIndexOf\n  if (Buffer.isBuffer(val)) {\n    // Special case: looking for empty string/buffer always fails\n    if (val.length === 0) {\n      return -1\n    }\n    return arrayIndexOf(buffer, val, byteOffset, encoding, dir)\n  } else if (typeof val === 'number') {\n    val = val & 0xFF // Search for a byte value [0-255]\n    if (typeof Uint8Array.prototype.indexOf === 'function') {\n      if (dir) {\n        return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)\n      } else {\n        return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)\n      }\n    }\n    return arrayIndexOf(buffer, [val], byteOffset, encoding, dir)\n  }\n\n  throw new TypeError('val must be string, number or Buffer')\n}\n\nfunction arrayIndexOf (arr, val, byteOffset, encoding, dir) {\n  let indexSize = 1\n  let arrLength = arr.length\n  let valLength = val.length\n\n  if (encoding !== undefined) {\n    encoding = String(encoding).toLowerCase()\n    if (encoding === 'ucs2' || encoding === 'ucs-2' ||\n        encoding === 'utf16le' || encoding === 'utf-16le') {\n      if (arr.length < 2 || val.length < 2) {\n        return -1\n      }\n      indexSize = 2\n      arrLength /= 2\n      valLength /= 2\n      byteOffset /= 2\n    }\n  }\n\n  function read (buf, i) {\n    if (indexSize === 1) {\n      return buf[i]\n    } else {\n      return buf.readUInt16BE(i * indexSize)\n    }\n  }\n\n  let i\n  if (dir) {\n    let foundIndex = -1\n    for (i = byteOffset; i < arrLength; i++) {\n      if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {\n        if (foundIndex === -1) foundIndex = i\n        if (i - foundIndex + 1 === valLength) return foundIndex * indexSize\n      } else {\n        if (foundIndex !== -1) i -= i - foundIndex\n        foundIndex = -1\n      }\n    }\n  } else {\n    if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength\n    for (i = byteOffset; i >= 0; i--) {\n      let found = true\n      for (let j = 0; j < valLength; j++) {\n        if (read(arr, i + j) !== read(val, j)) {\n          found = false\n          break\n        }\n      }\n      if (found) return i\n    }\n  }\n\n  return -1\n}\n\nBuffer.prototype.includes = function includes (val, byteOffset, encoding) {\n  return this.indexOf(val, byteOffset, encoding) !== -1\n}\n\nBuffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, true)\n}\n\nBuffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, false)\n}\n\nfunction hexWrite (buf, string, offset, length) {\n  offset = Number(offset) || 0\n  const remaining = buf.length - offset\n  if (!length) {\n    length = remaining\n  } else {\n    length = Number(length)\n    if (length > remaining) {\n      length = remaining\n    }\n  }\n\n  const strLen = string.length\n\n  if (length > strLen / 2) {\n    length = strLen / 2\n  }\n  let i\n  for (i = 0; i < length; ++i) {\n    const parsed = parseInt(string.substr(i * 2, 2), 16)\n    if (numberIsNaN(parsed)) return i\n    buf[offset + i] = parsed\n  }\n  return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n  return blitBuffer(asciiToBytes(string), buf, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n  return blitBuffer(base64ToBytes(string), buf, offset, length)\n}\n\nfunction ucs2Write (buf, string, offset, length) {\n  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nBuffer.prototype.write = function write (string, offset, length, encoding) {\n  // Buffer#write(string)\n  if (offset === undefined) {\n    encoding = 'utf8'\n    length = this.length\n    offset = 0\n  // Buffer#write(string, encoding)\n  } else if (length === undefined && typeof offset === 'string') {\n    encoding = offset\n    length = this.length\n    offset = 0\n  // Buffer#write(string, offset[, length][, encoding])\n  } else if (isFinite(offset)) {\n    offset = offset >>> 0\n    if (isFinite(length)) {\n      length = length >>> 0\n      if (encoding === undefined) encoding = 'utf8'\n    } else {\n      encoding = length\n      length = undefined\n    }\n  } else {\n    throw new Error(\n      'Buffer.write(string, encoding, offset[, length]) is no longer supported'\n    )\n  }\n\n  const remaining = this.length - offset\n  if (length === undefined || length > remaining) length = remaining\n\n  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\n    throw new RangeError('Attempt to write outside buffer bounds')\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  let loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'hex':\n        return hexWrite(this, string, offset, length)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Write(this, string, offset, length)\n\n      case 'ascii':\n      case 'latin1':\n      case 'binary':\n        return asciiWrite(this, string, offset, length)\n\n      case 'base64':\n        // Warning: maxLength not taken into account in base64Write\n        return base64Write(this, string, offset, length)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return ucs2Write(this, string, offset, length)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\nBuffer.prototype.toJSON = function toJSON () {\n  return {\n    type: 'Buffer',\n    data: Array.prototype.slice.call(this._arr || this, 0)\n  }\n}\n\nfunction base64Slice (buf, start, end) {\n  if (start === 0 && end === buf.length) {\n    return base64.fromByteArray(buf)\n  } else {\n    return base64.fromByteArray(buf.slice(start, end))\n  }\n}\n\nfunction utf8Slice (buf, start, end) {\n  end = Math.min(buf.length, end)\n  const res = []\n\n  let i = start\n  while (i < end) {\n    const firstByte = buf[i]\n    let codePoint = null\n    let bytesPerSequence = (firstByte > 0xEF)\n      ? 4\n      : (firstByte > 0xDF)\n          ? 3\n          : (firstByte > 0xBF)\n              ? 2\n              : 1\n\n    if (i + bytesPerSequence <= end) {\n      let secondByte, thirdByte, fourthByte, tempCodePoint\n\n      switch (bytesPerSequence) {\n        case 1:\n          if (firstByte < 0x80) {\n            codePoint = firstByte\n          }\n          break\n        case 2:\n          secondByte = buf[i + 1]\n          if ((secondByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\n            if (tempCodePoint > 0x7F) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 3:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\n            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 4:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          fourthByte = buf[i + 3]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\n            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\n              codePoint = tempCodePoint\n            }\n          }\n      }\n    }\n\n    if (codePoint === null) {\n      // we did not generate a valid codePoint so insert a\n      // replacement char (U+FFFD) and advance only 1 byte\n      codePoint = 0xFFFD\n      bytesPerSequence = 1\n    } else if (codePoint > 0xFFFF) {\n      // encode to utf16 (surrogate pair dance)\n      codePoint -= 0x10000\n      res.push(codePoint >>> 10 & 0x3FF | 0xD800)\n      codePoint = 0xDC00 | codePoint & 0x3FF\n    }\n\n    res.push(codePoint)\n    i += bytesPerSequence\n  }\n\n  return decodeCodePointsArray(res)\n}\n\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\n// the lowest limit is Chrome, with 0x10000 args.\n// We go 1 magnitude less, for safety\nconst MAX_ARGUMENTS_LENGTH = 0x1000\n\nfunction decodeCodePointsArray (codePoints) {\n  const len = codePoints.length\n  if (len <= MAX_ARGUMENTS_LENGTH) {\n    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\n  }\n\n  // Decode in chunks to avoid \"call stack size exceeded\".\n  let res = ''\n  let i = 0\n  while (i < len) {\n    res += String.fromCharCode.apply(\n      String,\n      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\n    )\n  }\n  return res\n}\n\nfunction asciiSlice (buf, start, end) {\n  let ret = ''\n  end = Math.min(buf.length, end)\n\n  for (let i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i] & 0x7F)\n  }\n  return ret\n}\n\nfunction latin1Slice (buf, start, end) {\n  let ret = ''\n  end = Math.min(buf.length, end)\n\n  for (let i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i])\n  }\n  return ret\n}\n\nfunction hexSlice (buf, start, end) {\n  const len = buf.length\n\n  if (!start || start < 0) start = 0\n  if (!end || end < 0 || end > len) end = len\n\n  let out = ''\n  for (let i = start; i < end; ++i) {\n    out += hexSliceLookupTable[buf[i]]\n  }\n  return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n  const bytes = buf.slice(start, end)\n  let res = ''\n  // If bytes.length is odd, the last 8 bits must be ignored (same as node.js)\n  for (let i = 0; i < bytes.length - 1; i += 2) {\n    res += String.fromCharCode(bytes[i] + (bytes[i + 1] * 256))\n  }\n  return res\n}\n\nBuffer.prototype.slice = function slice (start, end) {\n  const len = this.length\n  start = ~~start\n  end = end === undefined ? len : ~~end\n\n  if (start < 0) {\n    start += len\n    if (start < 0) start = 0\n  } else if (start > len) {\n    start = len\n  }\n\n  if (end < 0) {\n    end += len\n    if (end < 0) end = 0\n  } else if (end > len) {\n    end = len\n  }\n\n  if (end < start) end = start\n\n  const newBuf = this.subarray(start, end)\n  // Return an augmented `Uint8Array` instance\n  Object.setPrototypeOf(newBuf, Buffer.prototype)\n\n  return newBuf\n}\n\n/*\n * Need to make sure that buffer isn't trying to write out of bounds.\n */\nfunction checkOffset (offset, ext, length) {\n  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\n  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\n}\n\nBuffer.prototype.readUintLE =\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\n  offset = offset >>> 0\n  byteLength = byteLength >>> 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  let val = this[offset]\n  let mul = 1\n  let i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUintBE =\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\n  offset = offset >>> 0\n  byteLength = byteLength >>> 0\n  if (!noAssert) {\n    checkOffset(offset, byteLength, this.length)\n  }\n\n  let val = this[offset + --byteLength]\n  let mul = 1\n  while (byteLength > 0 && (mul *= 0x100)) {\n    val += this[offset + --byteLength] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUint8 =\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\n  offset = offset >>> 0\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  return this[offset]\n}\n\nBuffer.prototype.readUint16LE =\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\n  offset = offset >>> 0\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return this[offset] | (this[offset + 1] << 8)\n}\n\nBuffer.prototype.readUint16BE =\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\n  offset = offset >>> 0\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return (this[offset] << 8) | this[offset + 1]\n}\n\nBuffer.prototype.readUint32LE =\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\n  offset = offset >>> 0\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return ((this[offset]) |\n      (this[offset + 1] << 8) |\n      (this[offset + 2] << 16)) +\n      (this[offset + 3] * 0x1000000)\n}\n\nBuffer.prototype.readUint32BE =\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\n  offset = offset >>> 0\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] * 0x1000000) +\n    ((this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    this[offset + 3])\n}\n\nBuffer.prototype.readBigUInt64LE = defineBigIntMethod(function readBigUInt64LE (offset) {\n  offset = offset >>> 0\n  validateNumber(offset, 'offset')\n  const first = this[offset]\n  const last = this[offset + 7]\n  if (first === undefined || last === undefined) {\n    boundsError(offset, this.length - 8)\n  }\n\n  const lo = first +\n    this[++offset] * 2 ** 8 +\n    this[++offset] * 2 ** 16 +\n    this[++offset] * 2 ** 24\n\n  const hi = this[++offset] +\n    this[++offset] * 2 ** 8 +\n    this[++offset] * 2 ** 16 +\n    last * 2 ** 24\n\n  return BigInt(lo) + (BigInt(hi) << BigInt(32))\n})\n\nBuffer.prototype.readBigUInt64BE = defineBigIntMethod(function readBigUInt64BE (offset) {\n  offset = offset >>> 0\n  validateNumber(offset, 'offset')\n  const first = this[offset]\n  const last = this[offset + 7]\n  if (first === undefined || last === undefined) {\n    boundsError(offset, this.length - 8)\n  }\n\n  const hi = first * 2 ** 24 +\n    this[++offset] * 2 ** 16 +\n    this[++offset] * 2 ** 8 +\n    this[++offset]\n\n  const lo = this[++offset] * 2 ** 24 +\n    this[++offset] * 2 ** 16 +\n    this[++offset] * 2 ** 8 +\n    last\n\n  return (BigInt(hi) << BigInt(32)) + BigInt(lo)\n})\n\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\n  offset = offset >>> 0\n  byteLength = byteLength >>> 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  let val = this[offset]\n  let mul = 1\n  let i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\n  offset = offset >>> 0\n  byteLength = byteLength >>> 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  let i = byteLength\n  let mul = 1\n  let val = this[offset + --i]\n  while (i > 0 && (mul *= 0x100)) {\n    val += this[offset + --i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\n  offset = offset >>> 0\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  if (!(this[offset] & 0x80)) return (this[offset])\n  return ((0xff - this[offset] + 1) * -1)\n}\n\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\n  offset = offset >>> 0\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  const val = this[offset] | (this[offset + 1] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\n  offset = offset >>> 0\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  const val = this[offset + 1] | (this[offset] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\n  offset = offset >>> 0\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset]) |\n    (this[offset + 1] << 8) |\n    (this[offset + 2] << 16) |\n    (this[offset + 3] << 24)\n}\n\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\n  offset = offset >>> 0\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] << 24) |\n    (this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    (this[offset + 3])\n}\n\nBuffer.prototype.readBigInt64LE = defineBigIntMethod(function readBigInt64LE (offset) {\n  offset = offset >>> 0\n  validateNumber(offset, 'offset')\n  const first = this[offset]\n  const last = this[offset + 7]\n  if (first === undefined || last === undefined) {\n    boundsError(offset, this.length - 8)\n  }\n\n  const val = this[offset + 4] +\n    this[offset + 5] * 2 ** 8 +\n    this[offset + 6] * 2 ** 16 +\n    (last << 24) // Overflow\n\n  return (BigInt(val) << BigInt(32)) +\n    BigInt(first +\n    this[++offset] * 2 ** 8 +\n    this[++offset] * 2 ** 16 +\n    this[++offset] * 2 ** 24)\n})\n\nBuffer.prototype.readBigInt64BE = defineBigIntMethod(function readBigInt64BE (offset) {\n  offset = offset >>> 0\n  validateNumber(offset, 'offset')\n  const first = this[offset]\n  const last = this[offset + 7]\n  if (first === undefined || last === undefined) {\n    boundsError(offset, this.length - 8)\n  }\n\n  const val = (first << 24) + // Overflow\n    this[++offset] * 2 ** 16 +\n    this[++offset] * 2 ** 8 +\n    this[++offset]\n\n  return (BigInt(val) << BigInt(32)) +\n    BigInt(this[++offset] * 2 ** 24 +\n    this[++offset] * 2 ** 16 +\n    this[++offset] * 2 ** 8 +\n    last)\n})\n\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\n  offset = offset >>> 0\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, true, 23, 4)\n}\n\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\n  offset = offset >>> 0\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, false, 23, 4)\n}\n\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\n  offset = offset >>> 0\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, true, 52, 8)\n}\n\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\n  offset = offset >>> 0\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, false, 52, 8)\n}\n\nfunction checkInt (buf, value, offset, ext, max, min) {\n  if (!Buffer.isBuffer(buf)) throw new TypeError('\"buffer\" argument must be a Buffer instance')\n  if (value > max || value < min) throw new RangeError('\"value\" argument is out of bounds')\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n}\n\nBuffer.prototype.writeUintLE =\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset >>> 0\n  byteLength = byteLength >>> 0\n  if (!noAssert) {\n    const maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  let mul = 1\n  let i = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUintBE =\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset >>> 0\n  byteLength = byteLength >>> 0\n  if (!noAssert) {\n    const maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  let i = byteLength - 1\n  let mul = 1\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUint8 =\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset >>> 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nBuffer.prototype.writeUint16LE =\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset >>> 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  this[offset] = (value & 0xff)\n  this[offset + 1] = (value >>> 8)\n  return offset + 2\n}\n\nBuffer.prototype.writeUint16BE =\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset >>> 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  this[offset] = (value >>> 8)\n  this[offset + 1] = (value & 0xff)\n  return offset + 2\n}\n\nBuffer.prototype.writeUint32LE =\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset >>> 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  this[offset + 3] = (value >>> 24)\n  this[offset + 2] = (value >>> 16)\n  this[offset + 1] = (value >>> 8)\n  this[offset] = (value & 0xff)\n  return offset + 4\n}\n\nBuffer.prototype.writeUint32BE =\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset >>> 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  this[offset] = (value >>> 24)\n  this[offset + 1] = (value >>> 16)\n  this[offset + 2] = (value >>> 8)\n  this[offset + 3] = (value & 0xff)\n  return offset + 4\n}\n\nfunction wrtBigUInt64LE (buf, value, offset, min, max) {\n  checkIntBI(value, min, max, buf, offset, 7)\n\n  let lo = Number(value & BigInt(0xffffffff))\n  buf[offset++] = lo\n  lo = lo >> 8\n  buf[offset++] = lo\n  lo = lo >> 8\n  buf[offset++] = lo\n  lo = lo >> 8\n  buf[offset++] = lo\n  let hi = Number(value >> BigInt(32) & BigInt(0xffffffff))\n  buf[offset++] = hi\n  hi = hi >> 8\n  buf[offset++] = hi\n  hi = hi >> 8\n  buf[offset++] = hi\n  hi = hi >> 8\n  buf[offset++] = hi\n  return offset\n}\n\nfunction wrtBigUInt64BE (buf, value, offset, min, max) {\n  checkIntBI(value, min, max, buf, offset, 7)\n\n  let lo = Number(value & BigInt(0xffffffff))\n  buf[offset + 7] = lo\n  lo = lo >> 8\n  buf[offset + 6] = lo\n  lo = lo >> 8\n  buf[offset + 5] = lo\n  lo = lo >> 8\n  buf[offset + 4] = lo\n  let hi = Number(value >> BigInt(32) & BigInt(0xffffffff))\n  buf[offset + 3] = hi\n  hi = hi >> 8\n  buf[offset + 2] = hi\n  hi = hi >> 8\n  buf[offset + 1] = hi\n  hi = hi >> 8\n  buf[offset] = hi\n  return offset + 8\n}\n\nBuffer.prototype.writeBigUInt64LE = defineBigIntMethod(function writeBigUInt64LE (value, offset = 0) {\n  return wrtBigUInt64LE(this, value, offset, BigInt(0), BigInt('0xffffffffffffffff'))\n})\n\nBuffer.prototype.writeBigUInt64BE = defineBigIntMethod(function writeBigUInt64BE (value, offset = 0) {\n  return wrtBigUInt64BE(this, value, offset, BigInt(0), BigInt('0xffffffffffffffff'))\n})\n\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset >>> 0\n  if (!noAssert) {\n    const limit = Math.pow(2, (8 * byteLength) - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  let i = 0\n  let mul = 1\n  let sub = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset >>> 0\n  if (!noAssert) {\n    const limit = Math.pow(2, (8 * byteLength) - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  let i = byteLength - 1\n  let mul = 1\n  let sub = 0\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset >>> 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\n  if (value < 0) value = 0xff + value + 1\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset >>> 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  this[offset] = (value & 0xff)\n  this[offset + 1] = (value >>> 8)\n  return offset + 2\n}\n\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset >>> 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  this[offset] = (value >>> 8)\n  this[offset + 1] = (value & 0xff)\n  return offset + 2\n}\n\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset >>> 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  this[offset] = (value & 0xff)\n  this[offset + 1] = (value >>> 8)\n  this[offset + 2] = (value >>> 16)\n  this[offset + 3] = (value >>> 24)\n  return offset + 4\n}\n\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset >>> 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (value < 0) value = 0xffffffff + value + 1\n  this[offset] = (value >>> 24)\n  this[offset + 1] = (value >>> 16)\n  this[offset + 2] = (value >>> 8)\n  this[offset + 3] = (value & 0xff)\n  return offset + 4\n}\n\nBuffer.prototype.writeBigInt64LE = defineBigIntMethod(function writeBigInt64LE (value, offset = 0) {\n  return wrtBigUInt64LE(this, value, offset, -BigInt('0x8000000000000000'), BigInt('0x7fffffffffffffff'))\n})\n\nBuffer.prototype.writeBigInt64BE = defineBigIntMethod(function writeBigInt64BE (value, offset = 0) {\n  return wrtBigUInt64BE(this, value, offset, -BigInt('0x8000000000000000'), BigInt('0x7fffffffffffffff'))\n})\n\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n  if (offset < 0) throw new RangeError('Index out of range')\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n  value = +value\n  offset = offset >>> 0\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 23, 4)\n  return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n  value = +value\n  offset = offset >>> 0\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 52, 8)\n  return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, false, noAssert)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\n  if (!Buffer.isBuffer(target)) throw new TypeError('argument should be a Buffer')\n  if (!start) start = 0\n  if (!end && end !== 0) end = this.length\n  if (targetStart >= target.length) targetStart = target.length\n  if (!targetStart) targetStart = 0\n  if (end > 0 && end < start) end = start\n\n  // Copy 0 bytes; we're done\n  if (end === start) return 0\n  if (target.length === 0 || this.length === 0) return 0\n\n  // Fatal error conditions\n  if (targetStart < 0) {\n    throw new RangeError('targetStart out of bounds')\n  }\n  if (start < 0 || start >= this.length) throw new RangeError('Index out of range')\n  if (end < 0) throw new RangeError('sourceEnd out of bounds')\n\n  // Are we oob?\n  if (end > this.length) end = this.length\n  if (target.length - targetStart < end - start) {\n    end = target.length - targetStart + start\n  }\n\n  const len = end - start\n\n  if (this === target && typeof Uint8Array.prototype.copyWithin === 'function') {\n    // Use built-in when available, missing from IE11\n    this.copyWithin(targetStart, start, end)\n  } else {\n    Uint8Array.prototype.set.call(\n      target,\n      this.subarray(start, end),\n      targetStart\n    )\n  }\n\n  return len\n}\n\n// Usage:\n//    buffer.fill(number[, offset[, end]])\n//    buffer.fill(buffer[, offset[, end]])\n//    buffer.fill(string[, offset[, end]][, encoding])\nBuffer.prototype.fill = function fill (val, start, end, encoding) {\n  // Handle string cases:\n  if (typeof val === 'string') {\n    if (typeof start === 'string') {\n      encoding = start\n      start = 0\n      end = this.length\n    } else if (typeof end === 'string') {\n      encoding = end\n      end = this.length\n    }\n    if (encoding !== undefined && typeof encoding !== 'string') {\n      throw new TypeError('encoding must be a string')\n    }\n    if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {\n      throw new TypeError('Unknown encoding: ' + encoding)\n    }\n    if (val.length === 1) {\n      const code = val.charCodeAt(0)\n      if ((encoding === 'utf8' && code < 128) ||\n          encoding === 'latin1') {\n        // Fast path: If `val` fits into a single byte, use that numeric value.\n        val = code\n      }\n    }\n  } else if (typeof val === 'number') {\n    val = val & 255\n  } else if (typeof val === 'boolean') {\n    val = Number(val)\n  }\n\n  // Invalid ranges are not set to a default, so can range check early.\n  if (start < 0 || this.length < start || this.length < end) {\n    throw new RangeError('Out of range index')\n  }\n\n  if (end <= start) {\n    return this\n  }\n\n  start = start >>> 0\n  end = end === undefined ? this.length : end >>> 0\n\n  if (!val) val = 0\n\n  let i\n  if (typeof val === 'number') {\n    for (i = start; i < end; ++i) {\n      this[i] = val\n    }\n  } else {\n    const bytes = Buffer.isBuffer(val)\n      ? val\n      : Buffer.from(val, encoding)\n    const len = bytes.length\n    if (len === 0) {\n      throw new TypeError('The value \"' + val +\n        '\" is invalid for argument \"value\"')\n    }\n    for (i = 0; i < end - start; ++i) {\n      this[i + start] = bytes[i % len]\n    }\n  }\n\n  return this\n}\n\n// CUSTOM ERRORS\n// =============\n\n// Simplified versions from Node, changed for Buffer-only usage\nconst errors = {}\nfunction E (sym, getMessage, Base) {\n  errors[sym] = class NodeError extends Base {\n    constructor () {\n      super()\n\n      Object.defineProperty(this, 'message', {\n        value: getMessage.apply(this, arguments),\n        writable: true,\n        configurable: true\n      })\n\n      // Add the error code to the name to include it in the stack trace.\n      this.name = `${this.name} [${sym}]`\n      // Access the stack to generate the error message including the error code\n      // from the name.\n      this.stack // eslint-disable-line no-unused-expressions\n      // Reset the name to the actual name.\n      delete this.name\n    }\n\n    get code () {\n      return sym\n    }\n\n    set code (value) {\n      Object.defineProperty(this, 'code', {\n        configurable: true,\n        enumerable: true,\n        value,\n        writable: true\n      })\n    }\n\n    toString () {\n      return `${this.name} [${sym}]: ${this.message}`\n    }\n  }\n}\n\nE('ERR_BUFFER_OUT_OF_BOUNDS',\n  function (name) {\n    if (name) {\n      return `${name} is outside of buffer bounds`\n    }\n\n    return 'Attempt to access memory outside buffer bounds'\n  }, RangeError)\nE('ERR_INVALID_ARG_TYPE',\n  function (name, actual) {\n    return `The \"${name}\" argument must be of type number. Received type ${typeof actual}`\n  }, TypeError)\nE('ERR_OUT_OF_RANGE',\n  function (str, range, input) {\n    let msg = `The value of \"${str}\" is out of range.`\n    let received = input\n    if (Number.isInteger(input) && Math.abs(input) > 2 ** 32) {\n      received = addNumericalSeparator(String(input))\n    } else if (typeof input === 'bigint') {\n      received = String(input)\n      if (input > BigInt(2) ** BigInt(32) || input < -(BigInt(2) ** BigInt(32))) {\n        received = addNumericalSeparator(received)\n      }\n      received += 'n'\n    }\n    msg += ` It must be ${range}. Received ${received}`\n    return msg\n  }, RangeError)\n\nfunction addNumericalSeparator (val) {\n  let res = ''\n  let i = val.length\n  const start = val[0] === '-' ? 1 : 0\n  for (; i >= start + 4; i -= 3) {\n    res = `_${val.slice(i - 3, i)}${res}`\n  }\n  return `${val.slice(0, i)}${res}`\n}\n\n// CHECK FUNCTIONS\n// ===============\n\nfunction checkBounds (buf, offset, byteLength) {\n  validateNumber(offset, 'offset')\n  if (buf[offset] === undefined || buf[offset + byteLength] === undefined) {\n    boundsError(offset, buf.length - (byteLength + 1))\n  }\n}\n\nfunction checkIntBI (value, min, max, buf, offset, byteLength) {\n  if (value > max || value < min) {\n    const n = typeof min === 'bigint' ? 'n' : ''\n    let range\n    if (byteLength > 3) {\n      if (min === 0 || min === BigInt(0)) {\n        range = `>= 0${n} and < 2${n} ** ${(byteLength + 1) * 8}${n}`\n      } else {\n        range = `>= -(2${n} ** ${(byteLength + 1) * 8 - 1}${n}) and < 2 ** ` +\n                `${(byteLength + 1) * 8 - 1}${n}`\n      }\n    } else {\n      range = `>= ${min}${n} and <= ${max}${n}`\n    }\n    throw new errors.ERR_OUT_OF_RANGE('value', range, value)\n  }\n  checkBounds(buf, offset, byteLength)\n}\n\nfunction validateNumber (value, name) {\n  if (typeof value !== 'number') {\n    throw new errors.ERR_INVALID_ARG_TYPE(name, 'number', value)\n  }\n}\n\nfunction boundsError (value, length, type) {\n  if (Math.floor(value) !== value) {\n    validateNumber(value, type)\n    throw new errors.ERR_OUT_OF_RANGE(type || 'offset', 'an integer', value)\n  }\n\n  if (length < 0) {\n    throw new errors.ERR_BUFFER_OUT_OF_BOUNDS()\n  }\n\n  throw new errors.ERR_OUT_OF_RANGE(type || 'offset',\n                                    `>= ${type ? 1 : 0} and <= ${length}`,\n                                    value)\n}\n\n// HELPER FUNCTIONS\n// ================\n\nconst INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g\n\nfunction base64clean (str) {\n  // Node takes equal signs as end of the Base64 encoding\n  str = str.split('=')[0]\n  // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\n  str = str.trim().replace(INVALID_BASE64_RE, '')\n  // Node converts strings with length < 2 to ''\n  if (str.length < 2) return ''\n  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\n  while (str.length % 4 !== 0) {\n    str = str + '='\n  }\n  return str\n}\n\nfunction utf8ToBytes (string, units) {\n  units = units || Infinity\n  let codePoint\n  const length = string.length\n  let leadSurrogate = null\n  const bytes = []\n\n  for (let i = 0; i < length; ++i) {\n    codePoint = string.charCodeAt(i)\n\n    // is surrogate component\n    if (codePoint > 0xD7FF && codePoint < 0xE000) {\n      // last char was a lead\n      if (!leadSurrogate) {\n        // no lead yet\n        if (codePoint > 0xDBFF) {\n          // unexpected trail\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        } else if (i + 1 === length) {\n          // unpaired lead\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        }\n\n        // valid lead\n        leadSurrogate = codePoint\n\n        continue\n      }\n\n      // 2 leads in a row\n      if (codePoint < 0xDC00) {\n        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n        leadSurrogate = codePoint\n        continue\n      }\n\n      // valid surrogate pair\n      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000\n    } else if (leadSurrogate) {\n      // valid bmp char, but last char was a lead\n      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n    }\n\n    leadSurrogate = null\n\n    // encode utf8\n    if (codePoint < 0x80) {\n      if ((units -= 1) < 0) break\n      bytes.push(codePoint)\n    } else if (codePoint < 0x800) {\n      if ((units -= 2) < 0) break\n      bytes.push(\n        codePoint >> 0x6 | 0xC0,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x10000) {\n      if ((units -= 3) < 0) break\n      bytes.push(\n        codePoint >> 0xC | 0xE0,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x110000) {\n      if ((units -= 4) < 0) break\n      bytes.push(\n        codePoint >> 0x12 | 0xF0,\n        codePoint >> 0xC & 0x3F | 0x80,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else {\n      throw new Error('Invalid code point')\n    }\n  }\n\n  return bytes\n}\n\nfunction asciiToBytes (str) {\n  const byteArray = []\n  for (let i = 0; i < str.length; ++i) {\n    // Node's code seems to be doing this and not & 0x7F..\n    byteArray.push(str.charCodeAt(i) & 0xFF)\n  }\n  return byteArray\n}\n\nfunction utf16leToBytes (str, units) {\n  let c, hi, lo\n  const byteArray = []\n  for (let i = 0; i < str.length; ++i) {\n    if ((units -= 2) < 0) break\n\n    c = str.charCodeAt(i)\n    hi = c >> 8\n    lo = c % 256\n    byteArray.push(lo)\n    byteArray.push(hi)\n  }\n\n  return byteArray\n}\n\nfunction base64ToBytes (str) {\n  return base64.toByteArray(base64clean(str))\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n  let i\n  for (i = 0; i < length; ++i) {\n    if ((i + offset >= dst.length) || (i >= src.length)) break\n    dst[i + offset] = src[i]\n  }\n  return i\n}\n\n// ArrayBuffer or Uint8Array objects from other contexts (i.e. iframes) do not pass\n// the `instanceof` check but they should be treated as of that type.\n// See: https://github.com/feross/buffer/issues/166\nfunction isInstance (obj, type) {\n  return obj instanceof type ||\n    (obj != null && obj.constructor != null && obj.constructor.name != null &&\n      obj.constructor.name === type.name)\n}\nfunction numberIsNaN (obj) {\n  // For IE11 support\n  return obj !== obj // eslint-disable-line no-self-compare\n}\n\n// Create lookup table for `toString('hex')`\n// See: https://github.com/feross/buffer/issues/219\nconst hexSliceLookupTable = (function () {\n  const alphabet = '0123456789abcdef'\n  const table = new Array(256)\n  for (let i = 0; i < 16; ++i) {\n    const i16 = i * 16\n    for (let j = 0; j < 16; ++j) {\n      table[i16 + j] = alphabet[i] + alphabet[j]\n    }\n  }\n  return table\n})()\n\n// Return not function with Error if BigInt not supported\nfunction defineBigIntMethod (fn) {\n  return typeof BigInt === 'undefined' ? BufferBigIntNotDefined : fn\n}\n\nfunction BufferBigIntNotDefined () {\n  throw new Error('BigInt not supported')\n}\n","// This is a minimal subset of node-ip for handling IPMatch\n// https://github.com/indutny/node-ip/blob/master/lib/ip.js\n//\n// ### License\n//\n// This software is licensed under the MIT License.\n//\n// Copyright Fedor Indutny, 2012.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nimport { Buffer } from 'buffer';\n\nconst ipv4Regex = /^(\\d{1,3}\\.){3,3}\\d{1,3}$/;\nconst ipv6Regex = /^(::)?(((\\d{1,3}\\.){3}(\\d{1,3}){1})?([0-9a-f]){0,4}:{0,2}){1,8}(::)?$/i;\n\nexport const ip = {\n  toBuffer: function (ip: string, buff?: Buffer, offset?: number): Buffer {\n    offset = offset ? offset : 0;\n\n    let result;\n\n    if (this.isV4Format(ip)) {\n      result = buff || new Buffer(offset + 4);\n      ip.split(/\\./g).map(function (byte) {\n        offset = offset ? offset : 0;\n        result[offset++] = parseInt(byte, 10) & 0xff;\n      });\n    } else if (this.isV6Format(ip)) {\n      const sections = ip.split(':', 8);\n\n      let i;\n      for (i = 0; i < sections.length; i++) {\n        const isv4 = this.isV4Format(sections[i]);\n\n        let v4Buffer;\n\n        if (isv4) {\n          v4Buffer = this.toBuffer(sections[i]);\n          sections[i] = v4Buffer.slice(0, 2).toString('hex');\n        }\n\n        if (v4Buffer && ++i < 8) {\n          sections.splice(i, 0, v4Buffer.slice(2, 4).toString('hex'));\n        }\n      }\n\n      if (sections[0] === '') {\n        while (sections.length < 8) sections.unshift('0');\n      } else if (sections[sections.length - 1] === '') {\n        while (sections.length < 8) sections.push('0');\n      } else if (sections.length < 8) {\n        for (i = 0; i < sections.length && sections[i] !== ''; i++) {}\n        const argv = [i, 1];\n        for (i = 9 - sections.length; i > 0; i--) {\n          // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n          // @ts-ignore\n          argv.push('0');\n        }\n        // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n        // @ts-ignore\n        // eslint-disable-next-line prefer-spread\n        sections.splice.apply(sections, argv);\n      }\n\n      result = buff || new Buffer(offset + 16);\n      for (i = 0; i < sections.length; i++) {\n        const word = parseInt(sections[i], 16);\n        result[offset++] = (word >> 8) & 0xff;\n        result[offset++] = word & 0xff;\n      }\n    }\n\n    if (!result) {\n      throw Error('Invalid ip address: ' + ip);\n    }\n\n    return result;\n  },\n  toString: function (buff: Buffer, offset?: number, length?: number): string {\n    offset = offset ? offset : 0;\n    length = length || buff.length - offset;\n\n    let result = [];\n    if (length === 4) {\n      // IPv4\n      for (let i = 0; i < length; i++) {\n        result.push(buff[offset + i]);\n      }\n      // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n      // @ts-ignore\n      result = result.join('.');\n    } else if (length === 16) {\n      // IPv6\n      for (let i = 0; i < length; i += 2) {\n        result.push(buff.readUInt16BE(offset + i).toString(16));\n      }\n      // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n      // @ts-ignore\n      result = result.join(':');\n      // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n      // @ts-ignore\n      result = (result as string).replace(/(^|:)0(:0)*:0(:|$)/, '$1::$3');\n      // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n      // @ts-ignore\n      result = (result as string).replace(/:{3,4}/, '::');\n    }\n    // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n    // @ts-ignore\n    return result as string;\n  },\n  isV4Format: function (ip: string): boolean {\n    return ipv4Regex.test(ip);\n  },\n\n  isV6Format: function (ip: string): boolean {\n    return ipv6Regex.test(ip);\n  },\n\n  fromPrefixLen: function (prefixlen: number, family?: string): string {\n    if (prefixlen > 32) {\n      family = 'ipv6';\n    } else {\n      family = _normalizeFamily(typeof family === 'string' ? family : '');\n    }\n\n    let len = 4;\n    if (family === 'ipv6') {\n      len = 16;\n    }\n    const buff = new Buffer(len);\n\n    for (let i = 0, n = buff.length; i < n; ++i) {\n      let bits = 8;\n      if (prefixlen < 8) {\n        bits = prefixlen;\n      }\n      prefixlen -= bits;\n\n      buff[i] = ~(0xff >> bits) & 0xff;\n    }\n\n    return ip.toString(buff);\n  },\n\n  mask: function (addr: string, mask: string): string {\n    const addrBuffer = ip.toBuffer(addr);\n    const maskBuffer = ip.toBuffer(mask);\n\n    const result = new Buffer(Math.max(addrBuffer.length, maskBuffer.length));\n\n    let i;\n    // Same protocol - do bitwise and\n    if (addrBuffer.length === maskBuffer.length) {\n      for (i = 0; i < addrBuffer.length; i++) {\n        result[i] = addrBuffer[i] & maskBuffer[i];\n      }\n    } else if (maskBuffer.length === 4) {\n      // IPv6 address and IPv4 mask\n      // (Mask low bits)\n      for (i = 0; i < maskBuffer.length; i++) {\n        result[i] = addrBuffer[addrBuffer.length - 4 + i] & maskBuffer[i];\n      }\n    } else {\n      // IPv6 mask and IPv4 addr\n      for (let i = 0; i < result.length - 6; i++) {\n        result[i] = 0;\n      }\n\n      // ::ffff:ipv4\n      result[10] = 0xff;\n      result[11] = 0xff;\n      for (i = 0; i < addrBuffer.length; i++) {\n        result[i + 12] = addrBuffer[i] & maskBuffer[i + 12];\n      }\n      i = i + 12;\n    }\n    for (; i < result.length; i++) result[i] = 0;\n\n    return ip.toString(result);\n  },\n\n  subnet: function (addr: string, mask: string): any {\n    const networkAddress = ip.toLong(ip.mask(addr, mask));\n\n    // Calculate the mask's length.\n    const maskBuffer = ip.toBuffer(mask);\n    let maskLength = 0;\n\n    for (let i = 0; i < maskBuffer.length; i++) {\n      if (maskBuffer[i] === 0xff) {\n        maskLength += 8;\n      } else {\n        let octet = maskBuffer[i] & 0xff;\n        while (octet) {\n          octet = (octet << 1) & 0xff;\n          maskLength++;\n        }\n      }\n    }\n\n    return {\n      contains: function (other: string) {\n        return networkAddress === ip.toLong(ip.mask(other, mask));\n      },\n    };\n  },\n  cidrSubnet: function (cidrString: string): any {\n    const cidrParts = cidrString.split('/');\n\n    const addr = cidrParts[0];\n    if (cidrParts.length !== 2) throw new Error('invalid CIDR subnet: ' + addr);\n\n    const mask = ip.fromPrefixLen(parseInt(cidrParts[1], 10));\n\n    return ip.subnet(addr, mask);\n  },\n  isEqual: function (a: string, b: string): boolean {\n    let aBuffer = ip.toBuffer(a);\n    let bBuffer = ip.toBuffer(b);\n\n    // Same protocol\n    if (aBuffer.length === bBuffer.length) {\n      for (let i = 0; i < aBuffer.length; i++) {\n        if (aBuffer[i] !== bBuffer[i]) return false;\n      }\n      return true;\n    }\n\n    // Swap\n    if (bBuffer.length === 4) {\n      const t = bBuffer;\n      bBuffer = aBuffer;\n      aBuffer = t;\n    }\n\n    // a - IPv4, b - IPv6\n    for (let i = 0; i < 10; i++) {\n      if (bBuffer[i] !== 0) return false;\n    }\n\n    const word = bBuffer.readUInt16BE(10);\n    if (word !== 0 && word !== 0xffff) return false;\n\n    for (let i = 0; i < 4; i++) {\n      if (aBuffer[i] !== bBuffer[i + 12]) return false;\n    }\n\n    return true;\n  },\n  toLong: function (ip: string): number {\n    let ipl = 0;\n    ip.split('.').forEach(function (octet) {\n      ipl <<= 8;\n      ipl += parseInt(octet);\n    });\n    return ipl >>> 0;\n  },\n  fromLong: function (ipl: number): string {\n    return (ipl >>> 24) + '.' + ((ipl >> 16) & 255) + '.' + ((ipl >> 8) & 255) + '.' + (ipl & 255);\n  },\n};\n\nfunction _normalizeFamily(family: string): string {\n  return family ? family.toLowerCase() : 'ipv4';\n}\n","const isWindows = typeof process === 'object' &&\n  process &&\n  process.platform === 'win32'\nmodule.exports = isWindows ? { sep: '\\\\' } : { sep: '/' }\n","'use strict';\nmodule.exports = balanced;\nfunction balanced(a, b, str) {\n  if (a instanceof RegExp) a = maybeMatch(a, str);\n  if (b instanceof RegExp) b = maybeMatch(b, str);\n\n  var r = range(a, b, str);\n\n  return r && {\n    start: r[0],\n    end: r[1],\n    pre: str.slice(0, r[0]),\n    body: str.slice(r[0] + a.length, r[1]),\n    post: str.slice(r[1] + b.length)\n  };\n}\n\nfunction maybeMatch(reg, str) {\n  var m = str.match(reg);\n  return m ? m[0] : null;\n}\n\nbalanced.range = range;\nfunction range(a, b, str) {\n  var begs, beg, left, right, result;\n  var ai = str.indexOf(a);\n  var bi = str.indexOf(b, ai + 1);\n  var i = ai;\n\n  if (ai >= 0 && bi > 0) {\n    if(a===b) {\n      return [ai, bi];\n    }\n    begs = [];\n    left = str.length;\n\n    while (i >= 0 && !result) {\n      if (i == ai) {\n        begs.push(i);\n        ai = str.indexOf(a, i + 1);\n      } else if (begs.length == 1) {\n        result = [ begs.pop(), bi ];\n      } else {\n        beg = begs.pop();\n        if (beg < left) {\n          left = beg;\n          right = bi;\n        }\n\n        bi = str.indexOf(b, i + 1);\n      }\n\n      i = ai < bi && ai >= 0 ? ai : bi;\n    }\n\n    if (begs.length) {\n      result = [ left, right ];\n    }\n  }\n\n  return result;\n}\n","var balanced = require('balanced-match');\n\nmodule.exports = expandTop;\n\nvar escSlash = '\\0SLASH'+Math.random()+'\\0';\nvar escOpen = '\\0OPEN'+Math.random()+'\\0';\nvar escClose = '\\0CLOSE'+Math.random()+'\\0';\nvar escComma = '\\0COMMA'+Math.random()+'\\0';\nvar escPeriod = '\\0PERIOD'+Math.random()+'\\0';\n\nfunction numeric(str) {\n  return parseInt(str, 10) == str\n    ? parseInt(str, 10)\n    : str.charCodeAt(0);\n}\n\nfunction escapeBraces(str) {\n  return str.split('\\\\\\\\').join(escSlash)\n            .split('\\\\{').join(escOpen)\n            .split('\\\\}').join(escClose)\n            .split('\\\\,').join(escComma)\n            .split('\\\\.').join(escPeriod);\n}\n\nfunction unescapeBraces(str) {\n  return str.split(escSlash).join('\\\\')\n            .split(escOpen).join('{')\n            .split(escClose).join('}')\n            .split(escComma).join(',')\n            .split(escPeriod).join('.');\n}\n\n\n// Basically just str.split(\",\"), but handling cases\n// where we have nested braced sections, which should be\n// treated as individual members, like {a,{b,c},d}\nfunction parseCommaParts(str) {\n  if (!str)\n    return [''];\n\n  var parts = [];\n  var m = balanced('{', '}', str);\n\n  if (!m)\n    return str.split(',');\n\n  var pre = m.pre;\n  var body = m.body;\n  var post = m.post;\n  var p = pre.split(',');\n\n  p[p.length-1] += '{' + body + '}';\n  var postParts = parseCommaParts(post);\n  if (post.length) {\n    p[p.length-1] += postParts.shift();\n    p.push.apply(p, postParts);\n  }\n\n  parts.push.apply(parts, p);\n\n  return parts;\n}\n\nfunction expandTop(str) {\n  if (!str)\n    return [];\n\n  // I don't know why Bash 4.3 does this, but it does.\n  // Anything starting with {} will have the first two bytes preserved\n  // but *only* at the top level, so {},a}b will not expand to anything,\n  // but a{},b}c will be expanded to [a}c,abc].\n  // One could argue that this is a bug in Bash, but since the goal of\n  // this module is to match Bash's rules, we escape a leading {}\n  if (str.substr(0, 2) === '{}') {\n    str = '\\\\{\\\\}' + str.substr(2);\n  }\n\n  return expand(escapeBraces(str), true).map(unescapeBraces);\n}\n\nfunction embrace(str) {\n  return '{' + str + '}';\n}\nfunction isPadded(el) {\n  return /^-?0\\d/.test(el);\n}\n\nfunction lte(i, y) {\n  return i <= y;\n}\nfunction gte(i, y) {\n  return i >= y;\n}\n\nfunction expand(str, isTop) {\n  var expansions = [];\n\n  var m = balanced('{', '}', str);\n  if (!m) return [str];\n\n  // no need to expand pre, since it is guaranteed to be free of brace-sets\n  var pre = m.pre;\n  var post = m.post.length\n    ? expand(m.post, false)\n    : [''];\n\n  if (/\\$$/.test(m.pre)) {    \n    for (var k = 0; k < post.length; k++) {\n      var expansion = pre+ '{' + m.body + '}' + post[k];\n      expansions.push(expansion);\n    }\n  } else {\n    var isNumericSequence = /^-?\\d+\\.\\.-?\\d+(?:\\.\\.-?\\d+)?$/.test(m.body);\n    var isAlphaSequence = /^[a-zA-Z]\\.\\.[a-zA-Z](?:\\.\\.-?\\d+)?$/.test(m.body);\n    var isSequence = isNumericSequence || isAlphaSequence;\n    var isOptions = m.body.indexOf(',') >= 0;\n    if (!isSequence && !isOptions) {\n      // {a},b}\n      if (m.post.match(/,.*\\}/)) {\n        str = m.pre + '{' + m.body + escClose + m.post;\n        return expand(str);\n      }\n      return [str];\n    }\n\n    var n;\n    if (isSequence) {\n      n = m.body.split(/\\.\\./);\n    } else {\n      n = parseCommaParts(m.body);\n      if (n.length === 1) {\n        // x{{a,b}}y ==> x{a}y x{b}y\n        n = expand(n[0], false).map(embrace);\n        if (n.length === 1) {\n          return post.map(function(p) {\n            return m.pre + n[0] + p;\n          });\n        }\n      }\n    }\n\n    // at this point, n is the parts, and we know it's not a comma set\n    // with a single entry.\n    var N;\n\n    if (isSequence) {\n      var x = numeric(n[0]);\n      var y = numeric(n[1]);\n      var width = Math.max(n[0].length, n[1].length)\n      var incr = n.length == 3\n        ? Math.abs(numeric(n[2]))\n        : 1;\n      var test = lte;\n      var reverse = y < x;\n      if (reverse) {\n        incr *= -1;\n        test = gte;\n      }\n      var pad = n.some(isPadded);\n\n      N = [];\n\n      for (var i = x; test(i, y); i += incr) {\n        var c;\n        if (isAlphaSequence) {\n          c = String.fromCharCode(i);\n          if (c === '\\\\')\n            c = '';\n        } else {\n          c = String(i);\n          if (pad) {\n            var need = width - c.length;\n            if (need > 0) {\n              var z = new Array(need + 1).join('0');\n              if (i < 0)\n                c = '-' + z + c.slice(1);\n              else\n                c = z + c;\n            }\n          }\n        }\n        N.push(c);\n      }\n    } else {\n      N = [];\n\n      for (var j = 0; j < n.length; j++) {\n        N.push.apply(N, expand(n[j], false));\n      }\n    }\n\n    for (var j = 0; j < N.length; j++) {\n      for (var k = 0; k < post.length; k++) {\n        var expansion = pre + N[j] + post[k];\n        if (!isTop || isSequence || expansion)\n          expansions.push(expansion);\n      }\n    }\n  }\n\n  return expansions;\n}\n\n","const minimatch = module.exports = (p, pattern, options = {}) => {\n  assertValidPattern(pattern)\n\n  // shortcut: comments match nothing.\n  if (!options.nocomment && pattern.charAt(0) === '#') {\n    return false\n  }\n\n  return new Minimatch(pattern, options).match(p)\n}\n\nmodule.exports = minimatch\n\nconst path = require('./lib/path.js')\nminimatch.sep = path.sep\n\nconst GLOBSTAR = Symbol('globstar **')\nminimatch.GLOBSTAR = GLOBSTAR\nconst expand = require('brace-expansion')\n\nconst plTypes = {\n  '!': { open: '(?:(?!(?:', close: '))[^/]*?)'},\n  '?': { open: '(?:', close: ')?' },\n  '+': { open: '(?:', close: ')+' },\n  '*': { open: '(?:', close: ')*' },\n  '@': { open: '(?:', close: ')' }\n}\n\n// any single thing other than /\n// don't need to escape / when using new RegExp()\nconst qmark = '[^/]'\n\n// * => any number of characters\nconst star = qmark + '*?'\n\n// ** when dots are allowed.  Anything goes, except .. and .\n// not (^ or / followed by one or two dots followed by $ or /),\n// followed by anything, any number of times.\nconst twoStarDot = '(?:(?!(?:\\\\\\/|^)(?:\\\\.{1,2})($|\\\\\\/)).)*?'\n\n// not a ^ or / followed by a dot,\n// followed by anything, any number of times.\nconst twoStarNoDot = '(?:(?!(?:\\\\\\/|^)\\\\.).)*?'\n\n// \"abc\" -> { a:true, b:true, c:true }\nconst charSet = s => s.split('').reduce((set, c) => {\n  set[c] = true\n  return set\n}, {})\n\n// characters that need to be escaped in RegExp.\nconst reSpecials = charSet('().*{}+?[]^$\\\\!')\n\n// characters that indicate we have to add the pattern start\nconst addPatternStartSet = charSet('[.(')\n\n// normalizes slashes.\nconst slashSplit = /\\/+/\n\nminimatch.filter = (pattern, options = {}) =>\n  (p, i, list) => minimatch(p, pattern, options)\n\nconst ext = (a, b = {}) => {\n  const t = {}\n  Object.keys(a).forEach(k => t[k] = a[k])\n  Object.keys(b).forEach(k => t[k] = b[k])\n  return t\n}\n\nminimatch.defaults = def => {\n  if (!def || typeof def !== 'object' || !Object.keys(def).length) {\n    return minimatch\n  }\n\n  const orig = minimatch\n\n  const m = (p, pattern, options) => orig(p, pattern, ext(def, options))\n  m.Minimatch = class Minimatch extends orig.Minimatch {\n    constructor (pattern, options) {\n      super(pattern, ext(def, options))\n    }\n  }\n  m.Minimatch.defaults = options => orig.defaults(ext(def, options)).Minimatch\n  m.filter = (pattern, options) => orig.filter(pattern, ext(def, options))\n  m.defaults = options => orig.defaults(ext(def, options))\n  m.makeRe = (pattern, options) => orig.makeRe(pattern, ext(def, options))\n  m.braceExpand = (pattern, options) => orig.braceExpand(pattern, ext(def, options))\n  m.match = (list, pattern, options) => orig.match(list, pattern, ext(def, options))\n\n  return m\n}\n\n\n\n\n\n// Brace expansion:\n// a{b,c}d -> abd acd\n// a{b,}c -> abc ac\n// a{0..3}d -> a0d a1d a2d a3d\n// a{b,c{d,e}f}g -> abg acdfg acefg\n// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg\n//\n// Invalid sets are not expanded.\n// a{2..}b -> a{2..}b\n// a{b}c -> a{b}c\nminimatch.braceExpand = (pattern, options) => braceExpand(pattern, options)\n\nconst braceExpand = (pattern, options = {}) => {\n  assertValidPattern(pattern)\n\n  // Thanks to Yeting Li <https://github.com/yetingli> for\n  // improving this regexp to avoid a ReDOS vulnerability.\n  if (options.nobrace || !/\\{(?:(?!\\{).)*\\}/.test(pattern)) {\n    // shortcut. no need to expand.\n    return [pattern]\n  }\n\n  return expand(pattern)\n}\n\nconst MAX_PATTERN_LENGTH = 1024 * 64\nconst assertValidPattern = pattern => {\n  if (typeof pattern !== 'string') {\n    throw new TypeError('invalid pattern')\n  }\n\n  if (pattern.length > MAX_PATTERN_LENGTH) {\n    throw new TypeError('pattern is too long')\n  }\n}\n\n// parse a component of the expanded set.\n// At this point, no pattern may contain \"/\" in it\n// so we're going to return a 2d array, where each entry is the full\n// pattern, split on '/', and then turned into a regular expression.\n// A regexp is made at the end which joins each array with an\n// escaped /, and another full one which joins each regexp with |.\n//\n// Following the lead of Bash 4.1, note that \"**\" only has special meaning\n// when it is the *only* thing in a path portion.  Otherwise, any series\n// of * is equivalent to a single *.  Globstar behavior is enabled by\n// default, and can be disabled by setting options.noglobstar.\nconst SUBPARSE = Symbol('subparse')\n\nminimatch.makeRe = (pattern, options) =>\n  new Minimatch(pattern, options || {}).makeRe()\n\nminimatch.match = (list, pattern, options = {}) => {\n  const mm = new Minimatch(pattern, options)\n  list = list.filter(f => mm.match(f))\n  if (mm.options.nonull && !list.length) {\n    list.push(pattern)\n  }\n  return list\n}\n\n// replace stuff like \\* with *\nconst globUnescape = s => s.replace(/\\\\(.)/g, '$1')\nconst regExpEscape = s => s.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&')\n\nclass Minimatch {\n  constructor (pattern, options) {\n    assertValidPattern(pattern)\n\n    if (!options) options = {}\n\n    this.options = options\n    this.set = []\n    this.pattern = pattern\n    this.regexp = null\n    this.negate = false\n    this.comment = false\n    this.empty = false\n    this.partial = !!options.partial\n\n    // make the set of regexps etc.\n    this.make()\n  }\n\n  debug () {}\n\n  make () {\n    const pattern = this.pattern\n    const options = this.options\n\n    // empty patterns and comments match nothing.\n    if (!options.nocomment && pattern.charAt(0) === '#') {\n      this.comment = true\n      return\n    }\n    if (!pattern) {\n      this.empty = true\n      return\n    }\n\n    // step 1: figure out negation, etc.\n    this.parseNegate()\n\n    // step 2: expand braces\n    let set = this.globSet = this.braceExpand()\n\n    if (options.debug) this.debug = (...args) => console.error(...args)\n\n    this.debug(this.pattern, set)\n\n    // step 3: now we have a set, so turn each one into a series of path-portion\n    // matching patterns.\n    // These will be regexps, except in the case of \"**\", which is\n    // set to the GLOBSTAR object for globstar behavior,\n    // and will not contain any / characters\n    set = this.globParts = set.map(s => s.split(slashSplit))\n\n    this.debug(this.pattern, set)\n\n    // glob --> regexps\n    set = set.map((s, si, set) => s.map(this.parse, this))\n\n    this.debug(this.pattern, set)\n\n    // filter out everything that didn't compile properly.\n    set = set.filter(s => s.indexOf(false) === -1)\n\n    this.debug(this.pattern, set)\n\n    this.set = set\n  }\n\n  parseNegate () {\n    if (this.options.nonegate) return\n\n    const pattern = this.pattern\n    let negate = false\n    let negateOffset = 0\n\n    for (let i = 0; i < pattern.length && pattern.charAt(i) === '!'; i++) {\n      negate = !negate\n      negateOffset++\n    }\n\n    if (negateOffset) this.pattern = pattern.substr(negateOffset)\n    this.negate = negate\n  }\n\n  // set partial to true to test if, for example,\n  // \"/a/b\" matches the start of \"/*/b/*/d\"\n  // Partial means, if you run out of file before you run\n  // out of pattern, then that's fine, as long as all\n  // the parts match.\n  matchOne (file, pattern, partial) {\n    var options = this.options\n\n    this.debug('matchOne',\n      { 'this': this, file: file, pattern: pattern })\n\n    this.debug('matchOne', file.length, pattern.length)\n\n    for (var fi = 0,\n        pi = 0,\n        fl = file.length,\n        pl = pattern.length\n        ; (fi < fl) && (pi < pl)\n        ; fi++, pi++) {\n      this.debug('matchOne loop')\n      var p = pattern[pi]\n      var f = file[fi]\n\n      this.debug(pattern, p, f)\n\n      // should be impossible.\n      // some invalid regexp stuff in the set.\n      /* istanbul ignore if */\n      if (p === false) return false\n\n      if (p === GLOBSTAR) {\n        this.debug('GLOBSTAR', [pattern, p, f])\n\n        // \"**\"\n        // a/**/b/**/c would match the following:\n        // a/b/x/y/z/c\n        // a/x/y/z/b/c\n        // a/b/x/b/x/c\n        // a/b/c\n        // To do this, take the rest of the pattern after\n        // the **, and see if it would match the file remainder.\n        // If so, return success.\n        // If not, the ** \"swallows\" a segment, and try again.\n        // This is recursively awful.\n        //\n        // a/**/b/**/c matching a/b/x/y/z/c\n        // - a matches a\n        // - doublestar\n        //   - matchOne(b/x/y/z/c, b/**/c)\n        //     - b matches b\n        //     - doublestar\n        //       - matchOne(x/y/z/c, c) -> no\n        //       - matchOne(y/z/c, c) -> no\n        //       - matchOne(z/c, c) -> no\n        //       - matchOne(c, c) yes, hit\n        var fr = fi\n        var pr = pi + 1\n        if (pr === pl) {\n          this.debug('** at the end')\n          // a ** at the end will just swallow the rest.\n          // We have found a match.\n          // however, it will not swallow /.x, unless\n          // options.dot is set.\n          // . and .. are *never* matched by **, for explosively\n          // exponential reasons.\n          for (; fi < fl; fi++) {\n            if (file[fi] === '.' || file[fi] === '..' ||\n              (!options.dot && file[fi].charAt(0) === '.')) return false\n          }\n          return true\n        }\n\n        // ok, let's see if we can swallow whatever we can.\n        while (fr < fl) {\n          var swallowee = file[fr]\n\n          this.debug('\\nglobstar while', file, fr, pattern, pr, swallowee)\n\n          // XXX remove this slice.  Just pass the start index.\n          if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {\n            this.debug('globstar found match!', fr, fl, swallowee)\n            // found a match.\n            return true\n          } else {\n            // can't swallow \".\" or \"..\" ever.\n            // can only swallow \".foo\" when explicitly asked.\n            if (swallowee === '.' || swallowee === '..' ||\n              (!options.dot && swallowee.charAt(0) === '.')) {\n              this.debug('dot detected!', file, fr, pattern, pr)\n              break\n            }\n\n            // ** swallows a segment, and continue.\n            this.debug('globstar swallow a segment, and continue')\n            fr++\n          }\n        }\n\n        // no match was found.\n        // However, in partial mode, we can't say this is necessarily over.\n        // If there's more *pattern* left, then\n        /* istanbul ignore if */\n        if (partial) {\n          // ran out of file\n          this.debug('\\n>>> no match, partial?', file, fr, pattern, pr)\n          if (fr === fl) return true\n        }\n        return false\n      }\n\n      // something other than **\n      // non-magic patterns just have to match exactly\n      // patterns with magic have been turned into regexps.\n      var hit\n      if (typeof p === 'string') {\n        hit = f === p\n        this.debug('string match', p, f, hit)\n      } else {\n        hit = f.match(p)\n        this.debug('pattern match', p, f, hit)\n      }\n\n      if (!hit) return false\n    }\n\n    // Note: ending in / means that we'll get a final \"\"\n    // at the end of the pattern.  This can only match a\n    // corresponding \"\" at the end of the file.\n    // If the file ends in /, then it can only match a\n    // a pattern that ends in /, unless the pattern just\n    // doesn't have any more for it. But, a/b/ should *not*\n    // match \"a/b/*\", even though \"\" matches against the\n    // [^/]*? pattern, except in partial mode, where it might\n    // simply not be reached yet.\n    // However, a/b/ should still satisfy a/*\n\n    // now either we fell off the end of the pattern, or we're done.\n    if (fi === fl && pi === pl) {\n      // ran out of pattern and filename at the same time.\n      // an exact hit!\n      return true\n    } else if (fi === fl) {\n      // ran out of file, but still had pattern left.\n      // this is ok if we're doing the match as part of\n      // a glob fs traversal.\n      return partial\n    } else /* istanbul ignore else */ if (pi === pl) {\n      // ran out of pattern, still have file left.\n      // this is only acceptable if we're on the very last\n      // empty segment of a file with a trailing slash.\n      // a/* should match a/b/\n      return (fi === fl - 1) && (file[fi] === '')\n    }\n\n    // should be unreachable.\n    /* istanbul ignore next */\n    throw new Error('wtf?')\n  }\n\n  braceExpand () {\n    return braceExpand(this.pattern, this.options)\n  }\n\n  parse (pattern, isSub) {\n    assertValidPattern(pattern)\n\n    const options = this.options\n\n    // shortcuts\n    if (pattern === '**') {\n      if (!options.noglobstar)\n        return GLOBSTAR\n      else\n        pattern = '*'\n    }\n    if (pattern === '') return ''\n\n    let re = ''\n    let hasMagic = !!options.nocase\n    let escaping = false\n    // ? => one single character\n    const patternListStack = []\n    const negativeLists = []\n    let stateChar\n    let inClass = false\n    let reClassStart = -1\n    let classStart = -1\n    let cs\n    let pl\n    let sp\n    // . and .. never match anything that doesn't start with .,\n    // even when options.dot is set.\n    const patternStart = pattern.charAt(0) === '.' ? '' // anything\n    // not (start or / followed by . or .. followed by / or end)\n    : options.dot ? '(?!(?:^|\\\\\\/)\\\\.{1,2}(?:$|\\\\\\/))'\n    : '(?!\\\\.)'\n\n    const clearStateChar = () => {\n      if (stateChar) {\n        // we had some state-tracking character\n        // that wasn't consumed by this pass.\n        switch (stateChar) {\n          case '*':\n            re += star\n            hasMagic = true\n          break\n          case '?':\n            re += qmark\n            hasMagic = true\n          break\n          default:\n            re += '\\\\' + stateChar\n          break\n        }\n        this.debug('clearStateChar %j %j', stateChar, re)\n        stateChar = false\n      }\n    }\n\n    for (let i = 0, c; (i < pattern.length) && (c = pattern.charAt(i)); i++) {\n      this.debug('%s\\t%s %s %j', pattern, i, re, c)\n\n      // skip over any that are escaped.\n      if (escaping) {\n        /* istanbul ignore next - completely not allowed, even escaped. */\n        if (c === '/') {\n          return false\n        }\n\n        if (reSpecials[c]) {\n          re += '\\\\'\n        }\n        re += c\n        escaping = false\n        continue\n      }\n\n      switch (c) {\n        /* istanbul ignore next */\n        case '/': {\n          // Should already be path-split by now.\n          return false\n        }\n\n        case '\\\\':\n          clearStateChar()\n          escaping = true\n        continue\n\n        // the various stateChar values\n        // for the \"extglob\" stuff.\n        case '?':\n        case '*':\n        case '+':\n        case '@':\n        case '!':\n          this.debug('%s\\t%s %s %j <-- stateChar', pattern, i, re, c)\n\n          // all of those are literals inside a class, except that\n          // the glob [!a] means [^a] in regexp\n          if (inClass) {\n            this.debug('  in class')\n            if (c === '!' && i === classStart + 1) c = '^'\n            re += c\n            continue\n          }\n\n          // if we already have a stateChar, then it means\n          // that there was something like ** or +? in there.\n          // Handle the stateChar, then proceed with this one.\n          this.debug('call clearStateChar %j', stateChar)\n          clearStateChar()\n          stateChar = c\n          // if extglob is disabled, then +(asdf|foo) isn't a thing.\n          // just clear the statechar *now*, rather than even diving into\n          // the patternList stuff.\n          if (options.noext) clearStateChar()\n        continue\n\n        case '(':\n          if (inClass) {\n            re += '('\n            continue\n          }\n\n          if (!stateChar) {\n            re += '\\\\('\n            continue\n          }\n\n          patternListStack.push({\n            type: stateChar,\n            start: i - 1,\n            reStart: re.length,\n            open: plTypes[stateChar].open,\n            close: plTypes[stateChar].close\n          })\n          // negation is (?:(?!js)[^/]*)\n          re += stateChar === '!' ? '(?:(?!(?:' : '(?:'\n          this.debug('plType %j %j', stateChar, re)\n          stateChar = false\n        continue\n\n        case ')':\n          if (inClass || !patternListStack.length) {\n            re += '\\\\)'\n            continue\n          }\n\n          clearStateChar()\n          hasMagic = true\n          pl = patternListStack.pop()\n          // negation is (?:(?!js)[^/]*)\n          // The others are (?:<pattern>)<type>\n          re += pl.close\n          if (pl.type === '!') {\n            negativeLists.push(pl)\n          }\n          pl.reEnd = re.length\n        continue\n\n        case '|':\n          if (inClass || !patternListStack.length) {\n            re += '\\\\|'\n            continue\n          }\n\n          clearStateChar()\n          re += '|'\n        continue\n\n        // these are mostly the same in regexp and glob\n        case '[':\n          // swallow any state-tracking char before the [\n          clearStateChar()\n\n          if (inClass) {\n            re += '\\\\' + c\n            continue\n          }\n\n          inClass = true\n          classStart = i\n          reClassStart = re.length\n          re += c\n        continue\n\n        case ']':\n          //  a right bracket shall lose its special\n          //  meaning and represent itself in\n          //  a bracket expression if it occurs\n          //  first in the list.  -- POSIX.2 2.8.3.2\n          if (i === classStart + 1 || !inClass) {\n            re += '\\\\' + c\n            continue\n          }\n\n          // handle the case where we left a class open.\n          // \"[z-a]\" is valid, equivalent to \"\\[z-a\\]\"\n          // split where the last [ was, make sure we don't have\n          // an invalid re. if so, re-walk the contents of the\n          // would-be class to re-translate any characters that\n          // were passed through as-is\n          // TODO: It would probably be faster to determine this\n          // without a try/catch and a new RegExp, but it's tricky\n          // to do safely.  For now, this is safe and works.\n          cs = pattern.substring(classStart + 1, i)\n          try {\n            RegExp('[' + cs + ']')\n          } catch (er) {\n            // not a valid class!\n            sp = this.parse(cs, SUBPARSE)\n            re = re.substr(0, reClassStart) + '\\\\[' + sp[0] + '\\\\]'\n            hasMagic = hasMagic || sp[1]\n            inClass = false\n            continue\n          }\n\n          // finish up the class.\n          hasMagic = true\n          inClass = false\n          re += c\n        continue\n\n        default:\n          // swallow any state char that wasn't consumed\n          clearStateChar()\n\n          if (reSpecials[c] && !(c === '^' && inClass)) {\n            re += '\\\\'\n          }\n\n          re += c\n          break\n\n      } // switch\n    } // for\n\n    // handle the case where we left a class open.\n    // \"[abc\" is valid, equivalent to \"\\[abc\"\n    if (inClass) {\n      // split where the last [ was, and escape it\n      // this is a huge pita.  We now have to re-walk\n      // the contents of the would-be class to re-translate\n      // any characters that were passed through as-is\n      cs = pattern.substr(classStart + 1)\n      sp = this.parse(cs, SUBPARSE)\n      re = re.substr(0, reClassStart) + '\\\\[' + sp[0]\n      hasMagic = hasMagic || sp[1]\n    }\n\n    // handle the case where we had a +( thing at the *end*\n    // of the pattern.\n    // each pattern list stack adds 3 chars, and we need to go through\n    // and escape any | chars that were passed through as-is for the regexp.\n    // Go through and escape them, taking care not to double-escape any\n    // | chars that were already escaped.\n    for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) {\n      let tail\n      tail = re.slice(pl.reStart + pl.open.length)\n      this.debug('setting tail', re, pl)\n      // maybe some even number of \\, then maybe 1 \\, followed by a |\n      tail = tail.replace(/((?:\\\\{2}){0,64})(\\\\?)\\|/g, (_, $1, $2) => {\n        /* istanbul ignore else - should already be done */\n        if (!$2) {\n          // the | isn't already escaped, so escape it.\n          $2 = '\\\\'\n        }\n\n        // need to escape all those slashes *again*, without escaping the\n        // one that we need for escaping the | character.  As it works out,\n        // escaping an even number of slashes can be done by simply repeating\n        // it exactly after itself.  That's why this trick works.\n        //\n        // I am sorry that you have to see this.\n        return $1 + $1 + $2 + '|'\n      })\n\n      this.debug('tail=%j\\n   %s', tail, tail, pl, re)\n      const t = pl.type === '*' ? star\n        : pl.type === '?' ? qmark\n        : '\\\\' + pl.type\n\n      hasMagic = true\n      re = re.slice(0, pl.reStart) + t + '\\\\(' + tail\n    }\n\n    // handle trailing things that only matter at the very end.\n    clearStateChar()\n    if (escaping) {\n      // trailing \\\\\n      re += '\\\\\\\\'\n    }\n\n    // only need to apply the nodot start if the re starts with\n    // something that could conceivably capture a dot\n    const addPatternStart = addPatternStartSet[re.charAt(0)]\n\n    // Hack to work around lack of negative lookbehind in JS\n    // A pattern like: *.!(x).!(y|z) needs to ensure that a name\n    // like 'a.xyz.yz' doesn't match.  So, the first negative\n    // lookahead, has to look ALL the way ahead, to the end of\n    // the pattern.\n    for (let n = negativeLists.length - 1; n > -1; n--) {\n      const nl = negativeLists[n]\n\n      const nlBefore = re.slice(0, nl.reStart)\n      const nlFirst = re.slice(nl.reStart, nl.reEnd - 8)\n      let nlAfter = re.slice(nl.reEnd)\n      const nlLast = re.slice(nl.reEnd - 8, nl.reEnd) + nlAfter\n\n      // Handle nested stuff like *(*.js|!(*.json)), where open parens\n      // mean that we should *not* include the ) in the bit that is considered\n      // \"after\" the negated section.\n      const openParensBefore = nlBefore.split('(').length - 1\n      let cleanAfter = nlAfter\n      for (let i = 0; i < openParensBefore; i++) {\n        cleanAfter = cleanAfter.replace(/\\)[+*?]?/, '')\n      }\n      nlAfter = cleanAfter\n\n      const dollar = nlAfter === '' && isSub !== SUBPARSE ? '$' : ''\n      re = nlBefore + nlFirst + nlAfter + dollar + nlLast\n    }\n\n    // if the re is not \"\" at this point, then we need to make sure\n    // it doesn't match against an empty path part.\n    // Otherwise a/* will match a/, which it should not.\n    if (re !== '' && hasMagic) {\n      re = '(?=.)' + re\n    }\n\n    if (addPatternStart) {\n      re = patternStart + re\n    }\n\n    // parsing just a piece of a larger pattern.\n    if (isSub === SUBPARSE) {\n      return [re, hasMagic]\n    }\n\n    // skip the regexp for non-magical patterns\n    // unescape anything in it, though, so that it'll be\n    // an exact match against a file etc.\n    if (!hasMagic) {\n      return globUnescape(pattern)\n    }\n\n    const flags = options.nocase ? 'i' : ''\n    try {\n      return Object.assign(new RegExp('^' + re + '$', flags), {\n        _glob: pattern,\n        _src: re,\n      })\n    } catch (er) /* istanbul ignore next - should be impossible */ {\n      // If it was an invalid regular expression, then it can't match\n      // anything.  This trick looks for a character after the end of\n      // the string, which is of course impossible, except in multi-line\n      // mode, but it's not a /m regex.\n      return new RegExp('$.')\n    }\n  }\n\n  makeRe () {\n    if (this.regexp || this.regexp === false) return this.regexp\n\n    // at this point, this.set is a 2d array of partial\n    // pattern strings, or \"**\".\n    //\n    // It's better to use .match().  This function shouldn't\n    // be used, really, but it's pretty convenient sometimes,\n    // when you just want to work with a regex.\n    const set = this.set\n\n    if (!set.length) {\n      this.regexp = false\n      return this.regexp\n    }\n    const options = this.options\n\n    const twoStar = options.noglobstar ? star\n      : options.dot ? twoStarDot\n      : twoStarNoDot\n    const flags = options.nocase ? 'i' : ''\n\n    // coalesce globstars and regexpify non-globstar patterns\n    // if it's the only item, then we just do one twoStar\n    // if it's the first, and there are more, prepend (\\/|twoStar\\/)? to next\n    // if it's the last, append (\\/twoStar|) to previous\n    // if it's in the middle, append (\\/|\\/twoStar\\/) to previous\n    // then filter out GLOBSTAR symbols\n    let re = set.map(pattern => {\n      pattern = pattern.map(p =>\n        typeof p === 'string' ? regExpEscape(p)\n        : p === GLOBSTAR ? GLOBSTAR\n        : p._src\n      ).reduce((set, p) => {\n        if (!(set[set.length - 1] === GLOBSTAR && p === GLOBSTAR)) {\n          set.push(p)\n        }\n        return set\n      }, [])\n      pattern.forEach((p, i) => {\n        if (p !== GLOBSTAR || pattern[i-1] === GLOBSTAR) {\n          return\n        }\n        if (i === 0) {\n          if (pattern.length > 1) {\n            pattern[i+1] = '(?:\\\\\\/|' + twoStar + '\\\\\\/)?' + pattern[i+1]\n          } else {\n            pattern[i] = twoStar\n          }\n        } else if (i === pattern.length - 1) {\n          pattern[i-1] += '(?:\\\\\\/|' + twoStar + ')?'\n        } else {\n          pattern[i-1] += '(?:\\\\\\/|\\\\\\/' + twoStar + '\\\\\\/)' + pattern[i+1]\n          pattern[i+1] = GLOBSTAR\n        }\n      })\n      return pattern.filter(p => p !== GLOBSTAR).join('/')\n    }).join('|')\n\n    // must match entire pattern\n    // ending in a * or ** will make it less strict.\n    re = '^(?:' + re + ')$'\n\n    // can match anything, as long as it's not this.\n    if (this.negate) re = '^(?!' + re + ').*$'\n\n    try {\n      this.regexp = new RegExp(re, flags)\n    } catch (ex) /* istanbul ignore next - should be impossible */ {\n      this.regexp = false\n    }\n    return this.regexp\n  }\n\n  match (f, partial = this.partial) {\n    this.debug('match', f, this.pattern)\n    // short-circuit in the case of busted things.\n    // comments, etc.\n    if (this.comment) return false\n    if (this.empty) return f === ''\n\n    if (f === '/' && partial) return true\n\n    const options = this.options\n\n    // windows: need to use /, not \\\n    if (path.sep !== '/') {\n      f = f.split(path.sep).join('/')\n    }\n\n    // treat the test path as a set of pathparts.\n    f = f.split(slashSplit)\n    this.debug(this.pattern, 'split', f)\n\n    // just ONE of the pattern sets in this.set needs to match\n    // in order for it to be valid.  If negating, then just one\n    // match means that we have failed.\n    // Either way, return on the first hit.\n\n    const set = this.set\n    this.debug(this.pattern, 'set', set)\n\n    // Find the basename of the path by looking for the last non-empty segment\n    let filename\n    for (let i = f.length - 1; i >= 0; i--) {\n      filename = f[i]\n      if (filename) break\n    }\n\n    for (let i = 0; i < set.length; i++) {\n      const pattern = set[i]\n      let file = f\n      if (options.matchBase && pattern.length === 1) {\n        file = [filename]\n      }\n      const hit = this.matchOne(file, pattern, partial)\n      if (hit) {\n        if (options.flipNegate) return true\n        return !this.negate\n      }\n    }\n\n    // didn't get any hits.  this is success if it's a negative\n    // pattern, failure otherwise.\n    if (options.flipNegate) return false\n    return this.negate\n  }\n\n  static defaults (def) {\n    return minimatch.defaults(def).Minimatch\n  }\n}\n\nminimatch.Minimatch = Minimatch\n","// Copyright 2017 The casbin Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the 'License');\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an 'AS IS' BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport * as rbac from '../rbac';\nimport { ip } from './ip';\nimport minimatch from 'minimatch';\n\n// regexMatch determines whether key1 matches the pattern of key2 in regular expression.\nfunction regexMatch(key1: string, key2: string): boolean {\n  return new RegExp(key2).test(key1);\n}\n\n// keyMatch determines whether key1 matches the pattern of key2 (similar to RESTful path),\n// key2 can contain a *.\n// For example, '/foo/bar' matches '/foo/*'\nfunction keyMatch(key1: string, key2: string): boolean {\n  const pos: number = key2.indexOf('*');\n  if (pos === -1) {\n    return key1 === key2;\n  }\n\n  if (key1.length > pos) {\n    return key1.slice(0, pos) === key2.slice(0, pos);\n  }\n\n  return key1 === key2.slice(0, pos);\n}\n\n// keyMatchFunc is the wrapper for keyMatch.\nfunction keyMatchFunc(...args: any[]): boolean {\n  const [arg0, arg1] = args;\n  const name1: string = (arg0 || '').toString();\n  const name2: string = (arg1 || '').toString();\n\n  return keyMatch(name1, name2);\n}\n\n// KeyGet returns the matched part\n// For example, \"/foo/bar/foo\" matches \"/foo/*\"\n// \"bar/foo\" will been returned\nfunction keyGet(key1: string, key2: string): string {\n  const pos: number = key2.indexOf('*');\n  if (pos === -1) {\n    return '';\n  }\n  if (key1.length > pos) {\n    if (key1.slice(0, pos) === key2.slice(0, pos)) {\n      return key1.slice(pos, key1.length);\n    }\n  }\n  return '';\n}\n\n// keyGetFunc is the wrapper for keyGet.\nfunction keyGetFunc(...args: any[]): string {\n  const [arg0, arg1] = args;\n  const name1: string = (arg0 || '').toString();\n  const name2: string = (arg1 || '').toString();\n\n  return keyGet(name1, name2);\n}\n\n// keyMatch2 determines whether key1 matches the pattern of key2 (similar to RESTful path),\n// key2 can contain a *.\n// For example, '/foo/bar' matches '/foo/*', '/resource1' matches '/:resource'\nfunction keyMatch2(key1: string, key2: string): boolean {\n  key2 = key2.replace(/\\/\\*/g, '/.*');\n\n  const regexp = new RegExp(/(.*):[^/]+(.*)/g);\n  for (;;) {\n    if (!key2.includes('/:')) {\n      break;\n    }\n    key2 = key2.replace(regexp, '$1[^/]+$2');\n  }\n\n  if (key2 === '*') {\n    key2 = '(.*)';\n  }\n  return regexMatch(key1, '^' + key2 + '$');\n}\n\n// keyMatch2Func is the wrapper for keyMatch2.\nfunction keyMatch2Func(...args: any[]): boolean {\n  const [arg0, arg1] = args;\n  const name1: string = (arg0 || '').toString();\n  const name2: string = (arg1 || '').toString();\n\n  return keyMatch2(name1, name2);\n}\n\n// KeyGet2 returns value matched pattern\n// For example, \"/resource1\" matches \"/:resource\"\n// if the pathVar == \"resource\", then \"resource1\" will be returned\nfunction keyGet2(key1: string, key2: string, pathVar: string): string {\n  if (keyMatch2(key1, key2)) {\n    const re = new RegExp('[^/]+', 'g');\n    const keys = key2.match(re);\n    const values = key1.match(re);\n    if (!keys || !values) {\n      return '';\n    }\n    const index = keys.indexOf(`:${pathVar}`);\n    if (index === -1) {\n      return '';\n    }\n    return values[index];\n  } else {\n    return '';\n  }\n}\n\nfunction keyGet2Func(...args: any[]): string {\n  const [arg0, arg1, arg2] = args;\n  const name1: string = (arg0 || '').toString();\n  const name2: string = (arg1 || '').toString();\n  const name3: string = (arg2 || '').toString();\n\n  return keyGet2(name1, name2, name3);\n}\n\n// keyMatch3 determines whether key1 matches the pattern of key2 (similar to RESTful path), key2 can contain a *.\n// For example, '/foo/bar' matches '/foo/*', '/resource1' matches '/{resource}'\nfunction keyMatch3(key1: string, key2: string): boolean {\n  key2 = key2.replace(/\\/\\*/g, '/.*');\n\n  const regexp = new RegExp(/(.*){[^/]+}(.*)/g);\n  for (;;) {\n    if (!key2.includes('/{')) {\n      break;\n    }\n    key2 = key2.replace(regexp, '$1[^/]+$2');\n  }\n\n  return regexMatch(key1, '^' + key2 + '$');\n}\n\n// keyMatch3Func is the wrapper for keyMatch3.\nfunction keyMatch3Func(...args: any[]): boolean {\n  const [arg0, arg1] = args;\n  const name1: string = (arg0 || '').toString();\n  const name2: string = (arg1 || '').toString();\n\n  return keyMatch3(name1, name2);\n}\n\n// keyMatch4 determines whether key1 matches the pattern of key2 (similar to RESTful path), key2 can contain a *.\n// Besides what keyMatch3 does, keyMatch4 can also match repeated patterns:\n// \"/parent/123/child/123\" matches \"/parent/{id}/child/{id}\"\n// \"/parent/123/child/456\" does not match \"/parent/{id}/child/{id}\"\n// But keyMatch3 will match both.\nfunction keyMatch4(key1: string, key2: string): boolean {\n  key2 = key2.replace(/\\/\\*/g, '/.*');\n\n  const tokens: string[] = [];\n  let j = -1;\n  for (let i = 0; i < key2.length; i++) {\n    const c = key2.charAt(i);\n    if (c === '{') {\n      j = i;\n    } else if (c === '}') {\n      tokens.push(key2.substring(j, i + 1));\n    }\n  }\n\n  let regexp = new RegExp(/(.*){[^/]+}(.*)/g);\n\n  for (;;) {\n    if (!key2.includes('/{')) {\n      break;\n    }\n    key2 = key2.replace(regexp, '$1([^/]+)$2');\n  }\n\n  regexp = new RegExp('^' + key2 + '$');\n\n  let values: RegExpExecArray | null | string[] = regexp.exec(key1);\n\n  if (!values) {\n    return false;\n  }\n\n  values = values.slice(1);\n\n  if (tokens.length !== values.length) {\n    throw new Error('KeyMatch4: number of tokens is not equal to number of values');\n  }\n\n  const m = new Map<string, string[]>();\n  tokens.forEach((n, index) => {\n    const key = tokens[index];\n    let v = m.get(key);\n    if (!v) {\n      v = [];\n    }\n\n    if (values) {\n      v.push(values[index]);\n    }\n    m.set(key, v);\n  });\n\n  for (const value of m.values()) {\n    if (value.length > 1) {\n      for (let i = 1; i < values.length; i++) {\n        if (values[i] !== values[0]) {\n          return false;\n        }\n      }\n    }\n  }\n\n  return true;\n}\n\n// keyMatch4Func is the wrapper for keyMatch4.\nfunction keyMatch4Func(...args: any[]): boolean {\n  const [arg0, arg1] = args;\n  const name1: string = (arg0 || '').toString();\n  const name2: string = (arg1 || '').toString();\n\n  return keyMatch4(name1, name2);\n}\n\n// KeyMatch determines whether key1 matches the pattern of key2 and ignores the parameters in key2.\n// For example, \"/foo/bar?status=1&type=2\" matches \"/foo/bar\"\nfunction KeyMatch5(key1: string, key2: string): boolean {\n  const i: number = key1.indexOf('?');\n  if (i === -1) {\n    return key1 === key2;\n  }\n\n  return key1.slice(0, i) === key2;\n}\n\n// keyMatch5Func is the wrapper for KeyMatch5.\nfunction keyMatch5Func(...args: any[]): boolean {\n  const [arg0, arg1] = args;\n  const name1: string = (arg0 || '').toString();\n  const name2: string = (arg1 || '').toString();\n\n  return KeyMatch5(name1, name2);\n}\n\n// regexMatchFunc is the wrapper for regexMatch.\nfunction regexMatchFunc(...args: any[]): boolean {\n  const [arg0, arg1] = args;\n  const name1: string = (arg0 || '').toString();\n  const name2: string = (arg1 || '').toString();\n\n  return regexMatch(name1, name2);\n}\n\n// ipMatch determines whether IP address ip1 matches the pattern of IP address ip2,\n// ip2 can be an IP address or a CIDR pattern.\n// For example, '192.168.2.123' matches '192.168.2.0/24'\nfunction ipMatch(ip1: string, ip2: string): boolean {\n  try {\n    // eslint-disable-next-line @typescript-eslint/no-var-requires\n    require('buffer');\n  } catch {\n    throw new Error('Please add buffer to your dependency.');\n  }\n  // check ip1\n  if (!(ip.isV4Format(ip1) || ip.isV6Format(ip1))) {\n    throw new Error('invalid argument: ip1 in ipMatch() function is not an IP address.');\n  }\n  // check ip2\n  const cidrParts: string[] = ip2.split('/');\n  if (cidrParts.length === 2) {\n    return ip.cidrSubnet(ip2).contains(ip1);\n  } else {\n    if (!(ip.isV4Format(ip2) || ip.isV6Format(ip2))) {\n      console.log(ip2);\n      throw new Error('invalid argument: ip2 in ipMatch() function is not an IP address.');\n    }\n    return ip.isEqual(ip1, ip2);\n  }\n}\n\n// ipMatchFunc is the wrapper for ipMatch.\nfunction ipMatchFunc(...args: any[]): boolean {\n  const [arg0, arg1] = args;\n  const ip1: string = (arg0 || '').toString();\n  const ip2: string = (arg1 || '').toString();\n\n  return ipMatch(ip1, ip2);\n}\n\n/**\n * Returns true if the specified `string` matches the given glob `pattern`.\n *\n * @param string String to match\n * @param pattern Glob pattern to use for matching.\n * @returns Returns true if the string matches the glob pattern.\n *\n * @example\n * ```javascript\n * globMatch(\"abc.conf\", \"*.conf\") => true\n * ```\n */\nfunction globMatch(string: string, pattern: string): boolean {\n  return minimatch(string, pattern);\n}\n\n// generateGFunction is the factory method of the g(_, _) function.\nfunction generateGFunction(rm: rbac.RoleManager): any {\n  const memorized = new Map<string, boolean>();\n  return async function func(...args: any[]): Promise<boolean> {\n    const key = args.toString();\n    let value = memorized.get(key);\n    if (value) {\n      return value;\n    }\n\n    const [arg0, arg1] = args;\n    const name1: string = (arg0 || '').toString();\n    const name2: string = (arg1 || '').toString();\n\n    if (!rm) {\n      value = name1 === name2;\n    } else if (args.length === 2) {\n      value = await rm.hasLink(name1, name2);\n    } else {\n      const domain: string = args[2].toString();\n      value = await rm.hasLink(name1, name2, domain);\n    }\n\n    memorized.set(key, value);\n    return value;\n  };\n}\n\nexport {\n  keyMatchFunc,\n  keyGetFunc,\n  keyMatch2Func,\n  keyGet2Func,\n  keyMatch3Func,\n  regexMatchFunc,\n  ipMatchFunc,\n  generateGFunction,\n  keyMatch4Func,\n  keyMatch5Func,\n  globMatch,\n};\n","// Copyright 2017 The casbin Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the 'License');\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an 'AS IS' BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// escapeAssertion escapes the dots in the assertion,\n// because the expression evaluation doesn't support such variable names.\n\nfunction escapeAssertion(s: string): string {\n  if (s.startsWith('r') || s.startsWith('p')) {\n    s = s.replace('.', '_');\n  }\n  return s.replace(/([| =)(&<>,+\\-!*\\/])([rp][0-9]*)\\./g, (match) => {\n    return match.replace('.', '_');\n  });\n}\n\n// removeComments removes the comments starting with # in the text.\nfunction removeComments(s: string): string {\n  const pos = s.indexOf('#');\n  return pos > -1 ? s.slice(0, pos).trim() : s;\n}\n\n// arrayEquals determines whether two string arrays are identical.\nfunction arrayEquals(a: string[] = [], b: string[] = []): boolean {\n  const aLen = a.length;\n  const bLen = b.length;\n  if (aLen !== bLen) {\n    return false;\n  }\n\n  for (let i = 0; i < aLen; i++) {\n    if (a[i] !== b[i]) {\n      return false;\n    }\n  }\n  return true;\n}\n\n// array2DEquals determines whether two 2-dimensional string arrays are identical.\nfunction array2DEquals(a: string[][] = [], b: string[][] = []): boolean {\n  const aLen = a.length;\n  const bLen = a.length;\n  if (aLen !== bLen) {\n    return false;\n  }\n\n  for (let i = 0; i < aLen; i++) {\n    if (!arrayEquals(a[i], b[i])) {\n      return false;\n    }\n  }\n  return true;\n}\n\n// arrayRemoveDuplicates removes any duplicated elements in a string array.\nfunction arrayRemoveDuplicates(s: string[]): string[] {\n  return [...new Set(s)];\n}\n\n// arrayToString gets a printable string for a string array.\nfunction arrayToString(a: string[]): string {\n  return a.join(', ');\n}\n\n// paramsToString gets a printable string for variable number of parameters.\nfunction paramsToString(...v: string[]): string {\n  return v.join(', ');\n}\n\n// setEquals determines whether two string sets are identical.\nfunction setEquals(a: string[], b: string[]): boolean {\n  return arrayEquals(a.sort(), b.sort());\n}\n\nconst evalRegG = new RegExp(/\\beval\\(([^),]*)\\)/g);\nconst evalReg = new RegExp(/\\beval\\(([^),]*)\\)/);\n\n// hasEval determine whether matcher contains function eval\nfunction hasEval(s: string): boolean {\n  return evalReg.test(s);\n}\n\n// replaceEval replace function eval with the value of its parameters\nfunction replaceEval(s: string, ruleName: string, rule: string): string {\n  return s.replace(`eval(${ruleName})`, '(' + rule + ')');\n}\n\n// getEvalValue returns the parameters of function eval\nfunction getEvalValue(s: string): string[] {\n  const subMatch = s.match(evalRegG);\n  const rules: string[] = [];\n  if (!subMatch) {\n    return [];\n  }\n  for (const rule of subMatch) {\n    const index: number = rule.indexOf('(');\n    rules.push(rule.slice(index + 1, -1));\n  }\n  return rules;\n}\n\n// generatorRunSync handle generator function in Sync model and return value which is not Promise\nfunction generatorRunSync(iterator: Generator<any>): any {\n  let { value, done } = iterator.next();\n  while (true) {\n    if (value instanceof Promise) {\n      throw new Error('cannot handle Promise in generatorRunSync, Please use generatorRunAsync');\n    }\n    if (!done) {\n      const temp = value;\n      ({ value, done } = iterator.next(temp));\n    } else {\n      return value;\n    }\n  }\n}\n\n// generatorRunAsync handle generator function in Async model and return Promise\nasync function generatorRunAsync(iterator: Generator<any>): Promise<any> {\n  let { value, done } = iterator.next();\n  while (true) {\n    if (!done) {\n      const temp = await value;\n      ({ value, done } = iterator.next(temp));\n    } else {\n      return value;\n    }\n  }\n}\n\nfunction deepCopy(obj: Array<any> | any): any {\n  if (typeof obj !== 'object') return;\n  const newObj: any = obj instanceof Array ? [] : {};\n  for (const key in obj) {\n    if (obj.hasOwnProperty(key)) {\n      newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];\n    }\n  }\n  return newObj;\n}\n\nfunction policyArrayToString(policy: string[]): string {\n  return policy\n    .map((n) => {\n      return `\"${(n === null ? '' : n.toString()).replace(/\"/g, '\"\"')}\"`;\n    })\n    .join(',');\n}\n\nfunction policyStringToArray(policy: string): string[][] {\n  const endCommaRe = /,$/;\n  const quotaWrapperRe = /^\".*\"$/;\n\n  const lines: string[] = policy.split(/\\r?\\n/);\n  const arrays: string[][] = [];\n\n  for (let line of lines) {\n    const commentLabel = line.indexOf('#');\n    if (commentLabel !== -1) {\n      line = line.substr(0, commentLabel);\n    }\n\n    line = line.trim();\n\n    if (endCommaRe.test(line)) {\n      throw new Error('The csv standard does not allow a comma at the end of a sentence');\n    }\n\n    const slices = line.split(',');\n    let tokens: string[] = [];\n\n    for (let slice of slices) {\n      slice = slice.trim();\n\n      // Remove parcel quotes\n      if (quotaWrapperRe.test(slice)) {\n        slice = slice.substr(1, slice.length - 2);\n      }\n\n      if (slice.includes('\"\"')) {\n        // \"\" Escape processing\n        for (let i = 0; i < slice.length; ) {\n          if (slice[i] === '\"') {\n            if (slice[i + 1] !== '\"') {\n              throw new Error(`Unescaped \" at ${line}`);\n            }\n            i += 2;\n          }\n          i += 1;\n        }\n\n        slice = slice.replace(/\"\"/g, '\"');\n      }\n\n      tokens.push(slice);\n    }\n\n    arrays.push(deepCopy(tokens));\n    tokens = [];\n  }\n  return arrays;\n}\n\nfunction customIn(a: number | string, b: number | string): number {\n  if ((b as any) instanceof Array) {\n    return (((b as any) as Array<any>).includes(a) as unknown) as number;\n  }\n  return ((a in (b as any)) as unknown) as number;\n}\n\nfunction bracketCompatible(exp: string): string {\n  // TODO: This function didn't support nested bracket.\n  if (!(exp.includes(' in ') && exp.includes(' ('))) {\n    return exp;\n  }\n\n  const re = / \\([^)]*\\)/g;\n  const array = exp.split('');\n\n  let reResult: RegExpExecArray | null;\n  while ((reResult = re.exec(exp)) !== null) {\n    if (!(reResult[0] as string).includes(',')) {\n      continue;\n    }\n    array[reResult.index + 1] = '[';\n    array[re.lastIndex - 1] = ']';\n  }\n  exp = array.join('');\n  return exp;\n}\n\nexport {\n  escapeAssertion,\n  removeComments,\n  arrayEquals,\n  array2DEquals,\n  arrayRemoveDuplicates,\n  arrayToString,\n  paramsToString,\n  setEquals,\n  hasEval,\n  replaceEval,\n  getEvalValue,\n  generatorRunSync,\n  generatorRunAsync,\n  deepCopy,\n  policyArrayToString,\n  policyStringToArray,\n  customIn,\n  bracketCompatible,\n};\n","// Copyright 2018 The Casbin Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// ConfigInterface defines the behavior of a Config implementation\nexport interface ConfigInterface {\n  getString(key: string): string;\n\n  getStrings(key: string): string[];\n\n  getBool(key: string): boolean;\n\n  getInt(key: string): number;\n\n  getFloat(key: string): number;\n\n  set(key: string, value: string): void;\n}\n\nexport class Config implements ConfigInterface {\n  private static DEFAULT_SECTION = 'default';\n  private static DEFAULT_COMMENT = '#';\n  private static DEFAULT_COMMENT_SEM = ';';\n  private static DEFAULT_MULTI_LINE_SEPARATOR = '\\\\';\n\n  private data: Map<string, Map<string, string>>;\n\n  private constructor() {\n    this.data = new Map<string, Map<string, string>>();\n  }\n\n  /**\n   * newConfig create an empty configuration representation from file.\n   *\n   * @param text the content of the model file.\n   * @return the constructor of Config.\n   */\n  public static newConfig(text: string): Config {\n    const config = new Config();\n    config.parseText(text);\n    return config;\n  }\n\n  /**\n   * newConfigFromText create an empty configuration representation from text.\n   *\n   * @param text the model text.\n   * @return the constructor of Config.\n   */\n  public static newConfigFromText(text: string): Config {\n    const config = new Config();\n    config.parseText(text);\n    return config;\n  }\n\n  /**\n   * addConfig adds a new section->key:value to the configuration.\n   */\n  private addConfig(section: string, option: string, value: string): boolean {\n    if (section === '') {\n      section = Config.DEFAULT_SECTION;\n    }\n    const hasKey = this.data.has(section);\n    if (!hasKey) {\n      this.data.set(section, new Map<string, string>());\n    }\n\n    const item = this.data.get(section);\n    if (item) {\n      item.set(option, value);\n      return item.has(option);\n    } else {\n      return false;\n    }\n  }\n\n  private parseText(text: string): void {\n    const lines = text.split('\\n').filter((v) => v);\n    const linesCount = lines.length;\n    let section = '';\n    let currentLine = '';\n\n    lines.forEach((n, index) => {\n      let commentPos = n.indexOf(Config.DEFAULT_COMMENT);\n      if (commentPos > -1) {\n        n = n.slice(0, commentPos);\n      }\n      commentPos = n.indexOf(Config.DEFAULT_COMMENT_SEM);\n      if (commentPos > -1) {\n        n = n.slice(0, commentPos);\n      }\n\n      const line = n.trim();\n      if (!line) {\n        return;\n      }\n\n      const lineNumber = index + 1;\n\n      if (line.startsWith('[') && line.endsWith(']')) {\n        if (currentLine.length !== 0) {\n          this.write(section, lineNumber - 1, currentLine);\n          currentLine = '';\n        }\n        section = line.substring(1, line.length - 1);\n      } else {\n        let shouldWrite = false;\n        if (line.includes(Config.DEFAULT_MULTI_LINE_SEPARATOR)) {\n          currentLine += line.substring(0, line.length - 1).trim();\n        } else {\n          currentLine += line;\n          shouldWrite = true;\n        }\n        if (shouldWrite || lineNumber === linesCount) {\n          this.write(section, lineNumber, currentLine);\n          currentLine = '';\n        }\n      }\n    });\n  }\n\n  private write(section: string, lineNum: number, line: string): void {\n    const equalIndex = line.indexOf('=');\n    if (equalIndex === -1) {\n      throw new Error(`parse the content error : line ${lineNum}`);\n    }\n    const key = line.substring(0, equalIndex);\n    const value = line.substring(equalIndex + 1);\n    this.addConfig(section, key.trim(), value.trim());\n  }\n\n  public getBool(key: string): boolean {\n    return !!this.get(key);\n  }\n\n  public getInt(key: string): number {\n    return Number.parseInt(this.get(key), 10);\n  }\n\n  public getFloat(key: string): number {\n    return Number.parseFloat(this.get(key));\n  }\n\n  public getString(key: string): string {\n    return this.get(key);\n  }\n\n  public getStrings(key: string): string[] {\n    const v = this.get(key);\n    return v.split(',');\n  }\n\n  public set(key: string, value: string): void {\n    if (!key) {\n      throw new Error('key is empty');\n    }\n\n    let section = '';\n    let option;\n\n    const keys = key.toLowerCase().split('::');\n    if (keys.length >= 2) {\n      section = keys[0];\n      option = keys[1];\n    } else {\n      option = keys[0];\n    }\n\n    this.addConfig(section, option, value);\n  }\n\n  public get(key: string): string {\n    let section;\n    let option;\n\n    const keys = key.toLowerCase().split('::');\n    if (keys.length >= 2) {\n      section = keys[0];\n      option = keys[1];\n    } else {\n      section = Config.DEFAULT_SECTION;\n      option = keys[0];\n    }\n\n    const item = this.data.get(section);\n    const itemChild = item && item.get(option);\n\n    return itemChild ? itemChild : '';\n  }\n}\n","//     JavaScript Expression Parser (JSEP) 0.3.5\n//     JSEP may be freely distributed under the MIT License\n//     https://ericsmekens.github.io/jsep/\n\n/*global module: true, exports: true, console: true */\n(function (root) {\n\t'use strict';\n\t// Node Types\n\t// ----------\n\n\t// This is the full set of types that any JSEP node can be.\n\t// Store them here to save space when minified\n\tvar COMPOUND = 'Compound',\n\t\tIDENTIFIER = 'Identifier',\n\t\tMEMBER_EXP = 'MemberExpression',\n\t\tLITERAL = 'Literal',\n\t\tTHIS_EXP = 'ThisExpression',\n\t\tCALL_EXP = 'CallExpression',\n\t\tUNARY_EXP = 'UnaryExpression',\n\t\tBINARY_EXP = 'BinaryExpression',\n\t\tLOGICAL_EXP = 'LogicalExpression',\n\t\tCONDITIONAL_EXP = 'ConditionalExpression',\n\t\tARRAY_EXP = 'ArrayExpression',\n\n\t\tPERIOD_CODE = 46, // '.'\n\t\tCOMMA_CODE  = 44, // ','\n\t\tSQUOTE_CODE = 39, // single quote\n\t\tDQUOTE_CODE = 34, // double quotes\n\t\tOPAREN_CODE = 40, // (\n\t\tCPAREN_CODE = 41, // )\n\t\tOBRACK_CODE = 91, // [\n\t\tCBRACK_CODE = 93, // ]\n\t\tQUMARK_CODE = 63, // ?\n\t\tSEMCOL_CODE = 59, // ;\n\t\tCOLON_CODE  = 58, // :\n\n\t\tthrowError = function(message, index) {\n\t\t\tvar error = new Error(message + ' at character ' + index);\n\t\t\terror.index = index;\n\t\t\terror.description = message;\n\t\t\tthrow error;\n\t\t},\n\n\t// Operations\n\t// ----------\n\n\t// Set `t` to `true` to save space (when minified, not gzipped)\n\t\tt = true,\n\t// Use a quickly-accessible map to store all of the unary operators\n\t// Values are set to `true` (it really doesn't matter)\n\t\tunary_ops = {'-': t, '!': t, '~': t, '+': t},\n\t// Also use a map for the binary operations but set their values to their\n\t// binary precedence for quick reference:\n\t// see [Order of operations](http://en.wikipedia.org/wiki/Order_of_operations#Programming_language)\n\t\tbinary_ops = {\n\t\t\t'||': 1, '&&': 2, '|': 3,  '^': 4,  '&': 5,\n\t\t\t'==': 6, '!=': 6, '===': 6, '!==': 6,\n\t\t\t'<': 7,  '>': 7,  '<=': 7,  '>=': 7,\n\t\t\t'<<':8,  '>>': 8, '>>>': 8,\n\t\t\t'+': 9, '-': 9,\n\t\t\t'*': 10, '/': 10, '%': 10\n\t\t},\n\t// Get return the longest key length of any object\n\t\tgetMaxKeyLen = function(obj) {\n\t\t\tvar max_len = 0, len;\n\t\t\tfor(var key in obj) {\n\t\t\t\tif((len = key.length) > max_len && obj.hasOwnProperty(key)) {\n\t\t\t\t\tmax_len = len;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn max_len;\n\t\t},\n\t\tmax_unop_len = getMaxKeyLen(unary_ops),\n\t\tmax_binop_len = getMaxKeyLen(binary_ops),\n\t// Literals\n\t// ----------\n\t// Store the values to return for the various literals we may encounter\n\t\tliterals = {\n\t\t\t'true': true,\n\t\t\t'false': false,\n\t\t\t'null': null\n\t\t},\n\t// Except for `this`, which is special. This could be changed to something like `'self'` as well\n\t\tthis_str = 'this',\n\t// Returns the precedence of a binary operator or `0` if it isn't a binary operator\n\t\tbinaryPrecedence = function(op_val) {\n\t\t\treturn binary_ops[op_val] || 0;\n\t\t},\n\t// Utility function (gets called from multiple places)\n\t// Also note that `a && b` and `a || b` are *logical* expressions, not binary expressions\n\t\tcreateBinaryExpression = function (operator, left, right) {\n\t\t\tvar type = (operator === '||' || operator === '&&') ? LOGICAL_EXP : BINARY_EXP;\n\t\t\treturn {\n\t\t\t\ttype: type,\n\t\t\t\toperator: operator,\n\t\t\t\tleft: left,\n\t\t\t\tright: right\n\t\t\t};\n\t\t},\n\t\t// `ch` is a character code in the next three functions\n\t\tisDecimalDigit = function(ch) {\n\t\t\treturn (ch >= 48 && ch <= 57); // 0...9\n\t\t},\n\t\tisIdentifierStart = function(ch) {\n\t\t\treturn (ch === 36) || (ch === 95) || // `$` and `_`\n\t\t\t\t\t(ch >= 65 && ch <= 90) || // A...Z\n\t\t\t\t\t(ch >= 97 && ch <= 122) || // a...z\n                    (ch >= 128 && !binary_ops[String.fromCharCode(ch)]); // any non-ASCII that is not an operator\n\t\t},\n\t\tisIdentifierPart = function(ch) {\n\t\t\treturn (ch === 36) || (ch === 95) || // `$` and `_`\n\t\t\t\t\t(ch >= 65 && ch <= 90) || // A...Z\n\t\t\t\t\t(ch >= 97 && ch <= 122) || // a...z\n\t\t\t\t\t(ch >= 48 && ch <= 57) || // 0...9\n                    (ch >= 128 && !binary_ops[String.fromCharCode(ch)]); // any non-ASCII that is not an operator\n\t\t},\n\n\t\t// Parsing\n\t\t// -------\n\t\t// `expr` is a string with the passed in expression\n\t\tjsep = function(expr) {\n\t\t\t// `index` stores the character number we are currently at while `length` is a constant\n\t\t\t// All of the gobbles below will modify `index` as we move along\n\t\t\tvar index = 0,\n\t\t\t\tcharAtFunc = expr.charAt,\n\t\t\t\tcharCodeAtFunc = expr.charCodeAt,\n\t\t\t\texprI = function(i) { return charAtFunc.call(expr, i); },\n\t\t\t\texprICode = function(i) { return charCodeAtFunc.call(expr, i); },\n\t\t\t\tlength = expr.length,\n\n\t\t\t\t// Push `index` up to the next non-space character\n\t\t\t\tgobbleSpaces = function() {\n\t\t\t\t\tvar ch = exprICode(index);\n\t\t\t\t\t// space or tab\n\t\t\t\t\twhile(ch === 32 || ch === 9 || ch === 10 || ch === 13) {\n\t\t\t\t\t\tch = exprICode(++index);\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\t// The main parsing function. Much of this code is dedicated to ternary expressions\n\t\t\t\tgobbleExpression = function() {\n\t\t\t\t\tvar test = gobbleBinaryExpression(),\n\t\t\t\t\t\tconsequent, alternate;\n\t\t\t\t\tgobbleSpaces();\n\t\t\t\t\tif(exprICode(index) === QUMARK_CODE) {\n\t\t\t\t\t\t// Ternary expression: test ? consequent : alternate\n\t\t\t\t\t\tindex++;\n\t\t\t\t\t\tconsequent = gobbleExpression();\n\t\t\t\t\t\tif(!consequent) {\n\t\t\t\t\t\t\tthrowError('Expected expression', index);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tgobbleSpaces();\n\t\t\t\t\t\tif(exprICode(index) === COLON_CODE) {\n\t\t\t\t\t\t\tindex++;\n\t\t\t\t\t\t\talternate = gobbleExpression();\n\t\t\t\t\t\t\tif(!alternate) {\n\t\t\t\t\t\t\t\tthrowError('Expected expression', index);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\ttype: CONDITIONAL_EXP,\n\t\t\t\t\t\t\t\ttest: test,\n\t\t\t\t\t\t\t\tconsequent: consequent,\n\t\t\t\t\t\t\t\talternate: alternate\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthrowError('Expected :', index);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn test;\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\t// Search for the operation portion of the string (e.g. `+`, `===`)\n\t\t\t\t// Start by taking the longest possible binary operations (3 characters: `===`, `!==`, `>>>`)\n\t\t\t\t// and move down from 3 to 2 to 1 character until a matching binary operation is found\n\t\t\t\t// then, return that binary operation\n\t\t\t\tgobbleBinaryOp = function() {\n\t\t\t\t\tgobbleSpaces();\n\t\t\t\t\tvar biop, to_check = expr.substr(index, max_binop_len), tc_len = to_check.length;\n\t\t\t\t\twhile(tc_len > 0) {\n\t\t\t\t\t\t// Don't accept a binary op when it is an identifier.\n\t\t\t\t\t\t// Binary ops that start with a identifier-valid character must be followed\n\t\t\t\t\t\t// by a non identifier-part valid character\n\t\t\t\t\t\tif(binary_ops.hasOwnProperty(to_check) && (\n\t\t\t\t\t\t\t!isIdentifierStart(exprICode(index)) ||\n\t\t\t\t\t\t\t(index+to_check.length< expr.length && !isIdentifierPart(exprICode(index+to_check.length)))\n\t\t\t\t\t\t)) {\n\t\t\t\t\t\t\tindex += tc_len;\n\t\t\t\t\t\t\treturn to_check;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tto_check = to_check.substr(0, --tc_len);\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\t},\n\n\t\t\t\t// This function is responsible for gobbling an individual expression,\n\t\t\t\t// e.g. `1`, `1+2`, `a+(b*2)-Math.sqrt(2)`\n\t\t\t\tgobbleBinaryExpression = function() {\n\t\t\t\t\tvar ch_i, node, biop, prec, stack, biop_info, left, right, i, cur_biop;\n\n\t\t\t\t\t// First, try to get the leftmost thing\n\t\t\t\t\t// Then, check to see if there's a binary operator operating on that leftmost thing\n\t\t\t\t\tleft = gobbleToken();\n\t\t\t\t\tbiop = gobbleBinaryOp();\n\n\t\t\t\t\t// If there wasn't a binary operator, just return the leftmost node\n\t\t\t\t\tif(!biop) {\n\t\t\t\t\t\treturn left;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Otherwise, we need to start a stack to properly place the binary operations in their\n\t\t\t\t\t// precedence structure\n\t\t\t\t\tbiop_info = { value: biop, prec: binaryPrecedence(biop)};\n\n\t\t\t\t\tright = gobbleToken();\n\t\t\t\t\tif(!right) {\n\t\t\t\t\t\tthrowError(\"Expected expression after \" + biop, index);\n\t\t\t\t\t}\n\t\t\t\t\tstack = [left, biop_info, right];\n\n\t\t\t\t\t// Properly deal with precedence using [recursive descent](http://www.engr.mun.ca/~theo/Misc/exp_parsing.htm)\n\t\t\t\t\twhile((biop = gobbleBinaryOp())) {\n\t\t\t\t\t\tprec = binaryPrecedence(biop);\n\n\t\t\t\t\t\tif(prec === 0) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbiop_info = { value: biop, prec: prec };\n\n\t\t\t\t\t\tcur_biop = biop;\n\t\t\t\t\t\t// Reduce: make a binary expression from the three topmost entries.\n\t\t\t\t\t\twhile ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) {\n\t\t\t\t\t\t\tright = stack.pop();\n\t\t\t\t\t\t\tbiop = stack.pop().value;\n\t\t\t\t\t\t\tleft = stack.pop();\n\t\t\t\t\t\t\tnode = createBinaryExpression(biop, left, right);\n\t\t\t\t\t\t\tstack.push(node);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tnode = gobbleToken();\n\t\t\t\t\t\tif(!node) {\n\t\t\t\t\t\t\tthrowError(\"Expected expression after \" + cur_biop, index);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tstack.push(biop_info, node);\n\t\t\t\t\t}\n\n\t\t\t\t\ti = stack.length - 1;\n\t\t\t\t\tnode = stack[i];\n\t\t\t\t\twhile(i > 1) {\n\t\t\t\t\t\tnode = createBinaryExpression(stack[i - 1].value, stack[i - 2], node);\n\t\t\t\t\t\ti -= 2;\n\t\t\t\t\t}\n\t\t\t\t\treturn node;\n\t\t\t\t},\n\n\t\t\t\t// An individual part of a binary expression:\n\t\t\t\t// e.g. `foo.bar(baz)`, `1`, `\"abc\"`, `(a % 2)` (because it's in parenthesis)\n\t\t\t\tgobbleToken = function() {\n\t\t\t\t\tvar ch, to_check, tc_len;\n\n\t\t\t\t\tgobbleSpaces();\n\t\t\t\t\tch = exprICode(index);\n\n\t\t\t\t\tif(isDecimalDigit(ch) || ch === PERIOD_CODE) {\n\t\t\t\t\t\t// Char code 46 is a dot `.` which can start off a numeric literal\n\t\t\t\t\t\treturn gobbleNumericLiteral();\n\t\t\t\t\t} else if(ch === SQUOTE_CODE || ch === DQUOTE_CODE) {\n\t\t\t\t\t\t// Single or double quotes\n\t\t\t\t\t\treturn gobbleStringLiteral();\n\t\t\t\t\t} else if (ch === OBRACK_CODE) {\n\t\t\t\t\t\treturn gobbleArray();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tto_check = expr.substr(index, max_unop_len);\n\t\t\t\t\t\ttc_len = to_check.length;\n\t\t\t\t\t\twhile(tc_len > 0) {\n\t\t\t\t\t\t// Don't accept an unary op when it is an identifier.\n\t\t\t\t\t\t// Unary ops that start with a identifier-valid character must be followed\n\t\t\t\t\t\t// by a non identifier-part valid character\n\t\t\t\t\t\t\tif(unary_ops.hasOwnProperty(to_check) && (\n\t\t\t\t\t\t\t\t!isIdentifierStart(exprICode(index)) ||\n\t\t\t\t\t\t\t\t(index+to_check.length < expr.length && !isIdentifierPart(exprICode(index+to_check.length)))\n\t\t\t\t\t\t\t)) {\n\t\t\t\t\t\t\t\tindex += tc_len;\n\t\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t\ttype: UNARY_EXP,\n\t\t\t\t\t\t\t\t\toperator: to_check,\n\t\t\t\t\t\t\t\t\targument: gobbleToken(),\n\t\t\t\t\t\t\t\t\tprefix: true\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tto_check = to_check.substr(0, --tc_len);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (isIdentifierStart(ch) || ch === OPAREN_CODE) { // open parenthesis\n\t\t\t\t\t\t\t// `foo`, `bar.baz`\n\t\t\t\t\t\t\treturn gobbleVariable();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn false;\n\t\t\t\t},\n\t\t\t\t// Parse simple numeric literals: `12`, `3.4`, `.5`. Do this by using a string to\n\t\t\t\t// keep track of everything in the numeric literal and then calling `parseFloat` on that string\n\t\t\t\tgobbleNumericLiteral = function() {\n\t\t\t\t\tvar number = '', ch, chCode;\n\t\t\t\t\twhile(isDecimalDigit(exprICode(index))) {\n\t\t\t\t\t\tnumber += exprI(index++);\n\t\t\t\t\t}\n\n\t\t\t\t\tif(exprICode(index) === PERIOD_CODE) { // can start with a decimal marker\n\t\t\t\t\t\tnumber += exprI(index++);\n\n\t\t\t\t\t\twhile(isDecimalDigit(exprICode(index))) {\n\t\t\t\t\t\t\tnumber += exprI(index++);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tch = exprI(index);\n\t\t\t\t\tif(ch === 'e' || ch === 'E') { // exponent marker\n\t\t\t\t\t\tnumber += exprI(index++);\n\t\t\t\t\t\tch = exprI(index);\n\t\t\t\t\t\tif(ch === '+' || ch === '-') { // exponent sign\n\t\t\t\t\t\t\tnumber += exprI(index++);\n\t\t\t\t\t\t}\n\t\t\t\t\t\twhile(isDecimalDigit(exprICode(index))) { //exponent itself\n\t\t\t\t\t\t\tnumber += exprI(index++);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(!isDecimalDigit(exprICode(index-1)) ) {\n\t\t\t\t\t\t\tthrowError('Expected exponent (' + number + exprI(index) + ')', index);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\n\t\t\t\t\tchCode = exprICode(index);\n\t\t\t\t\t// Check to make sure this isn't a variable name that start with a number (123abc)\n\t\t\t\t\tif(isIdentifierStart(chCode)) {\n\t\t\t\t\t\tthrowError('Variable names cannot start with a number (' +\n\t\t\t\t\t\t\t\t\tnumber + exprI(index) + ')', index);\n\t\t\t\t\t} else if(chCode === PERIOD_CODE) {\n\t\t\t\t\t\tthrowError('Unexpected period', index);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: LITERAL,\n\t\t\t\t\t\tvalue: parseFloat(number),\n\t\t\t\t\t\traw: number\n\t\t\t\t\t};\n\t\t\t\t},\n\n\t\t\t\t// Parses a string literal, staring with single or double quotes with basic support for escape codes\n\t\t\t\t// e.g. `\"hello world\"`, `'this is\\nJSEP'`\n\t\t\t\tgobbleStringLiteral = function() {\n\t\t\t\t\tvar str = '', quote = exprI(index++), closed = false, ch;\n\n\t\t\t\t\twhile(index < length) {\n\t\t\t\t\t\tch = exprI(index++);\n\t\t\t\t\t\tif(ch === quote) {\n\t\t\t\t\t\t\tclosed = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t} else if(ch === '\\\\') {\n\t\t\t\t\t\t\t// Check for all of the common escape codes\n\t\t\t\t\t\t\tch = exprI(index++);\n\t\t\t\t\t\t\tswitch(ch) {\n\t\t\t\t\t\t\t\tcase 'n': str += '\\n'; break;\n\t\t\t\t\t\t\t\tcase 'r': str += '\\r'; break;\n\t\t\t\t\t\t\t\tcase 't': str += '\\t'; break;\n\t\t\t\t\t\t\t\tcase 'b': str += '\\b'; break;\n\t\t\t\t\t\t\t\tcase 'f': str += '\\f'; break;\n\t\t\t\t\t\t\t\tcase 'v': str += '\\x0B'; break;\n\t\t\t\t\t\t\t\tdefault : str += ch;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tstr += ch;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(!closed) {\n\t\t\t\t\t\tthrowError('Unclosed quote after \"'+str+'\"', index);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: LITERAL,\n\t\t\t\t\t\tvalue: str,\n\t\t\t\t\t\traw: quote + str + quote\n\t\t\t\t\t};\n\t\t\t\t},\n\n\t\t\t\t// Gobbles only identifiers\n\t\t\t\t// e.g.: `foo`, `_value`, `$x1`\n\t\t\t\t// Also, this function checks if that identifier is a literal:\n\t\t\t\t// (e.g. `true`, `false`, `null`) or `this`\n\t\t\t\tgobbleIdentifier = function() {\n\t\t\t\t\tvar ch = exprICode(index), start = index, identifier;\n\n\t\t\t\t\tif(isIdentifierStart(ch)) {\n\t\t\t\t\t\tindex++;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrowError('Unexpected ' + exprI(index), index);\n\t\t\t\t\t}\n\n\t\t\t\t\twhile(index < length) {\n\t\t\t\t\t\tch = exprICode(index);\n\t\t\t\t\t\tif(isIdentifierPart(ch)) {\n\t\t\t\t\t\t\tindex++;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tidentifier = expr.slice(start, index);\n\n\t\t\t\t\tif(literals.hasOwnProperty(identifier)) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype: LITERAL,\n\t\t\t\t\t\t\tvalue: literals[identifier],\n\t\t\t\t\t\t\traw: identifier\n\t\t\t\t\t\t};\n\t\t\t\t\t} else if(identifier === this_str) {\n\t\t\t\t\t\treturn { type: THIS_EXP };\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype: IDENTIFIER,\n\t\t\t\t\t\t\tname: identifier\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\t// Gobbles a list of arguments within the context of a function call\n\t\t\t\t// or array literal. This function also assumes that the opening character\n\t\t\t\t// `(` or `[` has already been gobbled, and gobbles expressions and commas\n\t\t\t\t// until the terminator character `)` or `]` is encountered.\n\t\t\t\t// e.g. `foo(bar, baz)`, `my_func()`, or `[bar, baz]`\n\t\t\t\tgobbleArguments = function(termination) {\n\t\t\t\t\tvar ch_i, args = [], node, closed = false;\n\t\t\t\t\tvar separator_count = 0;\n\t\t\t\t\twhile(index < length) {\n\t\t\t\t\t\tgobbleSpaces();\n\t\t\t\t\t\tch_i = exprICode(index);\n\t\t\t\t\t\tif(ch_i === termination) { // done parsing\n\t\t\t\t\t\t\tclosed = true;\n\t\t\t\t\t\t\tindex++;\n\t\t\t\t\t\t\tif(termination === CPAREN_CODE && separator_count && separator_count >= args.length){\n\t\t\t\t\t\t\t\tthrowError('Unexpected token ' + String.fromCharCode(termination), index);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t} else if (ch_i === COMMA_CODE) { // between expressions\n\t\t\t\t\t\t\tindex++;\n\t\t\t\t\t\t\tseparator_count++;\n\t\t\t\t\t\t\tif(separator_count !== args.length) { // missing argument\n\t\t\t\t\t\t\t\tif(termination === CPAREN_CODE) {\n\t\t\t\t\t\t\t\t\tthrowError('Unexpected token ,', index);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse if(termination === CBRACK_CODE) {\n\t\t\t\t\t\t\t\t\tfor(var arg = args.length; arg< separator_count; arg++) {\n\t\t\t\t\t\t\t\t\t\targs.push(null);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tnode = gobbleExpression();\n\t\t\t\t\t\t\tif(!node || node.type === COMPOUND) {\n\t\t\t\t\t\t\t\tthrowError('Expected comma', index);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\targs.push(node);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (!closed) {\n\t\t\t\t\t\tthrowError('Expected ' + String.fromCharCode(termination), index);\n\t\t\t\t\t}\n\t\t\t\t\treturn args;\n\t\t\t\t},\n\n\t\t\t\t// Gobble a non-literal variable name. This variable name may include properties\n\t\t\t\t// e.g. `foo`, `bar.baz`, `foo['bar'].baz`\n\t\t\t\t// It also gobbles function calls:\n\t\t\t\t// e.g. `Math.acos(obj.angle)`\n\t\t\t\tgobbleVariable = function() {\n\t\t\t\t\tvar ch_i, node;\n\t\t\t\t\tch_i = exprICode(index);\n\n\t\t\t\t\tif(ch_i === OPAREN_CODE) {\n\t\t\t\t\t\tnode = gobbleGroup();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnode = gobbleIdentifier();\n\t\t\t\t\t}\n\t\t\t\t\tgobbleSpaces();\n\t\t\t\t\tch_i = exprICode(index);\n\t\t\t\t\twhile(ch_i === PERIOD_CODE || ch_i === OBRACK_CODE || ch_i === OPAREN_CODE) {\n\t\t\t\t\t\tindex++;\n\t\t\t\t\t\tif(ch_i === PERIOD_CODE) {\n\t\t\t\t\t\t\tgobbleSpaces();\n\t\t\t\t\t\t\tnode = {\n\t\t\t\t\t\t\t\ttype: MEMBER_EXP,\n\t\t\t\t\t\t\t\tcomputed: false,\n\t\t\t\t\t\t\t\tobject: node,\n\t\t\t\t\t\t\t\tproperty: gobbleIdentifier()\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t} else if(ch_i === OBRACK_CODE) {\n\t\t\t\t\t\t\tnode = {\n\t\t\t\t\t\t\t\ttype: MEMBER_EXP,\n\t\t\t\t\t\t\t\tcomputed: true,\n\t\t\t\t\t\t\t\tobject: node,\n\t\t\t\t\t\t\t\tproperty: gobbleExpression()\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tgobbleSpaces();\n\t\t\t\t\t\t\tch_i = exprICode(index);\n\t\t\t\t\t\t\tif(ch_i !== CBRACK_CODE) {\n\t\t\t\t\t\t\t\tthrowError('Unclosed [', index);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tindex++;\n\t\t\t\t\t\t} else if(ch_i === OPAREN_CODE) {\n\t\t\t\t\t\t\t// A function call is being made; gobble all the arguments\n\t\t\t\t\t\t\tnode = {\n\t\t\t\t\t\t\t\ttype: CALL_EXP,\n\t\t\t\t\t\t\t\t'arguments': gobbleArguments(CPAREN_CODE),\n\t\t\t\t\t\t\t\tcallee: node\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t\tgobbleSpaces();\n\t\t\t\t\t\tch_i = exprICode(index);\n\t\t\t\t\t}\n\t\t\t\t\treturn node;\n\t\t\t\t},\n\n\t\t\t\t// Responsible for parsing a group of things within parentheses `()`\n\t\t\t\t// This function assumes that it needs to gobble the opening parenthesis\n\t\t\t\t// and then tries to gobble everything within that parenthesis, assuming\n\t\t\t\t// that the next thing it should see is the close parenthesis. If not,\n\t\t\t\t// then the expression probably doesn't have a `)`\n\t\t\t\tgobbleGroup = function() {\n\t\t\t\t\tindex++;\n\t\t\t\t\tvar node = gobbleExpression();\n\t\t\t\t\tgobbleSpaces();\n\t\t\t\t\tif(exprICode(index) === CPAREN_CODE) {\n\t\t\t\t\t\tindex++;\n\t\t\t\t\t\treturn node;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrowError('Unclosed (', index);\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\t// Responsible for parsing Array literals `[1, 2, 3]`\n\t\t\t\t// This function assumes that it needs to gobble the opening bracket\n\t\t\t\t// and then tries to gobble the expressions as arguments.\n\t\t\t\tgobbleArray = function() {\n\t\t\t\t\tindex++;\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: ARRAY_EXP,\n\t\t\t\t\t\telements: gobbleArguments(CBRACK_CODE)\n\t\t\t\t\t};\n\t\t\t\t},\n\n\t\t\t\tnodes = [], ch_i, node;\n\n\t\t\twhile(index < length) {\n\t\t\t\tch_i = exprICode(index);\n\n\t\t\t\t// Expressions can be separated by semicolons, commas, or just inferred without any\n\t\t\t\t// separators\n\t\t\t\tif(ch_i === SEMCOL_CODE || ch_i === COMMA_CODE) {\n\t\t\t\t\tindex++; // ignore separators\n\t\t\t\t} else {\n\t\t\t\t\t// Try to gobble each expression individually\n\t\t\t\t\tif((node = gobbleExpression())) {\n\t\t\t\t\t\tnodes.push(node);\n\t\t\t\t\t// If we weren't able to find a binary expression and are out of room, then\n\t\t\t\t\t// the expression passed in probably has too much\n\t\t\t\t\t} else if(index < length) {\n\t\t\t\t\t\tthrowError('Unexpected \"' + exprI(index) + '\"', index);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If there's only one expression just try returning the expression\n\t\t\tif(nodes.length === 1) {\n\t\t\t\treturn nodes[0];\n\t\t\t} else {\n\t\t\t\treturn {\n\t\t\t\t\ttype: COMPOUND,\n\t\t\t\t\tbody: nodes\n\t\t\t\t};\n\t\t\t}\n\t\t};\n\n\t// To be filled in by the template\n\tjsep.version = '0.3.5';\n\tjsep.toString = function() { return 'JavaScript Expression Parser (JSEP) v' + jsep.version; };\n\n\t/**\n\t * @method jsep.addUnaryOp\n\t * @param {string} op_name The name of the unary op to add\n\t * @return jsep\n\t */\n\tjsep.addUnaryOp = function(op_name) {\n\t\tmax_unop_len = Math.max(op_name.length, max_unop_len);\n\t\tunary_ops[op_name] = t; return this;\n\t};\n\n\t/**\n\t * @method jsep.addBinaryOp\n\t * @param {string} op_name The name of the binary op to add\n\t * @param {number} precedence The precedence of the binary op (can be a float)\n\t * @return jsep\n\t */\n\tjsep.addBinaryOp = function(op_name, precedence) {\n\t\tmax_binop_len = Math.max(op_name.length, max_binop_len);\n\t\tbinary_ops[op_name] = precedence;\n\t\treturn this;\n\t};\n\n\t/**\n\t * @method jsep.addLiteral\n\t * @param {string} literal_name The name of the literal to add\n\t * @param {*} literal_value The value of the literal\n\t * @return jsep\n\t */\n\tjsep.addLiteral = function(literal_name, literal_value) {\n\t\tliterals[literal_name] = literal_value;\n\t\treturn this;\n\t};\n\n\t/**\n\t * @method jsep.removeUnaryOp\n\t * @param {string} op_name The name of the unary op to remove\n\t * @return jsep\n\t */\n\tjsep.removeUnaryOp = function(op_name) {\n\t\tdelete unary_ops[op_name];\n\t\tif(op_name.length === max_unop_len) {\n\t\t\tmax_unop_len = getMaxKeyLen(unary_ops);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * @method jsep.removeAllUnaryOps\n\t * @return jsep\n\t */\n\tjsep.removeAllUnaryOps = function() {\n\t\tunary_ops = {};\n\t\tmax_unop_len = 0;\n\n\t\treturn this;\n\t};\n\n\t/**\n\t * @method jsep.removeBinaryOp\n\t * @param {string} op_name The name of the binary op to remove\n\t * @return jsep\n\t */\n\tjsep.removeBinaryOp = function(op_name) {\n\t\tdelete binary_ops[op_name];\n\t\tif(op_name.length === max_binop_len) {\n\t\t\tmax_binop_len = getMaxKeyLen(binary_ops);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * @method jsep.removeAllBinaryOps\n\t * @return jsep\n\t */\n\tjsep.removeAllBinaryOps = function() {\n\t\tbinary_ops = {};\n\t\tmax_binop_len = 0;\n\n\t\treturn this;\n\t};\n\n\t/**\n\t * @method jsep.removeLiteral\n\t * @param {string} literal_name The name of the literal to remove\n\t * @return jsep\n\t */\n\tjsep.removeLiteral = function(literal_name) {\n\t\tdelete literals[literal_name];\n\t\treturn this;\n\t};\n\n\t/**\n\t * @method jsep.removeAllLiterals\n\t * @return jsep\n\t */\n\tjsep.removeAllLiterals = function() {\n\t\tliterals = {};\n\n\t\treturn this;\n\t};\n\n\t// In desktop environments, have a way to restore the old value for `jsep`\n\tif (typeof exports === 'undefined') {\n\t\tvar old_jsep = root.jsep;\n\t\t// The star of the show! It's a function!\n\t\troot.jsep = jsep;\n\t\t// And a courteous function willing to move out of the way for other similarly-named objects!\n\t\tjsep.noConflict = function() {\n\t\t\tif(root.jsep === jsep) {\n\t\t\t\troot.jsep = old_jsep;\n\t\t\t}\n\t\t\treturn jsep;\n\t\t};\n\t} else {\n\t\t// In Node.JS environments\n\t\tif (typeof module !== 'undefined' && module.exports) {\n\t\t\texports = module.exports = jsep;\n\t\t} else {\n\t\t\texports.parse = jsep;\n\t\t}\n\t}\n}(this));\n","import jsep from 'jsep';\n\n/**\n * Evaluation code from JSEP project, under MIT License.\n * Copyright (c) 2013 Stephen Oney, http://jsep.from.so/\n */\n\n// Default operator precedence from https://github.com/EricSmekens/jsep/blob/master/src/jsep.js#L55\nconst DEFAULT_PRECEDENCE = {\n  '||': 1,\n  '&&': 2,\n  '|': 3,\n  '^': 4,\n  '&': 5,\n  '==': 6,\n  '!=': 6,\n  '===': 6,\n  '!==': 6,\n  '<': 7,\n  '>': 7,\n  '<=': 7,\n  '>=': 7,\n  '<<': 8,\n  '>>': 8,\n  '>>>': 8,\n  '+': 9,\n  '-': 9,\n  '*': 10,\n  '/': 10,\n  '%': 10\n};\n\nconst binops = {\n  '||': function (a, b) { return a || b; },\n  '&&': function (a, b) { return a && b; },\n  '|': function (a, b) { return a | b; },\n  '^': function (a, b) { return a ^ b; },\n  '&': function (a, b) { return a & b; },\n  '==': function (a, b) { return a == b; }, // jshint ignore:line\n  '!=': function (a, b) { return a != b; }, // jshint ignore:line\n  '===': function (a, b) { return a === b; },\n  '!==': function (a, b) { return a !== b; },\n  '<': function (a, b) { return a < b; },\n  '>': function (a, b) { return a > b; },\n  '<=': function (a, b) { return a <= b; },\n  '>=': function (a, b) { return a >= b; },\n  '<<': function (a, b) { return a << b; },\n  '>>': function (a, b) { return a >> b; },\n  '>>>': function (a, b) { return a >>> b; },\n  '+': function (a, b) { return a + b; },\n  '-': function (a, b) { return a - b; },\n  '*': function (a, b) { return a * b; },\n  '/': function (a, b) { return a / b; },\n  '%': function (a, b) { return a % b; }\n};\n\nconst unops = {\n  '-': function (a) { return -a; },\n  '+': function (a) { return +a; },\n  '~': function (a) { return ~a; },\n  '!': function (a) { return !a; },\n};\n\ndeclare type operand = number | string;\ndeclare type unaryCallback = (a: operand) => operand;\ndeclare type binaryCallback = (a: operand, b: operand) => operand;\n\ntype AnyExpression = jsep.ArrayExpression\n  | jsep.BinaryExpression\n  | jsep.MemberExpression\n  | jsep.CallExpression\n  | jsep.ConditionalExpression\n  | jsep.Identifier\n  | jsep.Literal\n  | jsep.LogicalExpression\n  | jsep.ThisExpression\n  | jsep.UnaryExpression;\n\nfunction evaluateArray(list, context) {\n  return list.map(function (v) { return evaluate(v, context); });\n}\n\nasync function evaluateArrayAsync(list, context) {\n  const res = await Promise.all(list.map((v) => evalAsync(v, context)));\n  return res;\n}\n\nfunction evaluateMember(node: jsep.MemberExpression, context: object) {\n  const object = evaluate(node.object, context);\n  if (node.computed) {\n    return [object, object[evaluate(node.property, context)]];\n  } else {\n    return [object, object[(node.property as jsep.Identifier).name]];\n  }\n}\n\nasync function evaluateMemberAsync(node: jsep.MemberExpression, context: object) {\n  const object = await evalAsync(node.object, context);\n  if (node.computed) {\n    return [object, object[await evalAsync(node.property, context)]];\n  } else {\n    return [object, object[(node.property as jsep.Identifier).name]];\n  }\n}\n\nfunction evaluate(_node: jsep.Expression, context: object) {\n\n  const node = _node as AnyExpression;\n\n  switch (node.type) {\n\n    case 'ArrayExpression':\n      return evaluateArray(node.elements, context);\n\n    case 'BinaryExpression':\n      return binops[node.operator](evaluate(node.left, context), evaluate(node.right, context));\n\n    case 'CallExpression':\n      let caller, fn, assign;\n      if (node.callee.type === 'MemberExpression') {\n        assign = evaluateMember(node.callee as jsep.MemberExpression, context);\n        caller = assign[0];\n        fn = assign[1];\n      } else {\n        fn = evaluate(node.callee, context);\n      }\n      if (typeof fn !== 'function') { return undefined; }\n      return fn.apply(caller, evaluateArray(node.arguments, context));\n\n    case 'ConditionalExpression':\n      return evaluate(node.test, context)\n        ? evaluate(node.consequent, context)\n        : evaluate(node.alternate, context);\n\n    case 'Identifier':\n      return context[node.name];\n\n    case 'Literal':\n      return node.value;\n\n    case 'LogicalExpression':\n      if (node.operator === '||') {\n        return evaluate(node.left, context) || evaluate(node.right, context);\n      } else if (node.operator === '&&') {\n        return evaluate(node.left, context) && evaluate(node.right, context);\n      }\n      return binops[node.operator](evaluate(node.left, context), evaluate(node.right, context));\n\n    case 'MemberExpression':\n      return evaluateMember(node, context)[1];\n\n    case 'ThisExpression':\n      return context;\n\n    case 'UnaryExpression':\n      return unops[node.operator](evaluate(node.argument, context));\n\n    default:\n      return undefined;\n  }\n\n}\n\nasync function evalAsync(_node: jsep.Expression, context: object) {\n\n  const node = _node as AnyExpression;\n\n  // Brackets used for some case blocks here, to avoid edge cases related to variable hoisting.\n  // See: https://stackoverflow.com/questions/57759348/const-and-let-variable-shadowing-in-a-switch-statement\n  switch (node.type) {\n\n    case 'ArrayExpression':\n      return await evaluateArrayAsync(node.elements, context);\n\n    case 'BinaryExpression': {\n      const [left, right] = await Promise.all([\n        evalAsync(node.left, context),\n        evalAsync(node.right, context)\n      ]);\n      return binops[node.operator](left, right);\n    }\n\n    case 'CallExpression': {\n      let caller, fn, assign;\n      if (node.callee.type === 'MemberExpression') {\n        assign = await evaluateMemberAsync(node.callee as jsep.MemberExpression, context);\n        caller = assign[0];\n        fn = assign[1];\n      } else {\n        fn = await evalAsync(node.callee, context);\n      }\n      if (typeof fn !== 'function') {\n        return undefined;\n      }\n      return await fn.apply(\n        caller,\n        await evaluateArrayAsync(node.arguments, context)\n      );\n    }\n\n    case 'ConditionalExpression':\n      return (await evalAsync(node.test, context))\n        ? await evalAsync(node.consequent, context)\n        : await evalAsync(node.alternate, context);\n\n    case 'Identifier':\n      return context[node.name];\n\n    case 'Literal':\n      return node.value;\n\n    case 'LogicalExpression': {\n      if (node.operator === '||') {\n        return (\n          (await evalAsync(node.left, context)) ||\n          (await evalAsync(node.right, context))\n        );\n      } else if (node.operator === '&&') {\n        return (\n          (await evalAsync(node.left, context)) &&\n          (await evalAsync(node.right, context))\n        );\n      }\n\n      const [left, right] = await Promise.all([\n        evalAsync(node.left, context),\n        evalAsync(node.right, context)\n      ]);\n\n      return binops[node.operator](left, right);\n    }\n\n    case 'MemberExpression':\n      return (await evaluateMemberAsync(node, context))[1];\n\n    case 'ThisExpression':\n      return context;\n\n    case 'UnaryExpression':\n      return unops[node.operator](await evalAsync(node.argument, context));\n\n    default:\n      return undefined;\n  }\n}\n\nfunction compile(expression: string | jsep.Expression): (context: object) => any {\n  return evaluate.bind(null, jsep(expression));\n}\n\nfunction compileAsync(expression: string | jsep.Expression): (context: object) => Promise<any> {\n  return evalAsync.bind(null, jsep(expression));\n}\n\n// Added functions to inject Custom Unary Operators (and override existing ones)\nfunction addUnaryOp(operator: string, _function: unaryCallback): void {\n  jsep.addUnaryOp(operator);\n  unops[operator] = _function;\n}\n\n// Added functions to inject Custom Binary Operators (and override existing ones)\nfunction addBinaryOp(operator: string, precedence_or_fn: number | binaryCallback, _function: binaryCallback): void {\n  if (_function) {\n    jsep.addBinaryOp(operator, precedence_or_fn as number);\n    binops[operator] = _function;\n  } else {\n    jsep.addBinaryOp(operator, DEFAULT_PRECEDENCE[operator] || 1);\n    binops[operator] = precedence_or_fn;\n  }\n}\n\nexport {\n  jsep as parse,\n  evaluate as eval,\n  evalAsync,\n  compile,\n  compileAsync,\n  addUnaryOp,\n  addBinaryOp\n};\n","// Copyright 2018 The Casbin Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Effect is the result for a policy rule.\n// Values for policy effect.\nimport { EffectorStream } from './effectorStream';\n\nexport enum Effect {\n  Allow = 1,\n  Indeterminate,\n  Deny,\n}\n\n// Effector is the interface for Casbin effectors.\nexport interface Effector {\n  newStream(expr: string): EffectorStream;\n}\n","// Copyright 2020 The Casbin Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { EffectorStream } from './effectorStream';\nimport { Effect } from './effector';\n\n/**\n * DefaultEffectorStream is the default implementation of EffectorStream.\n */\nexport class DefaultEffectorStream implements EffectorStream {\n  private done = false;\n  private res = false;\n  private rec = false;\n  private readonly expr: string;\n\n  constructor(expr: string) {\n    this.expr = expr;\n  }\n\n  current(): boolean {\n    return this.res;\n  }\n\n  public pushEffect(eft: Effect): [boolean, boolean, boolean] {\n    switch (this.expr) {\n      case 'some(where (p_eft == allow))':\n        if (eft === Effect.Allow) {\n          this.res = true;\n          this.done = true;\n          this.rec = true;\n        }\n        break;\n      case '!some(where (p_eft == deny))':\n        this.res = true;\n        if (eft === Effect.Deny) {\n          this.res = false;\n          this.done = true;\n          this.rec = true;\n        }\n        break;\n      case 'some(where (p_eft == allow)) && !some(where (p_eft == deny))':\n        if (eft === Effect.Allow) {\n          this.res = true;\n          this.rec = true;\n        } else if (eft === Effect.Deny) {\n          this.res = false;\n          this.done = true;\n          this.rec = true;\n        } else {\n          this.rec = false;\n        }\n        break;\n      case 'priority(p_eft) || deny':\n        if (eft !== Effect.Indeterminate) {\n          this.res = eft === Effect.Allow;\n          this.done = true;\n          this.rec = true;\n        }\n        break;\n      default:\n        throw new Error('unsupported effect');\n    }\n    return [this.res, this.rec, this.done];\n  }\n}\n","// Copyright 2018 The Casbin Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Effector } from './effector';\nimport { EffectorStream } from './effectorStream';\nimport { DefaultEffectorStream } from './defaultEffectorStream';\n\n/**\n * DefaultEffector is default effector for Casbin.\n */\nexport class DefaultEffector implements Effector {\n  newStream(expr: string): EffectorStream {\n    return new DefaultEffectorStream(expr);\n  }\n}\n","// Copyright 2019 The Casbin Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Logger } from './logger';\n\n// DefaultLogger is the implementation for a Logger\nexport class DefaultLogger implements Logger {\n  private enable = false;\n\n  public enableLog(enable: boolean): void {\n    this.enable = enable;\n  }\n\n  public isEnable(): boolean {\n    return this.enable;\n  }\n\n  public print(...v: any[]): void {\n    if (this.enable) {\n      console.log(...v);\n    }\n  }\n\n  public printf(format: string, ...v: any[]): void {\n    if (this.enable) {\n      console.log(format, ...v);\n    }\n  }\n}\n","// Copyright 2019 The Casbin Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { DefaultLogger } from './defaultLogger';\nimport { Logger } from './logger';\n\nlet logger: Logger = new DefaultLogger();\n\n// setLogger sets the current logger.\nfunction setLogger(l: Logger): void {\n  logger = l;\n}\n\n// getLogger returns the current logger.\nfunction getLogger(): Logger {\n  return logger;\n}\n\n// logPrint prints the log.\nfunction logPrint(...v: any[]): void {\n  logger.print(...v);\n}\n\n// logPrintf prints the log with the format.\nfunction logPrintf(format: string, ...v: any[]): void {\n  logger.printf(format, ...v);\n}\n\nexport { setLogger, getLogger, logPrint, logPrintf };\n","// Copyright 2018 The Casbin Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { RoleManager } from './roleManager';\nimport { getLogger, logPrint } from '../log';\n\nexport type MatchingFunc = (arg1: string, arg2: string) => boolean;\n\n// DEFAULT_DOMAIN defines the default domain space.\nconst DEFAULT_DOMAIN = 'casbin::default';\n\n// loadOrDefault returns the existing value for the key if present.\n// Otherwise, it stores and returns the given value.\nfunction loadOrDefault<K, V>(map: Map<K, V>, key: K, value: V): V {\n  const read = map.get(key);\n  if (read === undefined) {\n    map.set(key, value);\n    return value;\n  }\n  return read;\n}\n\n/**\n * Role represents the data structure for a role in RBAC.\n */\nclass Role {\n  public name: string;\n  private roles: Role[];\n\n  constructor(name: string) {\n    this.name = name;\n    this.roles = [];\n  }\n\n  public addRole(role: Role): void {\n    if (this.roles.some((n) => n.name === role.name)) {\n      return;\n    }\n    this.roles.push(role);\n  }\n\n  public deleteRole(role: Role): void {\n    this.roles = this.roles.filter((n) => n.name !== role.name);\n  }\n\n  public hasRole(name: string, hierarchyLevel: number): boolean {\n    if (this.name === name) {\n      return true;\n    }\n    if (hierarchyLevel <= 0) {\n      return false;\n    }\n    for (const role of this.roles) {\n      if (role.hasRole(name, hierarchyLevel - 1)) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  public hasDirectRole(name: string): boolean {\n    return this.roles.some((n) => n.name === name);\n  }\n\n  public toString(): string {\n    return this.name + this.roles.join(', ');\n  }\n\n  public getRoles(): string[] {\n    return this.roles.map((n) => n.name);\n  }\n}\n\nclass Roles extends Map<string, Role> {\n  constructor() {\n    super();\n  }\n\n  public hasRole(name: string, matchingFunc?: MatchingFunc): boolean {\n    let ok = false;\n    if (matchingFunc) {\n      this.forEach((value, key) => {\n        if (matchingFunc(name, key)) {\n          ok = true;\n        }\n      });\n    } else {\n      return this.has(name);\n    }\n    return ok;\n  }\n\n  public createRole(name: string, matchingFunc?: MatchingFunc): Role {\n    const role = loadOrDefault(this, name, new Role(name));\n    if (matchingFunc) {\n      this.forEach((value, key) => {\n        if (matchingFunc(name, key) && name !== key) {\n          // Add new role to matching role\n          const role1 = loadOrDefault(this, key, new Role(key));\n          role.addRole(role1);\n        }\n      });\n    }\n    return role;\n  }\n}\n\n// RoleManager provides a default implementation for the RoleManager interface\nexport class DefaultRoleManager implements RoleManager {\n  private allDomains: Map<string, Roles>;\n  private maxHierarchyLevel: number;\n  private hasPattern = false;\n  private hasDomainPattern = false;\n  private matchingFunc: MatchingFunc;\n  private domainMatchingFunc: MatchingFunc;\n\n  /**\n   * DefaultRoleManager is the constructor for creating an instance of the\n   * default RoleManager implementation.\n   *\n   * @param maxHierarchyLevel the maximized allowed RBAC hierarchy level.\n   */\n  constructor(maxHierarchyLevel: number) {\n    this.allDomains = new Map<string, Roles>();\n    this.allDomains.set(DEFAULT_DOMAIN, new Roles());\n    this.maxHierarchyLevel = maxHierarchyLevel;\n  }\n\n  /**\n   * addMatchingFunc support use pattern in g\n   * @param name name\n   * @param fn matching function\n   * @deprecated\n   */\n  public async addMatchingFunc(name: string, fn: MatchingFunc): Promise<void>;\n\n  /**\n   * addMatchingFunc support use pattern in g\n   * @param fn matching function\n   */\n  public async addMatchingFunc(fn: MatchingFunc): Promise<void>;\n\n  /**\n   * addMatchingFunc support use pattern in g\n   * @param name name\n   * @param fn matching function\n   * @deprecated\n   */\n  public async addMatchingFunc(name: string | MatchingFunc, fn?: MatchingFunc): Promise<void> {\n    this.hasPattern = true;\n    if (typeof name === 'string' && fn) {\n      this.matchingFunc = fn;\n    } else if (typeof name === 'function') {\n      this.matchingFunc = name;\n    } else {\n      throw new Error('error: domain should be 1 parameter');\n    }\n  }\n\n  /**\n   * addDomainMatchingFunc support use domain pattern in g\n   * @param fn domain matching function\n   * ```\n   */\n  public async addDomainMatchingFunc(fn: MatchingFunc): Promise<void> {\n    this.hasDomainPattern = true;\n    this.domainMatchingFunc = fn;\n  }\n\n  private generateTempRoles(domain: string): Roles {\n    loadOrDefault(this.allDomains, domain, new Roles());\n\n    const patternDomain = new Set([domain]);\n    if (this.hasDomainPattern) {\n      this.allDomains.forEach((value, key) => {\n        if (this.domainMatchingFunc(domain, key)) {\n          patternDomain.add(key);\n        }\n      });\n    }\n\n    const allRoles = new Roles();\n    patternDomain.forEach((domain) => {\n      loadOrDefault(this.allDomains, domain, new Roles()).forEach((value, key) => {\n        const role1 = allRoles.createRole(value.name, this.matchingFunc);\n        value.getRoles().forEach((n) => {\n          role1.addRole(allRoles.createRole(n, this.matchingFunc));\n        });\n      });\n    });\n    return allRoles;\n  }\n\n  /**\n   * addLink adds the inheritance link between role: name1 and role: name2.\n   * aka role: name1 inherits role: name2.\n   * domain is a prefix to the roles.\n   */\n  public async addLink(name1: string, name2: string, ...domain: string[]): Promise<void> {\n    if (domain.length === 0) {\n      domain = [DEFAULT_DOMAIN];\n    } else if (domain.length > 1) {\n      throw new Error('error: domain should be 1 parameter');\n    }\n\n    const allRoles = loadOrDefault(this.allDomains, domain[0], new Roles());\n\n    const role1 = loadOrDefault(allRoles, name1, new Role(name1));\n    const role2 = loadOrDefault(allRoles, name2, new Role(name2));\n    role1.addRole(role2);\n  }\n\n  /**\n   * clear clears all stored data and resets the role manager to the initial state.\n   */\n  public async clear(): Promise<void> {\n    this.allDomains = new Map();\n    this.allDomains.set(DEFAULT_DOMAIN, new Roles());\n  }\n\n  /**\n   * deleteLink deletes the inheritance link between role: name1 and role: name2.\n   * aka role: name1 does not inherit role: name2 any more.\n   * domain is a prefix to the roles.\n   */\n  public async deleteLink(name1: string, name2: string, ...domain: string[]): Promise<void> {\n    if (domain.length === 0) {\n      domain = [DEFAULT_DOMAIN];\n    } else if (domain.length > 1) {\n      throw new Error('error: domain should be 1 parameter');\n    }\n\n    const allRoles = loadOrDefault(this.allDomains, domain[0], new Roles());\n\n    if (!allRoles.has(name1) || !allRoles.has(name2)) {\n      return;\n    }\n\n    const role1 = loadOrDefault(allRoles, name1, new Role(name1));\n    const role2 = loadOrDefault(allRoles, name2, new Role(name2));\n    role1.deleteRole(role2);\n  }\n\n  /**\n   * hasLink determines whether role: name1 inherits role: name2.\n   * domain is a prefix to the roles.\n   */\n  public async hasLink(name1: string, name2: string, ...domain: string[]): Promise<boolean> {\n    if (domain.length === 0) {\n      domain = [DEFAULT_DOMAIN];\n    } else if (domain.length > 1) {\n      throw new Error('error: domain should be 1 parameter');\n    }\n\n    if (name1 === name2) {\n      return true;\n    }\n\n    let allRoles: Roles;\n    if (this.hasPattern || this.hasDomainPattern) {\n      allRoles = this.generateTempRoles(domain[0]);\n    } else {\n      allRoles = loadOrDefault(this.allDomains, domain[0], new Roles());\n    }\n\n    if (!allRoles.hasRole(name1, this.matchingFunc) || !allRoles.hasRole(name2, this.matchingFunc)) {\n      return false;\n    }\n\n    const role1 = allRoles.createRole(name1, this.matchingFunc);\n    return role1.hasRole(name2, this.maxHierarchyLevel);\n  }\n\n  /**\n   * getRoles gets the roles that a subject inherits.\n   * domain is a prefix to the roles.\n   */\n  public async getRoles(name: string, ...domain: string[]): Promise<string[]> {\n    if (domain.length === 0) {\n      domain = [DEFAULT_DOMAIN];\n    } else if (domain.length > 1) {\n      throw new Error('error: domain should be 1 parameter');\n    }\n\n    let allRoles: Roles;\n    if (this.hasPattern || this.hasDomainPattern) {\n      allRoles = this.generateTempRoles(domain[0]);\n    } else {\n      allRoles = loadOrDefault(this.allDomains, domain[0], new Roles());\n    }\n\n    if (!allRoles.hasRole(name, this.matchingFunc)) {\n      return [];\n    }\n\n    return allRoles.createRole(name, this.matchingFunc).getRoles();\n  }\n\n  /**\n   * getUsers gets the users that inherits a subject.\n   * domain is an unreferenced parameter here, may be used in other implementations.\n   */\n  public async getUsers(name: string, ...domain: string[]): Promise<string[]> {\n    if (domain.length === 0) {\n      domain = [DEFAULT_DOMAIN];\n    } else if (domain.length > 1) {\n      throw new Error('error: domain should be 1 parameter');\n    }\n\n    let allRoles: Roles;\n    if (this.hasPattern || this.hasDomainPattern) {\n      allRoles = this.generateTempRoles(domain[0]);\n    } else {\n      allRoles = loadOrDefault(this.allDomains, domain[0], new Roles());\n    }\n\n    if (!allRoles.hasRole(name, this.matchingFunc)) {\n      return [];\n    }\n\n    return [...allRoles.values()].filter((n) => n.hasDirectRole(name)).map((n) => n.name);\n  }\n\n  /**\n   * printRoles prints all the roles to log.\n   */\n  public async printRoles(): Promise<void> {\n    if (getLogger().isEnable()) {\n      [...this.allDomains.values()].forEach((n) => {\n        logPrint(n.toString());\n      });\n    }\n  }\n}\n","// Copyright 2018 The Casbin Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport * as rbac from '../rbac';\nimport * as util from '../util';\nimport { Config, ConfigInterface } from '../config';\nimport { Assertion } from './assertion';\nimport { getLogger, logPrint } from '../log';\nimport { DefaultRoleManager } from '../rbac';\n\nexport const sectionNameMap: { [index: string]: string } = {\n  r: 'request_definition',\n  p: 'policy_definition',\n  g: 'role_definition',\n  e: 'policy_effect',\n  m: 'matchers',\n};\n\nexport enum PolicyOp {\n  PolicyAdd,\n  PolicyRemove,\n}\n\nexport const requiredSections = ['r', 'p', 'e', 'm'];\n\nexport class Model {\n  // Model represents the whole access control model.\n  // Mest-map is the collection of assertions, can be \"r\", \"p\", \"g\", \"e\", \"m\".\n  public model: Map<string, Map<string, Assertion>>;\n\n  /**\n   * constructor is the constructor for Model.\n   */\n  public constructor(text?: string) {\n    this.model = new Map<string, Map<string, Assertion>>();\n    if (text) {\n      this.loadModelFromText(text);\n    }\n  }\n\n  private loadAssertion(cfg: ConfigInterface, sec: string, key: string): boolean {\n    const secName = sectionNameMap[sec];\n    const value = cfg.getString(`${secName}::${key}`);\n    return this.addDef(sec, key, value);\n  }\n\n  private static getKeySuffix(i: number): string {\n    if (i === 1) {\n      return '';\n    }\n\n    return i.toString();\n  }\n\n  private loadSection(cfg: ConfigInterface, sec: string): void {\n    let i = 1;\n    for (;;) {\n      if (!this.loadAssertion(cfg, sec, sec + Model.getKeySuffix(i))) {\n        break;\n      } else {\n        i++;\n      }\n    }\n  }\n\n  // addDef adds an assertion to the model.\n  public addDef(sec: string, key: string, value: string): boolean {\n    if (value === '') {\n      return false;\n    }\n\n    const ast = new Assertion();\n    ast.key = key;\n    ast.value = value;\n\n    if (sec === 'r' || sec === 'p') {\n      const tokens = value.split(',').map((n) => n.trim());\n\n      for (let i = 0; i < tokens.length; i++) {\n        tokens[i] = key + '_' + tokens[i];\n      }\n\n      ast.tokens = tokens;\n    } else if (sec === 'm') {\n      const stringArguments = value.match(/\\\"(.*?)\\\"/g) || [];\n\n      stringArguments.forEach((n, index) => {\n        value = value.replace(n, `$<${index}>`);\n      });\n\n      value = util.escapeAssertion(value);\n\n      stringArguments.forEach((n, index) => {\n        value = value.replace(`$<${index}>`, n);\n      });\n\n      ast.value = value;\n    } else {\n      ast.value = util.escapeAssertion(value);\n    }\n\n    const nodeMap = this.model.get(sec);\n\n    if (nodeMap) {\n      nodeMap.set(key, ast);\n    } else {\n      const assertionMap = new Map<string, Assertion>();\n      assertionMap.set(key, ast);\n      this.model.set(sec, assertionMap);\n    }\n\n    return true;\n  }\n\n  // loadModelFromText loads the model from the text.\n  public loadModelFromText(text: string): void {\n    const cfg = Config.newConfigFromText(text);\n\n    this.loadModelFromConfig(cfg);\n  }\n\n  public loadModelFromConfig(cfg: ConfigInterface): void {\n    for (const s in sectionNameMap) {\n      this.loadSection(cfg, s);\n    }\n\n    const ms: string[] = [];\n    requiredSections.forEach((n) => {\n      if (!this.hasSection(n)) {\n        ms.push(sectionNameMap[n]);\n      }\n    });\n\n    if (ms.length > 0) {\n      throw new Error(`missing required sections: ${ms.join(',')}`);\n    }\n  }\n\n  private hasSection(sec: string): boolean {\n    return this.model.get(sec) !== undefined;\n  }\n\n  // printModel prints the model to the log.\n  public printModel(): void {\n    logPrint('Model:');\n    this.model.forEach((value, key) => {\n      value.forEach((ast, astKey) => {\n        logPrint(`${key}.${astKey}: ${ast.value}`);\n      });\n    });\n  }\n\n  // buildIncrementalRoleLinks provides incremental build the role inheritance relations.\n  public async buildIncrementalRoleLinks(rm: rbac.RoleManager, op: PolicyOp, sec: string, ptype: string, rules: string[][]): Promise<void> {\n    if (sec === 'g') {\n      await this.model.get(sec)?.get(ptype)?.buildIncrementalRoleLinks(rm, op, rules);\n    }\n  }\n\n  // buildRoleLinks initializes the roles in RBAC.\n  public async buildRoleLinks(rmMap: Map<string, rbac.RoleManager>): Promise<void> {\n    const astMap = this.model.get('g');\n    if (!astMap) {\n      return;\n    }\n    for (const key of astMap.keys()) {\n      const ast = astMap.get(key);\n      let rm = rmMap.get(key);\n      if (!rm) {\n        rm = new DefaultRoleManager(10);\n        rmMap.set(key, rm);\n      }\n      await ast?.buildRoleLinks(rm);\n    }\n  }\n\n  // clearPolicy clears all current policy.\n  public clearPolicy(): void {\n    this.model.forEach((value, key) => {\n      if (key === 'p' || key === 'g') {\n        value.forEach((ast) => {\n          ast.policy = [];\n        });\n      }\n    });\n  }\n\n  // getPolicy gets all rules in a policy.\n  public getPolicy(sec: string, key: string): string[][] {\n    const policy: string[][] = [];\n\n    const ast = this.model.get(sec)?.get(key);\n    if (ast) {\n      policy.push(...ast.policy);\n    }\n    return policy;\n  }\n\n  // hasPolicy determines whether a model has the specified policy rule.\n  public hasPolicy(sec: string, key: string, rule: string[]): boolean {\n    const ast = this.model.get(sec)?.get(key);\n    if (!ast) {\n      return false;\n    }\n    return ast.policy.some((n: string[]) => util.arrayEquals(n, rule));\n  }\n\n  // addPolicy adds a policy rule to the model.\n  public addPolicy(sec: string, key: string, rule: string[]): boolean {\n    if (!this.hasPolicy(sec, key, rule)) {\n      const ast = this.model.get(sec)?.get(key);\n      if (!ast) {\n        return false;\n      }\n\n      const policy = ast.policy;\n      const tokens = ast.tokens;\n\n      const priorityIndex = tokens.indexOf('p_priority');\n\n      if (priorityIndex !== -1) {\n        const priorityRule = rule[priorityIndex];\n        const insertIndex = policy.findIndex((oneRule) => oneRule[priorityIndex] >= priorityRule);\n\n        if (priorityIndex === -1) {\n          policy.push(rule);\n        } else {\n          policy.splice(insertIndex, 0, rule);\n        }\n      } else {\n        policy.push(rule);\n      }\n      return true;\n    }\n\n    return false;\n  }\n\n  // addPolicies adds policy rules to the model.\n  public addPolicies(sec: string, ptype: string, rules: string[][]): [boolean, string[][]] {\n    const ast = this.model.get(sec)?.get(ptype);\n    if (!ast) {\n      return [false, []];\n    }\n\n    for (const rule of rules) {\n      if (this.hasPolicy(sec, ptype, rule)) {\n        return [false, []];\n      }\n    }\n\n    const priorityFlag = ast.tokens.indexOf('p_priority') !== -1;\n\n    if (priorityFlag) {\n      rules.forEach((rule) => {\n        this.addPolicy(sec, ptype, rule);\n      });\n    } else {\n      ast.policy = ast.policy.concat(rules);\n    }\n\n    return [true, rules];\n  }\n\n  // updatePolicy updates a policy from the model\n  public updatePolicy(sec: string, ptype: string, oldRule: string[], newRule: string[]): boolean {\n    const ast = this.model.get(sec)?.get(ptype);\n    if (!ast) {\n      return false;\n    }\n\n    const index = ast.policy.findIndex((r) => util.arrayEquals(r, oldRule));\n    if (index === -1) {\n      return false;\n    }\n\n    const priorityIndex = ast.tokens.indexOf('p_priority');\n\n    if (priorityIndex !== -1) {\n      if (oldRule[priorityIndex] === newRule[priorityIndex]) {\n        ast.policy[index] = newRule;\n      } else {\n        // this.removePolicy(sec, ptype, oldRule);\n        // this.addPolicy(sec, ptype, newRule);\n        throw new Error('new rule should have the same priority with old rule.');\n      }\n    } else {\n      ast.policy[index] = newRule;\n    }\n\n    return true;\n  }\n\n  // removePolicy removes a policy rule from the model.\n  public removePolicy(sec: string, key: string, rule: string[]): boolean {\n    if (this.hasPolicy(sec, key, rule)) {\n      const ast = this.model.get(sec)?.get(key);\n      if (!ast) {\n        return false;\n      }\n      ast.policy = ast.policy.filter((r) => !util.arrayEquals(rule, r));\n      return true;\n    }\n\n    return false;\n  }\n\n  // removePolicies removes policy rules from the model.\n  public removePolicies(sec: string, ptype: string, rules: string[][]): [boolean, string[][]] {\n    const effects: string[][] = [];\n    const ast = this.model.get(sec)?.get(ptype);\n    if (!ast) {\n      return [false, []];\n    }\n\n    for (const rule of rules) {\n      if (!this.hasPolicy(sec, ptype, rule)) {\n        return [false, []];\n      }\n    }\n\n    for (const rule of rules) {\n      ast.policy = ast.policy.filter((r: string[]) => {\n        const equals = util.arrayEquals(rule, r);\n        if (equals) {\n          effects.push(r);\n        }\n        return !equals;\n      });\n    }\n\n    return [true, effects];\n  }\n\n  // getFilteredPolicy gets rules based on field filters from a policy.\n  public getFilteredPolicy(sec: string, key: string, fieldIndex: number, ...fieldValues: string[]): string[][] {\n    const res: string[][] = [];\n    const ast = this.model.get(sec)?.get(key);\n    if (!ast) {\n      return res;\n    }\n    for (const rule of ast.policy) {\n      let matched = true;\n      for (let i = 0; i < fieldValues.length; i++) {\n        const fieldValue = fieldValues[i];\n        if (fieldValue !== '' && rule[fieldIndex + i] !== fieldValue) {\n          matched = false;\n          break;\n        }\n      }\n\n      if (matched) {\n        res.push(rule);\n      }\n    }\n\n    return res;\n  }\n\n  // removeFilteredPolicy removes policy rules based on field filters from the model.\n  public removeFilteredPolicy(sec: string, key: string, fieldIndex: number, ...fieldValues: string[]): [boolean, string[][]] {\n    const res = [];\n    const effects: string[][] = [];\n    let bool = false;\n    if (fieldValues.length === 0) {\n      return [false, effects];\n    }\n    const ast = this.model.get(sec)?.get(key);\n    if (!ast) {\n      return [false, []];\n    }\n    for (const rule of ast.policy) {\n      let matched = true;\n      for (let i = 0; i < fieldValues.length; i++) {\n        const fieldValue = fieldValues[i];\n        if (fieldValue !== '' && rule[fieldIndex + i] !== fieldValue) {\n          matched = false;\n          break;\n        }\n      }\n\n      if (matched) {\n        bool = true;\n        effects.push(rule);\n      } else {\n        res.push(rule);\n      }\n    }\n\n    if (effects.length !== 0) {\n      ast.policy = res;\n    }\n\n    return [bool, effects];\n  }\n\n  // getValuesForFieldInPolicy gets all values for a field for all rules in a policy, duplicated values are removed.\n  public getValuesForFieldInPolicy(sec: string, key: string, fieldIndex: number): string[] {\n    const values: string[] = [];\n    const ast = this.model.get(sec)?.get(key);\n    if (!ast) {\n      return values;\n    }\n    return util.arrayRemoveDuplicates(ast.policy.map((n: string[]) => n[fieldIndex]));\n  }\n\n  // getValuesForFieldInPolicyAllTypes gets all values for a field for all rules in a policy of all ptypes, duplicated values are removed.\n  public getValuesForFieldInPolicyAllTypes(sec: string, fieldIndex: number): string[] {\n    const values: string[] = [];\n\n    const ast = this.model.get(sec);\n    if (!ast) {\n      return values;\n    }\n\n    for (const ptype of ast.keys()) {\n      values.push(...this.getValuesForFieldInPolicy(sec, ptype, fieldIndex));\n    }\n\n    return util.arrayRemoveDuplicates(values);\n  }\n\n  // printPolicy prints the policy to log.\n  public printPolicy(): void {\n    if (!getLogger().isEnable()) {\n      return;\n    }\n    logPrint('Policy:');\n    this.model.forEach((map, key) => {\n      if (key === 'p' || key === 'g') {\n        map.forEach((ast) => {\n          logPrint(`key, : ${ast.value}, : , ${ast.policy}`);\n        });\n      }\n    });\n  }\n}\n","// Copyright 2017 The casbin Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport * as rbac from '../rbac';\nimport { logPrint } from '../log';\nimport { PolicyOp } from './model';\n\n// Assertion represents an expression in a section of the model.\n// For example: r = sub, obj, act\nexport class Assertion {\n  public key: string;\n  public value: string;\n  public tokens: string[];\n  public policy: string[][];\n  public rm: rbac.RoleManager;\n\n  /**\n   * constructor is the constructor for Assertion.\n   */\n  constructor() {\n    this.key = '';\n    this.value = '';\n    this.tokens = [];\n    this.policy = [];\n    this.rm = new rbac.DefaultRoleManager(10);\n  }\n\n  public async buildIncrementalRoleLinks(rm: rbac.RoleManager, op: PolicyOp, rules: string[][]): Promise<void> {\n    this.rm = rm;\n    const count = (this.value.match(/_/g) || []).length;\n    if (count < 2) {\n      throw new Error('the number of \"_\" in role definition should be at least 2');\n    }\n    for (let rule of rules) {\n      if (rule.length < count) {\n        throw new Error('grouping policy elements do not meet role definition');\n      }\n      if (rule.length > count) {\n        rule = rule.slice(0, count);\n      }\n      switch (op) {\n        case PolicyOp.PolicyAdd:\n          await this.rm.addLink(rule[0], rule[1], ...rule.slice(2));\n          break;\n        case PolicyOp.PolicyRemove:\n          await this.rm.deleteLink(rule[0], rule[1], ...rule.slice(2));\n          break;\n        default:\n          throw new Error('unsupported operation');\n      }\n    }\n  }\n\n  public async buildRoleLinks(rm: rbac.RoleManager): Promise<void> {\n    this.rm = rm;\n    const count = (this.value.match(/_/g) || []).length;\n    if (count < 2) {\n      throw new Error('the number of \"_\" in role definition should be at least 2');\n    }\n    for (let rule of this.policy) {\n      if (rule.length > count) {\n        rule = rule.slice(0, count);\n      }\n      await this.rm.addLink(rule[0], rule[1], ...rule.slice(2));\n    }\n    logPrint(`Role links for: ${this.key}`);\n    await this.rm.printRoles();\n  }\n}\n","// Copyright 2017 The casbin Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport * as util from '../util';\n\nexport type MatchingFunction = (...arg: any[]) => boolean | number | string | Promise<boolean> | Promise<number> | Promise<string>;\n\n// FunctionMap represents the collection of Function.\nexport class FunctionMap {\n  private functions: Map<string, any>;\n\n  /**\n   * constructor is the constructor for FunctionMap.\n   */\n  constructor() {\n    this.functions = new Map<string, any>();\n  }\n\n  // loadFunctionMap loads an initial function map.\n  public static loadFunctionMap(): FunctionMap {\n    const fm = new FunctionMap();\n\n    fm.addFunction('keyMatch', util.keyMatchFunc);\n    fm.addFunction('keyGet', util.keyGetFunc);\n    fm.addFunction('keyMatch2', util.keyMatch2Func);\n    fm.addFunction('keyGet2', util.keyGet2Func);\n    fm.addFunction('keyMatch3', util.keyMatch3Func);\n    fm.addFunction('keyMatch4', util.keyMatch4Func);\n    fm.addFunction('keyMatch5', util.keyMatch5Func);\n    fm.addFunction('regexMatch', util.regexMatchFunc);\n    fm.addFunction('ipMatch', util.ipMatchFunc);\n    fm.addFunction('globMatch', util.globMatch);\n\n    return fm;\n  }\n\n  // addFunction adds an expression function.\n  public addFunction(name: string, func: MatchingFunction): void {\n    if (!this.functions.get(name)) {\n      this.functions.set(name, func);\n    }\n  }\n\n  // getFunctions return all functions.\n  public getFunctions(): any {\n    return this.functions;\n  }\n}\n","import { newEnforcer } from './enforcer';\n\nexport class EnforceContext {\n  public pType: string;\n  public rType: string;\n  public eType: string;\n  public mType: string;\n\n  constructor(rType: string, pType: string, eType: string, mType: string) {\n    this.pType = pType;\n    this.eType = eType;\n    this.mType = mType;\n    this.rType = rType;\n  }\n}\nexport class NewEnforceContext {\n  constructor(index: string) {\n    return new EnforceContext('r' + index, 'p' + index, 'e' + index, 'm' + index);\n  }\n}\n","import { Model } from '../model';\nimport { policyStringToArray } from '../util';\n\nexport class Helper {\n  public static loadPolicyLine(line: string, model: Model): void {\n    if (!line || line.trimStart().charAt(0) === '#') {\n      return;\n    }\n\n    const tokens = policyStringToArray(line);\n\n    if (!tokens || !tokens[0]) {\n      return;\n    }\n\n    const key = tokens[0][0];\n    const sec = key.substring(0, 1);\n    const item = model.model.get(sec);\n    if (!item) {\n      return;\n    }\n\n    const policy = item.get(key);\n    if (!policy) {\n      return;\n    }\n    policy.policy.push(tokens[0].slice(1));\n  }\n}\n","import { Adapter } from './adapter';\nimport { Model } from '../model';\nimport { Helper } from './helper';\nimport { BatchAdapter } from './batchAdapter';\nimport { arrayEquals, policyArrayToString, policyStringToArray } from '../util';\n\n/**\n * MemoryAdapter is the memory adapter for Casbin.\n * It can load policy from a string.\n */\nexport class MemoryAdapter implements Adapter, BatchAdapter {\n  protected policies: string[][] = [];\n\n  /**\n   * MemoryAdapter is the constructor for MemoryAdapter.\n   * @param policy - policy formatted as a CSV string, or policy array.\n   */\n  constructor(policy: string | string[][]) {\n    if (!policy) {\n      return;\n    }\n    if (typeof policy === 'string') {\n      this.policies = policyStringToArray(policy);\n    } else {\n      this.policies = policy;\n    }\n  }\n\n  /**\n   * hasPolicy checks if specific policy exists in storage.\n   */\n  public hasPolicy(policy: string[]): boolean {\n    return this.policies.some((prePolicy) => {\n      return arrayEquals(prePolicy, policy);\n    });\n  }\n\n  /**\n   * loadPolicy loads data in adapter to model.\n   * @param model\n   */\n  public async loadPolicy(model: Model): Promise<void> {\n    this.policies.forEach((n: string[]) => {\n      if (!n) {\n        return;\n      }\n      Helper.loadPolicyLine(policyArrayToString(n), model);\n    });\n  }\n\n  /**\n   * savePolicy saves all policy rules to the storage.\n   */\n  public async savePolicy(model: Model): Promise<boolean> {\n    throw new Error('not implemented');\n  }\n\n  /**\n   * addPolicy adds a policy rule to the storage.\n   */\n  public async addPolicy(sec: string, ptype: string, rule: string[]): Promise<void> {\n    const policy = rule.slice();\n    policy.unshift(ptype);\n    if (!this.hasPolicy(rule)) {\n      this.policies.push(policy);\n    }\n  }\n\n  /**\n   * removePolicy removes a policy rule from the storage.\n   */\n  public async removePolicy(sec: string, ptype: string, rule: string[]): Promise<void> {\n    const ruleClone = rule.slice();\n    ruleClone.unshift(ptype);\n    this.policies = this.policies.filter((r) => !arrayEquals(ruleClone, r));\n  }\n\n  /**\n   * removeFilteredPolicy removes policy rules that match the filter from the storage.\n   */\n  public async removeFilteredPolicy(sec: string, ptype: string, fieldIndex: number, ...fieldValues: string[]): Promise<void> {\n    throw new Error('not implemented');\n  }\n\n  /**\n   * addPolicies adds policy rules to the storage.\n   */\n  public async addPolicies(sec: string, ptype: string, rules: string[][]): Promise<void> {\n    for (const rule of rules) {\n      if (!this.hasPolicy(rule)) {\n        await this.addPolicy(sec, ptype, rule);\n      }\n    }\n  }\n\n  /**\n   * removePolicies removes policy rules from the storage.\n   * This is part of the Auto-Save feature.\n   */\n  public async removePolicies(sec: string, ptype: string, rules: string[][]): Promise<void> {\n    this.policies = this.policies.filter((rule) => {\n      return !rules.some((deleteRule) => arrayEquals(deleteRule, rule));\n    });\n  }\n}\n","import { FilteredAdapter } from './filteredAdapter';\nimport { Model } from '../model';\nimport { Helper } from './helper';\nimport { MemoryAdapter } from './memoryAdapter';\nimport { policyArrayToString, policyStringToArray } from '../util';\n\nexport class Filter {\n  public g: string[] = [];\n  public p: string[] = [];\n}\n\nexport class DefaultFilteredAdapter extends MemoryAdapter implements FilteredAdapter {\n  private filtered: boolean;\n\n  constructor(policy: string) {\n    super(policy);\n    this.filtered = false;\n  }\n\n  // loadPolicy loads all policy rules from the storage.\n  public async loadPolicy(model: Model): Promise<void> {\n    this.filtered = false;\n    await super.loadPolicy(model);\n  }\n\n  public async loadFilteredPolicy(model: Model, filter: Filter): Promise<void> {\n    if (!filter) {\n      await this.loadPolicy(model);\n      return;\n    }\n\n    await this.loadFilteredPolicyFile(model, filter, Helper.loadPolicyLine);\n    this.filtered = true;\n  }\n\n  private async loadFilteredPolicyFile(model: Model, filter: Filter, handler: (line: string, model: Model) => void): Promise<void> {\n    this.policies.forEach((n: string[]) => {\n      const line = policyArrayToString(n);\n      if (!line || DefaultFilteredAdapter.filterLine(line, filter)) {\n        return;\n      }\n      handler(line, model);\n    });\n  }\n\n  public isFiltered(): boolean {\n    return this.filtered;\n  }\n\n  public async savePolicy(model: Model): Promise<boolean> {\n    if (this.filtered) {\n      throw new Error('cannot save a filtered policy');\n    }\n    await super.savePolicy(model);\n    return true;\n  }\n\n  private static filterLine(line: string, filter: Filter): boolean {\n    if (!filter) {\n      return false;\n    }\n    const p = line.split(',');\n    if (p.length === 0) {\n      return true;\n    }\n    let filterSlice: string[] = [];\n    switch (p[0].trim()) {\n      case 'p':\n        filterSlice = filter.p;\n        break;\n      case 'g':\n        filterSlice = filter.g;\n        break;\n    }\n\n    return DefaultFilteredAdapter.filterWords(p, filterSlice);\n  }\n\n  private static filterWords(line: string[], filter: string[]): boolean {\n    if (line.length < filter.length + 1) {\n      return true;\n    }\n    let skipLine = false;\n    for (let i = 0; i < filter.length; i++) {\n      if (filter[i] && filter[i] !== filter[i + 1]) {\n        skipLine = true;\n        break;\n      }\n    }\n    return skipLine;\n  }\n}\n","// Copyright 2018 The Casbin Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { ManagementEnforcer } from './managementEnforcer';\nimport { Model } from './model';\nimport { Adapter, MemoryAdapter } from './persist';\nimport { getLogger } from './log';\nimport { arrayRemoveDuplicates } from './util';\n\n/**\n * Enforcer = ManagementEnforcer + RBAC API.\n */\nexport class Enforcer extends ManagementEnforcer {\n  /**\n   * initWithModelAndAdapter initializes an enforcer with a model and a database adapter.\n   * @param m model instance\n   * @param adapter current adapter instance\n   * @param lazyLoad whether to load policy at initial time\n   */\n  public async initWithModelAndAdapter(m: Model, adapter?: Adapter, lazyLoad = false): Promise<void> {\n    if (adapter) {\n      this.adapter = adapter;\n    }\n\n    this.model = m;\n    this.model.printModel();\n\n    this.initRmMap();\n\n    if (!lazyLoad && this.adapter) {\n      await this.loadPolicy();\n    }\n  }\n\n  /**\n   * getRolesForUser gets the roles that a user has.\n   *\n   * @param name the user.\n   * @param domain the domain.\n   * @return the roles that the user has.\n   */\n  public async getRolesForUser(name: string, domain?: string): Promise<string[]> {\n    const rm = this.rmMap.get('g');\n    if (rm) {\n      if (domain === undefined) {\n        return rm.getRoles(name);\n      } else {\n        return rm.getRoles(name, domain);\n      }\n    }\n    throw new Error(\"RoleManager didn't exist.\");\n  }\n\n  /**\n   * getUsersForRole gets the users that has a role.\n   *\n   * @param name the role.\n   * @param domain the domain.\n   * @return the users that has the role.\n   */\n  public async getUsersForRole(name: string, domain?: string): Promise<string[]> {\n    const rm = this.rmMap.get('g');\n    if (rm) {\n      if (domain === undefined) {\n        return rm.getUsers(name);\n      } else {\n        return rm.getUsers(name, domain);\n      }\n    }\n    throw new Error(\"RoleManager didn't exist.\");\n  }\n\n  /**\n   * hasRoleForUser determines whether a user has a role.\n   *\n   * @param name the user.\n   * @param role the role.\n   * @param domain the domain.\n   * @return whether the user has the role.\n   */\n  public async hasRoleForUser(name: string, role: string, domain?: string): Promise<boolean> {\n    const roles = await this.getRolesForUser(name, domain);\n    let hasRole = false;\n    for (const r of roles) {\n      if (r === role) {\n        hasRole = true;\n        break;\n      }\n    }\n\n    return hasRole;\n  }\n\n  /**\n   * addRoleForUser adds a role for a user.\n   * Returns false if the user already has the role (aka not affected).\n   *\n   * @param user the user.\n   * @param role the role.\n   * @param domain the domain.\n   * @return succeeds or not.\n   */\n  public async addRoleForUser(user: string, role: string, domain?: string): Promise<boolean> {\n    if (domain === undefined) {\n      return this.addGroupingPolicy(user, role);\n    } else {\n      return this.addGroupingPolicy(user, role, domain);\n    }\n  }\n\n  /**\n   * addRoleForUserInDomain adds a role for a user.\n   * Returns false if the user already has the role (aka not affected).\n   *\n   * @param user the user.\n   * @param role the role.\n   * @param domain the domain.\n   * @return succeeds or not.\n   */\n  public async addRoleForUserInDomain(user: string, role: string, domain: string): Promise<boolean> {\n    return this.addGroupingPolicy(user, role, domain);\n  }\n\n  /**\n   * deleteRoleForUser deletes a role for a user.\n   * Returns false if the user does not have the role (aka not affected).\n   *\n   * @param user the user.\n   * @param role the role.\n   * @param domain the domain.\n   * @return succeeds or not.\n   */\n  public async deleteRoleForUser(user: string, role: string, domain?: string): Promise<boolean> {\n    if (domain === undefined) {\n      return this.removeGroupingPolicy(user, role);\n    } else {\n      return this.removeGroupingPolicy(user, role, domain);\n    }\n  }\n  /**\n   * deleteRoleForUserInDomain deletes a role for a user.\n   * Returns false if the user does not have the role (aka not affected).\n   *\n   * @param user the user.\n   * @param role the role.\n   * @param domain the domain.\n   * @return succeeds or not.\n   */\n  public async deleteRoleForUserInDomain(user: string, role: string, domain?: string): Promise<boolean> {\n    return this.deleteRoleForUser(user, role, domain);\n  }\n\n  /**\n   * deleteRolesForUser deletes all roles for a user.\n   * Returns false if the user does not have any roles (aka not affected).\n   *\n   * @param user the user.\n   * @param domain the domain.\n   * @return succeeds or not.\n   */\n  public async deleteRolesForUser(user: string, domain?: string): Promise<boolean> {\n    if (domain === undefined) {\n      return this.removeFilteredGroupingPolicy(0, user);\n    } else {\n      return this.removeFilteredGroupingPolicy(0, user, '', domain);\n    }\n  }\n\n  /**\n   * deleteRolesForUserInDomain deletes all roles for a user.\n   * Returns false if the user does not have any roles (aka not affected).\n   *\n   * @param user the user.\n   * @param domain the domain.\n   * @return succeeds or not.\n   */\n  public async deleteRolesForUserInDomain(user: string, domain?: string): Promise<boolean> {\n    return this.deleteRolesForUser(user, domain);\n  }\n\n  /**\n   * deleteUser deletes a user.\n   * Returns false if the user does not exist (aka not affected).\n   *\n   * @param user the user.\n   * @return succeeds or not.\n   */\n  public async deleteUser(user: string): Promise<boolean> {\n    const res1 = await this.removeFilteredGroupingPolicy(0, user);\n    const res2 = await this.removeFilteredPolicy(0, user);\n    return res1 || res2;\n  }\n\n  /**\n   * deleteRole deletes a role.\n   * Returns false if the role does not exist (aka not affected).\n   *\n   * @param role the role.\n   * @return succeeds or not.\n   */\n  public async deleteRole(role: string): Promise<boolean> {\n    const res1 = await this.removeFilteredGroupingPolicy(1, role);\n    const res2 = await this.removeFilteredPolicy(0, role);\n    return res1 || res2;\n  }\n\n  /**\n   * deletePermission deletes a permission.\n   * Returns false if the permission does not exist (aka not affected).\n   *\n   * @param permission the permission, usually be (obj, act). It is actually the rule without the subject.\n   * @return succeeds or not.\n   */\n  public async deletePermission(...permission: string[]): Promise<boolean> {\n    return this.removeFilteredPolicy(1, ...permission);\n  }\n\n  /**\n   * addPermissionForUser adds a permission for a user or role.\n   * Returns false if the user or role already has the permission (aka not affected).\n   *\n   * @param user the user.\n   * @param permission the permission, usually be (obj, act). It is actually the rule without the subject.\n   * @return succeeds or not.\n   */\n  public async addPermissionForUser(user: string, ...permission: string[]): Promise<boolean> {\n    permission.unshift(user);\n    return this.addPolicy(...permission);\n  }\n\n  /**\n   * deletePermissionForUser deletes a permission for a user or role.\n   * Returns false if the user or role does not have the permission (aka not affected).\n   *\n   * @param user the user.\n   * @param permission the permission, usually be (obj, act). It is actually the rule without the subject.\n   * @return succeeds or not.\n   */\n  public async deletePermissionForUser(user: string, ...permission: string[]): Promise<boolean> {\n    permission.unshift(user);\n    return this.removePolicy(...permission);\n  }\n\n  /**\n   * deletePermissionsForUser deletes permissions for a user or role.\n   * Returns false if the user or role does not have any permissions (aka not affected).\n   *\n   * @param user the user.\n   * @return succeeds or not.\n   */\n  public async deletePermissionsForUser(user: string): Promise<boolean> {\n    return this.removeFilteredPolicy(0, user);\n  }\n\n  /**\n   * getPermissionsForUser gets permissions for a user or role.\n   *\n   * @param user the user.\n   * @return the permissions, a permission is usually like (obj, act). It is actually the rule without the subject.\n   */\n  public async getPermissionsForUser(user: string): Promise<string[][]> {\n    return this.getFilteredPolicy(0, user);\n  }\n\n  /**\n   * hasPermissionForUser determines whether a user has a permission.\n   *\n   * @param user the user.\n   * @param permission the permission, usually be (obj, act). It is actually the rule without the subject.\n   * @return whether the user has the permission.\n   */\n  public async hasPermissionForUser(user: string, ...permission: string[]): Promise<boolean> {\n    permission.unshift(user);\n    return this.hasPolicy(...permission);\n  }\n\n  /**\n   * getImplicitRolesForUser gets implicit roles that a user has.\n   * Compared to getRolesForUser(), this function retrieves indirect roles besides direct roles.\n   * For example:\n   * g, alice, role:admin\n   * g, role:admin, role:user\n   *\n   * getRolesForUser(\"alice\") can only get: [\"role:admin\"].\n   * But getImplicitRolesForUser(\"alice\") will get: [\"role:admin\", \"role:user\"].\n   */\n  public async getImplicitRolesForUser(name: string, ...domain: string[]): Promise<string[]> {\n    const res = new Set<string>();\n    const q = [name];\n    let n: string | undefined;\n    while ((n = q.shift()) !== undefined) {\n      for (const rm of this.rmMap.values()) {\n        const role = await rm.getRoles(n, ...domain);\n        role.forEach((r) => {\n          if (!res.has(r)) {\n            res.add(r);\n            q.push(r);\n          }\n        });\n      }\n    }\n\n    return Array.from(res);\n  }\n\n  /**\n   * getImplicitPermissionsForUser gets implicit permissions for a user or role.\n   * Compared to getPermissionsForUser(), this function retrieves permissions for inherited roles.\n   * For example:\n   * p, admin, data1, read\n   * p, alice, data2, read\n   * g, alice, admin\n   *\n   * getPermissionsForUser(\"alice\") can only get: [[\"alice\", \"data2\", \"read\"]].\n   * But getImplicitPermissionsForUser(\"alice\") will get: [[\"admin\", \"data1\", \"read\"], [\"alice\", \"data2\", \"read\"]].\n   */\n  public async getImplicitPermissionsForUser(user: string, ...domain: string[]): Promise<string[][]> {\n    const roles = await this.getImplicitRolesForUser(user, ...domain);\n    roles.unshift(user);\n    const res: string[][] = [];\n    const withDomain = domain && domain.length !== 0;\n\n    for (const n of roles) {\n      if (withDomain) {\n        const p = await this.getFilteredPolicy(0, n, ...domain);\n        res.push(...p);\n      } else {\n        const p = await this.getPermissionsForUser(n);\n        res.push(...p);\n      }\n    }\n\n    return res;\n  }\n\n  /**\n   * getPermissionsForUserInDomain gets implicit permissions for a user or role.\n   * Compared to getPermissionsForUser(), this function retrieves permissions for inherited roles.\n   */\n\n  public async getPermissionsForUserInDomain(user: string, domain: string): Promise<string[][]> {\n    const res = await this.getImplicitPermissionsForUser(user, domain);\n    return res;\n  }\n\n  /**\n   * getImplicitUsersForRole gets implicit users that a role has.\n   * Compared to getUsersForRole(), this function retrieves indirect users besides direct users.\n   * For example:\n   * g, alice, role:admin\n   * g, role:admin, role:user\n   *\n   * getUsersForRole(\"user\") can only get: [\"role:admin\"].\n   * But getImplicitUsersForRole(\"user\") will get: [\"role:admin\", \"alice\"].\n   */\n  public async getImplicitUsersForRole(role: string, ...domain: string[]): Promise<string[]> {\n    const res = new Set<string>();\n    const q = [role];\n    let n: string | undefined;\n    while ((n = q.shift()) !== undefined) {\n      for (const rm of this.rmMap.values()) {\n        const user = await rm.getUsers(n, ...domain);\n        user.forEach((u) => {\n          if (!res.has(u)) {\n            res.add(u);\n            q.push(u);\n          }\n        });\n      }\n    }\n\n    return Array.from(res);\n  }\n\n  /**\n   * getRolesForUserInDomain gets the roles that a user has inside a domain\n   * An alias for getRolesForUser with the domain params.\n   *\n   * @param name the user.\n   * @param domain the domain.\n   * @return the roles that the user has.\n   */\n  public async getRolesForUserInDomain(name: string, domain: string): Promise<string[]> {\n    return this.getRolesForUser(name, domain);\n  }\n\n  /**\n   * getUsersForRoleInFomain gets the users that has a role inside a domain\n   * An alias for getUsesForRole with the domain params.\n   *\n   * @param name the role.\n   * @param domain the domain.\n   * @return the users that has the role.\n   */\n  public async getUsersForRoleInDomain(name: string, domain: string): Promise<string[]> {\n    return this.getUsersForRole(name, domain);\n  }\n\n  /**\n   * getImplicitUsersForPermission gets implicit users for a permission.\n   * For example:\n   * p, admin, data1, read\n   * p, bob, data1, read\n   * g, alice, admin\n   *\n   * getImplicitUsersForPermission(\"data1\", \"read\") will get: [\"alice\", \"bob\"].\n   * Note: only users will be returned, roles (2nd arg in \"g\") will be excluded.\n   */\n  public async getImplicitUsersForPermission(...permission: string[]): Promise<string[]> {\n    const res: string[] = [];\n    const policySubjects = await this.getAllSubjects();\n    const subjects = arrayRemoveDuplicates([...policySubjects, ...this.model.getValuesForFieldInPolicyAllTypes('g', 0)]);\n    const inherits = this.model.getValuesForFieldInPolicyAllTypes('g', 1);\n\n    for (const user of subjects) {\n      const allowed = await this.enforce(user, ...permission);\n      if (allowed) {\n        res.push(user);\n      }\n    }\n\n    return res.filter((n) => !inherits.some((m) => n === m));\n  }\n}\n\nexport async function newEnforcerWithClass<T extends Enforcer>(\n  enforcer: new () => T,\n  model?: Model,\n  adapter: Adapter = new MemoryAdapter([]),\n  enableLog = false\n): Promise<T> {\n  const e = new enforcer();\n\n  if (enableLog) {\n    getLogger().enableLog(enableLog);\n  }\n\n  if (model) {\n    await e.initWithModelAndAdapter(model, adapter);\n  }\n\n  return e;\n}\n\n/**\n * newEnforcer creates an enforcer via Model and Adapter.\n *\n * @example\n * const m = new Model(`\n * [request_definition]\n * r = sub, obj, act\n *\n * [policy_definition]\n * p = sub, obj, act\n *\n * [policy_effect]\n * e = some(where (p.eft == allow))\n *\n * [matchers]\n * m = r.sub == p.sub && r.obj == p.obj && r.act == p.act`)\n * `)\n *\n * const a = new MemoryAdapter(`\n * p, alice, data1, read\n * p, bob, data2, write\n * `)\n * const e = await newEnforcer(m, a, true)\n *\n * @param model the Model instance\n * @param adapter the Adapter instance\n * @param enableLog whether to enable the logging\n */\nexport async function newEnforcer(model?: Model, adapter: Adapter = new MemoryAdapter([]), enableLog = false): Promise<Enforcer> {\n  return newEnforcerWithClass(Enforcer, model, adapter, enableLog);\n}\n","// Copyright 2018 The Casbin Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { compile, compileAsync, addBinaryOp } from 'expression-eval';\n\nimport { DefaultEffector, Effect, Effector } from './effect';\nimport { FunctionMap, Model, PolicyOp } from './model';\nimport { Adapter, FilteredAdapter, Watcher } from './persist';\nimport { DefaultRoleManager, RoleManager } from './rbac';\nimport { EnforceContext } from './enforceContext';\n\nimport {\n  escapeAssertion,\n  generateGFunction,\n  getEvalValue,\n  hasEval,\n  replaceEval,\n  generatorRunSync,\n  generatorRunAsync,\n  customIn,\n  bracketCompatible,\n} from './util';\nimport { getLogger, logPrint } from './log';\nimport { MatchingFunc } from './rbac';\n\ntype Matcher = ((context: any) => Promise<any>) | ((context: any) => any);\n\ntype EnforceResult = Generator<(boolean | [boolean, string[]]) | Promise<boolean | [boolean, string[]]>>;\n\n/**\n * CoreEnforcer defines the core functionality of an enforcer.\n */\nexport class CoreEnforcer {\n  protected model: Model;\n  protected fm: FunctionMap = FunctionMap.loadFunctionMap();\n  protected eft: Effector = new DefaultEffector();\n  private matcherMap: Map<string, Matcher> = new Map();\n  private defaultEnforceContext: EnforceContext = new EnforceContext('r', 'p', 'e', 'm');\n\n  protected adapter: Adapter;\n  protected watcher: Watcher | null = null;\n  protected rmMap: Map<string, RoleManager>;\n\n  protected enabled = true;\n  protected autoSave = true;\n  protected autoBuildRoleLinks = true;\n  protected autoNotifyWatcher = true;\n\n  private getExpression(asyncCompile: boolean, exp: string): Matcher {\n    const matcherKey = `${asyncCompile ? 'ASYNC[' : 'SYNC['}${exp}]`;\n\n    addBinaryOp('in', 1, customIn);\n\n    let expression = this.matcherMap.get(matcherKey);\n    if (!expression) {\n      exp = bracketCompatible(exp);\n      expression = asyncCompile ? compileAsync(exp) : compile(exp);\n      this.matcherMap.set(matcherKey, expression);\n    }\n    return expression;\n  }\n\n  /**\n   * getModel gets the current model.\n   *\n   * @return the model of the enforcer.\n   */\n  public getModel(): Model {\n    return this.model;\n  }\n\n  /**\n   * setModel sets the current model.\n   *\n   * @param m the model.\n   */\n  public setModel(m: Model): void {\n    this.model = m;\n  }\n\n  /**\n   * getAdapter gets the current adapter.\n   *\n   * @return the adapter of the enforcer.\n   */\n  public getAdapter(): Adapter {\n    return this.adapter;\n  }\n\n  /**\n   * setAdapter sets the current adapter.\n   *\n   * @param adapter the adapter.\n   */\n  public setAdapter(adapter: Adapter): void {\n    this.adapter = adapter;\n  }\n\n  /**\n   * setWatcher sets the current watcher.\n   *\n   * @param watcher the watcher.\n   */\n  public setWatcher(watcher: Watcher): void {\n    this.watcher = watcher;\n    watcher.setUpdateCallback(async () => await this.loadPolicy());\n  }\n\n  /**\n   * setRoleManager sets the current role manager.\n   *\n   * @param rm the role manager.\n   */\n  public setRoleManager(rm: RoleManager): void {\n    this.rmMap.set('g', rm);\n  }\n\n  /**\n   * getRoleManager gets the current role manager.\n   */\n  public getRoleManager(): RoleManager {\n    return <RoleManager>this.rmMap.get('g');\n  }\n\n  /**\n   * getNamedRoleManager gets role manager by name.\n   */\n  public getNamedRoleManager(name: string): RoleManager | undefined {\n    return this.rmMap.get(name);\n  }\n\n  /**\n   * setEffector sets the current effector.\n   *\n   * @param eft the effector.\n   */\n  public setEffector(eft: Effector): void {\n    this.eft = eft;\n  }\n\n  /**\n   * clearPolicy clears all policy.\n   */\n  public clearPolicy(): void {\n    this.model.clearPolicy();\n  }\n\n  public initRmMap(): void {\n    this.rmMap = new Map<string, RoleManager>();\n    const rm = this.model.model.get('g');\n    if (rm) {\n      for (const ptype of rm.keys()) {\n        this.rmMap.set(ptype, new DefaultRoleManager(10));\n      }\n    }\n  }\n\n  public sortPolicies(): void {\n    const policy = this.model.model.get('p')?.get('p')?.policy;\n    const tokens = this.model.model.get('p')?.get('p')?.tokens;\n\n    if (policy && tokens) {\n      const priorityIndex = tokens.indexOf('p_priority');\n      if (priorityIndex !== -1) {\n        policy.sort((a, b) => {\n          return parseInt(a[priorityIndex], 10) - parseInt(b[priorityIndex], 10);\n        });\n      }\n    }\n  }\n\n  /**\n   * loadPolicy reloads the policy from adapter.\n   */\n  public async loadPolicy(): Promise<void> {\n    this.initRmMap();\n    this.model.clearPolicy();\n    await this.adapter.loadPolicy(this.model);\n\n    this.sortPolicies();\n\n    if (this.autoBuildRoleLinks) {\n      await this.buildRoleLinksInternal();\n    }\n  }\n\n  /**\n   * loadFilteredPolicy reloads a filtered policy from adapter.\n   *\n   * @param filter the filter used to specify which type of policy should be loaded.\n   */\n  // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\n  public async loadFilteredPolicy(filter: any): Promise<boolean> {\n    this.model.clearPolicy();\n\n    return this.loadIncrementalFilteredPolicy(filter);\n  }\n\n  /**\n   * LoadIncrementalFilteredPolicy append a filtered policy from adapter.\n   *\n   * @param filter the filter used to specify which type of policy should be appended.\n   */\n  // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\n  public async loadIncrementalFilteredPolicy(filter: any): Promise<boolean> {\n    if ('isFiltered' in this.adapter) {\n      await (this.adapter as FilteredAdapter).loadFilteredPolicy(this.model, filter);\n    } else {\n      throw new Error('filtered policies are not supported by this adapter');\n    }\n\n    this.sortPolicies();\n\n    if (this.autoBuildRoleLinks) {\n      await this.buildRoleLinksInternal();\n    }\n    return true;\n  }\n\n  /**\n   * isFiltered returns true if the loaded policy has been filtered.\n   *\n   * @return if the loaded policy has been filtered.\n   */\n  public isFiltered(): boolean {\n    if ('isFiltered' in this.adapter) {\n      return (this.adapter as FilteredAdapter).isFiltered();\n    }\n    return false;\n  }\n\n  /**\n   * savePolicy saves the current policy (usually after changed with\n   * Casbin API) back to adapter.\n   */\n  public async savePolicy(): Promise<boolean> {\n    if (this.isFiltered()) {\n      throw new Error('Cannot save a filtered policy');\n    }\n    const flag = await this.adapter.savePolicy(this.model);\n    if (!flag) {\n      return false;\n    }\n    if (this.watcher) {\n      return await this.watcher.update();\n    }\n    return true;\n  }\n\n  /**\n   * enableEnforce changes the enforcing state of Casbin, when Casbin is\n   * disabled, all access will be allowed by the enforce() function.\n   *\n   * @param enable whether to enable the enforcer.\n   */\n  public enableEnforce(enable: boolean): void {\n    this.enabled = enable;\n  }\n\n  /**\n   * enableLog changes whether to print Casbin log to the standard output.\n   *\n   * @param enable whether to enable Casbin's log.\n   */\n  public enableLog(enable: boolean): void {\n    getLogger().enableLog(enable);\n  }\n\n  /**\n   * enableAutoSave controls whether to save a policy rule automatically to\n   * the adapter when it is added or removed.\n   *\n   * @param autoSave whether to enable the AutoSave feature.\n   */\n  public enableAutoSave(autoSave: boolean): void {\n    this.autoSave = autoSave;\n  }\n\n  /**\n   * enableAutoNotifyWatcher controls whether to save a policy rule automatically notify the Watcher when it is added or removed.\n   * @param enable whether to enable the AutoNotifyWatcher feature.\n   */\n  public enableAutoNotifyWatcher(enable: boolean): void {\n    this.autoNotifyWatcher = enable;\n  }\n\n  /**\n   * enableAutoBuildRoleLinks controls whether to save a policy rule\n   * automatically to the adapter when it is added or removed.\n   *\n   * @param autoBuildRoleLinks whether to automatically build the role links.\n   */\n  public enableAutoBuildRoleLinks(autoBuildRoleLinks: boolean): void {\n    this.autoBuildRoleLinks = autoBuildRoleLinks;\n  }\n\n  /**\n   * add matching function to RoleManager by ptype\n   * @param ptype g\n   * @param fn the function will be added\n   */\n  public async addNamedMatchingFunc(ptype: string, fn: MatchingFunc): Promise<void> {\n    const rm = this.rmMap.get(ptype);\n    if (rm) {\n      return await (<DefaultRoleManager>rm).addMatchingFunc(fn);\n    }\n\n    throw Error('Target ptype not found.');\n  }\n\n  /**\n   * add domain matching function to RoleManager by ptype\n   * @param ptype g\n   * @param fn the function will be added\n   */\n  public async addNamedDomainMatchingFunc(ptype: string, fn: MatchingFunc): Promise<void> {\n    const rm = this.rmMap.get(ptype);\n    if (rm) {\n      return await (<DefaultRoleManager>rm).addDomainMatchingFunc(fn);\n    }\n  }\n\n  /**\n   * buildRoleLinks manually rebuild the role inheritance relations.\n   */\n  public async buildRoleLinks(): Promise<void> {\n    return this.buildRoleLinksInternal();\n  }\n\n  /**\n   * buildIncrementalRoleLinks provides incremental build the role inheritance relations.\n   * @param op policy operation\n   * @param ptype g\n   * @param rules policies\n   */\n  public async buildIncrementalRoleLinks(op: PolicyOp, ptype: string, rules: string[][]): Promise<void> {\n    let rm = this.rmMap.get(ptype);\n    if (!rm) {\n      rm = new DefaultRoleManager(10);\n      this.rmMap.set(ptype, rm);\n    }\n    await this.model.buildIncrementalRoleLinks(rm, op, 'g', ptype, rules);\n  }\n\n  protected async buildRoleLinksInternal(): Promise<void> {\n    for (const rm of this.rmMap.values()) {\n      await rm.clear();\n      await this.model.buildRoleLinks(this.rmMap);\n    }\n  }\n\n  private *privateEnforce(\n    asyncCompile = true,\n    explain = false,\n    enforceContext: EnforceContext = new EnforceContext('r', 'p', 'e', 'm'),\n    ...rvals: any[]\n  ): EnforceResult {\n    if (!this.enabled) {\n      return true;\n    }\n\n    let explainIndex = -1;\n\n    const functions: { [key: string]: any } = {};\n    this.fm.getFunctions().forEach((value: any, key: string) => {\n      functions[key] = value;\n    });\n\n    const astMap = this.model.model.get('g');\n\n    astMap?.forEach((value, key) => {\n      const rm = value.rm;\n      functions[key] = generateGFunction(rm);\n    });\n\n    const expString = this.model.model.get('m')?.get(enforceContext.mType)?.value;\n    if (!expString) {\n      throw new Error('Unable to find matchers in model');\n    }\n\n    const effectExpr = this.model.model.get('e')?.get(enforceContext.eType)?.value;\n    if (!effectExpr) {\n      throw new Error('Unable to find policy_effect in model');\n    }\n\n    const HasEval: boolean = hasEval(expString);\n    let expression: Matcher | undefined = undefined;\n\n    const p = this.model.model.get('p')?.get(enforceContext.pType);\n    const policyLen = p?.policy?.length;\n\n    const rTokens = this.model.model.get('r')?.get(enforceContext.rType)?.tokens;\n    const rTokensLen = rTokens?.length;\n\n    const effectStream = this.eft.newStream(effectExpr);\n\n    if (policyLen && policyLen !== 0) {\n      for (let i = 0; i < policyLen; i++) {\n        const parameters: { [key: string]: any } = {};\n\n        if (rTokens?.length !== rvals.length) {\n          throw new Error(`invalid request size: expected ${rTokensLen}, got ${rvals.length}, rvals: ${rvals}\"`);\n        }\n\n        rTokens.forEach((token, j) => {\n          parameters[token] = rvals[j];\n        });\n\n        p?.tokens.forEach((token, j) => {\n          parameters[token] = p?.policy[i][j];\n        });\n\n        if (HasEval) {\n          const ruleNames: string[] = getEvalValue(expString);\n          let expWithRule = expString;\n          for (const ruleName of ruleNames) {\n            if (ruleName in parameters) {\n              const rule = escapeAssertion(parameters[ruleName]);\n              expWithRule = replaceEval(expWithRule, ruleName, rule);\n            } else {\n              throw new Error(`${ruleName} not in ${parameters}`);\n            }\n          }\n          expression = this.getExpression(asyncCompile, expWithRule);\n        } else {\n          if (expression === undefined) {\n            expression = this.getExpression(asyncCompile, expString);\n          }\n        }\n\n        const context = { ...parameters, ...functions };\n        const result = asyncCompile ? yield expression(context) : expression(context);\n\n        let eftRes: Effect;\n        switch (typeof result) {\n          case 'boolean':\n            eftRes = result ? Effect.Allow : Effect.Indeterminate;\n            break;\n          case 'number':\n            if (result === 0) {\n              eftRes = Effect.Indeterminate;\n            } else {\n              eftRes = result;\n            }\n            break;\n          case 'string':\n            if (result === '') {\n              eftRes = Effect.Indeterminate;\n            } else {\n              eftRes = Effect.Allow;\n            }\n            break;\n          default:\n            throw new Error('matcher result should only be of type boolean, number, or string');\n        }\n\n        const eft = parameters['p_eft'];\n        if (eft && eftRes === Effect.Allow) {\n          if (eft === 'allow') {\n            eftRes = Effect.Allow;\n          } else if (eft === 'deny') {\n            eftRes = Effect.Deny;\n          } else {\n            eftRes = Effect.Indeterminate;\n          }\n        }\n\n        const [res, rec, done] = effectStream.pushEffect(eftRes);\n\n        if (rec) {\n          explainIndex = i;\n        }\n\n        if (done) {\n          break;\n        }\n      }\n    } else {\n      explainIndex = 0;\n\n      const parameters: { [key: string]: any } = {};\n\n      rTokens?.forEach((token, j): void => {\n        parameters[token] = rvals[j];\n      });\n\n      p?.tokens?.forEach((token) => {\n        parameters[token] = '';\n      });\n\n      expression = this.getExpression(asyncCompile, expString);\n      const context = { ...parameters, ...functions };\n      const result = asyncCompile ? yield expression(context) : expression(context);\n\n      if (result) {\n        effectStream.pushEffect(Effect.Allow);\n      } else {\n        effectStream.pushEffect(Effect.Indeterminate);\n      }\n    }\n\n    const res = effectStream.current();\n\n    // only generate the request --> result string if the message\n    // is going to be logged.\n    if (getLogger().isEnable()) {\n      let reqStr = 'Request: ';\n      for (let i = 0; i < rvals.length; i++) {\n        if (i !== rvals.length - 1) {\n          reqStr += `${rvals[i]}, `;\n        } else {\n          reqStr += rvals[i];\n        }\n      }\n      reqStr += ` ---> ${res}`;\n      logPrint(reqStr);\n    }\n\n    if (explain) {\n      if (explainIndex === -1) {\n        return [res, []];\n      }\n      return [res, p?.policy[explainIndex]];\n    }\n\n    return res;\n  }\n\n  /**\n   * If the matchers does not contain an asynchronous method, call it faster.\n   *\n   * enforceSync decides whether a \"subject\" can access a \"object\" with\n   * the operation \"action\", input parameters are usually: (sub, obj, act).\n   *\n   * @param rvals the request needs to be mediated, usually an array\n   *              of strings, can be class instances if ABAC is used.\n   * @return whether to allow the request.\n   */\n  public enforceSync(...rvals: any[]): boolean {\n    if (rvals[0] instanceof EnforceContext) {\n      const enforceContext: EnforceContext = rvals.shift();\n      return generatorRunSync(this.privateEnforce(false, false, enforceContext, ...rvals));\n    }\n    return generatorRunSync(this.privateEnforce(false, false, this.defaultEnforceContext, ...rvals));\n  }\n\n  /**\n   * If the matchers does not contain an asynchronous method, call it faster.\n   *\n   * enforceSync decides whether a \"subject\" can access a \"object\" with\n   * the operation \"action\", input parameters are usually: (sub, obj, act).\n   *\n   * @param rvals the request needs to be mediated, usually an array\n   *              of strings, can be class instances if ABAC is used.\n   * @return whether to allow the request and the reason rule.\n   */\n  public enforceExSync(...rvals: any[]): [boolean, string[]] {\n    if (rvals[0] instanceof EnforceContext) {\n      const enforceContext: EnforceContext = rvals.shift();\n      return generatorRunSync(this.privateEnforce(false, true, enforceContext, ...rvals));\n    }\n    return generatorRunSync(this.privateEnforce(false, true, this.defaultEnforceContext, ...rvals));\n  }\n\n  /**\n   * Same as enforceSync. To be removed.\n   */\n  public enforceWithSyncCompile(...rvals: any[]): boolean {\n    return this.enforceSync(...rvals);\n  }\n\n  /**\n   * enforce decides whether a \"subject\" can access a \"object\" with\n   * the operation \"action\", input parameters are usually: (sub, obj, act).\n   *\n   * @param rvals the request needs to be mediated, usually an array\n   *              of strings, can be class instances if ABAC is used.\n   * @return whether to allow the request.\n   */\n  public async enforce(...rvals: any[]): Promise<boolean> {\n    if (rvals[0] instanceof EnforceContext) {\n      const enforceContext: EnforceContext = rvals.shift();\n      return generatorRunAsync(this.privateEnforce(true, false, enforceContext, ...rvals));\n    }\n    return generatorRunAsync(this.privateEnforce(true, false, this.defaultEnforceContext, ...rvals));\n  }\n\n  /**\n   * enforce decides whether a \"subject\" can access a \"object\" with\n   * the operation \"action\", input parameters are usually: (sub, obj, act).\n   *\n   * @param rvals the request needs to be mediated, usually an array\n   *              of strings, can be class instances if ABAC is used.\n   * @return whether to allow the request and the reason rule.\n   */\n  public async enforceEx(...rvals: any[]): Promise<[boolean, string[]]> {\n    if (rvals[0] instanceof EnforceContext) {\n      const enforceContext: EnforceContext = rvals.shift();\n      return generatorRunAsync(this.privateEnforce(true, true, enforceContext, ...rvals));\n    }\n    return generatorRunAsync(this.privateEnforce(true, true, this.defaultEnforceContext, ...rvals));\n  }\n\n  /**\n   * batchEnforce enforces each request and returns result in a bool array.\n   * @param rvals the request need to be mediated, usually an array\n   *              of array of strings, can be class instances if ABAC is used.\n   * @returns whether to allow the requests.\n   */\n  public async batchEnforce(rvals: any[]): Promise<boolean[]> {\n    return await Promise.all(rvals.map((rval) => this.enforce(...rval)));\n  }\n}\n","// Copyright 2018 The Casbin Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { CoreEnforcer } from './coreEnforcer';\nimport { BatchAdapter } from './persist';\nimport { UpdatableAdapter } from './persist';\nimport { PolicyOp } from './model';\n\n/**\n * InternalEnforcer = CoreEnforcer + Internal API.\n */\nexport class InternalEnforcer extends CoreEnforcer {\n  /**\n   * addPolicyInternal adds a rule to the current policy.\n   */\n  public async addPolicyInternal(sec: string, ptype: string, rule: string[]): Promise<boolean> {\n    if (this.model.hasPolicy(sec, ptype, rule)) {\n      return false;\n    }\n\n    if (this.adapter && this.autoSave) {\n      try {\n        await this.adapter.addPolicy(sec, ptype, rule);\n      } catch (e) {\n        if (e.message !== 'not implemented') {\n          throw e;\n        }\n      }\n    }\n\n    if (this.watcher && this.autoNotifyWatcher) {\n      // error intentionally ignored\n      this.watcher.update();\n    }\n\n    const ok = this.model.addPolicy(sec, ptype, rule);\n\n    if (sec === 'g' && ok) {\n      await this.buildIncrementalRoleLinks(PolicyOp.PolicyAdd, ptype, [rule]);\n    }\n    return ok;\n  }\n\n  // addPolicies adds rules to the current policy.\n  // removePolicies removes rules from the current policy.\n  public async addPoliciesInternal(sec: string, ptype: string, rules: string[][]): Promise<boolean> {\n    for (const rule of rules) {\n      if (this.model.hasPolicy(sec, ptype, rule)) {\n        return false;\n      }\n    }\n\n    if (this.autoSave) {\n      if ('addPolicies' in this.adapter) {\n        try {\n          await (this.adapter as BatchAdapter).addPolicies(sec, ptype, rules);\n        } catch (e) {\n          if (e.message !== 'not implemented') {\n            throw e;\n          }\n        }\n      } else {\n        throw new Error('cannot to save policy, the adapter does not implement the BatchAdapter');\n      }\n    }\n\n    if (this.watcher && this.autoNotifyWatcher) {\n      // error intentionally ignored\n      this.watcher.update();\n    }\n\n    const [ok, effects] = await this.model.addPolicies(sec, ptype, rules);\n    if (sec === 'g' && ok && effects?.length) {\n      await this.buildIncrementalRoleLinks(PolicyOp.PolicyAdd, ptype, effects);\n    }\n    return ok;\n  }\n\n  /**\n   * updatePolicyInternal updates a rule from the current policy.\n   */\n  public async updatePolicyInternal(sec: string, ptype: string, oldRule: string[], newRule: string[]): Promise<boolean> {\n    if (!this.model.hasPolicy(sec, ptype, oldRule)) {\n      return false;\n    }\n\n    if (this.autoSave) {\n      if ('updatePolicy' in this.adapter) {\n        try {\n          await (this.adapter as UpdatableAdapter).updatePolicy(sec, ptype, oldRule, newRule);\n        } catch (e) {\n          if (e.message !== 'not implemented') {\n            throw e;\n          }\n        }\n      } else {\n        throw new Error('cannot to update policy, the adapter does not implement the UpdatableAdapter');\n      }\n    }\n\n    if (this.watcher && this.autoNotifyWatcher) {\n      // In fact I think it should wait for the respond, but they implement add_policy() like this\n      // error intentionally ignored\n      this.watcher.update();\n    }\n\n    const ok = this.model.updatePolicy(sec, ptype, oldRule, newRule);\n    if (sec === 'g' && ok) {\n      await this.buildIncrementalRoleLinks(PolicyOp.PolicyRemove, ptype, [oldRule]);\n      await this.buildIncrementalRoleLinks(PolicyOp.PolicyAdd, ptype, [newRule]);\n    }\n\n    return ok;\n  }\n\n  /**\n   * removePolicyInternal removes a rule from the current policy.\n   */\n  public async removePolicyInternal(sec: string, ptype: string, rule: string[]): Promise<boolean> {\n    if (!this.model.hasPolicy(sec, ptype, rule)) {\n      return false;\n    }\n\n    if (this.adapter && this.autoSave) {\n      try {\n        await this.adapter.removePolicy(sec, ptype, rule);\n      } catch (e) {\n        if (e.message !== 'not implemented') {\n          throw e;\n        }\n      }\n    }\n\n    if (this.watcher && this.autoNotifyWatcher) {\n      // error intentionally ignored\n      this.watcher.update();\n    }\n\n    const ok = await this.model.removePolicy(sec, ptype, rule);\n    if (sec === 'g' && ok) {\n      await this.buildIncrementalRoleLinks(PolicyOp.PolicyRemove, ptype, [rule]);\n    }\n    return ok;\n  }\n\n  // removePolicies removes rules from the current policy.\n  public async removePoliciesInternal(sec: string, ptype: string, rules: string[][]): Promise<boolean> {\n    for (const rule of rules) {\n      if (!this.model.hasPolicy(sec, ptype, rule)) {\n        return false;\n      }\n    }\n\n    if (this.autoSave) {\n      if ('removePolicies' in this.adapter) {\n        try {\n          await (this.adapter as BatchAdapter).removePolicies(sec, ptype, rules);\n        } catch (e) {\n          if (e.message !== 'not implemented') {\n            throw e;\n          }\n        }\n      } else {\n        throw new Error('cannot to save policy, the adapter does not implement the BatchAdapter');\n      }\n    }\n\n    if (this.watcher && this.autoNotifyWatcher) {\n      // error intentionally ignored\n      this.watcher.update();\n    }\n\n    const [ok, effects] = this.model.removePolicies(sec, ptype, rules);\n    if (sec === 'g' && ok && effects?.length) {\n      await this.buildIncrementalRoleLinks(PolicyOp.PolicyRemove, ptype, effects);\n    }\n    return ok;\n  }\n\n  /**\n   * removeFilteredPolicyInternal removes rules based on field filters from the current policy.\n   */\n  public async removeFilteredPolicyInternal(sec: string, ptype: string, fieldIndex: number, fieldValues: string[]): Promise<boolean> {\n    if (this.adapter && this.autoSave) {\n      try {\n        await this.adapter.removeFilteredPolicy(sec, ptype, fieldIndex, ...fieldValues);\n      } catch (e) {\n        if (e.message !== 'not implemented') {\n          throw e;\n        }\n      }\n    }\n\n    if (this.watcher && this.autoNotifyWatcher) {\n      // error intentionally ignored\n      this.watcher.update();\n    }\n\n    const [ok, effects] = this.model.removeFilteredPolicy(sec, ptype, fieldIndex, ...fieldValues);\n    if (sec === 'g' && ok && effects?.length) {\n      await this.buildIncrementalRoleLinks(PolicyOp.PolicyRemove, ptype, effects);\n    }\n    return ok;\n  }\n}\n","// Copyright 2018 The Casbin Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { InternalEnforcer } from './internalEnforcer';\nimport { MatchingFunction } from './model';\n\n/**\n * ManagementEnforcer = InternalEnforcer + Management API.\n */\nexport class ManagementEnforcer extends InternalEnforcer {\n  /**\n   * getAllSubjects gets the list of subjects that show up in the current policy.\n   *\n   * @return all the subjects in \"p\" policy rules. It actually collects the\n   *         0-index elements of \"p\" policy rules. So make sure your subject\n   *         is the 0-index element, like (sub, obj, act). Duplicates are removed.\n   */\n  public async getAllSubjects(): Promise<string[]> {\n    return this.getAllNamedSubjects('p');\n  }\n\n  /**\n   * getAllNamedSubjects gets the list of subjects that show up in the currentnamed policy.\n   *\n   * @param ptype the policy type, can be \"p\", \"p2\", \"p3\", ..\n   * @return all the subjects in policy rules of the ptype type. It actually\n   *         collects the 0-index elements of the policy rules. So make sure\n   *         your subject is the 0-index element, like (sub, obj, act).\n   *         Duplicates are removed.\n   */\n  public async getAllNamedSubjects(ptype: string): Promise<string[]> {\n    return this.model.getValuesForFieldInPolicy('p', ptype, 0);\n  }\n\n  /**\n   * getAllObjects gets the list of objects that show up in the current policy.\n   *\n   * @return all the objects in \"p\" policy rules. It actually collects the\n   *         1-index elements of \"p\" policy rules. So make sure your object\n   *         is the 1-index element, like (sub, obj, act).\n   *         Duplicates are removed.\n   */\n  public async getAllObjects(): Promise<string[]> {\n    return this.getAllNamedObjects('p');\n  }\n\n  /**\n   * getAllNamedObjects gets the list of objects that show up in the current named policy.\n   *\n   * @param ptype the policy type, can be \"p\", \"p2\", \"p3\", ..\n   * @return all the objects in policy rules of the ptype type. It actually\n   *         collects the 1-index elements of the policy rules. So make sure\n   *         your object is the 1-index element, like (sub, obj, act).\n   *         Duplicates are removed.\n   */\n  public async getAllNamedObjects(ptype: string): Promise<string[]> {\n    return this.model.getValuesForFieldInPolicy('p', ptype, 1);\n  }\n\n  /**\n   * getAllActions gets the list of actions that show up in the current policy.\n   *\n   * @return all the actions in \"p\" policy rules. It actually collects\n   *         the 2-index elements of \"p\" policy rules. So make sure your action\n   *         is the 2-index element, like (sub, obj, act).\n   *         Duplicates are removed.\n   */\n  public async getAllActions(): Promise<string[]> {\n    return this.getAllNamedActions('p');\n  }\n\n  /**\n   * GetAllNamedActions gets the list of actions that show up in the current named policy.\n   *\n   * @param ptype the policy type, can be \"p\", \"p2\", \"p3\", ..\n   * @return all the actions in policy rules of the ptype type. It actually\n   *         collects the 2-index elements of the policy rules. So make sure\n   *         your action is the 2-index element, like (sub, obj, act).\n   *         Duplicates are removed.\n   */\n  public async getAllNamedActions(ptype: string): Promise<string[]> {\n    return this.model.getValuesForFieldInPolicy('p', ptype, 2);\n  }\n\n  /**\n   * getAllRoles gets the list of roles that show up in the current policy.\n   *\n   * @return all the roles in \"g\" policy rules. It actually collects\n   *         the 1-index elements of \"g\" policy rules. So make sure your\n   *         role is the 1-index element, like (sub, role).\n   *         Duplicates are removed.\n   */\n  public async getAllRoles(): Promise<string[]> {\n    return this.getAllNamedRoles('g');\n  }\n\n  /**\n   * getAllNamedRoles gets the list of roles that show up in the current named policy.\n   *\n   * @param ptype the policy type, can be \"g\", \"g2\", \"g3\", ..\n   * @return all the subjects in policy rules of the ptype type. It actually\n   *         collects the 0-index elements of the policy rules. So make\n   *         sure your subject is the 0-index element, like (sub, obj, act).\n   *         Duplicates are removed.\n   */\n  public async getAllNamedRoles(ptype: string): Promise<string[]> {\n    return this.model.getValuesForFieldInPolicy('g', ptype, 1);\n  }\n\n  /**\n   * getPolicy gets all the authorization rules in the policy.\n   *\n   * @return all the \"p\" policy rules.\n   */\n  public async getPolicy(): Promise<string[][]> {\n    return this.getNamedPolicy('p');\n  }\n\n  /**\n   * getFilteredPolicy gets all the authorization rules in the policy, field filters can be specified.\n   *\n   * @param fieldIndex the policy rule's start index to be matched.\n   * @param fieldValues the field values to be matched, value \"\"\n   *                    means not to match this field.\n   * @return the filtered \"p\" policy rules.\n   */\n  public async getFilteredPolicy(fieldIndex: number, ...fieldValues: string[]): Promise<string[][]> {\n    return this.getFilteredNamedPolicy('p', fieldIndex, ...fieldValues);\n  }\n\n  /**\n   * getNamedPolicy gets all the authorization rules in the named policy.\n   *\n   * @param ptype the policy type, can be \"p\", \"p2\", \"p3\", ..\n   * @return the \"p\" policy rules of the specified ptype.\n   */\n  public async getNamedPolicy(ptype: string): Promise<string[][]> {\n    return this.model.getPolicy('p', ptype);\n  }\n\n  /**\n   * getFilteredNamedPolicy gets all the authorization rules in the named policy, field filters can be specified.\n   *\n   * @param ptype the policy type, can be \"p\", \"p2\", \"p3\", ..\n   * @param fieldIndex the policy rule's start index to be matched.\n   * @param fieldValues the field values to be matched, value \"\"\n   *                    means not to match this field.\n   * @return the filtered \"p\" policy rules of the specified ptype.\n   */\n  public async getFilteredNamedPolicy(ptype: string, fieldIndex: number, ...fieldValues: string[]): Promise<string[][]> {\n    return this.model.getFilteredPolicy('p', ptype, fieldIndex, ...fieldValues);\n  }\n\n  /**\n   * getGroupingPolicy gets all the role inheritance rules in the policy.\n   *\n   * @return all the \"g\" policy rules.\n   */\n  public async getGroupingPolicy(): Promise<string[][]> {\n    return this.getNamedGroupingPolicy('g');\n  }\n\n  /**\n   * getFilteredGroupingPolicy gets all the role inheritance rules in the policy, field filters can be specified.\n   *\n   * @param fieldIndex the policy rule's start index to be matched.\n   * @param fieldValues the field values to be matched, value \"\" means not to match this field.\n   * @return the filtered \"g\" policy rules.\n   */\n  public async getFilteredGroupingPolicy(fieldIndex: number, ...fieldValues: string[]): Promise<string[][]> {\n    return this.getFilteredNamedGroupingPolicy('g', fieldIndex, ...fieldValues);\n  }\n\n  /**\n   * getNamedGroupingPolicy gets all the role inheritance rules in the policy.\n   *\n   * @param ptype the policy type, can be \"g\", \"g2\", \"g3\", ..\n   * @return the \"g\" policy rules of the specified ptype.\n   */\n  public async getNamedGroupingPolicy(ptype: string): Promise<string[][]> {\n    return this.model.getPolicy('g', ptype);\n  }\n\n  /**\n   * getFilteredNamedGroupingPolicy gets all the role inheritance rules in the policy, field filters can be specified.\n   *\n   * @param ptype the policy type, can be \"g\", \"g2\", \"g3\", ..\n   * @param fieldIndex the policy rule's start index to be matched.\n   * @param fieldValues the field values to be matched, value \"\"\n   *                    means not to match this field.\n   * @return the filtered \"g\" policy rules of the specified ptype.\n   */\n  public async getFilteredNamedGroupingPolicy(ptype: string, fieldIndex: number, ...fieldValues: string[]): Promise<string[][]> {\n    return this.model.getFilteredPolicy('g', ptype, fieldIndex, ...fieldValues);\n  }\n\n  /**\n   * hasPolicy determines whether an authorization rule exists.\n   *\n   * @param params the \"p\" policy rule, ptype \"p\" is implicitly used.\n   * @return whether the rule exists.\n   */\n  public async hasPolicy(...params: string[]): Promise<boolean> {\n    return this.hasNamedPolicy('p', ...params);\n  }\n\n  /**\n   * hasNamedPolicy determines whether a named authorization rule exists.\n   *\n   * @param ptype the policy type, can be \"p\", \"p2\", \"p3\", ..\n   * @param params the \"p\" policy rule.\n   * @return whether the rule exists.\n   */\n  public async hasNamedPolicy(ptype: string, ...params: string[]): Promise<boolean> {\n    return this.model.hasPolicy('p', ptype, params);\n  }\n\n  /**\n   * addPolicy adds an authorization rule to the current policy.\n   * If the rule already exists, the function returns false and the rule will not be added.\n   * Otherwise the function returns true by adding the new rule.\n   *\n   * @param params the \"p\" policy rule, ptype \"p\" is implicitly used.\n   * @return succeeds or not.\n   */\n  public async addPolicy(...params: string[]): Promise<boolean> {\n    return this.addNamedPolicy('p', ...params);\n  }\n\n  /**\n   * addPolicies adds authorization rules to the current policy.\n   * If the rule already exists, the function returns false and the rules will not be added.\n   * Otherwise the function returns true by adding the new rules.\n   *\n   * @param rules the \"p\" policy rules, ptype \"p\" is implicitly used.\n   * @return succeeds or not.\n   */\n  public async addPolicies(rules: string[][]): Promise<boolean> {\n    return this.addNamedPolicies('p', rules);\n  }\n\n  /**\n   * addNamedPolicy adds an authorization rule to the current named policy.\n   * If the rule already exists, the function returns false and the rule will not be added.\n   * Otherwise the function returns true by adding the new rule.\n   *\n   * @param ptype the policy type, can be \"p\", \"p2\", \"p3\", ..\n   * @param params the \"p\" policy rule.\n   * @return succeeds or not.\n   */\n  public async addNamedPolicy(ptype: string, ...params: string[]): Promise<boolean> {\n    return this.addPolicyInternal('p', ptype, params);\n  }\n\n  /**\n   * addNamedPolicies adds authorization rules to the current named policy.\n   * If the rule already exists, the function returns false and the rules will not be added.\n   * Otherwise the function returns true by adding the new rules.\n   *\n   * @param ptype the policy type, can be \"p\", \"p2\", \"p3\", ..\n   * @param rules the \"p\" policy rules.\n   * @return succeeds or not.\n   */\n  public async addNamedPolicies(ptype: string, rules: string[][]): Promise<boolean> {\n    return this.addPoliciesInternal('p', ptype, rules);\n  }\n\n  /**\n   * updatePolicy updates an authorization rule from the current policy.\n   * If the rule not exists, the function returns false.\n   * Otherwise the function returns true by changing it to the new rule.\n   *\n   * @return succeeds or not.\n   * @param oldRule the policy will be remove\n   * @param newRule the policy will be added\n   */\n  public async updatePolicy(oldRule: string[], newRule: string[]): Promise<boolean> {\n    return this.updateNamedPolicy('p', oldRule, newRule);\n  }\n\n  /**\n   * updateNamedPolicy updates an authorization rule from the current named policy.\n   * If the rule not exists, the function returns false.\n   * Otherwise the function returns true by changing it to the new rule.\n   *\n   * @param ptype the policy type, can be \"p\", \"p2\", \"p3\", ..\n   * @param oldRule the policy rule will be remove\n   * @param newRule the policy rule will be added\n   * @return succeeds or not.\n   */\n  public async updateNamedPolicy(ptype: string, oldRule: string[], newRule: string[]): Promise<boolean> {\n    return this.updatePolicyInternal('p', ptype, oldRule, newRule);\n  }\n\n  /**\n   * removePolicy removes an authorization rule from the current policy.\n   *\n   * @param params the \"p\" policy rule, ptype \"p\" is implicitly used.\n   * @return succeeds or not.\n   */\n  public async removePolicy(...params: string[]): Promise<boolean> {\n    return this.removeNamedPolicy('p', ...params);\n  }\n\n  /**\n   * removePolicies removes an authorization rules from the current policy.\n   *\n   * @param rules the \"p\" policy rules, ptype \"p\" is implicitly used.\n   * @return succeeds or not.\n   */\n  public async removePolicies(rules: string[][]): Promise<boolean> {\n    return this.removeNamedPolicies('p', rules);\n  }\n\n  /**\n   * removeFilteredPolicy removes an authorization rule from the current policy, field filters can be specified.\n   *\n   * @param fieldIndex the policy rule's start index to be matched.\n   * @param fieldValues the field values to be matched, value \"\"\n   *                    means not to match this field.\n   * @return succeeds or not.\n   */\n  public async removeFilteredPolicy(fieldIndex: number, ...fieldValues: string[]): Promise<boolean> {\n    return this.removeFilteredNamedPolicy('p', fieldIndex, ...fieldValues);\n  }\n\n  /**\n   * removeNamedPolicy removes an authorization rule from the current named policy.\n   *\n   * @param ptype the policy type, can be \"p\", \"p2\", \"p3\", ..\n   * @param params the \"p\" policy rule.\n   * @return succeeds or not.\n   */\n  public async removeNamedPolicy(ptype: string, ...params: string[]): Promise<boolean> {\n    return this.removePolicyInternal('p', ptype, params);\n  }\n\n  /**\n   * removeNamedPolicies removes authorization rules from the current named policy.\n   *\n   * @param ptype the policy type, can be \"p\", \"p2\", \"p3\", ..\n   * @param rules the \"p\" policy rules.\n   * @return succeeds or not.\n   */\n  public async removeNamedPolicies(ptype: string, rules: string[][]): Promise<boolean> {\n    return this.removePoliciesInternal('p', ptype, rules);\n  }\n\n  /**\n   * removeFilteredNamedPolicy removes an authorization rule from the current named policy, field filters can be specified.\n   *\n   * @param ptype the policy type, can be \"p\", \"p2\", \"p3\", ..\n   * @param fieldIndex the policy rule's start index to be matched.\n   * @param fieldValues the field values to be matched, value \"\"\n   *                    means not to match this field.\n   * @return succeeds or not.\n   */\n  public async removeFilteredNamedPolicy(ptype: string, fieldIndex: number, ...fieldValues: string[]): Promise<boolean> {\n    return this.removeFilteredPolicyInternal('p', ptype, fieldIndex, fieldValues);\n  }\n\n  /**\n   * hasGroupingPolicy determines whether a role inheritance rule exists.\n   *\n   * @param params the \"g\" policy rule, ptype \"g\" is implicitly used.\n   * @return whether the rule exists.\n   */\n  public async hasGroupingPolicy(...params: string[]): Promise<boolean> {\n    return this.hasNamedGroupingPolicy('g', ...params);\n  }\n\n  /**\n   * hasNamedGroupingPolicy determines whether a named role inheritance rule exists.\n   *\n   * @param ptype the policy type, can be \"g\", \"g2\", \"g3\", ..\n   * @param params the \"g\" policy rule.\n   * @return whether the rule exists.\n   */\n  public async hasNamedGroupingPolicy(ptype: string, ...params: string[]): Promise<boolean> {\n    return this.model.hasPolicy('g', ptype, params);\n  }\n\n  /**\n   * addGroupingPolicy adds a role inheritance rule to the current policy.\n   * If the rule already exists, the function returns false and the rule will not be added.\n   * Otherwise the function returns true by adding the new rule.\n   *\n   * @param params the \"g\" policy rule, ptype \"g\" is implicitly used.\n   * @return succeeds or not.\n   */\n  public async addGroupingPolicy(...params: string[]): Promise<boolean> {\n    return this.addNamedGroupingPolicy('g', ...params);\n  }\n\n  /**\n   * addGroupingPolicies adds a role inheritance rules to the current policy.\n   * If the rule already exists, the function returns false and the rules will not be added.\n   * Otherwise the function returns true by adding the new rules.\n   *\n   * @param rules the \"g\" policy rules, ptype \"g\" is implicitly used.\n   * @return succeeds or not.\n   */\n  public async addGroupingPolicies(rules: string[][]): Promise<boolean> {\n    return this.addNamedGroupingPolicies('g', rules);\n  }\n\n  /**\n   * addNamedGroupingPolicy adds a named role inheritance rule to the current policy.\n   * If the rule already exists, the function returns false and the rule will not be added.\n   * Otherwise the function returns true by adding the new rule.\n   *\n   * @param ptype the policy type, can be \"g\", \"g2\", \"g3\", ..\n   * @param params the \"g\" policy rule.\n   * @return succeeds or not.\n   */\n  public async addNamedGroupingPolicy(ptype: string, ...params: string[]): Promise<boolean> {\n    return this.addPolicyInternal('g', ptype, params);\n  }\n\n  /**\n   * addNamedGroupingPolicies adds named role inheritance rules to the current policy.\n   * If the rule already exists, the function returns false and the rules will not be added.\n   * Otherwise the function returns true by adding the new rules.\n   *\n   * @param ptype the policy type, can be \"g\", \"g2\", \"g3\", ..\n   * @param rules the \"g\" policy rule.\n   * @return succeeds or not.\n   */\n  public async addNamedGroupingPolicies(ptype: string, rules: string[][]): Promise<boolean> {\n    return this.addPoliciesInternal('g', ptype, rules);\n  }\n\n  /**\n   * removeGroupingPolicy removes a role inheritance rule from the current policy.\n   *\n   * @param params the \"g\" policy rule, ptype \"g\" is implicitly used.\n   * @return succeeds or not.\n   */\n  public async removeGroupingPolicy(...params: string[]): Promise<boolean> {\n    return this.removeNamedGroupingPolicy('g', ...params);\n  }\n\n  /**\n   * removeGroupingPolicies removes role inheritance rules from the current policy.\n   *\n   * @param rules the \"g\" policy rules, ptype \"g\" is implicitly used.\n   * @return succeeds or not.\n   */\n  public async removeGroupingPolicies(rules: string[][]): Promise<boolean> {\n    return this.removeNamedGroupingPolicies('g', rules);\n  }\n\n  /**\n   * removeFilteredGroupingPolicy removes a role inheritance rule from the current policy, field filters can be specified.\n   *\n   * @param fieldIndex the policy rule's start index to be matched.\n   * @param fieldValues the field values to be matched, value \"\"\n   *                    means not to match this field.\n   * @return succeeds or not.\n   */\n  public async removeFilteredGroupingPolicy(fieldIndex: number, ...fieldValues: string[]): Promise<boolean> {\n    return this.removeFilteredNamedGroupingPolicy('g', fieldIndex, ...fieldValues);\n  }\n\n  /**\n   * removeNamedGroupingPolicy removes a role inheritance rule from the current named policy.\n   *\n   * @param ptype the policy type, can be \"g\", \"g2\", \"g3\", ..\n   * @param params the \"g\" policy rule.\n   * @return succeeds or not.\n   */\n  public async removeNamedGroupingPolicy(ptype: string, ...params: string[]): Promise<boolean> {\n    return this.removePolicyInternal('g', ptype, params);\n  }\n\n  /**\n   * removeNamedGroupingPolicies removes role inheritance rules from the current named policy.\n   *\n   * @param ptype the policy type, can be \"g\", \"g2\", \"g3\", ..\n   * @param rules the \"g\" policy rules.\n   * @return succeeds or not.\n   */\n  public async removeNamedGroupingPolicies(ptype: string, rules: string[][]): Promise<boolean> {\n    return this.removePoliciesInternal('g', ptype, rules);\n  }\n\n  /**\n   * removeFilteredNamedGroupingPolicy removes a role inheritance rule from the current named policy, field filters can be specified.\n   *\n   * @param ptype the policy type, can be \"g\", \"g2\", \"g3\", ..\n   * @param fieldIndex the policy rule's start index to be matched.\n   * @param fieldValues the field values to be matched, value \"\"\n   *                    means not to match this field.\n   * @return succeeds or not.\n   */\n  public async removeFilteredNamedGroupingPolicy(ptype: string, fieldIndex: number, ...fieldValues: string[]): Promise<boolean> {\n    return this.removeFilteredPolicyInternal('g', ptype, fieldIndex, fieldValues);\n  }\n\n  /**\n   * addFunction adds a customized function.\n   * @param name custom function name\n   * @param func function\n   */\n  public async addFunction(name: string, func: MatchingFunction): Promise<void> {\n    this.fm.addFunction(name, func);\n  }\n}\n","// Copyright 2020 The Casbin Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Enforcer, newEnforcerWithClass } from './enforcer';\nimport { Model } from './model';\nimport { Adapter, MemoryAdapter } from './persist';\n\n// CachedEnforcer wraps Enforcer and provides decision cache\nexport class CachedEnforcer extends Enforcer {\n  private enableCache = true;\n  private m = new Map<string, boolean>();\n\n  // invalidateCache deletes all the existing cached decisions.\n  public invalidateCache(): void {\n    this.m = new Map<string, boolean>();\n  }\n\n  // setEnableCache determines whether to enable cache on e nforce(). When enableCache is enabled, cached result (true | false) will be returned for previous decisions.\n  public setEnableCache(enableCache: boolean): void {\n    this.enableCache = enableCache;\n  }\n\n  private static canCache(...rvals: any[]): boolean {\n    return rvals.every((n) => typeof n === 'string');\n  }\n\n  private static getCacheKey(...rvals: string[]): string {\n    return rvals.join('$$');\n  }\n\n  private getCache(key: string): boolean | undefined {\n    return this.m.get(key);\n  }\n\n  private setCache(key: string, value: boolean): void {\n    this.m.set(key, value);\n  }\n\n  // enforce decides whether a \"subject\" can access a \"object\" with the operation \"action\", input parameters are usually: (sub, obj, act).\n  // if rvals is not string , ingore the cache\n  public async enforce(...rvals: any[]): Promise<boolean> {\n    if (!this.enableCache) {\n      return super.enforce(...rvals);\n    }\n\n    let key = '';\n    const cache = CachedEnforcer.canCache(...rvals);\n\n    if (cache) {\n      key = CachedEnforcer.getCacheKey(...rvals);\n      const res = this.getCache(key);\n\n      if (res !== undefined) {\n        return res;\n      }\n    }\n\n    const res = await super.enforce(...rvals);\n\n    if (cache) {\n      this.setCache(key, res);\n    }\n\n    return res;\n  }\n}\n\n// newCachedEnforcer creates a cached enforcer via string or DB.\nexport async function newCachedEnforcer(\n  model?: Model,\n  adapter: Adapter = new MemoryAdapter([]),\n  enableLog = false\n): Promise<CachedEnforcer> {\n  return newEnforcerWithClass(CachedEnforcer, model, adapter, enableLog);\n}\n",null,"// Copyright 2020 The Casbin Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Enforcer, newEnforcerWithClass } from './enforcer';\nimport AwaitLock from 'await-lock';\nimport { Adapter, MemoryAdapter, Watcher } from './persist';\nimport { MatchingFunc } from './rbac';\nimport { Model } from './model';\n\n// SyncedEnforcer wraps Enforcer and provides synchronized access\nexport class SyncedEnforcer extends Enforcer {\n  private lock = new AwaitLock();\n\n  /**\n   * setWatcher sets the current watcher.\n   *\n   * @param watcher the watcher.\n   */\n\n  public setWatcher(watcher: Watcher): void {\n    this.watcher = watcher;\n    this.watcher.setUpdateCallback(() => this.loadPolicy());\n  }\n\n  /**\n   * loadPolicy reloads the policy from adapter.\n   */\n  public async loadPolicy(): Promise<void> {\n    await this.lock.acquireAsync();\n    return super.loadPolicy().finally(() => this.lock.release());\n  }\n\n  /**\n   * clearPolicy clears all policy.\n   */\n  public clearPolicy(): void {\n    this.lock\n      .acquireAsync()\n      .then(() => super.clearPolicy())\n      .finally(() => this.lock.release());\n  }\n\n  /**\n   * savePolicy saves the current policy (usually after changed with Casbin API) back to adapter.\n   */\n  public async savePolicy(): Promise<boolean> {\n    await this.lock.acquireAsync();\n    return super.savePolicy().finally(() => this.lock.release());\n  }\n\n  /**\n   * buildRoleLinks manually rebuild the role inheritance relations.\n   */\n  public async buildRoleLinks(): Promise<void> {\n    await this.lock.acquireAsync();\n    return super.buildRoleLinks().finally(() => this.lock.release());\n  }\n\n  /**\n   * If the matchers does not contain an asynchronous method, call it faster.\n   *\n   * enforceWithSyncCompile decides whether a \"subject\" can access a \"object\" with\n   * the operation \"action\", input parameters are usually: (sub, obj, act).\n   *\n   * @param rvals the request needs to be mediated, usually an array\n   *              of strings, can be class instances if ABAC is used.\n   * @return whether to allow the request.\n   */\n  public enforceWithSyncCompile(...rvals: any[]): boolean {\n    return super.enforceWithSyncCompile(...rvals);\n  }\n\n  /**\n   * enforce decides whether a \"subject\" can access a \"object\" with\n   * the operation \"action\", input parameters are usually: (sub, obj, act).\n   *\n   * @param rvals the request needs to be mediated, usually an array\n   *              of strings, can be class instances if ABAC is used.\n   * @return whether to allow the request.\n   */\n  public async enforce(...rvals: any[]): Promise<boolean> {\n    await this.lock.acquireAsync();\n    return super.enforce(...rvals).finally(() => this.lock.release());\n  }\n\n  /**\n   * getAllSubjects gets the list of subjects that show up in the current policy.\n   *\n   * @return all the subjects in \"p\" policy rules. It actually collects the\n   *         0-index elements of \"p\" policy rules. So make sure your subject\n   *         is the 0-index element, like (sub, obj, act). Duplicates are removed.\n   */\n  public async getAllSubjects(): Promise<string[]> {\n    return this.getAllNamedSubjects('p');\n  }\n\n  /**\n   * getAllNamedSubjects gets the list of subjects that show up in the currentnamed policy.\n   *\n   * @param ptype the policy type, can be \"p\", \"p2\", \"p3\", ..\n   * @return all the subjects in policy rules of the ptype type. It actually\n   *         collects the 0-index elements of the policy rules. So make sure\n   *         your subject is the 0-index element, like (sub, obj, act).\n   *         Duplicates are removed.\n   */\n  public async getAllNamedSubjects(ptype: string): Promise<string[]> {\n    await this.lock.acquireAsync();\n    return super.getAllNamedSubjects(ptype).finally(() => this.lock.release());\n  }\n\n  /**\n   * getAllObjects gets the list of objects that show up in the current policy.\n   *\n   * @return all the objects in \"p\" policy rules. It actually collects the\n   *         1-index elements of \"p\" policy rules. So make sure your object\n   *         is the 1-index element, like (sub, obj, act).\n   *         Duplicates are removed.\n   */\n  public async getAllObjects(): Promise<string[]> {\n    return this.getAllNamedObjects('p');\n  }\n\n  /**\n   * getAllNamedObjects gets the list of objects that show up in the current named policy.\n   *\n   * @param ptype the policy type, can be \"p\", \"p2\", \"p3\", ..\n   * @return all the objects in policy rules of the ptype type. It actually\n   *         collects the 1-index elements of the policy rules. So make sure\n   *         your object is the 1-index element, like (sub, obj, act).\n   *         Duplicates are removed.\n   */\n  public async getAllNamedObjects(ptype: string): Promise<string[]> {\n    await this.lock.acquireAsync();\n    return super.getAllNamedObjects(ptype).finally(() => this.lock.release());\n  }\n\n  /**\n   * getAllActions gets the list of actions that show up in the current policy.\n   *\n   * @return all the actions in \"p\" policy rules. It actually collects\n   *         the 2-index elements of \"p\" policy rules. So make sure your action\n   *         is the 2-index element, like (sub, obj, act).\n   *         Duplicates are removed.\n   */\n  public async getAllActions(): Promise<string[]> {\n    return this.getAllNamedActions('p');\n  }\n\n  /**\n   * GetAllNamedActions gets the list of actions that show up in the current named policy.\n   *\n   * @param ptype the policy type, can be \"p\", \"p2\", \"p3\", ..\n   * @return all the actions in policy rules of the ptype type. It actually\n   *         collects the 2-index elements of the policy rules. So make sure\n   *         your action is the 2-index element, like (sub, obj, act).\n   *         Duplicates are removed.\n   */\n  public async getAllNamedActions(ptype: string): Promise<string[]> {\n    await this.lock.acquireAsync();\n    return super.getAllNamedActions(ptype).finally(() => this.lock.release());\n  }\n\n  /**\n   * getAllRoles gets the list of roles that show up in the current policy.\n   *\n   * @return all the roles in \"g\" policy rules. It actually collects\n   *         the 1-index elements of \"g\" policy rules. So make sure your\n   *         role is the 1-index element, like (sub, role).\n   *         Duplicates are removed.\n   */\n  public async getAllRoles(): Promise<string[]> {\n    return this.getAllNamedRoles('g');\n  }\n\n  /**\n   * getAllNamedRoles gets the list of roles that show up in the current named policy.\n   *\n   * @param ptype the policy type, can be \"g\", \"g2\", \"g3\", ..\n   * @return all the subjects in policy rules of the ptype type. It actually\n   *         collects the 0-index elements of the policy rules. So make\n   *         sure your subject is the 0-index element, like (sub, obj, act).\n   *         Duplicates are removed.\n   */\n  public async getAllNamedRoles(ptype: string): Promise<string[]> {\n    await this.lock.acquireAsync();\n    return super.getAllNamedRoles(ptype).finally(() => this.lock.release());\n  }\n\n  /**\n   * getPolicy gets all the authorization rules in the policy.\n   *\n   * @return all the \"p\" policy rules.\n   */\n  public async getPolicy(): Promise<string[][]> {\n    return this.getNamedPolicy('p');\n  }\n\n  /**\n   * getFilteredPolicy gets all the authorization rules in the policy, field filters can be specified.\n   *\n   * @param fieldIndex the policy rule's start index to be matched.\n   * @param fieldValues the field values to be matched, value \"\"\n   *                    means not to match this field.\n   * @return the filtered \"p\" policy rules.\n   */\n  public async getFilteredPolicy(fieldIndex: number, ...fieldValues: string[]): Promise<string[][]> {\n    return this.getFilteredNamedPolicy('p', fieldIndex, ...fieldValues);\n  }\n\n  /**\n   * getNamedPolicy gets all the authorization rules in the named policy.\n   *\n   * @param ptype the policy type, can be \"p\", \"p2\", \"p3\", ..\n   * @return the \"p\" policy rules of the specified ptype.\n   */\n  public async getNamedPolicy(ptype: string): Promise<string[][]> {\n    await this.lock.acquireAsync();\n    return super.getNamedPolicy(ptype).finally(() => this.lock.release());\n  }\n\n  /**\n   * getFilteredNamedPolicy gets all the authorization rules in the named policy, field filters can be specified.\n   *\n   * @param ptype the policy type, can be \"p\", \"p2\", \"p3\", ..\n   * @param fieldIndex the policy rule's start index to be matched.\n   * @param fieldValues the field values to be matched, value \"\"\n   *                    means not to match this field.\n   * @return the filtered \"p\" policy rules of the specified ptype.\n   */\n  public async getFilteredNamedPolicy(ptype: string, fieldIndex: number, ...fieldValues: string[]): Promise<string[][]> {\n    await this.lock.acquireAsync();\n    return super.getFilteredNamedPolicy(ptype, fieldIndex, ...fieldValues).finally(() => this.lock.release());\n  }\n\n  /**\n   * getGroupingPolicy gets all the role inheritance rules in the policy.\n   *\n   * @return all the \"g\" policy rules.\n   */\n  public async getGroupingPolicy(): Promise<string[][]> {\n    return this.getNamedGroupingPolicy('g');\n  }\n\n  /**\n   * getFilteredGroupingPolicy gets all the role inheritance rules in the policy, field filters can be specified.\n   *\n   * @param fieldIndex the policy rule's start index to be matched.\n   * @param fieldValues the field values to be matched, value \"\" means not to match this field.\n   * @return the filtered \"g\" policy rules.\n   */\n  public async getFilteredGroupingPolicy(fieldIndex: number, ...fieldValues: string[]): Promise<string[][]> {\n    return this.getFilteredNamedGroupingPolicy('g', fieldIndex, ...fieldValues);\n  }\n\n  /**\n   * getNamedGroupingPolicy gets all the role inheritance rules in the policy.\n   *\n   * @param ptype the policy type, can be \"g\", \"g2\", \"g3\", ..\n   * @return the \"g\" policy rules of the specified ptype.\n   */\n  public async getNamedGroupingPolicy(ptype: string): Promise<string[][]> {\n    await this.lock.acquireAsync();\n    return super.getNamedGroupingPolicy(ptype).finally(() => this.lock.release());\n  }\n\n  /**\n   * getFilteredNamedGroupingPolicy gets all the role inheritance rules in the policy, field filters can be specified.\n   *\n   * @param ptype the policy type, can be \"g\", \"g2\", \"g3\", ..\n   * @param fieldIndex the policy rule's start index to be matched.\n   * @param fieldValues the field values to be matched, value \"\"\n   *                    means not to match this field.\n   * @return the filtered \"g\" policy rules of the specified ptype.\n   */\n  public async getFilteredNamedGroupingPolicy(ptype: string, fieldIndex: number, ...fieldValues: string[]): Promise<string[][]> {\n    await this.lock.acquireAsync();\n    return super.getFilteredNamedGroupingPolicy(ptype, fieldIndex, ...fieldValues).finally(() => this.lock.release());\n  }\n\n  /**\n   * hasPolicy determines whether an authorization rule exists.\n   *\n   * @param params the \"p\" policy rule, ptype \"p\" is implicitly used.\n   * @return whether the rule exists.\n   */\n  public async hasPolicy(...params: string[]): Promise<boolean> {\n    return this.hasNamedPolicy('p', ...params);\n  }\n\n  /**\n   * hasNamedPolicy determines whether a named authorization rule exists.\n   *\n   * @param ptype the policy type, can be \"p\", \"p2\", \"p3\", ..\n   * @param params the \"p\" policy rule.\n   * @return whether the rule exists.\n   */\n  public async hasNamedPolicy(ptype: string, ...params: string[]): Promise<boolean> {\n    await this.lock.acquireAsync();\n    return super.hasNamedPolicy(ptype, ...params).finally(() => this.lock.release());\n  }\n\n  /**\n   * addPolicy adds an authorization rule to the current policy.\n   * If the rule already exists, the function returns false and the rule will not be added.\n   * Otherwise the function returns true by adding the new rule.\n   *\n   * @param params the \"p\" policy rule, ptype \"p\" is implicitly used.\n   * @return succeeds or not.\n   */\n  public async addPolicy(...params: string[]): Promise<boolean> {\n    return this.addNamedPolicy('p', ...params);\n  }\n\n  /**\n   * addNamedPolicy adds an authorization rule to the current named policy.\n   * If the rule already exists, the function returns false and the rule will not be added.\n   * Otherwise the function returns true by adding the new rule.\n   *\n   * @param ptype the policy type, can be \"p\", \"p2\", \"p3\", ..\n   * @param params the \"p\" policy rule.\n   * @return succeeds or not.\n   */\n  public async addNamedPolicy(ptype: string, ...params: string[]): Promise<boolean> {\n    await this.lock.acquireAsync();\n    return super.addNamedPolicy(ptype, ...params).finally(() => this.lock.release());\n  }\n\n  /**\n   * removePolicy removes an authorization rule from the current policy.\n   *\n   * @param params the \"p\" policy rule, ptype \"p\" is implicitly used.\n   * @return succeeds or not.\n   */\n  public async removePolicy(...params: string[]): Promise<boolean> {\n    return this.removeNamedPolicy('p', ...params);\n  }\n\n  /**\n   * removeFilteredPolicy removes an authorization rule from the current policy, field filters can be specified.\n   *\n   * @param fieldIndex the policy rule's start index to be matched.\n   * @param fieldValues the field values to be matched, value \"\"\n   *                    means not to match this field.\n   * @return succeeds or not.\n   */\n  public async removeFilteredPolicy(fieldIndex: number, ...fieldValues: string[]): Promise<boolean> {\n    return this.removeFilteredNamedPolicy('p', fieldIndex, ...fieldValues);\n  }\n\n  /**\n   * removeNamedPolicy removes an authorization rule from the current named policy.\n   *\n   * @param ptype the policy type, can be \"p\", \"p2\", \"p3\", ..\n   * @param params the \"p\" policy rule.\n   * @return succeeds or not.\n   */\n  public async removeNamedPolicy(ptype: string, ...params: string[]): Promise<boolean> {\n    await this.lock.acquireAsync();\n    return this.removePolicyInternal('p', ptype, params).finally(() => this.lock.release());\n  }\n\n  /**\n   * removeFilteredNamedPolicy removes an authorization rule from the current named policy, field filters can be specified.\n   *\n   * @param ptype the policy type, can be \"p\", \"p2\", \"p3\", ..\n   * @param fieldIndex the policy rule's start index to be matched.\n   * @param fieldValues the field values to be matched, value \"\"\n   *                    means not to match this field.\n   * @return succeeds or not.\n   */\n  public async removeFilteredNamedPolicy(ptype: string, fieldIndex: number, ...fieldValues: string[]): Promise<boolean> {\n    await this.lock.acquireAsync();\n    return super.removeFilteredNamedPolicy(ptype, fieldIndex, ...fieldValues).finally(() => this.lock.release());\n  }\n\n  /**\n   * hasGroupingPolicy determines whether a role inheritance rule exists.\n   *\n   * @param params the \"g\" policy rule, ptype \"g\" is implicitly used.\n   * @return whether the rule exists.\n   */\n  public async hasGroupingPolicy(...params: string[]): Promise<boolean> {\n    return this.hasNamedGroupingPolicy('g', ...params);\n  }\n\n  /**\n   * hasNamedGroupingPolicy determines whether a named role inheritance rule exists.\n   *\n   * @param ptype the policy type, can be \"g\", \"g2\", \"g3\", ..\n   * @param params the \"g\" policy rule.\n   * @return whether the rule exists.\n   */\n  public async hasNamedGroupingPolicy(ptype: string, ...params: string[]): Promise<boolean> {\n    await this.lock.acquireAsync();\n    return super.hasNamedGroupingPolicy(ptype, ...params).finally(() => this.lock.release());\n  }\n\n  /**\n   * addGroupingPolicy adds a role inheritance rule to the current policy.\n   * If the rule already exists, the function returns false and the rule will not be added.\n   * Otherwise the function returns true by adding the new rule.\n   *\n   * @param params the \"g\" policy rule, ptype \"g\" is implicitly used.\n   * @return succeeds or not.\n   */\n  public async addGroupingPolicy(...params: string[]): Promise<boolean> {\n    return this.addNamedGroupingPolicy('g', ...params);\n  }\n\n  /**\n   * addNamedGroupingPolicy adds a named role inheritance rule to the current policy.\n   * If the rule already exists, the function returns false and the rule will not be added.\n   * Otherwise the function returns true by adding the new rule.\n   *\n   * @param ptype the policy type, can be \"g\", \"g2\", \"g3\", ..\n   * @param params the \"g\" policy rule.\n   * @return succeeds or not.\n   */\n  public async addNamedGroupingPolicy(ptype: string, ...params: string[]): Promise<boolean> {\n    await this.lock.acquireAsync();\n    return super.addNamedGroupingPolicy(ptype, ...params).finally(() => this.lock.release());\n  }\n\n  /**\n   * removeGroupingPolicy removes a role inheritance rule from the current policy.\n   *\n   * @param params the \"g\" policy rule, ptype \"g\" is implicitly used.\n   * @return succeeds or not.\n   */\n  public async removeGroupingPolicy(...params: string[]): Promise<boolean> {\n    return this.removeNamedGroupingPolicy('g', ...params);\n  }\n\n  /**\n   * removeFilteredGroupingPolicy removes a role inheritance rule from the current policy, field filters can be specified.\n   *\n   * @param fieldIndex the policy rule's start index to be matched.\n   * @param fieldValues the field values to be matched, value \"\"\n   *                    means not to match this field.\n   * @return succeeds or not.\n   */\n  public async removeFilteredGroupingPolicy(fieldIndex: number, ...fieldValues: string[]): Promise<boolean> {\n    return this.removeFilteredNamedGroupingPolicy('g', fieldIndex, ...fieldValues);\n  }\n\n  /**\n   * removeNamedGroupingPolicy removes a role inheritance rule from the current named policy.\n   *\n   * @param ptype the policy type, can be \"g\", \"g2\", \"g3\", ..\n   * @param params the \"g\" policy rule.\n   * @return succeeds or not.\n   */\n  public async removeNamedGroupingPolicy(ptype: string, ...params: string[]): Promise<boolean> {\n    await this.lock.acquireAsync();\n    return super.removeNamedGroupingPolicy(ptype, ...params).finally(() => this.lock.release());\n  }\n\n  /**\n   * removeFilteredNamedGroupingPolicy removes a role inheritance rule from the current named policy, field filters can be specified.\n   *\n   * @param ptype the policy type, can be \"g\", \"g2\", \"g3\", ..\n   * @param fieldIndex the policy rule's start index to be matched.\n   * @param fieldValues the field values to be matched, value \"\"\n   *                    means not to match this field.\n   * @return succeeds or not.\n   */\n  public async removeFilteredNamedGroupingPolicy(ptype: string, fieldIndex: number, ...fieldValues: string[]): Promise<boolean> {\n    await this.lock.acquireAsync();\n    return super.removeFilteredNamedGroupingPolicy(ptype, fieldIndex, ...fieldValues).finally(() => this.lock.release());\n  }\n\n  /**\n   * add matching function to RoleManager by ptype\n   * @param ptype g\n   * @param fn the function will be added\n   */\n  public async addNamedMatchingFunc(ptype: string, fn: MatchingFunc): Promise<void> {\n    await this.lock.acquireAsync();\n    return super.addNamedMatchingFunc(ptype, fn).finally(() => this.lock.release());\n  }\n\n  /**\n   * add domain matching function to RoleManager by ptype\n   * @param ptype g\n   * @param fn the function will be added\n   */\n  public async addNamedDomainMatchingFunc(ptype: string, fn: MatchingFunc): Promise<void> {\n    await this.lock.acquireAsync();\n    return super.addNamedDomainMatchingFunc(ptype, fn).finally(() => {\n      this.lock.release();\n    });\n  }\n}\n\n// newSyncedEnforcer creates a synchronized enforcer via adapter.\nexport async function newSyncedEnforcer(model?: Model, adapter: Adapter = new MemoryAdapter([]), enableLog = false): Promise<Enforcer> {\n  return newEnforcerWithClass(SyncedEnforcer, model, adapter, enableLog);\n}\n","// Copyright 2020 The Casbin Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Enforcer } from './enforcer';\nimport { deepCopy } from './util';\n\n/**\n * Experiment!\n * getPermissionForCasbinJs returns a string include the whole model.\n * You can pass the returned string to the frontend and manage your webpage widgets and APIs with Casbin.js.\n * @param e the initialized enforcer\n * @param user the user\n */\nexport async function casbinJsGetPermissionForUser(e: Enforcer, user?: string): Promise<string> {\n  const obj: any = {};\n\n  const m = e.getModel().model;\n  let s = '';\n  s += '[request_definition]\\n';\n  s += `r = ${m.get('r')?.get('r')?.value.replace(/_/g, '.')}\\n`;\n  s += '[policy_definition]\\n';\n  s += `p = ${m.get('p')?.get('p')?.value.replace(/_/g, '.')}\\n`;\n  if (m.get('g')?.get('g') !== undefined) {\n    s += '[role_definition]\\n';\n    s += `g = ${m.get('g')?.get('g')?.value}\\n`;\n  }\n  s += '[policy_effect]\\n';\n  s += `e = ${m.get('e')?.get('e')?.value.replace(/_/g, '.')}\\n`;\n  s += '[matchers]\\n';\n  s += `m = ${m.get('m')?.get('m')?.value.replace(/_/g, '.')}`;\n  obj['m'] = s;\n  obj['p'] = deepCopy(await e.getPolicy());\n  for (const arr of obj['p']) {\n    arr.splice(0, 0, 'p');\n  }\n\n  return JSON.stringify(obj);\n}\n"],"names":["b64","lens","getLens","validLen","placeHoldersLen","tmp","i","arr","Arr","_byteLength","curByte","len","revLookup","charCodeAt","uint8","length","extraBytes","parts","maxChunkLength","len2","push","encodeChunk","lookup","join","Uint8Array","Array","code","Error","indexOf","start","end","num","output","buffer","offset","isLE","mLen","nBytes","e","m","eLen","eMax","eBias","nBits","d","s","NaN","Infinity","Math","pow","value","c","rt","abs","isNaN","floor","log","LN2","customInspectSymbol","Symbol","exports","Buffer","alloc","K_MAX_LENGTH","createBuffer","RangeError","buf","Object","setPrototypeOf","prototype","arg","encodingOrOffset","TypeError","allocUnsafe","from","string","encoding","isEncoding","byteLength","actual","write","slice","fromString","ArrayBuffer","isView","arrayView","isInstance","copy","fromArrayBuffer","byteOffset","fromArrayLike","fromArrayView","SharedArrayBuffer","valueOf","b","obj","isBuffer","checked","undefined","numberIsNaN","type","isArray","data","fromObject","toPrimitive","assertSize","size","array","toString","mustMatch","arguments","loweredCase","utf8ToBytes","base64ToBytes","toLowerCase","slowToString","this","hexSlice","utf8Slice","asciiSlice","latin1Slice","base64Slice","utf16leSlice","swap","n","bidirectionalIndexOf","val","dir","arrayIndexOf","call","lastIndexOf","indexSize","arrLength","valLength","String","read","readUInt16BE","foundIndex","found","j","hexWrite","Number","remaining","strLen","parsed","parseInt","substr","utf8Write","blitBuffer","asciiWrite","str","byteArray","asciiToBytes","base64Write","ucs2Write","units","hi","lo","utf16leToBytes","base64","fromByteArray","min","res","firstByte","codePoint","bytesPerSequence","secondByte","thirdByte","fourthByte","tempCodePoint","codePoints","MAX_ARGUMENTS_LENGTH","fromCharCode","apply","decodeCodePointsArray","TYPED_ARRAY_SUPPORT","proto","foo","typedArraySupport","console","error","defineProperty","enumerable","get","poolSize","fill","allocUnsafeSlow","_isBuffer","compare","a","x","y","concat","list","pos","set","swap16","swap32","swap64","toLocaleString","equals","inspect","max","INSPECT_MAX_BYTES","replace","trim","target","thisStart","thisEnd","thisCopy","targetCopy","includes","isFinite","toJSON","_arr","ret","out","hexSliceLookupTable","bytes","checkOffset","ext","checkInt","wrtBigUInt64LE","checkIntBI","BigInt","wrtBigUInt64BE","checkIEEE754","writeFloat","littleEndian","noAssert","ieee754","writeDouble","newBuf","subarray","readUintLE","readUIntLE","mul","readUintBE","readUIntBE","readUint8","readUInt8","readUint16LE","readUInt16LE","readUint16BE","readUint32LE","readUInt32LE","readUint32BE","readUInt32BE","readBigUInt64LE","defineBigIntMethod","validateNumber","first","last","boundsError","readBigUInt64BE","readIntLE","readIntBE","readInt8","readInt16LE","readInt16BE","readInt32LE","readInt32BE","readBigInt64LE","readBigInt64BE","readFloatLE","readFloatBE","readDoubleLE","readDoubleBE","writeUintLE","writeUIntLE","writeUintBE","writeUIntBE","writeUint8","writeUInt8","writeUint16LE","writeUInt16LE","writeUint16BE","writeUInt16BE","writeUint32LE","writeUInt32LE","writeUint32BE","writeUInt32BE","writeBigUInt64LE","writeBigUInt64BE","writeIntLE","limit","sub","writeIntBE","writeInt8","writeInt16LE","writeInt16BE","writeInt32LE","writeInt32BE","writeBigInt64LE","writeBigInt64BE","writeFloatLE","writeFloatBE","writeDoubleLE","writeDoubleBE","targetStart","copyWithin","errors","E","sym","getMessage","Base","constructor","super","writable","configurable","name","stack","message","addNumericalSeparator","range","ERR_OUT_OF_RANGE","checkBounds","ERR_INVALID_ARG_TYPE","ERR_BUFFER_OUT_OF_BOUNDS","input","msg","received","isInteger","INVALID_BASE64_RE","leadSurrogate","toByteArray","split","base64clean","src","dst","alphabet","table","i16","fn","BufferBigIntNotDefined","ipv4Regex","ipv6Regex","ip","toBuffer","buff","result","isV4Format","map","byte","isV6Format","sections","v4Buffer","splice","unshift","argv","word","test","fromPrefixLen","prefixlen","family","_normalizeFamily","bits","mask","addr","addrBuffer","maskBuffer","subnet","networkAddress","toLong","contains","other","cidrSubnet","cidrString","cidrParts","isEqual","aBuffer","bBuffer","t","ipl","forEach","octet","fromLong","process","platform","sep","balanced","RegExp","maybeMatch","r","pre","body","post","reg","match","begs","beg","left","right","ai","bi","pop","expand","escSlash","escOpen","escClose","escComma","escPeriod","escapeBraces","unescapeBraces","random","numeric","parseCommaParts","p","postParts","shift","embrace","isPadded","el","lte","gte","isTop","expansions","k","expansion","N","isNumericSequence","isAlphaSequence","isSequence","isOptions","width","incr","pad","some","need","z","minimatch","module","pattern","options","assertValidPattern","nocomment","charAt","Minimatch","path","GLOBSTAR","plTypes","open","close","qmark","star","charSet","reduce","reSpecials","addPatternStartSet","slashSplit","filter","keys","defaults","def","orig","makeRe","braceExpand","nobrace","SUBPARSE","mm","f","nonull","regexp","negate","comment","empty","partial","make","debug","parseNegate","globSet","args","globParts","si","parse","nonegate","negateOffset","matchOne","file","fi","pi","fl","pl","hit","fr","pr","dot","swallowee","isSub","noglobstar","re","hasMagic","nocase","escaping","patternListStack","negativeLists","stateChar","cs","sp","inClass","reClassStart","classStart","patternStart","clearStateChar","noext","reStart","reEnd","substring","er","tail","_","$1","$2","addPatternStart","nl","nlBefore","nlFirst","nlAfter","nlLast","openParensBefore","cleanAfter","globUnescape","flags","assign","_glob","_src","twoStar","regExpEscape","ex","filename","matchBase","flipNegate","static","regexMatch","key1","key2","keyMatchFunc","arg0","arg1","keyMatch","keyGetFunc","keyGet","keyMatch2","keyMatch2Func","keyGet2Func","arg2","pathVar","values","index","keyGet2","keyMatch3Func","keyMatch3","keyMatch4Func","tokens","exec","Map","key","v","keyMatch4","keyMatch5Func","KeyMatch5","regexMatchFunc","ipMatchFunc","ip1","ip2","require","ipMatch","globMatch","generateGFunction","rm","memorized","async","name1","name2","hasLink","domain","escapeAssertion","startsWith","arrayEquals","aLen","arrayRemoveDuplicates","Set","evalRegG","evalReg","hasEval","replaceEval","ruleName","rule","getEvalValue","subMatch","rules","generatorRunSync","iterator","done","next","Promise","temp","generatorRunAsync","deepCopy","newObj","hasOwnProperty","policyArrayToString","policy","policyStringToArray","endCommaRe","quotaWrapperRe","lines","arrays","line","commentLabel","slices","customIn","bracketCompatible","exp","reResult","lastIndex","sort","Config","text","config","parseText","addConfig","section","option","DEFAULT_SECTION","has","item","linesCount","currentLine","commentPos","DEFAULT_COMMENT","DEFAULT_COMMENT_SEM","lineNumber","endsWith","shouldWrite","DEFAULT_MULTI_LINE_SEPARATOR","lineNum","equalIndex","getBool","getInt","getFloat","parseFloat","getString","getStrings","itemChild","root","COMPOUND","MEMBER_EXP","LITERAL","throwError","description","unary_ops","binary_ops","getMaxKeyLen","max_len","max_unop_len","max_binop_len","literals","true","false","null","binaryPrecedence","op_val","createBinaryExpression","operator","isDecimalDigit","ch","isIdentifierStart","isIdentifierPart","jsep","expr","ch_i","node","charAtFunc","charCodeAtFunc","exprI","exprICode","gobbleSpaces","gobbleExpression","consequent","alternate","gobbleBinaryExpression","gobbleBinaryOp","to_check","tc_len","biop","prec","biop_info","cur_biop","gobbleToken","gobbleNumericLiteral","gobbleStringLiteral","gobbleArray","argument","prefix","gobbleVariable","chCode","number","raw","quote","closed","gobbleIdentifier","identifier","gobbleArguments","termination","separator_count","gobbleGroup","computed","object","property","callee","elements","nodes","version","addUnaryOp","op_name","addBinaryOp","precedence","addLiteral","literal_name","literal_value","removeUnaryOp","removeAllUnaryOps","removeBinaryOp","removeAllBinaryOps","removeLiteral","removeAllLiterals","evalAsync","Effect","_node","context","evaluateArrayAsync","all","binops","caller","_fn","evaluateMemberAsync","unops","DEFAULT_PRECEDENCE","||","&&","|","^","&","==","!=","===","!==","<",">","<=",">=","<<",">>",">>>","+","-","*","/","%","~","!","evaluateArray","evaluate","evaluateMember","DefaultEffectorStream","current","pushEffect","eft","Allow","rec","Deny","Indeterminate","DefaultEffector","newStream","DefaultLogger","enableLog","enable","isEnable","print","printf","format","logger","setLogger","l","getLogger","logPrint","logPrintf","loadOrDefault","Role","roles","addRole","role","deleteRole","hasRole","hierarchyLevel","hasDirectRole","getRoles","Roles","matchingFunc","ok","createRole","role1","DefaultRoleManager","maxHierarchyLevel","allDomains","hasPattern","hasDomainPattern","domainMatchingFunc","generateTempRoles","patternDomain","add","allRoles","role2","sectionNameMap","g","PolicyOp","requiredSections","Model","model","loadModelFromText","loadAssertion","cfg","sec","secName","addDef","loadSection","getKeySuffix","ast","Assertion","stringArguments","util.escapeAssertion","nodeMap","assertionMap","newConfigFromText","loadModelFromConfig","ms","hasSection","printModel","astKey","op","ptype","buildIncrementalRoleLinks","rmMap","astMap","buildRoleLinks","clearPolicy","getPolicy","hasPolicy","util.arrayEquals","addPolicy","priorityIndex","priorityRule","insertIndex","findIndex","oneRule","addPolicies","updatePolicy","oldRule","newRule","removePolicy","removePolicies","effects","getFilteredPolicy","fieldIndex","fieldValues","matched","fieldValue","removeFilteredPolicy","bool","getValuesForFieldInPolicy","util.arrayRemoveDuplicates","getValuesForFieldInPolicyAllTypes","printPolicy","rbac.DefaultRoleManager","count","PolicyAdd","addLink","PolicyRemove","deleteLink","printRoles","FunctionMap","functions","fm","addFunction","util.keyMatchFunc","util.keyGetFunc","util.keyMatch2Func","util.keyGet2Func","util.keyMatch3Func","util.keyMatch4Func","util.keyMatch5Func","util.regexMatchFunc","util.ipMatchFunc","util.globMatch","func","getFunctions","EnforceContext","rType","pType","eType","mType","Helper","trimStart","MemoryAdapter","policies","prePolicy","loadPolicyLine","ruleClone","deleteRule","Filter","DefaultFilteredAdapter","filtered","loadPolicy","loadFilteredPolicyFile","handler","filterLine","isFiltered","savePolicy","filterSlice","filterWords","skipLine","Enforcer","loadFunctionMap","getExpression","asyncCompile","matcherKey","precedence_or_fn","_function","expression","matcherMap","bind","compileAsync","compile","getModel","setModel","getAdapter","adapter","setAdapter","setWatcher","watcher","setUpdateCallback","setRoleManager","getRoleManager","getNamedRoleManager","setEffector","initRmMap","sortPolicies","autoBuildRoleLinks","buildRoleLinksInternal","loadIncrementalFilteredPolicy","loadFilteredPolicy","update","enableEnforce","enabled","enableAutoSave","autoSave","enableAutoNotifyWatcher","autoNotifyWatcher","enableAutoBuildRoleLinks","addMatchingFunc","addDomainMatchingFunc","clear","privateEnforce","explain","enforceContext","rvals","explainIndex","expString","effectExpr","HasEval","policyLen","rTokens","rTokensLen","effectStream","parameters","token","ruleNames","expWithRule","eftRes","reqStr","enforceSync","defaultEnforceContext","enforceExSync","enforceWithSyncCompile","rval","enforce","getAllNamedSubjects","getAllNamedObjects","getAllNamedActions","getAllNamedRoles","getNamedPolicy","getFilteredNamedPolicy","getNamedGroupingPolicy","getFilteredNamedGroupingPolicy","params","hasNamedPolicy","addNamedPolicy","addNamedPolicies","addPolicyInternal","addPoliciesInternal","updateNamedPolicy","updatePolicyInternal","removeNamedPolicy","removeNamedPolicies","removeFilteredNamedPolicy","removePolicyInternal","removePoliciesInternal","removeFilteredPolicyInternal","hasNamedGroupingPolicy","addNamedGroupingPolicy","addNamedGroupingPolicies","removeNamedGroupingPolicy","removeNamedGroupingPolicies","removeFilteredNamedGroupingPolicy","lazyLoad","getUsers","getRolesForUser","user","addGroupingPolicy","removeGroupingPolicy","deleteRoleForUser","removeFilteredGroupingPolicy","deleteRolesForUser","res1","res2","permission","q","getImplicitRolesForUser","withDomain","getPermissionsForUser","getImplicitPermissionsForUser","u","getUsersForRole","subjects","getAllSubjects","inherits","newEnforcerWithClass","enforcer","initWithModelAndAdapter","newEnforcer","CachedEnforcer","invalidateCache","setEnableCache","enableCache","every","getCache","setCache","cache","canCache","getCacheKey","newCachedEnforcer","acquired","_acquired","acquireAsync","resolve","_waitingResolvers","tryAcquire","release","SyncedEnforcer","AwaitLock","lock","finally","then","addNamedMatchingFunc","addNamedDomainMatchingFunc","newSyncedEnforcer","casbinJsGetPermissionForUser","JSON","stringify"],"mappings":"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"}