Flow Youtube Chat

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

目前为 2021-08-04 提交的版本。查看 最新版本

// ==UserScript==
// @name        Flow Youtube Chat
// @version     1.15.7
// @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
// @grant       GM.setClipboard
// @noframes
// @license     AGPL-3.0-or-later
// @require     https://cdn.jsdelivr.net/npm/[email protected]/dist/sweetalert2.all.min.js#sha384-EoPspU1QiQ0II6WaHKy5pERCBPBD1VqZByJ29O7fDUJxGXwWLyEREDpvym8c4v2S
// @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-B2HMABdZA26zJ9QwbG/c5zrcdr6+Zs8J4MgKs7udycjXgvRDA5nZKLzJ1vXWzJyH
// @require     https://unpkg.com/[email protected]/mithril.min.js#sha384-vo9crXih40MlEv6JWHqS7SsPiFp+76csaWQFOF2UU0/xI58Jm/ZvK/1UtpaicJT9
// @require     https://cdn.jsdelivr.net/npm/[email protected]/src/check-types.min.js#sha384-KGnImnhVjA5llfqKEbjBiY+1Mp6oa+NvW/TEY1XTPAKWNgrAwa3Qvn//MXL07wBM
// @require     https://cdn.jsdelivr.net/npm/[email protected]/index.min.js#sha384-Q/uiWfFlwn9XjOpL49VpFKn01EkScmaC3hh1prAn7S++WoZgXRrrjQvZ7cI7C7Zn
// @require     https://cdn.jsdelivr.net/npm/[email protected]/dist/astring.min.js#sha384-mGnfE+xZkK7mo04MqU0t7DI1ZTFZSKwfPNjrLFeibz94N4lJgdHXh5+kI6rf5x10
// @require     https://cdn.jsdelivr.net/npm/[email protected]/build/jsep.min.js#sha384-89PRdfFVlT2bC9VxvLdvlByyVGml9l14DjpPqZYVI9umfvV24KPZ5dY6qBOeKf2z
// @require     https://cdn.jsdelivr.net/npm/[email protected]/dist/hash-it.min.js#sha384-biRMep0zr/5fw/hIdnBIb56UHRgiIyhAagZrngd9dSxxQ9aDFMP0hbYR8PEj5lVu
// @require     https://cdn.jsdelivr.net/npm/[email protected]/dist/micro-memoize.min.js#sha384-aGxbSIH2oMTKxZ93i+/iQKx5xefR8mHJW3mkbRaiSZizVoCvKS6wzndlLeQzMv9B
// ==/UserScript==

/* jshint esversion: 6 */

