Iwara Custom Sort

Automatically sort teaser images on /videos, /images, /subscriptions, /users, /playlist, and sidebars using customizable sort function. Can load and sort multiple pages at once.

اعتبارا من 02-10-2020. شاهد أحدث إصدار.

// ==UserScript==
// @name           Iwara Custom Sort
// @version        1.0.7
// @description    Automatically sort teaser images on /videos, /images, /subscriptions, /users, /playlist, and sidebars using customizable sort function. Can load and sort multiple pages at once.
// @match          http://ecchi.iwara.tv/*
// @match          https://ecchi.iwara.tv/*
// @match          http://www.iwara.tv/*
// @match          https://www.iwara.tv/*
// @name:ja        Iwara Custom ソート
// @run-at         document-end
// @grant          GM.setValue
// @grant          GM.getValue
// @grant          GM.deleteValue
// @grant          GM.listValues
// @license        AGPL-3.0-or-later
// @description:ja /videos、/images、/subscriptions、/users、/playlistとサイドバーのサムネイルを自動的にソートします。ソート方法はカスタマイズすることができます、一度に複数のページを読み込んでソートすることができます。
// @require        https://cdn.jsdelivr.net/npm/sweetalert2@10.3.5/dist/sweetalert2.all.min.js#sha384-hmoGfyRv5Xg6BFqj6C1jQJ0y5HEpsJSc6VpsKkj0NgyiPevl9FNVNxEFpxKFNUaX
// @require        https://unpkg.com/loglevel@1.7.0/dist/loglevel.min.js#sha384-7gGuWfek8Ql6j/uNDFrS0BCe4x2ZihD4B68w9Eu580OVHJBV+bl3rZmEWC7q5/Gj
// @require        https://unpkg.com/rxjs@6.6.3/bundles/rxjs.umd.min.js#sha384-+VJt6dSQYKxS5YwAGX+zSPDqOcLAUx2tCjV8jSWnyJH8hWTgrHSZAt1106u1VmLn
// @require        https://unpkg.com/mithril@2.0.4/mithril.min.js#sha384-vo9crXih40MlEv6JWHqS7SsPiFp+76csaWQFOF2UU0/xI58Jm/ZvK/1UtpaicJT9
// @namespace      https://greasyfork.org/users/245195
// ==/UserScript==

/* jshint esversion: 6 */

