Flow Youtube Chat

Youtubeのチャットをニコニコ風に画面上へ流すスクリプトです(再アップ,絵文字バグ修正済み)

目前為 2021-02-03 提交的版本,檢視 最新版本

// ==UserScript==
// @name        Flow Youtube Chat
// @version     1.13.6
// @description Youtubeのチャットをニコニコ風に画面上へ流すスクリプトです(再アップ,絵文字バグ修正済み)
// @match       https://www.youtube.com/*
// @namespace   FlowYoutubeChatScript
// @run-at      document-end
// @grant       GM.setValue
// @grant       GM.getValue
// @grant       GM.deleteValue
// @grant       GM.listValues
// @noframes
// @license     AGPL-3.0-or-later
// @require     https://cdn.jsdelivr.net/npm/[email protected]/dist/sweetalert2.all.min.js#sha384-OCBhaEdUu7BFgaeRVey2PDeHof2MSQRFe/e6S8Q3XrmSV7wrKpLmhPj8FOldGiaF
// @require     https://unpkg.com/[email protected]/dist/loglevel.min.js#sha384-7gGuWfek8Ql6j/uNDFrS0BCe4x2ZihD4B68w9Eu580OVHJBV+bl3rZmEWC7q5/Gj
// @require     https://unpkg.com/[email protected]/dist/bundles/rxjs.umd.min.js#sha384-+BwV2u+ZJFwj586/3PlpsZdYS1U/+hT/zpjYSznHH4XzUJqgshDzZITJ+zGeWl//
// @require     https://unpkg.com/[email protected]/mithril.min.js#sha384-vo9crXih40MlEv6JWHqS7SsPiFp+76csaWQFOF2UU0/xI58Jm/ZvK/1UtpaicJT9
// ==/UserScript==

/* jshint esversion: 6 */