;(() => {
  var __webpack_modules__ = {
      73: (
        __unused_webpack_module,
        __unused_webpack___webpack_exports__,
        __webpack_require__
      ) => {
        "use strict"
        const external_log_namespaceObject = log
        var external_log_default = __webpack_require__.n(
          external_log_namespaceObject
        )
        const lib = observer => value => {
          observer.next(value)
        }
        function sleep(time) {
          time || (time = 0)
          return new Promise(function (res) {
            return setTimeout(res, time)
          })
        }
        function randomToken() {
          return Math.random().toString(36).substring(2)
        }
        var lastMs = 0,
          additional = 0
        function microSeconds() {
          var ms = new Date().getTime()
          if (ms === lastMs) return 1e3 * ms + ++additional
          lastMs = ms
          additional = 0
          return 1e3 * ms
        }
        var isNode =
          "[object process]" ===
          Object.prototype.toString.call(
            "undefined" != typeof process ? process : 0
          )
        const methods_native = {
          create: function (channelName) {
            var state = {
              messagesCallback: null,
              bc: new BroadcastChannel(channelName),
              subFns: [],
            }
            state.bc.onmessage = function (msg) {
              state.messagesCallback && state.messagesCallback(msg.data)
            }
            return state
          },
          close: function (channelState) {
            channelState.bc.close()
            channelState.subFns = []
          },
          onMessage: function (channelState, fn) {
            channelState.messagesCallback = fn
          },
          postMessage: function (channelState, messageJson) {
            try {
              channelState.bc.postMessage(messageJson, !1)
              return Promise.resolve()
            } catch (err) {
              return Promise.reject(err)
            }
          },
          canBeUsed: function () {
            if (isNode && "undefined" == typeof window) return !1
            if ("function" == typeof BroadcastChannel) {
              if (BroadcastChannel._pubkey)
                throw new Error(
                  "BroadcastChannel: Do not overwrite window.BroadcastChannel with this module, this is not a polyfill"
                )
              return !0
            }
            return !1
          },
          type: "native",
          averageResponseTime: function () {
            return 150
          },
          microSeconds,
        }
        var ObliviousSet = (function () {
          function ObliviousSet(ttl) {
            this.ttl = ttl
            this.set = new Set()
            this.timeMap = new Map()
          }
          ObliviousSet.prototype.has = function (value) {
            return this.set.has(value)
          }
          ObliviousSet.prototype.add = function (value) {
            var _this = this
            this.timeMap.set(value, now())
            this.set.add(value)
            setTimeout(function () {
              !(function (obliviousSet) {
                var olderThen = now() - obliviousSet.ttl,
                  iterator = obliviousSet.set[Symbol.iterator]()
                for (;;) {
                  var value = iterator.next().value
                  if (!value) return
                  if (!(obliviousSet.timeMap.get(value) < olderThen)) return
                  obliviousSet.timeMap.delete(value)
                  obliviousSet.set.delete(value)
                }
              })(_this)
            }, 0)
          }
          ObliviousSet.prototype.clear = function () {
            this.set.clear()
            this.timeMap.clear()
          }
          return ObliviousSet
        })()
        function now() {
          return new Date().getTime()
        }
        function options_fillOptionsWithDefaults() {
          var originalOptions =
              arguments.length > 0 && void 0 !== arguments[0]
                ? arguments[0]
                : {},
            options = JSON.parse(JSON.stringify(originalOptions))
          void 0 === options.webWorkerSupport && (options.webWorkerSupport = !0)
          options.idb || (options.idb = {})
          options.idb.ttl || (options.idb.ttl = 45e3)
          options.idb.fallbackInterval || (options.idb.fallbackInterval = 150)
          originalOptions.idb &&
            "function" == typeof originalOptions.idb.onclose &&
            (options.idb.onclose = originalOptions.idb.onclose)
          options.localstorage || (options.localstorage = {})
          options.localstorage.removeTimeout ||
            (options.localstorage.removeTimeout = 6e4)
          originalOptions.methods && (options.methods = originalOptions.methods)
          options.node || (options.node = {})
          options.node.ttl || (options.node.ttl = 12e4)
          void 0 === options.node.useFastPath && (options.node.useFastPath = !0)
          return options
        }
        function getIdb() {
          if ("undefined" != typeof indexedDB) return indexedDB
          if ("undefined" != typeof window) {
            if (void 0 !== window.mozIndexedDB) return window.mozIndexedDB
            if (void 0 !== window.webkitIndexedDB) return window.webkitIndexedDB
            if (void 0 !== window.msIndexedDB) return window.msIndexedDB
          }
          return !1
        }
        function getMessagesHigherThan(db, lastCursorId) {
          var objectStore = db.transaction("messages").objectStore("messages"),
            ret = []
          return new Promise(function (res) {
            ;(function () {
              try {
                var keyRangeValue = IDBKeyRange.bound(lastCursorId + 1, 1 / 0)
                return objectStore.openCursor(keyRangeValue)
              } catch (e) {
                return objectStore.openCursor()
              }
            })().onsuccess = function (ev) {
              var cursor = ev.target.result
              if (cursor)
                if (cursor.value.id < lastCursorId + 1)
                  cursor.continue(lastCursorId + 1)
                else {
                  ret.push(cursor.value)
                  cursor.continue()
                }
              else res(ret)
            }
          })
        }
        function cleanOldMessages(db, ttl) {
          return (function (db, ttl) {
            var olderThen = new Date().getTime() - ttl,
              objectStore = db.transaction("messages").objectStore("messages"),
              ret = []
            return new Promise(function (res) {
              objectStore.openCursor().onsuccess = function (ev) {
                var cursor = ev.target.result
                if (cursor) {
                  var msgObk = cursor.value
                  if (!(msgObk.time < olderThen)) {
                    res(ret)
                    return
                  }
                  ret.push(msgObk)
                  cursor.continue()
                } else res(ret)
              }
            })
          })(db, ttl).then(function (tooOld) {
            return Promise.all(
              tooOld.map(function (msgObj) {
                return (function (db, id) {
                  var request = db
                    .transaction(["messages"], "readwrite")
                    .objectStore("messages")
                    .delete(id)
                  return new Promise(function (res) {
                    request.onsuccess = function () {
                      return res()
                    }
                  })
                })(db, msgObj.id)
              })
            )
          })
        }
        function _readLoop(state) {
          state.closed ||
            readNewMessages(state)
              .then(function () {
                return sleep(state.options.idb.fallbackInterval)
              })
              .then(function () {
                return _readLoop(state)
              })
        }
        function readNewMessages(state) {
          return state.closed
            ? Promise.resolve()
            : state.messagesCallback
            ? getMessagesHigherThan(state.db, state.lastCursorId).then(
                function (newerMessages) {
                  newerMessages
                    .filter(function (msgObj) {
                      return !!msgObj
                    })
                    .map(function (msgObj) {
                      msgObj.id > state.lastCursorId &&
                        (state.lastCursorId = msgObj.id)
                      return msgObj
                    })
                    .filter(function (msgObj) {
                      return (function (msgObj, state) {
                        return !(
                          msgObj.uuid === state.uuid ||
                          state.eMIs.has(msgObj.id) ||
                          msgObj.data.time < state.messagesCallbackTime
                        )
                      })(msgObj, state)
                    })
                    .sort(function (msgObjA, msgObjB) {
                      return msgObjA.time - msgObjB.time
                    })
                    .forEach(function (msgObj) {
                      if (state.messagesCallback) {
                        state.eMIs.add(msgObj.id)
                        state.messagesCallback(msgObj.data)
                      }
                    })
                  return Promise.resolve()
                }
              )
            : Promise.resolve()
        }
        const indexed_db = {
          create: function (channelName, options) {
            options = options_fillOptionsWithDefaults(options)
            return (function (channelName) {
              var dbName = "pubkey.broadcast-channel-0-" + channelName,
                openRequest = getIdb().open(dbName, 1)
              openRequest.onupgradeneeded = function (ev) {
                ev.target.result.createObjectStore("messages", {
                  keyPath: "id",
                  autoIncrement: !0,
                })
              }
              return new Promise(function (res, rej) {
                openRequest.onerror = function (ev) {
                  return rej(ev)
                }
                openRequest.onsuccess = function () {
                  res(openRequest.result)
                }
              })
            })(channelName).then(function (db) {
              var state = {
                closed: !1,
                lastCursorId: 0,
                channelName,
                options,
                uuid: randomToken(),
                eMIs: new ObliviousSet(2 * options.idb.ttl),
                writeBlockPromise: Promise.resolve(),
                messagesCallback: null,
                readQueuePromises: [],
                db,
              }
              db.onclose = function () {
                state.closed = !0
                options.idb.onclose && options.idb.onclose()
              }
              _readLoop(state)
              return state
            })
          },
          close: function (channelState) {
            channelState.closed = !0
            channelState.db.close()
          },
          onMessage: function (channelState, fn, time) {
            channelState.messagesCallbackTime = time
            channelState.messagesCallback = fn
            readNewMessages(channelState)
          },
          postMessage: function (channelState, messageJson) {
            channelState.writeBlockPromise = channelState.writeBlockPromise
              .then(function () {
                return (function (db, readerUuid, messageJson) {
                  var writeObject = {
                      uuid: readerUuid,
                      time: new Date().getTime(),
                      data: messageJson,
                    },
                    transaction = db.transaction(["messages"], "readwrite")
                  return new Promise(function (res, rej) {
                    transaction.oncomplete = function () {
                      return res()
                    }
                    transaction.onerror = function (ev) {
                      return rej(ev)
                    }
                    transaction.objectStore("messages").add(writeObject)
                  })
                })(channelState.db, channelState.uuid, messageJson)
              })
              .then(function () {
                0 ===
                  (function (min, max) {
                    return Math.floor(Math.random() * (max - min + 1) + min)
                  })(0, 10) &&
                  cleanOldMessages(
                    channelState.db,
                    channelState.options.idb.ttl
                  )
              })
            return channelState.writeBlockPromise
          },
          canBeUsed: function () {
            return !isNode && !!getIdb()
          },
          type: "idb",
          averageResponseTime: function (options) {
            return 2 * options.idb.fallbackInterval
          },
          microSeconds,
        }
        function getLocalStorage() {
          var localStorage
          if ("undefined" == typeof window) return null
          try {
            localStorage = window.localStorage
            localStorage =
              window["ie8-eventlistener/storage"] || window.localStorage
          } catch (e) {}
          return localStorage
        }
        function storageKey(channelName) {
          return "pubkey.broadcastChannel-" + channelName
        }
        function localstorage_canBeUsed() {
          if (isNode) return !1
          var ls = getLocalStorage()
          if (!ls) return !1
          try {
            var key = "__broadcastchannel_check"
            ls.setItem(key, "works")
            ls.removeItem(key)
          } catch (e) {
            return !1
          }
          return !0
        }
        const localstorage = {
          create: function (channelName, options) {
            options = options_fillOptionsWithDefaults(options)
            if (!localstorage_canBeUsed())
              throw new Error("BroadcastChannel: localstorage cannot be used")
            var uuid = randomToken(),
              eMIs = new ObliviousSet(options.localstorage.removeTimeout),
              state = { channelName, uuid, eMIs }
            state.listener = (function (channelName, fn) {
              var key = storageKey(channelName),
                listener = function (ev) {
                  ev.key === key && fn(JSON.parse(ev.newValue))
                }
              window.addEventListener("storage", listener)
              return listener
            })(channelName, function (msgObj) {
              if (
                state.messagesCallback &&
                msgObj.uuid !== uuid &&
                msgObj.token &&
                !eMIs.has(msgObj.token) &&
                !(
                  msgObj.data.time &&
                  msgObj.data.time < state.messagesCallbackTime
                )
              ) {
                eMIs.add(msgObj.token)
                state.messagesCallback(msgObj.data)
              }
            })
            return state
          },
          close: function (channelState) {
            ;(listener = channelState.listener),
              window.removeEventListener("storage", listener)
            var listener
          },
          onMessage: function (channelState, fn, time) {
            channelState.messagesCallbackTime = time
            channelState.messagesCallback = fn
          },
          postMessage: function (channelState, messageJson) {
            return new Promise(function (res) {
              sleep().then(function () {
                var key = storageKey(channelState.channelName),
                  writeObj = {
                    token: randomToken(),
                    time: new Date().getTime(),
                    data: messageJson,
                    uuid: channelState.uuid,
                  },
                  value = JSON.stringify(writeObj)
                getLocalStorage().setItem(key, value)
                var ev = document.createEvent("Event")
                ev.initEvent("storage", !0, !0)
                ev.key = key
                ev.newValue = value
                window.dispatchEvent(ev)
                res()
              })
            })
          },
          canBeUsed: localstorage_canBeUsed,
          type: "localstorage",
          averageResponseTime: function () {
            var userAgent = navigator.userAgent.toLowerCase()
            return userAgent.includes("safari") && !userAgent.includes("chrome")
              ? 240
              : 120
          },
          microSeconds,
        }
        var simulate_microSeconds = microSeconds,
          SIMULATE_CHANNELS = new Set()
        const simulate = {
          create: function (channelName) {
            var state = { name: channelName, messagesCallback: null }
            SIMULATE_CHANNELS.add(state)
            return state
          },
          close: function (channelState) {
            SIMULATE_CHANNELS.delete(channelState)
          },
          onMessage: function (channelState, fn) {
            channelState.messagesCallback = fn
          },
          postMessage: function (channelState, messageJson) {
            return new Promise(function (res) {
              return setTimeout(function () {
                Array.from(SIMULATE_CHANNELS)
                  .filter(function (channel) {
                    return channel.name === channelState.name
                  })
                  .filter(function (channel) {
                    return channel !== channelState
                  })
                  .filter(function (channel) {
                    return !!channel.messagesCallback
                  })
                  .forEach(function (channel) {
                    return channel.messagesCallback(messageJson)
                  })
                res()
              }, 5)
            })
          },
          canBeUsed: function () {
            return !0
          },
          type: "simulate",
          averageResponseTime: function () {
            return 5
          },
          microSeconds: simulate_microSeconds,
        }
        var METHODS = [methods_native, indexed_db, localstorage]
        if (isNode) {
          var NodeMethod = __webpack_require__(633)
          "function" == typeof NodeMethod.canBeUsed && METHODS.push(NodeMethod)
        }
        var ENFORCED_OPTIONS,
          broadcast_channel_BroadcastChannel = function (name, options) {
            this.name = name
            ENFORCED_OPTIONS && (options = ENFORCED_OPTIONS)
            this.options = options_fillOptionsWithDefaults(options)
            this.method = (function (options) {
              var chooseMethods = []
                .concat(options.methods, METHODS)
                .filter(Boolean)
              if (options.type) {
                if ("simulate" === options.type) return simulate
                var ret = chooseMethods.find(function (m) {
                  return m.type === options.type
                })
                if (ret) return ret
                throw new Error("method-type " + options.type + " not found")
              }
              options.webWorkerSupport ||
                isNode ||
                (chooseMethods = chooseMethods.filter(function (m) {
                  return "idb" !== m.type
                }))
              var useMethod = chooseMethods.find(function (method) {
                return method.canBeUsed()
              })
              if (useMethod) return useMethod
              throw new Error(
                "No useable methode found:" +
                  JSON.stringify(
                    METHODS.map(function (m) {
                      return m.type
                    })
                  )
              )
            })(this.options)
            this._iL = !1
            this._onML = null
            this._addEL = { message: [], internal: [] }
            this._uMP = new Set()
            this._befC = []
            this._prepP = null
            !(function (channel) {
              var maybePromise = channel.method.create(
                channel.name,
                channel.options
              )
              if (
                ((obj = maybePromise), obj && "function" == typeof obj.then)
              ) {
                channel._prepP = maybePromise
                maybePromise.then(function (s) {
                  channel._state = s
                })
              } else channel._state = maybePromise
              var obj
            })(this)
          }
        broadcast_channel_BroadcastChannel._pubkey = !0
        broadcast_channel_BroadcastChannel.prototype = {
          postMessage: function (msg) {
            if (this.closed)
              throw new Error(
                "BroadcastChannel.postMessage(): Cannot post message after channel has closed"
              )
            return _post(this, "message", msg)
          },
          postInternal: function (msg) {
            return _post(this, "internal", msg)
          },
          set onmessage(fn) {
            var listenObj = { time: this.method.microSeconds(), fn }
            _removeListenerObject(this, "message", this._onML)
            if (fn && "function" == typeof fn) {
              this._onML = listenObj
              _addListenerObject(this, "message", listenObj)
            } else this._onML = null
          },
          addEventListener: function (type, fn) {
            _addListenerObject(this, type, {
              time: this.method.microSeconds(),
              fn,
            })
          },
          removeEventListener: function (type, fn) {
            _removeListenerObject(
              this,
              type,
              this._addEL[type].find(function (obj) {
                return obj.fn === fn
              })
            )
          },
          close: function () {
            var _this = this
            if (!this.closed) {
              this.closed = !0
              var awaitPrepare = this._prepP ? this._prepP : Promise.resolve()
              this._onML = null
              this._addEL.message = []
              return awaitPrepare
                .then(function () {
                  return Promise.all(Array.from(_this._uMP))
                })
                .then(function () {
                  return Promise.all(
                    _this._befC.map(function (fn) {
                      return fn()
                    })
                  )
                })
                .then(function () {
                  return _this.method.close(_this._state)
                })
            }
          },
          get type() {
            return this.method.type
          },
          get isClosed() {
            return this.closed
          },
        }
        function _post(broadcastChannel, type, msg) {
          var msgObj = {
            time: broadcastChannel.method.microSeconds(),
            type,
            data: msg,
          }
          return (
            broadcastChannel._prepP
              ? broadcastChannel._prepP
              : Promise.resolve()
          ).then(function () {
            var sendPromise = broadcastChannel.method.postMessage(
              broadcastChannel._state,
              msgObj
            )
            broadcastChannel._uMP.add(sendPromise)
            sendPromise.catch().then(function () {
              return broadcastChannel._uMP.delete(sendPromise)
            })
            return sendPromise
          })
        }
        function _hasMessageListeners(channel) {
          return (
            channel._addEL.message.length > 0 ||
            channel._addEL.internal.length > 0
          )
        }
        function _addListenerObject(channel, type, obj) {
          channel._addEL[type].push(obj)
          !(function (channel) {
            if (!channel._iL && _hasMessageListeners(channel)) {
              var listenerFn = function (msgObj) {
                  channel._addEL[msgObj.type].forEach(function (obj) {
                    msgObj.time >= obj.time && obj.fn(msgObj.data)
                  })
                },
                time = channel.method.microSeconds()
              if (channel._prepP)
                channel._prepP.then(function () {
                  channel._iL = !0
                  channel.method.onMessage(channel._state, listenerFn, time)
                })
              else {
                channel._iL = !0
                channel.method.onMessage(channel._state, listenerFn, time)
              }
            }
          })(channel)
        }
        function _removeListenerObject(channel, type, obj) {
          channel._addEL[type] = channel._addEL[type].filter(function (o) {
            return o !== obj
          })
          !(function (channel) {
            if (channel._iL && !_hasMessageListeners(channel)) {
              channel._iL = !1
              var time = channel.method.microSeconds()
              channel.method.onMessage(channel._state, null, time)
            }
          })(channel)
        }
        const external_DeepDiff_namespaceObject = DeepDiff
        var function_getMonoid = function (M) {
          var S,
            getSemigroupM =
              ((S = M),
              function () {
                return {
                  concat: function (f, g) {
                    return function (a) {
                      return S.concat(f(a), g(a))
                    }
                  },
                }
              })
          return function () {
            return {
              concat: getSemigroupM().concat,
              empty: function () {
                return M.empty
              },
            }
          }
        }
        function function_identity(a) {
          return a
        }
        function constant(a) {
          return function () {
            return a
          }
        }
        var constUndefined = constant(void 0)
        function function_flow(ab, bc, cd, de, ef, fg, gh, hi, ij) {
          switch (arguments.length) {
            case 1:
              return ab
            case 2:
              return function () {
                return bc(ab.apply(this, arguments))
              }
            case 3:
              return function () {
                return cd(bc(ab.apply(this, arguments)))
              }
            case 4:
              return function () {
                return de(cd(bc(ab.apply(this, arguments))))
              }
            case 5:
              return function () {
                return ef(de(cd(bc(ab.apply(this, arguments)))))
              }
            case 6:
              return function () {
                return fg(ef(de(cd(bc(ab.apply(this, arguments))))))
              }
            case 7:
              return function () {
                return gh(fg(ef(de(cd(bc(ab.apply(this, arguments)))))))
              }
            case 8:
              return function () {
                return hi(gh(fg(ef(de(cd(bc(ab.apply(this, arguments))))))))
              }
            case 9:
              return function () {
                return ij(hi(gh(fg(ef(de(cd(bc(ab.apply(this, arguments)))))))))
              }
          }
        }
        function function_pipe(
          a,
          ab,
          bc,
          cd,
          de,
          ef,
          fg,
          gh,
          hi,
          ij,
          jk,
          kl,
          lm,
          mn,
          no,
          op,
          pq,
          qr,
          rs,
          st
        ) {
          switch (arguments.length) {
            case 1:
              return a
            case 2:
              return ab(a)
            case 3:
              return bc(ab(a))
            case 4:
              return cd(bc(ab(a)))
            case 5:
              return de(cd(bc(ab(a))))
            case 6:
              return ef(de(cd(bc(ab(a)))))
            case 7:
              return fg(ef(de(cd(bc(ab(a))))))
            case 8:
              return gh(fg(ef(de(cd(bc(ab(a)))))))
            case 9:
              return hi(gh(fg(ef(de(cd(bc(ab(a))))))))
            case 10:
              return ij(hi(gh(fg(ef(de(cd(bc(ab(a)))))))))
            case 11:
              return jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a))))))))))
            case 12:
              return kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a)))))))))))
            case 13:
              return lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a))))))))))))
            case 14:
              return mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a)))))))))))))
            case 15:
              return no(mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a))))))))))))))
            case 16:
              return op(
                no(mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a))))))))))))))
              )
            case 17:
              return pq(
                op(no(mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a)))))))))))))))
              )
            case 18:
              return qr(
                pq(
                  op(no(mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a)))))))))))))))
                )
              )
            case 19:
              return rs(
                qr(
                  pq(
                    op(
                      no(mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a))))))))))))))
                    )
                  )
                )
              )
            case 20:
              return st(
                rs(
                  qr(
                    pq(
                      op(
                        no(
                          mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a)))))))))))))
                        )
                      )
                    )
                  )
                )
              )
          }
        }
        var isSome = function (fa) {
            return "Some" === fa._tag
          },
          none = { _tag: "None" },
          some = function (a) {
            return { _tag: "Some", value: a }
          },
          isLeft = function (ma) {
            return "Left" === ma._tag
          },
          right = function (a) {
            return { _tag: "Right", right: a }
          },
          internal_isNonEmpty = function (as) {
            return as.length > 0
          },
          head = function (as) {
            return as[0]
          },
          emptyReadonlyArray = [],
          Predicate_not =
            (Object.prototype.hasOwnProperty,
            function (predicate) {
              return function (a) {
                return !predicate(a)
              }
            })
        function map(F, G) {
          return function (f) {
            return function (fa) {
              return F.map(fa, function (ga) {
                return G.map(ga, f)
              })
            }
          }
        }
        function flap(F) {
          return function (a) {
            return function (fab) {
              return F.map(fab, function (f) {
                return f(a)
              })
            }
          }
        }
        function bindTo(F) {
          return function (name) {
            return function (fa) {
              return F.map(fa, function (a) {
                var _a
                return ((_a = {})[name] = a), _a
              })
            }
          }
        }
        function Functor_getFunctorComposition(F, G) {
          var _map = map(F, G)
          return {
            map: function (fga, f) {
              return function_pipe(fga, _map(f))
            },
          }
        }
        var Separated_separated = function (left, right) {
            return { left, right }
          },
          Separated_map = function (f) {
            return function (fa) {
              return Separated_separated(
                Separated_left(fa),
                f(Separated_right(fa))
              )
            }
          },
          Separated_left =
            (flap({
              URI: "Separated",
              map: function (fa, f) {
                return function_pipe(fa, Separated_map(f))
              },
            }),
            function (s) {
              return s.left
            }),
          Separated_right = function (s) {
            return s.right
          }
        function Witherable_wiltDefault(T, C) {
          return function (F) {
            var traverseF = T.traverse(F)
            return function (wa, f) {
              return F.map(traverseF(wa, f), C.separate)
            }
          }
        }
        function Witherable_witherDefault(T, C) {
          return function (F) {
            var traverseF = T.traverse(F)
            return function (wa, f) {
              return F.map(traverseF(wa, f), C.compact)
            }
          }
        }
        var Option_none = none,
          Option_some = some
        function fromPredicate(predicate) {
          return function (a) {
            return predicate(a) ? Option_some(a) : Option_none
          }
        }
        var getLeft = function (ma) {
            return "Right" === ma._tag ? Option_none : Option_some(ma.left)
          },
          getRight = function (ma) {
            return "Left" === ma._tag ? Option_none : Option_some(ma.right)
          },
          Option_map = function (fa, f) {
            return function_pipe(fa, es6_Option_map(f))
          },
          _ap = function (fab, fa) {
            return function_pipe(fab, ap(fa))
          },
          _chain = function (ma, f) {
            return function_pipe(ma, chain(f))
          },
          _reduce = function (fa, b, f) {
            return function_pipe(fa, reduce(b, f))
          },
          _foldMap = function (M) {
            var foldMapM = foldMap(M)
            return function (fa, f) {
              return function_pipe(fa, foldMapM(f))
            }
          },
          _reduceRight = function (fa, b, f) {
            return function_pipe(fa, reduceRight(b, f))
          },
          _traverse = function (F) {
            var traverseF = traverse(F)
            return function (ta, f) {
              return function_pipe(ta, traverseF(f))
            }
          },
          _alt = function (fa, that) {
            return function_pipe(fa, alt(that))
          },
          _filter = function (fa, predicate) {
            return function_pipe(fa, filter(predicate))
          },
          _filterMap = function (fa, f) {
            return function_pipe(fa, filterMap(f))
          },
          _extend = function (wa, f) {
            return function_pipe(wa, extend(f))
          },
          _partition = function (fa, predicate) {
            return function_pipe(fa, partition(predicate))
          },
          _partitionMap = function (fa, f) {
            return function_pipe(fa, partitionMap(f))
          },
          getEq = function (E) {
            return {
              equals: function (x, y) {
                return (
                  x === y ||
                  (Option_isNone(x)
                    ? Option_isNone(y)
                    : !Option_isNone(y) && E.equals(x.value, y.value))
                )
              },
            }
          },
          es6_Option_map = function (f) {
            return function (fa) {
              return Option_isNone(fa) ? Option_none : Option_some(f(fa.value))
            }
          },
          Option_Functor = { URI: "Option", map: Option_map },
          of = Option_some,
          ap = function (fa) {
            return function (fab) {
              return Option_isNone(fab) || Option_isNone(fa)
                ? Option_none
                : Option_some(fab.value(fa.value))
            }
          },
          Apply = { URI: "Option", map: Option_map, ap: _ap },
          chain = function (f) {
            return function (ma) {
              return Option_isNone(ma) ? Option_none : f(ma.value)
            }
          },
          reduce = function (b, f) {
            return function (fa) {
              return Option_isNone(fa) ? b : f(b, fa.value)
            }
          },
          foldMap = function (M) {
            return function (f) {
              return function (fa) {
                return Option_isNone(fa) ? M.empty : f(fa.value)
              }
            }
          },
          reduceRight = function (b, f) {
            return function (fa) {
              return Option_isNone(fa) ? b : f(fa.value, b)
            }
          },
          alt = function (that) {
            return function (fa) {
              return Option_isNone(fa) ? that() : fa
            }
          },
          zero = function () {
            return Option_none
          },
          extend = function (f) {
            return function (wa) {
              return Option_isNone(wa) ? Option_none : Option_some(f(wa))
            }
          },
          compact = chain(function_identity),
          defaultSeparated = Separated_separated(Option_none, Option_none),
          separate = function (ma) {
            return Option_isNone(ma)
              ? defaultSeparated
              : Separated_separated(getLeft(ma.value), getRight(ma.value))
          },
          Compactable = { URI: "Option", compact, separate },
          filter = function (predicate) {
            return function (fa) {
              return Option_isNone(fa)
                ? Option_none
                : predicate(fa.value)
                ? fa
                : Option_none
            }
          },
          filterMap = function (f) {
            return function (fa) {
              return Option_isNone(fa) ? Option_none : f(fa.value)
            }
          },
          partition = function (predicate) {
            return function (fa) {
              return Separated_separated(
                _filter(fa, Predicate_not(predicate)),
                _filter(fa, predicate)
              )
            }
          },
          partitionMap = function (f) {
            return function_flow(es6_Option_map(f), separate)
          },
          traverse = function (F) {
            return function (f) {
              return function (ta) {
                return Option_isNone(ta)
                  ? F.of(Option_none)
                  : F.map(f(ta.value), Option_some)
              }
            }
          },
          sequence = function (F) {
            return function (ta) {
              return Option_isNone(ta)
                ? F.of(Option_none)
                : F.map(ta.value, Option_some)
            }
          },
          Traversable = {
            URI: "Option",
            map: Option_map,
            reduce: _reduce,
            foldMap: _foldMap,
            reduceRight: _reduceRight,
            traverse: _traverse,
            sequence,
          },
          _wither = Witherable_witherDefault(Traversable, Compactable),
          _wilt = Witherable_wiltDefault(Traversable, Compactable),
          throwError = function () {
            return Option_none
          },
          Option_isSome = isSome,
          Option_isNone = function (fa) {
            return "None" === fa._tag
          },
          matchW = function (onNone, onSome) {
            return function (ma) {
              return Option_isNone(ma) ? onNone() : onSome(ma.value)
            }
          },
          match = matchW,
          getOrElseW = function (onNone) {
            return function (ma) {
              return Option_isNone(ma) ? onNone() : ma.value
            }
          },
          getOrElse = getOrElseW,
          fromNullable = function (a) {
            return null == a ? Option_none : Option_some(a)
          },
          chainNullableK = function (f) {
            return function (ma) {
              return Option_isNone(ma) ? Option_none : fromNullable(f(ma.value))
            }
          },
          toUndefined = match(constUndefined, function_identity)
        of(emptyReadonlyArray)
        var Option_option = {
          URI: "Option",
          map: Option_map,
          of,
          ap: _ap,
          chain: _chain,
          reduce: _reduce,
          foldMap: _foldMap,
          reduceRight: _reduceRight,
          traverse: _traverse,
          sequence,
          zero,
          alt: _alt,
          extend: _extend,
          compact,
          separate,
          filter: _filter,
          filterMap: _filterMap,
          partition: _partition,
          partitionMap: _partitionMap,
          wither: _wither,
          wilt: _wilt,
          throwError,
        }
        function Apply_apSecond(A) {
          return function (second) {
            return function (first) {
              return A.ap(
                A.map(first, function () {
                  return function (b) {
                    return b
                  }
                }),
                second
              )
            }
          }
        }
        function OptionT_some(F) {
          return function_flow(Option_some, F.of)
        }
        function OptionT_zero(F) {
          return constant(F.of(Option_none))
        }
        function fromF(F) {
          return function (ma) {
            return F.map(ma, Option_some)
          }
        }
        function OptionT_chain(M) {
          var zeroM = OptionT_zero(M)
          return function (f) {
            return function (ma) {
              return M.chain(
                ma,
                match(function () {
                  return zeroM()
                }, f)
              )
            }
          }
        }
        function Compactable_compact(F, G) {
          return function (fga) {
            return F.map(fga, G.compact)
          }
        }
        function Compactable_separate(F, C, G) {
          var _compact = Compactable_compact(F, C),
            _map = map(F, G)
          return function (fge) {
            return Separated_separated(
              _compact(function_pipe(fge, _map(getLeft))),
              _compact(function_pipe(fge, _map(getRight)))
            )
          }
        }
        function Filterable_filter(F, G) {
          return function (predicate) {
            return function (fga) {
              return F.map(fga, function (ga) {
                return G.filter(ga, predicate)
              })
            }
          }
        }
        function Filterable_filterMap(F, G) {
          return function (f) {
            return function (fga) {
              return F.map(fga, function (ga) {
                return G.filterMap(ga, f)
              })
            }
          }
        }
        function Chain_chainFirst(M) {
          return function (f) {
            return function (first) {
              return M.chain(first, function (a) {
                return M.map(f(a), function () {
                  return a
                })
              })
            }
          }
        }
        var M,
          apM,
          mapM,
          chainM,
          altM,
          foldM,
          getOrElseM,
          zeroM,
          IO_map = function (ma, f) {
            return function () {
              return f(ma())
            }
          },
          IO_ap = function (mab, ma) {
            return function () {
              return mab()(ma())
            }
          },
          IO_chain = function (ma, f) {
            return function () {
              return f(ma())()
            }
          },
          _chainRec = function (a, f) {
            return function () {
              for (var e = f(a)(); "Left" === e._tag; ) e = f(e.left)()
              return e.right
            }
          },
          es6_IO_map = function (f) {
            return function (fa) {
              return IO_map(fa, f)
            }
          },
          IO_of = constant,
          es6_IO_chain = function (f) {
            return function (ma) {
              return IO_chain(ma, f)
            }
          },
          IO_Functor = { URI: "IO", map: IO_map },
          IO_Apply = (flap(IO_Functor), { URI: "IO", map: IO_map, ap: IO_ap }),
          IO_apSecond = Apply_apSecond(IO_Apply),
          IO_Chain = { URI: "IO", map: IO_map, ap: IO_ap, chain: IO_chain },
          IO_chainFirst = Chain_chainFirst(IO_Chain),
          fromIO = function_identity,
          IO_ApT = IO_of(emptyReadonlyArray),
          IO_traverseReadonlyArrayWithIndex = function (f) {
            var g = (function (f) {
              return function (as) {
                return function () {
                  for (var out = [f(0, head(as))()], i = 1; i < as.length; i++)
                    out.push(f(i, as[i])())
                  return out
                }
              }
            })(f)
            return function (as) {
              return internal_isNonEmpty(as) ? g(as) : IO_ApT
            }
          },
          IO_sequenceArray = (function (f) {
            return IO_traverseReadonlyArrayWithIndex(function (_, a) {
              return f(a)
            })
          })(function_identity),
          IO_io = {
            URI: "IO",
            map: IO_map,
            of: IO_of,
            ap: IO_ap,
            chain: IO_chain,
            fromIO,
            chainRec: _chainRec,
          },
          __assign = function () {
            return (__assign =
              Object.assign ||
              function (t) {
                for (var s, i = 1, n = arguments.length; i < n; i++) {
                  s = arguments[i]
                  for (var p in s)
                    Object.prototype.hasOwnProperty.call(s, p) && (t[p] = s[p])
                }
                return t
              }).apply(this, arguments)
          },
          T =
            ((apM = (function (F) {
              return (function (F, G) {
                return function (fa) {
                  return function (fab) {
                    return F.ap(
                      F.map(fab, function (gab) {
                        return function (ga) {
                          return G.ap(gab, ga)
                        }
                      }),
                      fa
                    )
                  }
                }
              })(F, Apply)
            })((M = IO_io))),
            (mapM = (function (F) {
              return map(F, Option_Functor)
            })(M)),
            (chainM = OptionT_chain(M)),
            (altM = (function (M) {
              var _some = OptionT_some(M)
              return function (second) {
                return function (first) {
                  return M.chain(first, match(second, _some))
                }
              }
            })(M)),
            (foldM = (function (M) {
              return function (onNone, onSome) {
                return function (ma) {
                  return M.chain(ma, match(onNone, onSome))
                }
              }
            })(M)),
            (getOrElseM = (function (M) {
              return function (onNone) {
                return function (fa) {
                  return M.chain(fa, match(onNone, M.of))
                }
              }
            })(M)),
            (zeroM = OptionT_zero(M)),
            {
              map: function (fa, f) {
                return function_pipe(fa, mapM(f))
              },
              ap: function (fab, fa) {
                return function_pipe(fab, apM(fa))
              },
              of: OptionT_some(M),
              chain: function (ma, f) {
                return function_pipe(ma, chainM(f))
              },
              alt: function (fa, that) {
                return function_pipe(fa, altM(that))
              },
              fold: function (fa, onNone, onSome) {
                return function_pipe(fa, foldM(onNone, onSome))
              },
              getOrElse: function (fa, onNone) {
                return function_pipe(fa, getOrElseM(onNone))
              },
              fromM: fromF(M),
              none: function () {
                return zeroM()
              },
            }),
          F = (function (F, G) {
            var map = Functor_getFunctorComposition(F, G).map,
              _compact = Compactable_compact(F, G),
              _separate = Compactable_separate(F, G, G),
              _filter = Filterable_filter(F, G),
              _filterMap = Filterable_filterMap(F, G),
              _partition = (function (F, G) {
                var _filter = Filterable_filter(F, G)
                return function (predicate) {
                  var left = _filter(Predicate_not(predicate)),
                    right = _filter(predicate)
                  return function (fgb) {
                    return Separated_separated(left(fgb), right(fgb))
                  }
                }
              })(F, G),
              _partitionMap = (function (F, G) {
                var _filterMap = Filterable_filterMap(F, G)
                return function (f) {
                  return function (fga) {
                    return Separated_separated(
                      function_pipe(
                        fga,
                        _filterMap(function (a) {
                          return getLeft(f(a))
                        })
                      ),
                      function_pipe(
                        fga,
                        _filterMap(function (a) {
                          return getRight(f(a))
                        })
                      )
                    )
                  }
                }
              })(F, G)
            return {
              map,
              compact: _compact,
              separate: _separate,
              filter: function (fga, f) {
                return function_pipe(fga, _filter(f))
              },
              filterMap: function (fga, f) {
                return function_pipe(fga, _filterMap(f))
              },
              partition: function (fga, p) {
                return function_pipe(fga, _partition(p))
              },
              partitionMap: function (fga, f) {
                return function_pipe(fga, _partitionMap(f))
              },
            }
          })(IO_io, Option_option),
          IOOption_some = (T.none(), T.of),
          IOOption_fromIO = T.fromM,
          fromOption = IO_of,
          IOOption_map = function (f) {
            return function (fa) {
              return T.map(fa, f)
            }
          },
          IOOption_chain = function (f) {
            return function (ma) {
              return T.chain(ma, f)
            }
          },
          IOOption_chainFirst = function (f) {
            return function (ma) {
              return T.chain(ma, function (a) {
                return T.map(f(a), function () {
                  return a
                })
              })
            }
          },
          IOOption_chainOptionK = function (f) {
            return IOOption_chain(
              (function (f) {
                return function () {
                  for (var a = [], _i = 0; _i < arguments.length; _i++)
                    a[_i] = arguments[_i]
                  return fromOption(f.apply(void 0, a))
                }
              })(f)
            )
          },
          IOOption_filter =
            (F.compact,
            F.separate,
            function (predicate) {
              return function (fa) {
                return F.filter(fa, predicate)
              }
            }),
          eqStrict =
            (T.map,
            T.map,
            T.ap,
            T.map,
            T.ap,
            T.map,
            T.ap,
            T.chain,
            T.map,
            T.alt,
            T.map,
            T.ap,
            T.alt,
            T.map,
            F.filter,
            F.filterMap,
            F.partition,
            F.partitionMap,
            __assign(
              {
                URI: "IOOption",
                of: IOOption_some,
                ap: T.ap,
                chain: T.chain,
                alt: T.alt,
                fromIO: IOOption_fromIO,
              },
              F
            ),
            {
              equals: function (a, b) {
                return a === b
              },
            }),
          ReadonlyNonEmptyArray_spreadArray = function (to, from) {
            for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
              to[j] = from[i]
            return to
          },
          ReadonlyNonEmptyArray_empty = emptyReadonlyArray,
          ReadonlyNonEmptyArray_isNonEmpty = internal_isNonEmpty,
          isOutOfBound = function (i, as) {
            return i < 0 || i >= as.length
          },
          appendW = function (end) {
            return function (init) {
              return ReadonlyNonEmptyArray_spreadArray(
                ReadonlyNonEmptyArray_spreadArray([], init),
                [end]
              )
            }
          },
          append = appendW,
          uniq = function (E) {
            return function (as) {
              if (1 === as.length) return as
              for (
                var out = [ReadonlyNonEmptyArray_head(as)],
                  _loop_1 = function (a) {
                    out.every(function (o) {
                      return !E.equals(o, a)
                    }) && out.push(a)
                  },
                  _i = 0,
                  rest_1 = ReadonlyNonEmptyArray_tail(as);
                _i < rest_1.length;
                _i++
              ) {
                _loop_1(rest_1[_i])
              }
              return out
            }
          },
          makeBy = function (f) {
            return function (n) {
              for (
                var j = Math.max(0, Math.floor(n)), out = [f(0)], i = 1;
                i < j;
                i++
              )
                out.push(f(i))
              return out
            }
          }
        var ReadonlyNonEmptyArray_map = function (fa, f) {
            return function_pipe(fa, es6_ReadonlyNonEmptyArray_map(f))
          },
          es6_ReadonlyNonEmptyArray_map = function (f) {
            return mapWithIndex(function (_, a) {
              return f(a)
            })
          },
          mapWithIndex = function (f) {
            return function (as) {
              for (
                var out = [f(0, ReadonlyNonEmptyArray_head(as))], i = 1;
                i < as.length;
                i++
              )
                out.push(f(i, as[i]))
              return out
            }
          },
          extract = head,
          ReadonlyNonEmptyArray_Functor = {
            URI: "ReadonlyNonEmptyArray",
            map: ReadonlyNonEmptyArray_map,
          },
          ReadonlyNonEmptyArray_head =
            (flap(ReadonlyNonEmptyArray_Functor), extract),
          ReadonlyNonEmptyArray_tail = function (as) {
            return as.slice(1)
          }
        var isEmpty = function (as) {
            return 0 === as.length
          },
          ReadonlyArray_isNonEmpty = ReadonlyNonEmptyArray_isNonEmpty,
          ReadonlyArray_append = append,
          ReadonlyArray_makeBy = function (n, f) {
            return n <= 0 ? ReadonlyArray_empty : makeBy(f)(n)
          }
        var ReadonlyArray_isOutOfBound = isOutOfBound
        var findIndex = function (predicate) {
          return function (as) {
            for (var i = 0; i < as.length; i++)
              if (predicate(as[i])) return some(i)
            return none
          }
        }
        var ReadonlyArray_reverse = function (as) {
          return as.length <= 1 ? as : as.slice().reverse()
        }
        var ReadonlyArray_map = function (fa, f) {
            return function_pipe(fa, es6_ReadonlyArray_map(f))
          },
          ReadonlyArray_reduce = function (fa, b, f) {
            return function_pipe(fa, es6_ReadonlyArray_reduce(b, f))
          },
          ReadonlyArray_foldMap = function (M) {
            var foldMapM = es6_ReadonlyArray_foldMap(M)
            return function (fa, f) {
              return function_pipe(fa, foldMapM(f))
            }
          },
          ReadonlyArray_reduceRight = function (fa, b, f) {
            return function_pipe(fa, es6_ReadonlyArray_reduceRight(b, f))
          },
          ReadonlyArray_traverse = function (F) {
            var traverseF = es6_ReadonlyArray_traverse(F)
            return function (ta, f) {
              return function_pipe(ta, traverseF(f))
            }
          },
          ReadonlyArray_zero = function () {
            return ReadonlyArray_empty
          },
          es6_ReadonlyArray_chain = function (f) {
            return function (ma) {
              return function_pipe(
                ma,
                (function (f) {
                  return function (as) {
                    if (isEmpty(as)) return ReadonlyArray_empty
                    for (var out = [], i = 0; i < as.length; i++)
                      out.push.apply(out, f(i, as[i]))
                    return out
                  }
                })(function (_, a) {
                  return f(a)
                })
              )
            }
          },
          es6_ReadonlyArray_map = function (f) {
            return function (fa) {
              return fa.map(function (a) {
                return f(a)
              })
            }
          },
          es6_ReadonlyArray_mapWithIndex = function (f) {
            return function (fa) {
              return fa.map(function (a, i) {
                return f(i, a)
              })
            }
          },
          ReadonlyArray_separate = function (fa) {
            for (
              var left = [], right = [], _i = 0, fa_1 = fa;
              _i < fa_1.length;
              _i++
            ) {
              var e = fa_1[_i]
              "Left" === e._tag ? left.push(e.left) : right.push(e.right)
            }
            return Separated_separated(left, right)
          },
          es6_ReadonlyArray_filter = function (predicate) {
            return function (as) {
              return as.filter(predicate)
            }
          },
          filterMapWithIndex = function (f) {
            return function (fa) {
              for (var out = [], i = 0; i < fa.length; i++) {
                var optionB = f(i, fa[i])
                isSome(optionB) && out.push(optionB.value)
              }
              return out
            }
          },
          es6_ReadonlyArray_filterMap = function (f) {
            return filterMapWithIndex(function (_, a) {
              return f(a)
            })
          },
          ReadonlyArray_compact =
            es6_ReadonlyArray_filterMap(function_identity),
          es6_ReadonlyArray_foldMapWithIndex = function (M) {
            return function (f) {
              return function (fa) {
                return fa.reduce(function (b, a, i) {
                  return M.concat(b, f(i, a))
                }, M.empty)
              }
            }
          },
          es6_ReadonlyArray_reduce = function (b, f) {
            return es6_ReadonlyArray_reduceWithIndex(b, function (_, b, a) {
              return f(b, a)
            })
          },
          es6_ReadonlyArray_foldMap = function (M) {
            var foldMapWithIndexM = es6_ReadonlyArray_foldMapWithIndex(M)
            return function (f) {
              return foldMapWithIndexM(function (_, a) {
                return f(a)
              })
            }
          },
          es6_ReadonlyArray_reduceWithIndex = function (b, f) {
            return function (fa) {
              for (var len = fa.length, out = b, i = 0; i < len; i++)
                out = f(i, out, fa[i])
              return out
            }
          },
          es6_ReadonlyArray_reduceRight = function (b, f) {
            return es6_ReadonlyArray_reduceRightWithIndex(
              b,
              function (_, a, b) {
                return f(a, b)
              }
            )
          },
          es6_ReadonlyArray_reduceRightWithIndex = function (b, f) {
            return function (fa) {
              return fa.reduceRight(function (b, a, i) {
                return f(i, a, b)
              }, b)
            }
          },
          es6_ReadonlyArray_traverse = function (F) {
            var traverseWithIndexF = es6_ReadonlyArray_traverseWithIndex(F)
            return function (f) {
              return traverseWithIndexF(function (_, a) {
                return f(a)
              })
            }
          },
          ReadonlyArray_sequence = function (F) {
            return function (ta) {
              return ReadonlyArray_reduce(
                ta,
                F.of(ReadonlyArray_zero()),
                function (fas, fa) {
                  return F.ap(
                    F.map(fas, function (as) {
                      return function (a) {
                        return function_pipe(as, ReadonlyArray_append(a))
                      }
                    }),
                    fa
                  )
                }
              )
            }
          },
          es6_ReadonlyArray_traverseWithIndex = function (F) {
            return function (f) {
              return es6_ReadonlyArray_reduceWithIndex(
                F.of(ReadonlyArray_zero()),
                function (i, fbs, a) {
                  return F.ap(
                    F.map(fbs, function (bs) {
                      return function (b) {
                        return function_pipe(bs, ReadonlyArray_append(b))
                      }
                    }),
                    f(i, a)
                  )
                }
              )
            }
          },
          ReadonlyArray_Functor = {
            URI: "ReadonlyArray",
            map: ReadonlyArray_map,
          },
          ReadonlyArray_Compactable =
            (flap(ReadonlyArray_Functor),
            {
              URI: "ReadonlyArray",
              compact: ReadonlyArray_compact,
              separate: ReadonlyArray_separate,
            }),
          ReadonlyArray_Traversable = {
            URI: "ReadonlyArray",
            map: ReadonlyArray_map,
            reduce: ReadonlyArray_reduce,
            foldMap: ReadonlyArray_foldMap,
            reduceRight: ReadonlyArray_reduceRight,
            traverse: ReadonlyArray_traverse,
            sequence: ReadonlyArray_sequence,
          },
          toArray =
            (Witherable_witherDefault(
              ReadonlyArray_Traversable,
              ReadonlyArray_Compactable
            ),
            Witherable_wiltDefault(
              ReadonlyArray_Traversable,
              ReadonlyArray_Compactable
            ),
            function (as) {
              return as.slice()
            }),
          ReadonlyArray_empty = ReadonlyNonEmptyArray_empty,
          ReadonlyArray_some = function (predicate) {
            return function (as) {
              return as.some(predicate)
            }
          },
          ReadonlyArray_bindTo = bindTo(ReadonlyArray_Functor)
        const external_rxjs_namespaceObject = rxjs,
          package_namespaceObject_i8 = "1.15.7",
          appendLog =
            log =>
            (a, ...b) =>
              function_pipe(
                [...log, `${a}${b.length > 0 ? ": " : ""}${b.join(", ")}`],
                x => (x.length > 1e3 ? x.slice(0, 100) : x)
              ),
          consoleLog = (...[a, ...b]) =>
            function_pipe(
              () =>
                external_log_default().info(
                  ...("string" == typeof a ? [`【FYC】 ${a}`] : ["【FYC】", a])
                ),
              IO_apSecond(
                b.length > 0
                  ? () => external_log_default().info(...b)
                  : () => {}
              )
            ),
          external_jsep_namespaceObject = jsep
        var external_jsep_default = __webpack_require__.n(
            external_jsep_namespaceObject
          ),
          u = {
            "||": function (r, e) {
              return r || e
            },
            "&&": function (r, e) {
              return r && e
            },
            "|": function (r, e) {
              return r | e
            },
            "^": function (r, e) {
              return r ^ e
            },
            "&": function (r, e) {
              return r & e
            },
            "==": function (r, e) {
              return r == e
            },
            "!=": function (r, e) {
              return r != e
            },
            "===": function (r, e) {
              return r === e
            },
            "!==": function (r, e) {
              return r !== e
            },
            "<": function (r, e) {
              return r < e
            },
            ">": function (r, e) {
              return r > e
            },
            "<=": function (r, e) {
              return r <= e
            },
            ">=": function (r, e) {
              return r >= e
            },
            "<<": function (r, e) {
              return r << e
            },
            ">>": function (r, e) {
              return r >> e
            },
            ">>>": function (r, e) {
              return r >>> e
            },
            "+": function (r, e) {
              return r + e
            },
            "-": function (r, e) {
              return r - e
            },
            "*": function (r, e) {
              return r * e
            },
            "/": function (r, e) {
              return r / e
            },
            "%": function (r, e) {
              return r % e
            },
          },
          i = {
            "-": function (r) {
              return -r
            },
            "+": function (r) {
              return +r
            },
            "~": function (r) {
              return ~r
            },
            "!": function (r) {
              return !r
            },
          }
        function s(r, e) {
          return r.map(function (r) {
            return a(r, e)
          })
        }
        function c(r, e) {
          var n,
            t = a(r.object, e)
          if (
            ((n = r.computed ? a(r.property, e) : r.property.name),
            /^__proto__|prototype|constructor$/.test(n))
          )
            throw Error('Access to member "' + n + '" disallowed.')
          return [t, t[n]]
        }
        function a(r, e) {
          var n = r
          switch (n.type) {
            case "ArrayExpression":
              return s(n.elements, e)
            case "BinaryExpression":
              return u[n.operator](a(n.left, e), a(n.right, e))
            case "CallExpression":
              var t, o, l
              if (
                ("MemberExpression" === n.callee.type
                  ? ((t = (l = c(n.callee, e))[0]), (o = l[1]))
                  : (o = a(n.callee, e)),
                "function" != typeof o)
              )
                return
              return o.apply(t, s(n.arguments, e))
            case "ConditionalExpression":
              return a(n.test, e) ? a(n.consequent, e) : a(n.alternate, e)
            case "Identifier":
              return e[n.name]
            case "Literal":
              return n.value
            case "LogicalExpression":
              return "||" === n.operator
                ? a(n.left, e) || a(n.right, e)
                : "&&" === n.operator
                ? a(n.left, e) && a(n.right, e)
                : u[n.operator](a(n.left, e), a(n.right, e))
            case "MemberExpression":
              return c(n, e)[1]
            case "ThisExpression":
              return e
            case "UnaryExpression":
              return i[n.operator](a(n.argument, e))
            default:
              return
          }
        }
        const fycKey = key => `FYC_${key}`,
          stringsArgs = [
            [],
            x => x.split(/\r\n|\n/).filter(s => "" !== s),
            x => x.join("\n"),
          ],
          sc = (k, d) =>
            (async (key, defaultVal) => ({
              gmKey: key,
              val: (await GM.getValue(key)) ?? defaultVal,
              defaultVal,
              toGm: x => x,
            }))(fycKey(k), d),
          ic = (k, d, i, g) =>
            (async (key, defaultVal, toItem, toGm) => {
              const val = await GM.getValue(key)
              return {
                gmKey: key,
                val: void 0 !== val ? toItem(val) : defaultVal,
                defaultVal,
                toGm,
              }
            })(fycKey(k), d, i, g),
          chatApp = () =>
            function_pipe(
              fromNullable(document.querySelector("#chatframe")),
              filter(x => {
                const state = x.contentDocument?.readyState
                return "loading" === state || "complete" === state
              }),
              chainNullableK(x => x.contentDocument),
              alt(() => Option_some(document)),
              chainNullableK(x => x.querySelector("yt-live-chat-app"))
            ),
          observePair = con => {
            const subject = new external_rxjs_namespaceObject.Subject()
            return { subject, observer: new con(lib(subject)) }
          }
        var Eq = {
          equals: function (first, second) {
            return first === second
          },
        }
        const external_Swal_namespaceObject = Swal
        var external_Swal_default = __webpack_require__.n(
          external_Swal_namespaceObject
        )
        const addBanButton_button = document.createElement("button")
        addBanButton_button.classList.add(
          "style-scope",
          "yt-icon-button",
          "fyc_button"
        )
        Object.assign(addBanButton_button.style, {
          padding: "0px",
          width: "20px",
          height: "20px",
          fill: "#fff",
        })
        addBanButton_button.setAttribute(
          "aria-label",
          "NGに入れる(Ban this user)"
        )
        addBanButton_button.innerHTML =
          '<svg class="style-scope yt-icon" style="width: 100%; height: 75%; fill: var(--yt-spec-text-secondary);" viewBox="0 0 512 512"><path d="M440 78A256 256 0 1 0 73 435 256 256 0 0 0 440 78zm-99 35L113 341C37 179 212 44 341 113zM177 405l228-228c76 162-99 297-228 228z" fill-rule="evenodd"/></svg>'
        const addBanButton = (chat, id, getConfig, setConfig) =>
            chat.children.namedItem("card")
              ? () => {}
              : () => {
                  const clone = addBanButton_button.cloneNode(!0)
                  clone.onclick = function_pipe(
                    getConfig.bannedUsers,
                    IOOption_fromIO,
                    IOOption_filter(x => !x.includes(id)),
                    IOOption_map(
                      function_flow(
                        (function (E) {
                          var f = uniq(E)
                          return function (as) {
                            return ReadonlyArray_isNonEmpty(as) ? f(as) : as
                          }
                        })(Eq),
                        ReadonlyArray_append(id),
                        toArray
                      )
                    ),
                    IOOption_chain(x =>
                      IOOption_fromIO(() => {
                        setConfig.bannedUsers(x)
                        external_Swal_default()
                          .mixin({
                            toast: !0,
                            position: "bottom-left",
                            timer: 2500,
                            timerProgressBar: !0,
                            showConfirmButton: !1,
                            didOpen: toast => {
                              toast.addEventListener(
                                "pointerenter",
                                external_Swal_default().stopTimer
                              )
                              toast.addEventListener(
                                "pointerleave",
                                external_Swal_default().resumeTimer
                              )
                            },
                          })
                          .fire({
                            title: `Added Banned User: ${id}`,
                            icon: "success",
                          })
                      })
                    ),
                    IO_apSecond(() => {
                      chat.style.display = "none"
                    })
                  )
                  chat.querySelector("#content #message")?.append(clone)
                },
          getChatFontSize = mainState =>
            Math.round(
              ((Math.max(mainState.getConfig.fontSize() - 0.2, 0.01) *
                mainState.playerRect.height) /
                mainState.getConfig.laneCount()) *
                (mainState.getConfig.flowY2() - mainState.getConfig.flowY1()) *
                100
            ) / 100
        var equalsDefault = function (compare) {
            return function (first, second) {
              return first === second || 0 === compare(first, second)
            }
          },
          Ord_fromCompare = function (compare) {
            return {
              equals: equalsDefault(compare),
              compare: function (first, second) {
                return first === second ? 0 : compare(first, second)
              },
            }
          },
          Ord_contramap = function (f) {
            return function (fa) {
              return Ord_fromCompare(function (first, second) {
                return fa.compare(f(first), f(second))
              })
            }
          }
        constant(0)
        var number_Eq = {
            equals: function (first, second) {
              return first === second
            },
          },
          number_Ord = {
            equals: number_Eq.equals,
            compare: function (first, second) {
              return first < second ? -1 : first > second ? 1 : 0
            },
          }
        const external_window_micro_memoize_namespaceObject =
          window["micro-memoize"]
        var external_window_micro_memoize_default = __webpack_require__.n(
          external_window_micro_memoize_namespaceObject
        )
        const getFlowChatProgress = chat =>
            function_pipe(
              chat.animation,
              chainNullableK(x => x.currentTime),
              getOrElse(() => 0)
            ) / chat.animationDuration,
          getFlowChatRect = (chat, mainState) => {
            const x =
              mainState.playerRect.width -
              (chat.width + mainState.playerRect.width) *
                getFlowChatProgress(chat)
            return new DOMRect(x, chat.y, chat.width, chat.height)
          },
          getChatLane = (flowChat, progress, flowChats) => mainState => {
            const playerWidth = mainState.playerRect.width,
              chatRect = getFlowChatRect(flowChat, mainState),
              chatWidth = chatRect.width,
              chatHeight = chatRect.height,
              chatX = chatRect.x,
              chatIndex = flowChats.indexOf(flowChat),
              movingChats = function_pipe(
                flowChats,
                (function (n) {
                  return function (as) {
                    return ReadonlyArray_isOutOfBound(n, as)
                      ? as
                      : 0 === n
                      ? ReadonlyArray_empty
                      : as.slice(0, n)
                  }
                })(chatIndex >= 0 ? chatIndex : -1),
                es6_ReadonlyArray_filter(
                  chat => !chat.animationEnded && chat.width > 0
                ),
                (function (O) {
                  return function (as) {
                    return as.length <= 1 ? as : as.slice().sort(O.compare)
                  }
                })(Ord_contramap(x => x.lane)(number_Ord))
              ),
              tooCloseTo = external_window_micro_memoize_default()(
                i => {
                  const otherRect = getFlowChatRect(movingChats[i], mainState),
                    otherWidth = otherRect.width,
                    otherX = otherRect.x,
                    gap =
                      (chatHeight * otherWidth * chatWidth) ** 0.333 *
                      mainState.getConfig.minSpacing()
                  return (
                    (playerWidth - otherX) / (playerWidth + otherWidth) -
                      progress <
                      (chatWidth + gap) / (playerWidth + chatWidth) ||
                    otherX + otherWidth + gap > chatX
                  )
                },
                { maxSize: 1e3 }
              ),
              occupyInfo = [
                ...movingChats.map((x, i) => ({
                  tooClose: () => tooCloseTo(i),
                  lane: x.lane,
                })),
                { tooClose: () => !0, lane: mainState.getConfig.laneCount() },
              ],
              index = occupyInfo.findIndex(x => x.lane >= flowChat.lane),
              rightFreeLane = function_pipe(
                occupyInfo.slice(index),
                ((predicate = x => x.tooClose()),
                function (as) {
                  for (var i = 0; i < as.length; i++)
                    if (predicate(as[i])) return some(as[i])
                  return none
                }),
                es6_Option_map(x => x.lane),
                getOrElse(() => mainState.getConfig.laneCount())
              )
            var predicate
            const leftFreeLane = function_pipe(
                occupyInfo.slice(0, index),
                (function (predicate) {
                  return function (as) {
                    for (var i = as.length - 1; i >= 0; i--)
                      if (predicate(as[i])) return some(as[i])
                    return none
                  }
                })(x => x.tooClose()),
                es6_Option_map(x => x.lane),
                getOrElse(() => -1)
              ),
              formerLaneInterval = Math.min(
                flowChat.lane - leftFreeLane,
                rightFreeLane - flowChat.lane,
                1
              )
            return function_pipe(
              occupyInfo,
              es6_ReadonlyArray_reduce(
                { maxInterval: 0, maxIntervalLane: 0, lastLane: -1 },
                ({ maxInterval, maxIntervalLane, lastLane }, info) =>
                  maxInterval > 0.999 || !info.tooClose()
                    ? { maxInterval, maxIntervalLane, lastLane }
                    : (() => {
                        const nextLane = info.lane,
                          interLane = Math.min(
                            Math.max((lastLane + nextLane) / 2, 0),
                            mainState.getConfig.laneCount() - 1
                          ),
                          newInterval = Math.min(
                            interLane - lastLane,
                            nextLane - interLane,
                            1
                          )
                        return newInterval - maxInterval > 0.001
                          ? {
                              maxInterval: newInterval,
                              maxIntervalLane: Math.max(
                                lastLane + newInterval,
                                0
                              ),
                              lastLane: nextLane,
                            }
                          : { maxInterval, maxIntervalLane, lastLane: nextLane }
                      })()
              ),
              x => ({
                lane:
                  Math.abs(formerLaneInterval - x.maxInterval) < 0.001
                    ? flowChat.lane
                    : x.maxIntervalLane,
                interval: x.maxInterval,
              })
            )
          },
          intervalTooSmall = interval => getConfig =>
            getConfig.noOverlap() && interval < 0.999,
          external_m_namespaceObject = m
        var external_m_default = __webpack_require__.n(
          external_m_namespaceObject
        )
        const textShadow = shadowColor =>
            function_flow(
              x => `${x}px`,
              x => (a, b) => `${a}${x} ${b}${x} ${shadowColor}99`,
              x => [x("-", "-"), x("", "-"), x("-", ""), x("", "")].join(", ")
            ),
          textStyle = { fontFamily: "inherit" },
          chatNode = (chat, mainState) => {
            const { getConfig } = mainState,
              data = chat.getData(getConfig)
            return external_m_default()(
              "span",
              {
                style: {
                  fontSize: `${getChatFontSize(mainState)}px`,
                  visibility: getConfig.displayChats() ? "visible" : "hidden",
                  color:
                    "owner" === data.authorType
                      ? getConfig.ownerColor()
                      : "moderator" === data.authorType
                      ? getConfig.moderatorColor()
                      : "member" === data.authorType
                      ? getConfig.memberColor()
                      : getConfig.color(),
                  fontWeight: getConfig.fontWeight().toString(),
                  fontFamily: getConfig.font(),
                  opacity: getConfig.chatOpacity().toString(),
                  textShadow: textShadow(getConfig.shadowColor())(
                    getConfig.shadowFontWeight()
                  ),
                },
              },
              function_pipe(
                [
                  function_pipe(
                    data.authorName,
                    filter(x => x.visible),
                    es6_Option_map(x =>
                      external_m_default()(
                        "span",
                        {
                          style: {
                            color: toUndefined(data.textColor),
                            fontSize: "0.84em",
                            ...textStyle,
                          },
                        },
                        `${x.content}: `
                      )
                    )
                  ),
                  function_pipe(
                    data.messageElement,
                    es6_Option_map(x =>
                      ((message, getConfig) => {
                        const eleWin =
                            message.ownerDocument.defaultView ?? window,
                          maxChatLength = getConfig.maxChatLength()
                        return function_pipe(
                          Array.from(message.childNodes),
                          es6_ReadonlyArray_reduce(
                            { vnodes: [], length: 0 },
                            ({ vnodes, length }, node) => {
                              return length >= maxChatLength
                                ? { vnodes, length }
                                : !getConfig.textOnly() &&
                                  node instanceof eleWin.HTMLImageElement
                                ? {
                                    vnodes: [
                                      ...vnodes,
                                      external_m_default()("img", {
                                        style: {
                                          height: "1em",
                                          width: "1em",
                                          verticalAlign: "text-top",
                                        },
                                        src: node.src,
                                        alt: node.alt,
                                      }),
                                    ],
                                    length: length + 1,
                                  }
                                : function_pipe(
                                    node.textContent ?? "",
                                    ((start = 0),
                                    (end = maxChatLength),
                                    function (s) {
                                      return s.slice(start, end)
                                    }),
                                    x =>
                                      node instanceof eleWin.HTMLAnchorElement
                                        ? {
                                            vnodes: [
                                              ...vnodes,
                                              external_m_default()(
                                                "span",
                                                {
                                                  style: {
                                                    fontSize: "0.84em",
                                                    textDecoration: "underline",
                                                    ...textStyle,
                                                  },
                                                },
                                                x
                                              ),
                                            ],
                                            length: length + x.length,
                                          }
                                        : {
                                            vnodes: [
                                              ...vnodes,
                                              external_m_default().fragment(
                                                {},
                                                x
                                              ),
                                            ],
                                            length: length + x.length,
                                          }
                                  )
                              var start, end
                            }
                          )
                        )
                      })(x, getConfig)
                    ),
                    es6_Option_map(x =>
                      external_m_default()(
                        "span",
                        {
                          style: {
                            color: toUndefined(data.textColor),
                            ...textStyle,
                          },
                        },
                        x.vnodes
                      )
                    )
                  ),
                  function_pipe(
                    data.paymentInfo,
                    filter(x => x.visible),
                    es6_Option_map(x =>
                      external_m_default()(
                        "span",
                        {
                          style: {
                            color: toUndefined(data.paidColor),
                            fontSize: "0.84em",
                            ...textStyle,
                          },
                        },
                        external_m_default()(
                          "strong",
                          { style: textStyle },
                          x.content
                        )
                      )
                    )
                  ),
                ],
                ReadonlyArray_compact,
                toArray
              )
            )
          },
          renderChat = chat => mainState => () =>
            external_m_default().render(
              chat.element,
              chatNode(chat, mainState)
            ),
          external_window_hash_it_namespaceObject = window["hash-it"]
        var external_window_hash_it_default = __webpack_require__.n(
          external_window_hash_it_namespaceObject
        )
        const getLaneY = (lane, mainState) =>
            mainState.playerRect.height *
            ((lane / mainState.getConfig.laneCount() + 0.005) *
              (mainState.getConfig.flowY2() - mainState.getConfig.flowY1()) +
              mainState.getConfig.flowY1()),
          setChatPlayState = chat => mainState =>
            function_pipe(
              chat,
              fromPredicate(x => !x.animationEnded),
              x => x,
              fromOption,
              IOOption_chainOptionK(x => x.animation),
              IOOption_chainFirst(x =>
                IOOption_fromIO(
                  mainState.chatPlaying ? () => x.play() : () => x.pause()
                )
              ),
              IOOption_chain(x =>
                IOOption_fromIO(() => {
                  x.playbackRate = mainState.getConfig.flowSpeed() / 15
                })
              )
            ),
          getWidth = external_window_micro_memoize_default()(
            ele => ele?.getBoundingClientRect().width ?? 0,
            {
              maxSize: 2e3,
              transformKey: args => args.map(external_window_hash_it_default()),
            }
          ),
          setChatAnimation = (chat, chats) => mainState =>
            function_pipe(
              { fontSize: getChatFontSize(mainState) },
              IO_of,
              IO_chainFirst(x => () => {
                chat.element.style.transform = `translate(${
                  mainState.playerRect.width
                }px, -${2 * x.fontSize}px)`
              }),
              IOOption_fromIO,
              IOOption_filter(() => !chat.animationEnded),
              IOOption_chainFirst(x =>
                IOOption_fromIO(() => {
                  chat.animationDuration = 6400
                  chat.width = getWidth(chat.element.firstElementChild)
                  chat.height = x.fontSize
                })
              ),
              IOOption_map(() => ({ progress: getFlowChatProgress(chat) })),
              IOOption_map(x => ({
                ...x,
                ...getChatLane(chat, x.progress, chats)(mainState),
              })),
              IOOption_chain(ctx =>
                intervalTooSmall(ctx.interval)(mainState.getConfig)
                  ? function_pipe(
                      chat.animation,
                      fromOption,
                      IOOption_chain(x =>
                        IOOption_fromIO(() => {
                          x.finish()
                          chat.animation = Option_none
                        })
                      ),
                      es6_IO_map(() => Option_none)
                    )
                  : IOOption_some(ctx)
              ),
              IOOption_chainFirst(x =>
                IOOption_fromIO(() => {
                  chat.lane = x.lane
                })
              ),
              IOOption_map(x => ({
                ...x,
                laneY: getLaneY(chat.lane, mainState),
              })),
              IOOption_chain(ctx =>
                function_pipe(
                  [
                    function_pipe(
                      chat.animation,
                      fromOption,
                      IOOption_chain(x => IOOption_fromIO(() => x.cancel()))
                    ),
                    function_pipe(
                      [
                        [mainState.playerRect.width, ctx.laneY],
                        [-chat.width, ctx.laneY],
                      ],
                      es6_ReadonlyArray_map(
                        es6_ReadonlyArray_map(x => `${x}px`)
                      ),
                      es6_ReadonlyArray_map(
                        ([x, y]) => `translate(${x}, ${y})`
                      ),
                      ReadonlyArray_bindTo("transform"),
                      toArray,
                      x =>
                        chat.element.animate(x, {
                          duration: 6400,
                          easing: mainState.getConfig.timingFunction(),
                        }),
                      x => {
                        x.onfinish = () => {
                          chat.animationEnded = !0
                        }
                        chat.y = ctx.laneY
                        const newTime = 6400 * ctx.progress
                        x.currentTime = newTime
                        return x
                      },
                      Option_some,
                      x => () => {
                        chat.animation = x
                      },
                      IO_apSecond(setChatPlayState(chat)(mainState))
                    ),
                  ],
                  IO_sequenceArray,
                  IOOption_fromIO
                )
              ),
              es6_IO_map(Option_isSome)
            ),
          emptyElement = document.createElement("span")
        var Semigroup_concatAll = function (M) {
            return function (startWith) {
              return function (as) {
                return as.reduce(function (a, acc) {
                  return M.concat(a, acc)
                }, startWith)
              }
            }
          },
          semigroupVoid = (function (a) {
            return {
              concat: function () {
                return a
              },
            }
          })(void 0)
        var Monoid_concatAll = function (M) {
            return Semigroup_concatAll(M)(M.empty)
          },
          MonoidAll =
            (semigroupVoid.concat,
            {
              concat: function (first, second) {
                return first && second
              },
              empty: !0,
            }),
          MonoidAny = {
            concat: function (first, second) {
              return first || second
            },
            empty: !1,
          }
        const operators = {
            flip: x => b => a => x(a)(b),
            flow: fns => function_flow(...fns),
            and: Monoid_concatAll(MonoidAll),
            or: Monoid_concatAll(MonoidAny),
            RA: { some: ReadonlyArray_some, compact: ReadonlyArray_compact },
            O: {
              exists: function (predicate) {
                return function (ma) {
                  return !Option_isNone(ma) && predicate(ma.value)
                }
              },
            },
            allPreds: Monoid_concatAll(function_getMonoid(MonoidAll)()),
            anyPreds: Monoid_concatAll(function_getMonoid(MonoidAny)()),
            inText: text => x => text.content.includes(x),
            eqText: text => x => text.content === x,
            matchedByText: text => x =>
              Boolean(text.content.match(RegExp(x, "u"))),
            isVisible: x => x.visible,
          },
          checkBannedWords = (data, mainState, mainLog) =>
            function_pipe(
              data,
              fromPredicate(() =>
                function_pipe(
                  mainState.filterExp,
                  es6_Option_map(x =>
                    a(
                      x,
                      (data => ({
                        ...operators,
                        authorName: data.authorName,
                        message: data.message,
                        messageText: data.messageText,
                        paymentInfo: data.paymentInfo,
                        authorID: function_pipe(
                          data.authorID,
                          es6_Option_map(x => ({ visible: !1, content: x }))
                        ),
                      }))(data)
                    )
                  ),
                  getOrElse(() => !1)
                )
              ),
              es6_Option_map(x => [
                function_pipe(
                  x.message,
                  es6_Option_map(m => m.content)
                ),
                function_pipe(
                  x.paymentInfo,
                  es6_Option_map(p => p.content)
                ),
              ]),
              es6_Option_map(es6_ReadonlyArray_map(getOrElse(() => ""))),
              es6_Option_map(JSON.stringify),
              es6_Option_map(x => mainLog(`Banned: ${x}`)),
              match(
                () => () => !1,
                es6_IO_map(() => !0)
              )
            )(),
          assert_lib = check.assert,
          tapNonNull = x => {
            assert_lib(null != x)
            return x
          },
          onChatFieldMutate = (
            chatScrn,
            flowChats,
            mainState,
            setConfig,
            mainLog
          ) =>
            function_flow(
              es6_ReadonlyArray_chain(e => Array.from(e.addedNodes)),
              es6_ReadonlyArray_filter(x => x.children.length > 0),
              ReadonlyArray_reverse,
              es6_ReadonlyArray_map(chat => () => {
                const getData = (chat => {
                    const chatType = chat.querySelector(
                        ".yt-live-chat-ticker-paid-message-item-renderer"
                      )
                        ? "ticker"
                        : chat.querySelector(
                            ".yt-live-chat-membership-item-renderer"
                          )
                        ? "membership"
                        : chat.querySelector(
                            ".yt-live-chat-viewer-engagement-message-renderer"
                          )
                        ? "engagement"
                        : "normal",
                      isPaid =
                        "ticker" === chatType ||
                        Boolean(chat.querySelector("#card")),
                      paymentInfo = function_pipe(
                        fromNullable(
                          isPaid
                            ? chat.querySelector(
                                [
                                  "#purchase-amount",
                                  "#purchase-amount-chip",
                                  "#content>#text",
                                ].join(",")
                              )?.textContent
                            : void 0
                        ),
                        es6_Option_map(x => ({ visible: !0, content: x }))
                      ),
                      authorType = chat.querySelector(".owner")
                        ? "owner"
                        : chat.querySelector(".moderator")
                        ? "moderator"
                        : chat.querySelector(".member")
                        ? "member"
                        : "normal",
                      messageElement = fromNullable(
                        chat.querySelector("#message")
                      ),
                      isPaidNormal =
                        !!Option_isSome(paymentInfo) &&
                        Boolean(
                          chat.querySelector(
                            ".yt-live-chat-paid-message-renderer"
                          )
                        ),
                      isPaidSticker =
                        !(!Option_isSome(paymentInfo) || isPaidNormal) &&
                        Boolean(
                          chat.querySelector(
                            ".yt-live-chat-paid-sticker-renderer"
                          )
                        ),
                      textColor = fromNullable(
                        isPaidNormal
                          ? window
                              .getComputedStyle(
                                tapNonNull(chat.querySelector("#header"))
                              )
                              .getPropertyValue("background-color")
                          : isPaidSticker
                          ? window
                              .getComputedStyle(chat)
                              .getPropertyValue(
                                "--yt-live-chat-paid-sticker-chip-background-color"
                              )
                          : void 0
                      ),
                      paidColor = fromNullable(
                        isPaidNormal
                          ? window
                              .getComputedStyle(
                                tapNonNull(chat.querySelector("#content"))
                              )
                              .getPropertyValue("background-color")
                          : isPaidSticker
                          ? window
                              .getComputedStyle(chat)
                              .getPropertyValue(
                                "--yt-live-chat-paid-sticker-background-color"
                              )
                          : void 0
                      ),
                      authorPhotoMatches = chat
                        .querySelector(["#author-photo", "img"].join(" "))
                        ?.src.match(/ytc\/(.*)=/),
                      authorID = fromNullable(
                        authorPhotoMatches?.[authorPhotoMatches.length - 1]
                      ),
                      authorName = fromNullable(
                        chat.querySelector("#author-name")?.textContent
                      ),
                      message = function_pipe(
                        messageElement,
                        es6_Option_map(x => ({
                          visible: !0,
                          content: x.innerHTML,
                        }))
                      ),
                      messageText = function_pipe(
                        messageElement,
                        es6_Option_map(x => ({
                          visible: !0,
                          content: x.textContent ?? "",
                        }))
                      )
                    return getConfig => ({
                      chatType,
                      authorType,
                      authorID,
                      authorName: function_pipe(
                        authorName,
                        es6_Option_map(x => ({
                          visible:
                            ("moderator" === authorType &&
                              getConfig.displayModName()) ||
                            (Option_isSome(paymentInfo) &&
                              getConfig.displaySuperChatAuthor()),
                          content: x,
                        }))
                      ),
                      messageElement,
                      message,
                      messageText,
                      paymentInfo,
                      textColor,
                      paidColor,
                    })
                  })(chat),
                  { getConfig } = mainState,
                  data = getData(getConfig)
                ;(checkBannedWords(data, mainState, mainLog)
                  ? () => {
                      chat.style.display = "none"
                    }
                  : function_pipe(
                      [
                        function_pipe(
                          void 0,
                          fromPredicate(getConfig.createChats),
                          filter(() => "normal" === data.chatType),
                          fromOption,
                          IOOption_chain(() =>
                            IOOption_fromIO(
                              ((getData, flowChats, chatScrn, mainState) =>
                                function_pipe(
                                  {
                                    getData,
                                    element: emptyElement,
                                    lane: -1,
                                    animation: Option_none,
                                    animationDuration: 0,
                                    animationEnded: !1,
                                    width: 2,
                                    height: getChatFontSize(mainState),
                                    y: 0,
                                  },
                                  x =>
                                    getChatLane(x, 0, flowChats)(mainState)
                                      .interval,
                                  intervalTooSmall,
                                  x => x(mainState.getConfig)
                                )
                                  ? () => {}
                                  : () => {
                                      const offScreenIndex = function_pipe(
                                          flowChats,
                                          findIndex(
                                            chat =>
                                              chat.animationEnded ||
                                              flowChats.length >=
                                                mainState.getConfig.maxChatCount()
                                          )
                                        ),
                                        element = function_pipe(
                                          offScreenIndex,
                                          es6_Option_map(
                                            x => flowChats[x].element
                                          ),
                                          getOrElseW(() =>
                                            document.createElement("span")
                                          )
                                        )
                                      function_pipe(
                                        offScreenIndex,
                                        match(
                                          () => () => {
                                            external_log_default().debug(
                                              "CreateFlowChat"
                                            )
                                            chatScrn.append(element)
                                          },
                                          i =>
                                            function_pipe(
                                              () =>
                                                flowChats.splice(i, 1)[0]
                                                  .animation,
                                              IOOption_chain(oldAnimation =>
                                                IOOption_fromIO(() =>
                                                  oldAnimation.cancel()
                                                )
                                              )
                                            )
                                        )
                                      )()
                                      const flowChat = {
                                        getData,
                                        element,
                                        lane: -1,
                                        animation: Option_none,
                                        animationDuration: 0,
                                        animationEnded: !1,
                                        width: 2,
                                        height: getChatFontSize(mainState),
                                        y: 0,
                                      }
                                      element.classList.add("fyc_chat")
                                      function_pipe(
                                        mainState,
                                        IO_of,
                                        IO_chainFirst(renderChat(flowChat)),
                                        es6_IO_chain(
                                          setChatAnimation(flowChat, flowChats)
                                        ),
                                        es6_IO_chain(x =>
                                          x
                                            ? () => flowChats.push(flowChat)
                                            : () => flowChat.element.remove()
                                        )
                                      )()
                                    })(getData, flowChats, chatScrn, mainState)
                            )
                          )
                        ),
                        function_pipe(
                          data.authorID,
                          fromOption,
                          IOOption_filter(getConfig.createBanButton),
                          IOOption_chain(x =>
                            IOOption_fromIO(
                              addBanButton(chat, x, getConfig, setConfig)
                            )
                          ),
                          es6_IO_map(() => Option_some(void 0)),
                          IOOption_filter(getConfig.simplifyChatField),
                          IOOption_chain(() =>
                            IOOption_fromIO(
                              (chat =>
                                chat.querySelector(
                                  ".style-scope.yt-live-chat-paid-message-renderer"
                                )
                                  ? () => {}
                                  : function_pipe(
                                      [
                                        "#author-photo",
                                        "yt-live-chat-author-chip.style-scope.yt-live-chat-text-message-renderer",
                                      ],
                                      es6_ReadonlyArray_map(x =>
                                        fromNullable(chat.querySelector(x))
                                      ),
                                      ReadonlyArray_compact,
                                      es6_ReadonlyArray_map(x => () => {
                                        x.style.display = "none"
                                      }),
                                      ReadonlyArray_append(() => {
                                        chat.style.borderBottom =
                                          "1px solid var(--yt-spec-text-secondary)"
                                      }),
                                      IO_sequenceArray
                                    ))(chat)
                            )
                          )
                        ),
                      ],
                      IO_sequenceArray
                    ))()
              }),
              IO_sequenceArray
            ),
          removeOldChats = (flowChats, maxChatCount) => {
            flowChats.sort((a, b) =>
              a.animationEnded === b.animationEnded
                ? 0
                : a.animationEnded
                ? -1
                : 1
            )
            flowChats
              .splice(0, Math.max(0, flowChats.length - maxChatCount))
              .forEach(x => {
                external_log_default().debug("RemoveChat")
                x.element.remove()
              })
          }
        var EMPTY_OBJ = {},
          EMPTY_ARR = [],
          id = a => a,
          hyperapp_map = EMPTY_ARR.map,
          isArray = Array.isArray,
          enqueue =
            "undefined" != typeof requestAnimationFrame
              ? requestAnimationFrame
              : setTimeout,
          createClass = obj => {
            var out = ""
            if ("string" == typeof obj) return obj
            if (isArray(obj))
              for (var tmp, k = 0; k < obj.length; k++)
                (tmp = createClass(obj[k])) && (out += (out && " ") + tmp)
            else for (var k in obj) obj[k] && (out += (out && " ") + k)
            return out
          },
          shouldRestart = (a, b) => {
            for (var k in { ...a, ...b })
              if ("function" == typeof (isArray(a[k]) ? a[k][0] : a[k]))
                b[k] = a[k]
              else if (a[k] !== b[k]) return !0
          },
          getKey = vdom => (null == vdom ? vdom : vdom.key),
          patchProperty = (node, key, oldValue, newValue, listener, isSvg) => {
            if ("key" === key);
            else if ("style" === key)
              for (var k in { ...oldValue, ...newValue }) {
                oldValue =
                  null == newValue || null == newValue[k] ? "" : newValue[k]
                "-" === k[0]
                  ? node[key].setProperty(k, oldValue)
                  : (node[key][k] = oldValue)
              }
            else
              "o" === key[0] && "n" === key[1]
                ? ((node.events || (node.events = {}))[(key = key.slice(2))] =
                    newValue)
                  ? oldValue || node.addEventListener(key, listener)
                  : node.removeEventListener(key, listener)
                : !isSvg && "list" !== key && "form" !== key && key in node
                ? (node[key] = null == newValue ? "" : newValue)
                : null == newValue ||
                  !1 === newValue ||
                  ("class" === key && !(newValue = createClass(newValue)))
                ? node.removeAttribute(key)
                : node.setAttribute(key, newValue)
          },
          createNode = (vdom, listener, isSvg) => {
            var props = vdom.props,
              node =
                3 === vdom.type
                  ? document.createTextNode(vdom.tag)
                  : (isSvg = isSvg || "svg" === vdom.tag)
                  ? document.createElementNS(
                      "http://www.w3.org/2000/svg",
                      vdom.tag,
                      { is: props.is }
                    )
                  : document.createElement(vdom.tag, { is: props.is })
            for (var k in props)
              patchProperty(node, k, null, props[k], listener, isSvg)
            for (var i = 0; i < vdom.children.length; i++)
              node.appendChild(
                createNode(
                  (vdom.children[i] = maybeVNode(vdom.children[i])),
                  listener,
                  isSvg
                )
              )
            return (vdom.node = node)
          },
          patch = (parent, node, oldVNode, newVNode, listener, isSvg) => {
            if (oldVNode === newVNode);
            else if (
              null != oldVNode &&
              3 === oldVNode.type &&
              3 === newVNode.type
            )
              oldVNode.tag !== newVNode.tag && (node.nodeValue = newVNode.tag)
            else if (null == oldVNode || oldVNode.tag !== newVNode.tag) {
              node = parent.insertBefore(
                createNode((newVNode = maybeVNode(newVNode)), listener, isSvg),
                node
              )
              null != oldVNode && parent.removeChild(oldVNode.node)
            } else {
              var tmpVKid,
                oldVKid,
                oldKey,
                newKey,
                oldProps = oldVNode.props,
                newProps = newVNode.props,
                oldVKids = oldVNode.children,
                newVKids = newVNode.children,
                oldHead = 0,
                newHead = 0,
                oldTail = oldVKids.length - 1,
                newTail = newVKids.length - 1
              isSvg = isSvg || "svg" === newVNode.tag
              for (var i in { ...oldProps, ...newProps })
                ("value" === i || "selected" === i || "checked" === i
                  ? node[i]
                  : oldProps[i]) !== newProps[i] &&
                  patchProperty(
                    node,
                    i,
                    oldProps[i],
                    newProps[i],
                    listener,
                    isSvg
                  )
              for (
                ;
                newHead <= newTail &&
                oldHead <= oldTail &&
                null != (oldKey = getKey(oldVKids[oldHead])) &&
                oldKey === getKey(newVKids[newHead]);

              )
                patch(
                  node,
                  oldVKids[oldHead].node,
                  oldVKids[oldHead],
                  (newVKids[newHead] = maybeVNode(
                    newVKids[newHead++],
                    oldVKids[oldHead++]
                  )),
                  listener,
                  isSvg
                )
              for (
                ;
                newHead <= newTail &&
                oldHead <= oldTail &&
                null != (oldKey = getKey(oldVKids[oldTail])) &&
                oldKey === getKey(newVKids[newTail]);

              )
                patch(
                  node,
                  oldVKids[oldTail].node,
                  oldVKids[oldTail],
                  (newVKids[newTail] = maybeVNode(
                    newVKids[newTail--],
                    oldVKids[oldTail--]
                  )),
                  listener,
                  isSvg
                )
              if (oldHead > oldTail)
                for (; newHead <= newTail; )
                  node.insertBefore(
                    createNode(
                      (newVKids[newHead] = maybeVNode(newVKids[newHead++])),
                      listener,
                      isSvg
                    ),
                    (oldVKid = oldVKids[oldHead]) && oldVKid.node
                  )
              else if (newHead > newTail)
                for (; oldHead <= oldTail; )
                  node.removeChild(oldVKids[oldHead++].node)
              else {
                var keyed = {},
                  newKeyed = {}
                for (i = oldHead; i <= oldTail; i++)
                  null != (oldKey = oldVKids[i].key) &&
                    (keyed[oldKey] = oldVKids[i])
                for (; newHead <= newTail; ) {
                  oldKey = getKey((oldVKid = oldVKids[oldHead]))
                  newKey = getKey(
                    (newVKids[newHead] = maybeVNode(newVKids[newHead], oldVKid))
                  )
                  if (
                    newKeyed[oldKey] ||
                    (null != newKey && newKey === getKey(oldVKids[oldHead + 1]))
                  ) {
                    null == oldKey && node.removeChild(oldVKid.node)
                    oldHead++
                  } else if (null == newKey || 1 === oldVNode.type) {
                    if (null == oldKey) {
                      patch(
                        node,
                        oldVKid && oldVKid.node,
                        oldVKid,
                        newVKids[newHead],
                        listener,
                        isSvg
                      )
                      newHead++
                    }
                    oldHead++
                  } else {
                    if (oldKey === newKey) {
                      patch(
                        node,
                        oldVKid.node,
                        oldVKid,
                        newVKids[newHead],
                        listener,
                        isSvg
                      )
                      newKeyed[newKey] = !0
                      oldHead++
                    } else if (null != (tmpVKid = keyed[newKey])) {
                      patch(
                        node,
                        node.insertBefore(
                          tmpVKid.node,
                          oldVKid && oldVKid.node
                        ),
                        tmpVKid,
                        newVKids[newHead],
                        listener,
                        isSvg
                      )
                      newKeyed[newKey] = !0
                    } else
                      patch(
                        node,
                        oldVKid && oldVKid.node,
                        null,
                        newVKids[newHead],
                        listener,
                        isSvg
                      )
                    newHead++
                  }
                }
                for (; oldHead <= oldTail; )
                  null == getKey((oldVKid = oldVKids[oldHead++])) &&
                    node.removeChild(oldVKid.node)
                for (var i in keyed)
                  null == newKeyed[i] && node.removeChild(keyed[i].node)
              }
            }
            return (newVNode.node = node)
          },
          maybeVNode = (newVNode, oldVNode) =>
            !0 !== newVNode && !1 !== newVNode && newVNode
              ? "function" == typeof newVNode.tag
                ? ((!oldVNode ||
                    null == oldVNode.memo ||
                    ((a, b) => {
                      for (var k in a) if (a[k] !== b[k]) return !0
                      for (var k in b) if (a[k] !== b[k]) return !0
                    })(oldVNode.memo, newVNode.memo)) &&
                    ((oldVNode = newVNode.tag(newVNode.memo)).memo =
                      newVNode.memo),
                  oldVNode)
                : newVNode
              : hyperapp_text(""),
          recycleNode = node =>
            3 === node.nodeType
              ? hyperapp_text(node.nodeValue, node)
              : createVNode(
                  node.nodeName.toLowerCase(),
                  EMPTY_OBJ,
                  hyperapp_map.call(node.childNodes, recycleNode),
                  1,
                  node
                ),
          createVNode = (tag, props, children, type, node) => ({
            tag,
            props,
            key: props.key,
            children,
            type,
            node,
          }),
          hyperapp_text = (value, node) =>
            createVNode(value, EMPTY_OBJ, EMPTY_ARR, 3, node),
          h = (tag, props, children = EMPTY_ARR) =>
            createVNode(tag, props, isArray(children) ? children : [children]),
          app = ({
            node,
            view,
            subscriptions,
            dispatch = id,
            init = EMPTY_OBJ,
          }) => {
            var state,
              busy,
              vdom = node && recycleNode(node),
              subs = [],
              update = newState => {
                if (state !== newState) {
                  null == (state = newState) &&
                    (dispatch = subscriptions = render = id)
                  subscriptions &&
                    (subs = ((oldSubs, newSubs = EMPTY_ARR, dispatch) => {
                      for (
                        var oldSub, newSub, subs = [], i = 0;
                        i < oldSubs.length || i < newSubs.length;
                        i++
                      ) {
                        oldSub = oldSubs[i]
                        newSub = newSubs[i]
                        subs.push(
                          newSub && !0 !== newSub
                            ? !oldSub ||
                              newSub[0] !== oldSub[0] ||
                              shouldRestart(newSub[1], oldSub[1])
                              ? [
                                  newSub[0],
                                  newSub[1],
                                  (oldSub && oldSub[2](),
                                  newSub[0](dispatch, newSub[1])),
                                ]
                              : oldSub
                            : oldSub && oldSub[2]()
                        )
                      }
                      return subs
                    })(subs, subscriptions(state), dispatch))
                  view && !busy && enqueue(render, (busy = !0))
                }
              },
              render = () =>
                (node = patch(
                  node.parentNode,
                  node,
                  vdom,
                  (vdom = view(state)),
                  listener,
                  (busy = !1)
                )),
              listener = function (event) {
                dispatch(this.events[event.type], event)
              }
            return (
              (dispatch = dispatch((action, props) =>
                "function" == typeof action
                  ? dispatch(action(state, props))
                  : isArray(action)
                  ? "function" == typeof action[0]
                    ? dispatch(action[0], action[1])
                    : action
                        .slice(1)
                        .map(
                          fx => fx && !0 !== fx && fx[0](dispatch, fx[1]),
                          update(action[0])
                        )
                  : update(action)
              ))(init),
              dispatch
            )
          }
        const src_defaultSettingText = {
            setting: ["Settings", "設定"],
            font: ["Font", "フォント"],
            color: ["Color(Normal)", "色(通常)"],
            ownerColor: ["Color(Owner)", "色(オーナー)"],
            moderatorColor: ["Color(Moderator)", "色(モデレーター)"],
            memberColor: ["Color(Member)", "色(メンバー)"],
            feedback: ["Feedback", "バグ報告と要望"],
            eventLog: ["Event log", "イベントログ"],
            giveFeedback: [
              "Give your feedbacks here(Please attach the event log if they're bug related)",
              "バグ報告、要望はこちら(バグの場合は、イベントログを添付してください)",
            ],
            chatOpacity: ["Opacity", "不透明度"],
            fontSize: ["Size", "サイズ"],
            fontWeight: ["Weight", "太さ"],
            shadowFontWeight: ["Weight(Shadow)", "太さ(影)"],
            flowSpeed: ["Speed", "速度"],
            maxChatCount: ["Max number of chats", "最大表示数"],
            maxChatLength: ["Max number of characters", "最大文字数"],
            laneCount: ["Number of rows", "行数"],
            bannedWords: ["Banned Words", "NGワード"],
            bannedWordRegexs: ["Banned Words(Regex)", "NGワード(正規表現)"],
            bannedUsers: ["Banned Users", "NGユーザー"],
            simplifyChatField: ["Simplify", "簡略化する"],
            createBanButton: ["Show ban button", "NGボタンを表示する"],
            displayModName: [
              "Show moderator's name",
              "モデレータの名前を表示する",
            ],
            displaySuperChatAuthor: [
              "Show super chat author",
              "スパチャの作成者を表示する",
            ],
            createChats: ["Display flowing chats", "チャットを流す"],
            textOnly: [
              "Text only(ignore emojis)",
              "文字のみ(絵文字を無視する)",
            ],
            error: ["Error", "エラー"],
            video: ["Video", "画面"],
            chatField: ["Chat Window", "チャット欄"],
            useStepTiming: ["Move chat in steps", "チャットを段階的に動かす"],
            timingStepCount: ["└Step Count", "└段階数"],
            chatFilter: ["Chat Filter", "チャットフィルター"],
            flowChat: ["Flow Chat", "チャット流れ"],
            clearFlowChats: [
              "Clear Flowing Chats",
              "流れるチャットをクリアする",
            ],
            flowNewChatIf: [
              "A new chat will appear if all of the followings are met:",
              "新しいチャットは以下のすべてを満たす場合に流れます:",
            ],
            noOverlap: ["└Chats won't overlap", "└他のチャットと重ならない"],
            minSpacing: ["Min spacing between chats", "チャットの最小間隔"],
            fieldScale: ["Scale", "拡大率"],
            copy: ["Copy", "コピーする"],
            showChat: ["Show chats", "チャット非表示"],
            hideChat: ["Hide chats", "チャット表示"],
            flowY1: ["Flow area top edge", "流れ範囲の上端"],
            flowY2: ["Flow area bottom edge", "流れ範囲の下端"],
            shadowColor: ["Color(Shadow)", "色(影)"],
          },
          getLang = lang => key =>
            src_defaultSettingText[key]["FYC_EN" === lang ? 0 : 1],
          colorInput = action => color =>
            h("input", {
              style: { verticalAlign: "middle", width: "5.5em" },
              maxlength: 20,
              value: color,
              ...action,
            }),
          colorPicker = action => color =>
            h("input", {
              style: { width: "36px", verticalAlign: "middle" },
              type: "color",
              value: color,
              oninput: action.onchange,
            }),
          colorTextOutput = textStyle => color =>
            h(
              "span",
              { style: { ...textStyle, color } },
              hyperapp_text("Aa1あア亜")
            ),
          tapIs = (constructor, x) => {
            assert_lib(x instanceof constructor)
            return x
          },
          getValue = e => {
            const target = e.currentTarget ?? e.__target
            if (
              target instanceof HTMLSelectElement ||
              target instanceof HTMLTextAreaElement ||
              target instanceof HTMLInputElement
            )
              return target.value
            throw Error("Event target type isn't acceptable.")
          },
          ui_option = (value, label, selected) =>
            h("option", { value, selected }, hyperapp_text(label)),
          rangeRow = (min, max, step, value, editing, action) =>
            h("div", {}, [
              h("input", {
                style: { width: "150px", verticalAlign: "middle" },
                type: "range",
                min,
                max,
                step,
                value,
                oninput: action.onchange,
              }),
              h("input", {
                style: {
                  width: "30px",
                  backgroundColor: "transparent",
                  color: "inherit",
                  borderWidth: "1px",
                  verticalAlign: "middle",
                },
                inputmode: "decimal",
                value: editing
                  ? value
                  : Number.parseFloat(value)
                      .toFixed(4)
                      .replace(/\.?0+$/, ""),
                ...action,
              }),
            ]),
          settingRow = (label, content) =>
            h("div", {}, [
              h("span", {}, hyperapp_text(label)),
              h("div", {}, content),
            ]),
          tabContainer = (style, labels, tabs, mainTab, ontabSelect) =>
            h("div", {}, [
              h(
                "div",
                {},
                labels.map((x, i) =>
                  h(
                    "span",
                    {
                      style: {
                        ...style.label,
                        ...(mainTab === i ? style.labelFocus : {}),
                        display: "inline-block",
                      },
                      onpointerdown: [ontabSelect, i],
                    },
                    hyperapp_text(x)
                  )
                )
              ),
              h(
                "div",
                { style: { ...style.container, overflow: "hidden auto" } },
                h(
                  "div",
                  { style: { ...style.tab } },
                  tabs.find((_, i) => i === mainTab)?.()
                )
              ),
            ]),
          style = {
            resize: "horizontal",
            boxSizing: "border-box",
            width: "100%",
          },
          textAreaRow = (rows, value, readOnly, action) =>
            h("textarea", { rows, value, readOnly, style, ...action })
        var Either_right = right,
          Either_map = function (fa, f) {
            return function_pipe(fa, es6_Either_map(f))
          },
          es6_Either_map = function (f) {
            return function (fa) {
              return Either_isLeft(fa) ? fa : Either_right(f(fa.right))
            }
          },
          Either_Functor = { URI: "Either", map: Either_map },
          Either_of = Either_right,
          Either_isLeft = isLeft
        flap(Either_Functor)
        Either_of(emptyReadonlyArray)
        var Reader_map = function (fa, f) {
            return function_pipe(fa, es6_Reader_map(f))
          },
          es6_Reader_map = function (f) {
            return function (fa) {
              return function (r) {
                return f(fa(r))
              }
            }
          },
          Reader_of = constant,
          Reader_Functor = { URI: "Reader", map: Reader_map },
          Reader_ApT = (flap(Reader_Functor), Reader_of(emptyReadonlyArray)),
          Reader_traverseReadonlyArrayWithIndex = function (f) {
            var g = (function (f) {
              return function (as) {
                return function (r) {
                  for (var out = [f(0, head(as))(r)], i = 1; i < as.length; i++)
                    out.push(f(i, as[i])(r))
                  return out
                }
              }
            })(f)
            return function (as) {
              return internal_isNonEmpty(as) ? g(as) : Reader_ApT
            }
          },
          Reader_sequenceArray = (function (f) {
            return Reader_traverseReadonlyArrayWithIndex(function (_, a) {
              return f(a)
            })
          })(function_identity)
        const textColorRow = colorNodes =>
            function_pipe(
              colorNodes,
              Reader_sequenceArray,
              es6_Reader_map(x => h("div", {}, x))
            ),
          panelBoxStyle = width => ({ flex: `0 0 ${width}px`, margin: "2px" }),
          textRowStyle = { width: "70%", boxSizing: "border-box" },
          langs = [
            ["FYC_EN", "English"],
            ["FYC_JA", "日本語"],
          ],
          exampleTextStyle = s => ({
            fontFamily: s.font,
            fontWeight: s.fontWeight.toString(),
            textShadow: textShadow(s.shadowColor)(s.shadowFontWeight),
          }),
          computed = {
            useStepTiming: s => Boolean(s.timingFunction.match(/^steps\(.+/)),
          },
          stepTiming = stepCount => `steps(${stepCount}, jump-end)`,
          settingPanel = command => {
            const { setConfig, act } = command,
              configFx = (k, v) => [() => setConfig[k](v), void 0],
              setState = {
                flowY1: (s, v) => {
                  const flowY2 = Math.max(s.flowY2, v + 0.05)
                  return [
                    { ...s, flowY1: v, flowY2 },
                    configFx("flowY1", v),
                    configFx("flowY2", flowY2),
                  ]
                },
                flowY2: (s, v) => {
                  const flowY1 = Math.min(s.flowY1, v - 0.05)
                  return [
                    { ...s, flowY2: v, flowY1 },
                    configFx("flowY2", v),
                    configFx("flowY1", flowY1),
                  ]
                },
                timingStepCount: (s, v) => {
                  const timingFunction = stepTiming(v)
                  return [
                    { ...s, timingStepCount: v, timingFunction },
                    configFx("timingFunction", timingFunction),
                  ]
                },
                bannedWordRegexs: (s, v) =>
                  function_pipe(
                    v,
                    es6_ReadonlyArray_reduce(
                      { valid: !0, error: "" },
                      (acc, cur) => {
                        try {
                          RegExp(cur, "u")
                          return acc
                        } catch (e) {
                          return {
                            valid: !1,
                            error: `${acc.error}${e} in ${cur};`,
                          }
                        }
                      }
                    ),
                    x => [
                      {
                        ...s,
                        bannedWordRegexs: v,
                        bannedWordRegexsError: x.error,
                        bannedWordRegexsValid: x.valid,
                      },
                      ...(x.valid ? [configFx("bannedWordRegexs", v)] : []),
                    ]
                  ),
              },
              setComputed = {
                useStepTiming: (s, v) => {
                  const timingFunction = v
                    ? stepTiming(s.timingStepCount)
                    : "linear"
                  return [
                    { ...s, timingFunction },
                    configFx("timingFunction", timingFunction),
                  ]
                },
              },
              doAct = {
                copy: async s => {
                  GM.setClipboard(s.eventLog.join("\n"))
                },
                clearFlowChats: async s => {
                  act.clearFlowChats()
                },
              },
              getTrueState = (k, s) => (k in computed ? computed[k](s) : s[k]),
              getState = (k, s) =>
                s.editingInput.id === k
                  ? s.editingInput.committedState
                  : getTrueState(k, s),
              updateAt = (k, v, s) =>
                k in setComputed
                  ? setComputed[k](s, v)
                  : k in setState
                  ? setState[k](s, v)
                  : [
                      { ...s, [k]: v },
                      ...(k in setConfig ? [configFx(k, v)] : []),
                    ],
              updateString = key => (s, e) =>
                function_pipe(getValue(e), x => updateAt(key, x, s)),
              updateNumber = key => (s, e) =>
                function_pipe(getValue(e), parseFloat, x =>
                  updateAt(key, x, s)
                ),
              updateInt = key => (s, e) =>
                function_pipe(
                  getValue(e),
                  x => parseInt(x, 10),
                  x => updateAt(key, x, s)
                ),
              updateBool = key => (s, e) =>
                function_pipe(
                  (e => tapIs(HTMLInputElement, e.currentTarget).checked)(e),
                  x => updateAt(key, x, s)
                ),
              updateStrings = key => (s, e) =>
                function_pipe(
                  getValue(e),
                  x => x.split(/\r\n|\n/).filter(str => "" !== str),
                  x => updateAt(key, x, s)
                ),
              editAction = (key, onchange) => ({
                onfocus: (s, e) =>
                  updateAt(
                    "editingInput",
                    {
                      id: key,
                      committedState: getTrueState(key, s),
                      value: getValue(e),
                    },
                    s
                  ),
                onblur: s =>
                  updateAt(
                    "editingInput",
                    { id: "", committedState: "", value: "" },
                    s
                  ),
                oninput: (s, e) =>
                  updateAt(
                    "editingInput",
                    {
                      id: key,
                      committedState: s.editingInput.committedState,
                      value: getValue(e),
                    },
                    s
                  ),
                onchange: (s, e) => {
                  const [s1, ...es1] = onchange(key)(s, e),
                    x =
                      s1.editingInput.id === key
                        ? {
                            id: key,
                            committedState: getTrueState(key, s1),
                            value: getValue(e),
                          }
                        : s1.editingInput,
                    [s2, ...es2] = updateAt("editingInput", x, s1)
                  return [s2, ...es1, ...es2]
                },
              }),
              getEditValue = (s, k, t) =>
                s.editingInput.id === k
                  ? s.editingInput.value
                  : t(getState(k, s))
            return state => {
              const getText = getLang(state.lang),
                checkboxNode = label =>
                  ((label, checked, onchange) =>
                    h(
                      "div",
                      {},
                      h("label", {}, [
                        hyperapp_text(label),
                        h("input", { type: "checkbox", checked, onchange }),
                      ])
                    ))(
                    getText(label),
                    getState(label, state),
                    updateBool(label)
                  ),
                textColorNode = label =>
                  settingRow(getText(label), [
                    textColorRow(
                      function_pipe(editAction(label, updateString), x => [
                        colorPicker(x),
                        colorInput(x),
                        colorTextOutput(exampleTextStyle(state)),
                      ])
                    )(getEditValue(state, label, x => x)),
                  ]),
                intNode = (label, min, max, step) =>
                  settingRow(getText(label), [
                    rangeRow(
                      min,
                      max,
                      step,
                      getEditValue(state, label, x => x.toString()),
                      state.editingInput.id === label,
                      editAction(label, updateInt)
                    ),
                  ]),
                numberNode = (label, min, max, step) =>
                  settingRow(getText(label), [
                    rangeRow(
                      min,
                      max,
                      step,
                      getEditValue(state, label, x => x.toString()),
                      state.editingInput.id === label,
                      editAction(label, updateNumber)
                    ),
                  ]),
                buttonNode = label =>
                  h(
                    "button",
                    {
                      type: "button",
                      onclick: s => [s, [() => doAct[label](s), void 0]],
                    },
                    hyperapp_text(getText(label))
                  ),
                textAreaNode = (label, rows) =>
                  settingRow(getText(label), [
                    textAreaRow(
                      rows,
                      getEditValue(state, label, x => x.join("\n")),
                      !1,
                      editAction(label, updateStrings)
                    ),
                  ]),
                currentFonts = [
                  ["", "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", "游ゴシック体"],
                  [state.font, "Custom", "カスタム"],
                ]
              const logPageLength =
                Math.trunc(getState("eventLog", state).length / 100) + 1
              return state.showPanel
                ? h(
                    "div",
                    {
                      class: "fyc_panel",
                      style: {
                        backgroundColor: "rgba(30,30,30,0.9)",
                        zIndex: "10000",
                        position: "absolute",
                        bottom: "40px",
                        right: "0px",
                        color: "#fff",
                        fontSize: "14px",
                        width: "660px",
                        border: "solid 1px #666",
                        fontFamily: "MS PGothic",
                        lineHeight: "1.2",
                      },
                    },
                    [
                      h(
                        "div",
                        { style: { float: "right", margin: "3px 3px 0 0" } },
                        [
                          hyperapp_text("🌐"),
                          h(
                            "select",
                            { onchange: updateString("lang") },
                            langs.map(x => ui_option(...x, x[0] === state.lang))
                          ),
                        ]
                      ),
                      tabContainer(
                        {
                          container: { height: "364px" },
                          label: { padding: "6px" },
                          labelFocus: { background: "#666" },
                          tab: { display: "flex", padding: "6px" },
                        },
                        [
                          getText("flowChat"),
                          getText("chatFilter"),
                          getText("chatField"),
                          getText("feedback"),
                        ],
                        [
                          () => {
                            return [
                              h("div", { style: panelBoxStyle(212) }, [
                                settingRow(getText("font"), [
                                  h(
                                    "select",
                                    {
                                      style: textRowStyle,
                                      onchange: updateString("font"),
                                    },
                                    function_pipe(
                                      currentFonts,
                                      findIndex(x => x[0] === state.font),
                                      getOrElse(() => 0),
                                      index =>
                                        currentFonts.map((x, i) =>
                                          ui_option(
                                            x[0],
                                            "FYC_JA" === state.lang
                                              ? x[2]
                                              : x[1],
                                            i === index
                                          )
                                        )
                                    )
                                  ),
                                ]),
                                h("input", {
                                  style: textRowStyle,
                                  maxlength: 20,
                                  value: state.font,
                                  oninput: updateString("font"),
                                }),
                                textColorNode("color"),
                                textColorNode("ownerColor"),
                                textColorNode("moderatorColor"),
                                textColorNode("memberColor"),
                                ((label = "shadowColor"),
                                settingRow(getText(label), [
                                  textColorRow(
                                    function_pipe(
                                      [colorPicker, colorInput],
                                      es6_ReadonlyArray_map(f =>
                                        f(editAction(label, updateString))
                                      )
                                    )
                                  )(getEditValue(state, label, x => x)),
                                ])),
                              ]),
                              h("div", { style: panelBoxStyle(212) }, [
                                numberNode("chatOpacity", 0, 1, 0.05),
                                numberNode("fontSize", 0.3, 2, 0.05),
                                numberNode("fontWeight", 10, 1e3, 10),
                                numberNode("shadowFontWeight", 0, 3, 0.1),
                                numberNode("flowSpeed", 1, 50, 1),
                                intNode("maxChatCount", 5, 200, 5),
                                intNode("maxChatLength", 5, 200, 5),
                                intNode("laneCount", 1, 25, 1),
                              ]),
                              h("div", { style: panelBoxStyle(212) }, [
                                numberNode("flowY1", 0, 0.95, 0.05),
                                numberNode("flowY2", 0.05, 1, 0.05),
                                numberNode("minSpacing", 0, 2.5, 0.1),
                                checkboxNode("useStepTiming"),
                                h(
                                  "div",
                                  {
                                    style: {
                                      ...(getState("useStepTiming", state)
                                        ? {}
                                        : { opacity: "0.5" }),
                                    },
                                  },
                                  intNode("timingStepCount", 1, 400, 1)
                                ),
                                checkboxNode("createChats"),
                                checkboxNode("displayModName"),
                                checkboxNode("displaySuperChatAuthor"),
                                checkboxNode("textOnly"),
                                h(
                                  "span",
                                  {},
                                  hyperapp_text(getText("flowNewChatIf"))
                                ),
                                checkboxNode("noOverlap"),
                                buttonNode("clearFlowChats"),
                              ]),
                            ]
                            var label
                          },
                          () => [
                            h(
                              "div",
                              { style: panelBoxStyle(212) },
                              textAreaNode("bannedWords", 18)
                            ),
                            h(
                              "div",
                              { style: panelBoxStyle(212) },
                              settingRow(getText("bannedWordRegexs"), [
                                h(
                                  "span",
                                  {},
                                  hyperapp_text(
                                    state.bannedWordRegexsValid
                                      ? ""
                                      : `${getText("error")}: ${
                                          state.bannedWordRegexsError
                                        }`
                                  )
                                ),
                                textAreaRow(
                                  18,
                                  getEditValue(state, "bannedWordRegexs", x =>
                                    x.join("\n")
                                  ),
                                  !1,
                                  editAction("bannedWordRegexs", updateStrings)
                                ),
                              ])
                            ),
                            h(
                              "div",
                              { style: panelBoxStyle(212) },
                              textAreaNode("bannedUsers", 18)
                            ),
                          ],
                          () => [
                            h("div", { style: panelBoxStyle(644) }, [
                              numberNode("fieldScale", 0.7, 1.5, 0.05),
                              checkboxNode("simplifyChatField"),
                              checkboxNode("createBanButton"),
                            ]),
                          ],
                          () => [
                            h("div", { style: panelBoxStyle(644) }, [
                              h(
                                "div",
                                { style: { float: "right" } },
                                h(
                                  "a",
                                  {
                                    style: { color: "#f0f" },
                                    href: "https://gf.qytechs.cn/en/scripts/411442-flow-youtube-chat/feedback",
                                    target: "_blank",
                                  },
                                  hyperapp_text(getText("giveFeedback"))
                                )
                              ),
                              h("div", {}, [
                                h(
                                  "span",
                                  {},
                                  hyperapp_text(getText("eventLog"))
                                ),
                                buttonNode("copy"),
                                tabContainer(
                                  {
                                    container: { height: "276px" },
                                    label: {
                                      padding: "4px",
                                      width: "2em",
                                      textAlign: "center",
                                    },
                                    labelFocus: { background: "#666" },
                                    tab: {
                                      display: "flex",
                                      flexDirection: "column",
                                      padding: "6px",
                                    },
                                  },
                                  function_pipe(
                                    ReadonlyArray_makeBy(logPageLength, i =>
                                      i.toString()
                                    )
                                  ),
                                  function_pipe(
                                    ReadonlyArray_makeBy(
                                      logPageLength,
                                      i => () =>
                                        function_pipe(
                                          getState("eventLog", state).slice(
                                            100 * i,
                                            100 * (i + 1)
                                          ),
                                          es6_ReadonlyArray_mapWithIndex(
                                            (j, x) =>
                                              h(
                                                "div",
                                                { style: { display: "flex" } },
                                                [
                                                  h(
                                                    "div",
                                                    {
                                                      style: {
                                                        userSelect: "none",
                                                        flex: "0 0 2em",
                                                      },
                                                    },
                                                    [hyperapp_text(100 * i + j)]
                                                  ),
                                                  h(
                                                    "div",
                                                    {
                                                      style: {
                                                        background:
                                                          j % 2 == 0
                                                            ? "#fff"
                                                            : "#ddd",
                                                        color: "#000",
                                                        flex: "auto",
                                                        wordBreak: "break-all",
                                                        padding: "0 2px",
                                                      },
                                                    },
                                                    [hyperapp_text(x)]
                                                  ),
                                                ]
                                              )
                                          )
                                        )
                                    )
                                  ),
                                  getState("logTab", state),
                                  (s, n) => updateAt("logTab", n, s)
                                ),
                              ]),
                            ]),
                          ],
                        ],
                        getState("mainTab", state),
                        (s, n) => updateAt("mainTab", n, s)
                      ),
                    ]
                  )
                : h("div", {})
            }
          },
          togglePanel = (x, e) => [
            { ...x, showPanel: !x.showPanel },
            [
              x.showPanel
                ? () => tapIs(HTMLElement, e.currentTarget).blur()
                : () => {},
              void 0,
            ],
          ],
          simpleWrap = (comp, init) => {
            const node = document.createElement(comp.tag)
            return { node, dispatch: app({ init, view: comp.view, node }) }
          },
          initialize = async () => {
            const userConfig = await (async () => ({
                lang: await sc("LANG", "FYC_EN"),
                font: await sc("FONT", "MS PGothic"),
                chatOpacity: await sc("OPACITY", 0.8),
                color: await sc("COLOR", "#ffffff"),
                ownerColor: await sc("COLOR_OWNER", "#ffd600"),
                moderatorColor: await sc("COLOR_MODERATOR", "#a74fff"),
                memberColor: await sc("COLOR_MEMBER", "#9fffff"),
                fontSize: await sc("SIZE", 1),
                fontWeight: await sc("WEIGHT", 730),
                shadowFontWeight: await sc("WEIGHT_SHADOW", 1),
                maxChatCount: await sc("LIMIT", 40),
                flowSpeed: await sc("SPEED", 18),
                maxChatLength: await sc("MAX", 100),
                laneCount: await sc("LANE_DIV", 12),
                bannedWords: await ic("NG_WORDS", ...stringsArgs),
                bannedWordRegexs: await ic("NG_REG_WORDS", ...stringsArgs),
                bannedUsers: await ic("NG_USERS", ...stringsArgs),
                createChats: await sc("TOGGLE_CREATE_COMMENTS", !0),
                noOverlap: await sc("NO_OVERLAP", !0),
                createBanButton: await sc("NG_BUTTON", !0),
                simplifyChatField: await sc("SIMPLE_CHAT_FIELD", !1),
                displayModName: await sc("DISPLAY_MODERATOR_NAME", !0),
                displaySuperChatAuthor: await sc(
                  "DISPLAY_SUPER_CHAT_AUTHOR",
                  !0
                ),
                textOnly: await sc("TEXT_ONLY", !1),
                timingFunction: await sc("TIMING_FUNCTION", "linear"),
                displayChats: await sc("DISPLAY_COMMENTS", !0),
                minSpacing: await sc("MIN_SPACING", 0.5),
                fieldScale: await sc("FIELD_SCALE", 1),
                flowY1: await sc("flowY1", 0),
                flowY2: await sc("flowY2", 1),
                shadowColor: await sc("shadowColor", "#000000"),
              }))(),
              configKeys = Object.keys(userConfig),
              getConfig = function_pipe(
                configKeys,
                es6_ReadonlyArray_map(x => [x, () => userConfig[x].val]),
                Object.fromEntries
              ),
              mainState = {
                chatPlaying: !0,
                playerRect: new DOMRect(24, 80, 839, 472),
                filterExp: Option_none,
                getConfig,
              },
              configSubject = function_pipe(
                configKeys,
                es6_ReadonlyArray_map(x => [
                  x,
                  new external_rxjs_namespaceObject.Subject(),
                ]),
                Object.fromEntries
              ),
              channel = new broadcast_channel_BroadcastChannel(
                "fyc-0615654655528523"
              ),
              setConfigPlain = function_pipe(
                configKeys,
                es6_ReadonlyArray_map(x => [
                  x,
                  async val => {
                    userConfig[x].val = val
                    configSubject[x].next(val)
                  },
                ]),
                Object.fromEntries
              ),
              setConfig = function_pipe(
                configKeys,
                es6_ReadonlyArray_map(x => [
                  x,
                  async val => {
                    setConfigPlain[x](val)
                    const item = userConfig[x]
                    channel.postMessage([x, val])
                    GM.setValue(item.gmKey, item.toGm(val))
                  },
                ]),
                Object.fromEntries
              ),
              reinitSubject = new external_rxjs_namespaceObject.Subject(),
              reinitialize = () => {
                requestAnimationFrame(() => lib(reinitSubject)())
              },
              chatScreen = (() => {
                const element = document.createElement("div")
                element.style.pointerEvents = "none"
                element.style.zIndex = "30"
                return element
              })(),
              css = (() => {
                const element = document.createElement("style")
                element.innerHTML =
                  ".fyc_chat {\n    line-height: 1;\n    z-index: 30;\n    position: absolute;\n    user-select: none;\n    white-space: nowrap;\n    will-change: transform;\n  }\n  .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  }"
                return element
              })(),
              flowChats = [],
              documentMutationPair = observePair(MutationObserver),
              chatMutationPair = observePair(MutationObserver),
              playerResizePair = observePair(ResizeObserver),
              toggleChatButtonInit = {
                lang: getConfig.lang(),
                displayChats: getConfig.displayChats(),
              },
              wrappedToggleChatBtn = simpleWrap(
                (setConfig => ({
                  tag: "button",
                  view: state => {
                    const label = getLang(state.lang)(
                      state.displayChats ? "hideChat" : "showChat"
                    )
                    return h(
                      "button",
                      {
                        class: "ytp-button",
                        style: {
                          background: "none",
                          border: "none",
                          cursor: "pointer",
                          float: "left",
                          fontSize: "1em",
                          height: "4em",
                          outline: "none",
                          overflow: "visible",
                          padding: "0 0 0em",
                          position: "relative",
                          width: "3em",
                        },
                        type: "button",
                        "aria-label": label,
                        title: label,
                        onclick: s => {
                          const displayChats = !s.displayChats
                          return [
                            { ...s, displayChats },
                            [
                              () => setConfig.displayChats(displayChats),
                              void 0,
                            ],
                          ]
                        },
                      },
                      [
                        h(
                          "svg",
                          { style: { width: "100%" }, viewBox: "0 0 36 36" },
                          [
                            h("path", {
                              class: "chat-button-path",
                              d: "m11 12h17q1 0 1 1v9q0 1-1 1h-1v2l-4-2h-12q-1 0-1-1v-9q0-1 1-1z",
                              fill: "#fff",
                              "fill-opacity": state.displayChats ? "1" : "0",
                              stroke: "#fff",
                              "stroke-width": "2",
                            }),
                          ]
                        ),
                      ]
                    )
                  },
                }))(setConfig),
                toggleChatButtonInit
              ),
              wrappedSetting = simpleWrap(
                (command => {
                  const panel = settingPanel(command)
                  return {
                    tag: "span",
                    view: s => {
                      return h("span", { style: { display: "contents" } }, [
                        panel(s),
                        ((state = s),
                        h(
                          "button",
                          {
                            class: "fyc_button",
                            style: {
                              background: "rgba(0,0,0,0)",
                              marginLeft: "10px",
                              whiteSpace: "nowrap",
                            },
                            onclick: togglePanel,
                          },
                          [
                            h(
                              "svg",
                              {
                                preserveAspectRatio: "xMidYMid meet",
                                viewBox: "0 0 640 640",
                                width: "15",
                                height: "15",
                                style: { position: "relative", top: "1px" },
                              },
                              [
                                h(
                                  "defs",
                                  {},
                                  h("path", {
                                    id: "d1TbzTC1zI",
                                    d: "M135 58c25 14 67 30 82 35-7 49 16 109-15 149-50 71-19 184 64 213 74 31 165-18 183-95-3-38 23-62 58-36l120 55c-39 10-106 35-72 85 40 38 1 71-29 98-29 53-70-17-109-5-46 22-25 109-96 85h-55c-24-31-21-103-80-84-32 32-70 31-93-9l-35-36c4-40 57-96-6-120-45 5-58-32-52-68 2-19-4-41 3-59 35-15 100-22 77-79-48-43 1-84 35-115 5-6 12-12 20-14zM577 2c52 3 72 62 62 106-5 51 19 117-27 155-18 24 8 49 11 74-39-8-98-46-146-60-55-1-111 2-167-2-52-15-57-76-52-121S242 52 282 18c38-30 88-11 132-16h163z",
                                  })
                                ),
                                h("use", {
                                  href: "#d1TbzTC1zI",
                                  opacity: "1",
                                  fill: "var(--iron-icon-fill-color, currentcolor)",
                                  "fill-opacity": "1",
                                }),
                              ]
                            ),
                            h(
                              "span",
                              {
                                style: {
                                  position: "relative",
                                  top: "-2px",
                                  marginLeft: "8px,",
                                },
                              },
                              hyperapp_text(getLang(state.lang)("setting"))
                            ),
                          ]
                        )),
                      ])
                      var state
                    },
                  }
                })({
                  setConfig,
                  act: {
                    clearFlowChats: async () => removeOldChats(flowChats, 0),
                  },
                }),
                (getConfig => ({
                  ...function_pipe(
                    Object.entries(getConfig),
                    es6_ReadonlyArray_map(([k, v]) => [k, v()]),
                    Object.fromEntries
                  ),
                  showPanel: !1,
                  bannedWordRegexsValid: !0,
                  bannedWordRegexsError: "",
                  mainTab: 0,
                  logTab: 0,
                  timingStepCount: parseInt(
                    getConfig.timingFunction().match(/^steps\((\d+),.+/)?.[1] ??
                      "150",
                    10
                  ),
                  eventLog: [],
                  editingInput: { id: "", committedState: void 0, value: "" },
                }))(getConfig)
              ),
              mainLog =
                (...x) =>
                () =>
                  wrappedSetting.dispatch(s => ({
                    ...s,
                    eventLog: appendLog(s.eventLog)(...x),
                  })),
              mixLog = (...x) =>
                function_pipe(
                  [mainLog, consoleLog],
                  es6_ReadonlyArray_map(f => f(...x)),
                  IO_sequenceArray
                )
            mainLog("Version", package_namespaceObject_i8)()
            mainLog("User Agent", window.navigator.userAgent)()
            mainLog("UserConfig", JSON.stringify(userConfig))()
            const cs = function_pipe(
                configSubject,
                Object.entries,
                es6_ReadonlyArray_map(([k, v]) => [
                  k,
                  v.pipe(
                    (0, external_rxjs_namespaceObject.tap)(x =>
                      function_pipe(
                        () => wrappedSetting.dispatch(s => ({ ...s, [k]: x })),
                        IO_apSecond(
                          k in toggleChatButtonInit
                            ? () =>
                                wrappedToggleChatBtn.dispatch(s => ({
                                  ...s,
                                  [k]: x,
                                }))
                            : () => {}
                        ),
                        requestAnimationFrame
                      )
                    )
                  ),
                ]),
                Object.fromEntries
              ),
              livePage = {
                toggleChatBtnParent: () =>
                  fromNullable(document.querySelector(".ytp-right-controls")),
                settingNextElement: () =>
                  fromNullable(
                    document.querySelector(
                      "#menu-container .dropdown-trigger.ytd-menu-renderer"
                    )
                  ),
                player: () =>
                  fromNullable(document.querySelector("#movie_player")),
                video: () =>
                  fromNullable(
                    document.querySelector(
                      "video.video-stream.html5-main-video"
                    )
                  ),
                chatField: () =>
                  function_pipe(
                    chatApp(),
                    chainNullableK(x =>
                      x.querySelector("#items.yt-live-chat-item-list-renderer")
                    )
                  ),
                chatTicker: () =>
                  function_pipe(
                    chatApp(),
                    chainNullableK(x =>
                      x.querySelector("#items.yt-live-chat-ticker-renderer")
                    )
                  ),
                chatScroller: () =>
                  function_pipe(
                    chatApp(),
                    chainNullableK(x =>
                      x.querySelector(
                        "#item-scroller.yt-live-chat-item-list-renderer"
                      )
                    )
                  ),
                offlineSlate: () =>
                  fromNullable(document.querySelector(".ytp-offline-slate")),
              },
              liveElementKeys = Object.keys(livePage),
              live = function_pipe(
                liveElementKeys,
                es6_ReadonlyArray_map(x => {
                  return [
                    x,
                    ((key = x), { ele: Option_none, read: livePage[key] }),
                  ]
                  var key
                }),
                Object.fromEntries
              ),
              config$ = (0, external_rxjs_namespaceObject.merge)(
                (0, external_rxjs_namespaceObject.merge)(
                  cs.bannedWordRegexs,
                  cs.bannedWords,
                  cs.bannedUsers
                ).pipe(
                  (0, external_rxjs_namespaceObject.startWith)(void 0),
                  (0, external_rxjs_namespaceObject.tap)(() => {
                    mainState.filterExp = Option_some(
                      (getConfig =>
                        external_jsep_default()(
                          `\nor([\nRA.some(anyPreds([\n  flip(flow([matchedByText, RA.some]))(${JSON.stringify(
                            getConfig.bannedWordRegexs()
                          )}),\n  flip(flow([inText, RA.some]))(${JSON.stringify(
                            getConfig.bannedWords()
                          )})\n]))(RA.compact([\n  messageText,\n  paymentInfo\n])),\nO.exists(\n  flip(flow([eqText, RA.some]))(${JSON.stringify(
                            getConfig.bannedUsers()
                          )})\n)(authorID)\n])\n`
                        ))(getConfig)
                    )
                  })
                ),
                cs.fieldScale.pipe(
                  (0, external_rxjs_namespaceObject.startWith)(
                    getConfig.fieldScale()
                  ),
                  (0, external_rxjs_namespaceObject.tap)(scale =>
                    function_pipe(
                      live.chatField.ele,
                      fromOption,
                      IOOption_chain(field =>
                        IOOption_fromIO(() =>
                          function_pipe(
                            [
                              function_pipe(
                                fromNullable(field.parentElement),
                                es6_Option_map(x => () => {
                                  x.style.transformOrigin =
                                    (scale >= 1 ? "top" : "bottom") + " left"
                                  x.style.transform = `scale(${scale})`
                                  x.style.width = 100 / scale + "%"
                                  x.style.height = `${field.offsetHeight}px`
                                })
                              ),
                              function_pipe(
                                live.chatScroller.ele,
                                es6_Option_map(scroller => () => {
                                  scroller.scrollTop = scroller.scrollHeight
                                })
                              ),
                            ],
                            ReadonlyArray_compact,
                            IO_sequenceArray
                          )
                        )
                      )
                    )()
                  )
                ),
                (0, external_rxjs_namespaceObject.merge)(
                  (0, external_rxjs_namespaceObject.merge)(
                    cs.font,
                    cs.fontSize,
                    cs.fontWeight,
                    cs.laneCount,
                    cs.minSpacing,
                    cs.flowY1,
                    cs.flowY2,
                    cs.textOnly
                  ).pipe(
                    (0, external_rxjs_namespaceObject.mapTo)({
                      render: !0,
                      setAnimation: !0,
                    })
                  ),
                  (0, external_rxjs_namespaceObject.merge)(
                    cs.color,
                    cs.ownerColor,
                    cs.moderatorColor,
                    cs.memberColor,
                    cs.shadowColor,
                    cs.chatOpacity,
                    cs.shadowFontWeight,
                    cs.displayChats
                  ).pipe(
                    (0, external_rxjs_namespaceObject.mapTo)({ render: !0 })
                  ),
                  (0, external_rxjs_namespaceObject.merge)(cs.flowSpeed).pipe(
                    (0, external_rxjs_namespaceObject.mapTo)({
                      setPlayState: !0,
                    })
                  ),
                  (0, external_rxjs_namespaceObject.merge)(
                    cs.maxChatCount.pipe(
                      (0, external_rxjs_namespaceObject.tap)(x =>
                        removeOldChats(flowChats, x)
                      )
                    ),
                    cs.noOverlap,
                    cs.timingFunction
                  ).pipe(
                    (0, external_rxjs_namespaceObject.mapTo)({
                      setAnimation: !0,
                    })
                  )
                ).pipe(
                  (0, external_rxjs_namespaceObject.throttleTime)(180, void 0, {
                    leading: !0,
                    trailing: !0,
                  }),
                  (0, external_rxjs_namespaceObject.tap)(config =>
                    function_pipe(
                      flowChats,
                      es6_ReadonlyArray_filter(x => !x.animationEnded),
                      es6_ReadonlyArray_map(chat =>
                        function_pipe(
                          {
                            render: !1,
                            setAnimation: !1,
                            setPlayState: !1,
                            ...config,
                          },
                          x =>
                            function_pipe(
                              [
                                function_pipe(
                                  renderChat(chat),
                                  fromPredicate(() => x.render)
                                ),
                                function_pipe(
                                  setChatAnimation(chat, flowChats),
                                  fromPredicate(() => x.setAnimation),
                                  alt(() =>
                                    function_pipe(
                                      setChatPlayState(chat),
                                      fromPredicate(() => x.setPlayState)
                                    )
                                  )
                                ),
                              ],
                              ReadonlyArray_compact,
                              es6_ReadonlyArray_map(
                                (function (a) {
                                  return function (f) {
                                    return f(a)
                                  }
                                })(mainState)
                              ),
                              IO_sequenceArray
                            )
                        )
                      ),
                      IO_sequenceArray
                    )()
                  )
                ),
                cs.lang,
                cs.maxChatLength,
                cs.simplifyChatField,
                cs.createBanButton,
                cs.createChats,
                cs.displayModName,
                cs.displaySuperChatAuthor,
                cs.fieldScale,
                cs.bannedWords,
                cs.bannedWordRegexs,
                cs.bannedUsers
              ),
              eq = getEq(eqStrict).equals
            reinitSubject
              .pipe(
                (0, external_rxjs_namespaceObject.observeOn)(
                  external_rxjs_namespaceObject.asyncScheduler
                ),
                (0, external_rxjs_namespaceObject.delay)(100),
                (0, external_rxjs_namespaceObject.tap)(mixLog("Init")),
                (0, external_rxjs_namespaceObject.switchMap)(() =>
                  (0, external_rxjs_namespaceObject.interval)(700).pipe(
                    (0, external_rxjs_namespaceObject.filter)(() =>
                      function_pipe(
                        liveElementKeys,
                        es6_ReadonlyArray_map(key =>
                          function_pipe(
                            live[key].read(),
                            fromPredicate(newEle => !eq(live[key].ele, newEle)),
                            es6_Option_map(x => () => {
                              live[key].ele = x
                            }),
                            es6_Option_map(
                              IO_apSecond(mixLog(`${key} changed`))
                            )
                          )
                        ),
                        ReadonlyArray_compact,
                        IO_sequenceArray,
                        es6_IO_map(ReadonlyArray_isNonEmpty)
                      )()
                    ),
                    (0, external_rxjs_namespaceObject.startWith)(0)
                  )
                ),
                (0, external_rxjs_namespaceObject.tap)(mixLog("Loading...")),
                (0, external_rxjs_namespaceObject.tap)(() => {
                  removeOldChats(flowChats, 0)
                  documentMutationPair.observer.disconnect()
                  documentMutationPair.observer.observe(document, {
                    childList: !0,
                    subtree: !0,
                  })
                  chatMutationPair.observer.disconnect()
                  playerResizePair.observer.disconnect()
                  document.head.append(css)
                  function_pipe(
                    [
                      function_pipe(
                        live.chatField.ele,
                        es6_Option_map(x => () => {
                          ;((chatField = x),
                          () =>
                            function_pipe(
                              fromNullable(chatField.parentElement),
                              es6_Option_map(x => () => {
                                x.style.overflow = "unset"
                              })
                            ))()
                          var chatField
                          chatMutationPair.observer.observe(x, {
                            childList: !0,
                          })
                        })
                      ),
                      function_pipe(
                        live.chatTicker.ele,
                        es6_Option_map(
                          x => () =>
                            chatMutationPair.observer.observe(x, {
                              childList: !0,
                            })
                        )
                      ),
                      function_pipe(
                        live.player.ele,
                        es6_Option_map(x => () => {
                          playerResizePair.observer.observe(x)
                          x.insertAdjacentElement("afterbegin", chatScreen)
                        })
                      ),
                      function_pipe(
                        live.toggleChatBtnParent.ele,
                        es6_Option_map(
                          x => () => x.append(wrappedToggleChatBtn.node)
                        )
                      ),
                      function_pipe(
                        live.settingNextElement.ele,
                        es6_Option_map(x => () => {
                          x.insertAdjacentElement(
                            "beforebegin",
                            wrappedSetting.node
                          )
                        })
                      ),
                    ],
                    ReadonlyArray_compact,
                    ReadonlyArray_append(
                      function_pipe(
                        live.video.ele,
                        filter(x => !x.paused),
                        alt(() => live.offlineSlate.ele),
                        Option_isSome,
                        x => () => {
                          mainState.chatPlaying = x
                        }
                      )
                    ),
                    IO_sequenceArray
                  )()
                }),
                (0, external_rxjs_namespaceObject.switchMap)(() =>
                  (0, external_rxjs_namespaceObject.merge)(
                    (0, external_rxjs_namespaceObject.fromEvent)(
                      channel,
                      "message"
                    ).pipe(
                      (0, external_rxjs_namespaceObject.tap)(([key, val]) =>
                        function_pipe(
                          [
                            "lang",
                            "bannedWords",
                            "bannedWordRegexs",
                            "bannedUsers",
                            "simplifyChatField",
                            "createBanButton",
                            "fieldScale",
                          ].includes(key),
                          x => (x ? () => setConfigPlain[key](val) : () => {})
                        )()
                      )
                    ),
                    ...function_pipe(
                      configKeys,
                      es6_ReadonlyArray_map(key =>
                        cs[key].pipe(
                          (0, external_rxjs_namespaceObject.startWith)(
                            getConfig[key]()
                          ),
                          (0, external_rxjs_namespaceObject.bufferCount)(2, 1),
                          (0, external_rxjs_namespaceObject.map)(([x, y]) =>
                            (0, external_DeepDiff_namespaceObject.diff)(x, y)
                          ),
                          (0, external_rxjs_namespaceObject.tap)(x =>
                            mainLog(
                              `Config ${key}`,
                              JSON.stringify(x, void 0, 2)
                            )()
                          )
                        )
                      )
                    ),
                    config$,
                    function_pipe(
                      live.video.ele,
                      match(
                        () => external_rxjs_namespaceObject.EMPTY,
                        x => {
                          return ((video = x),
                          (0, external_rxjs_namespaceObject.merge)(
                            (0, external_rxjs_namespaceObject.fromEvent)(
                              video,
                              "playing"
                            ).pipe(
                              (0, external_rxjs_namespaceObject.mapTo)(!0)
                            ),
                            (0, external_rxjs_namespaceObject.fromEvent)(
                              video,
                              "waiting"
                            ).pipe(
                              (0, external_rxjs_namespaceObject.mapTo)(!1)
                            ),
                            (0, external_rxjs_namespaceObject.fromEvent)(
                              video,
                              "pause"
                            ).pipe((0, external_rxjs_namespaceObject.mapTo)(!1))
                          )).pipe(
                            (0, external_rxjs_namespaceObject.map)(
                              playing =>
                                playing || Option_isSome(live.offlineSlate.ele)
                            ),
                            (0, external_rxjs_namespaceObject.tap)(
                              chatPlaying => {
                                mainState.chatPlaying = chatPlaying
                                flowChats.forEach(chat =>
                                  setChatPlayState(chat)(mainState)()
                                )
                              }
                            )
                          )
                          var video
                        }
                      )
                    ),
                    chatMutationPair.subject.pipe(
                      (0, external_rxjs_namespaceObject.map)(
                        onChatFieldMutate(
                          chatScreen,
                          flowChats,
                          mainState,
                          setConfig,
                          mainLog
                        )
                      ),
                      (0, external_rxjs_namespaceObject.tap)(x => x())
                    ),
                    documentMutationPair.subject.pipe(
                      (0, external_rxjs_namespaceObject.map)(
                        () => window.location.href
                      ),
                      (0, external_rxjs_namespaceObject.distinctUntilChanged)(),
                      (0, external_rxjs_namespaceObject.skip)(1),
                      (0, external_rxjs_namespaceObject.tap)(x => {
                        mixLog("URL Changed", x)()
                        removeOldChats(flowChats, 0)
                        mixLog("Wait for 1700ms...")()
                      }),
                      (0, external_rxjs_namespaceObject.delay)(1700),
                      (0, external_rxjs_namespaceObject.tap)(() =>
                        reinitialize()
                      )
                    ),
                    playerResizePair.subject.pipe(
                      (0, external_rxjs_namespaceObject.throttleTime)(
                        500,
                        void 0,
                        { leading: !0, trailing: !0 }
                      ),
                      (0, external_rxjs_namespaceObject.startWith)([]),
                      (0, external_rxjs_namespaceObject.map)(
                        () => live.player.ele
                      ),
                      (0, external_rxjs_namespaceObject.map)(
                        es6_Option_map(x => x.getBoundingClientRect())
                      ),
                      (0, external_rxjs_namespaceObject.tap)(x =>
                        ((rect, flowChats, mainState, mainLog) =>
                          function_pipe(
                            rect,
                            match(
                              () => () => {},
                              x => () => {
                                mainLog("Resize detected")()
                                mainState.playerRect = x
                                flowChats.forEach(chat => {
                                  renderChat(chat)(mainState)()
                                  setChatAnimation(chat, flowChats)(mainState)()
                                })
                              }
                            )
                          )())(x, flowChats, mainState, mainLog)
                      )
                    )
                  )
                ),
                (0, external_rxjs_namespaceObject.retryWhen)(e =>
                  e.pipe(
                    (0, external_rxjs_namespaceObject.tap)(
                      mixLog("Errored", e)
                    ),
                    (0, external_rxjs_namespaceObject.delay)(5e3),
                    (0, external_rxjs_namespaceObject.tap)(x => {
                      mixLog(x)()
                      reinitialize()
                    })
                  )
                )
              )
              .subscribe({
                error: x => mixLog("Stream error", x)(),
                complete: mixLog("Stream complete"),
              })
            reinitialize()
          }
        ;(async () => {
          external_log_namespaceObject.setLevel("info")
          try {
            await initialize()
          } catch (error) {
            external_log_namespaceObject.info("【FYC】 Error", error)
          }
        })()
      },
      633: () => {},
    },
    __webpack_module_cache__ = {}
  function __webpack_require__(moduleId) {
    var cachedModule = __webpack_module_cache__[moduleId]
    if (void 0 !== cachedModule) return cachedModule.exports
    var module = (__webpack_module_cache__[moduleId] = { exports: {} })
    __webpack_modules__[moduleId](module, module.exports, __webpack_require__)
    return module.exports
  }
  __webpack_require__.n = module => {
    var getter =
      module && module.__esModule ? () => module.default : () => module
    __webpack_require__.d(getter, { a: getter })
    return 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)
  __webpack_require__(73)
})()

QingJ © 2025

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