(() => {
  const __webpack_modules__ = {
    923(module, exports, __webpack_require__) {
      let __WEBPACK_AMD_DEFINE_RESULT__;
      !(function (globals) {
        let messages; let predicates; let functions; let assert; let not; let maybe; let collections; let hasOwnProperty; let toString; let keys; let slice; let isArray; let neginf; let posinf; let haveSymbols; let haveMaps; let haveSets;
        function assigned(data) { return data != null; }

        function number(data) { return typeof data === 'number' && data > neginf && data < posinf; }

        function integer(data) { return typeof data === 'number' && data % 1 == 0; }

        function greater(lhs, rhs) { return number(lhs) && lhs > rhs; }

        function less(lhs, rhs) { return number(lhs) && lhs < rhs; }

        function greaterOrEqual(lhs, rhs) { return number(lhs) && lhs >= rhs; }

        function lessOrEqual(lhs, rhs) { return number(lhs) && lhs <= rhs; }

        function string(data) { return typeof data === 'string'; }

        function nonEmptyString(data) { return string(data) && data !== ''; }

        function object(data) { return toString.call(data) === '[object Object]'; }

        function some(data, predicate) {
          for (const key in data) if (hasOwnProperty.call(data, key) && predicate(key, data[key])) return !0;
          return !1;
        }

        function instanceStrict(data, prototype) { try { return data instanceof prototype; } catch (error) { return !1; } }

        function like(data, archetype) {
          let name;
          for (name in archetype) {
            if (hasOwnProperty.call(archetype, name)) {
              if (!1 === hasOwnProperty.call(data, name) || typeof data[name] !== typeof archetype[name]) return !1;
              if (object(data[name]) && !1 === like(data[name], archetype[name])) return !1;
            }
          }

          return !0;
        }

        function arrayLike(data) { return assigned(data) && data.length >= 0; }

        function iterable(data) { return haveSymbols ? assigned(data) && isFunction(data[Symbol.iterator]) : arrayLike(data); }

        function contains(data, value) {
          let iterator; let iteration;
          if (!assigned(data)) return !1;
          if (haveSets && instanceStrict(data, Set)) return data.has(value);
          if (string(data)) return data.indexOf(value) !== -1;
          if (haveSymbols && data[Symbol.iterator] && isFunction(data.values)) {
            iterator = data.values();
            do { if ((iteration = iterator.next()).value === value) return !0; } while (!iteration.done);

            return !1;
          }

          return some(data, ((key, dataValue) => dataValue === value));
        }

        function containsKey(data, key) { return !!assigned(data) && (haveMaps && instanceStrict(data, Map) ? data.has(key) : !(iterable(data) && !number(+key)) && !!data[key]); }

        function isFunction(data) { return typeof data === 'function'; }

        function forEach(object, action) { for (const key in object)hasOwnProperty.call(object, key) && action(key, object[key]); }

        function testArray(data, result) {
          let i;
          for (i = 0; i < data.length; i += 1) if (data[i] === result) return result;
          return !result;
        }

        function testObject(data, result) {
          let key; let value;
          for (key in data) {
            if (hasOwnProperty.call(data, key)) {
              if (object(value = data[key]) && testObject(value, result) === result) return result;
              if (value === result) return result;
            }
          }

          return !result;
        }

        function mixin(target, source) { return forEach(source, ((key, value) => { target[key] = value; })), target; }

        function assertModifier(predicate, defaultMessage) {
          return function () {
            const args = arguments; const argCount = predicate.l || predicate.length; const message = args[argCount]; const ErrorType = args[argCount + 1];
            return assertImpl(predicate.apply(null, args), nonEmptyString(message) ? message : defaultMessage.replace('{a}', messageFormatter(args[0])).replace('{e}', messageFormatter(args[1])).replace('{e2}', messageFormatter(args[2])).replace('{t}', (() => {
              const arg = args[1];
              return arg && arg.name ? arg.name : arg;
            })), isFunction(ErrorType) ? ErrorType : TypeError), args[0];
          };
        }

        function messageFormatter(arg) { return function () { return string(arg) ? `"${arg.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"` : arg && !0 !== arg && arg.constructor && !instanceStrict(arg, RegExp) && typeof arg !== 'number' ? arg.constructor.name : arg; }; }

        function assertImpl(value, message, ErrorType) {
          if (value) return value;
          throw new (ErrorType || Error)(message || 'assert failed');
        }

        function notModifier(predicate) {
          const modifiedPredicate = function () { return notImpl(predicate.apply(null, arguments)); };

          return modifiedPredicate.l = predicate.length, modifiedPredicate;
        }

        function notImpl(value) { return !value; }

        function ofModifier(target, type, predicate) {
          const modifiedPredicate = function () {
            let collection; let args;
            if (collection = arguments[0], target === 'maybe' && not.assigned(collection)) return !0;
            if (!type(collection)) return !1;
            collection = coerceCollection(type, collection), args = slice.call(arguments, 1);
            try { collection.forEach(((item) => { if ((target !== 'maybe' || assigned(item)) && !predicate.apply(null, [item].concat(args))) throw 0; })); } catch (ignore) { return !1; }

            return !0;
          };

          return modifiedPredicate.l = predicate.length, modifiedPredicate;
        }

        function coerceCollection(type, collection) {
          switch (type) {
          case arrayLike: return slice.call(collection);
          case object: return keys(collection).map(((key) => collection[key]));
          default: return collection;
          }
        }

        function createModifiedPredicates(modifier, object) { return createModifiedFunctions([modifier, predicates, object, '']); }

        function createModifiedFunctions(args) {
          let modifier; let messageModifier; let object;
          return modifier = args.shift(), messageModifier = args.pop(), object = args.pop(), forEach(args.pop(), ((key, fn) => {
            let message = messages[key];
            message && messageModifier && (message = message.replace('to', `${messageModifier}to`)), Object.defineProperty(object, key, {
              configurable: !1,
              enumerable: !0,
              writable: !1,
              value: modifier.apply(null, args.concat(fn, message)),
            });
          })), object;
        }

        function createModifiedModifier(modifier, modified, messageModifier) { return createModifiedFunctions([modifier, modified, {}, messageModifier]); }

        function createOfModifiers(base, modifier) { collections.forEach(((key) => { base[key].of = createModifiedModifier(modifier, predicates[key].of); })); }

        messages = {}, predicates = {}, [
          {
            n: 'equal',
            f(lhs, rhs) { return lhs === rhs; },
            s: 'equal {e}',
          }, {
            n: 'undefined',
            f(data) { return void 0 === data; },
            s: 'be undefined',
          }, {
            n: 'null',
            f(data) { return data === null; },
            s: 'be null',
          }, {
            n: 'assigned',
            f: assigned,
            s: 'be assigned',
          }, {
            n: 'primitive',
            f(data) {
              let type;
              switch (data) { case null: case void 0: case !1: case !0: return !0; }

              return (type = typeof data) === 'string' || type === 'number' || haveSymbols && type === 'symbol';
            },
            s: 'be primitive type',
          }, {
            n: 'contains',
            f: contains,
            s: 'contain {e}',
          }, {
            n: 'in',
            f(value, data) { return contains(data, value); },
            s: 'be in {e}',
          }, {
            n: 'containsKey',
            f: containsKey,
            s: 'contain key {e}',
          }, {
            n: 'keyIn',
            f(key, data) { return containsKey(data, key); },
            s: 'be key in {e}',
          }, {
            n: 'zero',
            f(data) { return data === 0; },
            s: 'be 0',
          }, {
            n: 'one',
            f(data) { return data === 1; },
            s: 'be 1',
          }, {
            n: 'infinity',
            f(data) { return data === neginf || data === posinf; },
            s: 'be infinity',
          }, {
            n: 'number',
            f: number,
            s: 'be Number',
          }, {
            n: 'integer',
            f: integer,
            s: 'be integer',
          }, {
            n: 'float',
            f(data) { return number(data) && data % 1 != 0; },
            s: 'be non-integer number',
          }, {
            n: 'even',
            f(data) { return typeof data === 'number' && data % 2 == 0; },
            s: 'be even number',
          }, {
            n: 'odd',
            f(data) { return integer(data) && data % 2 != 0; },
            s: 'be odd number',
          }, {
            n: 'greater',
            f: greater,
            s: 'be greater than {e}',
          }, {
            n: 'less',
            f: less,
            s: 'be less than {e}',
          }, {
            n: 'between',
            f(data, x, y) {
              if (x < y) return greater(data, x) && data < y;
              return less(data, x) && data > y;
            },
            s: 'be between {e} and {e2}',
          }, {
            n: 'greaterOrEqual',
            f: greaterOrEqual,
            s: 'be greater than or equal to {e}',
          }, {
            n: 'lessOrEqual',
            f: lessOrEqual,
            s: 'be less than or equal to {e}',
          }, {
            n: 'inRange',
            f(data, x, y) {
              if (x < y) return greaterOrEqual(data, x) && data <= y;
              return lessOrEqual(data, x) && data >= y;
            },
            s: 'be in the range {e} to {e2}',
          }, {
            n: 'positive',
            f(data) { return greater(data, 0); },
            s: 'be positive number',
          }, {
            n: 'negative',
            f(data) { return less(data, 0); },
            s: 'be negative number',
          }, {
            n: 'string',
            f: string,
            s: 'be String',
          }, {
            n: 'emptyString',
            f(data) { return data === ''; },
            s: 'be empty string',
          }, {
            n: 'nonEmptyString',
            f: nonEmptyString,
            s: 'be non-empty string',
          }, {
            n: 'match',
            f(data, regex) { return string(data) && !!data.match(regex); },
            s: 'match {e}',
          }, {
            n: 'boolean',
            f(data) { return !1 === data || !0 === data; },
            s: 'be Boolean',
          }, {
            n: 'object',
            f: object,
            s: 'be Object',
          }, {
            n: 'emptyObject',
            f(data) { return object(data) && !some(data, (() => !0)); },
            s: 'be empty object',
          }, {
            n: 'nonEmptyObject',
            f(data) { return object(data) && some(data, (() => !0)); },
            s: 'be non-empty object',
          }, {
            n: 'instanceStrict',
            f: instanceStrict,
            s: 'be instanceof {t}',
          }, {
            n: 'thenable',
            f(data) { return assigned(data) && isFunction(data.then); },
            s: 'be promise-like',
          }, {
            n: 'instance',
            f(data, prototype) { try { return instanceStrict(data, prototype) || data.constructor.name === prototype.name || toString.call(data) === `[object ${prototype.name}]`; } catch (error) { return !1; } },
            s: 'be {t}',
          }, {
            n: 'like',
            f: like,
            s: 'be like {e}',
          }, {
            n: 'array',
            f(data) { return isArray(data); },
            s: 'be Array',
          }, {
            n: 'emptyArray',
            f(data) { return isArray(data) && data.length === 0; },
            s: 'be empty array',
          }, {
            n: 'nonEmptyArray',
            f(data) { return isArray(data) && data.length > 0; },
            s: 'be non-empty array',
          }, {
            n: 'arrayLike',
            f: arrayLike,
            s: 'be array-like',
          }, {
            n: 'iterable',
            f: iterable,
            s: 'be iterable',
          }, {
            n: 'date',
            f(data) { return instanceStrict(data, Date) && integer(data.getTime()); },
            s: 'be valid Date',
          }, {
            n: 'function',
            f: isFunction,
            s: 'be Function',
          }, {
            n: 'hasLength',
            f(data, length) { return assigned(data) && data.length === length; },
            s: 'have length {e}',
          }, {
            n: 'throws',
            f(data) {
              if (!isFunction(data)) return !1;
              try { data(); } catch (error) { return !0; }

              return !1;
            },
            s: 'throw',
          },
        ].map(((data) => {
          const {
            n,
          } = data;

          messages[n] = `assert failed: expected {a} to ${data.s}`, predicates[n] = data.f;
        })), functions = {
          map: function map(data, predicates) {
            let result;
            result = isArray(data) ? [] : {};
            if (isFunction(predicates))forEach(data, ((key, value) => { result[key] = predicates(value); }));
            else {
              isArray(predicates) || assert.object(predicates);
              const dataKeys = keys(data || {});
              forEach(predicates, ((key, predicate) => { dataKeys.some(((dataKey, index) => dataKey === key && (dataKeys.splice(index, 1), !0))), isFunction(predicate) ? not.assigned(data) ? result[key] = !!predicate.m : result[key] = predicate(data[key]) : result[key] = map(data[key], predicate); }));
            }

            return result;
          },
          all(data) {
            if (isArray(data)) return testArray(data, !1);
            return assert.object(data), testObject(data, !1);
          },
          any(data) {
            if (isArray(data)) return testArray(data, !0);
            return assert.object(data), testObject(data, !0);
          },
        }, collections = ['array', 'arrayLike', 'iterable', 'object'], hasOwnProperty = Object.prototype.hasOwnProperty, toString = Object.prototype.toString, keys = Object.keys, slice = Array.prototype.slice, isArray = Array.isArray, neginf = Number.NEGATIVE_INFINITY, posinf = Number.POSITIVE_INFINITY, haveSymbols = typeof Symbol === 'function', haveMaps = typeof Map === 'function', haveSets = typeof Set === 'function', functions = mixin(functions, predicates), assert = createModifiedPredicates(assertModifier, assertImpl), not = createModifiedPredicates(notModifier, notImpl), maybe = createModifiedPredicates(((predicate) => {
          const modifiedPredicate = function () { return !!not.assigned(arguments[0]) || predicate.apply(null, arguments); };

          return modifiedPredicate.l = predicate.length, modifiedPredicate.m = !0, modifiedPredicate;
        }), ((value) => {
          if (!1 === assigned(value)) return !0;
          return value;
        })), assert.not = createModifiedModifier(assertModifier, not, 'not '), assert.maybe = createModifiedModifier(assertModifier, maybe, 'maybe '), collections.forEach(((key) => { predicates[key].of = createModifiedFunctions([ofModifier.bind(null, null), predicates[key], predicates, {}, '']); })), createOfModifiers(assert, assertModifier), createOfModifiers(not, notModifier), collections.forEach(((key) => { maybe[key].of = createModifiedFunctions([ofModifier.bind(null, 'maybe'), predicates[key], predicates, {}, '']), assert.maybe[key].of = createModifiedModifier(assertModifier, maybe[key].of), assert.not[key].of = createModifiedModifier(assertModifier, not[key].of); })), (function (functions) { void 0 === (__WEBPACK_AMD_DEFINE_RESULT__ = function () { return functions; }.call(exports, __webpack_require__, exports, module)) || (module.exports = __WEBPACK_AMD_DEFINE_RESULT__); }(mixin(functions, {
          assert,
          not,
          maybe,
        })));
      }());
    },
    780: (module) => {
      const createAbortError = () => {
        const error = new Error('Delay aborted');
        return error.name = 'AbortError', error;
      };

      const createDelay = ({
        clearTimeout: defaultClear, setTimeout: set, willResolve,
      }) => (ms, {
        value, signal,
      } = {}) => {
        if (signal && signal.aborted) return Promise.reject(createAbortError());
        let timeoutId; let settle; let rejectFn;
        const clear = defaultClear || clearTimeout; const signalListener = () => { clear(timeoutId), rejectFn(createAbortError()); };

        const delayPromise = new Promise((resolve, reject) => { settle = () => { signal && signal.removeEventListener('abort', signalListener), willResolve ? resolve(value) : reject(value); }, rejectFn = reject, timeoutId = (set || setTimeout)(settle, ms); });
        return signal && signal.addEventListener('abort', signalListener, {
          once: !0,
        }), delayPromise.clear = () => { clear(timeoutId), timeoutId = null, settle(); }, delayPromise;
      };

      const
        delay = createDelay({
          willResolve: !0,
        });

      delay.reject = createDelay({
        willResolve: !1,
      }), delay.range = (minimum, maximum, options) => delay(((minimum, maximum) => Math.floor(Math.random() * (maximum - minimum + 1) + minimum))(minimum, maximum), options), delay.createWithTimers = ({
        clearTimeout, setTimeout,
      }) => {
        const delay = createDelay({
          clearTimeout,
          setTimeout,
          willResolve: !0,
        });

        return delay.reject = createDelay({
          clearTimeout,
          setTimeout,
          willResolve: !1,
        }), delay;
      }, module.exports = delay, module.exports.default = delay;
    },
  };

  const
    __webpack_module_cache__ = {};

  function __webpack_require__(moduleId) {
    if (__webpack_module_cache__[moduleId]) return __webpack_module_cache__[moduleId].exports;
    const module = __webpack_module_cache__[moduleId] = {
      exports: {},
    };

    return __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__), module.exports;
  }

  __webpack_require__.n = (module) => {
    const getter = module && module.__esModule ? () => module.default : () => module;
    return __webpack_require__.d(getter, {
      a: getter,
    }), getter;
  }, __webpack_require__.d = (exports, definition) => {
    for (const 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), (() => {
    const external_log_namespaceObject = log;
    const delay = __webpack_require__(780);
    const delay_default = __webpack_require__.n(delay);
    const check_types = __webpack_require__(923);

    const getTeaserContainers = (node) => Array.from(node.querySelectorAll('.views-responsive-grid, .node-playlist .field-name-field-videos')).filter((grid) => grid.querySelector('.node-teaser, .node-sidebar_teaser, .node-wide_teaser')); const src_assert = (value, message) => { (0, check_types.assert)(value, message); };

    const
      tapNonNull = (x) => (src_assert(x), x);

    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)))))))))))))))))));
      }
    }

    const isNone = function (fa) { return fa._tag === 'None'; };

    const Option_none = {
      _tag: 'None',
    };

    const Option_some = function (a) {
      return {
        _tag: 'Some',
        value: a,
      };
    };

    function fromNullable(a) { return a == null ? Option_none : Option_some(a); }

    const getOrElse = function (onNone) { return function (ma) { return isNone(ma) ? onNone() : ma.value; }; };

    const map_ = function (fa, f) { return isNone(fa) ? Option_none : Option_some(f(fa.value)); };

    const map = function (f) { return function (fa) { return map_(fa, f); }; };

    function compare(x, y) { return x < y ? -1 : x > y ? 1 : 0; }

    function strictEqual(a, b) { return a === b; }

    const ordNumber = {
      equals: strictEqual,
      compare,
    };

    function fromCompare(compare) {
      const optimizedCompare = function (x, y) { return x === y ? 0 : compare(x, y); };

      return {
        equals(x, y) { return optimizedCompare(x, y) === 0; },
        compare: optimizedCompare,
      };
    }

    const contramap = function (f) { return function (fa) { return fromCompare(((x, y) => fa.compare(f(x), f(y)))); }; };

    contramap(((date) => date.valueOf()));
    const ReadonlyArray_filter = function (predicate) { return function (fa) { return fa.filter(predicate); }; };

    const Array_filter = ReadonlyArray_filter;
    const external_m_namespaceObject = m;
    const external_m_default = __webpack_require__.n(external_m_namespaceObject);
    const external_rxjs_namespaceObject = rxjs; const external_rxjs_operators_namespaceObject = rxjs.operators; const
      external_Swal_namespaceObject = Swal;

    const external_Swal_default = __webpack_require__.n(external_Swal_namespaceObject);
    const classAttr = (classNames) => classNames.map((x) => `.${x}`).join(''); const conditionPresets = {
      'Default Condition': '(Math.asinh(ratio * 15) / 15 / (private * 1.8 + 1) + Math.log(likes) / 230) / (image + 8)',
      Newest: '-index',
      Oldest: 'index',
      'Likes / Views': 'ratio',
      'Most Liked': 'likes',
      'Most Viewed': 'views',
    };

    const forwardTo = (observer) => (value) => { observer.next(value); };

    const partial = (f, ...headArgs) => (...restArgs) => f(...headArgs, ...restArgs); const tapIs = (constructor, x) => (src_assert(x instanceof constructor), x); const getInputValue = (event$) => event$.pipe((0, external_rxjs_operators_namespaceObject.pluck)('currentTarget'), (0, external_rxjs_operators_namespaceObject.map)(partial(tapIs, HTMLInputElement)), (0, external_rxjs_operators_namespaceObject.pluck)('value')); const getPageParam = (URL_) => ((URL_, name) => {
      const param = URL_.searchParams.get(name);
      return param ? Number.parseInt(param, 10) : 0;
    })(URL_, 'page');

    const reloadImage = (image) => {
      const {
        src,
      } = image;

      image.src = '', image.src = src;
    };

    const removeEmbeddedPage = (page) => { page.src = '', page.remove(); };

    const getTeaserValue = (info, condition) => {
      const sortParamPairs = [['index', info.initialIndex], ['views', info.viewCount], ['likes', info.likeCount], ['ratio', Math.min(info.likeCount / Math.max(1, info.viewCount), 1)], ['image', info.imageFactor], ['gallery', info.galleryFactor], ['private', info.privateFactor]];
      return new Function(...sortParamPairs.map(([name]) => name), `return (${condition})`)(...sortParamPairs.map((pair) => pair[1]));
    };

    const changeAnchorPageParam = (anchor, value) => ((anchor, key, value) => {
      const newURL = new URL(anchor.href, window.location.href);
      newURL.searchParams.set(key, value), anchor.href = newURL.href;
    })(anchor, 'page', value.toString());

    const groupPageItems = (pageItems) => {
      const group = document.createElement('li');
      pageItems[0].before(group), pageItems[0].style.marginLeft = '0', pageItems.forEach((item) => { item.classList.replace('pager-item', 'pager-current'); });
      const groupList = external_m_default()('ul', {
        style: {
          display: 'inline',
          backgroundColor: 'hsla(0, 0%, 75%, 50%)',
        },
        oncreate(vnode) { vnode.dom.append(...pageItems); },
      });

      external_m_default().render(group, groupList);
    };

    const adjustPager = (adjust$) => adjust$.pipe((0, external_rxjs_operators_namespaceObject.tap)(({
      container, pageCount,
    }) => {
      const currentPage = getPageParam(new URL(window.location.href)); const nextPage = currentPage + pageCount;
      let predicate; [
        ...[() => [tapNonNull(container.querySelector('.pager-previous a')), Math.max(0, currentPage - pageCount)]].filter(() => currentPage > 0), ...(() => {
          const nextPageAnchor = container.querySelector('.pager-next a'); const lastPageAnchor = container.querySelector('.pager-last a');
          if (lastPageAnchor) {
            const reachedLastPage = getPageParam(new URL(lastPageAnchor.href, window.location.href)) < nextPage; const display = reachedLastPage ? 'none' : '';
            if (lastPageAnchor.style.display = display, src_assert(nextPageAnchor), nextPageAnchor.style.display = display, !reachedLastPage) return [() => [nextPageAnchor, nextPage]];
          } else if (nextPageAnchor) return [() => [nextPageAnchor, nextPage]];
          return [];
        })(),
      ].forEach((getArgs) => changeAnchorPageParam(...getArgs())), function_pipe(Array.from(container.querySelectorAll('.pager-item a')), Array_filter((anchor) => {
        const page = getPageParam(new URL(anchor.href, window.location.href));
        return page >= currentPage && page < nextPage;
      }), (predicate = (currentPageAnchors) => currentPageAnchors.length > 0, function (a) { return predicate(a) ? Option_some(a) : Option_none; }), map((anchors) => [...Array.from(container.querySelectorAll('.pager-current')), ...anchors.map((anchor) => tapNonNull(anchor.parentElement))]), map(groupPageItems));
    }));

    const getBrokenImages = () => getTeaserContainers(document).flatMap((container) => Array.from(container.querySelectorAll('img'))).filter((img) => img.complete && img.naturalWidth === 0); const createPreloadPage = (createContainer, parentPageId, url) => {
      const container = createContainer();
      return container.src = url.toString(), container.style.display = 'none', container.classList.add(parentPageId), container;
    };

    const createPreloadUrl = (startURL, page) => {
      const preloadURL = new URL('', startURL);
      return preloadURL.searchParams.set('page', page.toString()), preloadURL;
    };

    const preloadUrlStream = (startURL, pageCount$) => pageCount$.pipe((0, external_rxjs_operators_namespaceObject.scan)((max, value) => Math.max(max, value), 1), (0, external_rxjs_operators_namespaceObject.scan)(([, last], current) => [last, current], [1, 1]), (0, external_rxjs_operators_namespaceObject.mergeMap)(([last, current]) => (0, external_rxjs_namespaceObject.from)([...Array(current - last).keys()].map((i) => getPageParam(startURL) + last + i))), (0, external_rxjs_operators_namespaceObject.map)(partial(createPreloadUrl, startURL))); const trySortTeasers = (condition$) => condition$.pipe((0, external_rxjs_operators_namespaceObject.map)((condition) => [getTeaserContainers(document), condition]), (0, external_rxjs_operators_namespaceObject.mergeMap)((x) => (0, external_rxjs_namespaceObject.of)(x).pipe((0, external_rxjs_operators_namespaceObject.tap)(([containers, condition]) => containers.forEach((container) => ((container, condition) => {
      const teaserDivs = Array.from(container.querySelectorAll('.node-teaser, .node-sidebar_teaser, .node-wide_teaser')); const sortedTeaserCount = container.dataset.sortedTeaserCount ? parseInt(container.dataset.sortedTeaserCount, 10) : 0;
      teaserDivs.filter(({
        dataset,
      }) => !dataset.initialIndex).forEach(({
        dataset,
      }, index) => { dataset.initialIndex = (sortedTeaserCount + index).toString(); }), container.dataset.sortedTeaserCount = teaserDivs.length.toString();

      const getNearbyNumber = (element) => {
        return str = tapIs(Text, element.nextSibling).wholeText.replace(/,/g, ''), Number.parseFloat(str) * (str.includes('k') ? 1e3 : 1);
      };

      const nearbyNumberOrZero = (element) => function_pipe(fromNullable(element), map(getNearbyNumber), getOrElse(() => 0)); const divValuePairs = teaserDivs.map((div) => ({
        initialIndex: parseInt(tapNonNull(div.dataset.initialIndex), 10),
        viewCount: nearbyNumberOrZero(div.querySelector('.glyphicon-eye-open')),
        likeCount: nearbyNumberOrZero(div.querySelector('.glyphicon-heart')),
        imageFactor: div.querySelector('.field-type-image') ? 1 : 0,
        galleryFactor: div.querySelector('.glyphicon-th-large') ? 1 : 0,
        privateFactor: div.querySelector('.private-video') ? 1 : 0,
      })).map((info, index) => [teaserDivs[index], getTeaserValue(info, condition)]);

      divValuePairs.sort((itemA, itemB) => itemB[1] - itemA[1]), teaserDivs.forEach((div) => div.after(document.createElement('span'))), teaserDivs.map((div) => tapNonNull(div.nextSibling)).forEach((anchor, index) => anchor.replaceWith(divValuePairs[index][0]));
    })(container, condition))), (0, external_rxjs_operators_namespaceObject.catchError)((error) => (external_Swal_default().fire('Sorting Failed', `An error accured while sorting: ${error.toString()}`), external_log_namespaceObject.error(error), external_rxjs_namespaceObject.EMPTY)))), (0, external_rxjs_operators_namespaceObject.map)(([containers]) => ({
      containersCount: containers.length,
    })));

    const initParent = async () => {
      if (getTeaserContainers(document).length === 0) return;
      const initialCondition = tapNonNull(await GM.getValue('sortValue', conditionPresets['Default Condition'])); const pageCount = tapNonNull(await GM.getValue('pageCount', 1)); const haveMorePages = document.querySelector('.pager') && !document.querySelector('#comments'); const sortComponent = new class {
        constructor(initialCondition, initialPageCount) {
          this.conditionInputInput$ = new external_rxjs_namespaceObject.Subject(), this.conditionInputChange$ = new external_rxjs_namespaceObject.Subject(), this.conditionInputKeydown$ = new external_rxjs_namespaceObject.Subject(), this.sortButtonClick$ = new external_rxjs_namespaceObject.Subject(), this.presetSelectChange$ = new external_rxjs_namespaceObject.Subject(), this.pageCountInputInput$ = new external_rxjs_namespaceObject.Subject(), this.pageCountInputChange$ = new external_rxjs_namespaceObject.Subject(), this.conditionInputEnterDown$ = this.conditionInputKeydown$.pipe((0, external_rxjs_operators_namespaceObject.filter)((e) => e.key === 'Enter')), this.conditionChange$ = (0, external_rxjs_namespaceObject.merge)(this.conditionInputEnterDown$, this.presetSelectChange$, this.conditionInputChange$), this.sort$ = (0, external_rxjs_namespaceObject.merge)(this.sortButtonClick$, this.conditionInputEnterDown$, this.presetSelectChange$).pipe((0, external_rxjs_operators_namespaceObject.map)(() => this.state.condition)), this.condition$ = this.conditionChange$.pipe((0, external_rxjs_operators_namespaceObject.startWith)(void 0), (0, external_rxjs_operators_namespaceObject.map)(() => this.state.condition)), this.pageCount$ = this.pageCountInputChange$.pipe((0, external_rxjs_operators_namespaceObject.startWith)(void 0), (0, external_rxjs_operators_namespaceObject.map)(() => this.state.pageCount)), this.state = {
            condition: initialCondition,
            pageCount: initialPageCount,
            loadedPageCount: 0,
          }, (0, external_rxjs_namespaceObject.merge)(this.conditionInputInput$.pipe(getInputValue, (0, external_rxjs_operators_namespaceObject.tap)((value) => { this.state.condition = value; })), (0, external_rxjs_namespaceObject.merge)(this.conditionChange$, this.presetSelectChange$.pipe((0, external_rxjs_operators_namespaceObject.tap)((e) => { this.state.condition = tapIs(HTMLSelectElement, e.target).value; }))).pipe((0, external_rxjs_operators_namespaceObject.map)(() => this.state.condition), (0, external_rxjs_operators_namespaceObject.tap)((value) => GM.setValue('sortValue', value))), this.pageCountInputInput$.pipe(getInputValue, (0, external_rxjs_operators_namespaceObject.map)((value) => Number.parseInt(value, 10)), (0, external_rxjs_operators_namespaceObject.tap)((pageCount) => { this.state.pageCount = pageCount; })), this.pageCountInputChange$.pipe((0, external_rxjs_operators_namespaceObject.tap)(() => GM.setValue('pageCount', this.state.pageCount)))).subscribe();
        }

        view() {
          const commonStyle = {
            margin: '5px 2px',
          };

          const presetOptions = Object.entries(conditionPresets).map(([name, value]) => external_m_default()('option', {
            value,
          }, name));

          const uiChildren = {
            conditionInput: external_m_default()(`input${classAttr(['form-control', 'input-sm'])}`, {
              size: 60,
              value: this.state.condition,
              style: commonStyle,
              list: 'iwara-custom-sort-conditions',
              oninput: forwardTo(this.conditionInputInput$),
              onchange: forwardTo(this.conditionInputChange$),
              onkeydown: forwardTo(this.conditionInputKeydown$),
            }),
            conditionDatalist: external_m_default()('datalist', {
              id: 'iwara-custom-sort-conditions',
            }, presetOptions),
            presetSelect: external_m_default()(`select${classAttr(['btn', 'btn-sm', 'btn-info'])}`, {
              onupdate: (vnode) => { tapIs(HTMLSelectElement, vnode.dom).selectedIndex = 0; },
              style: {
                width: '95px',
                ...commonStyle,
              },
              onchange: forwardTo(this.presetSelectChange$),
            }, [
              external_m_default()('option', {
                hidden: !0,
              }, 'Presets'), ...presetOptions,
            ]),
            sortButton: external_m_default()(`button${classAttr(['btn', 'btn-sm', 'btn-primary'])}`, {
              style: commonStyle,
              onclick: forwardTo(this.sortButtonClick$),
            }, 'Sort'),
            label1: external_m_default()(`label${classAttr(['text-primary'])}`, {
              style: commonStyle,
            }, 'load'),
            pageCountInput: external_m_default()(`input${classAttr(['form-control', 'input-sm'])}`, {
              type: 'number',
              value: this.state.pageCount,
              min: 1,
              max: 500,
              step: 1,
              style: {
                width: '7rem',
                ...commonStyle,
              },
              oninput: forwardTo(this.pageCountInputInput$),
              onchange: forwardTo(this.pageCountInputChange$),
            }),
            label2: external_m_default()(`label${classAttr(['text-primary'])}`, {
              style: commonStyle,
            }, 'pages. '),
            statusLabel: external_m_default()(`label${classAttr(['text-primary'])}`, {
              style: commonStyle,
            }, this.state.loadedPageCount < this.state.pageCount ? `${this.state.loadedPageCount} of ${this.state.pageCount} pages done` : 'All pages done'),
          };

          return external_m_default()(`div${classAttr(['form-inline', 'container'])}`, {
            style: {
              display: 'inline-block',
            },
          }, Object.values(uiChildren));
        }

        addLoadedPageCount() { this.state.loadedPageCount += 1, external_m_default().redraw(); }
      }(initialCondition, pageCount);

      const preloadUrl$ = (haveMorePages ? sortComponent.pageCount$ : (0, external_rxjs_namespaceObject.of)(1)).pipe(partial(preloadUrlStream, new URL(window.location.href))); const channel = new BroadcastChannel('iwara-custom-sort'); const parentPageId = `t-${performance.now().toString()}`; const pageLoad$ = (0, external_rxjs_namespaceObject.fromEvent)(channel, 'message').pipe((0, external_rxjs_operators_namespaceObject.pluck)('data'), (0, external_rxjs_operators_namespaceObject.filter)((data) => data.parentPageId === parentPageId)); const teaserPageLoad$ = pageLoad$.pipe((0, external_rxjs_operators_namespaceObject.filter)((message) => message.hasTeasers)); const pageFromUrl = new Map(); const unsortedTeasers$ = teaserPageLoad$.pipe((0, external_rxjs_operators_namespaceObject.mapTo)(void 0), (0, external_rxjs_operators_namespaceObject.startWith)(void 0)); const clonedClass = 'iwara-custom-sort-cloned'; const allStreams = {
        adjustPager$: sortComponent.pageCount$.pipe((0, external_rxjs_operators_namespaceObject.mergeMap)((count) => (0, external_rxjs_namespaceObject.from)(document.querySelectorAll(`.pager:not(.${clonedClass})`)).pipe((0, external_rxjs_operators_namespaceObject.tap)((pager) => { pager.style.display = 'none'; }), (0, external_rxjs_operators_namespaceObject.map)((pager) => {
          const clonedPager = tapIs(HTMLElement, pager.cloneNode(!0));
          return clonedPager.style.display = '', [pager, clonedPager];
        }), (0, external_rxjs_operators_namespaceObject.tap)(([pager, clonedPager]) => {
          const sibling = pager.previousElementSibling;
          sibling && sibling.matches(`.${clonedClass}`) ? sibling.replaceWith(clonedPager) : pager.before(clonedPager);
        }), (0, external_rxjs_operators_namespaceObject.tap)(([, clonedPager]) => { clonedPager.classList.add(clonedClass); }), (0, external_rxjs_operators_namespaceObject.map)(([, clonedPager]) => ({
          container: clonedPager,
          pageCount: count,
        })))), adjustPager),
        logPageLoad$: pageLoad$.pipe((0, external_rxjs_operators_namespaceObject.tap)(external_log_namespaceObject.info)),
        reloadBrokenImages$: unsortedTeasers$.pipe((0, external_rxjs_operators_namespaceObject.mergeMap)(() => (0, external_rxjs_namespaceObject.timer)(0, 8e3).pipe((0, external_rxjs_operators_namespaceObject.take)(2))), (0, external_rxjs_operators_namespaceObject.auditTime)(6e3), (0, external_rxjs_operators_namespaceObject.map)(getBrokenImages), (0, external_rxjs_operators_namespaceObject.tap)((images) => images.forEach(reloadImage)), (0, external_rxjs_operators_namespaceObject.map)((images) => `Reload ${images.length} broken image(s)`), (0, external_rxjs_operators_namespaceObject.tap)(external_log_namespaceObject.info)),
        sortTeasers$: (0, external_rxjs_namespaceObject.merge)(unsortedTeasers$.pipe((0, external_rxjs_operators_namespaceObject.withLatestFrom)(sortComponent.condition$), (0, external_rxjs_operators_namespaceObject.map)(([, condition]) => condition), (0, external_rxjs_operators_namespaceObject.tap)(() => sortComponent.addLoadedPageCount())), sortComponent.sort$).pipe(trySortTeasers, (0, external_rxjs_operators_namespaceObject.map)((result) => `${result.containersCount} containers sorted`), (0, external_rxjs_operators_namespaceObject.tap)(external_log_namespaceObject.info)),
        removeLoadedPage$: pageLoad$.pipe((0, external_rxjs_operators_namespaceObject.map)(({
          url,
        }) => ({
          url,
          container: pageFromUrl.get(url),
        })), (0, external_rxjs_operators_namespaceObject.tap)(({
          url,
        }) => pageFromUrl.delete(url)), (0, external_rxjs_operators_namespaceObject.pluck)('container'), (0, external_rxjs_operators_namespaceObject.map)(tapNonNull), (0, external_rxjs_operators_namespaceObject.tap)(removeEmbeddedPage)),
        addHiddenPreload$: (0, external_rxjs_namespaceObject.zip)(preloadUrl$, teaserPageLoad$.pipe((0, external_rxjs_operators_namespaceObject.scan)((countDown) => (countDown > 0 ? countDown - 1 : countDown), 5), (0, external_rxjs_operators_namespaceObject.map)((countDown) => (countDown > 0 ? 2 : 1)), (0, external_rxjs_operators_namespaceObject.startWith)(2), (0, external_rxjs_operators_namespaceObject.mergeMap)((createPageCount) => (0, external_rxjs_namespaceObject.of)(...Array.from({
          length: createPageCount,
        }, () => {}))))).pipe((0, external_rxjs_operators_namespaceObject.map)(([url]) => [
          url, () => {
            return userAgent = window.navigator.userAgent, document.createElement(userAgent.indexOf('Firefox') > -1 ? 'embed' : 'iframe');
          },
        ]), (0, external_rxjs_operators_namespaceObject.map)(([url, createContainer]) => [url.toString(), createPreloadPage(createContainer, parentPageId, url)]), (0, external_rxjs_operators_namespaceObject.tap)((entry) => pageFromUrl.set(...entry)), (0, external_rxjs_operators_namespaceObject.tap)(([, container]) => document.body.append(container))),
      };

      (0, external_rxjs_namespaceObject.merge)(...Object.values(allStreams)).subscribe();
      const sortComponentContainer = document.createElement('div');
      tapNonNull(document.querySelector('#user-links')).after(sortComponentContainer), external_m_default().mount(sortComponentContainer, sortComponent), external_log_namespaceObject.debug(await GM.listValues());
    };

    const
      initialize = async () => {
        const isParent = window === window.parent;
        external_log_namespaceObject.debug(`${isParent ? 'Parent' : 'Child'}: ${window.location.href}`), await (isParent ? initParent() : (async () => {
          const teaserContainers = getTeaserContainers(document);
          const channel = new BroadcastChannel('iwara-custom-sort');
          const hasTeasers = teaserContainers.length > 0;
          const message = {
            url: window.location.href,
            parentPageId: Array.from(tapNonNull(window.frameElement).classList).filter((x) => x.startsWith('t-'))[0],
            hasTeasers,
          };

          hasTeasers && (await delay_default()(500), ((children, parents) => {
            for (let i = 0, j = 0; i < parents.length && j < children.length; i += 1) {
              const parent = parents[i]; const
                child = children[j];

              parent.className === child.className && (child.className = '', parent.append(child), j += 1);
            }
          })(teaserContainers, getTeaserContainers(window.parent.document))), channel.postMessage(message);
        })());
      };

    (async () => {
      external_log_namespaceObject.setLevel('debug');
      try { await initialize(); } catch (error) { external_log_namespaceObject.error(error); }
    })();
  })();
})();