;(() => {
  var __webpack_modules__ = {
      494: function (module, exports, __webpack_require__) {
        var __WEBPACK_AMD_DEFINE_RESULT__
        !(function (globals) {
          "use strict"
          var messages,
            predicates,
            functions,
            assert,
            not,
            maybe,
            collections,
            hasOwnProperty,
            toString,
            keys,
            slice,
            isArray,
            neginf,
            posinf,
            haveSymbols,
            haveMaps,
            haveSets
          function assigned(data) {
            return null != data
          }
          function number(data) {
            return "number" == typeof data && data > neginf && data < posinf
          }
          function integer(data) {
            return "number" == typeof data && data % 1 == 0
          }
          function greater(lhs, rhs) {
            return number(lhs) && lhs > rhs
          }
          function less(lhs, rhs) {
            return number(lhs) && lhs < rhs
          }
          function greaterOrEqual(lhs, rhs) {
            return number(lhs) && lhs >= rhs
          }
          function lessOrEqual(lhs, rhs) {
            return number(lhs) && lhs <= rhs
          }
          function string(data) {
            return "string" == typeof data
          }
          function nonEmptyString(data) {
            return string(data) && "" !== data
          }
          function object(data) {
            return "[object Object]" === toString.call(data)
          }
          function some(data, predicate) {
            for (var key in data)
              if (hasOwnProperty.call(data, key) && predicate(key, data[key]))
                return !0
            return !1
          }
          function instanceStrict(data, prototype) {
            try {
              return data instanceof prototype
            } catch (error) {
              return !1
            }
          }
          function like(data, archetype) {
            var name
            for (name in archetype)
              if (hasOwnProperty.call(archetype, name)) {
                if (
                  !1 === hasOwnProperty.call(data, name) ||
                  typeof data[name] != typeof archetype[name]
                )
                  return !1
                if (
                  object(data[name]) &&
                  !1 === like(data[name], archetype[name])
                )
                  return !1
              }
            return !0
          }
          function arrayLike(data) {
            return assigned(data) && data.length >= 0
          }
          function iterable(data) {
            return haveSymbols
              ? assigned(data) && isFunction(data[Symbol.iterator])
              : arrayLike(data)
          }
          function contains(data, value) {
            var iterator, iteration
            if (!assigned(data)) return !1
            if (haveSets && instanceStrict(data, Set)) return data.has(value)
            if (string(data)) return -1 !== data.indexOf(value)
            if (
              haveSymbols &&
              data[Symbol.iterator] &&
              isFunction(data.values)
            ) {
              iterator = data.values()
              do {
                if ((iteration = iterator.next()).value === value) return !0
              } while (!iteration.done)
              return !1
            }
            return some(data, function (key, dataValue) {
              return dataValue === value
            })
          }
          function containsKey(data, key) {
            return (
              !!assigned(data) &&
              (haveMaps && instanceStrict(data, Map)
                ? data.has(key)
                : !(iterable(data) && !number(+key)) && !!data[key])
            )
          }
          function isFunction(data) {
            return "function" == typeof data
          }
          function forEach(object, action) {
            for (var key in object)
              hasOwnProperty.call(object, key) && action(key, object[key])
          }
          function testArray(data, result) {
            var i
            for (i = 0; i < data.length; i += 1)
              if (data[i] === result) return result
            return !result
          }
          function testObject(data, result) {
            var key, value
            for (key in data)
              if (hasOwnProperty.call(data, key)) {
                if (
                  object((value = data[key])) &&
                  testObject(value, result) === result
                )
                  return result
                if (value === result) return result
              }
            return !result
          }
          function mixin(target, source) {
            return (
              forEach(source, function (key, value) {
                target[key] = value
              }),
              target
            )
          }
          function assertModifier(predicate, defaultMessage) {
            return function () {
              var args = arguments,
                argCount = predicate.l || predicate.length,
                message = args[argCount],
                ErrorType = args[argCount + 1]
              return (
                assertImpl(
                  predicate.apply(null, args),
                  nonEmptyString(message)
                    ? message
                    : defaultMessage
                        .replace("{a}", messageFormatter(args[0]))
                        .replace("{e}", messageFormatter(args[1]))
                        .replace("{e2}", messageFormatter(args[2]))
                        .replace("{t}", function () {
                          var arg = args[1]
                          return arg && arg.name ? arg.name : arg
                        }),
                  isFunction(ErrorType) ? ErrorType : TypeError
                ),
                args[0]
              )
            }
          }
          function messageFormatter(arg) {
            return function () {
              return string(arg)
                ? '"' + arg.replace(/\\/g, "\\\\").replace(/"/g, '\\"') + '"'
                : arg &&
                  !0 !== arg &&
                  arg.constructor &&
                  !instanceStrict(arg, RegExp) &&
                  "number" != typeof arg
                ? arg.constructor.name
                : arg
            }
          }
          function assertImpl(value, message, ErrorType) {
            if (value) return value
            throw new (ErrorType || Error)(message || "assert failed")
          }
          function notModifier(predicate) {
            var modifiedPredicate = function () {
              return notImpl(predicate.apply(null, arguments))
            }
            return (modifiedPredicate.l = predicate.length), modifiedPredicate
          }
          function notImpl(value) {
            return !value
          }
          function ofModifier(target, type, predicate) {
            var modifiedPredicate = function () {
              var collection, args
              if (
                ((collection = arguments[0]),
                "maybe" === target && not.assigned(collection))
              )
                return !0
              if (!type(collection)) return !1
              ;(collection = coerceCollection(type, collection)),
                (args = slice.call(arguments, 1))
              try {
                collection.forEach(function (item) {
                  if (
                    ("maybe" !== target || assigned(item)) &&
                    !predicate.apply(null, [item].concat(args))
                  )
                    throw 0
                })
              } catch (ignore) {
                return !1
              }
              return !0
            }
            return (modifiedPredicate.l = predicate.length), modifiedPredicate
          }
          function coerceCollection(type, collection) {
            switch (type) {
              case arrayLike:
                return slice.call(collection)
              case object:
                return keys(collection).map(function (key) {
                  return collection[key]
                })
              default:
                return collection
            }
          }
          function createModifiedPredicates(modifier, object) {
            return createModifiedFunctions([modifier, predicates, object, ""])
          }
          function createModifiedFunctions(args) {
            var modifier, messageModifier, object
            return (
              (modifier = args.shift()),
              (messageModifier = args.pop()),
              (object = args.pop()),
              forEach(args.pop(), function (key, fn) {
                var message = messages[key]
                message &&
                  messageModifier &&
                  (message = message.replace("to", messageModifier + "to")),
                  Object.defineProperty(object, key, {
                    configurable: !1,
                    enumerable: !0,
                    writable: !1,
                    value: modifier.apply(null, args.concat(fn, message)),
                  })
              }),
              object
            )
          }
          function createModifiedModifier(modifier, modified, messageModifier) {
            return createModifiedFunctions([
              modifier,
              modified,
              {},
              messageModifier,
            ])
          }
          function createOfModifiers(base, modifier) {
            collections.forEach(function (key) {
              base[key].of = createModifiedModifier(
                modifier,
                predicates[key].of
              )
            })
          }
          ;(messages = {}),
            (predicates = {}),
            [
              {
                n: "equal",
                f: function (lhs, rhs) {
                  return lhs === rhs
                },
                s: "equal {e}",
              },
              {
                n: "undefined",
                f: function (data) {
                  return void 0 === data
                },
                s: "be undefined",
              },
              {
                n: "null",
                f: function (data) {
                  return null === data
                },
                s: "be null",
              },
              { n: "assigned", f: assigned, s: "be assigned" },
              {
                n: "primitive",
                f: function (data) {
                  var type
                  switch (data) {
                    case null:
                    case void 0:
                    case !1:
                    case !0:
                      return !0
                  }
                  return (
                    "string" === (type = typeof data) ||
                    "number" === type ||
                    (haveSymbols && "symbol" === type)
                  )
                },
                s: "be primitive type",
              },
              { n: "contains", f: contains, s: "contain {e}" },
              {
                n: "in",
                f: function (value, data) {
                  return contains(data, value)
                },
                s: "be in {e}",
              },
              { n: "containsKey", f: containsKey, s: "contain key {e}" },
              {
                n: "keyIn",
                f: function (key, data) {
                  return containsKey(data, key)
                },
                s: "be key in {e}",
              },
              {
                n: "zero",
                f: function (data) {
                  return 0 === data
                },
                s: "be 0",
              },
              {
                n: "one",
                f: function (data) {
                  return 1 === data
                },
                s: "be 1",
              },
              {
                n: "infinity",
                f: function (data) {
                  return data === neginf || data === posinf
                },
                s: "be infinity",
              },
              { n: "number", f: number, s: "be Number" },
              { n: "integer", f: integer, s: "be integer" },
              {
                n: "float",
                f: function (data) {
                  return number(data) && data % 1 != 0
                },
                s: "be non-integer number",
              },
              {
                n: "even",
                f: function (data) {
                  return "number" == typeof data && data % 2 == 0
                },
                s: "be even number",
              },
              {
                n: "odd",
                f: function (data) {
                  return integer(data) && data % 2 != 0
                },
                s: "be odd number",
              },
              { n: "greater", f: greater, s: "be greater than {e}" },
              { n: "less", f: less, s: "be less than {e}" },
              {
                n: "between",
                f: function (data, x, y) {
                  if (x < y) return greater(data, x) && data < y
                  return less(data, x) && data > y
                },
                s: "be between {e} and {e2}",
              },
              {
                n: "greaterOrEqual",
                f: greaterOrEqual,
                s: "be greater than or equal to {e}",
              },
              {
                n: "lessOrEqual",
                f: lessOrEqual,
                s: "be less than or equal to {e}",
              },
              {
                n: "inRange",
                f: function (data, x, y) {
                  if (x < y) return greaterOrEqual(data, x) && data <= y
                  return lessOrEqual(data, x) && data >= y
                },
                s: "be in the range {e} to {e2}",
              },
              {
                n: "positive",
                f: function (data) {
                  return greater(data, 0)
                },
                s: "be positive number",
              },
              {
                n: "negative",
                f: function (data) {
                  return less(data, 0)
                },
                s: "be negative number",
              },
              { n: "string", f: string, s: "be String" },
              {
                n: "emptyString",
                f: function (data) {
                  return "" === data
                },
                s: "be empty string",
              },
              {
                n: "nonEmptyString",
                f: nonEmptyString,
                s: "be non-empty string",
              },
              {
                n: "match",
                f: function (data, regex) {
                  return string(data) && !!data.match(regex)
                },
                s: "match {e}",
              },
              {
                n: "boolean",
                f: function (data) {
                  return !1 === data || !0 === data
                },
                s: "be Boolean",
              },
              { n: "object", f: object, s: "be Object" },
              {
                n: "emptyObject",
                f: function (data) {
                  return (
                    object(data) &&
                    !some(data, function () {
                      return !0
                    })
                  )
                },
                s: "be empty object",
              },
              {
                n: "nonEmptyObject",
                f: function (data) {
                  return (
                    object(data) &&
                    some(data, function () {
                      return !0
                    })
                  )
                },
                s: "be non-empty object",
              },
              {
                n: "instanceStrict",
                f: instanceStrict,
                s: "be instanceof {t}",
              },
              {
                n: "thenable",
                f: function (data) {
                  return assigned(data) && isFunction(data.then)
                },
                s: "be promise-like",
              },
              {
                n: "instance",
                f: function (data, prototype) {
                  try {
                    return (
                      instanceStrict(data, prototype) ||
                      data.constructor.name === prototype.name ||
                      toString.call(data) === "[object " + prototype.name + "]"
                    )
                  } catch (error) {
                    return !1
                  }
                },
                s: "be {t}",
              },
              { n: "like", f: like, s: "be like {e}" },
              {
                n: "array",
                f: function (data) {
                  return isArray(data)
                },
                s: "be Array",
              },
              {
                n: "emptyArray",
                f: function (data) {
                  return isArray(data) && 0 === data.length
                },
                s: "be empty array",
              },
              {
                n: "nonEmptyArray",
                f: function (data) {
                  return isArray(data) && data.length > 0
                },
                s: "be non-empty array",
              },
              { n: "arrayLike", f: arrayLike, s: "be array-like" },
              { n: "iterable", f: iterable, s: "be iterable" },
              {
                n: "date",
                f: function (data) {
                  return instanceStrict(data, Date) && integer(data.getTime())
                },
                s: "be valid Date",
              },
              { n: "function", f: isFunction, s: "be Function" },
              {
                n: "hasLength",
                f: function (data, length) {
                  return assigned(data) && data.length === length
                },
                s: "have length {e}",
              },
              {
                n: "throws",
                f: function (data) {
                  if (!isFunction(data)) return !1
                  try {
                    data()
                  } catch (error) {
                    return !0
                  }
                  return !1
                },
                s: "throw",
              },
            ].map(function (data) {
              var n = data.n
              ;(messages[n] = "assert failed: expected {a} to " + data.s),
                (predicates[n] = data.f)
            }),
            (functions = {
              map: function map(data, predicates) {
                var result
                result = isArray(data) ? [] : {}
                if (isFunction(predicates))
                  forEach(data, function (key, value) {
                    result[key] = predicates(value)
                  })
                else {
                  isArray(predicates) || assert.object(predicates)
                  var dataKeys = keys(data || {})
                  forEach(predicates, function (key, predicate) {
                    dataKeys.some(function (dataKey, index) {
                      return dataKey === key && (dataKeys.splice(index, 1), !0)
                    }),
                      isFunction(predicate)
                        ? not.assigned(data)
                          ? (result[key] = !!predicate.m)
                          : (result[key] = predicate(data[key]))
                        : (result[key] = map(data[key], predicate))
                  })
                }
                return result
              },
              all: function (data) {
                if (isArray(data)) return testArray(data, !1)
                return assert.object(data), testObject(data, !1)
              },
              any: function (data) {
                if (isArray(data)) return testArray(data, !0)
                return assert.object(data), testObject(data, !0)
              },
            }),
            (collections = ["array", "arrayLike", "iterable", "object"]),
            (hasOwnProperty = Object.prototype.hasOwnProperty),
            (toString = Object.prototype.toString),
            (keys = Object.keys),
            (slice = Array.prototype.slice),
            (isArray = Array.isArray),
            (neginf = Number.NEGATIVE_INFINITY),
            (posinf = Number.POSITIVE_INFINITY),
            (haveSymbols = "function" == typeof Symbol),
            (haveMaps = "function" == typeof Map),
            (haveSets = "function" == typeof Set),
            (functions = mixin(functions, predicates)),
            (assert = createModifiedPredicates(assertModifier, assertImpl)),
            (not = createModifiedPredicates(notModifier, notImpl)),
            (maybe = createModifiedPredicates(
              function (predicate) {
                var modifiedPredicate = function () {
                  return (
                    !!not.assigned(arguments[0]) ||
                    predicate.apply(null, arguments)
                  )
                }
                return (
                  (modifiedPredicate.l = predicate.length),
                  (modifiedPredicate.m = !0),
                  modifiedPredicate
                )
              },
              function (value) {
                if (!1 === assigned(value)) return !0
                return value
              }
            )),
            (assert.not = createModifiedModifier(assertModifier, not, "not ")),
            (assert.maybe = createModifiedModifier(
              assertModifier,
              maybe,
              "maybe "
            )),
            collections.forEach(function (key) {
              predicates[key].of = createModifiedFunctions([
                ofModifier.bind(null, null),
                predicates[key],
                predicates,
                {},
                "",
              ])
            }),
            createOfModifiers(assert, assertModifier),
            createOfModifiers(not, notModifier),
            collections.forEach(function (key) {
              ;(maybe[key].of = createModifiedFunctions([
                ofModifier.bind(null, "maybe"),
                predicates[key],
                predicates,
                {},
                "",
              ])),
                (assert.maybe[key].of = createModifiedModifier(
                  assertModifier,
                  maybe[key].of
                )),
                (assert.not[key].of = createModifiedModifier(
                  assertModifier,
                  not[key].of
                ))
            }),
            (function (functions) {
              void 0 ===
                (__WEBPACK_AMD_DEFINE_RESULT__ = function () {
                  return functions
                }.call(exports, __webpack_require__, exports, module)) ||
                (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)
            })(mixin(functions, { assert, not, maybe }))
        })()
      },
      228: module => {
        "use strict"
        const createAbortError = () => {
            const error = new Error("Delay aborted")
            return (error.name = "AbortError"), error
          },
          createDelay = ({
            clearTimeout: defaultClear,
            setTimeout: set,
            willResolve,
          }) => (ms, { value, signal } = {}) => {
            if (signal && signal.aborted)
              return Promise.reject(createAbortError())
            let timeoutId, settle, rejectFn
            const clear = defaultClear || clearTimeout,
              signalListener = () => {
                clear(timeoutId), rejectFn(createAbortError())
              },
              delayPromise = new Promise((resolve, reject) => {
                ;(settle = () => {
                  signal && signal.removeEventListener("abort", signalListener),
                    willResolve ? resolve(value) : reject(value)
                }),
                  (rejectFn = reject),
                  (timeoutId = (set || setTimeout)(settle, ms))
              })
            return (
              signal &&
                signal.addEventListener("abort", signalListener, { once: !0 }),
              (delayPromise.clear = () => {
                clear(timeoutId), (timeoutId = null), settle()
              }),
              delayPromise
            )
          },
          delay = createDelay({ willResolve: !0 })
        ;(delay.reject = createDelay({ willResolve: !1 })),
          (delay.range = (minimum, maximum, options) =>
            delay(
              ((minimum, maximum) =>
                Math.floor(Math.random() * (maximum - minimum + 1) + minimum))(
                minimum,
                maximum
              ),
              options
            )),
          (delay.createWithTimers = ({ clearTimeout, setTimeout }) => {
            const delay = createDelay({
              clearTimeout,
              setTimeout,
              willResolve: !0,
            })
            return (
              (delay.reject = createDelay({
                clearTimeout,
                setTimeout,
                willResolve: !1,
              })),
              delay
            )
          }),
          (module.exports = delay),
          (module.exports.default = delay)
      },
    },
    __webpack_module_cache__ = {}
  function __webpack_require__(moduleId) {
    if (__webpack_module_cache__[moduleId])
      return __webpack_module_cache__[moduleId].exports
    var module = (__webpack_module_cache__[moduleId] = { exports: {} })
    return (
      __webpack_modules__[moduleId].call(
        module.exports,
        module,
        module.exports,
        __webpack_require__
      ),
      module.exports
    )
  }
  ;(__webpack_require__.n = module => {
    var getter =
      module && module.__esModule ? () => module.default : () => module
    return __webpack_require__.d(getter, { a: getter }), getter
  }),
    (__webpack_require__.d = (exports, definition) => {
      for (var key in definition)
        __webpack_require__.o(definition, key) &&
          !__webpack_require__.o(exports, key) &&
          Object.defineProperty(exports, key, {
            enumerable: !0,
            get: definition[key],
          })
    }),
    (__webpack_require__.o = (obj, prop) =>
      Object.prototype.hasOwnProperty.call(obj, prop)),
    (() => {
      "use strict"
      const external_log_namespaceObject = log
      var external_log_default = __webpack_require__.n(
        external_log_namespaceObject
      )
      const lib = observer => value => {
          observer.next(value)
        },
        external_rxjs_namespaceObject = rxjs,
        external_rxjs_operators_namespaceObject = rxjs.operators,
        livePage_getPlayer = () => {
          var _a
          return null !== (_a = document.querySelector("#movie_player")) &&
            void 0 !== _a
            ? _a
            : void 0
        },
        livePage_getMainVideo = () => {
          var _a
          return null !==
            (_a = document.querySelector(
              "video.video-stream.html5-main-video"
            )) && void 0 !== _a
            ? _a
            : void 0
        },
        livePage_getChatFrame = () => {
          var _a
          return null !== (_a = document.querySelector("#chatframe")) &&
            void 0 !== _a
            ? _a
            : void 0
        },
        livePage_getChatField = () => {
          var _a, _b, _c
          return null !==
            (_c = (null !==
              (_b =
                null === (_a = document.querySelector("#chatframe")) ||
                void 0 === _a
                  ? void 0
                  : _a.contentDocument) && void 0 !== _b
              ? _b
              : document
            ).querySelector(
              "#items.style-scope.yt-live-chat-item-list-renderer"
            )) && void 0 !== _c
            ? _c
            : void 0
        }
      const assert_lib = __webpack_require__(494).assert,
        tapIs = (constructor, x) => (assert_lib(x instanceof constructor), x),
        changeChatAnimState = playing => {
          var _a
          tapIs(
            CSSStyleRule,
            null ===
              (_a = document.styleSheets.item(
                document.styleSheets.length - 1
              )) || void 0 === _a
              ? void 0
              : _a.cssRules.item(0)
          ).style.animationPlayState = playing ? "running" : "paused"
        },
        checkBannedRegexpWords = (chatData, userConfig) =>
          userConfig.bannedWordRegexs.some(word => {
            const result = chatData.html.match(word)
            return (
              !!result &&
              (external_log_default().debug(
                `Banned Word: "${result}" in "${chatData.html}"`
              ),
              !0)
            )
          }),
        checkBannedUsers = (chatData, userConfig) =>
          Boolean(chatData.authorID) &&
          userConfig.bannedUsers.some(user => {
            var _a
            const result =
              null === (_a = chatData.authorID) || void 0 === _a
                ? void 0
                : _a.match(user)
            return (
              !!result &&
              (external_log_default().debug(
                `Banned User: "${result}" in "${chatData.html}"`
              ),
              !0)
            )
          }),
        checkBannedWords = (chatData, userConfig) =>
          userConfig.bannedWords.some(
            word =>
              !!chatData.html.includes(word) &&
              (external_log_default().debug(
                `Banned Word: "${word}" in "${chatData.html}"`
              ),
              !0)
          ),
        tapNonNull = x => (assert_lib(null != x), x),
        parseMessage = (lengthBefore, message, userConfig) => {
          const { maxChatLength } = userConfig
          let html = "",
            length = lengthBefore
          return (
            message.innerHTML.split(/(?=<img)|">/g).some(part => {
              var _a, _b
              if (part.match(/^<img/)) {
                if (!userConfig.textOnly) {
                  const src = part.match(/src="(\\.|[^"\\])*"/g),
                    size =
                      Math.round(
                        (userConfig.fontSize - 0.2) *
                          ((null !==
                            (_b =
                              null === (_a = livePage_getMainVideo()) ||
                              void 0 === _a
                                ? void 0
                                : _a.clientHeight) && void 0 !== _b
                            ? _b
                            : 0) /
                            userConfig.laneCount) *
                          100
                      ) / 100
                  ;(html += `<img ${src} height="${size}px">`), (length += 1)
                }
              } else
                (html +=
                  part.length >= maxChatLength
                    ? part.substr(0, maxChatLength)
                    : part),
                  (length += part.length)
              return length >= maxChatLength
            }),
            { html, length }
          )
        },
        convertChat = (chat, userConfig) => {
          let html = "",
            length = 0
          const isMember = Boolean(chat.querySelector(".member"))
          let authorID
          const color = chat.querySelector(".owner")
            ? userConfig.colorOwner
            : chat.querySelector(".moderator")
            ? userConfig.colorModerator
            : isMember
            ? userConfig.colorMember
            : userConfig.color
          return (
            Array.from(chat.children).forEach(child => {
              var _a, _b, _c, _d, _e
              const childID = child.id,
                message = child.querySelector("#message")
              if (
                "content" === childID &&
                (chat.querySelector(".moderator") &&
                  !0 === userConfig.displayModeratorName &&
                  (html += `${
                    null === (_a = child.querySelector("#author-name")) ||
                    void 0 === _a
                      ? void 0
                      : _a.innerText
                  }: `),
                message)
              ) {
                const result = parseMessage(length, message, userConfig)
                ;(html += result.html), (length += result.length)
              }
              if ("author-photo" === childID) {
                const matches = (
                  (null === (_b = child.lastElementChild) || void 0 === _b
                    ? void 0
                    : _b.getAttribute("src")) || ""
                ).match(/ytc\/(.*)=/)
                authorID =
                  null == matches ? void 0 : matches[matches.length - 1]
              }
              if ("card" === childID) {
                const authorName = child.querySelector("#author-name"),
                  paidAmount =
                    child.querySelector("#purchase-amount") ||
                    child.querySelector("#purchase-amount-chip")
                if (
                  child.className ===
                  ["style-scope", "yt-live-chat-paid-message-renderer"].join(
                    " "
                  )
                ) {
                  const header = tapNonNull(child.querySelector("#header")),
                    content = child.querySelector("#content"),
                    headerColor = window
                      .getComputedStyle(header)
                      .getPropertyValue("background-color"),
                    paidColor = window
                      .getComputedStyle(content)
                      .getPropertyValue("background-color")
                  if (message) {
                    const result = parseMessage(length, message, userConfig)
                    ;(html += `<span style="color: ${headerColor}; font-size: smaller;">${
                      null == authorName ? void 0 : authorName.innerText
                    }: </span><span style="color: ${headerColor};">${
                      result.html
                    }</span><span style="color: ${paidColor}; font-size: smaller;"><strong>${
                      null == paidAmount ? void 0 : paidAmount.innerText
                    }</strong></span>`),
                      (length +=
                        result.length +
                        (null !==
                          (_c =
                            null == paidAmount
                              ? void 0
                              : paidAmount.innerText.length) && void 0 !== _c
                          ? _c
                          : 0))
                  }
                  authorID = void 0
                }
                if (
                  child.className ===
                  ["style-scope", "yt-live-chat-paid-sticker-renderer"].join(
                    " "
                  )
                ) {
                  const headerColor = window
                      .getComputedStyle(chat)
                      .getPropertyValue(
                        "--yt-live-chat-paid-sticker-chip-background-color"
                      ),
                    amountColor = window
                      .getComputedStyle(chat)
                      .getPropertyValue(
                        "--yt-live-chat-paid-sticker-background-color"
                      )
                  ;(html += `<span style="color: ${headerColor};">${
                    null == authorName ? void 0 : authorName.innerText
                  }: </span>`),
                    (html += `<span style="color: ${amountColor}; font-size: smaller;"><strong>${
                      null == paidAmount ? void 0 : paidAmount.innerText
                    }</strong></span>`),
                    (length +=
                      null !==
                        (_e =
                          null ===
                            (_d =
                              null == paidAmount
                                ? void 0
                                : paidAmount.innerText) || void 0 === _d
                            ? void 0
                            : _d.length) && void 0 !== _e
                        ? _e
                        : 0),
                    (authorID = void 0)
                }
              }
            }),
            { html, length, color, isMine: !1, isMember, authorID }
          )
        },
        getFlowingChats = () => document.querySelectorAll(".fyc_chat"),
        createChat = (chatData, userConfig) => {
          var _a, _b, _c
          const screenHeight =
              null !==
                (_b =
                  null === (_a = livePage_getMainVideo()) || void 0 === _a
                    ? void 0
                    : _a.clientHeight) && void 0 !== _b
                ? _b
                : 0,
            chatHTML = chatData.html,
            chatLength = chatData.length,
            chatColor = chatData.color,
            chatIsMine = chatData.isMine,
            chatSize =
              Math.round(
                (userConfig.fontSize - 0.2) *
                  (screenHeight / userConfig.laneCount) *
                  100
              ) / 100,
            chatSpeed = ((length, userConfig) =>
              (720 / (Math.min(length, userConfig.maxChatLength) + 30)) *
              (20 / userConfig.flowSpeed))(chatLength, userConfig),
            chatLaneNum = ((chatData, userConfig) => {
              var _a, _b
              const screenWidth =
                  null !==
                    (_b =
                      null === (_a = livePage_getPlayer()) || void 0 === _a
                        ? void 0
                        : _a.clientWidth) && void 0 !== _b
                    ? _b
                    : 0,
                chats = getFlowingChats(),
                latestChatLength = chatData.length,
                acceptableLane = new Array(2 * userConfig.laneCount - 1).fill(
                  !0
                )
              for (let i = 0; i < chats.length; i += 1) {
                const chat = chats[i],
                  chatLane = Number.parseInt(
                    tapNonNull(chat.getAttribute("data-lane")),
                    10
                  ),
                  rect = chat.getBoundingClientRect(),
                  chatX = rect.x + rect.width,
                  chatLength = chat.innerText.length,
                  chatBoxAdjustment =
                    (latestChatLength - chatLength >= 3 &&
                      chatX > 0.8 * screenWidth) ||
                    (latestChatLength - chatLength >= 10 &&
                      chatX > 0.4 * screenWidth)
                      ? screenWidth - chatX + 70
                      : 0
                acceptableLane[chatLane] &&
                  (acceptableLane[chatLane] = !(
                    chatX + chatBoxAdjustment >
                    screenWidth
                  ))
              }
              let resultLaneNum = 0,
                i = 0
              for (; 0 === resultLaneNum; ) {
                if (1 == acceptableLane[i]) {
                  ;(resultLaneNum = i), (i = 0)
                  break
                }
                if (i > 3 * userConfig.laneCount - 1) {
                  ;(resultLaneNum = 0), (i = 0)
                  break
                }
                0 == acceptableLane[i] && (resultLaneNum = 0), (i += 1)
              }
              return resultLaneNum
            })(chatData, userConfig)
          let html = ""
          if (
            ((html += `<span class="fyc_chat" data-lane="${chatLaneNum}" style="`),
            (html += `visibility: ${
              userConfig.displayChats ? "visible" : "hidden"
            };`),
            chatIsMine && (html += 'border-style: "solid";'),
            (html += `color: ${chatColor};`),
            (html += `font-size: ${chatSize}px;`),
            (html += `font-weight: ${userConfig.fontWeight};`),
            (html += `font-family: ${userConfig.font};`),
            (html += `opacity: ${userConfig.chatOpacity};`),
            (html += `animation-name: lane${chatLaneNum};`),
            (html += `animation-duration: ${chatSpeed}s;`),
            (html += `">${chatHTML}</span>`),
            document.querySelector(".fyc_chat_usable"))
          ) {
            const element = document.querySelectorAll(".fyc_chat_usable")
            element[element.length - 1].outerHTML = html
          } else
            external_log_default().debug("AppendChat"),
              null === (_c = document.querySelector(".fyc_chat_screen")) ||
                void 0 === _c ||
                _c.insertAdjacentHTML("beforeend", html)
        },
        external_m_namespaceObject = m
      var external_m_default = __webpack_require__.n(external_m_namespaceObject)
      const external_Swal_namespaceObject = Swal
      var external_Swal_default = __webpack_require__.n(
        external_Swal_namespaceObject
      )
      const logFyc = (...x) => external_log_default().info(`【FYC】 ${x}`),
        createNgButton = (chat, id, userConfig) => {
          var _a, _b, _c
          if (
            null === (_a = chat.children.namedItem("content")) || void 0 === _a
              ? void 0
              : _a.children.namedItem("fyc_ngbutton")
          )
            return
          if (chat.children.namedItem("card")) return
          const button = document.createElement("button")
          button.classList.add("style-scope", "yt-icon-button", "fyc_button"),
            (button.id = "fyc_ngbutton"),
            (button.style.padding = "0px"),
            (button.style.width = "20px"),
            (button.style.height = "20px"),
            button.setAttribute("aria-label", "NGに入れる"),
            (button.innerHTML =
              '<div style="width: 100%; height: 75%;fill: var(--yt-spec-text-secondary);"><svg class="style-scope yt-icon" width="100%" height="100%" version="1.1" viewBox="0 0 512 512" x="0px" y="0px"><path d="M437.023,74.977c-99.984-99.969-262.063-99.969-362.047,0c-99.969,99.984-99.969,262.063,0,362.047c99.969,99.969,262.078,99.969,362.047,0S536.992,174.945,437.023,74.977z M137.211,137.211c54.391-54.391,137.016-63.453,201.016-27.531L109.68,338.227C73.758,274.227,82.82,191.602,137.211,137.211z M374.805,374.789c-54.391,54.391-137.031,63.469-201.031,27.547l228.563-228.563C438.258,237.773,429.18,320.414,374.805,374.789z" fill-rule="evenodd"></path></svg></div>'),
            (button.onclick = () => {
              logFyc(`Added to Banned Users: ${id}`),
                userConfig.bannedUsers.push(id),
                GM.setValue("FYC_NG_USERS", userConfig.bannedUsers.join("\n")),
                external_m_default().redraw(),
                (chat.style.display = "none"),
                external_Swal_default()
                  .mixin({
                    toast: !0,
                    position: "bottom-left",
                    timer: 2500,
                    timerProgressBar: !0,
                    showConfirmButton: !1,
                    didOpen: toast => {
                      toast.addEventListener(
                        "mouseenter",
                        external_Swal_default().stopTimer
                      ),
                        toast.addEventListener(
                          "mouseleave",
                          external_Swal_default().resumeTimer
                        )
                    },
                  })
                  .fire({ title: `Added Banned User: ${id}`, icon: "success" })
            }),
            external_log_default().debug("AppendNgButton"),
            null ===
              (_c =
                null === (_b = chat.children.namedItem("content")) ||
                void 0 === _b
                  ? void 0
                  : _b.children.namedItem("message")) ||
              void 0 === _c ||
              _c.appendChild(button)
        },
        deleteOldChats = userConfig => {
          const chats = getFlowingChats()
          Array.from(chats)
            .slice(0, Math.max(0, chats.length - userConfig.maxChatCount))
            .forEach(x => {
              external_log_default().debug("RemoveOldChat"), x.remove()
            })
        },
        findChatsOutOfScreen = () => {
          const chats = getFlowingChats()
          for (let i = chats.length - 1; i >= 0; i -= 1) {
            const chat = chats[i],
              rect = chat.getBoundingClientRect()
            rect.x + rect.width <= 0 &&
              "fyc_chat fyc_chat_usable" !== chat.className &&
              (chat.className += " fyc_chat_usable")
          }
        },
        setChatFieldSimplifyStyle = (chat, simplify) => {
          if (
            ((chat.style.borderBottom = simplify
              ? "1px solid var(--yt-spec-text-secondary)"
              : "none"),
            chat.querySelector(
              ".style-scope.yt-live-chat-paid-message-renderer"
            ) || chat.querySelector(".owner"))
          )
            return
          const authorPhoto = chat.children.namedItem("author-photo")
          authorPhoto &&
            (authorPhoto.style.display = simplify ? "none" : "block")
          const authorChip = chat.querySelector(
            "yt-live-chat-author-chip.style-scope.yt-live-chat-text-message-renderer"
          )
          authorChip &&
            (authorChip.style.display = simplify ? "none" : "inline-flex")
        },
        componentMounter = (root, placeRoot) => component => {
          const success = placeRoot(root)
          return success && external_m_default().mount(root, component), success
        }
      var delay = __webpack_require__(228),
        delay_default = __webpack_require__.n(delay)
      const setChatFrameCss = () =>
          (async (func, count, interval) => {
            let exception,
              succeed = !1
            for (let i = 0; i < count; i += 1) {
              try {
                await func(i), (succeed = !0)
                break
              } catch (e) {
                exception = e
              }
              external_log_default().debug("Retry"),
                await delay_default()(interval)
            }
            if (!succeed) throw exception
          })(
            () => {
              var _a, _b
              const element =
                null ===
                  (_b =
                    null === (_a = document.querySelector("#chatframe")) ||
                    void 0 === _a
                      ? void 0
                      : _a.contentDocument) || void 0 === _b
                  ? void 0
                  : _b.querySelector(
                      "#item-scroller.animated.yt-live-chat-item-list-renderer #item-offset.yt-live-chat-item-list-renderer"
                    )
              element && (element.style.overflow = "unset")
            },
            5,
            1e3
          ),
        settingPanel_option = (value, label) =>
          external_m_default()("option", { value }, label),
        settingRow = (label, content) =>
          external_m_default()("div", [
            external_m_default()("span", label),
            external_m_default()("div", content),
          ]),
        textColorRow = (color, textStyle, oninput) =>
          external_m_default()("div", [
            external_m_default()("input", {
              type: "text",
              size: 10,
              maxlength: 30,
              value: color,
              oninput,
            }),
            external_m_default()(
              "span",
              { style: { ...textStyle, color } },
              "Aa1あア亜"
            ),
          ]),
        rangeRow = (min, max, step, value, oninput) =>
          external_m_default()("div", [
            external_m_default()("input", {
              className: "fyc_range",
              type: "range",
              min,
              max,
              step,
              value,
              oninput,
            }),
            external_m_default()("output", value),
          ]),
        checkboxRow = (label, checked, onchange) =>
          external_m_default()(
            "div",
            external_m_default()("label", [
              label,
              external_m_default()("input", {
                type: "checkbox",
                checked,
                onchange,
              }),
            ])
          ),
        getInputValue = e => {
          const target = e.currentTarget
          if (
            target instanceof HTMLSelectElement ||
            target instanceof HTMLTextAreaElement ||
            target instanceof HTMLInputElement
          )
            return target.value
          throw Error(
            "Event target isn't an Input or TextArea or Input element"
          )
        },
        langRecord = {
          FYC_EN: {
            language: "Language",
            font: "Font",
            color: "Color(Normal)",
            ownerColor: "Color(Owner)",
            moderatorColor: "Color(Moderator)",
            memberColor: "Color(Member)",
            feedback: "Give your feedbacks here",
            chatOpacity: "Opacity",
            fontSize: "Size",
            fontWeight: "Weight",
            shadowFontWeight: "Weight(Shadow)",
            flowSpeed: "Speed",
            maxChatCount: "Max number of chats",
            maxChatLength: "Max number of characters",
            laneCount: "Number of Line",
            bannedWords: "Banned Words",
            bannedWordRegexs: "Banned Words(Regexp)",
            bannedUsers: "Banned Users",
            simplifyChatField: "Simple Chat Field",
            createBanButton: "Show Button to Ban",
            displayModeratorName: "Show Moderator's Name",
            createChats: "Flow chats on screen",
            textOnly: "Text only(Ignore emojis)",
            reload: "Reload",
            save: "Save",
            error: "Error",
          },
          FYC_JA: {
            language: "言語",
            font: "フォント",
            color: "色(通常)",
            ownerColor: "色(オーナー)",
            moderatorColor: "色(モデレーター)",
            memberColor: "色(メンバー)",
            feedback: "バグ報告、要望はこちら",
            chatOpacity: "透明度",
            fontSize: "サイズ",
            fontWeight: "太さ",
            shadowFontWeight: "太さ(影)",
            flowSpeed: "速度",
            maxChatCount: "最大表示数",
            maxChatLength: "最大文字数",
            laneCount: "行数",
            bannedWords: "NGワード",
            bannedWordRegexs: "NGワード(正規表現)",
            bannedUsers: "NGユーザー",
            simplifyChatField: "チャット欄を簡略化する",
            createBanButton: "NGボタンを表示する",
            displayModeratorName: "モデレータの名前を表示する",
            createChats: "画面上にコメントを流す",
            textOnly: "文字のみ(絵文字を無視する)",
            reload: "再読み込み",
            save: "保存",
            error: "エラー",
          },
        },
        langOptions = [
          ["FYC_EN", "English"],
          ["FYC_JA", "日本語"],
        ],
        fontOptions = [
          ["", "Default", "デフォルト"],
          ["arial", "Arial", "Arial"],
          ["arial black", "Arial Black", "Arial Black"],
          ["arial narrow", "Arial Narrow", "Arial Narrow"],
          ["Century", "Century", "Century"],
          ["Comic Sans MS", "Comic Sans MS", "Comic Sans MS"],
          ["Courier", "Courier", "Courier"],
          ["cursive", "cursive", "cursive"],
          ["fantasy", "fantasy", "fantasy"],
          ["Impact", "Impact", "Impact"],
          ["Meiryo", "Meiryo", "メイリオ"],
          ["Meiryo UI", "Meiryo UI", "メイリオ UI"],
          ["monospace", "monospace", "monospace"],
          ["Monotype Corsiva", "Monotype Corsiva", "Monotype Corsiva"],
          ["MS PGothic", "MS PGothic", "MS Pゴシック"],
          ["MS Gothic", "MS Gothic", "MS ゴシック"],
          ["MS Sans Serif", "MS Sans Serif", "MS Sans Serif"],
          ["MS Serif", "MS Serif", "MS Serif"],
          ["MS UI Gothic", "MS UI Gothic", "MS UI Gothic"],
          ["sans-serif", "Sans-serif", "Sans-serif"],
          ["serif", "Serif", "Serif"],
          ["Times New Roman", "Times New Roman", "Times New Roman"],
          ["Yu Gothic", "Yu Gothic", "遊ゴシック"],
          ["YuGothic", "YuGothic", "游ゴシック体"],
        ],
        settingComponent = (reinitialize, userConfig) => {
          const state = { showPanel: !1 },
            panel = ((reinitialize, state, userConfig) => {
              const exampleTextStyle = () => ({
                  fontFamily: userConfig.font,
                  fontWeight: userConfig.fontWeight.toString(),
                }),
                textState = {
                  bannedWordRegexs: userConfig.bannedWordRegexs,
                  bannedWordRegexsValid: !0,
                  bannedWordRegexsError: "",
                },
                getLang = () => langRecord[userConfig.lang],
                langSelectChange$ = new external_rxjs_namespaceObject.Subject(),
                fontSelectChange$ = new external_rxjs_namespaceObject.Subject(),
                colorInputInput$ = new external_rxjs_namespaceObject.Subject(),
                colorOwnerInputInput$ = new external_rxjs_namespaceObject.Subject(),
                colorModeratorInputInput$ = new external_rxjs_namespaceObject.Subject(),
                colorMemberInputInput$ = new external_rxjs_namespaceObject.Subject(),
                chatOpacityInputInput$ = new external_rxjs_namespaceObject.Subject(),
                fontSizeInputInput$ = new external_rxjs_namespaceObject.Subject(),
                fontWeightInputInput$ = new external_rxjs_namespaceObject.Subject(),
                shadowFontWeightInputInput$ = new external_rxjs_namespaceObject.Subject(),
                flowSpeedInputInput$ = new external_rxjs_namespaceObject.Subject(),
                maxChatCountInputInput$ = new external_rxjs_namespaceObject.Subject(),
                maxChatLengthInputInput$ = new external_rxjs_namespaceObject.Subject(),
                laneCountInputInput$ = new external_rxjs_namespaceObject.Subject(),
                bannedWordsTextAreaChange$ = new external_rxjs_namespaceObject.Subject(),
                bannedWordRegexsTextAreaChange$ = new external_rxjs_namespaceObject.Subject(),
                bannedUsersTextAreaChange$ = new external_rxjs_namespaceObject.Subject(),
                simplifyChatFieldInputChange$ = new external_rxjs_namespaceObject.Subject(),
                createBanButtonInputChange$ = new external_rxjs_namespaceObject.Subject(),
                displayModeratorNameInputChange$ = new external_rxjs_namespaceObject.Subject(),
                createChatsInputChange$ = new external_rxjs_namespaceObject.Subject(),
                textOnlyInputChange$ = new external_rxjs_namespaceObject.Subject()
              return (
                (0, external_rxjs_namespaceObject.merge)(
                  langSelectChange$.pipe(
                    (0, external_rxjs_operators_namespaceObject.map)(
                      getInputValue
                    ),
                    (0, external_rxjs_operators_namespaceObject.tap)(x => {
                      ;(userConfig.lang = x), GM.setValue("FYC_LANG", x)
                    })
                  ),
                  fontSelectChange$.pipe(
                    (0, external_rxjs_operators_namespaceObject.map)(
                      getInputValue
                    ),
                    (0, external_rxjs_operators_namespaceObject.tap)(x => {
                      ;(userConfig.font = x), GM.setValue("FYC_FONT", x)
                    })
                  ),
                  colorInputInput$.pipe(
                    (0, external_rxjs_operators_namespaceObject.map)(
                      getInputValue
                    ),
                    (0, external_rxjs_operators_namespaceObject.tap)(x => {
                      ;(userConfig.color = x), GM.setValue("FYC_COLOR", x)
                    })
                  ),
                  colorOwnerInputInput$.pipe(
                    (0, external_rxjs_operators_namespaceObject.map)(
                      getInputValue
                    ),
                    (0, external_rxjs_operators_namespaceObject.tap)(x => {
                      ;(userConfig.colorOwner = x),
                        GM.setValue("FYC_COLOR_OWNER", x)
                    })
                  ),
                  colorModeratorInputInput$.pipe(
                    (0, external_rxjs_operators_namespaceObject.map)(
                      getInputValue
                    ),
                    (0, external_rxjs_operators_namespaceObject.tap)(x => {
                      ;(userConfig.colorModerator = x),
                        GM.setValue("FYC_COLOR_MODERATOR", x)
                    })
                  ),
                  colorMemberInputInput$.pipe(
                    (0, external_rxjs_operators_namespaceObject.map)(
                      getInputValue
                    ),
                    (0, external_rxjs_operators_namespaceObject.tap)(x => {
                      ;(userConfig.colorMember = x),
                        GM.setValue("FYC_COLOR_MEMBER", x)
                    })
                  ),
                  chatOpacityInputInput$.pipe(
                    (0, external_rxjs_operators_namespaceObject.map)(
                      getInputValue
                    ),
                    (0, external_rxjs_operators_namespaceObject.map)(
                      parseFloat
                    ),
                    (0, external_rxjs_operators_namespaceObject.tap)(x => {
                      ;(userConfig.chatOpacity = x),
                        GM.setValue("FYC_OPACITY", x)
                    })
                  ),
                  fontSizeInputInput$.pipe(
                    (0, external_rxjs_operators_namespaceObject.map)(
                      getInputValue
                    ),
                    (0, external_rxjs_operators_namespaceObject.map)(
                      parseFloat
                    ),
                    (0, external_rxjs_operators_namespaceObject.tap)(x => {
                      ;(userConfig.fontSize = x), GM.setValue("FYC_SIZE", x)
                    })
                  ),
                  fontWeightInputInput$.pipe(
                    (0, external_rxjs_operators_namespaceObject.map)(
                      getInputValue
                    ),
                    (0, external_rxjs_operators_namespaceObject.map)(
                      parseFloat
                    ),
                    (0, external_rxjs_operators_namespaceObject.tap)(x => {
                      ;(userConfig.fontWeight = x), GM.setValue("FYC_WEIGHT", x)
                    })
                  ),
                  shadowFontWeightInputInput$.pipe(
                    (0, external_rxjs_operators_namespaceObject.map)(
                      getInputValue
                    ),
                    (0, external_rxjs_operators_namespaceObject.map)(
                      parseFloat
                    ),
                    (0, external_rxjs_operators_namespaceObject.tap)(x => {
                      ;(userConfig.shadowFontWeight = x),
                        GM.setValue("FYC_WEIGHT_SHADOW", x),
                        reinitialize()
                    })
                  ),
                  flowSpeedInputInput$.pipe(
                    (0, external_rxjs_operators_namespaceObject.map)(
                      getInputValue
                    ),
                    (0, external_rxjs_operators_namespaceObject.map)(
                      parseFloat
                    ),
                    (0, external_rxjs_operators_namespaceObject.tap)(x => {
                      ;(userConfig.flowSpeed = x), GM.setValue("FYC_SPEED", x)
                    })
                  ),
                  maxChatCountInputInput$.pipe(
                    (0, external_rxjs_operators_namespaceObject.map)(
                      getInputValue
                    ),
                    (0, external_rxjs_operators_namespaceObject.map)(x =>
                      parseInt(x, 10)
                    ),
                    (0, external_rxjs_operators_namespaceObject.tap)(x => {
                      ;(userConfig.maxChatCount = x),
                        GM.setValue("FYC_LIMIT", x)
                    })
                  ),
                  maxChatLengthInputInput$.pipe(
                    (0, external_rxjs_operators_namespaceObject.map)(
                      getInputValue
                    ),
                    (0, external_rxjs_operators_namespaceObject.map)(x =>
                      parseInt(x, 10)
                    ),
                    (0, external_rxjs_operators_namespaceObject.tap)(x => {
                      ;(userConfig.maxChatLength = x), GM.setValue("FYC_MAX", x)
                    })
                  ),
                  laneCountInputInput$.pipe(
                    (0, external_rxjs_operators_namespaceObject.map)(
                      getInputValue
                    ),
                    (0, external_rxjs_operators_namespaceObject.map)(x =>
                      parseInt(x, 10)
                    ),
                    (0, external_rxjs_operators_namespaceObject.tap)(x => {
                      ;(userConfig.laneCount = x),
                        GM.setValue("FYC_LANE_DIV", x),
                        reinitialize()
                    })
                  ),
                  bannedWordsTextAreaChange$.pipe(
                    (0, external_rxjs_operators_namespaceObject.map)(
                      getInputValue
                    ),
                    (0, external_rxjs_operators_namespaceObject.map)(x =>
                      x.split(/\r\n|\n/).filter(word => "" !== word)
                    ),
                    (0, external_rxjs_operators_namespaceObject.tap)(x => {
                      ;(userConfig.bannedWords = x),
                        GM.setValue("FYC_NG_WORDS", x.join("\n"))
                    })
                  ),
                  bannedWordRegexsTextAreaChange$.pipe(
                    (0, external_rxjs_operators_namespaceObject.map)(
                      getInputValue
                    ),
                    (0, external_rxjs_operators_namespaceObject.map)(x =>
                      x.split(/\r\n|\n/).filter(regex => "" !== regex)
                    ),
                    (0, external_rxjs_operators_namespaceObject.tap)(x => {
                      textState.bannedWordRegexs = x
                      let valid = !0
                      ;(textState.bannedWordRegexsError = ""),
                        textState.bannedWordRegexs.forEach(regex => {
                          try {
                            new RegExp(regex)
                          } catch (error) {
                            logFyc(`Invalid Regex: ${regex}`),
                              external_log_default().warn(error),
                              (textState.bannedWordRegexsError += `${error} in ${regex};`),
                              (valid = !1)
                          }
                        }),
                        valid &&
                          ((userConfig.bannedWordRegexs = x),
                          GM.setValue("FYC_NG_REG_WORDS", x.join("\n"))),
                        (textState.bannedWordRegexsValid = valid)
                    })
                  ),
                  bannedUsersTextAreaChange$.pipe(
                    (0, external_rxjs_operators_namespaceObject.map)(
                      getInputValue
                    ),
                    (0, external_rxjs_operators_namespaceObject.map)(x =>
                      x.split(/\r\n|\n/).filter(user => "" !== user)
                    ),
                    (0, external_rxjs_operators_namespaceObject.tap)(x => {
                      ;(userConfig.bannedUsers = x),
                        GM.setValue("FYC_NG_USERS", x.join("\n"))
                    })
                  ),
                  simplifyChatFieldInputChange$.pipe(
                    (0, external_rxjs_operators_namespaceObject.map)(
                      e => tapIs(HTMLInputElement, e.currentTarget).checked
                    ),
                    (0, external_rxjs_operators_namespaceObject.tap)(x => {
                      ;(userConfig.simplifyChatField = x),
                        GM.setValue("FYC_SIMPLE_CHAT_FIELD", x)
                    })
                  ),
                  createBanButtonInputChange$.pipe(
                    (0, external_rxjs_operators_namespaceObject.map)(
                      e => tapIs(HTMLInputElement, e.currentTarget).checked
                    ),
                    (0, external_rxjs_operators_namespaceObject.tap)(x => {
                      ;(userConfig.createBanButtons = x),
                        GM.setValue("FYC_NG_BUTTON", x)
                    })
                  ),
                  displayModeratorNameInputChange$.pipe(
                    (0, external_rxjs_operators_namespaceObject.map)(
                      e => tapIs(HTMLInputElement, e.currentTarget).checked
                    ),
                    (0, external_rxjs_operators_namespaceObject.tap)(x => {
                      ;(userConfig.displayModeratorName = x),
                        GM.setValue("FYC_DISPLAY_MODERATOR_NAME", x)
                    })
                  ),
                  createChatsInputChange$.pipe(
                    (0, external_rxjs_operators_namespaceObject.map)(
                      e => tapIs(HTMLInputElement, e.currentTarget).checked
                    ),
                    (0, external_rxjs_operators_namespaceObject.tap)(x => {
                      ;(userConfig.createChats = x),
                        GM.setValue("FYC_TOGGLE_CREATE_COMMENTS", x)
                    })
                  ),
                  textOnlyInputChange$.pipe(
                    (0, external_rxjs_operators_namespaceObject.map)(
                      e => tapIs(HTMLInputElement, e.currentTarget).checked
                    ),
                    (0, external_rxjs_operators_namespaceObject.tap)(x => {
                      ;(userConfig.textOnly = x),
                        GM.setValue("FYC_TEXT_ONLY", x)
                    })
                  )
                ).subscribe(),
                {
                  view: () =>
                    external_m_default()(
                      "div",
                      {
                        className: "fyc_panel",
                        style: {
                          visibility: state.showPanel ? "visible" : "hidden",
                        },
                      },
                      [
                        external_m_default()(
                          "div",
                          { className: "fyc_panel_box" },
                          [
                            settingRow(getLang().language, [
                              external_m_default()(
                                "select",
                                {
                                  style: { width: "60%" },
                                  selectedIndex: langOptions.findIndex(
                                    x => x[0] === userConfig.lang
                                  ),
                                  onchange: lib(langSelectChange$),
                                },
                                langOptions.map(x => settingPanel_option(...x))
                              ),
                            ]),
                            settingRow(getLang().font, [
                              external_m_default()(
                                "select",
                                {
                                  style: { width: "60%" },
                                  selectedIndex: fontOptions.findIndex(
                                    x => x[0] === userConfig.font
                                  ),
                                  onchange: lib(fontSelectChange$),
                                },
                                fontOptions.map(x =>
                                  settingPanel_option(
                                    x[0],
                                    "FYC_JA" === userConfig.lang ? x[2] : x[1]
                                  )
                                )
                              ),
                            ]),
                            settingRow(getLang().color, [
                              textColorRow(
                                userConfig.color,
                                exampleTextStyle(),
                                lib(colorInputInput$)
                              ),
                            ]),
                            settingRow(getLang().ownerColor, [
                              textColorRow(
                                userConfig.colorOwner,
                                exampleTextStyle(),
                                lib(colorOwnerInputInput$)
                              ),
                            ]),
                            settingRow(getLang().moderatorColor, [
                              textColorRow(
                                userConfig.colorModerator,
                                exampleTextStyle(),
                                lib(colorModeratorInputInput$)
                              ),
                            ]),
                            settingRow(getLang().memberColor, [
                              textColorRow(
                                userConfig.colorMember,
                                exampleTextStyle(),
                                lib(colorMemberInputInput$)
                              ),
                            ]),
                            external_m_default()(
                              "div",
                              {
                                style: {
                                  textAlign: "right",
                                  margin: "3px 6px",
                                },
                              },
                              external_m_default()(
                                "a",
                                {
                                  style: { color: "white" },
                                  href:
                                    "https://gf.qytechs.cn/en/scripts/411442-flow-youtube-chat/feedback",
                                  target: "_blank",
                                },
                                getLang().feedback
                              )
                            ),
                          ]
                        ),
                        external_m_default()(
                          "div",
                          { className: "fyc_panel_box" },
                          [
                            settingRow(getLang().chatOpacity, [
                              rangeRow(
                                0,
                                1,
                                0.1,
                                userConfig.chatOpacity,
                                lib(chatOpacityInputInput$)
                              ),
                            ]),
                            settingRow(getLang().fontSize, [
                              rangeRow(
                                0.1,
                                2,
                                0.1,
                                userConfig.fontSize,
                                lib(fontSizeInputInput$)
                              ),
                            ]),
                            settingRow(getLang().fontWeight, [
                              rangeRow(
                                10,
                                1e3,
                                10,
                                userConfig.fontWeight,
                                lib(fontWeightInputInput$)
                              ),
                            ]),
                            settingRow(getLang().shadowFontWeight, [
                              rangeRow(
                                0,
                                3,
                                0.1,
                                userConfig.shadowFontWeight,
                                lib(shadowFontWeightInputInput$)
                              ),
                            ]),
                            settingRow(getLang().flowSpeed, [
                              rangeRow(
                                1,
                                50,
                                1,
                                userConfig.flowSpeed,
                                lib(flowSpeedInputInput$)
                              ),
                            ]),
                            settingRow(getLang().maxChatCount, [
                              rangeRow(
                                5,
                                200,
                                5,
                                userConfig.maxChatCount,
                                lib(maxChatCountInputInput$)
                              ),
                            ]),
                            settingRow(getLang().maxChatLength, [
                              rangeRow(
                                5,
                                200,
                                5,
                                userConfig.maxChatLength,
                                lib(maxChatLengthInputInput$)
                              ),
                            ]),
                            settingRow(getLang().laneCount, [
                              rangeRow(
                                1,
                                20,
                                1,
                                userConfig.laneCount,
                                lib(laneCountInputInput$)
                              ),
                            ]),
                          ]
                        ),
                        external_m_default()(
                          "div",
                          { className: "fyc_panel_box" },
                          [
                            settingRow(getLang().bannedWords, [
                              external_m_default()(
                                "textarea",
                                {
                                  rows: 4,
                                  style: {
                                    resize: "horizontal",
                                    width: "190px",
                                  },
                                  onchange: lib(bannedWordsTextAreaChange$),
                                },
                                userConfig.bannedWords.join("\n")
                              ),
                            ]),
                            settingRow(
                              `${getLang().bannedWordRegexs}${
                                textState.bannedWordRegexsValid
                                  ? ""
                                  : `${getLang().error}: ${
                                      textState.bannedWordRegexsError
                                    }`
                              }`,
                              [
                                external_m_default()(
                                  "textarea",
                                  {
                                    rows: 4,
                                    style: {
                                      resize: "horizontal",
                                      width: "190px",
                                    },
                                    onchange: lib(
                                      bannedWordRegexsTextAreaChange$
                                    ),
                                  },
                                  textState.bannedWordRegexs.join("\n")
                                ),
                              ]
                            ),
                            settingRow(getLang().bannedUsers, [
                              external_m_default()(
                                "textarea",
                                {
                                  rows: 4,
                                  style: {
                                    resize: "horizontal",
                                    width: "190px",
                                  },
                                  onchange: lib(bannedUsersTextAreaChange$),
                                },
                                userConfig.bannedUsers.join("\n")
                              ),
                            ]),
                            checkboxRow(
                              getLang().simplifyChatField,
                              userConfig.simplifyChatField,
                              lib(simplifyChatFieldInputChange$)
                            ),
                            checkboxRow(
                              getLang().createBanButton,
                              userConfig.createBanButtons,
                              lib(createBanButtonInputChange$)
                            ),
                            checkboxRow(
                              getLang().displayModeratorName,
                              userConfig.displayModeratorName,
                              lib(displayModeratorNameInputChange$)
                            ),
                            checkboxRow(
                              getLang().createChats,
                              userConfig.createChats,
                              lib(createChatsInputChange$)
                            ),
                            checkboxRow(
                              getLang().textOnly,
                              userConfig.textOnly,
                              lib(textOnlyInputChange$)
                            ),
                          ]
                        ),
                      ]
                    ),
                }
              )
            })(reinitialize, state, userConfig),
            toggleButton = ((state, userConfig) => {
              const click$ = new external_rxjs_namespaceObject.Subject()
              return (
                click$
                  .pipe(
                    (0, external_rxjs_operators_namespaceObject.tap)(() => {
                      state.showPanel = !state.showPanel
                    })
                  )
                  .subscribe(),
                {
                  view: () =>
                    external_m_default()(
                      "button",
                      {
                        className: "fyc_button",
                        style: {
                          background: "rgba(0,0,0,0)",
                          marginLeft: "10px",
                          whiteSpace: "nowrap",
                        },
                        onclick: lib(click$),
                      },
                      [
                        external_m_default()(
                          "svg",
                          {
                            preserveAspectRatio: "xMidYMid meet",
                            viewBox: "0 0 640 640",
                            width: "15",
                            height: "15",
                            style: { position: "relative", top: "1px" },
                          },
                          [
                            external_m_default()(
                              "defs",
                              external_m_default()("path", {
                                id: "d1TbzTC1zI",
                                d:
                                  "M135.38 58.17L136.02 58.22L136.65 58.29L137.3 58.39L137.95 58.52L138.61 58.66L139.27 58.83L139.94 59.01L140.61 59.22L141.29 59.45L141.98 59.7L142.66 59.96L143.35 60.25L144.05 60.55L144.74 60.87L145.44 61.2L146.15 61.55L146.85 61.92L147.56 62.3L148.27 62.69L148.97 63.1L149.69 63.52L150.4 63.95L151.11 64.4L196.98 91.31L197.88 90.81L206.8 86.34L215.92 82.22L216.84 81.84L216.84 224.11L214.42 226.66L210.89 230.67L207.51 234.82L204.29 239.1L201.23 243.51L198.33 248.04L195.6 252.69L193.05 257.45L190.68 262.32L188.49 267.29L186.49 272.36L184.67 277.53L183.06 282.79L181.65 288.14L180.44 293.57L179.44 299.08L178.66 304.65L178.09 310.3L177.75 316.01L177.63 321.78L177.75 327.56L178.09 333.27L178.66 338.91L179.44 344.49L180.44 350L181.65 355.43L183.06 360.77L184.67 366.04L186.49 371.2L188.49 376.28L190.68 381.25L193.05 386.12L195.6 390.88L198.33 395.53L201.23 400.06L204.29 404.47L207.51 408.75L210.89 412.89L214.42 416.91L218.1 420.78L221.92 424.51L225.88 428.08L229.97 431.51L234.2 434.77L238.54 437.87L243.01 440.81L247.6 443.57L252.3 446.16L257.1 448.56L262.01 450.78L267.02 452.81L272.12 454.65L277.31 456.28L282.59 457.72L287.95 458.94L293.38 459.95L298.89 460.75L304.46 461.32L310.09 461.67L315.79 461.78L321.48 461.67L327.12 461.32L332.69 460.75L338.2 459.95L343.63 458.94L348.99 457.72L354.27 456.28L359.46 454.65L364.56 452.81L369.57 450.78L374.48 448.56L379.28 446.16L383.98 443.57L388.57 440.81L393.03 437.87L397.38 434.77L401.61 431.51L405.7 428.08L409.66 424.51L413.48 420.78L417.16 416.91L420.69 412.89L424.07 408.75L427.29 404.47L430.35 400.06L433.25 395.53L435.97 390.88L438.53 386.12L440.9 381.25L443.09 376.28L445.09 371.2L446.9 366.04L448.52 360.77L449.93 355.43L451.14 350L452.14 344.49L452.92 338.91L453.49 333.27L453.83 327.56L453.95 321.78L453.83 316.01L453.77 314.95L487.06 314.95L627.33 378.59L627.31 378.6L626.83 379L626.32 379.38L625.8 379.75L625.25 380.11L624.68 380.47L624.1 380.81L623.5 381.15L622.87 381.48L622.24 381.8L621.58 382.11L620.91 382.42L620.22 382.72L619.52 383.01L618.81 383.31L618.08 383.59L617.34 383.87L616.58 384.15L615.82 384.43L615.04 384.7L614.26 384.98L613.46 385.25L612.66 385.52L611.84 385.78L560.61 399.62L559.29 403.96L555.92 413.56L552.21 422.99L548.14 432.23L543.73 441.27L543.23 442.18L569.79 488.66L570.23 489.38L570.65 490.1L571.07 490.82L571.47 491.54L571.86 492.26L572.24 492.98L572.6 493.69L572.94 494.4L573.27 495.11L573.59 495.82L573.89 496.52L574.17 497.22L574.43 497.92L574.67 498.61L574.9 499.3L575.1 499.98L575.29 500.65L575.45 501.33L575.59 501.99L575.71 502.65L575.81 503.31L575.89 503.96L575.94 504.6L575.96 505.23L575.97 505.85L575.94 506.47L575.89 507.08L575.81 507.68L575.71 508.27L575.58 508.86L575.42 509.43L575.22 510L575 510.55L574.75 511.09L574.47 511.63L574.16 512.15L573.81 512.66L573.44 513.16L573.03 513.64L572.58 514.12L505.59 582L505.12 582.45L504.65 582.86L504.16 583.24L503.67 583.58L503.16 583.89L502.65 584.16L502.12 584.4L501.59 584.61L501.05 584.79L500.5 584.93L499.94 585.05L499.38 585.14L498.8 585.2L498.22 585.23L497.63 585.24L497.03 585.22L496.42 585.18L495.8 585.11L495.18 585.02L494.55 584.9L493.91 584.77L493.26 584.61L492.61 584.44L491.95 584.24L491.28 584.03L490.6 583.8L489.92 583.55L489.23 583.29L488.54 583.01L487.83 582.71L487.13 582.41L486.41 582.09L485.69 581.76L484.96 581.42L484.23 581.06L483.49 580.7L482.74 580.33L481.99 579.95L481.23 579.56L480.47 579.17L434.6 552.26L433.7 552.76L424.78 557.23L415.66 561.35L406.36 565.12L396.89 568.53L392.6 569.87L378.95 621.78L378.68 622.61L378.42 623.42L378.15 624.23L377.88 625.03L377.61 625.81L377.34 626.59L377.06 627.35L376.78 628.1L376.5 628.84L376.21 629.57L375.92 630.28L375.62 630.97L375.32 631.65L375.01 632.32L374.69 632.96L374.37 633.59L374.04 634.2L373.7 634.8L373.35 635.37L372.99 635.92L372.63 636.46L372.25 636.97L371.86 637.46L371.46 637.92L371.05 638.37L370.63 638.79L370.19 639.18L369.74 639.55L369.28 639.89L368.8 640.21L368.31 640.5L367.81 640.76L367.29 641L366.75 641.2L366.19 641.38L365.62 641.52L365.03 641.64L364.43 641.72L363.8 641.77L363.16 641.78L268.42 641.78L267.78 641.77L267.14 641.72L266.53 641.64L265.93 641.52L265.34 641.38L264.77 641.2L264.22 641L263.68 640.76L263.15 640.5L262.63 640.21L262.13 639.89L261.64 639.55L261.17 639.18L260.71 638.79L260.26 638.37L259.83 637.92L259.4 637.46L258.99 636.97L258.59 636.46L258.21 635.92L257.83 635.37L257.47 634.8L257.11 634.2L256.77 633.59L256.44 632.96L256.12 632.32L255.81 631.65L255.51 630.97L255.22 630.28L254.94 629.57L254.67 628.84L254.41 628.1L254.16 627.35L253.91 626.59L253.68 625.81L253.45 625.03L253.24 624.23L253.03 623.42L252.82 622.61L252.63 621.78L238.98 569.87L234.69 568.53L225.22 565.12L215.92 561.35L206.8 557.23L197.88 552.76L196.8 552.17L151.11 578.98L150.4 579.42L149.69 579.86L148.97 580.28L148.27 580.68L147.56 581.08L146.85 581.46L146.15 581.83L145.44 582.18L144.74 582.51L144.05 582.83L143.35 583.13L142.66 583.42L141.98 583.68L141.29 583.93L140.61 584.16L139.94 584.36L139.27 584.55L138.61 584.72L137.95 584.86L137.3 584.98L136.65 585.08L136.02 585.16L135.38 585.21L134.76 585.24L134.14 585.24L133.53 585.21L132.93 585.16L132.34 585.08L131.75 584.98L131.18 584.84L130.61 584.68L130.05 584.49L129.51 584.26L128.97 584.01L128.45 583.73L127.93 583.41L127.43 583.06L126.94 582.68L126.46 582.26L125.99 581.81L59 513.93L58.55 513.45L58.15 512.97L57.78 512.48L57.44 511.98L57.14 511.46L56.87 510.94L56.63 510.41L56.42 509.87L56.25 509.33L56.1 508.77L55.99 508.2L55.9 507.63L55.84 507.05L55.81 506.45L55.8 505.85L55.82 505.25L55.86 504.63L55.93 504.01L56.02 503.37L56.13 502.73L56.27 502.09L56.42 501.43L56.59 500.77L56.78 500.1L57 499.42L57.22 498.74L57.47 498.05L57.73 497.35L58 496.64L58.29 495.93L58.59 495.21L58.91 494.49L59.24 493.76L59.57 493.02L59.92 492.28L60.28 491.53L60.65 490.77L61.02 490.01L61.4 489.24L61.79 488.47L88.29 442.09L87.85 441.27L83.44 432.23L79.37 422.99L75.65 413.56L72.29 403.96L70.96 399.62L19.74 385.78L18.92 385.52L18.12 385.25L17.32 384.98L16.54 384.7L15.76 384.43L15 384.15L14.24 383.87L13.5 383.59L12.77 383.31L12.06 383.01L11.36 382.72L10.67 382.42L10 382.11L9.34 381.8L8.7 381.48L8.08 381.15L7.48 380.81L6.9 380.47L6.33 380.11L5.78 379.75L5.26 379.38L4.75 379L4.27 378.6L3.81 378.2L3.37 377.78L2.96 377.35L2.57 376.91L2.2 376.46L1.87 375.99L1.55 375.51L1.27 375.01L1.01 374.5L0.78 373.97L0.57 373.42L0.4 372.86L0.26 372.28L0.15 371.68L0.07 371.07L0.02 370.44L0 369.78L0 273.78L0.02 273.13L0.07 272.49L0.15 271.87L0.26 271.26L0.4 270.67L0.57 270.09L0.78 269.52L1.01 268.98L1.27 268.44L1.55 267.92L1.87 267.41L2.2 266.92L2.57 266.44L2.96 265.97L3.37 265.52L3.81 265.07L4.27 264.65L4.75 264.23L5.26 263.83L5.78 263.43L6.33 263.05L6.9 262.68L7.48 262.33L8.08 261.98L8.7 261.64L9.34 261.32L10 261L10.67 260.7L11.36 260.41L12.06 260.12L12.77 259.85L13.5 259.58L14.24 259.33L15 259.08L15.76 258.84L16.54 258.62L17.32 258.4L18.12 258.18L18.92 257.98L19.74 257.78L70.96 243.95L72.29 239.6L75.65 230L79.37 220.58L83.44 211.34L87.85 202.3L88.35 201.39L61.79 154.91L61.4 154.13L61.02 153.37L60.65 152.61L60.28 151.85L59.92 151.1L59.57 150.36L59.24 149.62L58.91 148.89L58.59 148.16L58.29 147.45L58 146.73L57.73 146.03L57.47 145.33L57.22 144.64L57 143.96L56.78 143.28L56.59 142.61L56.42 141.95L56.27 141.29L56.13 140.64L56.02 140L55.93 139.37L55.86 138.75L55.82 138.13L55.8 137.52L55.81 136.92L55.84 136.33L55.9 135.75L55.99 135.17L56.1 134.61L56.25 134.05L56.42 133.5L56.63 132.96L56.87 132.43L57.14 131.91L57.44 131.4L57.78 130.9L58.15 130.41L58.55 129.92L59 129.45L125.99 61.57L126.46 61.12L126.94 60.7L127.43 60.32L127.93 59.97L128.45 59.65L128.97 59.37L129.51 59.11L130.05 58.89L130.61 58.7L131.18 58.53L131.75 58.4L132.34 58.29L132.93 58.21L133.53 58.16L134.14 58.14L134.76 58.14L135.38 58.17ZM576.75 2.01L579.53 2.29L582.28 2.69L584.99 3.18L587.66 3.79L590.29 4.49L592.88 5.3L595.42 6.2L597.92 7.2L600.37 8.29L602.76 9.47L605.11 10.75L607.39 12.11L609.62 13.55L611.79 15.08L613.9 16.68L615.94 18.37L617.91 20.13L619.82 21.96L621.65 23.87L623.41 25.84L625.1 27.89L626.71 29.99L628.23 32.16L629.68 34.39L631.04 36.68L632.31 39.02L633.49 41.42L634.59 43.86L635.58 46.36L636.49 48.91L637.29 51.49L638 54.13L638.6 56.8L639.1 59.51L639.49 62.25L639.77 65.03L639.94 67.84L640 70.68L640 208.48L639.94 211.32L639.77 214.13L639.49 216.91L639.1 219.66L638.6 222.37L638 225.04L637.29 227.67L636.49 230.26L635.58 232.8L634.59 235.3L633.49 237.75L632.31 240.14L631.04 242.49L629.68 244.77L628.23 247L626.71 249.17L625.1 251.28L623.41 253.32L621.65 255.29L619.82 257.2L617.91 259.03L615.94 260.79L613.9 262.48L611.79 264.09L609.62 265.61L607.39 267.06L605.11 268.42L602.76 269.69L601.78 270.18L623.59 340.98L481.84 277.38L326.79 277.38L323.95 277.32L321.14 277.15L318.36 276.87L315.62 276.48L312.91 275.98L310.24 275.38L307.6 274.67L305.02 273.87L302.47 272.96L299.97 271.96L297.53 270.87L295.13 269.69L292.79 268.42L290.5 267.06L288.27 265.61L286.1 264.09L284 262.48L281.95 260.79L279.98 259.03L278.07 257.2L276.24 255.29L274.48 253.32L272.8 251.28L271.19 249.17L269.66 247L268.22 244.77L266.86 242.49L265.59 240.14L264.4 237.75L263.31 235.3L262.31 232.8L261.41 230.26L260.6 227.67L259.9 225.04L259.29 222.37L258.8 219.66L258.41 216.91L258.12 214.13L257.95 211.32L257.89 208.48L257.89 70.68L257.95 67.84L258.12 65.03L258.41 62.25L258.8 59.51L259.29 56.8L259.9 54.13L260.6 51.49L261.41 48.91L262.31 46.36L263.31 43.86L264.4 41.42L265.59 39.02L266.86 36.68L268.22 34.39L269.66 32.16L271.19 29.99L272.8 27.89L274.48 25.84L276.24 23.87L278.07 21.96L279.98 20.13L281.95 18.37L284 16.68L286.1 15.08L288.27 13.55L290.5 12.11L292.79 10.75L295.13 9.47L297.53 8.29L299.97 7.2L302.47 6.2L305.02 5.3L307.6 4.49L310.24 3.79L312.91 3.18L315.62 2.69L318.36 2.29L321.14 2.01L323.95 1.84L326.79 1.78L571.1 1.78L573.94 1.84L576.75 2.01Z",
                              })
                            ),
                            external_m_default()("use", {
                              "xlink:href": "#d1TbzTC1zI",
                              opacity: "1",
                              fill: "var(--iron-icon-fill-color, currentcolor)",
                              "fill-opacity": "1",
                            }),
                          ]
                        ),
                        external_m_default()(
                          "span",
                          {
                            style: {
                              position: "relative",
                              top: "-2px",
                              marginLeft: "8px,",
                            },
                          },
                          "FYC_JA" === userConfig.lang ? "設定" : "Settings"
                        ),
                      ]
                    ),
                }
              )
            })(state, userConfig)
          return {
            view: () =>
              external_m_default()("span", { style: { display: "contents" } }, [
                external_m_default()(panel),
                external_m_default()(toggleButton),
              ]),
          }
        },
        requirementMet = () =>
          livePage_getChatFrame() &&
          livePage_getChatField() &&
          livePage_getPlayer(),
        initialize = async () => {
          logFyc("Script started")
          const reinitSubject = new external_rxjs_namespaceObject.Subject(),
            userConfig = await (async () => ({
              lang: tapNonNull(await GM.getValue("FYC_LANG", "FYC_EN")),
              font: tapNonNull(await GM.getValue("FYC_FONT", "")),
              chatOpacity: tapNonNull(await GM.getValue("FYC_OPACITY", 1)),
              color: tapNonNull(await GM.getValue("FYC_COLOR", "#FFFFFF")),
              colorOwner: tapNonNull(
                await GM.getValue("FYC_COLOR_OWNER", "#ffd600")
              ),
              colorModerator: tapNonNull(
                await GM.getValue("FYC_COLOR_MODERATOR", "#5e84f1")
              ),
              colorMember: tapNonNull(
                await GM.getValue("FYC_COLOR_MEMBER", "#2ba640")
              ),
              fontSize: tapNonNull(await GM.getValue("FYC_SIZE", 1)),
              fontWeight: tapNonNull(await GM.getValue("FYC_WEIGHT", 730)),
              shadowFontWeight: tapNonNull(
                await GM.getValue("FYC_WEIGHT_SHADOW", 1)
              ),
              maxChatCount: tapNonNull(await GM.getValue("FYC_LIMIT", 25)),
              flowSpeed: tapNonNull(await GM.getValue("FYC_SPEED", 18)),
              maxChatLength: tapNonNull(await GM.getValue("FYC_MAX", 100)),
              laneCount: tapNonNull(await GM.getValue("FYC_LANE_DIV", 12)),
              bannedWords: tapNonNull(await GM.getValue("FYC_NG_WORDS", ""))
                .split(/\r\n|\n/)
                .filter(x => "" !== x),
              bannedWordRegexs: tapNonNull(
                await GM.getValue("FYC_NG_REG_WORDS", "")
              )
                .split(/\r\n|\n/)
                .filter(x => "" !== x),
              bannedUsers: tapNonNull(await GM.getValue("FYC_NG_USERS", ""))
                .split(/\r\n|\n/)
                .filter(x => "" !== x),
              createChats: tapNonNull(
                await GM.getValue("FYC_TOGGLE_CREATE_COMMENTS", !0)
              ),
              displayChats: tapNonNull(
                await GM.getValue("FYC_DISPLAY_COMMENTS", !0)
              ),
              createBanButtons: tapNonNull(
                await GM.getValue("FYC_NG_BUTTON", !0)
              ),
              simplifyChatField: tapNonNull(
                await GM.getValue("FYC_SIMPLE_CHAT_FIELD", !1)
              ),
              displayModeratorName: tapNonNull(
                await GM.getValue("FYC_DISPLAY_MODERATOR_NAME", !0)
              ),
              textOnly: tapNonNull(await GM.getValue("FYC_TEXT_ONLY", !1)),
            }))(),
            chatObserver = (userConfig =>
              new MutationObserver(mutations => {
                mutations.forEach(e => {
                  const addedChats = Array.from(e.addedNodes).filter(
                    x => x.children.length > 0
                  )
                  if (!(addedChats.length <= 0))
                    for (let i = 0; i < addedChats.length; i += 1) {
                      const chat = addedChats[i],
                        chatData = convertChat(chat, userConfig)
                      checkBannedWords(chatData, userConfig) ||
                      checkBannedRegexpWords(chatData, userConfig) ||
                      checkBannedUsers(chatData, userConfig)
                        ? (chat.style.display = "none")
                        : ((chat.style.display =
                            chat.querySelectorAll(
                              ".style-scope.yt-live-chat-paid-message-renderer"
                            ).length > 0
                              ? "block"
                              : "flex"),
                          userConfig.createChats &&
                            (findChatsOutOfScreen(),
                            createChat(chatData, userConfig)),
                          userConfig.createBanButtons &&
                            chatData.authorID &&
                            !chat.querySelector(".owner") &&
                            createNgButton(chat, chatData.authorID, userConfig),
                          setChatFieldSimplifyStyle(
                            chat,
                            userConfig.simplifyChatField
                          ),
                          deleteOldChats(userConfig))
                    }
                })
              }))(userConfig),
            reinitialize = lib(reinitSubject)
          let chatField
          const toggleChatBtn = (userConfig => {
              const click$ = new external_rxjs_namespaceObject.Subject()
              click$
                .pipe(
                  (0, external_rxjs_operators_namespaceObject.tap)(() => {
                    const newDisplay = !userConfig.displayChats
                    getFlowingChats().forEach(x => {
                      x.style.visibility = newDisplay ? "visible" : "hidden"
                    }),
                      (userConfig.displayChats = newDisplay),
                      GM.setValue("FYC_DISPLAY_COMMENTS", newDisplay)
                  })
                )
                .subscribe()
              const label = () =>
                "コメント" + (userConfig.displayChats ? "非表示" : "表示")
              return {
                view: () =>
                  external_m_default()(
                    "button",
                    {
                      className: ["ytp-button", "fyc-chat-button"].join(" "),
                      type: "button",
                      "aria-label": label(),
                      title: label(),
                      onclick: lib(click$),
                    },
                    [
                      external_m_default()(
                        "svg",
                        { style: { width: "100%" }, viewBox: "0 0 36 36" },
                        [
                          external_m_default()("path", {
                            className: ["chat-button-path"].join(" "),
                            d:
                              "M 11 12 L 28 12 Q 29 12 29 13 L 29 22 Q 29 23 28 23 L 27 23 L 27 25 L 23 23 L 11 23 Q 10 23 10 22 L 10 13 Q 10 12 11 12 Z",
                            fill: "#fff",
                            "fill-opacity": userConfig.displayChats ? "1" : "0",
                            stroke: "#fff",
                            "stroke-width": "2",
                          }),
                        ]
                      ),
                    ]
                  ),
              }
            })(userConfig),
            mountToggleChatBtn = componentMounter(
              document.createElement("span"),
              x => {
                const parent = document.querySelector(".ytp-right-controls")
                return (
                  parent && (parent.append(x), (x.style.display = "contents")),
                  Boolean(parent)
                )
              }
            ),
            settingComp = settingComponent(reinitialize, userConfig),
            mountSettingComp = componentMounter(
              document.createElement("span"),
              x => {
                const parent = document.querySelector(
                  "#menu-container .dropdown-trigger.style-scope.ytd-menu-renderer"
                )
                return (
                  parent &&
                    (parent.insertAdjacentElement("beforebegin", x),
                    (x.style.display = "contents")),
                  Boolean(parent)
                )
              }
            )
          external_log_default().debug("Append ToggleChatDisplayButton")
          reinitSubject
            .pipe(
              (0, external_rxjs_operators_namespaceObject.observeOn)(
                external_rxjs_namespaceObject.asyncScheduler
              ),
              (0, external_rxjs_operators_namespaceObject.switchMap)(() =>
                (0, external_rxjs_namespaceObject.interval)(800).pipe(
                  (0, external_rxjs_operators_namespaceObject.startWith)(0),
                  (0, external_rxjs_operators_namespaceObject.map)(
                    requirementMet
                  ),
                  (0, external_rxjs_operators_namespaceObject.filter)(() => {
                    var _a, _b
                    const chatFieldLost =
                      chatField &&
                      !(null ===
                        (_b =
                          null === (_a = livePage_getChatFrame()) ||
                          void 0 === _a
                            ? void 0
                            : _a.contentDocument) || void 0 === _b
                        ? void 0
                        : _b.contains(chatField)) &&
                      !document.contains(chatField)
                    return (
                      chatFieldLost &&
                        (logFyc("Chat container changed"),
                        (chatField = void 0),
                        reinitialize()),
                      !chatFieldLost
                    )
                  }),
                  (0, external_rxjs_operators_namespaceObject.startWith)(!1),
                  (0,
                  external_rxjs_operators_namespaceObject.distinctUntilChanged)(),
                  (0, external_rxjs_operators_namespaceObject.tap)(x =>
                    logFyc(
                      x
                        ? "Found the chat container and the player"
                        : "Waiting to load..."
                    )
                  ),
                  (0, external_rxjs_operators_namespaceObject.filter)(Boolean)
                )
              ),
              (0, external_rxjs_operators_namespaceObject.tap)(() =>
                logFyc("Wait for 3000ms...")
              ),
              (0, external_rxjs_operators_namespaceObject.delay)(3e3),
              (0, external_rxjs_operators_namespaceObject.tap)(() =>
                logFyc("Initializing...")
              ),
              (0, external_rxjs_operators_namespaceObject.tap)(() => {
                var _a
                chatObserver.disconnect(),
                  (chatField = livePage_getChatField()),
                  chatField
                    ? chatObserver.observe(chatField, { childList: !0 })
                    : reinitialize(),
                  document.querySelector(".fyc_chat_screen") ||
                    (external_log_default().debug("AppendChatScreen"),
                    null === (_a = livePage_getPlayer()) ||
                      void 0 === _a ||
                      _a.insertAdjacentHTML(
                        "afterbegin",
                        '<div class="fyc_chat_screen" style="pointer-events: none;"></div>'
                      )),
                  mountToggleChatBtn(toggleChatBtn),
                  mountSettingComp(settingComp),
                  (userConfig => {
                    var _a, _b, _c, _d, _e, _f
                    const screenWidth =
                        null !==
                          (_b =
                            null === (_a = livePage_getPlayer()) ||
                            void 0 === _a
                              ? void 0
                              : _a.clientWidth) && void 0 !== _b
                          ? _b
                          : 0,
                      screenHeight =
                        null !==
                          (_d =
                            null === (_c = livePage_getMainVideo()) ||
                            void 0 === _c
                              ? void 0
                              : _c.clientHeight) && void 0 !== _d
                          ? _d
                          : 0,
                      screenY =
                        ((null !==
                          (_f =
                            null === (_e = livePage_getPlayer()) ||
                            void 0 === _e
                              ? void 0
                              : _e.clientHeight) && void 0 !== _f
                          ? _f
                          : 0) -
                          screenHeight) /
                        2,
                      screenWidthLimit = 4 * -screenWidth,
                      scriptCss = document.querySelector(".fyc_style")
                    scriptCss &&
                      (external_log_default().debug("RemoveCss"),
                      scriptCss.remove())
                    let scriptCssHtml = ""
                    scriptCssHtml += '<style type="text/css" class="fyc_style">'
                    const offset = userConfig.shadowFontWeight
                    ;(scriptCssHtml += `.fyc_chat {\n    line-height: 1;\n    z-index: 30;\n    position: absolute;\n    display: inline-block;\n    user-select: none;\n    white-space: nowrap;\n    text-shadow: -${offset}px -${offset}px #000, ${offset}px -${offset}px #000, -${offset}px ${offset}px #000, ${offset}px ${offset}px #000;\n    display: inline-block;\n    animation-timing-function: linear;\n    animation-fill-mode: forwards;\n    animation-play-state: running;\n  }`),
                      (scriptCssHtml +=
                        ".fyc_chat > img {\n    vertical-align: text-top;\n  }"),
                      (scriptCssHtml +=
                        ".fyc_chat_screen {\n    z-index: 30;\n  }"),
                      (scriptCssHtml +=
                        ".fyc-chat-button {\n    background: none;\n    border: none;\n    cursor: pointer;\n    float: left;\n    font-size: 1em;\n    height: 4em;\n    outline: none;\n    overflow: visible;\n    padding: 0 0 0em;\n    position: relative;\n    width: 3em;\n  }"),
                      (scriptCssHtml +=
                        ".fyc_panel {\n    background-color: rgba(30,30,30,0.9);\n    width: 650px;\n    height: auto;\n    z-index: 5;\n    display: inline-block;\n    position: absolute;\n    bottom: 35px;\n    right: 10px;\n    padding: 10px;\n    color: #fff;\n    font-size: 14px;\n  }"),
                      (scriptCssHtml +=
                        ".fyc_panel_box {\n    width: 210px;\n    float: left;\n    padding-left: 5px;\n  }"),
                      (scriptCssHtml +=
                        ".fyc_button {\n    display: inline-block;\n    border-style: none;\n    z-index: 4;\n    font-weight: 500;\n    color: var(--yt-spec-text-secondary);\n  }"),
                      (scriptCssHtml +=
                        ".fyc_inputform {\n    width: 100%;\n    background-color: transparent;\n    color: #FFF;\n    border: 2px solid #aaa;\n    border-radius: 4px;\n    margin: 0px 10px;\n    outline: none;\n    padding: 8px;\n    box-sizing: border-box;\n    transition: 0.3s;\n  }"),
                      (scriptCssHtml +=
                        ".fyc_ngbutton {\n    fill: #fff;\n  }"),
                      (scriptCssHtml +=
                        ".fyc_range {\n    width: 150px\n  }\n"),
                      (scriptCssHtml += ".toast {\n    font-size: 14px;\n  }")
                    const { laneCount } = userConfig
                    for (let i = 0; i < 3 * laneCount - 1; i += 1) {
                      let laneHeight =
                        screenHeight * ((i % laneCount) / laneCount) + 4
                      i > laneCount - 1 &&
                        i < 2 * laneCount - 1 &&
                        (laneHeight =
                          screenHeight *
                          ((i % laneCount) / laneCount + 1 / (2 * laneCount))),
                        i > 2 * laneCount - 2 &&
                          (laneHeight =
                            screenHeight * (((i + 1) % laneCount) / laneCount) +
                            4),
                        (laneHeight = Math.round(100 * laneHeight) / 100),
                        (scriptCssHtml += `@keyframes lane${i} {from{ transform: translate(${screenWidth}px, ${
                          screenY + laneHeight
                        }px); }to{ transform: translate(${screenWidthLimit}px, ${
                          screenY + laneHeight
                        }px); }}\n`)
                    }
                    ;(scriptCssHtml += "</style>"),
                      external_log_default().debug("AppendCss"),
                      document.body.insertAdjacentHTML(
                        "beforeend",
                        scriptCssHtml
                      )
                  })(userConfig)
              }),
              (0, external_rxjs_operators_namespaceObject.switchMap)(
                setChatFrameCss
              ),
              (0, external_rxjs_operators_namespaceObject.switchMap)(() =>
                (0, external_rxjs_namespaceObject.merge)(
                  (() => {
                    const video = livePage_getMainVideo()
                    return video
                      ? (0, external_rxjs_namespaceObject.merge)(
                          (0, external_rxjs_namespaceObject.fromEvent)(
                            video,
                            "playing"
                          ),
                          (0, external_rxjs_namespaceObject.fromEvent)(
                            video,
                            "pause"
                          )
                        ).pipe(
                          (0, external_rxjs_operators_namespaceObject.map)(
                            () => !video.paused
                          )
                        )
                      : (0, external_rxjs_namespaceObject.of)(!0)
                  })().pipe(
                    (0, external_rxjs_operators_namespaceObject.tap)(
                      changeChatAnimState
                    )
                  ),
                  (0, external_rxjs_namespaceObject.interval)(1e3)
                    .pipe(
                      (0, external_rxjs_operators_namespaceObject.map)(
                        livePage_getPlayer
                      ),
                      (0, external_rxjs_operators_namespaceObject.filter)(
                        Boolean
                      ),
                      (0, external_rxjs_operators_namespaceObject.map)(x => [
                        x.clientWidth,
                        x.clientHeight,
                      ]),
                      (0,
                      external_rxjs_operators_namespaceObject.distinctUntilChanged)(
                        (x, y) => x[0] === y[0] && x[1] === y[1]
                      )
                    )
                    .pipe(
                      (0, external_rxjs_operators_namespaceObject.skip)(1),
                      (0, external_rxjs_operators_namespaceObject.tap)(x =>
                        logFyc(`Resize detected: ${x}`)
                      ),
                      (0, external_rxjs_operators_namespaceObject.tap)(() =>
                        getFlowingChats().forEach(x => {
                          external_log_default().debug("RemoveAllChat"),
                            x.remove()
                        })
                      ),
                      (0, external_rxjs_operators_namespaceObject.tap)(() =>
                        reinitialize()
                      )
                    )
                )
              ),
              (0, external_rxjs_operators_namespaceObject.retryWhen)(x =>
                x.pipe(
                  (0, external_rxjs_operators_namespaceObject.tap)(e => {
                    logFyc("Errored:"), external_log_default().warn(e)
                  })
                )
              )
            )
            .subscribe()
          let storedHref = window.location.href
          new MutationObserver(async () => {
            storedHref !== window.location.href &&
              ((storedHref = window.location.href),
              logFyc("URL Changed", storedHref, window.location.href),
              await reinitialize())
          }).observe(document, { childList: !0, subtree: !0 }),
            await reinitialize()
        }
      ;(async () => {
        external_log_namespaceObject.setLevel("info")
        try {
          await initialize()
        } catch (error) {
          external_log_namespaceObject.error(error)
        }
      })()
    })()
})()

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址